sábado, 5 de dezembro de 2020

Classe String Template em Python

No módulo string, a classe Template nos permite criar sintaxe simplificada para especificação de saída. O formato usa nomes de placeholder formados por $ com identificadores Python válidos (caracteres alfanuméricos e sublinhados). Rodear o placeholder com colchetes permite que ele seja seguido por mais letras alfanuméricas sem espaços intermediários. Escrever $$ cria um único $ com escape.

String Template python

O modelo de string do Python é criado passando a string do modelo para seu construtor. Ele suporta substituições baseadas em $. Esta classe possui 2 métodos principais:

  • substitute(mapping, **kwds): Este método realiza substituições usando um dicionário com um processo semelhante a objetos de mapeamento baseados em chave. argumentos de palavra-chave também podem ser usados para o mesmo propósito. Caso o mapeamento baseado em chave e os argumentos de palavra-chave tenham a mesma chave, ele lança um TypeError. Se as chaves estiverem faltando, ele retornará um KeyError.
  • substitute(mapping, **kwds): o comportamento deste método é semelhante ao do método substitute, mas não lança um KeyError se uma chave estiver faltando, em vez disso, ele retorna um marcador de posição na string de resultado.

O método substitute() gera um KeyError quando um espaço reservado não é fornecido em um dicionário ou em um argumento de palavra-chave. Para aplicativos de estilo mala direta, os dados fornecidos pelo usuário podem estar incompletos e o método safe_substitute() pode ser mais apropriado - ele deixará os marcadores de posição inalterados se houver dados ausentes:

Abaixo estão alguns exemplos simples.

Exemplo 1:

# Um exemplo simples usando Template
from string import Template

# Cria um modelo que tenha espaço reservado para o valor de x
t = Template('x é $x')

# Valor substituto de x no modelo acima
print(t.substitute({'x' : 1}))

Resultado:

x é 1

A seguir está outro exemplo em que importamos nomes e marcas de alunos de uma lista e os imprimimos usando um modelo.

Exemplo 2:

# Um programa Python para demonstrar o
# funcionamento de Template
from string import Template

# Lista Aluno armazena o nome e as notas de três alunos
Aluno = [('Ram',90), ('Ankit',78), ('Bob',92)]

# Estamos criando uma estrutura básica para
# imprimir o nome e as notas dos alunos.
t = Template('Olá $nome, você tem a nota $nota') 

for i in Aluno:
    print (t.substitute(nome = i[0], nota = i[1])) 

Resultado:

Olá Ram, você tem a nota 90
Olá Ankit, você tem a nota 78
Olá Bob, você tem a nota 92

O exemplo abaixo mostra a implementação do método safe_substitute().

Exemplo 3:

from string import Template

template = Template('$nome é o novo $função da $empresa')

string = template.safe_substitute(nome='Raju Kumar', empresa='TCE')
print(string)

Resultado:

Raju Kumar é o novo $função da TCE

Observe que não fornecemos ao marcador de posição $função quaisquer dados, mas isso não gerará um erro, em vez disso, retornará o marcador de posição como uma string, conforme discutido acima.

Imprimindo uma template String

O atributo “template” do objeto Template pode ser usado para retornar a string do template conforme mostrado abaixo:

Exemplo:

t = Template('Eu sou $nome e venho de $cidade')
print('Template String =', t.template)

Resultado:

Template String = Eu sou $nome e venho de $cidade

Sinal de escape $

O $$ pode ser usado para escapar de $ e ser tratado como parte da string.

Exemplo:

template = Template('$$ é o simbolo usado para se referir ao $name')
string = template.substitute(name='Dollar')
print(string)

Resultado:

$ é o simbolo usado para se referir ao Dollar

O ${identificador}

O ${identificador} funciona de forma semelhante ao de $identificador. É útil quando caracteres identificadores válidos seguem o espaço reservado, mas não fazem parte do espaço reservado.

Exemplo:

template = Template('That $noun looks ${noun}y')
string = template.substitute(noun='Fish')
print(string)

Resultado:

That Fish looks Fishy

Outra aplicação para template é separar a lógica do programa dos detalhes de vários formatos de saída. Isso torna possível substituir modelos personalizados por arquivos XML, relatórios de texto simples e relatórios da web em HTML.

Observe que existem outras maneiras de imprimir a saída formatada como %d para inteiro, %f para flutuante.

