ошибка питона - unboundLocalError - PullRequest
1 голос
/ 17 ноября 2011

Я новичок в программировании, но я на естественных языках (как вы можете видеть).Я пытаюсь написать простую программу, которая поможет протестировать глаголы настоящего времени на французском языке.Тем не менее, в этом коде я продолжаю получать сообщение об ошибке, потому что correctAnswers, очевидно, не был задан в качестве глобальной переменной.Есть идеи!?

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()

Ответы [ 5 ]

1 голос
/ 18 ноября 2011

Как уже упоминалось @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 3 и outer 5
  • y3 также создает свой собственный x - но пытается использовать его, прежде чем он приобретет значение -> сбой и запись !!

После внесения этого изменения ваша программа заработает. Хотя в этом нет необходимости, вы, возможно, захотите улучшить качество своего кода и научиться писать более идиоматический код на Python. Например:

  • заменить рекурсию циклом while
  • использовать словари
  • используйте raw_input вместо input

Но это произойдет со временем и опытом, если вы продолжите в том же духе!

1 голос
/ 17 ноября 2011

Я очистил ваш код и сделал его немного более Pythonic.Попробуйте сейчас:

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()
1 голос
/ 17 ноября 2011

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()

Вы могли бы оптимизировать это больше, если бы у вас был контроль над входом level1 / level2, предварительно разделив части или используя dict.

0 голосов
/ 18 ноября 2011

В начале вашей функции вы можете сказать Python, что correctAnswers является глобальной переменной:

def getVerb():
    global correctAnswers
    ...

Удачи в получении глаголов!

0 голосов
/ 17 ноября 2011

Более питонический подход - использовать генератор, чтобы получить следующий вопрос для текущего уровня:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...