Python: Biblioteca Padrão



Vimos que um usuário pode gravar suas classes em módulos para depois importá-las para dentro de seu código. Nas instalações de Python um conjunto de módulos vem instalado por padrão.

A biblioteca padrão do Python é extensa e inclui recursos diversos voltados para muitas áreas de aplicação. Alguns desses módulos são escritos em C para garantir velocidade de execução, outros em Python. Uma lista completa desses módulos pode ser encontrada em Python Docs: Standard Library. Muitos outros módulos podem ser encontrados em Pypi: The Python Package Index. Esse últimos devem ser baixados e instalados antes de sua utilização.

Lista de alguns módulos da biblioteca padrão:

Módulo 🖱 descrição
argparse processamento de argumentos em comando de linhas,
datetime 🖱 classes para manipulação de datas e horas,
decimal tipo de dados decimais para aritmética de ponto flutuante,
doctest ferramenta para validar testes embutidos em docstrings de um módulo,
glob 🖱 manipulação de listas de arquivos e pastas usando coringas,
io 🖱 gerenciamento de IO (input/output),
math 🖱 matemática de ponto flutuante,
os 🖱 funções para a interação com o sistema operacional,
pprint habilidade pretty print para estruturas de dados,
random 🖱 geração de números e escolhas aleatórios ,
re 🖱 processamento de expressões regulares,
reprlib versão de repr() personalizada para exibições de contêineres grandes,
shutil 🖱 interface com arquivos e coleções de arquivos,
statistics 🖱 funções estatísticas (média, mediana, variância, etc.),
string 🖱 métodos para formatação de strings,
textwrap formata parágrafos de texto para determinada largura de tela,
threading executa tarefas em segundo plano,
time 🖱 acesso ao clock do computador,
timeit 🖱 medidas de intervalo de tempo,
unittest conjunto de testes que podem ser mantidos em arquivo separado,
zlib, gzip, bz2, lzma, zipfile, tarfile suporte a formatos de compactação e arquivamento de dados.

Vamos exibir alguns dos métodos disponibilizados por esses módulos.

Módulo os

O módulo os permite a interação com o sistema operacional, executando várias tarefas. Ele contém funções para criar ou remover uma pasta, fazer pesquisa em seu conteúdo, alterar e identificar a pasta atual, etc.

» # importar o módulo os
» import os

» # mudar a pasta atual para /home/usr/Temp
» os.chdir('/home/usr/Temp')
» os.getcwd()
↳ '/home/usr/Temp'

» # lembrando: no Windows o caminho dever ser compatível
» # os.chdir("C:\\Projetos")

» # retornar para a pasta acima
» os.chdir('..')
» os.getcwd()
↳ '/home/usr'

» # retornando para a pasta temp
» pasta = '/home/usr/Temp'
» os.chdir(pasta)

» # criar uma pasta em temp
» os.mkdir('temp2')

» # alternativamente, de qualquer pasta
» novaPasta = '/home/usr/Temp/temp3'
» os.mkdir(novaPasta)

» # para remover a última pasta
» os.rmdir('temp3')

» # listdir retorna uma lista com os arquivos (e pastas) na pasta atual
» lista = os.listdir('/home/guilherme/Public/Programação/Python')
» for t in lista:
»     print(t)
↳ temp.html
↳ python-01.html
↳ python-02.html
↳ python-03.html    
↳ ...
# lista truncada

O módulo os possui algumas propriedades úteis, entre elas os.environ, que contém informação sobre o sistema operacional, e os.environ que armazena um dicionário com informações sobre o ambiente (environment).

» os.system
↳ <function posix.system(command)>
        
» os.environ
↳ environ{'QT_SCALE_FACTOR': '1',
        'LANGUAGE': 'en_US',
        'SHELL': '/bin/bash',
        'LC_NUMERIC': 'pt_BR.UTF-8',
        'LC_PAPER': 'pt_BR.UTF-8',
        'MATE_DESKTOP_SESSION_ID': 'this-is-deprecated',
        'JPY_PARENT_PID': '9099',
        'TERM': 'xterm-color',
        ... [truncado]
        'MPLBACKEND': 'module://ipykernel.pylab.backend_inline'}

» # essa propriedade é um tipo dicionário. por ex.:
» os.environ['USER']
↳ guilherme

Os seguintes testes foram realizados no prompt do python, em sessão do Anaconda.

>>> import os
>>> os.times()
↳ posix.times_result(user=0.03, system=0.0, children_user=0.0, children_system=0.0, elapsed=17180795.37)
>>> os.system('date')
↳ sáb 05 jun 2021 14:19:27 -03

# supondo a existência de um programa (ou atalho) de nome caja
# o aplicativo caja é executado (no caso um gerenciador de arquivos)
>>> os.system('caja')

O método os.walk(top, topdown=True, onerror=None, followlinks=False) retorna tuplas com pasta atual, subpastas e arquivos nelas contidos. Por default ele percorre as pastas iniciando em top e descendo para as substastas nele localizadas.

» import os
» path = '/home/guilherme/Temp'
» for (root, dirs, files) in os.walk(path):
»     print('Pasta atual: %s' % root)
»     print('Com as subpastas:\n', dirs)
»     print('Arquivos presentes:\n', files)
»     print('\n--------------------------------\n')

# saida (truncada)
↳ Pasta atual: /home/guilherme/Temp
↳ Com as subpastas:
↳  ['RevelationSpace', 'pandas']
↳ Arquivos presentes:
↳  ['Livro1', 'modal.html', 'FileZilla.xml']
↳ 
↳ Pasta atual: /home/guilherme/Temp/RevelationSpace
↳ Com as subpastas:
↳  []
↳ Arquivos presentes:
↳  ['01-RevealSpace.mp3', '02-RevealSpace.mp3', '03-RevealSpace.mp3', '04-RevealSpace.mp3', '05-RevealSpace.mp3']
↳ 
↳ Pasta atual: /home/guilherme/Temp/pandas
↳ Com as subpastas:
↳  ['Lambda', 'Pandas']
↳ Arquivos presentes:
↳  ['Lambda.html', 'Pandas.html']

Segue uma lista de alguns dos atributos de os:

Método significado
os.system() executa um comando shell,
os.environ() obtenha o ambiente dos usuários,
os.getcwd() retorna pasta de trabalho atual,
os.getgid() retorna id de grupo real do processo atual,
os.getuid() retorna ID do usuário do processo atual,
os.getpid() retorna ID de processo real do processo atual,
os.umask(mascara) define o umask numérico atual e retorne o umask anterior,
os.uname() retorna informações que identificam o sistema operacional atual,
os.chroot(caminho) altera pasta raiz do processo atual para caminho,
os.listdir(caminho) retorna lista de arquivos e pastas no caminho,
os.mkdir(caminho) cria pasta caminho,
os.makedirs(caminho) criação recursiva de pastas,
os.remove(caminho) remove arquivo em caminho,
os.removedirs(caminho) remove pastas recursivamente,
os.rename(src, dst) renomeia arquivo ou pasta src para dst,
os.rmdir(caminho) remove pasta em caminho,
os.system(comando) executa comando na shell do sistema operacional,
os.walk(caminho) retorna tuplas com pasta, subpastas e arquivos em cada uma.

Módulo shutil

O módulo shutil contém vários métodos que operam em arquivos e pastas, usados para copiar, apagar, entre outras funcionalidades. Vamos carregar os módulos os e shutil para experimentar alguns desses métodos. No Linux o sinal ‘./’ indica a pasta atual, ‘./Temp’, é uma subpasta de nome Temp.

Método significado
os.system() Executa um comando shell,
shutil.copy(origem, destino) copia arquivos,
shutil.copy2(origem, destino) copia arquivos com metadados,
shutil.move(origem, destino) move arquivos,
shutil.copyfile(origem, destino) copia arquivos,
shutil.copytree(pastaOrigem, pastaDestino) copia pasta e seu conteúdo

shutil.rmtree(pastaDestino) paga pastas recursivamente,
shutil.disk_usage(caminho) dados de uso do disco,
shutil.which(app) caminho de um aplicativo no path.

Exemplos de uso:
shutil.copy(origem, destino)
O método shutil.copy copia o arquivo origem para o destino, retornando uma exceção se a pasta de destino não existir.

shutil.copy2(origem, destino)
O método shutil.copy2 tem o mesmo efeito que o anterior, mas tenta copiar junto com o arquivo origem os seus metadados para o destino.
shutil.move(origem, destino)
O método shutil.move move o arquivo origem para o destino, retornando uma exceção se a pasta de destino não existir. O arquivo original deixa de existir.

» import os
» import shutil

» origem = './renomear.py'
» destino = './temp/renomear.py'

» # Vamos copiar o arquivo renomar.py para a paste temp de destino
» dest = shutil.copy(origem, destino)

» # um arquivo pode ser copiado em sua própria pasta
» shutil.copy('nomeAntigo.txt','nomeNovo.txt')

» # um arquivo pode ser renomeado
» shutil.move('nomeAntigo.txt','nomeNovo.txt')

» # o método retorna a pasta e arquivo de destino
» print('Pasta de destino:', dest)
↳ Pasta de destino: ./temp/renomear.py

» shutil.move('nomeAntigo.txt', , 'nomeNovo.txt')
↳ 'nomeNovo.txt'

» # considerando que nomeNovo.txt é o único arquivo na pasta
» os.listdir('./temp')
↳ ['nomeNovo.txt']

No Windows os caminhos devem ser escritos de forma compatível com o sistema.

» import shutil
» import os

» caminho = 'C:\\temp1\\temp2'
» print('A pasta atual contém os arquivos:') 
» print(os.listdir(caminho))
» # os arquivos são listados

» destino = 'C:\\temp1\\temp3'
» shutil.move('arquivo.txt',destino + '\\temp3\\arquivo.txt')

» print('A pasta de destino passa a ter os arquivos:') 
» print(os.listdir(destino))
» # uma lista é impressa, incluindo arquivo.txt

shutil.copyfile(origem, destino)
Um arquivo pode ser copiado com shutil.copyfile, origem é o caminho relativo ou absoluto da arquivo a ser copiado, destino o caminho do arquivo copiado.

shutil.copytree(pastaOrigem, pastaDestino)
O método shutil.copytree copia uma pasta inteira juntamente com todos os seus arquivos e outras pastas, de pastaOrigem para pastaDestino. A pasta de destino é criada na cópia ou uma exceção é lançada se a pasta ou os arquivos já existirem no destino.

» # copiando um arquivo da pasta ativa para Temp do usuário
» origem = './teste.txt'
» destino = '/home/usuario/Temp/testeNovo.txt'
» shutil.copytree(origem, destino)
	
» origem = '/home/usr/Projetos/'
» destino = '/home/usr/Projetos/temp2'

» shutil.copytree(origem, destino)
» print(os.listdir(destino))
» # uma lista dos arquivos no destino é exibida

shutil.rmtree(pastaDestino)
Para apagar pastas recursivamente podemos usar shutil.rmtree. Um erro será lançado de
a pasta pastaDestino não existir ou se não for uma pasta (se for um arquivo).

» print(os.listdir('./'))
↳ ['texto1.txt', 'alunos.csv', 'temp', 'temp2']

» # apagar pasta temp2 e todos os seus arquivos
» shutil.rmtree('./temp2')

» print(os.listdir('./'))
↳ ['texto1.txt', 'alunos.csv', 'temp']	

shutil.disk_usage(caminho)
shutil.which(app)
O método shutil.disk_usage informa dados de uso do disco sendo acessado e shutil.which(app) informa o caminho completo do aplicativo app que seria executado se estiver no PATH acessável no momento. O método retorna None se o app não existir ou não estiver no PATH.

» caminho = '/home/usuario/'
» estatistica = shutil.disk_usage(caminho)
» print(estatistica)
↳  usage(total=234684264448, used=172971024384, free=49720573952)

» comando = 'python'
» local = shutil.which(comando) 
» print(local)
↳ /home/guilherme/.anaconda3/bin/python

» comando = 'firefox'
» locate = shutil.which(comando) 
» print(local)
↳ /usr/bin/firefox

Biblioteca glob

O módulo glob fornece métodos para a busca de arquivos e pastas usando padrões de construção de nomes semelhantes aos usados pelo shell do Unix.

Método Descrição
glob.glob(padrao) retorna lista de arquivos que satisfazem o padrão em padrao,
glob.iglob(padrao) retorna um iterador contendo os nomes dos arquivos individuais,
glob.escape(padrao) Usado nos casos em que os nomes de arquivos usam caracteres especiais.

Usando o módulo glob é possível pesquisar por nomes de arquivo literais ou usar caracteres especiais, similares aos das expressões regulares (mas bem mais simples).

