Python

Nessa seção você encontrará conteúdos sobre a linguagem de programação Python, mas não pretendo abordar conteúdos mais básicos principalmente por que já existem muitos materiais sobre isso na internet, então vou focar em conteúdos mais avançados ou que são pouco abordados em outros lugares mas que são muito úteis.

Caso você tenha chegado aqui sem saber nada de Python, recomendo que você passe em algum dos links abaixo para aprender o básico.

Minha visão sobre Python

Linguagens de programação entram naquela categoria de assuntos que geram muitas polêmicas, principalmente quando adotamos a postura de “torcida organizada”. Eu particularmente não gosto de entrar nesse tipo de discussão quando percebo que a postura adotada é exatamente essa pois acredito que o caso não seja defender uma bandeira até a morte, mas sim entender as vantagens e e desvantagens e tirar proveito disso.

Dito isso, quero começar desse ponto: Python é uma linguagem para iniciantes?

Aqui entra uma das melhores respostas, DEPENDE.

Acredito que por Python ser uma linguagem com uma sintaxe simples e de baixa verbosidade ela acaba sendo a escolha de muitas pessoas que estão começando a programar, mas isso não significa que ela é uma linguagem para iniciantes.

Python é considerada atualmente uma linguagem de propósito geral, pelo menos é assim que ela é vendida por aí, eu particularmente não concordo com isso, mas isso é assunto para outro dia, mas só para adiantar qual seria o rumo da conversa, olha só:

“Uma chave de fenda pode abrir uma lata de tinta, mas isso não significa que ela é uma ferramenta para abrir latas”

Mas voltando ao assunto, quando estamos iniciando na programação umas das coisas mais prazerosas é ver as coisas de fato acontecendo, tu mete um input aqui, da um print ali e isso já é motivo de alegria, daí tu ja compartilha com os amigos e solta aquela: “olha só o programa que fiz”, e isso é demais, nesse sentido acho que Python é uma ótima pedida, a barreira de entrada é muito baixa.

Agora de verdade, desenvolver software é muito mais do que isso, e aqui Python acaba sendo omisso. Desenvolver software não é tão simples como iniciar em Python e isso pode te trazer mais malefícios do que benefícios a longo prazo, em outras palavras você pode desenvolver um racional menos apurado para resolver problemas, ou pior ainda, criar problemas que não deveriam existir.

Python não deixa evidente a necessidade de se preocupar com a estrutura do seu código, com a arquitetura, com a qualidade do código, com a performance, com a segurança, com a escalabilidade, com a testabilidade, com a documentação, com a legibilidade, com a organização, com a modularização, com a reutilização, com a manutenção… e por aí vai.

Isso não é uma crítica a linguagem, mas sim a forma como ela é vendida, aliás para deixar claro a linguagem que eu mais uso é Python, principalmente pelo contexto que eu trabalho e não por que Python serve para tudo.

Então assim, se você está iniciando na programação, Python é uma ótima pedida, mas não se acomode com isso, tu vai precisar correr por fora para aprender sobre os assuntos que eu citei acima, isso não significa que outras linguagens não demandem isso, a diferença é que “elas” deixam isso mais evidente.

Em resumo é isso que gostaria de compartilhar sobre Python, espero que tenha sido útil e até a próxima.

Subsections of Python

Template String

Imagine que você criou uma automação para envio de email aos funcionários da empresa que você trabalha e que no corpo desse email existem dados que precisam ser alterados dinamicamente, exatamente aqui Template String entra em ação.

Veja esse caso de uso:

from string import Template  
  
tmpl_email = """  

Caro $employee_name,  
  
Espero que este e-mail o encontre bem. Gostaríamos de informar que realizamos uma revisão salarial anual e,  
como resultado, houve um ajuste no seu salário com base no índice de correção pela inflação.  
  
Após análises e cálculos cuidadosos, verificamos que o índice de inflação acumulada nos últimos 12 meses foi de  
$idx_inflation_rate. Com base nesse valor, o seu salário será corrigido para refletir a variação do custo de vida e  
garantir que você seja devidamente compensado.  
  
A partir do próximo mês, seu salário corrigido será de $salary. Essa correção foi aplicada retroativamente, o que s  
ignifica que você também receberá um valor adicional referente ao período desde a última atualização salarial.  
  
Se você tiver alguma dúvida sobre o cálculo ou qualquer outro aspecto relacionado à sua remuneração, fique à vontade  
para entrar em contato com o setor de Recursos Humanos. Estamos aqui para ajudar e fornecer qualquer esclarecimento  
adicional que você precise.  
  
Agradecemos sua dedicação e contribuição para a empresa. Reconhecemos que seu trabalho é fundamental  
para o nosso sucesso contínuo, e a atualização salarial é uma forma de valorizarmos seus esforços.  
  
Parabenizamos pelo seu desempenho e estamos ansiosos para continuar trabalhando juntos.  
  
Atenciosamente,  
  
$sender_name  
$sender_role  
$sender_company  
  
"""  
to_replace = {  
'employee_name': 'João da Silva',  
'idx_inflation_rate': '5%',  
'salary': 'R$ 1.500,00',  
'sender_name': 'Maria de Souza',  
'sender_role': 'Gerente de RH',  
'sender_company': 'Empresa XYZ'  
}  
  
to_replace_two = {  
'employee_name': 'João da Silva',  
'idx_inflation_rate': '5%',  
'salary': 'R$ 1.500,00',  
'sender_name': 'Maria de Souza',  
'sender_role': 'Gerente de RH',  
}  
  
tmpl_email = Template(tmpl_email)  
  
print(tmpl_email.substitute(to_replace))  
print(tmpl_email.safe_substitute(to_replace_two))   

