diff options
Diffstat (limited to 'venv/lib/python3.11/site-packages/faker/providers/isbn')
-rw-r--r-- | venv/lib/python3.11/site-packages/faker/providers/isbn/__init__.py | 72 | ||||
-rw-r--r-- | venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/__init__.cpython-311.pyc | bin | 0 -> 4288 bytes | |||
-rw-r--r-- | venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/isbn.cpython-311.pyc | bin | 0 -> 6081 bytes | |||
-rw-r--r-- | venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/rules.cpython-311.pyc | bin | 0 -> 2263 bytes | |||
-rw-r--r-- | venv/lib/python3.11/site-packages/faker/providers/isbn/en_US/__init__.py | 5 | ||||
-rw-r--r-- | venv/lib/python3.11/site-packages/faker/providers/isbn/en_US/__pycache__/__init__.cpython-311.pyc | bin | 0 -> 490 bytes | |||
-rw-r--r-- | venv/lib/python3.11/site-packages/faker/providers/isbn/isbn.py | 85 | ||||
-rw-r--r-- | venv/lib/python3.11/site-packages/faker/providers/isbn/rules.py | 45 |
8 files changed, 207 insertions, 0 deletions
diff --git a/venv/lib/python3.11/site-packages/faker/providers/isbn/__init__.py b/venv/lib/python3.11/site-packages/faker/providers/isbn/__init__.py new file mode 100644 index 0000000..cad4e81 --- /dev/null +++ b/venv/lib/python3.11/site-packages/faker/providers/isbn/__init__.py @@ -0,0 +1,72 @@ +from typing import List, Tuple + +from faker.providers.isbn.rules import RegistrantRule + +from .. import BaseProvider +from .isbn import ISBN, ISBN10, ISBN13 +from .rules import RULES + + +class Provider(BaseProvider): + """Generates fake ISBNs. ISBN rules vary across languages/regions + so this class makes no attempt at replicating all of the rules. It + only replicates the 978 EAN prefix for the English registration + groups, meaning the first 4 digits of the ISBN-13 will either be + 978-0 or 978-1. Since we are only replicating 978 prefixes, every + ISBN-13 will have a direct mapping to an ISBN-10. + + See https://www.isbn-international.org/content/what-isbn for the + format of ISBNs. + See https://www.isbn-international.org/range_file_generation for the + list of rules pertaining to each prefix/registration group. + """ + + def _body(self) -> List[str]: + """Generate the information required to create an ISBN-10 or + ISBN-13. + """ + ean: str = self.random_element(RULES.keys()) + reg_group: str = self.random_element(RULES[ean].keys()) + + # Given the chosen ean/group, decide how long the + # registrant/publication string may be. + # We must allocate for the calculated check digit, so + # subtract 1 + reg_pub_len: int = ISBN.MAX_LENGTH - len(ean) - len(reg_group) - 1 + + # Generate a registrant/publication combination + reg_pub: str = self.numerify("#" * reg_pub_len) + + # Use rules to separate the registrant from the publication + rules: List[RegistrantRule] = RULES[ean][reg_group] + registrant, publication = self._registrant_publication(reg_pub, rules) + return [ean, reg_group, registrant, publication] + + @staticmethod + def _registrant_publication(reg_pub: str, rules: List[RegistrantRule]) -> Tuple[str, str]: + """Separate the registration from the publication in a given + string. + :param reg_pub: A string of digits representing a registration + and publication. + :param rules: A list of RegistrantRules which designate where + to separate the values in the string. + :returns: A (registrant, publication) tuple of strings. + """ + for rule in rules: + if rule.min <= reg_pub[:-1] <= rule.max: + reg_len = rule.registrant_length + break + else: + raise Exception("Registrant/Publication not found in registrant " "rule list.") + registrant, publication = reg_pub[:reg_len], reg_pub[reg_len:] + return registrant, publication + + def isbn13(self, separator: str = "-") -> str: + ean, group, registrant, publication = self._body() + isbn = ISBN13(ean, group, registrant, publication) + return isbn.format(separator) + + def isbn10(self, separator: str = "-") -> str: + ean, group, registrant, publication = self._body() + isbn = ISBN10(ean, group, registrant, publication) + return isbn.format(separator) diff --git a/venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/__init__.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..946bb55 --- /dev/null +++ b/venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/__init__.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/isbn.cpython-311.pyc b/venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/isbn.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..46a758f --- /dev/null +++ b/venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/isbn.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/rules.cpython-311.pyc b/venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/rules.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..d9f13ba --- /dev/null +++ b/venv/lib/python3.11/site-packages/faker/providers/isbn/__pycache__/rules.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/faker/providers/isbn/en_US/__init__.py b/venv/lib/python3.11/site-packages/faker/providers/isbn/en_US/__init__.py new file mode 100644 index 0000000..3df1adc --- /dev/null +++ b/venv/lib/python3.11/site-packages/faker/providers/isbn/en_US/__init__.py @@ -0,0 +1,5 @@ +from .. import Provider as ISBNProvider + + +class Provider(ISBNProvider): + pass diff --git a/venv/lib/python3.11/site-packages/faker/providers/isbn/en_US/__pycache__/__init__.cpython-311.pyc b/venv/lib/python3.11/site-packages/faker/providers/isbn/en_US/__pycache__/__init__.cpython-311.pyc Binary files differnew file mode 100644 index 0000000..0677340 --- /dev/null +++ b/venv/lib/python3.11/site-packages/faker/providers/isbn/en_US/__pycache__/__init__.cpython-311.pyc diff --git a/venv/lib/python3.11/site-packages/faker/providers/isbn/isbn.py b/venv/lib/python3.11/site-packages/faker/providers/isbn/isbn.py new file mode 100644 index 0000000..b712a83 --- /dev/null +++ b/venv/lib/python3.11/site-packages/faker/providers/isbn/isbn.py @@ -0,0 +1,85 @@ +""" +This module is responsible for generating the check digit and formatting +ISBN numbers. +""" +from typing import Any, Optional + + +class ISBN: + MAX_LENGTH = 13 + + def __init__( + self, + ean: Optional[str] = None, + group: Optional[str] = None, + registrant: Optional[str] = None, + publication: Optional[str] = None, + ) -> None: + self.ean = ean + self.group = group + self.registrant = registrant + self.publication = publication + + +class ISBN13(ISBN): + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.check_digit = self._check_digit() + + def _check_digit(self) -> str: + """Calculate the check digit for ISBN-13. + See https://en.wikipedia.org/wiki/International_Standard_Book_Number + for calculation. + """ + weights = (1 if x % 2 == 0 else 3 for x in range(12)) + body = "".join([part for part in [self.ean, self.group, self.registrant, self.publication] if part is not None]) + remainder = sum(int(b) * w for b, w in zip(body, weights)) % 10 + diff = 10 - remainder + check_digit = 0 if diff == 10 else diff + return str(check_digit) + + def format(self, separator: str = "") -> str: + return separator.join( + [ + part + for part in [ + self.ean, + self.group, + self.registrant, + self.publication, + self.check_digit, + ] + if part is not None + ] + ) + + +class ISBN10(ISBN): + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, **kwargs) + self.check_digit = self._check_digit() + + def _check_digit(self) -> str: + """Calculate the check digit for ISBN-10. + See https://en.wikipedia.org/wiki/International_Standard_Book_Number + for calculation. + """ + weights = range(1, 10) + body = "".join([part for part in [self.group, self.registrant, self.publication] if part is not None]) + remainder = sum(int(b) * w for b, w in zip(body, weights)) % 11 + check_digit = "X" if remainder == 10 else str(remainder) + return str(check_digit) + + def format(self, separator: str = "") -> str: + return separator.join( + [ + part + for part in [ + self.group, + self.registrant, + self.publication, + self.check_digit, + ] + if part is not None + ] + ) diff --git a/venv/lib/python3.11/site-packages/faker/providers/isbn/rules.py b/venv/lib/python3.11/site-packages/faker/providers/isbn/rules.py new file mode 100644 index 0000000..db5d126 --- /dev/null +++ b/venv/lib/python3.11/site-packages/faker/providers/isbn/rules.py @@ -0,0 +1,45 @@ +""" +This module exists solely to figure how long a registrant/publication +number may be within an ISBN. The rules change based on the prefix and +language/region. This list of rules only encapsulates the 978 prefix +for English books. 978 is the largest and, until recently, the only +prefix. + +The complete list of prefixes and rules can be found at +https://www.isbn-international.org/range_file_generation +""" + +from collections import namedtuple +from typing import Dict, List + +RegistrantRule = namedtuple("RegistrantRule", ["min", "max", "registrant_length"]) + +# Structure: RULES[`EAN Prefix`][`Registration Group`] = [Rule1, Rule2, ...] +RULES: Dict[str, Dict[str, List[RegistrantRule]]] = { + "978": { + "0": [ + RegistrantRule("0000000", "1999999", 2), + RegistrantRule("2000000", "2279999", 3), + RegistrantRule("2280000", "2289999", 4), + RegistrantRule("2290000", "6479999", 3), + RegistrantRule("6480000", "6489999", 7), + RegistrantRule("6490000", "6999999", 3), + RegistrantRule("7000000", "8499999", 4), + RegistrantRule("8500000", "8999999", 5), + RegistrantRule("9000000", "9499999", 6), + RegistrantRule("9500000", "9999999", 7), + ], + "1": [ + RegistrantRule("0000000", "0999999", 2), + RegistrantRule("1000000", "3999999", 3), + RegistrantRule("4000000", "5499999", 4), + RegistrantRule("5500000", "7319999", 5), + RegistrantRule("7320000", "7399999", 7), + RegistrantRule("7400000", "8697999", 5), + RegistrantRule("8698000", "9729999", 6), + RegistrantRule("9730000", "9877999", 4), + RegistrantRule("9878000", "9989999", 6), + RegistrantRule("9990000", "9999999", 7), + ], + }, +} |