在另一函数中使用在一个函数中分配了值的生成变量

时间:2018-08-16 15:48:53

标签: python-3.x loops variables scope global

新的python业余爱好者,并且第一次发布问题,如果问题的结构不规范,请原谅

完整代码,如果您了解我要实现的目标,请跳过介绍,并无论如何都要跳过前四个功能(如果您要执行完整的代码,请提供它们):< / p>

import os, random
modes = ['Addition', 'Subtraction', 'Multiplication', 'Division']

global very_beginning, c_add, c_sub, c_mul, c_div, add_rounds, sub_rounds, mul_rounds, div_rounds, Round, correct, total_time

def mode_addition():
    num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
    print(num1, " + ", num2)
    return num1 + num2


def mode_subtraction():
    num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
    while num1 <= num2:
        num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
    print(num1, " - ", num2)
    return num1 - num2


def mode_multiplication():
    num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
    print(num1, " X ", num2)
    return num1 * num2


def mode_division():
    num2, num3 = random.randrange(1, 10), random.randrange(1, 10)
    num1 = num2 * num3
    print(num1, " ÷ ", num2)
    return num3


def mode_var_names(mode):
    return "mode_" + mode.lower() + "()", "c_" + mode.lower()[0:3], mode.lower()[0:3] + "_rounds"

def mental_math():
    print("Mental math game: ")
    global Round, correct, total_time, c_add, c_sub, c_mul, c_div, add_rounds, sub_rounds, mul_rounds, div_rounds
    Round, total_time = 1, 0
    correct, c_add, c_sub, c_mul, c_div, add_rounds, sub_rounds, mul_rounds, div_rounds = int(), int(), int(), int(), int(), int(), int(), int(), int()
    while Round <= 20:
        print('Round ' + str(Round), end=":\n\n")
        roundmode = random.choice(modes)
        mode_info = mode_var_names(roundmode)
        print("This round will be about:", roundmode)
        correct_answer = eval(mode_info[0])
        exec(mode_info[2] + " += 1")
        print("The answer is: ", end='')
        roundanswer = int(input())
        if roundanswer == correct_answer:
            print("The answer {} is correct.".format(roundanswer))
            correct += 1
            exec(mode_info[1] + " += 1")
        else:
            print("The answer {} is incorrect. The answer should be: {}".format(roundanswer, correct_answer))
        print("You got {} out of {} questions correct".format(correct, Round))
        user = input("Press enter to continue, or type 'stop' to end this quiz\n")
        if user == 'stop' or Round == 20:
            result_page()
            break
        Round += 1

def result_page():
    mark = round(correct / Round * 100)
    os.system('cls')
    print("Mental math game")
    print('FIN\n\n')
    print("You solved {} questions".format(Round))
    print("You got {}% of the questions correct.".format(mark))
    print("If you want detailed results type 'details'")
    print("If you want to continue, type 'again', else just close this windows or press Enter")
    user = input()
    if user == "details":
    for i in modes:
        print("In", i, "You got ", eval(mode_var_names(i)[1]), "correct answers out of ",
              eval(mode_var_names(i)[2]))

mental_math()

简介

我正在整理一个心理数学游戏作为编码练习。它从字符串列表中随机选择模式:['Addition','Subtraction','Multiplication'和'Division'],使用其名称来调用创建问题的相应函数(例如,如果选择了Addition,则会调用一个称为mode_addition的函数),并使用预先确定的模板在现场生成的变量中跟踪每种模式的总数中每种模式的正确答案的数量(例如,如果选择加法,则会创建2个称为c_add的变量(存储正确答案)和add_rounds(存储涉及加法的总回合/问题),如下所示:

modes = ['Addition', 'Subtraction', 'Multiplication', 'Division']
def mode_var_names(mode):
    return "mode_" + mode.lower() + "()", "c_" + mode.lower()[0:3], mode.lower()[0:3] + "_rounds" 
roundmode = random.choice(modes)
mode_info = mode_var_names(roundmode)
  

return关键字返回一个包含变量名的字符串,其中   然后通过exec函数

递增      

ex:如果mode为,则exec(mode_info [1] +“ + = 1”)递增c_add   加

我将应用程序分为2个主要功能,主要功能称为mental_math(包含上面的代码并生成变量),另一个功能称为results_page(一旦我在解释器中输入“ stop”或20个问题),以显示我正确掌握每种模式的百分比以及多少个问题。

出现问题

我试图通过以下代码获取在mental_math生成的变量,以将它们的值打印在results_page上:

for i in modes:
    print("In", i, "You got ", eval(mode_var_names(i)[1]), "correct answers out of ",
        eval(mode_var_names(i)[2]))

正确的和所有回合的总和都返回0:

In Addition You got  0 correct answers out of  0
In Subtraction You got  0 correct answers out of  0
In Multiplication You got  0 correct answers out of  0
In Division You got  0 correct answers out of  0

,而百分比“ mark = round(正确/ Round * 100)”是正确的。当我将打印循环复制回mental_math时,我得到了正确的数字(但我仍然想知道为什么原始状态不起作用)

到目前为止我尝试过的事情

抛出的全局关键字是一次失败的尝试,试图获得result_page以获取模式的变量(但要进行Round和Correct变量的工作),而且我无法传递用于生成变量的eval()代码'直接命名为global,我想到了使用return方法,但不知道如何在这种情况下使用它(宁愿只是使生成的变量可访问)

我还尝试将它们分组为一个类,希望所有变量都可以被其他函数或实例访问,但失败了,因为我刚刚开始学习OOP

更新和解决方案

(至少)有2个修复程序,答案是Jason Nick Porter,并将2个函数添加到同一类中

1 个答案:

答案 0 :(得分:2)

注意:我最终做了很多编辑,所以随着您的使用,它变得越来越正确:)

