Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/faker/providers/isbn/isbn.py: 34%
33 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-07-17 14:22 -0600
1"""
2This module is responsible for generating the check digit and formatting
3ISBN numbers.
4"""
5from typing import Any, Optional
8class ISBN:
10 MAX_LENGTH = 13
12 def __init__(
13 self,
14 ean: Optional[str] = None,
15 group: Optional[str] = None,
16 registrant: Optional[str] = None,
17 publication: Optional[str] = None,
18 ) -> None:
19 self.ean = ean
20 self.group = group
21 self.registrant = registrant
22 self.publication = publication
25class ISBN13(ISBN):
26 def __init__(self, *args: Any, **kwargs: Any) -> None:
27 super().__init__(*args, **kwargs)
28 self.check_digit = self._check_digit()
30 def _check_digit(self) -> str:
31 """Calculate the check digit for ISBN-13.
32 See https://en.wikipedia.org/wiki/International_Standard_Book_Number
33 for calculation.
34 """
35 weights = (1 if x % 2 == 0 else 3 for x in range(12))
36 body = "".join([part for part in [self.ean, self.group, self.registrant, self.publication] if part is not None])
37 remainder = sum(int(b) * w for b, w in zip(body, weights)) % 10
38 diff = 10 - remainder
39 check_digit = 0 if diff == 10 else diff
40 return str(check_digit)
42 def format(self, separator: str = "") -> str:
43 return separator.join(
44 [
45 part
46 for part in [
47 self.ean,
48 self.group,
49 self.registrant,
50 self.publication,
51 self.check_digit,
52 ]
53 if part is not None
54 ]
55 )
58class ISBN10(ISBN):
59 def __init__(self, *args: Any, **kwargs: Any) -> None:
60 super().__init__(*args, **kwargs)
61 self.check_digit = self._check_digit()
63 def _check_digit(self) -> str:
64 """Calculate the check digit for ISBN-10.
65 See https://en.wikipedia.org/wiki/International_Standard_Book_Number
66 for calculation.
67 """
68 weights = range(1, 10)
69 body = "".join([part for part in [self.group, self.registrant, self.publication] if part is not None])
70 remainder = sum(int(b) * w for b, w in zip(body, weights)) % 11
71 check_digit = "X" if remainder == 10 else str(remainder)
72 return str(check_digit)
74 def format(self, separator: str = "") -> str:
75 return separator.join(
76 [
77 part
78 for part in [
79 self.group,
80 self.registrant,
81 self.publication,
82 self.check_digit,
83 ]
84 if part is not None
85 ]
86 )