import pandas import random # Functions go here def make_statement(statement, decoration): """Emphasises headings by adding decoration at the start and end""" return f"{decoration * 1} {statement} {decoration * 1}" 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 is the entire world if response == item: return item # check if it's the first letter elif response == item[:num_letters]: return item print(f"Please choose an option from {valid_ans_list}") def instructions(): make_statement("Instructions", "ℹ️") print(''' When you start the program, it will first prompt you for instructions, then ask for your name and your budget. Afterward, it will display a list of vegetables, each with a corresponding number for easy selection. You can then select multiple vegetables to purchase, with the option to stop purchasing at any time. The program will record each purchase and continuously calculate the total cost against your budget. Once you finish, it will display an itemized list of all the vegetables purchased and their costs , and it will save this list to a file for future reference. ''') def not_blank(question): """Checks that a user response is not blank""" while True: response = input(question) if response != "": return response print("Sorry, this can't be blank. Please try again.") def int_check(question): """Checks users enter an integer / float that is more than zero (or the 'xxx' exit code)""" error = "Oops - please enter an integer." while True: response = input(question).lower() # check for the exit code if response == "xxx": return response try: # Change the response to an integer and check that it's more than zero response = int(response) if response > 0: return response else: print(error) except ValueError: print(error) def currency(x): """Formats numbers as currency ($#.##)""" return "${:.2f}".format(x) # Main Routine goes here # Initialise ticket numbers MAX_TICKETS = 5 tickets_sold = 0 # initialise variables payment_ans = ('cash', 'credit') # Ticket Price List CHILD_PRICE = 7.50 ADULT_PRICE = 10.50 SENIOR_PRICE = 6.50 # Credit card surcharge (currently 5%) CREDIT_SURCHARGE = 0.05 # lists to hold ticket details all_names = [] all_ticket_costs = [] all_surcharges = [] mini_movie_dict = { 'Name': all_names, 'Ticket Price': all_ticket_costs, 'Surcharge': all_surcharges } # Program main heading print(make_statement("Mini-Movie Fundraiser Program", "🍿")) # Ask user if they want to see the instructions # display them if necessary print() want_instructions = string_check("Do you want to see the instructions? ") if want_instructions == "yes": instructions() print() # Loop to get name, age and payment details while tickets_sold < MAX_TICKETS: # Ask user for their name (and check it's not blank) print() name = not_blank("Name: ") # if name is exit code, break out of loop if name == "xxx": break # Ask for their age and check it's between 12 and 120 age = int_check("Age: ") # Output error message / success message if age < 12: print(f"{name} is too young") continue # Child ticket price ($7.50) elif age < 16: ticket_price = CHILD_PRICE # Adult ticket ($10.50) elif age < 65: ticket_price = ADULT_PRICE # Senior Citizen ticket ($6.50) elif age < 121: ticket_price = SENIOR_PRICE else: print(f"{name} is too old") continue # Ask user for payment method (cash / credit / ca / cr) pay_method = string_check("Payment method: ", payment_ans, 2) if pay_method == "cash": surcharge = 0 # if paying by credit, calculate surcharge else: surcharge = ticket_price * CREDIT_SURCHARGE # add name, ticket cost and surcharge to all_names.append(name) all_ticket_costs.append(ticket_price) all_surcharges.append(surcharge) tickets_sold += 1 # End of Ticket Loop # create dataframe / table from dictionary mini_movie_frame = pandas.DataFrame(mini_movie_dict) # Calculate the total payable for each ticket mini_movie_frame['Total'] = mini_movie_frame['Ticket Price'] + mini_movie_frame['Surcharge'] mini_movie_frame['Profit'] = mini_movie_frame['Ticket Price'] - 5 # Work out total paid and total profit... total_paid = mini_movie_frame['Total'].sum() total_profit = mini_movie_frame['Profit'].sum() # choose random winner... winner = random.choice(all_names) # find index of winner (ie: position in list) winner_index = all_names.index(winner) # retrieve Winner Ticket Price and Profit (so we can adjust # profit numbers so that the winning ticket is excluded) ticket_won = mini_movie_frame.at[winner_index, 'Total'] profit_won = mini_movie_frame.at[winner_index, 'Profit'] # Currency Formatting (uses currency function) add_dollars = ['Ticket Price', 'Surcharge', 'Total', 'Profit'] for var_item in add_dollars: mini_movie_frame[var_item] = mini_movie_frame[var_item].apply(currency) # Output movie frame without index mini_movie_string = mini_movie_frame.to_string(index=False) total_paid_string = f"Total Paid: ${total_paid:.2f}" total_profit_string = f"Total Profit: ${total_profit:.2f}" # winner announcement lucky_winner_string = (f"The lucky winner is {winner}. " f"Their ticket worth ${ticket_won:.2f} is free!") final_total_paid_string = f"Total Paid is now ${total_paid - ticket_won:.2f}" final_profit_string = f"Total Profit is now ${total_profit - profit_won:.2f}" if tickets_sold == MAX_TICKETS: num_sold_string = make_statement(f"You have sold all the tickets " f"(ie: {MAX_TICKETS} tickets)", "-") else: num_sold_string = make_statement(f"You have sold {tickets_sold} / " f"{MAX_TICKETS} tickets.", "-") # Additional strings / Headings heading_string = make_statement("Mini Movie Fundraiser", "=") ticket_details_heading = make_statement("Ticket Details", "-") raffle_heading = make_statement("--- Raffle Winner ---", "-") adjusted_sales_heading = make_statement("Adjusted Sales & Profit", "-") adjusted_explanation = (f"We have given away a ticket worth ${ticket_won:.2f} which means \nour" f"sales have decreased by ${ticket_won:.2f} and our profit \n " f"decreased by ${profit_won:.2f}") # List of strings to be outputted / written to file to_write = [heading_string, "\n", ticket_details_heading, mini_movie_string, "\n", total_paid_string, total_profit_string, "\n", raffle_heading, lucky_winner_string, "\n", adjusted_sales_heading, adjusted_explanation, "\n", final_total_paid_string, final_profit_string, "\n", num_sold_string] # Print Area print() for item in to_write: print(item) # create file to hold data (add .txt extension) file_name = "MMF_ticket_details" write_to = f"{file_name}.txt" text_file = open(write_to, "w+") # write the item to file for item in to_write: text_file.write(item) text_file.write("\n")