Limpieza y actualizacion de documentos

This commit is contained in:
Miguel 2025-06-05 17:59:33 +02:00
parent 2cf06fb5f5
commit b2a4237504
17 changed files with 1837 additions and 3663 deletions

View File

@ -1,150 +0,0 @@
# Solución: Contexto Limpio en Cada Evaluación
## Problema Identificado
La aplicación tenía un comportamiento inesperado donde al evaluar una secuencia como:
```
x
x=1
y+x
x=x+1
x
```
El primer `x` ya mostraba un valor (en este caso `2[Integer]`) cuando debería estar indefinido inicialmente.
## Causa Raíz REAL
El problema **NO era solo el historial**, sino que la aplicación mantenía el contexto de variables entre evaluaciones. Cuando el usuario modificaba cualquier línea, la aplicación reevaluaba **manteniendo las variables previamente definidas**, en lugar de construir el contexto desde cero.
Esto significaba que:
1. Si había `x=1` en alguna línea anterior
2. Y luego el usuario añadía una línea `x` al principio
3. El `x` del principio usaba el valor de la evaluación anterior en lugar de iniciar limpio
## Solución Implementada
### Modificación Principal: Contexto Limpio en Cada Evaluación
**Antes:**
```python
def _evaluate_and_update(self):
"""Evalúa todas las líneas y actualiza la salida"""
try:
input_content = self.input_text.get("1.0", tk.END)
if not input_content.strip():
self._clear_output()
return
lines = input_content.splitlines()
self._evaluate_lines(lines) # ← Mantenía contexto anterior
except Exception as e:
self._show_error(f"Error durante evaluación: {e}")
```
**Después:**
```python
def _evaluate_and_update(self):
"""Evalúa todas las líneas y actualiza la salida"""
try:
input_content = self.input_text.get("1.0", tk.END)
if not input_content.strip():
self._clear_output()
return
# NUEVO: Limpiar completamente el contexto antes de cada evaluación
# Esto garantiza que cada modificación reevalúe todo desde cero
self.engine.clear_all()
lines = input_content.splitlines()
self._evaluate_lines(lines)
except Exception as e:
self._show_error(f"Error durante evaluación: {e}")
```
### Cambios Adicionales
1. **Eliminación de llamadas redundantes**: Los métodos `clear_variables()`, `clear_equations()` y `clear_all()` ya no llaman a `_evaluate_and_update()` porque ahora cada evaluación limpia automáticamente.
2. **Limpieza del historial**: También se limpió el historial, pero esto era secundario al problema real.
3. **Opción manual para limpiar historial**: Se añadió en el menú **Editar → Limpiar historial**.
## Comportamiento Resultante
Ahora **cada vez que se modifica cualquier línea**:
1. **Se limpia completamente el contexto** - `engine.clear_all()`
2. **Se reevalúa TODO desde la línea 1** - construcción paso a paso
3. **El contexto se construye de arriba hacia abajo** - sin memoria de evaluaciones anteriores
4. **Variables solo existen si están definidas en líneas anteriores** - comportamiento predictible
## Prueba de Verificación
El script `test_contexto_limpio.py` confirma el comportamiento:
```
=== PRUEBA DE CONTEXTO LIMPIO POR EVALUACIÓN ===
--- PRIMERA EVALUACIÓN: x solo ---
Resultado: x # ← Símbolo puro, sin valor
Variables después: {} # ← Contexto limpio
--- TERCERA EVALUACIÓN: x, x=1, y+x ---
x (antes de asignar): x # ← Siempre símbolo puro al inicio
x=1: 1 # ← Se asigna
y+x: y + 1 # ← Usa el x=1 asignado arriba
Variables después: {'x': 1} # ← Contexto construido paso a paso
```
## Beneficios de la Solución Real
- ✅ **Contexto predecible**: Cada evaluación inicia completamente limpia
- ✅ **Construcción desde arriba**: Las variables solo existen si se definen arriba
- ✅ **Sin memoria persistente**: No hay variables "fantasma" de evaluaciones anteriores
- ✅ **Comportamiento intuitivo**: Lo que ves es lo que tienes
- ✅ **Reevaluación completa**: Cada cambio reconstruye todo desde cero
## Archivos Modificados
1. `main_calc_app.py` - Método `_evaluate_and_update()` con limpieza automática
2. `main_calc_app.py` - Métodos `clear_*()` simplificados
3. `main_calc_app.py` - **Menús simplificados**: Eliminadas opciones redundantes
4. `hybrid_calc_history.txt` - Limpiado (cambio menor)
5. `test_contexto_limpio.py` - Script de prueba (nuevo)
### Cambios en la Interfaz de Usuario
**Opciones ELIMINADAS del menú (ya no tienen sentido):**
- **Menú Editar**:
- ❌ "Limpiar variables"
- ❌ "Limpiar ecuaciones"
- ❌ "Limpiar todo"
- **Menú CAS completo**:
- ❌ "Mostrar variables"
- ❌ "Mostrar ecuaciones"
- ❌ "Resolver sistema"
**Opciones CONSERVADAS (aún útiles):**
- **Menú Editar**:
- ✅ "Limpiar entrada" - limpia el editor de texto
- ✅ "Limpiar salida" - limpia el panel de resultados
- ✅ "Limpiar historial" - elimina el archivo de historial
- **Menú Archivo**:
- ✅ "Nuevo" - inicia sesión nueva (limpia entrada y salida)
- ✅ "Cargar..." / "Guardar como..." - manejo de archivos
**La solución real no era el historial, sino garantizar que cada evaluación construye el contexto completamente desde cero.**
## Impacto en la Experiencia de Usuario
**✅ Interfaz más limpia**: Sin opciones confusas que no funcionan como se espera
**✅ Comportamiento predecible**: Lo que ves en el editor es exactamente lo que tienes
**✅ Simplicidad**: Menos opciones que manejar, enfoque en la funcionalidad principal
**✅ Consistencia**: El comportamiento es coherente con la filosofía "de arriba hacia abajo"

426
.doc/Desarrollo.md Normal file
View File

