Automate the Boring Stuff with Python 2nd Edition - Sandwich Maker Practice Project I am in learning process, even though its a very easy project, I still want experts to please review it and share the improvement that can be done, if anyone wants to use other modules to shorten the code then you can also use them, I already thank you to the people who wants to spend their precious time for this. other beginners will also find it helpful.
import pyinputplus as pyp


menu = True

# price of all ingredients
prices = {'wheat': 2, 'white': 1, 'sour dough': 3, 'chicken': 2, 'turkey': 3, 'ham': 2, 'tofu': 1,
          'cheddar': 1, 'swiss': 2, 'mozzarella': 3, 'mayo': 1, 'mustard': 1, 'lettuce': 1,
          'ketchup': 1}
while menu:
    # options to select bread, protein, cheese with inputMenu() method
    bread = pyp.inputMenu(['wheat', 'white', 'sour dough'],
                          prompt='Please select the type of bread you want for your sandwich: \n',
                          numbered=True)

    protein = pyp.inputMenu(['chicken', 'Turkey', 'Ham', 'Tofu'],
                            prompt='Which type of protein you would like: \n',
                            numbered=True)

    cheese = pyp.inputYesNo('Do you want Cheese in your sandwich?(Y/N)\n')
    cheese_type = ''
    if cheese == 'yes':
        cheese_type = pyp.inputMenu(['cheddar', 'swiss', 'mozzarella'], numbered=True)

    # using inputYesNo() for single ingredients with no further types
    mayo = pyp.inputYesNo('Do you want mayo?(Y/N) \n')
    mustard = pyp.inputYesNo('Do you want mustard?(Y/N) \n')
    lettuce = pyp.inputYesNo('Do you want lettuce?(Y/N) \n')
    ketchup = pyp.inputYesNo('Do you want tomato ketchup?(Y/N) \n')

    # using inputInt() and blockRegexes that do not allow negative integer, float or 0
    sandwichQT = pyp.inputInt('How much sandwiches you would like to order?\n',
                              blockRegexes=['[0|-|.]'])

    total_amount = 0

    # using for loop to print items, prices and adding their amount to total_amount variable
    for item, price in prices.items():
        if bread == item:
            print(f'Your sandwich ingredients and prices are as follows: \n'
                  f'{item}= {price}')
            total_amount += price

        if protein == item:
            print(f'{item}= {price}')
            total_amount += price

        if cheese_type == item:
            print(f'{item}= {price}')
            total_amount += price

    # for items that have yes and no values stored and also adding their amount to total
    if mayo == 'yes':
        print(f&quot;mayo = {prices['mayo']}&quot;)
        total_amount += prices['mayo']

    if mustard == 'yes':
        print(f&quot;mustard = {prices['mustard']}&quot;)
        total_amount += prices['mustard']

    if lettuce == 'yes':
        print(f&quot;lettuce = {prices['lettuce']}&quot;)
        total_amount += prices['lettuce']

    if ketchup == 'yes':
        print(f&quot;ketchup = {prices['ketchup']}&quot;)
        total_amount += prices['ketchup']

    # at the end printing total amount and how much sandwiches have been ordered
    print(f&quot;sandwich cost x sandwich Qt ordered = {total_amount}x{sandwichQT} = &quot;
          f&quot;{total_amount*sandwichQT}&quot;)

    # confirming if the user need to reorder or user wants to confirm the order by simple yes/no
    # if user confirm by typing yes or y then menu will become false and while loop will terminate
    order_confirm = pyp.inputYesNo('Please confirm your order: (Y/N)\n')
    if order_confirm == 'yes':
        print('Please take your order number from the machine and you will be notified when '
              'its ready')
        menu = False
while True
First of all, using &quot;flag&quot; variables is not customary in Python. Instead of using a boolean variable to control a while loop, you can just do while True: ... break.
Avoiding many ifs
You might notice the repeating structure of:
print(f'{item}= {price}')
total_amount += price

under every if. This is because your logic is reversed. You are currently iterating over ALL possible ingredients and checking if you need them. But there might be many that are not in use. It makes more sense to create a list of ingredients in use and then just take their price in a loop. This will require changing how you save your sauces. Instead of saving them as 'yes', we will save them with their name - to match with the prices dict keys.
So we will create a list of ingredients, and add the sauces as well:
if pyp.inputYesNo('Do you want mayo?(Y/N) \n') == 'yes':
    ingredients.append('mayo')

And now the printing loop will be if-free:
print(f'Your sandwich ingredients and prices are as follows: \n')
for item in ingredients:
    price = prices[item]
    print(f'{item}= {price}')
    total_amount += price

Full Code
import pyinputplus as pyp

# price of all ingredients
prices = {'wheat': 2, 'white': 1, 'sour dough': 3, 'chicken': 2, 'turkey': 3, 'ham': 2, 'tofu': 1,
          'cheddar': 1, 'swiss': 2, 'mozzarella': 3, 'mayo': 1, 'mustard': 1, 'lettuce': 1,
          'ketchup': 1}

while True:
    ingredients = []
    # options to select bread, protein, cheese with inputMenu() method
    ingredients.append(pyp.inputMenu(['wheat', 'white', 'sour dough'],
                          prompt='Please select the type of bread you want for your sandwich: \n',
                          numbered=True))

    ingredients.append(pyp.inputMenu(['chicken', 'Turkey', 'Ham', 'Tofu'],
                            prompt='Which type of protein you would like: \n',
                            numbered=True))

    if pyp.inputYesNo('Do you want Cheese in your sandwich?(Y/N)\n')== 'yes':
        ingredients.append(pyp.inputMenu(['cheddar', 'swiss', 'mozzarella'], numbered=True))

    # using inputYesNo() for single ingredients with no further types
    if pyp.inputYesNo('Do you want mayo?(Y/N) \n') == 'yes':
        ingredients.append('mayo')
    if pyp.inputYesNo('Do you want mustard?(Y/N) \n') == 'yes':
        ingredients.append('mustard')
    if pyp.inputYesNo('Do you want lettuce?(Y/N) \n') == 'yes':
        ingredients.append('lettuce')
    if pyp.inputYesNo('Do you want tomato ketchup?(Y/N) \n') == 'yes':
        ingredients.append('ketchup')

    # using inputInt() and blockRegexes that do not allow negative integer, float or 0
    sandwichQT = pyp.inputInt('How much sandwiches you would like to order?\n',
                              blockRegexes=['[0|-|.]'])

    total_amount = 0
    # using for loop to print items, prices and adding their amount to total_amount variable
    print(f'Your sandwich ingredients and prices are as follows: \n')
    for item in ingredients:
        price = prices[item]
        print(f'{item}= {price}')
        total_amount += price

    # at the end printing total amount and how much sandwiches have been ordered
    print(f&quot;sandwich cost x sandwich Qt ordered = {total_amount}x{sandwichQT} = &quot;
          f&quot;{total_amount*sandwichQT}&quot;)

    # confirming if the user need to reorder or user wants to confirm the order by simple yes/no
    # if user confirm by typing yes or y then menu will become false and while loop will terminate
    if pyp.inputYesNo('Please confirm your order: (Y/N)\n')== 'yes':
        print('Please take your order number from the machine and you will be notified when '
              'its ready')
        break