Sinal Descrição
* Asterisco: corresponde a zero ou mais caracteres,
? Interrogação: corresponde exatamente a um caractere,
[] Colchetes: intervalo de caracteres alfanuméricos,
[!] negativa: não contém os caracteres listados.

A sintaxe de glob é:

glob.glob(caminho, recursive = False)
glob.iglob(caminho, recursive = False)
onde caminho é o nome dos arquivo ou arquivos, usando os sinais acima e caminho relativo ou absoluto. Se recursive = True a busca é realizada recursivamente dentro das subpastas. O método iglob tem o mesmo efeito mas retorna um objeto iterável. Alguns exemplos são:

» import glob
» import os

» # retorna todos os arquivos na pasta /home/usuario/Temp/
» glob.glob('/home/usuario/Temp/*')
↳ ['/home/usuario/Temp/musica02.mp4',
↳  '/home/usuario/Temp/Musica01.mp3',
↳  '/home/usuario/Temp/teste.txt',
↳  '/home/usuario/Temp/Programa.py']

» # arquivos com nomes começados com letra minúscula 
» glob.glob('/home/usuario/Temp/[a-z]*')
↳ ['/home/usuario/Temp/musica02.mp4',
↳  '/home/usuario/Temp/teste.txt']

» # arquivos com nomes começados com letra maiúscula 
» glob.glob('/home/usuario/Temp/[A-H]*')
↳ ['/home/usuario/Temp/Programa.py',
↳  '/home/usuario/Temp/Musica01.mp3']

» # arquivos com extensão mp(0 até 9)
» glob.glob('/home/usuario/Temp/*.mp[0-9]')
↳ ['/home/usuario/Temp/Musica01.mp3',
↳   '/home/usuario/Temp/musica02.mp4']

» # podemos trocar a pasta ativa
» os.chdir('/home/usuario/Temp/')
» glob.glob('*')
» # retorna todos os arquivos na pasta

» # iglob retorna um iterável
» it = glob.iglob('*')
» for t in it:
»     print(t)
↳ /home/usuario/Temp/musica02.mp4
↳ /home/usuario/Temp/Musica01.mp3
↳ /home/usuario/Temp/teste.txt
↳ /home/usuario/Temp/Programa.py

» # usando a negativa
» # arquivos que não começam com m, M ou t.
» glob.glob('[!mMt]*')
↳ ['/home/usuario/Temp/Programa.py']

glob.escape(caminho, recursive = False)
O método escape permite o uso de caracateres especiais como _, #, $ no nome dos arquivos. O caracter especial é inserido por meio de glob.escape(char).

» caminho = '*' + glob.escape('#') + '*.jpeg'
» glob.glob(caminho)
↳ ['Foto#001.jpeg']

» caminho = 'A*' + glob.escape('_') + '*.gif'
» glob.glob(caminho)
↳ ['Abcd_001.gif']

Um exemplo de uso pode ser dado no código que procura e apaga arquivos temporários, com a extensão .tmp

» import glob
» import os

» # apague arquivos temporários, tipo *.tmp
» for t in (glob.glob('*.tmp')):
»     print('Apagando ', t)
»     os.remove(t)

Módulo math

O módulo math do Python contém diversas funções matemáticas, especialmente úteis em projetos científicos, de engenharia ou financeiros. Eles são um acréscimo aos operadores matemáticos básicos do módulo básico, como os operadores matemáticos integrados, como adição (+), subtração (-), divisão (/) e multiplicação (*).

As seguintes funções são encontradas no módulo:

Método descrição
Funções trigonométricas e geométricas
math.sin() seno, ângulo em radianos,
math.cos() cosseno,
math.tan() tangente,
math.asin() arco seno,
math.acos() arco cosseno,
math.atan() arco tangente em radianos,
math.atan2() arco tangente de y/x em radianos,
math.sinh() seno hiperbólico,
math.cosh() cosseno hiperbólico,
math.tanh() tangente hiperbólica,
math.asinh() inverso do seno hiperbólico,
math.acosh() inverso do cosseno hiperbólico,
math.atanh() inversa da tangente hiperbólica,
math.degrees() ângulo convertido de radianos para graus,
math.radians() ângulo convertido de grau para radianos,
math.dist() distância euclidiana entre 2 pontos p e q,
math.hypot() norma euclidiana, distância da origem,
Exponencial e logarítmica
math.pow() potência, xy,
math.erf() função de erro de um número,
math.erfc() a função de erro complementar de um número,
math.exp() exponencial de x, ex,
math.expm1() exponencial de x menos 1, ex-1,
math.frexp() mantissa e expoente de número especificado,
math.log() logaritmo natural, ln(x),
math.log10() logaritmo de base 10, log10(x),
math.log1p() logaritmo natural de 1 + x, , ln(1+x),
math.log2() logaritmo de base 2, log2(x),
math.ldexp() inverso de math.frexp() que é x×2i,
math.gamma() função gama,
math.lgamma() gama do log de x,
Arredondamentos e truncamentos
math.ceil() número arredondado para o maior inteiro mais próximo,
math.floor() número arredondado para o menor inteiro mais próximo,
math.copysign() float, valor do primeiro parâmetro com o sinal do segundo parâmetro,
math.trunc() número truncado, parte inteira,
math.fabs() valor absoluto,
Análise combinatória
math.comb() quantas formas de k itens de n sem repetição e ordem,
math.perm() permutações, maneiras de escolher k itens de n com ordem, sem repetição,
math.factorial() fatorial,
Funções sobre iteráveis
math.prod() produto dos elementos de um iterável,
math.fsum() soma dos elementos de um iterável,
Outras funções
math.fmod() resto da divisão x/y,
math.remainder() resto da divisão x/y,
math.gcd() mdc, maior divisor comum de inteiros,
math.lcm() mdc, mínimo múltiplo comum de inteiros,
math.sqrt() raiz quadrada,
math.isqrt() raiz quadrada arredondada para o menor inteiro mais próximo,
Testes
math.isclose() booleano, se dois valores estão próximos,
math.isfinite() booleano, se um número é finito,
math.isinf() booleano, se um número é infinito,
math.isnan() booleano, se um valor é NaN.

As seguintes constantes são carregadas:

Constante valor
math.e número de Euler (2.7182…),
math.inf infinito positivo de ponto flutuante,
math.nan NaN positivo de ponto flutuante,
math.pi π = 3.1415…,
math.tau τ = 2 π.

Alguns exemplos de operações:

» import math
» math.cos(0)        # 1.0
» math.sin(0)        # 0.0
» math.ceil(1.17)    # 2
» math.floor(1.75)   # 1
» math.fabs(-1.75)   # 1.75
» math.comb(7,3)     # 35,   comb(n,k) = n! / (k! * (n - k)!) se k <= n, 0 se  k > n
» math.copysign(3.7,-4.5) # -3.7
» math.fmod(125,3)   # 2.0
» math.fsum([1.2, 2.3, 3.4, 4.5]) # 11.4  (qualquer iterável no argumento)
» math.gcd(12, 8)    # 4 mdc (máximo divisor comum)
» math.pow(2,15)     # 32768.0
» math.sqrt(135)     # 11.61895003862225
» p, q = [1,2,3], [3,2,1]
» math.dist(p,q)     # 2.8284271247461903
» math.hypot(1,2,3)  # 3.741657386773941

Módulos cmath e Numpy

As funções do módulo math são todos definidas para parâmetros “reais” (números de ponto flutuante, pra ser mais preciso). Elas não podem receber números complexos como parâmetros. Para operações com complexos existe o módulo cmath que implementa muitas das mesmas funções. Mais informações sobre esse módulo em Python Docs.


Para operações matemáticas mais sofisticadas existem várias bibliotecas de uso específico. Uma das mais usadas é Numerical Python ou NumPy, usado principalmente na computação científica e no tratamento de dados. NumPy não faz parte da biblioteca padrão e deve ser instalado separadamente.

Além de diversas funções semelhantes às do módulo math, NumPy é capaz de realizar operações alto desempenho com matrizes n-dimensionais. Frequentemente NumPy é utilizado junto com o pandas (veja artigo) para a análise de dados, treinamento de máquina e inteligência artificial.

Módulos statistics e random

O módulo statistics contém diversos métodos para o cálculo de funções estatísticas sobre um conjunto de dados numéricos. A maioria dessas funções podem receber como parâmetros dados int, float, Decimal e Fraction.

Método descrição
Médias e medidas de localização central
mean() Média aritmética dos dados,
fmean() Média aritmética rápida, de ponto flutuante,
geometric_mean() Média geométrica dos dados,
harmonic_mean() Média harmônica dos dados,
median() Mediana,
median_low() Mediana baixa,
median_high() Mediana alta,
median_grouped() Mediana ou 50-ésimo percentil de dados agrupados,
mode() Moda (o valor mais comum) de dados discretos,
multimode() Lista de modas (valores mais comuns) de dados discretos,
quantiles() Divide dados em intervalos de igual probabilidade,
Medidas de espalhamento
stdev() Desvio padrão,
pstdev() Desvio padrão,
variance() Variância da amostra,
pvariance() Variância de toda a população.

Alguns exemplos simples de cálculos estatísticos:

» from statistics import *
» mean([1.2, 2.3, 3.4, 4.5, 5.6])
↳ 3.4

» mode([1.2,2.1,2.1,3.8,4.6])
↳ 2.1

» # mode pode ser usada com dados nominais
» mode(['carro', 'casa', 'casa', 'carro', 'avião', 'helicóptero', 'casa'])
↳ 'casa'

» # multimode retorna lista com valores mais frequentes, na ordem em que aparecem 
» multimode('aaaabbbccddddeeffffgg')
↳ ['a', 'd', 'f']

» multimode([1,1,1,2,3,3,3,4,5,5,6,6,6])
↳ [1, 3, 6]

» dados = [1.5, 2.5, 2.5, 2.75, 3.25, 4.75]
» pstdev(dados)
↳ 0.986893273527251

» # statistics.pvariance(data, mu=None): variação populacional de dados
» # se mu (ponto central da média) não for fornecido ele é calculado como a média
» # se for conhecido pode ser passado como parâmetro

» mu = mean(dados)
» pstdev(dados, mu)
↳ 0.986893273527251

» from fractions import Fraction as F
» dados = [F(1, 4), F(5, 4), F(1, 2)]
» pvariance(dados)
↳ Fraction(13, 72)

» pvariance([1/4, 5/4, 1/2])   # o mesmo resultado seria obtido com floats:  13/72 =
↳ 0.18055555555555555

» # desvio padrão
» dados = [1.25, 3.12, 2.15, 5.68, 7.23, 3.01]
» stdev(dados)
↳ 2.2622643523691037	

Muitos outras bibliotecas existem para cálculo estatístico no Python, como NumPy e SciPy, alémm de outros aplicativos como Minitab, SAS, Matlab e R (nesse site).

Módulo random

Números aleatórios ou randômicos gerados em computadores são números produzidos à partir de uma semente ( ou seed) por meio de algoritmos que visam produzir valores o mais espalhados e imprevisíveis quanto possível. Como os algoritmos são todos determinísticos a distribuição não será de fato aleatória, a menos que o computador possa estar conectado a um evento externo realmente randômico (como o decaimento de uma substância radioativa).

Para fins práticos, tais como uso em jogos, teste e geração de chaves criptográficas, a pseudo aleatoriedade pode ser suficiente.

O módulo random contém diversos métodos para geração desses números e de escolhas entre listas.

Método descrição
seed() inicilaliza o gerador de números aleatórios,
getstate() retorna o estado atual do gerador,
setstate() restaura o estado do gerador,
getrandbits() retorna um número representando bits aleatórios,
randrange() retorna um número aleatório dentro do intervalo,
randint() retorna um inteiro aleatório dentro do intervalo,
choice() retorna um elemento aleatório da sequência dada,
choices() retorna uma lista de elementos aleatórios da sequência dada,
shuffle() embaralha os elementos de lista, retorna None,
sample() retorna uma amostra da sequência,
random() retorna número de ponto flutuante entre 0 e 1,
uniform() retorna float no intervalo,
triangular() retorna float no intervalo, com possibilidade de determinar o ponto central.

Os métodos abaixo retornam um número de ponto flutuante (float) entre 0 e 1 baseado na distribuição mencionada:

Método distribuição
betavariate() Beta,
expovariate() Exponential,
gammavariate() Gamma,
gauss() Gaussiana,
lognormvariate() log-normal,
normalvariate() normal,
vonmisesvariate() de von Mises,
paretovariate() de Pareto,
weibullvariate() de Weibull.

O método random() retorna um número randômico entre 0 e 1 (no intervalo [0, 1)).

seed(semente) é usado para inicializar o gerador. A partir de uma determinada inicialização os números gerados sempre se repetem, o que é útil para testes, em execuções repetidas do código. Se nenhuma semente for fornecida a semente default é a hora atual do sistema.