Referência: https://docs.python.org/3.3/tutorial/stdlib2.html

Artigo escrito por Siddharth Lalwani e traduzido por Acervo Lima de String Template Class in Python

str() vs repr() em Python

str() e repr() são usados para obter uma representação de string do objeto.

Exemplo de str():

s = 'Olá, Acervo Lima'
print(str(s)) 
print(str(2.0/11.0)) 

Saída:

Olá, Acervo Lima
0.181818181818

Exemplo de repr():

s = 'Olá, Acervo Lima'
print(repr(s))
print(repr(2.0/11.0))

Saída:

'Olá, Acervo Lima'
0.18181818181818182

A partir da saída acima, podemos ver se imprimimos string usando a função repr(), em seguida, ela imprime com um par de aspas e, se calcularmos um valor, obtemos um valor mais preciso do que a função str().

A seguir estão as diferenças:

  • str() é usado para criar saída para o usuário final, enquanto repr() é usado principalmente para depuração e desenvolvimento. o objetivo de repr é ser inequívoco e str’s deve ser legível. Por exemplo, se suspeitarmos que um float tem um pequeno erro de arredondamento, repr irá nos mostrar, enquanto str pode não.
  • repr() calcula a representação de string "oficial" de um objeto (uma representação que tem todas as informações sobre o objeto) e str() é usado para calcular a representação de string "informal" de um objeto (uma representação que é útil para imprimir o objeto).
  • A função print e a função interna str() usam __str__ para exibir a representação de string do objeto, enquanto a função interna repr() usa __repr__ para exibir o objeto.

Vamos entender isso por um exemplo:

import datetime
today = datetime.datetime.now()

# Imprime formato legível para objeto de data e hora
print(str(today))

# imprime o formato oficial do objeto data-hora
print(repr(today))

Resultado:

2020-12-05 19:05:20.173734
datetime.datetime(2020, 12, 5, 19, 5, 20, 173734)

str() exibe a data de hoje de uma forma que o usuário pode entender a data e hora.

repr() imprime a representação “oficial” de um objeto de data e hora (significa que usando a representação de string “oficial” podemos reconstruir o objeto).

Como fazê-los funcionar para nossas próprias classes definidas?
Uma classe definida pelo usuário também deve ter um __repr__ se precisarmos de informações detalhadas para depuração. E se acharmos que seria útil ter uma versão string para os usuários, criamos uma função __str__.

# Programa Python para demonstrar a escrita
# de __repr__ e __str__ para classes definidas pelo usuário

# Uma classe definida pelo usuário para representar números complexos
class Complex:

    # construtor
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag

    # Para chamar repr (). Imprime informações do objeto
    def __repr__(self):
        return 'Racional(%s, %s)' % (self.real, self.imag)

    # Para chamar str(). Imprime forma legível
    def __str__(self):
        return '%s + i%s' % (self.real, self.imag)

t = Complex(10, 20)

print(str(t))
print(repr(t))

Resultado:

10 + i20
Racional(10, 20)

Artigo escrito por Arpit Agarwal e melhorado por rajivsarkar67 e traduzido por Acervo Lima de str() vs repr() in Python

Como inserir vários valores do usuário em uma linha em Python?

Por exemplo, em C podemos fazer algo assim:

// lê dois valores em uma linha
scanf("%d %d", &x, &y)

Uma solução é usar input() duas vezes.

x, y = input(), input()

Outra solução é usar split().

x, y = input().split()

Observe que não temos que especificar explicitamente split('') porque split() usa qualquer caractere de espaço em branco como delimitador como padrão.

Uma coisa a se notar no código Python acima é que tanto x quanto y seriam do tipo string. Podemos convertê-los para inteiros usando outra linha.

x, y = [int(x), int(y)]

# Também podemos usar a compreensão de lista
x, y = [int(x) for x in [x, y]]

Abaixo está o código completo de uma linha para ler duas variáveis inteiras da entrada padrão usando divisão e compreensão de lista.

# Lê dois números a partir da entrada e os converte para int usando
# compreensão da lista
x, y = [int(x) for x in input().split()]
# Lê dois números a partir da entrada e os converte para int usando
# a função map
x, y = map(int, input().split())

Artigo escrito por Abhishek Shukla e melhorado por dev_aditya e traduzido por Acervo Lima de How to input multiple values from user in one line in Python?

