272 lines
9.2 KiB
Python
272 lines
9.2 KiB
Python
|
|
from django import template
|
|
from django.db.models import Count, Min
|
|
from django.shortcuts import get_object_or_404
|
|
|
|
from khana.people.models import Gymnast, CanDoRelation
|
|
from khana.objective.models import Educative, Skill
|
|
|
|
register = template.Library()
|
|
|
|
|
|
def __getInformationsFromLevel(gymnast, totalKnownSkill):
|
|
"""
|
|
Calcule toutes les statistiques par rapport au niveau.
|
|
"""
|
|
|
|
context = {}
|
|
maxLevelEducative = Educative.objects.filter(cando__gymnast=gymnast.id).order_by(
|
|
"-level"
|
|
)[:1]
|
|
|
|
# Nombre de Skill que le gymnaste sait faire, groupé par niveau
|
|
nbKnownSkillByLevel = (
|
|
Skill.objects.values("level")
|
|
.filter(cando__gymnast=gymnast.id)
|
|
.order_by("level")
|
|
.annotate(nbknownskill=Count("id"))
|
|
)
|
|
|
|
if maxLevelEducative:
|
|
# Niveau maximum de l'élève
|
|
context["maxLevelEducative"] = maxLevelEducative[0].level
|
|
|
|
# Nombre de Skill qui ont un niveau inférieur ou égal
|
|
context["totalSkill"] = Skill.objects.filter(
|
|
level__lte=context["maxLevelEducative"]
|
|
).count()
|
|
|
|
# Nombre de Skill qui ont un niveau intérieur ou égal, groupé par niveau
|
|
nbSkillByLevel = (
|
|
Skill.objects.values("level")
|
|
.filter(level__lte=context["maxLevelEducative"])
|
|
.order_by("level")
|
|
.annotate(nbskill=Count("id"))
|
|
)
|
|
|
|
j = 0
|
|
tmp = None
|
|
percentages = []
|
|
for skill in nbSkillByLevel:
|
|
tmp = None
|
|
if skill["level"] == nbKnownSkillByLevel[j]["level"]:
|
|
if skill["nbskill"] != nbKnownSkillByLevel[j]["nbknownskill"]:
|
|
tmp = (
|
|
skill["level"],
|
|
skill["nbskill"],
|
|
nbKnownSkillByLevel[j]["nbknownskill"],
|
|
int(
|
|
(nbKnownSkillByLevel[j]["nbknownskill"] / skill["nbskill"])
|
|
* 100
|
|
),
|
|
)
|
|
|
|
j += 1
|
|
else:
|
|
tmp = (skill["level"], skill["nbskill"], 0, 0)
|
|
|
|
if tmp:
|
|
percentages.append(tmp)
|
|
|
|
context["percentages"] = percentages
|
|
|
|
# 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)
|
|
context["skillByLevel"] = Skill.objects.filter(
|
|
level__lte=context["maxLevelEducative"]
|
|
).exclude(cando__gymnast=gymnast.id)
|
|
|
|
# Liste des Skill que le gymnaste ne sais PAS faire (ayant un niveau plus grand que le niveau max du gym)
|
|
context["newUnknownSkill"] = Skill.objects.filter(
|
|
level__gt=context["maxLevelEducative"]
|
|
).exclude(cando__gymnast=gymnast.id)
|
|
|
|
else:
|
|
context["maxLevelEducative"] = 0
|
|
context["totalSkill"] = Skill.objects.all().count()
|
|
context["newUnknownSkill"] = Skill.objects.all()
|
|
|
|
# Calcul des statistiques
|
|
if context["totalSkill"] != 0:
|
|
context["completude"] = "%s%%" % (
|
|
int((totalKnownSkill / context["totalSkill"]) * 100)
|
|
)
|
|
context["evaluatedLevel"] = int(
|
|
context["maxLevelEducative"] * (totalKnownSkill / context["totalSkill"])
|
|
)
|
|
else:
|
|
context["completude"] = 0
|
|
context["evaluatedLevel"] = 0
|
|
|
|
return context
|
|
|
|
|
|
def __getInformationsFromRank(gymnast, totalKnownSkill):
|
|
"""
|
|
Calcule toutes les statistiques par rapport au rang.
|
|
"""
|
|
|
|
context = {}
|
|
|
|
min_rank = (
|
|
Skill.objects.values("rank")
|
|
.exclude(cando__gymnast=gymnast.id)
|
|
.order_by("rank")
|
|
.aggregate(Min("rank"))["rank__min"]
|
|
)
|
|
# print(min_rank)
|
|
|
|
# Nombre de Skill que le gymnaste sait faire, groupé par niveau
|
|
nbKnownSkillByRank = (
|
|
Skill.objects.values("rank")
|
|
.filter(cando__gymnast=gymnast.id)
|
|
.order_by("rank")
|
|
.annotate(nbknownskill=Count("id"))
|
|
)
|
|
|
|
# Rang maximum dans les éducatifs que le gymnaste sait faire
|
|
maxRankEducative = Educative.objects.filter(cando__gymnast=gymnast.id).order_by(
|
|
"-rank"
|
|
)[:1]
|
|
|
|
if maxRankEducative:
|
|
# Niveau maximum de l'élève
|
|
context["maxRankEducative"] = maxRankEducative[0].rank
|
|
|
|
# Nombre de Skill qui ont un niveau inférieur ou égal
|
|
context["totalSkill"] = Skill.objects.filter(
|
|
level__lte=context["maxRankEducative"]
|
|
).count()
|
|
|
|
# Nombre de Skill qui ont un niveau intérieur ou égal, groupé par niveau
|
|
nbSkillByRank = (
|
|
Skill.objects.values("rank")
|
|
.filter(level__lte=context["maxRankEducative"])
|
|
.order_by("rank")
|
|
.annotate(nbskill=Count("id"))
|
|
)
|
|
|
|
j = 0
|
|
tmp = None
|
|
percentages = []
|
|
for skill in nbSkillByRank:
|
|
# les deux lignes ci-derssous doiuvent partir
|
|
if j >= nbKnownSkillByRank.count():
|
|
break
|
|
|
|
tmp = None
|
|
# print(j)
|
|
if skill["rank"] == nbKnownSkillByRank[j]["rank"]:
|
|
if skill["nbskill"] != nbKnownSkillByRank[j]["nbknownskill"]:
|
|
tmp = (
|
|
skill["rank"],
|
|
skill["nbskill"],
|
|
nbKnownSkillByRank[j]["nbknownskill"],
|
|
int(
|
|
(nbKnownSkillByRank[j]["nbknownskill"] / skill["nbskill"])
|
|
* 100
|
|
),
|
|
)
|
|
|
|
j += 1
|
|
else:
|
|
# print('dans le else')
|
|
tmp = (skill["rank"], skill["nbskill"], 0, 0)
|
|
|
|
if tmp:
|
|
percentages.append(tmp)
|
|
|
|
context["percentages"] = percentages
|
|
|
|
# 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)
|
|
context["skillByRank"] = Skill.objects.filter(
|
|
level__lte=context["maxRankEducative"]
|
|
).exclude(cando__gymnast=gymnast.id)
|
|
|
|
# Liste des Skill que le gymnaste ne sais PAS faire (ayant un niveau plus grand que le niveau max du gym)
|
|
context["newUnknownSkill"] = Skill.objects.filter(
|
|
level__gt=context["maxRankEducative"]
|
|
).exclude(cando__gymnast=gymnast.id)
|
|
|
|
else:
|
|
context["maxRankEducative"] = 0
|
|
context["totalSkill"] = Skill.objects.all().count()
|
|
context["newUnknownSkill"] = Skill.objects.all()
|
|
|
|
# Calcul des statistiques
|
|
if context["totalSkill"] != 0:
|
|
context["completude"] = "%s%%" % (
|
|
int((totalKnownSkill / context["totalSkill"]) * 100)
|
|
)
|
|
context["evaluatedLevel"] = (min_rank - 1) + (
|
|
int(context["maxRankEducative"] * (totalKnownSkill / context["totalSkill"]))
|
|
)
|
|
else:
|
|
context["completude"] = 0
|
|
context["evaluatedLevel"] = 0
|
|
|
|
return context
|
|
|
|
|
|
@register.inclusion_tag("gymnast_statistics.html")
|
|
def display_stats(gymnast):
|
|
"""
|
|
Tag affichant les statistiques d'un gymnaste : le nombre de saut qu'il sait faire (total,
|
|
par niveau, par rank, …), calcule la complétude, …
|
|
|
|
.. todo:: Générer UNE fois la liste de skill que le gymnaste ne sait pas faire (1 query)
|
|
et les counts puis, dans le template on parcourt plusieurs fois cette même liste mais on
|
|
affiche conditionnellement (par age, par rank, ...)
|
|
"""
|
|
|
|
# Nombre de Skill que le gymnaste sait faire
|
|
gymnast_known_skills = gymnast.known_skills.count()
|
|
context = __getInformationsFromLevel(gymnast, gymnast_known_skills)
|
|
context.update(__getInformationsFromRank(gymnast, gymnast_known_skills))
|
|
|
|
if gymnast.gender:
|
|
context["skillByAge"] = Skill.objects.filter(age_girl__lte=gymnast.age).exclude(
|
|
cando__gymnast=gymnast.id
|
|
)
|
|
else:
|
|
context["skillByAge"] = Skill.objects.filter(age_boy__lte=gymnast.age).exclude(
|
|
cando__gymnast=gymnast.id
|
|
)
|
|
|
|
context["gymnast"] = gymnast
|
|
context["totalKnownSkill"] = gymnast_known_skills
|
|
|
|
return context
|
|
|
|
|
|
@register.inclusion_tag("gymnast_display_level.html")
|
|
def display_level(gymnast):
|
|
"""
|
|
Tag affichant les statistiques d'un gymnaste : le nombre de saut qu'il sait faire (total,
|
|
par niveau, par rank, …), calcule la complétude, …
|
|
|
|
.. todo:: Générer UNE fois la liste de skill que le gymnaste ne sait pas faire (1 query)
|
|
et les counts puis, dans le template on parcourt plusieurs fois cette même liste mais on
|
|
affiche conditionnellement (par age, par rank, ...)
|
|
"""
|
|
|
|
# Nombre de Skill que le gymnaste sait faire
|
|
gymnast_known_skills = gymnast.known_skills.count()
|
|
# print(gymnast_known_skills)
|
|
# context = __getInformationsFromLevel(gymnast, gymnast_known_skills)
|
|
context = __getInformationsFromRank(gymnast, gymnast_known_skills)
|
|
# context.update(__getInformationsFromRank(gymnast, gymnast_known_skills))
|
|
|
|
if gymnast.gender:
|
|
context["skillByAge"] = Skill.objects.filter(age_girl__lte=gymnast.age).exclude(
|
|
cando__gymnast=gymnast.id
|
|
)
|
|
else:
|
|
context["skillByAge"] = Skill.objects.filter(age_boy__lte=gymnast.age).exclude(
|
|
cando__gymnast=gymnast.id
|
|
)
|
|
|
|
context["gymnast"] = gymnast
|
|
context["totalKnownSkill"] = gymnast_known_skills
|
|
|
|
return context
|