Skip to content

Primera entrega: Implementación de analizador de fórmulas tipo Excel #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# 🧮 Archivo: `logic.py`

Este archivo implementa una clase llamada `Logic` en Python, la cual sirve como un **intérprete básico de expresiones tipo Excel**. Su propósito es descomponer una fórmula dada en sus partes fundamentales: funciones, constantes, referencias a celdas y rangos.

---

## ✨ Funcionalidad del archivo

Al ejecutar el script, el usuario puede ingresar una fórmula por consola (por ejemplo: `=SUMA(1,A1,B2:B5)`), y el programa identificará automáticamente:

- Funciones utilizadas (`SUMA`)
- Números constantes (`1`)
- Referencias a celdas individuales (`A1`)
- Rangos de celdas (`B2:B5`)

---

## 📌 Estructura del código

El archivo contiene:

### Clase: `Logic`

| Método | Función |
|---------------------|-------------------------------------------------------------------------|
| `__init__` | Inicializa la expresión y prepara los contenedores |
| `funcionesFun()` | Extrae los nombres de funciones usando expresiones regulares |
| `constantesFun()` | Detecta constantes numéricas en la expresión |
| `referenciasFun()` | Identifica celdas individuales y rangos, evitando duplicación |
| `imprimirCadenaFun()`| Muestra los resultados si la fórmula es válida |
| `clasificacionFun()` | Ejecuta el análisis completo si la cadena inicia con `=` |

### Interfaz por consola

Un bucle `while` al final del archivo permite al usuario probar expresiones hasta ingresar una válida (que comience con `=`).

---

## ▶️ Cómo ejecutar

```bash
python logic_interpreter.py
109 changes: 109 additions & 0 deletions src/logic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import re

# El interprete de las expresiones brindadas
class Logic:
def __init__(self, texto):
self.texto = texto.strip()
self.division = ""
self.constantes = []
self.funciones = []
self.referencias = []
self.rangos = []
self.value = False

def funcionesFun(self):
try:
formula = self.division[1].upper() # Normalizar a mayúsculas
pattern = r"\b([A-Z]+)\s*\("
self.funciones = re.findall(pattern, formula)
except IndexError:
print("No se encontró ninguna función")
except Exception as e:
print(f"Error en funciones: {e}")

def constantesFun(self):
try:
formula = self.division[1]
pattern = r'[-+]?\b\d+(?:\.\d+)?\b'
self.constantes = re.findall(pattern, formula)
except IndexError:
print("No se encontró ninguna constante")
except Exception as e:
print(f"Error en constantes: {e}")

def referenciasFun(self):
try:
formula = self.division[1].upper()
# Detectar rangos como A1:B34
self.rangos = re.findall(r'\b[A-Z]{1,3}[1-9][0-9]{0,4}:[A-Z]{1,3}[1-9][0-9]{0,4}\b', formula)
# Detectar referencias simples (excluyendo las que ya están en rangos)
todas = re.findall(r'\b[A-Z]{1,3}[1-9][0-9]{0,4}\b', formula)
partes_de_rangos = [celda for r in self.rangos for celda in r.split(":")]
self.referencias = [ref for ref in todas if ref not in partes_de_rangos]
except Exception as e:
print(f"Error en referencias: {e}")

def imprimirCadenaFun(self):
if self.value:
print("\n--- Resultado ---")
print(f"Funciones encontradas: {self.funciones}")
print(f"Constantes encontradas: {self.constantes}")
print(f"Referencias individuales: {self.referencias}")
print(f"Rangos detectados: {self.rangos}")
print("------------------\n")
else:
print("No puedes imprimir nada. La fórmula no empieza con '='.")

def direccionamientoFun(self):
funciones_basicas = {"SUMA", "MAX", "MIN", "PROMEDIO"}
funciones_ext = {"SI", "CONTAR.SI", "CONCATENAR"}

print("\n--- Clasificación y Direccionamiento ---")
for constante in self.constantes:
print(f"🔹 Constante '{constante}' → Evaluación directa")

for referencia in self.referencias:
print(f"🔹 Referencia '{referencia}' → Resolución de referencia")

for rango in self.rangos:
print(f"🔹 Rango '{rango}' → Resolución de referencia (rango)")

for funcion in self.funciones:
if funcion in funciones_basicas:
print(f"🔹 Función básica '{funcion}' → Evaluación funcional")
elif funcion in funciones_ext:
print(f"🔹 Función extendida '{funcion}' → Evaluación funcional")
else:
print(f"❌ Función '{funcion}' no reconocida → Error: función desconocida")

print("-----------------------------------------\n")


def clasificacionFun(self):
if "=" in self.texto:
self.value = True
else:
print("❌ La fórmula no contiene '='.")
return

try:
self.division = self.texto.split("=", maxsplit=1)
self.funcionesFun()
self.constantesFun()
self.referenciasFun()
self.imprimirCadenaFun()
self.direccionamientoFun()
except Exception as e:
print(f"Ocurrió un error general: {e}")





#parte para hacer el test de la prueba logica
while True:
test = input("Ingrese su expresión a valorar (ej: =SUMA(1,A1,B2:B5)): ")
prueba = Logic(test)
prueba.clasificacionFun()
if prueba.value:
break