SENAI Goiás — Análise e Desenvolvimento de Sistemas

Programação Orientada a Objetos (Python)

2ª Verificação de Aprendizagem (VA) — Parte Prática

Como entregar: resolva as duas questões e envie dois arquivos: questao1.py e questao2.py. Cada arquivo deve conter a solução da questão e, no fim, o trecho de teste fornecido. Dica: rode seu código e compare com a saída esperada antes de entregar. A Questão 2 cria o arquivo pizzaria.db — rode com um banco novo (apague o pizzaria.db antes) para bater a saída.

Questão 1 — Cardápio (classes, herança, polimorfismo)

Conceitos: classe abstrata (ABC), herança, polimorfismo, encapsulamento (property/setter) e validação com exceção.

Implemente, no arquivo questao1.py, o cardápio de uma pizzaria usando POO, atendendo aos requisitos:

  • Uma classe abstrata ItemCardapio (módulo abc): o construtor recebe nome e preco; um método abstrato descricao().
  • Controle o preco com @property / @setter: se o valor for menor ou igual a zero, o setter deve levantar ValueError com a mensagem preço deve ser positivo.
  • Duas subclasses concretas, cada uma implementando descricao() (veja o formato na saída esperada): Pizza — recebe também um tamanho; e Bebida — sem atributos extras (reaproveita o construtor da classe-mãe).
  • O descricao() é o ponto do polimorfismo: o mesmo for chama o método em itens de tipos diferentes e cada um responde do seu jeito.

Trecho de teste (coloque no fim do arquivo):

itens = [
    Pizza("Calabresa", 45.0, "grande"),
    Bebida("Guaraná", 8.0),
]

for item in itens:                    # polimorfismo: cada item descreve do seu jeito
    print(item.descricao())

try:                                  # preço inválido barrado pela property
    Pizza("Promo", 0, "broto")
except ValueError as erro:
    print("Recusada:", erro)

Saída esperada:

Pizza Calabresa (grande) — R$ 45.00
Bebida Guaraná — R$ 8.00
Recusada: preço deve ser positivo

Questão 2 — App Tkinter que salva no SQLite

Conceitos: Tkinter (App(tk.Tk), Entry, Button, Listbox) + persistência em SQLite (ORM manual from_row / to_params, CRUD com ?).

Implemente, no arquivo questao2.py, um app de cadastro de pizzas que salva num banco SQLite, atendendo aos requisitos:

  • Classe Pizza — construtor recebe nome, preco e id=None; from_row(linha) (@classmethod, transforma a tupla do SELECT em objeto); to_params() (devolve a tupla (nome, preco), SEM o id); e __str__ no formato Calabresa — R$ 45.00.
  • Classe RepositorioPizza — no construtor, cria a tabela com CREATE TABLE IF NOT EXISTS pizzas (colunas: id INTEGER PRIMARY KEY AUTOINCREMENT, nome TEXT NOT NULL, preco REAL NOT NULL). Métodos: salvar(pizza) (INSERT com placeholder ? e to_params(), guardando o id com lastrowid) e listar() (SELECT com ORDER BY id, devolvendo objetos Pizza via from_row).
  • Classe App(tk.Tk) — dois Entry (nome e preço), um Button "Adicionar" ligado por command, e um Listbox. Ao clicar, o callback lê os campos com .get(), salva a pizza no repositório, atualiza o Listbox (limpa com delete(0, tk.END) e reinsere a partir do listar()) e imprime a confirmação (veja a saída).

Trecho de teste (coloque no fim do arquivo):

app = App()
app.entrada_nome.insert(0, "Calabresa")
app.entrada_preco.insert(0, "45")
app.adicionar()          # o usuário clica em "Adicionar"
print("No cardápio:", app.lista.get(0))

Saída esperada (com um pizzaria.db novo):

Salva: Calabresa
No cardápio: Calabresa — R$ 45.00