Home > Enterprise >  How to process credit card input string according to the following conditions with python
How to process credit card input string according to the following conditions with python

Time:12-15

I have a credit card company ABC which issues credit card numbers based on the following rules:

1. The number must contain exactly 16 digits

2. The input string must not have any other character apart from hyphen as separator

3. The input may contain four number groups separated by a hyphen e.g 5122-2368-7954- 3214

4. The input must not have 4 or more repeated numbers

5. The input must start with either 4 , 5 or 6

I wrote python code to get an input from a user and process it according to the conditions above, if string satisfies all the requirements above then the code should output "Valid" else it should print "Invalid"

Input Format

My first input line takes the number of input strings the program is to take from the user. For example if user wants to pass string input four times, he would pass 4 as an input for this first line.

##take input for number of test cases user wants to run
T=int(input())

The next T lines contain the credit card number input needed for the program to process. My code has been broken down into how I tried to tackle each step declared above, if string fails a single condition then we ignore the body of our loop and skip to the next iteration to process the next user string.

for r in range(T):
   ##read current credit card string from user
   credit=input()
   ##step 1
   ##check if the string has a minumum of 16 digits
   digit_count=0
   for el in credit:
       if(el.isdigit()):
          digit_count =1
   ##check and skip to next iteration if false after Invalid output
   if(digit_count!=16):
     print("Invalid")
     continue
   ##If this string does have a hyphen then we have to make sure the other 
   if('-' in credit):
     ##check and make sure that te hyphen indices do not have a non hyphen character
     if(credit[4]!='-' or credit[9]!='-' or credit[14]!='-'):
        ##print invalid and go to the next iteration
        print("Invalid")
        continue
     ##also make sure the hyphen split the input into a group of four numbers
     if(len(credit.split("-")!=4):#this operation should create an array of four members
        print("Invalid")
        continue

    ##continuing to processs input not having 4 or more repeated characters
    ##remove the hyphens first from the input
    pure_nos=credit.replace("-","")
    ##compare length of set of pure_nos against the length of pure_nos
    if(len(pure_nos)-len(set(pure_nos))>=4):
      print("Invalid")
      continue
      
    ##make sure the first character is either a 4 , 5 or 6
    if(credit[0]!='4' or credit[0]!='5' or credit[0]!='6'):
      print("Invalid")
      continue

    ##if a string passes all the above then it must be valid
    print("Valid")
 

The input strings I am using

Foreach iteration i pass the values below as input in that order downwards

    6

    4123456789123456

    5123-4567-8912-3456

    61234-567-8912-3456

    4123356789123456

    5133-3367-8912-3456

    5123 - 3567 - 8912 - 3456

Output

My code returns Invalid for all test cases , please help me correct this.

CodePudding user response:

I would take a slighly different approach. First refactor your check into a function: Now you can return if the credit is valid or not and don't have to work with many continues. First I would process the numbers in the credit card:

numbers = ""
for number in credit:
    # ignore spaces
    if number == " ":
        continue
    # we found a "-".
    # Now check if the length of numbers is divisible by 4
    if number == "-" and len(numbers) % 4 == 0:
        continue
    # not a number 
    # (Note that "-" and " " are also valid because 
    # of the continue)
    if not number.isdigit():
        return False
    # add the number to all numbers
    numbers  = number

Now you can check their length:

if len(numbers) != 16:
    return False

After that check the repetition: For each number in the credit card, check if any of the following 3 numbers is not equal

# iterate over all numbers but not the last three
# because if a repetition would start there 
# it would be to small
for i in range(len(numbers) - 3):
    repetition = True
    # check each of the next three characters
    for j in range(1, 4):
        # we have found a different number,
        # so there is no repetition here
        if numbers[i] != numbers[i j]:
            repetition = False
    if repetition:
        return False

Last check the first character:

if credit[0] not in "456":
    return False

Full code of check function:

def check_credit(credit):
    # process numbers
    numbers = ""
    for number in credit:
        if number == " ":
            continue
        if number == "-" and len(numbers) % 4 == 0:
            continue
        if not number.isdigit():
            return False
        numbers  = number
    # check length
    if len(numbers) != 16:
        return False
    # check for repetition
    for i in range(len(numbers) - 3):
        repetition = True
        for j in range(1, 4):
            if numbers[i] != numbers[i j]:
                repetition = False
        if repetition:
            return False
    # check first character
    if credit[0] not in "456":
        return False
    return True

Additionally I added a function to test the check function with your testcases (assert throws an exception if the value behind it is not truthy):

def test():
    assert check_credit("4123456789123456")
    assert check_credit("5123-4567-8912-3456")
    # invalid: group of five
    assert not check_credit("61234-567-8912-3456")
    assert check_credit("4123356789123456")
    # invalid: repetition 
    assert not check_credit("5133-3367-8912-3456")
    assert check_credit("5123 - 3567 - 8912 - 3456")

And last I added a function to get the user input as you did in your question:

def user_input():
    # note that variables in python should be lowercase
    t = int(input())
    for r in range(t):
        credit = input()
        if check_credit(credit):
            print("Valid")
        else:
            print("Invalid")
  • Related