0

I'm a beginner python programmer...Today I was trying to write a program with several functionalities:

  1. Takes orders from customers and puts them inside a list(which the orders are dictionaries)
  2. Displays the menu
  3. Displays the summary of the order
  4. Remove certain items from your order
  5. And finally submit the order(which displays the summary of your order and then empties the list)

Two things that I should mention here:

  • I designed it in a way so that you can also order special toppings with each sandwich you order...Once you choose your sandwich, it will be added to the list of your order and then you will be asked if you want to add a special topping to it or not...If you choose to order a special topping with it, the topping will be added as a key to your sandwich(dictionary) in your order list(not the sandwiches list)
  • I declared sandwiches as dictionaries manually and added them to a list...The same thing happend to the toppings as well...

So first of all here is the program:

sandwich1 = {
    'Name': 'Normal Chicken Sandwich',
    'Price': 20.99,
    'Tag': 1,
}
sandwich2 = {
    'Name': 'Egg Sandwich',
    'Price': 15.99,
    'Tag': 2,
}
sandwich3 = {
    'Name': 'Fish Sandwich',
    'Price': 17.99,
    'Tag': 3,
}
sandwich4 = {
    'Name': 'Grilled Cheese Sandwich',
    'Price': 25.99,
    'Tag': 4,
}
sandwich5 = {
    'Name': 'Grilled Chicken Sandwich',
    'Price': 23.99,
    'Tag': 5,
}
sandwich6 = {
    'Name': 'Ham Sandwich',
    'Price': 21.99,
    'Tag': 6,
}
sandwich7 = {
    'Name': 'Roast Beef Sandwich',
    'Price': 25.99,
    'Tag': 7,
}
topping1 = {
    'Name': 'Sliced egg with chili sauce',
    'Price': 5.99,
    'Tag': 8,
}
topping2 = {
    'Name': 'Beef with wasabi mayonnaise',
    'Price': 6.99,
    'Tag': 9,
}
topping3 = {
    'Name': 'Reduced fat ricotta, peas & mint',
    'Price': 4.99,
    'Tag': 10,
}
topping4 = {
    'Name': 'Turkey, cranberry & avocado',
    'Price': 8.99,
    'Tag': 11,
}
sandwiches = [sandwich1, sandwich2, sandwich3, sandwich4, sandwich5, sandwich6,
 sandwich7]
toppings = [topping1, topping2, topping3, topping4]
ordered_sandwiches = []
counter = 0
def instructions():
    print("========================")
    print("S --> Show Menu")
    print("P --> Place Order")
    print("O --> Order Summary")
    print("R --> Remove Item From Order")
    print("T --> Submit Your Order")
    print("quit --> Quit The Program")
    print("========================")
def show_menu(sandwiches_list, toppings_list):
    print("==========Menu==========")
    print("\n=======Sandwiches=======")
    for sandwich in sandwiches_list:
        print(f"- {sandwich['Name']} ---> ${sandwich['Price']} --> Tag:{sandwich['Tag']}")
    print("\n========Toppings========")
    for topping in toppings_list:
        print(f"- {topping['Name']} ---> ${topping['Price']} --> Tag:{topping['Tag']}")
def place_order(sandwiches_list, toppings_list, ordered_sandwiches_list):
    while True:
        print("Type 666 To Quit Ordering...")
        choice2 = int(input("Please Type The Sandwich Tag Number: "))
        if choice2 == 666:
            break
        elif choice2 > 7 or choice2 < 1:
            print("Unknown Tag Number -- Please Try Again!")
            continue
        for sandwich in sandwiches_list:
            if choice2 == sandwich['Tag']:
                ordered_sandwiches_list.append(sandwich)
        choice3 = input("Do You Want To Order Special Topping With It?(y/n): ")
        if choice3 == 'y' or choice3 == 'Y':
            for topping in toppings_list:
                print(f"- {topping['Name']} ---> ${topping['Price']} -->"
                f" Tag:{topping['Tag']}")
            choice4 = int(input("Please Type The Topping Tag Number: "))
            for topping in toppings_list:
                if choice4 == topping['Tag']:
                    for sandwich in ordered_sandwiches_list:
                        if choice2 == sandwich['Tag']:
                            sandwich['Topping'] = topping['Name']
                            sandwich['Price'] += topping['Price']
                            break
        elif choice3 == 'N' or choice3 == 'n':
            continue