我将首先放弃全局球。全局变量是一个善变的情妇,我不惜一切代价避免这样做。这将是在mental_math() fcn中使用数组的好地方。在当前具有的功能内:

global Round, correct, total_time, c_add, c_sub, c_mul, c_div, add_rounds, sub_rounds, mul_rounds, div_rounds
Round, total_time = 1, 0
correct, c_add, c_sub, c_mul, c_div, add_rounds, sub_rounds, mul_rounds, div_rounds = int(), int(), int(), int(), int(), int(), int(), int(), int()

我只想输入:

level, total_time = [1,0] # I put level instead of Round, since round is a keyword and could be confusing
correct = [0,0,0,0] # the index here corresponds to the mode
asked = [0,0,0,0]   # numpy.zeros would be an even more robust way to do this

使每个变量都存在于函数中,然后在mental_math()的末尾具有以下内容:

if user == 'stop' or level == 20:
    stats = [level, correct, total_time ] # and all the rest...
    result_page(stats)
    break

然后将您拥有的所有统计信息传递到results_page()。现在,您需要将模式设置为元组,而不是程序顶部的字符串。元组基本上是最好的,因为您可以将不同类型的变量链接在一起,如下所示:

modes = [('Addition'       , 3 , 7), # These numbers correspond to where the correct
         ('Subtraction'    , 4 , 8), # and total numbers will be located in the stats
         ('Multiplication' , 5 , 9), # array.
         ('Division'       , 6 , 10)] # The spacing just makes it easier to see

现在,您必须调整results_page()才能接收阵列。然后,您可以代替每个变量名称的索引来访问所有值。像这样:

def result_page(stats):
    mark = round(correct / stats[0] * 100)
    os.system('cls')
    print("Mental math game")
    print('FIN\n\n')
    print("You solved {} questions".format(stats[0]))
    print("You got {}% of the questions correct.".format(mark))
    print("If you want detailed results type 'details'")
    user = input("If you want to continue, type 'again', else just close this window or press Enter")
    # Fun-fact: If you pass a string to input() it prints it as a prompt
    if user == "details":
    for i in modes:
        print("In", i[0], " you got ", stats[i[1]], " correct answers out of ",
              stats[i[2]])

那么您甚至不需要mode_var_names()

编辑:

好吧,我没有意识到我的代码中的某些问题,因此上述内容并不是很好。如果有帮助,我会留在那里。

下面的代码已更新,应该可以让您添加任意数量的模式。问题是我没有仔细查看mental_math(),所以我没有意识到它仍在调用mode_var_names()。现在,它不再使用可变字符串执行函数,而是将一个int传递给单个函数,并使用相同的int来确定要在“正确”和“要求”数组中更新的数字。

import os
import random
import numpy as np

modes = [('Addition'       , 3 , 7), # These numbers correspond to where the correct
         ('Subtraction'    , 4 , 8), # and total numbers will be located in the stats
         ('Multiplication' , 5 , 9), # array.
         ('Division'       , 6 , 10)] # The spacing just makes it easier to see


def process(mode):
    # if you have more modes you want to add, just add more elif statements
    if mode == 0:
        num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
        print(num1, " + ", num2)
        return num1 + num2

    elif mode == 1:
        num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
        while num1 <= num2:
            num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
        print(num1, " - ", num2)
        return num1 - num2

    elif mode == 2:
        num1, num2 = random.randrange(1, 10), random.randrange(1, 10)
        print(num1, " X ", num2)
        return num1 * num2

    elif mode == 3:
        num2, num3 = random.randrange(1, 10), random.randrange(1, 10)
        num1 = num2 * num3
        print(num1, " ÷ ", num2)
        return num3

def mental_math():
    print("Mental math game: ")
    level, total_time = 0,0 # I put level instead of level, since level is a keyword and could be confusing

    correct = np.zeros(len(modes)) # the index here corresponds to the mode
    asked = np.zeros(len(modes))

    while level <= 20:
        level += 1
        print('Round ' + str(level), end=":\n\n")
        m = random.choice(range(len(modes)))
        print("This level will be about:", modes[m][0])

        correct_answer = process(m)
        asked[m] += 1

        levelanswer = int(input("The answer is: "))

        if levelanswer == correct_answer:
            print("The answer {} is correct.".format(levelanswer))
            correct[m] += 1
        else:
            print("The answer {} is incorrect. The answer should be: {}".format(levelanswer, correct_answer))

        print("You got {} out of {} questions correct".format(sum(correct), level))
        user = input("Press enter to continue, or type 'stop' to end this quiz\n")
        if user == 'stop' or level == 20:
            stats = np.hstack((level,sum(correct),total_time,correct,asked))
            result_page(stats)
            break


def result_page(stats):
    mark = round(stats[1] / stats[0] * 100)
    os.system('cls')
    print("Mental math game")
    print('FIN\n\n')
    print("You solved {} questions".format(stats[0]))
    print("You got {}% of the questions correct.".format(mark))
    print("If you want detailed results type 'details'")
    user = input("If you want to continue, type 'again', else just close this window or press Enter\n")
    if user == "details":
        for i in modes:
            print("In", i[0], " you got ", stats[i[1]], " correct answers out of ",
                  stats[i[2]])

mental_math()