Python: Credit Card digits verification - python

I need to implement a function called “verify” that takes a single parameter called “number” and then checks the following rules:
The first digit must be a 4.
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 ####-####-####.
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
This is what I have come up with so far:
def verify(number) : # do not change this line!
# write your code here so that it verifies the card number
number_string = number.replace("-","")
cardnumber = [int(n) for n in number_string]
if cardnumber[0] != 4:
return 1
elif cardnumber[3] != cardnumber[4] + 1:
return 2
elif sum(map(int, cardnumber)) % 4 != 0:
return 3
elif cardnumber[0:2] + cardnumber[6:8] != 100:
return 4
return True
# be sure to indent your code!
input = "4002-1001-0000" # change this as you test your function
output = verify(input) # invoke the method using a test input
print(output) # prints the output of the function
# do not remove this line!

You seem to have forgotten that you already converted cardnumber to a list of integers. It's not a string any more, so you don't need to use int each and every time. To compute your sums, you just need cardnumber[0]*10+cardnumber[1] and cardnumber[7]*10+cardnumber[8].

cardnumber is a list. A list can not be converted to an integer. To do so, you first need to convert the list to a string and to integer or directly to an integer using some logic.
using string to integer logic
elif int(''.join(cardnum[0:2])) + int(''.join(cardnum[7:9])) != 100:

Related

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

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.
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")

Luhns Algorithm, mod 10 check

I have to make an assignment for my course computational thinking, but when I give this valid credit card number as input it keeps saying that the number is invalid, does anyone know why??
def ask_user():
string = (str(input("Please input your credit card number")))
numbers = list(map(int, string.split()))
if card_length(numbers):
validation(numbers)
else:
print("The credit card number you entered is invalid")
"""
This function takes the credit card number as a parameter and checks the length of the credit card number
to see if it is valid or not.
"""
def card_length(numbers):
for i in numbers:
if 13 <= i <= 16:
if numbers[0] == 4 or numbers[0] == 5 or numbers[0] == 6 or (numbers[0] == 3 and numbers[1] == 7):
return True
else:
return False
"""
This method takes the list of numbers and tells the user if it is a valid combination with a print statement
"""
def validation(numbers):
odd_results = odd_digits(numbers)
even_results = even_digits(numbers)
sum_of_results = odd_results + even_results
if sum_of_results % 10 == 0:
print("This credit card number is valid")
else:
print("This credit card number is invalid")
"""
This function takes the credit card number as a string list parameter and adds all
of the even digits in it.
"""
def even_digits(numbers):
length = len(numbers)
sumEven = 0
for i in range(length - 2, -1, -2):
num = eval(numbers[i])
num = num * 2
if num > 9:
strNum = str(num)
num = eval(strNum[0] + strNum[1])
sumEven += num
return sumEven
"""
This function takes the credit card number as a string list parameter and adds all
of the odd digits in it.
"""
def odd_digits(numbers):
length = len(numbers)
sumOdd = 0
for i in range(length - 1, -1, -2):
numbers += sumOdd
return sumOdd
"""
This is the main function that defines our first function called ask_user
"""
def main():
ask_user()
if __name__ == '__main__':
main()
The split() method returns a list of strings after breaking the given string by the specified separator.
Syntax : str.split(separator, maxsplit)
separator : This is a delimiter. The string splits at this specified separator. If is not provided then any white space is a separator.
maxsplit : It is a number, which tells us to split the string into maximum of provided number of times. If it is not provided then there is no limit.
Since you are taking the credit card number as a string without any spaces between the numbers, on splitting the credit card number you will get a list which contains the entire credit card number as a single element of the list(numbers). Therefore, the length of the numbers list will always be one and the card length function will always return False. I suggest you do something like:
string = (str(input("Please input your credit card number")))
numbers = list(map(int, list(string)))
Moving on, let me explain how the Luhn algorithm works:
The last digit in the number is taken as checksum. Alternate numbers starting from the number
next(on the left) to the checksum digit are doubled. If the number becomes a double digit on doubling
then the individual digits are added: 14 --> 1+4 = 5 (or) we could also subtract 9 from the digit
which would give us the same answer: 14-9 =5. All the digits(excluding the checksum digit) are now
added. The sum of these digits is multiplied by 9 and the mod 10 of the number is taken. If the
result of the mod 10 of the number is equal to the checksum digit, then the number is valid.
This is one of the ways in which you could write the code for the algorithm:
card_number = list(map(int, list(input('Enter the credit card number : '))))
card_number.reverse()
checksum = card_number.pop(0)
for i in range(len(card_number)):
if i % 2 == 0:
x = card_number[i] * 2
if len(str(x)) == 2:
x -= 9
card_number[i] = x
total = sum(card_number) * 9
total %= 10
if total == checksum:
print('It is a valid number')
else:
print('It is not a valid number')

