我用Python编写的GTIN程序中的“NameError”是什么意思?

2024-04-19 09:16:36 发布

您现在位置:Python中文网/ 问答频道 /正文

请注意我是初学者。 下面的程序是关于计算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")

“名称错误”消息是:

^{pr2}$

Tags: thenumberinputbybewillfinalint
3条回答

您应该更改validation函数的签名

def gtin_validate(gtin):
    # @param {str} gtin
    # @returns {bool}
    evens, odds = gtin[0:-1:2], gtin[1:-1:2]
    total = 0
    for even in evens:
        total += int(even) * 3
    for odd in odds:
        total += int(odd) * 1
    checkdigit = 10 - (total % 10)
    return checkdigit == int(gtin[-1])

慢慢地逐步执行函数:

^{pr2}$

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

evens, odds = gtin[0:-1:2], gtin[1:-2:2]

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

total = 0
for even in evens:
    total += int(even) * 3
for odd in odds:
    total += int(odd) * 1

这只是对数字的总结。应该是自我描述的。事实上,sum([int(n) for n in itertools.chain(evens, odds)])是我为一个刚起步的人写这篇文章的方式!在

checkdigit = 10 - (total % 10)

这取代了你想象中的“四舍五入到十的最接近的倍数,然后减去原来的总和”的公式。total % 10是模函数,它给出除法的余数而不是商(10 / 4 == 2.5,而是10 % 4 == 2)。这是一个很好的方法来绑定一个数,而模10是特殊的,因为它本质上给了你一个正数的“个”位。既然我们有了“1”的位置,我们可以从10中减去它来得到校验位。在

return checkdigit == int(gtin[-1])

现在我们只返回checkdigit是否与GTIN的最后一位匹配。万岁!在

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

因为您有许多这样的变量,所以将它们全部存储在一个名为digitstotal、和{}的列表中,其中digit[0]将是当前定义为数字1的整数,digit_7将是当前在{}中定义的整数。您应该为totals,和final_total创建另一个列表。为了在不改变整个代码的情况下实现这一点,我建议如下。在

您的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

{13>确保调用^时返回变量。定义验证时,请确保可以通过digitstotals和{}。在

^{pr2}$

我包括了你的函数应该如何索引列表的前3位数,但这将是相似的所有值。记住gtin_number_8存储在digits[7]

def validation(digits, totals, final_totals):
    print("Your previous GTIN code:", digits[0], digits[1], digits[2])

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

编辑:我之前忘了传递总数,最后一个总数。在

来自https://docs.python.org/2/reference/executionmodel.html

A scope defines the visibility of a name within a block. If a local variable is defined in a block, its scope includes that block.

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

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

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

global digit_1    #  , and all the other variables

GTIN()(以及任何其他要更改其值的函数)的开头。这意味着GTIN()中发生的赋值将在全局范围(即在整个文件的级别)生效,因此{}将能够访问它们。在

在当前形式下,如果您在同一范围内执行所有操作,则您的特定程序也可以工作(并且可以在代码块之间共享变量,而无需考虑)。这意味着完全删除def语句,并将GTIN的代码块移到if option == 1下面,validate的代码块移到{}之下。在

相关问题 更多 >