credit-card-validator.py

'''
@author : Alicia Sykes <https://aliciasykes.com>
@date   : 22 Oct 2012
'''

#Remove Bad Characters
def validate(cardNumber):
    validCardNumber = ""
    for number in cardNumber:
        if (ord(number)>=48 and ord(number)<=57): validCardNumber += str(number)    
    if not cardNumber or not validCardNumber: validCardNumber="00"       
    return validCardNumber

#Calculate sum of digits for validation
def calculateSum(cardNumber):
    sum = 0; 
    for each in ((cardNumber)): sum+=int(each)
    return sum


#Check the Card Numbers Length and Composition
def checkFormat(cardNumber):
    if (calculateSum(cardNumber) == 0 or len(cardNumber)<4 or not cardNumber): return False
    else: return True


#Check the Card Numbers Check Sum and Calculate Check Bit
def checkNumber(cardNumber):
    def calculateSum(cardNumber):
        sum1 = sum3 = 0; sum2 = ""
        for each in ((cardNumber[-1::-2])): sum1+=int(each)
        for each in ((cardNumber[-2::-2])): sum2+=str((int(each)*2))
        for each in (sum2): sum3+=int(each)
        return str(sum1+sum3)
    cd = int(calculateSum(str(int(str(cardNumber)[:-1])*10)))%10
    global checkDigit; checkDigit = cd if cd == 0 else 10 - cd
    return True if checkFormat(cardNumber) == True and calculateSum(cardNumber)[-1] == '0' else False


#Determine why the card number is not correct
def getReason(cardNumber):
    reason = ""
    if(calculateSum(cardNumber) == 0 or not cardNumber): 
        reason="a blank Card Number %s was Inputed"%cardNumber
    elif(len(cardNumber) < 4): 
        reason="the card number is too short (%s digits)"%len(cardNumber)  
    elif(cardNumber[-1]!=checkDigit): 
        reason="The last digit, or check digit should have been %s"%checkDigit            
    return reason


#Declare Variables
cardNumber = validate(input("Enter a Card Number\t"))
valid = False
reason = ""

#Determine Whether Number is Correct and get a Reason
valid = checkNumber(cardNumber)
if valid == False: reason = getReason(cardNumber)

#Output Result to User
outputStatement = "The card number %s is %s"
outputStatement += "%s" if reason == "" else " because %s" 
print(outputStatement%(cardNumber, "Valid" if valid == True else "Invalid",reason))