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

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.randrange(10)
  20 
  21 def mod(dividendo,divisor):
  22     """ Funcao pra retornar o resto da divisao de dois numeros """
  23     return round(dividendo % divisor)
  24 
  25 def cpf():
  26     """ Funcao pra gerar o bendito cpf """
  27 
  28     # Gera os numeros randonomicos ;)
  29     n1 = gera_random()
  30     n2 = gera_random()
  31     n3 = gera_random()
  32     n4 = gera_random()
  33     n5 = gera_random()
  34     n6 = gera_random()
  35     n7 = gera_random()
  36     n8 = gera_random()
  37     n9 = gera_random()
  38 
  39     # debugger purposes ;)
  40     DEBUG and debug(n1, n2, n3, n4, n5, n6, n7, n8, n9)
  41 
  42     # Contas e mais contas, dividi pra fica mais bonitinho
  43     a1 = n9 * 2
  44     a2 = n8 * 3
  45     a3 = n7 * 4
  46     a4 = n6 * 5
  47     a5 = n5 * 6
  48     a6 = n4 * 7
  49     a7 = n3 * 8
  50     a8 = n2 * 9
  51     a9 = n1 * 10
  52 
  53     # Soma os resultados de todas as contas anteriores e faz 
  54     # outra continha.. tudo regra do cpf, para ele ser valido :P
  55     d1 = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9
  56     d1 = 11 - mod(d1,11)
  57 
  58     # Caso d1 seja maior que 10, o que não pode, ele deve ser
  59     # igualado a 0
  60     if d1 >= 10:
  61         d1 = 0
  62 
  63     # debugger purposes
  64     DEBUG and debug(a1, a2, a3, a4, a5, a6, a7, a8, a9, d1)
  65 
  66     # Mesma coisa da de cima so que agora pra variavel d2
  67     a1 = d1 * 2
  68     a2 = n9 * 3
  69     a3 = n8 * 4
  70     a4 = n7 * 5
  71     a5 = n6 * 6
  72     a6 = n5 * 7
  73     a7 = n4 * 8
  74     a8 = n3 * 9
  75     a9 = n2 * 10
  76     a10 = n1 * 11
  77 
  78     # ... rola a barra de rolagem pra cima que tu vai entender :P
  79     d2 = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10
  80     d2 = 11 - mod(d2,11)
  81 
  82     # chega de repeticao de codigo :)
  83     if d2 >= 10:
  84         d2 = 0
  85 
  86     # debugger purposes
  87     DEBUG and debug(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, d2)
  88 
  89 
  90     # o esperado print final ... que maravilha
  91     return "%d%d%d.%d%d%d.%d%d%d-%d%d" % \
  92             (n1, n2, n3,  n4, n5, n6,  n7, n8, n9,  d1, d2)
  93 
  94 
  95 
  96 if __name__ == '__main__':
  97     # Temos os holofotes em nós, somos a atração principal!
  98 
  99     message = "Bem-vindo ao Gerador de CPFs"
 100     print '\t%s\n' % message, '\t%s\n' % ('=' * len(message))
 101 
 102     user_response = raw_input('Ativar debug (responda "sim" ativar)? ')
 103     if user_response.lower().strip() == "sim":
 104         DEBUG = True
 105 
 106     try:
 107         n_cpfs = input('Quantos CPFs aleatórios devem ser gerados? '))
 108         for i in xrange(n_cpfs):
 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 = [random.randrange(10) for i in xrange(9)]
   4                                                                                                     
   5     # calcula digito 1 e acrescenta ao numero
   6     s = sum(x * y for x, y in zip(n, range(10, 1, -1)))
   7     d1 = 11 - s % 11
   8     if d1 >= 10:
   9         d1 = 0
  10     n.append(d1)
  11                                                                                                     
  12     # calcula digito 2 e acrescenta ao numero
  13     s = sum(x * y for x, y in zip(n, range(11, 1, -1)))
  14     d2 = 11 - s % 11
  15     if d2 >= 10:
  16         d2 = 0
  17     n.append(d2)
  18                                                                                                     
  19     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 import random;\
   2 def cpf_obscuro(): n = [random.randrange(10) for a in range(9)];\
   3 o=11-sum(map(int.__mul__,n,range(10+len(n)-9,1,\
   4 -1)))%11;n+=[(o>=10 and[0]or[o])[0]];o=11-sum( \
   5 map(int.__mul__,n,range(10+len(n)-9,1,-1)))%11;n+=[(o>=10 and[0]\
   6 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.randrange(10) 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

Que tal uma interface gráfica usando tanto o "Código" acima como o "Código limpo"?

   1 #Estou utilizando o gerador de tela Eagle (http://www.gustavobarbieri.com.br/eagle/)
   2 #Apenas para estudo, o que vale é programar...
   3 
   4 # Adicionar o módulo no início do programa, após tê-lo instalado, claro.
   5 from eagle import *
   6 ...
   7 
   8 #Após o def cpf(): criar mais uma:
   9 def teste( app, table ):
  10     table = app[ "table-cpf" ]
  11     c = app[ "qtd" ]
  12     del table[:]
  13     for i in xrange(1,c+1):
  14         table += (i, cpf())
  15     table.columns_autosize()
  16 
  17 #Logo após criar a aplicação gráfica em si:
  18 App(
  19    title="Gerador de CPF's",
  20    top=(
  21         Button(id="button", label="Gerar CPF", callback=teste),
  22         UIntSpin(id="qtd",
  23                  label="Quantos CPF's:",
  24                  min=1,
  25                  value=1,
  26                  ),
  27         ),
  28    left=( 
  29         Table( "table-cpf", "Lista de CPF's",
  30                 types=( str, str ),
  31                 headers=( "Ordem", "CPF" ),
  32                 )
  33         )
  34    )
  35 
  36 run()
  37 
  38 #Comentar ou apagar toda a parte do if __name__ == '__main__': para baixo
  39 #Ao criar o programa use a extensão .pyw para não aparecer a "tela preta" atrás dele.
  40 #No site há muitas informações sobre a API, inclusive a própria API bem detalhada.
  41 #Última observação: minha primeira participação.

Esse tal de Eagle promete. Facilita bastante fazer telas gráficas. -- VictorMarcus

Volta para CookBook.


Ruivaldo Neto, FelipeLessa (algumas alterações)