Python

construye un gestor de gastos personales en la terminal

Construye paso a paso un gestor de gastos personales en Python desde la terminal. Aprende a registrar ingresos y gastos, calcular balances, organizar movimientos por categorías, validar datos y guardar la información …

Contenido de la guía
🐍 Python desde cero · Proyecto 1

Tu primera aplicación completa

Construye un gestor de gastos personales en la terminal y descubre cómo varias piezas de Python pueden trabajar juntas para resolver un problema real.

Hasta ahora aprendiste las piezas. Ha llegado el momento de construir algo con ellas.

A lo largo de las guías anteriores has trabajado con variables, decisiones, bucles, listas, diccionarios y funciones. Cada concepto resolvía una parte concreta de un problema. En este proyecto comenzaremos a conectarlos para construir un programa completo.

El objetivo será desarrollar, paso a paso, un gestor de gastos personales en Python capaz de registrar ingresos y gastos, conservar movimientos, calcular un balance y mostrar en qué categorías se está utilizando el dinero.

No empezaremos con una aplicación enorme ni con decenas de funciones. Primero entenderemos el problema, después diseñaremos los datos y, a partir de ahí, añadiremos cada capacidad hasta llegar a una aplicación interactiva que funcione desde la terminal.

Utilizarás conocimientos que ya has aprendido para construir algo mayor. Las variables almacenarán información, los condicionales permitirán tomar decisiones, los bucles repetirán operaciones, las listas y los diccionarios organizarán los movimientos y las funciones dividirán el programa en tareas pequeñas.

Más adelante también aprenderás a guardar los movimientos en un archivo JSON para que la información permanezca disponible cuando cierres el programa. Así, el resultado final será algo más que un ejercicio: será una pequeña aplicación capaz de recibir datos, tomar decisiones, calcular resultados y conservar su estado.

Aprender las piezas de Python es el comienzo. Construir software empieza cuando consigues que esas piezas trabajen juntas.

  • 💶 Gastos
  • 📥 Ingresos
  • 📊 Balance
  • 🗂️ Categorías
  • 💾 JSON
  • ⌨️ Terminal
Ilustración de un gestor de gastos personales en Python que recibe ingresos y gastos desde la terminal y genera un resumen con balance financiero.
Figura 1 — El gestor procesa ingresos y gastos para convertir movimientos individuales en un resumen financiero claro y organizado.

Del problema cotidiano al programa

Antes de comenzar a escribir funciones o construir un menú, necesitamos entender qué problema resolverá nuestro programa.

Imagina que durante varios días recibes dinero y también realizas pequeños gastos. Puedes intentar recordarlo todo, anotarlo en diferentes lugares o hacer las cuentas cada vez que quieras saber cuánto dinero te queda.

Nuestro gestor de gastos personales convertirá ese problema cotidiano en información que Python pueda organizar y procesar.

📥 ¿Cuánto dinero ingresó?

Necesitamos identificar y sumar todos los movimientos que representan ingresos.

💶 ¿Cuánto gastó?

Tendremos que reconocer los gastos y acumular sus cantidades.

🗂️ ¿En qué lo gastó?

Cada gasto tendrá una categoría que permitirá organizar mejor la información.

📊 ¿Cuánto le queda?

El balance aparecerá al comparar el dinero ingresado con el dinero gastado.

Primero el problema, después el código

Antes de programar debemos transformar preguntas cotidianas en operaciones concretas que el programa pueda realizar.

Ya sabemos qué preguntas queremos responder. El siguiente paso consiste en convertir cada necesidad en una capacidad concreta del programa.

Esta traducción es importante porque nos permite saber qué debemos construir antes de preocuparnos por los detalles del código.

Necesidad Lo que hará el programa
Anotar un gasto Registrar un movimiento
Saber cuánto gasté Sumar los gastos
Saber cuánto dinero tengo Calcular el balance
Saber en qué gasto Agrupar gastos por categoría
No perder los datos Guardarlos en un archivo

Antes de escribir código, decide qué debe saber hacer tu programa.

Cómo representar un movimiento

