iaianmcd - 25 days ago 4
Python Question

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
``````

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
``````
Source (Stackoverflow)