Validação de CPF pytônico

1,241 views
Skip to first unread message

matheus.saraiva

unread,
Aug 14, 2015, 10:51:11 AM8/14/15
to Python Brasil
Como python é tem uma sitaxe muito enxuta e eu não me considero ainda 100% pythônico. Gostaria que os amigos avaliassem minha validação de CPF e me sugerissem (caso haja) uma formato mais pythônico.

    @cpf.setter
   
def cpf(self, valor):
       
"""
            Valida o CPF informado
        """

       
       
if not valor.isdigit() or len(valor) != 11:
           
raise ValueError('CPF Inválido! Deve ser composto por 11 números, sem caracteres especiais')

        cpf_valido
= valor[0:9]
       
base = 10
       
       
while len(cpf_valido) < 11:
       
            soma
= 0
           
           
for n in cpf_valido:
                soma
+= int(n) * base
               
base -= 1
           
            digito
= soma % 11
           
           
if digito < 2:
                digito
= 0
           
else:
                digito
= 11 - digito
               
            cpf_valido
+= str(digito)

           
base = 11

       
if cpf_valido == valor:
           
self.__cpf = valor
       
else:
           
raise InvalidCpf(valor)



Juan Lopes

unread,
Aug 14, 2015, 1:34:01 PM8/14/15
to python...@googlegroups.com
def correct_cpf(cpf):
    numbers = list(map(int, cpf[:9]))
    numbers.append((11-sum(x*(10-i) for i, x in enumerate(numbers))%11)%10)
    numbers.append((11-sum(x*(11-i) for i, x in enumerate(numbers))%11)%10)
    return ''.join(map(str, numbers))

--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
 
<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil
 
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com

---
Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.

--

matheus.saraiva

unread,
Aug 14, 2015, 3:31:33 PM8/14/15
to Python Brasil
Em sexta-feira, 14 de agosto de 2015 14:34:01 UTC-3, Juan Lopes escreveu:
def correct_cpf(cpf):
    numbers = list(map(int, cpf[:9]))
    numbers.append((11-sum(x*(10-i) for i, x in enumerate(numbers))%11)%10)
    numbers.append((11-sum(x*(11-i) for i, x in enumerate(numbers))%11)%10)
    return ''.join(map(str, numbers))


Grato Juan,

Eu realmente não lembrava do recurso de list comprehension, o hábito C++ e Java é muito forte eu sempre esqueço que Python é muito flexível para trabalhar com listas.
Mas sua função ainda não funciona. Pois pelo algoritmo de validação de CPF, 11 - sum() só pode ser calculado se sum()%11 for >= 2.
Também não entendi qual a finalidade de sum()%10 no final.
Estou aqui pensando em uma forma de usar if/else nessa comprehension mas ainda não consegui montar.

matheus.saraiva

unread,
Aug 14, 2015, 3:51:00 PM8/14/15
to Python Brasil

Rsrsrsrs
Consegui fazer uma gambiarra, duplicando a list comprehension:

>>> def correct_cpf(cpf):
...     numbers = list(map(int, cpf[:9]))
...     numbers.append(11-sum(x*(10-i) for i, x in enumerate(numbers))%11 if sum(x*(10-i) for i, x in enumerate(numbers))%11 >= 2 else 0)
...     numbers.append(11-sum(x*(11-i) for i, x in enumerate(numbers))%11 if sum(x*(11-i) for i, x in enumerate(numbers))%11 >= 2 else 0)
...     return ''.join(map(str, numbers))



Funcionou mas tenho certeza que não é o melhor jeito, não consigo pensar em outra forma que não seja armazenado sum() em uma variável.

Rafael Henrique da Silva Correia

unread,
Aug 14, 2015, 4:42:57 PM8/14/15
to Python Brasil

Srs boa tarde...

Aproveitando a thread gostaria de perguntar... qual o limite entre list comprehension e legibilidade do código??

Sei que é uma pergunta polêmica mas as vezes sinto uma certa dificuldade para ler códigos conforme o que foi postado acima... realmente isso tem um ganho?

Pelo que me consta eu não ganho performance, e abusando muito de list comprehension eu mais perco do que ganho (em legibilidade).

