I'm reworking a set of two functions that return a text file name, constructed from a string argument and string variables from a module called inventory
. It seems the inventory
module served as a sort of constants
module, so I've changed it to constants.py
and capitalized the variables. The old functions suffer from a large swath of if/elifs on the order of 600 or so lines with too many elifs to count. The original intent of the code was to not only put together the text file name but to also raise value errors if incorrect strings were passed into the function or constants were changed. I figured I could rewrite this into a try except block, but the only way I could get it to work was nest a second try inside the second except clause. Instead of using single string constants, I've stored the constants in a dictionary to validate the string values before assembling the file name. I'm sure this is silly and there's probably a better way to do it, which is why I'm here.
The function was originally written to accept two arguments, a recipe
(e.g.; 'Cake'
, 'Jam'
, 'Pie'
) and an optional argument for an add in ingredient called add_in
(e.g.;'ChoclateChip'
, 'Maple'
, 'Honey'
), with the default set to None. Throughout the remainder of the program, two parameters are never passed, only one, with the idea being that if the parameter passed is an add_in
, the recipe
retrieved would be for 'Cookies'. This doesn't mean that two parameters will never be passed but as long as I am working on this project they won't, or I will switch it to to require both with keywords. For now, I'm using an arbitrary argument just to keep it flexible. If this is a bad idea, I have no problems changing it. Is this something I should be doing? Or should I just punt this and use just a handful of if/elifs and not do any validating/error checking?
Anyhow. Here's my code:
In constants.py
RECIPES = ['Pie', 'Jam', 'Cookies', 'Doughnuts', 'Cake', 'Marmalade']
ADD_INS = ['ChocolateChip', 'Maple', 'Honey', 'Pecan', 'Walnut', 'BrownSugar']
BAKERY_DICT = {'Apple': {'Recipes': RECIPES, 'Add-ins': ADD_INS},
'Orange': {'Recipes': RECIPES, 'Add-ins': ADD_INS}}
FRUIT = 'Apple'
The get_file_name function:
def get_file_name(*recipe_or_addin): # formerly get_file_name(recipe, addin=None)
try:
# validate the fruit by dictionary key and recipe by index in the dictionary
constants.BAKERY_DICT[constants.FRUIT]['Recipes'].index(recipe_or_addin[0])
return 'cook_book/recipe_' + "_".join([constants.FRUIT, recipe_or_addin[0]]) + '.txt'
except KeyError:
return 'No ' + constants.FRUIT + ' recipes in the bakery'
except ValueError:
try: #<--------#####I'm not so sure I should do it this way#####
# validate the add_in in the dictionary
constants.BAKERY_DICT[constants.FRUIT]['Add-ins'].index(recipe_or_addin[0])
return 'cook_book/recipe' + "_".join([constants.FRUIT, recipe_or_addin[0]]) + 'Cookies.txt'
except ValueError:
return 'No ' + recipe_or_addin[0] + ' in the inventory'