Source

play-problems / problema09.py

Full commit
def run():

    table = {
        13: (
                {'prefix': '4', 'type': 'visa', 'check': True},
            ),
        14: (
                {'prefix': '300-305', 'type': 'dinners/carte', 'check': True},
                {'prefix': '36', 'type': 'dinners/carte', 'check': True},
                {'prefix': '38', 'type': 'dinners/carte', 'check': True},
            ),
        15: (
                {'prefix': '34', 'type': 'amex', 'check': True},
                {'prefix': '37', 'type': 'amex', 'check': True},
                {'prefix': '2014', 'type': 'enroute', 'check': False},
                {'prefix': '2149', 'type': 'enroute', 'check': False},
                {'prefix': '2131', 'type': 'jcb', 'check': True},
                {'prefix': '1800', 'type': 'jcb', 'check': True},
            ),
        16:  (
                {'prefix': '51-55', 'type': 'mastercard', 'check': True},
                {'prefix': '4', 'type': 'visa', 'check': True},
                {'prefix': '6011', 'type': 'discover', 'check': True},
                {'prefix': '3', 'type': 'jcb', 'check': True},
            ),
    }

    def check_table(number):

        data = table.get(len(number))

        if data:

            for x in data:

                prefix = x.get('prefix')
                type = x.get('type')
                check = x.get('check')

                if '-' in prefix:

                    prefixs = prefix.split('-')
                    prefixs = [str(x) for x in \
                        range(int(prefixs[0]), int(prefixs[1]) + 1)]

                    for p in prefixs:

                        size = len(p)

                        if number[:size] == p:

                            if check:

                                if check_primary_account(number[size:]):
                                    return type
                else:

                    size = len(prefix)

                    if number[:size] == prefix:

                        if check:

                            if check_primary_account(number[size:]):
                                return type

        return None

    def check_primary_account(number):

        n = len(number) - 1
        i = 0
        tot = 0
        flat = False

        while 0 <= n:

            digit = int(number[n])

            # if i % 2 == 1
            if flat:
                flat = False
                tot += sum([int(x) for x in str(digit * 2)])
            else:
                flat = True
                tot += digit

            n -= 1
            i += 1

        return True if tot % 10 == 0 else False

    input = open('tarjetas.txt', 'r')
    input = input.read().split('\n')[:-1]

    #number = '30249927398716' dinners
    #print check_table(number)

    for number in input:

        type = check_table(number)

        if type:
            print 'card number %s: %s is valid' % (type, number)
        else:
            print 'card number: %s is not valid' % number

if __name__ == '__main__':

    run()