40 lines
1.2 KiB
Python
40 lines
1.2 KiB
Python
# apps/participants/services.py
|
|
from django.db import transaction
|
|
from .models import Participant
|
|
from apps.settingsapp.models import GradingSettings
|
|
|
|
def _factor(diff: float) -> float:
|
|
if diff <= 10:
|
|
return 1.0
|
|
elif diff <= 20:
|
|
return 0.8
|
|
return 0.6
|
|
|
|
def calculate_scores():
|
|
"""Recalcula y persiste 'score' para todos los participantes"""
|
|
settings = GradingSettings.get()
|
|
participants = list(Participant.objects.all())
|
|
|
|
# 1) Base Entregable + Presentación
|
|
for p in participants:
|
|
p.score = settings.report_weight + settings.presentation_weight
|
|
|
|
# 2) Similitud
|
|
for diff, weight in [
|
|
(p.R_diff, settings.R_weight),
|
|
(p.L_diff, settings.L_weight),
|
|
(p.Ph_diff, settings.Ph_weight),
|
|
(p.Pcu_diff,settings.Pcu_weight),
|
|
]:
|
|
p.score += _factor(diff) * weight
|
|
|
|
# 3) Objetivo (rank por métrica)
|
|
sorted_by_obj = sorted(participants, key=lambda x: x.s_vol_over_eta)
|
|
for idx, p in enumerate(sorted_by_obj, start=1):
|
|
p.score += max(settings.objective_weight - (idx - 1), 0)
|
|
|
|
# 4) Persistimos en batch
|
|
with transaction.atomic():
|
|
for p in participants:
|
|
p.save(update_fields=["score"])
|