Eu também gosto muito de list comprehension e acho um recurso fantástico! Mas até que ponto podemos usar e abusar?

Gostaria de saber a opinião dos srs.

Achei legal levantar esse assunto nessa thread justamente pela pergunta inicial sobre ser Pythonico ou não.

Abraço!!

--

Alexandre Souza

unread,
Aug 14, 2015, 4:52:52 PM8/14/15
to python...@googlegroups.com
0,02:

* list(map(add, foo)) -> apenas iterando sobre um mapa (em python3 o map devolve apenas um iterável, mas até onde eu sei, ele não é "lazy" no python2)
* list(x for x in foo) -> generator expression
* [x for x in foo] -> list comprehension

Onde é que tem list comp. no post do Juan? ^~

Obs.: Os três exemplos acima (com o foo) fazem a mesma coisa...há alguns comentários sobre map vs list comp.[0]. Eu acho que existe uma adoção bem maior para o uso de list comp ou até mesmo um generator ao invés de utilizar map/filter. Eu acho todos os recursos bem legais e, IMHO, acho mais legível um map/filter/reduce que um list comp. direto justamente pelo nome da função ("bato o olh na palavra map/filter/reduce" e já tenho uma ideia previa do que acontece ali). Eu acho que o maior problema para legibilidade é abusar de lambdas quando escrevemos um map/filter...

[ ]'s
--
-- 
Twitter: @_AleSou || GitHub: alexandre || Reddit: ubbersith
--
[...]o sentido disso tudo é que não há sentido em tentar enlouquecer
para impedir-se de ficar louco...guarde sua sanidade para mais
tarde[...] - Douglas Adams

Alexandre Souza

unread,
Aug 14, 2015, 4:58:16 PM8/14/15
to python...@googlegroups.com

Rafael Henrique da Silva Correia

unread,
Aug 14, 2015, 5:12:06 PM8/14/15
to Python Brasil

É Alexandre me expressei mal...

Quando disse list comp. queria dizer generator... enfim minha pergunta foi mais relativa a sintaxe em si, pois em desempenho ele ja perdeu o lazy jogando isso pra dentro do append.. ao meu ver lazy ou não ele já deixa de ser lazy nessa hora.

Att

--

Juan Lopes

unread,
Aug 14, 2015, 5:12:40 PM8/14/15
to python...@googlegroups.com
Desculpe, Matheus, faltou mais um mod na versão que mandei. Aproveitei e mudei algumas outras coisas e testei com uma massa de CPFs pra garantir que não errei dessa vez :)

def correct_cpf(cpf):
    numbers = list(map(int, cpf[:9]))
    numbers.append(-sum(x*(10-i) for i, x in enumerate(numbers))%11%10)
    numbers.append(-sum(x*(11-i) for i, x in enumerate(numbers))%11%10)
    return ''.join(map(str, numbers))

Em primeiro lugar, (11-x)%11 é matematicamente o mesmo que -x%11. O operador % tem uma semântica um pouco diferente no C para números negativos, mas no Python ele tem a semântica matemática correta.

Assim já elimina a necessidade do x<2 para um dos casos, pois -0%11 já é igual a zero. Aí resta só transformar em 0 o caso de x==1. Já que -1%11 == 10, basta fazer um %10 no final e tá tudo resolvido.

--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
 
<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil
 
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com

---
Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.

matheus.saraiva

unread,
Aug 14, 2015, 7:32:08 PM8/14/15
to Python Brasil
Em sexta-feira, 14 de agosto de 2015 17:52:52 UTC-3, Alexandre Souza escreveu:
0,02:

* list(map(add, foo)) -> apenas iterando sobre um mapa (em python3 o map devolve apenas um iterável, mas até onde eu sei, ele não é "lazy" no python2)
* list(x for x in foo) -> generator expression
* [x for x in foo] -> list comprehension

Onde é que tem list comp. no post do Juan? ^~

Obs.: Os três exemplos acima (com o foo) fazem a mesma coisa...há alguns comentários sobre map vs list comp.[0]. Eu acho que existe uma adoção bem maior para o uso de list comp ou até mesmo um generator ao invés de utilizar map/filter. Eu acho todos os recursos bem legais e, IMHO, acho mais legível um map/filter/reduce que um list comp. direto justamente pelo nome da função ("bato o olh na palavra map/filter/reduce" e já tenho uma ideia previa do que acontece ali). Eu acho que o maior problema para legibilidade é abusar de lambdas quando escrevemos um map/filter...

