5
\$\begingroup\$

I'm new to using python and wanted to know how I could improve my program. I'm using the Luhn algorithm, the beginning numbers of the credit cards, and the number of digits in the credit card.

from cs50 import get_string
import re
import sys

number = get_string("NUMBER: ")
check = []

if (len(number)) not in (13,15,16):
    print("INVALID")
    print(len(number))
    sys.exit(1)

for i in range(len(number)): # for the length of the string,
    if i%2 == (-2+len(number))%2: # if a counter is modulo 1
        digits = str(int(number[i])*2) #obtains the value of the multiplication
        for j in range(len(digits)):
            check.append(int(digits[j]))
    else:
        check.append(int(number[i]))

total = str(sum(check))


if re.search("0$", total):
    if re.search("^3(4|7)", number):
        print("AMEX")
    elif number[0] == str(4):
        print("VISA")
    elif re.search("^5(1|2|3|4|5)", number):
        print("MASTERCARD")
else:
    print("INVALID")

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Your program would benefit from breaking up logic into functions. This also eliminates the global variables involved.

if i%2 == (-2+len(number))%2

This line is strange and not immediately obvious what it's doing. A reversed iteration would be easier to understand.

import re

def luhn_digit(digit,double):
    if double:
        doubled = digit*2
        return doubled-9 if doubled>9 else doubled
    else:
        return digit

def is_valid_luhn(card):
    check_digit = int(card[-1])
    luhn_sum = sum([
        luhn_digit(int(digit),i%2==0)
        for i,digit in enumerate(reversed(card[:-1]))
    ])
    total = check_digit+luhn_sum
    return total%10==0

def is_valid_card(card):
    return (
        len(card) in (13,15,16) and
        is_valid_luhn(card)
    )

def get_card_type(card):
    if not is_valid_card(card):
        return "INVALID"
    if re.search("^3(4|7)", card):
        return "AMEX"
    if card[0] == str(4):
        return "VISA"
    if re.search("^5(1|2|3|4|5)", card):
        return "MASTERCARD"
    return "INVALID"

print(get_card_type(input("NUMBER: ")))
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.