Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Credit card check exercise python

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 string S as input. First, if the string does not follow the format "#### #### #### ####" where each # is a digit, then it should return False. Then, if the sum of the digits is divisible by 10 (a "checksum" method), then the procedure should return True, else it should return False. For example, if S is the string "9384 3495 3297 0123" then although the format is correct, the digit sum is 72 so you should return False.

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
like image 574
iaianmcd Avatar asked Aug 29 '26 17:08

iaianmcd


1 Answers

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
like image 133
Martijn Pieters Avatar answered Sep 01 '26 07:09

Martijn Pieters



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!