Dicas sobre desenvolvimento de software, gestão e tributações

Rede Social

27 de outubro de 2020

Python: List Slices


 Como executar seu código python diretamente no Sublime-Text | by Willyan  Guimarães | experienceCode | Medium

No post de hoje vamos ver uma forma bem interessante e que facilita bastante para se obter valores de listas.
Imagine que temos uma lista de ints conforme a lista abaixo.

list = [0, 1, 5, 8, 14, 27, 31, 45, 63, 76]

E eu quero imprimir na tela os valores das posições 2 até a 5, normalmente pensaríamos em um loop como um for, mas em Python temos uma forma bem simples de resolver isso.

print(list[2:6])

Com esse comando o retorno seria:

[5, 8, 14, 27]

Ou seja os ints nas posições 2 (não se esqueça que a contagem começa do zero), até a posição 5 (a posição 6 não é selecionada por mais que se tenha colocado 6 no comando).

Também podemos omitir um dos dois parâmetros, seja o primeiro que é o número inicial ou o segundo que é o número final
Se eu executar o comando:

print(list[:5])

Seria a mesma coisa que executar o comando print(list[0:5]).

E se executar
print(list[7:])

Ele vai imprimir à partir da posição 7 até o final da lista.

List slices também pode ser usado com um terceiro parâmetro que serve para indicar a quantidade de posições à percorrer de cada vez, como por exemplo:

print(list[2:9:2])

O resultado irá imprimir à partir da posição 2 até a posição 9 de dois em dois como o abaixo:

[5, 14, 31, 63]

 

Também temos a opção de colocar um número negativo no terceiro parâmetro, isso faz com que a lista seja retornada ao contrário como por exemplo:

 print(list[7:4:-1])

Retorno:

[45, 31, 27]

Ler

15 de outubro de 2020

Python: Uma função Pythônica para validar CNPJ



Seguindo a ideia do post anterior, onde mostrei uma solução para a validação de CPF, falarei hoje sobre a validação de CNPJ. Mas como o cálculo é bem parecido, vou destacar apenas as diferenças entre eles.

 

Para a validação do CPF, os pesos aplicados aos seus dígitos vão de 2 a 11. Para o CNPJ, os pesos vão de 2 a 9 e então reiniciamos os pesos (novamente em 2). E, assim como para o CPF, os pesos são aplicados da direita para a esquerda.


Vamos usar o CNPJ (gerado aleatoriamente) 90.306.453/0001-33 como exemplo.

Ao aplicarmos os pesos teremos as seguintes associações:

9
0
3
0
6
4
5
3
0
0
0
1

5

4

3

2

9

8

7

6

5

4

3

2

Sem contar o primeiro DV.

E

9
0
3
0
6
4
5
3
0
0
0
1
3
6
5
4
3
2
9
8
7
6
5
4
3
2

Contando o primeiro DV.


Como a partir da aplicação dos pesos o algoritmo é exatamente o mesmo ao do CPF, vamos direto para o código.

 

from itertools import cycle

LENGTH_CNPJ = 14


def is_cnpj_valido(cnpj: str) -> bool:
if len(cnpj) != LENGTH_CNPJ:
return False

if cnpj in (c * LENGTH_CNPJ for c in "1234567890"):
return False

cnpj_r = cnpj[::-1]
for i in range(2, 0, -1):
cnpj_enum = zip(cycle(range(2, 10)), cnpj_r[i:])
dv = sum(map(lambda x: int(x[1]) * x[0], cnpj_enum)) * 10 % 11
if cnpj_r[i - 1:i] != str(dv % 10):
return False

return True


if __name__ == "__main__":
print("CNPJs inválidos")
print(is_cnpj_valido("0"))
print(is_cnpj_valido("123456789012345"))
print(is_cnpj_valido("5" * LENGTH_CNPJ))
print(is_cnpj_valido("90306453000103"))
print(is_cnpj_valido("90306453000130"))
print("CNPJs válidos")
print(is_cnpj_valido("90306453000133"))
print(is_cnpj_valido("82671952000100"))
print(is_cnpj_valido("31049514000165"))
print(is_cnpj_valido("77437514000133"))
print(is_cnpj_valido("00059549000151"))


Temos apenas 3 diferenças entre os códigos de validação de CNPJ e CPF, que são:

1. A importação da função "cycle" do pacote "intertools"

2. O tamanho da constante que é 14 para CNPJ

3. O método da aplicação dos pesos.


Como são apenas estas as diferenças, e a importação e o tamanho da constante não precisam maiores explicações, vou explicar apenas a parte dos pesos. (Para a explicação do restante do algoritmo, acesse o post do CPF).