Cada ingreso o gasto necesita guardar varios datos relacionados. Un diccionario es una estructura adecuada porque permite relacionar cada dato con un nombre.

Un gasto de transporte podría representarse conceptualmente de esta forma:

movimiento
{     "tipo": "gasto",     "concepto": "Transporte",     "cantidad": 12.50,     "categoria": "transporte" }
↕️ tipo

Indica si el movimiento representa un ingreso o un gasto.

🏷️ concepto

Describe brevemente qué originó el movimiento.

💰 cantidad

Guarda el valor numérico asociado al movimiento.

🗂️ categoria

Permite agrupar movimientos relacionados.

movimiento = {
    "tipo": "gasto",
    "concepto": "Transporte",
    "cantidad": 12.50,
    "categoria": "transporte"
}

print(movimiento)

Guardar varios movimientos

Un diccionario puede representar un movimiento individual, pero nuestro gestor necesitará almacenar muchos ingresos y gastos.

Para conseguirlo utilizaremos una lista. Cada elemento de esa lista será uno de los diccionarios que representa un movimiento.

Diccionario

tipo

concepto

cantidad

categoria

Lista de movimientos

├── movimiento 1

├── movimiento 2

└── movimiento 3

Un diccionario representa un movimiento. Una lista puede guardar todos los movimientos.

movimientos = [
    {
        "tipo": "ingreso",
        "concepto": "Mesada",
        "cantidad": 150.0,
        "categoria": "otros"
    },
    {
        "tipo": "gasto",
        "concepto": "Transporte",
        "cantidad": 12.50,
        "categoria": "transporte"
    },
    {
        "tipo": "gasto",
        "concepto": "Almuerzo",
        "cantidad": 8.0,
        "categoria": "alimentación"
    }
]

print(movimientos)

Crear movimientos sin repetir código

Crear cada diccionario manualmente funciona, pero repetir la misma estructura una y otra vez aumenta la cantidad de código y facilita cometer errores.

Las funciones que aprendiste anteriormente nos permiten convertir este procedimiento repetido en una tarea con nombre.

Crearemos una función llamada crear_movimiento(). Recibirá cuatro datos y devolverá el diccionario correspondiente.

↕️ tipo
🏷️ concepto
💰 cantidad
🗂️ categoria
📦 Diccionario
def crear_movimiento(tipo, concepto, cantidad, categoria):
    return {
        "tipo": tipo,
        "concepto": concepto,
        "cantidad": cantidad,
        "categoria": categoria
    }


movimiento_ingreso = crear_movimiento(
    "ingreso",
    "Mesada",
    150.0,
    "otros"
)

movimiento_gasto = crear_movimiento(
    "gasto",
    "Transporte",
    12.50,
    "transporte"
)

print(movimiento_ingreso)
print(movimiento_gasto)

La función ya puede construir un diccionario, pero todavía necesitamos incorporarlo a la colección completa.

Para añadir un elemento al final de una lista utilizamos append().

📝 Datos
⚙️ crear_movimiento()
📦 Diccionario
append()
📚 Lista
La lista es nuestra memoria temporal

Mientras el programa permanezca abierto, cada nuevo movimiento podrá añadirse a la misma lista.

def crear_movimiento(tipo, concepto, cantidad, categoria):
    return {
        "tipo": tipo,
        "concepto": concepto,
        "cantidad": cantidad,
        "categoria": categoria
    }


movimientos = []

movimiento_1 = crear_movimiento(
    "ingreso",
    "Mesada",
    150.0,
    "otros"
)

movimiento_2 = crear_movimiento(
    "gasto",
    "Transporte",
    12.50,
    "transporte"
)

movimiento_3 = crear_movimiento(
    "gasto",
    "Almuerzo",
    8.0,
    "alimentación"
)

movimientos.append(movimiento_1)
movimientos.append(movimiento_2)
movimientos.append(movimiento_3)

print(movimientos)

Consultar lo que hemos registrado

Guardar información sirve de poco si después no podemos consultarla. Como todos los movimientos están dentro de una lista, podemos recorrerla mediante un bucle for.

