712 lines
22 KiB
Markdown
712 lines
22 KiB
Markdown
# 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* |