-2

I'm learning to wrap my head around programming and have been given the following task:

The ISBN (International Standard Book Number) is made out of 10 digits.

z1z2z3z4z5z6z7z8z9z10

The last digit z10 is a check-digit. It's made like this: First, you create a kind of cross-sum with this formula:

s = 1 * z1 + 2 * z2 + 3 * z3 + 4 * z4 + 5 * z5 + 6 * z6 + 7 * z7 + 8 * z8 + 9 * z9

The check-digit z10 is the remainder of the integer division of s divided by 11. For the remainder 10 you write x or X. Example: For the ISBN 3826604237 you get the check-digit 7.

Calculation: 1*3+2*8+3*2+4*6+5*6+6*0+7*4+8*2+9*3 = 150

The remainder of the division of 150 and 11 is 7.

The code-solution given is as followed:

# isbn.py
number = int(input("Please enter a 9-digit number: "))
z9 = number % 10
number = number//10
z8 = number % 10
number = number//10
z7 = number % 10
number = number//10
z6 = number % 10
number = number//10
z5 = number % 10
number = number//10
z4 = number % 10
number = number//10
z3 = number % 10
number = number//10
z2 = number % 10
number = number//10
z1 = number
sum = z1+2*z2+3*z3+4*z4+5*z5+6*z6+7*z7+8*z8+9*z9
checkdigit = sum%11
print("\nCheckdigit:", checkdigit)

My question simply is: How does it work? Why do I have to calculate "number // 10" and "number % 10" and this all the time? Is there a name for this kind of algorithm, and if so, how is it called?

I'd appreciate any kind of answer for this and if it seems like the easiest thing for you and you feel like I'm wasting your time, I'm sorry. So far I understood pretty much anything I've learned thus far learning python, but this task seemed a bit hard (it was in a very early chapter of the book I'm studying on work) and I got stuck and didn't get this out of my head.

Thank you in advance and have a nice day!

KVMVSVBI
  • 21
  • 1
  • 4
  • "how is it called", yes, its called division. – Deepak Saini Aug 25 '18 at 10:12
  • My question is why it is working that way and what I've overseen working on it, that it's using divisions is clear to me, I even used the word "division" in this text multiple times, but this is not helping at all. – KVMVSVBI Aug 25 '18 at 10:14
  • Whenever you see code that repeats the same few lines over and over, you should try to replace it with a `for` loop. – John Zwinck Aug 25 '18 at 10:15
  • See, say we have number = 123(a number in decimal - base 10), each time you do number%10, you get the left most digit of the number. So for 123, 123%10 gives you 3. Also, number//10 cuts off the left most digit. So 123//10 makes it 12. You then repeat the same steps multiple times to get all the digits. – Deepak Saini Aug 25 '18 at 10:16
  • 10 is special here because, the number is in base 10(decimal). Say if you had a number in binary, you would do the same with 2. To understand it further imagine 123 = 1*100 + 2*10 + 3, so you see the remainder of 123 when divided by 10 is 3, which is nothing but the right most digit of 123. And when you divide it by 10, it becomes 12 = 1*10+2(i.e all digits shift by 1 to right). – Deepak Saini Aug 25 '18 at 10:23
  • @Deepak: "rightmost" in all places is what you mean. – user1016274 Aug 25 '18 at 10:25
  • @user1016274, ohh yeah. can't edit it now. – Deepak Saini Aug 25 '18 at 10:26
  • Ah! Now I'ts getting clearer. It's just crunching it through and giving every digit one after another to the z1 - z9, if I'm not totally wrong? So it's just breaking the number down for the sum-calculation, right? Now it makes sense I think! – KVMVSVBI Aug 25 '18 at 10:28

3 Answers3

1

The operation x % 10 is called 'modulus' and returns the remainder of the division by 10. You use it in your code to isolate the rightmost digit.

The next operation x // 10 is called 'integer division', that is, a division which returns integers only (the fractional part (if any) is cut off). Integer division by 10 on a decimal number corresponds to a rightshift by one digit so that the next digit is shifted into the rightmost place.

You repeat these 2 steps until the last digit is isolated. Then you perform the multiplications, and finally take the modulus of 11 (the remainder of the division by 11) to obtain the check digit.

This repetitive code cries for a loop. Just imagine you had to handle 100 digit numbers.

user1016274
  • 4,071
  • 1
  • 23
  • 19
0

You are using % aka modulus and integer division // to get one digit a time.

It is easier to not convert the whole number into an integer and then extract the individual digits, but to process the inputted string character wise.

Throw in some input validation and you get:

while True:
    # don't convert to int
    # repeat until exactly 9 digits are given
    number = input("Please enter a 9-digit number: ").strip()  
    if number.isdigit() and len(number) == 9:
        break

# generator method - enumerate gives you the position and the value of each character 
# i.e. for enumerate('123') you get (0,'1') then (1,'2') then (2,'3')
# the sum function adds up each given tuple but premultiplies the value with its (pos+1) as position inside strings start at 0 for the 1st character - it also
# converts each single character to its integer value
s1 = sum( (pos+1)*int(num) for pos,num in enumerate(number)) 

# s1 is a summed generator expression for this: 
s2 = 0  # do not use sum - its a built-in functions name
for pos,num in enumerate(number):        
    s2 += (pos+1)*int(num)

print(s1,s2)  # both are the same ;o)

checkdigit = s1%11
print("\nCheckdigit:", checkdigit)

For 382660423 you get:

150 150

Checkdigit: 7
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
0

It's began from modulo arytmetic. And module, length of ICBN and coefficients is just agreement, cause coefficients has no matter (by modulo arytmetic properties (if x mod y = 0, than k * x mod y = 0, where k is integer)).

Eugene Trofimov
  • 169
  • 1
  • 2
  • 13
  • There is no 'ϕ' ("ph") in [αριθμός](https://en.wiktionary.org/wiki/%E1%BC%80%CF%81%CE%B9%CE%B8%CE%BC%CF%8C%CF%82#Ancient_Greek), as there is no 'ϕ' in [ῥυθμός](https://en.wikipedia.org/wiki/Rhythm) ("rhy**th**m"). Both have been written with 'θ', later transliterated into "th". This little shift in pronunciation is neither uncommon, nor [is it exactly new](https://en.wikipedia.org/wiki/Fita#Old_Russian_and_Church_Slavonic), though... – Andrey Tyukin Aug 25 '18 at 11:01
  • Oh, sorry, that "rhythm" cognate did more harm than good. It was only about the 'ph' -> 'th' shift ("[arithmetic](https://en.wiktionary.org/wiki/arithmetic)"), the 'y' seems to come from the 'υ'... – Andrey Tyukin Aug 25 '18 at 11:11