En cada recorrido obtendremos un diccionario y podremos consultar sus claves para construir una línea fácil de leer.

movimientos
INGRESO | Mesada | 150,00 € | otros GASTO | Transporte | 12,50 € | transporte GASTO | Almuerzo | 8,00 € | alimentación
def mostrar_movimientos(movimientos):
    for movimiento in movimientos:
        tipo = movimiento["tipo"].upper()
        concepto = movimiento["concepto"]
        cantidad = movimiento["cantidad"]
        categoria = movimiento["categoria"]

        print(
            f"{tipo} | {concepto} | "
            f"{cantidad:.2f} € | {categoria}"
        )


mostrar_movimientos(movimientos)

Calcular totales a partir de los movimientos

Nuestro programa ya puede almacenar y mostrar movimientos. Ahora necesitamos convertir esos datos individuales en información útil.

Para calcular un total utilizaremos un patrón sencillo: comenzar en cero, recorrer los movimientos, comprobar cuáles nos interesan y acumular sus cantidades.

total = 0 Crear el acumulador
Recorrer Examinar cada movimiento
Comprobar tipo Ingreso o gasto
Acumular Sumar la cantidad
def calcular_ingresos(movimientos):
    total = 0

    for movimiento in movimientos:
        if movimiento["tipo"] == "ingreso":
            total += movimiento["cantidad"]

    return total


ingresos = calcular_ingresos(movimientos)

print(f"Ingresos totales: {ingresos:.2f} €")
def calcular_gastos(movimientos):
    total = 0

    for movimiento in movimientos:
        if movimiento["tipo"] == "gasto":
            total += movimiento["cantidad"]

    return total


gastos = calcular_gastos(movimientos)

print(f"Gastos totales: {gastos:.2f} €")

Ya tenemos una función que calcula los ingresos y otra que calcula los gastos. No necesitamos volver a escribir esas operaciones para conocer cuánto dinero queda.

Podemos reutilizar ambos resultados y calcular el balance mediante una resta.

📥 calcular_ingresos()
📊 Balance Ingresos menos gastos
💶 calcular_gastos()

Cuando una función ya resuelve una tarea, podemos utilizar su resultado en lugar de repetir la lógica.

def calcular_balance(movimientos):
    ingresos = calcular_ingresos(movimientos)
    gastos = calcular_gastos(movimientos)

    return ingresos - gastos


balance = calcular_balance(movimientos)

print(f"Balance: {balance:.2f} €")

✅ Punto de control

Representar un movimiento mediante un diccionario.
Guardar varios movimientos dentro de una lista.
Crear movimientos mediante una función.
Recorrer y mostrar los movimientos.
Calcular los ingresos totales.
Calcular los gastos y el balance.
Ingresos 150,00 €
Gastos 20,50 €
Balance 129,50 €

Descubrir en qué se está gastando

Conocer el total gastado es útil, pero todavía no nos dice cómo se distribuye ese dinero.

Las categorías permiten responder una pregunta más interesante: ¿en qué estamos gastando?

Para calcularlo construiremos otro diccionario. En este caso, cada clave será una categoría y cada valor almacenará el gasto acumulado.

Movimientos

Transporte → 12,50 €

Alimentación → 8,00 €

Transporte → 12,00 €

Acumulado

transporte → 24,50

alimentación → 8,00

def calcular_gastos_por_categoria(movimientos):
    gastos_por_categoria = {}

    for movimiento in movimientos:
        if movimiento["tipo"] == "gasto":
            categoria = movimiento["categoria"]
            cantidad = movimiento["cantidad"]

            if categoria in gastos_por_categoria:
                gastos_por_categoria[categoria] += cantidad
            else:
                gastos_por_categoria[categoria] = cantidad

    return gastos_por_categoria


categorias = calcular_gastos_por_categoria(movimientos)

print(categorias)

Hemos construido todas las operaciones necesarias para obtener una visión general de nuestras finanzas.

Ahora podemos reunir esos resultados dentro de un único resumen sin volver a implementar ninguno de los cálculos.

Ingresos 150,00 €
Gastos 20,50 €
Balance 129,50 €
Las piezas ya existen

