HomePage RecentChanges

Lesson08

Primeiro projecto 2014/15

Vejamos a implementação proposta para o primeiro projecto de Fundamentos de Programação em 2014/15.

import random



# -- CONSTANTES -- #

# Define-se um conjunto de tuplos com a informacao referente a cada rede
# emissora. Cada tuplo tem a seguinte constituicao:
#
#  . Elemento 1: Rede emissora
#  . Elemento 2: Numero de digitos
#  . Elementos 3, ..., n: Digitos iniciais do IIN

AE  = ('American Express',          'AE', (15,) ,   '34',   '37')
DCI = ('Diners Club International', 'DCI',(14,),    '309',  '36',   '38',   '39')
DC  = ('Discovery Card',            'DC', (16,),    '65')
M   = ('Maestro',                   'M',  (13, 19), '5018', '5020', '5038')
MC  = ('Master Card',               'MC', (16,),    '19',   '50',   '51',   '52', '53', '54')
VE  = ('Visa Electron',             'VE', (16,),    '4026', '426',  '4405', '4508')
V   = ('Visa',                      'V',  (13, 16), '4024', '4532', '4556')

# Define-se ainda um tuplo com todas as redes emissoras

REDES = (AE, DCI, DC, M, MC, VE, V) 



# = = = = = = = = = = = = = = = = = = = = = = = = = #
#                                                   #
# = = =  F U N C O E S   A U X I L I A R E S  = = = #
#                                                   #
# = = = = = = = = = = = = = = = = = = = = = = = = = #


def calc_soma(cad):
    ''' calc_soma : str -> int
        calc_soma(s) calcula a soma dos digitos que compoem a string s, 
        ponderados de acordo com o algoritmo de Luhn.'''
    
    soma = 0
    
    for i in range(1, len(cad)+1):
        k = eval(cad[-i])

        if i % 2 != 0 and k != 0:
            k = (2 * k - 1) % 9 + 1 
            
        soma = soma + k
        
    return soma

# -- Fim: calc_soma -- #


def luhn_verifica(cad):
    ''' luhn_verifica : str -> logico
        luhn_verifica(s) devolve True caso s corresponda a uma cadeia de 
        caracteres que verifica o algoritmo de Luhn e False em caso 
        contrario.'''
        
    return (calc_soma(cad[:-1]) + eval(cad[-1])) % 10 == 0

# -- Fim: luhn_verifica -- #


def comeca_por(cad1, cad2):
    ''' comeca_por : str x str -> logico
        comeca_por(s1, s2) devolve True caso a string s1 comece pela string 
        s2 e False em caso contrario.'''
    
    l = len(cad2)
    
    return cad1[:l] == cad2

# -- Fim: comeca_por -- #


def comeca_por_um(cad, tuplo_cads):
    ''' comeca_por_um : str x tuplo -> logico
        comeca_por_um(s, t) devolve True caso a cadeia de caracteres s 
        comece por alguma das cadeias de caracteres no tuplo t.'''
    
    for s in tuplo_cads:
        if comeca_por(cad, s):
            return True
        
    return False

# -- Fim: comeca_por_um -- #


def valida_iin(cad):
    ''' valida_iin : str -> str
        valida_iin(s) devolve uma cadeia de caracteres correspondente 'a
        rede emissora cujos digitos sao dados por s.'''

    
    for rede in REDES:
        if len(cad) in rede[2] and comeca_por_um(cad, rede[3:]):
            return rede[0]
        
    return ''

# -- Fim: valida_iin -- #


def categoria(cad):
    ''' categoria : str -> str
        categoria(s) devolve a categoria correspondente ao prefixo s.'''
    
    CATEGORIAS = ('Companhias aereas', 
                  'Companhias aereas', 
                  'Viagens e entretenimento e bancario', 
                  'Servicos bancarios e financeiros', 
                  'Servicos bancarios e financeiros',
                  'Merchandising e bancario',
                  'Petroleo', 
                  'Saude e telecomunicacoes',
                  'Atribuicao nacional')
    
    mii = eval(cad[0])
    
    if mii == 0:
        raise ValueError ('categoria: categoria invalida')
    else:
        return CATEGORIAS[mii - 1]
    
# -- Fim: categoria -- #
    
    
def digito_verificacao(cad):
    ''' digito_verificacao : str -> str
        digito_verificacao(s) devolve o digito de verificacao a acrescentar
        a s por forma a que o numero obtido apos justapor o digito calculado
        a s seja um numero de cartao valido (i.e., que obedece ao algoritmo
        de Luhn.'''
    
    return str(10 - (calc_soma(cad) % 10))

# -- Fim: digito_verificacao -- #


def selecciona_elemento(t):
    ''' selecciona_elemento : tuplo -> universal
        selecciona_elemento(t) devolve um elemento de t seleccionado 
        aleatoriamente.'''
    
    i = int(len(t) * random.random())
    
    return t[i]