Tratamento de exceções Python

O erro em Python pode ser de dois tipos, ou seja, erros de sintaxe e exceções. Erros são os problemas em um programa devido aos quais o programa interromperá a execução. Por outro lado, exceções são levantadas quando ocorrem alguns eventos internos que alteram o fluxo normal do programa.

A diferença entre erro de sintaxe e exceções

Erro de sintaxe: como o nome sugere, esse erro é causado por sintaxe incorreta no código. Isso leva ao encerramento do programa.

Exemplo

# inicializar a variável de quantidade
montante = 10000

# verifique se você está qualificado para
# Comprar Dsa no seu próprio ritmo ou não
if (montante > 2999)
    print("Você está qualificado para comprar Dsa no seu próprio ritmo")

Resultado:

  File "/home/thor/Documentos/teste.py", line 6
    if (montante > 2999)
                       ^
SyntaxError: invalid syntax

Exceções: as exceções são levantadas quando o programa está sintaticamente correto, mas o código resultou em um erro. Este erro não interrompe a execução do programa, porém altera o fluxo normal do programa.

Exemplo:

# inicializa a variável
marks = 10000

# tenta fazer uma divisão por zero
a = marks / 0
print(a)

Resultado:

Traceback (most recent call last):
  File "/home/thor/Documentos/teste.py", line 5, in 
    a = marks / 0
ZeroDivisionError: division by zero

No exemplo acima, levantou ZeroDivisionError, pois estamos tentando dividir um número por 0.

Nota: Exception é a classe base para todas as exceções em Python. Você pode verificar a hierarquia de exceções aqui.

try e except no tratamento de exceções

Vamos tentar acessar o elemento da matriz cujo índice está fora do limite e tratar a exceção correspondente.

# Programa python para mostrar como
# lidar com erros em tempo de execução

a = [1, 2, 3]
try:
    print("Segundo elemento = %d" %(a[1]))

    # Lança o erro IndexError porque
    # estamos tentando acessar um
    # elemento fora dos limites
    print("Quarto elemento = %d" %(a[3]))

except IndexError:
    print('O erro IndexError foi lançado')

Resultado:

Segundo elemento = 2
O erro IndexError foi lançado

Uma instrução try pode ter mais de uma cláusula except, para especificar manipuladores para diferentes exceções. Observe que no máximo um manipulador será executado.

# Programa para lidar com vários erros com uma instrução except
try :
    a = 3
    if a < 4 :

        # lança ZeroDivisionError para a = 3
        b = a / (a-3)

    # lança NameError se a >= 4
    print(f"Valor de b = {b}") 

# note que parenteses é necessário
# quando vamos lidar com mais de uma
# exceção
except(ZeroDivisionError, NameError): 
    print("Complicações surgirão, continuaram e foram superadas")

Resultado:

Complicações surgirão, continuaram e foram superadas

Se você alterar o valor de 'a' para maior ou igual a 4, a saída será:

Complicações surgirão, continuaram e foram superadas

A saída acima é assim porque assim que o python tenta acessar o valor de b, ocorre NameError.

Cláusula Else

Em python, você também pode usar a cláusula else no bloco try-except, que deve estar presente após todas as cláusulas except. O código entra no bloco else apenas se a cláusula try não gerar uma exceção.

# Programa para representar a cláusula else com try-except

# Função que retorna a / b 
def AbyB(a , b):
    try:
        c = ((a+b) / (a-b))
    except ZeroDivisionError:
        print("a/b resulta em 0")
    else:
        print(c)

AbyB(2.0, 3.0) 
AbyB(3.0, 3.0) 

A saída para o programa acima é:

-5.0
a/b resulta em 0

Palavra-chave finally em Python

Python fornece a palavra-chave finally, que sempre é executada após blocos try e except. O bloco finally sempre executa após o término normal do bloco try ou depois que o bloco try termina devido a alguma exceção.

Sintaxe:

try:
       # Algum código.... 

except:
       # bloco opcional
       # lidando com a exceção
else:
       # executa se não tiver nenhuma exceção

finally:
      # sempre é executado, com ou sem exceções

Exemplo:

# demonstração de finally

try:
    k = 5//0 # lança o erro de divisão por zero
    print(k)

# lida com o erro de divisão por zero
except ZeroDivisionError:
    print("Não é possivel dividir por zero")

