2011-11-17 165 views
1

我是一個新手編程,但我進入自然語言(你可以看到)。我正在編寫一個簡單的程序來幫助測試法語現在時動詞。但是,在這段代碼中,我一直收到錯誤消息,因爲correctAnswers顯然沒有被設置爲全局變量。有任何想法嗎!?蟒蛇錯誤 - unboundLocalError

import random 

level1=["(manger)","je mange", "tu manges", "il mange", "elle mange", "nous mangeons", "vous mangez", "ils mangent", "elles mangent"] 
level2=["(boire)", "je bois", "tu bois", "il boit", "elle boit", "nous buvons", "vous buvez", "ils boivent", "elles boivent"] 

correctAnswers=0 
blanks = '_' * 8 

def getVerb(): 
    verbIndex=random.randint(1,len(level1)-1) 
    print (level1[verbIndex].split()[0], blanks, level1[0]) 
    ans=input() 
    while ans==level1[verbIndex].split()[1]: 
     correctAnswers=correctAnswers+1 
     print ("Nice one!") 
     print (correctAnswers) 
     getVerb() 
    else: 
     print ("Bad luck!") 
     getVerb() 


getVerb() 

回答

1

correctAnswers=0超出範圍。他們應該在getVerb之內。你也不需要遞歸。

假設你要測試每一個級別和每一個問題一次:

import random 


level1=["(manger)","je mange", "tu manges", "il mange", "elle mange", "nous mangeons", "vous mangez", "ils mangent", "elles mangent"] 
level2=["(boire)", "je bois", "tu bois", "il boit", "elle boit", "nous buvons", "vous buvez", "ils boivent", "elles boivent"] 
blanks = '_' * 8 

def getVerb():  
    correctAnswers = 0   

    # Do each level once 
    for level in (level1, level2): 
     level_name, choices = level[0], level[1:] 

     # Shuffle the choices, this makes sure we only do each question once 
     random.shuffle(choices) 

     # Go through all the choices once 
     for choice in choices: 
      prefix, suffix = choice.split(' ', 2) 
      print (prefix, blanks, level_name) 

      ans = raw_input('Answer: ') # input() if Python 3 
      while True: 
       if ans == suffix: 
        correctAnswers += 1 
        print ("Nice one!") 
        print (correctAnswers) 

        # Got the right answer, break out 
        break 
       else: 
        print ("Bad luck!") 
        # Change prompt to "Try again" on failure 
        ans = raw_input('Try again: ') # input() if Python 3 


getVerb() 

如果通過預裂的部分或使用字典有你的1級/ level2的輸入的控制,您可以優化這個更多。

+0

此外,你可能想的raw_input'()'和'不輸入()''作爲輸入()'執行輸入Python和'的raw_input()'返回一個字符串。 – six8

+1

這取決於。如果OP使用Python2,那麼是的,如果Python3,那麼沒有。 – Blender

1

我已經清理了你的代碼,並使它更加噁心。現在就來試試:

import random 

def getVerb(): 
    level1 = ["(manger)","je mange", "tu manges", "il mange", "elle mange", "nous mangeons", "vous mangez", "ils mangent", "elles mangent"] 
    level2 = ["(boire)", "je bois", "tu bois", "il boit", "elle boit", "nous buvons", "vous buvez", "ils boivent", "elles boivent"] 

    blanks = '_' * 8 
    correctAnswers = 0 
    randomElement = random.choice(level1) 

    print(randomElement.split()[0], blanks, level1[0]) 

    ans = input() 

    while True: 
     if ans == randomElement.split()[1]: 
      correctAnswers += 1 

      print("Nice one!") 
      print(correctAnswers) 
     else: 
      print("Bad luck!") 

     ans = input() 

if __name__ == '__main__': 
    getVerb() 
+0

此代碼不起作用。 –

+0

你能否詳細說明一下?這對我來說可以。 – Blender

-1

一個更Python的方法是使用一個發電機來獲取當前級別的下一個問題:

