Skip to content

Commit 7bdfe54

Browse files
[Sync Iteration] python/isbn-verifier/5
1 parent d259f7d commit 7bdfe54

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
ISBN Verifier.
3+
4+
The ISBN-10 verification process is used to validate book identification
5+
numbers. These normally contain dashes and look like: 3-598-21508-8
6+
7+
ISBN
8+
The ISBN-10 format is 9 digits (0 to 9) plus one check character
9+
(either a digit or an X only). In the case the check character is an X,
10+
this represents the value '10'. These may be communicated with or without
11+
hyphens, and can be checked for their validity by the following formula:
12+
13+
(d₁ * 10 + d₂ * 9 + d₃ * 8 + d₄ * 7 + d₅ * 6 +
14+
d₆ * 5 + d₇ * 4 + d₈ * 3 + d₉ * 2 + d₁₀ * 1) mod 11 == 0
15+
16+
If the result is 0, then it is a valid ISBN-10, otherwise it is invalid.
17+
"""
18+
19+
ISBN: str = "0123456789X"
20+
21+
22+
def formatted_isbn(isbn: str) -> list[int]:
23+
"""
24+
Extract and format ISBN digits from input string.
25+
26+
Converts ISBN string to list of integers, treating 'X' as 10.
27+
Ignores non-digit characters except for trailing 'X'.
28+
29+
:param isbn: ISBN string that may contain digits, hyphens, and trailing 'X'
30+
:return: List of integers representing ISBN digits, 'X' converted to 10
31+
"""
32+
result: list[int] = []
33+
for char in isbn:
34+
if char.isdigit():
35+
result.append(int(char))
36+
if isbn[-1] == "X":
37+
result.append(10)
38+
return result
39+
40+
41+
def is_valid(isbn: str) -> bool:
42+
"""
43+
Verify ISBN.
44+
45+
:param isbn: 9 digits ISBN 10 format
46+
:return: Tru if isbn is valid, False otherwise
47+
"""
48+
# Non ISBN chars or empty strings not allowed
49+
isbn = isbn.upper()
50+
if not all(char in ISBN for char in isbn.replace("-", "")) or not isbn:
51+
return False
52+
# In case X is present, it should be at the end of the string only
53+
if "X" in isbn and isbn.index("X") != len(isbn) - 1:
54+
return False
55+
56+
# Convert all isbn chars to digits
57+
isbn_digits: list[int] = formatted_isbn(isbn)
58+
# ISBN total length should be = 10
59+
if len(isbn_digits) != 10:
60+
return False
61+
62+
return (
63+
sum(digit * (10 - i) for i, digit in enumerate(isbn_digits)) % 11 == 0
64+
)

0 commit comments

Comments
 (0)