Working 2.0
This commit is contained in:
parent
a10fce5731
commit
69b0fa02a4
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.utils.safestring import mark_safe
|
||||
from .models import Participant
|
||||
import re
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
_DECIMAL_RE = re.compile(r"[^\d,\.]")
|
||||
|
||||
class ParticipantForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Participant
|
||||
fields = ["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"})
|
||||
model = Participant
|
||||
fields = [
|
||||
"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"})
|
||||
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
|
||||
from django.db import models
|
||||
from apps.core.models import TimeStampedModel
|
||||
import re
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
class Participant(TimeStampedModel):
|
||||
group_name = models.CharField(max_length=80, unique=True)
|
||||
@ -10,8 +12,7 @@ class Participant(TimeStampedModel):
|
||||
L_diff = models.FloatField()
|
||||
Ph_diff = models.FloatField()
|
||||
Pcu_diff= models.FloatField()
|
||||
|
||||
s_vol_over_eta = models.FloatField(help_text="S*Vol/η") # métrica objetiva
|
||||
s_vol_over_eta = models.FloatField()
|
||||
score = models.FloatField(default=0)
|
||||
|
||||
class Meta:
|
||||
@ -19,3 +20,8 @@ class Participant(TimeStampedModel):
|
||||
|
||||
def __str__(self):
|
||||
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
|
||||
|
||||
# 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):
|
||||
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,39 +1,103 @@
|
||||
/* static/css/styles.css */
|
||||
:root{
|
||||
--brand-blue:#002e5d;
|
||||
--brand-yellow:#f4b400;
|
||||
--brand-orange:#ffa94d;
|
||||
}
|
||||
|
||||
body{background:var(--brand-blue);color:#fff;font-family:Inter,system-ui,sans-serif}
|
||||
|
||||
/*–– Botones ––*/
|
||||
.btn{
|
||||
@apply inline-block px-6 py-3 rounded-xl font-medium transition transform;
|
||||
}
|
||||
.btn-primary{
|
||||
background:var(--brand-orange);color:#222;
|
||||
}
|
||||
.btn-primary:hover{filter:brightness(1.1) scale(1.02)}
|
||||
.btn-secondary{
|
||||
background:transparent;border:2px solid var(--brand-orange);color:var(--brand-orange);
|
||||
}
|
||||
.btn-secondary:hover{background:var(--brand-orange);color:#222}
|
||||
|
||||
/*–– Animaciones hero ––*/
|
||||
@keyframes scaleFade{
|
||||
0%{opacity:0;transform:scale(.7)}
|
||||
100%{opacity:1;transform:scale(1)}
|
||||
}
|
||||
.hero-appear{animation:scaleFade .6s ease-out both}
|
||||
|
||||
/*–– Transición logo grande→pequeño ––*/
|
||||
.logo-big {width: 60%}
|
||||
.logo-small {width:48px}
|
||||
|
||||
/*–– 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}
|
||||
|
||||
:root {
|
||||
--brand-blue: #002e5d;
|
||||
--brand-orange: #ffa94d;
|
||||
}
|
||||
|
||||
/* Cuerpo */
|
||||
body {
|
||||
background: var(--brand-blue);
|
||||
color: #fff;
|
||||
font-family: Inter, system-ui, sans-serif;
|
||||
}
|
||||
|
||||
/*–– Botones ––*/
|
||||
.btn {
|
||||
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 {
|
||||
background-color: var(--brand-orange);
|
||||
color: #222;
|
||||
border: none;
|
||||
}
|
||||
.btn-primary:hover {
|
||||
background-color: #ee993f;
|
||||
}
|
||||
|
||||
/* Botón secundario */
|
||||
.btn-secondary {
|
||||
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;
|
||||
}
|
||||
|
||||
/*–– Animaciones hero ––*/
|
||||
@keyframes scaleFade {
|
||||
0% { opacity: 0; transform: scale(.7) }
|
||||
100% { opacity: 1; transform: scale(1) }
|
||||
}
|
||||
.hero-appear { animation: scaleFade .6s ease-out both }
|
||||
|
||||
/*–– Logos ––*/
|
||||
.logo-big { width: 60% }
|
||||
.logo-small { width: 100px }
|
||||
|
||||
/*-- Texto matemático --*/
|
||||
label sub,
|
||||
label sup {
|
||||
font-size: 0.75em;
|
||||
vertical-align: baseline;
|
||||
position: relative;
|
||||
top: 0.25em;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
</head>
|
||||
<body class="min-h-screen flex flex-col">
|
||||
|
||||
{% block navbar %}
|
||||
<!-- NAVBAR -->
|
||||
<header class="flex items-center gap-4 px-6 py-4">
|
||||
<a href="/" aria-label="Inicio">
|
||||
@ -22,6 +23,7 @@
|
||||
<a href="{% url 'settings' %}" class="btn btn-secondary hidden sm:inline-block">Administración</a>
|
||||
</nav>
|
||||
</header>
|
||||
{% endblock %}
|
||||
|
||||
<!-- CONTENIDO -->
|
||||
<main class="flex-1 flex flex-col items-center justify-center px-4">
|
||||
|
@ -1,6 +1,7 @@
|
||||
<!-- templates/home.html -->
|
||||
{% extends "base.html" %}
|
||||
{% load static %}
|
||||
{% block navbar %}{% endblock %}
|
||||
{% block title %}Trafoking{% endblock %}
|
||||
{% block content %}
|
||||
<section class="flex flex-col items-center text-center gap-12 hero-appear">
|
||||
|
@ -20,4 +20,4 @@
|
||||
</button>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user