associação pythonbrasil[11] django zope/plone planet Início Logado como (Entrar)

Revisão 13e 2004-03-09 20:28:33

Excluir mensagem

GeradorDeCpf

Receita: Gerador de CPF

Programa para gerar números de CPF aleatoriamente. Escrito por ralobao ( Kandalf ) e com alterações de FelipeLessa.

Código

   1 #!/usr/bin/env python
   2 import random
   3 import math
   4 
   5 # Mude para True para incluir debug
   6 DEBUG = False
   7 
   8 def debug(*string):
   9     """ Imprime para stderr (simples). """
  10 
  11     # Eu sei que imports dentro de funcoes eh feio, 
  12     # mas eh para tirar a carga do import no caso de eu nao querer debug
  13     import sys
  14 
  15     print >> sys.stderr, string
  16 
  17 def gera_random():
  18     """ Funcao para gerar um inteiro aleatório entre 0 e n """
  19     return random.randint(0, 9)
  20 
  21 def mod(dividendo,divisor):
  22     """ Funcao pra retornar o resto da divisao de dois numeros """
  23     x = dividendo - (math.floor(dividendo/divisor)*divisor)
  24     return round(x)
  25 
  26 
  27 
  28 def cpf():
  29     """ Funcao pra gerar o bendito cpf """
  30 
  31     # Gera os numeros randonomicos ;)
  32     n1 = gera_random()
  33     n2 = gera_random()
  34     n3 = gera_random()
  35     n4 = gera_random()
  36     n5 = gera_random()
  37     n6 = gera_random()
  38     n7 = gera_random()
  39     n8 = gera_random()
  40     n9 = gera_random()
  41 
  42     # debugger purposes ;)
  43     DEBUG and debug(n1, n2, n3, n4, n5, n6, n7, n8, n9)
  44 
  45     # Contas e mais contas, dividi pra fica mais bonitinho
  46     a1 = n9 * 2
  47     a2 = n8 * 3
  48     a3 = n7 * 4
  49     a4 = n6 * 5
  50     a5 = n5 * 6
  51     a6 = n4 * 7
  52     a7 = n3 * 8
  53     a8 = n2 * 9
  54     a9 = n1 * 10
  55 
  56     # Soma os resultados de todas as contas anteriores e faz 
  57     # outra continha.. tudo regra do cpf, para ele ser valido :P
  58     d1 = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9
  59     d1 = 11 - (mod(d1,11))
  60 
  61     # Caso d1 seja maior que 10, o que não pode, ele deve ser igualado a 0
  62     if d1 >= 10:
  63         d1 = 0
  64 
  65     # debugger purposes
  66     DEBUG and debug(a1, a2, a3, a4, a5, a6, a7, a8, a9, d1)
  67 
  68     # Mesma coisa da de cima so que agora pra variavel d2
  69     a1 = d1 * 2
  70     a2 = n9 * 3
  71     a3 = n8 * 4
  72     a4 = n7 * 5
  73     a5 = n6 * 6
  74     a6 = n5 * 7
  75     a7 = n4 * 8
  76     a8 = n3 * 9
  77     a9 = n2 * 10
  78     a10 = n1 * 11
  79 
  80     # ... rola a barra de rolagem pra cima que tu vai entender :P
  81     d2 = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10
  82     d2 = 11 - (mod(d2,11))
  83 
  84     # chega de repeticao de codigo :)
  85     if d2 >= 10:
  86         d2 = 0
  87 
  88     # debugger purposes
  89     DEBUG and debug(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, d2)
  90 
  91 
  92     # o esperado print final ... que maravilha
  93     return "%d%d%d.%d%d%d.%d%d%d-%d%d" % (n1, n2, n3,  n4, n5, n6,  n7, n8, n9,  d1, d2)
  94 
  95 
  96 
  97 if __name__ == '__main__':
  98     # Temos os holofotes em nós, somos a atração principal!
  99 
 100     message = "Bem-vindo ao Gerador de CPFs"
 101     print '\t%s\n' % message, '\t%s\n' % ('=' * len(message))
 102 
 103     user_response = raw_input('Ativar debug (responda "sim", "yes", "1" ou "true" para ativar)? ')
 104     if user_response.lower().strip() in ("sim", "yes", "1", "true"):
 105         DEBUG = True
 106 
 107     try:
 108         for i in xrange(int(raw_input('Quantos CPFs aleatórios devem ser gerados? '))):
 109             print cpf()
 110             if DEBUG:
 111                 # Deixa o visual mais limpo
 112                 print
 113     except ValueError, x:
 114         print 'Valor inválido ("%s")' % x

