Ultron/ultron/people/models.py

303 lines
10 KiB
Python
Raw Normal View History

2022-09-08 18:47:47 +02:00
""" Modelisation des gymnastes """
2022-01-07 18:08:39 +01:00
2022-02-06 15:44:55 +01:00
from django.contrib.auth import get_user_model
2022-01-07 18:08:39 +01:00
from django.db.models import Count
2022-02-06 15:44:55 +01:00
from django.db import models
User = get_user_model()
2021-12-09 16:53:44 +01:00
2022-02-06 15:44:55 +01:00
from datetime import date
2021-12-09 16:53:44 +01:00
import pendulum
from ultron.location.models import Club
from ultron.objective.models import Skill
from ultron.tools.models import Markdownizable
2022-09-08 18:47:47 +02:00
from ultron.objective.tools import (
nb_skill_by_type,
nb_skill_lte_type,
compute_completude,
compute_statistics_by_type,
)
2021-12-09 16:53:44 +01:00
class Gymnast(Markdownizable):
"""Représente un gymnaste.
2021-12-19 09:30:51 +01:00
Un gymnaste peut être actif ou inactif.
"""
2021-12-09 16:53:44 +01:00
class Meta:
verbose_name = "Gymnast"
verbose_name_plural = "Gymnasts"
GENDER_CHOICES = ((0, "Male"), (1, "Female"))
2022-09-07 08:56:26 +02:00
# CATEGORY_CHOICES = ((9, "I9"), (10, "I10"), (11, "A11"), (12, "A12"), (13, "A13-14"), (15, "A15-16"), (18, "Senior"))
2021-12-09 16:53:44 +01:00
2022-02-06 15:44:55 +01:00
user = models.OneToOneField(
User,
on_delete=models.SET_NULL,
related_name="gymnast",
blank=True,
null=True
)
2021-12-09 16:53:44 +01:00
last_name = models.CharField(max_length=40, null=False, blank=False)
first_name = models.CharField(max_length=25, null=False, blank=False)
birthdate = models.DateField(verbose_name="Date de naissance")
gender = models.PositiveSmallIntegerField(
choices=GENDER_CHOICES, verbose_name="Sexe"
)
is_active = models.BooleanField(default=1, verbose_name="Active")
club = models.ForeignKey(
Club, null=True, on_delete=models.SET_NULL, related_name="gymnast"
)
2022-09-07 08:56:26 +02:00
# category = models.PositiveSmallIntegerField(
# choices=CATEGORY_CHOICES, verbose_name="Category"
# )
email_trainer = models.EmailField(max_length=254, null=True, blank=True, verbose_name="Trainer's email")
2021-12-19 09:30:51 +01:00
trainings_by_week = models.PositiveSmallIntegerField(
verbose_name="# Training by week"
)
2021-12-09 16:53:44 +01:00
hours_by_week = models.PositiveSmallIntegerField(verbose_name="# Hours by week")
def __str__(self):
2022-01-07 18:08:39 +01:00
return "%s %s" % (self.first_name, self.last_name)
2021-12-09 16:53:44 +01:00
@property
def next_birthday(self):
"""Définit la prochaine date (de fête) d'anniversaire pour cette personne.
2021-12-19 09:30:51 +01:00
Returns:
Soit le jour/mois pour cette année
Soit le jour/mois pour l'année prochaine.
2021-12-09 16:53:44 +01:00
2021-12-19 09:30:51 +01:00
Examples: en supposant qu'on soit le 23/05/2019
>>> from datetime import date
>>> gregg = Gymnast(name='Tru', firstname='Gregg', birthdate=date(1982, 2, 5))
>>> gregg.next_birthday()
Date(2020, 2, 5)
"""
2021-12-09 16:53:44 +01:00
now = pendulum.now()
this_year_birthday = pendulum.date(
now.year, self.birthdate.month, self.birthdate.day
)
if this_year_birthday.is_past():
return pendulum.date(now.year + 1, self.birthdate.month, self.birthdate.day)
return this_year_birthday
@property
def next_birthday_in_days(self):
now = pendulum.now()
return self.next_birthday.diff(now).in_days()
@property
def age(self):
2021-12-19 09:30:51 +01:00
"""Renvoie l'âge d'un gymnaste."""
2021-12-09 16:53:44 +01:00
today = date.today()
return (
today.year
- self.birthdate.year
- ((today.month, today.day) < (self.birthdate.month, self.birthdate.day))
)
@property
def next_age(self):
2021-12-19 09:30:51 +01:00
"""Renvoie l'âge prochain du gymnaste."""
2021-12-09 16:53:44 +01:00
return (self.age) + 1
def min_rank_skill(self):
2021-12-19 09:30:51 +01:00
tmp = (
Skill.objects.filter(known_by__gymnast=self.id)
.order_by("rank")
.values("rank")[:1]
)
2021-12-09 16:53:44 +01:00
if tmp:
2021-12-19 09:30:51 +01:00
min_rank = tmp[0]["rank"]
2021-12-09 16:53:44 +01:00
else:
min_rank = 0
2021-12-19 09:30:51 +01:00
2021-12-09 16:53:44 +01:00
return min_rank
def max_rank_skill(self):
2021-12-19 09:30:51 +01:00
tmp = (
Skill.objects.filter(known_by__gymnast=self.id)
.order_by("-rank")
.values("rank")[:1]
)
2021-12-09 16:53:44 +01:00
if tmp:
2021-12-19 09:30:51 +01:00
max_rank = tmp[0]["rank"]
2021-12-09 16:53:44 +01:00
else:
max_rank = 0
2021-12-19 09:30:51 +01:00
2021-12-09 16:53:44 +01:00
return max_rank
2022-09-08 18:47:47 +02:00
def nb_known_skill_by_rank(self):
2021-12-09 16:53:44 +01:00
"""
Renvoie le nombre de Skill qu'un gymnast sait faire par rang
"""
nb_known_skill_by_rank = (
Skill.objects.values("rank")
.filter(known_by__gymnast=self.id)
.order_by("rank")
.annotate(nb_known_skill=Count("id"))
)
return nb_known_skill_by_rank
def max_level_skill(self):
"""
Retourne le niveau maximum des skill que le gymnaste sait faire.
"""
2021-12-19 09:30:51 +01:00
tmp = (
Skill.objects.filter(known_by__gymnast=self.id)
.order_by("-level")
.values("level")[:1]
)
2021-12-09 16:53:44 +01:00
if tmp:
2021-12-19 09:30:51 +01:00
max_level = tmp[0]["level"]
2021-12-09 16:53:44 +01:00
else:
max_level = 0
return max_level
def nb_known_skill_by_level(self):
"""
Renvoie le nombre de Skill qu'un gymnast sait faire par niveau
"""
nb_known_skill_by_level = (
Skill.objects.values("level")
.filter(known_by__gymnast=self.id)
.order_by("level")
.annotate(nb_known_skill=Count("id"))
)
return nb_known_skill_by_level
def unknown_skill_lte_level(self, max_level_skill):
"""
2022-01-07 19:28:33 +01:00
Liste des Skill que le gymnaste ne sait PAS faire/
Ces skills sont classé par niveau.
2021-12-09 16:53:44 +01:00
"""
2021-12-19 09:30:51 +01:00
return Skill.objects.filter(level__lte=max_level_skill).exclude(
known_by__gymnast=self.id
)
2021-12-09 16:53:44 +01:00
def unknown_skill_gt_level(self, max_level_skill):
"""
2022-01-07 19:28:33 +01:00
Liste des Skill que le gymnaste ne sait PAS faire,
classé par niveau (ayant un niveau inférieur ou égal au niveau max du gym)
2021-12-09 16:53:44 +01:00
"""
2021-12-19 09:30:51 +01:00
return Skill.objects.filter(level__gt=max_level_skill).exclude(
known_by__gymnast=self.id
)
2021-12-09 16:53:44 +01:00
def unknown_skill_lte_rank(self, max_rank_skill):
# Liste des Skill que le gymnaste ne sait PAS faire, classé par niveau
# (ayant un niveau inférieur ou égal au niveau max du gym)
2021-12-19 09:30:51 +01:00
return Skill.objects.filter(level__lte=max_rank_skill).exclude(
known_by__gymnast=self.id
)
2021-12-09 16:53:44 +01:00
def unknown_skill_gt_rank(self, max_rank_skill):
"""
2022-01-07 19:28:33 +01:00
Liste des Skill que le gymnaste ne sais PAS faire
(ayant un niveau plus grand que le niveau max du gym)
2021-12-09 16:53:44 +01:00
"""
2021-12-19 09:30:51 +01:00
return Skill.objects.filter(level__gt=max_rank_skill).exclude(
known_by__gymnast=self.id
)
2021-12-09 16:53:44 +01:00
def get_informations_from_level(self):
"""
Calcule toutes les statistiques par rapport au niveau.
1. on va chercher le niveau maximum de skill que le gymnast sait faire
2. on va chercher le nombre de skill par niveau que le gymnast sait faire
2022-01-07 19:28:33 +01:00
nb_known_skill_by_level = [
{
'level': 1,
'nb_known_skill': 1
},
{
'level': 2,
'nb_known_skill': 2
}
]
2021-12-09 16:53:44 +01:00
3. si le niveau max est supérieur à 0
OUI:
2022-01-07 19:28:33 +01:00
a. on va chercher le nombre total des skills dont le niveau
est inférieur ou égale au niveau max (cf. 1.)
2021-12-09 16:53:44 +01:00
b. on va chercher le nombre de skill qu'il y a par niveau :
2022-01-07 19:28:33 +01:00
[
{
'level': 1, 'nb_skill': 1
},
{
'level': 2, 'nb_skill': 1
}
]
2021-12-09 16:53:44 +01:00
c. Pour chaque élément da la liste obtenue en b :
2022-01-07 19:28:33 +01:00
- si le niveau du skill est le même que le niveau courant ...
je sais pas, je comprends plus...
2021-12-09 16:53:44 +01:00
- on incrémente j
NON:
"""
context = {}
max_level_skill = self.max_level_skill()
nb_known_skill_by_level = self.nb_known_skill_by_level()
2021-12-19 09:30:51 +01:00
gymnast_nb_known_skills = self.known_skills.distinct("skill").count()
2021-12-09 16:53:44 +01:00
if max_level_skill > 0:
2022-09-08 18:47:47 +02:00
cpt_skill_by_level = nb_skill_by_type(max_level_skill, "level")
context["total_skill"] = nb_skill_lte_type(max_level_skill, "level")
context["percentages"] = compute_statistics_by_type(
cpt_skill_by_level, nb_known_skill_by_level, "level"
2021-12-19 09:30:51 +01:00
)
2021-12-09 16:53:44 +01:00
context["skill_by_level"] = self.unknown_skill_lte_level(max_level_skill)
context["unknown_skill"] = self.unknown_skill_gt_level(max_level_skill)
else:
tmp = Skill.objects.all()
context["total_skill"] = tmp.count()
context["unknown_skill"] = tmp
2022-09-08 18:47:47 +02:00
context["completude"], context["evaluated_level"] = compute_completude(
2021-12-19 09:30:51 +01:00
context["total_skill"], gymnast_nb_known_skills, max_level_skill
)
2021-12-09 16:53:44 +01:00
context["max_level_skill"] = max_level_skill
return context
def get_informations_from_rank(self):
"""
Calcule toutes les statistiques des skills par rapport au rang du gymnaste.
"""
context = {}
2022-01-07 19:28:33 +01:00
# min_rank_skill = self.min_rank_skill()
2021-12-09 16:53:44 +01:00
max_rank_skill = self.max_rank_skill()
context["max_rank_skill"] = max_rank_skill
2022-09-08 18:47:47 +02:00
nb_known_skill_by_rank = self.nb_known_skill_by_rank()
2021-12-19 09:30:51 +01:00
gymnast_nb_known_skills = self.known_skills.distinct("skill").count()
2021-12-09 16:53:44 +01:00
if max_rank_skill > 0:
2022-09-08 18:47:47 +02:00
cpt_skill_by_rank = nb_skill_by_type(max_rank_skill, "rank")
context["total_skill"] = nb_skill_lte_type(max_rank_skill, "rank")
context["percentages"] = compute_statistics_by_type(
cpt_skill_by_rank, nb_known_skill_by_rank, "rank"
2021-12-19 09:30:51 +01:00
)
2021-12-09 16:53:44 +01:00
context["skill_by_rank"] = self.unknown_skill_lte_rank(max_rank_skill)
context["unknown_skill"] = self.unknown_skill_gt_rank(max_rank_skill)
else:
tmp = Skill.objects.all()
context["unknown_skill"] = tmp
context["total_skill"] = tmp.count()
2022-09-08 18:47:47 +02:00
context["completude"], context["evaluated_level"] = compute_completude(
2021-12-19 09:30:51 +01:00
context["total_skill"], gymnast_nb_known_skills, max_rank_skill
)
2021-12-09 16:53:44 +01:00
2021-12-19 09:30:51 +01:00
return context