3294
Comentário: converted to 1.6 markup
|
3071
corrigido método _translate e assert para cpf inválido.
|
Deleções são marcadas assim. | Adições são marcadas assim. |
Linha 3: | Linha 3: |
Esse módulo contém algumas funções e classes úteis para aplicações que envolvam cadastros e necessitem validar números de CPF antes de incluir no banco de dados. Além de útil, também é um bom exemplo de como otimizar código que lida com manipulação de números e strings, usando as funções reduce(), map() e ''list compreensions''. | Esse módulo contém algumas funções e classes úteis para aplicações que envolvam cadastros e necessitem validar números de CPF antes de incluir no banco de dados. Além de útil, também é um bom exemplo de como otimizar código que lida com manipulação de números e strings, usando as funções sum(), map() e ''list compreensions''. |
Linha 11: | Linha 11: |
# fonte: http://www.python.org.br/wiki/VerificadorDeCPF | |
Linha 12: | Linha 13: |
import re # traduz 123.456.789-10 para 12345678910 _translate = lambda cpf: ''.join(re.findall("\d", cpf)) |
|
Linha 20: | Linha 25: |
b = (len(cpf) + 1 - i) | b = len(cpf) + 1 - i |
Linha 23: | Linha 28: |
res = reduce(int.__add__, res) % 11 | res = sum(res) % 11 |
Linha 26: | Linha 31: |
return (11 - res) | return 11 - res |
Linha 29: | Linha 34: |
def _translate(cpf): """Traduz o número como string na forma: 123.456.789-10 para a forma: 12345678910 """ i = xrange(256) t = [' '] * 256 e = ''.join([chr(x) for x in i if not chr(x).isdigit()]) for x in i: if chr(x).isdigit(): t[x] = chr(x) return cpf.translate(''.join(t), e) |
|
Linha 150: | Linha 132: |
assert valido.verificar() assert not invalido.verificar() |
assert valido.isValid() assert invalido.isValid() |
Linha 161: | Linha 143: |
edit 05/05/2010: Italo Maia |
Receita: Verificador de CPF
Esse módulo contém algumas funções e classes úteis para aplicações que envolvam cadastros e necessitem validar números de CPF antes de incluir no banco de dados. Além de útil, também é um bom exemplo de como otimizar código que lida com manipulação de números e strings, usando as funções sum(), map() e list compreensions.
Código
1 #/usr/bin/env python
2 # -*- coding:UTF-8 -*-
3 # fonte: http://www.python.org.br/wiki/VerificadorDeCPF
4
5 import re
6
7 # traduz 123.456.789-10 para 12345678910
8 _translate = lambda cpf: ''.join(re.findall("\d", cpf))
9
10 def _gen(cpf):
11 """Gera o próximo dígito do número de CPF
12
13 """
14 res = []
15 for i in range(len(cpf)):
16 a = cpf[i]
17 b = len(cpf) + 1 - i
18 res.append(b * a)
19
20 res = sum(res) % 11
21
22 if res > 1:
23 return 11 - res
24 else:
25 return 0
26
27
28 class CPF(object):
29
30 _gen = staticmethod(_gen)
31 _translate = staticmethod(_translate)
32
33 def __init__(self, cpf):
34 """O argumento cpf pode ser uma string nas formas:
35
36 12345678910
37 123.456.789-10
38
39 ou uma lista ou tuple
40 [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0]
41 (1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 0)
42
43 """
44
45 if isinstance(cpf, basestring):
46 if not cpf.isdigit():
47 cpf = self._translate(cpf)
48
49 self.cpf = [int(x) for x in cpf]
50
51 def __getitem__(self, index):
52 """Retorna o dígito em index como string
53
54 """
55
56 return self.cpf[index]
57
58 def __repr__(self):
59 """Retorna uma representação 'real', ou seja:
60
61 eval(repr(cpf)) == cpf
62
63 """
64
65 return "CPF('%s')" % ''.join([str(x) for x in self.cpf])
66
67 def __eq__(self, other):
68 """Provê teste de igualdade para números de CPF
69
70 """
71
72 if isinstance(other, CPF):
73 return self.cpf == other.cpf
74 return False
75
76 def __str__(self):
77 """Retorna uma representação do CPF na forma:
78
79 123.456.789-10
80
81 """
82
83 d = iter("..-")
84 s = map(str, self.cpf)
85 for i in xrange(3, 12, 4):
86 s.insert(i, d.next())
87 r = ''.join(s)
88 return r
89
90 def isValid(self):
91 """Valida o número de cpf
92
93 """
94
95 s = self.cpf[:9]
96 s.append(self._gen(s))
97 s.append(self._gen(s))
98 return s == self.cpf[:]
Exemplo de uso
1 #/usr/bin/env python
2 # -*- coding:UTF-8 -*-
3
4
5 from cpf import CPF
6
7 # Estes números foram gerados aleatoriamente :)
8
9 VALIDO = "113.451.253-80"
10 INVALIDO = "31354110274"
11
12 # qualquer um dos dois formatos (com pontos ou não) pode ser usado
13
14 valido = CPF(VALIDO)
15 invalido = CPF(INVALIDO)
16
17 assert valido.isValid()
18 assert invalido.isValid()
Volta para CookBook.
Pedro Werneck
edit 05/05/2010: Italo Maia