1# coding=utf-8 2""" 3This module is responsible for generating the check digit and formatting 4ISBN numbers. 5""" 6 7 8class ISBN(object): 9 10 MAX_LENGTH = 13 11 12 def __init__(self, ean=None, group=None, registrant=None, publication=None): 13 self.ean = ean 14 self.group = group 15 self.registrant = registrant 16 self.publication = publication 17 18 19class ISBN13(ISBN): 20 21 def __init__(self, *args, **kwargs): 22 super(ISBN13, self).__init__(*args, **kwargs) 23 self.check_digit = self._check_digit() 24 25 def _check_digit(self): 26 """ Calculate the check digit for ISBN-13. 27 See https://en.wikipedia.org/wiki/International_Standard_Book_Number 28 for calculation. 29 """ 30 weights = (1 if x % 2 == 0 else 3 for x in range(12)) 31 body = ''.join([self.ean, self.group, self.registrant, 32 self.publication]) 33 remainder = sum(int(b) * w for b, w in zip(body, weights)) % 10 34 diff = 10 - remainder 35 check_digit = 0 if diff == 10 else diff 36 return str(check_digit) 37 38 def format(self, separator=''): 39 return separator.join([self.ean, self.group, self.registrant, 40 self.publication, self.check_digit]) 41 42 43class ISBN10(ISBN): 44 45 def __init__(self, *args, **kwargs): 46 super(ISBN10, self).__init__(*args, **kwargs) 47 self.check_digit = self._check_digit() 48 49 def _check_digit(self): 50 """ Calculate the check digit for ISBN-10. 51 See https://en.wikipedia.org/wiki/International_Standard_Book_Number 52 for calculation. 53 """ 54 weights = range(1, 10) 55 body = ''.join([self.group, self.registrant, self.publication]) 56 remainder = sum(int(b) * w for b, w in zip(body, weights)) % 11 57 check_digit = 'X' if remainder == 10 else str(remainder) 58 return str(check_digit) 59 60 def format(self, separator=''): 61 return separator.join([self.group, self.registrant, self.publication, 62 self.check_digit]) 63