import pandas # Functions go here def make_statement(statement, decoration): """Emphasises headings by adding decoration at the start and end""" print(f"{decoration * 3} {statement} {decoration * 3}") def string_check(question, valid_answers=('yes', 'no'), num_letters=1): """Checks that users enter the full word or the 'n' letter/s of a word from a list of valid responses""" while True: response = input(question).lower() for answer in valid_answers: # check if the response is the entire word if response == answer: return answer # check if it's the first letter elif response == answer[:num_letters]: return answer print(f"Please choose an option from {valid_answers}") def instructions(): print() make_statement("Instructions", "✔") print(''' 1. Enter your name. 2. Choose pickup or delivery. An $11.99 fee applies to delivery. 3. If you choose delivery, you’ll also enter your phone number and address. 4. Select your pizza, base type, size and any extra toppings using the menus. 5. Choose to add another pizza. A maximum of 5 pizzas can be ordered. 6. When you're done, you’ll see a full summary that shows your details and everything you ordered—including prices. 7. The grand total will be displayed and you can then confirm your order. ''') def not_blank(question): """Checks that a user response is not blank""" while True: response = input(question).strip() if response != "": return response print("Sorry, this can't be blank. Please try again.\n") def phone_number_check(question): """Checks users enter an integer that is at least 7 digits long""" error = "Please enter a phone number at least 7 digits long (no spaces, decimals, letters, or symbols)." while True: response = input(question).strip() # Checks if the input is at least 7 digits long if response.isdigit() and len(response) >= 7: return response else: print(error) def int_check(question, low, high): """Checks users enter an integer between two values""" error = f"Please enter an integer between {low} and {high} (ie: a number which does not have a decimal part)." while True: try: # Change the response to an integer and check if it's between the chosen numbers response = int(input(question)) if low <= response <= high: return response else: print(error) except ValueError: print(error) def currency(x): """Formats numbers as currency ($#.##)""" return "${:.2f}".format(x) # Menu setup: # Pizzas pizza_data = { "Item": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], "Pizza": ["Cheese", "Ham & Cheese", "Pepperoni", "Hawaiian", "Meat Lovers", "BBQ Chicken", "Vegetarian", "Seafood", "Supreme", "Butter Chicken"], "Price": [5.99, 6.99, 6.99, 6.99, 8.99, 8.99, 11.99, 12.99, 12.99, 13.99] } # Base type type_of_base_data = { "Item": [1, 2, 3, 4, 5], "Base Type": ["Regular Crust", "Thin Crust", "Stuffed Crust", "Extra Cheese", "Garlic Crust"], "Price": [0.00, 1.99, 1.99, 1.99, 1.99] } # Base size size_of_base_data = { "Item": [1, 2, 3], "Size": ["Small", "Medium", "Large"], "Price": [0.00, 2.99, 5.99] } # Additional toppings extra_toppings = { "Item": [1, 2, 3, 4, 5, 6, 7], "Extra Toppings": ["No Extra Toppings", "Ham", "Pepperoni", "Pineapple", "Olives", "Chicken", "Bacon"], "Price": [0.00, 1.99, 1.99, 1.99, 1.99, 2.99, 3.99] } # Convert each dictionary into a DataFrame pizza_df = pandas.DataFrame(pizza_data) base_df = pandas.DataFrame(type_of_base_data) size_df = pandas.DataFrame(size_of_base_data) extras_df = pandas.DataFrame(extra_toppings) # Main routine starts here # Order confirmation loop while True: # Program main heading make_statement("Welcome to the Pizza Ordering Program", "🍕") # Ask user if they want to see the ordering instructions and display them if requested print() want_instructions = string_check("Do you want to see the ordering instructions? ") # Get customers details if want_instructions == "yes": instructions() print() # Ask user for their name (and check it's not blank) name = not_blank("Enter your name: ") # Ask user for pickup or delivery order_method = string_check("Pickup or delivery? (Note: Delivery is $11.99 extra) ", ['pickup', 'delivery']) # If delivery is chosen ask for phone number and address if order_method == "delivery": phone_number = phone_number_check("Phone number: ") address = not_blank("Delivery address: ") else: phone_number = None address = None # Order variables max_pizzas = 5 pizza_count = 0 total_order_price = 0 total_order = [] grand_total = 0 # Collecting the order from the customer loop while True: # Change pizzas by + 1 pizza_count += 1 # Main statement print() make_statement("Menu", "-") # PIZZA # Printing out pizza menu print() print("Pizzas:") print(pizza_df.to_string(index=False)) # Asking for what number the pizza they want is assigned to print() pizza_choice = int_check("Enter the number assigned to the pizza you want (1,10): ", 1, 10) pizza_item = pizza_choice - 1 pizza_name = pizza_df.at[pizza_item, "Pizza"] pizza_price = pizza_df.at[pizza_item, "Price"] # BASE TYPE # Printing out the base type menu print() print() print("Base Type:") print(base_df.to_string(index=False)) # Asking for what number the type of base they want is assigned to print() base_choice = int_check("Enter the number assigned to the base type you want (1,5): ", 1, 5) base_item = base_choice - 1 base_name = base_df.at[base_item, "Base Type"] base_price = base_df.at[base_item, "Price"] # SIZE # Printing out the size menu print() print() print("Size:") print(size_df.to_string(index=False)) # Asking for what number the type of base they want is assigned to print() size_choice = int_check("Enter the number assigned to the size you want (1–3): ", 1, 3) size_item = size_choice - 1 size_name = size_df.at[size_item, "Size"] size_price = size_df.at[size_item, "Price"] # EXTRA TOPPINGS toppings_selected = [] total_extras_price = 0 # Extra toppings loop so the customer can add more than one extra topping on the same pizza while True: # Printing out the extra toppings menu print() print() print("Extra Toppings:") print(extras_df.to_string(index=False)) # Asking for what number the extra topping they want is assigned to print() extras_choice = int_check("Enter the number assigned to the extra topping you want (1-7): ", 1, 7) extras_item = extras_choice - 1 extras_name = extras_df.at[extras_item, "Extra Toppings"] extras_price = extras_df.at[extras_item, "Price"] toppings_selected.append(f"{extras_name} - {currency(extras_price)}") total_extras_price += extras_price # Break out of the loop if the customer selected no extra toppings if extras_name == "No Extra Toppings": break # Ask customer if they want more additional toppings extra_topping_answer = string_check("Do you want to add another extra topping? ") if extra_topping_answer == "no": break # Calculate total individual pizza price individual_pizza_price = pizza_price + base_price + size_price + total_extras_price # Add individual pizza price to the total order price total_order_price += individual_pizza_price # Gather individual pizza order and add into the total order list order = { "Pizza #": pizza_count, "Pizza": pizza_name, "Pizza Price": pizza_price, "Base Type": base_name, "Base Price": base_price, "Size": size_name, "Size Price": size_price, "Extra Toppings": toppings_selected, "Total Price": individual_pizza_price } # Store as dictionary in list total_order.append(order) # Check if the customer has ordered the maximum amount of pizzas if pizza_count < max_pizzas: # Ask them if they would like to order another pizza print() another_pizza = string_check("Do you want to order another pizza? ") if another_pizza == "no": break # Inform the user that they have ordered the maximum amount of pizzas else: print() print("You have ordered the maximum amount of 5 pizzas.") break # End of ordering loop # ORDER SUMMARY: # Output customers details print() make_statement("Order Summary", "-") print() print(f"Name: {name.capitalize()}.") print(f"Order Method: {order_method.capitalize()}") if order_method == "delivery": delivery_fee = 11.99 grand_total += delivery_fee print(f"Delivery: {currency(delivery_fee)}") print(f"Phone Number: {phone_number}") print(f"Address: {address}") # Output total order print() for item in total_order: print(f"Pizza #{item['Pizza #']}") print(f"Pizza: {item['Pizza']} - {currency(item['Pizza Price'])}") print(f"Base Type: {item['Base Type']} - {currency(item['Base Price'])}") print(f"Size: {item['Size']} - {currency(item['Size Price'])}") print(f"Extra Toppings: {', '.join(item['Extra Toppings'])}") print(f"Total: {currency(item['Total Price'])}") print() # Output grand total - all pizzas and delivery cost grand_total += total_order_price print(f"Your grand total is {currency(grand_total)}") # Confirm order confirmation = string_check("Do you confirm your order? ") print() if confirmation == "yes": print("Your order has been sent.") # Ask if the user want to place another order print() another_order = string_check("Would you like to place another order? ") # Message to customer if they do not want to order another pizza and exit code if another_order == "no": print("Thank you for ordering from the Pizza Ordering Program.") break # Message to customer if they cancel their order else: print("Order Cancelled. Returning to the start.") print()