Para aplicar os pesos do CPF, nós fazemos uso da função "enumerate", porém não podemos fazer o uso da mesma função para o CNPJ, pois os pesos do CNPJ não são sequenciais, uma vez que a sequência é reiniciada ao atingir o valor 9.

Para atendermos esta particularidade, fazemos uso de 3 funções: "range", "cycle" e "zip". Como todas são funções que merecem posts específicos para explicá-las, vamos apenas resumir como elas agem no algoritmo.

A função range irá nos retornar um iterável que se inicia em 2 e termina em 9 (o 10 não é incluso).

Este iterável é recebido pela função cycle, que por sua vez devolve um objeto "itertools.cycle". Vamos dizer que esse objeto é tipo um "iterável infinito", pois se fizermos um "for" nele, o loop "nunca" será finalizado.

Por fim pegamos este "iterável infinito" e o iterável com os dígitos invertidos do CNPJ e passamos para a função zip. A função irá unir estes 2 iteráveis, limitando o resultado pelo tamanho do menor iterável (neste caso o CNPJ). Com isso teremos todos os dígitos do CNPJ com seus respectivos pesos aplicados, similar ao que a função enumerate faz com o CPF.

A partir daqui segue igual ao que é feito com o CPF.

Ler

13 de outubro de 2020

Python: Particularidades com números em Python


Como executar seu código python diretamente no Sublime-Text | by Willyan  Guimarães | experienceCode | Medium 

No post de hoje vou mostrar algumas particularidades quando estamos tratando números em Python.


Imagine que eu tenho um número 25555777, quando olhamos para ele fica um pouco complicado de rapidamente saber qual número é, mas em Python podemos utilizá-lo de maneira mais amigável ao ser humano como 25_555_777 pronto fica muito mais fácil de saber que o número é 25 milhões, 555 mil e 777, o compilador entende isso normalmente.

Outro exemplo é quando eu quero utilizar apenas a parte inteira de um número decimal, por exemplo 7 / 3 é 2,33333, caso queira saber apenas qual o número inteiro ignorando a parte decimal eu poderia converter com um cast int (7 / 3) que ele me retornaria 2, mas um forma mais fácil e rápida seria 7 // 3 com duas barras, também me retornará 2. Inclusive pode ser utilizado em cálculos mais extensos.

Mais uma seria particularidade é que os números não tem o mesmo limite que outras linguagens, um inteiro pode ter o tamanho até que a memória da máquina suporte e não o tamanho do tipo inteiro.

Ler

6 de outubro de 2020

SQL: Selecionar apenas os decimais dos números


SQL Server Express - Backup, Recursos, Comparando edições
No post de hoje vamos ver como selecionar apenas os decimais de um número no SQL Server.

É bem simples, para demonstrar isso vou declarar uma variável decimal.
declare @teste decimal(4,3)

Setar um valor com casas decimais.
select @teste = 2.938

E executar o comando:
select PARSENAME(@teste, 1)

Na verdade essa é uma função mais utilizada para tratamento de texto, mas para esse caso funciona, o que o parsename faz é separar o texto pelo "." no caso separando o "2" do "938".

Confira também a documentação oficial.
Ler

1 de outubro de 2020

Python: Uma função Pythônica para validar CPF


 


Algoritmos para validação de CPF são alguns dos primeiros algoritmos que aprendemos em cursos de programação (pelo menos foi assim comigo).

CPFs são compostos por 11 dígitos, sendo que os 2 últimos são dígitos verificadores. Portanto, para sabermos se um CPF é ou não válido, precisamos realizar o cálculo (que foi definido pela Receita Federal) e comparar o resultado obtido com os valores do dígito verificador.
 
O cálculo é bem simples! Vamos imaginar o seguinte CPF:
504.065.090-69 (CPF gerado aleatoriamente)
Primeiro pegamos os 9 primeiros dígitos e aplicamos a cada um deles um peso que se inicia em 2, da direita para a esquerda.

5

0

4

0

6

5

0

9

0

10

9

8

7

6

5

4

3

2

 
Após isso, basta somarmos cada dígito multiplicado por seu peso:
5 * 10 + 0 * 9 + 4 * 8 + ... + 0 * 2 = 170
 
Com este resultado, podemos optar entre 2 cálculos:
 
11 - 170 % 11

ou
 
170 * 10 % 11
 
Obs.: Lembrando que "%" é usado para calcular o resto (módulo) da divisão na maioria das linguagens de programação.
Ambos os cálculos nos levará ao valor do primeiro dígito verificador, que para este exemplo é 6.

