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

前端 未结 2 1193
别那么骄傲
别那么骄傲 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条回答
  • 2021-01-29 14:16

    There are a few problems here.

    The first is that the logic to respond to a choice is outside your while loops. That can be fixed by indenting that whole block.

    Second when the user inputs 5, the condition in while choice not in [1,2,3,4]: evaluates to True, so the user is prompted to enter a valid choice again. This can be fixed by removing that inner while loop entirely.

    Finally upon reaching the elif choice == 5 block, the user will not see any of these receipt prints because choice is 5 and therefore not 1, 2, 3, or 4. I think what you mean here is for the count of chocolate, strawberry, vanilla, or honey to be nonzero. Also these should all be if rather than elif blocks since they are independent of each other (a user can get some chocolate and some vanilla).

    With all that in mind here is a refactor:

    print("Welcome to Dino's International Doughnut Shoppe!")
    name = input("Please enter your name to begin: ")
    
    #doughnuts menu
    chocolate = strawberry = vanilla = honey = 0
    done = False
    while not done:
        print("Please enter a valid choice from 1-4.")
        print("Please select a doughnut 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.")
        choice = int(input(">"))
    
    
        if choice == 1:
            chocolate = int(input("How many chocolate-dipped Maple Puff(s) would you like to purchase? "))
        elif choice == 2:
            strawberry = int(input("How many Strawberry Twizzler(s) would you like to purchase? "))
        elif choice == 3:
            vanilla = int(input("How many Vanilla Chai Strudel(s) would you like to purchase? "))
        elif choice == 4:
            honey = int(input("How many Honey-drizzled Lemon Dutchie(s) would you like to purchase? "))
        elif choice == 5:
            done = True
            print(f"{name}, Here is your receipt: ")
    
            if chocolate > 1:
                print("==========================================")
                print(f"{chocolate} Chocolate Dipped Maple Puffs")
                print("==========================================")
                print(f"Total Cost: ${chocolate*3.50:.2f}")
            if strawberry > 1:
                print("==========================================")
                print(f"{strawberry} Strawberry Twizzlers")
                print("==========================================")
                print(f"Total Cost: ${strawberry*2.25:.2f}")
            if vanilla > 1:
                print("==========================================")
                print(f"{vanilla} Vanilla Chai Strudels")
                print("==========================================")
                print(f"Total Cost: ${vanilla*4.05:.2f}")
            if honey > 1:
                print("==========================================")
                print(f"{honey} Honey-drizzled Lemon Dutchies")
                print("==========================================")
                print(f"Total Cost: ${honey*1.99:.2f}")
    
        print("Thank you for shopping at Dino's International Doughnut Shoppe! Please come again!")
    
    0 讨论(0)
  • 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}")
    
    0 讨论(0)
提交回复
热议问题