Merge branch 'develop' into feature/ui-tablero-cartas
This commit is contained in:
@@ -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
@@ -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}
|
||||||
|
|||||||
Reference in New Issue
Block a user