import random 

levels = { 
    '(manger)' : ["je mange", "tu manges", "il mange", "elle mange", "nous mangeons", "vous mangez", "ils mangent", "elles mangent"], 
    '(boire)' : ["je bois", "tu bois", "il boit", "elle boit", "nous buvons", "vous buvez", "ils boivent", "elles boivent"] 
} 

def getVerb(words): 
    random.shuffle(words) 
    for verb in words: 
     yield verb.split() 

if __name__ == '__main__': 

    blanks = '_' * 8 
    correct = 0 
    missed = 0 

    for level, words in levels.items(): 
     for pronoun, verb in getVerb(words): 
      print pronoun, blanks, level 
      answer = raw_input('Answer: ') 

      if answer == verb: 
       correct += 1 
       print 'Nice!' 
      else: 
       missed += 1 
       print 'Missed =[' 

     print 'Level', level ,'Complete!', 'Correct:', correct, 'Missed:', missed 
     print 
+0

分號? :-) – wberry

+1

如果可以的話,你當然應該避免使用'global'。幾乎沒有理由使用它。 – six8

1

正如@Cixate已經提到的,這可以通過設置固定correctAnswers = 0內部getVerb和一個while循環更換遞歸:

def getVerb(): 
    correctAnswers = 0 
    ... the rest of your code, as before ... 
    ... making sure to replace the recursion with a while-loop ... 

問題是Python實際上在兩個不同的作用域中看到兩個不同的變量的相同的correctAnswer。這導致了所謂的「陰影」發生。

因此,Python只會在getVerb內使用correctAnswers時使用getVerb的版本。而這個變量從來沒有被賦予一個值!所以Python抱怨說你試圖在沒有分配它的情況下使用它。

但是......等等!我們沒有分配一個值嗎?那麼,我們分配給一個名爲correctAnswers的變量,但它是一個不同的變量,具有不同的範圍。

看看下面的例子:

x = 3 

print "outer 1:", x # prints 3 

def y1(): 
    print "in y1:", x # print 3 -- !! 

print "outer 2:", x # still prints 3 

def y2(): 
    x = 4 
    print "in y2:", x # prints 4 !!! 

print "outer 3:", x # prints 3 ???? 

def y3(): 
    print "in y3:", x # raises an exception! 
    x = 5 

print "outer 4:", x # prints 3 

y1() 

y2() 

print "outer 5:", x # still prints 3 !!! 

try: 
    y3() 
except: 
    print "y3 doesn't work!" 

所以,總結一下瘋狂:

  • y1看到x從外部範圍 - 第一行宣佈
  • y2創建自己的x - 並不能看到或者使用另一種
  • 也不要緊,y2分配一個新值自己的x,外x仍然是不變的 - 見outer 3outer 5
  • y3還創建了自己的x - 但試圖在它有價值之前使用它 - >崩潰並燃燒!

使這一變化將讓你的程序的工作。儘管這不是馬上需要,你最終可能會希望改善代碼質量,並學習如何編寫更地道的Python代碼。例如:

  • 用while循環替代遞歸
  • 用詞典
  • 使用raw_input代替input

但是這會隨着時間和經驗自然來,如果你跟不上好工作!

+0

範圍的好解釋。但是,移動'correctAnswers'還不夠。遞歸失去了'correctAnswers'的總和,因爲它每次都重置它。你可以通過'correctAnswers'作爲參數傳遞給GetVerb屬性()保持的總和,但我不認爲,僅僅抓住了OP想要什麼精神。 – six8

+0

@Cixate - 你說得對,我完全忘記了!謝謝! –

0

在你的函數的開始,你可以告訴Python的那correctAnswers是一個全局變量:

def getVerb(): 
    global correctAnswers 
    ... 

好運氣讓你的動詞!

+0

我只注意到這兩個+1和-1這裏 - 如果有人知道的東西我做錯了,我會很感激的學習! – user