Programador Leigo
Python 15 min leitura 15 MAR 2026

Projeto Python: gerenciador de finanças pessoais no terminal

Construa um gerenciador de finanças pessoais completo no terminal. Projeto final que combina tudo o que você aprendeu na trilha.


O que vamos construir

Um programa de terminal onde você pode registrar receitas e despesas, organizar por categoria, ver o saldo atual e gerar um resumo mensal. É o tipo de ferramenta que qualquer pessoa pode usar no dia a dia.

Ao longo deste projeto, vamos usar tudo que aprendemos na trilha:

Conceito Onde aparece
Variáveis e tipos Valores, datas, categorias
Condicionais Menu de opções, validações
Strings Formatação de valores, datas
Loops Menu principal, listagem
Listas e dicionários Armazenamento das transações
Funções Organização de cada funcionalidade

Estrutura do projeto

Vamos construir em etapas. Cada etapa adiciona uma funcionalidade nova.

financas.py       ← arquivo unico com todo o codigo

Etapa 1: estrutura básica e menu

from datetime import datetime

transacoes = []

def exibir_menu():
    print("\n" + "=" * 40)
    print("  GERENCIADOR DE FINANCAS PESSOAIS")
    print("=" * 40)
    print("1. Adicionar receita")
    print("2. Adicionar despesa")
    print("3. Ver extrato")
    print("4. Ver resumo por categoria")
    print("5. Ver saldo")
    print("0. Sair")
    print("-" * 40)

def main():
    while True:
        exibir_menu()
        opcao = input("Escolha uma opcao: ").strip()

        if opcao == "1":
            adicionar_transacao("receita")
        elif opcao == "2":
            adicionar_transacao("despesa")
        elif opcao == "3":
            ver_extrato()
        elif opcao == "4":
            resumo_por_categoria()
        elif opcao == "5":
            ver_saldo()
        elif opcao == "0":
            print("\nAte logo! Cuide bem do seu dinheiro.")
            break
        else:
            print("Opcao invalida. Tente novamente.")

main()

O while True mantém o programa rodando até o usuário digitar 0. Cada opção chama uma função específica.


Etapa 2: adicionando transações

CATEGORIAS_RECEITA = ["salario", "freelance", "investimento", "outros"]
CATEGORIAS_DESPESA = ["alimentacao", "moradia", "transporte", "lazer", "saude", "educacao", "outros"]

def escolher_categoria(tipo):
    categorias = CATEGORIAS_RECEITA if tipo == "receita" else CATEGORIAS_DESPESA

    print(f"\nCategorias de {tipo}:")
    for i, cat in enumerate(categorias, 1):
        print(f"  {i}. {cat.capitalize()}")

    while True:
        escolha = input("Escolha o numero da categoria: ").strip()
        if escolha.isdigit() and 1 <= int(escolha) <= len(categorias):
            return categorias[int(escolha) - 1]
        print("Opcao invalida.")

def ler_valor():
    while True:
        entrada = input("Valor (R$): ").strip().replace(",", ".")
        try:
            valor = float(entrada)
            if valor > 0:
                return valor
            print("O valor deve ser positivo.")
        except ValueError:
            print("Valor invalido. Use apenas numeros.")

def adicionar_transacao(tipo):
    print(f"\n--- Nova {tipo.upper()} ---")

    descricao = input("Descricao: ").strip()
    if not descricao:
        print("Descricao nao pode ser vazia.")
        return

    valor = ler_valor()
    categoria = escolher_categoria(tipo)

    transacao = {
        "tipo": tipo,
        "descricao": descricao,
        "valor": valor,
        "categoria": categoria,
        "data": datetime.now().strftime("%d/%m/%Y"),
    }

    transacoes.append(transacao)
    print(f"\n{tipo.capitalize()} de R$ {valor:.2f} adicionada com sucesso!")

Repare como usamos: - Listas para as categorias - Dicionário para cada transação - Funções para separar responsabilidades - Validação com loop para garantir dados corretos - Strings para formatar valores e datas


Etapa 3: extrato e saldo

def ver_extrato():
    if not transacoes:
        print("\nNenhuma transacao registrada.")
        return

    print("\n" + "=" * 55)
    print(f"  {'DATA':<12} {'TIPO':<10} {'CATEGORIA':<15} {'VALOR':>10}")
    print("-" * 55)

    for t in transacoes:
        sinal = "+" if t["tipo"] == "receita" else "-"
        print(
            f"  {t['data']:<12} "
            f"{t['tipo']:<10} "
            f"{t['categoria']:<15} "
            f"{sinal} R$ {t['valor']:>8.2f}"
        )

    print("=" * 55)
    print(f"  {t['descricao']}")