Como podemos notar ao instanciarmos o objeto Template passamos no construtor um modelo contendo a “marcação” de quais campos queremos interpolar, na implementação da classe podemos ver que essa “marcação” leva o nome de “delimiter” e que por padrão seu valor é $.

class Template:
    """A string class for supporting $-substitutions."""

    delimiter = '$'
    # r'[a-z]' matches to non-ASCII letters when used with IGNORECASE, but
    # without the ASCII flag.  We can't add re.ASCII to flags because of
    # backward compatibility.  So we use the ?a local flag and [a-z] pattern.
    # See https://bugs.python.org/issue31672
    idpattern = r'(?a:[_a-z][_a-z0-9]*)'
    braceidpattern = None
    flags = _re.IGNORECASE

Então na prática as strings que serão substituídas devem iniciar com o delimitador $, caso você não criei um classe personalizada para isso.

Agora falando em substituir existem dois métodos disponíveis para isso:

string.substitute()

string.safe_substitute()

O método substitute() irá lançar uma exceção do tipo KeyError caso algum campo não seja encontrado no objeto que você passou como parâmetro, veja o exemplo abaixo onde o campo sender_company não foi passado no objeto to_replace_two.

print(tmpl_email.substitute(to_replace_two)) 

#output
Traceback (most recent call last):
  File "/home/python/app/src/template_string.py", line 52, in <module>
    print(tmpl_email.substitute(to_replace_two))
  File "/usr/local/lib/python3.10/string.py", line 121, in substitute
    return self.pattern.sub(convert, self.template)
  File "/usr/local/lib/python3.10/string.py", line 114, in convert
    return str(mapping[named])
KeyError: 'sender_company'

Agora caso não queira esse comportamento você pode utilizar o método safe_substitute() que irá ignorar os campos que não forem encontrados no objeto passado como parâmetro, retornando a string original.

print(tmpl_email.safe_substitute(to_replace_two))

#output
...
...
...
Agradecemos sua dedicação e contribuição para a empresa. Reconhecemos que seu trabalho é fundamental 
para o nosso sucesso contínuo, e a atualização salarial é uma forma de valorizarmos seus esforços.

Parabenizamos pelo seu desempenho e estamos ansiosos para continuar trabalhando juntos.

Atenciosamente,

Maria de Souza
Gerente de RH
$sender_company

Podemos inclusive usar com objetos mais complexos:

from string import Template

dados_cliente = {
    "nome": "João da Silva",
    "idade": 35,
    "endereco": {
        "rua": "Rua Principal",
        "cidade": "São Paulo",
        "estado": "SP"
    },
    "pedidos": ["Item 1", "Item 2", "Item 3"]
}

tmpl_string = """
Olá, $nome!

Agradecemos por sua compra recente. Abaixo estão os detalhes do seu pedido:

- Itens comprados:
  $itens

- Endereço de entrega:
  Rua: $endereco_rua
  Cidade: $endereco_cidade
  Estado: $endereco_estado

Atenciosamente,
Empresa XYZ
"""


tmpl = Template(tmpl_string)

formatted = tmpl.substitute(
    nome=dados_cliente["nome"],
    itens="\n  ".join(dados_cliente["pedidos"]),
    endereco_rua=dados_cliente["endereco"]["rua"],
    endereco_cidade=dados_cliente["endereco"]["cidade"],
    endereco_estado=dados_cliente["endereco"]["estado"]
)

print(formatted)

#output

Olá, João da Silva!

Agradecemos por sua compra recente. Abaixo estão os detalhes do seu pedido:

- Itens comprados:
  Item 1
  Item 2
  Item 3

- Endereço de entrega:
  Rua: Rua Principal
  Cidade: São Paulo
  Estado: SP

Atenciosamente,
Empresa XYZ

Template String com Classe Personalizada

E para finalizarmos quero mostrar como podemos utilizar uma classe personalizada para fazer a interpolação dos campos. Você pode fazer isso criando uma classe que herde de Template e sobrescreva o atributo delimiter, veja o exemplo abaixo:

from string import Template

class MyTemplate(Template):
    delimiter = '%'

dados_cliente = {
    "nome": "João da Silva",
    "idade": 35,
    "endereco": {
        "rua": "Rua Principal",
        "cidade": "São Paulo",
        "estado": "SP"
    },
    "pedidos": ["Item 1", "Item 2", "Item 3"]
}

tmpl_string = """
Olá, %nome!

Agradecemos por sua compra recente. Abaixo estão os detalhes do seu pedido:

- Itens comprados:
  %itens

- Endereço de entrega:
  Rua: %endereco_rua
  Cidade: %endereco_cidade
  Estado: %endereco_estado

Atenciosamente,
Empresa XYZ
"""


tmpl = MyTemplate(tmpl_string)

formatted = tmpl.substitute(
    nome=dados_cliente["nome"],
    itens="\n  ".join(dados_cliente["pedidos"]),
    endereco_rua=dados_cliente["endereco"]["rua"],
    endereco_cidade=dados_cliente["endereco"]["cidade"],
    endereco_estado=dados_cliente["endereco"]["estado"]
)

print(formatted)

#output

Olá, João da Silva!

Agradecemos por sua compra recente. Abaixo estão os detalhes do seu pedido:

- Itens comprados:
  Item 1
  Item 2
  Item 3

- Endereço de entrega:
  Rua: Rua Principal
  Cidade: São Paulo
  Estado: SP

Atenciosamente,
Empresa XYZ

"""

Como pode ver esse é um recurso muito útil e inclusive muito utilizado em softwares que dão suporte a internacionalização i18n.

Por hoje é isso, espero que tenha gostado e até a próxima.

Fonte: https://docs.python.org/pt-br/3.10/library/string.html