def isacn(obj):
"""isacn(string or int) -> True|False
Validate an ACN (Australian Company Number).
http://www.asic.gov.au/asic/asic.nsf/byheadline/Australian+Company+Number+(ACN)+Check+Digit
Accepts an int, or a string of digits including any leading zeroes.
Digits may be optionally separated with spaces. Any other input raises
TypeError or ValueError.
Return True if the argument is a valid ACN, otherwise False.
>>> isacn('004 085 616')
True
>>> isacn('005 085 616')
False
"""
if isinstance(obj, int):
if not 0 <= obj < 10**9:
raise ValueError('int out of range for an ACN')
obj = '%09d' % obj
assert len(obj) == 9
if not isinstance(obj, str):
raise TypeError('expected a str or int but got %s' % type(obj))
obj = obj.replace(' ', '')
if len(obj) != 9:
raise ValueError('ACN must have exactly 9 digits')
if not obj.isdigit():
raise ValueError('non-digit found in ACN')
digits = [int(c) for c in obj]
weights = [8, 7, 6, 5, 4, 3, 2, 1]
assert len(digits) == 9 and len(weights) == 8
chksum = 10 - sum(d*w for d,w in zip(digits, weights)) % 10
if chksum == 10:
chksum = 0
return chksum == digits[-1]
if __name__ == '__main__':
# Check the list of valid ACNs from the ASIC website.
ACNs = '''
000 000 019 * 000 250 000 * 000 500 005 * 000 750 005
001 000 004 * 001 250 004 * 001 500 009 * 001 749 999
001 999 999 * 002 249 998 * 002 499 998 * 002 749 993
002 999 993 * 003 249 992 * 003 499 992 * 003 749 988
003 999 988 * 004 249 987 * 004 499 987 * 004 749 982
004 999 982 * 005 249 981 * 005 499 981 * 005 749 986
005 999 977 * 006 249 976 * 006 499 976 * 006 749 980
006 999 980 * 007 249 989 * 007 499 989 * 007 749 975
007 999 975 * 008 249 974 * 008 499 974 * 008 749 979
008 999 979 * 009 249 969 * 009 499 969 * 009 749 964
009 999 964 * 010 249 966 * 010 499 966 * 010 749 961
'''.replace('*', '\n').split('\n')
ACNs = [s for s in ACNs if s and not s.isspace()]
for s in ACNs:
n = int(s.replace(' ', ''))
if not (isacn(s) and isacn(n) and not isacn(n+1)):
print('test failed for ACN: %s' % s.strip())
break
else:
print('all ACNs tested okay')