22 KiB
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
y192.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
python calc.py --setup
Método 2: Instalación Manual
# 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)
# 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)
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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:
# 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
# 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 UIhybrid_calc_history.txt
: Historial de sesión anteriorlogs/
: 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
# 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
# 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
# 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
# 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
# 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/
# 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
# 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
@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
# 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
y192.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 únicamenteELIMINADO - ✅ 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?
- Crear archivo en
custom_types/nuevo_type.py
- Implementar clase con
get_tokenization_patterns()
yregister_classes_in_module()
- 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