» # número entre 0 (inclusive) e 1 (exclusive)
» random.random()
↳ 0.15084917392450192

» # a semente inicializa o gerador
» # o bloco seguinte sempre gera os mesmos números
» random.seed(10)
» for t in range(5):
»     print(random.random(), end=' ')
↳ 0.5714025946899135 0.4288890546751146 0.5780913011344704 0.20609823213950174 0.81332125135732     	

» # inteiros entre 1 e 10 (inclusive)
» for t in range(10):
»     print(int(random.random()*10+1), end=' ')
↳ 3 9 8 9 10 3 9 8 5 4

» # o mesmo se pode conseguir com randint
» for t in range(10):
»     print(random.randint(1,10), end=' ')
↳ 4 1 6 1 5 3 5 2 7 10 

O método choice(lista) retorna um ítem escolhido aleatoriamente entre membros de uma lista, tupla ou string. sample(lista, k) escolhe k elementos da lista.

» import random
» lista = [123, 234, 345, 456, 567, 678,789]
» print(random.choice(lista))
↳ 789

» lista = ['banana', 'laranja', 'abacaxi', 'uva', 'pera']
» print(random.choice(lista))
↳ abacaxi

» # escolhe um elemento de uma string
» texto = 'Phylos.net'
» print(random.choice(texto)	
↳ h

» # podemos simular o experimento de 1000 dados jogados
» milDados = {1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 0}
» for t in range(1000):
»     milDados[random.choice([1,2,3,4,5,6])] += 1
» for t in range(1,7,2):
»     print('Lado {}: {} \t Lado {}: {}'.format(t, milDados[t], t+1, milDados[t+1]))
↳ Lado 1: 178 	 Lado 2: 171
↳ Lado 3: 160 	 Lado 4: 166
↳ Lado 5: 158 	 Lado 6: 167

» # o método sample(lista, n) escolhe n elementos da lista
» lista = [i for i in range(10,100,5)]
» print(lista)
↳ [10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
» print(random.sample(lista, 4))
↳ [20, 90, 95, 55]

» lista = ['banana', 'laranja', 'abacaxi', 'uva', 'pera']
» random.sample(lista, 2)
↳ ['abacaxi', 'banana']

randrange(inicio, fim, passo) retorna um aleatório entre inicio (inclusive) e fim (exclusive) com passos de passo, um parâmetro opcional com default de passo = 1. Todos os parâmetros são inteiros.

uniform(inicio, fim) retorna um float aleatório entre inicio e fim (ambos inclusive). Os parâmetros podem ser floats.

» # randrange(5, 10, 2) só pode retornar 5, 7 ou 9
» print(randrange(5, 10, 2))
↳ 9

» for t in range(5):
»     print(random.randrange(0, 4), end=' ')
↳ 0 3 3 1 2     

» # uniform lida com floats
» for t in range (5):
»     print(random.uniform(3.14, 3.16), end=' ')
↳ 3.1561382140695495 3.1525027738382234 3.152682503779535 3.1532559087053946 3.1411872204770708     

Aviso importante: Os pseudo geradores desse módulo não devem ser usados para gerar números (pseudo) aleatórios para fins de segurança, tais como a geração de chaves de criptografia, gerenciamento de segurança de passwords e autenticação e tokens de segurança. Para essa finalidade use o módulo secrets.

Datas e calendários

Para trabalhar com datas podemos importar o módulo datetime.

Uma das classes definidas nesse módulo é datetime que tem os métodos datetime.now(), a data e hora do momento, e e datetime.today(), a data apenas, ambas de acordo com o ajuste do computador. Um objeto de data contém o ano (year), mês (month), dia (day), hora (hour), minuto (minute), segundo (second), e microsegundo (microsecond).

O módulo datetime contém as classes date, time, datetime e timedelta.

» import datetime as dt

» # datetime.now() retorna a data e hora do momento
» d = dt.datetime.now()
» print(d)
↳ 2021-06-05 16:27:46.444763

» print('%d/%d/%d' % ( x.day, x.month, d.year))
↳ 5/6/2021

» # usando o método format de strings
» print('Ano: {}, Mẽs: {}, Dia: {}'.format(d.day, d.month, d.year))
↳ Ano: 7, Mẽs: 6, Dia: 2021

# ou
» print('{d.day}/{d.month}/{d.year}'.format(d=d))
↳ 7/6/2021

» print('minutos: %d, segundos:%d,%d' % ( d.minute, d.second, d.microsecond))
↳ minutos: 27, segundos:46,444763

» # usando o método format de strings:
» print('minutos: {}, segundos:{},{}'.format(d.minute, d.second, d.microsecond))
↳ minutos: 1, segundos:56,516050

» # ou
» print('{d.minute}min:{d.second},{d.microsecond}s'.format(d=d))
↳ 1min:56,516050s

Para inicializar uma variável com um valor qualquer usamos o construtor da classe datetime. Horas, minutos e seguntos, se não fornecidos, são ajustados para zero por default.

Uma data pode ser criada à partir um timestamp, que é o número de segundos decorridos desde 01 de janeiro de 1970 (UTC), usando o método fromtimestamp().

» # inicializando uma data
» d2 = dt.datetime(1996, 6, 14)
» print(d2)
↳ 1996-06-14 00:00:00

» # data de um timestamp
» ttp = dt.datetime.fromtimestamp(1613000000)
» print(ttp)
↳ 2021-02-10 20:33:20

Para conseguir uma formatação mais minuciosa de datas e hotas podemos usar o método strftime que converte um data em string de acordo com alguns parâmetros de valores pré-estabelecidos. Objetos das classes date, datetime e time todos possuem o método strftime(padrao) para criar uma representação de string representando seu valor.

Por outro lado o método datetime.strptime() constroi um objeto datetime partindo de uma string, representada em um padrão.

» d = dt.datetime.now()
» print(d.strftime('%d/%m/%y'))
↳ 07/06/21

» print(d.strftime('%d/%m/%Y')) 
↳ 07/06/2021

» print(d.strftime('%b'))   # sistema em inglês
↳ Jun

» print(d.strftime('%A, %d de %B, dia %j do ano de %Y')) 
↳ Monday, 07 de June, dia 158 do ano de 2021

A representação de horas segue o mesmo padrão:

» from datetime import time
» # time(hour = 0, minute = 0, second = 0) default
» a = time()
» print('a =', a)
↳ a = 00:00:00

» # time(hour, minute and second)
» b = time(8, 14, 15)
» print('b =', b)
↳ b = 08:14:15

» # time(hour, minute and second)
» c = time(hour = 8, minute = 14, second = 15)
» print('c =', c)
↳ c = 08:14:15

» # time(hour, minute, second, microsecond)
» d = time(8, 14, 15, 34567)
» print('d =', d)
↳ d = 08:14:15.034567

» print(b.strftime('Hora: %I%p, Minuto:%M, Segundo: %S '))
↳ Hora: 08AM, Minuto:14, Segundo: 15 

A diferença entre datas, calculadas com objetos datetime ou date é um objeto timedelta. O número de segundos em um intervalo é dado pelo método total_seconds().

» # diferença entre datas feitas entre objetos datetime e date 
» from datetime import datetime, date

» t1 = date(year = 2021, month = 6, day = 7)
» t2 = date(year = 1957, month = 6, day = 28)
» t3 = t1 - t2
» print('Diferença entre t1 e t2 =', t1 - t2)
↳ Diferença entre t1 e t2 = 23355 days, 0:00:00

» t4 = datetime(year = 2018, month = 7, day = 12, hour = 3, minute = 19, second = 3)
» t5 = datetime(year = 2021, month = 2, day = 12, hour = 1, minute = 15, second = 1)
» print('Diferença entre t4 e t5 =', t4 - t5)
↳ Diferença entre t4 e t5 = -946 days, 2:04:02

» print("type of t3 =", type(t3))
↳ type of t3 = <class 'datetime.timedelta'>
» print("type of t6 =", type(t6))
↳ type of t3 = <class 'datetime.timedelta'>

A diferença entre datas e horas pode ser calculada diretamente entre objetos timedelta.

» from datetime import timedelta
» t1 = timedelta(weeks = 2, days = 5, hours = 1, seconds = 33)
» t2 = timedelta(days = 4, hours = 11, minutes = 4, seconds = 54)
» deltaT = t1 - t2
» print("Diferença: ", deltaT)
↳ Diferença:  14 days, 13:55:39

» print("Segundos decorridos =", deltaT.total_seconds())

O método datetime.strptime(formato, data) tem o efeito oposto. Dada uma string contendo uma data escrita de acordo com formato ele retorna a data correspondente.

» from datetime import datetime
» data_string = '21 jun, 18'
» data1= datetime.strptime(data_string, '%d %b, %y')
» print('data =', data1)
↳ data = 2018-06-21 00:00:00

» data_string = '21 June, 2018'
» data2 = datetime.strptime(data_string, '%d %B, %Y')
» print('data =', data2)        
↳ data = 2018-06-21 00:00:00

Abaixo uma lista com os valores de parâmetros de formatação de strftime e strptime. Os exemplos são para a data datetime.datetime(2013, 9, 30, 7, 6, 5).

Código Significado Exemplo
%a dia da semana abreviado (l). seg,
%A dia da semana completo (l). Segunda-feira,
%w dia da semana, numerado: 0 é domingo e 6 é sábado. 1,
%d dia do mês preenchido com zero. 30,
%-d dia do mês como um número decimal. (p) 30,
%b nome do mês abreviado (l). Set,
%B nome do mês, completo (l). setembro,
%m número do mês preenchido com zero. 09,
%-m número do mês. (p) 9,
%y ano sem século como um número decimal preenchido com zero. 13,
%Y ano com século como um número decimal. 2013,
%H hora (em 24 horas) como um número decimal preenchido com zero. 07,
%-Hv hora (em 24 horas) como um número decimal. (p) 7,
%I hora (em 12 horas) como um número decimal preenchido com zero. 07,
%-I hora (em 12 horas) como um número decimal. (p) 7,
%p AM ou PM (l). AM,
%M minuto, número preenchido com zero. 06,
%-M minuto, número. (p) 6,
%S segundos, número preenchido com zero. 05,
%-S segundo como um número decimal. (p) 5,
%f microssegundo, número preenchido com zeros à esquerda. 000000,
%z deslocamento UTC no formato + HHMM ou -HHMM.
%Z nome do fuso horário. ,
%j dia do ano, número preenchido com zero. 273,
%-j dia do ano, número. (p) 273,
%U número da semana no ano (domingo é dia 1), número preenchido com zero. 39,
%W número da semana do ano (segunda-feira é dia 1), número. 39,
%c representação completa de data e hora (l). Seg, 30 de setembro 07:06:05 2013,
%x representação completa de data apenas (l). 30/09/13,
%X representação completa de tempo (l). 07:06:05,
%% o caracter literal ‘%‘.

Códigos marcados com (l) tem resultado dependente do ajuste local para datas. Os marcados com (p) são variáveis de acordo com a a plataforma.

Módulo timeit

O módulo timeit contém métodos úteis para medir o tempo decorrido na execução de um bloco de código. Diferentes modos de implementação de um código podem ser executados em tempos muito diferentes e medir esse tempo, em execuções mais longas, pode ser uma ótima forma de decidir por um otimização.

O método principal é
timeit.timeit(stmt=’codigo1′, setup=’codigo2′, timer=<timer>, number=1000000, globals=None)
onde codigo1 é uma string com as linhas de cógigo cujo tempo de execução se quer medir, codigo2 é string com o cógigo a ser executado previamente, <timer> é o timer a ser usado, number é o número de repetições da execução, e globals especifica o namespace onde será rodado o código.

No exemplo abaixo timeit.timeit('123456 + 654321', number=100_000) mede o tempo de execução da soma 123456 + 654321, repetida 100_000 vezes. O resultado da medida é retornado em segundos, no caso de t = 8.7 x 10-9 seg.

» import timeit
» timeit.timeit('123456 + 654321', number = 100_000)
↳ 0.000865324996993877
» timeit.timeit('123456 + 654321', number = 1_000_000)
↳ 0.008846134001942119

» # o código é realmente executado (evite outputs extensos)
» timeit.timeit('print("-", end=" ")', number = 10)
↳ - - - - - - - - - - 
↳ 0.0006212080006662291

Lembrando, podemos usar o underline como separador de milhares, apenas para facilitar a leitura de números longos. Vemos que realizar a mesma soma 10 vezes mais aumento o tempo de execução.

Suponha que queremos comparar o tempo de construção de uma tupla e uma lista usando o mesmo procedimento de listas de compreensão.

» # lista e tupla com inteiros de 0 a 1000, apenas múltiplos de 5
» lista = [i for i in range(1000) if i%5==0]
» tupla = (i for i in range(1000) if i%5==0)
» # qual deles é mais rápido?

» codigo1 = '''
» lista = [i for i in range(1000) if i%5==0]
» '''
» codigo2 = '''
» tupla = (i for i in range(1000) if i%5==0)
» '''
» # medimos o tempo de construção desses 2 objetos
» t1 = timeit.timeit(codigo1, number = 1000)
» print(t1)
↳ 0.07810732900179573

» t2 = timeit.timeit(codigo2, number = 1000)
» print(t2)
↳ 0.000657964003039524

» # comparando
» print('t1 = {} t2'.format(t1/t2))
» t1 = 118.71064167792143 t2

Vemos pelo último teste que a construção da tupla é mais de 100 vezes mais rápida que a da lista.

O tempo medido varia entre experimentos diferentes pois depende de uma série de fatores tais como quais os processos o computador já tem em execução e qual tempo está disponivel para o processamento do Python. É claro que varia também para máquinas diversas com velocidades de processador e memória disponível diferentes.

Qualquer bloco de código pode ser inserido para parâmetro de timeit, transformado em uma string. Também podemos passar funções como parâmetro.

» timeit.timeit('''
» import math
» listaFat = []
» def fatoriais(n):
»     for t in range(n):
»         listaFat.append(math.factorial(t))
»     print(listaFat)
» ''', number = 1_000_000)
↳ 0.28315910099991015

» # passando funções como parâmetros
» # soma dos 1000 primeiros numeros

» def soma1():
»     soma=0
»     cont=0
»     while cont ≤ 1000:
»         soma +=cont
»         cont +=1

» def soma2():
»     soma=0
»     for i in range(1001):
»         soma +=i

» timeit.timeit(soma1, number = 10000)
↳ 0.9234309990024485

» timeit.timeit(soma2, number = 10000)
↳ 0.6420390400016913

» import math
» def soma3():
»     soma = math.fsum(range(1001))    

» timeit.timeit(soma3, number = 10000)
↳ 0.2940528209983313

Vemos que usar range() para gerar uma sequência é mais rápido do que somar um contador um a um. O método math.fsum() é otimizado para velocidade e roda mais rápido de que as operações anteriores.

No exemplo abaixo um bloco de código é executado antes do código cuja execução é medida. Ele é usado para inicializar variáveis e preparar um cabeçalho para a exibição do resultado e seu tempo de execução não é incluído na medida.

» pre='a=10;conta=0;print("Conta |Valor de a");print("----------------")'
» cod='''
» for t in range(100):
»     conta +=1
»     a+=t
» print("{}   |  {}".format(conta, a))
» '''
» t = timeit.timeit(stmt = cod, setup = pre, number=5)
» print('O tempo de execução do código foi de \nt = {} seg'.format(t))
↳ Conta |Valor de a
↳ ----------------
↳ 100   |  4960
↳ 200   |  9910
↳ 300   |  14860
↳ 400   |  19810
↳ 500   |  24760
↳ O tempo de execução do código foi de 
↳ t = 0.0005647910002153367 seg

timeit no Jupyter Notebook

Leia sobre Jupyter Notebook

No Jupyter Notebook existe um método mágico para aplicar timeit a um bloco de código sem necessidade de se importar o módulo. Usamos %timeit comando para medir o tempo de execução do comando, e %%timeit célula para medir o tempo de execução em toda a célula.

No modo de linha várias comandos podem ser separados por ponto e vírgula, (;). Assim como na execução com timeit importado, como várias rodadas de execução do código são medidas, o código é efetivamente executado e, por isso, se deve evitar inserir partes com outputs extensos.

» %timeit r = range(10)
↳ 199 ns ± 9.94 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

» %timeit r = range(1000)
↳ 270 ns ± 18.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

» # o código é avaliado em namespace separado
» print(r)
↳ NameError: name 'r' is not defined

» # comandos alinhados com ;
» %timeit import math; n=10; m=100; math.pow(n,m)
↳ 303 ns ± 16.6 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

» # exemplo de exibição longa:
» %timeit for t in range(100): print(t)

» # 81125 linhas são exibidas

Para medida do tempo de execução de uma célula inteira usamos %%timeit.

» def fatorial(n):
»     if n <= 1: return 1
»     else: return n*fatorial(n-1)

-----------------------------------(início da célula)-------
» %%timeit
» n = 10
» fatorial(n)
-----------------------------------(  fim da célula )-------
↳ 1.54 µs ± 77 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

-----------------------------------(início da célula)-------
» %%timeit
» import math
» n=10
» math.factorial(n)
-----------------------------------(  fim da célula )-------
↳ 250 ns ± 8.43 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

» # em linha
» %timeit math.factorial(10)
↳ 110 ns ± 2.85 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)    	

Para medir o tempo de execução de um bloco de código também podemos usar o método timeit.default_timer() para obter um marco de tempo antes e após sua execução.

» import timeit
» import math

» def funcao_1():
»     soma = 0
»     t = 0
»     while t < 1_000_000:
»         soma += t
»         t += 1
»     return soma

» def funcao_2():
»     nums = [i for i in range(1_000_000)]
»     return math.fsum(nums)
    
» inicio = timeit.default_timer()
» funcao_1()
» intervalo_1 = timeit.default_timer() - inicio

» inicio = timeit.default_timer()
» funcao_2()
» intervalo_2 = timeit.default_timer() - inicio

» print('A função 1 demorou {} seg'.format(intervalo_1))
» print('A função 2 demorou {} seg'.format(intervalo_2))
↳ A função 1 demorou 0.12041138499989756 seg
↳ A função 2 demorou 0.07828983699982928 seg

O método timeit admite as seguintes opções:
Em modo de linha:
%timeit [-n N -r R [-t|-c] -q -p P -o]
Em modo de célula:
%%timeit [-n N -r R [-t|-c] -q -p P -o]
onde as opções são:

opção descrição
-n n executa o bloco n vezes em cada loop. Se não fornecido um valor de ajuste é escolhido,
-r r repete o loop r vezes e toma o melhor resultado. Default: r = 3,
-t usa time.time para medir o tempo, que é o default no Unix,
-c usa time.clock para medir o tempo, que é o default no Windows,
-p p usa precisão de p dígitos para exibir o resultado. Default: p = 3,
-q modo silencioso, não imprime o resultado,
-o retorna TimeitResult que pode ser atribuído a uma variável.

O módulo timeit é considerado mais preciso que time, descrito a seguir. Ele executa, por default, o bloco de código 1 milhão de vezes, retornando o menor tempo de execução. Esse número pode ser alterado com o parâmetro number.

Módulo time

O módulo time possui o método time.time() que retorna o momento de sua execução como um timestamp do Unix. The ctime() transforma esse timestamp em um formato padrão de ano, mês, dia e hora.

» import time
» t = time.time()
» print('Tempo decorrido desde a "época" {} segundos'.format(t))
↳ Tempo decorrido desde a "época" 1625697356.5482924 segundos

» horaLocal = time.ctime(t)
» print("Hora local: {}".format(horaLocal))
↳ Hora local: Wed Jul  7 19:35:56 2021

O método time.sleep(n) pausa a execução do código por n segundos, onde n pode ser um inteiro ou float.

» import time
» ti = time.time()
» time.sleep(3.5)
» tf = time.time()

» print('Pausa de {delta:.2f} segundos'.format(delta=tf - ti))
↳ Pausa de 3.50 segundos

Também existe, no Jupiter Notebook, o método mágico %time que mede o tempo decorrido na execução de uma função, similar ao comando time do Unix. Diferentemente de %timeit esse método também exibe o resultado do cálculo.

-----------------------------------(início da célula)-------	
» %time sum(range(100000))
-----------------------------------(  fim da célula )-------
↳ CPU times: user 2.1 ms, sys: 0 ns, total: 2.1 ms
↳ Wall time: 2.1 ms
↳ 4999950000

-----------------------------------(início da célula)-------
» %%time
» soma = 0
» for t in range(1000):
»     soma+=t
» soma
-----------------------------------(  fim  da célula)-------
↳ CPU times: user 150 µs, sys: 7 µs, total: 157 µs
↳ Wall time: 160 µs
↳ 499500 

» # w está disponível após a operação
» %time w = [u for u in range(1000)]
↳ CPU times: user 36 µs, sys: 8 µs, total: 44 µs
↳ Wall time: 47 µs

» print(w)
↳ [0,1,2,...,999]

Módulo string

O Python é notoriamente bom para o gerenciamento de texto. Uma das extensões dessas funcionalidades está no módulo string que contém uma única função e duas classes. A função é capwords(s, sep=None) que parte a string usando str.split() no separador sep; em seguida ela torna o primeiro caracter de cada parte em maiúsculo, usando str.capitalize(); finalmente junta as partes com str.join(). O separador default é sep=’ ‘ (espaço).

» # usando separador default    
» frase = 'nem tudo que reluz é ouro'
» maiuscula = string.capwords(frase)
» print(maiuscula)
↳ Nem Tudo Que Reluz É Ouro

# usando separador '\n' (quebra de linha)
» frase = 'mais vale um pássaro na mão\nque dois voando'
» maiuscula = string.capwords(frase, sep='\n')
» print(maiuscula)
↳ Mais vale um pássaro na mão
↳ Que dois voando    

Um número de constantes são carregadas com o módulo. Elas são especialmente úteis no tratamento de texto, por exemplo quando se deseja remover toda a pontuação de um texto base.

» # string module constants
» print('1.', string.ascii_letters)
» print('2.', string.ascii_lowercase)
» print('3.', string.ascii_uppercase)
» print('4.', string.digits)
» print('5.', string.hexdigits)
» print('6.', string.whitespace)  # ' \t\n\r\x0b\x0c'
» print('7.', string.punctuation)
↳ 1. abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
↳ 2. abcdefghijklmnopqrstuvwxyz
↳ 3. ABCDEFGHIJKLMNOPQRSTUVWXYZ
↳ 4. 0123456789
↳ 5. 0123456789abcdefABCDEF
↳ 6. 
↳ 
↳ 7. !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

Um exemplo simples de remoção de pontuação de um texto.

» # removendo pontuação de um texto
» txtBasico = 'Partimos de um texto com pontuação, queremos remover essas marcações!'
» pontuacao = string.punctuation
» filtrado =''
» for t in txtBasico:
»     if not t in pontuacao:
»         filtrado += t
» print(filtrado)
↳ Partimos de um texto com pontuação queremos remover essas marcações

O módulo string possui duas classes: Formatter e Template.

Formatter funciona da mesma forma que a função str.format(). A utilidade dessa classe está na possibilidade de derivar dela subclasses para a definição customizada de formatações.

» from string import Formatter
» formatador = Formatter()

» print(formatador.format('{} {}.{}', 'Recomendo o site','phylos', 'net'))
↳ Recomendo o site phylos.net

» print(formatador.format('{site}', site='phylos.net'))
↳ phylos.net

» print(formatador.format('{} {site}', 'Visite o site', site='phylos.net'))
↳ Visite o site phylos.net

» # A função format() tem o mesmo comportamento
» print('{} {website}'.format('Visite o site', website='phylos.net'))
↳ Visite o site phylos.net

A classe Templater é usada para criar templates para substituições em strings. Essa funcionalidade é útil, por exemplo, na criação de aplicativos internacionalizados (contendo mais de uma língua como opção na interface).

» from string import Template
» t = Template('$txt $sobrenome, $nome $sobrenome!')
» ing = t.substitute(txt='My name is', nome='James', sobrenome='Bond')
» pt = t.substitute(txt='Meu nome é', nome='Quim', sobrenome='Joah')

» print(ing)
↳ My name is Bond, James Bond!

» print(pt)
↳ Meu nome é Quim, Joah Quim!
Constantes de Strings
Constante Significado
string.ascii_letters Concatenação de ascii_lowercase e ascii_uppercase descritos abaixo,
string.ascii_lowercase Caracteres minúsculos ‘abcdefghijklmnopqrstuvwxyz’,
string.ascii_uppercase Caracteres maiúsculos ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’,
string.digits Dígitos: a string ‘0123456789’,
string.hexdigits Dígitos hexadecimais: a string ‘0123456789abcdefABCDEF’,
string.octdigits Dígitos octais: string ‘01234567’,
string.punctuation Caracteres ASCII considerados pontuação local: !”#$%&'()*+,-./:;<=>?@[\]^_`{|}~,
string.printable Caracteres ASCII imprimíveis: digits, ascii_letters, punctuation, e whitespace,
string.whitespace String com todos os caracteres ASCII impressos como espaços em branco (space, tab, linefeed, return, formfeed, vertical tab).
🔺Início do artigo

Bibliografia

Consulte a bibliografia no final do primeiro artigo dessa série.