[ ]'s


Bem, baseado nisso acho que sempre entedi errado o conceito de list comp. Para mim tudo que itera usando a sintaxe:
fazalgocom(X) for x in algo_iteravel

É uma list comp.

matheus.saraiva

unread,
Aug 14, 2015, 7:36:42 PM8/14/15
to Python Brasil


Malditas Vídeo aulas, kkkkkkkkkkkkkkkkkk, na video aula que assisti o cara chama expressões geradores de list comp, rsrsrs

Fábio Cerqueira

unread,
Aug 15, 2015, 2:45:56 AM8/15/15
to python...@googlegroups.com
Rafael,
se tiver mais uma operação cabulosa eu já acho que deve ser evitada. Acho legível  quando tem no máximo um condicional e uma função aplicada.

--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
 
<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil
 
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com

---
Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.



--
Fábio Cerqueira

matheus.saraiva

unread,
Aug 15, 2015, 12:31:01 PM8/15/15
to Python Brasil


Em sexta-feira, 14 de agosto de 2015 18:12:40 UTC-3, Juan Lopes escreveu:
Desculpe, Matheus, faltou mais um mod na versão que mandei. Aproveitei e mudei algumas outras coisas e testei com uma massa de CPFs pra garantir que não errei dessa vez :)

def correct_cpf(cpf):
    numbers = list(map(int, cpf[:9]))
    numbers.append(-sum(x*(10-i) for i, x in enumerate(numbers))%11%10)
    numbers.append(-sum(x*(11-i) for i, x in enumerate(numbers))%11%10)
    return ''.join(map(str, numbers))

Em primeiro lugar, (11-x)%11 é matematicamente o mesmo que -x%11. O operador % tem uma semântica um pouco diferente no C para números negativos, mas no Python ele tem a semântica matemática correta.

Assim já elimina a necessidade do x<2 para um dos casos, pois -0%11 já é igual a zero. Aí resta só transformar em 0 o caso de x==1. Já que -1%11 == 10, basta fazer um %10 no final e tá tudo resolvido.


Fiz uns testes aqui, o resultado do modulo de um dividendo negativo é diferente do mesmo número positivo. Parece que ele continua a divisão quando o dividendo é negativo e para no primeiro resto quando o divisor é positivo. Em c++ ele para no primeiro resto e apenas inverte o sinal. Você disse que em python ele segue a matemática correta? Não entendi, minha matemática anda meio enferrujada.

Denis Costa

unread,
Aug 15, 2015, 12:48:53 PM8/15/15
to python...@googlegroups.com
2015-08-14 20:36 GMT-03:00 matheus.saraiva <matheus...@gmail.com>:
Malditas Vídeo aulas, kkkkkkkkkkkkkkkkkk, na video aula que assisti o cara chama expressões geradores de list comp, rsrsrs

Na verdade você tem 3 coisa de sintaxe similiar em Python. Generator Expressions[1], List Comprehensions[1][2] e Dict Comprehensions[3]. Apesar da sintaxe similar, eles são diferentes.

Exemplos dos 3 respectivamentes:

>>> (i*i for i in range(10))
<generator object <genexpr> at 0x7f2b4fa95d20>

>>> [i*i for i in range(10)]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

>>> {i:i for i in range(10)}
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}

[1] - https://docs.python.org/2/howto/functional.html#generator-expressions-and-list-comprehensions
[2] - https://docs.python.org/2/tutorial/datastructures.html#list-comprehensions
[3] - https://www.python.org/dev/peps/pep-0274/


--
Denis Costa

“Do or do not... There is no try.” - Yoda

Juan Lopes

unread,
Aug 15, 2015, 1:58:50 PM8/15/15
to python...@googlegroups.com
Os dois resultados são matematicamente corretos, mas um é mais útil do que outro, algebricamente falando.

