Merge branch 'develop' into feature/ui-tablero-cartas

This commit is contained in:
Alexis
2026-03-23 14:05:48 +01:00
2 changed files with 169 additions and 30 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
# deck-of-cards # deck-of-cards
Prueba de feature en una rama hija de develop para hacer un pull request. V2 Prueba de feature en una rama hija de develop para hacer un pull request.
+168 -29
View File
@@ -1,54 +1,193 @@
from fastapi import FastAPI from fastapi import FastAPI
from pydantic import BaseModel from pydantic import BaseModel
from typing import List, Dict from typing import List, Dict, Tuple
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI() app = FastAPI()
# Configuración CORS para permitir peticiones desde React
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Permite cualquier origen (perfecto para desarrollo local)
allow_credentials=True,
allow_methods=["*"], # Permite POST, GET, OPTIONS, etc.
allow_headers=["*"], # Permite cualquier cabecera
)
# -----------------------------
# MODELOS
# -----------------------------
class ValueFunctionRequest(BaseModel): class ValueFunctionRequest(BaseModel):
criterion_name: str criterion_name: str
levels: List[str] levels: List[str]
blank_cards: List[int] blank_cards: List[int]
references: Dict[str, float] references: Dict[str, float]
@app.get("/prueba") class DoCMFRequest(BaseModel):
def prueba(): term: str
return {"mensaje": "¡Hola desde FastAPI! El contenedor de docker está funcionando"} core: Tuple[float, float] # [a, b]
support: Tuple[float, float] # [c, d]
left_nodes_x: List[float]
left_blank_cards: List[int]
right_nodes_x: List[float]
right_blank_cards: List[int]
class EvaluationRequest(BaseModel):
x: float
left_nodes: List[Tuple[float, float]]
right_nodes: List[Tuple[float, float]]
core: Tuple[float, float]
support: Tuple[float, float]
# -----------------------------
# ENDPOINT 1: FUNCIÓN DE VALOR DoC
# -----------------------------
@app.post("/api/criteria/doc/value-function") @app.post("/api/criteria/doc/value-function")
def calcular(request: ValueFunctionRequest): def calcular_value_function(request: ValueFunctionRequest):
levels = request.levels levels = request.levels
cards_between_levels = request.blank_cards cards = request.blank_cards
reference_values = request.references refs = request.references
# Índices de referencia (por ejemplo 0 y 4) ref_indices = sorted(int(k) for k in refs)
ref_indices = sorted(int(k) for k in reference_values) p, q = ref_indices
lower_ref, upper_ref = ref_indices up, uq = refs[str(p)], refs[str(q)]
# Valores asignados a esas referencias total_units = sum(cards[i] + 1 for i in range(p, q))
lower_value = reference_values[str(lower_ref)] alpha = (uq - up) / total_units if total_units else 0
upper_value = reference_values[str(upper_ref)]
# Total de unidades entre las referencias
total_units = sum(cards_between_levels[i] + 1 for i in range(lower_ref, upper_ref))
# Valor por unidad
unit_value = (upper_value - lower_value) / total_units if total_units else 0
# Lista de valores finales
values = [0] * len(levels) values = [0] * len(levels)
values[lower_ref] = lower_value values[p] = up
# Hacia arriba for i in range(p + 1, len(levels)):
for i in range(lower_ref + 1, len(levels)): units = sum(cards[r] + 1 for r in range(p, i))
units = sum(cards_between_levels[r] + 1 for r in range(lower_ref, i)) values[i] = up + alpha * units
values[i] = lower_value + unit_value * units
# Hacia abajo for i in range(p - 1, -1, -1):
for i in range(lower_ref - 1, -1, -1): units = sum(cards[r] + 1 for r in range(i, p))
units = sum(cards_between_levels[r] + 1 for r in range(i, lower_ref)) values[i] = up - alpha * units
values[i] = lower_value - unit_value * units
return { return {
"criterion_name": request.criterion_name, "criterion_name": request.criterion_name,
"values": {levels[i]: round(values[i], 4) for i in range(len(levels))} "values": {levels[i]: round(values[i], 4) for i in range(len(levels))}
} }
# -----------------------------
# ENDPOINT 2: CONSTRUIR DoC-MF
# -----------------------------
@app.post("/api/criteria/doc-mf/build")
def build_doc_mf(request: DoCMFRequest):
a, b = request.core
c, d = request.support
# ---- LADO IZQUIERDO ----
left_x = request.left_nodes_x
left_e = request.left_blank_cards
TL = sum(e + 1 for e in left_e)
YL = 1 / TL if TL else 0
left_nodes = []
acc = 0
for i in range(len(left_x)):
if i == 0:
left_nodes.append((left_x[i], 0.0))
else:
acc += (left_e[i-1] + 1)
left_nodes.append((left_x[i], round(acc * YL, 4)))
# ---- LADO DERECHO ----
right_x = request.right_nodes_x
right_e = request.right_blank_cards
TR = sum(e + 1 for e in right_e)
YR = 1 / TR if TR else 0
right_nodes = []
acc = 0
for i in range(len(right_x)):
if i == 0:
right_nodes.append((right_x[i], 1.0))
else:
acc += (right_e[i-1] + 1)
right_nodes.append((right_x[i], round(1 - acc * YR, 4)))
return {
"term": request.term,
"core": request.core,
"support": request.support,
"left_nodes": left_nodes,
"right_nodes": right_nodes
}
# -----------------------------
# ENDPOINT 3: EVALUAR UN VALOR x
# -----------------------------
def linear_interpolation(x, nodes):
for i in range(len(nodes) - 1):
x0, y0 = nodes[i]
x1, y1 = nodes[i+1]
if x0 <= x <= x1:
t = (x - x0) / (x1 - x0)
return y0 + t * (y1 - y0)
return 0.0
@app.post("/api/criteria/doc-mf/evaluate")
def evaluate_doc_mf(request: EvaluationRequest):
x = request.x
a, b = request.core
c, d = request.support
if x < c or x > d:
return {"membership": 0.0}
if a <= x <= b:
return {"membership": 1.0}
if c <= x < a:
return {"membership": linear_interpolation(x, request.left_nodes)}
if b < x <= d:
return {"membership": linear_interpolation(x, request.right_nodes)}
return {"membership": 0.0}
# -----------------------------
# ENDPOINT 4: PUNTOS (x,y) DE LA FUNCIÓN DE VALOR
# -----------------------------
@app.post("/api/criteria/doc/value-function/points")
def value_function_points(request: ValueFunctionRequest):
levels = request.levels
cards = request.blank_cards
refs = request.references
ref_indices = sorted(int(k) for k in refs)
p, q = ref_indices
up, uq = refs[str(p)], refs[str(q)]
total_units = sum(cards[i] + 1 for i in range(p, q))
alpha = (uq - up) / total_units if total_units else 0
values = [0] * len(levels)
values[p] = up
for i in range(p + 1, len(levels)):
units = sum(cards[r] + 1 for r in range(p, i))
values[i] = up + alpha * units
for i in range(p - 1, -1, -1):
units = sum(cards[r] + 1 for r in range(i, p))
values[i] = up - alpha * units
points = [{"x": i, "y": round(values[i], 4)} for i in range(len(levels))]
return {"points": points}