ISBN final digit finder - python

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)

Related

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

Write a program that accepts a positive integer from the user and prints the first four multiples of that integer. Use a while loop

I am trying to write as the question is stated, Write a program that accepts a positive integer from the user and print the first four multiples of that integer; Use while loop (Python)
total = 0
number = int(input("Enter integer: "))
while number <= 15:
total = total + number
print(number)
SAMPLE
Enter integer: 5
0
5
10
15
this is the example my professor wanted
This is what i have so far, but i'm a bit lost...
You should loop over a counter variable instead of a hard coded limit
counter = 1
while counter <= 4:
counter += 1
total = total + number
print(number)
The loop condition should be set on total, not number, and total should be incremented by 1, not number (assuming total is used as a loop counter):
total = 0
number = int(input("Enter integer: "))
while total <= 3:
print(total * number)
total = total + 1
Sample:
Enter integer: 5
0
5
10
15
A normal while loop that counts upto 4:
count, total = 0, 0
number = int(input("Enter integer: "))
while count < 4:
print(total)
total = total + number
count += 1
Python for loop is more pythonic than while:
number = int(input("Enter integer: "))
for i in range(4):
print(number * i)
Although you have the right idea from the example there's still a couple of things the sample is missing.
1. You don't check whether the input is positive or not
2. The while loop is dependent on knowing the input
Try the following:
# Get Input and check if it's positive
number = int(input('Enter positive integer: '))
if number <= 0:
number = int(input('Not positive integer, enter positive integer: '))
# This increments i by one each time it goes through it, until it reaches 5
i=1
while i < 5:
new_number = number*i
i = i + 1
print(new_number)
Note: This does not take into account if the input is a letter or string. If so, it'll throw an error.

Only the last item is being appended to a list in a while loop (Python)

I'm trying to create a program that gets each digit of an inputted number into a list using a while loop. However, it only appends the last digit of the number to the list.
Code -
num = int(input("Enter a number: "))
numstr = str(num)
numlen = len(numstr)
x = 0
while x < numlen:
digits = []
a = numstr[x]
digits.append(a)
x = x + 1
print(digits)
So if I were to put in 372 as the number, the list would just simply be ['2'] with a length of 1.
Try this code:
digits = [i for i in str(num)]
You cannot do better than digits = list(str(num)). In fact, since input returns a string, even the conversion to a number is not necessary:
num = input("Enter a number: ")
digits = list(num)
(You still may want to ensure that what's typed is indeed a number, not a random string.)

How to multiply every other list item by 2 in python

I'm making a program that validates a credit card, by multiplying every other number in the card number by 2; after i'll add the digits multiplied by 2 to the ones not multiplied by 2. All of the double digit numbers are added by the sum of their digits, so 14 becomes 1+4. I have a photo below that explains it all. I'm making a python program that does all of the steps. I've done some code below for it, but I have no idea what to do next? Please help, and it would be greatly appreciated. The code I have returns an error anyway.
class Validator():
def __init__(self):
count = 1
self.card_li = []
while count <= 16:
try:
self.card = int(input("Enter number "+str(count)+" of your card number: "))
self.card_li.append(self.card)
#print(self.card_li)
if len(str(self.card)) > 1:
print("Only enter one number!")
count -= 1
except ValueError:
count -= 1
count += 1
self.validate()
def validate(self):
self.card_li.reverse()
#print(self.card_li)
count = 16
while count >= 16:
self.card_li[count] = self.card_li[count] * 2
count += 2
Validator()
To perform that sum:
>>> s = '4417123456789113'
>>> sum(int(c) for c in ''.join(str(int(x)*(2-i%2)) for i, x in enumerate(s)))
70
How it works
The code consists of two parts. The first part creates a string with every other number doubled:
>>> ''.join(str(int(x)*(2-i%2)) for i, x in enumerate(s))
'8427226410614818123'
For each character x in string s, this converts the character to integer, int(x) and multiplies it by either 1 or 2 depending on whether the index, i, is even or odd: (2-i%2). The resulting product is converted back to a string: str(int(x)*(2-i%2)). All the strings are then joined together.
The second part sums each digit in the string:
>>> sum(int(c) for c in '8427226410614818123')
70
You need to increment the count inside the while() loop. Also, append the user input to your card_li list after you have the if.. check. Your init method should look like:
def __init__(self):
count = 1
self.card_li = []
while count <= 16:
try:
self.card = int(input("Enter number "+str(count)+" of your card number: "))
if len(str(self.card)) > 1:
print("Only enter one number!")
self.card_li.append(self.card)
count += 1
except ValueError:
pass
self.validate()
As for your validate method, it doesn't seem complete even according to the logic you have written.

Using loops in python to configure credit card number

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.

Categories

Resources