This program calculates the 7th digit of a GTIN-8 barcode and calculates the validity of an 8 digit GTIN-8 barcode. Could I simplify my code any further?
import math
def roundup(x):
return int(math.ceil(x / 10.0)) * 10
def doMaths(number):
count = 0
total = 0
for n in number:
n = int(n)
if count %2 == 0:
total += n * 3
else:
total += n
count += 1
if len(number) == 8:
if total %10 == 0:
print("Valid")
else:
print("Invalid")
else:
print(number + str(roundup(total) - total))
while True:
try:
number = input("Enter a 7 or 8 digit number for testing: ")
i = int(number)
if len(number) == 7 or len(number) == 8:
doMaths(number)
break
else:
print("Length of number must be 7 or 8")
continue
except ValueError:
print("Only enter numbers.")
continue
1 Answer 1
The doMaths
function has no clear purpose — hence its weird name. It acts as both to calculate the expected last digit of a 7-digit input and to validate the last digit of an 8-digit input. Furthermore, it prints its results instead of returning them, hindering reuse of the function.
What you really want to do is share the code that calculates total
. You could write a function like this, using slices:
def gtin8_checksum_digit(number):
"""
Given a 7- or 8-digit string, calculate the expected GTIN-8 checksum.
>>> gtin8_checksum_digit('3141592')
'7'
>>> gtin8_checksum_digit('31415927')
'7'
"""
total = sum(3 * int(d) for d in number[0:7:2]) + \
sum(int(d) for d in number[1:6:2])
return str(10 - (total % 10))
No floating-point arithmetic should be necessary.
Note the docstring, and in particular, the doctests that make it clear how the function behaves.
To use that function...
if __name__ == '__main__':
while True:
try:
number = input("Enter a 7 or 8 digit number for testing: ")
int(number) # Trigger possible ValueError
if 7 <= len(number) <= 8: break
print("Length of number must be 7 or 8")
except ValueError:
print("Only enter numbers.")
if len(number) == 8:
print("Valid" if gtin8_checksum_digit(number) == number[7] else "Invalid")
else:
print(gtin8_checksum_digit(number))
-
\$\begingroup\$ @Graipher That concern did cross my mind. How about Rev 3? \$\endgroup\$200_success– 200_success2016年10月06日 13:37:28 +00:00Commented Oct 6, 2016 at 13:37
-
\$\begingroup\$ Definitely better. Although I would put the
break
on its own line for PEP8 compliance. \$\endgroup\$Graipher– Graipher2016年10月06日 14:31:08 +00:00Commented Oct 6, 2016 at 14:31