global name not defined error - python

I keep on getting an error with my discount variable. name-error: global name 'discount' not defined. please take a look at my code and help me out. I don't want to modify the parameters of the functions at all.
def finddiscount(quantity):
if quantity >= 1 and quantity <= 9:
discount = 0
elif quantity >= 10 and quantity <= 19:
discount = .2
elif quantity >= 20 and quantity <= 49:
discount = .30
elif quantity >= 50 and quantity <= 99:
discount = .40
elif quantity >= 100:
discount = .50
return discount
def calctotal(quantity, price):
finddiscount(quantity)
disc = (price*quantity)*discount
total = (price*quantity)
due = (price*quantity)-(price*quantity)*dicount
print ("\t","Order total $",format(total, "10.2"),"\n\t","Discount $",format(disc,"10.2"),"\n\t","Amount Due $",format (due, "10.2"),sep="")
def main():
quantity = int(input("How many packages where purchased?"))
price = float(input("How much is each item?"))
calctotal(quantity, price)
main()

You have to declare discount as a global if you want to access it in a multi block scope.
discount = 0
def finddiscount(quantity):
...
global discount # Needed to modify global copy of discount
discount = 1

disc = (price*quantity)*discount
You never defined discount in calctotal (and neither in global scope). Assign the result from finddiscount(quantity) to it. At the moment you are calculating the discount, but drop the result immediately by not assigning it to any variable:
def calctotal(quantity, price):
discount = finddiscount(quantity)
disc = (price*quantity)*discount
total = (price*quantity)
due = (price*quantity)-(price*quantity)*dicount
print ("\t","Order total $",format(total, "10.2"),"\n\t","Discount $",format(disc,"10.2"),"\n\t","Amount Due $",format (due, "10.2"),sep="")

