[Diario] Control de gastos. Python & PostgreSQL

B

Terminados los exámenes y a modo de aprendizaje quiero hacer un side project que me sirva y adorne mi GitHub que es un nido de mierda ahora mismo. Tengo pendiente desde hace un mes una code review de otro proyectillo por parte de un vegano que ama la sobre ingeniería, de cuyo nombre no quiero acordarme pero está sudando.

Proyecto control de gastos

Voy a hacerlo en Python que es lo que necesito reforzar ahora mismo.

La idea es analizar todos mis movimientos bancarios y poder categorizarlos desde la app para hacer un análisis de por dónde se me va la pasta y conseguir ahorrar, me gustaría también generar visualizaciones tipo gnuplot, imagino que haré que me envíe esas visualizaciones a Telegram.

Base de datos

PosrgreSQL en un pc viejo que tengo siempre encendido

ORM

PonyORM https://ponyorm.org/ me lo ha recomendado @eondev y me gusta la forma de hacer las querys.

Cómo funcionará

De momento no quiero liarme con extaer la información del banco de forma automática, así que configuraré una ruta en mi pc que automáticamente inserte la información a la BBDD leyendo los CSVs que entren en esa ruta.

Tendrá test y CI.

Me interesan vuestros comentarios sobre el código ya que mi interés principal es aprender y siendo programador de ERP estoy muy deprecated

5
B

Día 1. 2 Julio 2021

  • Crear contenedor Postgre en un PC abandonado de casa
  • Poner IP fija al PC
  • Intentar conectarme desde mi equipo

EDIT: Ya tengo montado el servidor Postgre con ip fija y consigo conectarme desde el pc donde desarrollo, añado un punto más para hoy:

  • Crear tablas necesarias
1 respuesta
bestarcher

Genial, esta interesante. Aunque en realidad python y postgre no lo uso mucho pero seguire el post a ver si me empapo de algo.

JuAn4k4

#2 Vas a gastar más en luz que lo que te cuesta poner un server vps o un free tier por ahí

1 respuesta
B

#4 jajaja no te falta razón, pero como lo tengo siempre porque tengo varios docker en marcha, pues uno más xdd

B

Día 2. 4 Julio 2021

Tengo ya la primera entidad creada, al instanciarla en el main.py los datos persisten en la base de datos. Tengo dudas de cómo he implementado la conexión con la base de datos. @eondev a ver si puedes darle un vistazo para saber tu opinión. En la rama develop he dejado el avance actual. @Wei-Yu te digo igual, si tienes un ratillo y lo puedes mirar.

He creado una clase para la base de datos, que lee los datos de conexión de un archivo que no está en el r

Gracias chicos

2 respuestas
Fyn4r

#6 Para tema de la config si tienes un fichero con los datos y por eso no lo subes al repo, puedes utilizar varibles de entorno. En general creo que queda más claro si alguien entra al código e incluso puedes poner unos valores por defecto, además que si no me equivoco es algo estándar

P.D Organiza el código antes de que se te vaya de las manos >.<

2 respuestas
Leos

#6 #7 Para el tema de config no es más estándar un .env y en el repo subir un .env.example? Aunque en este caso no haría falta el example si nadie más va a contribuir al repo

2 respuestas
Fyn4r

#8 Sí, eso sí. Luego con dotenv o algo así lo lees y cargas las variables

B

#7 gracias, me interesa lo de organizar el código ¿qué le ves? Estoy muy interesado en que quede lo mejor posible

#8 gracias, lo revisaré y cambiaré

B

Día 3. 5 Julio 2021

  • Reemplazado archivo cutre de configuración para usar python-dotenv. Me gusta mucho más esta forma
  • Refactoricé las entidades en un solo archivo, creé unos test que se ejecutan sobre una base de datos en memoria que trae ponyorm. Me está encantando este orm, va a ser lo único que use
1
B

Día 4. 6 Julio 2021

  • La base de datos ya está lista, ahora toca hacer la importación de los excels que se descargan del banco
  • Implementado pre-commit y black formatter para ahorrar tiempo y evitar hacer push con problemas de formato
Phatality

Recomiendo el black formatter, lo puedes aplicar automaticamente antes de cada commit local usando pre-commit (muy recomendado tambien para gestionar pre-commit hooks con git).

1 2 respuestas
B

#13 de puta madre, no conocía ninguno de los dos, voy probando. Muchas gracias

Phatality

Otra cosa, si eres como yo y te da por culo el tipado dinamico de python, esto te hace analisis estatico del codigo y te dice donde deberias meter type hints: http://mypy-lang.org/

1 respuesta
PiPePiTo

#15 Esto... se puede meter en un IDE para que lo vaya haciendo on the fly como el resharper de .NET? xDD me parece super util, la verdad.

1 respuesta
Phatality

#16 Que yo sepa no, pero pycharm te va dando avisos muy parecidos (no tan detallados como mypy).

Mypy en si al final es muy cutrecillo, es un cli que ejecutas y te saca un output quejandose de cosas xD en plan: esta funcion no tiene return type, esta implementacion no respeta la interfaz q implementa, etc XD

Luego tambien esta pylint pero es el linter al uso y funciona igual q mypy: cli que ejecutas y te saca un output quejandose de historias.

1 respuesta
PiPePiTo