Quando fazemos c = a%b, queremos encontrar "c" tal que "k*b+c = a", para um certo k inteiro. Existem infinitos valores para o qual isso é verdade. Inclusive o próprio "a", pois "0*b+a = a". O ponto é que todos os valores de "c" possíveis criam uma certa relação de equivalência, sob a ótica da "congruência mod b". Esta relação de equivalência é importantíssima no estudo de anéis comutativos finitos que tem inúmeras aplicações, entre elas a criptografia de chave assimétrica (em especial RSA) e códigos corretores de erros (que dá origem ao dígito verificador).

Mas nada disso importa. O que importa é que do ponto de vista da relação de equivalência, o conjunto dos restos de divisão por 5, por exemplo, formam um anel comutativo (na verdade, como 5 é primo, este é um corpo de Galois).

Z_5 = {0, 1, 2, 3, 4}.

As operações ⊕ e ⊗ presentes neste conjunto são fechadas sob o mesmo. Então, por exemplo 2⊗3 = 1 (podemos racionalizar que 2*3 =6 e 6%5=1).

A operação ⊖ não é definida diretamente. Mas o inverso aditivo sim. Por exemplo, em Z_5, ⊖3=2, pois 3⊕2=0.

Exatamente por esse motivo disse que (11-x)%11 é o mesmo que -x%11, pois na verdade 11 não existe em Z_11. 11≡0 mod 11, na verdade.

O motivo do mod em Python ser mais útil é pq ele sempre retorna valores entre 0 e m-1 para elementos em Z_m. Quando você retorna valores negativos, com frequência precisa corrigir para que os resultados sejam expressos com os representantes canônicos do anel.

Ainda sobre aquele código, fica o exercício entender por que essa versão é equivalente a todas as outras:

def correct_cpf(cpf):
    numbers = list(map(int, cpf[:9]))
    numbers.append(sum(x*i for i, x in enumerate(numbers, 1))%11%10)
    numbers.append(sum(x*i for i, x in enumerate(numbers, 0))%11%10)
    return ''.join(map(str, numbers))

--

matheus.saraiva

unread,
Aug 15, 2015, 6:38:36 PM8/15/15
to Python Brasil
Em sábado, 15 de agosto de 2015 14:58:50 UTC-3, Juan Lopes escreveu:
Os dois resultados são matematicamente corretos, mas um é mais útil do que outro, algebricamente falando.

Quando fazemos c = a%b, queremos encontrar "c" tal que "k*b+c = a", para um certo k inteiro. Existem infinitos valores para o qual isso é verdade. Inclusive o próprio "a", pois "0*b+a = a". O ponto é que todos os valores de "c" possíveis criam uma certa relação de equivalência, sob a ótica da "congruência mod b". Esta relação de equivalência é importantíssima no estudo de anéis comutativos finitos que tem inúmeras aplicações, entre elas a criptografia de chave assimétrica (em especial RSA) e códigos corretores de erros (que dá origem ao dígito verificador).

Mas nada disso importa. O que importa é que do ponto de vista da relação de equivalência, o conjunto dos restos de divisão por 5, por exemplo, formam um anel comutativo (na verdade, como 5 é primo, este é um corpo de Galois).

Z_5 = {0, 1, 2, 3, 4}.

As operações ⊕ e ⊗ presentes neste conjunto são fechadas sob o mesmo. Então, por exemplo 2⊗3 = 1 (podemos racionalizar que 2*3 =6 e 6%5=1).

A operação ⊖ não é definida diretamente. Mas o inverso aditivo sim. Por exemplo, em Z_5, ⊖3=2, pois 3⊕2=0.

Exatamente por esse motivo disse que (11-x)%11 é o mesmo que -x%11, pois na verdade 11 não existe em Z_11. 11≡0 mod 11, na verdade.

O motivo do mod em Python ser mais útil é pq ele sempre retorna valores entre 0 e m-1 para elementos em Z_m. Quando você retorna valores negativos, com frequência precisa corrigir para que os resultados sejam expressos com os representantes canônicos do anel.

Ainda sobre aquele código, fica o exercício entender por que essa versão é equivalente a todas as outras:

def correct_cpf(cpf):
    numbers = list(map(int, cpf[:9]))
    numbers.append(sum(x*i for i, x in enumerate(numbers, 1))%11%10)
    numbers.append(sum(x*i for i, x in enumerate(numbers, 0))%11%10)
    return ''.join(map(str, numbers))


