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))