Hi,

I wrote this sample code to check the integrity of an IBAN (International Bank Account Number) bank account number.
(See Wikipedia for further information)
Any advice to simplify this?

#
# IBAN_Check.py
# Utility to check the integrity of an IBAN bank account No.
# Python 2.5.1

# Sample IBAN account numbers.
#-----------------------------
# BE31435411161155
# CH5108686001256515001
# GB35MIDL40253432144670


# Dictionaries - Refer to ISO 7064 mod 97-10 
letter_dic={"A":10, "B":11, "C":12, "D":13, "E":14, "F":15, "G":16, "H":17, "I":18, "J":19, "K":20, "L":21, "M":22,
            "N":23, "O":24, "P":25, "Q":26, "R":27, "S":28, "T":29, "U":30, "V":31, "W":32, "X":33, "Y":34, "Z":35}

# ISO 3166-1 alpha-2 country code
country_dic={"AL":[28,"Albania"],
             "AD":[24,"Andorra"],
             "AT":[20,"Austria"],
             "BE":[16,"Belgium"],
             "BA":[20,"Bosnia"],
             "BG":[22,"Bulgaria"],
             "HR":[21,"Croatia"],
             "CY":[28,"Cyprus"],
             "CZ":[24,"Czech Republic"],
             "DK":[18,"Denmark"],
             "EE":[20,"Estonia"],
             "FO":[18,"Faroe Islands"],
             "FI":[18,"Finland"],
             "FR":[27,"France"],
             "DE":[22,"Germany"],
             "GI":[23,"Gibraltar"],
             "GR":[27,"Greece"],
             "GL":[18,"Greenland"],
             "HU":[28,"Hungary"],
             "IS":[26,"Iceland"],
             "IE":[22,"Ireland"],
             "IL":[23,"Israel"],
             "IT":[27,"Italy"],
             "LV":[21,"Latvia"],
             "LI":[21,"Liechtenstein"],
             "LT":[20,"Lithuania"],
             "LU":[20,"Luxembourg"],
             "MK":[19,"Macedonia"],
             "MT":[31,"Malta"],
             "MU":[30,"Mauritius"],
             "MC":[27,"Monaco"],
             "ME":[22,"Montenegro"],
             "NL":[18,"Netherlands"],
             "NO":[15,"Northern Ireland"],
             "PO":[28,"Poland"],
             "PT":[25,"Portugal"],
             "RO":[24,"Romania"],
             "SM":[27,"San Marino"],
             "SA":[24,"Saudi Arabia"],
             "RS":[22,"Serbia"],
             "SK":[24,"Slovakia"],
             "SI":[19,"Slovenia"],
             "ES":[24,"Spain"],
             "SE":[24,"Sweden"],
             "CH":[21,"Switzerland"],
             "TR":[26,"Turkey"],
             "TN":[24,"Tunisia"],
             "GB":[22,"United Kingdom"]}

def check(n):
    if int(n)%97 !=1:
        result=0                                                # False
    else:
        result=1                                                # True
    return result

while True:
    # IBAN = (raw_input("Enter account No. : ")).upper()          # Input account No.
    IBAN = "GB35MIDL40253432144670"                             # Sample UK IBAN
    length = len(IBAN)
    country = IBAN[:2]
    if country_dic.has_key(country):
        data = country_dic[country]
        length_c = data[0]
        name_c = data[1]
        if length == length_c:
            print name_c,"/ IBAN length",length_c,"OK!"
            header = IBAN[:4]                                   # Get the first four characters
            body = IBAN[4:]                                     # And the remaining characters
            IBAN = body+header                                  # Move the first block at the end
            IBAN_ = list(IBAN)                                  # Transform string into a list
            string_="" 
            for index in range(len(IBAN_)):                     # Convert letters to integers
                if letter_dic.has_key(IBAN_[index]):
                    value = letter_dic[IBAN_[index]]
                    IBAN_[index] = value
            for index in range(len(IBAN_)):                     # Transform list into a string
                string_ = string_ + str(IBAN_[index])
            valid = check(string_)                              # Check validity
            if not valid:
                print "Not a valid IBAN account No."
            else:
                print "IBAN account No. accepted."              # Rebuild the original IBAN
                trailer = IBAN[len(IBAN)-4:]                    # Get the four last characters
                body = IBAN[:len(IBAN)-4]                       # And the remaining characters
                IBAN = trailer+body                             # Move the trailer at the begin
                print "Exit loop ..."
                break
        else:
            print name_c,"/ Wrong IBAN code length!"
    else:
        print "Wrong IBAN country code!"

print "IBAN account No. :",IBAN
# Display a formated account No. (Thanks to Griboullis)
split_IBAN = lambda block,string:[string[f:f+block] for f in range(0,len(string),block)]
BankAccountNo = split_IBAN(4,IBAN)
print "Formated bank account No :",
for block in BankAccountNo:
    print block,
print

I guess it depends on what you mean by simplify. If you mean fewer lines of code, then yeah there are ways to simplify it.

If you mean make the code more readable so that the next person who has to maintain your code will be able to, then probably not. The code you've written is easy to follow, well commented, and doesn't make use of any obscure libraries or tricks. Your variable names make sense and the whole thing is easy on my eyes. Personally, I would be proud of this code. You might be able to shave a few microseconds here or there by doing something, but if it comes at the expense of readability then it isn't worth it.

I guess it depends on what you mean by simplify. If you mean fewer lines of code, then yeah there are ways to simplify it.

If you mean make the code more readable so that the next person who has to maintain your code will be able to, then probably not. The code you've written is easy to follow, well commented, and doesn't make use of any obscure libraries or tricks. Your variable names make sense and the whole thing is easy on my eyes. Personally, I would be proud of this code. You might be able to shave a few microseconds here or there by doing something, but if it comes at the expense of readability then it isn't worth it.