#17 Es que aquí uno que trabaja con .NET se acostumbra demasiado fácil a toda la mierda que me da Visual Studio como si fuera retrasado y...claro, moverme a python a veces me cuesta horrores, tendré que ir mirandome estas mierdas, gracias!

B

#13 he metido en el proyecto pre-commit y black. Una maravilla. Me modifica automáticamente los ficheros cuando intento hacer el commit desde local.

Muchas gracias, estoy aprendiendo muchísimo gracias a este hilo

JuAn4k4

Has pensado en hacerlo APi first? De manera que tienes una API super simple de meter gastos en tu BD, y luego ir metiendo bots que metan gastos de forma automática? Así puedes hacer uso de cosas como zappier o pipedream para conectarlo con el resto de apps/cosas.

También metería un webhook para notificar eventos y desde ese hook hacer lo mismo para conectarlo y mandar emails, SMS, slack, Telegram sin programar.

1 1 respuesta
B

#20 Pues esa fue mi idea inicial, para poder meter gastos directamente con un bot en telegram por ejemplo. Finalmente lo que quiero hacer es importar movimientos del banco, categorizarlos y explotar la información.

Si no tengo la api first para meter gastos manualmente se me presentan problemas. Ejemplo:

  • Saco 20 euros del cajero, ese movimiento se me refleja en el banco, pero luego con esos 20 euros compro lejía y un bocadillo, me interesa partir ese movimiento en dos. Sin api, no puedo meter nada manualmente, solo tendría en el banco un movimiento de -20 sin categorizar, por lo que tendría que tratarlo después.

Si tengo api podría meter movimiento manualmente, pero debería estar pendiente de los duplicados que me genere la importación de movimientos del banco.

Si se os ocurre una buena forma de atajar estos problemas thanks jajaja

1 respuesta
_Rpv

Mi consejo es que tengas super claro la lógica de "negocio", antes de picar nada.

Yo hice un proyecto parecido (pero en MEAN) y al final se me descuadraba todo con los gastos compartidos. Por ejemplo si pagas tu una comida con tarjeta, un amigo te paga en efectivo, y otro amigo te paga por bizum.
Por lo tanto las transacciones no eran 1:1 con los gastos/ingresos y sudé de rediseñarlo.

#21vago_21:

Si tengo api podría meter movimiento manualmente, pero debería estar pendiente de los duplicados que me genere la importación de movimientos del banco.

Si metes la fecha puedes comprobar si ya has metido un movimiento igual ese día.

¿Meterás todo vía excel del banco o tendrás algunos gastos automatizados? (como las subscripciones)

1 respuesta
B

#22 En teoría las suscripciones también pasan por el banco, así que salvo que se me haya pasado algo será todo vía excel del banco.

Tengo la fecha, pero me refiero al duplicado en el sentido de que si saco 20 euros del cajero, tendría un -20, pero luego me gasto 10 en una cosa y 10 en otra, teniendo una api, podría meter desde telegram dos movimientos bien categorízados, pero debería borrar el original de -20 que saqué del cajero, en ese caso, la fecha sería la misma, pero el importe no, por lo que ese duplicado no se podría detectar automáticamente. Debería meter una función de "dividir movimiento"

1 respuesta
_Rpv

#23 sacar dinero del banco realmente no es un gasto, así que yo ni los incluiría
Lo de dividir movimiento vendría bien para los casos que te he comentado.

1
B

Día 5. 7 Julio 2021

  • He tenido problemas con la librería para importar excels ya que solo admite xlsx y el banco me descarga xls, había pensado en renombrar todos los ficheros antes de importar, pero al final he usado otra librería
  • Hoy me gustaría hacer ya los insert en la base de datos y mover los ficheros importados a una carpeta de "procesados". Para los próximos días tendré que hacer unas fuciones que recategorizen los movimientos porque la información que da ING no está suficientemente desglosada.

Tengo dudas sobre la organización de código, lo dejo aquí para que lo veáis. Cualquier opinión es bienvenida:

Ronso

Me mola la idea, me quedo por aquí aunque estoy pegado de la mitad de cosas que decís.
Yo me hice un bot en telegram para los gastos, los enviaba a una hoja excel, te dejo info por si te interesa.
https://medium.com/@mars_escobin/telegram-bot-to-track-your-expenses-in-a-spreadsheet-d07393513bd5

1 1 respuesta
B

#26 gracias, le echo un ojo!

NeV3rKilL

Como idea para el futuro;

Yo uso https://www.youneedabudget.com/the-four-rules/ y estoy muy contento con ello.

Es un concepto diferente, bastante empresarial, el de crear un presupuesto con el dinero que tienes más que le de simplemente ver dónde ha ido tu dinero gastado. La cosa es categorizar tu dinero antes de gastarlo, y no categorizarlo después.

Pero eso es para una vez tienes la BBDD de gastos creada.

2 1 respuesta
B

#28 me gusta. Pero paso a paso, primero ver por dónde se me va el dinero, ver cuáles son fijos e intentar minimizar los gastos tontos. Tener una foto de por dónde se va el dinero ya es un paso, pero sí, el futuro es ese, tener un presupuesto. Gracias por compartirlo.

Al final me puede quedar algo bastante útil por lo que estoy viendo

B

Siguiendo vuestros consejos he refactorizado las variables de entorno, sigo usando dotenv, pero ahora están todas declaradas en un fichero de constantes