Python Forum
Please help me refactor my clunky fridge script
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Please help me refactor my clunky fridge script
#1
I am new to Python and programming in general. I am just learning how to use functions.

I made a Fridge script, where it asks a user to input different kinds of food items, adds them to a food category, and then moves on to the next category. At the end it lists everything they've added to the fridge by category. Here is an example of one function:

def add_fruit_fridge():
    """Puts fruit in the fridge until user terminates loop."""
    while True:
        print("\n:::What fruits do you want to add?::: ")
        fruits.append(input("\n"))
        answer = input("Anything else? Please enter Y or N: ")
        if answer == 'Y':
            print("\n")
        elif answer == 'N':
            break
        else:
            break
I am using a different function for each type of food. The script comes out to over 100 lines long, and I realize it is very inefficient. My question is, how can I refactor this script so it uses only one, or less functions to achieve the same result?
Also, I tried to make a Fridge Class, in case a user may have multiple fridges, but I'm having trouble getting the arguments to be correct, and gave up on it and just made it using functions. If anyone can suggest how to make this Class-based, I would appreciate that as well.

This link goes to the entire thing:
https://pastebin.com/LL0x31AS
Reply
#2
Use a dictionary. You have:

fruits = []
meats = []
dairy = []
vegetables = []
sauces = []
sweets = []
Replace it with a dictionary of empty lists:

fridge = {food: [] for food in 'fruits meats dairy vegetebales sauces sweets'.split()}
Then you can input food_type, validate it by checking if it's in the dictionary, use an f-string or the format method to ask 'What {food_type} do you want to put in the fridge? ', and then append it to fridge[food_type].
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply
#3
Thank you for the reply, Ichabod.

I'm starting over, and realize I haven't learned to use dictionaries very well, especially nesting a list within a dictionary. Before I start implementing user input into the script, I'd like to just format the output correctly and properly display what contents are in which food category by looping through each list.

How do I write a for loop to properly display the contents of each list within the dictionary? I am stuck at this part:
fridge = {food: [] for food in 'fruits meats dairy vegetables '
		                       'sauces sweets'.split()}

fridge['sauces'].append('ketchup')

for food_type, food_item in fridge.items():
	print("\n" + food_type.title() + ":")
	for food_item in fridge:
		("\t" + food_item.title())
This prints the food types, but not the items within each list.
Also, the first line is a bit long, is that the correct way to format it? Is it better in general to have less lines overall, or just go for readability?
Reply
#4
You are already looping through fridge in the outer loop. You don't want to do that in the inner loop as well. The inner loop should be over the items in that food type:

for food_type, food_items in fridge.items():
    print("\n" + food_type.title() + ":")
    for item in food_items:
        print("\t" + item.title())
(Oct-12-2019, 07:02 AM)Brompy Wrote: I'd like to just format the output correctly

Then I really suggest looking at the output formatting options in Python. I tend to use the format method of strings:

for food_type, food_items in fridge.items():
    print("\n{}:".format(food_type.title()))
    for item in food_items:
        print("\t{}".format(item.title()))
That's a good method for backward compatibility. It replaces the curly braces ({}) with the parameters to the format method. The newer f-strings are easier, and allow you just put the expressions in the curly braces:

for food_type, food_items in fridge.items():
    print(f"\n{food_type.title()}:")
    for item in food_items:
        print(f"\t{item.title()}")
The first line is 86 characters long. I don't think that's very long at all. It's just over the 79 character limit in PEP8, which is very restrictive. I don't worry until lines are over 108 characters. But there is a balance there in terms of readability, and experience level plays into that. When things do go over the limit, I recommend refactoring the line into separate expressions rather than continuing it across multiple lines. So if that line is hard for you to read, you might write it as:

food_types = 'fruits meats dairy vegetebales sauces sweets'.split()
fridge = {food: [] for food in food_types}
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020