Python中GTIN程序中的'NameError'是什么意思?

Python中GTIN程序中的'NameError'是什么意思?,python,Python,请注意我是初学者。 下面的程序是关于计算GTIN数的。基本上,不起作用的部分是验证部分。程序应该验证代码,同时向用户解释代码;然而,由于某些原因,计算机似乎无法识别我使用的变量。只有当您确实刚刚计算了GTIN数,并且菜单在询问是否要重新运行程序时重新出现时,验证选项才可用。我希望你能理解我的问题!非常感谢!下面是我的代码: print("Welcome. Do you want to start? (Y/N)") answer = input() while(answer == "Y"):

请注意我是初学者。 下面的程序是关于计算GTIN数的。基本上,不起作用的部分是验证部分。程序应该验证代码,同时向用户解释代码;然而,由于某些原因,计算机似乎无法识别我使用的变量。只有当您确实刚刚计算了GTIN数,并且菜单在询问是否要重新运行程序时重新出现时,验证选项才可用。我希望你能理解我的问题!非常感谢!下面是我的代码:

print("Welcome. Do you want to start? (Y/N)")
answer = input()

while(answer == "Y"):
    print("1. Calculate a GTIN number")
    print("2. Validate Previous Code (Please note that this option is only valid if you have just calculated a GTIN number)")
    print("3. End Program")
    option = int(input())

    def GTIN():
        #Step 1
        print("Enter the first digit of your GTIN code")
        digit_1 = int(input())

        print("Enter the second digit")
        digit_2 = int(input())

        print("Enter the third digit")
        digit_3 = int(input())

        print("Enter the fourth digit")
        digit_4 = int(input())

        print("Enter the fifth digit")
        digit_5 = int(input())

        print("Enter the sixth digit")
        digit_6 = int(input())

        print("Enter the seventh digit")
        digit_7 = int(input())

        #Step 2
        total_1 = digit_1 * 3
        total_2 = digit_2 * 1
        total_3 = digit_3 * 3
        total_4 = digit_4 * 1
        total_5 = digit_5 * 3
        total_6 = digit_6 * 1
        total_7 = digit_7 * 3

        #Step 3
        final_total = total_1 + total_2 + total_3 + total_4 + total_5 + total_6 + total_7


        #Step 4
        import math
        def roundup(final_total):
            return int(math.ceil(final_total / 10.0) * 10)

        final_total_2 = roundup(final_total)


        GTIN_number_8 = final_total_2 - final_total

        print("Your complete GTIN number is:", digit_1, digit_2, digit_3, digit_4, digit_5, digit_6, digit_7, GTIN_number_8)
        return digit_1, digit_2, digit_3, digit_4, digit_5, digit_6, digit_7, GTIN_number_8

    def validation(digits, totals):
        print("Your previous GTIN code:", digits[0], digits[1], digits[2])
        print("Firstly, the computer will collect all of the digits, then it will multiply them by either 3 or 1:")
        print("The 1st digit: ", digit_1, "will be multiplied by 3")
        print("The 2nd digit: ", digit_2, "will be mutliplied by 1")
        print("The 3rd digit: ", digit_3, "will be multiplied by 3")
        print("The 4th digit: ", digit_4, "will be mutliplied by 1")
        print("The 5th digit: ", digit_5, "will be multiplied by 3")
        print("The 6th digit: ", digit_6, "will be mutliplied by 1")
        print("The 7th digit: ", digit_7, "will be multiplied by 3")

        print("Secondly, the computer will add up all of the digits:")
        print("1st digit + 2nd digit + 3rd digit + 4th digit + 5th digit + 6th digit + 7th digit")
        print(total_1, "+", total_2, "+", total_3, "+", total_4, "+", total_5, "+", total_6, "+", total_7)
        print("Total =", final_total)

        print("Thirdly, the total will be rounded to the highest multiple of 10")
        print("The total rounded =", final_total_2)

        print("Lastly, the total will then be subtracted from the rounded number to give the GTIN number 8")
        print("Final GTIN number including the final digit:", digit_1, digit_2, digit_3, digit_4, digit_5, digit_6, digit_7, GTIN_number_8)

    def end():
        print("Ending Program")

    if(option == 1):
        GTIN(digits, totals)
    elif(option == 2):
        validation(digits)
    elif(option == 3):
        end()
    else:
        print("Ending Program")

    print("Do you want to re-run the program? (Y/N)")
    answer = input()


print("Ending Program")
“名称错误”消息为:

Traceback (most recent call last):
  File "G:\Year 10 - Computer Science\GCSE Coursework\Part One\Code Versions\GTIN Code V4.py", line 85, in <module>
    GTIN(digits, totals)
NameError: name 'digits' is not defined
发件人:

作用域定义名称在块中的可见性。如果在块中定义了局部变量,则其范围包括该块

在代码中,数字_1的值在GTIN函数的范围内分配。这意味着它在该范围之外不可见-它是该函数的局部变量。因此,当您尝试从另一个函数validation访问它时,名称digit_1无法识别

设计该类的最佳方法可能是使GTIN self和validation self方法属于同一个类,并创建该类的实例并使用它。然后,如果希望在类实例的方法之间共享变量,则可以将它们指定为self的属性,即使用self.digit_1,而当前只有digit_1

在函数之间共享变量的一个更快更脏的解决方案是

global digit_1    #  , and all the other variables
在GTIN和任何其他想要更改其值的函数开始时。这意味着GTIN中发生的分配将在全局范围内生效,即在整个文件的级别上生效,因此validate将能够访问它们


在当前的形式下,您的特定程序也可以工作,并且如果您在同一范围内执行所有操作,那么您无需考虑就可以在代码块之间共享变量。这意味着完全摆脱def语句,如果选项==1,则将GTIN的代码块移到下面,如果选项==2,则将验证的代码块移到下面。