Python: Detect duplicate and consecutive numbers

Instructions:
"Create a python program to detect if a number of 10 digits is valid. The number should have 10 digits, it can't contain the number "0" and can't contain duplicate consecutive numbers."
...I am using the append to request the 10 numbers and validating that they are different of 0, but I still dont know how to see if the numbers are consecutive.
This is what I have so far:
list=[]
for num in range (1,10): #Request 10 numbers (it can't be zero)
num=int (input("Add 10 digits:"))
list.append (num)
while num != 0:
print ("The number is valid.")
Hints:
Convert the number to a string using the str() function
Use the len() function to validate the length
Use the in-operator to see validate whether the number contains zero
Use zip(s, s[1:]) as a simple way to bring consecutive characters together
use while because for will end you loop before finished if there duplicate digit
mylist=[]
while len(mylist) < 10: #Request 10 numbers (it can't be zero)
mylistLength = str(len(mylist))
num=int(input("Add 10 digits [" + mylistLength +"]: "))
if num not in mylist:
mylist.append(num)
else:
num=int(input("Digit exist, try other: "))
if len(mylist) == 10:
print("The number is valid.")
print(mylist)

Last 2 digits of an integer? Python 3

With my code, I want to get the last two digits of an integer. But when I make x a positive number, it will take the first x digits, if it is a negative number, it will remove the first x digits.
Code:
number_of_numbers = 1
num = 9
while number_of_numbers <= 100:
done = False
num = num*10
num = num+1
while done == False:
num_last = int(repr(num)[x])
if num_last%14 == 0:
number_of_numbers = number_of_numbers + 1
done = True
else:
num = num + 1
print(num)
Why don't you extract the absolute value of the number modulus 100? That is, use
abs(num) % 100
to extract the last two digits?
In terms of performance and clarity, this method is hard to beat.
To get the last 2 digits of num I would use a 1 line simple hack:
str(num)[-2:]
This would give a string.
To get an int, just wrap with int:
int(str(num)[-2:])
Simpler way to extract last two digits of the number (less efficient) is to convert the number to str and slice the last two digits of the number. For example:
# sample function
def get_last_digits(num, last_digits_count=2):
return int(str(num)[-last_digits_count:])
# ^ convert the number back to `int`
OR, you may achieve it via using modulo % operator (more efficient), (to know more, check How does % work in Python?) as:
def get_last_digits(num, last_digits_count=2):
return abs(num) % (10**last_digits_count)
# ^ perform `%` on absolute value to cover `-`ive numbers
Sample run:
>>> get_last_digits(95432)
32
>>> get_last_digits(2)
2
>>> get_last_digits(34644, last_digits_count=4)
4644
to get the last 2 digits of an integer.
a = int(input())
print(a % 100)
You can try this:
float(str(num)[-2:])

How to pick one number of an Integer

How can I pick one of the digits from an Integer like: 97723
and choose (for example) the number 2 from that number and check if its an odd or an even number?
Also, can I print only the odd numbers from an Integer directly? (Is there any default function for that already?)
Thanks in advance
2 is the 4th digit.
You can get the digits of a number using this construct.
digits = [int(_) for _ in str(97723)]
This expression will be true if the 4th digit is even.
digits[3] % 2 == 0
# choose a digit (by index)
integer = 97723
digit_3 = str(integer)[3]
print(digit_3)
# check if even:
if int(digit_3) % 2 == 0:
print(digit_3, "is even")
# get all odd numbers directly
odd_digits = [digit for digit in str(integer) if int(digit) % 2 == 1]
print(odd_digits)
even = lambda integer: int("".join([num for num in str(integer) if int(num) % 2 == 0]))
or
def even(integer):
result = ""
integer = str(integer)
for num in integer:
if int(num) % 2 == 0:
result += num
result = int(result)
return(result)
If you want to "parse" a number the easiest way to do this is to convert it to string. You can convert an int to string like this s = string(500). Then use string index to get character that you want. For example if you want first character (number) then use this string_name[0], for second character (number) use string_name[1] . To get length of your string (number) use len(string). And to check if number is odd or even mod it with 2.
# Converting int to string
int_to_sting = str(97723)
# Getting number of characters in your string (in this case number)
n_of_numbers = len(int_to_sting)
# Example usage of string index
print("First number in your number is: ",int_to_sting[0])
print("Second number in your number is: ",int_to_sting[1])
# We need to check for every number, and since the first number is int_to_sting[0] and len(int_to_sting) returns actual length of string we need to reduce it by 1
for i in range(n_of_numbers-1):
if int_to_sting[i]%2==0:
print(int_to_sting[i]," is even")
else:
print(int_to_sting[i]," is odd")

Categories

Resources