É realmente uma excelente jogada para enxugar o código usando a matemática. Mas optei por deixar um pouco mais legível resolvendo do modo trivial, visto que não serei o único a ler esse código.
De qualquer maneira, ainda ficou bem mais enxuto que a primeira versão, que devo confessar não tinha nada de pythônico.

    @cpf.setter
   
def cpf(self, valor):
       
"""
            Valida o CPF informado
           
            Ex. cliente.cpf = '989989555'
           
        """

       
       
if not valor.isdigit() or len(valor) != 11:
           
raise ValueError('CPF Inválido! Deve ser composto por 11 números, sem caracteres especiais')


        cpf_valido
= list(map(int, valor[:9]))

       
while len(cpf) < 11:
           
base = len(cpf) + 1
            soma
= sum(x * (base + 1 - i) for i, x in enumerate(cpf_valido)) % 11
            cpf_valido
.append(11 - soma if soma >= 2 else 0)


       
if ''.join(map(str, cpf_valido)) == valor:

           
self.__cpf = valor
       
else:
           
raise InvalidCpf(valor)


Grato pela ajuda dos senhores.

Rafael Henrique da Silva Correia

unread,
Aug 15, 2015, 6:46:50 PM8/15/15
to Python Brasil

Matheus!!! Chegou ao ponto que eu comentei!!!

"É realmente uma excelente jogada para enxugar o código usando a matemática. Mas optei por deixar um pouco mais legível resolvendo do modo trivial, visto que não serei o único a ler esse código."

Ai eu concordo que é Pythonico!!!!

Srs a comunidade Python faz um esforço tremendo para deixar as coisas bonitas e claras de entender (o Guido e os outros caras também), eu sempre que codifico penso nos outros, sempre alguém vai ler seu código!

Como nós temos uma sintaxe bonita e cheia de coisas boas.. pra que complicar se podemos facilitar?

Achei muito bonito seu novo código Matheus! Parabéns!!

Att.

--

matheus.saraiva

unread,
Aug 15, 2015, 6:53:50 PM8/15/15
to Python Brasil, raf...@abraseucodigo.com.br
Só uma pequena correção:

        while len(cpf) < 11:
           
base = len(cpf) + 1

            soma
= sum(x * (base - i) for i, x in enumerate(cpf_valido)) % 11

            cpf_valido
.append(11 - soma if soma >= 2 else 0)

Faltou tirar o (base + 1) da expressão de soma.

 

Alexandre Souza

unread,
Aug 15, 2015, 6:59:06 PM8/15/15
to python...@googlegroups.com
IMHO,

x = [item for sublista em lista for item in sublista]
y = list(itertools.chain.from_iterable(lista))

Um exemplo bem bobo, mas a versão y é menos legível só porque usou mais recursos da linguagem?

O Juan só demonstrou que ele sabe como utilizar mais recursos de uma "linguagem"(?) (matemática) para resolver o problema. Eu provavelmente pensaria em algo parecido com o Matheus, mas não dá para afirmar que o código dele não está legível; "menos legível" tem mais a ver com o uso errado ou o abuso de um recurso do que aproveitar uma maneira elegante (me arrisco a dizer "mais declarativa") para resolver o problema.

Deixo aqui o meu obrigado pela explicações e comentários... =]

[ ]'s

matheus.saraiva

unread,
Aug 15, 2015, 7:08:25 PM8/15/15
to Python Brasil
Em sábado, 15 de agosto de 2015 19:59:06 UTC-3, Alexandre Souza escreveu:
IMHO,

x = [item for sublista em lista for item in sublista]
y = list(itertools.chain.from_iterable(lista))

Um exemplo bem bobo, mas a versão y é menos legível só porque usou mais recursos da linguagem?

O Juan só demonstrou que ele sabe como utilizar mais recursos de uma "linguagem"(?) (matemática) para resolver o problema. Eu provavelmente pensaria em algo parecido com o Matheus, mas não dá para afirmar que o código dele não está legível; "menos legível" tem mais a ver com o uso errado ou o abuso de um recurso do que aproveitar uma maneira elegante (me arrisco a dizer "mais declarativa") para resolver o problema.

