# 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.