Agora basta fazermos o mesmo calculo anterior, mas considerando também o primeiro dígito.
Os pesos ficarão conforme abaixo:
 

 5

0

4

0

6

5

0

9

0

6

11

10

9

8

7

6

5

4

3

2

 

Como a partir daqui o cálculo é exatamente o mesmo, vamos então para o algoritmo em Python!

TAMANHO_CPF = 11


def is_cpf_valido(cpf: str) -> bool:
if len(cpf) != TAMANHO_CPF:
return False

if cpf in (c * TAMANHO_CPF for c in "1234567890"):
return False

cpf_reverso = cpf[::-1]
for i in range(2, 0, -1):
cpf_enumerado = enumerate(cpf_reverso[i:], start=2)
dv_calculado = sum(map(lambda x: int(x[1]) * x[0], cpf_enumerado)) * 10 % 11
if cpf_reverso[i - 1:i] != str(dv_calculado % 10):
return False

return True


if __name__ == "__main__":
print(is_cpf_valido("0"))
print(is_cpf_valido("123456789012345"))
print(is_cpf_valido("55555555555"))
print(is_cpf_valido("19627722000"))
print(is_cpf_valido("19627722091"))
print(is_cpf_valido("19627722090"))
print(is_cpf_valido("02927367035"))
print(is_cpf_valido("64935775009"))
print(is_cpf_valido("45508834052"))
print(is_cpf_valido("50406509069"))

Na linha 1 apenas definimos uma constante com o tamanho do CPF.
 
Na linha 4 temos a declaração da nossa função.
 
Na linha 5 realizamos nossa primeira validação. Se o CPF não tiver exatamente 11 caracteres retornamos que o CPF informado é inválido. (lembre-se de limpar a mascara do CPF antes de chamar esta função).
 
Na linha 8 validamos se não é um CPF inválido conhecido (111.111.111-11, 222.222.222-22, ..., 000.000.000-00). Esta validação é feita a partir de um iterável gerado com uma comprehension. A comprehension irá iterar sobre cada valor da string "1234567890" e irá multiplicar cada caractere pelo tamanho do CPF. Aqui temos 2 particularidades sobre strings no Python:
1. Strings são iteráveis
2. Quando multiplicamos uma string por um valor inteiro, o resultado obtido será aquela string repetida x vezes.
 
Exemplo:
"a" * 10 = 'aaaaaaaaaa'
 
Na linha 11 o CPF informado é invertido. Exemplo:
De 12345678910 para 01987654321
A inversão é feita para facilitar a aplicação dos pesos.
 
Na linha 12 nós declaramos um for que irá iterar 2x, iniciando em 2 e finalizando em 1.

Na linha 13 é onde aplicamos os pesos de cada digito do CPF.
Primeiro nós pegamos o CPF invertido e fazemos uma substring delete que vai de "i" até o final.
Então pegamos esta substring e aplicamos os pesos nela, através da função "enumerate".
A função enumerate merece um post só para ela. Mas, de maneira resumida, ela recebe um iterável e enumera cada posição deste iterável. Ela retorna um "enumerate object" (que é também um iterável) de tuplas. Podemos converter este "enumarete object" em uma lista, por exemplo.
 
Exemplo:
list(enumerate([1, "b", 3])) = [(0, 1), (1, 'b'), (2, 3)]

Obs.: Vale atentar que no nosso caso nós iniciamos a função enumerate em 2 e não em 0.
 
A linha 14 é onde aplicamos o cálculo explicado no começo do post.
Primeiro multiplicamos os dígitos por seus respectivos pesos através da função "map". Assim como a função enumerate, a função map merece um post só para falar dela, mas vamos para um resumo. Ela recebe uma função e um iterável, e a partir disso gera um novo iterável.
No nosso exemplo, a função informada é uma expressão lambda (que resumidamente é uma função anônima) e o enumerate object criado na linha anterior. É na expressão lambda que ocorre a multiplicação dos digitos pelos seus pesos.
Usamos então função sum para somar o iterável retornado pela função map e aplicamos o resto da fórmula.

Na linha 15 nós comparamos o dígito do CPF informado com o dígito calculado. Caso os valores sejam diferentes, retornamos que o CPF é inválido.
A única observação que cabe aqui (além da conversão do dígito calculado para string) é que nós comparamos o módulo do dígito calculado por 10. Fazemos isso, pois quando o módulo da divisão por 11 resulta em 10, o valor que deve ser considerado é 0.

Como dito anteriormente, o loop será executado 2x. E caso não haja nenhuma inconsistência, a função irá retornar que o CPF é válido (linha 18).

Ler