@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)
--
--
------------------------------------
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.--
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))
>>> 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))
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!!
--
-- 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 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
--
--
--
------------------------------------
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.
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 comprehensionOnde é 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
fazalgocom(X) for x in algo_iteravel--
--
------------------------------------
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.
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.
Malditas Vídeo aulas, kkkkkkkkkkkkkkkkkk, na video aula que assisti o cara chama expressões geradores de list comp, rsrsrs
--
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))
@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)
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.
--
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)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
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!--
--
------------------------------------
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.
Although practicality beats purity.