Módulo 16 - Projeto final: seu gerenciador de tarefas

Estruturando o programa: o esqueleto que já funciona

11 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026

O que você vai aprender

  • Entender por que programas grandes começam pelo esqueleto, não pela primeira funcionalidade.
  • Criar as sete funções do gerenciador, ainda vazias, com nomes que se explicam.
  • Montar o loop principal com while True e o if/elif que despacha cada opção.
  • Rodar o esqueleto e confirmar que todas as opções respondem.

Por que começar pelo esqueleto

Existe um jeito amador e um jeito profissional de começar um programa de 100 linhas. O amador escreve a primeira funcionalidade completa, depois a segunda, e vai emendando; quando algo quebra, não sabe se o problema é da parte nova ou da cola entre as partes. O profissional desenha primeiro a estrutura: quais funções vão existir, o que cada uma faz e como o fluxo passa por elas. Só depois preenche uma por vez. Essa estrutura vazia mas funcional tem nome: esqueleto.

Sem esqueleto

  • Escreve tudo misturado e organiza depois, se der
  • Um erro pode estar em qualquer lugar do arquivo
  • Só descobre se o fluxo do menu funciona no final
  • Cada funcionalidade nova mexe no código das antigas

Com esqueleto

  • Decide os nomes e o fluxo antes de qualquer lógica
  • Um erro só pode estar na única função recém-preenchida
  • O menu, o loop e a saída funcionam desde o primeiro dia
  • Cada aula preenche uma função sem tocar nas outras

O ganho prático aparece já na próxima aula: quando você implementar adicionar_tarefa e algo der errado, vai saber com certeza que o problema está dentro daquela função, porque todo o resto já rodava antes. Esse isolamento de suspeitos é o que faz programadores experientes parecerem rápidos ao caçar erros. Não é mágica, é estrutura.

pass
Palavra do Python que significa não faça nada. Serve de corpo temporário para uma função que precisa existir mas ainda não tem lógica, porque uma função com corpo vazio de verdade seria erro de sintaxe.

As sete funções e o loop principal

Crie o arquivo gerenciador.py na sua pasta de projetos (ou uma sessão limpa no Playground) e digite o esqueleto completo abaixo. São as sete funções do programa e o loop principal. Repare que os nomes contam a história sozinhos: quem lê mostrar_menu, adicionar_tarefa ou salvar_tarefas sabe o que esperar sem abrir a função. Nomear bem é metade da organização.

# gerenciador.py - versão 1: o esqueleto

def mostrar_menu():
    print("\n=== MINHAS TAREFAS ===")
    print("1. Adicionar tarefa")
    print("2. Listar tarefas")
    print("3. Concluir tarefa")
    print("4. Remover tarefa")
    print("5. Sair")

def adicionar_tarefa(tarefas):
    print("(adicionar tarefa: em construção)")

def listar_tarefas(tarefas):
    print("(listar tarefas: em construção)")

def concluir_tarefa(tarefas):
    print("(concluir tarefa: em construção)")

def remover_tarefa(tarefas):
    print("(remover tarefa: em construção)")

def salvar_tarefas(tarefas):
    pass

def carregar_tarefas():
    return []

tarefas = []

while True:
    mostrar_menu()
    opcao = input("Escolha uma opção: ")
    if opcao == "1":
        adicionar_tarefa(tarefas)
    elif opcao == "2":
        listar_tarefas(tarefas)
    elif opcao == "3":
        concluir_tarefa(tarefas)
    elif opcao == "4":
        remover_tarefa(tarefas)
    elif opcao == "5":
        print("Até logo!")
        break
    else:
        print("Opção inválida. Digite um número de 1 a 5.")

O esqueleto completo: 7 funções, a lista tarefas e o loop principal. Ele já roda de ponta a ponta.

Três decisões desse código merecem explicação. Primeira: quase todas as funções recebem tarefas como parâmetro, em vez de mexer numa variável solta. É a lição do módulo 13: função que recebe o que precisa é mais fácil de entender e de testar. Segunda: a comparação usa opcao == "1" com aspas, porque input sempre devolve texto, como o módulo 5 martelou. Terceira: mostrar_menu não recebe nada, porque só imprime; e carregar_tarefas devolve uma lista vazia por enquanto, para a aula 5 ter onde encaixar a leitura do arquivo sem mudar o formato.

