Aprenda Python escrevendo Python.
Um caderno de estudo que segue a mesma ordem da matéria: de algoritmo em português até vetores, registros e funções. Todo exemplo roda aqui mesmo, no navegador, sem instalar nada.
Seu progresso
Nenhum exercício resolvido ainda.
A trilha
As lições seguem os capítulos da sua lista de exercícios. Faça na ordem: cada uma usa o que veio antes.
Como usar este caderno
- Rodar executa o exemplo e mostra a saída logo abaixo. Mude o código no Playground para testar suas ideias.
- Quando o programa usa
input(), os valores "digitados" vêm da caixa Entrada, uma linha porinput(). - Nos exercícios, o botão Verificar testa sua resposta com vários casos e marca o exercício como resolvido.
Para rodar no seu computador: instale o Python em python.org/downloads (no Windows, marque Add Python to PATH). Salve o código num arquivo programa.py e rode com python programa.py no terminal, ou use o IDLE, o VS Code ou o Thonny.
Do algoritmo em português ao Python
Um algoritmo é uma sequência finita de passos claros que resolve um problema. Programar é escrever esses passos numa língua que o computador entende.
Os três blocos de todo programa
Quase todo exercício da lista tem o mesmo esqueleto: entrada → processamento → saída. Antes de escrever código, separe essas três partes.
| Parte | Pergunta | Exemplo: média de 3 notas |
|---|---|---|
| Entrada | Quais dados eu preciso receber? | nota1, nota2, nota3 |
| Processamento | Que conta ou decisão eu faço com eles? | media = (nota1 + nota2 + nota3) / 3 |
| Saída | O que eu mostro no final? | a média |
nota1 = float(input("Nota 1: ")) # entrada
nota2 = float(input("Nota 2: "))
nota3 = float(input("Nota 3: "))
media = (nota1 + nota2 + nota3) / 3 # processamento
print("Média:", round(media, 2)) # saída
Tradutor Portugol → Python
Na aula você escreve pseudocódigo (Portugol). Esta tabela mostra o equivalente de cada comando. Guarde ela: é a ponte entre a lista e o Python.
| Portugol | Python | Observação |
|---|---|---|
inteiro: X | x = 0 | Python não declara tipo; ele vem do valor |
real / caractere / lógico | float / str / bool | lógico: True e False |
X ← 5 | x = 5 | atribuição usa um só = |
leia(X) | x = int(input()) | input() devolve texto; converta |
escreva(X) | print(x) | |
X MOD 2 | x % 2 | resto da divisão |
X DIV 2 | x // 2 | divisão inteira |
X ** 3 | x ** 3 | potência (igual!) |
= (comparar), <> | ==, != | |
E, OU, NÃO, XOU | and, or, not, != | XOU entre lógicos é "diferente" |
se … então … senão … fim_se | if …: / else: | o bloco é marcado pela indentação |
senão se | elif | |
escolha (X) caso 1: … | match x: / case 1: | ou uma cadeia de elif |
enquanto … faça | while …: | |
para I de 1 até 10 faça | for i in range(1, 11): | o fim do range não entra |
repita … até (cond) | while True: … if cond: break | Python não tem repita |
vetor[1..10] de inteiro | v = [0] * 10 | índices começam em 0 |
matriz[1..3,1..3] | m = [[0]*3 for _ in range(3)] | m[i][j] |
registro | dict ou class | aluno["nome"] |
procedimento / função | def nome(...): | função usa return |
Exemplo lado a lado
Exercício 31 da lista: dizer se um número é positivo, negativo ou zero.
início
inteiro: NUM
leia(NUM)
se (NUM > 0) então
QUALE ← "NÚMERO POSITIVO"
senão
se (NUM < 0) então
QUALE ← "NÚMERO NEGATIVO"
senão
QUALE ← "ZERO"
escreva(QUALE)
fim
num = int(input("Número: "))
if num > 0:
quale = "NÚMERO POSITIVO"
elif num < 0:
quale = "NÚMERO NEGATIVO"
else:
quale = "ZERO"
print(quale)
Pensar antes de codar
- Entenda o problema. Reescreva com suas palavras. Quais são as entradas e a saída?
- Resolva um caso no papel. Com números de verdade: se o salário é 1000 e o aumento 22%, o resultado é 1220.
- Escreva os passos em português. Do jeito do exercício 8 (o robô MANNY): instruções pequenas, sem pular nada.
- Traduza para Python usando a tabela acima.
- Teste com casos diferentes, inclusive os chatos: zero, negativo, lista vazia, empate.
Os exercícios 1 a 11 (banho, pneu, lâmpada, travessia do rio, Torre de Hanói) treinam justamente o passo 3. Não pule: quem escreve bons passos em português escreve bons programas.
A Torre de Hanói (exercício 10) tem uma solução famosa em Python. Rode e veja os movimentos para 3 discos:
def hanoi(n, origem, destino, auxiliar):
if n == 1:
print(f"Mova o disco 1 de {origem} para {destino}")
return
hanoi(n - 1, origem, auxiliar, destino)
print(f"Mova o disco {n} de {origem} para {destino}")
hanoi(n - 1, auxiliar, destino, origem)
hanoi(3, "A", "C", "B")
Variáveis e tipos de dados
Uma variável é um nome que guarda um valor. Em Python você não declara o tipo: ele é descoberto pelo valor que você coloca.
Os tipos básicos
| Portugol | Python | Exemplos | Uso |
|---|---|---|---|
| inteiro | int | -5, 0, 3257 | contagens, idade, matrícula |
| real | float | 0.21, -0.001, 2.0 | notas, preços, alturas (use ponto, não vírgula) |
| caractere | str | "José", "a", "+3257" | nomes, textos, códigos |
| lógico | bool | True, False | condições, flags |
| — | NoneType | None | "nenhum valor ainda" |
nb = 8.5 # nota do aluno -> float na = "Maria" # nome do aluno -> str nmat = 20241532 # matrícula -> int sx = "F" # sexo -> str aprovado = nb >= 7 # resultado de comparação -> bool print(type(nb), type(na), type(nmat), type(sx), type(aprovado))
Pegadinha do exercício 16: "+3257" com aspas é texto, não número. 0,35 com vírgula não é um número em Python (vira uma tupla!). R$ 50,00 e 1% não têm tipo definido: precisam ser convertidos.
Regras para nomes (identificadores)
Exercício 17. Um nome válido:
- começa com letra ou
_(nunca com número):b248✔,3x4✘ - tem só letras, números e
_:nota*do*aluno✘,km/h✘,ah!✘ - não tem espaço:
nome empresa✘ → usenome_empresa - não é palavra reservada (
if,for,class…) e diferencia maiúsculas:Maria≠maria
Convenção em Python: snake_case, tudo minúsculo com _: salario_liquido, total_vendas.
Conversão entre tipos
input() sempre devolve texto. Para fazer contas, converta:
print(int("42") + 1) # 43
print(float("7.5") * 2) # 15.0
print(str(10) + " anos") # '10 anos'
print(int(9.99)) # 9 (corta, não arredonda)
print(round(9.99)) # 10
print(bool(0), bool(5), bool(""), bool("oi")) # False True False True
print("5" + "5", 5 + 5) # 55 10 (texto junta, número soma)
Atribuição múltipla e troca
Os exercícios 41 e 57 pedem para trocar o conteúdo de A e B. No Portugol você usa uma variável auxiliar. Em Python dá para fazer dos dois jeitos:
a, b = 10, 20 aux = a # jeito clássico, com auxiliar a = b b = aux print(a, b) # 20 10 a, b = b, a # jeito Python, troca direta print(a, b) # 10 20
Operadores e expressões
Aritméticos
| Operador | Nome | Exemplo | Resultado |
|---|---|---|---|
+ | soma | 7 + 2 | 9 |
- | subtração | 7 - 2 | 5 |
* | multiplicação | 7 * 2 | 14 |
/ | divisão (sempre real) | 7 / 2 | 3.5 |
// | divisão inteira (DIV) | 7 // 2 | 3 |
% | resto (MOD) | 7 % 2 | 1 |
** | potência | 7 ** 2 | 49 |
% e // aparecem o tempo todo: n % 2 == 0 testa se é par; n % 10 pega o último dígito; n // 10 tira o último dígito.
Precedência (quem vem primeiro)
( )parênteses**potência-xsinal negativo*///%(da esquerda para a direita)+-- comparações
== != < <= > >= not, depoisand, depoisor
Exercício 18: os pares dão o mesmo resultado? Tente responder antes de rodar.
print((4/2)+(2/4), 4/2+2/4, (4/2)+(2/4) == 4/2+2/4) print(4/(2+2)/4, 4/2+2/4, 4/(2+2)/4 == 4/2+2/4) print((4+2)*2-4, 4+2*2-4, (4+2)*2-4 == 4+2*2-4)
Exercício 19 (tirar parênteses sem mudar o resultado): se a resposta estiver certa, as duas contas dão igual.
print(6*(3+2), "=", 6*(3+2)) # a) não dá para tirar print((6/3)+(8/2), "=", 6/3+8/2) # b) print(((3+(8/2))*4)+(3*2), "=", (3+8/2)*4+3*2) # d) print((((10*8)+3)*9), "=", (10*8+3)*9) # h)
Comparação e lógica
Comparações devolvem True ou False. Combine com and (E), or (OU), not (NÃO).
| A | B | A and B | A or B | not A | A != B (XOU) |
|---|---|---|---|---|---|
| True | True | True | True | False | False |
| True | False | False | True | False | True |
| False | True | False | True | True | True |
| False | False | False | False | True | False |
Exercícios 20b, 21, 23 e 24 traduzidos. Escreva sua resposta no caderno e depois confira rodando:
A, B, C = 1, 2, 3
X, Y, Z = 2.0, 10.0, -1.0
L1, L2 = True, False
NOME, RUA = "PEDRO", "PEDRINHO"
print("20b a)", A + C / B)
print("20b c)", C / B / A)
print("20b e)", (-X) ** C)
print("20b f)", NOME + RUA)
print("20b g)", NOME == RUA)
print("20b k)", (L1 and not L2) or (L2 and not L1))
print("20b l)", X == Y and C == B)
A, B, C = True, True, False
print("21 a)", (A and B) or (A != B))
print("21 b)", (A or B) and (A and C))
print("21 c)", A or (C and B) != (A and not B))
A, B, C = 3, 7, 4
print("23:", (A+C) > B, B >= (A+2), C == (B-A), (B+A) <= C, (C+A) > B)
A, B, C, D = 5, 4, 3, 6
print("24:", (A > C) and (C <= D), (A+B) > D or (A+B) == (C+D), (A >= C) and (D >= C))
Atribuição composta
total = 10 total += 5 # total = total + 5 -> 15 total -= 3 # 12 total *= 2 # 24 total //= 5 # 4 total **= 2 # 16 print(total)
Teste de mesa: rodar o programa na cabeça
Fazer teste de mesa é executar o algoritmo à mão, linha por linha, anotando o valor de cada variável numa tabela. É o melhor jeito de achar erros de lógica.
Como fazer
- Desenhe uma coluna para cada variável.
- Leia uma linha do algoritmo por vez.
- Toda vez que uma variável recebe valor, escreva o novo valor embaixo (risque o antigo).
- Nas decisões (
if), calcule a condição e siga só o caminho que deu verdadeiro.
Pratique: exercício 27
O algoritmo lê x e y, calcula z = x*y + 5 e classifica: z <= 0 → A, z <= 100 → B, senão → C. Preencha a tabela e clique em conferir.
| X | Y | Z | Resposta |
|---|
Depois confira com o Python:
for x, y in [(3, 2), (150, 3), (7, -1), (-2, 5), (50, 3)]:
z = (x * y) + 5
if z <= 0:
resposta = "A"
elif z <= 100:
resposta = "B"
else:
resposta = "C"
print(x, y, z, resposta)
Exercício 32: separando dígitos
Faça a tabela de NUM, DIGITO1..4 e depois rode:
num = 1352 digito4 = num % 10 digito3 = (num // 10) % 10 digito2 = (num // 100) % 10 digito1 = (num // 1000) % 10 print(digito4, digito3, digito2, digito1)
Exercício 30
A, B, C = False, True, False
X, Y = 1.8, 3.4
X = X + 1
if C or ((X + Y > 5) or (A and B)):
L = 0
else:
L = 1
print("X + Y =", X + Y, "-> L =", L)
Teste de mesa com print
No computador, o jeito mais rápido de "ver" as variáveis é colocar print dentro do laço. Isso é um teste de mesa automático:
soma = 0
for i in range(1, 6):
soma = soma + i
print(f"i={i} soma={soma}")
Entrada, contas e saída
Estrutura sequencial: as instruções rodam uma depois da outra, de cima para baixo, sem desvio. É o capítulo dos exercícios 33 a 71.
print: mostrar na tela
print("Olá, mundo!")
print("Soma:", 2 + 3) # vários itens separados por espaço
print("a", "b", "c", sep="-") # muda o separador
print("sem pular linha", end=" ")
print("continua aqui")
input: ler do teclado
O texto entre parênteses é a mensagem que aparece para o usuário. O resultado é sempre str.
nome = input("Seu nome: ")
idade = int(input("Sua idade: ")) # inteiro
altura = float(input("Sua altura (m): ")) # real
print(nome, "tem", idade, "anos e", altura, "m")
Esqueceu de converter? input("x: ") + 1 dá TypeError (texto + número). Sempre use int(...) ou float(...) em volta do input quando o dado for número.
f-strings: formatar a saída
Coloque um f antes das aspas e as variáveis entre { }. Para dinheiro, use :.2f (duas casas).
nome = "Carla"
salario = 2500
novo = salario * 1.22
print(f"{nome} vai receber R$ {novo:.2f}")
print(f"{0.1534:.1%}") # porcentagem: 15.3%
print(f"[{'dir':>8}]") # alinhado à direita em 8 casas
print(f"{1234567.891:,.2f}") # separador de milhar
Para o formato brasileiro (vírgula decimal), troque os caracteres:
valor = 1234.5
texto = f"{valor:,.2f}".replace(",", "X").replace(".", ",").replace("X", ".")
print("R$", texto) # R$ 1.234,50
Modelo pronto para os exercícios de sequência
Exercício 47 (aumento de 22%) e 66 (IMC) no mesmo formato. Repare: entrada, conta, saída.
salario = float(input("Salário: "))
novo_salario = salario * 1.22 # 22% a mais = multiplicar por 1.22
print(f"Novo salário: R$ {novo_salario:.2f}")
massa = float(input("Massa (kg): "))
altura = float(input("Altura (m): "))
imc = massa / altura ** 2
print(f"IMC = {imc:.1f}")
Porcentagens: aumento de 22% → valor * 1.22. Desconto de 20% → valor * 0.80. "X% de valor" → valor * X / 100.
Precisa de raiz quadrada ou π (exercícios 36, 56, 67)? Importe o módulo math:
import math print(math.sqrt(3**2 + 4**2)) # hipotenusa: 5.0 raio = 2 print(2 * math.pi * raio) # comprimento da circunferência print(4/3 * math.pi * raio**3) # volume da esfera
Decisões com if, elif e else
A estrutura de seleção escolhe qual bloco executar conforme uma condição. Exercícios 72 a 115.
A forma geral
media = float(input("Média: "))
if media >= 7:
print("Aprovado")
elif media >= 5:
print("Recuperação")
else:
print("Reprovado")
print("Fim") # fora do if: roda sempre
- Todo
if,elifeelsetermina com dois-pontos:. - O bloco de dentro tem 4 espaços de recuo. É o recuo que diz o que está dentro do
if(no Portugol era ofim_se). - O Python testa de cima para baixo e executa só o primeiro bloco verdadeiro.
Faixas de valores
Tabelas como as dos exercícios 77, 96, 97 e 114 viram uma cadeia de elif. Como o primeiro verdadeiro ganha, você só precisa testar o limite de cima:
salario = float(input("Salário atual: "))
if salario <= 1000:
aumento = 0.20
elif salario <= 5000: # aqui já sabemos que é > 1000
aumento = 0.10
else:
aumento = 0.0
print(f"Novo salário: R$ {salario * (1 + aumento):.2f}")
Python aceita comparações encadeadas, como na matemática:
n = 5 print(1 <= n <= 9) # exercício 87: está na faixa? idade = 15 print(16 <= idade < 18) # voto facultativo?
Condições compostas
idade, tempo = 61, 26
# exercício 115: qualquer um dos requisitos serve -> OR
if idade >= 65 or tempo >= 30 or (idade >= 60 and tempo >= 25):
print("Requerer aposentadoria")
else:
print("Não requerer")
Ifs aninhados
Um if dentro do outro. Útil quando a segunda pergunta só faz sentido depois da primeira (exercício 84):
notas = [float(input(f"Nota {i}: ")) for i in range(1, 5)]
media = sum(notas) / 4
if media >= 7:
print(f"Aprovado com média {media:.1f}")
else:
exame = float(input("Nota do exame: "))
nova = (media + exame) / 2
if nova >= 5:
print(f"Aprovado em exame com média {nova:.1f}")
else:
print(f"Reprovado com média {nova:.1f}")
If de uma linha
n = 7 paridade = "par" if n % 2 == 0 else "ímpar" print(n, "é", paridade)
Valores "verdadeiros" e "falsos"
Zero, texto vazio "", lista vazia [] e None contam como falso. O resto conta como verdadeiro.
nome = ""
if not nome:
print("Nome não informado")
Escolha-caso: match, elif e dicionários
Quando uma variável pode ter vários valores e cada um leva a uma ação diferente (menus, códigos de produto, meses). Exercícios 116 a 122.
match / case (Python 3.10+)
É o escolha do Portugol. O case _ é o "senão" (qualquer outro valor).
codigo = int(input("Código do produto: "))
match codigo:
case 1:
print("Alimento não-perecível")
case 2 | 3 | 4: # vários valores no mesmo caso
print("Alimento perecível")
case 5 | 6:
print("Vestuário")
case 7:
print("Higiene Pessoal")
case n if 8 <= n <= 15: # faixa com "guarda"
print("Limpeza e Utensílios Domésticos")
case _:
print("Código inválido")
Com elif (funciona em qualquer versão)
codigo = 3
if codigo == 1:
print("Alimento não-perecível")
elif codigo in (2, 3, 4):
print("Alimento perecível")
else:
print("Outro")
Tabela de preços com dicionário
Quando a escolha é só "buscar um valor numa tabela" (cardápios dos exercícios 116 e 117), um dicionário resolve sem nenhum if:
cardapio = {
100: ("Cachorro quente", 1.20),
101: ("Bauru simples", 1.30),
102: ("Bauru com ovo", 1.50),
103: ("Hambúrguer", 1.20),
104: ("Cheeseburguer", 1.30),
105: ("Refrigerante", 1.00),
}
codigo = int(input("Código: "))
qtd = int(input("Quantidade: "))
if codigo in cardapio:
nome, preco = cardapio[codigo]
print(f"{qtd}x {nome} = R$ {qtd * preco:.2f}")
else:
print("Código inválido")
Menu que repete
Exercício 121 e a calculadora: um menu dentro de um laço, que só para quando o usuário escolhe sair.
while True:
op = input("Operação (+ - * /) ou S para sair: ").strip().upper()
if op == "S":
print("Até mais!")
break
a = float(input("a: "))
b = float(input("b: "))
match op:
case "+": print("Resultado:", a + b)
case "-": print("Resultado:", a - b)
case "*": print("Resultado:", a * b)
case "/":
if b == 0:
print("Não existe divisão por zero")
else:
print("Resultado:", a / b)
case _:
print("Operação inválida")
Laços: for e while
Repetir um bloco várias vezes. É o maior capítulo da lista (123 a 187) e o que mais treina lógica.
for com range: quando você sabe quantas vezes
for i in range(5): # 0, 1, 2, 3, 4
print(i, end=" ")
print()
for i in range(1, 11): # 1 até 10 (o 11 não entra!)
print(i, end=" ")
print()
for i in range(10, 0, -1): # 10 até 1, contando para trás (ex. 139)
print(i, end=" ")
print()
for i in range(10, 1001, 10): # 10, 20, ..., 1000 (ex. 136)
pass
print("último:", i)
| Portugol | Python |
|---|---|
para i de 1 até N faça | for i in range(1, n + 1): |
para i de N até 1 passo -1 | for i in range(n, 0, -1): |
para i de 0 até 100 passo 2 | for i in range(0, 101, 2): |
while: enquanto a condição for verdadeira
contador = 1
while contador <= 5:
print("Volta", contador)
contador += 1 # sem isso o laço nunca acaba!
Laço infinito: se a condição do while nunca ficar falsa, o programa não para. Aqui no navegador isso trava a aba. Confira sempre se alguma coisa dentro do laço muda a condição.
Os 4 padrões que resolvem quase tudo
1. Contador: quantos?
idades = [15, 22, 51, 19, 63, 30]
menores_21 = 0
for idade in idades:
if idade < 21:
menores_21 += 1 # conta +1
print("Menores de 21:", menores_21)
2. Acumulador: quanto ao todo?
soma = 0
for n in range(2, 101, 2): # pares de 1 a 100 (ex. 157)
soma += n # acumula o valor
print("Soma dos pares:", soma)
3. Maior e menor
Comece com o primeiro valor (não com zero!) e compare com cada um dos outros.
n = int(input("Quantos números? "))
maior = menor = None
for i in range(n):
x = int(input(f"Número {i + 1}: "))
if maior is None or x > maior:
maior = x
if menor is None or x < menor:
menor = x
print("Maior:", maior, "Menor:", menor)
4. Flag (valor de parada)
"Leia até digitar 0" (exercícios 130, 135, 156, 173). O 0 não entra na conta.
soma = 0
quantidade = 0
numero = int(input("Número (0 para parar): "))
while numero != 0:
soma += numero
quantidade += 1
numero = int(input("Número (0 para parar): "))
if quantidade > 0:
print("Média:", soma / quantidade)
else:
print("Nenhum número digitado")
Outra forma, com while True e break. É o "repita… até" do Portugol:
while True:
valor = float(input("Valor positivo: "))
if valor > 0:
break
print("Inválido, digite de novo")
print("Ok:", valor)
break, continue e else
for n in range(1, 21):
if n % 3 == 0:
continue # pula para a próxima volta
if n > 10:
break # sai do laço
print(n, end=" ")
print()
# for ... else: o else roda se o laço NÃO saiu por break
n = 29
for d in range(2, n):
if n % d == 0:
print(n, "não é primo")
break
else:
print(n, "é primo")
Laços aninhados
for i in range(1, 4):
for j in range(1, 4):
print(f"{i}x{j}={i*j}", end=" ")
print()
Ferramentas úteis
nomes = ["Ana", "Bia", "Caio"]
notas = [8.0, 6.5, 9.2]
for i, nome in enumerate(nomes): # índice e valor juntos
print(i, nome)
for nome, nota in zip(nomes, notas): # percorre duas listas juntas
print(nome, nota)
print(sum(notas), max(notas), min(notas), len(notas))
Trabalhando com textos
Uma str é uma sequência de caracteres. Dá para acessar cada letra, fatiar, procurar e transformar.
Índices e fatias
s = "PYTHON"
print(s[0], s[1], s[-1]) # P Y N (negativo conta do fim)
print(s[0:3]) # PYT (do 0 até antes do 3)
print(s[2:]) # THON
print(s[::-1]) # NOHTYP (invertido)
print(len(s)) # 6
for letra in s:
print(letra, end=" ")
Strings não mudam (são imutáveis). s[0] = "J" dá erro. Para "mudar", crie outra: s = "J" + s[1:].
Métodos mais usados
frase = " Socorram me subi no onibus em Marrocos "
print(frase.strip()) # tira espaços das pontas
print(frase.upper()) # MAIÚSCULAS
print(frase.lower()) # minúsculas
print(frase.strip().title()) # Cada Palavra Maiúscula
print(frase.replace(" ", "")) # remove todos os espaços
print(frase.split()) # quebra em lista de palavras
print("-".join(["a", "b", "c"])) # junta lista com separador: a-b-c
print(frase.count("o")) # quantas vezes aparece
print(frase.find("subi")) # posição (ou -1)
print("onibus" in frase) # True
print("123".isdigit(), "abc".isalpha())
A lista completa está em Métodos.
Exemplo: palíndromo (exercício 243)
def eh_palindromo(texto):
limpo = texto.replace(" ", "").lower()
return limpo == limpo[::-1]
for nome in ["ARARA", "ANA", "Pedro", "Socorram me subi no onibus em Marrocos"]:
print(nome, "->", eh_palindromo(nome))
Contando letras (exercícios 174 e 247)
frase = "programar em python e divertido"
vogais = {"a": 0, "e": 0, "i": 0, "o": 0, "u": 0}
for letra in frase:
if letra in vogais:
vogais[letra] += 1
print(vogais)
Caracteres e códigos
print(ord("A"), chr(66)) # 65 B
print(ord("a") - ord("A")) # distância entre minúscula e maiúscula
Listas: vetores e matrizes em Python
O vetor do Portugol vira uma list. Ela guarda vários valores em ordem, cresce sozinha e aceita qualquer tipo. Exercícios 188 a 273.
Criando e acessando
notas = [7.5, 8.0, 6.0, 9.5] print(notas[0]) # primeiro: 7.5 (índice começa em 0!) print(notas[-1]) # último: 9.5 notas[2] = 6.5 # altera a posição 2 print(notas, len(notas)) vazio = [] zeros = [0] * 10 # vetor de 10 posições com zero print(zeros)
No Portugol o vetor costuma ir de 1 a N. Em Python vai de 0 a N-1. Acessar v[len(v)] dá IndexError.
Lendo um vetor do usuário
n = int(input("Quantos valores? "))
v = []
for i in range(n):
v.append(int(input(f"v[{i}] = "))) # append adiciona no fim
print("Vetor:", v)
print("Invertido:", v[::-1]) # exercício 188/229
print("Soma:", sum(v), "Média:", sum(v) / len(v))
Ou numa linha só, com os números separados por espaço:
v = [int(x) for x in input("Números: ").split()]
print(v, "maior:", max(v), "na posição", v.index(max(v)))
Métodos de lista
v = [5, 3, 8] v.append(1) # [5, 3, 8, 1] v.insert(0, 9) # [9, 5, 3, 8, 1] v.remove(3) # remove o primeiro 3 ultimo = v.pop() # tira e devolve o último v.sort() # ordena (muda a lista) print(v, ultimo) print(sorted([3, 1, 2], reverse=True)) # cria lista nova ordenada print(8 in v, v.count(8), v.index(8))
Percorrendo dois vetores (exercícios 189, 204, 230)
a = [23, 37, 30]
b = [30, 32, 46]
c = []
for i in range(len(a)):
c.append(a[i] + b[i])
print(c)
print([x + y for x, y in zip(a, b)]) # mesma coisa, em uma linha
List comprehension
Um jeito curto de criar listas a partir de outras:
v = [4, -2, 7, 0, -9, 12] negativos = [x for x in v if x < 0] # exercício 202 pares = [x for x in v if x % 2 == 0] dobro = [x * 2 for x in v] # exercício 228 print(negativos, pares, dobro)
Ordenação na mão (exercício 232)
A professora pode pedir sem usar sort(). O método da bolha compara vizinhos e troca:
v = [5, 2, 9, 1, 7]
n = len(v)
for i in range(n - 1):
for j in range(n - 1 - i):
if v[j] > v[j + 1]:
v[j], v[j + 1] = v[j + 1], v[j]
print(v)
Matrizes: lista de listas
m = [
[1, 2, 3],
[4, 5, 6],
]
print(m[1][2]) # linha 1, coluna 2 -> 6
linhas, colunas = len(m), len(m[0])
for i in range(linhas): # percorre tudo
for j in range(colunas):
print(m[i][j], end="\t")
print()
soma_linhas = [sum(linha) for linha in m] # exercício 272
print(soma_linhas, "total:", sum(soma_linhas))
transposta = [[m[i][j] for i in range(linhas)] for j in range(colunas)]
print(transposta) # exercício 219/270
Criando uma matriz vazia N×M do jeito certo:
n, m = 3, 4 mat = [[0] * m for _ in range(n)] # certo mat[0][0] = 9 print(mat) errado = [[0] * m] * n # ERRADO: as linhas são a mesma lista errado[0][0] = 9 print(errado) # o 9 aparece em todas as linhas!
Diagonais de uma matriz quadrada:
m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] n = len(m) principal = [m[i][i] for i in range(n)] secundaria = [m[i][n - 1 - i] for i in range(n)] print(principal, secundaria)
Registros com dicionários
Um registro junta dados diferentes de uma mesma coisa (nome, idade, endereço de uma pessoa). Em Python, o jeito mais simples é o dict: pares de chave: valor.
Criando e usando um dicionário
aluno = {"nome": "Ana", "idade": 17, "notas": [8.0, 7.5, 9.0]}
print(aluno["nome"])
aluno["idade"] = 18 # altera
aluno["curso"] = "DS" # cria chave nova
print(aluno.get("email", "sem e-mail")) # get evita erro se não existir
print("notas" in aluno)
for chave, valor in aluno.items():
print(chave, "=>", valor)
Lista de registros (exercício 274)
pessoas = [
{"nome": "Ana", "idade": 17},
{"nome": "Bruno", "idade": 25},
{"nome": "Carla", "idade": 31},
{"nome": "Davi", "idade": 15},
]
primeira = pessoas[0]["idade"]
print("Mais velhos que a primeira:", [p["nome"] for p in pessoas if p["idade"] > primeira])
media = sum(p["idade"] for p in pessoas) / len(pessoas)
print("Acima da média:", [p["nome"] for p in pessoas if p["idade"] > media])
mais_velha = max(pessoas, key=lambda p: p["idade"])
mais_nova = min(pessoas, key=lambda p: p["idade"])
print("Maior idade:", mais_velha["nome"], "| Menor:", mais_nova["nome"])
Registro dentro de registro (exercício 275)
aluno = {
"nome": "Ana",
"endereco": {"rua": "Rua A, 10", "bairro": "Centro", "cidade": "São Paulo", "estado": "SP", "cep": "01000-000"},
}
print(aluno["endereco"]["cidade"])
Dicionário para contar
valores = [3, 1, 3, 2, 3, 1]
contagem = {}
for v in valores:
contagem[v] = contagem.get(v, 0) + 1 # exercício 251
print(contagem)
Tuplas e conjuntos
Tupla (( )) é uma lista que não muda: boa para pares fixos como coordenadas. Conjunto (set) não tem repetidos nem ordem: ótimo para "valores diferentes".
ponto = (3, 4)
x, y = ponto # desempacotar
print(x, y)
numeros = [1, 2, 2, 3, 3, 3]
print(set(numeros)) # {1, 2, 3}
print(len(set(numeros)) != len(numeros)) # tem repetidos? (ex. 200)
a, b = {1, 2, 3}, {2, 3, 4}
print(a & b, a | b, a - b) # interseção, união, diferença
Registro com classe (opcional)
Para registros com formato fixo, uma dataclass deixa o código mais organizado:
from dataclasses import dataclass
@dataclass
class Produto:
codigo: int
qtd_min: int
qtd_max: int
qtd_est: int
produtos = [Produto(1, 10, 50, 8), Produto(2, 5, 30, 20)]
for p in produtos: # exercício 277
if p.qtd_est <= p.qtd_min:
print("Comprar", p.qtd_max - p.qtd_est, "do produto", p.codigo)
Funções: dar nome a um pedaço de código
Uma função recebe dados (parâmetros), faz um trabalho e pode devolver um resultado (return). Sem return ela é o que o Portugol chama de procedimento.
Definindo e chamando
def saudacao(nome): # procedimento: só mostra
print(f"Olá, {nome}!")
def area_retangulo(base, altura): # função: devolve um valor
return base * altura
saudacao("Ana")
a = area_retangulo(3, 4)
print("Área:", a)
print(area_retangulo(2.5, 2) + 1)
print vs return: print só mostra na tela. return entrega o valor para quem chamou, que pode guardar numa variável, fazer contas ou mostrar. Nos exercícios com correção automática, a função precisa retornar.
Parâmetros com valor padrão e nomeados
def preco_final(preco, desconto=0.0, frete=10):
return preco * (1 - desconto) + frete
print(preco_final(100)) # 110.0
print(preco_final(100, 0.2)) # 90.0
print(preco_final(100, frete=0)) # 100.0
Retornando vários valores
def divisao(a, b):
return a // b, a % b # devolve uma tupla
q, r = divisao(17, 5)
print("quociente", q, "resto", r)
Escopo: variáveis locais
O que é criado dentro da função só existe lá dentro. Para usar fora, devolva com return.
def dobra(x):
resultado = x * 2
return resultado
print(dobra(5))
# print(resultado) -> NameError: resultado só existe dentro da função
Programa organizado em funções
Exercício 279: uma função por operação e um procedimento que conversa com o usuário.
def somar(a, b): return a + b
def subtrair(a, b): return a - b
def multiplicar(a, b): return a * b
def dividir(a, b): return a / b if b != 0 else None
def menu():
print("1-Somar 2-Subtrair 3-Multiplicar 4-Dividir")
op = int(input("Opção: "))
a = float(input("a: "))
b = float(input("b: "))
operacoes = {1: somar, 2: subtrair, 3: multiplicar, 4: dividir}
resultado = operacoes[op](a, b)
print("Resultado:", resultado)
menu()
Funções que chamam a si mesmas (recursão)
Precisa de um caso base (onde para) e de um passo que se aproxima dele.
def fatorial(n):
if n <= 1: # caso base
return 1
return n * fatorial(n - 1) # passo
print(fatorial(5), fatorial(10))
lambda: função de uma linha
quadrado = lambda x: x ** 2
print(quadrado(9))
alunos = [("Ana", 8.5), ("Bia", 9.7), ("Caio", 6.0)]
print(sorted(alunos, key=lambda a: a[1], reverse=True)) # ordena pela nota
Documentando
def eh_bissexto(ano: int) -> bool:
"""Retorna True se o ano for bissexto."""
return ano % 4 == 0 and (ano % 100 != 0 or ano % 400 == 0)
print(eh_bissexto(2024), eh_bissexto(1900), eh_bissexto(2000))
Erros comuns e como tratar
Lendo a mensagem de erro
A última linha da mensagem diz o tipo do erro. Aqui o caderno também explica cada um em português.
| Erro | Causa típica |
|---|---|
SyntaxError | faltou :, parêntese ou aspas |
IndentationError | recuo errado dentro de if/for/def |
NameError | variável não criada ou nome digitado errado |
TypeError | misturou tipos: "5" + 1 |
ValueError | conversão impossível: int("abc") |
IndexError | posição fora da lista |
KeyError | chave que não existe no dicionário |
ZeroDivisionError | divisão por zero |
Rode e leia a explicação:
idade = 17
print("Idade: " + idade)
try / except
try:
n = int(input("Número: "))
print("Dobro:", n * 2)
except ValueError:
print("Isso não é um número inteiro!")
Validar até acertar
O padrão mais útil da lição: repetir a pergunta até o usuário digitar algo válido (exercícios 181 e o desafio do 170).
def ler_positivo(msg):
while True:
try:
valor = float(input(msg))
except ValueError:
print("Digite um número.")
continue
if valor > 0:
return valor
print("O valor precisa ser maior que zero.")
divisor = ler_positivo("Divisor: ")
print("10 /", divisor, "=", 10 / divisor)
else, finally e raise
def sacar(saldo, valor):
if valor > saldo:
raise ValueError("Saldo insuficiente")
return saldo - valor
try:
novo = sacar(100, 250)
except ValueError as erro:
print("Erro:", erro)
else:
print("Novo saldo:", novo) # roda se não houve erro
finally:
print("Operação encerrada") # roda sempre
Módulos: math, random e datetime
Módulos são pacotes de funções prontas. Você importa e usa.
Formas de importar
import math print(math.sqrt(16)) from math import pi, ceil print(pi, ceil(4.1)) import random as rd print(rd.randint(1, 6))
math
import math print(math.sqrt(2)) # raiz quadrada print(math.pi, math.e) print(math.ceil(2.1)) # arredonda para cima: 3 (azulejos, ex. 65) print(math.floor(2.9)) # para baixo: 2 print(math.pow(2, 10)) # 1024.0 print(math.factorial(5)) # 120 print(math.gcd(12, 18)) # MDC: 6 print(math.hypot(3, 4)) # hipotenusa: 5.0
random
import random
print(random.randint(1, 60)) # inteiro entre 1 e 60
print(random.random()) # real entre 0 e 1
print(random.choice(["pedra", "papel", "tesoura"]))
palpite = sorted(random.sample(range(1, 61), 6)) # 6 números sem repetir (ex. 278)
print("Mega-Sena:", palpite)
cartas = [1, 2, 3, 4, 5]
random.shuffle(cartas)
print(cartas)
datetime
from datetime import date
hoje = date.today()
print(hoje, hoje.year)
nascimento = date(2008, 3, 15)
idade_dias = (hoje - nascimento).days
print("Dias de vida:", idade_dias)
print(hoje.strftime("%d/%m/%Y"))
Lendo e gravando arquivos
Para guardar dados depois que o programa termina (exercício 276). Os exemplos desta lição não rodam no navegador: teste no seu computador.
Gravar
produtos = [("P01", 12.50), ("P02", 8.90)]
with open("precos.txt", "w", encoding="utf-8") as arq:
for codigo, preco in produtos:
arq.write(f"{codigo};{preco}\n")
with fecha o arquivo sozinho. Modos: "r" ler, "w" escrever (apaga o que tinha), "a" acrescentar no fim.
Ler
with open("precos.txt", "r", encoding="utf-8") as arq:
for linha in arq:
codigo, preco = linha.strip().split(";")
print(codigo, float(preco))
CSV (abre no Excel)
import csv
with open("alunos.csv", "w", newline="", encoding="utf-8") as arq:
escritor = csv.writer(arq, delimiter=";")
escritor.writerow(["nome", "media"])
escritor.writerow(["Ana", 8.5])
with open("alunos.csv", encoding="utf-8") as arq:
for linha in csv.DictReader(arq, delimiter=";"):
print(linha["nome"], linha["media"])
Classes e objetos
Uma classe junta dados (atributos) e ações (métodos). É o próximo passo depois dos registros e o que vem no módulo seguinte do curso.
Criando uma classe
class ContaBancaria:
def __init__(self, titular, saldo=0): # construtor
self.titular = titular
self.saldo = saldo
def depositar(self, valor):
self.saldo += valor
def sacar(self, valor):
if valor > self.saldo:
return False
self.saldo -= valor
return True
def __str__(self): # como o objeto aparece no print
return f"{self.titular}: R$ {self.saldo:.2f}"
conta = ContaBancaria("Ana", 100)
conta.depositar(50)
print(conta.sacar(500), conta.sacar(30))
print(conta)
selfé o próprio objeto. Todo método recebe ele primeiro.__init__roda quando você cria o objeto.
Herança
class Funcionario:
def __init__(self, nome, salario):
self.nome = nome
self.salario = salario
def bonus(self):
return self.salario * 0.10
class Gerente(Funcionario): # Gerente herda de Funcionario
def bonus(self): # sobrescreve o método
return self.salario * 0.20 + 500
equipe = [Funcionario("Bia", 3000), Gerente("Caio", 6000)]
for f in equipe:
print(f.nome, f.bonus())
Todas as funções embutidas
As funções que o Python traz prontas, sem precisar importar nada. Use a busca ou filtre por assunto.
Métodos de texto, lista, dicionário e conjunto
Métodos são funções que pertencem a um tipo e são chamados com ponto: texto.upper(), lista.append(x).
Como montar cada tipo de programa
Moldes prontos para os tipos de exercício que mais caem. Copie a estrutura e troque as partes marcadas.
Exercícios com correção automática
Exercícios de lógica de programação (e alguns extras), na ordem dos capítulos. Nos de programa, escreva a solução e clique em Verificar: o caderno testa com vários casos. Nos de perguntas, o caderno confere cada resposta. Nos de resposta escrita (capítulo 1), compare com a resposta-modelo.
Método para resolver: 1) leia o enunciado e os exemplos; 2) resolva um caso no papel; 3) escreva os passos em português como comentário; 4) traduza para Python; 5) clique em Rodar para ver o que acontece e em Verificar quando achar que está certo. Travou? Use a dica antes de olhar a solução.
Playground
Escreva qualquer código Python e rode. Ctrl + Enter também executa. O que você escreve fica salvo neste navegador.