Luhn Formula not working for different inputs - python

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

Related

Python Credit Card Check Function not running correctly

Trying to implement a program in Python that can check if the input is a valid credit card and display the credit card type(VISA/MASTERCARD/AMEX). For 2 values it's displaying incorrectly and for 2 days I have no ideas how to fix it ?
Output received:( last 2 are incorect 4111111111111113 and 4222222222223) I guess is something related with the check_last_digit function ....
identifies 378282246310005 as AMEX
:) identifies 371449635398431 as AMEX
:) identifies 5555555555554444 as MASTERCARD
:) identifies 5105105105105100 as MASTERCARD
:) identifies 4111111111111111 as VISA
:) identifies 4012888888881881 as VISA
:) identifies 4222222222222 as VISA
:) identifies 1234567890 as INVALID
:) identifies 369421438430814 as INVALID
:) identifies 4062901840 as INVALID
:) identifies 5673598276138003 as INVALID
:( **identifies 4111111111111113 as INVALID**
**expected "INVALID\n", not "VISA\n\n"**
:( **identifies 4222222222223 as INVALID**
**expected "INVALID\n", not "VISA\n\n**
My Code:
#function to find out the sum of every other numbers from the input card
def odd_sum(num):
num = list(str(num))
my_list_digits = [int(item) * 2 for item in num][::2]
total_odd = 0
for number in my_list_digits:
if number > 9:
first_digit = number // 10
second_digit = number % 10
total_odd += first_digit + second_digit
else:
total_odd += number
return total_odd
# function to find out the sum of the other remaining numbers
def even_sum(num):
num = list(str(num))
del num[::2]
my_list_digits1 = [int(item) for item in num]
total_even = 0
for item in my_list_digits1:
total_even += item
return total_even
# function to check the lenght of the input card
def check_length(num):
num = str(num)
num_length = len(num)
if 13 <= num_length <= 16:
return True
else:
print("INVALID")
# function to check the last digit of the sum ( even and odd)
def check_last_digit(num):
odd = odd_sum(num)
even = even_sum(num)
if (odd + even) % 10 == 0:
return True
else:
return False
# function to determine the type of card that was provided
def card_type(card_num):
card_num = str(card_num)
AMEX = ["34", "37"]
MASTERCARD = ["51", "52", "53", "54", "55"]
VISA = ["4"]
if (card_num[0:2]) in AMEX:
print("AMEX")
elif (card_num[0:2]) in MASTERCARD:
print("MASTERCARD")
elif (card_num[0]) == VISA[0]:
print("VISA\n")
else:
print("INVALID")
# main program to run all the above created functions
def main():
#get input from user
card_num = int(input("CARD: "))
#check if the bellow 2 functions are True and if so, run the card type function so we can see what type of card was usde(visa, mastercard,amex)
if check_length(card_num):
card_type(card_num)
else:
if check_last_digit(card_num):
card_type(card_num)
main()
It looks like in your main function
#check if the bellow 2 functions are True and if so, run the card type function so we can see what type of card was usde(visa, mastercard,amex)
if check_length(card_num):
card_type(card_num)
else:
if check_last_digit(card_num):
card_type(card_num)
is supposed to check that both check_length and check_last_digit are passed. However, in your code, if check_length returns True, then the second check is not ran. You need to change your code to make sure that both test are run:
def main():
#get input from user
card_num = int(input("CARD: "))
#check if the bellow 2 functions are True and if so, run the card type function so we can see what type of card was usde(visa, mastercard,amex)
if check_length(card_num) and check_last_digit(card_num):
card_type(card_num)
else:
print("INVALID")
Edit:
There are two other errors in your implementation of the Luhn algorithm.
The odd_sum function is supposed to sum every other digit, starting from the right-most one, and skipping one, but your implementation sums the wrong digits if the number of digits of the input number is odd. To correct for that, you should, for instance, reverse the list first:
l = [int(item) * 2 for item in num[::-1]]
then, remove the first digit (the rightmost one)
l = l[1:]
and finally, take every other digit:
my_list_digits = l[::2]
Then, there's a similar error in even_sum, you should also consider reversing the list, to make sure to consider the correct digits:
my_list_digits1 = [int(item) for item in num[::-1]]
return sum(my_list_digits1)
Lastly, as Jakob mentioned, you should return False instead of "INVALID" in your check_length function.
As a refactoring tip, if you see yourself writing
if condition:
return True
else:
return False
then you can refactor that in the cleaner:
return condition
So for instance:
def check_last_digit(num):
odd = odd_sum(num)
even = even_sum(num)
return (odd + even) % 10 == 0:

WAP in python script to input a multidigit number and find each of the number's factorial

The output shows a different result. Yes, the factorials of those numbers are right but the numbers outputted aren't right.
Here's the code:
input:
n = int(input("Enter a number: "))
s = 0
fact = 1
a = 1
for i in range(len(str(n))):
r = n % 10
s += r
n //= 10
while a <= s:
fact *= a
a += 1
print('The factorial of', s, 'is', fact)
Output:
Enter a number: 123
The factorial of 3 is 6
The factorial of 5 is 120
The factorial of 6 is 720
You're confusing yourself by doing it all in one logic block. The logic for finding a factorial is easy, as is the logic for parsing through strings character by character. However, it is easy to get lost in trying to keep the program "simple," as you have.
Programming is taking your problem, designing a solution, breaking that solution down into as many simple, repeatable individual logic steps as possible, and then telling the computer how to do every simple step you need, and what order they need to be done in to accomplish your goal.
Your program has 3 functions.
The first is taking in input data.
input("Give number. Now.")
The second is finding individual numbers in that input.
for character in input("Give number. Now."):
try:
int(character)
except:
pass
The third is calculating factorials for the number from step 2. I won't give an example of this.
Here is a working program, that is, in my opinion, much more readable and easier to look at than yours and others here. Edit: it also prevents a non numerical character from halting execution, as well as using only basic Python logic.
def factorialize(int_in):
int_out = int_in
int_multiplier = int_in - 1
while int_multiplier >= 1:
int_out = int_out * int_multiplier
int_multiplier -= 1
return int_out
def factorialize_multinumber_string(str_in):
for value in str_in:
print(value)
try:
print("The factorial of {} is {}".format(value, factorialize(int(value))))
except:
pass
factorialize_multinumber_string(input("Please enter a series of single digits."))
You can use map function to get every single digit from number:
n = int(input("Enter a number: "))
digits = map(int, str(n))
for i in digits:
fact = 1
a = 1
while a <= i:
fact *= a
a += 1
print('The factorial of', i, 'is', fact)
Ok, apart from the fact that you print the wrong variable, there's a bigger error. You are assuming that your digits are ever increasing, like in 123. Try your code with 321... (this is true of Karol's answer as well). And you need to handle digit zero, too
What you need is to restart the calculation of the factorial from scratch for every digit. For example:
n = '2063'
for ch in reversed(n):
x = int(ch)
if x == 0:
print(f'fact of {x} is 1')
else:
fact = 1
for k in range(2,x+1):
fact *= k
print(f'fact of {x} is {fact}')

I am getting a ZeroDivisionError , how do i solve this?

im new at this and i was trying to calculate the total of the given numbers, if one of those numbers were a odd number, it wouldn't add up to the total amount, that is b
what i was doing is, if a / 2 has no split rest it would be evens, then it would add to b, but im getting a ZeroDivisionError, what am i doing wrong?
sorry if i misspelled any word
for c in range(1, 7):
a = int(input("type a number {}: ".format(c)))
if a / 2 % 0:
b += a
print("the sum of the numbers is equivalent to:", b)
if you are checking for even number than it should be :
if a % 2 == 0:
I think you want to sum the even numbers entered by the user. In that case, a % 2 returns 0 for even and 1 for odd positive whole numbers.
Please consider using meaningful variable names, like 'even_sum' instead of 'b'.
Consider commenting your code with what you expect a line or code block to do.
The corrected code is as follows.
# initialize b, which will hold the sum of the even numbers
# entered by the user.
b = 0
# prompt the user for a number 6 times.
for c in range(1, 7):
# request a number
a = int(input("type a number {}: ".format(c)))
# if the number is even
if a % 2 == 0:
# the number is even, so add it to the running total, b
b += a
print("The sum of the EVEN numbers is equivalent to:", b)

Error with big number calculations: Why is this happening? [duplicate]

This question already has answers here:
Why does integer division yield a float instead of another integer?
(4 answers)
Closed 3 years ago.
I have created a small Python program in repl.it to illustrate the Collatz Conjecture, which says that if you start with any positive integer number n and you apply the following operations recursively: n/2 if n is even, 3n+1 if n is odd, you will always reach 1.
This is the code:
invalid_input = 0
while(invalid_input == 0):
n = input("Give me a positive integer: ")
try: #check for positive integer. If it cannot do int(n) it means a string was entered, and it goes to except.
if(int(n)>0):
invalid_input = 1 #this is to tell the while loop above that the right input was entered
print("Thank you.")
print("Now loading:")
else: #an integer was entered, but it was negative
print("Please enter a positive integer")
except: #a string was entered
print("Please enter a positive integer")
n=int(n)
nentered = n #this will keep track of the initial n
npeak = n #this will keep track of the highest n reached
iteration = 1 #this will keep track of the number of iterations
iterationmax = 1 #this will keep tack of the iteration at which npeak was reached
while(n != 1):
print("%5i: %5i" % (iteration,n))
if(n % 2 == 0): #divide by 2 if even
n=n/2
else: #if it is odd, multiply by 3 and add 1
n=3*n+1
iteration = iteration + 1
if(n>npeak): #record the higher n and its iteration
npeak = n
iterationmax = iteration
It works. But there is a problem: if the entered number is big enough, for example 6666666666666666666666666, then it does something really strange. This is what I get:
Give me a positive integer: 6666666666666666666666666
Thank you.
Now loading:
1: 6666666666666666666666666
2: 3333333333333333277409280
3: 1666666666666666638704640
4: 833333333333333319352320
5: 416666666666666659676160
6: 208333333333333329838080
7: 104166666666666664919040
8: 52083333333333332459520
9: 26041666666666666229760
10: 13020833333333333114880
etc
As you can see, I am expecting the second number to be exactly 3333333333333333333333333, but instead I am getting different numbers at the end.
As another example, entering 1000000000000000000000000 returns 499999999999999991611392 in the second iteration.
What could be the reason for this?
The reason of why what #ruohola said is true, is because when you use floating-point division with a single /, what happens is that a floating-point number is created. However, it cannot be represented as the number is so large, so it is rounded to the closest most accurate representation. So you will have to use // instead of /.
However, using //, is integer division. This results in an integer which can be represented much easier than a high float.
A very similar question can be found here, it contains some more explanation.
Change your / operation to be //, so that they don't result in (inaccurate) floating point values.
So this:
if(n % 2 == 0): #divide by 2 if even
n=n/2
Should be:
if(n % 2 == 0): #divide by 2 if even
n=n//2
Or as properly formatted by Python conventions:
if n % 2 == 0:
n //= 2

Why am I not getting an output for the following python code?

I am not getting any output from interpreter after I input a value.
Here's my code:
number = int(input("Enter the number to test:"))
count = 0
if number % 2 == 0:
while number > 1:
number /= 2
count += 1
else:
while number > 1:
number = (3 * number) + 1
count += 1
print("Iteration count: " + count)
Expected output is 15 for input = 11
Edit: The Collatz Conjecture (above) use the following algorithm: If n is even, divide it by 2, else multiply by 3 and add 1. Start over until you get 1.
You have created an infinite loop in your while statements. A good way you can check this yourself is to print number inside the while loop, and you will quickly see where you are going wrong.
I don't want to give away the solution as this sounds too much like homework - but you must ensure your while loop condition is met, or it will never exit.

Categories

Resources