HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonModerate

Bakery - Python 3.4.2

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
bakerypythonstackoverflow

Problem

I have made a program to calculate the amount of flour, eggs, sugar and butter required for making lemon cakes and cupcakes.

```
import math

cupcake = [4, 0.1, 12, 14]
#[Butter, egg, flour, sugar]
lemon = [80, 4.5, 240, 300]
#[Butter, egg, flour, sugar]

cup_in = int(input('How many cupcakes would you like? '))
lem_in = int(input('How much lemon cake would you like? '))

amount_cup = []
amount_cup = [x*cup_in for x in cupcake]

amount_lemon = []
amount_lemon = [(x * lem_in) for x in lemon]

print(amount_cup)
print(amount_lemon)

total = []
total = [x + y for x, y in zip(amount_cup, amount_lemon)]

print(total)

amt_butter = total[0]
amt_egg = total[1]
amt_flour = total[2]
amt_sugar = total[3]

bag_but_large = 0
bag_but_medium = 0
bag_but_small = 0

bag_flr_large = 0
bag_flr_medium = 0
bag_flr_small = 0

bag_egg_large = 0
bag_egg_medium = 0
bag_egg_small = 0

bag_sgr_large = 0
bag_sgr_medium = 0
bag_sgr_small = 0

#Calculates the amount of butter bags needed
while amt_butter > 0:

if amt_butter > 500:
amt_butter -= 500
bag_but_large += 1

elif amt_butter > 250:
amt_butter -= 250
bag_but_medium += 1

elif amt_butter > 125:
amt_butter -= 125
bag_but_small += 1

else:
bag_but_small += 1
amt_butter = 0

#Flour
while amt_flour > 0:

if amt_flour > 750:
amt_flour -= 750
bag_flr_large += 1

elif amt_flour > 500:
amt_flour -= 500
bag_flr_medium += 1

elif amt_flour > 250:
amt_flour -= 250
bag_flr_small += 1

else:
bag_flr_small += 1
amt_flour = 0

#Egg
while amt_egg > 0:

if amt_egg > 12:
amt_egg -= 12
bag_egg_large += 1

elif amt_egg > 10:
amt_egg -= 10
bag_egg_medium += 1

elif amt_egg > 6:
amt_egg -= 6
bag_egg_small += 1

else:
bag_egg_small += 1
a

Solution

You should use functions and better datatypes.

You need to know how many; butter, egg, flour and sugar, bags you need, which come in large, medium and small sizes.
And so wrote the same while loop four times.
Which is perfect for a function!

Instead you should make a function if we keep it simple and have it work the way you have it now,
then you can use a function like trickle_groups(amount: int, large: int, medium: int, small: int) -> tuple.
Which would get you the function:

def trickle_groups(amount, large, medium, small):
    large_bags, medium_bags, small_bags = 0, 0, 0
    while amount > 0:
        if amount > large:
            amount -= large
            large_bags += 1
        elif amount > medium:
            amount -= medium
            medium_bags += 1
        elif amount > small:
            amount -= small
            small_bags += 1
        else:
            small_bags += 1
            amount = 0
    return (large_bags, medium_bags, small_bags)


We can then use it on all the different ingredients:

butter_bags = trickle_groups(total[0], [500, 250, 125])
egg_bags    = trickle_groups(total[1], [12, 10, 6])
flour_bags  = trickle_groups(total[2], [750, 500, 250])
sugar_bags  = trickle_groups(total[3], [600, 400, 200])


Bam almost all your code is gone!
After this you should want to do the same with your print statements.
Make a format for the three duplicate print lines, and put it in a function.

DISPLAY_FORMAT = '''\
{1} large bags of {0} needed.
{2} medium bags of {0} needed.
{3} small bags of {0} needed.'''

def display_bags(type, bags):
    print(DISPLAY_FORMAT.format(type, *bags))

# ...

print("Purchases needed: ")
display_bags('butter', butter_bags)
display_bags('flour', flour_bags)
display_bags('sugar', sugar_bags)
display_bags('eggs', egg_bags)


After this I'd recommend that you rearrange the way that you go from input to output.
Instead of manually looping, you can instead actually use a for loop.
To do this you need to make a lists to loop through, so ingredients and bag sizes.
After this you'd want to actually loop through them, with zip you can quite simply.
And then you want to put it in a function main, which you call if you're in the main function:

INGREDIENTS = ['butter', 'egg', 'flour', 'sugar']
CUPCAKE = [4, 0.1, 12, 14]
LEMON = [80, 4.5, 240, 300]
BAG_SIZES = [
    [500, 250, 125],
    [12, 10, 6],
    [750, 500, 250],
    [600, 400, 200],
]

def main():
    cup_in = int(input('How many cupcakes would you like? '))
    lem_in = int(input('How much lemon cake would you like? '))

    amount_cup = [x*cup_in for x in CUPCAKE]
    amount_lemon = [x*lem_in for x in LEMON]
    total = [x + y for x, y in zip(amount_cup, amount_lemon)]
    bags = [trickle_groups(a, b) for a, b in zip(total, BAG_SIZES)]
    print("Purchases needed: ")
    for ingredient, bag in zip(INGREDIENTS, bags):
        display_bags(ingredient, bags)

if __name__ == '__main__':
    main()


You can also optimize trickle_groups, rather than looping until the amount is zero, you can instead find the amount of large bags you need, and the remainder with divmod.
Where you get the amount you need with the division, and you get the amount left with the modulo part.
I change it also to take any amount of bags, and so you should be able to get:

def trickle_groups(amount, bag_sizes):
    bag_sizes = list(bag_sizes)
    bag_sizes.sort(reverse=True)
    amount_bags = []
    for bag in bag_sizes:
        n, amount = divmod(amount, bag)
        amount_bags.append(n)
    if amount:
        amount_bags[-1] += 1
    return tuple(amount_bags)

Code Snippets

def trickle_groups(amount, large, medium, small):
    large_bags, medium_bags, small_bags = 0, 0, 0
    while amount > 0:
        if amount > large:
            amount -= large
            large_bags += 1
        elif amount > medium:
            amount -= medium
            medium_bags += 1
        elif amount > small:
            amount -= small
            small_bags += 1
        else:
            small_bags += 1
            amount = 0
    return (large_bags, medium_bags, small_bags)
butter_bags = trickle_groups(total[0], [500, 250, 125])
egg_bags    = trickle_groups(total[1], [12, 10, 6])
flour_bags  = trickle_groups(total[2], [750, 500, 250])
sugar_bags  = trickle_groups(total[3], [600, 400, 200])
DISPLAY_FORMAT = '''\
{1} large bags of {0} needed.
{2} medium bags of {0} needed.
{3} small bags of {0} needed.'''

def display_bags(type, bags):
    print(DISPLAY_FORMAT.format(type, *bags))

# ...

print("Purchases needed: ")
display_bags('butter', butter_bags)
display_bags('flour', flour_bags)
display_bags('sugar', sugar_bags)
display_bags('eggs', egg_bags)
INGREDIENTS = ['butter', 'egg', 'flour', 'sugar']
CUPCAKE = [4, 0.1, 12, 14]
LEMON = [80, 4.5, 240, 300]
BAG_SIZES = [
    [500, 250, 125],
    [12, 10, 6],
    [750, 500, 250],
    [600, 400, 200],
]

def main():
    cup_in = int(input('How many cupcakes would you like? '))
    lem_in = int(input('How much lemon cake would you like? '))

    amount_cup = [x*cup_in for x in CUPCAKE]
    amount_lemon = [x*lem_in for x in LEMON]
    total = [x + y for x, y in zip(amount_cup, amount_lemon)]
    bags = [trickle_groups(a, b) for a, b in zip(total, BAG_SIZES)]
    print("Purchases needed: ")
    for ingredient, bag in zip(INGREDIENTS, bags):
        display_bags(ingredient, bags)

if __name__ == '__main__':
    main()
def trickle_groups(amount, bag_sizes):
    bag_sizes = list(bag_sizes)
    bag_sizes.sort(reverse=True)
    amount_bags = []
    for bag in bag_sizes:
        n, amount = divmod(amount, bag)
        amount_bags.append(n)
    if amount:
        amount_bags[-1] += 1
    return tuple(amount_bags)

Context

StackExchange Code Review Q#149385, answer score: 17

Revisions (0)

No revisions yet.