【问题标题】:Why am I getting this Error "IndexError: string index out of range"为什么我会收到此错误“IndexError:字符串索引超出范围”
【发布时间】:2016-01-24 11:09:14
【问题描述】:

我们被要求编写一个验证 GTIN-8 代码的程序。 验证如下:

  1. 前 7 位数字交替乘以 3,然后乘以 1

  2. 把它们加起来

  3. 从等于或大于 10 的倍数中减去该数字

  4. 得到的数字是第八位数字

这是我的代码:

def validgtin():  

    gtin = input("Enter the 8 digits of GTIN-8 product code: ")   
    valid = False
    while valid == False:
        if gtin.isdigit():               
            gtin = str(gtin)
            if len(gtin) == 8:          
                valid = True
            else:
                print("That is not correct, enter 8 digits, try again: ")       
                gtin = input("Enter the 8 digits of GTIN-8 product code: ")
        else:
            print("That is not correct, type in numbers, try again: ")
            gtin = input("Enter the 8 digits of GTIN-8 product code: ")     


    sumdigit =  3*(int(gtin[0])) + 1*(int(gtin[1])) + 3*(int(gtin[2])) + 1*(int(gtin[3])) + 3*(int(gtin[4])) + 1*(int(gtin[5])) + 3*(int(gtin[6]))  #sum of the digits

    gtin = str(gtin)  

    valid1 = False
    while not valid1:
        if sumdigit%10 == 0:    
            eightdigit = 0
        else:
            eightdigit = (((sumdigit + 10)//10)*10) - sumdigit  

        if eightdigit == (gtin[7]):
            valid1 = True
            print("Your GTIN-8 product code is valid.")

        else:
            print("Your GTIN-8 product code is not valid.")
            gtin = input("Enter the 8 digits of GTIN-8 product code: ")


    return

validgtin()

当我运行此代码并输入无效的 GTIN-8 代码时,它表示该代码无效并提示我输入新的 GTIN-8 代码

但是

在我输入新的有效 GTIN-8 代码后,它仍然显示它无效

之后发生这种情况:

Traceback (most recent call last):



File "C:\Users\Yash Dwivedi\Documents\Year 10\GCSE Computing\Assignment\Task 1 v2.py", line 29, in validgtin
    if eightdigit == (gtin[7]):
IndexError: string index out of range

我不明白为什么 如有任何帮助,我将不胜感激。

【问题讨论】:

  • 您可以尝试在出错之前打印 gtin
  • gtin = str(gtin) 的意义何在?这在 Python 2 中是有意义的——但在这种情况下,你应该使用raw_input。另一方面,如果这个 is Python 2 则 gtin.isdigit() 会在用户实际上输入了仅由数字组成的内容时引发运行时错误。
  • 请研究发布指南,您必须提取一个最小的发布示例,而不是您在此处引用的全部内容。这也是有原因的!

标签: python


【解决方案1】:

我建议创建一个“is_valid_gtin”函数,它只检查 GTIN 是否有效,无需 I/O。然后一个简单的“main()”来检查代码:

def is_valid_gtin(gtin):
    if len(gtin) != 8 or not gtin.isdigit():
        return False
    sum = 0
    for i in list(gtin)[0:6:2]:
        sum += 3*int(i)
    for i in list(gtin)[1:6:2]:
        sum += int(i)
    checksum = (10 - sum % 10) % 10
    return checksum == int(gtin[7])


def main():
    while (True):
        gtin = input("Enter the 8 digits of GTIN-8 product code: ")
        if is_valid_gtin(gtin):
            print("Your GTIN-8 product code is valid.")
            break
        else:
            print("That is not correct, try again.")

if __name__ == '__main__':
    main()

【讨论】:

    【解决方案2】:

    这是我的快速实现。遗憾的是我没有任何测试数据来检查它是否正确!

    def _round_up_ten(number):
        if number % 10 == 0:
            return number
        return 10 * (1 + (number / 10))
    
    
    def validate_gtin(gtin):
        if not gtin.isdigit() or len(gtin) != 8:
            raise ValueError("GTIN must be an 8-digit number")
    
        digits = [int(digit) for digit in gtin[:-1]]
        check_digit = int(gtin[-1])
    
        multiplied_digits = (
            digits[0] * 3
            + digits[1]
            + digits[2] * 3
            + digits[3]
            + digits[4] * 3
            + digits[5]
            + digits[6] * 3
        )
    
        expected_check_digit = _round_up_ten(multiplied_digits) - multiplied_digits
    
        if check_digit!= expected_check_digit:
            raise ValueError("Incorrect check digit ({}) (expected {})".format(check_digit, expected_check_digit))
    

    【讨论】:

      【解决方案3】:

      bug 就在这条线上

      if eightdigit == (gtin[7]):
      

      eightdigit 是一个 int 但 gtin[7] 是一个字符串。因此,这种比较 always 是错误的——因此您处于无限循环中(只要您输入的字符串至少包含 8 个字符)。您变得沮丧,然后只需按回车键 - 它将向您的代码传递空字符串,该字符串缺少第八个字符,会触发索引超出范围错误。

      因此你需要:

      if eightdigit == int(gtin[7]):
      

      修复那个特定的错误,尽管这仍然会给你留下一个逻辑错误——因为你的代码底部的循环没有验证输入,你正试图检查新的候选 gtins 与计算的校验位上一个输入。您可能应该遵循@JacquesSupik 的绝妙想法并重构代码,以便将验证逻辑与I/O 逻辑分开。

      【讨论】:

        猜你喜欢
        • 2014-03-10
        • 1970-01-01
        • 2020-10-11
        • 1970-01-01
        • 2012-02-01
        • 1970-01-01
        • 2011-11-30
        • 1970-01-01
        • 2023-03-30
        相关资源
        最近更新 更多