Legal! Achei um jeito de treinar o uso de programação funcional em Python :) O código abaixo faz o mesmo que o acima, só que é menos legível/entendível/didático que o feito pelo Ruivaldo e pelo Lessa. Eu fiz ele porque precisava de um exemplo prático de onde é útil usar programação as funções map/reduce/filter/zip. Pra quem tiver interesse nessas funções eu recomendo uma olhada no PythonFuncional. -- OsvaldoSantanaNeto

   1 def cpf_funcional():
   2                                                                                                     
   3     n = []
   4     for i in xrange(9):
   5         n.append(random.randint(0, 9))
   6                                                                                                     
   7     # calcula digito 1 e acrescenta ao numero
   8     s = reduce(lambda x, y: x + y, map(lambda x, y: x * y, n, range(10, 1, -1)))
   9     d1 = 11 - s % 11
  10     if d1 >= 10:
  11         d1 = 0
  12     n.append(d1)
  13                                                                                                     
  14     # calcula digito 2 e acrescenta ao numero
  15     s = reduce(lambda x, y: x + y, map(lambda x, y: x * y, n, range(11, 1, -1)))
  16     d2 = 11 - s % 11
  17     if d2 >= 10:
  18         d2 = 0
  19     n.append(d2)
  20                                                                                                     
  21     return "%d%d%d.%d%d%d.%d%d%d-%d%d" % tuple(n)

Que tal a versão obscura em uma linha? (tã-tã-tã-tã...) -- FelipeLessa

   1 def cpf_obscuro():n=[random.randint(0,9)for a in range(9)];o=11-(reduce(int.\
   2 __add__,map(int.__mul__,n,range(10+len(n)-9,1,-1)))%11);n+=[(o>=10 and[0]or[o])\
   3 [0]];o=11-(reduce(int.__add__,map(int.__mul__,n,range(10+len(n)-9,1,-1)))%11);n\
   4 +=[(o>=10 and[0]or[o])[0]];return"%d%d%d.%d%d%d.%d%d%d-%d%d"%tuple(n)

Ok, você venceu! :) Só espero não ser o programador que vai manter esse código depois hehe :) -- OsvaldoSantanaNeto

Código limpo

   1 import random
   2 
   3 def cpf():
   4     def calcula_digito(digs):
   5        s = 0
   6        qtd = len(digs)
   7        for i in xrange(qtd):
   8           s += n[i] * (1+qtd-i)
   9        res = 11 - s % 11
  10        if res >= 10: return 0
  11        return res                                                                              
  12     n = [random.randint(0,9) for i in xrange(9)]
  13     n.append(calcula_digito(n))
  14     n.append(calcula_digito(n))
  15     return "%d%d%d.%d%d%d.%d%d%d-%d%d" % tuple(n)

Exemplo de uso

   1 # Exemplo de como usar
   2 import geradorcpf
   3 print geradorcpf.cpf()

Falta só alguém fazer um unittest entre este cookbook e o VerificadorDeCpf, esse aqui gerando um milhão de números e o outro checando. Hehehe. --FelipeLessa

Valeu Felipe !, Abraços meu camagada. Só pra consta tu testou o codigo após suas alterações ? Tipo reeditei pra ficar mais original e parecido com o codigo javascript que eu "parseei"-- ralobao

Volta para CookBook.


Ruivaldo Neto, FelipeLessa (algumas alterações)