finally:
    # Esse bloco sempre é executado
    # com ou sem exceções
    print('Isso é sempre executado')   

Resultado:

Não é possivel dividir por zero
Isso é sempre executado

Levantando exceções

A instrução raise permite que o programador force a ocorrência de uma exceção específica. O único argumento em aumento indica a exceção a ser levantada. Deve ser uma instância de Exception ou a classe exception (uma classe que deriva de Exception).

# Programa python demonstrando
# o uso de raise

try:
    raise NameError("Um erro!!!") # lança um erro
except NameError:
    print("Uma exceção")
    raise # Para determinar qual exceção ocorreu ou não 

A saída do código acima será simplesmente impressa na linha "Umerro", mas um erro de tempo de execução também ocorrerá na última devido a instrução raise na última linha. Portanto, a saída em sua linha de comando será semelhante a essa:

Uma exceção
Traceback (most recent call last):
  File "/home/thor/Documentos/teste.py", line 5, in 
    raise NameError("Um erro!!!") # lança um erro
NameError: Um erro!!!

Artigo escrito por Nikhil Kumar Singh (nickzuck_007) e melhorado por Akanksha_Rai, nikhilaggarwal3 e traduzido por Acervo Lima de Python Exception Handling

Qual é o valor máximo possível de um inteiro em Python?

Considere o programa Python abaixo.

# Um programa Python para demonstrar que podemos
# armazenar grandes números em Python

x = 10000000000000000000000000000000000000000000;
x = x + 1
print(x)

Resultado :

10000000000000000000000000000000000000000001

Em Python, o valor de um inteiro não é restrito pelo número de bits e pode se expandir até o limite da memória disponível (Fontes: esse e esse). Portanto, nunca precisamos de nenhum arranjo especial para armazenar grandes números (imagine fazer a aritmética acima em C/ C++).

Como uma observação lateral, no Python 3, há apenas um tipo “int” para todos os tipos de inteiros. Em Python 2.7. existem dois tipos separados "int" (que é de 32 bits) e "long int" que é o mesmo que "int" do Python 3.x, ou seja, pode armazenar números arbitrariamente grandes.

# Um programa Python para mostrar que existem dois tipos em
# Python 2.7: int e long int
# E em Python 3, há apenas um tipo: int

x = 10
print(type(x))

x = 10000000000000000000000000000000000000000000
print(type(x))

Saída em Python 2.7:

<type 'int'>
<type 'long'>

Saída em Python 3:

<type 'int'>
<type 'int'>

Podemos tentar programas mais interessantes, como abaixo:

# Imprimindo 100 elevado a 100
print(100**100)

Artigo escrito por Abhay Rathi e traduzido por Acervo Lima de What is the maximum possible value of an integer in Python ?

Função trunc() em Python

Truncar em Python

Existem muitos módulos integrados em python. Fora desses módulos, existe um módulo interessante conhecido como módulo math que possui várias funções como teto, piso, truncar, fatorial, fabs, etc.

Destas funções, existe uma função interessante chamada trunc() que se comporta como uma função de teto para número negativo e função de piso para número positivo.

Em caso de número positivo

# script em python para demonstrar o uso
# de floor(), ceil() truncate() com um número positivo
import math

print(math.floor(3.5)) # arredonda pra baixo
print(math.trunc(3.5)) # funciona como a função floor
print(math.ceil(3.5)) # arredonda pra cima

Resultado:

3
3
4

Em caso de número negativo

# script em python para demonstrar o uso
# de floor(), ceil() truncate() com um número negativos
import math

print(math.floor(-3.5)) # arredonda pra baixo
print(math.trunc(-3.5)) # funciona como a função floor
print(math.ceil(-3.5)) # arredonda pra cima

Resultado:

-4
-3
-3

Isso ocorre porque a função de teto (ceil()) é usada para arredondar para cima, ou seja, em direção ao infinito positivo e a função de fundo é usada para arredondar para baixo, ou seja, em direção ao infinito negativo.

Mas a função trunc() é usada para arredondar para cima ou para baixo em direção a zero.

Artigo escrito por Arpit Agarwal e traduzido por Acervo Lima de trunc() in Python

Fatos interessantes sobre strings em Python

Strings são imutáveis

Depois que uma string é definida, ela não pode ser alterada.

# Programa para mostrar
# que strings não podem ser alteradas

a = 'Acervo Lima'

# mostra o valor de a
print(a) 