If we look at this block of code
def calctotal(quantity, price):
finddiscount(quantity)
disc = (price*quantity)*discount
total = (price*quantity)
due = (price*quantity)-(price*quantity)*dicount
print ("\t","Order total $",format(total, "10.2"),"\n\t","Discount $",format(disc,"10.2"),"\n\t","Amount Due $",format (due, "10.2"),sep="")
neither discount nor dicount (I'm assuming typo) have been declared in calctotal(). Below should solve yoru issue
def calctotal(quantity, price):
discount = finddiscount(quantity)
disc = (price*quantity)*discount
total = (price*quantity)
due = (price*quantity)-(price*quantity)*discount
print ("\t","Order total $",format(total, "10.2"),"\n\t","Discount $",format(disc,"10.2"),"\n\t","Amount Due $",format (due, "10.2"),sep="")
EDIT:
While making discount a global variable is certainly a way to do this, in general I'd recommend not making a variable global unless you have a good reason. For example - if the discount applied was going to be affected by external functions, and you wanted it changed in finddiscount() as well then a global variable would work nicely. However in this scenario you are creating all possible values of discount within finddiscount() and it just makes more sense to use assignment.
The problem with global variables is that you can accidentally reassign them to things you didn't intend to do, and it can clutter up the namespace if done for no reason.

Related

How do I create a variable that can be changed by calling a function in Python but also saves the data of the past changes?

For example, let's say I'm trying to create a wallet system in python where money can be add to and taken out of. I try this code here:
balance = 0
def addmoney(x):
x += balance
addmoney(10000)
print(balance)
but it just gave me 0.
so then I tried this:
def addmoney(x):
balance = 0
balance += x
And I realized that this would set the money back to 0 every time the user adds money, which I didn't want. Is there a solution to this?
You could declare the balance variable as global inside the function.
balance = 0
def addmoney(x):
global balance
balance += x
addmoney(10000)
print(balance)
This is usually do with OOP:
class BankAccount:
def __init__(self, owner, balance, currency):
self.owner = owner
self.balance = balance
self.currency = currency
def print_balance(self):
print("Your current balance is:")
print(self.balance)
def make_deposit(self, amount):
if amount > 0:
self.balance += amount
else:
print("Please enter a valid amount.")
def make_withdrawal(self, amount):
if self.balance - amount >= 0:
self.balance -= amount
else:
print("You don't have enough funds to make this withdrawal.")
To call the function:
my_savings_account = BankAccount("Pepita Perez", 45600, "USD")
my_savings_account.print_balance()
my_savings_account.make_deposit(5000)
my_savings_account.make_withdrawal(200)
my_savings_account.print_balance()
In Python, you must use the global keyword when accessing global variables from within a function. See here.
One way to keep track of the changes is to store the previous values in a list outside the function. Again, using the global keyword
Also your logic for the balance is backwards. You should be adding x to the balance.
balance = 0
historyLst = []
def addmoney(x):
global balance
global historyLst
historyLst.append(balance)
balance += x
addmoney(10000)
print(balance)

Creating a function for a simple menu equation

I'm very new to coding and I've managed to create the equation but I just can't wrap my head around the function side of things - The task is to create a menu which adds 20% VAT - 10% discount and 4.99 delivery fee - I was originally going to repeat the equation and change the price variable but a function would be much better and will require less coding but I just can't figure out how to perform it - Any help would be appreciated.
def menu():
print("[1] I7 9700k")
print("[2] GTX 1080 graphics card")
print("[3] SSD 2 Tb")
price = 399;
discount_percentage = 0.9;
taxed_percentage = 1.2;
Delivery_cost = 4.50;
Vat_price = (price*taxed_percentage)
Fin_price = (Vat_price*discount_percentage)
Final_price = (Fin_price+Delivery_cost)
print("Final price including delivery:", "£" + str(Final_price))
menu()
option = int(input("Enter your option: "))
while option != 0:
if option ==1:
print("I will add equations later :)")
elif option ==3:
print("I will add")
else:
print("You numpty")
print()
menu()
option = int(input("Enter your option: "))```
Since you already have a function for menu() I am going to assume the difficulty is in passing the values. You can define the function as follows:
def get_total_price(price, discount, tax, delivery_cost):
price *= tax
price *= discount
price += delivery_cost
return price
product_price = get_total_price(399, 0.9, 1.2, 4.50)
If the tax, discount and delivery are the same each time, you can hard-code those values into the function and only give the price as a variable as such:
def get_total_price(price):
price *= 1.2
price *= 0.9
price += 4.5
return price
product_price = get_total_price(399)

How to ask if a user is a member and if so, display their discounted price and how to add all values up? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 12 months ago.
Improve this question
I want to ask the user if they are members and if so, give them a 5% discount on the seats they have purchased, if they are not members, there is no discount. I also want to display that discounted price. Also, how would I go about adding up all the final prices and displaying those as well? I don't know where to start with this, any help is appreciated, thanks. There may be some formatting issues, but here is my code:
def main():
print("Your final price for Orchestra seats will be $",get_orchp())
print("Your final price for Center seats will be $",get_centerp())
def get_orchp():
ORCH_SEATS = 75
frontseats = float(input('Enter the number of Orchestra seats you want to purchase : '))
Finalorchp = ORCH_SEATS * frontseats
member = str(input('Are you a member of the local theater group? Enter y or n: '))
if member == 'y':
discount = 0.5
disc = Finalorchp * discount
Findiscorchp = Finalorchp - disc
elif member == 'n':
print('There is no discount for non-members')
return Finalorchp
return findiscorchp
def get_centerp():
CENTER_SEATS = 50
middleseats = float(input('Enter the number of Center Stage seats you want to purchase : '))
Finalcenterp = CENTER_SEATS * middleseats
return Finalcenterp
main()
This is how I would resolve all of your questions:
def main():
orchp = get_orchp()
centerp = get_centerp()
print(f"Your final price for Orchestra seats will be ${orchp}")
print(f"Your final price for Center seats will be ${centerp}")
print(f'Your final price for all tickets is {orchp + centerp}')
def get_orchp():
ORCH_SEATS = 75
frontseats = float(input('Enter the number of Orchestra seats you want to purchase : '))
Finalorchp = ORCH_SEATS * frontseats
member = str(input('Are you a member of the local theater group? Enter y or n: '))
if member == 'y':
Finalorchp *= .95
return Finalorchp
else:
print('There is no discount for non-members')
return Finalorchp
def get_centerp():
CENTER_SEATS = 50
middleseats = float(input('Enter the number of Center Stage seats you want to purchase : '))
Finalcenterp = CENTER_SEATS * middleseats
return Finalcenterp
main()
Please note these
I change the location of the calls to your functions and set a variable to receive them
I changed the prints for the final price to an f string to receive the variables from the functions
Changed Finalorchp to the pythonic version of variable = variable * .95 right under the if member statement
Changed the else statement in get_orchp to else in the event that the user doesn't only put y or n (you could add onto this to have fault tolerance of if it isn't y or n then do something else)
Added another final price print with an f string to add the two variables that receive the 2 variables from the functions.
This code does what you want.
you can see that in the code I have returned both price and discount amount from the getorchp() function as a tuple and using which I have printed the actual price and discount in the main function. If the user is not a member the discount will be zero and in the main function, I have added both orchestra seats and center seat price and printed the total final price. This code answers all questions you have asked
def main():
orc = get_orchp()
print("Your final price for Orchestra seats will be $",orc[0], " and discount is ", orc[1])
cen = get_centerp()
print("Your final price for Center seats will be $",cen)
print("total final price", orc[0]+cen)
def get_orchp():
ORCH_SEATS = 75
frontseats = float(input('Enter the number of Orchestra seats you want to purchase : '))
Finalorchp = ORCH_SEATS * frontseats
member = str(input('Are you a member of the local theater group? Enter y or n: '))
if member == 'y':
discount = 0.5
disc = Finalorchp * discount
Findiscorchp = Finalorchp - disc
return (Findiscorchp, disc)
elif member == 'n':
print('There is no discount for non-members')
return (Finalorchp, 0)
def get_centerp():
CENTER_SEATS = 50
middleseats = float(input('Enter the number of Center Stage seats you want to purchase : '))
Finalcenterp = CENTER_SEATS * middleseats
return Finalcenterp
main()

Tkinter update label when variable changes

I am working on a code that is a clicker game. I have done 90% myself as I have never used Tkinter module before so was a learning project really, anyway to the problem:
I have just sorted the auto clicking function and a label in the window attached to a variable (the amount of cash), at the moment I have the label at a .pack(), and set so it creates a new label after every second. Obviously this will create confusion and isn't what you would expect from a game, so I wondered if there was a way to either:
1) Make the label update every time the variable (Amount of cash) updates (This would be Ideal if you can help me with this)
2)Delete the label with a line of code and then put the new label in with the current variables number (Not as good as the first, but would still be great to have this one if the first isn't possible)
Here is the code so far:
import time
from tkinter import *
root=Tk()
CPS=0
cash=0
mult=1
def blankLine():
for i in range(16):
print ("")
def infoprint():
print("Cash =",cash)
print("")
print("Each click is worth",mult,"cash")
print("")
print("CPS =",CPS)
blankLine()
def CashASecond():
global root
global cash
global CPS
cash += CPS
root.after(1000, CashASecond)
CashASecond()
def CashLabel():
label1=Label(root,text=cash)
label1.pack()
root.after(1000, CashLabel)
CashLabel()
def ManualClicker():
global cash
global mult
cash += 1*(mult)
infoprint()
ManualClickerButton=Button(root,text="Click",command=ManualClicker)
ManualClickerButton.pack()
class upgrades():
def DoubleManualClicker():
global cash
global mult
if cash < 1000:
print("Not enough cash, sorry")
elif cash>= 1000:
print ("Double clicks purchased!")
mult *= 2
cash = cash - 1,000
DoubleManualClickerButton=Button(root,text="Purchase double clicks",command=DoubleManualClicker)
DoubleManualClickerButton.pack()
DoubleManualClickerLabel=Label(root,text="Each click is worth twice as much, costs 1,000 \n")
DoubleManualClickerLabel.pack()
def clicker():
global cash
global mult
global CPS
if cash < 25:
print("Not enough cash, sorry")
elif cash >=25:
CPS += 1
print("CPS is now",CPS)
cash = cash - 25
ClickerButton=Button(root,text="Purchase auto clicker", command=clicker)
ClickerButton.pack()
ClickerLabel=Label(root,text="+1 CPS, costs 25 \n")
ClickerLabel.pack()
def SingleMachine():
global cash
global mult
global CPS
if cash < 50:
print("Not enough cash, sorry")
elif cash >= 50:
CPS += 3
print("CPS is now",CPS)
cash = cash - 50
SingleMachineButton=Button(root,text="Purcahse Single Cash Printer",command=SingleMachine)
SingleMachineButton.pack()
SingleMachineLabel=Label(root,text="+3 CPS, costs 50 \n")
SingleMachineLabel.pack()
def LoftOfCashPrinter():
global cash
global mult
global CPS
if cash < 100:
print("Not enough cash, sorry")
elif cash >= 100:
CPS += 5
print("CPS is now",CPS)
cash=cash-100
LoftOfCashPrinterButton=Button(root,text="Purchase a loft of cash printers",command=LoftOfCashPrinter)
LoftOfCashPrinterButton.pack()
loftlabel=Label(root,text="+7 CPS, costs 100 \n")
loftlabel.pack()
root.title("Cash Clicker! ALPHA! By George Hill")
root.geometry("500x900+900+0")
root.mainloop()
Thanks in advance :)
I had this problem before and the way I managed to fix this was to use events and bindings. Note that I am using classes and Application. e.g.
def Click(self, event):
self.Label['text'] = ....
....
self.Buy = Button(....)
self.Buy.grid(....)
self.Buy.bind('<Button>', self.Click)
self.Label = Label(....)
self.Label.grid(....)
I understand this code is very basic (it won't work) and the use of .... is to show where the use of variables and the like will be used. This is written purely to show you how to bind widgets.

NameError: Global Name not defined

my python code keeps getting nameerror, global variable not defined on ticketSold. I am not sure how to fix this, as I did define it as a global variable. Any help is appreciated.
aLimit=300
bLimit=500
cLimit=100
aPrice=20
bPrice=15
cPrice=10
def Main():
global ticketSold
getTickets(aLimit)
sectionIncome=calcIncome(ticketSold,aPrice)
SectionIncome+=totalIncome
print("The theater generated this much money from section A "+str(sectionIncome))
getTickets(bLimit)
sectionIncome=calcIncome(ticketSold,bPrice)
SectionIncome+=totalIncome
print("The theater generated this much money from section B "+str(sectionIncome))
getTickets(cLimit)
sectionIncome=calcIncome(ticketSold,cPrice)
sectionIncome+=totalIncome
print("The theater generated this much money from section C "+str(sectionIncome))
print("The Theater generated "+str(totalIncome)+" total in ticket sales.")
def getTickets(limit):
ticketSold=int(input("How many tickets were sold? "))
if (ticketsValid(ticketSold,limit)==True):
return ticketSold
else:
getTickets(limit)
def ticketsValid(ticketSold,limit):
while (ticketSold>limit or ticketSold<0):
print ("ERROR: There must be tickets less than "+str(limit)+" and more than 0")
return False
return True
def calcIncome(ticketSold,price):
return ticketSold*price
Saying global varname does not magically create varname for you. You have to declare ticketSold in the global namespace, for example after cPrice=10. global only makes sure that when you say ticketSold, you're using the global variable named ticketSold and not a local variable by that same name.
Here is a version which:
is Python 2 / 3 compatible
does not use any global variables
is easily extended to any number of sections
demonstrates some benefits of OOP (as opposed to a proliferation of named variables: aLimit, bLimit, etc - what will you do when you reach 27 sections?)
And so:
import sys
if sys.hexversion < 0x3000000:
# Python 2.x
inp = raw_input
else:
# Python 3.x
inp = input
def get_int(prompt):
while True:
try:
return int(inp(prompt))
except ValueError: # could not convert to int
pass
class Section:
def __init__(self, name, seats, price, sold):
self.name = name
self.seats = seats
self.price = price
self.sold = sold
def empty_seats(self):
return self.seats - self.sold
def gross_income(self):
return self.sold * self.price
def sell(self, seats):
if 0 <= seats <= self.empty_seats():
self.sold += seats
else:
raise ValueError("Cannot sell {} seats, only {} are available".format(seats, self.empty_seats))
def main():
# create the available sections
sections = [
Section("Loge", 300, 20., 0),
Section("Floor", 500, 15., 0),
Section("Wings", 100, 10., 0)
]
# get section seat sales
for section in sections:
prompt = "\nHow many seats were sold in the {} Section? ".format(section.name)
while True:
# prompt repeatedly until a valid number of seats is sold
try:
section.sell(get_int(prompt))
break
except ValueError as v:
print(v)
# report section earnings
print("The theatre earned ${:0.2f} from the {} Section".format(section.gross_income(), section.name))
# report total earnings
total_earnings = sum(section.gross_income() for section in sections)
print("\nTotal income was ${:0.2f} on ticket sales.".format(total_earnings))
if __name__=="__main__":
main()
which gives us
How many seats were sold in the Loge Section? 300
The theatre earned $6000.00 from the Loge Section
How many seats were sold in the Floor Section? 300
The theatre earned $4500.00 from the Floor Section
How many seats were sold in the Wings Section? 100
The theatre earned $1000.00 from the Wings Section
Total income was $11500.00 on ticket sales.

Categories