![]() |
What is going on? - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Homework (https://python-forum.io/forum-9.html) +--- Thread: What is going on? (/thread-42388.html) |
What is going on? - zimmytheflygirl - Jun-28-2024 What it needs to do.... Quote:2. InputExpenseNames What I have... def InputExpenseNames(): expenseItems = [] name = input("Enter expense name (q for quit):") while name != "q" : expenseItems.append(name) name = input("Enter expense name (q for quit):") return expenseItems #expense amounts expenseAmounts def InputExpenseAmounts(expenseItems): expenseAmounts = [] print('How much was spent on ') for i in expenseItems: amount = int(input(i + 'expense items?')) expenceAmount.append(amount) return expenseAmountsWhat I am getting is it goes back to the main_menu and not allowing me to input. Recommendations on how to fix this so I can input into the expenseItems list. This is what I have def in main... while choice != quitOp: main_menu() choice = int(input('Enter expense report option: ')) if choice == nameOp: InputExpenseNames() elif choice == amountOp: InputExpenseAmounts(expenseItems) elif choice == reportOp: displayExpenseReport(expenseItems, expenseAmounts) else: print('Thank you, goodbye') RE: What is going on? - deanhystad - Jun-28-2024 Your posted code does not do what you describe. It contains errors that prevent running the code at all. After I fix the errors I cannot call amountOp or reportOp because your main function does not save the list returned by InputExpenseNames. I can call InputExpenseNames, and that does not do what you describe. Next time post the actual code. Your functions don't work with your main. Main ignores the list returned by InputExpenseNames. Maybe this is what you are talking about. Calling InputExpenseNames creates a new list and adds expense names to this list. Your main loop ignores this list, and the list returned by InputExpenseAmounts, so when you call InputExpenseAmounts, it must be passing an empty list that you initialized in some code you did not post (more reason to include all code in post). These two expenseItems lists are completely different lists. expenseItems = [] def InputExpenseNames(): expenseItems = []It doesn't matter that they have the same name. Assignment inside a function creates a variable that is local to the function, even if there is a global variable that has the same name. Your main needs to assign the list returned by InputExpenseNames. Like this: if choice == nameOp: expenseItems = InputExpenseNames()This loop is wrong. while choice != quitOp: main_menu() choice = int(input('Enter expense report option: ')) if choice == nameOp: expenseItems = InputExpenseNames() # Fixed this elif choice == amountOp: expenseAmounts = InputExpenseAmounts(expenseItems) # Fixed this elif choice == reportOp: displayExpenseReport(expenseItems, expenseAmounts) else: print('Thank you, goodbye')If the user enters something that is not nameOp, amountOp, reportOp or quitOp, your program prints "Thank you. goodbye" and asks for the next menu option. You need to test your code by providing invalid inputs to see what happens. Why are you doing this? choice = int(input('Enter expense report option: '))Do you do math with choice? Is it an index into a list? If you don't use something as an int, don't make it an int. You can check if user input is "1" without worrying about the user entering "a" and crashing the program. Entering an int is dangerous and should be avoided when possible. Why does this code have two inputs? def InputExpenseNames(): expenseItems = [] name = input("Enter expense name (q for quit):") while name != "q" : expenseItems.append(name) name = input("Enter expense name (q for quit):") return expenseItemsRepeating code, even if it is one line of code, should make your skin crawl. You should only have one input and break out of the loop if the user inputs "q". There is a python naming convention that function and variable names don't contain capital letters. Instead of InputExpenseNames the convention is to use underscores: input_expense_names. May as well follow coding conventions while learning coding. You won't learn any bad habits. It may be a matter of omission, like you posted code, but the instructions you posted make no mention of having a menu. Is the menu required? If a menu is required, do you need an option to input expense names and another to input expense amounts? It seems odd that you would not do them at the same time. Maybe a menu option for entering expenses that would call your funciton to input names and then call the function to enter amounts. Make sure you are solving the correct problem. Most coding errors are not writing code that matches the requirements, and the hardest part of coding is understanding what your customer needs. Once you understand the requirments the coding is fairly easy. As an exmaple, your code does not address this requirement: Quote: Input validation should be done including using try … except … to ensure a number was entered. RE: What is going on? - zimmytheflygirl - Jun-28-2024 Thank you for the input...but understand...I have been doing this for one month. This is homework, which means I am learning. In some moment, the code does not look pretty, but it works. I did not post the 5 page pdf of what is expected for this project, I just wanted help on getting the list made in one function and using it in another. If I have it in the code...it has to be there. Quote:PROJECT 4 INTRODUCTION this is most of what is expected RE: What is going on? - deanhystad - Jun-28-2024 You did not need explode. The problem was you passed expenseItems as a positional parameter, so pie accepted this as the optional explode argument. The correct way to solve the problem is use named parameters. Like this:\ def report(items, amounts): plt.pie(amounts, labels=items) # Tells pyplot.pie that items is the labels for the plot. plt.show() RE: What is going on? - zimmytheflygirl - Jun-29-2024 (Jun-28-2024, 08:34 PM)deanhystad Wrote: You did not need explode. Not exploding...but you did say...make my skin crawl. Also understand, I am a perfectionist, and this class is going to bring down my 4.0 ...i am stressing... RE: What is going on? - Pedroski55 - Jun-29-2024 Personally, if I have the name of / reason for an expense and its value, I think they are better in a dictionary. The teacher obviously does not like students! from string import ascii_uppercase from random import choices, randint from pprint import pprint from matplotlib import pyplot as plt import matplotlib.colors # make some random names, save all that inputting by hand # unlikely to be any identical entries in a small sample # otherwise exclude them somehow names = [''.join(choices(ascii_uppercase, k=5)) for i in range(10)] # if you really need the amounts as a list: amounts_list = [randint(1, 1001) for i in range(10)] # make a dictionary of name: amount, save all that inputting by hand amounts = {name: randint(1, 1001) for name in names} # show the data pprint(amounts) def main(): # make some random names, save all that inputting by hand names = [''.join(choices(ascii_uppercase, k=5)) for i in range(10)] # if you really need the amounts as a list: amounts_list = [randint(1, 1001) for i in range(10)] # make a dictionary of name: amount, save all that inputting by hand amounts = {name: randint(1, 1001) for name in names} # show the data pprint(amounts) # or for item in amounts.items(): print(f'We wasted {item[1]} on {item[0]}.') # Creating a pie fig = plt.figure(figsize=(10, 7), num="Apple pie") plt.pie(amounts_list, labels=names) # show plot plt.show() RE: What is going on? - LauraB - Jun-29-2024 There are some errors in the code: Typo in InputExpenseAmounts function: expenceAmount.append(amount) should be expenseAmounts.append(amount). Not storing the returned lists from InputExpenseNames and InputExpenseAmounts in the main loop. RE: What is going on? - Pedroski55 - Jun-29-2024 Here is a function for the bar chart exploded! (I am a terrorist!) def pie_chart(): colours = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink', 'tab:gray', 'tab:olive', 'tab:cyan'] explode = (0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1) expense_names = ['beer', 'car', 'computers', 'flowers', 'food', 'fun', 'girlfriend', 'hotels', 'lawyer', 'mobile'] expense_amounts = {name: randint(1, 1001) for name in expense_names} values = list(expense_amounts.values()) names = list(expense_amounts.keys()) total = sum(values) # Wedge properties wp = {'linewidth': 1, 'edgecolor': "blue"} # Creating autocpt arguments # percent values def func(pct, allvalues): absolute = int(pct / 100.*sum(allvalues)) return "{:.1f}%\n(£{:d})".format(pct, absolute) # Creating plot fig, ax = plt.subplots(figsize=(10, 7), num="My Expenses per Week") # setting the axes title invokes the axes don't want to see them so hide them ax.set_title(f"My Expenses Total = £{total}.00", fontsize=16) #hide x-axis ax.get_xaxis().set_visible(False) #hide y-axis ax.get_yaxis().set_visible(False) wedges, texts, autotexts = ax.pie(values, autopct=lambda pct: func(pct, values), explode=explode, labels=names, shadow=True, colors=colours, startangle=90, wedgeprops=wp, textprops=dict(color="black")) # Adding legend ax.legend(wedges, names, title="My Expenses", loc="upper left", bbox_to_anchor=(-0.4, 0, 0.5, 1)) plt.setp(autotexts, size=8, weight="bold") # show plot plt.show()New, improved! |