# tenta alterar o terceiro elemento da string
a[2] = 'E' # isso vai lançar o erro TypeError
print(a)

Resultado:

Acervo Lima
Traceback (most recent call last):
  File "/home/thor/Documentos/teste.py", line 10, in 
    a[2] = 'E' # isso vai causar um erro
TypeError: 'str' object does not support item assignment

Mas o código abaixo funciona bem.

# programa para mostrar que uma string
# pode ser concatenada com outra string

a = 'Acervo '

# mostra o conteúdo de a
print(a)
a = a + 'Lima'

print(a) # tudo funciona como deveria

Resultado:

Acervo 
Acervo Lima

No segundo programa, o intérprete faz uma cópia da string original e então trabalha nela e a modifica. Portanto, a expressão a = a + 'Lima' não muda a string, mas reatribui a variável a um novo valor (o resultado da concatenação das duas strings).

Entenda o uso da função id().
A função id() é usada para retornar a identidade de um objeto.

# script python para mostrar que
# as duas string tem o mesmo id

string1 = "Hello"
string2 = "Hello"

print(id(string1)) 
print(id(string2)) 

Resultado:

140595101158640
140595101158640

string1 e string2 apontam para o mesmo objeto ou mesmo local. Agora, se alguém tentar modificar qualquer um dos resultados da string, os resultados serão diferentes.

# Modificando a string

string1 = "Hello"

# id da string string1 
print(id(string1)) 

string1 += "World"
print(string1) 

# id da string modificada string1 
print(id(string1))

Resultado:

140495269678192
HelloWorld
140495269678832

String1 é modificado, o que contradiz o fato de que as strings são imutáveis, mas a identidade antes e depois da modificação são diferentes. Isso significa que um novo objeto da string1 é criado após a modificação, o que confirma o fato de que as strings são imutáveis, pois nenhuma mudança foi feita no objeto anterior da string1 em vez disso uma nova é criada.

Três maneiras de criar strings

Strings em Python podem ser criadas usando aspas simples, aspas duplas ou aspas triplas.

As aspas simples e duplas funcionam da mesma forma para a criação da string. Por falar em aspas triplas, elas são usadas quando temos que escrever uma string em várias linhas e imprimir como está, sem usar nenhuma sequência de escape.

# script python parar criar
# strings de três modos diferentes
# e concatenalas 

# string com aspas simples
a = 'Acervo'

# string com aspas duplas
b = " Lima"

# string com aspas triplas
c = ''' Acervo Lima
o maior acervo de de tutoriais '''

d = '''Ele disse, "É armadilha"'''

print(a)
print(b)
print(c)
print(d)

# concatenando strings criadas
# com aspas simples, duplas e triplas
print(a + b + c) 

Resultado:

Acervo
 Lima
 Acervo Lima
o maior acervo de de tutoriais 
Ele disse, "É armadilha"
Acervo Lima Acervo Lima
o maior acervo de de tutoriais

Como imprimir aspas simples ou aspas duplas na tela?

Podemos fazer isso das duas maneiras a seguir:

  • O primeiro é usar o caractere de escape para exibir a citação adicional.
  • A segunda maneira é usando aspas combinadas, ou seja, quando queremos imprimir aspas simples, usando aspas duplas como delimitadores e vice-versa.

Exemplo:

print("Olá, senhor Alberto") 

# usando o caracter de escape
print("Ele disse, \"Bem-vindo ao Acervo Lima\"")

print('Tão feliz em estar aqui')

# Usando aspas diferentes
print ('Ele esta procurando pelo Billy "the Kid"')                

Resultado:

Olá, senhor Alberto
Ele disse, "Bem-vindo ao Acervo Lima"
Tão feliz em estar aqui
Ele esta procurando pelo Billy "the Kid"

Como imprimir o caractere de escape?

Se houver a necessidade de imprimir o caractere de escape (\), então, se o usuário mencioná-lo em um interpretador de string, pensará nele como um caractere de escape e não o imprimirá. Para imprimir o caractere de escape, o usuário deve usar o caractere de escape antes de '\' conforme mostrado no exemplo.

# imprime o caractere de escape
print ("\\ barra invertida")

Resultado:

\ barra invertida

Artigo escrito por Arpit Agarwal, melhorado por tuhinpaul e traduzido por Acervo Lima de Interesting facts about strings in Python | Set 1