def calcular_saldo():
    receitas = sum(t["valor"] for t in transacoes if t["tipo"] == "receita")
    despesas = sum(t["valor"] for t in transacoes if t["tipo"] == "despesa")
    return receitas, despesas

def ver_saldo():
    receitas, despesas = calcular_saldo()
    saldo = receitas - despesas

    print("\n" + "=" * 35)
    print(f"  Receitas:  R$ {receitas:>10.2f}")
    print(f"  Despesas:  R$ {despesas:>10.2f}")
    print("-" * 35)

    if saldo >= 0:
        print(f"  Saldo:     R$ {saldo:>10.2f}")
    else:
        print(f"  Saldo:    -R$ {abs(saldo):>10.2f}")

    print("=" * 35)

Aqui usamos f-strings com alinhamento (:<12, :>10, :.2f) para criar uma tabela formatada no terminal.


Etapa 4: resumo por categoria

def resumo_por_categoria():
    if not transacoes:
        print("\nNenhuma transacao registrada.")
        return

    print("\n--- RESUMO POR CATEGORIA ---\n")

    for tipo in ["receita", "despesa"]:
        transacoes_tipo = [t for t in transacoes if t["tipo"] == tipo]
        if not transacoes_tipo:
            continue

        print(f"  {tipo.upper()}S:")

        totais = {}
        for t in transacoes_tipo:
            cat = t["categoria"]
            totais[cat] = totais.get(cat, 0) + t["valor"]

        total_tipo = sum(totais.values())

        for cat, valor in sorted(totais.items(), key=lambda x: x[1], reverse=True):
            percentual = (valor / total_tipo) * 100
            barra = "#" * int(percentual / 5)
            print(f"    {cat:<15} R$ {valor:>8.2f}  ({percentual:>5.1f}%) {barra}")

        print(f"    {'TOTAL':<15} R$ {total_tipo:>8.2f}")
        print()

Esse resumo mostra onde seu dinheiro está indo, com porcentagem e uma barra visual feita com #. Usamos dict.get() para acumular valores e sorted() com lambda para ordenar do maior para o menor.


Código completo

from datetime import datetime

transacoes = []

CATEGORIAS_RECEITA = ["salario", "freelance", "investimento", "outros"]
CATEGORIAS_DESPESA = [
    "alimentacao", "moradia", "transporte",
    "lazer", "saude", "educacao", "outros",
]


def exibir_menu():
    print("\n" + "=" * 40)
    print("  GERENCIADOR DE FINANCAS PESSOAIS")
    print("=" * 40)
    print("1. Adicionar receita")
    print("2. Adicionar despesa")
    print("3. Ver extrato")
    print("4. Ver resumo por categoria")
    print("5. Ver saldo")
    print("0. Sair")
    print("-" * 40)


def escolher_categoria(tipo):
    categorias = CATEGORIAS_RECEITA if tipo == "receita" else CATEGORIAS_DESPESA

    print(f"\nCategorias de {tipo}:")
    for i, cat in enumerate(categorias, 1):
        print(f"  {i}. {cat.capitalize()}")

    while True:
        escolha = input("Escolha o numero da categoria: ").strip()
        if escolha.isdigit() and 1 <= int(escolha) <= len(categorias):
            return categorias[int(escolha) - 1]
        print("Opcao invalida.")


def ler_valor():
    while True:
        entrada = input("Valor (R$): ").strip().replace(",", ".")
        try:
            valor = float(entrada)
            if valor > 0:
                return valor
            print("O valor deve ser positivo.")
        except ValueError:
            print("Valor invalido. Use apenas numeros.")


def adicionar_transacao(tipo):
    print(f"\n--- Nova {tipo.upper()} ---")

    descricao = input("Descricao: ").strip()
    if not descricao:
        print("Descricao nao pode ser vazia.")
        return

    valor = ler_valor()
    categoria = escolher_categoria(tipo)

    transacao = {
        "tipo": tipo,
        "descricao": descricao,
        "valor": valor,
        "categoria": categoria,
        "data": datetime.now().strftime("%d/%m/%Y"),
    }

    transacoes.append(transacao)
    print(f"\n{tipo.capitalize()} de R$ {valor:.2f} adicionada com sucesso!")


