Using loops in python to configure credit card number - python

I am working on this project in which I have to check if a credit card number is valid or not. In this case I only need an 8 digit credit card(I know that's not reality). Here is the question
The last digit of a credit card number is the check digit, which protects against transcription errors such as an error in a single digit or switching two digits. The following method is used to verify actual credit card numbers but, for simplicity, we will describe it for numbers with 8 digits instead of 16:
• Starting from the rightmost digit, form the sum of every other
digit. For example, if the credit card number is 4358 9795, then you
form the sum 5 + 7 + 8 + 3 = 23.
• Double each of the digits that were not included in the preceding
step. Add all digits of the resulting numbers. For example, with the
number given above, doubling the digits, starting with the
next-to-last one, yields 18 18 10 8. Adding all digits in these values
yields 1 + 8 + 1 + 8 + 1 + 0 + 8 = 27.
• Add the sums of the two preceding steps. If the last digit of the
result is 0, the number is valid. In our case, 23 + 27 = 50, so the
number is valid.
Write a program that implements this algorithm. The user should supply an 8-digit number, and you should print out whether the number is valid or not. If it is not valid, you should print the value of the check digit that would make it valid.
I have to use loops to do the sum. However, I do not know how to use loops for that.
Here's my code
# Credit Card Number Check. The last digit of a credit card number is the check digit,
# which protects against transcription errors such as an error in a single digit or
# switching two digits. The following method is used to verify actual credit card
# numbers but, for simplicity, we will describe it for numbers with 8 digits instead
# of 16:
# Starting from the rightmost digit, form the sum of every other digit. For
# example, if the credit card number is 43589795, then you form the sum
# 5 + 7 + 8 + 3 = 23.
# Double each of the digits that were not included in the preceding step. Add # all
# digits of the resulting numbers. For example, with the number given above,
# doubling the digits, starting with the next-to-last one, yields 18 18 10 8. Adding
# all digits in these values yields 1 + 8 + 1 + 8 + 1 + 0 + 8 = 27.
# Add the sums of the two preceding steps. If the last digit of the result is 0, the
# number is valid. In our case, 23 + 27 = 50, so the number is valid.
# Write a program that implements this algorithm. The user should supply an 8-digit
# number, and you should print out whether the number is valid or not. If it is not
# valid, you should print out the value of the check digit that would make the number
# valid.
card_number = int(input("8-digit credit card number: "))
rights = 0
for i in card_number[1::2]:
rights += int(i)
lefts = 0
for i in card_number[::2]:
lefts += int(i)*2%10+int(i)*2/10
print card_number, (rights +lefts)/10
if remaining == 0:
print("Card number is valid")
else:
print("Card number is invalid")
if digit_7 - remaining < 0:
checkDigit = int(digit_7 + (10 - remaining))
print("Check digit should have been:", checkDigit)
else:
checkDigit = int(digit_7 - remaining)
print("Check digit should have been:", checkDigit)

If I understand correctly, you are looking for something like this:
cards = ["43589795"]
for card_number in cards:
rights = sum(map(int, card_number[1::2]))
lefts = sum(map(lambda x: int(x)*2%10+int(x)*2/10, card_number[::2])) # sum of doubled values
print card_number, (rights +lefts)/10
Same solution without map and lambda magic:
rights = 0
for i in card_number[1::2]:
rights += int(i)
lefts = 0
for i in card_number[::2]:
lefts += int(i)*2%10+int(i)*2/10
print card_number, (rights +lefts)/10
And full answer on your question:
card_number = str(raw_input("8-digit credit card number: ")).replace(" ", "")
rights = 0
for i in card_number[1::2]:
rights += int(i)
lefts = 0
for i in card_number[::2]:
lefts += int(i)*2%10+int(i)*2/10
remaining = (rights +lefts)%10
digit_7 = int(card_number[-1]) # Last digit
if remaining == 0:
print("Card number is valid")
else:
print("Card number is invalid")
if digit_7 - remaining < 0:
checkDigit = int(digit_7 + (10 - remaining))
print("Check digit should have been:", checkDigit)
else:
checkDigit = int(digit_7 - remaining)
print("Check digit should have been:", checkDigit)

Here is another possible solution:
cc_number = input("8-digit credit card number: ").replace(" ", "")
total1 = 0
total2 = 0
for digit in cc_number[-1::-2]:
total1 += int(digit)
for digit in cc_number[-2::-2]:
total2 += sum(int(x) for x in str(int(digit)*2))
remainder = (total1 + total2) % 10
if remainder == 0:
print("Card is valid!")
else:
invalid_check_digit = int(cc_number[-1])
if invalid_check_digit - remainder < 0:
valid_check_digit = invalid_check_digit + (10 - remainder)
else:
valid_check_digit = invalid_check_digit - remainder
print("Card is invalid - the correct check digit is {}".format(valid_check_digit))
Giving you the following output:
8-digit credit card number: 4358 9795
Card is valid!
Or:
8-digit credit card number: 4358 9794
Card is invalid - the correct check digit is 5

Prune all spaces from the credit card number and try the following code:
import itertools
sum = 0
for multiplicand,didgit in zip(itertools.cycle([2,1]), str(CREDIT_CARD_NUMBER)):
result = multiplicand * int(didgit)
sum += result / 10
sum += result % 10
print "valid" if sum % 10 == 0 else "invalid"
The above code loops through the credit card number and computes both sums simultainously.

Here is a solution using numpy:
import numpy as np
d1=np.transpose(np.array(list('43589795'), dtype=np.uint8).reshape((4,2)))[0]*2
d2=np.transpose(np.array(list('43589795'), dtype=np.uint8).reshape((4,2)))[1]
if (np.sum(np.hstack([list(entry) for entry in d1.astype(str)]).astype(np.uint8))+np.sum(d2))%10==0:
return "Validated"
In the example case, we get 50 which is validated.

Related

How to make simple number identification Python?

I have this exercise:
Receive 10 integers using input (one at a time).
Tells how many numbers are positive, negative and how many are equal to zero. Print the number of positive numbers on one line, negative numbers on the next, and zeros on the next.
That i need to solve it with control/repetition structures and without lists. And i'm stuck in the first part in dealing with the loops
Until now I only writed the part that deal with the amount of zeros, I'm stuck here:
n = float(input()) #my input
#Amounts of:
pos = 0 # positive numbers
neg = 0 # negative numbers
zero = 0 # zero numbers
while (n<0):
resto = (n % 2)
if (n == 0): #to determine amount of zeros
zz = zero+1
print (zz)
elif (resto == 0): #to determine amout of positive numbers
pp = pos+1
print (pp)
elif (n<0): #to determine amount of negative numbers
nn = neg+1
else:
("finished")
My inputs are very random but there are like negatives and a bunch of zeros too and obviously some positive ones. What specific condition i write inside while to make it work and to make a loop passing by all the numbers inside a range of negative and positive ones?
Soo.. i made it turn into float because theres some broken numbers like 2.5 and the inputs are separated by space, individual inputs of numbers one after other
example input (one individual input at a time):
25
2.1
-19
5
0
# ------------------------------------------
# the correct awnser for the input would be:
3 #(amount of Positive numbers)
1 #(amount of Negatives numbers)
1 #(amount of Zeros numbers)
how to make them all pass by my filters and count each specific type of it?
obs: i can't use lists!
If I understood you right, I think the below code may be what you are after.
Wishing you much success in your future ventures and projects!:D
pos_count = 0
neg_count = 0
zero_count = 0
turn_count = 0
while turn_count < 10:
user_input = input("Please enter a whole number: ") #Get input from user
try:
user_number = int(user_input) # Catch user input error
except:
print("Input not valid. Please enter a whole number using digits 0-9")
continue # Start over
# Check each number:
if user_number > 0:
pos_count += 1
turn_count +=1
elif user_number < 0:
neg_count += 1
turn_count +=1
elif user_number == 0:
zero_count += 1
turn_count +=1
print("Positive count:", pos_count) # Print positive count
print("Negative count:", neg_count) # Print negative count
print("Zero count:", zero_count) # Print zero count
Why not something like this?
pos = 0
neg = 0
zer = 0
for x in range(10):
number = int(input())
if number > 0:
pos +=1
if number < 0:
neg +=1
else: # number is not positive and not negative, hence zero
zer +=1
print(pos)
print(neg)
print(zer)
EDIT: Thanks #Daniel Hao for pointing out that casting to int is necessary with input().

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')

Luhn Formula not working for different inputs

I'm very much new to programming.
I implemented Credit card validation program according to following instructions.
Let the input be input.
Reverse input.
Multiply all odd positions (i.e. indexes 1, 3, 5, etc.) of input by 2.
If any of these multiplied entries is greater than 9, subtract 9.
Sum all of the entries of input, store as sum.
If sum (mod 10) is equal to 0, the credit card number is valid.
code
# credit card validation - Luhn Formula
card_number = list(reversed(input("enter card number: ")))
status = False
temp1 = []
temp2 = []
sum = 0
for i in card_number:
if card_number.index(i) % 2 != 0:
temp1.append(int(i) * 2)
else:
temp1.append(int(i))
for e in temp1:
if e > 9:
temp2.append(e - 9)
else:
temp2.append(e)
for f in temp2:
sum += f
if sum % 10 == 0:
status = True
print("card is VALID")
else:
print("card is INVALID")
code sometimes works and sometimes not. is there a problem with my code.
valid number 49927398716 - works
valid number 4916092180934319 - not working
please don't link to this - Implementation of Luhn Formula
I don't need another implementation. If possible please tell me what's wrong with my code. So I can correct it.
Thank you
Your problem is here:
if card_number.index(i) % 2 != 0:
This looks for a specific digit in the number, but if the digit is repeated, you will get the position of the first occurrence. If both (or all, or no) occurrences are in odd positions, your code will work. But if one is in an even position and another not, then your odd/even test will produce the wrong answer. Do the odd/even position check this way:
for n,i in enumerate(card_number):
if n % 2 != 0:
temp1.append(int(i) * 2)
else:
temp1.append(int(i))

My GTIN 8 check digit and validity check isn't working

My code supposed to ask for a 7 digit number (GTIN 8) and tell you the 8th digit and/or ask you for an 8 digit (GTIN 8) number and tell whether it's a valid GTIN 8 number. I am not getting these outputs though.
ERROR message when I type in a not 7 digit number
c = int(GTIN[2])*3
IndexError: string index out of range
ERROR message when I type in an 8 digit number
if len(str(GTIN))==8 and sum(total)%10==0:
TypeError: 'int' object is not iterable
What do I need to do to my code to fix this error?
Thanks. This is my code (I can clarify anything you aren't sure about):
while 2>1:
GTIN = input("Enter 7 digit number for check-digit. Enter 8 digit number for validity.")
if GTIN.isdigit()==False:
continue
a = int(GTIN[0])*3
b = int(GTIN[1])*1
c = int(GTIN[2])*3
d = int(GTIN[3])*1
e = int(GTIN[4])*3
f = int(GTIN[5])*1
g = int(GTIN[6])*3
total = (a+b+c+d+e+f+g)
checkdigit = (total + 9) // 10 * 10 - total
if len(GTIN) == 7:
print("Your check digit is",checkdigit)
if len(str(GTIN))==8 and sum(total)%10==0:
print("Valid GTIN-8 number")
else: print("Invalid GTIN number")
What I suggest doing here is to do some extra checking to ensure you have what you need. So, when you get the user input and you are checking for isdigit, make sure the length as well.
Furthermore, you should not use continue the way you have your condition set up. You should let the logic just proceed if it passes initial validation. So, instead, what you can do is check if it does not match the conditions and you can print an error message and then pass a continue to re-prompt the user:
if not GTIN.isdigit() or not len(GTIN) == 8:
print("invalid entry...")
continue
To total up the numbers you can use a short list that you can use as the variable to calculate the check digit.
I put mine like this:
num_sum = num * 3 +num_1 + num_2 * 3 + num_3 + num_4 * 3 + num_5 + num_6 * 3
Then when you calculate you can use rounded - num_sum = check digit.

ISBN final digit finder

I am working in python 3 and I am making a program that will take in a 10 digit ISBN Number and applying a method to it to find the 11th number.
Here is my current code
ISBN=input('Please enter the 10 digit number: ')
while len(ISBN)!= 10:
print('Please make sure you have entered a number which is exactly 10 characters long.')
ISBN=int(input('Please enter the 10 digit number: '))
continue
else:
Digit1=int(ISBN[0])*11
Digit2=int(ISBN[1])*10
Digit3=int(ISBN[2])*9
Digit4=int(ISBN[3])*8
Digit5=int(ISBN[4])*7
Digit6=int(ISBN[5])*6
Digit7=int(ISBN[6])*5
Digit8=int(ISBN[7])*4
Digit9=int(ISBN[8])*3
Digit10=int(ISBN[9])*2
Sum=(Digit1+Digit2+Digit3+Digit4+Digit5+Digit6+Digit7+Digit8+Digit9+Digit10)
Mod=Sum%11
Digit11=11-Mod
if Digit11==10:
Digit11='X'
ISBNNumber=str(ISBN)+str(Digit11)
print('Your 11 digit ISBN Number is ' + ISBNNumber)
I want to create some kind of loop so that the number after "Digit" for the variable name increases starting from 1 (or zero if it makes life easier), the number in the square brackets increases starting from 0 and the multiplication number to decrease from 11 to 2.
Is there any way of doing this code in a more efficient way?
I think this should do what you want.
def get_isbn_number(isbn):
digits = [(11 - i) * num for i, num in enumerate(map(int, list(isbn)))]
digit_11 = 11 - (sum(digits) % 11)
if digit_11 == 10:
digit_11 = 'X'
digits.append(digit_11)
isbn_number = "".join(map(str, digits))
return isbn_number
EXAMPLE
>>> print(get_isbn_number('2345432681'))
22303640281810242428
>>> print(get_isbn_number('2345432680'))
2230364028181024240X
Explanation of second line:
digits = [(11 - i) * num for i, num in enumerate(map(int, list(isbn)))]
Could be written out like:
isbn_letters = list(isbn) # turn a string into a list of characters
isbn_numbers = map(int, isbn_letters) # run the function int() on each of the items in the list
digits = [] # empty list to hold the digits
for i, num in enumerate(isbn_numbers): # loop over the numbers - i is a 0 based counter you get for free when using enumerate
digits.append((11 - i) * num) # If you notice the pattern, if you subtract the counter value (starting at 0) from 11 then you get your desired multiplier
Terms you should look up to understand the one line version of the code:
map,
enumerate,
list conprehension
ISBN=int(input('Please enter the 10 digit number: ')) # Ensuring ISBN is an integer
while len(ISBN)!= 10:
print('Please make sure you have entered a number which is exactly 10 characters long.')
ISBN=int(input('Please enter the 10 digit number: '))
continue
else:
Sum = 0
for i in range(len(ISBN)):
Sum += ISBN[i]
Mod=Sum%11
Digit11=11-Mod
if Digit11==10:
Digit11='X'
ISBNNumber=str(ISBN)+str(Digit11)
print('Your 11 digit ISBN Number is ' + ISBNNumber)

Categories

Resources