Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions mejoras-codigo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
## 1. Robustez y Manejo de Errores (Prioridad Alta)

* **Implementar Mecanismo de Reintentos (Retries)**
* **Problema:** En `download_us_money_supply.py` (método server) y en partes de `pyroboadvisor.py`, se usa `requests.get()` directamente. Si la conexión falla momentáneamente, el script se detiene.
* **Solución:** Utilizar una `requests.Session` con un `HTTPAdapter` configurado con `urllib3.util.retry.Retry`. Esto permite reintentar automáticamente la petición (por ejemplo, 3 veces con espera exponencial) en caso de errores de conexión o códigos de estado 5xx.
* **Ejemplo:**
```python
from requests.adapters import HTTPAdapter
from urllib3.util import Retry

session = requests.Session()
retry = Retry(total=3, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
session.mount('https://', HTTPAdapter(max_retries=retry))

response = session.get(url) # Ahora tiene reintentos automáticos
```

* **Manejo de Errores Específico**
* **Problema:** En `daemon.py`, se usa un `except:` genérico al intentar borrar la caché. Esto puede ocultar errores graves (como problemas de permisos o disco lleno) que no son simplemente "archivo no encontrado".
* **Solución:** Capturar excepciones específicas (ej. `FileNotFoundError`, `PermissionError`).

## 2. Calidad de Código y Buenas Prácticas

* **Centralizar la Configuración**
* **Problema:** `sample_b.py` y `daemon.py` comparten un diccionario de configuración (`p`) casi idéntico y muy extenso. Cualquier cambio en la estrategia requiere editar ambos archivos, lo que lleva a errores e inconsistencias.
* **Solución:** Extraer la configuración a un archivo separado (ej. `config_strategy.py` o `config.json`) e importarlo en ambos scripts.

* **Mover Importaciones al Inicio**
* **Problema:** `daemon.py` realiza importaciones (`from download_us_money_supply...`, `import sys`) dentro de la función `run()` y del bucle principal.
* **Solución:** Mover todas las importaciones al principio del archivo (**PEP 8**). Esto mejora la legibilidad y evita la sobrecarga de importar el módulo repetidamente en cada iteración del bucle.

* **Desacoplar Interfaz de Usuario de la Lógica (SRP)**
* **Problema:** La clase `PyRoboAdvisor` (`pyroboadvisor.py`) mezcla lógica de negocio con interacción de consola (CLI), como `input("Email: ")` dentro del `__init__`. Esto hace que el código sea difícil de testear automáticamente y no sea apto para ejecutarse como un servicio desatendido (daemon) real sin interacción humana.
* **Solución:** Pasar toda la configuración (credenciales, opciones) como argumentos al constructor. Si faltan datos, lanzar una excepción en lugar de pedir input al usuario. La interacción con el usuario debe estar en el script principal (`sample_b.py`), no en la librería.

* **Eliminar URLs Locales "Hardcodeadas"**
* **Problema:** `pyroboadvisor.py` contiene `url="https://127.0.0.1:443/index..."`. Esto rompe el código si se ejecuta en un entorno donde el servidor local no está corriendo.
* **Solución:** Definir la URL base en una variable de configuración o constante global.

* **Usar `pathlib` para Rutas**
* **Problema:** Se usa manipulación de cadenas y `os.path.join` de forma mixta.
* **Solución:** Usar el módulo moderno `pathlib`. Es más robusto y legible (ej. `Path.home() / ".gemini" / "tmp"`).

## 3. Optimización de Ejecución

* **Optimización Algorítmica en `UsMoneySupply` (Crítico)**
* **Problema:** En `download_us_money_supply.py`, el método `date2usms` busca la fecha recorriendo la lista elemento a elemento (`for ... in enumerate`). Si simulas varios años, esto crea un cuello de botella enorme de rendimiento ($O(N \times M)$).
* **Solución:** Dado que los datos están ordenados por fecha, usar búsqueda binaria (con `bisect` o `np.searchsorted`) para encontrar la fecha en tiempo logarítmico $O(\log N)$.

* **Evitar Re-descargar Datos en Bucles**
* **Problema:** `daemon.py` llama a `run()` en un bucle infinito. Dentro de `run()`, se instancia `MakerUsMoneySupply`, lo que dispara una petición a `pyroboadvisor.org` en cada iteración.
* **Solución:** Instanciar `MakerUsMoneySupply` y descargar los datos **fuera** del bucle `while True` en `daemon.py`. Pasar el objeto de datos a la función `run()`. Solo refrescar los datos si ha pasado mucho tiempo (ej. una vez al día).

* **Reducir Creación Redundante de Objetos**
* **Problema:** `daemon.py` destruye y recrea el objeto `PyRoboAdvisor` y borra la caché en cada ciclo.
* **Solución:** Considerar añadir un método a `PyRoboAdvisor` para "avanzar al siguiente día" o "refrescar estado" sin tener que reinicializar toda la librería y purgar archivos temporales innecesariamente.

## 4. Seguridad

* **Habilitar Verificación SSL**
* **Problema:** Múltiples llamadas usan `verify=False` en `requests.get`. Esto hace que la aplicación sea vulnerable a ataques "Man-in-the-Middle" (alguien interceptando tu tráfico).
* **Solución:** Eliminar `verify=False`. Si el servidor usa certificados autofirmados, apuntar `verify` a la ruta del certificado CA en lugar de desactivarlo.

* **Evitar Credenciales en Código**
* **Problema:** Se usan cadenas vacías como placeholders y se guardan en `config.json` en texto plano.
* **Solución:** Usar variables de entorno para cargar claves API sensibles.

## 5. Limpieza de Código

* **Eliminar Código Muerto/Comentado**
* **Problema:** Hay muchos bloques de código comentado antiguo que dificultan la lectura.
* **Solución:** Borrar el código comentado. Usar Git para recuperar versiones antiguas si fuera necesario.

* **Logging en lugar de Print**
* **Problema:** El daemon usa `print()` para estados.
* **Solución:** Usar el módulo `logging`. Permite rotación de logs, niveles (INFO, ERROR) y timestamps, fundamental para procesos que corren de fondo.