您应该更改验证函数的签名

慢慢地逐步完成该功能:

def gtin_validate(gtin):
    # @param {str} gtin
    # @returns {bool}
新函数签名接受整个GTIN的字符串,例如01234567,如果GTIN有效,则返回True,如果无效,则返回False。我在这里使用Javadoc注释只是因为更广泛的程序员更熟悉它,但当前的样式应该是:def gtin_validategtin:str->bool:

这将获取从最后一个字符切掉的所有偶数顺序数和所有奇数顺序数,并将它们存储在相应的变量中。在s[i:j:k]一节中阅读更多内容

这只是对数字的总结。应该是自我描述的。事实上,sum[itertools.chainevens中的intn for n,赔率]是我为一个不只是刚开始的人写这篇文章的方式

checkdigit = 10 - (total % 10)
这将取代你的幻想四舍五入到十的最接近倍数,并减去原来的总公式。total%10是模函数,它给出除法的余数,而不是商10/4==2.5,但10%4==2。这是一个很好的方法来限制一个数,模10是特别的,因为它基本上给你一个正数的位置。因为我们有一个位置,我们可以从10中减去它得到我们的校验位

return checkdigit == int(gtin[-1])
现在我们只返回该校验位是否与GTIN的最后一位匹配。万岁

您需要传递数字_1,因为函数只能看到其中定义的变量。这意味着您需要从GTIN返回数字_1。您需要对函数中定义的所有变量执行此操作

因为您有许多这样的变量,所以将它们全部存储在名为digits、total和final_total的列表中会更简单,其中Digital[0]将是您当前定义为Digital_1的整数,Digital_7将是gtin_number_8中当前定义的整数。您应该为总计和最终总计创建另一个列表。为了在不改变整个代码的情况下实现这一点,我建议如下

def GTIN:的最后一行应为:

digits = [digit_1, digit_2, digit_3, digit_4, digit_5, digit_6, digit_7, GTIN_number_8]
#create a totals list in similar way
#create a final_totals list in similar way
return digits, totals, final_totals
然后,当您调用GTIN时,请确保存储返回的变量。定义验证时,请确保可以传递数字、总计和最终总计

我包括了函数应该如何为前3位数字的列表编制索引,但对于所有值,这都是类似的。记住gtin_编号_8以数字[7]存储

我强烈建议将导入数学移到代码的第一行。模块只导入一次并在整个会话中保留,因此不需要每次函数运行时都导入模块


编辑:我以前忘记传递总计、最终总计。

请包含您收到的错误消息。寻求调试帮助的问题为什么没有此代码
工作必须包括所需的行为、特定的问题或错误以及在问题本身中重现这些问题所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:函数验证中未定义数字_1。将这些值从GTIN返回给调用者,并将其用作验证参数。不要依赖全局变量!所以使用参数传递@Matthia实际上,是否有必要将数字逐个作为输入?而不是作为一个整体?这确实影响了可读性,使事情变得复杂。你有列表和循环的想法吗?没有更简单的方法吗?根据我的导师,验证它应该比实际设计程序容易得多。我想我可能太复杂了。你熟悉列表吗?您应该将所有数字放在一个列表中,这样数字[0]=数字_1@user1435522那只是一根绳子函数通过接受参数与外部世界进行通信。如果希望通用函数validate处理其自身范围之外的值,请对其进行设置,使其接受括号之间的输入参数并使用这些参数。然后,当你调用validate时,输入你想要检查的数字;因此,我不想因为它而破坏我的整个计划。我希望你能理解@user1435522我会使用这种方法,但我对它没有信心;因此,我无法解释它,更不用说将其转换为伪代码和流程图了。对不起,如果我听起来很愚蠢@勒比一点也不。我写了一个长得多的答案,在我发帖之前,我接到了4个电话,办公室的门被敲了一下。如果你还有什么不明白的,请告诉我。我现在更了解你的方法了-谢谢-但是,这个解决方案不会一步一步地为用户验证代码。所有内容都必须在定义验证中打印给用户。这是我的课程,但无论如何,我感谢您的帮助。谢天谢地,我长大后不想再深入编程了,因为我觉得它太复杂了。不幸的是,我们不得不使用打印语句,因为我们必须向用户解释标准中的说明。再次感谢!没错,但我就是不喜欢!不过,谢谢你给我一个实际项目的见解!谢谢我添加了您的修改,但仍然无法工作。这是我现在收到的语法错误:回溯上一次最新调用:文件G:\Year 10-Computer Science\GCSE Coursew\Part One\Code Versions\GTIN Code V4.py,第89行,在validationdigits类型错误:验证接受0个位置参数,但给出了1>>您是否执行了def validationdigits,totals?另外,请看我的编辑,您需要传递所有在验证中使用但未在验证中定义的变量。我刚刚添加了您编辑的版本,但由于未定义名称“digits”,程序中没有任何内容。我怀疑有拼写错误,但我无法确定是否需要查看。我建议用新代码更新你的帖子,并用一个3位数的最小示例,这样每个人都可以看到你遇到的问题。我已经给出了你建议修改的代码。
checkdigit = 10 - (total % 10)
return checkdigit == int(gtin[-1])
digits = [digit_1, digit_2, digit_3, digit_4, digit_5, digit_6, digit_7, GTIN_number_8]
#create a totals list in similar way
#create a final_totals list in similar way
return digits, totals, final_totals
if(option == 1):
    digits, totals, final_totals = GTIN()
elif(option == 2):
    validation(digits, totals, final_totals)
def validation(digits, totals, final_totals):
    print("Your previous GTIN code:", digits[0], digits[1], digits[2])