2017-04-13 4 views
0

私は、ユーザーが食べたカロリーの数を数え続け、これをデータベースに挿入しながら、ユーザーが食べたカロリーの量に関するフィードバックを与えたいと考えています。私は関数の外TotalCaloriesを定義し、(それは別の関数内で使用することができるように)グローバル変数に設定すると、私はエラーを取得する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)  

あなたが見ることができるように、私はAでTotalCaloriesを使用する必要がありますこのコードではさまざまな関数が使用されているので、グローバル変数にすることでこれを実行できると思いました。

提案がありますか?ここで

+1

、このような入れ子構造を持ってする理由はほぼ確実にありません。関数を呼び出す関数に値を代入するだけで、関数の値を '返す '必要があります。 – roganjosh

答えて

1

はあなたの問題のMCVEです:このコードを実行する

global TotalCalories 
TotalCalories = 0 

def FoodChoices(selection): 

    if selection == "No Food": 
     TotalCalories = 100 

    elif selection == "Boiled Eggs": 
     TotalCalories = 100 + TotalCalories 

FoodChoices("Boiled Eggs") 

は、この出力を生成します

$ 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 

と機能にglobal TotalCaloriesを挿入すると、それが離れて行かせる:

def FoodChoices(selection): 
    global TotalCalories 

    if selection == "No Food": 
     TotalCalories = 100 

    elif selection == "Boiled Eggs": 
     TotalCalories = 100 + TotalCalories 

Pythonでは、functioでグローバル名を宣言する必要がありますあなたがグローバルを再バインドしようとしている場合は、それを使用する場所です。それを読んだり、突然変異させたりしているのであれば、関数内で宣言をしなくても済むでしょう。

+0

これは完璧に機能しました。ありがとうございます。 – jamielevy

0

代替手段を検討していない可能性があります。 Pythonでは、ある目的のためにオブジェクトを関数のように見せることができます。次に、関数がオブジェクトの変数で呼び出されたときに収集する情報を蓄積することができます。あなたの場合、TotalCaloriesはオブジェクト内の変数である可能性があります。そのトリックは、オブジェクト内のメソッドに__call__という名前を使用することです。それは「呼び出し可能」になります。

class FoodSelection: 
    def __init__ (self): 
     self.TotalCalories = 0 
    def __call__ (self, choice): 
     if choice == 'potatoes': 
      print (choice, ''': eat as little as possible!''') 
      self.TotalCalories += 10000 
     elif choice == 'salad': 
      print (choice, ': good choice!') 
      self.TotalCalories += 0 
     else: 
      print (choice, ''': sorry, don't understand that''') 


foodSelection = FoodSelection() 

foodSelection('potatoes') 
print (foodSelection.TotalCalories) 

foodSelection('salad') 
print (foodSelection.TotalCalories) 

foodSelection('bacon') 
print (foodSelection.TotalCalories) 

foodSelection('potatoes') 
print (foodSelection.TotalCalories) 

ここでは出力です:

potatoes : eat as little as possible! 
10000 
salad : good choice! 
10000 
bacon : sorry, don't understand that 
10000 
potatoes : eat as little as possible! 
20000 
関連する問題