Here here!

That said, I would suggest you use if x in dict.keys() rather than if dict.has_key() since the latter is deprecated in later versions of python (it's never too early to start preparing yourself for the switch, even if you don't intend to anytime soon). Besides, it's slightly closer to what you would actually say in English, which makes it slightly easier to follow. Slightly.

I have no experience on IBAN parse, but i think all your core algorithms is to "Check validity".

I add all element into dictionary to avoid checking exist of a key.

Maybe we can assign all value to str later.

My poor English....

#
# IBAN_Check.py
# Utility to check the integrity of an IBAN bank account No.
# Python 2.5.1

# Sample IBAN account numbers.
#-----------------------------
# BE31435411161155
# CH5108686001256515001
# GB35MIDL40253432144670


# Dictionaries - Refer to ISO 7064 mod 97-10 
letter_dic={"A":10, "B":11, "C":12, "D":13, "E":14, "F":15, "G":16, "H":17, "I":18, "J":19, "K":20, "L":21, "M":22,
            "N":23, "O":24, "P":25, "Q":26, "R":27, "S":28, "T":29, "U":30, "V":31, "W":32, "X":33, "Y":34, "Z":35,
            "0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9}

# ISO 3166-1 alpha-2 country code
country_dic={"AL":[28,"Albania"],
             "AD":[24,"Andorra"],
             "AT":[20,"Austria"],
             "BE":[16,"Belgium"],
             "BA":[20,"Bosnia"],
             "BG":[22,"Bulgaria"],
             "HR":[21,"Croatia"],
             "CY":[28,"Cyprus"],
             "CZ":[24,"Czech Republic"],
             "DK":[18,"Denmark"],
             "EE":[20,"Estonia"],
             "FO":[18,"Faroe Islands"],
             "FI":[18,"Finland"],
             "FR":[27,"France"],
             "DE":[22,"Germany"],
             "GI":[23,"Gibraltar"],
             "GR":[27,"Greece"],
             "GL":[18,"Greenland"],
             "HU":[28,"Hungary"],
             "IS":[26,"Iceland"],
             "IE":[22,"Ireland"],
             "IL":[23,"Israel"],
             "IT":[27,"Italy"],
             "LV":[21,"Latvia"],
             "LI":[21,"Liechtenstein"],
             "LT":[20,"Lithuania"],
             "LU":[20,"Luxembourg"],
             "MK":[19,"Macedonia"],
             "MT":[31,"Malta"],
             "MU":[30,"Mauritius"],
             "MC":[27,"Monaco"],
             "ME":[22,"Montenegro"],
             "NL":[18,"Netherlands"],
             "NO":[15,"Northern Ireland"],
             "PO":[28,"Poland"],
             "PT":[25,"Portugal"],
             "RO":[24,"Romania"],
             "SM":[27,"San Marino"],
             "SA":[24,"Saudi Arabia"],
             "RS":[22,"Serbia"],
             "SK":[24,"Slovakia"],
             "SI":[19,"Slovenia"],
             "ES":[24,"Spain"],
             "SE":[24,"Sweden"],
             "CH":[21,"Switzerland"],
             "TR":[26,"Turkey"],
             "TN":[24,"Tunisia"],
             "GB":[22,"United Kingdom"]}

def check(n):
    if int(n)%97 !=1:
        result=0                                                # False
    else:
        result=1                                                # True
    return result

while True:
    # IBAN = (raw_input("Enter account No. : ")).upper()          # Input account No.
    IBAN = "GB35MIDL40253432144670"                             # Sample UK IBAN
    print "original:",
    print IBAN
    length = len(IBAN)
    country = IBAN[:2]
    if country_dic.has_key(country):
        data = country_dic[country]
        length_c = data[0]
        name_c = data[1]
        if length == length_c:
            print name_c,"/ IBAN length",length_c,"OK!"
            header = IBAN[:4]                                   # Get the first four characters
            body = IBAN[4:]                                     # And the remaining characters
            IBAN = body+header                                  # Move the first block at the end
            IBAN_ = list(IBAN)                                  # Transform string into a list
            print "C1:", IBAN
            string_="" 
#            for index in range(len(IBAN_)):                     # Convert letters to integers
#                if letter_dic.has_key(IBAN_[index]):
#                    value = letter_dic[IBAN_[index]]
#                    print IBAN_[index], 
#                    IBAN_[index] = value
#                    print value
#            for index in range(len(IBAN_)):                     # Transform list into a string
#                string_ = string_ + str(IBAN_[index])
            string_="".join(map(lambda x: str(letter_dic[x]), IBAN_))
            print string_
            valid = check(string_)                              # Check validity
            if not valid:
                print "Not a valid IBAN account No."
            else:
                print "IBAN account No. accepted."              # Rebuild the original IBAN
                trailer = IBAN[len(IBAN)-4:]                    # Get the four last characters
                body = IBAN[:len(IBAN)-4]                       # And the remaining characters
                IBAN = trailer+body                             # Move the trailer at the begin
                print "Exit loop ..."
                break
        else:
            print name_c,"/ Wrong IBAN code length!"
    else:
        print "Wrong IBAN country code!"

print "IBAN account No. :",IBAN
# Display a formated account No. (Thanks to Griboullis)
split_IBAN = lambda block,string:[string[f:f+block] for f in range(0,len(string),block)]
BankAccountNo = split_IBAN(4,IBAN)
print "Formated bank account No :",
for block in BankAccountNo:
    print block,
print

Edited 7 Years Ago by orinbai: n/a

This question has already been answered. Start a new discussion instead.