I want to keep a running total of how many calories a user has eaten and then insert this into a database whilst also giving feedback on the amount of calories the user has eaten. When I define TotalCalories
outside the function and set it to a global variable (so that it can be used inside another function), I get the error UnboundLocalError: local variable 'TotalCalories' referenced before assignment
def FoodSelection(choice):
global CurrentPupil
CurrentPupil = ""
global FoodSelectionWindow
FoodSelectionWindow = Toplevel()
FoodSelectionWindow.configure(bg="black")
DateAdded = datetime.date.today()
TimeTaken = 0
NoFoodOption = 0
#The validation timer starts here:
while TimeTaken < 2:
time.sleep(60)
TimeTaken = TimeTaken +1
#and ends here
class food():
def __init__(self, name = "no name", calories = 0, photo = ""):
self.name = name
self.calories = calories
self.photo = photo
BoiledEggs = food("Boiled Egg", 155, PhotoImage(file="BoiledEgg.gif"))
ScrambledEggs = food("Scrambled Egg", 148, PhotoImage(file="ScrambledEgg.gif"))
FriedEggs = food("Fried Egg", 196, PhotoImage(file="FriedEgg.gif"))
PoachedEggs = food ("Poached Egg", 143, PhotoImage(file="PoachedEgg.gif"))
Toast = food("Toast", 313, PhotoImage(file="Toast.gif"))
Bacon = food("Bacon", 514, PhotoImage(file="Bacon.gif"))
Cereal = food("Cereal", 379, PhotoImage(file="Cereal.gif"))
Porridge = food("Porridge", 68, PhotoImage(file="Cereal.gif"))
NoBreakfast = food("No Breakfast", 0, PhotoImage(file="NoBreakfast.gif"))
def NoFood():
FoodChoices("No Food")
def BoiledEggsFunct():
FoodChoices("Boiled Eggs")
def FriedEggsFunct():
FoodChoices("Fried Eggs")
def ScrambledEggsFunct():
FoodChoices("Scrambled Eggs")
def PoachedEggsFunct():
FoodChoices("Poached Eggs")
def ToastFunct():
FoodChoices("Toast")
def BaconFunct():
FoodChoices("Bacon")
def CerealFunct():
FoodChoices("Cereal")
def PorridgeFunct():
FoodChoices("Porridge")
global TotalCalories
TotalCalories = 0
def FoodChoices(selection):
if selection == "No Food":
TotalCalories = NoBreakfast.calories
elif selection == "Boiled Eggs":
TotalCalories = BoiledEggs.calories + TotalCalories
elif selection == "Fried Eggs":
TotalCalories = FriedEggs.calories + TotalCalories
elif selection == "Scrambled Eggs":
TotalCalories = ScrambledEggs.calories + TotalCalories
elif selection == "Poached Eggs":
TotalCalories = PoachedEggs.calories + TotalCalories
elif selection == "Toast":
TotalCalories = Toast.calories + TotalCalories
elif selection == "Bacon":
TotalCalories = Bacon.calories + TotalCalories
elif selection == "Cereal":
TotalCalories = Cereal.calories + TotalCalories
elif selection == "Porridge":
TotalCalories = Porridge.calories + TotalCalories
if choice == 'chris':
CurrentPupil = "Chris"
with db:
cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupilID) VALUES (?,?,?,?)''',
([TotalCalories, DateAdded, CurrentPupil,"1"]))
elif choice == 'josh':
CurrentPupil = "Josh"
with db:
cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupilID) VALUES (?,?,?,?)''',
([TotalCalories, DateAdded, CurrentPupil,"2"]))
elif choice == 'sam':
CurrentPupil = "Sam"
with db:
cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupilID) VALUES (?,?,?,?)''',
([TotalCalories, DateAdded, CurrentPupil,"3"]))
elif choice == 'daniel':
CurrentPupl = "Daniel"
with db:
cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupillID) VALUES (?,?,?,?)''',
([TotalCalories, DateAdded, CurrentPupil, "4"]))
elif choice == 'jim':
CurrentPupil = "Jim"
with db:
cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupilID) VALUES (?,?,?,?)''',
([TotalCalories, DateAdded, CurrentPupil,"5"]))
elif choice == 'sean':
CurrentPupil = "Sean"
with db:
cursor.execute(''' INSERT INTO 'Breakfast_History' (CaloriesTotal, DateAddded, PupilNames, PupilID) VALUES (?,?,?,?)''',
([TotalCalories, DateAdded, CurrentPupil,"6"]))
db.commit()
def FeedbackScreen():
FinishWindow = Toplevel()
if TotalCalories > 0 and TotalCalories < 1000:
HealthyLabel = Label(FinishWindow, text = "Congratulations, you are healthy!", font=("Comic Sans MS", 25), fg = "light green",
bg = "black")
HealthyLabel.grid(columnspan=10)
elif TotalCalories > 1000:
UnhealthyLabel = Label(FinishWindow, text = "Try to eat healthier tomorrow. See personalised advice", font=("Comic Sans MS", 25), fg = "yellow",
bg = "black")
UnhealthyLabel.grid(columnspan=10)
elif NoFoodOption == 1:
NoFoodLabel = Label(FinishWindow, text = "Not eating can be harmful to your health. See personalised advice", font=("Comic Sans MS", 25), fg = "red",
bg = "black")
NoFoodLabel.grid(columnspan=10)
else:
Error = Label(FinishWindow, text = "error", font=("Comic Sans MS", 25), fg = "red",
bg = "black")
NoFoodLabel.grid(columnspan=10)
As you can see, I need to use TotalCalories
in a variety of functions throughout this code and so I thought that by making it a global variable, I would be able to do this.
Any suggestions?
Here is a MCVE
of your problem:
global TotalCalories
TotalCalories = 0
def FoodChoices(selection):
if selection == "No Food":
TotalCalories = 100
elif selection == "Boiled Eggs":
TotalCalories = 100 + TotalCalories
FoodChoices("Boiled Eggs")
Running this code produces this output:
$ python test.py
Traceback (most recent call last):
File "test.py", line 13, in <module>
FoodChoices("Boiled Eggs")
File "test.py", line 11, in FoodChoices
TotalCalories = 100 + TotalCalories
UnboundLocalError: local variable 'TotalCalories' referenced before assignment
And inserting global TotalCalories
into the function makes it go away:
def FoodChoices(selection):
global TotalCalories
if selection == "No Food":
TotalCalories = 100
elif selection == "Boiled Eggs":
TotalCalories = 100 + TotalCalories
Python requires that a global name be declared in the function where you are going to use it, if you intend to rebind the global. If you're just reading from it, or mutating it, then you can get away with no declaration in the function.