1

Prompt: Implement a function that determines whether or not a card number is valid, according to some simple algorithms. Assume that the credit card number is a string consisting of 14 characters and is in the format ####-####-####, including the dashes, where ‘#’ represents a digit between 0-9, so that there are 12 digits overall.

Objective: Implement a function called “verify” that takes a single parameter called “number” and then checks the following rules:

  1. The first digit must be a 4.
  2. The fourth digit must be one greater than the fifth digit; keep in mind that these are separated by a dash since the format is ####-####-####.
  3. The sum of all digits must be evenly divisible by 4.
  4. If you treat the first two digits as a two-digit number, and the seventh and eighth digits as a two-digit number, their sum must be 100.

If conditions are not met return "rule#X" depending on which rule was failed.

My Progress:

def verify(number):
    if len(number) != 14:
        return False
    if number[0] != 4:
        print("rule#1")
    if number[5] + 1 != number[3]:
        print("rule#2")
    if sum(number) != int:
        print("rule#3")
    if number[0,1] + number[6,7] != 100
        print("rule#4")

    return True # 

input = "5000-0000-0000" 
output = verify(input) 
print(output) 

I think I'm having difficulties with the 3rd and fourth condition but not sure what to do / how to approach it.

ywbaek
  • 2,971
  • 3
  • 9
  • 28
Michael
  • 17
  • 2
  • Instead of printing the strings, you want to `return "rule#1"`, etc. instead. FYI – BruceWayne Jun 21 '20 at 03:53
  • can you provide some more example of input values and corresponding expected output? – Narendra Prasath Jun 21 '20 at 03:58
  • 1
    The first thing you have to deal with is that `number` is a string, not a number, so you will need to convert relevant parts to integers to be able to do sums on them. Also the correct way to index into a string is `number[0:1]`, not `number[0,1]` – Nick Jun 21 '20 at 03:59
  • 1
    To get the sum you can use this; `sum(map(int, '1234-5678-9012'.replace('-', ''))) ` – Aditya Jun 21 '20 at 04:15
  • Does this answer your question? [Python Credit Card Validation](https://stackoverflow.com/questions/40688156/python-credit-card-validation) – Joe Jun 21 '20 at 06:02
  • https://stackoverflow.com/questions/39272087/validate-credit-card-number-using-luhn-algorithm-python – Joe Jun 21 '20 at 06:02
  • So I'm still having difficulties with this fourth criteria. It's the following: If you treat the first two digits as a two-digit number, and the seventh and eighth digits as a two-digit number, their sum must be 100. I think the below code is adding it together (2+3=5) instead of treating it as a two digit number (2+3=23). I need the latter. – Michael Jun 22 '20 at 18:40

3 Answers3

0

For the 3rd rule you can do it like this.Remove the '-' character and add all the digits.

strippedNum=number.replace('-','')  # remove '-'
digits_sum = sum([int(digit) for digit in strippedNum]) # make a list with all the digits and find their sum
if sum_of_all % 4 != 0:
    print(rule#3)

And for the fourth you might be getting an error because you are trying to concatenate two strings and equate it to a integer.This is how it should be,

  if int(number[0:1]) + int(number[6:7]) != 100 # Use [lower_limit:upper_limit] when extracting from a list
    print("rule#4")

So this is how your final code should look(be careful when handling strings and integers)

def verify(number):
    valid = True
    if len(number) != 14:
        valid = False
if number[0] != '4':    # number[0] is a string
    print("rule#1")
    valid = False


if number[5] < number[3]:
    print("rule#2")
    valid = False


strippedNum=number.replace('-','')  # remove '-'
digits_sum = sum([int(digit) for digit in strippedNum]) # make a list with all the digits and find their sum
print(digits_sum)
if digits_sum % 4 != 0:
    print("rule#3")
    valid = False


if int(number[0:1]) + int(number[6:7]) != 100:
    print("rule#4")
    valid = False


return valid 

input = "5000-0000-0000" 
output = verify(input) 
print(output)

This method prints all the faults at once and give the boolean output.

AfiJaabb
  • 316
  • 3
  • 11
0

You should return the strings instead of printing. For the third rule, you can use the modulo % function. Here's one way to do it (the fourth rule can almost certainly be improved...)

def verify(number):
    if len(number) != 14 or int(number[0]) != 4:
        return False
    if int(number[0]) != 4:
        return "rule#1"
    if int(number[5]) + 1 != int(number[3]):
        return "rule#2"
    if sum(int(num) for num in number.replace("-","")) % 4 != 0:
        return "rule#3"
    if int(str(number[0] + str(number[1]))) + int(str(number[6] + str(number[7]))) != 100:
        return "rule#4"
    return True

input = "4501-0550-0000"
output = verify(input)
print(output)
BruceWayne
  • 22,923
  • 15
  • 65
  • 110
0

you can try this:

import re
def verify(number):
    try:
        ## remove any spaces in begginng and end
        number = number.strip()
        ## remove any spaces between numbers
        number = re.sub("\s+","",number)
        if len(number) != 14:
            return False, "current number length is "+str(len(number)) + " but number is missing the expected length of 14."
        if int(number[0]) != 4:
            return False, "First digit must be 4. but received first digit is " + number[0]
        if int(number[5]) + 1 != int(number[3]):
             return False, "The fourth digit must be one greater than the fifth digit"
        if sum([int(digit) for digit in re.sub("-","",input)]) % 4 != 0:
            return False, "Sum of all digit is not divisible by 4"
        if int(input[0:2]) +  int(input[-2:]) != 100:
            return False, "Sum of first two digit and last two digit is not 100"
        return True, "All conditions are met"
    except Exception as e:
        print(e)
        return False, "code got interrupted."
    
input = "4000-0000-0010" 
output = verify(input) 
print(output) 

output you can acces by output[0] for true/false and output[1] for message

Narendra Prasath
  • 1,501
  • 1
  • 10
  • 20