def order_summary(ordered_sandwiches_list):
    Price = 0
    print("========================")
    for sandwich in ordered_sandwiches_list:
        Price += sandwich['Price']
        print("------------------------")
        for key, info in sandwich.items():
            print(f"{key}: {info}")
        print("------------------------")
    print("========================")
    print(f"Overall Price: ${Price}")
def order_remove(ordered_sandwiches_list):
    order_summary(ordered_sandwiches)
    print("Which Item Do You Want To Remove From Your Order?")
    print("Type 666 To Cancel")
    while True:
        choice5 = int(input("Please Type The Tag Number: "))
        if choice5 == 666:
            break
        for sandwich in ordered_sandwiches_list:
            if choice5 == sandwich['Tag']:
                ordered_sandwiches_list.remove(sandwich)
                break
def order_submit(ordered_sandwiches_list):
    choice6 = input("Are You Sure You Want To Submit Your Order?(y/n): ")
    if choice6 == 'Y' or choice6 == 'y':
        order_summary(ordered_sandwiches)
        while len(ordered_sandwiches_list) != 0:
            del ordered_sandwiches_list[counter]
def sandwich_order():
    print("Welcome To Our Restaurant!")
    while True:
        instructions()
        choice = input("Please Type The Corresponding letter for certain actions: ")
        if choice == 'S' or choice == 's':
            show_menu(sandwiches, toppings)
        elif choice == 'P' or choice == 'p':
            place_order(sandwiches, toppings, ordered_sandwiches)
        elif choice == 'O' or choice == 'o':
            order_summary(ordered_sandwiches)
        elif choice == 'R' or choice == 'r':
            order_remove(ordered_sandwiches)
        elif choice == 'T' or choice == 't':
            order_submit(ordered_sandwiches)
        elif choice == 'quit':
            break
        else:
            print("Unknown Selection --- Please Try Again")
sandwich_order()

There is a hidden bug that I can't spot...The problem is that when I decide to order a topping with it, not only the key is added to my order but also it's added to sandwich in the sandwiches list...I want the topping to be added to my order not the sandwich in the sandwiches list...

What's the bug here?

And also, if you know better solution than mine, please let me know here and put an answer

Edit: I think the problem here is with the append method...because when I try to append dictionaries from one list to another, I see both dictionaries get changed...

David Peterson
  • 169
  • 2
  • 9
  • 2
    It seems to me like you need to make a copy of the sandwich that you add to `ordered_sandwiches_list`. Otherwise you are modifying the same global sandwich as referenced by `sandwiches_list`. – 0x5453 May 21 '20 at 18:20
  • 1
    look into solutions using `copy.deepcopy(....)` - they will work with your dictionaries as well. See [how-to-clone-or-copy-a-list](https://stackoverflow.com/questions/2612802/how-to-clone-or-copy-a-list) - copying a dict is the same as copying a list – Patrick Artner May 21 '20 at 18:35

1 Answers1

1

Your ordered_sandwiches_list.append(sandwich) is simply appending the same object not duplicate. Your list items share the same object reference

Fix: Use the .copy() or dict() func for a "top level" copies

ordered_sandwiches_list.append(sandwich.copy())
Dratius
  • 49
  • 4
  • Thank you for your answer...It seems that it solved the problem...But I still don't get something....shouldn't append actually copy the dictionary and place it inside a new list? what does append actually do here?...I'm so confused :) – David Peterson May 22 '20 at 12:41
  • 1
    No append just adds the object as is(equivalent to: s[len(s):] = [x]) unlike extend which takes on a iterable and appends it one by one – Dratius May 22 '20 at 19:30