How to stop loop until user inputs a keyword to stop?

前端 未结 2 1228
别那么骄傲
别那么骄傲 2021-01-29 13:55

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\". <

2条回答
  •  萌比男神i
    2021-01-29 14:24

    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)
    

    Example

    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.

    Use data structures

    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}")
    

    Example

    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
    

    Final version

    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}")
    

提交回复
热议问题