Repare também no salvar_tarefas com pass no corpo. O Python não aceita função sem corpo, e pass é o jeito oficial de dizer por enquanto, nada. As outras funções vazias usam um print de em construção em vez de pass por um motivo prático: quando você rodar o esqueleto e escolher uma opção, quer ver uma resposta na tela confirmando que o despacho do menu chamou a função certa.

Rodando o esqueleto

Hora do teste. Rode o programa e passeie pelo menu: escolha 1, 2, 3 e 4 e confira se cada opção responde com a sua mensagem de em construção. Digite algo inválido, como 9 ou banana, e confira a mensagem de opção inválida. Por fim, escolha 5 e veja o programa se despedir e encerrar. A sessão deve se parecer com isto:

=== MINHAS TAREFAS ===
1. Adicionar tarefa
2. Listar tarefas
3. Concluir tarefa
4. Remover tarefa
5. Sair
Escolha uma opção: 1
(adicionar tarefa: em construção)

=== MINHAS TAREFAS ===
1. Adicionar tarefa
2. Listar tarefas
3. Concluir tarefa
4. Remover tarefa
5. Sair
Escolha uma opção: banana
Opção inválida. Digite um número de 1 a 5.

=== MINHAS TAREFAS ===
1. Adicionar tarefa
2. Listar tarefas
3. Concluir tarefa
4. Remover tarefa
5. Sair
Escolha uma opção: 5
Até logo!

O esqueleto em ação: menu, despacho, opção inválida tratada e saída limpa. Tudo antes de qualquer lógica de tarefa.

Se a sua sessão bateu com essa, parabéns: o fluxo inteiro do programa está pronto e testado. Daqui em diante, cada aula só troca o miolo de duas funções, e o resto permanece intocado. Se não bateu, os suspeitos de sempre estão na lista abaixo.

Teste rápido

No esqueleto, por que o menu reaparece depois de cada ação escolhida?

Perguntas frequentes

Por que escrever sete funções vazias em vez de ir direto ao que interessa?
Porque o esqueleto testa de graça a parte mais traiçoeira do programa: o fluxo. Menu, leitura da opção, despacho e saída já ficam prontos e verificados. Nas próximas aulas, qualquer erro novo só pode estar na função que você acabou de preencher, o que corta o tempo de caça pela metade.
Qual a diferença entre usar pass e usar um print de em construção?
Os dois servem de corpo temporário. O print dá feedback visível quando a função é chamada, útil para testar o menu. O pass fica mudo, e foi usado em salvar_tarefas de propósito: ela será chamada automaticamente no futuro e não deve poluir a tela enquanto não faz nada.
Por que as funções recebem a lista tarefas como parâmetro?
Para deixar explícito o que cada função usa. Função que recebe os dados pelo parâmetro é autoexplicativa, testável isolada e não depende de variáveis soltas no arquivo. É a prática do módulo 13 aplicada num programa de verdade, e o hábito que separa código organizado de código emaranhado.
Por que comparar a opção com "1" entre aspas e não com o número 1?
Porque input sempre devolve uma string, mesmo quando a pessoa digita um número. A string "1" e o inteiro 1 são valores de tipos diferentes, e a comparação entre eles dá False. Como só queremos saber qual tecla foi escolhida, comparar texto com texto resolve sem conversão.
O while True não é perigoso? O programa não pode travar para sempre?
Ele é seguro quando existe uma saída garantida, e aqui existe: a opção 5 executa break, que encerra o loop na hora. É o padrão clássico de menu interativo visto no módulo 8. Loop infinito de verdade é o que não tem break nem condição de parada alcançável.
Posso mudar os nomes das funções para outros que eu prefira?
Neste módulo, não mude. As aulas 3 a 6 substituem funções pelo nome exato, e qualquer renomeio seu vira caça ao erro desnecessária. Depois do curso, renomeie à vontade; aí a regra é uma só: o nome deve contar o que a função faz sem precisar abri-la.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.