Most credit cards are assigned a unique number that can be validated by an algorithm developed by Hans Peter Luhn from IBM. The Luhn algorithm can detect almost any single-letter, almost all transpositions of adjacent digits except 09 and 90, and many other errors. In 1960 a patent on the Luhn algorithm was granted to IBM (U.S. Patent 29500481), but nowadays it can be freely used by everyone.
The Luhn algorithm verifies a credit card number against its included check digit, which is appended to a partial credit card number to generate the full credit card number. This credit card number must pass the following test:
From the rightmost digit, which is the check digit, moving left, double the value of every second digit. If the product of this doubling operation is greater than 9 (e.g. $$7 \times 2 = 14$$), then sum the digits of the product (e.g. $$10 = 1 + 0 = 1$$; $$14 = 1 + 4 = 5$$).
Take the sum of all resulting digits, including the check digit.
If the total sum is divisible by 10, the credit card number is valid. Otherwise the credit card number is invalid.
According to the Luhn algorithm, the credit card number 49927398716 is valid. The sum is calculated as follows: \[ 6 + (2) + 7 + (1 + 6) + 9 + (6) + 7 + (4) + 9 + (1 + 8) + 4 = 70 \] and this result is divisible by 10. In this example, we have enclosed the digits of the numbers that have been doubled in between brackets.
Your task is to write the following three functions, that each take a credit card number as a string argument.
A function luhn that returns the sum of the digits of the credit card number, as computed by the Luhn algorithm.
A function valid that returns a Boolean value indicating whether or not the credit card number is valid according to the Luhn algorithm.
A function addcheck that completes the (partial) credit card number with an additional check digit, that results in a valid full credit card number (returned by the function) according to the Luhn algorithm.
Make sure to make optimal reuse of your source code when implementing these three functions.
>>> luhn('49927398716')
70
>>> luhn('49927938716')
67
>>> luhn('79927398716')
73
>>> valid('49927398716')
True
>>> valid('49927938716')
False
>>> valid('79927398716')
False
>>> addcheck('4992739871')
'49927398716'
>>> addcheck('4992793871')
'49927938719'
>>> addcheck('7992739871')
'79927398713'