@ -0,0 +1,426 @@
# Guía de Desarrollo - Calculadora MAV CAS Híbrido
## Visión General
Este documento describe el estado actual y los objetivos de desarrollo para la **Calculadora MAV**, un **Sistema de Álgebra Computacional (CAS) híbrido**. El proyecto busca combinar la potencia de SymPy como motor algebraico central con capacidades especializadas (IP4, Hex, etc.) integradas de forma nativa.
## Objetivos Principales
### 1. **SymPy como Motor Central**
- ✅ Integrar todas las funciones de SymPy directamente
- ✅ SymPy maneja toda la evaluación algebraica y ecuaciones
- ✅ Cada línea de ingreso corresponde a una sola línea de resultados
- ✅ **CONTEXTO LIMPIO POR EVALUACIÓN**: Cada vez que se hace una evaluación se comienza con el contexto completamente limpio y se evalúa desde arriba hacia abajo, línea por línea. Esto garantiza comportamiento predecible sin "memoria" de evaluaciones anteriores.
- ✅ La interfaz de usuario se divide en 2 columnas, a la izquierda el área de ingreso de datos y ecuaciones a ser evaluadas, a la derecha el área de resultados que se colorean según cada tipo de respuesta.
### 2. **Sistema de Tokenización Automática** ⭐ **ACTUALIZADO**
- ❌ ~~Usar **exclusivamente** `Class[args]` en lugar de `Class("args")`~~ **ELIMINADO**
- ✅ **Tokenización automática de patrones específicos**:
- `16#FF``IntBase('FF', 16)` automáticamente
- `192.168.1.1``FourBytes('192.168.1.1')` automáticamente
- ✅ **Sistema distribuido**: Cada clase define sus propios patrones de tokenización
- ✅ **Precedencia automática**: Patrones más específicos tienen mayor prioridad
- ✅ **Parser genérico**: No hardcodea lógica específica de tipos
### 3. **Detección Automática y Manejo de Ecuaciones**
- ✅ Ecuaciones ingresadas directamente (ej. `3+b=5+c`) se detectan y añaden al sistema interno de SymPy.
- ✅ Soporte para comparaciones SymPy (ej. `x > 5`, `a == b`, `x <= 10`) como expresiones evaluables.
- ✅ Sintaxis de atajo para solve: `variable=?` equivale a `solve(variable)`
### 4. **Evaluación Híbrida con Variables SymPy Puras**
- ✅ Resultado simbólico (siempre disponible)
- ✅ Evaluación numérica con `.evalf()` (cuando sea aplicable y las variables estén definidas). Esta evaluación se muestra a la derecha del resultado simbólico.
- ✅ Las asignaciones son siempre simbólicas, solo los resultados se muestra la evaluación numérica.
- ✅ **Todas las variables son símbolos SymPy**: Sin variables Python tradicionales
- 🔄 **Conversión perezosa a SymPy**: Objetos nativos hasta que se necesite álgebra compleja
### 5. **Resultados Interactivos**
- ✅ **Tags clickeables** en el widget Text para resultados complejos que necesitan más de una línea de resultado como Plot, Matrices y Listas.
- ✅ **Detección automática** de tipos que requieren visualización especial:
- ✅ Plots de SymPy → "📊 Ver Plot" (abre ventana matplotlib).
- ✅ Matrices → "📋 Ver Matriz" (muestra matriz formateada).
- ✅ Listas largas → "📋 Ver Lista" (muestra contenido expandido).
- ✅ Objetos complejos → "🔍 Ver Detalles" (representación completa).
- ✅ **Implementación con tags**: Usar `text.tag_bind()` en widget existente
- ✅ **Ventanas popup** para contenido que no cabe en línea.
### 6. **Sistema de Tipos Auto-Descubrible** ⭐ **NUEVO**
- ✅ **Directorio unificado**: Todos los tipos en `custom_types/`
- ✅ **Auto-registro**: Sistema automático de descubrimiento de clases
- ✅ **Función de registro**: Cada módulo tiene `register_classes_in_module()`
- ✅ **Metadatos**: Categorías, opciones y descripciones por tipo
- ✅ **Helpers dinámicos**: Sistema de ayuda contextual distribuido
### 7. **Clases Base Universales** ⭐ **NUEVO**
- ✅ **IntBase**: Representación universal de números en cualquier base
- ✅ **FourBytes**: Representación universal de patrones x.x.x.x
- ✅ **Manejo interno de símbolos**: Sin conversión prematura a SymPy
- ✅ **Aritmética nativa**: Operaciones que mantienen el tipo original
- ✅ **Conversión explícita**: `.to_sympy()` cuando se necesite álgebra compleja
## Arquitectura Actual ⭐ **ACTUALIZADA**
### Estructura de archivos
```
/
├── logs/ # Subcarpeta de logs
├── docs/ # Documentación técnica
├── custom_types/ # ⭐ NUEVO: Sistema de tipos unificado
│ ├── intbase_type.py # IntBase + tokenización + registro
│ ├── fourbytes_type.py # FourBytes + tokenización + registro
│ ├── hex_type.py # Hex (usa IntBase)
│ ├── bin_type.py # Bin (usa IntBase)
│ ├── dec_type.py # Dec
│ ├── chr_type.py # Chr
│ ├── ip4_type.py # IP4 + IP4Mask (usa FourBytes)
│ └── latex_type.py # LaTeX
├── calc.py # Launcher principal
├── main_calc_app.py # Aplicación principal
├── main_evaluation.py # Motor de evaluación híbrido
├── type_registry.py # ⭐ NUEVO: Auto-descubrimiento de tipos
├── tl_popup.py # Motor de ventanas emergentes
├── tl_bracket_parser.py # ⭐ ACTUALIZADO: Tokenizador universal
├── class_base.py # Clases base
├── sympy_Base.py # Base para integración SymPy
└── sympy_helper.py # Helpers para SymPy
```
### Flujo de Procesamiento ⭐ **ACTUALIZADO**
```
Entrada Usuario → [Universal Tokenizer] → [Evaluación Híbrida] → {
1. Resultado Nativo (FourBytes, IntBase, etc.)
2. Conversión a SymPy (solo si es necesario)
3. Evaluación numérica (evalf si aplica)
4. Métodos especializados disponibles
}
```
### Transformación de Sintaxis ⭐ **ACTUALIZADA**
```python
# Tokenización automática (NUEVO):
16#FF + 2#1010 → IntBase("FF", 16) + IntBase("1010", 2)
192.168.1.1 + 5 → FourBytes("192.168.1.1") + 5
IP4(10.1.1.1, 255.255.0.0) → IP4(FourBytes("10.1.1.1"), FourBytes("255.255.0.0"))
# Detección contextual de ecuaciones (EXISTENTE):
3+b=5+c → Se detecta como ecuación standalone (agregar al sistema SymPy)
"x > 5" → Se procesa como desigualdad SymPy
x**2 + 2*x == 0 → Se detecta como igualdad lógica standalone
# Sintaxis de atajo para solve (EXISTENTE):
x=? → solve(x)
```
## Componentes Técnicos ⭐ **ACTUALIZADOS**
### 1. **Sistema de Auto-Descubrimiento de Tipos**
```python
# type_registry.py
class TypeRegistry:
def discover_and_register_all(self):
"""Descubre y registra todas las clases en custom_types/"""
for type_file in self.types_directory.glob("*_type.py"):
self._process_type_file(type_file)
def _register_classes_from_info(self, class_info_list):
"""Registra clases basándose en metadatos"""
for name, class_obj, category, options in class_info_list:
self._register_single_class(name, class_obj, category, options)
```
### 2. **Tokenizador Universal Distribuido**
```python
# tl_bracket_parser.py
class UniversalTokenizer:
def _discover_tokenization_rules(self):
"""Auto-descubre reglas desde todas las clases registradas"""
for class_name, class_obj in registered_classes.items():
if hasattr(class_obj, 'get_tokenization_patterns'):
patterns = class_obj.get_tokenization_patterns()
for pattern_info in patterns:
self.tokenization_rules.append({
'class_name': class_name,
'class_obj': class_obj,
**pattern_info
})
```
### 3. **Clases con Tokenización Propia**
```python
# custom_types/intbase_type.py
class IntBase(ClassBase):
@staticmethod
def get_tokenization_patterns():
return [
{
'pattern': r'(\d+)#([0-9A-Fa-fx]+)',
'replacement': lambda match: f'IntBase("{match.group(2)}", {match.group(1)})',
'priority': 5,
'description': 'Números con base: 16#FF, 2#1010'
}
]
```
### 4. **Conversión Perezosa a SymPy** ⭐ **NUEVO CONCEPTO**
```python
class FourBytes(ClassBase): # No SympyClassBase
def substitute(self, **kwargs):
"""Sustitución interna sin involucrar SymPy"""
# Lógica nativa
def to_sympy(self):
"""Conversión EXPLÍCITA cuando se necesite álgebra"""
# Solo convertir cuando se requiera
```
### 5. **Sistema de Evaluación Integrado**
```python
# main_evaluation.py
class HybridEvaluationEngine:
def __init__(self, auto_discover_types=True):
# Auto-descubrir tipos dinámicamente
self.registered_types_info = discover_and_register_types()
# Configurar parser con tokenización distribuida
self.parser = BracketParser(enable_tokenization=True)
# Configurar contexto con tipos descubiertos
self._setup_base_context()
```
## Capacidades Expandidas ⭐ **ACTUALIZADAS**
### 1. **Funciones SymPy Completas con Objetos Nativos**
```python
# Objetos nativos en álgebra (conversión automática cuando es necesario):
diff(IP4(192.168.x.1) + offset, x) # FourBytes → SymPy automático
integrate(Hex(16#x0) * sin(x), x) # IntBase → SymPy automático
solve([IP4(192.168.x.y) == IP4(192.168.1.10)], [x, y])
# Aritmética nativa (mantiene tipos):
base_ip = 192.168.1.1 # → FourBytes automático
next_ip = base_ip + 5 # → FourBytes('192.168.1.6')
hex_val = 16#FF + 16#10 # → IntBase('10F', 16)
```
### 2. **Conversiones Automáticas Bidireccionales**
```python
# Conversiones fluidas entre tipos:
ip = 192.168.1.1 # → FourBytes automático
ip_hex = ip.ToHex() # → "16#C0.16#A8.16#1.16#1"
mask = 255.255.255.0 # → FourBytes automático
mask_cidr = IP4Mask(mask) # → /24 automático
# Constructores inteligentes:
IP4(192.168.1.1, 16#ffffff00) # FourBytes + IntBase → IP4
Hex(192.168.1.1) # FourBytes → Hex automático
```
### 3. **Sistema de Ayuda Dinámico**
```python
# Helpers auto-descubiertos:
help_functions = get_registered_helper_functions() # De todas las clases
help_context = obtener_ayuda("16#FF") # Helper de IntBase
autocompletado = obj.PopupFunctionList() # Métodos disponibles
```
## Ejemplos de Uso Objetivo ⭐ **ACTUALIZADOS**
```python
# Tokenización automática de patrones:
16#FF + 2#1010 # → IntBase('FF', 16) + IntBase('1010', 2)
192.168.1.1 + 5 # → FourBytes('192.168.1.6')
10.x.1.y # → FourBytes('10.x.1.y') simbólico
# Constructores inteligentes:
IP4(192.168.1.1, 24) # → IP4(FourBytes('192.168.1.1'), 24)
IP4(10.1.1.1, 255.255.0.0) # → Ambos FourBytes automáticamente
Hex(192.168.1.1) # → Conversión FourBytes → Hex
# Conversiones fluidas:
mask = 255.255.255.0 # → FourBytes automático
mask.ToHex() # → "16#FF.16#FF.16#FF.16#0"
mask.ToBase(2) # → "2#11111111.2#11111111.2#11111111.2#0"
# Álgebra con objetos nativos:
network = 10.x.0.0 # → FourBytes simbólico
solve(network + 256 == 10.5.0.0, x) # → x = 5
# Aritmética que preserva tipos:
base = 192.168.0.0 # → FourBytes
for i in range(4):
subnet = base + (i * 256) # → Cada resultado es FourBytes
print(f"Red {i}: {subnet}")
# Evaluación directa con SymPy:
solve(x + 10 - 15, x) # → [5]
diff(16#x0, x) # → 16*log(16) (conversión automática)
# Variables puras SymPy:
x = 5 # → x es Symbol('x') con valor 5
y = x + 2 # → y es expresión simbólica: Symbol('x') + 2
# Funciones avanzadas con resultados interactivos:
plot(sin(2*pi*16#x/256), (x, 0, 255)) # → "📊 Ver Plot"
Matrix([[1, 2, 3], [4, 5, 6]]) # → "📋 Ver Matriz"
```
## Beneficios Logrados ⭐ **ACTUALIZADOS**
### 1. **Usabilidad Mejorada**
- ✅ Sintaxis natural sin artificios (no más `Class[args]`)
- ✅ Tokenización invisible al usuario
- ✅ Acceso completo a capacidades de CAS
- ✅ Evaluación automática simbólica + numérica
### 2. **Potencia Matemática Expandida**
- ✅ Todas las funciones de SymPy disponibles
- ✅ Objetos especializados participan en álgebra cuando es necesario
- ✅ Aritmética nativa que preserva tipos
- ✅ Conversiones automáticas bidireccionales
### 3. **Extensibilidad Real**
- ✅ Sistema verdaderamente modular sin hardcoding
- ✅ Fácil agregar nuevos tipos sin modificar código core
- ✅ Tokenización distribuida y auto-descubrible
- ✅ Compatible con ecosystem SymPy completo
### 4. **Arquitectura Limpia**
- ✅ Responsabilidad única: cada clase maneja su tokenización
- ✅ Parser genérico sin conocimiento específico de tipos
- ✅ Auto-descubrimiento completo del sistema de tipos
- ✅ Manejo unificado de errores
## Sistema de Autocompletado y Ayuda Contextual ⭐ **IMPLEMENTADO**
### 1. **Helpers Dinámicos**
- ✅ **Auto-descubrimiento**: Sistema obtiene helpers de todas las clases registradas
- ✅ **Ayuda contextual**: Cada tipo define su propio `Helper(input_str)`
- ✅ **Integración con SymPy**: Helper especializado para funciones SymPy
- ✅ **Manejo centralizado**: Lista dinámica de helpers disponibles
### 2. **Autocompletado Inteligente**
- ✅ **Popup tras punto**: Evaluación automática del objeto para métodos disponibles
- ✅ **PopupFunctionList()**: Cada clase define sus métodos sugeridos
- ✅ **Filtrado inteligente**: Solo métodos útiles y públicos
- ✅ **No invasivo**: Solo aparece cuando el usuario lo solicita
### 3. **Ejemplos de Integración**
```python
# Sistema distribuido:
HELPERS = get_registered_helper_functions() # Auto-descubierto
# Ayuda contextual:
16#FF. # → Popup con métodos de IntBase
192.168.1.1. # → Popup con métodos de FourBytes
IP4(10.1.1.1). # → Popup con métodos de IP4
# Helpers específicos:
ayuda = obtener_ayuda("16#FF") # → "Números con base: 16#FF, 2#1010..."
```
## Estado de Implementación ⭐ **ACTUALIZADO**
### ✅ **Completamente Implementado**
- **Sistema de auto-descubrimiento**: `type_registry.py`
- **Tokenizador universal**: `tl_bracket_parser.py` refactorizado
- **Clases base universales**: `intbase_type.py`, `fourbytes_type.py`
- **Motor híbrido integrado**: `main_evaluation.py` con auto-descubrimiento
- **Tipos en custom_types/**: Todos los tipos migrados al sistema unificado
- **Helpers dinámicos**: Sistema de ayuda contextual distribuido
- **Resultados interactivos**: Tags clickeables y ventanas popup
- **Contexto limpio**: Evaluación completa desde cero en cada cambio
### 🔄 **En Progreso**
- **Conversión perezosa a SymPy**: Algunos objetos aún se convierten prematuramente
- **Aritmética que preserva tipos**: Necesita refinamiento para todos los casos
- **Optimización de precedencia**: Ajuste fino de prioridades de tokenización
### 📋 **Pendiente**
- **Tipos adicionales**: MAC addresses, timestamps, coordenadas
- **Performance optimization**: Caching y evaluación lazy
- **Documentación de usuario**: Guías y ejemplos actualizados
## Métricas de Éxito ⭐ **ACTUALIZADAS**
- ✅ **Sistema de tokenización automática funcional**:
- ✅ Patrones `16#FF`, `2#1010` → IntBase automático
- ✅ Patrones `192.168.1.1` → FourBytes automático
- ✅ Precedencia automática por especificidad
- ✅ Parser genérico sin hardcoding
- ✅ **Sistema de tipos auto-descubrible**:
- ✅ Todas las clases en `custom_types/`
- ✅ Función `register_classes_in_module()` en cada módulo
- ✅ Auto-registro con metadatos y opciones
- ✅ Helpers dinámicos desde todas las clases
- ✅ **Clases base universales funcionales**:
- ✅ IntBase con aritmética nativa y tokenización propia
- ✅ FourBytes con aritmética nativa y tokenización propia
- ✅ Conversión explícita `.to_sympy()` cuando sea necesario
- ✅ Operadores que mantienen tipos nativos
- ✅ **Motor híbrido integrado**:
- ✅ Auto-descubrimiento de tipos al inicializar
- ✅ Tokenización distribuida automática
- ✅ Contexto limpio por evaluación
- ✅ Evaluación simbólica + numérica
- 🔄 **Conversión perezosa optimizada**:
- ✅ Objetos nativos por defecto
- 🔄 Conversión solo cuando se necesite álgebra compleja
- 🔄 Aritmética preservando tipos en todos los casos
- ✅ **Detección contextual de ecuaciones**:
- ✅ Ecuaciones standalone detectadas y agregadas al sistema
- ✅ Sintaxis de atajo `variable=?``solve(variable)`
- ✅ Protección contra detección en argumentos de función
- ✅ **Resultados interactivos**:
- ✅ Tags clickeables para plots, matrices, listas
- ✅ Ventanas popup con posicionamiento inteligente
- ✅ Detección automática de tipos complejos
- ✅ **Sistema de ayuda avanzado**:
- ✅ Helpers auto-descubiertos desde todas las clases
- ✅ Autocompletado tras punto con métodos disponibles
- ✅ Ayuda contextual no invasiva
- ✅ **Performance aceptable**: Debounce y evaluación optimizada
- ✅ **Manejo robusto de errores**: Logging centralizado y presentación clara
- ✅ **Documentación actualizada**: Guías técnicas y de desarrollo
## Consideraciones Futuras
### **Tipos Adicionales Planeados**
```python
custom_types/
├── mac_type.py # Direcciones MAC: AA:BB:CC:DD:EE:FF
├── time_type.py # Timestamps: HH:MM:SS, ISO format
├── coordinate_type.py # Coordenadas: lat,lon
├── ipv6_type.py # IPv6: 2001:db8::1
└── range_type.py # Rangos: 1..100, a..z
```
### **Optimizaciones de Performance**
- Caching de patrones de tokenización frecuentes
- Evaluación lazy de `evalf()` solo cuando se muestre
- Memoización de conversiones SymPy costosas
### **Extensiones del Parser**
- Soporte para sintaxis de múltiples líneas
- Macros y templates definidos por usuario
- Validación contextual más sofisticada
## Conclusión
La calculadora MAV ha evolucionado hacia un **sistema verdaderamente híbrido y extensible** que combina:
1. **Potencia algebraica completa** de SymPy
2. **Objetos nativos especializados** con aritmética propia
3. **Tokenización automática invisible** al usuario
4. **Arquitectura modular** sin hardcoding
5. **Auto-descubrimiento completo** del sistema de tipos
El resultado es una herramienta que es **más simple para el usuario** (sintaxis natural) pero **más poderosa internamente** (álgebra simbólica + tipos especializados), con una **arquitectura limpia y extensible** que facilita agregar nuevas capacidades sin modificar código existente.

712
.doc/Documentacion.md Normal file
View File

@ -0,0 +1,712 @@
# Calculadora MAV - CAS Híbrido
## Descripción General
La Calculadora MAV es un **Sistema de Álgebra Computacional (CAS) Híbrido** que combina la potencia de SymPy con clases especializadas para networking, programación y análisis numérico, usando un **sistema de tokenización automática** que convierte patrones específicos en objetos tipados.
### Características Principales
- **Motor SymPy completo**: Todas las funciones de cálculo simbólico
- **Tokenización automática invisible**: `16#FF` y `192.168.1.1` se convierten automáticamente en objetos tipados
- **Sistema de tipos dinámico**: Auto-descubrimiento desde `custom_types/`
- **Detección automática de ecuaciones**: Sin necesidad de comillas especiales
- **Resultados interactivos**: Plots, matrices y listas clickeables
- **Clases especializadas**: IntBase, FourBytes, IP4, Hex, Bin, Chr y más
- **Variables SymPy puras**: Todas las variables son símbolos automáticamente
- **Contexto limpio por evaluación**: Comportamiento predecible sin "memoria" de evaluaciones anteriores
## Instalación
### Método 1: Instalación Automática
```bash
python calc.py --setup
```
### Método 2: Instalación Manual
```bash
# Instalar dependencias
pip install sympy matplotlib numpy
# En Linux: instalar tkinter
sudo apt-get install python3-tk
# Ejecutar tests (opcional)
python test_suite.py
# Iniciar aplicación
python calc.py
```
### Dependencias Requeridas
- **Python 3.8+**
- **SymPy ≥ 1.12** (motor algebraico)
- **Matplotlib ≥ 3.7.0** (plotting)
- **NumPy ≥ 1.24.0** (cálculos numéricos)
- **Tkinter** (interfaz gráfica, incluido con Python)
### Dependencias Opcionales
- **Markdown ≥ 3.4.0** (ayuda mejorada)
- **pytest ≥ 7.0.0** (testing)
## Guía de Uso
### Tokenización Automática ⭐ **NUEVO**
La aplicación reconoce patrones específicos y los convierte automáticamente en objetos tipados:
#### Números con Base (IntBase)
```python
# Tokenización automática de números con base
16#FF # → IntBase('FF', 16) = 255
2#1010 # → IntBase('1010', 2) = 10
8#777 # → IntBase('777', 8) = 511
16#x0 # → IntBase('x0', 16) = simbólico
# Aritmética que mantiene la base original
16#FF + 16#10 # → IntBase('10F', 16) = 271
2#1010 * 3 # → IntBase('11110', 2) = 30
```
#### Patrones x.x.x.x (FourBytes)
```python
# Tokenización automática de patrones dotted
192.168.1.1 # → FourBytes('192.168.1.1')
255.255.255.0 # → FourBytes('255.255.255.0')
10.x.1.y # → FourBytes('10.x.1.y') = simbólico
# Aritmética de direcciones (32-bit)
192.168.1.1 + 5 # → FourBytes('192.168.1.6')
10.0.0.0 + 256 # → FourBytes('10.0.1.0')
```
### Clases Especializadas
#### Uso Natural con Constructores
```python
# Los constructores reciben objetos ya tokenizados
IP4(192.168.1.100, 24) # FourBytes automático
IP4(10.0.0.1, 255.255.0.0) # Ambos son FourBytes
Hex(16#FF) # IntBase automático
Dec(255) # Entero normal
Chr(65) # Carácter ASCII
```
#### Métodos de Clases Especializadas
```python
# Métodos de IP4
ip = IP4(192.168.1.100, 24)
ip.NetworkAddress() # → IP4(192.168.1.0, 24)
ip.BroadcastAddress() # → IP4(192.168.1.255, 24)
ip.Nodes() # → 254 (hosts disponibles)
# Conversiones de IntBase
val = 16#FF # → IntBase('FF', 16)
val.to_decimal() # → 255
val.to_base(2) # → IntBase('11111111', 2)
# Conversiones de FourBytes
addr = 192.168.1.1 # → FourBytes('192.168.1.1')
addr.ToHex() # → "16#C0.16#A8.16#1.16#1"
addr.ToBinary() # → "2#11000000.2#10101000.2#1.2#1"
```
### Conversiones Automáticas Bidireccionales
#### Flujo Natural Entre Tipos
```python
# IP con máscara hexadecimal
IP4(192.168.1.1, 16#ffffff00) # IntBase → IP4Mask automático
# Conversión desde IP a Hex
ip_bytes = 192.168.1.1 # → FourBytes
hex_ip = Hex(ip_bytes) # → Hex con valor 32-bit
# Análisis de máscara en múltiples bases
mask = 255.255.255.0 # → FourBytes
mask_hex = Hex(mask) # → Hex basado en 32-bit
mask_bin = Bin(mask) # → Bin por elementos
mask_cidr = IP4Mask(mask) # → /24
# Operaciones mixtas
base_ip = 192.168.0.0 # → FourBytes
offset = 16#100 # → IntBase('100', 16) = 256
next_ip = base_ip + offset # → FourBytes('192.168.1.0')
```
### Ecuaciones y Álgebra
#### Detección Automática de Ecuaciones
```python
# Ecuaciones simples (detectadas automáticamente)
x + 2 = 5
3*a + b = 10
y**2 = 16
# Desigualdades
x > 5
a <= 10
b != 0
# Ecuaciones complejas
sin(x) = 1/2
log(y) + 3 = 5
# Ecuaciones con objetos tipados
10.x.1.1 + 256 = 10.5.1.1 # Resuelve: x = 4
```
#### Resolución de Ecuaciones
```python
# Resolver ecuación específica
solve(x**2 + 2*x - 8, x) # [-4, 2]
# Atajo para resolver variable
x=? # Equivale a solve(x)
# Resolver sistema de ecuaciones
x + y = 10
x - y = 2
solve([x + y - 10, x - y - 2], [x, y]) # {x: 6, y: 4}
# Sistemas con objetos tipados
network = 10.a.b.0
solve(network + 256 == 10.5.1.0, [a, b]) # Encuentra valores de a, b
```
### Variables y Símbolos
#### Variables SymPy Automáticas
```python
# Todas las variables son símbolos SymPy automáticamente
x + 2*y # Expresión simbólica
z = 5 # z es Symbol('z') con valor 5
w = z**2 + 3 # w es expresión: Symbol('z')**2 + 3
# Con objetos tipados
ip_base = 10.x.1.1 # FourBytes simbólico
ip_final = ip_base + 10 # Aritmética simbólica
substitute(ip_final, x=5) # → FourBytes('10.5.1.11')
```
#### Contexto Limpio por Evaluación
```python
# Cada modificación reevalúa todo desde cero:
x # → Symbol('x') puro (sin valor)
x = 1 # → Asigna x = 1
y = x + 2 # → y = 3 (usa x=1 definido arriba)
# Si modifica cualquier línea, se reevalúa todo nuevamente
# Esto garantiza comportamiento predecible y determinista
```
### Funciones Matemáticas
#### Cálculo Diferencial e Integral
```python
# Derivadas con objetos tipados
diff(16#x0, x) # → 16*log(16)
diff(sin(192.168.x.1), x) # → cos(3232235777 + x)
# Integrales
integrate(x**2, x) # → x**3/3
integrate(sin(x), (x, 0, pi)) # → 2
# Límites
limit(sin(x)/x, x, 0) # → 1
# Series de Taylor
series(exp(x), x, 0, 5) # → 1 + x + x**2/2 + x**3/6 + x**4/24 + O(x**5)
```
#### Funciones Trigonométricas
```python
# Funciones básicas
sin(pi/2) # → 1
cos(0) # → 1
tan(pi/4) # → 1
# Con valores hexadecimales
sin(16#FF / 255 * pi) # → Seno de π (aproximadamente)
```
#### Álgebra y Simplificación
```python
# Simplificación
simplify((x**2 - 1)/(x - 1)) # → x + 1
expand((x + 1)**3) # → x**3 + 3*x**2 + 3*x + 1
factor(x**2 - 1) # → (x - 1)*(x + 1)
# Con objetos especializados
simplify(16#FF + 2#1010 - 265) # → 0 (IntBase convertido automáticamente)
```
### Álgebra Lineal
#### Matrices
```python
# Crear matrices
M = Matrix([[1, 2], [3, 4]])
N = Matrix([[5, 6], [7, 8]])
# Operaciones básicas
M + N # Suma de matrices
M * N # Multiplicación
M**2 # Potencia
# Propiedades (clickeables en interfaz)
det(M) # Determinante: -2
inv(M) # Matriz inversa
M.transpose() # Transpuesta
```
### Plotting Interactivo
#### Plots 2D
```python
# Plot básico
plot(sin(x), (x, -2*pi, 2*pi))
# Múltiples funciones
plot(sin(x), cos(x), (x, 0, 2*pi))
# Plot con objetos tipados
plot(16#x/256, (x, 0, 255)) # Hex values
plot(sin(192.168.x.1 / 1000), (x, 0, 255)) # IP arithmetic
```
#### Plots 3D
```python
# Superficie 3D
plot3d(x**2 + y**2, (x, -5, 5), (y, -5, 5))
# Con funciones trigonométricas
plot3d(sin(x)*cos(y), (x, 0, 2*pi), (y, 0, 2*pi))
# Con objetos tipados
plot3d(16#x + 16#y, (x, 0, 255), (y, 0, 255))
```
### Resultados Interactivos
#### Elementos Clickeables
- **📊 Ver Plot**: Abre ventana matplotlib para plots
- **📋 Ver Matriz**: Muestra matriz formateada con operaciones
- **📋 Ver Lista**: Expande listas largas
- **🔍 Ver Detalles**: Información completa de objetos
#### Ejemplo de Uso
```python
# Estos resultados serán clickeables en la interfaz
Matrix([[1, 2, 3], [4, 5, 6]]) # → 📋 Ver Matriz 2×3
plot(x**2, (x, -10, 10)) # → 📊 Ver Plot
solve(x**3 - 6*x**2 + 11*x - 6, x) # → 📋 Ver Soluciones
```
## Casos de Uso Avanzados
### Análisis de Redes con Álgebra
```python
# Definir red con variables
network = 192.168.x.0 # → FourBytes simbólico
subnet_size = 2#100000000 # → IntBase('100000000', 2) = 256
# Encontrar valores específicos
solve(network + subnet_size == 192.168.5.0, x) # → x = 4
# Análisis de rangos
base_ip = 10.a.b.0
constraints = [
base_ip[1] >= 0, # a >= 0
base_ip[1] <= 255, # a <= 255
base_ip[2] >= 0, # b >= 0
base_ip[2] <= 255 # b <= 255
]
valid_ranges = solve(constraints, [a, b])
```
### Programación y Conversiones Avanzadas
```python
# Análisis de valores hex con variables
hex_pattern = 16#x0 # → IntBase simbólico
solve(hex_pattern + 16#10 == 256, x) # → x = 15 (0xF)
# Conversiones automáticas en cadena
ip = 192.168.1.1 # → FourBytes
ip_hex = ip.ToHex() # → "16#C0.16#A8.16#1.16#1"
ip_bin = ip.ToBinary() # → "2#11000000.2#10101000.2#1.2#1"
# Operaciones bit a bit con conversión automática
mask1 = 255.255.255.0 # → FourBytes
mask2 = 255.255.0.0 # → FourBytes
combined = mask1 & mask2 # → Operación bit a bit
```
### Análisis Matemático con Tipos Especializados
```python
# Función compleja con valores hex
f = sin(16#x * pi / 256) # IntBase convertido automáticamente
# Análisis completo
df_dx = diff(f, x) # Derivada
critical_points = solve(df_dx, x) # Puntos críticos
integral = integrate(f, (x, 0, 255)) # Integral en rango hex
# Visualización
plot(f, df_dx, (x, 0, 255)) # Plot función y derivada
```
### Sistemas de Ecuaciones con Redes
```python
# Sistema con direcciones IP
ip1 = 192.168.x.y
ip2 = 10.a.b.c
# Condiciones de red
ip1 + 256 = 192.168.5.10
ip2.NetworkAddress() = 10.1.0.0
# Resolver para encontrar valores válidos
solve([
ip1 + 256 - 192.168.5.10,
ip2[1] - 1, # a = 1
ip2[2] - 0 # b = 0
], [x, y, a, b, c])
```
## Sistema de Tipos Dinámico ⭐ **NUEVO**
### Auto-descubrimiento de Tipos
```python
# El sistema automáticamente descubre tipos desde custom_types/
custom_types/
├── intbase_type.py # IntBase + tokenización + registro
├── fourbytes_type.py # FourBytes + tokenización + registro
├── hex_type.py # Hex (usa IntBase)
├── bin_type.py # Bin (usa IntBase)
├── ip4_type.py # IP4 + IP4Mask (usa FourBytes)
├── chr_type.py # Chr
└── latex_type.py # LaTeX
```
### Tokenización Distribuida
Cada clase define sus propios patrones de reconocimiento:
```python
# En intbase_type.py
@staticmethod
def get_tokenization_patterns():
return [
{
'pattern': r'(\d+)#([0-9A-Fa-fx]+)',
'replacement': lambda match: f'IntBase("{match.group(2)}", {match.group(1)})',
'priority': 5,
'description': 'Números con base: 16#FF, 2#1010'
}
]
```
### Precedencia Automática
- **IntBase**: Prioridad 5 (alta) - patrón muy específico
- **FourBytes**: Prioridad 10 (media) - patrón más general
- Sistema ordena automáticamente por especificidad
### Información de Tipos
Use **Menú Tipos → Información de tipos** para ver tipos descubiertos automáticamente.
## Interfaz de Usuario
### Paneles
- **Panel Izquierdo**: Entrada de código
- **Panel Derecho**: Resultados con colores y elementos interactivos
### Sistema de Ayuda Dinámico
- **Helpers auto-descubiertos**: Cada tipo define su ayuda contextual
- **Autocompletado inteligente**: Escribir `.` muestra métodos del objeto
- **PopupFunctionList**: Lista de métodos disponibles por tipo
### Menús Actualizados
- **Archivo**: Nuevo, Cargar, Guardar
- **Editar**: Limpiar entrada/salida, Limpiar historial
- **Configuración**: Modo simbólico, Recargar tipos personalizados
- **Tipos**: Información de tipos, Sintaxis de tipos ⭐ **NUEVO**
- **Ayuda**: Guías, sintaxis, funciones SymPy
### Autocompletado Avanzado
```python
# Ejemplos de autocompletado tras punto:
192.168.1.1. # → Métodos de FourBytes
16#FF. # → Métodos de IntBase
IP4(10.1.1.1). # → Métodos de IP4
Matrix([[1,2]]). # → Métodos de SymPy Matrix
```
## Configuración y Personalización
### Archivos de Configuración
- **`hybrid_calc_settings.json`**: Configuración de ventana y UI
- **`hybrid_calc_history.txt`**: Historial de sesión anterior
- **`logs/`**: Archivos de log para debugging
### Modo Simbólico Configurable
- **Resultado simbólico**: Siempre disponible
- **Aproximación numérica**: Configurable (mostrar/ocultar)
- **Fracciones simbólicas**: Mantener como fracción vs decimal
- **Auto-simplificación**: Activar/desactivar
## Resolución de Problemas
### Errores Comunes
#### Dependencias Faltantes
```bash
# Error: ModuleNotFoundError: No module named 'sympy'
pip install sympy matplotlib numpy
# Linux: tkinter no disponible
sudo apt-get install python3-tk
```
#### Problemas de Tokenización
```python
# Problema: Pattern no reconocido
192.168.1 # No es x.x.x.x completo, no se tokeniza
# Solución: Usar patrón completo
192.168.1.1 # → FourBytes automático
# Verificar tipos cargados
# Menú Tipos → Información de tipos
```
#### Problemas de Variables
```python
# Las variables son símbolos automáticamente
x = 5 # → x es Symbol('x') con valor 5, no variable Python
y = x + 2 # → y es Symbol('x') + 2, evaluado como 7
# Con objetos tipados
ip = 10.x.1.1 # → FourBytes simbólico
ip.substitute(x=5) # → FourBytes('10.5.1.1')
```
### Performance
#### Optimizaciones Implementadas
- **Contexto limpio**: Cada evaluación es independiente y predecible
- **Tokenización cacheada**: Patrones frecuentes se cachean
- **Evaluación lazy**: `evalf()` solo cuando se muestra resultado
- **Auto-descubrimiento optimizado**: Una sola carga al inicio
#### Límites Conocidos
- Sistemas de ecuaciones muy grandes pueden ser lentos
- Plots 3D complejos requieren tiempo de renderizado
- Matrices muy grandes pueden consumir memoria
- Objetos simbólicos complejos necesitan más tiempo de evaluación
### Debugging del Sistema de Tipos
#### Verificación de Auto-descubrimiento
```python
# En código o logs
print(f"Tipos descubiertos: {len(registered_classes)}")
print(f"Reglas de tokenización: {len(tokenization_rules)}")
# En interfaz
# Menú Tipos → Información de tipos
```
#### Recarga de Tipos en Desarrollo
```python
# Para desarrollo en tiempo real
# Menú Configuración → Recargar Tipos Personalizados
# O reiniciar aplicación para cambios en custom_types/
```
## Desarrollo y Extensión
### Estructura Actual del Proyecto
```
calculadora-mav-cas/
├── calc.py # Launcher principal
├── main_calc_app.py # Aplicación principal
├── main_evaluation.py # Motor CAS híbrido
├── type_registry.py # Auto-descubrimiento de tipos ⭐
├── tl_bracket_parser.py # Tokenizador universal ⭐
├── tl_popup.py # Resultados interactivos
├── class_base.py # Clases base
├── sympy_Base.py # Base para integración SymPy
├── sympy_helper.py # Helpers para SymPy
├── custom_types/ # ⭐ Sistema de tipos unificado
│ ├── intbase_type.py # IntBase + tokenización
│ ├── fourbytes_type.py # FourBytes + tokenización
│ ├── hex_type.py # Hex (usa IntBase)
│ ├── bin_type.py # Bin (usa IntBase)
│ ├── ip4_type.py # IP4 + IP4Mask (usa FourBytes)
│ ├── chr_type.py # Chr
│ └── latex_type.py # LaTeX
├── logs/ # Logs de debugging
└── docs/ # Documentación técnica
```
### Agregar Nuevos Tipos ⭐ **SIMPLIFICADO**
#### 1. Crear Archivo en `custom_types/`
```python
# custom_types/ejemplo_type.py
from class_base import ClassBase
import re
class Class_Ejemplo(ClassBase):
def __init__(self, value_input):
# Procesar entrada
super().__init__(processed_value, original_str)
@staticmethod
def get_tokenization_patterns():
"""Define cómo reconocer y tokenizar este tipo"""
return [
{
'pattern': r'@([a-zA-Z0-9_]+)',
'replacement': lambda match: f'Ejemplo("{match.group(1)}")',
'priority': 8,
'description': 'Patrones @ejemplo'
}
]
@staticmethod
def Helper(input_str):
if re.match(r"^\s*@\w+", input_str):
return "Ej: @usuario, @sistema. Funciones: .validate(), .expand()"
return None
@staticmethod
def PopupFunctionList():
return [
("validate", "Valida formato del ejemplo"),
("expand", "Expande el valor del ejemplo")
]
def register_classes_in_module():
return [
("Ejemplo", Class_Ejemplo, "ClassBase", {
"add_lowercase": True,
"supports_brackets": False,
"has_tokenization": True,
"description": "Ejemplos con @patron"
})
]
```
#### 2. Usar Automáticamente
```python
# Después de crear el archivo, automáticamente funciona:
@usuario # → Ejemplo('usuario')
@sistema.validate() # → Autocompletado disponible
```
### Tokenización Personalizada Avanzada
#### Múltiples Patrones por Tipo
```python
@staticmethod
def get_tokenization_patterns():
return [
{
'pattern': r'([0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2})',
'replacement': lambda match: f'MAC("{match.group(1)}", format="colon")',
'priority': 6,
'description': 'MAC con dos puntos: AA:BB:CC:DD:EE:FF'
},
{
'pattern': r'([0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2})',
'replacement': lambda match: f'MAC("{match.group(1)}", format="dash")',
'priority': 6,
'description': 'MAC con guiones: AA-BB-CC-DD-EE-FF'
}
]
```
### Herencia de Tipos Base
#### Usar IntBase para Nuevas Bases
```python
# custom_types/octal_type.py
from sympy_Base import SympyClassBase
class Class_Octal(SympyClassBase):
def __init__(self, value_input):
# Obtener IntBase dinámicamente del registro
IntBase = get_intbase_class()
if isinstance(value_input, IntBase):
if value_input.base == 8:
self.int_base = value_input
else:
# Convertir a octal
octal_value = IntBase._convert_to_base_string(value_input._numeric_value, 8)
self.int_base = IntBase(octal_value, 8)
super().__init__(self.int_base.value, str(self.int_base))
# Automáticamente disponible: 8#777 → IntBase, Octal(8#777) → Class_Octal
```
## Changelog
### Versión 2.1 (Sistema de Tipos Dinámico) ⭐ **ACTUAL**
- ✅ **Tokenización automática**: Patrones `16#FF` y `192.168.1.1` convertidos automáticamente
- ✅ **Sistema de tipos dinámico**: Auto-descubrimiento desde `custom_types/`
- ✅ **Clases base universales**: IntBase y FourBytes como tipos fundamentales
- ✅ **Tokenización distribuida**: Cada clase define sus propios patrones
- ✅ **Parser genérico**: Sin hardcoding de tipos específicos
- ✅ **Conversión perezosa a SymPy**: Objetos nativos hasta que se necesite álgebra
- ✅ **Helpers dinámicos**: Sistema de ayuda contextual auto-descubierto
- ✅ **Aritmética nativa**: Operaciones que preservan tipos originales
### Versión 2.0 (CAS Híbrido) - **ANTERIOR**
- ✅ Motor SymPy completo como base
- ❌ ~~Sintaxis con corchetes únicamente~~ **ELIMINADO**
- ✅ Detección automática de ecuaciones
- ✅ Variables SymPy puras
- ✅ Resultados interactivos clickeables
- ✅ Sistema de plotting integrado
- ✅ Arquitectura modular extensible
### Diferencias vs Versión Anterior
| Característica | v2.0 | v2.1 |
|---|---|---|
| Sintaxis | `Class[args]` | Tokenización automática |
| Tipos | Hardcodeados | Auto-descubrimiento |
| Parser | Específico | Genérico distribuido |
| Extensibilidad | Manual | Automática |
| Aritmética | SymPy siempre | Nativa + SymPy cuando se necesite |
| Tokenización | Centralizada | Distribuida por clase |
## FAQ
### ¿Cómo funciona la tokenización automática?
El sistema reconoce patrones como `16#FF` y `192.168.1.1` automáticamente y los convierte en objetos `IntBase` y `FourBytes` respectivamente. No necesita sintaxis especial.
### ¿Puedo usar la sintaxis de corchetes?
No. La v2.1 usa tokenización automática invisible que es más natural e intuitiva.
### ¿Cómo agregar nuevos tipos?
1. Crear archivo en `custom_types/nuevo_type.py`
2. Implementar clase con `get_tokenization_patterns()` y `register_classes_in_module()`
3. El sistema lo detecta automáticamente
### ¿Los resultados son exactos?
Sí. Los objetos mantienen precisión nativa hasta que se convierten a SymPy para álgebra compleja.
### ¿Cómo funcionan las conversiones entre tipos?
Son automáticas y bidireccionales. Por ejemplo: `Hex(192.168.1.1)` convierte FourBytes a Hex automáticamente.
### ¿Puedo crear tipos que usen múltiples patrones?
Sí. Cada tipo puede definir múltiples patrones con diferentes prioridades en `get_tokenization_patterns()`.
### ¿Cómo debuggear problemas de tipos?
Use **Menú Tipos → Información de tipos** para ver tipos descubiertos y **Menú Configuración → Recargar Tipos** para desarrollo.
---
*Calculadora MAV - CAS Híbrido v2.1*
*Sistema extensible con tokenización automática para cálculo matemático avanzado*

View File

@ -1,549 +0,0 @@
# Guía de Desarrollo - Calculadora MAV CAS Híbrido
## Visión General
Este documento describe el estado actual y los objetivos de desarrollo para la **Calculadora MAV**, un **Sistema de Álgebra Computacional (CAS) híbrido**. El proyecto busca combinar la potencia de SymPy como motor algebraico central con capacidades especializadas (IP4, Hex, etc.) integradas de forma nativa.
## Objetivos Principales
### 1. **SymPy como Motor Central**
- Integrar todas las funciones de SymPy directamente
- SymPy maneja toda la evaluación algebraica y ecuaciones
- Cada linea de ingreso corresponde a una sola linea de resultados
- **CONTEXTO LIMPIO POR EVALUACIÓN**: Cada vez que se hace una evaluación se comienza con el contexto completamente limpio y se evalúa desde arriba hacia abajo, línea por línea. Esto garantiza comportamiento predecible sin "memoria" de evaluaciones anteriores.
- La interfaz de usuario se divide en 2 columnas, a la izquierda el area de ingreso de datos y equaciones a ser evaluadas, a la derecha el area de resultados que se colorean segun cada tipo de respuesta.
### 2. **Sintaxis Simplificada con Corchetes (Única)**
- Usar **exclusivamente** `Class[args]` en lugar de `Class("args")` . Cuando se usan los corchetes los parametros se separan por `;`
- Los corchetes indican parsing especial (agregar comillas automáticamente)
- Mantiene sintaxis limpia y reduce errores de tipeo
### 3. **Detección Automática y Manejo de Ecuaciones**
- Ecuaciones ingresadas directamente (ej. `3+b=5+c`) se detectan y añaden al sistema interno de SymPy.
- Soporte para comparaciones SymPy (ej. `x > 5`, `a == b`, `x <= 10`) como expresiones evaluables.
- Sintaxis de atajo para solve: `variable=?` equivale a `solve(variable)`
### 4. **Evaluación Híbrida con Variables SymPy Puras**
- Resultado simbólico (siempre disponible)
- Evaluación numérica con `.evalf()` (cuando sea aplicable y las variables estén definidas). Esta evaluacion se muestra a la derecha del resultado simbolico.
- Las asignaciones son siempre simbolicas, solo los resultados se muestra la evaluacion numerica.
- **Todas las variables son símbolos SymPy**: Sin variables Python tradicionales
- **Sin eval/exec por defecto**: Solo SymPy, a menos que se indique sintaxis especial
### 4. **Resultados Interactivos**
- **Tags clickeables** en el widget Text para resultados complejos que necesitan mas de una linea de resultado como Plot, Matrices y Listas.
- **Detección automática** de tipos que requieren visualización especial:
- Plots de SymPy → "📊 Ver Plot" (abre ventana matplotlib).
- Matrices → "📋 Ver Matriz" (muestra matriz formateada).
- Listas largas → "📋 Ver Lista" (muestra contenido expandido).
- Objetos complejos → "🔍 Ver Detalles" (representación completa).
- **Implementación simple**: Usar `text.tag_bind()` en widget existente
- **Ventanas popup** para contenido que no cabe en línea.
- **Actualización automática**: Las ventanas de plot, listas y matrices deben tener la capacidad de actualizarse automáticamente si los datos subyacentes cambian y la ventana permanece abierta.
- **Posicionamiento inteligente**:
- Cuando no hay otras ventanas de resultados (plot, lista, matriz) abiertas, la primera que se abra debe tener su altura igual a la de la ventana principal de la aplicación.
- Esta primera ventana se posicionará automáticamente a la derecha de la ventana principal de la aplicación.
### 5. **Clases Especializadas como Objetos SymPy**
- Todas las clases (IP4, Hex, Bin, etc.) heredan de `sympy.Basic`
- Participan en manipulación algebraica: `solve()`, `diff()`, `integrate()`
- Mantienen funcionalidad especializada (métodos `.NetworkAddress()`, `.toHex()`, etc.)
## Arquitectura Propuesta
### Estructura de archivos
- Subcarperta de log "/.log"
- Subcarpeta de documentos md de ayuda y documentacion tecnica "/.doc"
- Aplicacion principal launcher: main_calc.py
- Aplicacion principal app: main_calc_app.py
- Motor de evaluacion: main_evaluation.py
- Motor de ventanas emergentes: tl_popup.py
- Objetos especiales: [nombre objeto]_type.py . Ejemplo ip4_type.py
- Tools del motor: tl_[nombre tool].py . Ejemplo: tl_bracket_parser.py
### Flujo de Procesamiento
```
Entrada Usuario → [Bracket Parser] → [SymPy Evaluation] → {
1. Resultado Simbólico (siempre)
2. evalf() (si variables definidas)
3. Métodos especializados disponibles
}
```
### Transformación de Sintaxis
```python
# Clases con corchetes:
IP4[192.168.1.1/24].NetworkAddress[] → IP4("192.168.1.1/24").NetworkAddress()
# Detección contextual de ecuaciones:
3+b=5+c → Se detecta como ecuación standalone (agregar al sistema SymPy)
"x > 5" → Se procesa como desigualdad SymPy
x**2 + 2*x == 0 → Se detecta como igualdad lógica standalone
# NO se detectan como ecuaciones (parsing contextual):
solve(x + 2 = 5, x) → "=" es argumento de función, no ecuación
result = solve(a + b = 10, a) → "=" izquierdo es asignación Python
IP4[192.168.1.1].Mask() == "255.255.255.0" → Expresión de comparación
# Sintaxis de atajo para solve:
x=? → solve(x)
```
## Componentes Técnicos
### 1. **Bracket Parser y Detección Contextual de Ecuaciones**
- Preprocesador que convierte `Class[args]``Class("args")`
- La separacion de argumentos se hace con el ";"
- Soporte para clases: `IP4`, `Hex`, `Bin`, `Date`, `Dec`, `Chr`
- **Detección contextual inteligente de ecuaciones**:
- Ecuaciones standalone: `3+b=5+c` (detectar como ecuación)
- Strings con ecuaciones: `"expresión = expresión"` (detectar como ecuación)
- **NO detectar** cuando `=`, `==`, `>`, etc. están dentro de llamadas a funciones: `solve(x=5, y)`
- **NO detectar** asignaciones Python: `result = solve(...)`
- Conversión de atajo: `variable=?``solve(variable)`
- Usa AST parsing para distinguir contexto sintáctico
- Extensible para futuras transformaciones más complejas
### 2. **Clases Híbridas**
```python
class IP4(BaseCalcType, sympy.Basic):
def __new__(cls, address, mask=None):
# Crear objeto SymPy válido
obj = sympy.Basic.__new__(cls)
# Inicializar funcionalidad IP4
obj._init_ip4(address, mask)
return obj
def _sympystr(self, printer):
return f"IP4({self.address})"
```
### 3. **Sistema de Evaluación y Detección Contextual**
```python
def detect_equation_context(code_line):
"""
Usa AST para determinar si una línea contiene una ecuación standalone
vs. comparaciones dentro de funciones o asignaciones Python
"""
tree = ast.parse(code_line)
# Casos que NO son ecuaciones:
# - Asignaciones: result = solve(...)
# - Argumentos de función: solve(x = 5, y)
# - Expresiones dentro de llamadas: func(a == b)
# Casos que SÍ son ecuaciones:
# - Comparaciones standalone: x + 2 == 5
# - Strings con ecuaciones: "a = b"
return is_standalone_equation
def evaluate_expression(expr):
# 1. Detección contextual de ecuaciones
if detect_equation_context(expr):
add_to_equation_system(expr)
return "Ecuación agregada al sistema"
# 2. Evaluación simbólica (SymPy)
symbolic_result = sympy.sympify(expr)
# 3. Intentar evaluación numérica
try:
if all_variables_defined(symbolic_result):
numeric_result = symbolic_result.evalf()
else:
numeric_result = None
except:
numeric_result = None
return {
'symbolic': symbolic_result,
'numeric': numeric_result
}
```
## Capacidades Expandidas
### 1. **Funciones SymPy Completas**
```python
# Todas disponibles directamente:
diff(IP4[192.168.x.1] + offset, x)
integrate(Hex[x] * sin(x), x)
solve([IP4[192.168.x.y] == IP4[192.168.1.10]], [x, y])
limit(Dec[x]/x, x, 0)
series(exp(Hex[x]), x, 0, 5)
```
### 2. **Plotting Integrado con Interface Interactiva**
```python
# SymPy plotting nativo:
plot(sin(Hex[x]), (x, 0, 255)) # Muestra: "📊 Ver Plot" (clickeable)
plot3d(IP4[192.168.x.y].to_decimal(), (x, 1, 254), (y, 1, 254))
# Resultados complejos interactivos:
Matrix([[1, 2], [3, 4]]) # Muestra: "📋 Ver Matriz" (clickeable)
solve(x**2 + 2*x + 1, x) # Lista: "📋 Ver Soluciones" (clickeable)
```
### 3. **Manipulación Algebraica de Objetos Especializados**
```python
# Objetos especializados en expresiones algebraicas:
network = IP4[192.168.x.0/24]
solve(network.NetworkAddress() == IP4[192.168.5.0/24], x)
# Resultado: x = 5
```
## Ejemplos de Uso Objetivo
```python
# Evaluación directa con SymPy:
solve(x + 10 - 15, x) # Resultado: [5]
# Detección automática de ecuaciones:
3+b=5+c # Se agrega automáticamente al sistema
x > 5 # Desigualdad procesada por SymPy
a == b # Igualdad lógica procesada por SymPy
# Sintaxis de atajo:
x=? # Equivale a solve(x)
# Solo sintaxis con corchetes:
IP4[192.168.1.1/24].NetworkAddress[] # Resultado: 192.168.1.0/24
# Variables puras SymPy:
x = 5 # x es Symbol('x') con valor 5, no variable Python
y = x + 2 # y es expresión simbólica: Symbol('x') + 2
# Álgebra con objetos especializados:
base_ip = IP4[10.0.x.1]
solve(base_ip + 255 == IP4[10.0.5.0], x) # Resultado: x = 4
# Funciones avanzadas con resultados interactivos:
diff(Hex[x**2], x) # Derivada: 2*x*log(16)
plot(sin(2*pi*Hex[x]/256), (x, 0, 255)) # Resultado: "📊 Ver Plot"
# Matrices y estructuras complejas:
Matrix([[1, 2, 3], [4, 5, 6]]) # Resultado: "📋 Ver Matriz"
solve([x + y == 10, x - y == 2], [x, y]) # Resultado: "📋 Ver Soluciones"
# eval/exec opcional con sintaxis especial:
@eval: import os; os.getcwd() # Solo cuando se necesite Python puro
```
## Beneficios Esperados
### 1. **Usabilidad**
- Sintaxis más limpia (sin comillas constantes)
- Acceso completo a capacidades de CAS
- Evaluación automática simbólica + numérica
### 2. **Potencia Matemática**
- Todas las funciones de SymPy disponibles
- Objetos especializados participan en álgebra
- Capacidades de plotting integradas
### 3. **Extensibilidad**
- Parser extensible para futuras sintaxis
- Fácil agregar nuevas clases especializadas
- Compatible con ecosystem SymPy completo
### 4. **Consistencia**
- Un solo motor de evaluación (SymPy)
- Reglas algebraicas consistentes
- Manejo unificado de errores
## Fases de Implementación
### Fase 1: Foundation
- Implementar bracket parser básico
- Convertir clases existentes a `sympy.Basic`
- Sistema de evaluación híbrida
### Fase 2: Integration
- Remover clase `solve` separada
- Integrar todas las funciones SymPy
- Testing de manipulación algebraica
### Fase 3: Enhancement
- Capacidades de plotting
- Sintaxis extendida del parser
- Optimizaciones de performance
### Fase 4: Polish
- Documentación completa
- Ejemplos avanzados
- UI/UX improvements
## Consideraciones Adicionales
### **Performance y Caching (Crítico)**
- **Caching de líneas precedentes**: Las líneas anteriores no se recalculan
- **Incremental evaluation**: Solo evaluar líneas nuevas/modificadas
- **Caching de parsing**: Bracket parsing se cachea para expresiones repetidas
- **Lazy evalf()**: Solo evaluar numéricamente cuando se solicite mostrar
- **Optimización SymPy**: Configurar para performance en contexto interactivo
### **Manejo Robusto de Errores y Logging**
- **Logging centralizado enfocado en errores**: El sistema de logging (`main_launcher.py`) debe registrar principalmente errores para facilitar la depuración, evitando logs informativos excesivos en producción. Los logs detallados (DEBUG) pueden activarse con un flag. Solo crear un archivo de log bajo la carpeta "/.logs"
- **Errores de SymPy y del Motor CAS**: Priorizar mensajes de error claros provenientes de SymPy o del motor de evaluación.
- **Errores contextuales**: Mensajes específicos para errores de parsing vs evaluación
- **Sugerencias automáticas**: "¿Quisiste decir...?" para funciones mal escritas
- **eval/exec explícito**: Solo disponible con sintaxis especial cuando sea necesario
### **Extensibilidad del Parser**
- **Arquitectura modular**: Fácil agregar nuevas transformaciones sintácticas
- **Plugin system**: Permitir extensiones de terceros
- **Configurabilidad**: Usuario puede habilitar/deshabilitar transformaciones
### **Sistema de Ayuda Avanzado**
- **Autocompletado SymPy**: Funciones y métodos disponibles según contexto o cuando se presiona el "."
- **Help integrado**: `help(diff)` muestra documentación SymPy completa
- **Ejemplos interactivos**: Templates para operaciones comunes
- **Cheat sheet**: Referencia rápida de sintaxis nueva vs antigua
## Sistema de Autocompletado y Ayuda Contextual (Helpers)
### Objetivo
Proveer al usuario de una experiencia de ayuda y autocompletado inteligente, no invasiva y extensible, que facilite el uso de funciones avanzadas y objetos personalizados, integrando tanto métodos propios como todas las funciones de SymPy.
---
### 1. **Helpers: Ayuda Contextual por Tipo**
Cada tipo de objeto (por ejemplo, `IP4`, `Hex`, etc.) debe definir una función `Helper(input_str)` que:
- Recibe el string de entrada del usuario.
- Decide, usando su propia lógica (por ejemplo, expresiones regulares), si puede ofrecer una ayuda relevante.
- Devuelve un string de ayuda (ejemplo de uso, sintaxis, sugerencia) o `None` si no aplica.
- Las respuestas no pueden tener mas de una linea nunca.
**Ejemplo:**
```python
# En ip4_type.py
def Helper(input_str):
if re.match(r"^\s*IP4(\b|\s*\[.*)?", input_str, re.IGNORECASE):
return 'Ej: IP4[192.168.1.1/24], IP4[10.0.0.1, 8], o IP4[172.16.0.5, 255.255.0.0]'
return None
```
**Ventajas:**
- Cada Helper es autocontenido y puede evolucionar de forma independiente.
- Permite personalizar la ayuda para cada tipo de objeto o función.
---
### 2. **Helper para SymPy**
Dado que ahora todas las funciones de SymPy están disponibles, se debe agregar un Helper general para SymPy que:
- Detecte si el usuario está comenzando a escribir el nombre de una función de SymPy (por ejemplo, `diff`, `integrate`, `solve`, `limit`, etc.).
- Sugiera la sintaxis básica y ejemplos de uso para la función detectada.
- Puede usar una lista de funciones comunes de SymPy y sus descripciones.
**Ejemplo:**
```python
# En sympy_helper.py
def Helper(input_str):
sympy_funcs = {
"diff": "Derivada: diff(expr, var). Ej: diff(sin(x), x)",
"integrate": "Integral: integrate(expr, var). Ej: integrate(x**2, x)",
"solve": "Resolver ecuaciones: solve(expr, var). Ej: solve(x**2-1, x)",
"limit": "Límite: limit(expr, var, valor). Ej: limit(sin(x)/x, x, 0)",
# ...agregar más funciones comunes
}
for func, ayuda in sympy_funcs.items():
if input_str.strip().startswith(func):
return ayuda
return None
```
---
### 3. **Manejo Centralizado de Helpers**
En el motor principal de la aplicación, se debe mantener una lista de todas las funciones Helper disponibles (incluyendo la de SymPy).
Al evaluar la línea de entrada y esta da error de evaluacion entonces:
- Se llama a cada Helper en orden.
- Si alguna Helper retorna una ayuda, se muestra esa ayuda al usuario (en la línea de resultado, tooltip, etc.).
- Si ninguna Helper ayuda, se muestra el mensaje de error real.
**Ejemplo:**
```python
HELPERS = [
IP4.Helper,
Hex.Helper,
SympyHelper.Helper,
# ...otros helpers
]
def obtener_ayuda(input_str):
for helper in HELPERS:
ayuda = helper(input_str)
if ayuda:
return ayuda
return None
```
---
### 4. **Autocompletado de Métodos y Funciones (Popup tras el punto)**
- Cuando el usuario escribe un punto (`.`) después de un objeto válido, se evalúa el objeto y se obtiene la lista de métodos disponibles.
- Se muestra un popup de autocompletado con los métodos relevantes (filtrando los no útiles). La lista de funciones se debe obtener de una funcione de cada objeto llamada PopupFunctionList() esta funcion en cada objeto mantendra la lista de las funciones disponibles y una explicacion corta tipo hint. Esta funcion retorna una lista de tuplas con el nombre de la funcion y el hint.
- El usuario puede seleccionar un método con el teclado o mouse, y se inserta automáticamente (con paréntesis si corresponde).
- El popup solo aparece tras el punto, no en cada pulsación de tecla, para no ser invasivo.
**Puntos clave:**
- Priorizar métodos útiles y públicos.
- Permitir que cada tipo defina una lista de métodos sugeridos.
- Cerrar el popup fácilmente (Escape, clic fuera, etc.).
---
### 5. **Flujo de Evaluación y Ayuda**
1. El usuario escribe una línea.
2. Si presiona `.`, se muestra el popup de autocompletado de métodos.
3. Si la línea tiene error:
- Se consulta a los Helpers para mostrar ayuda contextual.
- Si ninguna Helper ayuda, se muestra el mensaje de error real.
4. Si la línea es válida, se evalúa normalmente.
---
### 6. **Extensibilidad**
- Para agregar ayuda para un nuevo tipo, solo se debe definir un nuevo Helper y registrarlo en la lista central.
- El Helper de SymPy puede expandirse para cubrir más funciones y ejemplos.
- El sistema de autocompletado puede ampliarse para sugerir funciones de SymPy al escribir el nombre de la función (no solo tras el punto).
---
### 7. **Resumen de Beneficios**
- **No invasivo:** El autocompletado solo aparece cuando el usuario lo solicita (tras el punto).
- **Ayuda contextual:** Los Helpers ofrecen ayuda específica y relevante según el contexto.
- **Extensible:** Fácil de agregar nuevos tipos y funciones de ayuda.
- **Consistente:** El usuario recibe ayuda o autocompletado solo cuando es útil, no en cada pulsación.
---
### 8. **Ejemplo de Integración**
```python
# En el motor principal:
ayuda = obtener_ayuda(linea_usuario)
if ayuda:
mostrar_ayuda(ayuda)
elif error:
mostrar_error(error)
else:
mostrar_resultado(resultado)
```
---
**Este sistema permite que la ayuda y el autocompletado evolucionen de forma incremental, mejorando la experiencia del usuario sin ser molestos ni invasivos.**
### **Gestión de Variables Puras SymPy**
- **Solo símbolos SymPy**: Todas las variables son `Symbol()` automáticamente
- **Sin variables Python**: Eliminación de `eval()` como mecanismo por defecto
- **Evaluación consistente**: `x = 5` crea `Symbol('x')` con valor 5 en contexto
- **eval/exec opcional**: Solo disponible con sintaxis especial (ej: `@eval: código_python`)
- **Contexto unificado**: Un solo namespace SymPy para toda la sesión
### **Comportamiento de Contexto Limpio (IMPLEMENTADO)**
**Principio fundamental**: Cada modificación del usuario resulta en una evaluación completa desde cero.
#### Implementación
- **Limpieza automática**: Cada evaluación inicia con `engine.clear_all()`
- **Construcción incremental**: El contexto se construye línea por línea, de arriba hacia abajo
- **Sin persistencia**: No hay variables "fantasma" de evaluaciones anteriores
- **Predictibilidad total**: El primer `x` en cualquier secuencia siempre es un símbolo puro
- **Evaluación inicial del historial**: Al cargar la aplicación, se evalúa el historial una vez para mostrar resultados
#### Ejemplo de Comportamiento
```python
# Primera evaluación: solo "x"
x # → Symbol('x') puro, sin valor
# Segunda evaluación: "x, x=1"
x # → Symbol('x') puro (contexto limpio)
x=1 # → Asigna x=1
# Tercera evaluación: "x, x=1, y+x"
x # → Symbol('x') puro (contexto limpio)
x=1 # → Asigna x=1
y+x # → y + 1 (usa x=1 definido arriba)
```
#### Implicaciones para el Desarrollo
- **No necesidad de gestión manual de contexto**: El sistema lo maneja automáticamente
- **Comportamiento determinista**: Misma entrada → mismo resultado, siempre
- **Simplicidad de debugging**: El estado siempre es predecible
- **Eliminación de opciones de menú obsoletas**: "Limpiar variables/ecuaciones" no tienen sentido
#### Cambios en la Interfaz de Usuario
**Opciones ELIMINADAS (redundantes):**
- Menú CAS completo (variables, ecuaciones, resolver sistema)
- "Limpiar variables", "Limpiar ecuaciones", "Limpiar todo"
**Opciones CONSERVADAS (útiles):**
- "Limpiar entrada/salida" (afecta interfaz visual)
- "Limpiar historial" (afecta archivo persistente)
## Métricas de Éxito
- [X] Sintaxis `Class[args]` funciona consistentemente (`bracket_parser.py`, `hybrid_base_types.py`).
- [+] **Detección contextual inteligente de ecuaciones (Motor CAS/Parser):**
- [+] Ecuaciones standalone: `3+b=5+c`, `x**2 == 0` se detectan y añaden al sistema (`bracket_parser.py`, `hybrid_evaluation_engine.py`). `x**2==0` se evalúa como expresión booleana, no se añade como ecuación al sistema automáticamente.
- [ ] _(Parser)_ Strings con ecuaciones: `"a=b"`, `"x>5"` se procesan como ecuaciones (actualmente el parser maneja `a=b` directo, no como string literal).
- [+] **NO detectar** comparaciones en argumentos: `solve(x=5, y)`, `func(a==b)` (AST en `bracket_parser.py` ayuda, `EquationDetector` es un prototipo).
- [X] **NO detectar** asignaciones Python: `result = solve(...)` (`bracket_parser.py` lo maneja).
- [X] Sintaxis de atajo `variable=?` funciona como `solve(variable)` (`bracket_parser.py`).
- [+] Todas las funciones SymPy disponibles en interfaz (`hybrid_evaluation_engine.py` tiene contexto base amplio; `hybrid_calc_app.py` expone algunas en menús).
- [+] Objetos especializados participan en `solve()`, `diff()`, etc. (`hybrid_base_types.py` heredan de `sympy.Basic`; la profundidad de integración en operaciones aritméticas necesita revisión para preservar el tipo).
- [X] Evaluación híbrida (simbólica + numérica) automática (`hybrid_evaluation_engine.py`).
- [+] Plotting funcional con objetos especializados (Infraestructura en `hybrid_evaluation_engine.py` y `interactive_results.py`; depende de la convertibilidad del objeto a datos ploteables).
- [+] **Resultados interactivos funcionando:**
- [X] Implementación de ventanas popup (Toplevel) para mostrar información detallada (ej. diálogo de error, plots, matrices, listas en `main_launcher.py`, `interactive_results.py`).
- [X] Tags clickeables en el widget Text para resultados complejos (`hybrid_calc_app.py`, `interactive_results.py`).
- [+] Detección automática de tipos para visualización especial:
- [X] Plots de SymPy → "📊 Ver Plot" (`interactive_results.py`).
- [X] Matrices → "📋 Ver Matriz" (`interactive_results.py`).
- [X] Listas largas → "📋 Ver Lista" (`interactive_results.py`).
- [ ] _(UI/Engine)_ Objetos complejos → "🔍 Ver Detalles" (Infraestructura parcial, no implementado genéricamente).
- [ ] _(UI)_ Ventanas de plot/lista/matriz con actualización automática si se mantienen abiertas.
- [+] _(UI)_ Posicionamiento y dimensionamiento inteligente de la primera ventana de plot/lista/matriz (`interactive_results.py` tiene base, necesita lógica de "solo si no hay otras abiertas" y ajuste de altura).
- [+] Performance aceptable para uso interactivo (Debounce en `hybrid_calc_app.py` ayuda).
- [+] **Sistema de ayuda avanzado:**
- [X] Ayuda básica por línea de comandos (`main_launcher.py`).
- [ ] _(UI)_ Autocompletado para funciones SymPy y métodos de objetos (`hybrid_calc_app.py` tiene TODO).
- [+] _(Engine/UI)_ `help()` integrado con documentación SymPy (`hybrid_evaluation_engine.py` tiene base, `hybrid_calc_app.py` tiene menús estáticos).
- [+] _(UI)_ Ejemplos y templates interactivos (`hybrid_calc_app.py` tiene `insert_example`).
- [X] **Manejo robusto de errores y logging (Launcher):**
- [X] Logging centralizado de errores (`main_launcher.py`, configurable para ser error-only).
- [X] Presentación de errores al usuario en ventana dedicada (`main_launcher.py`).
- [X] Verificación de dependencias y archivos de la aplicación al inicio (`main_launcher.py`).
- [X] Intento de instalación automática de dependencias (`main_launcher.py`).
- [X] Provisión de comandos para troubleshooting (`main_launcher.py`).
- [+] **Manejo robusto de errores (Motor CAS):**
- [+] Solo errores de SymPy, sin fallbacks automáticos a eval/exec (Motor (`hybrid_evaluation_engine.py`) usa `eval` y `sympify`; se busca minimizar `eval` directo de input de usuario).
- [+] Errores contextuales: mensajes específicos para errores de parsing vs. evaluación (`EvaluationResult` tiene campo de error).
- [ ] _(Engine)_ Sugerencias automáticas: "¿Quisiste decir...?" para funciones mal escritas.
- [ ] _(Engine/Parser)_ `eval/exec` explícito: solo disponible con sintaxis especial (ej. `@eval:`) (Planeado, no implementado).
- [ ] **Performance optimizada (Motor CAS):**
- [ ] Caching de expresiones repetidas
- [ ] Evaluación lazy de `evalf()`
- [ ] Tiempo de respuesta < 200ms para operaciones comunes
- [+] **Parser extensible** con arquitectura modular (`bracket_parser.py` es un buen inicio).
- [+] **Documentación y ejemplos completos:**
- [X] Docstrings en el código (`main_launcher.py`, `hybrid_evaluation_engine.py`, etc.).
- [X] Guía de Desarrollo (este documento).
- [X] Splash screen eliminado (`main_launcher.py`).
- [+] Documentación de usuario final completa (`comprehensive_documentation.md` es una base sólida).
- [+] Ejemplos de uso avanzados en la documentación (`comprehensive_documentation.md`).

File diff suppressed because it is too large Load Diff

View File

@ -1,469 +0,0 @@
# Calculadora MAV - CAS Híbrido
## Descripción General
La Calculadora MAV es un **Sistema de Álgebra Computacional (CAS) Híbrido** que combina la potencia de SymPy con clases especializadas para networking, programación y análisis numérico.
### Características Principales
- **Motor SymPy completo**: Todas las funciones de cálculo simbólico
- **Sintaxis simplificada**: `Class[args]` en lugar de `Class("args")`
- **Detección automática de ecuaciones**: Sin necesidad de comillas especiales
- **Resultados interactivos**: Plots, matrices y listas clickeables
- **Clases especializadas**: IP4, Hex, Bin, Date, Dec, Chr
- **Variables SymPy puras**: Todas las variables son símbolos automáticamente
## Instalación
### Método 1: Instalación Automática
```bash
python launcher.py --setup
```
### Método 2: Instalación Manual
```bash
# Instalar dependencias
pip install sympy matplotlib numpy
# En Linux: instalar tkinter
sudo apt-get install python3-tk
# Ejecutar tests (opcional)
python test_suite.py
# Iniciar aplicación
python launcher.py
```
### Dependencias Requeridas
- **Python 3.8+**
- **SymPy ≥ 1.12** (motor algebraico)
- **Matplotlib ≥ 3.7.0** (plotting)
- **NumPy ≥ 1.24.0** (cálculos numéricos)
- **Tkinter** (interfaz gráfica, incluido con Python)
### Dependencias Opcionales
- **Markdown ≥ 3.4.0** (ayuda mejorada)
- **pytest ≥ 7.0.0** (testing)
## Guía de Uso
### Sintaxis Básica
#### Clases Especializadas (Solo Corchetes)
```python
# Direcciones IP con funcionalidad de red
IP4[192.168.1.100/24]
IP4[10.0.0.1, 8]
IP4[172.16.0.5, 255.255.0.0]
# Números en diferentes bases
Hex[FF] # Hexadecimal: 0xFF
Bin[1010] # Binario: 0b1010
Dec[10.5] # Decimal: 10.5
# Caracteres ASCII
Chr[A] # Carácter único: 'A' (ASCII 65)
Chr[Hello] # String: 'Hello'
```
#### Métodos de Clases Especializadas
```python
# Métodos de IP4
ip = IP4[192.168.1.100/24]
ip.NetworkAddress[] # 192.168.1.0/24
ip.BroadcastAddress[] # 192.168.1.255/24
ip.Nodes() # 254 (hosts disponibles)
# Conversiones
Hex[255].toDecimal() # 255
Dec[66].toChr() # Chr('B')
```
### Ecuaciones y Álgebra
#### Detección Automática de Ecuaciones
```python
# Ecuaciones simples (detectadas automáticamente)
x + 2 = 5
3*a + b = 10
y**2 = 16
# Desigualdades
x > 5
a <= 10
b != 0
# Ecuaciones complejas
sin(x) = 1/2
log(y) + 3 = 5
```
#### Resolución de Ecuaciones
```python
# Resolver ecuación específica
solve(x**2 + 2*x - 8, x) # [-4, 2]
# Atajo para resolver variable
x=? # Equivale a solve(x)
# Resolver sistema de ecuaciones
x + y = 10
x - y = 2
solve([x + y - 10, x - y - 2], [x, y]) # {x: 6, y: 4}
```
### Variables y Símbolos
#### Variables SymPy Automáticas
```python
# Todas las variables son símbolos SymPy automáticamente
x + 2*y # Expresión simbólica
z = 5 # z es Symbol('z') con valor 5
w = z**2 + 3 # w es expresión: Symbol('z')**2 + 3
# Evaluación automática cuando es posible
a = 10
b = a + 5 # b = 15 (evaluado)
c = a + x # c = 10 + x (simbólico)
```
### Funciones Matemáticas
#### Cálculo Diferencial e Integral
```python
# Derivadas
diff(x**3, x) # 3*x**2
diff(sin(x)*cos(x), x) # -sin(x)**2 + cos(x)**2
# Integrales
integrate(x**2, x) # x**3/3
integrate(sin(x), (x, 0, pi)) # 2
# Límites
limit(sin(x)/x, x, 0) # 1
# Series de Taylor
series(exp(x), x, 0, 5) # 1 + x + x**2/2 + x**3/6 + x**4/24 + O(x**5)
```
#### Funciones Trigonométricas
```python
# Funciones básicas
sin(pi/2) # 1
cos(0) # 1
tan(pi/4) # 1
# Funciones inversas
asin(1) # pi/2
acos(0) # pi/2
atan(1) # pi/4
# Funciones hiperbólicas
sinh(0) # 0
cosh(0) # 1
tanh(0) # 0
```
#### Álgebra y Simplificación
```python
# Simplificación
simplify((x**2 - 1)/(x - 1)) # x + 1
expand((x + 1)**3) # x**3 + 3*x**2 + 3*x + 1
factor(x**2 - 1) # (x - 1)*(x + 1)
# Manipulación de expresiones
collect(x**2 + 2*x + x**2, x) # 2*x**2 + 2*x
cancel((x**2 - 1)/(x - 1)) # x + 1
```
### Álgebra Lineal
#### Matrices
```python
# Crear matrices
M = Matrix([[1, 2], [3, 4]])
N = Matrix([[5, 6], [7, 8]])
# Operaciones básicas
M + N # Suma de matrices
M * N # Multiplicación
M**2 # Potencia
# Propiedades (clickeables en interfaz)
det(M) # Determinante: -2
inv(M) # Matriz inversa
M.transpose() # Transpuesta
```
### Plotting Interactivo
#### Plots 2D
```python
# Plot básico
plot(sin(x), (x, -2*pi, 2*pi))
# Múltiples funciones
plot(sin(x), cos(x), (x, 0, 2*pi))
# Plot con clases especializadas
plot(Hex[x]/256, (x, 0, 255))
```
#### Plots 3D
```python
# Superficie 3D
plot3d(x**2 + y**2, (x, -5, 5), (y, -5, 5))
# Con funciones trigonométricas
plot3d(sin(x)*cos(y), (x, 0, 2*pi), (y, 0, 2*pi))
```
### Resultados Interactivos
#### Elementos Clickeables
- **📊 Ver Plot**: Abre ventana matplotlib para plots
- **📋 Ver Matriz**: Muestra matriz formateada con operaciones
- **📋 Ver Lista**: Expande listas largas
- **🔍 Ver Detalles**: Información completa de objetos
#### Ejemplo de Uso
```python
# Estos resultados serán clickeables en la interfaz
Matrix([[1, 2, 3], [4, 5, 6]]) # 📋 Ver Matriz 2×3
plot(x**2, (x, -10, 10)) # 📊 Ver Plot
solve(x**3 - 6*x**2 + 11*x - 6, x) # 📋 Ver Soluciones
```
## Casos de Uso Avanzados
### Análisis de Redes
```python
# Definir red
network = IP4[192.168.0.0/24]
host = IP4[192.168.0.100/24]
# Análisis
network.Nodes() # 254 hosts disponibles
host.NetworkAddress[] # 192.168.0.0/24
host.BroadcastAddress[] # 192.168.0.255/24
# Cálculos con variables
base_ip = IP4[10.0.x.0/24]
solve(base_ip.Nodes() == 254, x) # Encuentra x para 254 hosts
```
### Programación y Conversiones
```python
# Conversiones entre bases
hex_val = Hex[FF] # 255 en decimal
bin_val = Bin[hex_val] # Convertir a binario
chr_val = Chr[hex_val] # Carácter ASCII
# Análisis de caracteres
text = Chr[Hello World]
ascii_values = text.value # Lista de valores ASCII
# Operaciones bit a bit (con SymPy)
a = Hex[F0]
b = Hex[0F]
a | b # OR bit a bit
a & b # AND bit a bit
a ^ b # XOR bit a bit
```
### Análisis Matemático Completo
```python
# Definir función compleja
f = sin(x) * exp(-x**2/2)
# Análisis completo
df_dx = diff(f, x) # Derivada
critical_points = solve(df_dx, x) # Puntos críticos
integral = integrate(f, (x, -oo, oo)) # Integral impropia
# Visualización
plot(f, df_dx, (x, -3, 3)) # Plot función y derivada
# Serie de Taylor en punto específico
taylor_series = series(f, x, 0, 6) # Serie alrededor de x=0
```
### Resolución de Sistemas Complejos
```python
# Sistema de ecuaciones no lineales
x**2 + y**2 = 25
x*y = 12
# Resolver
solutions = solve([x**2 + y**2 - 25, x*y - 12], [x, y])
# Análisis paramétrico
# Ecuación con parámetro
a*x**2 + b*x + c = 0
# Resolver para diferentes valores
a_val = 1
b_val = 2
c_val = -3
solve(a_val*x**2 + b_val*x + c_val, x)
```
## Interfaz de Usuario
### Paneles
- **Panel Izquierdo**: Entrada de código
- **Panel Derecho**: Resultados con colores y elementos interactivos
### Menús
- **Archivo**: Nuevo, Cargar, Guardar
- **Editar**: Limpiar, operaciones de texto
- **CAS**: Mostrar variables/ecuaciones, resolver sistema
- **Ayuda**: Guías, sintaxis, funciones SymPy
### Atajos de Teclado
- **Ctrl+S**: Guardar archivo
- **Ctrl+O**: Abrir archivo
- **Ctrl+N**: Nueva sesión
- **F1**: Ayuda rápida
### Menú Contextual (Clic Derecho)
- **Panel Entrada**: Cortar, Copiar, Pegar, Insertar ejemplo
- **Panel Salida**: Copiar todo, Limpiar salida
## Configuración y Personalización
### Archivos de Configuración
- **`hybrid_calc_settings.json`**: Configuración de ventana y UI
- **`hybrid_calc_history.txt`**: Historial de sesión anterior
### Variables de Entorno
- **`PYTHONPATH`**: Asegurar que módulos sean encontrados
- **`MPLBACKEND`**: Backend de matplotlib (ej: `TkAgg`)
## Resolución de Problemas
### Errores Comunes
#### Dependencias Faltantes
```bash
# Error: ModuleNotFoundError: No module named 'sympy'
pip install sympy matplotlib numpy
# Linux: tkinter no disponible
sudo apt-get install python3-tk
```
#### Errores de Sintaxis
```python
# Incorrecto: sintaxis antigua
IP4("192.168.1.1/24")
# Correcto: nueva sintaxis
IP4[192.168.1.1/24]
```
#### Problemas de Variables
```python
# Las variables son símbolos automáticamente
x = 5 # x es Symbol('x') con valor 5, no variable Python
y = x + 2 # y es Symbol('x') + 2, evaluado como 7
# Para variables Python tradicionales, usar eval explícito:
@eval: python_var = 5 # Sintaxis especial (si implementada)
```
### Performance
#### Optimizaciones
- Las líneas anteriores se cachean (no se re-evalúan)
- Parsing de corchetes se cachea para expresiones repetidas
- `evalf()` es lazy (solo cuando se muestra resultado)
#### Límites Conocidos
- Sistemas de ecuaciones muy grandes pueden ser lentos
- Plots 3D complejos requieren tiempo de renderizado
- Matrices muy grandes pueden consumir memoria
## Desarrollo y Extensión
### Estructura del Proyecto
```
calculadora-mav-cas/
├── launcher.py # Launcher principal
├── setup.py # Script de instalación
├── test_suite.py # Tests unitarios
├── requirements.txt # Dependencias
├── bracket_parser.py # Parser de sintaxis
├── hybrid_base_types.py # Clases especializadas
├── hybrid_evaluation_engine.py # Motor CAS
├── interactive_results.py # Resultados clickeables
└── hybrid_calc_app.py # Aplicación principal
```
### Agregar Nuevas Clases
```python
# En hybrid_base_types.py
class HybridNewType(HybridCalcType):
def __new__(cls, value_input):
obj = HybridCalcType.__new__(cls)
return obj
def __init__(self, value_input):
# Procesar entrada
super().__init__(processed_value, original_str)
def specialized_method(self):
# Funcionalidad específica
pass
```
### Extender Parser
```python
# En bracket_parser.py
class BracketParser:
BRACKET_CLASSES = {'IP4', 'Hex', 'Bin', 'Date', 'Dec', 'Chr', 'NewType'}
```
## Changelog
### Versión 2.0 (CAS Híbrido)
- ✅ Motor SymPy completo como base
- ✅ Sintaxis con corchetes únicamente
- ✅ Detección automática de ecuaciones
- ✅ Variables SymPy puras
- ✅ Resultados interactivos clickeables
- ✅ Sistema de plotting integrado
- ✅ Arquitectura modular extensible
### Diferencias vs Versión 1.0
| Característica | v1.0 | v2.0 |
|---|---|---|
| Motor | Python eval/exec | SymPy completo |
| Sintaxis | `Class("args")` | `Class[args]` |
| Ecuaciones | `"x + 2 = 5"` | `x + 2 = 5` (automático) |
| Variables | Python mixto | SymPy puro |
| Resultados | Texto plano | Interactivos clickeables |
| Funciones | Básicas math | SymPy completo |
## FAQ
### ¿Puedo usar la sintaxis antigua?
No. La v2.0 usa exclusivamente sintaxis con corchetes para consistencia y simplicidad.
### ¿Cómo evalúo código Python tradicional?
Todas las operaciones se manejan con SymPy. Para casos especiales, se puede implementar sintaxis `@eval:` en futuras versiones.
### ¿Los resultados son exactos?
Sí. SymPy maneja aritmética exacta por defecto. Use `.evalf()` para aproximaciones decimales.
### ¿Puedo crear plots personalizados?
Sí. Los resultados de `plot()` son clickeables y abren matplotlib completo con opciones de personalización.
### ¿Cómo reportar bugs?
Ejecute `python test_suite.py` para diagnosticar problemas y reporte cualquier test que falle.
---
*Calculadora MAV - CAS Híbrido v2.0*
*Desarrollado para cálculo matemático avanzado con soporte especializado*

View File

@ -1,160 +0,0 @@
# Correcciones Implementadas - CAS Híbrido
## 🔧 Problemas Identificados y Solucionados
### 1. **Operaciones Aritméticas con Clases Híbridas**
**Problema:** `Error: unsupported operand type(s) for +: 'HybridHex' and 'One'`
**Solución:**
- ✅ Implementados métodos mágicos de SymPy en `HybridCalcType`
- ✅ Agregados `__add__`, `__mul__`, `__sub__`, `__truediv__`, `__pow__`
- ✅ Integración completa con operaciones SymPy
```python
# Ahora funciona:
Hex[FF] + 1 # Retorna expresión SymPy válida
Bin[1010] * 2 # Multiplicación correcta
```
### 2. **Parser de Corchetes - Métodos Vacíos**
**Problema:** `IP4("192.168.1.100/24").NetworkAddress[]` no parseaba correctamente
**Solución:**
- ✅ Agregado patrón para `método[]``método()`
- ✅ Expresión regular mejorada para corchetes vacíos
```python
# Ahora funciona:
IP4[192.168.1.100/24].NetworkAddress[] # → IP4("192.168.1.100/24").NetworkAddress()
```
### 3. **Asignaciones de Variables**
**Problema:** SymPy no puede parsear `z = 5` directamente
**Solución:**
- ✅ Detección automática de asignaciones en parser
- ✅ Función especial `_assign_variable()` en motor
- ✅ Integración con tabla de símbolos
```python
# Ahora funciona:
z = 5 # Detectado como asignación
w = z**2 + 3 # Evaluación correcta
```
### 4. **Integración SymPy Mejorada**
**Problema:** Conflictos entre evaluación SymPy y clases especializadas
**Solución:**
- ✅ Evaluación híbrida: SymPy primero, fallback a eval
- ✅ Manejo de contexto mejorado
- ✅ Propiedades SymPy implementadas en clases base
## 🧪 Verificar Correcciones
### Ejecutar Tests de Debug
```bash
python debug_and_test.py
```
### Ejecutar Ejemplos Corregidos
```bash
python launcher.py
# Luego pegar el contenido de corrected_examples.py
```
### Verificar Suite Completa
```bash
python test_suite.py
```
## 📋 Resultados Esperados
### Antes (Errores)
```
Hex[FF] + 1 → Error: unsupported operand type(s)
IP4[...].NetworkAddress[] → SyntaxError: invalid syntax
z = 5 → SyntaxError: invalid syntax
```
### Después (Correcto)
```
Hex[FF] + 1 → 256 (o expresión SymPy equivalente)
IP4[192.168.1.100/24].NetworkAddress[] → 192.168.1.0/24
z = 5 → z = 5 (variable asignada)
w = z**2 + 3 → w = 28 (evaluado)
```
## 🔍 Cambios Técnicos Específicos
### En `bracket_parser.py`
- ✅ Método `_is_assignment()` para detectar asignaciones
- ✅ Método `_transform_assignment()` para convertir a función especial
- ✅ Patrón regex para `método[]``método()`
### En `hybrid_base_types.py`
- ✅ Métodos mágicos completos en `HybridCalcType`
- ✅ Propiedades SymPy: `is_number`, `is_real`, `is_integer`
- ✅ Método `_eval_evalf()` para evaluación numérica
### En `hybrid_evaluation_engine.py`
- ✅ Función `_assign_variable()` para manejar asignaciones
- ✅ Método `_evaluate_assignment()` para procesar asignaciones
- ✅ Evaluación híbrida mejorada en `_eval_in_context()`
### En `hybrid_calc_app.py`
- ✅ Manejo de resultado tipo "assignment"
- ✅ Tag de color "info" para asignaciones
## 🚨 Problemas Conocidos y Limitaciones
### Limitaciones Actuales
1. **Operaciones complejas**: Algunas operaciones muy complejas pueden requerir evaluación manual
2. **Performance**: Evaluación híbrida puede ser más lenta que SymPy puro
3. **Compatibilidad**: Algunas funciones SymPy avanzadas pueden requerir ajustes
### Soluciones de Trabajo
```python
# Si una operación no funciona automáticamente:
result = sympify("Hex[FF] + 1") # Forzar evaluación SymPy
# Para debugging:
engine.debug = True # Activar modo debug
```
## 📈 Próximos Pasos
### Mejoras Sugeridas
1. **Performance**: Implementar caching más agresivo
2. **Operaciones**: Agregar más operaciones especializadas
3. **UI**: Mejorar feedback de errores en interfaz
4. **Testing**: Expandir suite de tests para casos edge
### Testing Continuo
```bash
# Ejecutar antes de cada sesión:
python debug_and_test.py
# Verificar funcionalidad específica:
python -c "
from hybrid_evaluation_engine import HybridEvaluationEngine
engine = HybridEvaluationEngine()
print(engine.evaluate_line('Hex[FF] + 1'))
"
```
## ✅ Checklist de Verificación
- [ ] `python debug_and_test.py` pasa todos los tests
- [ ] `Hex[FF] + 1` retorna resultado válido
- [ ] `IP4[...].NetworkAddress[]` funciona correctamente
- [ ] `z = 5` se asigna correctamente
- [ ] Ejemplos de `corrected_examples.py` funcionan
- [ ] Interfaz gráfica inicia sin errores
- [ ] Resultados interactivos son clickeables
---
**¡Las correcciones están implementadas y listas para usar!** 🎉
Para cualquier problema adicional, ejecutar `debug_and_test.py` para diagnosticar.

View File

@ -1,147 +0,0 @@
# Plots Interactivos - Correcciones Implementadas
## 🎯 **Estado Actual**
**Operaciones aritméticas corregidas**: `Hex[FF] + 1`, `Bin[1010] * 2`
**Asignaciones funcionando**: `z = 5`, `w = z + 3`
🔧 **Plots interactivos**: En proceso de corrección
## 🔧 **Correcciones Implementadas para Plots**
### **1. Reorganización de PlotResult**
- ✅ Movido `PlotResult` a `interactive_results.py` para evitar importaciones circulares
- ✅ Importación correcta en motor de evaluación y aplicación principal
### **2. Detección de Resultados Interactivos**
- ✅ Método `is_interactive` corregido en `EvaluationResult`
- ✅ Detección de `PlotResult`, `Matrix`, y listas largas
### **3. Manejo de Tags Clickeables**
- ✅ Método `create_interactive_tag()` retorna tupla `(tag, display_text)`
- ✅ Manejo robusto de casos donde no se puede crear tag
## 🧪 **Scripts de Verificación**
### **Test Operaciones Básicas** (YA FUNCIONA ✅)
```bash
python debug_and_test.py
```
**Resultados esperados:**
```
✅ Hex[FF] + 1 → 256
✅ Bin[1010] * 2 → 20
✅ IP4[...].NetworkAddress[] → 192.168.1.0/24
✅ z = 5 → z = 5
✅ w = z + 3 → w = 8
```
### **Test Plots Interactivos** (NUEVO)
```bash
python test_interactive_plots.py
```
**Verificará:**
- Creación de objetos `PlotResult`
- Evaluación de expresiones `plot()`
- Funcionalidad del `InteractiveResultManager`
- Flujo completo: evaluación → tag clickeable
### **Test Ejemplos Completos** (NUEVO)
```bash
python final_examples_test.py
```
**Ejecutará todos los ejemplos originales** que antes fallaban
## 🎯 **Lo que Debería Funcionar Ahora**
| Expresión | Estado | Resultado Esperado |
|-----------|--------|--------------------|
| `Hex[FF] + 1` | ✅ FUNCIONA | `256` |
| `Bin[1010] * 2` | ✅ FUNCIONA | `20` |
| `IP4[...].NetworkAddress[]` | ✅ FUNCIONA | `192.168.1.0/24` |
| `z = 5` | ✅ FUNCIONA | `z = 5` |
| `w = z + 3` | ✅ FUNCIONA | `w = 8` |
| `plot(sin(x), (x, -pi, pi))` | 🔧 EN TEST | `📊 Ver Plot` (clickeable) |
| `Matrix([[1, 2], [3, 4]])` | 🔧 EN TEST | `📋 Ver Matriz 2×2` (clickeable) |
## 🚀 **Próximos Pasos**
### **1. Verificar Plots**
```bash
# Ejecutar test específico
python test_interactive_plots.py
# Si hay errores, revisar logs
python log_viewer.py
```
### **2. Test en Aplicación Completa**
```bash
# Iniciar aplicación
python launcher.py
# Probar en interfaz:
plot(sin(x), (x, -2*pi, 2*pi))
Matrix([[1, 2], [3, 4]])
```
### **3. Verificar Funcionalidad Clickeable**
- Los resultados de `plot()` deberían mostrar `📊 Ver Plot`
- Al hacer click debería abrir ventana matplotlib
- Las matrices deberían mostrar `📋 Ver Matriz NxM`
- Al hacer click debería mostrar matriz formateada
## 🔍 **Debugging si Plots No Funcionan**
### **Verificar Creación de PlotResult**
```python
from interactive_results import PlotResult
plot_obj = PlotResult("plot", (sin(x), (x, -pi, pi)), {})
print(plot_obj) # Debería mostrar: 📊 Ver Plot
```
### **Verificar Evaluación**
```python
from hybrid_evaluation_engine import HybridEvaluationEngine
engine = HybridEvaluationEngine()
result = engine.evaluate_line("plot(sin(x), (x, -pi, pi))")
print(f"Resultado: {result.result}")
print(f"Tipo: {type(result.result)}")
print(f"Es interactivo: {result.is_interactive}")
```
### **Verificar Manager**
```python
import tkinter as tk
from interactive_results import InteractiveResultManager
root = tk.Tk()
manager = InteractiveResultManager(root)
# Test con plot_obj...
```
## 📊 **Logs para Debugging**
Todos los errores se registran automáticamente en:
```
logs/mav_calc_YYYYMMDD_HHMMSS.log
```
Para ver logs en tiempo real:
```bash
tail -f logs/mav_calc_*.log | grep -A 5 "plot\|Plot\|interactive"
```
## ✅ **Checklist de Verificación**
- [ ] `python debug_and_test.py` pasa todos los tests ✅ (YA FUNCIONA)
- [ ] `python test_interactive_plots.py` pasa todos los tests
- [ ] `python final_examples_test.py` muestra 100% éxito
- [ ] `plot(sin(x), (x, -pi, pi))` retorna `📊 Ver Plot`
- [ ] `Matrix([[1, 2], [3, 4]])` retorna `📋 Ver Matriz 2×2`
- [ ] La aplicación inicia sin errores: `python launcher.py`
- [ ] Los elementos clickeables funcionan en la interfaz
---
**Estado**: ✅ Operaciones básicas corregidas, 🔧 plots interactivos en verificación
**Siguiente paso**: Ejecutar `python test_interactive_plots.py` y reportar resultados

View File

@ -1,261 +0,0 @@
# Calculadora MAV - CAS Híbrido
## Estructura del Proyecto
```
📁 Calcv2/
├── main_calc.py # 🚀 Launcher principal
├── main_calc_app.py # 🖥️ Interfaz gráfica
├── main_evaluation.py # 🧮 Motor CAS
├── hybrid_base.py # 🏗️ Clase base
├── ip4_type.py # 🌐 Clase IP4
├── hex_type.py # 🔢 Clase Hex
├── bin_type.py # 🔢 Clase Bin
├── dec_type.py # 🔢 Clase Dec
├── chr_type.py # 🔤 Clase Chr
├── tl_bracket_parser.py # 📝 Parser sintaxis
└── tl_popup.py # 📊 Resultados clickeables
```
## Inicio Rápido
1. Instalar dependencias:
```bash
pip install sympy matplotlib numpy
```
2. Ejecutar la aplicación:
```bash
python main_calc.py
```
3. Ejemplos de uso:
```python
# Tipos especializados
Hex[FF] + 1
IP4[192.168.1.100/24].NetworkAddress[]
Bin[1010] * 2
# Matemáticas simbólicas
x + 2*y
diff(x**2 + sin(x), x)
integrate(x**2, x)
# Ecuaciones
x**2 + 2*x - 8 = 0
solve(x**2 + 2*x - 8, x)
```
## Características
- ✅ Motor algebraico completo (SymPy)
- ✅ Sintaxis simplificada con corchetes
- ✅ Detección automática de ecuaciones
- ✅ Resultados interactivos clickeables
- ✅ Tipos especializados (IP4, Hex, Bin, etc.)
- ✅ Variables SymPy puras
- ✅ Plotting integrado
## Comandos Útiles
- `python main_calc.py --help` - Muestra ayuda
- `python main_calc.py --test` - Ejecuta tests
- `python main_calc.py --setup` - Instala dependencias
- `python main_calc.py --debug` - Activa logging detallado
## 🚀 Inicio Rápido
### Instalación Automática
```bash
python launcher.py --setup
```
### Instalación Manual
```bash
pip install sympy matplotlib numpy
python launcher.py
```
### En Linux (para tkinter)
```bash
sudo apt-get install python3-tk
```
## ✨ Características Principales
- **🧮 Motor SymPy completo**: Cálculo simbólico avanzado
- **🔧 Sintaxis simplificada**: `IP4[192.168.1.1/24]` en lugar de `IP4("192.168.1.1/24")`
- **📐 Ecuaciones automáticas**: `x + 2 = 5` detectado automáticamente
- **📊 Resultados interactivos**: Plots y matrices clickeables
- **🌐 Clases especializadas**: IP4, Hex, Bin, Date, Dec, Chr
## 📝 Ejemplos Básicos
### Clases Especializadas
```python
# Redes
IP4[192.168.1.100/24].NetworkAddress[] # 192.168.1.0/24
IP4[10.0.0.1/8].Nodes() # 16777214 hosts
# Números
Hex[FF] + 1 # 0x100
Bin[1010] * 2 # 0b10100
# Caracteres
Chr[A] # 'A' (ASCII 65)
```
### Matemáticas Simbólicas
```python
# Variables automáticas
x + 2*y # Expresión simbólica
# Cálculo
diff(x**2 + sin(x), x) # 2*x + cos(x)
integrate(x**2, x) # x**3/3
# Ecuaciones (detección automática)
x**2 + 2*x - 8 = 0 # Agregada al sistema
solve(x**2 + 2*x - 8, x) # [-4, 2]
x=? # Atajo para solve(x)
```
### Plotting Interactivo
```python
plot(sin(x), (x, -2*pi, 2*pi)) # 📊 Ver Plot (clickeable)
Matrix([[1, 2], [3, 4]]) # 📋 Ver Matriz (clickeable)
```
## 🎯 Casos de Uso
### Networking
```python
# Análisis de red
network = IP4[192.168.0.0/24]
network.Nodes() # 254
network.BroadcastAddress[] # 192.168.0.255/24
# Cálculo con variables
base = IP4[10.0.x.0/24]
solve(base.Nodes() == 254, x) # Encuentra x
```
### Programación
```python
# Conversiones entre bases
Hex[255].toDecimal() # 255
Dec[66].toChr() # Chr('B')
# Análisis ASCII
Chr[Hello].value # [72, 101, 108, 108, 111]
```
### Matemáticas Avanzadas
```python
# Sistema de ecuaciones
x + y = 10
x - y = 2
solve([x + y - 10, x - y - 2], [x, y]) # {x: 6, y: 4}
# Análisis completo
f = sin(x) * exp(-x**2)
diff(f, x) # Derivada
integrate(f, (x, -oo, oo)) # Integral impropia
series(f, x, 0, 5) # Serie de Taylor
```
## 🖥️ Interfaz
### Paneles
- **Izquierda**: Editor de código con sintaxis nueva
- **Derecha**: Resultados coloreados e interactivos
### Menús
- **Archivo**: Nuevo, Cargar, Guardar
- **CAS**: Variables, Ecuaciones, Resolver sistema
- **Ayuda**: Guías y documentación completa
### Resultados Clickeables
- **📊 Ver Plot**: Abre ventana matplotlib
- **📋 Ver Matriz**: Vista expandida con operaciones
- **📋 Ver Lista**: Contenido completo de listas largas
## 🔧 Archivos del Proyecto
```
calculadora-mav-cas/
├── launcher.py # 🚀 Inicio principal
├── setup.py # 🛠️ Instalación
├── test_suite.py # 🧪 Tests
├── bracket_parser.py # 📝 Parser sintaxis
├── hybrid_base_types.py # 🏗️ Clases especializadas
├── hybrid_evaluation_engine.py # 🧮 Motor CAS
├── interactive_results.py # 📊 Resultados clickeables
├── hybrid_calc_app.py # 🖥️ Interfaz gráfica
└── requirements.txt # 📦 Dependencias
```
## 🆘 Resolución de Problemas
### Errores Comunes
```bash
# Dependencias faltantes
pip install sympy matplotlib numpy
# Linux: tkinter faltante
sudo apt-get install python3-tk
# Verificar instalación
python test_suite.py
```
### Sintaxis Correcta
```python
# ✅ Correcto (nueva sintaxis)
IP4[192.168.1.1/24]
Hex[FF]
# ❌ Incorrecto (sintaxis antigua)
IP4("192.168.1.1/24")
Hex("FF")
```
## 📚 Documentación Completa
Ver `comprehensive_documentation.md` para:
- Guía completa de sintaxis
- Casos de uso avanzados
- API de desarrollo
- Ejemplos detallados
## 🧪 Testing
```bash
# Tests básicos
python test_suite.py
# Tests con verbosidad
python test_suite.py --verbose
# Setup con tests
python launcher.py --test
```
## 🚀 Ejecutar
```bash
# Método recomendado
python launcher.py
# Sin splash screen
python launcher.py --no-splash
# Con verificación
python launcher.py --test
```
---
**¡Disfruta del poder del CAS híbrido!** 🎉
*Para soporte y documentación completa, consulta los archivos de documentación incluidos.*

View File

@ -0,0 +1,392 @@
# Simple Debug API - Calculadora MAV CAS
## Descripción
API CLI simple que usa el motor de evaluación existente para generar debug traces sin modificar el código base. Permite debuggear "como si usaras la aplicación" mediante archivos JSON.
---
## Uso
```bash
# Ejecutar debug
python simple_debug.py debug_input.json
# Con archivo de salida específico
python simple_debug.py debug_input.json --output debug_results.json
# Modo verboso
python simple_debug.py debug_input.json --verbose
```
---
## Formato de Entrada
### Estructura Simple
```json
{
"queries": [
{"index": 0, "type": "input", "content": "10.1.1.1 + 1"},
{"index": 1, "type": "input", "content": "16#FF + 10"},
{"index": 2, "type": "exec", "content": "engine.symbol_table"},
{"index": 3, "type": "input", "content": "x = 5"},
{"index": 4, "type": "exec", "content": "len(engine.symbol_table)"}
]
}
```
### Tipos de Query
#### Input Query
Evalúa expresiones como si las escribieras en la calculadora:
```json
{"index": 0, "type": "input", "content": "10.1.1.1 + 1"}
{"index": 1, "type": "input", "content": "mask = 255.255.0.0"}
{"index": 2, "type": "input", "content": "solve(x**2 + 1, x)"}
```
#### Exec Query
Ejecuta código Python para inspeccionar el estado interno:
```json
{"index": 3, "type": "exec", "content": "engine.symbol_table"}
{"index": 4, "type": "exec", "content": "engine.parser.get_tokenization_info()"}
{"index": 5, "type": "exec", "content": "list(engine.base_context.keys())[:10]"}
```
---
## Formato de Salida
### Estructura de Respuesta
```json
{
"execution_info": {
"timestamp": "2025-01-01T10:30:15Z",
"total_queries": 5,
"successful": 4,
"failed": 1
},
"results": [
{
"index": 0,
"input": "10.1.1.1 + 1",
"output": "10.1.1.2",
"result_type": "FourBytes",
"success": true
},
{
"index": 1,
"input": "16#FF + 10",
"output": "16#109",
"result_type": "IntBase",
"success": true
},
{
"index": 2,
"input": "engine.symbol_table",
"output": "{'x': Symbol('x'), 'mask': FourBytes('255.255.0.0')}",
"result_type": "dict",
"success": true
}
]
}
```
### Resultado Individual
```json
{
"index": 0,
"input": "10.1.1.1 + 1",
"output": "10.1.1.2",
"result_type": "FourBytes",
"success": true,
"error": null,
"display_class": "[FourBytes]"
}
```
### Resultado con Error
```json
{
"index": 3,
"input": "IP4Mask(255.240.0.3)",
"output": null,
"result_type": null,
"success": false,
"error": "ValueError: Máscara inválida: 255.240.0.3"
}
```
### Resultado de Exec
```json
{
"index": 4,
"input": "len(engine.symbol_table)",
"output": "3",
"result_type": "int",
"success": true,
"exec_result": 3
}
```
---
## Casos de Uso Comunes
### 1. Debug de Tokenización
```json
{
"queries": [
{"index": 0, "type": "input", "content": "192.168.1.1 + 16#FF"},
{"index": 1, "type": "exec", "content": "engine.parser.process_expression('192.168.1.1 + 16#FF')"},
{"index": 2, "type": "exec", "content": "engine.parser.get_tokenization_info()"}
]
}
```
### 2. Debug de Contexto
```json
{
"queries": [
{"index": 0, "type": "input", "content": "x = 5"},
{"index": 1, "type": "input", "content": "y = x + 10"},
{"index": 2, "type": "exec", "content": "engine.symbol_table"},
{"index": 3, "type": "exec", "content": "len(engine.equations)"}
]
}
```
### 3. Debug de Tipos
```json
{
"queries": [
{"index": 0, "type": "input", "content": "ip = 10.1.1.x"},
{"index": 1, "type": "exec", "content": "type(engine.symbol_table['ip'])"},
{"index": 2, "type": "exec", "content": "engine.symbol_table['ip'].has_symbols"},
{"index": 3, "type": "input", "content": "ip.substitute(x=5)"}
]
}
```
### 4. Debug de Errores
```json
{
"queries": [
{"index": 0, "type": "input", "content": "bad_mask = 255.240.0.3"},
{"index": 1, "type": "input", "content": "IP4Mask(bad_mask)"},
{"index": 2, "type": "exec", "content": "engine.last_result"}
]
}
```
### 5. Testing de Regresión
```json
{
"queries": [
{"index": 0, "type": "input", "content": "10.1.1.1 + 1"},
{"index": 1, "type": "exec", "content": "str(type(engine.last_result))"},
{"index": 2, "type": "exec", "content": "engine.last_result.original"},
{"index": 3, "type": "input", "content": "16#FF + 10"},
{"index": 4, "type": "exec", "content": "engine.last_result.base"}
]
}
```
---
## Funciones Útiles para Exec
### Estado del Motor
```python
# Contexto y variables
"engine.symbol_table" # Variables actuales
"list(engine.base_context.keys())" # Funciones disponibles
"len(engine.equations)" # Ecuaciones en el sistema
"engine.last_result" # Último resultado
# Configuración del motor
"engine.symbolic_mode" # ¿Modo simbólico?
"engine.debug" # ¿Debug habilitado?
```
### Información de Tipos
```python
# Tipos registrados
"engine.get_available_types()" # Info completa de tipos
"list(engine.registered_types_info['registered_classes'].keys())" # Tipos disponibles
"engine.registered_types_info['class_count']" # Cantidad de tipos
# Análisis de objetos
"type(engine.last_result)" # Tipo del último resultado
"engine.last_result.__class__.__name__" # Nombre de la clase
"hasattr(engine.last_result, 'has_symbols')" # ¿Tiene símbolos?
```
### Tokenización y Parsing
```python
# Tokenización
"engine.parser.get_tokenization_info()" # Info de tokenización
"engine.parser.process_expression('test')" # Procesar expresión
"len(engine.parser.tokenizer.tokenization_rules)" # Cantidad de reglas
# Análisis de expresiones
"engine._classify_line('x = 5')" # Clasificar línea
"engine._extract_variable_names('x + y')" # Extraer variables
```
### Testing de Funciones Específicas
```python
# Testing de FourBytes
"engine.last_result._numeric_value" # Valor numérico interno
"engine.last_result.has_symbols" # ¿Tiene símbolos?
"engine.last_result.original" # String original
# Testing de IntBase
"engine.last_result.base" # Base numérica
"engine.last_result.value_str" # String del valor
"engine.last_result._symbols" # Símbolos detectados
```
---
## Implementación Simple
### Estructura Mínima
```
simple_debug.py # CLI principal (~100 líneas)
debug_templates/ # Templates de ejemplo
├── basic_test.json
├── tokenization_test.json
└── regression_test.json
```
### CLI Principal (Pseudocódigo)
```python
# simple_debug.py
import json
from main_evaluation import HybridEvaluationEngine
def run_debug(input_file, output_file=None):
# Cargar queries
with open(input_file) as f:
data = json.load(f)
# Crear motor
engine = HybridEvaluationEngine()
results = []
# Ejecutar cada query
for query in data['queries']:
if query['type'] == 'input':
result = engine.evaluate_line(query['content'])
output = {
'index': query['index'],
'input': query['content'],
'output': str(result.result),
'result_type': type(result.result).__name__,
'success': not result.is_error,
'error': result.error if result.is_error else None
}
elif query['type'] == 'exec':
try:
exec_result = eval(query['content'], {'engine': engine})
output = {
'index': query['index'],
'input': query['content'],
'output': str(exec_result),
'result_type': type(exec_result).__name__,
'success': True,
'exec_result': exec_result
}
except Exception as e:
output = {
'index': query['index'],
'input': query['content'],
'success': False,
'error': str(e)
}
results.append(output)
# Guardar resultados
final_output = {
'execution_info': {...},
'results': results
}
with open(output_file, 'w') as f:
json.dump(final_output, f, indent=2)
```
---
## Templates de Ejemplo
### basic_test.json
```json
{
"queries": [
{"index": 0, "type": "input", "content": "10.1.1.1 + 1"},
{"index": 1, "type": "exec", "content": "type(engine.last_result).__name__"},
{"index": 2, "type": "input", "content": "16#FF"},
{"index": 3, "type": "exec", "content": "engine.last_result.base"}
]
}
```
### tokenization_test.json
```json
{
"queries": [
{"index": 0, "type": "exec", "content": "engine.parser.process_expression('192.168.1.1 + 16#FF')"},
{"index": 1, "type": "input", "content": "192.168.1.1 + 16#FF"},
{"index": 2, "type": "exec", "content": "engine.parser.get_tokenization_info()['rules'][:3]"}
]
}
```
### regression_test.json
```json
{
"queries": [
{"index": 0, "type": "input", "content": "mask=255.240.0.0"},
{"index": 1, "type": "exec", "content": "type(engine.symbol_table['mask']).__name__"},
{"index": 2, "type": "input", "content": "10.1.1.1 + 1"},
{"index": 3, "type": "exec", "content": "type(engine.last_result).__name__"},
{"index": 4, "type": "input", "content": "IP4Mask(255.255.0.0)"},
{"index": 5, "type": "exec", "content": "engine.last_result.get_prefix_int()"}
]
}
```
---
## Ventajas de este Diseño
**Simplicidad**: ~100 líneas de código total
**Sin modificaciones**: Usa el motor existente tal como está
**Flexibilidad**: Cualquier función del engine es accesible via exec
**Debugging real**: Exactamente como usar la aplicación
**Fácil testing**: JSON simple para casos de prueba
**Serialización automática**: Python maneja la conversión a string
Esta aproximación te permite debuggear efectivamente sin crear una infraestructura compleja, usando el poder del motor existente.

View File

@ -1,99 +0,0 @@
#!/usr/bin/env python3
"""
Diagnóstico del problema de asignaciones
"""
if __name__ == "__main__":
print("🔍 DIAGNOSTICANDO PROBLEMA DE ASIGNACIONES")
print("=" * 60)
try:
from main_evaluation import HybridEvaluationEngine
from tl_bracket_parser import UniversalTokenizer
# Crear motor de evaluación
engine = HybridEvaluationEngine()
engine.debug = True # Activar debug completo
# Crear tokenizador para ver qué pasa
tokenizer = UniversalTokenizer()
tokenizer.debug = True
# Casos de prueba exactos del usuario
test_cases = [
"mask=255.240.0.3",
"mask",
"ip=10.1.1.1",
"10.1.1.1",
"ip"
]
print("\n🧪 Procesando casos de prueba del usuario:")
for i, case in enumerate(test_cases, 1):
print(f"\n{'='*50}")
print(f"CASO {i}: '{case}'")
print(f"{'='*50}")
# 1. Ver tokenización
tokenized = tokenizer.preprocess_tokens(case)
print(f"1. TOKENIZACIÓN: '{case}''{tokenized}'")
# 2. Ver clasificación de línea
classification = engine._classify_line(tokenized)
print(f"2. CLASIFICACIÓN: {classification}")
# 3. Evaluar con debug
print(f"3. EVALUACIÓN:")
result = engine.evaluate_line(case)
print(f" RESULTADO:")
print(f" - Tipo de resultado: {result.result_type}")
print(f" - Es error: {result.is_error}")
if result.is_error:
print(f" - Error: {result.error}")
else:
print(f" - Valor: {result.result}")
print(f" - Tipo de valor: {type(result.result)}")
# 4. Ver estado de variables
print(f"4. ESTADO DE VARIABLES:")
print(f" Variables en symbol_table: {list(engine.symbol_table.keys())}")
for var_name, var_value in engine.symbol_table.items():
print(f" {var_name} = {var_value} (tipo: {type(var_value)})")
# 5. Ver ecuaciones
print(f"5. ECUACIONES ALMACENADAS:")
print(f" Total ecuaciones: {len(engine.equations)}")
for j, eq in enumerate(engine.equations):
print(f" {j+1}. {eq}")
print(f"\n{'_'*50}")
# 6. Prueba manual de asignación directa
print(f"\n🔧 PRUEBA MANUAL DE ASIGNACIÓN DIRECTA:")
try:
# Probar evaluación manual del lado derecho
print(f"6.1 Evaluando 'FourBytes(\"255.240.0.3\")' directamente:")
manual_result = engine._eval_in_context('FourBytes("255.240.0.3")')
print(f" Resultado: {manual_result} (tipo: {type(manual_result)})")
# Probar asignación manual
print(f"6.2 Asignación manual 'test_var = FourBytes(\"255.240.0.3\")':")
exec_result = engine._eval_in_context('test_var = FourBytes("255.240.0.3")')
print(f" Resultado exec: {exec_result}")
# Ver si se guardó
test_var_value = engine.get_variable('test_var')
print(f" test_var guardada: {test_var_value} (tipo: {type(test_var_value)})")
except Exception as e:
print(f" Error en prueba manual: {e}")
import traceback
traceback.print_exc()
except Exception as e:
print(f"Error general: {e}")
import traceback
traceback.print_exc()

View File

@ -1,100 +0,0 @@
#!/usr/bin/env python3
"""
Diagnóstico de problemas específicos del usuario:
1. IP4Mask(mask) no funciona
2. 10.1.1.1 + 1 devuelve Integer en lugar de FourBytes
"""
if __name__ == "__main__":
print("🔍 DIAGNOSTICANDO PROBLEMAS ESPECÍFICOS DEL USUARIO")
print("=" * 60)
try:
from main_evaluation import HybridEvaluationEngine
# Crear motor con debug
engine = HybridEvaluationEngine()
engine.debug = True
print("📋 Reproduciendo secuencia del usuario:")
# 1. Crear mask
print(f"\n1. Creando mask:")
result1 = engine.evaluate_line("mask=255.240.0.3")
print(f" mask asignada: {result1.result} (tipo: {type(result1.result)})")
# Ver qué hay en mask
mask_value = engine.get_variable('mask')
print(f" mask en symbol_table: {mask_value} (tipo: {type(mask_value)})")
print(f"\n2. Problema 1: IP4Mask(mask) no funciona")
print(f" Intentando: IP4Mask(mask)")
# Probar directamente
try:
result2 = engine.evaluate_line("IP4Mask(mask)")
print(f" Resultado: {result2.result} (tipo: {type(result2.result)})")
if result2.is_error:
print(f" Error: {result2.error}")
except Exception as e:
print(f" Excepción: {e}")
# Ver qué pasa cuando llamamos IP4Mask directamente con el valor
print(f"\n Probando IP4Mask directamente con el valor de mask:")
try:
# Obtener IP4Mask del contexto
IP4Mask = engine.base_context.get('IP4Mask')
if IP4Mask:
print(f" IP4Mask disponible: {IP4Mask}")
direct_result = IP4Mask(mask_value)
print(f" Resultado directo: {direct_result} (tipo: {type(direct_result)})")
else:
print(f" IP4Mask no encontrada en contexto")
except Exception as e:
print(f" Error en llamada directa: {e}")
import traceback
traceback.print_exc()
print(f"\n3. Problema 2: 10.1.1.1 + 1 devuelve Integer")
print(f" Intentando: 10.1.1.1 + 1")
result3 = engine.evaluate_line("10.1.1.1 + 1")
print(f" Resultado: {result3.result} (tipo: {type(result3.result)})")
# Analizar paso a paso
print(f"\n Análisis paso a paso:")
# Crear FourBytes manualmente para probar
try:
FourBytes = engine.base_context.get('FourBytes')
if FourBytes:
print(f" FourBytes disponible: {FourBytes}")
fb = FourBytes("10.1.1.1")
print(f" FourBytes creado: {fb} (tipo: {type(fb)})")
print(f" fb._numeric_value: {fb._numeric_value}")
# Probar suma manual
sum_result = fb + 1
print(f" fb + 1 = {sum_result} (tipo: {type(sum_result)})")
# Ver el método __add__
print(f" Método __add__ de FourBytes: {fb.__add__}")
except Exception as e:
print(f" Error en análisis: {e}")
import traceback
traceback.print_exc()
print(f"\n4. Verificando contexto:")
relevant_classes = ['FourBytes', 'IP4Mask', 'IP4']
for cls_name in relevant_classes:
cls_obj = engine.base_context.get(cls_name)
if cls_obj:
print(f"{cls_name}: {cls_obj}")
else:
print(f"{cls_name}: No encontrada")
except Exception as e:
print(f"Error general: {e}")
import traceback
traceback.print_exc()

401
readme.md
View File

@ -2,45 +2,140 @@
## Descripción
Sistema de Álgebra Computacional (CAS) que combina SymPy con clases especializadas para networking, programación y análisis numérico. Incluye sistema de tipos dinámico con auto-descubrimiento.
Sistema de Álgebra Computacional (CAS) que combina SymPy con clases especializadas para networking, programación y análisis numérico. Incluye **sistema de tokenización automática** y **auto-descubrimiento dinámico** de tipos.
## Características Principales
- **Motor SymPy completo**: Cálculo simbólico y numérico integrado
- **Sistema de tipos dinámico**: Auto-descubrimiento desde `custom_types/`
- **Sintaxis simplificada**: `Tipo[args]` en lugar de `Tipo("args")`
- **Tokenización automática**: `16#FF`, `192.168.1.1` se convierten en objetos tipados automáticamente
- **Sistema de tipos auto-descubrible**: Auto-registro desde `custom_types/` sin modificar código
- **Clases base universales**: IntBase (números en cualquier base) y FourBytes (patrones x.x.x.x)
- **Conversión perezosa a SymPy**: Objetos nativos hasta que se necesite álgebra compleja
- **Detección automática de ecuaciones**: Sin sintaxis especial
- **Contexto limpio por evaluación**: Cada modificación evalúa todo desde cero, garantizando comportamiento predecible
- **Resultados interactivos**: Elementos clickeables para plots, matrices y listas
- **Autocompletado inteligente**: Basado en tipos registrados dinámicamente
## Tokenización Automática ⭐ **NUEVO**
El sistema reconoce automáticamente patrones específicos y los convierte en objetos tipados:
### Números en Bases
```python
# Entrada del usuario → Conversión automática
16#FF # → IntBase('FF', 16) = 255
2#1010 # → IntBase('1010', 2) = 10
8#777 # → IntBase('777', 8) = 511
16#x0 # → IntBase('x0', 16) = simbólico
```
### Patrones x.x.x.x
```python
# Entrada del usuario → Conversión automática
192.168.1.1 # → FourBytes('192.168.1.1')
255.255.0.0 # → FourBytes('255.255.0.0')
10.x.1.y # → FourBytes('10.x.1.y') = simbólico
```
### Constructores Inteligentes
```python
# Los constructores aceptan objetos tokenizados automáticamente
IP4(192.168.1.1, 24) # FourBytes tokenizado automáticamente
IP4(10.1.1.1, 255.255.0.0) # Ambos FourBytes automáticamente
Hex(16#FF) # IntBase tokenizado automáticamente
Hex(192.168.1.1) # Conversión FourBytes → Hex
```
## Tipos Especializados
### Redes y Direcciones IP
### Clases Base Universales ⭐ **NUEVO**
#### IntBase - Números Universales
```python
IP4[192.168.1.100/24]
IP4[10.0.0.1, 8]
IP4[172.16.0.5, 255.255.0.0]
IP4Mask[24]
IP4Mask[255.255.255.0]
# Aritmética que mantiene la base original:
a = 16#FF # → IntBase('FF', 16)
b = 16#10 # → IntBase('10', 16)
result = a + b # → IntBase('10F', 16) [271 en decimal]
# Operaciones mixtas:
c = 16#A0 + 32 # → IntBase('C0', 16) [192 en decimal]
d = 2#1010 * 3 # → IntBase('11110', 2) [30 en decimal]
# Conversiones:
a.to_base(2) # → IntBase('11111111', 2)
a.to_decimal() # → 255
```
### Sistemas Numéricos
#### FourBytes - Patrones x.x.x.x Universales
```python
Hex[FF] # Hexadecimal
Bin[1010] # Binario
Dec[255] # Decimal
Chr[A] # Caracteres ASCII
# Aritmética de direcciones IP:
ip1 = 192.168.1.1 # → FourBytes automático
ip2 = ip1 + 5 # → FourBytes('192.168.1.6')
next_net = 10.0.0.0 + 256 # → FourBytes('10.0.1.0')
# Conversiones automáticas:
ip = 192.168.1.1 # → FourBytes
ip_hex = ip.ToHex() # → "16#C0.16#A8.16#1.16#1"
ip_bin = ip.ToBinary() # → "2#11000000.2#10101000.2#1.2#1"
# Aritmética simbólica:
network = 10.x.0.0 # → FourBytes simbólico
network.substitute(x=5) # → FourBytes('10.5.0.0')
```
### Redes y Direcciones IP
```python
# Constructores automáticos con tokenización:
IP4(192.168.1.100, 24) # FourBytes + CIDR
IP4(10.0.0.1, 255.255.248.0) # FourBytes + máscara FourBytes
IP4(172.16.0.5, 16#ffffff00) # FourBytes + máscara IntBase
# Métodos de red:
ip = IP4(192.168.1.100, 24)
ip.NetworkAddress() # → IP4(192.168.1.0, 24)
ip.BroadcastAddress() # → IP4(192.168.1.255, 24)
ip.Nodes() # → 254 hosts disponibles
ip.next_ip() # → IP4(192.168.1.101, 24)
# Máscaras inteligentes:
IP4Mask(24) # → CIDR
IP4Mask(255.255.255.0) # → Dotted decimal (tokenizado)
IP4Mask(16#ffffff00) # → Desde hex (tokenizado)
```
### Sistemas Numéricos Especializados
```python
# Conversiones automáticas desde clases base:
Hex(16#FF) # IntBase → Hex
Bin(2#1010) # IntBase → Bin
Dec(255) # → Decimal
Chr(65) # → Chr('A')
# Conversiones desde FourBytes:
Hex(192.168.1.1) # FourBytes → Hex (32-bit)
Bin(192.168.1.1) # FourBytes → Bin por elementos
```
### Métodos Disponibles
Los tipos incluyen métodos específicos accesibles con autocompletado:
```python
ip = IP4[192.168.1.100/24]
ip.NetworkAddress[] # Dirección de red
ip.Nodes() # Hosts disponibles
Hex[FF].toDecimal() # Conversiones
# IntBase universal:
val = 16#FF
val.to_base(2) # Conversión a otra base
val.substitute(x=15) # Sustitución simbólica
val.to_sympy() # Conversión explícita a SymPy
# FourBytes universal:
addr = 192.168.1.1
addr.ToHex() # → "16#C0.16#A8.16#1.16#1"
addr.substitute(x=5) # Para casos simbólicos
addr.is_valid_ip_range() # Validación de rango IP
# IP4 especializado:
ip = IP4(192.168.1.100, 24)
ip.NetworkAddress() # Dirección de red
ip.add_hosts(10) # Suma hosts
ip.in_same_network(other_ip) # Comparación de redes
```
## Sistema de Ecuaciones
@ -50,37 +145,46 @@ Hex[FF].toDecimal() # Conversiones
x + 2 = 5 # Detectado automáticamente
y**2 - 4 = 0 # Agregado al sistema
sin(x) = 1/2 # Ecuaciones trigonométricas
# Con objetos tokenizados:
16#x0 + 16#10 = 256 # Ecuación con IntBase
10.x.1.1 + 255 = 10.x.2.0 # Ecuación con FourBytes
```
### Resolución
```python
solve(x**2 + 2*x - 8, x) # Resolver ecuación específica
x=? # Atajo para solve(x)
solve(x**2 + 2*x - 8, x) # Resolver ecuación específica
x=? # Atajo para solve(x)
# Con objetos especializados:
solve(16#x0 + 16#10 - 256, x) # → x = 240 (en decimal)
network = 10.x.0.0
solve(network + 256 == 10.5.0.0, x) # → x = 5
```
## Funciones Matemáticas
### Cálculo
```python
diff(x**3, x) # Derivadas
integrate(sin(x), (x, 0, pi)) # Integrales
limit(sin(x)/x, x, 0) # Límites
series(exp(x), x, 0, 5) # Series
# Con objetos nativos (conversión automática cuando es necesario):
diff(16#x0, x) # → 16*log(16)
integrate(sin(16#x), x) # Conversión a SymPy automática
limit(192.168.x.1 / x, x, 0) # Con FourBytes simbólico
```
### Álgebra
```python
simplify(expr) # Simplificación
expand((x+1)**3) # Expansión
factor(x**2-1) # Factorización
solve([eq1, eq2], [x, y]) # Sistemas
simplify(expr) # Simplificación
expand((16#x + 1)**3) # Expansión con IntBase
factor(x**2 - 16#100) # Factorización mixta
solve([eq1, eq2], [x, y]) # Sistemas
```
### Matrices
```python
Matrix([[1, 2], [3, 4]]) # Crear matriz
det(M) # Determinante
inv(M) # Inversa
Matrix([[16#FF, 2#1010], [192.168.1.1, 255.255.0.0]]) # Con objetos tokenizados
det(M) # Determinante
inv(M) # Inversa
```
## Resultados Interactivos
@ -94,8 +198,10 @@ Los siguientes resultados son clickeables en la interfaz:
## Plotting
```python
plot(sin(x), (x, -2*pi, 2*pi)) # Plot 2D
plot3d(x**2 + y**2, (x, -5, 5), (y, -5, 5)) # Plot 3D
# Con objetos nativos (conversión automática):
plot(sin(16#x), (x, 0, 255)) # IntBase en plot
plot(192.168.x.1, (x, 0, 255)) # FourBytes simbólico
plot3d(x**2 + y**2, (x, -5, 5), (y, -5, 5)) # Plot 3D tradicional
```
## Variables y Símbolos
@ -105,6 +211,10 @@ Todas las variables son símbolos SymPy automáticamente:
x = 5 # x es Symbol('x') con valor 5
y = x + 2 # y es 7 (evaluado)
z = x + a # z es Symbol('x') + Symbol('a') (simbólico)
# Con objetos tokenizados:
ip_base = 192.168.x.0 # FourBytes simbólico
hex_val = 16#x0 # IntBase simbólico
```
### Comportamiento de Contexto Limpio
@ -125,103 +235,194 @@ x=1 # → Asigna x=1
y+x # → y + 1 (usa x=1 definido arriba)
x=x+1 # → Incrementa x a 2
x # → Muestra 2
# Con tokenización automática:
ip = 192.168.1.1 # → FourBytes('192.168.1.1')
ip + 5 # → FourBytes('192.168.1.6')
```
**Importante**: Cada modificación reconstruye el contexto desde la línea 1 hacia abajo.
#### Carga de Historial
- Al abrir la aplicación, se carga el historial anterior y se evalúa una vez para mostrar resultados
- A partir de ese momento, cada modificación limpia el contexto y reevalúa todo desde cero
- El historial se guarda automáticamente al cerrar la aplicación
## Interfaz de Usuario
### Paneles
- **Izquierdo**: Entrada de código
- **Derecho**: Resultados con colores y elementos interactivos
### Autocompletado
### Autocompletado Dinámico
- Escribir `.` después de cualquier objeto muestra métodos disponibles
- El sistema usa tipos registrados dinámicamente
- Funciona con objetos SymPy y tipos personalizados
- Sistema auto-descubre métodos desde tipos registrados dinámicamente
- Funciona con objetos SymPy, IntBase, FourBytes y tipos personalizados
- Soporte para objetos tokenizados automáticamente
### Menús
- **Archivo**: Nuevo, Cargar, Guardar
- **Editar**: Limpiar entrada/salida, Limpiar historial
- **Configuración**: Modos simbólicos, Recargar tipos personalizados
- **Tipos**: Información de tipos, Sintaxis de tipos
- **Tipos**: Información de tipos, Sintaxis de tipos ⭐ **NUEVO**
- **Ayuda**: Guías y referencia
**Nota**: Se han eliminado las opciones relacionadas con limpiar variables/ecuaciones ya que el contexto se limpia automáticamente en cada evaluación.
## Sistema de Tipos Dinámico
## Sistema de Tipos Auto-Descubrible ⭐ **ACTUALIZADO**
### Auto-descubrimiento
Los tipos se cargan automáticamente desde `custom_types/`:
- Archivos `*_type.py` son detectados automáticamente
- Cada archivo define clases y función `register_classes_in_module()`
- Sistema modular y extensible sin modificar código central
### Auto-Descubrimiento Completo
- **Tipos fundamentales**: IntBase y FourBytes en `custom_types/`
- **Tipos especializados**: Todos los tipos en el directorio unificado
- **Tokenización distribuida**: Cada clase define sus propios patrones
- **Precedencia automática**: Patrones más específicos tienen mayor prioridad
- **Parser genérico**: Sin hardcoding de tipos específicos
### Arquitectura Modular
```
custom_types/
├── intbase_type.py # IntBase + tokenización + registro
├── fourbytes_type.py # FourBytes + tokenización + registro
├── hex_type.py # Hex (usa IntBase)
├── bin_type.py # Bin (usa IntBase)
├── dec_type.py # Dec
├── chr_type.py # Chr
├── ip4_type.py # IP4 + IP4Mask (usa FourBytes)
└── latex_type.py # LaTeX
```
### Información de Tipos
Use **Menú Tipos → Información de tipos** para ver:
- Clases registradas disponibles
- Sintaxis de corchetes soportada
- Patrones de tokenización activos
- Precedencia de conversión
- Métodos de cada tipo
### Recargar Tipos
### Recarga Dinámica
**Menú Tipos → Recargar tipos** para desarrollo en tiempo real.
## Casos de Uso
## Casos de Uso ⭐ **ACTUALIZADOS**
### Análisis de Redes
### Análisis de Redes con Tokenización
```python
network = IP4[192.168.0.0/24]
host = IP4[192.168.0.100/24]
network.Nodes() # Hosts disponibles
host.NetworkAddress[] # Dirección de red
# Tokenización automática en acción:
network = 192.168.0.0 # → FourBytes automático
mask = 255.255.255.0 # → FourBytes automático
ip = IP4(network, mask) # Constructor inteligente
# Aritmética de redes:
first_host = network + 1 # → FourBytes('192.168.0.1')
last_host = network + 254 # → FourBytes('192.168.0.254')
# Análisis con variables:
base = 10.x.0.0 # → FourBytes simbólico
solve(base + 256 == 10.5.0.0, x) # → x = 5
```
### Conversiones Numéricas
### Conversiones Automáticas entre Bases
```python
Hex[FF].toDecimal() # 255
Dec[66].toChr() # Chr('B')
# IntBase universal:
hex_val = 16#FF # → IntBase('FF', 16)
bin_val = hex_val.to_base(2) # → IntBase('11111111', 2)
oct_val = hex_val.to_base(8) # → IntBase('377', 8)
# Aritmética preservando base:
result = 16#FF + 16#10 # → IntBase('10F', 16)
mixed = 16#A0 + 32 # → IntBase('C0', 16)
# FourBytes a otras representaciones:
ip = 192.168.1.1 # → FourBytes automático
ip_hex = ip.ToHex() # → "16#C0.16#A8.16#1.16#1"
ip_binary = ip.ToBinary() # → "2#11000000.2#10101000.2#1.2#1"
```
### Análisis Matemático
### Análisis Matemático con Objetos Nativos
```python
f = sin(x) * exp(-x**2/2)
df_dx = diff(f, x) # Derivada
# Funciones con objetos tokenizados:
f = sin(16#x0) * exp(-x**2/2) # IntBase en función
df_dx = diff(f, x) # Derivada (conversión automática)
critical_points = solve(df_dx, x) # Puntos críticos
plot(f, df_dx, (x, -3, 3)) # Visualización
# Visualización:
plot(f, df_dx, (x, -3, 3)) # Plot función y derivada
# Con FourBytes simbólico:
network_func = 10.x.1.0 + sin(x)
plot(network_func, (x, 0, 255))
```
## Extensibilidad
### Álgebra Simbólica Avanzada
```python
# Sistemas con objetos nativos:
ip1 = 192.168.x.1 # FourBytes simbólico
ip2 = 10.y.1.1 # FourBytes simbólico
### Crear Nuevos Tipos
# Ecuaciones con conversión automática:
solve([ip1 + 255 == 192.168.5.0, ip2 - 10.0.1.1 == 0], [x, y])
# → {x: 4, y: 0}
# Análisis de rangos:
hex_range = 16#x0 # IntBase simbólico
constraints = [hex_range >= 16#A0, hex_range <= 16#FF]
solve(constraints, x) # → Rango válido para x
```
## Extensibilidad ⭐ **ACTUALIZADA**
### Crear Nuevos Tipos con Tokenización
1. Crear archivo en `custom_types/nuevo_type.py`
2. Definir clase heredando de `ClassBase` o `SympyClassBase`
3. Implementar función `register_classes_in_module()`
4. El sistema detecta automáticamente el nuevo tipo
3. Implementar `get_tokenization_patterns()` (opcional)
4. Implementar `register_classes_in_module()`
5. El sistema detecta automáticamente el nuevo tipo
### Ejemplo de Estructura
### Ejemplo Completo con Tokenización
```python
# custom_types/ejemplo_type.py
from sympy_Base import SympyClassBase
# custom_types/mac_type.py
from class_base import ClassBase
import re
class Class_Ejemplo(SympyClassBase):
def __init__(self, value):
super().__init__(processed_value, original_str)
class MACAddress(ClassBase):
def __init__(self, mac_string):
# Procesar dirección MAC
super().__init__(processed_value, mac_string)
@staticmethod
def get_tokenization_patterns():
"""Define patrones de tokenización automática"""
return [
{
'pattern': r'\b([0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2})\b',
'replacement': lambda match: f'MACAddress("{match.group(1)}")',
'priority': 6,
'description': 'MAC con dos puntos: AA:BB:CC:DD:EE:FF'
}
]
@staticmethod
def Helper(input_str):
return "Ayuda para Ejemplo"
if re.search(r'([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}', input_str):
return "Direcciones MAC: AA:BB:CC:DD:EE:FF"
return None
@staticmethod
def PopupFunctionList():
return [("metodo", "Descripción del método")]
return [
("to_vendor", "Busca fabricante por OUI"),
("is_unicast", "Verifica si es unicast"),
("to_binary", "Convierte a representación binaria")
]
def register_classes_in_module():
return [("Ejemplo", Class_Ejemplo, "SympyClassBase", {})]
return [
("MACAddress", MACAddress, "ClassBase", {
"add_lowercase": True,
"supports_brackets": False, # Usa tokenización
"has_tokenization": True,
"description": "Direcciones MAC con auto-detección"
})
]
```
### Uso Automático del Nuevo Tipo
```python
# Después de agregar mac_type.py:
# AA:BB:CC:DD:EE:FF se convierte automáticamente en MACAddress("AA:BB:CC:DD:EE:FF")
mac = AA:BB:CC:DD:EE:FF # Tokenización automática
vendor = mac.to_vendor() # Métodos disponibles automáticamente
```
## Resolución de Problemas
@ -229,35 +430,47 @@ def register_classes_in_module():
### Errores Comunes
- **Dependencias faltantes**: Ejecutar `pip install sympy matplotlib numpy`
- **tkinter en Linux**: `sudo apt-get install python3-tk`
- **Sintaxis**: Usar `Tipo[args]` no `Tipo("args")`
- **Conversión prematura a SymPy**: Algunos objetos se convierten antes de tiempo (en desarrollo)
### Performance
- Tokenización automática es muy eficiente
- Expresiones complejas pueden ser lentas en SymPy
- Objetos nativos son más rápidos que conversiones SymPy
- Plots 3D requieren tiempo de renderizado
- Matrices grandes consumen memoria
### Debugging
### Debugging del Sistema de Tipos
- Los logs se guardan en `logs/`
- Usar **Menú Tipos → Información** para verificar tipos cargados
- Usar **Menú Tipos → Información** para verificar tipos cargados y patrones activos
- Verificar `custom_types/` para tipos personalizados
- Debug de tokenización: activar modo debug en el parser
## Arquitectura
## Arquitectura ⭐ **ACTUALIZADA**
### Componentes Principales
- **type_registry.py**: Sistema de auto-descubrimiento
- **main_evaluation.py**: Motor CAS híbrido
- **tl_bracket_parser.py**: Parser de sintaxis con corchetes
- **type_registry.py**: Sistema de auto-descubrimiento completo
- **custom_types/**: Directorio unificado de todos los tipos
- **tl_bracket_parser.py**: Tokenizador universal distribuido
- **main_evaluation.py**: Motor CAS híbrido integrado
- **tl_popup.py**: Resultados interactivos
- **main_calc_app.py**: Aplicación principal
### Flujo de Ejecución
1. Auto-descubrimiento de tipos en `custom_types/`
2. Registro dinámico de clases y métodos
3. Parser convierte sintaxis con corchetes
4. Motor SymPy evalúa expresiones
5. Resultados se presentan interactivamente
### Flujo de Ejecución ⭐ **ACTUALIZADO**
1. **Auto-descubrimiento**: Carga tipos desde `custom_types/`
2. **Registro dinámico**: Clases, métodos, helpers y patrones de tokenización
3. **Tokenización distribuida**: Cada clase define sus propios patrones
4. **Conversión automática**: Patrones específicos → objetos tipados
5. **Evaluación híbrida**: Objetos nativos + SymPy cuando es necesario
6. **Resultados interactivos**: Presentación con elementos clickeables
### Precedencia de Tokenización
```python
# Orden automático por especificidad:
IntBase: priority = 5 # Muy específico: 16#FF
MAC: priority = 6 # Específico: AA:BB:CC:DD:EE:FF
FourBytes: priority = 10 # General: x.x.x.x
```
---
**Calculadora MAV - CAS Híbrido**
*Sistema extensible para cálculo matemático y análisis especializado*
**Calculadora MAV - CAS Híbrido v2.1**
*Sistema extensible con tokenización automática para cálculo matemático y análisis especializado*

View File

@ -1,164 +0,0 @@
#!/usr/bin/env python3
"""
Script de prueba para el sistema de tokenización distribuida
"""
def test_distributed_tokenization():
"""Prueba el sistema de tokenización distribuida completo"""
print("🧪 PROBANDO SISTEMA DE TOKENIZACIÓN DISTRIBUIDA")
print("=" * 60)
# Importar dependencias
try:
from tl_bracket_parser import TokenizationParser, preview_tokenization, test_tokenization_patterns
from type_registry import discover_and_register_types, get_registered_base_context
from main_evaluation import HybridEvaluationEngine
print("✅ Todas las importaciones exitosas")
except ImportError as e:
print(f"❌ Error en importaciones: {e}")
return False
# 1. Probar auto-descubrimiento de tipos
print("\n1⃣ PROBANDO AUTO-DESCUBRIMIENTO DE TIPOS")
print("-" * 40)
try:
registry_info = discover_and_register_types()
print(f"✅ Tipos descubiertos: {registry_info['class_count']} clases")
registered_context = get_registered_base_context()
# Verificar clases fundamentales
fundamental_classes = ['IntBase', 'FourBytes']
for cls_name in fundamental_classes:
if cls_name in registered_context:
print(f"{cls_name} registrada")
# Verificar si tiene tokenización
cls_obj = registered_context[cls_name]
if hasattr(cls_obj, 'get_tokenization_patterns'):
patterns = cls_obj.get_tokenization_patterns()
print(f" 🔧 Tiene {len(patterns)} reglas de tokenización")
for pattern in patterns:
print(f" 📋 Prioridad {pattern['priority']}: {pattern['description']}")
else:
print(f" ⚠️ Sin reglas de tokenización")
else:
print(f"{cls_name} NO registrada")
except Exception as e:
print(f"❌ Error en auto-descubrimiento: {e}")
return False
# 2. Probar tokenizador universal
print("\n2⃣ PROBANDO TOKENIZADOR UNIVERSAL")
print("-" * 40)
try:
parser = TokenizationParser(debug=True)
# Casos de prueba
test_cases = [
"16#FF", # IntBase
"2#1010", # IntBase
"192.168.1.1", # FourBytes
"10.x.1.y", # FourBytes simbólico
"0xFF", # Hex con prefijo
"0b1010", # Bin con prefijo
"16#FF + 192.168.1.1", # Mixto
"normal + variable", # Sin tokenización
]
print("🧪 Casos de prueba:")
results = parser.test_patterns(test_cases)
print(f"\n📊 Resultados:")
print(f" ✅ Exitosos: {len(results['successful_conversions'])}")
print(f" ⚪ Sin cambios: {len(results['failed_conversions'])}")
if results['successful_conversions']:
print(f"\n🎉 Conversiones exitosas:")
for expr in results['successful_conversions']:
result = results['tokenized_results'][expr]
print(f" '{expr}''{result}'")
# Obtener información de reglas
tokenization_info = parser.get_tokenization_info()
print(f"\n📋 {len(tokenization_info['rules'])} reglas activas:")
for rule in tokenization_info['rules']:
print(f" {rule['priority']:2d}: {rule['class']} - {rule['description']}")
except Exception as e:
print(f"❌ Error en tokenizador: {e}")
return False
# 3. Probar integración con motor de evaluación
print("\n3⃣ PROBANDO INTEGRACIÓN CON MOTOR DE EVALUACIÓN")
print("-" * 40)
try:
engine = HybridEvaluationEngine(debug=True)
# Probar expresiones tokenizadas
test_expressions = [
"a = 16#FF",
"b = 192.168.1.1",
"c = a + 5",
"d = b + 256",
"16#10 + 2#1010",
]
print("🧪 Probando expresiones:")
for expr in test_expressions:
try:
result = engine.evaluate_line(expr)
if result.is_error:
print(f"'{expr}' → Error: {result.error}")
else:
print(f"'{expr}'{result.result}")
except Exception as e:
print(f"'{expr}' → Excepción: {e}")
except Exception as e:
print(f"❌ Error en motor de evaluación: {e}")
return False
# 4. Prueba de casos específicos reportados por el usuario
print("\n4⃣ PROBANDO CASOS ESPECÍFICOS DEL USUARIO")
print("-" * 40)
try:
engine = HybridEvaluationEngine()
# El caso específico que reportó el usuario
test_expression = "m=255.240.0.0 16#ff + 5"
print(f"🎯 Probando: '{test_expression}'")
# Primero ver cómo se tokeniza
preview = preview_tokenization(test_expression, debug=False)
print(f" 🔧 Tokenización: '{preview['original']}''{preview['tokenized']}'")
# Ahora evaluar
result = engine.evaluate_line(test_expression)
if result.is_error:
print(f" ❌ Error: {result.error}")
else:
print(f" ✅ Resultado: {result.result}")
except Exception as e:
print(f"❌ Error en caso específico: {e}")
return False
print("\n🎉 TODAS LAS PRUEBAS COMPLETADAS")
return True
if __name__ == "__main__":
success = test_distributed_tokenization()
if success:
print("\n✅ Sistema de tokenización distribuida funcionando correctamente")
else:
print("\n❌ Hay problemas en el sistema de tokenización distribuida")

View File

@ -1,54 +0,0 @@
#!/usr/bin/env python3
"""
Script rápido para probar tokenización
"""
if __name__ == "__main__":
print("🧪 Prueba rápida de tokenización")
try:
# 1. Verificar registro de tipos
print("\n1. Verificando registro de tipos...")
from type_registry import discover_and_register_types, get_registered_base_context
registry_info = discover_and_register_types()
print(f"Clases registradas: {registry_info['class_count']}")
context = get_registered_base_context()
print(f"Clases en contexto: {list(context.keys())}")
# 2. Verificar si las clases tienen tokenización
print("\n2. Verificando métodos de tokenización...")
for name, cls in context.items():
if hasattr(cls, 'get_tokenization_patterns'):
patterns = cls.get_tokenization_patterns()
print(f"{name}: {len(patterns)} patrones")
for p in patterns:
print(f" - Prioridad {p['priority']}: {p['description']}")
else:
print(f"{name}: sin tokenización")
# 3. Probar tokenizador
print("\n3. Probando tokenizador...")
from tl_bracket_parser import UniversalTokenizer
tokenizer = UniversalTokenizer()
tokenizer.debug = True
print(f"Reglas cargadas: {len(tokenizer.tokenization_rules)}")
test_cases = [
"192.168.1.1",
"16#FF",
"0xFF",
"2#1010",
"10.x.1.y"
]
for case in test_cases:
result = tokenizer.preprocess_tokens(case)
print(f"'{case}''{result}'")
except Exception as e:
print(f"Error: {e}")
import traceback
traceback.print_exc()

View File

@ -1,49 +0,0 @@
#!/usr/bin/env python3
"""
Prueba de uso real del sistema corregido
"""
if __name__ == "__main__":
print("🎯 PRUEBA DE USO REAL")
print("=" * 40)
try:
from main_evaluation import HybridEvaluationEngine
# Crear motor sin debug para simular uso real
engine = HybridEvaluationEngine()
engine.debug = False
# Casos exactos del usuario
test_sequence = [
"mask=255.240.0.3",
"mask",
"ip=10.1.1.1",
"10.1.1.1",
"ip"
]
print("Secuencia de comandos del usuario:")
print("-" * 40)
for i, command in enumerate(test_sequence, 1):
print(f"\n{i}. {command}")
result = engine.evaluate_line(command)
if result.is_error:
print(f" ❌ Error: {result.error}")
else:
print(f"{result.result}")
if hasattr(result.result, '__class__'):
print(f" [{result.result.__class__.__name__}]")
print(f"\n" + "=" * 40)
print("ESTADO FINAL:")
print(f"Variables: {list(engine.symbol_table.keys())}")
for var, value in engine.symbol_table.items():
print(f" {var} = {value}")
except Exception as e:
print(f"Error: {e}")
import traceback
traceback.print_exc()

View File

@ -1,105 +0,0 @@
#!/usr/bin/env python3
"""
Prueba del caso específico del usuario: m=255.240.0.0 16#ff + 5
"""
if __name__ == "__main__":
print("🎯 Probando caso específico del usuario")
try:
# Debug completo del sistema
from type_registry import discover_and_register_types, get_registered_base_context
from tl_bracket_parser import UniversalTokenizer
print("\n🔍 DEBUG COMPLETO DEL SISTEMA:")
# 1. Verificar registro de tipos
print("\n1. Verificando registro de tipos...")
registry_info = discover_and_register_types()
print(f"Clases registradas: {registry_info['class_count']}")
context = get_registered_base_context()
fundamental_classes = ['IntBase', 'FourBytes']
for cls_name in fundamental_classes:
if cls_name in context:
print(f"{cls_name} está registrada")
cls_obj = context[cls_name]
if hasattr(cls_obj, 'get_tokenization_patterns'):
patterns = cls_obj.get_tokenization_patterns()
print(f" 🔧 Tiene {len(patterns)} reglas de tokenización")
for i, pattern in enumerate(patterns):
print(f" {i+1}. Prioridad {pattern['priority']}: {pattern['description']}")
print(f" Patrón: {pattern['pattern']}")
else:
print(f" ❌ Sin reglas de tokenización")
else:
print(f"{cls_name} NO está registrada")
# 2. Crear tokenizador y verificar reglas
print("\n2. Creando tokenizador...")
tokenizer = UniversalTokenizer()
print(f"Reglas cargadas en tokenizador: {len(tokenizer.tokenization_rules)}")
if len(tokenizer.tokenization_rules) > 0:
print("Reglas activas:")
for i, rule in enumerate(tokenizer.tokenization_rules):
print(f" {i+1}. {rule['class_name']} (prioridad {rule['priority']}): {rule['description']}")
else:
print("❌ No hay reglas cargadas en el tokenizador")
# 3. Probar tokenización manual
print("\n3. Probando tokenización manual...")
tokenizer.debug = True
test_simple = "192.168.1.1"
print(f"\nProbando: '{test_simple}'")
result = tokenizer.preprocess_tokens(test_simple)
print(f"Resultado: '{result}'")
test_hex = "16#ff"
print(f"\nProbando: '{test_hex}'")
result = tokenizer.preprocess_tokens(test_hex)
print(f"Resultado: '{result}'")
# 4. Verificar que las clases estén disponibles en motor
print("\n4. Verificando motor de evaluación...")
from main_evaluation import HybridEvaluationEngine
engine = HybridEvaluationEngine()
engine.debug = True
print(f"Contexto del motor tiene {len(engine.base_context)} entradas")
# Verificar que IntBase y FourBytes estén en el contexto
for cls_name in ['IntBase', 'FourBytes']:
if cls_name in engine.base_context:
print(f"{cls_name} está en contexto del motor")
else:
print(f"{cls_name} NO está en contexto del motor")
# 5. Probar evaluación directa
print("\n5. Probando evaluación directa...")
# Probar evaluación manual sin tokenización
test_manual = "IntBase('ff', 16)"
print(f"Probando evaluación manual: {test_manual}")
try:
result = engine._eval_in_context(test_manual)
print(f"✅ Resultado: {result} (tipo: {type(result)})")
except Exception as e:
print(f"❌ Error: {e}")
# Probar FourBytes manual
test_manual2 = "FourBytes('192.168.1.1')"
print(f"Probando evaluación manual: {test_manual2}")
try:
result = engine._eval_in_context(test_manual2)
print(f"✅ Resultado: {result} (tipo: {type(result)})")
except Exception as e:
print(f"❌ Error: {e}")
except Exception as e:
print(f"Error: {e}")
import traceback
traceback.print_exc()