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