22
33:Provided barcodes: EAN-14, EAN-13, EAN-8, JAN
44"""
5+
56from __future__ import annotations
67
78__docformat__ = "restructuredtext en"
3132class EuropeanArticleNumber13 (Barcode ):
3233 """Initializes EAN13 object.
3334
34- :param ean: The ean number as string.
35+ :param ean: The ean number as string. If the value is too long, it is trimmed.
3536 :param writer: The writer to render the barcode (default: SVGWriter).
3637 :param no_checksum: Don't calculate the checksum. Use the provided input instead.
3738 """
@@ -43,21 +44,25 @@ class EuropeanArticleNumber13(Barcode):
4344 def __init__ (
4445 self , ean : str , writer = None , no_checksum = False , guardbar = False
4546 ) -> None :
46- ean = ean [: self .digits ]
47- if not ean . isdigit ():
48- raise IllegalCharacterError ( "EAN code can only contain numbers." )
49- if len (ean ) != self .digits :
47+ if not ean [: self .digits ]. isdigit ():
48+ raise IllegalCharacterError ( f"EAN code can only contain numbers { ean } ." )
49+
50+ if len (ean ) < self .digits :
5051 raise NumberOfDigitsError (
51- f"EAN must have { self .digits } digits, not { len (ean )} ."
52+ f"EAN must have { self .digits } digits, received { len (ean )} ."
5253 )
53- self . ean = ean
54- # If no checksum
54+
55+ base = ean [: self . digits ]
5556 if no_checksum :
56- # Add a thirteen char if given in parameter,
57- # otherwise pad with zero
58- self .ean = f"{ ean } { ean [self .digits ] if len (ean ) > self .digits else 0 } "
57+ # Use the thirteenth digit if given in parameter, otherwise pad with zero
58+ if len (ean ) > self .digits and ean [self .digits ].isdigit ():
59+ last = int (ean [self .digits ])
60+ else :
61+ last = 0
5962 else :
60- self .ean = f"{ ean } { self .calculate_checksum ()} "
63+ last = self .calculate_checksum (base )
64+
65+ self .ean = f"{ base } { last } "
6166
6267 self .guardbar = guardbar
6368 if guardbar :
@@ -76,13 +81,14 @@ def get_fullcode(self) -> str:
7681 return self .ean [0 ] + " " + self .ean [1 :7 ] + " " + self .ean [7 :] + " >"
7782 return self .ean
7883
79- def calculate_checksum (self ) -> int :
80- """Calculates the checksum for EAN13-Code.
84+ def calculate_checksum (self , value : str | None = None ) -> int :
85+ """Calculates and returns the checksum for EAN13-Code.
8186
82- :returns: The checksum for ``self.ean``.
87+ Calculates the checksum for the supplied `value` (if any) or for this barcode's
88+ internal ``self.ean`` property.
8389 """
8490
85- ean_without_checksum = self .ean [: self .digits ]
91+ ean_without_checksum = value or self .ean [: self .digits ]
8692
8793 evensum = sum (int (x ) for x in ean_without_checksum [- 2 ::- 2 ])
8894 oddsum = sum (int (x ) for x in ean_without_checksum [- 1 ::- 2 ])
@@ -206,13 +212,14 @@ class EuropeanArticleNumber14(EuropeanArticleNumber13):
206212 name = "EAN-14"
207213 digits = 13
208214
209- def calculate_checksum (self ) -> int :
210- """Calculates the checksum for EAN13 -Code.
215+ def calculate_checksum (self , value : str | None = None ) -> int :
216+ """Calculates and returns the checksum for EAN14 -Code.
211217
212- :returns: The checksum for ``self.ean``.
218+ Calculates the checksum for the supplied `value` (if any) or for this barcode's
219+ internal ``self.ean`` property.
213220 """
214221
215- ean_without_checksum = self .ean [: self .digits ]
222+ ean_without_checksum = value or self .ean [: self .digits ]
216223
217224 evensum = sum (int (x ) for x in ean_without_checksum [::2 ])
218225 oddsum = sum (int (x ) for x in ean_without_checksum [1 ::2 ])
0 commit comments