ISBN Numbers, or International Standard Book Numbers are commercial numeric book identifiers which are used to uniquely identify a publication. There are two types of ISBN numbers – ISBN-10 and ISBN-13.
Validation is a very important topic in computer programming which has many applications. In this article we will look at the challenge of checking that an ISBN 10 number is valid.
The rule is that for an ISBN 10 number to be valid we multiply the first digit by 10
, the second by 9
, the third by 8
etc. down to the 10th digit by 1
. If the result is divisible by 11
then the code is valid (at least numerically – there may not be a book with a particular numerically valid code available..)
Validating ISBN 10 Numbers
Look at this example:
ISBN-10 number: 0553418025
(10 * 0) + (9 * 5) + (8 * 5) + (7 * 3) + (6 * 4) + (5 * 1) + (4 * 8) + (3 * 0) + (2 * 2) + (1 * 5) = 176
176 % 11 = 0
Since 176 % 11 = 0
, we know that 176
is a multiple of 11
so the ISBN-10 number is valid.
One extra detail is that the last character of an ISBN 10 Numbers can be an X
. When checking the validity of the code, this X
is interpreted as having the value of 10
.
The Modulo Operator in Python
The key here is divisibility by 11. We can check for this property in Python using the modulo operator (%). If you are not familiar with the*modulo operator, now is a good time to learn about it. It has many important uses in programming.
The modulo operator gives the remainder on division by an integer.
E.g 10 % 3 = 1
because
10 = 3 * 3 + 1
As an example of its usefulness, to test whether a number is even of odd we can do the following:
for i in range(21):
print(f"{i} is {'even' if i % 2 == 0 else 'odd'}")
(There’s a couple of handy Python shortcuts in there – f-strings for variable interpolation, and Python ternary conditional operator.)
If you want to master the modulo operator, check out this complete lesson with worksheets and practice examples, including Python code solutions.
[product id=4961]
A Python Function for Validating ISBN 10 Numbers
Have a go now at completing the function below for or Validating ISBN 10 Numbers. As usual some I have included some basis tests in the form of assertions so you can be clear about what output is expected for a given input. In this first version, don’t worry about the X = 10
for the last digit issue – we’ll come to that in a bit.
def validate_isbn10(code_string):
pass
isbn = "123"
assert validate_isbn10(isbn) is False
isbn = "0136091814"
assert validate_isbn10(isbn) is True
isbn = "1616550416"
assert validate_isbn10(isbn) is False
isbn = "0553418025"
assert validate_isbn10(isbn) is True
isbn = "3859574859"
assert validate_isbn10(isbn) is False
If you feel you need a bit more structure, here is a version of the stub with comments to guide you
def validate_isbn10(code_string):
# Make sure string argument is 10 chars long.
# Initialise result to 0
result = 0
# Iterate through code_string
# for each character, multiply by a different decreasing number: 10 - x
print(result) # For debugging if required
# Return whether the isbn is valid as a Boolean
You can see my solution by clicking below.
That’s OK for a basic solution. However, there is room for improvement. Firstly we need to handle the case where X = 10
for the last digit, but also there are some other details, like stripping spaces and dashes so that an ISBN-10 like 1-55404-295-X
will pass as valid, as this is how they often appear.
Python Improved Solution for Validation of an ISBN-10 Number
The version below contains several improvements on the basic solution above. It’s up to you whether you want to try and implement the improved version yourself or just look at the version below for one way it can be done.
def validate_isbn10(code_string):
# Strip spaces and dashes
code_string = code_string.replace("-", "").replace(" ", "")
# Make sure string argument is valid
if len(code_string) != 10:
return False
if not code_string[0:8].isdigit() or not (code_string[9].isdigit() or code_string[9].lower() == "x"):
return False
# Initialise result to 0
result = 0
# Iterate through code_string
for i in range(9):
# for each character, multiply by a different decreasing number: 10 - x
result = result + int(code_string[i]) * (10 - i)
# Handle last character
if code_string[9].lower() == "x":
result += 10
else:
result += int(code_string[9])
print(result) # For debugging if required
# Return whether the isbn is valid
if result % 11 == 0:
return True
else:
return False
# If you prefer and understand why it is equivalent
# return result % 11 == 0
isbn = "123"
assert validate_isbn10(isbn) is False
isbn = "abc"
assert validate_isbn10(isbn) is False
isbn = "0136091814"
assert validate_isbn10(isbn) is True
isbn = "1616550416"
assert validate_isbn10(isbn) is False
isbn = "0553418025"
assert validate_isbn10(isbn) is True
isbn = "3859574859"
assert validate_isbn10(isbn) is False
isbn = "1-55404-295-X"
assert validate_isbn10(isbn) is True
In this article we have looked at the challenge of writing a Python function to validate an ISBN-10 number. I hope you found it interesting. Please feel free to comment below to share how you got on.
Happy computing.
1 Comment on “Python Programming Challenge – Validate ISBN-10 Number”