El resumen no necesita saber cómo se calcula cada valor. Puede pedir los resultados a las funciones que ya hemos construido.

def mostrar_resumen(movimientos):
    ingresos = calcular_ingresos(movimientos)
    gastos = calcular_gastos(movimientos)
    balance = calcular_balance(movimientos)
    gastos_por_categoria = calcular_gastos_por_categoria(
        movimientos
    )

    print("\n--- RESUMEN FINANCIERO ---")
    print(f"Ingresos: {ingresos:.2f} €")
    print(f"Gastos: {gastos:.2f} €")
    print(f"Balance: {balance:.2f} €")

    print("\nGastos por categoría:")

    for categoria, total in gastos_por_categoria.items():
        print(f"- {categoria}: {total:.2f} €")


mostrar_resumen(movimientos)

Convertir el programa en una aplicación

Hasta ahora los movimientos estaban escritos directamente dentro del código. Eso nos permitió concentrarnos primero en la organización y los cálculos.

El siguiente paso consiste en permitir que una persona escriba los datos mientras el programa está funcionando.

Python dispone de la función input() para recibir información desde la terminal.

entrada
Concepto: Transporte Cantidad: 12.50 Categoría: transporte
input() comienza entregando texto

Aunque una persona escriba 12.50, el dato recibido inicialmente es texto. Cuando necesitemos realizar cálculos tendremos que convertirlo a un número.

Una aplicación de terminal necesita una forma sencilla de preguntar qué quiere hacer el usuario. Nuestro menú ofrecerá cinco acciones.

gestor de gastos
1. Registrar ingreso 2. Registrar gasto 3. Ver movimientos 4. Ver resumen 5. Salir
while Mantener la aplicación activa
Mostrar menú
Leer opción
if / elif Elegir la acción
def mostrar_menu():
    print("\n========================================")
    print("      GESTOR DE GASTOS PERSONALES")
    print("========================================")
    print("1. Registrar ingreso")
    print("2. Registrar gasto")
    print("3. Ver movimientos")
    print("4. Ver resumen")
    print("5. Salir")

Para registrar un movimiento necesitamos pedir tres datos al usuario: concepto, cantidad y categoría.

El concepto y la categoría pueden conservarse como texto. La cantidad, en cambio, debe convertirse para poder utilizarse posteriormente en sumas y restas.

Para realizar esa conversión utilizaremos float().

input() 12.50 como texto
float() Convertir
12.50 Número utilizable
def registrar_gasto(movimientos):
    concepto = input("Concepto: ")
    cantidad = float(input("Cantidad: "))
    categoria = input("Categoría: ")

    movimiento = crear_movimiento(
        "gasto",
        concepto,
        cantidad,
        categoria
    )

    movimientos.append(movimiento)

    print("✓ Gasto registrado correctamente.")
def registrar_ingreso(movimientos):
    concepto = input("Concepto: ")
    cantidad = float(input("Cantidad: "))
    categoria = input("Categoría: ")

    movimiento = crear_movimiento(
        "ingreso",
        concepto,
        cantidad,
        categoria
    )

    movimientos.append(movimiento)

    print("✓ Ingreso registrado correctamente.")

Qué ocurre cuando el usuario se equivoca

Nuestra primera entrada interactiva funciona mientras el usuario escriba exactamente lo que esperamos.

Pero una aplicación real debe considerar que la entrada puede ser incorrecta.

entrada incorrecta
Cantidad: hola
float() no puede convertir cualquier texto

Si intentamos convertir hola a un número, Python produce un ValueError y el programa se detiene si no hacemos nada al respecto.

Podemos intentar realizar la conversión dentro de try y utilizar except ValueError para reaccionar cuando esa conversión falla.

No necesitamos estudiar todavía todos los tipos de excepciones. En este proyecto utilizaremos solamente la que necesitamos para proteger la lectura de cantidades.

Estás viendo solo el 60% del contenido. Hazte Premium para acceder a la guía completa.

Comunidad

Comentarios y valoraciones

No hay comentarios aún. ¡Sé el primero en opinar!