随机发生错误

时间:2015-01-30 19:16:07

标签: python

我目前正在对我的任务进行逻辑测试,所以我的代码仍然需要进行一些重构,并且不需要全局和导入,但是我得到一个随机出现的错误。

错误将随机发生,有时可能不会发生40次迭代,有时则会发生在第一次。这完全是随机的。

错误发生在我预先计算总和答案的行上并存储它。

  

answer = operator(times,toTimesBy)

我收到错误,说明在赋值之前引用了变量运算符,尽管此错误只会随机弹出。

  

UnboundLocalError:赋值前引用的局部变量'operator'

#import required additional libraries
import random
import operator
import sys


global times
global toTimesBy
global answer
global ops
global stringOperator
global questionCounter


#dictionary to hold operators which allow assignment to variables
ops = {"+": operator.add,
       "-": operator.sub,
       "*": operator.mul}

questionCounter = 1
print(questionCounter)

def generate(questionCounter):
    #set question counter
    questionCounter = questionCounter + 1
    #generate questions
    times = random.randint(1, 12)
    toTimesBy = random.randint(1, 12)
    #randomly select the operator
    operatorSelector = random.randint(1, 100)

    if operatorSelector in range(0, 32):
        operator = ops["+"]
        stringOperator = "+"
    elif operatorSelector in range (33, 65):
        operator = ops["-"]
        stringOperator = "-"
    elif operatorSelector in range(66, 100):
        operator = ops["*"]
        stringOperator = "*"

    #to work out answer
    answer = operator(times, toTimesBy)
    print(answer)
    #print which question the user is answering
    print('question ' + str(questionCounter) + ' is:')
    #print the question
    print(str(times) + stringOperator + str(toTimesBy))
    #collect input
    userInput = input('What is your answer? ')
    #check if right
    if userInput == str(answer):
        print('correct')
        generate(questionCounter)
        #check if wrong
    else:
        print('wrong')
        generate(questionCounter)


generate(questionCounter)

2 个答案:

答案 0 :(得分:1)

大多数Python函数的上限是非包含性的(但在random.randint中,上限是包含的)。 range(0, 32)是从0到31的可迭代,range(33, 65)是从33到64的可迭代,依此类推。当operatorSelector为32,65或100时,不会执行if的分支。

同样,像Python 2中的in range(1, 31)这样的检查可能必须执行最多30次operatorSelector与数字的比较。

您应该只使用运算符比较运算符:

if 0 <= operatorSelector <= 32:
    operator = ops["+"]
    stringOperator = "+"
elif 33 <= operatorSelector <= 65:
    operator = ops["-"]
    stringOperator = "-"
elif 66 <= operatorSelector <= 100:
    operator = ops["*"]
    stringOperator = "*"

答案 1 :(得分:0)

您的错误是if / elif函数未覆盖整个range可能的值。 range不是端点的inclusive

if operatorSelector in range(0, 32):

这不包括32

elif operatorSelector in range (33, 65):

这不包括65

elif operatorSelector in range(66, 100):

这不包括100

选择3265100时,不会执行查找要使用的运算符。


有几种方法可以解决这个问题:

  • 选项1是在if / elif之前设置默认值,并意识到您对此特定运营商略有偏见(在下面的情况下为“+”)

示例:

operator = ops["+"]
stringOperator = "+"
...
if operatorSelector in range(33, 65):
    operator = ops["-"]
    stringOperator = "-"
  • 选项2是扩展您的范围以包含缺少的数字:

示例:

if operatorSelector in range(0, 33):
    ...
elif operatorSelector in range (33, 66):
    ...
elif operatorSelector in range(66, 100):
    ...

同样,由于范围不包括终点,因此这里没有重叠。