2014-06-22 102 views
1

我試圖從12位ISBN中返回ISBN-13校驗位,但遇到了一個奇怪的錯誤。ISBN 12到13位數字

採取以下作爲我的12位數字ISBN - 978311020318

每個數字替代地乘以1或3

9 * 1 + 7 * 3 + 8 * 1 + 3 * 3 + 1 * 1 + 1 * 3 + 0 * 1 + 2 * 3 + 0 * 1 + 3 * 3 + 1 * 1 + 8×3 = 91

91%10 = 1

10 - 1 = 9 ,這是我們的ISBN-13校驗碼。

這是我迄今爲止...

def isbn_check_digit(isbn): 
    s = 0 
    for i, d in enumerate(isbn): 
     if i % 2 == 0: 
      s += int(d*1) 
     else: 
      s += int(d*3) 
      print(s) 
    return (10 - (s % 10)) 

print(isbn_check_digit("978311020318")) 

,它輸出以下...

786 
1127 
1239 
1461 
1794 
2683 
7 

我打破它,看看發生了什麼事

if i % 2 == 0: 
     s += int(d*1) 
     print(s) 
    else: 
     s += 0 

9 
17 
18 
18 
18 
19 
1 

1的倍數工作正常,但爲什麼3的倍數表現奇怪?

回答

2

因爲在評估表達式int(d * 3)時,d不是一個數字 - 它是由一個字符組成的字符串,它是一個數字。結果,「乘以」3將重複該數字三次:例如,3將變成333,而不是9

您想在乘3 字符串轉換爲整數後:

int(d) * 3 
+0

非常感謝,這讓我感覺很好。我被int(d * 1)工作的事實拋棄了。 – Ergo

0

@dustwuff給你的原因,但另一個解決將是使用map,然後你的字符串轉換爲清單:

from itertools import izip_longest 

def grouper(n, iterable, fillvalue=None): 
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return izip_longest(fillvalue=fillvalue, *args) 

def isbn_check_digit(isbn): 
    number = list(map(int, isbn)) 
    check_sum = 0 
    for i, d in grouper(2, number): 
     check_sum += i*1 + d*3 
    return 10 - check_sum % 10 

map將應用功能,可迭代的每個成員。在這種情況下,應用int會將您的字符串轉換爲數字列表。