def ver_extrato():
    if not transacoes:
        print("\nNenhuma transacao registrada.")
        return

    print("\n" + "=" * 60)
    print(f"  {'DATA':<12} {'DESCRICAO':<18} {'CATEGORIA':<15} {'VALOR':>10}")
    print("-" * 60)

    for t in transacoes:
        sinal = "+" if t["tipo"] == "receita" else "-"
        desc = t["descricao"][:16]
        print(
            f"  {t['data']:<12} "
            f"{desc:<18} "
            f"{t['categoria']:<15} "
            f"{sinal} R$ {t['valor']:>7.2f}"
        )

    print("=" * 60)


def calcular_saldo():
    receitas = sum(t["valor"] for t in transacoes if t["tipo"] == "receita")
    despesas = sum(t["valor"] for t in transacoes if t["tipo"] == "despesa")
    return receitas, despesas


def ver_saldo():
    receitas, despesas = calcular_saldo()
    saldo = receitas - despesas

    print("\n" + "=" * 35)
    print(f"  Receitas:  R$ {receitas:>10.2f}")
    print(f"  Despesas:  R$ {despesas:>10.2f}")
    print("-" * 35)

    if saldo >= 0:
        print(f"  Saldo:     R$ {saldo:>10.2f}")
    else:
        print(f"  Saldo:    -R$ {abs(saldo):>10.2f}")

    print("=" * 35)


def resumo_por_categoria():
    if not transacoes:
        print("\nNenhuma transacao registrada.")
        return

    print("\n--- RESUMO POR CATEGORIA ---\n")

    for tipo in ["receita", "despesa"]:
        transacoes_tipo = [t for t in transacoes if t["tipo"] == tipo]
        if not transacoes_tipo:
            continue

        print(f"  {tipo.upper()}S:")

        totais = {}
        for t in transacoes_tipo:
            cat = t["categoria"]
            totais[cat] = totais.get(cat, 0) + t["valor"]

        total_tipo = sum(totais.values())

        for cat, valor in sorted(totais.items(), key=lambda x: x[1], reverse=True):
            percentual = (valor / total_tipo) * 100
            barra = "#" * int(percentual / 5)
            print(f"    {cat:<15} R$ {valor:>8.2f}  ({percentual:>5.1f}%) {barra}")

        print(f"    {'TOTAL':<15} R$ {total_tipo:>8.2f}")
        print()


def main():
    print("\nBem-vindo ao Gerenciador de Financas Pessoais!")

    while True:
        exibir_menu()
        opcao = input("Escolha uma opcao: ").strip()

        if opcao == "1":
            adicionar_transacao("receita")
        elif opcao == "2":
            adicionar_transacao("despesa")
        elif opcao == "3":
            ver_extrato()
        elif opcao == "4":
            resumo_por_categoria()
        elif opcao == "5":
            ver_saldo()
        elif opcao == "0":
            print("\nAte logo! Cuide bem do seu dinheiro.")
            break
        else:
            print("Opcao invalida. Tente novamente.")


main()

Testando o programa

Execute no terminal:

python financas.py

Experimente adicionar algumas transações:

Escolha uma opcao: 1
--- Nova RECEITA ---
Descricao: Salario março
Valor (R$): 3500
Categoria: 1 (salario)

Escolha uma opcao: 2
--- Nova DESPESA ---
Descricao: Aluguel
Valor (R$): 1200
Categoria: 2 (moradia)

Escolha uma opcao: 2
Descricao: Supermercado
Valor (R$): 450,00
Categoria: 1 (alimentacao)

Escolha uma opcao: 5
===================================
  Receitas:  R$    3500.00
  Despesas:  R$    1650.00
-----------------------------------
  Saldo:     R$    1850.00
===================================

O que aprendemos

Conceito Como usamos
Variáveis Armazenar valores, descrições, categorias
Condicionais Menu de opções, validações de entrada
Strings f-strings com alinhamento, formatação de moeda
Loops Menu principal, listagem, validação com retry
Listas Lista de transações e categorias
Dicionários Cada transação, totais por categoria
Funções Uma função para cada funcionalidade

Próximos passos

Ideias para evoluir o projeto:

  • Salvar em arquivo JSON para não perder os dados ao fechar
  • Filtrar por mês para ver gastos de um período específico
  • Editar e excluir transações
  • Exportar para CSV para abrir no Excel
  • Adicionar cores no terminal com a biblioteca colorama

Esse projeto é seu. Melhore, personalize e use de verdade. Você acabou de construir um programa útil com Python puro — sem nenhuma biblioteca externa. Isso é programar.

Continue lendo

Compartilhar