Working 2.0
This commit is contained in:
parent
a10fce5731
commit
69b0fa02a4
apps
__pycache__
core
__pycache__
migrations/__pycache__
participants
__pycache__
__init__.cpython-311.pycadmin.cpython-311.pycapps.cpython-311.pycforms.cpython-311.pycmodels.cpython-311.pycservices.cpython-311.pycurls.cpython-311.pycviews.cpython-311.pyc
forms.pymigrations/__pycache__
models.pyservices.pysettingsapp
static/css
templates
trafoking/__pycache__
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,10 +1,44 @@
|
|||||||
|
# forms.py
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
from .models import Participant
|
from .models import Participant
|
||||||
|
import re
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
|
_DECIMAL_RE = re.compile(r"[^\d,\.]")
|
||||||
|
|
||||||
class ParticipantForm(forms.ModelForm):
|
class ParticipantForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Participant
|
model = Participant
|
||||||
fields = ["group_name","R_diff","L_diff","Ph_diff","Pcu_diff","s_vol_over_eta"]
|
fields = [
|
||||||
widgets = {f: forms.NumberInput(attrs={"step": "0.1", "class": "input"})
|
"group_name",
|
||||||
for f in fields if f!="group_name"}
|
"R_diff",
|
||||||
|
"L_diff",
|
||||||
|
"Ph_diff",
|
||||||
|
"Pcu_diff",
|
||||||
|
"s_vol_over_eta",
|
||||||
|
]
|
||||||
|
widgets = {
|
||||||
|
f: forms.NumberInput(attrs={"step": "0.1", "class": "input"})
|
||||||
|
for f in fields if f != "group_name"
|
||||||
|
}
|
||||||
widgets["group_name"] = forms.TextInput(attrs={"class": "input"})
|
widgets["group_name"] = forms.TextInput(attrs={"class": "input"})
|
||||||
|
labels = {
|
||||||
|
"group_name": "Nombre del grupo",
|
||||||
|
"R_diff": mark_safe("R<sub>diff</sub>"),
|
||||||
|
"L_diff": mark_safe("L<sub>diff</sub>"),
|
||||||
|
"Ph_diff": mark_safe("P<sub>h, diff</sub>"),
|
||||||
|
"Pcu_diff": mark_safe("P<sub>cu, diff</sub>"),
|
||||||
|
"s_vol_over_eta": mark_safe("S/Vol·η"),
|
||||||
|
}
|
||||||
|
def clean_s_vol_over_eta(self):
|
||||||
|
raw = self.data.get("s_vol_over_eta", "")
|
||||||
|
raw = _DECIMAL_RE.sub("", raw) # quita letras o espacios
|
||||||
|
raw = raw.replace(",", ".") # coma → punto
|
||||||
|
try:
|
||||||
|
value = float(raw)
|
||||||
|
except ValueError:
|
||||||
|
raise ValidationError("Introduce un número válido (ej. 12.3)")
|
||||||
|
if value <= 0:
|
||||||
|
raise ValidationError("Debe ser mayor que 0")
|
||||||
|
return value
|
Binary file not shown.
Binary file not shown.
@ -1,6 +1,8 @@
|
|||||||
# apps/participants/models.py
|
# apps/participants/models.py
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from apps.core.models import TimeStampedModel
|
from apps.core.models import TimeStampedModel
|
||||||
|
import re
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
|
||||||
class Participant(TimeStampedModel):
|
class Participant(TimeStampedModel):
|
||||||
group_name = models.CharField(max_length=80, unique=True)
|
group_name = models.CharField(max_length=80, unique=True)
|
||||||
@ -10,8 +12,7 @@ class Participant(TimeStampedModel):
|
|||||||
L_diff = models.FloatField()
|
L_diff = models.FloatField()
|
||||||
Ph_diff = models.FloatField()
|
Ph_diff = models.FloatField()
|
||||||
Pcu_diff= models.FloatField()
|
Pcu_diff= models.FloatField()
|
||||||
|
s_vol_over_eta = models.FloatField()
|
||||||
s_vol_over_eta = models.FloatField(help_text="S*Vol/η") # métrica objetiva
|
|
||||||
score = models.FloatField(default=0)
|
score = models.FloatField(default=0)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -19,3 +20,8 @@ class Participant(TimeStampedModel):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.group_name
|
return self.group_name
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
super().clean()
|
||||||
|
if self.s_vol_over_eta <= 0:
|
||||||
|
raise ValidationError({"s_vol_over_eta": "Debe ser mayor que 0"})
|
||||||
|
@ -29,7 +29,7 @@ def calculate_scores():
|
|||||||
p.score += _factor(diff) * weight
|
p.score += _factor(diff) * weight
|
||||||
|
|
||||||
# 3) Objetivo (rank por métrica)
|
# 3) Objetivo (rank por métrica)
|
||||||
sorted_by_obj = sorted(participants, key=lambda x: x.s_vol_over_eta)
|
sorted_by_obj = sorted(participants, key=lambda x: x.s_vol_over_eta, reverse=True)
|
||||||
for idx, p in enumerate(sorted_by_obj, start=1):
|
for idx, p in enumerate(sorted_by_obj, start=1):
|
||||||
p.score += max(settings.objective_weight - (idx - 1), 0)
|
p.score += max(settings.objective_weight - (idx - 1), 0)
|
||||||
|
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
@ -1,24 +1,86 @@
|
|||||||
/* static/css/styles.css */
|
|
||||||
:root {
|
:root {
|
||||||
--brand-blue: #002e5d;
|
--brand-blue: #002e5d;
|
||||||
--brand-yellow:#f4b400;
|
|
||||||
--brand-orange: #ffa94d;
|
--brand-orange: #ffa94d;
|
||||||
}
|
}
|
||||||
|
|
||||||
body{background:var(--brand-blue);color:#fff;font-family:Inter,system-ui,sans-serif}
|
/* Cuerpo */
|
||||||
|
body {
|
||||||
|
background: var(--brand-blue);
|
||||||
|
color: #fff;
|
||||||
|
font-family: Inter, system-ui, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
/*–– Botones ––*/
|
/*–– Botones ––*/
|
||||||
.btn {
|
.btn {
|
||||||
@apply inline-block px-6 py-3 rounded-xl font-medium transition transform;
|
display: inline-block;
|
||||||
|
padding: 0.75rem 1.25rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
font-weight: 600;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: box-shadow 0.2s ease, background-color 0.2s ease, color 0.2s ease;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.btn:hover {
|
||||||
|
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
|
||||||
|
}
|
||||||
|
.btn:focus {
|
||||||
|
outline: 2px solid rgba(255,255,255,0.6);
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Botón principal */
|
||||||
.btn-primary {
|
.btn-primary {
|
||||||
background:var(--brand-orange);color:#222;
|
background-color: var(--brand-orange);
|
||||||
|
color: #222;
|
||||||
|
border: none;
|
||||||
}
|
}
|
||||||
.btn-primary:hover{filter:brightness(1.1) scale(1.02)}
|
.btn-primary:hover {
|
||||||
|
background-color: #ee993f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Botón secundario */
|
||||||
.btn-secondary {
|
.btn-secondary {
|
||||||
background:transparent;border:2px solid var(--brand-orange);color:var(--brand-orange);
|
background-color: transparent;
|
||||||
|
border: 2px solid var(--brand-orange);
|
||||||
|
color: var(--brand-orange);
|
||||||
|
}
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background-color: var(--brand-orange);
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*–– Formularios ––*/
|
||||||
|
form {
|
||||||
|
max-width: 360px;
|
||||||
|
margin: 0 auto; /* centra el bloque del formulario */
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
form label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
form input,
|
||||||
|
form select,
|
||||||
|
form textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #333;
|
||||||
|
font-size: 1rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
form input:focus,
|
||||||
|
form select:focus,
|
||||||
|
form textarea:focus {
|
||||||
|
outline: 2px solid var(--brand-orange);
|
||||||
|
outline-offset: 2px;
|
||||||
}
|
}
|
||||||
.btn-secondary:hover{background:var(--brand-orange);color:#222}
|
|
||||||
|
|
||||||
/*–– Animaciones hero ––*/
|
/*–– Animaciones hero ––*/
|
||||||
@keyframes scaleFade {
|
@keyframes scaleFade {
|
||||||
@ -27,13 +89,15 @@
|
|||||||
}
|
}
|
||||||
.hero-appear { animation: scaleFade .6s ease-out both }
|
.hero-appear { animation: scaleFade .6s ease-out both }
|
||||||
|
|
||||||
/*–– Transición logo grande→pequeño ––*/
|
/*–– Logos ––*/
|
||||||
.logo-big { width: 60% }
|
.logo-big { width: 60% }
|
||||||
.logo-small {width:48px}
|
.logo-small { width: 100px }
|
||||||
|
|
||||||
/*–– Table ––*/
|
|
||||||
table{border-collapse:collapse;width:100%;max-width:640px;margin-inline:auto}
|
|
||||||
th,td{padding:.6rem 1rem;border-bottom:1px solid #ffffff33}
|
|
||||||
thead{background:#ffffff11}
|
|
||||||
tbody tr:nth-child(even){background:#ffffff08}
|
|
||||||
|
|
||||||
|
/*-- Texto matemático --*/
|
||||||
|
label sub,
|
||||||
|
label sup {
|
||||||
|
font-size: 0.75em;
|
||||||
|
vertical-align: baseline;
|
||||||
|
position: relative;
|
||||||
|
top: 0.25em;
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body class="min-h-screen flex flex-col">
|
<body class="min-h-screen flex flex-col">
|
||||||
|
|
||||||
|
{% block navbar %}
|
||||||
<!-- NAVBAR -->
|
<!-- NAVBAR -->
|
||||||
<header class="flex items-center gap-4 px-6 py-4">
|
<header class="flex items-center gap-4 px-6 py-4">
|
||||||
<a href="/" aria-label="Inicio">
|
<a href="/" aria-label="Inicio">
|
||||||
@ -22,6 +23,7 @@
|
|||||||
<a href="{% url 'settings' %}" class="btn btn-secondary hidden sm:inline-block">Administración</a>
|
<a href="{% url 'settings' %}" class="btn btn-secondary hidden sm:inline-block">Administración</a>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
<!-- CONTENIDO -->
|
<!-- CONTENIDO -->
|
||||||
<main class="flex-1 flex flex-col items-center justify-center px-4">
|
<main class="flex-1 flex flex-col items-center justify-center px-4">
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<!-- templates/home.html -->
|
<!-- templates/home.html -->
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
{% block navbar %}{% endblock %}
|
||||||
{% block title %}Trafoking{% endblock %}
|
{% block title %}Trafoking{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<section class="flex flex-col items-center text-center gap-12 hero-appear">
|
<section class="flex flex-col items-center text-center gap-12 hero-appear">
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user