0 Como usar este manual
Um roteiro de laboratório, não um livro de teoria: cada assunto aparece como um experimento curto, pronto para ser digitado, executado e modificado.
Os códigos seguem a numeração CÓDIGO seção.item, de modo que qualquer exemplo pode ser citado em aula ou em uma lista de exercícios. Cada bloco preto traz o programa completo e, logo abaixo, a saída real produzida pelo interpretador: nenhuma saída deste manual foi digitada à mão, todas vieram da execução do próprio código em Python 3.12.
Os exemplos foram mantidos curtos de propósito. Quando um assunto exige um programa maior, ele aparece separado, no fim da seção ou na seção 16, para que o conceito nunca fique escondido dentro de um exercício longo demais.
Elementos da página
- Bloco preto: o programa. Use o botão copiar no canto direito para levá-lo ao editor.
- Saída: o que aparece no terminal ao executar aquele programa.
- Nota: informação complementar que vale conhecer.
- Atenção: armadilha frequente, do tipo que custa uma tarde de depuração.
- Dica: atalho ou boa prática da comunidade Python.
- Sintaxe: a forma geral da construção que está sendo apresentada.
- Experimentos propostos: ao fim de cada seção, quatro tarefas curtas para fixar o conteúdo.
Roteiro sugerido
As seções 1 a 5 formam a base indispensável e devem ser feitas na ordem. As seções 6 a 8 tratam de coleções e texto, onde a maior parte dos exercícios de disciplina se resolve. As seções 9 a 11 organizam o código em funções, módulos e objetos. As seções 12 a 15 preparam o programa para o mundo real, com arquivos, erros e estilo. A seção 16 reúne projetos completos e os apêndices servem de consulta rápida durante as avaliações.
Primeiros passos
Escrever, executar, entrar e sair com dados, nomear valores.
1Estrutura fundamental
Como um programa Python é escrito, comentado e executado. As convenções desta seção valem para todo o restante do manual.
Python é uma linguagem interpretada, de tipagem dinâmica e indentação significativa. Não existe declaração de tipo, não existem chaves delimitando blocos e não há ponto e vírgula obrigatório no fim das linhas. O que organiza o programa é o recuo do texto.
Como executar os exemplos
- Terminal: salve o arquivo como
exemplo.pye rodepython3 exemplo.py. - Modo interativo: digite
python3e teste expressões linha a linha (ótimo para experimentar). - Editor: VS Code com a extensão Python, ou Thonny para quem está começando.
- Navegador: Google Colab, sem instalar nada.
A função print() escreve na saída padrão e pula uma linha ao final.
# Uma linha ja e um programa completo.
print("Olá, mundo!")
print("Manual de Experimentos com Python")Olá, mundo! Manual de Experimentos com Python
Aspas triplas na primeira linha de um módulo, função ou classe formam a docstring, acessível em tempo de execução por __doc__ e por help().
# Comentario de linha: tudo apos o # e ignorado.
print("Executando") # comentario no fim da linha
def area_circulo(raio):
"""Retorna a área de um círculo de raio informado."""
return 3.14159 * raio ** 2
print(area_circulo(2))
print(area_circulo.__doc__)Executando 12.56636 Retorna a área de um círculo de raio informado.
Quatro espaços por nível é o padrão da comunidade (PEP 8). Nunca misture espaços e tabulações no mesmo arquivo.
temperatura = 31
if temperatura > 30:
print("Dentro do bloco: está calor")
print("Ainda dentro do bloco")
print("Fora do bloco: executa sempre")Dentro do bloco: está calor Ainda dentro do bloco Fora do bloco: executa sempre
Vale conhecer a mensagem antes de encontrá-la em uma avaliação.
if 10 > 5:
print("faltou recuar esta linha") File "exemplo.py", line 2
print("faltou recuar esta linha")
^
IndentationError: expected an indented block after 'if' statement on line 1# Ponto e virgula no fim da linha nao e necessario.
nome = "Python"
# Forma preferida: quebrar dentro de parenteses.
total = (10 + 20 + 30 +
40 + 50)
# Alternativa com barra invertida (use com moderacao).
media = 10 + 20 \
+ 30
print(nome, total, media)Python 150 60
Experimentos propostos
- Escreva um programa que imprima seu nome, seu curso e o semestre em três linhas.
- Crie uma função
area_retangulo(base, altura)com docstring e imprima__doc__. - Remova propositalmente a indentação de um bloco e anote a mensagem de erro completa.
2Entrada e saída de dados
Mostrar resultados na tela, ler dados do teclado e converter texto em número. Três estilos de formatação convivem em Python: aqui você vê os três e aprende qual usar.
Os argumentos são separados por um espaço automático.
print("Olá", "mundo", 2026)
print(42)
print("Soma:", 2 + 3)Olá mundo 2026 42 Soma: 5
sep troca o separador entre argumentos e end troca o que vem depois do último.
print("A", "B", "C", sep="-")
print("2026", "07", "22", sep="/")
print("Esta linha", end=" ")
print("continua aqui.")
print("Sem quebra no fim", end="")
print(" | e o resto vem junto")A-B-C 2026/07/22 Esta linha continua aqui. Sem quebra no fim | e o resto vem junto
Mesmo quando o usuário digita números, o retorno é texto. Repare no tipo exibido.
nome = input("Digite seu nome: ")
idade = input("Digite sua idade: ")
print("Olá,", nome)
print("Tipo do que foi digitado:", type(idade))Digite seu nome: Ramon Digite sua idade: 38 Olá, Ramon Tipo do que foi digitado: <class 'str'>
int() e float() convertem texto em número. Se o texto não representar um número, ocorre ValueError (tratado na seção 13).
idade = int(input("Idade: "))
altura = float(input("Altura em metros: "))
print("No ano que vem você terá", idade + 1)
print("Altura em centímetros:", altura * 100)Idade: 38 Altura em metros: 1.78 No ano que vem você terá 39 Altura em centímetros: 178.0
Três estilos de formatação
Prefixo f antes das aspas. Qualquer expressão Python pode ir entre chaves.
nome = "Maria"
idade = 25
preco = 29.9
print(f"Nome: {nome}")
print(f"{nome} tem {idade} anos e no ano que vem terá {idade + 1}")
print(f"Preço: R$ {preco:.2f}")Nome: Maria Maria tem 25 anos e no ano que vem terá 26 Preço: R$ 29.90
A sintaxe é {valor:formato}. O sufixo = imprime a expressão e o resultado, útil durante a depuração.
valor = 1234.5678
taxa = 0.0725
item = "Cabo"
print(f"Moeda: {valor:,.2f}")
print(f"Percentual: {taxa:.2%}")
print(f"Científico: {valor:.3e}")
print(f"Zeros: {42:05d}")
print(f"Alinhado: |{item:<10}|{item:>10}|{item:^10}|")
print(f"Depuração: {valor=}")Moeda: 1,234.57 Percentual: 7.25% Científico: 1.235e+03 Zeros: 00042 Alinhado: |Cabo | Cabo| Cabo | Depuração: valor=1234.5678
Estilo anterior às f-strings. Você ainda encontra muito código assim, e ele é útil quando o texto do modelo vem de fora do programa.
nome, idade = "João", 30
print("Nome: {}, Idade: {}".format(nome, idade))
print("Trocando a ordem: {1} anos, {0}".format(nome, idade))
print("Com nomes: {n} ganha R$ {s:.2f}".format(n=nome, s=3500.5))Nome: João, Idade: 30 Trocando a ordem: 30 anos, João Com nomes: João ganha R$ 3500.50
Herança da linguagem C. Aparece em códigos antigos e em mensagens de log.
nome, idade, nota = "Ana", 28, 8.75
print("Nome: %s" % nome)
print("%s tem %d anos e nota %.1f" % (nome, idade, nota))
print("Largura fixa: |%10s|%3d|" % (nome, idade))Nome: Ana Ana tem 28 anos e nota 8.8 Largura fixa: | Ana| 28|
| Estilo | Exemplo | Quando usar |
|---|---|---|
| f-string | f"{n}" | Padrão em código novo (Python 3.6+) |
| .format() | "{}".format(n) | Modelos de texto vindos de arquivo ou banco |
| % | "%s" % n | Código legado e módulo logging |
Entrada, conversão, cálculo e saída formatada em um só roteiro.
nome = input("Aluno: ")
n1 = float(input("Nota 1: "))
n2 = float(input("Nota 2: "))
media = (n1 + n2) / 2
situacao = "Aprovado" if media >= 7 else "Reprovado"
print()
print(f"{'RESULTADO':^28}")
print("-" * 28)
print(f"{'Aluno:':<12}{nome}")
print(f"{'Média:':<12}{media:.2f}")
print(f"{'Situação:':<12}{situacao}")Aluno: Beatriz
Nota 1: 8.5
Nota 2: 6.0
RESULTADO
----------------------------
Aluno: Beatriz
Média: 7.25
Situação: AprovadoExperimentos propostos
- Peça dois números e imprima soma, diferença, produto e quociente com duas casas decimais.
- Peça o preço de um produto e imprima o valor com desconto de 12%, alinhado em coluna de largura 12.
- Reescreva o CÓDIGO 2.9 usando
.format()e depois usando%. Compare a legibilidade.
3Tipos de dados e variáveis
Os tipos primitivos, as operações que eles suportam e as armadilhas de conversão que mais aparecem em provas e em laboratório.
Uma variável em Python é um nome ligado a um objeto. O tipo pertence ao objeto, não ao nome, e por isso o mesmo nome pode apontar para valores de tipos diferentes ao longo do programa.
idade = 25 # int
altura = 1.78 # float
nome = "Python" # str
ativo = True # bool
print(idade, type(idade))
print(altura, type(altura))
print(nome, type(nome))
print(ativo, type(ativo))25 <class 'int'> 1.78 <class 'float'> Python <class 'str'> True <class 'bool'>
a, b, c = 1, 2, 3
x = y = z = 100
print(a, b, c, x, y, z)
# Troca sem variavel auxiliar (bem pythonico)
a, b = b, a
print("Depois da troca:", a, b)
# Nome descartavel por convencao
_, sobrenome = "Ramon Martins".split()
print(sobrenome)1 2 3 100 100 100 Depois da troca: 2 1 Martins
Operações numéricas
a, b = 15, 4
print("soma ", a + b)
print("subtração ", a - b)
print("multiplicação ", a * b)
print("divisão ", a / b) # sempre float
print("divisão inteira", a // b) # descarta a parte fracionaria
print("resto ", a % b)
print("potência ", a ** b)soma 19 subtração 11 multiplicação 60 divisão 3.75 divisão inteira 3 resto 3 potência 50625
x = 10
x += 5 # x = x + 5
x *= 2 # x = x * 2
x -= 4
print("x =", x)
print(abs(-7.5), round(3.14159, 2), pow(2, 10))
print(min(3, 9, 1), max(3, 9, 1), sum([3, 9, 1]))
print(divmod(17, 5)) # quociente e resto de uma vezx = 26 7.5 3.14 1024 1 9 13 (3, 2)
import math
a = 0.1 + 0.2
print(a)
print("a == 0.3?", a == 0.3)
print("próximo o bastante?", math.isclose(a, 0.3))
from decimal import Decimal
print(Decimal("0.1") + Decimal("0.2"))0.30000000000000004 a == 0.3? False próximo o bastante? True 0.3
print(int("42") + 8)
print(float("19.99"))
print(str(2026) + "/2")
print(int(8.75)) # trunca, nao arredonda
print(round(8.75)) # arredonda
print(int("1010", 2)) # base 2
# Conversao que falha
# int("abc") -> ValueError: invalid literal for int()50 19.99 2026/2 8 9 10
Booleanos e valores verdadeiros
nota, frequencia = 8.5, 85
aprovado = nota >= 7 and frequencia >= 75
print("Aprovado:", aprovado)
print("Não aprovado:", not aprovado)
print("Recuperação possível:", nota >= 4 or frequencia >= 90)
# True e False sao inteiros disfarcados
print(True + True, int(False))Aprovado: True Não aprovado: False Recuperação possível: True 2 0
Zero, vazio e None são falsos. Todo o resto é verdadeiro. Por isso if lista: já testa se a lista tem elementos.
vazios = [0, 0.0, "", [], {}, set(), None]
cheios = [1, -3, "texto", [0], {"a": 1}, {0}]
for v in vazios:
print(f"{repr(v):>8} -> {bool(v)}")
print("---")
print("todos verdadeiros?", all(bool(v) for v in cheios)) 0 -> False
0.0 -> False
'' -> False
[] -> False
{} -> False
set() -> False
None -> False
---
todos verdadeiros? TruePrefira isinstance(): ele respeita herança e aceita uma tupla de tipos.
valor = 3.14
print(type(valor))
print(type(valor) == float)
print(isinstance(valor, float))
print(isinstance(valor, (int, float))) # aceita varios tipos
def dobrar(x):
if isinstance(x, (int, float)):
return x * 2
return "Erro: não é número"
print(dobrar(10), dobrar("abc"))<class 'float'> True True True 20 Erro: não é número
Compare com is None, nunca com == None.
resultado = None # ausencia de valor
print(resultado, type(resultado))
print("é None?", resultado is None)
# Convencoes de nome (PEP 8)
taxa_juros = 0.05 # snake_case para variaveis
VELOCIDADE_LUZ = 299792458 # MAIUSCULAS para constantes
print(taxa_juros, VELOCIDADE_LUZ)None <class 'NoneType'> é None? True 0.05 299792458
| Operador | Nome | Exemplo | Resultado |
|---|---|---|---|
+ | soma | 7 + 2 | 9 |
- | subtração | 7 - 2 | 5 |
* | multiplicação | 7 * 2 | 14 |
/ | divisão real | 7 / 2 | 3.5 |
// | divisão inteira | 7 // 2 | 3 |
% | resto | 7 % 2 | 1 |
** | potência | 7 ** 2 | 49 |
Experimentos propostos
- Peça um número de segundos e converta para horas, minutos e segundos usando
//e%. - Verifique se
1.1 + 2.2 == 3.3e corrija a comparação commath.isclose. - Escreva uma função que receba qualquer valor e devolva o texto
"numérico"ou"não numérico". - Explique por que
int(-8.7)eround(-8.7)dão resultados diferentes.
Controle de fluxo
Decidir caminhos e repetir tarefas sem repetir código.
4Estruturas de decisão
Fazer o programa escolher um caminho. Em Python isso se resume a if, elif, else e, desde a versão 3.10, match/case.
- Dois pontos sempre encerram a linha da condição.
- O bloco é definido pela indentação, não por chaves.
- Os operadores lógicos são palavras:
and,or,not. elifsubstitui oelse ifde outras linguagens.
a = 10
if a < 20:
print("a é menor que 20")
print("fim")a é menor que 20 fim
saldo = 100.0
compra = 149.9
if saldo >= compra:
print("Compra aprovada")
else:
print(f"Faltam R$ {compra - saldo:.2f}")Faltam R$ 49.90
A ordem importa: o primeiro teste verdadeiro vence e os demais nem são avaliados.
media = 6.4
if media >= 9:
conceito = "A"
elif media >= 7:
conceito = "B"
elif media >= 5:
conceito = "C"
else:
conceito = "D"
print(f"Média {media} -> conceito {conceito}")Média 6.4 -> conceito C
Funciona, mas dois níveis já pedem atenção. O CÓDIGO 4.6 resolve o mesmo caso sem aninhamento.
nota = 8.0
frequencia = 60
if nota >= 7:
if frequencia >= 75:
print("Aprovado")
else:
print("Reprovado por frequência")
else:
print("Reprovado por nota")Reprovado por frequência
| Operador | Significado | Exemplo verdadeiro |
|---|---|---|
== | igual a | 3 == 3 |
!= | diferente de | 3 != 4 |
> | maior que | 4 > 3 |
< | menor que | 3 < 4 |
>= | maior ou igual | 3 >= 3 |
<= | menor ou igual | 3 <= 4 |
in | pertence a | "a" in "casa" |
is | é o mesmo objeto | x is None |
nota, frequencia = 8.0, 60
if nota >= 7 and frequencia >= 75:
print("Aprovado")
elif nota >= 7 and frequencia < 75:
print("Reprovado por frequência")
else:
print("Reprovado por nota")
print("Tem alguma pendência?", not (nota >= 7 and frequencia >= 75))Reprovado por frequência Tem alguma pendência? True
Escrever 18 <= idade < 60 é mais claro do que idade >= 18 and idade < 60.
idade = 25
temperatura = 36.8
# Em Python isso e legal e legivel:
if 18 <= idade < 60:
print("Faixa adulta")
if 36.0 <= temperatura <= 37.5:
print("Temperatura normal")Faixa adulta Temperatura normal
Funciona em strings, listas, tuplas, conjuntos e dicionários (nas chaves).
vogais = "aeiou"
letra = "e"
print(letra in vogais)
turma = ["Ana", "Bruno", "Carlos"]
print("Diana" not in turma)
if letra in vogais and "Ana" in turma:
print("As duas verificações passaram")True True As duas verificações passaram
Use apenas quando a linha continuar legível. Encadear ternários costuma piorar o código.
idade = 17
status = "maior" if idade >= 18 else "menor"
print(f"Você é {status} de idade")
nota = 6.5
print("Aprovado" if nota >= 7 else "Recuperação")Você é menor de idade Recuperação
Mais do que um switch: match compara estruturas e já extrai valores.
def descrever(comando):
match comando.split():
case ["ligar"]:
return "Ligando o equipamento"
case ["desligar"]:
return "Desligando"
case ["canal", numero]:
return f"Mudando para o canal {numero}"
case _:
return "Comando desconhecido"
for c in ["ligar", "canal 12", "reiniciar"]:
print(f"{c:12} -> {descrever(c)}")ligar -> Ligando o equipamento canal 12 -> Mudando para o canal 12 reiniciar -> Comando desconhecido
print("=== MENU ===")
print("1 - Cadastrar")
print("2 - Consultar")
print("0 - Sair")
opcao = input("Escolha: ")
if opcao == "1":
print("Cadastro selecionado")
elif opcao == "2":
print("Consulta selecionada")
elif opcao == "0":
print("Encerrando")
else:
print("Opção inválida")=== MENU === 1 - Cadastrar 2 - Consultar 0 - Sair Escolha: 2 Consulta selecionada
entrada = input("Digite algo: ")
if entrada.isdigit():
numero = int(entrada)
tipo = "par" if numero % 2 == 0 else "ímpar"
print(f"Número inteiro {tipo}")
elif entrada.replace(".", "", 1).isdigit():
print("Número com casas decimais")
elif entrada.isalpha():
print("Somente letras")
else:
print("Combinação de caracteres")Digite algo: 144 Número inteiro par
Experimentos propostos
- Peça três notas e informe o conceito (A a D) usando
elif. - Escreva um verificador de senha: mínimo 8 caracteres, com pelo menos um dígito.
- Refaça o CÓDIGO 4.4 sem aninhamento, usando
and. - Converta o menu do CÓDIGO 4.11 para
match/case.
5Estruturas de repetição
for percorre coleções, while repete enquanto uma condição for verdadeira. Saber escolher entre os dois evita metade dos laços infinitos.
- for: use quando a quantidade de repetições é conhecida ou quando existe algo a percorrer.
- while: use quando a repetição depende de um evento, como uma resposta do usuário.
breakencerra o laço,continuepula para a próxima volta.- Python não tem
++; use+= 1.
range(5) gera 0, 1, 2, 3, 4. O fim é sempre exclusivo.
for i in range(5):
print("volta", i)volta 0 volta 1 volta 2 volta 3 volta 4
print(list(range(10, 15)))
print(list(range(0, 21, 5)))
print(list(range(10, 0, -2)))
for i in range(1, 6):
print(f"{i} ao quadrado = {i ** 2}")[10, 11, 12, 13, 14] [0, 5, 10, 15, 20] [10, 8, 6, 4, 2] 1 ao quadrado = 1 2 ao quadrado = 4 3 ao quadrado = 9 4 ao quadrado = 16 5 ao quadrado = 25
Percorra os elementos diretamente. Usar range(len(lista)) só é necessário quando você precisa alterar a lista pelo índice.
frutas = ["maçã", "banana", "laranja"]
for fruta in frutas:
print(f"- {fruta} ({len(fruta)} letras)")- maçã (4 letras) - banana (6 letras) - laranja (7 letras)
palavra = "engenharia"
vogais = 0
for letra in palavra:
if letra in "aeiou":
vogais += 1
print(f"{palavra} tem {vogais} vogais")engenharia tem 5 vogais
cores = ["vermelho", "azul", "verde"]
for i, cor in enumerate(cores):
print(i, cor)
print("---")
for posicao, cor in enumerate(cores, start=1):
print(f"{posicao}º lugar: {cor}")0 vermelho 1 azul 2 verde --- 1º lugar: vermelho 2º lugar: azul 3º lugar: verde
zip para na menor das sequências.
alunos = ["Ana", "Bruno", "Carlos"]
notas = [9.5, 7.0, 8.2]
for aluno, nota in zip(alunos, notas):
print(f"{aluno:<8} {nota:>4.1f}")
print(dict(zip(alunos, notas)))Ana 9.5
Bruno 7.0
Carlos 8.2
{'Ana': 9.5, 'Bruno': 7.0, 'Carlos': 8.2}Esqueça o i += 1 e o laço nunca termina. Interrompa com Ctrl+C.
i = 0
while i < 5:
print("valor:", i)
i += 1
print("fim do laço")valor: 0 valor: 1 valor: 2 valor: 3 valor: 4 fim do laço
numero = 1
soma = 0
while numero <= 10:
soma += numero
numero += 1
print("soma de 1 a 10:", soma)
print("conferindo:", sum(range(1, 11)))soma de 1 a 10: 55 conferindo: 55
for i in range(1, 100):
if i * i > 50:
print(f"o primeiro quadrado acima de 50 é {i * i}")
break
print(i * i, end=" ")1 4 9 16 25 36 49 o primeiro quadrado acima de 50 é 64
for i in range(1, 11):
if i % 3 == 0:
continue
print(i, end=" ")
print("\n(múltiplos de 3 foram pulados)")1 2 4 5 7 8 10 (múltiplos de 3 foram pulados)
O else do laço executa apenas se o laço terminar sem break. É a forma limpa de dizer "não encontrei".
nomes = ["Ana", "Bruno", "Carlos"]
procurado = "Diana"
for nome in nomes:
if nome == procurado:
print("encontrado")
break
else:
print(f"{procurado} não está na lista")Diana não está na lista
while True com break é o padrão para menus.
while True:
print("\n1 - Somar | 2 - Sobre | 0 - Sair")
opcao = input("Opção: ")
if opcao == "1":
a = float(input("a: "))
b = float(input("b: "))
print("resultado:", a + b)
elif opcao == "2":
print("Manual de Experimentos com Python")
elif opcao == "0":
print("Encerrando")
break
else:
print("Opção inválida")1 - Somar | 2 - Sobre | 0 - Sair Opção: 1 a: 2 b: 3 resultado: 5.0 1 - Somar | 2 - Sobre | 0 - Sair Opção: 2 Manual de Experimentos com Python 1 - Somar | 2 - Sobre | 0 - Sair Opção: 0 Encerrando
O laço interno completa todas as voltas a cada volta do externo.
for i in range(1, 4):
print(f"\nTabuada do {i}")
for j in range(1, 6):
print(f" {i} x {j} = {i * j}")Tabuada do 1 1 x 1 = 1 1 x 2 = 2 1 x 3 = 3 1 x 4 = 4 1 x 5 = 5 Tabuada do 2 2 x 1 = 2 2 x 2 = 4 2 x 3 = 6 2 x 4 = 8 2 x 5 = 10 Tabuada do 3 3 x 1 = 3 3 x 2 = 6 3 x 3 = 9 3 x 4 = 12 3 x 5 = 15
Combinação de while, try e break que aparece em quase todo programa interativo.
while True:
try:
idade = int(input("Idade (0 a 120): "))
except ValueError:
print("Digite apenas números inteiros")
continue
if 0 <= idade <= 120:
break
print("Fora da faixa permitida")
print("Idade registrada:", idade)Idade (0 a 120): abc Digite apenas números inteiros Idade (0 a 120): 999 Fora da faixa permitida Idade (0 a 120): 38 Idade registrada: 38
Experimentos propostos
- Some apenas os números pares entre 1 e 100 usando
for. - Peça números ao usuário até que ele digite 0 e informe a média dos valores digitados.
- Imprima a tabuada completa de 1 a 10 em colunas alinhadas.
- Escreva um jogo de adivinhação: o programa sorteia um número e o usuário tem 5 tentativas.
Coleções e texto
Guardar muitos valores, percorrê-los e transformá-los.
6Estruturas de dados
Lista, tupla, dicionário e conjunto. Escolher a estrutura certa costuma simplificar mais o programa do que qualquer truque de sintaxe.
| Estrutura | Sintaxe | Ordenada | Mutável | Duplicatas | Uso típico |
|---|---|---|---|---|---|
| Lista | [1, 2, 3] | sim | sim | sim | sequência que muda |
| Tupla | (1, 2, 3) | sim | não | sim | registro fixo |
| Dicionário | {"a": 1} | sim | sim | chaves únicas | associar chave a valor |
| Conjunto | {1, 2, 3} | não | sim | não | eliminar repetidos |
Listas
frutas = ["maçã", "banana", "laranja"]
mista = ["Python", 3.12, True, None]
print(frutas[0]) # primeiro
print(frutas[-1]) # ultimo
print(len(frutas), len(mista))maçã laranja 3 4
animais = ["gato", "cachorro"]
animais.append("pássaro") # no fim
animais.insert(1, "peixe") # na posicao 1
print(animais)
animais.remove("gato") # por valor
ultimo = animais.pop() # remove e devolve o ultimo
print(ultimo, animais)
animais.extend(["arara", "tatu"])
print(animais)['gato', 'peixe', 'cachorro', 'pássaro'] pássaro ['peixe', 'cachorro'] ['peixe', 'cachorro', 'arara', 'tatu']
numeros = [12, 5, 8, 5, 20]
print("tamanho:", len(numeros))
print("soma:", sum(numeros))
print("maior/menor:", max(numeros), min(numeros))
print("média:", sum(numeros) / len(numeros))
print("o 5 aparece", numeros.count(5), "vezes")
print("posição do 8:", numeros.index(8))
print("20 está na lista?", 20 in numeros)tamanho: 5 soma: 50 maior/menor: 20 5 média: 10.0 o 5 aparece 2 vezes posição do 8: 2 20 está na lista? True
sorted() devolve uma nova lista; .sort() modifica a original e devolve None.
notas = [7.5, 9.0, 5.5, 8.0]
print(sorted(notas)) # copia ordenada
print(sorted(notas, reverse=True))
print("original intacta:", notas)
notas.sort() # ordena no lugar
print("depois de sort():", notas)
nomes = ["carlos", "Ana", "bruno"]
print(sorted(nomes, key=str.lower))[5.5, 7.5, 8.0, 9.0] [9.0, 8.0, 7.5, 5.5] original intacta: [7.5, 9.0, 5.5, 8.0] depois de sort(): [5.5, 7.5, 8.0, 9.0] ['Ana', 'bruno', 'carlos']
A forma geral é [início:fim:passo], com o fim sempre exclusivo.
letras = ["a", "b", "c", "d", "e", "f", "g"]
print(letras[:3]) # inicio ate 2
print(letras[-3:]) # ultimos tres
print(letras[2:5]) # do meio
print(letras[::2]) # de dois em dois
print(letras[::-1]) # invertida['a', 'b', 'c'] ['e', 'f', 'g'] ['c', 'd', 'e'] ['a', 'c', 'e', 'g'] ['g', 'f', 'e', 'd', 'c', 'b', 'a']
Atribuir uma lista a outro nome não copia nada. É o erro silencioso mais comum de quem está começando.
original = [1, 2, 3]
apelido = original # mesmo objeto
copia = original.copy() # objeto novo (ou original[:])
apelido.append(99)
print("original:", original)
print("apelido:", apelido)
print("cópia:", copia)
print("apelido é o mesmo objeto?", apelido is original)original: [1, 2, 3, 99] apelido: [1, 2, 3, 99] cópia: [1, 2, 3] apelido é o mesmo objeto? True
matriz = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
print(matriz[1][2]) # linha 1, coluna 2
for linha in matriz:
print(" ".join(f"{v:3d}" for v in linha))
diagonal = [matriz[i][i] for i in range(3)]
print("diagonal:", diagonal)6 1 2 3 4 5 6 7 8 9 diagonal: [1, 5, 9]
Tuplas
(42) é apenas o número 42 entre parênteses. A vírgula é o que cria a tupla.
coordenada = (10, 20)
cores = ("vermelho", "azul", "verde")
sozinha = (42,) # a virgula e obrigatoria
sem_parenteses = 1, 2, 3
print(coordenada[0], cores[-1], sozinha, sem_parenteses)
print(type(sozinha), type((42)))10 verde (42,) (1, 2, 3) <class 'tuple'> <class 'int'>
cores = ("vermelho", "azul")
try:
cores[0] = "amarelo"
except TypeError as erro:
print("Erro:", erro)
# Para "mudar", crie outra tupla
cores = cores + ("verde",)
print(cores)Erro: 'tuple' object does not support item assignment
('vermelho', 'azul', 'verde')ponto = (15, 25)
x, y = ponto
print(x, y)
pessoa = ("Ramon", 38, "São José")
nome, idade, cidade = pessoa
print(f"{nome}, {idade}, {cidade}")
# O asterisco recolhe o resto
primeiro, *meio, ultimo = [1, 2, 3, 4, 5]
print(primeiro, meio, ultimo)15 25 Ramon, 38, São José 1 [2, 3, 4] 5
Dicionários
[] gera KeyError se a chave não existir; .get() devolve None ou o padrão que você escolher.
aluno = {
"nome": "Maria",
"curso": "Telecomunicações",
"fase": 4,
}
print(aluno["nome"])
print(aluno.get("fase"))
print(aluno.get("email", "não informado")) # valor padraoMaria 4 não informado
estudante = {"nome": "Ana", "curso": "Python"}
estudante["fase"] = 2 # adiciona
estudante["curso"] = "Ciência de Dados" # atualiza
estudante.update({"nota": 9.5, "ativo": True})
print(estudante)
nota = estudante.pop("nota") # remove e devolve
del estudante["ativo"] # remove
print(nota, estudante){'nome': 'Ana', 'curso': 'Ciência de Dados', 'fase': 2, 'nota': 9.5, 'ativo': True}
9.5 {'nome': 'Ana', 'curso': 'Ciência de Dados', 'fase': 2}notas = {"João": 8.5, "Maria": 9.0, "Pedro": 7.5}
for nome in notas: # percorre as chaves
print(nome, end=" ")
print()
for nota in notas.values():
print(nota, end=" ")
print()
for nome, nota in notas.items(): # forma mais usada
print(f"{nome:<8} {nota:>4.1f}")João Maria Pedro 8.5 9.0 7.5 João 8.5 Maria 9.0 Pedro 7.5
O padrão d[k] = d.get(k, 0) + 1 resolve qualquer contagem. A seção 14 mostra a versão com Counter.
texto = "engenharia de telecomunicacoes"
contagem = {}
for letra in texto:
if letra == " ":
continue
contagem[letra] = contagem.get(letra, 0) + 1
mais_comuns = sorted(contagem.items(),
key=lambda par: par[1],
reverse=True)
print(mais_comuns[:5])[('e', 6), ('n', 3), ('a', 3), ('c', 3), ('i', 2)]turma = {
"Ana": {"notas": [8.5, 9.0], "faltas": 2},
"Bruno": {"notas": [7.0, 6.0], "faltas": 6},
}
for nome, dados in turma.items():
notas = dados["notas"]
media = sum(notas) / len(notas)
print(f"{nome:<6} média {media:.1f} faltas {dados['faltas']}")Ana média 8.8 faltas 2 Bruno média 6.5 faltas 6
Conjuntos
frutas = {"maçã", "banana", "maçã"}
print(frutas)
numeros = [1, 2, 2, 3, 3, 3, 4]
print(set(numeros))
print("sem repetidos, ordenado:", sorted(set(numeros)))
vazio = set() # cuidado: {} cria um dicionario
print(type(vazio), type({})){'maçã', 'banana'}
{1, 2, 3, 4}
sem repetidos, ordenado: [1, 2, 3, 4]
<class 'set'> <class 'dict'>cores = {"vermelho", "azul"}
cores.add("amarelo")
cores.update(["verde", "roxo"])
cores.discard("inexistente") # nao gera erro
cores.remove("roxo") # geraria KeyError se faltasse
print(sorted(cores))['amarelo', 'azul', 'verde', 'vermelho']
Também existem os métodos .union(), .intersection(), .difference() e .symmetric_difference().
turma_a = {"Ana", "Bruno", "Carlos", "Diana"}
turma_b = {"Bruno", "Diana", "Eduardo"}
print("união: ", sorted(turma_a | turma_b))
print("interseção: ", sorted(turma_a & turma_b))
print("só na turma A:", sorted(turma_a - turma_b))
print("exclusivos: ", sorted(turma_a ^ turma_b))união: ['Ana', 'Bruno', 'Carlos', 'Diana', 'Eduardo'] interseção: ['Bruno', 'Diana'] só na turma A: ['Ana', 'Carlos'] exclusivos: ['Ana', 'Carlos', 'Eduardo']
vogais = {"a", "e", "i", "o", "u"}
algumas = {"a", "e"}
consoantes = {"x", "y", "z"}
print("a é vogal?", "a" in vogais)
print("subconjunto?", algumas.issubset(vogais))
print("superconjunto?", vogais.issuperset(algumas))
print("sem elementos comuns?", vogais.isdisjoint(consoantes))a é vogal? True subconjunto? True superconjunto? True sem elementos comuns? True
Pilha e fila
lista.pop(0) também funciona como fila, mas é lento em listas grandes porque desloca todos os elementos.
from collections import deque
# Pilha: ultimo a entrar, primeiro a sair
pilha = []
pilha.append("página 1")
pilha.append("página 2")
print("desempilhou:", pilha.pop(), "| resta:", pilha)
# Fila: primeiro a entrar, primeiro a sair
fila = deque(["cliente 1", "cliente 2"])
fila.append("cliente 3")
print("atendeu:", fila.popleft(), "| resta:", list(fila))desempilhou: página 2 | resta: ['página 1'] atendeu: cliente 1 | resta: ['cliente 2', 'cliente 3']
registros = ["ok", "erro", "ok", "ok", "erro"]
print("lista mantém a ordem e as repetições:", registros)
print("conjunto responde 'quais tipos existem':", set(registros))
resumo = {}
for r in registros:
resumo[r] = resumo.get(r, 0) + 1
print("dicionário responde 'quantos de cada':", resumo)
print("tupla protege o que não muda:", tuple(sorted(set(registros))))lista mantém a ordem e as repetições: ['ok', 'erro', 'ok', 'ok', 'erro']
conjunto responde 'quais tipos existem': {'ok', 'erro'}
dicionário responde 'quantos de cada': {'ok': 3, 'erro': 2}
tupla protege o que não muda: ('erro', 'ok')Experimentos propostos
- Leia 5 números, guarde em uma lista e informe maior, menor e média.
- Dadas duas listas de alunos, descubra quem está nas duas usando conjuntos.
- Monte um dicionário de agenda (nome para telefone) com opções de incluir, consultar e remover.
- Explique por que
a = bea = b.copy()produzem comportamentos diferentes ao alterar a lista.
7Compreensões
A forma idiomática de criar listas, dicionários e conjuntos a partir de outra coleção. Substitui laços de três ou quatro linhas por uma expressão legível.
# Versao com laco
quadrados = []
for n in range(1, 6):
quadrados.append(n ** 2)
print(quadrados)
# Mesma coisa em uma linha
quadrados = [n ** 2 for n in range(1, 6)]
print(quadrados)[1, 4, 9, 16, 25] [1, 4, 9, 16, 25]
O if no fim seleciona quais itens entram.
numeros = [12, 7, 30, 5, 18, 3]
pares = [n for n in numeros if n % 2 == 0]
grandes = [n for n in numeros if n > 10]
print(pares)
print(grandes)
nomes = ["ana", "Bruno", "carlos"]
print([n.title() for n in nomes if n[0].islower()])[12, 30, 18] [12, 30, 18] ['Ana', 'Carlos']
Quando o if/else aparece antes do for, ele escolhe o valor, não filtra a lista.
notas = [9.0, 5.5, 7.0, 4.0]
situacao = ["aprovado" if n >= 7 else "reprovado" for n in notas]
print(situacao)
ajustadas = [min(n + 1, 10) if n < 7 else n for n in notas]
print(ajustadas)['aprovado', 'reprovado', 'aprovado', 'reprovado'] [9.0, 6.5, 7.0, 5.0]
A ordem dos for é a mesma dos laços equivalentes, de fora para dentro.
matriz = [[1, 2, 3], [4, 5, 6]]
plana = [valor for linha in matriz for valor in linha]
print(plana)
tabela = [[i * j for j in range(1, 5)] for i in range(1, 4)]
for linha in tabela:
print(linha)[1, 2, 3, 4, 5, 6] [1, 2, 3, 4] [2, 4, 6, 8] [3, 6, 9, 12]
alunos = ["Ana", "Bruno", "Carlos"]
notas = [9.5, 7.0, 8.2]
boletim = {a: n for a, n in zip(alunos, notas)}
print(boletim)
aprovados = {a: n for a, n in boletim.items() if n >= 8}
print(aprovados)
print({a: round(n) for a, n in boletim.items()}){'Ana': 9.5, 'Bruno': 7.0, 'Carlos': 8.2}
{'Ana': 9.5, 'Carlos': 8.2}
{'Ana': 10, 'Bruno': 7, 'Carlos': 8}texto = "engenharia de telecomunicacoes"
letras = {c for c in texto if c.isalpha()}
print(sorted(letras))
tamanhos = {len(p) for p in texto.split()}
print(tamanhos)['a', 'c', 'd', 'e', 'g', 'h', 'i', 'l', 'm', 'n', 'o', 'r', 's', 't', 'u']
{16, 10, 2}Sem colchetes, a expressão produz um item por vez em vez de montar a lista inteira na memória. Para um milhão de elementos, a diferença é enorme.
numeros = range(1, 1_000_001)
soma = sum(n for n in numeros if n % 3 == 0)
print("soma dos múltiplos de 3:", soma)
print("algum acima de 999999?", any(n > 999_999 for n in numeros))
print("todos positivos?", all(n > 0 for n in numeros))soma dos múltiplos de 3: 166666833333 algum acima de 999999? True todos positivos? True
Compreensão é para transformar e filtrar de forma direta. Se a lógica não couber confortavelmente em uma linha, o laço explícito é a escolha melhor.
dados = ["12", "abc", "7", "", "30"]
# Difícil de ler em uma linha só:
# validos = [int(d) for d in dados if d.isdigit() and int(d) > 10]
# Preferível quando há mais de uma regra:
validos = []
for d in dados:
if not d.isdigit():
continue
numero = int(d)
if numero > 10:
validos.append(numero)
print(validos)[12, 30]
Experimentos propostos
- Crie uma lista com os cubos dos números de 1 a 20 que sejam múltiplos de 3.
- A partir de uma lista de nomes, monte um dicionário nome para quantidade de letras.
- Use uma expressão geradora para somar os quadrados de 1 a 1000000 e compare o tempo com a versão em lista.
- Converta
[[1,2],[3,4],[5,6]]em[1,2,3,4,5,6].
8Strings
Texto é o tipo de dado mais manipulado em qualquer programa. Strings em Python são sequências imutáveis: toda operação que parece modificar na verdade cria um texto novo.
simples = 'aspas simples'
duplas = "aspas duplas"
mistura = "Ele disse: 'tudo certo'"
bloco = """Primeira linha
Segunda linha"""
vazia = ""
print(simples, "|", duplas, "|", mistura)
print(bloco)
print("string vazia é falsa?", not vazia)aspas simples | aspas duplas | Ele disse: 'tudo certo' Primeira linha Segunda linha string vazia é falsa? True
palavra = "Python"
print(palavra[0], palavra[1], palavra[-1], palavra[-2])
print("tamanho:", len(palavra))
for i, letra in enumerate(palavra):
print(f"{i:>2} {letra}")P y n o tamanho: 6 0 P 1 y 2 t 3 h 4 o 5 n
frase = "Python é uma linguagem clara"
print(frase[:6])
print(frase[-5:])
print(frase[7:15])
print(frase[::2])
print(frase[::-1])Python clara é uma li Pto m igae lr aralc megaugnil amu é nohtyP
nome = "python"
try:
nome[0] = "P"
except TypeError as erro:
print("Erro:", erro)
# A saida e sempre uma string nova
maiuscula = nome.capitalize()
print(nome, "->", maiuscula)Erro: 'str' object does not support item assignment python -> Python
Métodos de transformação
texto = " Python É uma Linguagem incrível "
print(f"[{texto.strip()}]")
print(f"[{texto.lstrip()}] [{texto.rstrip()}]")
print(texto.strip().upper())
print(texto.strip().lower())
print(texto.strip().title())
print(texto.strip().capitalize())
print("-".join(texto.split()))[Python É uma Linguagem incrível] [Python É uma Linguagem incrível ] [ Python É uma Linguagem incrível] PYTHON É UMA LINGUAGEM INCRÍVEL python é uma linguagem incrível Python É Uma Linguagem Incrível Python é uma linguagem incrível Python-É-uma-Linguagem-incrível
Todos devolvem True ou False e são a base de qualquer validação de entrada.
amostras = ["12345", "Python", "Python3", " ", "TITULO"]
for a in amostras:
print(f"{repr(a):>10} "
f"digito={a.isdigit():<2} "
f"alpha={a.isalpha():<2} "
f"alnum={a.isalnum():<2} "
f"espaco={a.isspace():<2} "
f"maiusc={a.isupper()}") '12345' digito=1 alpha=0 alnum=1 espaco=0 maiusc=False
'Python' digito=0 alpha=1 alnum=1 espaco=0 maiusc=False
'Python3' digito=0 alpha=0 alnum=1 espaco=0 maiusc=False
' ' digito=0 alpha=0 alnum=0 espaco=1 maiusc=False
'TITULO' digito=0 alpha=1 alnum=1 espaco=0 maiusc=True.index() faz o mesmo que .find(), mas levanta ValueError quando não encontra.
frase = "Python é rápido e Python é claro"
print("in:", "rápido" in frase)
print("find:", frase.find("Python")) # primeira ocorrencia
print("rfind:", frase.rfind("Python")) # ultima
print("find ausente:", frase.find("Java")) # -1
print("count:", frase.count("Python"))
print("startswith:", frase.startswith("Python"))
print("endswith:", frase.endswith("claro"))in: True find: 0 rfind: 18 find ausente: -1 count: 2 startswith: True endswith: True
texto = "Eu gosto de Java, Java é interessante"
print(texto.replace("Java", "Python"))
print(texto.replace("Java", "Python", 1)) # so a primeira
telefone = "(48) 99999-1234"
limpo = (telefone.replace("(", "").replace(")", "")
.replace(" ", "").replace("-", ""))
print("só dígitos:", limpo)Eu gosto de Python, Python é interessante Eu gosto de Python, Java é interessante só dígitos: 48999991234
split transforma texto em lista, join faz o caminho de volta. Note a variável quebra: veja a advertência a seguir.
linha = "Python,Java,C,Rust"
linguagens = linha.split(",")
print(linguagens)
texto = "palavra1 palavra2\tpalavra3"
print(texto.split()) # qualquer espaco em branco
print("1-2-3-4".split("-", 2)) # no maximo 2 divisoes
frutas = ["maçã", "banana", "uva"]
print(", ".join(frutas))
print(" | ".join(frutas))
quebra = "\n"
print(quebra.join(frutas))['Python', 'Java', 'C', 'Rust'] ['palavra1', 'palavra2', 'palavra3'] ['1', '2', '3-4'] maçã, banana, uva maçã | banana | uva maçã banana uva
Formatação e alinhamento
produtos = [("Cabo HDMI", 39.9), ("Roteador", 289.0),
("Antena", 129.5)]
print(f"{'PRODUTO':<14}{'PREÇO':>10}")
print("-" * 24)
for nome, preco in produtos:
print(f"{nome:<14}{preco:>10.2f}")
print("-" * 24)
print(f"{'TOTAL':<14}{sum(p for _, p in produtos):>10.2f}")PRODUTO PREÇO ------------------------ Cabo HDMI 39.90 Roteador 289.00 Antena 129.50 ------------------------ TOTAL 458.40
titulo = "RELATÓRIO"
print(titulo.center(30, "="))
print(titulo.ljust(20, ".") + "ok")
print(titulo.rjust(30))
print(f"{titulo:*^30}")
print(f"{42:0>5}")==========RELATÓRIO===========
RELATÓRIO...........ok
RELATÓRIO
**********RELATÓRIO***********
00042O prefixo r desliga a interpretação das barras invertidas. Use em caminhos do Windows e em expressões regulares.
print("Linha 1\nLinha 2")
print("Coluna1\tColuna2")
print("Aspas: \"Python\"")
print("Barra: C:\\Users\\Documentos")
caminho = r"C:\Users\Documentos\dados.txt"
print(caminho)
padrao = r"\d+\.\d+" # util em expressoes regulares
print(padrao)Linha 1 Linha 2 Coluna1 Coluna2 Aspas: "Python" Barra: C:\Users\Documentos C:\Users\Documentos\dados.txt \d+\.\d+
Aplicações
email = "ramon.mayor@ifsc.edu.br"
usuario, dominio = email.split("@")
print("usuário:", usuario)
print("domínio:", dominio)
print("extensão:", dominio[dominio.rfind("."):])
print("nome formatado:", usuario.replace(".", " ").title())usuário: ramon.mayor domínio: ifsc.edu.br extensão: .br nome formatado: Ramon Mayor
def validar_email(email):
"""Validação simples: devolve (valido, mensagem)."""
email = email.strip().lower()
if not email:
return False, "não pode estar vazio"
if email.count("@") != 1:
return False, "precisa de exatamente um @"
usuario, dominio = email.split("@")
if not usuario or not dominio:
return False, "usuário e domínio são obrigatórios"
if "." not in dominio:
return False, "domínio precisa de um ponto"
return True, "válido"
testes = ["ramon@ifsc.edu.br", "@ifsc.edu.br", "sem-arroba.com",
" ALUNO@IFSC.EDU.BR "]
for t in testes:
ok, msg = validar_email(t)
marca = "ok " if ok else "erro"
print(f"[{marca}] {t.strip():<24} {msg}")[ok ] ramon@ifsc.edu.br válido [erro] @ifsc.edu.br usuário e domínio são obrigatórios [erro] sem-arroba.com precisa de exatamente um @ [ok ] ALUNO@IFSC.EDU.BR válido
texto = """Python é uma linguagem de programação.
É fácil de aprender e muito poderosa.
Versão usada: 3.12"""
palavras = texto.split()
vogais = sum(1 for c in texto.lower() if c in "aeiou")
digitos = sum(1 for c in texto if c.isdigit())
print("caracteres:", len(texto))
print("palavras:", len(palavras))
print("linhas:", len(texto.splitlines()))
print("vogais:", vogais)
print("dígitos:", digitos)
print("maior palavra:", max(palavras, key=len))caracteres: 95 palavras: 16 linhas: 3 vogais: 30 dígitos: 3 maior palavra: programação.
| Categoria | Métodos |
|---|---|
| Caixa | .upper() .lower() .title() .capitalize() .swapcase() |
| Limpeza | .strip() .lstrip() .rstrip() |
| Verificação | .isdigit() .isalpha() .isalnum() .isspace() .isupper() .islower() |
| Busca | .find() .rfind() .index() .count() .startswith() .endswith() |
| Transformação | .replace() .split() .splitlines() .join() |
| Alinhamento | .center() .ljust() .rjust() .zfill() |
Experimentos propostos
- Peça uma frase e informe quantas palavras e quantas vogais ela tem.
- Escreva uma função que receba um CPF com pontuação e devolva apenas os dígitos.
- Monte um cabeçalho de relatório centralizado em 40 colunas com bordas de
=. - Verifique se uma palavra é palíndromo ignorando maiúsculas e espaços.
Organização do código
Funções, módulos e objetos: como um script vira um programa.
9Funções
Dar nome a um trecho de código é a primeira ferramenta de organização de qualquer programa. Uma função bem escrita faz uma coisa só e o seu nome diz qual é.
def cabecalho():
"""Imprime o cabeçalho padrão do relatório."""
print("=" * 34)
print("IFSC - Manual de Experimentos")
print("=" * 34)
cabecalho()
print("conteúdo do relatório")================================== IFSC - Manual de Experimentos ================================== conteúdo do relatório
def saudacao(nome, curso):
print(f"Olá, {nome}! Bem-vindo ao curso de {curso}.")
saudacao("Maria", "Telecomunicações")
saudacao("João", "Redes")
saudacao(curso="Python", nome="Ana") # argumentos nomeadosOlá, Maria! Bem-vindo ao curso de Telecomunicações. Olá, João! Bem-vindo ao curso de Redes. Olá, Ana! Bem-vindo ao curso de Python.
return encerra a função imediatamente. Sem return, a função devolve None.
def area_retangulo(base, altura):
return base * altura
def celsius_para_fahrenheit(c):
return c * 9 / 5 + 32
print(area_retangulo(3, 4))
print(f"{celsius_para_fahrenheit(25):.1f} °F")
print("soma de áreas:", area_retangulo(2, 2) + area_retangulo(3, 3))12 77.0 °F soma de áreas: 13
Na prática a função devolve uma tupla, que você desempacota na chamada.
def estatisticas(valores):
return min(valores), max(valores), sum(valores) / len(valores)
menor, maior, media = estatisticas([7.5, 9.0, 5.5, 8.0])
print(f"menor {menor} | maior {maior} | média {media:.2f}")
tudo = estatisticas([1, 2, 3])
print(tudo, type(tudo))menor 5.5 | maior 9.0 | média 7.50 (1, 3, 2.0) <class 'tuple'>
Tratar os casos inválidos primeiro e sair cedo mantém o corpo da função plano e legível.
def classificar(idade):
if idade < 0:
return "idade inválida"
if idade < 13:
return "criança"
if idade < 18:
return "adolescente"
if idade < 60:
return "adulto"
return "idoso"
for i in [-1, 5, 15, 30, 70]:
print(f"{i:>3} -> {classificar(i)}")-1 -> idade inválida 5 -> criança 15 -> adolescente 30 -> adulto 70 -> idoso
Parâmetros
Parâmetros com valor padrão vêm sempre depois dos obrigatórios.
def criar_perfil(nome, curso="não informado", ativo=True):
status = "ativo" if ativo else "inativo"
print(f"{nome:<8} | {curso:<16} | {status}")
criar_perfil("Maria", "Telecomunicações")
criar_perfil("João")
criar_perfil("Ana", ativo=False)Maria | Telecomunicações | ativo João | não informado | ativo Ana | não informado | inativo
def somar(*numeros):
print(f"recebi {numeros} ->", sum(numeros))
return sum(numeros)
somar(1, 2, 3)
somar(10, 20, 30, 40)
somar()
valores = [5, 10, 15]
somar(*valores) # o asterisco desempacota a listarecebi (1, 2, 3) -> 6 recebi (10, 20, 30, 40) -> 100 recebi () -> 0 recebi (5, 10, 15) -> 30
def relatorio(**dados):
if not dados:
print("nenhum dado recebido")
return
for chave, valor in dados.items():
print(f"{chave.replace('_', ' ').title():<12}: {valor}")
print("-" * 26)
relatorio(nome="Pedro", cargo="Técnico", setor="Redes")
relatorio()
equipamento = {"modelo": "RTL-SDR", "faixa_mhz": "24 a 1766"}
relatorio(**equipamento)Nome : Pedro Cargo : Técnico Setor : Redes -------------------------- nenhum dado recebido Modelo : RTL-SDR Faixa Mhz : 24 a 1766 --------------------------
A ordem é fixa: obrigatórios, com padrão, *args, **kwargs.
def registrar(evento, nivel="info", *tags, **extras):
print(f"[{nivel.upper()}] {evento}")
if tags:
print(" tags:", ", ".join(tags))
if extras:
print(" extras:", extras)
registrar("sistema iniciado")
registrar("falha na antena", "erro", "rf", "campo", codigo=42)[INFO] sistema iniciado
[ERRO] falha na antena
tags: rf, campo
extras: {'codigo': 42}Escopo
contador = 0 # global
def mostrar():
interno = 10 # local
print("dentro:", interno, contador)
mostrar()
print("fora:", contador)
try:
print(interno)
except NameError as erro:
print("Erro:", erro)dentro: 10 0 fora: 0 Erro: name 'interno' is not defined
Use global com parcimônia: funções que dependem de estado externo são mais difíceis de testar.
total = 0
def somar_errado(valor):
total = valor # cria uma variavel local nova
return total
def somar_certo(valor):
global total
total += valor
somar_errado(10)
print("depois do errado:", total)
somar_certo(10)
somar_certo(5)
print("depois do certo:", total)
def contador():
n = 0
def incrementar():
nonlocal n
n += 1
return n
return incrementar
c = contador()
print(c(), c(), c())depois do errado: 0 depois do certo: 15 1 2 3
O valor padrão é criado uma única vez, quando a função é definida. Para listas e dicionários, use None como padrão.
def adicionar_errado(item, lista=[]):
lista.append(item)
return lista
print(adicionar_errado("a"))
print(adicionar_errado("b")) # a lista lembrou do "a"!
def adicionar_certo(item, lista=None):
if lista is None:
lista = []
lista.append(item)
return lista
print(adicionar_certo("a"))
print(adicionar_certo("b"))['a'] ['a', 'b'] ['a'] ['b']
Funções como valores
lambda é uma função anônima de uma expressão só. O uso mais frequente é como key em sorted, max e min.
quadrado = lambda x: x ** 2
print(quadrado(5))
alunos = [("Ana", 9.5), ("Bruno", 7.0), ("Carlos", 8.2)]
print(sorted(alunos, key=lambda par: par[1]))
print(sorted(alunos, key=lambda par: par[1], reverse=True))
print(max(alunos, key=lambda par: par[1]))25
[('Bruno', 7.0), ('Carlos', 8.2), ('Ana', 9.5)]
[('Ana', 9.5), ('Carlos', 8.2), ('Bruno', 7.0)]
('Ana', 9.5)numeros = [1, 2, 3, 4, 5, 6]
print(list(map(lambda x: x ** 2, numeros)))
print(list(filter(lambda x: x % 2 == 0, numeros)))
# Mesma coisa, mais legivel para a maioria das pessoas:
print([x ** 2 for x in numeros])
print([x for x in numeros if x % 2 == 0])[1, 4, 9, 16, 25, 36] [2, 4, 6] [1, 4, 9, 16, 25, 36] [2, 4, 6]
Funções são objetos: podem ser passadas, guardadas em listas e devolvidas por outras funções.
def aplicar(funcao, valores):
return [funcao(v) for v in valores]
def dobro(x):
return x * 2
print(aplicar(dobro, [1, 2, 3]))
print(aplicar(str.upper, ["a", "b"]))
print(aplicar(len, ["python", "ifsc"]))[2, 4, 6] ['A', 'B'] [6, 4]
Toda função recursiva precisa de um caso base. Sem ele, o resultado é RecursionError.
def fatorial(n):
if n <= 1: # caso base
return 1
return n * fatorial(n - 1)
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print([fatorial(i) for i in range(7)])
print([fibonacci(i) for i in range(10)])[1, 1, 2, 6, 24, 120, 720] [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
As anotações não são verificadas em tempo de execução, mas documentam a intenção e alimentam ferramentas como o mypy e o autocompletar do editor.
def calcular_imc(peso: float, altura: float) -> dict:
"""Calcula o IMC e devolve o valor com a classificação.
Args:
peso: massa em quilogramas.
altura: altura em metros.
Returns:
Dicionário com as chaves 'imc' e 'classificacao'.
Raises:
ValueError: se peso ou altura não forem positivos.
"""
if peso <= 0 or altura <= 0:
raise ValueError("peso e altura devem ser positivos")
imc = peso / altura ** 2
if imc < 18.5:
faixa = "abaixo do peso"
elif imc < 25:
faixa = "peso normal"
elif imc < 30:
faixa = "sobrepeso"
else:
faixa = "obesidade"
return {"imc": round(imc, 2), "classificacao": faixa}
print(calcular_imc(70, 1.75))
print(calcular_imc.__doc__.splitlines()[0]){'imc': 22.86, 'classificacao': 'peso normal'}
Calcula o IMC e devolve o valor com a classificação.Um decorador recebe uma função e devolve outra que a envolve. É assim que frameworks acrescentam comportamento sem alterar o seu código.
import time
def cronometrar(funcao):
"""Mede o tempo de execução da função decorada."""
def interna(*args, **kwargs):
inicio = time.perf_counter()
resultado = funcao(*args, **kwargs)
gasto = time.perf_counter() - inicio
print(f"{funcao.__name__} levou {gasto:.4f} s")
return resultado
return interna
@cronometrar
def somar_ate(n):
return sum(range(n))
print(somar_ate(1_000_000))somar_ate levou 0.0244 s 499999500000
Experimentos propostos
- Escreva
media(*notas)que aceite qualquer quantidade de notas. - Crie
maior_de(lista, chave)que usekeypara achar o maior por qualquer critério. - Implemente a soma dos dígitos de um número de forma recursiva.
- Escreva um decorador
@contar_chamadasque informe quantas vezes a função foi executada.
10Módulos e pacotes
Todo arquivo .py é um módulo. Importar é a forma de reaproveitar o que já foi escrito, seja por você, pela biblioteca padrão ou pela comunidade.
O nome do módulo fica como prefixo, o que deixa claro de onde a função veio.
import math
print(math.pi)
print(math.sqrt(144))
print(math.floor(3.7), math.ceil(3.2))
print(math.log10(1000))3.141592653589793 12.0 3 4 3.0
from math import pi, sqrt, radians, sin
print(pi)
print(sqrt(81))
print(round(sin(radians(30)), 4))
# Evite: importa tudo e polui o espaco de nomes
# from math import *3.141592653589793 9.0 0.5
Apelidos curtos são convenção em bibliotecas conhecidas, como import numpy as np.
import statistics as stat
from datetime import datetime as dt
amostras = [12.5, 13.0, 11.8, 12.9]
print("média:", stat.mean(amostras))
print("mediana:", stat.median(amostras))
print("ano atual:", dt(2026, 7, 22).year)média: 12.55 mediana: 12.7 ano atual: 2026
Na prática você apenas salva conversoes.py na mesma pasta e escreve import conversoes.
# Aqui o modulo e gravado em disco e depois importado.
codigo = """
def celsius_para_fahrenheit(c):
return c * 9 / 5 + 32
def watts_para_dbm(p):
import math
return 10 * math.log10(p * 1000)
"""
with open("conversoes.py", "w", encoding="utf-8") as arquivo:
arquivo.write(codigo)
import conversoes
print(conversoes.celsius_para_fahrenheit(25))
print(conversoes.watts_para_dbm(0.001), "dBm") # 1 mW
print(round(conversoes.watts_para_dbm(0.1), 2), "dBm")77.0 0.0 dBm 20.0 dBm
Quando o arquivo é executado diretamente, __name__ vale "__main__". Quando é importado, vale o nome do módulo. Esse teste impede que o código de teste rode ao importar.
def principal():
print("executando o programa")
print("valor de __name__:", __name__)
if __name__ == "__main__":
principal()valor de __name__: __main__ executando o programa
Com essa estrutura, main.py escreve from pacote.conversoes import watts_para_dbm.
meu_projeto/
|-- main.py # ponto de entrada
|-- requisitos.txt # dependencias
|-- dados/
| `-- medidas.csv
`-- pacote/
|-- __init__.py # marca a pasta como pacote
|-- conversoes.py
`-- relatorio.pyUm ambiente virtual por projeto evita conflito de versões entre trabalhos diferentes.
# Criar e ativar um ambiente isolado do sistema
python3 -m venv .venv
source .venv/bin/activate # Linux e macOS
.venv\Scripts\activate # Windows
# Instalar, listar e registrar dependencias
pip install requests matplotlib
pip list
pip freeze > requisitos.txt
# Reproduzir o ambiente em outra maquina
pip install -r requisitos.txt| Módulo | Serve para |
|---|---|
math | funções matemáticas |
random | sorteios e amostragem |
datetime | datas e horas |
statistics | média, mediana, desvio |
collections | contadores e filas |
itertools | combinações e permutações |
json / csv | leitura e escrita de dados |
pathlib / os | caminhos e sistema de arquivos |
re | expressões regulares |
Experimentos propostos
- Crie um módulo
geometria.pycom três funções de área e importe-o em outro arquivo. - Acrescente ao módulo um bloco
if __name__ == "__main__":com testes rápidos. - Crie um ambiente virtual, instale uma biblioteca e gere o arquivo de requisitos.
11Programação orientada a objetos
Quando dados e comportamento andam juntos, a classe é a forma natural de organizar. Esta seção cobre o essencial para ler e escrever código orientado a objetos.
Uma classe é o molde; um objeto é cada exemplar criado a partir dele. Os atributos guardam o estado e os métodos definem o que o objeto sabe fazer.
__init__ é chamado automaticamente na criação do objeto. self é a referência ao próprio objeto e é sempre o primeiro parâmetro.
class Aluno:
"""Representa um aluno da turma."""
def __init__(self, nome, curso):
self.nome = nome # atributo de instancia
self.curso = curso
self.notas = []
ana = Aluno("Ana", "Telecomunicações")
bruno = Aluno("Bruno", "Redes")
print(ana.nome, "|", ana.curso, "|", ana.notas)
print(bruno.nome, "|", bruno.curso)Ana | Telecomunicações | [] Bruno | Redes
class Aluno:
def __init__(self, nome):
self.nome = nome
self.notas = []
def adicionar_nota(self, nota):
if 0 <= nota <= 10:
self.notas.append(nota)
else:
print("nota fora da faixa")
def media(self):
if not self.notas:
return 0.0
return sum(self.notas) / len(self.notas)
def aprovado(self):
return self.media() >= 7
ana = Aluno("Ana")
ana.adicionar_nota(8.5)
ana.adicionar_nota(9.0)
ana.adicionar_nota(15)
print(ana.notas, f"média {ana.media():.2f}", ana.aprovado())nota fora da faixa [8.5, 9.0] média 8.75 True
__str__ é para o usuário final e __repr__ é para quem está depurando.
class Ponto:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return f"({self.x}, {self.y})"
def __repr__(self):
return f"Ponto(x={self.x}, y={self.y})"
p = Ponto(3, 4)
print(p) # usa __str__
print(repr(p)) # usa __repr__
print([p, p]) # listas usam __repr__(3, 4) Ponto(x=3, y=4) [Ponto(x=3, y=4), Ponto(x=3, y=4)]
class Turma:
instituicao = "IFSC" # compartilhado por todos
total = 0
def __init__(self, codigo):
self.codigo = codigo # exclusivo de cada objeto
Turma.total += 1
a = Turma("TEL-2026-1")
b = Turma("RED-2026-1")
print(a.codigo, b.codigo)
print(a.instituicao, b.instituicao)
print("turmas criadas:", Turma.total)TEL-2026-1 RED-2026-1 IFSC IFSC turmas criadas: 2
O sublinhado inicial é um acordo entre programadores: "não mexa aqui de fora". A property transforma um método em atributo somente de leitura.
class Conta:
def __init__(self, titular, saldo=0):
self.titular = titular
self._saldo = saldo # convencao: uso interno
@property
def saldo(self):
return self._saldo
def depositar(self, valor):
if valor <= 0:
raise ValueError("valor deve ser positivo")
self._saldo += valor
def sacar(self, valor):
if valor > self._saldo:
return False
self._saldo -= valor
return True
c = Conta("Ana", 100)
c.depositar(50)
print("saque de 500 deu certo?", c.sacar(500))
print("saldo:", c.saldo)
try:
c.saldo = 1_000_000 # bloqueado: property sem setter
except AttributeError as erro:
print("Erro:", erro)saque de 500 deu certo? False saldo: 150 Erro: property 'saldo' of 'Conta' object has no setter
class Equipamento:
def __init__(self, modelo):
self.modelo = modelo
self.ligado = False
def ligar(self):
self.ligado = True
return f"{self.modelo} ligado"
def descrever(self):
return f"Equipamento {self.modelo}"
class Radio(Equipamento):
def __init__(self, modelo, frequencia):
super().__init__(modelo) # reaproveita o __init__
self.frequencia = frequencia
def descrever(self): # sobrescreve
return f"Rádio {self.modelo} em {self.frequencia} MHz"
r = Radio("RTL-SDR", 145.8)
print(r.ligar())
print(r.descrever())
print("é um Equipamento?", isinstance(r, Equipamento))RTL-SDR ligado Rádio RTL-SDR em 145.8 MHz é um Equipamento? True
O laço chama .ganho() sem saber a classe exata. Cada objeto responde à sua maneira.
class Antena:
def ganho(self):
return 0.0
class Dipolo(Antena):
def ganho(self):
return 2.15
class Yagi(Antena):
def __init__(self, elementos):
self.elementos = elementos
def ganho(self):
return 2.15 + 2.5 * (self.elementos - 1)
for antena in [Antena(), Dipolo(), Yagi(4)]:
nome = type(antena).__name__
print(f"{nome:<8} ganho {antena.ganho():>5.2f} dBi")Antena ganho 0.00 dBi Dipolo ganho 2.15 dBi Yagi ganho 9.65 dBi
O decorador gera __init__, __repr__ e __eq__. Para atributos mutáveis use field(default_factory=...).
from dataclasses import dataclass, field
@dataclass
class Medida:
sensor: str
valor: float
unidade: str = "dBm"
tags: list = field(default_factory=list)
m1 = Medida("ant-01", -73.5)
m2 = Medida("ant-01", -73.5)
print(m1)
print("iguais?", m1 == m2) # __eq__ vem de graca
m1.tags.append("teste")
print(m1.tags, m2.tags)Medida(sensor='ant-01', valor=-73.5, unidade='dBm', tags=[]) iguais? True ['teste'] []
class Aluno:
def __init__(self, nome):
self.nome = nome
self.notas = []
def media(self):
return sum(self.notas) / len(self.notas) if self.notas else 0
class Turma:
def __init__(self, codigo):
self.codigo = codigo
self.alunos = []
def matricular(self, aluno):
self.alunos.append(aluno)
def relatorio(self):
print(f"Turma {self.codigo}")
print(f"{'ALUNO':<10}{'MÉDIA':>7} SITUAÇÃO")
for a in sorted(self.alunos, key=lambda x: -x.media()):
situacao = "aprovado" if a.media() >= 7 else "exame"
print(f"{a.nome:<10}{a.media():>7.2f} {situacao}")
turma = Turma("TEL-2026-1")
for nome, notas in [("Ana", [8.5, 9.0]), ("Bruno", [6.0, 6.5]),
("Carlos", [7.5, 8.0])]:
aluno = Aluno(nome)
aluno.notas = notas
turma.matricular(aluno)
turma.relatorio()Turma TEL-2026-1 ALUNO MÉDIA SITUAÇÃO Ana 8.75 aprovado Carlos 7.75 aprovado Bruno 6.25 exame
Experimentos propostos
- Crie a classe
Retangulocom métodosarea()eperimetro(). - Acrescente
__str__para queprint(retangulo)mostre as medidas. - Crie
Quadradoherdando deRetangulo. - Reescreva a classe
Medidasemdataclasse compare a quantidade de linhas.
Dados, robustez e prática
Persistir informação, tratar falhas e fechar projetos.
12Manipulação de arquivos
Ler e gravar dados em disco, incluindo os formatos CSV e JSON, que resolvem quase todo intercâmbio de dados em laboratório.
| Modo | Significado | Se o arquivo existe | Se não existe |
|---|---|---|---|
"r" | leitura | lê | erro |
"w" | escrita | apaga o conteúdo | cria |
"a" | acréscimo | escreve no fim | cria |
"x" | criação exclusiva | erro | cria |
"rb" / "wb" | modo binário | imagens, áudio | cria |
write não acrescenta quebra de linha: você controla cada \n. Informe sempre o encoding.
with open("exemplo.txt", "w", encoding="utf-8") as arquivo:
arquivo.write("Primeira linha\n")
arquivo.write("Segunda linha\n")
arquivo.writelines(["terceira\n", "quarta\n"])
print("arquivo gravado")arquivo gravado
with open("dados.txt", "w", encoding="utf-8") as f:
f.write("linha 1\nlinha 2\nacentuação: ção, ã, ê\n")
with open("dados.txt", "r", encoding="utf-8") as f:
conteudo = f.read()
print(conteudo)
print("caracteres lidos:", len(conteudo))linha 1 linha 2 acentuação: ção, ã, ê caracteres lidos: 38
Percorrer o arquivo diretamente lê uma linha por vez e funciona com arquivos de qualquer tamanho. readlines() carrega tudo na memória.
with open("dados.txt", "w", encoding="utf-8") as f:
f.write("alfa\nbeta\ngama\n")
with open("dados.txt", "r", encoding="utf-8") as f:
for numero, linha in enumerate(f, 1):
print(f"{numero}: {linha.strip()}")
with open("dados.txt", "r", encoding="utf-8") as f:
linhas = f.readlines()
print(linhas)1: alfa 2: beta 3: gama ['alfa\n', 'beta\n', 'gama\n']
with open("registro.log", "w", encoding="utf-8") as f:
f.write("início da sessão\n")
for evento in ["antena conectada", "sinal capturado"]:
with open("registro.log", "a", encoding="utf-8") as f:
f.write(evento + "\n")
with open("registro.log", encoding="utf-8") as f:
print(f.read())início da sessão antena conectada sinal capturado
# Forma frágil: se ocorrer um erro antes do close, o arquivo fica aberto
arquivo = open("teste.txt", "w", encoding="utf-8")
arquivo.write("dado")
arquivo.close()
print("fechado manualmente?", arquivo.closed)
# Forma correta: o with fecha ate se houver excecao
with open("teste.txt", "a", encoding="utf-8") as arquivo:
arquivo.write(" e mais dado")
print("fechado pelo with?", arquivo.closed)fechado manualmente? True fechado pelo with? True
Caminhos com pathlib
pathlib substitui a concatenação de strings e boa parte do módulo os.path.
from pathlib import Path
pasta = Path("medidas")
pasta.mkdir(exist_ok=True)
arquivo = pasta / "sessao01.txt" # a barra monta o caminho
arquivo.write_text("-73.5 dBm\n-71.2 dBm\n", encoding="utf-8")
print("existe?", arquivo.exists())
print("nome:", arquivo.name, "| extensão:", arquivo.suffix)
print("tamanho:", arquivo.stat().st_size, "bytes")
print("conteúdo:", arquivo.read_text(encoding="utf-8").split())
print("arquivos na pasta:", [p.name for p in pasta.iterdir()])existe? True nome: sessao01.txt | extensão: .txt tamanho: 20 bytes conteúdo: ['-73.5', 'dBm', '-71.2', 'dBm'] arquivos na pasta: ['sessao01.txt']
Formatos de intercâmbio
newline="" evita linhas em branco no Windows. DictReader entrega cada linha como dicionário usando o cabeçalho.
import csv
linhas = [
["sensor", "valor_dbm", "data"],
["ant-01", -73.5, "2026-07-22"],
["ant-02", -68.1, "2026-07-22"],
]
with open("medidas.csv", "w", newline="", encoding="utf-8") as f:
csv.writer(f).writerows(linhas)
with open("medidas.csv", encoding="utf-8") as f:
for registro in csv.DictReader(f):
print(f"{registro['sensor']}: {registro['valor_dbm']} dBm")ant-01: -73.5 dBm ant-02: -68.1 dBm
dump/load trabalham com arquivos; dumps/loads trabalham com strings. ensure_ascii=False preserva os acentos.
import json
config = {
"estacao": "IFSC-389",
"frequencias": [145.8, 437.5],
"ativa": True,
"operador": {"nome": "Ramon", "indicativo": "PU4MAY"},
}
with open("config.json", "w", encoding="utf-8") as f:
json.dump(config, f, indent=2, ensure_ascii=False)
with open("config.json", encoding="utf-8") as f:
lido = json.load(f)
print(lido["operador"]["indicativo"])
print(lido["frequencias"][0])
print(json.dumps(lido, ensure_ascii=False)[:60], "...")PU4MAY
145.8
{"estacao": "IFSC-389", "frequencias": [145.8, 437.5], "ativ ...Duas funções pequenas, uma para carregar e outra para salvar, resolvem a persistência de quase qualquer trabalho de disciplina.
import json
from pathlib import Path
ARQUIVO = Path("tarefas.json")
def carregar():
if not ARQUIVO.exists():
return []
return json.loads(ARQUIVO.read_text(encoding="utf-8"))
def salvar(tarefas):
ARQUIVO.write_text(
json.dumps(tarefas, indent=2, ensure_ascii=False),
encoding="utf-8")
tarefas = carregar()
tarefas.append({"texto": "revisar o manual", "feita": False})
tarefas.append({"texto": "testar a antena", "feita": True})
salvar(tarefas)
for i, t in enumerate(carregar(), 1):
marca = "x" if t["feita"] else " "
print(f"[{marca}] {i}. {t['texto']}")[ ] 1. revisar o manual [x] 2. testar a antena
Experimentos propostos
- Grave em arquivo os nomes digitados até o usuário escrever "fim" e depois releia mostrando a numeração.
- Leia um arquivo de texto e informe quantas linhas, palavras e caracteres ele tem.
- Converta o CSV do CÓDIGO 12.8 em JSON.
- Acrescente ao CÓDIGO 12.9 a opção de marcar uma tarefa como concluída.
13Tratamento de exceções
Programas encontram arquivos que não existem, entradas inválidas e divisões por zero. Tratar exceções é decidir o que fazer quando o esperado não acontece.
try: trecho que pode falhar.except: o que fazer quando falha.else: executa quando não houve erro.finally: executa sempre, com erro ou sem erro.raise: provoca uma exceção de propósito.
try:
resultado = 10 / 0
except ZeroDivisionError:
print("não é possível dividir por zero")
resultado = None
print("resultado:", resultado)
print("o programa continuou")não é possível dividir por zero resultado: None o programa continuou
Coloque sempre as exceções específicas antes das genéricas: o primeiro except compatível vence.
def dividir(texto_a, texto_b):
try:
return float(texto_a) / float(texto_b)
except ZeroDivisionError:
return "divisor igual a zero"
except ValueError:
return "entrada não numérica"
print(dividir("10", "4"))
print(dividir("10", "0"))
print(dividir("dez", "2"))2.5 divisor igual a zero entrada não numérica
A tupla agrupa tipos que recebem o mesmo tratamento. as erro dá acesso à mensagem original.
entradas = ["12", "abc", None]
for valor in entradas:
try:
print("dobro:", int(valor) * 2)
except (ValueError, TypeError) as erro:
print(f"falhou com {valor!r}: {type(erro).__name__}: {erro}")dobro: 24 falhou com 'abc': ValueError: invalid literal for int() with base 10: 'abc' falhou com None: TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
def ler_config(nome):
try:
arquivo = open(nome, encoding="utf-8")
except FileNotFoundError:
print("arquivo não encontrado, usando padrões")
return {}
else:
print("arquivo aberto com sucesso")
conteudo = arquivo.read()
return {"linhas": len(conteudo.splitlines())}
finally:
print("fim da tentativa de leitura")
with open("config.txt", "w", encoding="utf-8") as f:
f.write("a=1\nb=2\n")
print(ler_config("config.txt"))
print(ler_config("inexistente.txt"))arquivo aberto com sucesso
fim da tentativa de leitura
{'linhas': 2}
arquivo não encontrado, usando padrões
fim da tentativa de leitura
{}Uma função de biblioteca sinaliza o problema com raise; quem chamou decide o que fazer.
def calcular_media(notas):
if not notas:
raise ValueError("a lista de notas está vazia")
return sum(notas) / len(notas)
print(calcular_media([8, 9, 10]))
try:
calcular_media([])
except ValueError as erro:
print("Erro tratado:", erro)9.0 Erro tratado: a lista de notas está vazia
Criar uma exceção própria deixa o erro do seu domínio distinguível dos erros da linguagem.
class IdadeInvalida(Exception):
"""Erro de domínio: idade fora da faixa aceitável."""
def __init__(self, idade, mensagem="idade inválida"):
self.idade = idade
super().__init__(f"{mensagem} ({idade})")
def validar(idade):
if not isinstance(idade, int):
raise TypeError("idade deve ser um inteiro")
if idade < 0:
raise IdadeInvalida(idade, "não pode ser negativa")
if idade > 150:
raise IdadeInvalida(idade, "acima do limite")
return True
for candidato in [25, -5, 200, "trinta"]:
try:
validar(candidato)
print(f"{candidato!r}: ok")
except IdadeInvalida as erro:
print(f"{candidato!r}: {erro}")
except TypeError as erro:
print(f"{candidato!r}: {erro}")25: ok -5: não pode ser negativa (-5) 200: acima do limite (200) 'trinta': idade deve ser um inteiro
def ler_texto(nome):
try:
with open(nome, encoding="utf-8") as arquivo:
conteudo = arquivo.read()
except FileNotFoundError:
print(f"'{nome}' não existe")
except PermissionError:
print(f"sem permissão para ler '{nome}'")
except UnicodeDecodeError:
print(f"'{nome}' não está em UTF-8")
else:
if not conteudo.strip():
print(f"'{nome}' está vazio")
return conteudo
return None
with open("ok.txt", "w", encoding="utf-8") as f:
f.write("conteúdo válido")
print(repr(ler_texto("ok.txt")))
print(repr(ler_texto("faltando.txt")))'conteúdo válido' 'faltando.txt' não existe None
Lendo um traceback
Leia de baixo para cima: a última linha diz o que aconteceu, a linha imediatamente acima diz onde, e o restante mostra o caminho de chamadas até ali.
Traceback (most recent call last):
File "relatorio.py", line 18, in <module>
main()
File "relatorio.py", line 12, in main
media = calcular(notas)
File "relatorio.py", line 6, in calcular
return sum(notas) / len(notas)
~~~~~~~~~~~^~~~~~~~~~~~
ZeroDivisionError: division by zero| Exceção | Causa típica |
|---|---|
ValueError | conversão impossível, como int("abc") |
TypeError | operação entre tipos incompatíveis |
IndexError | índice fora da lista |
KeyError | chave inexistente no dicionário |
ZeroDivisionError | divisão por zero |
FileNotFoundError | arquivo não existe |
PermissionError | sem permissão de acesso |
AttributeError | método ou atributo que não existe |
NameError | nome usado antes de existir |
IndentationError | recuo incorreto |
Experimentos propostos
- Peça dois números e trate
ValueErroreZeroDivisionErrorao dividi-los. - Crie a exceção
NotaInvalidae use-a em uma função de cadastro de notas. - Escreva uma função que leia um JSON e trate arquivo ausente e conteúdo malformado.
- Provoque cada exceção da Tabela 13.1 e registre a mensagem completa.
14Biblioteca padrão essencial
Python vem com muita coisa pronta. Conhecer estes módulos evita reescrever o que já existe e testado.
import math
print(math.pi, math.e)
print(math.sqrt(2), math.hypot(3, 4))
print(math.floor(3.7), math.ceil(3.2), math.trunc(-3.7))
print(math.log10(1000), math.log2(1024))
print(math.degrees(math.pi), math.sin(math.radians(90)))
print(math.factorial(5), math.gcd(24, 36))3.141592653589793 2.718281828459045 1.4142135623730951 5.0 3 4 -3 3.0 10.0 180.0 1.0 120 12
Sem seed cada execução dá um resultado diferente. Com seed, o sorteio se repete, o que é essencial para testar.
import random
random.seed(42) # torna o resultado reproduzivel
print(random.random())
print(random.randint(1, 6))
print(random.uniform(1.5, 2.5))
print(random.choice(["ouro", "prata", "bronze"]))
print(random.sample(range(1, 61), 6))
cartas = ["A", "2", "3", "4"]
random.shuffle(cartas)
print(cartas)0.6394267984578837 1 2.241550499759833 ouro [15, 9, 48, 7, 44, 58] ['4', '2', '3', 'A']
strftime formata para texto e strptime interpreta texto. Use datetime.now() para o instante atual.
from datetime import datetime, date, timedelta
hoje = date(2026, 7, 22)
agora = datetime(2026, 7, 22, 14, 30)
print(hoje.strftime("%d/%m/%Y"))
print(agora.strftime("%d/%m/%Y às %H:%M"))
print("dia da semana:", hoje.weekday()) # 0 = segunda
prazo = hoje + timedelta(days=30)
print("prazo:", prazo, "| faltam", (prazo - hoje).days, "dias")
lida = datetime.strptime("01/03/2026", "%d/%m/%Y")
print("convertida:", lida.date())22/07/2026 22/07/2026 às 14:30 dia da semana: 2 prazo: 2026-08-21 | faltam 30 dias convertida: 2026-03-01
import statistics as stat
amostras = [12.5, 13.0, 11.8, 12.9, 12.1, 13.4]
print("média:", round(stat.mean(amostras), 3))
print("mediana:", stat.median(amostras))
print("desvio padrão:", round(stat.stdev(amostras), 4))
print("variância:", round(stat.variance(amostras), 4))
print("moda:", stat.mode([1, 2, 2, 3]))média: 12.617 mediana: 12.7 desvio padrão: 0.5981 variância: 0.3577 moda: 2
Counter resolve contagem em uma linha e defaultdict dispensa verificar se a chave já existe.
from collections import Counter, defaultdict, namedtuple
texto = "engenharia de telecomunicacoes"
contagem = Counter(c for c in texto if c.isalpha())
print(contagem.most_common(4))
grupos = defaultdict(list)
for nome in ["Ana", "Bruno", "Alice", "Carlos"]:
grupos[nome[0]].append(nome)
print(dict(grupos))
Medida = namedtuple("Medida", "sensor valor")
m = Medida("ant-01", -73.5)
print(m, m.sensor, m.valor)[('e', 6), ('n', 3), ('a', 3), ('c', 3)]
{'A': ['Ana', 'Alice'], 'B': ['Bruno'], 'C': ['Carlos']}
Medida(sensor='ant-01', valor=-73.5) ant-01 -73.5from itertools import combinations, permutations, product, count
print(list(combinations("ABC", 2)))
print(list(permutations("ABC", 2)))
print(list(product([0, 1], repeat=2)))
contador = count(start=10, step=5)
print([next(contador) for _ in range(4)])[('A', 'B'), ('A', 'C'), ('B', 'C')]
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
[(0, 0), (0, 1), (1, 0), (1, 1)]
[10, 15, 20, 25]Use sempre raw strings nos padrões. findall busca todas as ocorrências, search a primeira e fullmatch valida o texto inteiro.
import re
texto = "Contatos: ramon@ifsc.edu.br, suporte@ifsc.edu.br, (48) 3381-2800"
emails = re.findall(r"[\w.]+@[\w.]+", texto)
print(emails)
telefone = re.search(r"\(\d{2}\)\s?\d{4}-\d{4}", texto)
print(telefone.group() if telefone else "não encontrado")
print(re.sub(r"\d", "#", "senha 12345"))
print(bool(re.fullmatch(r"\d{3}\.\d{3}\.\d{3}-\d{2}",
"123.456.789-00")))['ramon@ifsc.edu.br', 'suporte@ifsc.edu.br'] (48) 3381-2800 senha ##### True
import os
import sys
import time
print("versão:", sys.version.split()[0])
print("plataforma:", sys.platform)
print("pasta atual:", os.path.basename(os.getcwd()))
print("variável de ambiente HOME existe?", "HOME" in os.environ)
inicio = time.perf_counter()
soma = sum(range(200_000))
print(f"tempo: {time.perf_counter() - inicio:.4f} s")versão: 3.12.3 plataforma: linux pasta atual: tmp32igper7 variável de ambiente HOME existe? True tempo: 0.0049 s
Experimentos propostos
- Sorteie 6 números da megassena sem repetição usando
random.sample. - Calcule quantos dias faltam para o fim do semestre com
timedelta. - Use
Counterpara achar as 10 palavras mais comuns de um arquivo de texto. - Escreva uma expressão regular que valide placas de veículo no padrão Mercosul.
15Estilo, depuração e testes
O código é lido muito mais vezes do que é escrito. Esta seção reúne as convenções e as ferramentas que separam um script que funciona de um programa que se pode manter.
PEP 8 em uma página
| Elemento | Convenção | Exemplo |
|---|---|---|
| Variável e função | snake_case | calcular_media() |
| Constante | MAIÚSCULAS | VELOCIDADE_LUZ |
| Classe | CapWords | ContaCorrente |
| Módulo | minúsculas curtas | conversoes.py |
| Indentação | 4 espaços | sem tabulação |
| Linha | até 79 caracteres | quebre dentro de parênteses |
| Espaços | ao redor de operadores | a = b + 1 |
| Uso interno | sublinhado inicial | _saldo |
Mesmo resultado, esforço de leitura bem diferente. Ferramentas como black, ruff e flake8 automatizam essa revisão.
# Antes
def Calc(L):
T=0
for I in range( len(L) ):T=T+L[I]
return T/len(L)
# Depois
def calcular_media(valores):
"""Retorna a média aritmética de uma sequência numérica."""
if not valores:
return 0.0
return sum(valores) / len(valores)
print(Calc([7, 8, 9]), calcular_media([7, 8, 9]))8.0 8.0
Python não impõe os tipos anotados em tempo de execução, mas o editor e o mypy passam a apontar erros antes de você rodar o programa.
def media(valores: list[float]) -> float:
return sum(valores) / len(valores) if valores else 0.0
def formatar(nome: str, nota: float, aprovado: bool = False) -> str:
marca = "aprovado" if aprovado else "em avaliação"
return f"{nome}: {nota:.1f} ({marca})"
print(media([8.0, 9.0]))
print(formatar("Ana", 8.5, True))
print(media.__annotations__)8.5
Ana: 8.5 (aprovado)
{'valores': list[float], 'return': <class 'float'>}Depuração
assert documenta e verifica hipóteses durante o desenvolvimento. Não use para validar entrada do usuário: asserções somem quando o Python roda com a opção -O.
def desconto(preco, percentual):
assert 0 <= percentual <= 100, "percentual fora da faixa"
return preco * (1 - percentual / 100)
print(desconto(100, 15))
try:
desconto(100, 150)
except AssertionError as erro:
print("AssertionError:", erro)85.0 AssertionError: percentual fora da faixa
Cada método iniciado por test_ vira um caso de teste. Rodar os testes depois de cada alteração é o que permite refatorar sem medo.
import unittest
def media(valores):
return sum(valores) / len(valores) if valores else 0.0
class TesteMedia(unittest.TestCase):
def test_lista_normal(self):
self.assertAlmostEqual(media([8, 9, 10]), 9.0)
def test_lista_vazia(self):
self.assertEqual(media([]), 0.0)
def test_um_elemento(self):
self.assertEqual(media([7]), 7)
unittest.main(argv=["prog"], exit=False, verbosity=2)test_lista_normal (__main__.TesteMedia.test_lista_normal) ... ok test_lista_vazia (__main__.TesteMedia.test_lista_vazia) ... ok test_um_elemento (__main__.TesteMedia.test_um_elemento) ... ok ---------------------------------------------------------------------- Ran 3 tests in 0.000s OK
Com logging você liga e desliga o nível de detalhe sem apagar linhas de código, e ainda pode gravar tudo em arquivo.
import logging
logging.basicConfig(
level=logging.INFO,
format="%(levelname)s | %(message)s")
logging.debug("detalhe que só interessa ao desenvolvedor")
logging.info("processando 3 arquivos")
logging.warning("valor de RSSI acima do esperado")
logging.error("falha ao abrir a porta serial")INFO | processando 3 arquivos WARNING | valor de RSSI acima do esperado ERROR | falha ao abrir a porta serial
| Sintoma | Causa provável | Como resolver |
|---|---|---|
IndentationError | espaços e tabulação misturados | configure o editor para 4 espaços |
NameError | nome digitado errado ou usado antes de existir | confira a grafia e a ordem |
TypeError: can only concatenate str | somar texto com número | converta com str() ou use f-string |
| Lista muda sozinha | duas variáveis apontam para a mesma lista | use .copy() |
| Laço nunca termina | condição do while nunca muda | verifique o incremento |
| Resultado 0 em divisão | divisão inteira com // | use / |
| Acento vira símbolo | encoding errado na leitura | informe encoding="utf-8" |
Experimentos propostos
- Reescreva um programa antigo seu seguindo a Tabela 15.1.
- Acrescente anotações de tipo a três funções já escritas.
- Escreva testes
unittestpara a sua função de média. - Troque todos os
printde depuração de um projeto por chamadas delogging.
16Projetos integradores
Quatro programas completos que combinam o conteúdo das seções anteriores. Cada um cabe em uma tela e serve de ponto de partida para trabalhos maiores.
Conjuntos guardam as letras tentadas, all() detecta a vitória e uma função pequena cuida da máscara.
import random
PALAVRAS = ["python", "antena", "modulacao", "protocolo"]
def mascarar(palavra, achadas):
return " ".join(c if c in achadas else "_" for c in palavra)
def jogar(tentativas=6):
random.seed(2) # remova para sortear de fato
palavra = random.choice(PALAVRAS).upper()
achadas = set()
while tentativas > 0:
print(f"\n{mascarar(palavra, achadas)} "
f"({tentativas} tentativas)")
if all(c in achadas for c in palavra):
return f"Acertou: {palavra}"
letra = input("letra: ").upper().strip()
if len(letra) != 1 or not letra.isalpha():
print("digite uma única letra")
continue
if letra in achadas:
print("letra já usada")
continue
achadas.add(letra)
if letra in palavra:
print("existe na palavra")
else:
tentativas -= 1
print("não existe")
return f"Acabaram as tentativas. Era {palavra}"
print(jogar())_ _ _ _ _ _ (6 tentativas) letra: p existe na palavra P _ _ _ _ _ (6 tentativas) letra: y existe na palavra P Y _ _ _ _ (6 tentativas) letra: t existe na palavra P Y T _ _ _ (6 tentativas) letra: a não existe P Y T _ _ _ (5 tentativas) letra: h existe na palavra P Y T H _ _ (5 tentativas) letra: o existe na palavra P Y T H O _ (5 tentativas) letra: n existe na palavra P Y T H O N (5 tentativas) Acertou: PYTHON
import json
from pathlib import Path
ARQUIVO = Path("boletim.json")
def media(notas):
return sum(notas) / len(notas) if notas else 0.0
def salvar(turma):
ARQUIVO.write_text(json.dumps(turma, ensure_ascii=False,
indent=2), encoding="utf-8")
def carregar():
if ARQUIVO.exists():
return json.loads(ARQUIVO.read_text(encoding="utf-8"))
return {}
def relatorio(turma):
print(f"{'ALUNO':<10}{'MÉDIA':>7} SITUAÇÃO")
print("-" * 30)
for nome, notas in sorted(turma.items(),
key=lambda p: -media(p[1])):
m = media(notas)
print(f"{nome:<10}{m:>7.2f} "
f"{'aprovado' if m >= 7 else 'exame'}")
medias = [media(n) for n in turma.values()]
print("-" * 30)
print(f"{'TURMA':<10}{sum(medias) / len(medias):>7.2f}")
turma = carregar()
turma.update({"Ana": [8.5, 9.0], "Bruno": [6.0, 6.5],
"Carlos": [7.5, 8.0]})
salvar(turma)
relatorio(carregar())ALUNO MÉDIA SITUAÇÃO ------------------------------ Ana 8.75 aprovado Carlos 7.75 aprovado Bruno 6.25 exame ------------------------------ TURMA 7.58
from collections import Counter
LINHAS = """2026-07-22 10:01 INFO estação iniciada
2026-07-22 10:03 WARNING sinal fraco em 145.8
2026-07-22 10:04 ERROR falha na porta serial
2026-07-22 10:07 INFO pacote recebido
2026-07-22 10:09 ERROR falha na porta serial"""
with open("estacao.log", "w", encoding="utf-8") as f:
f.write(LINHAS)
niveis = Counter()
mensagens_erro = []
with open("estacao.log", encoding="utf-8") as f:
for linha in f:
partes = linha.split(maxsplit=3)
if len(partes) < 4:
continue
_, hora, nivel, mensagem = partes
niveis[nivel] += 1
if nivel == "ERROR":
mensagens_erro.append((hora, mensagem.strip()))
print("ocorrências por nível:", dict(niveis))
print("erros registrados:")
for hora, msg in mensagens_erro:
print(f" {hora} {msg}")
print("mensagem de erro mais comum:",
Counter(m for _, m in mensagens_erro).most_common(1))ocorrências por nível: {'INFO': 2, 'WARNING': 1, 'ERROR': 2}
erros registrados:
10:04 falha na porta serial
10:09 falha na porta serial
mensagem de erro mais comum: [('falha na porta serial', 2)]O mesmo esqueleto (menu, dicionário e persistência em JSON) atende a controle de estoque, cadastro de equipamentos e registro de medidas.
import json
from pathlib import Path
ARQUIVO = Path("agenda.json")
def carregar():
if ARQUIVO.exists():
return json.loads(ARQUIVO.read_text(encoding="utf-8"))
return {}
def salvar(agenda):
ARQUIVO.write_text(json.dumps(agenda, ensure_ascii=False,
indent=2), encoding="utf-8")
def menu():
agenda = carregar()
while True:
print("\n1 incluir | 2 listar | 3 remover | 0 sair")
opcao = input("opção: ").strip()
if opcao == "1":
nome = input("nome: ").strip()
agenda[nome] = input("telefone: ").strip()
salvar(agenda)
print("contato salvo")
elif opcao == "2":
if not agenda:
print("agenda vazia")
for nome, fone in sorted(agenda.items()):
print(f" {nome:<10} {fone}")
elif opcao == "3":
removido = agenda.pop(input("nome: ").strip(), None)
salvar(agenda)
print("removido" if removido else "não encontrado")
elif opcao == "0":
print("até logo")
break
else:
print("opção inválida")
menu()1 incluir | 2 listar | 3 remover | 0 sair opção: 1 nome: Ana telefone: 48 99999-1111 contato salvo 1 incluir | 2 listar | 3 remover | 0 sair opção: 1 nome: Bruno telefone: 48 98888-2222 contato salvo 1 incluir | 2 listar | 3 remover | 0 sair opção: 2 Ana 48 99999-1111 Bruno 48 98888-2222 1 incluir | 2 listar | 3 remover | 0 sair opção: 3 nome: Ana removido 1 incluir | 2 listar | 3 remover | 0 sair opção: 2 Bruno 48 98888-2222 1 incluir | 2 listar | 3 remover | 0 sair opção: 0 até logo
Experimentos propostos
- Acrescente ao jogo da forca um placar salvo em arquivo.
- Inclua no boletim a opção de lançar notas pelo teclado.
- Estenda o analisador de log para aceitar o nome do arquivo como argumento de linha de comando (
sys.argv). - Reescreva a agenda usando uma classe
Contatoe uma classeAgenda.
Apêndices
Tabelas de consulta rápida durante as aulas e as provas.
AReferência de operadores
Tudo o que aparece entre valores, reunido em uma página.
| Aritmético | Efeito | Exemplo |
|---|---|---|
+ - * | soma, subtração, multiplicação | 3 * 4 = 12 |
/ | divisão real | 7 / 2 = 3.5 |
// | divisão inteira | 7 // 2 = 3 |
% | resto | 7 % 2 = 1 |
** | potência | 2 ** 10 = 1024 |
| Atribuição | Equivale a |
|---|---|
x += 3 | x = x + 3 |
x -= 3 | x = x - 3 |
x *= 3 | x = x * 3 |
x /= 3 | x = x / 3 |
x //= 3 | x = x // 3 |
x %= 3 | x = x % 3 |
x **= 3 | x = x ** 3 |
| Lógico e de pertencimento | Resultado |
|---|---|
a and b | verdadeiro só quando os dois são verdadeiros |
a or b | verdadeiro quando pelo menos um é verdadeiro |
not a | inverte o valor |
x in colecao | x pertence à coleção |
x not in colecao | x não pertence |
a is b | a e b são o mesmo objeto |
a is not b | objetos diferentes |
BMétodos essenciais por tipo
As chamadas que resolvem a maior parte dos exercícios.
Listas
| Método | Faz |
|---|---|
.append(x) | acrescenta no fim |
.insert(i, x) | insere na posição i |
.extend(outra) | concatena outra sequência |
.remove(x) | remove a primeira ocorrência |
.pop(i) | remove e devolve (padrão: o último) |
.index(x) | posição da primeira ocorrência |
.count(x) | quantas vezes x aparece |
.sort() | ordena no lugar |
.reverse() | inverte no lugar |
.copy() | cópia rasa |
.clear() | esvazia |
Dicionários
| Método | Faz |
|---|---|
.get(k, padrao) | valor sem erro se faltar |
.keys() | as chaves |
.values() | os valores |
.items() | pares chave e valor |
.update(outro) | mescla outro dicionário |
.pop(k) | remove e devolve o valor |
.setdefault(k, v) | devolve o valor, criando se faltar |
.copy() | cópia rasa |
Conjuntos
| Método | Faz |
|---|---|
.add(x) | acrescenta um elemento |
.update(iteravel) | acrescenta vários |
.remove(x) | remove (erro se faltar) |
.discard(x) | remove sem erro |
.union(b) ou | | união |
.intersection(b) ou & | interseção |
.difference(b) ou - | diferença |
.issubset(b) | está contido em b |
Funções internas mais usadas
| Função | Faz |
|---|---|
len(x) | quantidade de elementos |
sum(x) | soma |
min(x) max(x) | menor e maior |
sorted(x, key=, reverse=) | cópia ordenada |
enumerate(x, start=) | índice e valor |
zip(a, b) | percorre em paralelo |
any(x) all(x) | algum ou todos verdadeiros |
range(i, f, p) | sequência numérica |
type(x) isinstance(x, T) | tipo do objeto |
round(x, n) | arredondamento |
abs(x) | valor absoluto |
repr(x) | representação para depuração |
CFormatação de saída
Referência dos códigos usados dentro de f-strings e de strftime.
| Especificação | Efeito | Exemplo | Resultado |
|---|---|---|---|
:.2f | duas casas decimais | f"{3.14159:.2f}" | 3.14 |
:,.2f | separador de milhar | f"{1234.5:,.2f}" | 1,234.50 |
:.1% | percentual | f"{0.256:.1%}" | 25.6% |
:.2e | notação científica | f"{12345:.2e}" | 1.23e+04 |
:05d | zeros à esquerda | f"{42:05d}" | 00042 |
:<10 | alinha à esquerda | f"{'ab':<10}|" | ab________| |
:>10 | alinha à direita | f"{'ab':>10}|" | ________ab| |
:^10 | centraliza | f"{'ab':^10}|" | ____ab____| |
:*^10 | centraliza preenchendo | f"{'ab':*^10}" | ****ab**** |
:x :o :b | hexadecimal, octal, binário | f"{255:x}" | ff |
= | mostra a expressão | f"{preco=}" | preco=39.9 |
| Código | Significado | Exemplo |
|---|---|---|
%d | dia com dois dígitos | 22 |
%m | mês com dois dígitos | 07 |
%Y | ano com quatro dígitos | 2026 |
%H:%M:%S | hora, minuto e segundo | 14:30:00 |
%A %B | dia e mês por extenso | depende do idioma do sistema |
%j | dia do ano | 203 |
DCartão de consulta rápida
A sintaxe do manual inteiro em um bloco só, para imprimir e deixar ao lado do teclado.
# ---- entrada e saida -------------------------------------------
nome = input("Nome: ")
idade = int(input("Idade: "))
print(f"{nome} tem {idade} anos e média {7.5:.2f}")
# ---- decisao ---------------------------------------------------
if nota >= 7: pass
elif nota >= 5: pass
else: pass
conceito = "A" if nota >= 9 else "B"
# ---- repeticao -------------------------------------------------
for i in range(1, 11): pass
for i, item in enumerate(lista, start=1): pass
for a, b in zip(lista_a, lista_b): pass
while condicao: pass # break / continue / else
# ---- colecoes --------------------------------------------------
lista = [1, 2, 3]; lista.append(4)
tupla = (1, 2, 3)
dicio = {"chave": "valor"}; dicio.get("chave", "padrao")
conj = {1, 2, 3}; conj.add(4)
pares = [x ** 2 for x in lista if x % 2 == 0]
# ---- funcoes ---------------------------------------------------
def calcular(a, b=1, *args, **kwargs) -> float:
"""Docstring."""
return a + b
# ---- classes ---------------------------------------------------
class Aluno:
def __init__(self, nome):
self.nome = nome
def __str__(self):
return self.nome
# ---- arquivos --------------------------------------------------
with open("dados.txt", "w", encoding="utf-8") as f:
f.write("linha\n")
# ---- excecoes --------------------------------------------------
try: pass
except ValueError as erro: print(erro)
else: pass
finally: pass
# ---- ponto de entrada ------------------------------------------
if __name__ == "__main__":
main()Para continuar estudando
- Documentação oficial em português:
docs.python.org/pt-br/3/ - Tutorial oficial, capítulos 3 a 9, cobre tudo o que há neste manual com mais profundidade.
- PEP 8, o guia de estilo:
peps.python.org/pep-0008/ - Exercícios progressivos: Beecrowd, Exercism e Advent of Code.
- Próximos passos naturais no curso:
numpyematplotlibpara análise de sinais,pandaspara tabelas,requestspara APIs epyserialpara instrumentação.