Deixo aqui o meu obrigado pela explicações e comentários... =]

[ ]'s


O exemplo do Juan é perfeito, funciona perfeitamente e é até mais enxuto que o meu no quesito linhas de código. Mas para ler o código exige conhecimento de umas "regrinhas" matemáticas das quais eu só entendo agora pois ele explicou. Mas quem garante que o próximo a ler não será um enferrujado como eu.

Rafael Henrique da Silva Correia

unread,
Aug 16, 2015, 9:41:58 AM8/16/15
to Python Brasil
Galera... 

Minha intenção não é gerar flames nem dizer qual o melhor e qual o pior.... Mas sim qual é o mais Pythonico conforme o Matheus mencionou no início do thread. 

Pra mim os primeiros exemplos não são Pythonicos devido a legibilidade do código. 
Pra ser Pythonico tem que seguir o Zen do Python.... destaco em negrito os pontos que eu vi que não achei Pythonico:

Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    Complex is better than complicated.
    Flat is better than nested.
    Sparse is better than dense.
    Readability counts.
    Special cases aren't special enough to break the rules.
    Although practicality beats purity.
    Errors should never pass silently.
    Unless explicitly silenced.
    In the face of ambiguity, refuse the temptation to guess.
    There should be one-- and preferably only one --obvious way to do it.
    Although that way may not be obvious at first unless you're Dutch.
    Now is better than never.
    Although never is often better than *right* now.
    If the implementation is hard to explain, it's a bad idea.
    If the implementation is easy to explain, it may be a good idea.
    Namespaces are one honking great idea -- let's do more of those!
Sem Flames galera!! Somos todos amiguinhos e cada um tem sua opinião <3

Abraço!


--
--
------------------------------------
Grupo Python-Brasil
http://www.python.org.br/wiki/AntesDePerguntar
 
<*> Para visitar o site do grupo na web, acesse:
http://groups.google.com/group/python-brasil
 
<*> Para sair deste grupo, envie um e-mail para:
python-brasi...@googlegroups.com

---
Você recebeu essa mensagem porque está inscrito no grupo "Python Brasil" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para python-brasi...@googlegroups.com.
Para mais opções, acesse https://groups.google.com/d/optout.



--
Rafael Henrique da Silva Correia

Fabio C. Barrionuevo da Luz

unread,
Aug 16, 2015, 9:44:58 AM8/16/15
to python...@googlegroups.com
Although practicality beats purity.
Fábio C. Barrionuevo da Luz
Acadêmico de Sistemas de Informação na Faculdade Católica do Tocantins - FACTO
Palmas - Tocantins - Brasil - América do Sul


Blog colaborativo sobre Python e tecnologias Relacionadas, mantido totalmente no https://github.com/pythonclub/pythonclub.github.io .

Todos são livres para publicar. É só fazer fork, escrever sua postagem e mandar o pull-request. Leia mais sobre como publicar em README.md e contributing.md.
Regra básica de postagem:
"Você" acha interessante? É útil para "você"? Pode ser utilizado com Python ou é útil para quem usa Python? Está esperando o que? Publica logo, que estou louco para ler...

Ivanelson Nunes

unread,
Aug 17, 2015, 11:34:43 AM8/17/15
to python...@googlegroups.com
E qual é o mais prático esse ou outro?
    @cpf.setter
    
def cpf(self, valor):
        
"""
            Valida o CPF informado
            
            Ex. cliente.cpf = '989989555'
        """
        
        
if not valor.isdigit() or len(valor) != 11:
            
raise ValueError('CPF Inválido! Deve ser composto por 11 números, sem caracteres especiais')

        cpf_valido 
= list(map(int, valor[:9]))
        
while len(cpf) < 11:
            
base = len(cpf) + 1
            soma 
= sum(* (base + 1 - i) for i, x in enumerate(cpf_valido)) % 11
            cpf_valido
.append(11 - soma if soma >= 2 else 0)

        
if ''.join(map(str, cpf_valido)) == valor:
            
self.__cpf = valor
        
else:
            
raise InvalidCpf(valor)

@ivanelson
[]s
Reply all
Reply to author
Forward
0 new messages