Questão por questão: o código, a saída real e por que a resposta certa é certa. Aulas 14–24.
Questão 1 · Tratamento de exceções
O que este programa imprime?
def processar(a, b):
try:
print(a / b)
except ZeroDivisionError:
print("divisão por zero")
else:
print("deu certo")
finally:
print("fim")
processar(10, 0)
# Saída no terminal:
# divisão por zero
# fim 10 / 0 levanta ZeroDivisionError, capturada pelo except → "divisão por zero". Como HOUVE exceção, o else (caminho feliz) é pulado. O finally roda SEMPRE → "fim".Questão 2 · Encapsulamento
O que acontece ao rodar este programa?
class Produto:
def __init__(self, nome, preco):
self.nome = nome
self.preco = preco
@property
def preco(self):
return self._preco
@preco.setter
def preco(self, valor):
if valor < 0:
raise ValueError("Preço não pode ser negativo")
self._preco = valor
p = Produto("Ração", 50.0)
p.preco = 45.0
print(p.preco) # 45.0
p.preco = -10 # ValueError: Preço não pode ser negativo __init__ quanto na atribuição direta. 50 e 45 passam; print mostra 45.0. Ao atribuir -10, o if valor < 0 levanta ValueError e o programa para. (Migrada do simulado Q1 — lá a correta era A.)Questão 3 · Herança + __str__
O que este programa imprime, nesta ordem?
class Veiculo:
def __init__(self, marca):
self.marca = marca
def descrever(self):
return f"Veículo {self.marca}"
def __str__(self):
return f"Veiculo({self.marca})"
class Carro(Veiculo):
def __init__(self, marca, portas):
super().__init__(marca)
self.portas = portas
def descrever(self):
return f"{super().descrever()} com {self.portas} portas"
c = Carro("Fiat", 4)
print(c.descrever()) # Veículo Fiat com 4 portas
print(c) # Veiculo(Fiat) Carro sobrescreve descrever() e usa super().descrever() pra reaproveitar a mãe e ACRESCENTAR as portas. Já __str__ NÃO foi sobrescrito em Carro → print(c) usa o herdado de Veiculo → Veiculo(Fiat).Questão 4 · Exceção customizada
O que este programa imprime?
class EstoqueInsuficienteError(Exception):
def __init__(self, pedido, disponivel):
self.faltam = pedido - disponivel
super().__init__(f"Faltam {self.faltam} unidades")
class Estoque:
def __init__(self, disponivel):
self.disponivel = disponivel
def retirar(self, pedido):
if pedido > self.disponivel:
raise EstoqueInsuficienteError(pedido, self.disponivel)
self.disponivel -= pedido
estoque = Estoque(5)
try:
estoque.retirar(8)
except EstoqueInsuficienteError as erro:
print("Erro:", erro) # Erro: Faltam 3 unidades
print("Faltam:", erro.faltam) # Faltam: 3 retirar() levanta a exceção quando o pedido passa do disponível. O super().__init__(mensagem) faz print(erro) mostrar "Faltam 3 unidades". O atributo self.faltam (8 − 5 = 3) é lido no except via erro.faltam.Questão 5 · ABC + polimorfismo
O que este programa imprime?
from abc import ABC, abstractmethod
class Animal(ABC):
def __init__(self, nome):
self.nome = nome
@abstractmethod
def falar(self):
pass
class Cachorro(Animal):
def falar(self):
return "Au au"
class Gato(Animal):
def falar(self):
return "Miau"
animais = [Cachorro("Rex"), Gato("Mimi")]
for a in animais:
print(f"{a.nome}: {a.falar()}")
# Saída no terminal:
# Rex: Au au
# Mimi: Miau for chama a.falar() em classes DIFERENTES e cada uma responde do seu jeito. Animal é ABC (não instanciável direto), mas Cachorro/Gato implementam falar(), então instanciam normal. (Migrada do simulado Q3 — lá era A.)Questão 6 · Coleções (sorted + key)
O que é impresso?
produtos = [("cafe", 18), ("leite", 5), ("pao", 8)]
ordenados = sorted(produtos, key=lambda p: p[1])
print(ordenados)
# [('leite', 5), ('pao', 8), ('cafe', 18)] sorted(key=lambda p: p[1]) ordena pelo 2º elemento (o preço), crescente → leite(5), pao(8), cafe(18). sorted() devolve uma lista NOVA (não None — isso seria .sort()). O key=lambda é a mesma ideia do Strategy (aula 21).Questão 7 · Persistência (from_row/to_params)
Rodando num banco loja.db recém-criado, o que este programa imprime?
import sqlite3
class Produto:
def __init__(self, nome, preco, id=None):
self.id = id
self.nome = nome
self.preco = preco
@classmethod
def from_row(cls, linha):
id, nome, preco = linha
return cls(nome, preco, id)
def to_params(self):
return (self.nome, self.preco)
def __str__(self):
return f"#{self.id} {self.nome} — R$ {self.preco:.2f}"
con = sqlite3.connect("loja.db")
con.execute("CREATE TABLE produtos (id INTEGER PRIMARY KEY AUTOINCREMENT, nome TEXT, preco REAL)")
cafe = Produto("Café", 18.0)
con.execute("INSERT INTO produtos (nome, preco) VALUES (?, ?)", cafe.to_params())
linha = con.execute("SELECT id, nome, preco FROM produtos").fetchone()
p = Produto.from_row(linha)
print(p) # #1 Café — R$ 18.00 to_params() devolve (nome, preco) SEM o id (o banco gera via AUTOINCREMENT). O SELECT devolve (1, 'Café', 18.0); from_row remonta o objeto JÁ com id=1 → #1. O :.2f dá 18.00. (Migrada do simulado Q20 — lá era E.)Questão 8 · Strategy
O que este programa imprime?
class Carrinho:
def __init__(self, desconto):
self.desconto = desconto
self.itens = []
def adicionar(self, preco):
self.itens.append(preco)
def total(self):
subtotal = sum(self.itens)
return self.desconto(subtotal)
def sem_desconto(v):
return v
def black_friday(v):
return v * 0.5
c = Carrinho(black_friday)
c.adicionar(100)
c.adicionar(60)
print(c.total()) # 80.0 Carrinho (Contexto) guarda UMA estratégia (a função black_friday) e delega o cálculo a ela. total() soma os itens (160) e aplica → 160 * 0.5 = 80.0. Trocar a estratégia muda o resultado sem mexer no Carrinho.Questão 9 · Tkinter — App(tk.Tk) + Listbox
O que este programa imprime?
import tkinter as tk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.clientes = ["Ana", "Beto", "Carla"]
self.lista = tk.Listbox(self)
self.lista.pack()
self.atualizar()
def atualizar(self):
self.lista.delete(0, tk.END)
for c in self.clientes:
self.lista.insert(tk.END, c)
def remover(self, nome):
self.clientes.remove(nome)
self.atualizar()
app = App()
app.remover("Beto")
print(app.lista.get(1)) # Carla atualizar() LIMPA o Listbox (delete(0, tk.END)) e re-insere de self.clientes → o Listbox espelha a lista. Antes, a posição 1 era "Beto"; depois de remover("Beto"), a lista vira ['Ana', 'Carla'] e get(1) devolve "Carla". (Migrada do simulado Q17 — lá era D.)Questão 10 · SQLite (NOT NULL)
Rodando num banco loja.db recém-criado, o que este programa imprime?
import sqlite3
con = sqlite3.connect("loja.db")
con.execute("CREATE TABLE itens (id INTEGER PRIMARY KEY, nome TEXT NOT NULL)")
try:
con.execute("INSERT INTO itens (nome) VALUES (?)", (None,))
print("inserido")
except sqlite3.IntegrityError:
print("recusado pelo NOT NULL") # recusado pelo NOT NULL nome é NOT NULL, então inserir None fere a regra e o banco levanta sqlite3.IntegrityError — capturada pelo except → "recusado pelo NOT NULL". É esse o mecanismo que uma exceção de domínio traduz num Repositório.Questão 1 · Cardápio (POO)
Implementar ItemCardapio (ABC, property com ValueError) + subclasses Pizza e Bebida; polimorfismo no loop.
from abc import ABC, abstractmethod
class ItemCardapio(ABC):
def __init__(self, nome, preco):
self.nome = nome
self.preco = preco # passa pelo setter
@property
def preco(self):
return self._preco
@preco.setter
def preco(self, valor):
if valor <= 0:
raise ValueError("preço deve ser positivo")
self._preco = valor
@abstractmethod
def descricao(self):
pass
class Pizza(ItemCardapio):
def __init__(self, nome, preco, tamanho):
super().__init__(nome, preco)
self.tamanho = tamanho
def descricao(self):
return f"Pizza {self.nome} ({self.tamanho}) — R$ {self.preco:.2f}"
class Bebida(ItemCardapio):
def descricao(self):
return f"Bebida {self.nome} — R$ {self.preco:.2f}"
# Teste + saída:
itens = [Pizza("Calabresa", 45.0, "grande"), Bebida("Guaraná", 8.0)]
for item in itens:
print(item.descricao())
try:
Pizza("Promo", 0, "broto")
except ValueError as erro:
print("Recusada:", erro)
# Pizza Calabresa (grande) — R$ 45.00
# Bebida Guaraná — R$ 8.00
# Recusada: preço deve ser positivo @abstractmethod; herança com super().__init__ (e Bebida reaproveitando o construtor); polimorfismo no loop; property/setter com ValueError. O texto da mensagem pode variar — conta o comportamento.Questão 2 · App Tkinter + SQLite
Implementar Pizza (from_row/to_params/__str__) + RepositorioPizza (CRUD SQLite) + App(tk.Tk) que cadastra e lista.
import tkinter as tk
import sqlite3
from pathlib import Path
BANCO = Path(__file__).parent / "pizzaria.db"
class Pizza:
def __init__(self, nome, preco, id=None):
self.id = id
self.nome = nome
self.preco = preco
@classmethod
def from_row(cls, linha):
id, nome, preco = linha
return cls(nome, preco, id)
def to_params(self):
return (self.nome, self.preco)
def __str__(self):
return f"{self.nome} — R$ {self.preco:.2f}"
class RepositorioPizza:
def __init__(self, caminho=BANCO):
self.caminho = caminho
with sqlite3.connect(self.caminho) as con:
con.execute(
"CREATE TABLE IF NOT EXISTS pizzas ("
"id INTEGER PRIMARY KEY AUTOINCREMENT, "
"nome TEXT NOT NULL, "
"preco REAL NOT NULL)"
)
def salvar(self, pizza):
with sqlite3.connect(self.caminho) as con:
cursor = con.execute(
"INSERT INTO pizzas (nome, preco) VALUES (?, ?)",
pizza.to_params(),
)
pizza.id = cursor.lastrowid
def listar(self):
with sqlite3.connect(self.caminho) as con:
cursor = con.execute("SELECT id, nome, preco FROM pizzas ORDER BY id")
return [Pizza.from_row(l) for l in cursor.fetchall()]
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Pizzaria")
self.repo = RepositorioPizza()
self.entrada_nome = tk.Entry(self)
self.entrada_nome.pack()
self.entrada_preco = tk.Entry(self)
self.entrada_preco.pack()
tk.Button(self, text="Adicionar", command=self.adicionar).pack()
self.lista = tk.Listbox(self, width=40)
self.lista.pack()
self.atualizar()
def adicionar(self):
nome = self.entrada_nome.get()
preco = float(self.entrada_preco.get())
self.repo.salvar(Pizza(nome, preco))
self.atualizar()
print(f"Salva: {nome}")
def atualizar(self):
self.lista.delete(0, tk.END)
for p in self.repo.listar():
self.lista.insert(tk.END, str(p))
# No app real: App().mainloop(). Teste (simula o clique):
app = App()
app.entrada_nome.insert(0, "Calabresa")
app.entrada_preco.insert(0, "45")
app.adicionar()
print("No cardápio:", app.lista.get(0))
# Salva: Calabresa
# No cardápio: Calabresa — R$ 45.00 App(tk.Tk) com super().__init__(); Entry.get() no callback; command= como valor; refresh do Listbox (delete(0, tk.END) + reinsere); from_row/to_params e o CRUD com ?; o id vindo do banco via lastrowid.Resumo
As dez respostas em um lugar. A parte prática é avaliada pela execução correta, não por letra.
exceções
encapsulamento
herança
exceção custom
ABC/polim.
sorted+key
from_row
Strategy
App/Listbox
NOT NULL