import pandas import numpy # --------------------- FUNCTIONS --------------------- def make_statement(statement, decoration): """Emphasises headings by adding decoration at the start and end""" return f"{decoration * 3} {statement} {decoration * 3}" def string_check(question, valid_ans_list=('yes', 'no'), num_letters=1): """Checks that user enters the full word or the first letter of a word from a list of valid responses""" while True: response = input(question).lower() for item in valid_ans_list: # Check if the response matches a valid full word if response == item: return item # Check if the response matches the first letter of a valid word elif response == item[:num_letters]: return item # ask user again if the input is invalid print(f"Please choose an option from {valid_ans_list}") def instructions(): make_statement("Instructions", "â„šī¸") print(''' When you start my program it will ask ... - Instructions - Name - budget - Display a list of vegetables with corresponding numbers to purchase The program will record the purchases and calculate the cost/budget. Users will have the option to purchase multiple vegetables and will be able to stop if wanted It will finally show an itemised list of all the purchases ''') def not_blank(question): """Checks that a user response is not blank or only spaces.""" while True: response = input(question) if response.strip() == "": print("Sorry, this can't be blank. Please try again.") else: return response def int_check(question, low, high): """Checks users enter an integer between two values""" error = f"Oops - please enter an integer between {low} and {high}." while True: try: # Change the response to an integer and check that it's within the allowed range response = int(input(question)) if low <= response <= high: return response else: print(error) except ValueError: # Catches invalid inputs to prevent errors print(error) def currency(x): """Formats numbers as currency ($#.##)""" return "${:.2f}".format(x) # --------------------- MAIN ROUTINE --------------------- # Max budget MAX_SPEND = 1000 budget = 0 # lists to hold vegetable names and costs all_vegetables = ["Potatoes", "Carrots", "Cabbage", "Onions", "Pumpkin", "Cauliflower", "Broccoli", "Lettuce", "Tomatoes", "Cucumber"] all_vegetables_costs = [2.20, 2.50, 2.70, 3.00, 3.30, 3.60, 4.00, 7.00, 10.00, 13.20] vegetable_dict = { 'Vegetables': all_vegetables, 'Vegetables Price': all_vegetables_costs, } # create dataframe / table from dictionary vegetables_frame = pandas.DataFrame(vegetable_dict) # rearranging index vegetables_frame.index = numpy.arange(1, len(vegetables_frame) + 1) # currency formatting add_dollars = ['Vegetables Price'] for var_item in add_dollars: vegetables_frame[var_item] = vegetables_frame[var_item].apply(currency) # Display main heading print(make_statement("Ezra's Vegetable Enterprise", "đŸĨ•")) # Ask user if they want to see the instructions print() want_instructions = string_check("Do you want to see the instructions? ") if want_instructions == "yes": instructions() print() # ask user for their name (cant be blank) print() name = not_blank("Name: ") # ask user for budget between $10 and $300 budget = int_check(f"Hello {name}, what is your budget? ", 10, 300) print(f"your budget is ${budget}") print() # set purchase vegetables to none purchased_vegetables = [] purchased_prices = [] # create a purchased dict purchased_dict = { 'Vegetables': purchased_vegetables, 'Vegetables Prices': purchased_prices, } # important list if vegetables vegetable_string = vegetables_frame.to_string(index=False) # --------------------- MAIN LOOP --------------------- while budget <= MAX_SPEND: print() # display vegetables print("Here's a list of vegetables") print(vegetables_frame) print() # prompt user to select a row try: # ask user for choice choice = int_check("choose your Vegetable with the number of the corresponding row: ", 1, 10) selected_row = all_vegetables[choice - 1] vegetable_price = all_vegetables_costs[choice - 1] # check if budget fits the purchase if budget >= vegetable_price: budget -= vegetable_price # Add the chosen vegetable and price to list purchased_vegetables.append(selected_row) purchased_prices.append(vegetable_price) # display choice and new budget print(f"You selected {selected_row} costing ${vegetable_price} ") print(f"Your new budget is ${budget} ") print() else: # tell user if budget is insufficient print(f"sorry the {selected_row} costing ${vegetable_price} " f"is above your current budget of ${budget}. Please try again.") continue # end loop if budget is too low for any more purchases if budget <= 2.2: print("❌ No budget left ❌") print() break # ask the user if they would like to purchase any more vegetables repurchase = string_check("Would you like to purchase another vegetable ") if repurchase == "no": break except ValueError: print("Please enter a valid number") # --------------------- END OF LOOP --------------------- # --------------------- PURCHASE SUMMARY --------------------- # itemised purchase list total_spent = sum(purchased_prices) # create dataframe / table from dictionary purchased_frame = pandas.DataFrame(purchased_dict) # rearranging index purchased_frame.index = numpy.arange(1, len(purchased_frame) + 1) # currency formatting add_dollars = ['Vegetables Prices'] for var_item in add_dollars: purchased_frame[var_item] = purchased_frame[var_item].apply(currency) # displayed itemised purchases if purchased_vegetables: print(make_statement(f"Here are your purchases!", "🍀")) print() print(purchased_frame) print(f"Your total amount spent is: ${total_spent}")