Программирование на Python – проверка номера ISBN-10

Номера ISBN или Международные стандартные номера книг – это коммерческие числовые идентификаторы книг, которые используются для однозначной идентификации публикации. Есть два типа номеров ISBN – ISBN-10 и ISBN-13.

Валидация – очень важная тема в компьютерном программировании, которая имеет множество приложений. В этой статье мы рассмотрим задачу проверки допустимости номера ISBN 10 .

Правило состоит в том, что для того, чтобы номер ISBN 10 был действительным, мы умножаем первую цифру на 10, вторую 9, третью и 8 т. д. До 10-й цифры на 1. Если результат делится на 11 то код действителен.

Проверка номеров ISBN 10

Взгляните на этот пример:

Номер ISBN-10: 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

Поскольку 176 % 11 = 0 мы знаем, что 176 кратно 11, поэтому номер ISBN-10 действителен.

Одна дополнительная деталь заключается в том, что последний символ номеров ISBN 10 может быть X. При проверке достоверности кода X интерпретируется как равный 10.

Оператор по модулю в Python

Ключевым моментом здесь является делимость на 11 . Мы можем проверить это свойство в Python, используя оператор по модулю (%) . Если вы не знакомы с оператором * по модулю, сейчас самое время узнать о нем. Он имеет много важных применений в программировании.

Оператор по модулю дает остаток от деления на целое число.

Например, 10 % 3 = 1 потому что

10 = 3 * 3 + 1

В качестве примера его использования, мы можем проверить, является число четным или нечетным, сделав следующее:

for i in range(21):
    print(f"{i} is {'even' if i % 2 == 0 else 'odd'}")

В этом примере используется пара удобных ярлыков Python – f-строки для интерполяции переменных и тернарный условный оператор Python.

Функция Python для проверки номеров ISBN 10

Попробуйте выполнить приведенную ниже функцию для проверки номеров ISBN 10. Я включил некоторые базовые тесты в виде утверждений, чтобы вы могли четко понимать, какой результат ожидается для данного ввода. 

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

Если вы чувствуете, что вам нужно немного больше структуры, вот версия заглушки с комментариями, которые помогут вам

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

Мой код для решение задачи:

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

Этот код является нормальным для базового решения. Однако есть возможности для улучшения. Во-первых, нам нужно обработать случай, когда X = 10 для последней цифры, но также есть некоторые другие детали, такие как удаление пробелов и тире.

Улучшенное решение Python для проверки номера ISBN-10

Версия ниже содержит несколько улучшений по сравнению с базовым решением, указанным выше. Вам решать, хотите ли вы попробовать реализовать улучшенную версию самостоятельно или просто посмотрите версию ниже, чтобы узнать, как это можно сделать.

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

Ответить