python-3.x - 使用生成的变量,其值在一个函数中分配给另一个函数

标签 python-3.x loops variables scope global

新的Python业余爱好者,第一次发布问题,如果问题的结构不标准,请原谅

完整代码,如果您了解我想要实现的目标,请跳过介绍,并跳过前四个函数(如果您想在自己这边执行完整代码,请提供它们):

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

简介:

我正在制作一个心理数学游戏作为编码练习。它从字符串列表中随机选择模式:[“加法”、“减法”、“乘法”和“除法”],使用其名称来调用创建问题的相应函数(例如,如果它选择加法,它将调用一个名为 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)

the return keyword returns a string containing the variable name which is then incremented through exec function

ex: exec(mode_info[1] + " += 1") increments the c_add if mode is addition

我将应用程序分为 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 时,我得到了正确的数字(但我仍然想知道为什么原始状态不起作用)

到目前为止我尝试过的

抛出的全局关键字是尝试获取 results_page 来获取模式变量的失败尝试(但执行 Round 和正确变量的工作),并且我无法传递用于生成变量的 eval() 代码' 直接命名为 global ,我想过使用 return 方法,但不知道如何在这种情况下使用它(并且宁愿只是使生成的变量可访问)

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

更新及解决方案:

有(至少)2 个修复,答案是 Jason Nick Porter,并将这 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()

关于python-3.x - 使用生成的变量,其值在一个函数中分配给另一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51880940/

相关文章:

c - 查找数组中两个数字的目标和

java - 这不是用 Java 解释 Final 的一个坏例子吗?

javascript - 未捕获的类型错误 : Cannot set property of undefined - but console. 日志显示值

c# - 声明变量总是最佳实践吗?

python-3.x - 连接拒绝在 docker 上使用 Postgresql

python - asyncio.subprocess 总是阻塞

bash - powershell bash 循环随机卡住等待键盘输入

python - 在 Pytorch 中查找前 k 个匹配项

python-3.x - python : create new column and copy value from other row which is a swap of current row

Python 遍历嵌套列表,但只遍历偶数索引