My code right now is in an infinite loop, displaying the menu choices for doughnuts. I want it so that the user selects as many doughnuts as they want until they input \"5\". <
tl;dr check the improved version at the bottom of the answer
You can use the second form of iter to conveniently loop over user input until a certain value is given, in that case 5
.
def get_choice():
while True:
choice = input('> ')
if choice in ('1', '2', '3', '4', '5'):
return int(choice)
else:
print("Please enter a valid choice from 1-5.")
if __name__ == '__main__':
print("Please select doughnuts from the following menu: ")
print("1. Chocolate-dipped Maple Puff ($3.50 each)")
print("2. Strawberry Twizzler ($2.25 each)")
print("3. Vanilla Chai Strudel ($4.05 each)")
print("4. Honey-drizzled Lemon Dutchie ($1.99)")
print("5. No more doughnuts.")
order = set(iter(get_choice, 5))
print(order)
Please select doughnuts from the following menu:
1. Chocolate-dipped Maple Puff ($3.50 each)
2. Strawberry Twizzler ($2.25 each)
3. Vanilla Chai Strudel ($4.05 each)
4. Honey-drizzled Lemon Dutchie ($1.99)
5. No more doughnuts.
> 2
> 4
> 3
> 7
Please enter a valid choice from 1-5.
> 5
{2, 3, 4}
As you can see, this generated a set
of orders which can then be used to request further inputs.
Although, using a bunch of elif statements is not optimal here because it adds a lot of repetition and is not very maintainable. Instead, you should use a list of dictionaries to store information specific to each donut.
doughnuts = [
{'name': 'Chocolate-dipped Maple Puff', 'price': 3.50},
{'name': 'Stawberry Twizzler', 'price': 2.25},
...
]
Now, all the print
above can be simplified like so.
for i, doughnut in enumerate(doughnuts, start=1):
print(f'{i}. {doughnut["name"]} (${doughnut["price"]} each)')
print(f'{i + 1}. No more doughnuts.')
You should do the same for you arithmetic, when variable are highly related, their values should instead be stored together in a list
or a dict
.
receipt = [
{
**doughnuts[i],
'qty': int(input(f'How many {doughnuts[i]["name"]} '))
}
for i in order
]
print(f"Here is your receipt: ")
for item in receipt:
print("==========================================")
print(f"{item['qty']} {item['name']}")
print("==========================================")
print(f"Total Cost: ${item['qty'] * item['price']:.2f}")
1. Chocolate-dipped Maple Puff ($3.5 each)
2. Stawberry Twizzler ($2.25 each)
3. Vanilla Chai Strudel ($4.05 each)
4. Honey-drizzled Lemon Dutchie ($1.99 each)
5. No more doughnuts.
> 1
> 2
> 5
How many Stawberry Twizzler 2
How many Vanilla Chai Strudel 1
Here is your receipt:
==========================================
2 Stawberry Twizzler
==========================================
Total Cost: $4.50
==========================================
1 Vanilla Chai Strudel
==========================================
Total Cost: $4.05
You then have a simplified version of you code. Shorter and more easy to maintain: to add doughnuts you simply need to update the initial list doughnuts
.
doughnuts = [
{'name': 'Chocolate-dipped Maple Puff', 'price': 3.50},
{'name': 'Stawberry Twizzler', 'price': 2.25},
{'name': 'Vanilla Chai Strudel', 'price': 4.05},
{'name': 'Honey-drizzled Lemon Dutchie', 'price': 1.99}
]
def get_choice():
allowed = map(str, range(1, len(doughnuts) + 2))
while True:
choice = input('> ')
if choice in allowed:
return int(choice)
else:
print("Please enter a valid choice.")
if __name__ == '__main__':
for i, doughnut in enumerate(doughnuts, start=1):
print(f'{i}. {doughnut["name"]} (${doughnut["price"]} each)')
print(f'{i + 1}. No more doughnuts.')
receipt = [
{
**doughnuts[i],
'qty': int(input(f'How many {doughnuts[i]["name"]}'))
}
for i in set(iter(get_choice, 5))
]
print(f"Here is your receipt: ")
for item in receipt:
print("==========================================")
print(f"{item['qty']} {item['name']}")
print("==========================================")
print(f"Total Cost: ${item['qty'] * item['price']:.2f}")