Creada API de Debug
This commit is contained in:
parent
b2a4237504
commit
60401010a6
|
@ -0,0 +1,508 @@
|
|||
# Simple Debug API - Guía para LLM
|
||||
|
||||
## Propósito
|
||||
|
||||
Esta API permite debuggear la **Calculadora MAV CAS** sin modificar código fuente ni crear scripts adicionales. Como LLM, puedes usar esta herramienta para:
|
||||
|
||||
- **Diagnosticar problemas** en el motor de evaluación
|
||||
- **Verificar comportamiento** de tipos personalizados (FourBytes, IntBase, IP4Mask, etc.)
|
||||
- **Inspeccionar el estado interno** del motor (variables, contexto, tipos registrados)
|
||||
- **Analizar el formato de salida** exacto como se muestra en la aplicación
|
||||
- **Testing de regresión** para verificar que cambios no rompan funcionalidad existente
|
||||
|
||||
## Flujo de Trabajo Recomendado
|
||||
|
||||
### 1. Crear archivo JSON con queries
|
||||
### 2. Ejecutar: `python simple_debug.py archivo.json`
|
||||
### 3. Analizar resultados en el archivo `*_results.json`
|
||||
|
||||
---
|
||||
|
||||
## Tipos de Query
|
||||
|
||||
### Query tipo `input`
|
||||
Evalúa expresiones como si el usuario las escribiera en la calculadora.
|
||||
|
||||
```json
|
||||
{"index": 0, "type": "input", "content": "10.1.1.1 + 1"}
|
||||
```
|
||||
|
||||
### Query tipo `exec`
|
||||
Ejecuta código Python para inspeccionar el estado interno del motor.
|
||||
|
||||
```json
|
||||
{"index": 1, "type": "exec", "content": "type(engine.last_result).__name__"}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Plantilla Base
|
||||
|
||||
```json
|
||||
{
|
||||
"queries": [
|
||||
{"index": 0, "type": "input", "content": "EXPRESION_A_EVALUAR"},
|
||||
{"index": 1, "type": "exec", "content": "CODIGO_PYTHON_INSPECCION"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Casos de Uso Comunes
|
||||
|
||||
### Debugging de Tipos Personalizados
|
||||
|
||||
**Problema**: Verificar si FourBytes maneja correctamente operaciones IP.
|
||||
|
||||
```json
|
||||
{
|
||||
"queries": [
|
||||
{"index": 0, "type": "input", "content": "192.168.1.1 + 1"},
|
||||
{"index": 1, "type": "exec", "content": "type(engine.last_result).__name__"},
|
||||
{"index": 2, "type": "exec", "content": "engine.last_result.original"},
|
||||
{"index": 3, "type": "exec", "content": "engine.last_result._numeric_value"},
|
||||
{"index": 4, "type": "input", "content": "10.0.0.0/8 + 256"},
|
||||
{"index": 5, "type": "exec", "content": "engine.last_result.has_symbols"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Debugging de Tokenización
|
||||
|
||||
**Problema**: La expresión `192.168.1.x + 16#FF` no se tokeniza correctamente.
|
||||
|
||||
```json
|
||||
{
|
||||
"queries": [
|
||||
{"index": 0, "type": "exec", "content": "engine.parser.process_expression('192.168.1.x + 16#FF')"},
|
||||
{"index": 1, "type": "input", "content": "192.168.1.x + 16#FF"},
|
||||
{"index": 2, "type": "exec", "content": "engine.parser.get_tokenization_info()"},
|
||||
{"index": 3, "type": "exec", "content": "len(engine.parser.tokenizer.tokenization_rules)"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Debugging de Errores
|
||||
|
||||
**Problema**: IP4Mask rechaza máscaras que deberían ser válidas.
|
||||
|
||||
```json
|
||||
{
|
||||
"queries": [
|
||||
{"index": 0, "type": "input", "content": "mask = 255.240.0.0"},
|
||||
{"index": 1, "type": "input", "content": "IP4Mask(mask)"},
|
||||
{"index": 2, "type": "exec", "content": "engine.last_result"},
|
||||
{"index": 3, "type": "input", "content": "IP4Mask(255.240.0.3)"},
|
||||
{"index": 4, "type": "exec", "content": "engine.last_result"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Debugging de Estado del Motor
|
||||
|
||||
**Problema**: Las variables no se están guardando correctamente.
|
||||
|
||||
```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.symbol_table)"},
|
||||
{"index": 4, "type": "exec", "content": "list(engine.symbol_table.keys())"},
|
||||
{"index": 5, "type": "input", "content": "solve(z**2 + x, z)"},
|
||||
{"index": 6, "type": "exec", "content": "len(engine.equations)"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Interpretación de Resultados
|
||||
|
||||
### Estructura del Resultado
|
||||
|
||||
```json
|
||||
{
|
||||
"execution_info": {
|
||||
"timestamp": "2025-06-05T18:01:28.644799Z",
|
||||
"total_queries": 5,
|
||||
"successful": 4,
|
||||
"failed": 1
|
||||
},
|
||||
"results": [...]
|
||||
}
|
||||
```
|
||||
|
||||
### Resultado Individual (Query `input`)
|
||||
|
||||
```json
|
||||
{
|
||||
"index": 0,
|
||||
"input": "10.1.1.1 + 1",
|
||||
"output": "10.1.1.2", // Resultado básico
|
||||
"result_type": "FourBytes", // Tipo del objeto resultado
|
||||
"success": true,
|
||||
"error": null,
|
||||
"display_class": "[FourBytes]", // Nombre de clase para display
|
||||
"output_raw": { // ⭐ INFORMACIÓN DE FORMATO
|
||||
"parts": [
|
||||
["custom_type", "10.1.1.2"], // [tag_color, contenido]
|
||||
["class_hint", "[FourBytes]"]
|
||||
],
|
||||
"formatted_text": "[custom_type]10.1.1.2[class_hint][FourBytes]",
|
||||
"tag_info": { // Información de colores
|
||||
"custom_type": {"fg": "#f9a825"},
|
||||
"class_hint": {"fg": "#888888"}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Resultado Individual (Query `exec`)
|
||||
|
||||
```json
|
||||
{
|
||||
"index": 1,
|
||||
"input": "type(engine.last_result).__name__",
|
||||
"output": "FourBytes",
|
||||
"result_type": "str",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": "FourBytes" // Resultado crudo del exec
|
||||
}
|
||||
```
|
||||
|
||||
### Resultado con Error
|
||||
|
||||
```json
|
||||
{
|
||||
"index": 2,
|
||||
"input": "IP4Mask(255.240.0.3)",
|
||||
"output": "None",
|
||||
"result_type": "NoneType",
|
||||
"success": false,
|
||||
"error": "❌ Máscara inválida: 255.240.0.3...",
|
||||
"output_raw": {
|
||||
"parts": [["error", "Error: ❌ Máscara inválida..."]],
|
||||
"formatted_text": "[error]Error: ❌ Máscara inválida...",
|
||||
"tag_info": {"error": {"fg": "#ff6b6b", "font": "bold"}}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Funciones de Inspección Útiles
|
||||
|
||||
### Estado del Motor
|
||||
|
||||
```python
|
||||
"engine.symbol_table" # Variables actuales
|
||||
"engine.last_result" # Último resultado
|
||||
"engine.symbolic_mode" # ¿Modo simbólico activo?
|
||||
"len(engine.equations)" # Cantidad de ecuaciones en el sistema
|
||||
"engine.debug" # ¿Debug habilitado?
|
||||
"list(engine.base_context.keys())[:10]" # Funciones disponibles (muestra 10)
|
||||
```
|
||||
|
||||
### Información de Tipos
|
||||
|
||||
```python
|
||||
"engine.get_available_types()" # Info completa de tipos registrados
|
||||
"list(engine.registered_types_info['registered_classes'].keys())" # Lista de tipos
|
||||
"engine.registered_types_info['class_count']" # Cantidad de tipos registrados
|
||||
"type(engine.last_result).__name__" # Tipo del último resultado
|
||||
"hasattr(engine.last_result, 'has_symbols')" # ¿El resultado tiene símbolos?
|
||||
```
|
||||
|
||||
### Tokenización y Parsing
|
||||
|
||||
```python
|
||||
"engine.parser.get_tokenization_info()" # Info completa de tokenización
|
||||
"engine.parser.process_expression('test')" # Procesar expresión específica
|
||||
"len(engine.parser.tokenizer.tokenization_rules)" # Cantidad de reglas
|
||||
"engine._classify_line('x = 5')" # Clasificar tipo de línea
|
||||
"engine._extract_variable_names('x + y')" # Extraer nombres de variables
|
||||
```
|
||||
|
||||
### Análisis de Objetos Específicos
|
||||
|
||||
```python
|
||||
# Para FourBytes
|
||||
"engine.last_result.original" # String original
|
||||
"engine.last_result._numeric_value" # Valor numérico interno
|
||||
"engine.last_result.has_symbols" # ¿Tiene símbolos?
|
||||
|
||||
# Para IntBase
|
||||
"engine.last_result.base" # Base numérica (10, 16, 8, 2)
|
||||
"engine.last_result.value_str" # String del valor
|
||||
"engine.last_result._symbols" # Símbolos detectados
|
||||
|
||||
# Para IP4Mask
|
||||
"engine.last_result.get_prefix_int()" # Prefijo como entero
|
||||
"engine.last_result.is_valid()" # ¿Es máscara válida?
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Patrones de Debugging
|
||||
|
||||
### 1. Debugging de Regresión
|
||||
|
||||
**Cuándo usar**: Verificar que cambios no rompan funcionalidad existente.
|
||||
|
||||
```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 + 10"},
|
||||
{"index": 3, "type": "exec", "content": "engine.last_result.base"},
|
||||
{"index": 4, "type": "input", "content": "IP4Mask(255.255.0.0)"},
|
||||
{"index": 5, "type": "exec", "content": "engine.last_result.get_prefix_int()"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Debugging de Nuevas Funcionalidades
|
||||
|
||||
**Cuándo usar**: Verificar que nueva funcionalidad trabaja correctamente.
|
||||
|
||||
```json
|
||||
{
|
||||
"queries": [
|
||||
{"index": 0, "type": "input", "content": "NUEVA_FUNCIONALIDAD_AQUI"},
|
||||
{"index": 1, "type": "exec", "content": "type(engine.last_result)"},
|
||||
{"index": 2, "type": "exec", "content": "dir(engine.last_result)"},
|
||||
{"index": 3, "type": "exec", "content": "str(engine.last_result)"},
|
||||
{"index": 4, "type": "exec", "content": "engine.symbol_table"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Debugging de Performance
|
||||
|
||||
**Cuándo usar**: Identificar operaciones lentas o problemáticas.
|
||||
|
||||
```json
|
||||
{
|
||||
"queries": [
|
||||
{"index": 0, "type": "exec", "content": "import time; start = time.time()"},
|
||||
{"index": 1, "type": "input", "content": "OPERACION_LENTA"},
|
||||
{"index": 2, "type": "exec", "content": "time.time() - start"},
|
||||
{"index": 3, "type": "exec", "content": "len(engine.symbol_table)"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Debugging de Display/Formato
|
||||
|
||||
**Cuándo usar**: Verificar cómo se muestra exactamente un resultado.
|
||||
|
||||
```json
|
||||
{
|
||||
"queries": [
|
||||
{"index": 0, "type": "input", "content": "EXPRESION"},
|
||||
{"index": 1, "type": "exec", "content": "str(engine.last_result)"},
|
||||
{"index": 2, "type": "exec", "content": "repr(engine.last_result)"},
|
||||
{"index": 3, "type": "exec", "content": "type(engine.last_result).__name__"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Análisis de output_raw
|
||||
|
||||
El campo `output_raw` contiene información exacta sobre cómo se muestra el resultado en la aplicación:
|
||||
|
||||
### Tags de Color Importantes
|
||||
|
||||
- **`error`** (`#ff6b6b`): Errores
|
||||
- **`custom_type`** (`#f9a825`): Tipos personalizados (FourBytes, IntBase, etc.)
|
||||
- **`symbolic`** (`#82aaff`): Expresiones simbólicas
|
||||
- **`numeric`** (`#c3e88d`): Aproximaciones numéricas
|
||||
- **`class_hint`** (`#888888`): Pistas de clase `[FourBytes]`
|
||||
- **`ip`** (`#fff176`): Direcciones IP específicamente
|
||||
- **`hex`** (`#f9a825`): Números hexadecimales
|
||||
|
||||
### Interpretación de Parts
|
||||
|
||||
```json
|
||||
"parts": [
|
||||
["custom_type", "192.168.1.2"], // Resultado principal en naranja
|
||||
["class_hint", "[FourBytes]"] // Pista de clase en gris
|
||||
]
|
||||
```
|
||||
|
||||
Esto significa: "192.168.1.2" se muestra en color naranjo seguido de "[FourBytes]" en gris.
|
||||
|
||||
---
|
||||
|
||||
## Comandos de Ejecución
|
||||
|
||||
```bash
|
||||
# Ejecución básica
|
||||
python simple_debug.py mi_debug.json
|
||||
|
||||
# Con archivo de salida específico
|
||||
python simple_debug.py mi_debug.json --output resultados.json
|
||||
|
||||
# Modo verboso (para ver progreso)
|
||||
python simple_debug.py mi_debug.json --verbose
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Templates Existentes para Reutilizar
|
||||
|
||||
### Casos Básicos
|
||||
**Archivo**: `debug_templates/basic_test.json`
|
||||
- Operaciones con FourBytes e IntBase
|
||||
- Variables y SymPy básico
|
||||
|
||||
### Testing de Errores
|
||||
**Archivo**: `debug_templates/error_debug.json`
|
||||
- Máscaras inválidas
|
||||
- IPs fuera de rango
|
||||
- Expresiones malformadas
|
||||
|
||||
### Información de Contexto
|
||||
**Archivo**: `debug_templates/context_debug.json`
|
||||
- Estado completo del motor
|
||||
- Tipos registrados
|
||||
- Sistema de ecuaciones
|
||||
|
||||
### Formato de Display
|
||||
**Archivo**: `debug_templates/display_format_test.json`
|
||||
- Demostración de `output_raw`
|
||||
- Diferentes tipos de formato
|
||||
|
||||
### Tokenización
|
||||
**Archivo**: `debug_templates/tokenization_test.json`
|
||||
- Debug del sistema de parsing
|
||||
- Reglas de tokenización
|
||||
|
||||
---
|
||||
|
||||
## Flujo de Resolución de Problemas
|
||||
|
||||
### 1. Identificar el Problema
|
||||
- ¿Es un error de evaluación?
|
||||
- ¿Es un problema de formato/display?
|
||||
- ¿Es un problema de tokenización?
|
||||
- ¿Es un problema de estado del motor?
|
||||
|
||||
### 2. Crear Query de Diagnóstico
|
||||
- Usar query `input` para reproducir el problema
|
||||
- Usar query `exec` para inspeccionar el estado
|
||||
|
||||
### 3. Analizar Resultados
|
||||
- Verificar `success: true/false`
|
||||
- Examinar `error` si hay fallo
|
||||
- Analizar `output_raw` para problemas de display
|
||||
- Usar `exec_result` para inspección detallada
|
||||
|
||||
### 4. Iterar
|
||||
- Crear nuevas queries basadas en hallazgos
|
||||
- Profundizar en áreas problemáticas
|
||||
- Verificar soluciones con queries adicionales
|
||||
|
||||
---
|
||||
|
||||
## Ejemplo Completo de Debugging
|
||||
|
||||
**Problema**: "La operación `192.168.1.x + 1` no funciona correctamente"
|
||||
|
||||
### Paso 1: Crear archivo de debug
|
||||
|
||||
```json
|
||||
{
|
||||
"queries": [
|
||||
{"index": 0, "type": "input", "content": "192.168.1.x + 1"},
|
||||
{"index": 1, "type": "exec", "content": "type(engine.last_result).__name__"},
|
||||
{"index": 2, "type": "exec", "content": "engine.last_result.has_symbols"},
|
||||
{"index": 3, "type": "exec", "content": "engine.parser.process_expression('192.168.1.x + 1')"},
|
||||
{"index": 4, "type": "input", "content": "ip = 192.168.1.x"},
|
||||
{"index": 5, "type": "exec", "content": "type(engine.symbol_table['ip'])"},
|
||||
{"index": 6, "type": "input", "content": "ip.substitute(x=5)"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Paso 2: Ejecutar
|
||||
```bash
|
||||
python simple_debug.py debug_problema.json
|
||||
```
|
||||
|
||||
### Paso 3: Analizar resultados
|
||||
- Verificar si `192.168.1.x + 1` se evalúa correctamente
|
||||
- Comprobar el tipo resultante
|
||||
- Verificar si tiene símbolos
|
||||
- Examinar cómo se tokeniza la expresión
|
||||
- Probar operaciones relacionadas
|
||||
|
||||
Este flujo te permite identificar exactamente dónde está el problema y verificar la solución.
|
||||
|
||||
---
|
||||
|
||||
## Consejos para LLMs
|
||||
|
||||
1. **Siempre usa índices secuenciales** en las queries para facilitar la lectura
|
||||
2. **Combina queries `input` y `exec`** para obtener contexto completo
|
||||
3. **Verifica tanto `output` como `output_raw`** para problemas de display
|
||||
4. **Usa los templates existentes** como punto de partida
|
||||
5. **Examina `success` y `error`** antes de analizar resultados
|
||||
6. **Aprovecha `exec_result`** para inspección detallada del estado
|
||||
7. **Crea queries incrementales** que construyan sobre resultados anteriores
|
||||
|
||||
Con esta API, puedes debuggear efectivamente la calculadora sin necesidad de modificar código fuente o crear scripts adicionales.
|
||||
|
||||
---
|
||||
|
||||
## Referencia Rápida
|
||||
|
||||
### Query Básica
|
||||
```json
|
||||
{"index": N, "type": "input|exec", "content": "CONTENIDO"}
|
||||
```
|
||||
|
||||
### Comandos Esenciales
|
||||
```bash
|
||||
python simple_debug.py archivo.json # Ejecutar debug
|
||||
python simple_debug.py archivo.json --verbose # Con detalles
|
||||
python simple_debug.py archivo.json -o resultado.json # Salida específica
|
||||
```
|
||||
|
||||
### Inspección Básica del Motor
|
||||
```python
|
||||
"engine.last_result" # Último resultado
|
||||
"type(engine.last_result)" # Tipo del resultado
|
||||
"engine.symbol_table" # Variables actuales
|
||||
"engine.get_available_types()" # Tipos registrados
|
||||
"engine.parser.get_tokenization_info()" # Info de parsing
|
||||
```
|
||||
|
||||
### Análisis de Resultado
|
||||
```python
|
||||
"success": true/false # ¿Éxito?
|
||||
"error": "mensaje" # Error si falla
|
||||
"output": "resultado" # Resultado básico
|
||||
"output_raw": {...} # Formato exacto de la app
|
||||
"exec_result": valor # Resultado crudo (exec queries)
|
||||
```
|
||||
|
||||
### Templates Disponibles
|
||||
- `debug_templates/basic_test.json` - Pruebas básicas
|
||||
- `debug_templates/error_debug.json` - Testing de errores
|
||||
- `debug_templates/context_debug.json` - Estado del motor
|
||||
- `debug_templates/tokenization_test.json` - Debug de parsing
|
||||
- `debug_templates/display_format_test.json` - Formato de display
|
||||
|
||||
### Workflow Típico
|
||||
1. **Identificar problema** → Crear query `input` para reproducir
|
||||
2. **Inspeccionar estado** → Añadir queries `exec` para diagnosticar
|
||||
3. **Analizar resultados** → Examinar `success`, `error`, `output_raw`
|
||||
4. **Iterar** → Crear nuevas queries basadas en hallazgos
|
|
@ -0,0 +1,339 @@
|
|||
{
|
||||
"execution_info": {
|
||||
"timestamp": "2025-06-05T18:10:43.323812Z",
|
||||
"total_queries": 8,
|
||||
"successful": 8,
|
||||
"failed": 0,
|
||||
"input_file": "debug_templates\\basic_test.json"
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"index": 0,
|
||||
"input": "10.1.1.1 + 1",
|
||||
"output": "10.1.1.2",
|
||||
"result_type": "FourBytes",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"custom_type",
|
||||
"10.1.1.2"
|
||||
],
|
||||
[
|
||||
"class_hint",
|
||||
"[FourBytes]"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[custom_type]10.1.1.2[class_hint][FourBytes]",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[FourBytes]"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"input": "type(engine.last_result).__name__",
|
||||
"output": "FourBytes",
|
||||
"result_type": "str",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": "FourBytes"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"input": "16#FF",
|
||||
"output": "16#FF",
|
||||
"result_type": "IntBase",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"custom_type",
|
||||
"16#FF"
|
||||
],
|
||||
[
|
||||
"class_hint",
|
||||
"[IntBase]"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[custom_type]16#FF[class_hint][IntBase]",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[IntBase]"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"input": "engine.last_result.base",
|
||||
"output": "16",
|
||||
"result_type": "int",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": 16
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"input": "mask = 255.255.0.0",
|
||||
"output": "255.255.0.0",
|
||||
"result_type": "FourBytes",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"info",
|
||||
"mask = 255.255.0.0"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[info]mask = 255.255.0.0",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[FourBytes]"
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"input": "engine.symbol_table",
|
||||
"output": "{'mask': FourBytes('255.255.0.0')}",
|
||||
"result_type": "dict",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": "{'mask': FourBytes('255.255.0.0')}"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"input": "solve(x**2 + 1, x)",
|
||||
"output": "[-I, I]",
|
||||
"result_type": "list",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"result",
|
||||
"[-I, I]"
|
||||
],
|
||||
[
|
||||
"class_hint",
|
||||
"[List]"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[result][-I, I][class_hint][List]",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[list]"
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"input": "len(engine.symbol_table)",
|
||||
"output": "1",
|
||||
"result_type": "int",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": 1
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
{
|
||||
"execution_info": {
|
||||
"timestamp": "2025-06-05T18:02:09.698502Z",
|
||||
"total_queries": 11,
|
||||
"successful": 11,
|
||||
"failed": 0,
|
||||
"input_file": "debug_templates\\context_debug.json"
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"index": 0,
|
||||
"input": "x = 5",
|
||||
"output": "5",
|
||||
"result_type": "Integer",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"display_class": "[Integer]"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"input": "y = x + 10",
|
||||
"output": "15",
|
||||
"result_type": "Integer",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"display_class": "[Integer]"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"input": "engine.symbol_table",
|
||||
"output": "{'x': 5, 'y': 15}",
|
||||
"result_type": "dict",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": "{'x': 5, 'y': 15, 'z': [-sqrt(-b), sqrt(-b)]}"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"input": "len(engine.equations)",
|
||||
"output": "2",
|
||||
"result_type": "int",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": 2
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"input": "list(engine.base_context.keys())[:10]",
|
||||
"output": "['pi', 'e', 'I', 'oo', 'sin', 'cos', 'tan', 'asin', 'acos', 'atan']",
|
||||
"result_type": "list",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": [
|
||||
"pi",
|
||||
"e",
|
||||
"I",
|
||||
"oo",
|
||||
"sin",
|
||||
"cos",
|
||||
"tan",
|
||||
"asin",
|
||||
"acos",
|
||||
"atan"
|
||||
]
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"input": "engine.get_available_types()",
|
||||
"output": "{'registered_classes': {'Bin': <class 'bin_type.Class_Bin'>, 'Chr': <class 'chr_type.Class_Chr'>, 'Dec': <class 'dec_type.Class_Dec'>, 'FourBytes': <class 'fourbytes_type.FourBytes'>, 'Hex': <class 'hex_type.Class_Hex'>, 'IntBase': <class 'intbase_type.IntBase'>, 'IP4': <class 'ip4_type.Class_IP4'>, 'IP4Mask': <class 'ip4_type.IP4Mask'>, 'LaTeX': <class 'latex_type.Class_LaTeX'>}, 'bracket_classes': ['bin', 'intbase', 'IP4', 'chr', 'IntBase', 'ip4', 'fourbytes', 'Chr', 'dec', 'latex', 'FourBytes', 'Hex', 'LaTeX', 'Dec', 'Bin', 'IP4Mask', 'hex', 'ip4mask'], 'total_context_entries': 64, 'helper_functions_count': 9}",
|
||||
"result_type": "dict",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": "{'registered_classes': {'Bin': <class 'bin_type.Class_Bin'>, 'Chr': <class 'chr_type.Class_Chr'>, 'Dec': <class 'dec_type.Class_Dec'>, 'FourBytes': <class 'fourbytes_type.FourBytes'>, 'Hex': <class 'hex_type.Class_Hex'>, 'IntBase': <class 'intbase_type.IntBase'>, 'IP4': <class 'ip4_type.Class_IP4'>, 'IP4Mask': <class 'ip4_type.IP4Mask'>, 'LaTeX': <class 'latex_type.Class_LaTeX'>}, 'bracket_classes': ['bin', 'intbase', 'IP4', 'chr', 'IntBase', 'ip4', 'fourbytes', 'Chr', 'dec', 'latex', 'FourBytes', 'Hex', 'LaTeX', 'Dec', 'Bin', 'IP4Mask', 'hex', 'ip4mask'], 'total_context_entries': 64, 'helper_functions_count': 9}"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"input": "list(engine.registered_types_info['registered_classes'].keys())",
|
||||
"output": "['Bin', 'Chr', 'Dec', 'FourBytes', 'Hex', 'IntBase', 'IP4', 'IP4Mask', 'LaTeX']",
|
||||
"result_type": "list",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": [
|
||||
"Bin",
|
||||
"Chr",
|
||||
"Dec",
|
||||
"FourBytes",
|
||||
"Hex",
|
||||
"IntBase",
|
||||
"IP4",
|
||||
"IP4Mask",
|
||||
"LaTeX"
|
||||
]
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"input": "engine.registered_types_info['class_count']",
|
||||
"output": "9",
|
||||
"result_type": "int",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": 9
|
||||
},
|
||||
{
|
||||
"index": 8,
|
||||
"input": "z = solve(a**2 + b, a)",
|
||||
"output": "[-sqrt(-b), sqrt(-b)]",
|
||||
"result_type": "list",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"display_class": "[list]"
|
||||
},
|
||||
{
|
||||
"index": 9,
|
||||
"input": "engine._classify_line('z = solve(a**2 + b, a)')",
|
||||
"output": "assignment",
|
||||
"result_type": "str",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": "assignment"
|
||||
},
|
||||
{
|
||||
"index": 10,
|
||||
"input": "engine._extract_variable_names('x + y + z')",
|
||||
"output": "['x', 'y', 'z']",
|
||||
"result_type": "list",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": [
|
||||
"x",
|
||||
"y",
|
||||
"z"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
# Templates de Debug - Simple Debug API
|
||||
|
||||
Esta carpeta contiene templates predefinidos para debuggear diferentes aspectos de la Calculadora MAV CAS.
|
||||
|
||||
## Uso Básico
|
||||
|
||||
```bash
|
||||
# Ejecutar un template
|
||||
python simple_debug.py debug_templates/basic_test.json
|
||||
|
||||
# Con archivo de salida personalizado
|
||||
python simple_debug.py debug_templates/basic_test.json --output mi_debug.json
|
||||
|
||||
# Con información detallada
|
||||
python simple_debug.py debug_templates/basic_test.json --verbose
|
||||
```
|
||||
|
||||
## Templates Disponibles
|
||||
|
||||
### `basic_test.json`
|
||||
**Propósito**: Pruebas básicas de funcionalidad
|
||||
- Operaciones con FourBytes (IPs)
|
||||
- Operaciones con IntBase (números en diferentes bases)
|
||||
- Variables y tabla de símbolos
|
||||
- Funciones de SymPy
|
||||
|
||||
### `tokenization_test.json`
|
||||
**Propósito**: Debug del sistema de tokenización
|
||||
- Análisis de expresiones complejas
|
||||
- Información de reglas de tokenización
|
||||
- Procesamiento de expressions mixtas (IP + hex)
|
||||
|
||||
### `regression_test.json`
|
||||
**Propósito**: Testing de regresión para casos específicos
|
||||
- Verificación de tipos: FourBytes, IntBase, IP4Mask
|
||||
- Operaciones simbólicas
|
||||
- Substitución de variables
|
||||
|
||||
### `error_debug.json`
|
||||
**Propósito**: Debug de manejo de errores
|
||||
- Máscaras IP inválidas
|
||||
- IPs fuera de rango
|
||||
- Números hexadecimales malformados
|
||||
- División por cero
|
||||
- Variables indefinidas
|
||||
|
||||
### `context_debug.json`
|
||||
**Propósito**: Debug del contexto y estado del motor
|
||||
- Tabla de símbolos
|
||||
- Tipos registrados
|
||||
- Contexto base
|
||||
- Sistema de ecuaciones
|
||||
|
||||
### `display_format_test.json`
|
||||
**Propósito**: Demostración de formatos de display y output_raw
|
||||
- Diferentes tipos de resultados (IP, hex, símbolos, matrices)
|
||||
- Comentarios y errores
|
||||
- Comparación entre `output` y `output_raw`
|
||||
|
||||
## Formato de Template
|
||||
|
||||
Cada template es un archivo JSON con esta estructura:
|
||||
|
||||
```json
|
||||
{
|
||||
"queries": [
|
||||
{
|
||||
"index": 0,
|
||||
"type": "input",
|
||||
"content": "10.1.1.1 + 1"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"type": "exec",
|
||||
"content": "type(engine.last_result).__name__"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Tipos de Query
|
||||
|
||||
- **`input`**: Evalúa expresiones como si las escribieras en la calculadora
|
||||
- **`exec`**: Ejecuta código Python para inspeccionar el estado interno del motor
|
||||
|
||||
## Casos de Uso Comunes
|
||||
|
||||
### Debug de un Bug Específico
|
||||
1. Copia `basic_test.json` a `mi_bug_debug.json`
|
||||
2. Modifica las queries para reproducir el bug
|
||||
3. Añade queries `exec` para inspeccionar el estado
|
||||
4. Ejecuta: `python simple_debug.py mi_bug_debug.json`
|
||||
|
||||
### Verificar una Nueva Funcionalidad
|
||||
1. Crea un template con queries `input` que usen la nueva funcionalidad
|
||||
2. Añade queries `exec` para verificar el estado interno
|
||||
3. Compara resultados antes y después de los cambios
|
||||
|
||||
### Testing de Regresión
|
||||
1. Usa `regression_test.json` como base
|
||||
2. Añade casos específicos que deben mantenerse funcionando
|
||||
3. Ejecuta regularmente para detectar regresiones
|
||||
|
||||
## Funciones Útiles para Queries `exec`
|
||||
|
||||
### Estado del Motor
|
||||
```python
|
||||
"engine.symbol_table" # Variables actuales
|
||||
"engine.last_result" # Último resultado
|
||||
"engine.symbolic_mode" # ¿Modo simbólico?
|
||||
"len(engine.equations)" # Cantidad de ecuaciones
|
||||
```
|
||||
|
||||
### Información de Tipos
|
||||
```python
|
||||
"type(engine.last_result).__name__" # Tipo del resultado
|
||||
"engine.get_available_types()" # Tipos disponibles
|
||||
"list(engine.registered_types_info['registered_classes'].keys())"
|
||||
```
|
||||
|
||||
### Tokenización
|
||||
```python
|
||||
"engine.parser.get_tokenization_info()" # Info de tokenización
|
||||
"engine.parser.process_expression('test')" # Procesar expresión
|
||||
```
|
||||
|
||||
### Análisis de Objetos
|
||||
```python
|
||||
"engine.last_result.original" # String original (FourBytes)
|
||||
"engine.last_result.base" # Base numérica (IntBase)
|
||||
"engine.last_result.has_symbols" # ¿Tiene símbolos?
|
||||
```
|
||||
|
||||
## Formato de Resultado
|
||||
|
||||
### Resultado Individual para Query `input`
|
||||
|
||||
```json
|
||||
{
|
||||
"index": 0,
|
||||
"input": "10.1.1.1 + 1",
|
||||
"output": "10.1.1.2",
|
||||
"result_type": "FourBytes",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"display_class": "[FourBytes]",
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
["custom_type", "10.1.1.2"],
|
||||
["class_hint", "[FourBytes]"]
|
||||
],
|
||||
"formatted_text": "[custom_type]10.1.1.2[class_hint][FourBytes]",
|
||||
"tag_info": {
|
||||
"custom_type": {"fg": "#f9a825"},
|
||||
"class_hint": {"fg": "#888888"}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Campos del Resultado
|
||||
|
||||
- **`output`**: Resultado básico (antes del post-procesamiento)
|
||||
- **`output_raw`**: Resultado exacto como se muestra en la aplicación
|
||||
- **`parts`**: Lista de tuplas `[tag, contenido]` con información de color/formato
|
||||
- **`formatted_text`**: Texto formateado como se vería en la aplicación
|
||||
- **`tag_info`**: Información de colores y estilos para cada tag
|
||||
- **`result_type`**: Tipo del objeto resultado
|
||||
- **`display_class`**: Nombre de clase para mostrar
|
||||
|
||||
### Tags de Color Disponibles
|
||||
|
||||
- **`error`**: `#ff6b6b` (rojo) - Errores
|
||||
- **`result`**: `#abdbe3` (azul claro) - Resultados generales
|
||||
- **`symbolic`**: `#82aaff` (azul) - Expresiones simbólicas
|
||||
- **`numeric`**: `#c3e88d` (verde) - Aproximaciones numéricas
|
||||
- **`custom_type`**: `#f9a825` (naranja) - Tipos personalizados
|
||||
- **`ip`**: `#fff176` (amarillo) - Direcciones IP
|
||||
- **`hex`**: `#f9a825` (naranja) - Números hexadecimales
|
||||
- **`class_hint`**: `#888888` (gris) - Pistas de clase
|
||||
|
||||
## Tips
|
||||
|
||||
- Usa `index` secuencial para facilitar la lectura de resultados
|
||||
- Combina queries `input` y `exec` para verificar comportamiento y estado
|
||||
- El archivo de resultados contiene información detallada de éxito/error
|
||||
- **Usa `output_raw` para entender exactamente cómo se mostraría el resultado en la aplicación**
|
||||
- Puedes copiar y modificar templates existentes para casos específicos
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"type": "input",
|
||||
"content": "mask = 255.255.0.0"
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"type": "exec",
|
||||
"content": "engine.symbol_table"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"type": "input",
|
||||
"content": "solve(x**2 + 1, x)"
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"type": "exec",
|
||||
"content": "len(engine.symbol_table)"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"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)"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"type": "exec",
|
||||
"content": "list(engine.base_context.keys())[:10]"
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"type": "exec",
|
||||
"content": "engine.get_available_types()"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"type": "exec",
|
||||
"content": "list(engine.registered_types_info['registered_classes'].keys())"
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"type": "exec",
|
||||
"content": "engine.registered_types_info['class_count']"
|
||||
},
|
||||
{
|
||||
"index": 8,
|
||||
"type": "input",
|
||||
"content": "z = solve(a**2 + b, a)"
|
||||
},
|
||||
{
|
||||
"index": 9,
|
||||
"type": "exec",
|
||||
"content": "engine._classify_line('z = solve(a**2 + b, a)')"
|
||||
},
|
||||
{
|
||||
"index": 10,
|
||||
"type": "exec",
|
||||
"content": "engine._extract_variable_names('x + y + z')"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"queries": [
|
||||
{
|
||||
"index": 0,
|
||||
"type": "input",
|
||||
"content": "192.168.1.1 + 1"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"type": "exec",
|
||||
"content": "engine.last_result"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"type": "input",
|
||||
"content": "16#FF00"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"type": "exec",
|
||||
"content": "engine.last_result.base"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"type": "input",
|
||||
"content": "x = solve(a**2 - 4, a)"
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"type": "exec",
|
||||
"content": "type(engine.symbol_table['x'])"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"type": "input",
|
||||
"content": "IP4Mask(255.255.255.0)"
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"type": "exec",
|
||||
"content": "engine.last_result.get_prefix_int()"
|
||||
},
|
||||
{
|
||||
"index": 8,
|
||||
"type": "input",
|
||||
"content": "# Este es un comentario"
|
||||
},
|
||||
{
|
||||
"index": 9,
|
||||
"type": "input",
|
||||
"content": "invalid_expression"
|
||||
},
|
||||
{
|
||||
"index": 10,
|
||||
"type": "input",
|
||||
"content": "matriz = Matrix([[1, 2], [3, 4]])"
|
||||
},
|
||||
{
|
||||
"index": 11,
|
||||
"type": "exec",
|
||||
"content": "engine.symbol_table['matriz'].shape"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"type": "input",
|
||||
"content": "invalid_ip = 300.1.1.1"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"type": "exec",
|
||||
"content": "hasattr(engine, 'last_error')"
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"type": "input",
|
||||
"content": "16#GG"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"type": "exec",
|
||||
"content": "engine.debug"
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"type": "input",
|
||||
"content": "divide_by_zero = 10/0"
|
||||
},
|
||||
{
|
||||
"index": 8,
|
||||
"type": "exec",
|
||||
"content": "engine.symbolic_mode"
|
||||
},
|
||||
{
|
||||
"index": 9,
|
||||
"type": "input",
|
||||
"content": "undefined_var + 5"
|
||||
},
|
||||
{
|
||||
"index": 10,
|
||||
"type": "exec",
|
||||
"content": "list(engine.symbol_table.keys())"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
{
|
||||
"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": "exec",
|
||||
"content": "engine.last_result.original"
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"type": "input",
|
||||
"content": "IP4Mask(255.255.0.0)"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"type": "exec",
|
||||
"content": "engine.last_result.get_prefix_int()"
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"type": "input",
|
||||
"content": "16#FF + 10"
|
||||
},
|
||||
{
|
||||
"index": 8,
|
||||
"type": "exec",
|
||||
"content": "engine.last_result.base"
|
||||
},
|
||||
{
|
||||
"index": 9,
|
||||
"type": "exec",
|
||||
"content": "engine.last_result.value_str"
|
||||
},
|
||||
{
|
||||
"index": 10,
|
||||
"type": "input",
|
||||
"content": "ip = 10.1.1.x"
|
||||
},
|
||||
{
|
||||
"index": 11,
|
||||
"type": "exec",
|
||||
"content": "type(engine.symbol_table['ip'])"
|
||||
},
|
||||
{
|
||||
"index": 12,
|
||||
"type": "exec",
|
||||
"content": "engine.symbol_table['ip'].has_symbols"
|
||||
},
|
||||
{
|
||||
"index": 13,
|
||||
"type": "input",
|
||||
"content": "ip.substitute(x=5)"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"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]"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"type": "input",
|
||||
"content": "10.0.0.0/8 + 1"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"type": "exec",
|
||||
"content": "engine.parser.get_tokenization_info()"
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"type": "input",
|
||||
"content": "x = 192.168.y.z"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"type": "exec",
|
||||
"content": "engine.parser.process_expression('x = 192.168.y.z')"
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"type": "exec",
|
||||
"content": "len(engine.parser.tokenizer.tokenization_rules)"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,569 @@
|
|||
{
|
||||
"execution_info": {
|
||||
"timestamp": "2025-06-05T18:11:38.337776Z",
|
||||
"total_queries": 12,
|
||||
"successful": 12,
|
||||
"failed": 0,
|
||||
"input_file": "debug_templates\\display_format_test.json"
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"index": 0,
|
||||
"input": "192.168.1.1 + 1",
|
||||
"output": "192.168.1.2",
|
||||
"result_type": "FourBytes",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"custom_type",
|
||||
"192.168.1.2"
|
||||
],
|
||||
[
|
||||
"class_hint",
|
||||
"[FourBytes]"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[custom_type]192.168.1.2[class_hint][FourBytes]",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[FourBytes]"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"input": "engine.last_result",
|
||||
"output": "192.168.1.2",
|
||||
"result_type": "FourBytes",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": "192.168.1.2"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"input": "16#FF00",
|
||||
"output": "16#FF00",
|
||||
"result_type": "IntBase",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"custom_type",
|
||||
"16#FF00"
|
||||
],
|
||||
[
|
||||
"class_hint",
|
||||
"[IntBase]"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[custom_type]16#FF00[class_hint][IntBase]",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[IntBase]"
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"input": "engine.last_result.base",
|
||||
"output": "16",
|
||||
"result_type": "int",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": 16
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"input": "x = solve(a**2 - 4, a)",
|
||||
"output": "[-2, 2]",
|
||||
"result_type": "list",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"info",
|
||||
"x = [-2, 2]"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[info]x = [-2, 2]",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[list]"
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"input": "type(engine.symbol_table['x'])",
|
||||
"output": "<class 'list'>",
|
||||
"result_type": "type",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": "<class 'list'>"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"input": "IP4Mask(255.255.255.0)",
|
||||
"output": "255.255.255.0",
|
||||
"result_type": "IP4Mask",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"custom_type",
|
||||
"255.255.255.0"
|
||||
],
|
||||
[
|
||||
"class_hint",
|
||||
"[IP4Mask]"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[custom_type]255.255.255.0[class_hint][IP4Mask]",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[IP4Mask]"
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"input": "engine.last_result.get_prefix_int()",
|
||||
"output": "24",
|
||||
"result_type": "int",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": 24
|
||||
},
|
||||
{
|
||||
"index": 8,
|
||||
"input": "# Este es un comentario",
|
||||
"output": "None",
|
||||
"result_type": "NoneType",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"comment",
|
||||
"# Este es un comentario"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[comment]# Este es un comentario",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[NoneType]"
|
||||
},
|
||||
{
|
||||
"index": 9,
|
||||
"input": "invalid_expression",
|
||||
"output": "invalid_expression",
|
||||
"result_type": "Symbol",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"symbolic",
|
||||
"invalid_expression"
|
||||
],
|
||||
[
|
||||
"class_hint",
|
||||
"[Sympy]"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[symbolic]invalid_expression[class_hint][Sympy]",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[Symbol]"
|
||||
},
|
||||
{
|
||||
"index": 10,
|
||||
"input": "matriz = Matrix([[1, 2], [3, 4]])",
|
||||
"output": "Matrix([[1, 2], [3, 4]])",
|
||||
"result_type": "MutableDenseMatrix",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"info",
|
||||
"matriz = Matrix([[1, 2], [3, 4]])"
|
||||
],
|
||||
[
|
||||
"numeric",
|
||||
"≈ Matrix([[1.00000000000000, 2.00000000000000], [3.00000000000000, 4.00000000000000]])"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[info]matriz = Matrix([[1, 2], [3, 4]]) [numeric]≈ Matrix([[1.00000000000000, 2.00000000000000], [3.00000000000000, 4.00000000000000]])",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[MutableDenseMatrix]"
|
||||
},
|
||||
{
|
||||
"index": 11,
|
||||
"input": "engine.symbol_table['matriz'].shape",
|
||||
"output": "(2, 2)",
|
||||
"result_type": "tuple",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": [
|
||||
2,
|
||||
2
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
{
|
||||
"execution_info": {
|
||||
"timestamp": "2025-06-05T18:01:38.085095Z",
|
||||
"total_queries": 11,
|
||||
"successful": 9,
|
||||
"failed": 2,
|
||||
"input_file": "debug_templates\\error_debug.json"
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"index": 0,
|
||||
"input": "bad_mask = 255.240.0.3",
|
||||
"output": "255.240.0.3",
|
||||
"result_type": "FourBytes",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"display_class": "[FourBytes]"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"input": "IP4Mask(bad_mask)",
|
||||
"output": "None",
|
||||
"result_type": "NoneType",
|
||||
"success": false,
|
||||
"error": "\n❌ Máscara inválida: 255.240.0.3 (0xFFF00003)\n\n🔍 Análisis binario: 11111111.11110000.00000000.00000011\n Los bits deben ser contiguos: todos los 1s seguidos de todos los 0s\n\n✅ Ejemplos de máscaras válidas:\n /24 → 255.255.255.0 (11111111.11111111.11111111.00000000)\n /20 → 255.240.0.0 (11111111.11110000.00000000.00000000)\n /16 → 255.255.0.0 (11111111.11111111.00000000.00000000)\n /12 → 255.240.0.0 (11111111.11110000.00000000.00000000)\n\n💡 ¿Quizás querías usar 255.240.0.0 en lugar de 255.240.0.3?\n",
|
||||
"display_class": "[NoneType]"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"input": "engine.last_result",
|
||||
"output": "None",
|
||||
"result_type": "NoneType",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": null
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"input": "invalid_ip = 300.1.1.1",
|
||||
"output": "None",
|
||||
"result_type": "NoneType",
|
||||
"success": false,
|
||||
"error": "Error en asignación: Elemento inválido: '300'",
|
||||
"display_class": "[NoneType]"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"input": "hasattr(engine, 'last_error')",
|
||||
"output": "False",
|
||||
"result_type": "bool",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": false
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"input": "16#GG",
|
||||
"output": "16",
|
||||
"result_type": "Integer",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"display_class": "[Integer]"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"input": "engine.debug",
|
||||
"output": "False",
|
||||
"result_type": "bool",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": false
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"input": "divide_by_zero = 10/0",
|
||||
"output": "zoo",
|
||||
"result_type": "ComplexInfinity",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"display_class": "[ComplexInfinity]"
|
||||
},
|
||||
{
|
||||
"index": 8,
|
||||
"input": "engine.symbolic_mode",
|
||||
"output": "True",
|
||||
"result_type": "bool",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": true
|
||||
},
|
||||
{
|
||||
"index": 9,
|
||||
"input": "undefined_var + 5",
|
||||
"output": "undefined_var + 5",
|
||||
"result_type": "Add",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"display_class": "[Add]"
|
||||
},
|
||||
{
|
||||
"index": 10,
|
||||
"input": "list(engine.symbol_table.keys())",
|
||||
"output": "['bad_mask', 'divide_by_zero']",
|
||||
"result_type": "list",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": [
|
||||
"bad_mask",
|
||||
"divide_by_zero"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,491 @@
|
|||
{
|
||||
"execution_info": {
|
||||
"timestamp": "2025-06-05T18:11:18.061505Z",
|
||||
"total_queries": 11,
|
||||
"successful": 9,
|
||||
"failed": 2,
|
||||
"input_file": "debug_templates\\error_debug.json"
|
||||
},
|
||||
"results": [
|
||||
{
|
||||
"index": 0,
|
||||
"input": "bad_mask = 255.240.0.3",
|
||||
"output": "255.240.0.3",
|
||||
"result_type": "FourBytes",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"info",
|
||||
"bad_mask = 255.240.0.3"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[info]bad_mask = 255.240.0.3",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[FourBytes]"
|
||||
},
|
||||
{
|
||||
"index": 1,
|
||||
"input": "IP4Mask(bad_mask)",
|
||||
"output": "None",
|
||||
"result_type": "NoneType",
|
||||
"success": false,
|
||||
"error": "\n❌ Máscara inválida: 255.240.0.3 (0xFFF00003)\n\n🔍 Análisis binario: 11111111.11110000.00000000.00000011\n Los bits deben ser contiguos: todos los 1s seguidos de todos los 0s\n\n✅ Ejemplos de máscaras válidas:\n /24 → 255.255.255.0 (11111111.11111111.11111111.00000000)\n /20 → 255.240.0.0 (11111111.11110000.00000000.00000000)\n /16 → 255.255.0.0 (11111111.11111111.00000000.00000000)\n /12 → 255.240.0.0 (11111111.11110000.00000000.00000000)\n\n💡 ¿Quizás querías usar 255.240.0.0 en lugar de 255.240.0.3?\n",
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"error",
|
||||
"Error: \n❌ Máscara inválida: 255.240.0.3 (0xFFF00003)\n\n🔍 Análisis binario: 11111111.11110000.00000000.00000011\n Los bits deben ser contiguos: todos los 1s seguidos de todos los 0s\n\n✅ Ejemplos de máscaras válidas:\n /24 → 255.255.255.0 (11111111.11111111.11111111.00000000)\n /20 → 255.240.0.0 (11111111.11110000.00000000.00000000)\n /16 → 255.255.0.0 (11111111.11111111.00000000.00000000)\n /12 → 255.240.0.0 (11111111.11110000.00000000.00000000)\n\n💡 ¿Quizás querías usar 255.240.0.0 en lugar de 255.240.0.3?\n"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[error]Error: \n❌ Máscara inválida: 255.240.0.3 (0xFFF00003)\n\n🔍 Análisis binario: 11111111.11110000.00000000.00000011\n Los bits deben ser contiguos: todos los 1s seguidos de todos los 0s\n\n✅ Ejemplos de máscaras válidas:\n /24 → 255.255.255.0 (11111111.11111111.11111111.00000000)\n /20 → 255.240.0.0 (11111111.11110000.00000000.00000000)\n /16 → 255.255.0.0 (11111111.11111111.00000000.00000000)\n /12 → 255.240.0.0 (11111111.11110000.00000000.00000000)\n\n💡 ¿Quizás querías usar 255.240.0.0 en lugar de 255.240.0.3?\n",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[NoneType]"
|
||||
},
|
||||
{
|
||||
"index": 2,
|
||||
"input": "engine.last_result",
|
||||
"output": "None",
|
||||
"result_type": "NoneType",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": null
|
||||
},
|
||||
{
|
||||
"index": 3,
|
||||
"input": "invalid_ip = 300.1.1.1",
|
||||
"output": "None",
|
||||
"result_type": "NoneType",
|
||||
"success": false,
|
||||
"error": "Error en asignación: Elemento inválido: '300'",
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"error",
|
||||
"Error: Error en asignación: Elemento inválido: '300'"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[error]Error: Error en asignación: Elemento inválido: '300'",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[NoneType]"
|
||||
},
|
||||
{
|
||||
"index": 4,
|
||||
"input": "hasattr(engine, 'last_error')",
|
||||
"output": "False",
|
||||
"result_type": "bool",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": false
|
||||
},
|
||||
{
|
||||
"index": 5,
|
||||
"input": "16#GG",
|
||||
"output": "16",
|
||||
"result_type": "Integer",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"symbolic",
|
||||
"16"
|
||||
],
|
||||
[
|
||||
"class_hint",
|
||||
"[Integer]"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[symbolic]16[class_hint][Integer]",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[Integer]"
|
||||
},
|
||||
{
|
||||
"index": 6,
|
||||
"input": "engine.debug",
|
||||
"output": "False",
|
||||
"result_type": "bool",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": false
|
||||
},
|
||||
{
|
||||
"index": 7,
|
||||
"input": "divide_by_zero = 10/0",
|
||||
"output": "zoo",
|
||||
"result_type": "ComplexInfinity",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"info",
|
||||
"divide_by_zero = zoo"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[info]divide_by_zero = zoo",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[ComplexInfinity]"
|
||||
},
|
||||
{
|
||||
"index": 8,
|
||||
"input": "engine.symbolic_mode",
|
||||
"output": "True",
|
||||
"result_type": "bool",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": true
|
||||
},
|
||||
{
|
||||
"index": 9,
|
||||
"input": "undefined_var + 5",
|
||||
"output": "undefined_var + 5",
|
||||
"result_type": "Add",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"output_raw": {
|
||||
"parts": [
|
||||
[
|
||||
"symbolic",
|
||||
"undefined_var + 5"
|
||||
],
|
||||
[
|
||||
"class_hint",
|
||||
"[Sympy]"
|
||||
],
|
||||
[
|
||||
"numeric",
|
||||
"≈ undefined_var + 5.0"
|
||||
]
|
||||
],
|
||||
"formatted_text": "[symbolic]undefined_var + 5[class_hint][Sympy] [numeric]≈ undefined_var + 5.0",
|
||||
"tag_info": {
|
||||
"error": {
|
||||
"fg": "#ff6b6b",
|
||||
"font": "bold"
|
||||
},
|
||||
"result": {
|
||||
"fg": "#abdbe3"
|
||||
},
|
||||
"symbolic": {
|
||||
"fg": "#82aaff"
|
||||
},
|
||||
"numeric": {
|
||||
"fg": "#c3e88d"
|
||||
},
|
||||
"equation": {
|
||||
"fg": "#c792ea"
|
||||
},
|
||||
"info": {
|
||||
"fg": "#ffcb6b"
|
||||
},
|
||||
"comment": {
|
||||
"fg": "#546e7a"
|
||||
},
|
||||
"class_hint": {
|
||||
"fg": "#888888"
|
||||
},
|
||||
"type_hint": {
|
||||
"fg": "#6a6a6a"
|
||||
},
|
||||
"custom_type": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"hex": {
|
||||
"fg": "#f9a825"
|
||||
},
|
||||
"bin": {
|
||||
"fg": "#4fc3f7"
|
||||
},
|
||||
"ip": {
|
||||
"fg": "#fff176"
|
||||
},
|
||||
"date": {
|
||||
"fg": "#ff8a80"
|
||||
},
|
||||
"chr_type": {
|
||||
"fg": "#80cbc4"
|
||||
},
|
||||
"helper": {
|
||||
"fg": "#ffd700",
|
||||
"font": "italic"
|
||||
}
|
||||
}
|
||||
},
|
||||
"display_class": "[Add]"
|
||||
},
|
||||
{
|
||||
"index": 10,
|
||||
"input": "list(engine.symbol_table.keys())",
|
||||
"output": "['bad_mask', 'divide_by_zero']",
|
||||
"result_type": "list",
|
||||
"success": true,
|
||||
"error": null,
|
||||
"exec_result": [
|
||||
"bad_mask",
|
||||
"divide_by_zero"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
mask=255.240.0.x
|
||||
mask=255.240.0.0
|
||||
mask.ToHex()
|
||||
ip=10.1.1.x
|
||||
10.1.1.1 + 1
|
||||
|
@ -7,4 +7,6 @@ ip
|
|||
|
||||
IP4(10.1.1.4)
|
||||
IP4Mask(mask)
|
||||
IP4Mask(255.255.0.0)
|
||||
IP4Mask(255.255.0.0)
|
||||
|
||||
bad_mask = 255.240.0.3
|
|
@ -0,0 +1,462 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple Debug API - Calculadora MAV CAS
|
||||
|
||||
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:
|
||||
python simple_debug.py debug_input.json
|
||||
python simple_debug.py debug_input.json --output debug_results.json
|
||||
python simple_debug.py debug_input.json --verbose
|
||||
"""
|
||||
|
||||
import json
|
||||
import sys
|
||||
import argparse
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
# Importar el motor de evaluación existente
|
||||
from main_evaluation import HybridEvaluationEngine
|
||||
import sympy
|
||||
|
||||
|
||||
def _process_evaluation_result_for_debug(result, engine):
|
||||
"""
|
||||
Procesa el resultado de evaluación tal como lo haría la aplicación
|
||||
Retorna información de formato, colores y contenido exacto
|
||||
"""
|
||||
output_parts = []
|
||||
|
||||
if result.is_error:
|
||||
# Intentar obtener ayuda como lo hace la app
|
||||
ayuda = _obtener_ayuda_simulada(result.original_line, engine)
|
||||
if ayuda:
|
||||
ayuda_linea = ayuda.replace("\n", " ").replace("\r", " ")
|
||||
if len(ayuda_linea) > 120:
|
||||
ayuda_linea = ayuda_linea[:117] + "..."
|
||||
output_parts.append(("helper", ayuda_linea))
|
||||
else:
|
||||
output_parts.append(("error", f"Error: {result.error}"))
|
||||
elif result.result_type == "comment":
|
||||
output_parts.append(("comment", result.original_line))
|
||||
elif result.result_type == "equation_added":
|
||||
output_parts.append(("equation", result.symbolic_result))
|
||||
elif result.result_type == "assignment":
|
||||
output_parts.append(("info", result.symbolic_result))
|
||||
# Mostrar evaluación numérica para asignaciones si existe
|
||||
if result.numeric_result is not None and result.numeric_result != result.result:
|
||||
output_parts.append(("numeric", f"≈ {result.numeric_result}"))
|
||||
else:
|
||||
# Resultado normal
|
||||
if result.result is not None:
|
||||
# Determinar tag basado en tipo (simulando lógica dinámica)
|
||||
tag = _get_result_tag_dynamic_debug(result.result, engine)
|
||||
|
||||
# Verificar si es resultado interactivo (simulado)
|
||||
if _is_interactive_result(result.result):
|
||||
interactive_tag, display_text = _create_interactive_tag_debug(result.result)
|
||||
if interactive_tag:
|
||||
output_parts.append((interactive_tag, display_text))
|
||||
else:
|
||||
output_parts.append((tag, str(result.result)))
|
||||
else:
|
||||
output_parts.append((tag, str(result.result)))
|
||||
|
||||
# Añadir pista de clase para el resultado principal
|
||||
class_display_name = _get_class_display_name_dynamic_debug(result.result, engine)
|
||||
if class_display_name:
|
||||
output_parts.append(("class_hint", f"[{class_display_name}]"))
|
||||
|
||||
# Mostrar evaluación numérica si existe
|
||||
if result.numeric_result is not None and result.numeric_result != result.result:
|
||||
output_parts.append(("numeric", f"≈ {result.numeric_result}"))
|
||||
|
||||
# Mostrar información adicional
|
||||
if result.info:
|
||||
output_parts.append(("info", f"({result.info})"))
|
||||
|
||||
# Convertir partes a string formateado como la app
|
||||
formatted_output = _format_output_parts_debug(output_parts)
|
||||
|
||||
return {
|
||||
'parts': output_parts,
|
||||
'formatted_text': formatted_output,
|
||||
'tag_info': _get_tag_color_info()
|
||||
}
|
||||
|
||||
|
||||
def _obtener_ayuda_simulada(input_str, engine):
|
||||
"""Simula la obtención de ayuda como lo hace la app"""
|
||||
try:
|
||||
# Intentar usar los helpers del engine si están disponibles
|
||||
if hasattr(engine, 'HELPERS'):
|
||||
for helper in engine.HELPERS:
|
||||
try:
|
||||
ayuda = helper(input_str)
|
||||
if ayuda:
|
||||
return ayuda
|
||||
except:
|
||||
continue
|
||||
except:
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
def _get_result_tag_dynamic_debug(result, engine):
|
||||
"""Simula _get_result_tag_dynamic de la app"""
|
||||
try:
|
||||
registered_classes = engine.get_available_types().get('registered_classes', {})
|
||||
|
||||
# Verificar si es una instancia de alguna clase registrada
|
||||
for name, cls in registered_classes.items():
|
||||
if isinstance(result, cls):
|
||||
name_lower = name.lower()
|
||||
if name_lower == "hex":
|
||||
return "hex"
|
||||
elif name_lower == "bin":
|
||||
return "bin"
|
||||
elif name_lower in ["ip4", "ip"]:
|
||||
return "ip"
|
||||
elif name_lower == "chr":
|
||||
return "chr_type"
|
||||
elif name_lower == "date":
|
||||
return "date"
|
||||
else:
|
||||
return "custom_type"
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Fallback a tags existentes para tipos no registrados
|
||||
if isinstance(result, sympy.Basic):
|
||||
return "symbolic"
|
||||
else:
|
||||
return "result"
|
||||
|
||||
|
||||
def _get_class_display_name_dynamic_debug(obj, engine):
|
||||
"""Simula _get_class_display_name_dynamic de la app"""
|
||||
try:
|
||||
# Verificar si es una clase registrada dinámicamente
|
||||
registered_classes = engine.get_available_types().get('registered_classes', {})
|
||||
|
||||
for name, cls in registered_classes.items():
|
||||
if isinstance(obj, cls):
|
||||
return name
|
||||
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Fallback a lógica existente para tipos nativos
|
||||
if isinstance(obj, sympy.logic.boolalg.BooleanAtom):
|
||||
return "Boolean"
|
||||
elif isinstance(obj, sympy.Basic):
|
||||
if hasattr(obj, 'is_number') and obj.is_number:
|
||||
if hasattr(obj, 'is_Integer') and obj.is_Integer:
|
||||
return "Integer"
|
||||
elif hasattr(obj, 'is_Rational') and obj.is_Rational and not obj.is_Integer:
|
||||
return "Rational"
|
||||
elif hasattr(obj, 'is_Float') and obj.is_Float:
|
||||
return "Float"
|
||||
else:
|
||||
return "SympyNumber"
|
||||
else:
|
||||
return "Sympy"
|
||||
elif isinstance(obj, bool):
|
||||
return "Boolean"
|
||||
elif isinstance(obj, (int, float, str, list, dict, tuple, type(None))):
|
||||
class_display_name = type(obj).__name__.capitalize()
|
||||
if class_display_name == "Nonetype":
|
||||
class_display_name = "None"
|
||||
return class_display_name
|
||||
|
||||
return ""
|
||||
|
||||
|
||||
def _is_interactive_result(result):
|
||||
"""Simula la lógica is_interactive de EvaluationResult"""
|
||||
try:
|
||||
# Intentar importar PlotResult si existe
|
||||
from tl_popup import PlotResult
|
||||
if isinstance(result, PlotResult):
|
||||
return True
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
return isinstance(result, sympy.Matrix) or \
|
||||
(isinstance(result, list) and len(result) > 3)
|
||||
|
||||
|
||||
def _create_interactive_tag_debug(result):
|
||||
"""Simula la creación de tags interactivos"""
|
||||
try:
|
||||
from tl_popup import PlotResult
|
||||
if isinstance(result, PlotResult):
|
||||
return f"plot_{id(result)}", f"📊 Ver {result.plot_type.title()}"
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
if isinstance(result, sympy.Matrix):
|
||||
rows, cols = result.shape
|
||||
return f"matrix_{id(result)}", f"📋 Ver Matriz {rows}×{cols}"
|
||||
elif isinstance(result, list) and len(result) > 5:
|
||||
return f"list_{id(result)}", f"📋 Ver Lista ({len(result)} elementos)"
|
||||
elif isinstance(result, dict) and len(result) > 3:
|
||||
return f"dict_{id(result)}", f"🔍 Ver Diccionario ({len(result)} entradas)"
|
||||
|
||||
return None, None
|
||||
|
||||
|
||||
def _format_output_parts_debug(output_parts):
|
||||
"""Simula cómo _display_output formatea las partes para mostrar"""
|
||||
formatted_lines = []
|
||||
|
||||
for part_idx, (tag, content) in enumerate(output_parts):
|
||||
if not content:
|
||||
continue
|
||||
|
||||
prefix = ""
|
||||
if part_idx > 0:
|
||||
prev_tag, prev_content = output_parts[part_idx-1] if part_idx > 0 else (None, None)
|
||||
|
||||
if tag not in ["class_hint", "numeric", "info"] and prev_content:
|
||||
prefix = " ; "
|
||||
elif tag in ["numeric", "info"] and prev_content:
|
||||
prefix = " "
|
||||
|
||||
formatted_lines.append(f"{prefix}[{tag}]{content}")
|
||||
|
||||
return "".join(formatted_lines)
|
||||
|
||||
|
||||
def _get_tag_color_info():
|
||||
"""Información sobre los colores de los tags como en setup_output_tags"""
|
||||
return {
|
||||
"error": {"fg": "#ff6b6b", "font": "bold"},
|
||||
"result": {"fg": "#abdbe3"},
|
||||
"symbolic": {"fg": "#82aaff"},
|
||||
"numeric": {"fg": "#c3e88d"},
|
||||
"equation": {"fg": "#c792ea"},
|
||||
"info": {"fg": "#ffcb6b"},
|
||||
"comment": {"fg": "#546e7a"},
|
||||
"class_hint": {"fg": "#888888"},
|
||||
"type_hint": {"fg": "#6a6a6a"},
|
||||
"custom_type": {"fg": "#f9a825"},
|
||||
"hex": {"fg": "#f9a825"},
|
||||
"bin": {"fg": "#4fc3f7"},
|
||||
"ip": {"fg": "#fff176"},
|
||||
"date": {"fg": "#ff8a80"},
|
||||
"chr_type": {"fg": "#80cbc4"},
|
||||
"helper": {"fg": "#ffd700", "font": "italic"}
|
||||
}
|
||||
|
||||
|
||||
def run_debug(input_file: str, output_file: str = None, verbose: bool = False):
|
||||
"""
|
||||
Ejecuta las queries de debug desde un archivo JSON y guarda los resultados.
|
||||
|
||||
Args:
|
||||
input_file: Archivo JSON con las queries
|
||||
output_file: Archivo de salida (opcional)
|
||||
verbose: Modo verboso
|
||||
"""
|
||||
|
||||
# Cargar queries del archivo de entrada
|
||||
try:
|
||||
with open(input_file, 'r', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
except FileNotFoundError:
|
||||
print(f"Error: No se encontró el archivo '{input_file}'")
|
||||
sys.exit(1)
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"Error: JSON inválido en '{input_file}': {e}")
|
||||
sys.exit(1)
|
||||
|
||||
if 'queries' not in data:
|
||||
print("Error: El archivo JSON debe contener una clave 'queries'")
|
||||
sys.exit(1)
|
||||
|
||||
# Crear motor de evaluación
|
||||
if verbose:
|
||||
print("Iniciando motor de evaluación...")
|
||||
|
||||
engine = HybridEvaluationEngine()
|
||||
results = []
|
||||
successful = 0
|
||||
failed = 0
|
||||
|
||||
# Ejecutar cada query
|
||||
for query in data['queries']:
|
||||
if verbose:
|
||||
print(f"Ejecutando query {query.get('index', '?')}: {query.get('content', '')[:50]}...")
|
||||
|
||||
try:
|
||||
if query['type'] == 'input':
|
||||
# Query de tipo input: evaluar expresión como si fuera entrada del usuario
|
||||
result = engine.evaluate_line(query['content'])
|
||||
|
||||
output = {
|
||||
'index': query['index'],
|
||||
'input': query['content'],
|
||||
'output': str(result.result) if hasattr(result, 'result') else str(result),
|
||||
'result_type': type(result.result).__name__ if hasattr(result, 'result') else type(result).__name__,
|
||||
'success': not (hasattr(result, 'is_error') and result.is_error),
|
||||
'error': result.error if hasattr(result, 'is_error') and result.is_error else None
|
||||
}
|
||||
|
||||
# Generar output_raw: resultado exacto como se muestra en la aplicación
|
||||
try:
|
||||
output_raw_data = _process_evaluation_result_for_debug(result, engine)
|
||||
output['output_raw'] = output_raw_data
|
||||
except Exception as e:
|
||||
output['output_raw'] = f"Error generando output_raw: {e}"
|
||||
|
||||
# Añadir información adicional si está disponible
|
||||
if hasattr(result, 'result') and hasattr(result.result, '__class__'):
|
||||
output['display_class'] = f"[{result.result.__class__.__name__}]"
|
||||
|
||||
if not (hasattr(result, 'is_error') and result.is_error):
|
||||
successful += 1
|
||||
else:
|
||||
failed += 1
|
||||
|
||||
elif query['type'] == 'exec':
|
||||
# Query de tipo exec: ejecutar código Python para inspeccionar el estado
|
||||
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,
|
||||
'error': None,
|
||||
'exec_result': exec_result
|
||||
}
|
||||
successful += 1
|
||||
|
||||
else:
|
||||
raise ValueError(f"Tipo de query desconocido: {query['type']}")
|
||||
|
||||
except Exception as e:
|
||||
# Manejar errores en la ejecución
|
||||
output = {
|
||||
'index': query['index'],
|
||||
'input': query['content'],
|
||||
'output': None,
|
||||
'result_type': None,
|
||||
'success': False,
|
||||
'error': str(e)
|
||||
}
|
||||
failed += 1
|
||||
|
||||
if verbose:
|
||||
print(f" Error: {str(e)}")
|
||||
|
||||
results.append(output)
|
||||
|
||||
# Preparar salida final
|
||||
final_output = {
|
||||
'execution_info': {
|
||||
'timestamp': datetime.now().isoformat() + 'Z',
|
||||
'total_queries': len(data['queries']),
|
||||
'successful': successful,
|
||||
'failed': failed,
|
||||
'input_file': input_file
|
||||
},
|
||||
'results': results
|
||||
}
|
||||
|
||||
# Determinar archivo de salida
|
||||
if output_file is None:
|
||||
base_name = Path(input_file).stem
|
||||
output_file = f"{base_name}_results.json"
|
||||
|
||||
# Guardar resultados
|
||||
try:
|
||||
# Usar un encoder personalizado para objetos no serializables
|
||||
def json_serializer(obj):
|
||||
"""Serializar objetos no estándar a string"""
|
||||
try:
|
||||
# Intentar conversión normal primero
|
||||
json.dumps(obj)
|
||||
return obj
|
||||
except TypeError:
|
||||
# Si no es serializable, convertir a string
|
||||
return str(obj)
|
||||
|
||||
# Aplicar serialización personalizada a exec_result
|
||||
for result in final_output['results']:
|
||||
if 'exec_result' in result:
|
||||
result['exec_result'] = json_serializer(result['exec_result'])
|
||||
|
||||
with open(output_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(final_output, f, indent=2, ensure_ascii=False, default=str)
|
||||
|
||||
if verbose:
|
||||
print(f"\nResultados guardados en: {output_file}")
|
||||
print(f"Queries exitosas: {successful}")
|
||||
print(f"Queries con error: {failed}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error al guardar resultados: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
return final_output
|
||||
|
||||
|
||||
def main():
|
||||
"""Función principal del CLI"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Simple Debug API para Calculadora MAV CAS',
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Ejemplos de uso:
|
||||
python simple_debug.py debug_input.json
|
||||
python simple_debug.py debug_input.json --output custom_results.json
|
||||
python simple_debug.py debug_input.json --verbose
|
||||
"""
|
||||
)
|
||||
|
||||
parser.add_argument('input_file',
|
||||
help='Archivo JSON con las queries de debug')
|
||||
parser.add_argument('--output', '-o',
|
||||
help='Archivo de salida (por defecto: <input>_results.json)')
|
||||
parser.add_argument('--verbose', '-v',
|
||||
action='store_true',
|
||||
help='Modo verboso')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Verificar que el archivo de entrada existe
|
||||
if not Path(args.input_file).exists():
|
||||
print(f"Error: El archivo '{args.input_file}' no existe")
|
||||
sys.exit(1)
|
||||
|
||||
# Ejecutar debug
|
||||
try:
|
||||
results = run_debug(args.input_file, args.output, args.verbose)
|
||||
|
||||
# Mostrar resumen si no es modo verboso
|
||||
if not args.verbose:
|
||||
info = results['execution_info']
|
||||
print(f"Debug completado: {info['successful']}/{info['total_queries']} exitosas")
|
||||
if args.output:
|
||||
print(f"Resultados en: {args.output}")
|
||||
else:
|
||||
base_name = Path(args.input_file).stem
|
||||
print(f"Resultados en: {base_name}_results.json")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nInterrumpido por el usuario")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"Error inesperado: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Reference in New Issue