Python: 无法停止此程序的哨兵循环

Python: Unable to stop this program's sentinel loop

所以我正在制作一个关于曲棍球运动员比赛的节目,我会记录他们的目标。

这是应该发生的事情:

Who scored? 4
Who scored? 5
Who scored? 6
Who scored? 4
Who scored? 3
Game still going?(y/n) y
Who scored? 3
Who scored? 2
Who scored? 5
Who scored? 2
Who scored? 3
Game still going?(y/n) n

Creating a histogram from values: 
Element Goals Histogram
      1     0 
      2     2 **
      3     2 ***
      4     2 **
      5     2 **
      6     1 *
      7     1 *
      8     0 
      9     0 
     10     0 

这是我的代码:

def info():
    ranking = [0,0,0,0,0,0,0,0,0,0,0]
    survey = []
    return ranking,survey
def info2(survey):   
    x = ''
    for i in range(0,5):
        x = int(input("Who scored?"))           
        survey.append(x)
    again(x)
    return survey
def info3(ranking,survey):
    for i in range(len(survey)):
        ranking[survey[i]]+=1
    return ranking, survey

def again(x):
    y = input("Game still on? y/n").lower()
    if y == "yes" or y == "y":
        info()
    elif y == "n" or y =="no":
        hg(x)


#create histogram
def hg():
    print("\nCreating a histogram from values: ")
    print("%3s %5s %7s"%("Element", "Goals", "Histogram"))

#start from element 1 instead of 0
    for i in range(len(ranking)-1):
        print("%7d %5d %-s"%(i+1, ranking[i+1], "*" * ranking[i+1]))

def main():
    x,y = info()
    a = info2(y)
    d = again(x)
    b,c = info3(x,a)
    z = hg(x)
main()

当我按原样 运行 时,我得到了谁得分的东西,我在 y/n 上输入 'y' 并且它有效,但是当我输入 y/n 并且我输入 n,它打印 "element goals histogram" 然后抛出以下内容:

Traceback (most recent call last):
 line 48, in <module>
    main()
 line 44, in main
    a = info2(y)
 line 17, in info2
    again(x)
 line 29, in again
    hg(x)
 line 39, in hg
    for i in range(len(ranking)-1):
NameError: name 'ranking' is not defined

我发现代码存在一些问题...

首先,您的 again() 函数中有 lower 而不是 lower()。这将函数本身绑定到 x 而不是调用它并分配它的 return 值。

此外,您的 hg() 函数需要一个参数,但您没有在此处传递参数。 info() 中定义的 ranking 是该函数的局部变量,在 hg().

中不可见

根据我上面的评论更新 OP 的代码后编辑以响应 OP:

此外,您对 again() 中退出案例的处理存在问题。我认为你根本不应该在那里调用 hg(),而是 return info2().

中一个单独变量的答案

所以这两个函数的代码看起来像这样:

def info2(survey):
    x = ''
    ans = 'y'

    while ans in ('y', 'yes'):
        for i in range(0,5):
            x = int(input("Who scored?"))
            survey.append(x)
        ans = again()
    return survey

def again():
    x = input("Game still on? y/n").lower()
    if x == "yes" or x == "y":
        info()

    return x

注意附加变量的使用,以及 pass.

编辑以回应来自 OP 的第二条评论:

info3()不变。我在更改中添加了 again()info2()。你会保持 info3() 不变(至少在这个特定问题上)。

此外,由于我的更改在 No 情况下只有 pass,因此实际上可以将其完全删除。只需检查 Yes 情况,否则 return(在这种特殊情况下甚至不需要 else)。

当我 运行 代码进行了我提到的更改时,它似乎按要求工作。这是示例输出:

Who scored?1
Who scored?1
Who scored?1
Who scored?2
Who scored?2
Game still on? y/ny
Who scored?3
Who scored?3
Who scored?3
Who scored?2
Who scored?2
Game still on? y/nn

Creating a histogram from values: 
Element Goals Histogram
      1     3 ***
      2     4 ****
      3     3 ***
      4     0 
      5     0 
      6     0 
      7     0 
      8     0 
      9     0 
     10     0 
x = input("Game still on? y/n").lower

应该是:

x = input("Game still on? y/n").lower()

我不确定所有函数和变量应该做什么。如果您为函数和变量使用合理的名称,则调试和理解代码会更容易。

from collections import OrderedDict

def main():
    list_of_players = [str(number) for number in range(1, 11)]
    ranking = play(list_of_players)
    print_histogram(ranking)

def play(list_of_players):
    ranking = OrderedDict([(player, 0) for player in list_of_players])
    while True:
        for i in range(5):
            player = input('Who scored? ')
            try:
                ranking[player] += 1
            except KeyError:
                print('Not a player')
        if input('Game still going?(y/n) ').lower() in ['n', 'no']:
            return ranking

def print_histogram(ranking):
    template = '{player:^7} {goals:^7} {stars}'
    print('\nCreating a histogram from values: ')
    print(template.format(player='Element', goals='Goals', stars='Histogram'))
    for player, goals in ranking.items():
        print(template.format(player=player, goals=goals, stars='*' * goals))

if __name__ == '__main__':
    main()