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

1""" 

2This module is responsible for generating the check digit and formatting 

3ISBN numbers. 

4""" 

5from typing import Any, Optional 

6 

7 

8class ISBN: 

9 

10 MAX_LENGTH = 13 

11 

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 

23 

24 

25class ISBN13(ISBN): 

26 def __init__(self, *args: Any, **kwargs: Any) -> None: 

27 super().__init__(*args, **kwargs) 

28 self.check_digit = self._check_digit() 

29 

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) 

41 

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 ) 

56 

57 

58class ISBN10(ISBN): 

59 def __init__(self, *args: Any, **kwargs: Any) -> None: 

60 super().__init__(*args, **kwargs) 

61 self.check_digit = self._check_digit() 

62 

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) 

73 

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 )