2016-01-24 106 views
0

我們被要求編寫驗證GTIN-8代碼的程序。 的valdation如下:爲什麼我得到這個錯誤「IndexError:字符串索引超出範圍」

  1. 乘第一7位交替由3然後1

  2. 添加起來

  3. 減去該數量從10

  4. 的相等或更高的多
  5. 生成的數字是第八位數字

這裏是我的代碼:

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 

我不明白爲什麼我 會感謝任何幫助。

+1

你可以嘗試打印gtin,就在你出錯之前 – AlokThakur

+1

gtin = str(gtin)'是什麼意思?這在Python 2中會有一些意義 - 但是在那種情況下你應該使用'raw_input'。另一方面,如果這個*是* Python 2那麼'gtin.isdigit()'會拋出一個運行時錯誤,如果用戶事實上輸入了一些只包含數字的東西。 –

+0

請研究發佈指南,您必須提取一個最小的發佈示例,而不是您在此處引用的所有內容。這也是有原因的! –

回答

0

這是我的快速實施。可悲的是,我沒有任何測試數據來檢查它是正確的!

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)) 
+0

我希望他能從中學到一些很好的編碼風格。 –

1

我會建議做一個「is_valid_gtin」函數,它只檢查GTIN是否有效,沒有I/O。然後一個簡單的 「主()」 來檢查代碼:

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

該缺陷是在該行

if eightdigit == (gtin[7]): 

eightdigit是int但gtin[7]是一個字符串。因此,這種比較是始終爲 false - 因此您處於無限循環(只要您輸入至少包含8個字符的字符串)。你越來越沮喪,然後只是按下回車鍵 - 它將您的代碼傳遞給空字符串,缺少第八個字符會觸發索引超出範圍錯誤。

因此,你將需要:

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

來解決特定的漏洞,儘管這仍然會留下一個邏輯上的錯誤 - 因爲在您的代碼底部的循環不會驗證輸入和您正在嘗試使用之前的輸入計算checkdigit來檢查新的候選gtins。您應該遵循@JacquesSupik的出色想法並重構代碼,以便將驗證邏輯從I/O邏輯中分離出來。

相關問題