2

I tried to create a python-based ISBN13 Validity Calculator, which is supposed to work according to the following snip of code. It takes in an argument of type string and prints the result.

I don't understand where I got wrong here, In this program, common sense tells me num will give a 3 or a 1 alternatively.

def isbncheck(isbn):
    num = int(0)
    for i in range(0,12):
        if num % 2 is 1:
            num = num + (int(isbn[i])*3)
            print(isbn[i] + " * 3 + at i=" + str(i))
        elif num % 2 is 0:
            num = num + (int(isbn[i]))
            print(isbn[i] + " * 1 + at i=" + str(i))
        else:
            print("Unhandled Exception.")

    print("_"*7)
    print(num)
    num = num%10
    print(num)
    print(isbn[12])
    print(int(isbn[12]))
    if num != int(isbn[12]):
        print("This is not valid")
    else:
        print("It is Valid.")

print(isbncheck("9788177000252"))

I expected the output to alternate factors of 1 and 3. Instead, I got this:

9 * 1 + at i=0
7 * 3 + at i=1
8 * 1 + at i=2
8 * 1 + at i=3
1 * 1 + at i=4
7 * 3 + at i=5
7 * 1 + at i=6
0 * 3 + at i=7
0 * 3 + at i=8
0 * 3 + at i=9
2 * 3 + at i=10
5 * 3 + at i=11
_______
96
6
2
2
This is not valid
None

How do you work around it? Other than not expanding the loop?

Prune
  • 76,765
  • 14
  • 60
  • 81

2 Answers2

2

Your problem is here:

for i in range(0,12):
    if num % 2 is 1:

num is your accumulated sum. You have to check the index, not the sum so far.

for i in range(len(isbn)):
    digit = int(isbn[i])
    if i % 2 == 1:
        num += 3 * digit

Also note some minor improvements:

  • Since you have to refer to the value twice, convert to int and hold it in a temporary digit.
  • use == for numerical comparison; is gives you object comparison, which will fail for general cases.
Prune
  • 76,765
  • 14
  • 60
  • 81
1

According to the ISBN spec, the 3 goes on every other digit, so your if statement should be if i % 2 is 1:, not if num % 2 is 1: (and the elif should be changed accordingly).

Also, you must take 10 minus the result of the modulo operation; so after num = num%10 you would have the new line num = 10 - num. Otherwise your computed check digit (num) will be incorrect.

Another note: is only works on some implementations to compare numbers between -1 and 256 (source), which is why it works in this case. But in general == is more suited for comparing two numbers.

APerson
  • 8,140
  • 8
  • 35
  • 49