for a free online Python tutorial I need to:
to write a function which checks if a given credit card number is valid. The function
check(S)should take a stringSas input. First, if the string does not follow the format"#### #### #### ####"where each#is a digit, then it should returnFalse. Then, if the sum of the digits is divisible by10(a "checksum" method), then the procedure should returnTrue, else it should returnFalse. For example, ifSis the string"9384 3495 3297 0123"then although the format is correct, the digit sum is72so you should returnFalse.
The following shows what I have come up with. I think my logic is correct but don't quite understand why it is giving me the wrong value. Is there a structural issue in my code, or am I using a method incorrectly?
def check(S):
if len(S) != 19 and S[4] != '' and S[9] != '' and S[14] != '':
return False # checking if the format is correct
S = S.replace(" ",'') # Taking away spaces in the string
if not S.isdigit():
return False # checking that the string has only numbers
L = []
for i in S:
i = int(i) # Making a list out of the string and converting each character to an integer so that it the list can be summed
L.append(i)
if sum(L)//10 != 0: # checking to see if the sum of the list is divisible by 10
return False
You are not testing for spaces, only for empty strings, which you'll never find when using straight indices on a python string.
Moreover, you should return False if any of those 4 conditions is true, not if they are all true at the same time:
if len(S) != 19 or S[4] != ' ' or S[9] != ' ' or S[14] != ' ':
return False
Next, you replace the spaces, but don't check the length again. What if I had given you 19 spaces:
S = S.replace(" ", '')
if len(S) != 16 or not S.isdigit():
return False
Last, you want first collect all the digits, and check if there is a remainder:
L = map(int, S) # makes S into a sequence of integers in one step
if sum(L) % 10 != 0: # % calculates the remainder, which should be 0
return False
and don't forget to return True if all those tests have passed:
return True
at the end.
Put that all together and you get:
>>> def check(S):
... if len(S) != 19 or S[4] != ' ' or S[9] != ' ' or S[14] != ' ':
... return False
... S = S.replace(" ", '')
... if len(S) != 16 or not S.isdigit():
... return False
... L = map(int, S) # makes S into a sequence of integers in one step
... if sum(L) % 10 != 0: # % calculates the remainder, which should be 0
... return False
... return True
...
>>> check('9384 3495 3297 0123')
False
>>> check('9384 3495 3297 0121')
True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With