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 ⌄
- Del problema cotidiano al programa
- Cómo representar un movimiento
- Guardar varios movimientos
- Crear movimientos sin repetir código
- Consultar lo que hemos registrado
- Calcular totales a partir de los movimientos
- Descubrir en qué se está gastando
- Convertir el programa en una aplicación
- Qué ocurre cuando el usuario se equivoca
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
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.
Necesitamos identificar y sumar todos los movimientos que representan ingresos.
Tendremos que reconocer los gastos y acumular sus cantidades.
Cada gasto tendrá una categoría que permitirá organizar mejor la información.
El balance aparecerá al comparar el dinero ingresado con el dinero gastado.
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:
Indica si el movimiento representa un ingreso o un gasto.
Describe brevemente qué originó el movimiento.
Guarda el valor numérico asociado al movimiento.
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.
tipo
concepto
cantidad
categoria
├── 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.
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().
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.
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.
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.
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
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.
Transporte → 12,50 €
Alimentación → 8,00 €
Transporte → 12,00 €
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.
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.
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.
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().
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.
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.
Comentarios y valoraciones
No hay comentarios aún. ¡Sé el primero en opinar!