Codementor Events

Python Programming Challenge - Validate ISBN-10 Number

Published Jan 06, 2021Last updated Jul 04, 2021
Python Programming Challenge - Validate ISBN-10 Number

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.)

A Python Function for Validating ISBN 10 Numbers

Have a go now at completing the function below for or Validating ISBN 10 Numbers. 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 below.

def validate_isbn10(code_string):
    # Make sure string argument is 10 chars long.
    if len(code_string) != 10:
        return False

    # Initialise result to 0
    result = 0

    # Iterate through code_string
    for x in range(10):
        # for each character, multiply by a different decreasing number: 10 - x
        result = result + int(code_string[x]) * (10 - x)

    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

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.

This article first appeared on the Compucademy website.

Discover and read more posts from Robin Andrews
get started
post comments1Reply
Jerry Norton
4 years ago

This would be good in a collection of quick exercises for building python confidence. You could even use it with levels (like you did, although final result is really the minimum for me). How about another level for using Regex to validate string (can even validate final [0-9]$ or [Xx]$). Maybe another level to use list comprehension to do the summation?