# -- Fim: selecciona_elemento -- #


def gera_digitos(n):
    ''' gera_digitos : int -> str
        gera_digitos(n) gera um conjunto aleatorio de n digitos na forma de
        string.'''
    
    s = ''
    
    for i in range(n):
        s = s + selecciona_elemento('0123456789')
        
    return s

# -- Fim: gera_digitos -- #

    

# = = = = = = = = = = = = = = = = = = = = = = = = = #
#                                                   #
# = = =  F U N C O E S   P R I N C I P A I S  = = = #
#                                                   #
# = = = = = = = = = = = = = = = = = = = = = = = = = #


def verifica_cc(cc):
    ''' verifica_cc : int -> tuplo
        verifica_cc(s) devolve um tuplo contendo a entidade emissora e 
        categoria correspondente ao numero de cc s.'''
    
    cad = str(cc)
    
    emissor = valida_iin(cad)
    categ   = categoria(cad)
    
    if emissor == '' or not luhn_verifica(cad):
        return 'cartao invalido'
    else:
        return categ, emissor
    
# -- Fim: verifica_cc -- #


def gera_num_cc(rede):
    ''' gera_num_cc : str -> int
        gera_num_cc(s) devolve um numero de cartao de credito gerado pela
        rede s.'''
    
    n_digitos = 0
    inicio    = ''
    
    for r in REDES:
        if rede == r[1]:
            n_digitos = selecciona_elemento(r[2])
            inicio = selecciona_elemento(r[3:])
        
    if n_digitos == 0:
        raise ValueError ('gera_num_cc: rede invalida')
    
    cc = inicio + gera_digitos(n_digitos - len(inicio) - 1)
    
    return cc + digito_verificacao(cc)

# -- Fim: gera_num_cc -- #
    


# = = = = = = = = = = = = = = = = = = = = = = = = = #
#                                                   #
# = = =  E X E M P L O S   E N U N C I A D O  = = = #
#                                                   #
# = = = = = = = = = = = = = = = = = = = = = = = = = #

# -- calc_soma -- #

#print('>>> calc_soma("3248")')
#print(calc_soma("3248"))


# -- luhn_verifica -- #

#print('>>> luhn_verifica("4556245018079")')
#print(luhn_verifica("4556245018079"))
#
#print('>>> luhn_verifica("4556245018072")')
#print(luhn_verifica("4556245018072"))


# -- comeca_por -- #

#print('>>> comeca_por("12345678", "123")')
#print(comeca_por("12345678", "123"))
#
#print('>>> comeca_por("12345678", "23")')
#print(comeca_por("12345678", "23"))
#
#print('>>> comeca_por("123", "12345678")')
#print(comeca_por("123", "12345678"))


# -- comeca_por_um -- #

#print('>>> comeca_por_um("36238462919584", ("309", "36", "38", "39")')
#print(comeca_por_um("36238462919584", ("309", "36", "38", "39")))
#
#print('>>> comeca_por_um("36238462919584", ("34", "37"))')
#print(comeca_por_um("36238462919584", ("34", "37")))


# -- valida_iin -- #

#print('>>> valida_iin("4508654345231273")')
#print(valida_iin("4508654345231273"))

#print('>>> valida_iin("45086")')
#print(valida_iin("45086"))


# -- categoria -- #

#print('>>> categoria("193")')
#print(categoria("193"))
#
#print('>>> categoria("1")')
#print(categoria("1"))


# -- verifica_cc -- #

#print('>>> verifica_cc(38153682601755)')
#print(verifica_cc(38153682601755))

#print('>>> verifica_cc(4532728243332223)')
#print(verifica_cc(4532728243332223))
#
#print('>>> verifica_cc(4556223160581)')
#print(verifica_cc(4556223160581))
#
#print('>>> verifica_cc(5485060128076517)')
#print(verifica_cc(5485060128076517))
#
#print('>>> verifica_cc(6554615813812884)')
#print(verifica_cc(6554615813812884))


# -- digito_verificacao -- #

#print('>>> digito_verificacao("30229065652764")')
#print(digito_verificacao("30229065652764"))


# -- gera_num_cc -- #

#print('>>> gera_num_cc("MC")')
#cc = gera_num_cc("MC")
#print('Numero gerado:', cc)
#print('Validacao:', verifica_cc(cc))

#print('>>> gera_num_cc("DC")')
#cc = gera_num_cc("DC")
#print('Numero gerado:', cc)
#print('Validacao:', verifica_cc(cc))

#print('>>> gera_num_cc("V")')
#cc = gera_num_cc("V")
#print('Numero gerado:', cc)
#print('Validacao:', verifica_cc(cc))

#print('>>> gera_num_cc("V")')
#cc = gera_num_cc("V")
#print('Numero gerado:', cc)
#print('Validacao:', verifica_cc(cc))