Jarvis/jarvis/objective/tools.py

163 lines
5.4 KiB
Python

from django.db.models import Count
from jarvis.objective.models import Skill
def nb_skill_by_type(max_value, desired_type="level"):
"""
Renvoie le nombre de Skill qui ont un niveau/rang inférieur ou égal à celui passé en paramètre,
groupé par niveau/rank.
Args:
max_value (int): valeur du niveau/rang maximum désiré.
desired_type (string): type ("level" ou "rank") des Skills désirés.
Returns:
QuerySet
Example:
>>> from jarvis.objective.tools import nb_skill_by_type
>>> nb_skill_by_type(2)
<QuerySet [{'level': 0, 'nb_skill': 23}, {'level': 1, 'nb_skill': 20}, {'level': 2, 'nb_skill': 19}]> # pylint: disable=line-too-long
"""
if desired_type not in ("level", "rank"):
return None
nb_skill_by_level = (
Skill.objects.values(desired_type)
.filter(level__lte=max_value)
.order_by(desired_type)
.annotate(nb_skill=Count("id"))
)
return nb_skill_by_level
def nb_skill_lte_type(max_value, desired_type="level"):
"""
Renvoie le nombre de Skill qui ont un niveau inférieur ou égal à un niveau/rang passé en
paramètre.
Args:
max_value (int): valeur du niveau/rang maximum désiré.
desired_type (string): type ("level" ou "rank") des Skills désirés.
Returns:
int
Example:
>>> from jarvis.objective.tools import nb_skill_lte_type
>>> nb_skill_lte_type(2)
62
"""
if desired_type not in ("level", "rank"):
return None
if desired_type == "level":
nb_skill = Skill.objects.filter(level__lte=max_value)
else:
nb_skill = Skill.objects.filter(rank__lte=max_value)
return nb_skill.count()
def compute_completude(total_skill, gymnast_nb_known_skills, max_level_skill):
"""
Calcule la complétude et le niveau estimé d'un gymnaste.
Args:
total_skill (int): nombre totale de skill.
gymnast_nb_known_skills (int): nombre de skill connus du gymnaste.
max_skill (int): nombre maximum de skill.
Returns:
string: pourcentage de skill connus.
int: niveau estimé du gymnaste.
Example:
>>> from jarvis.objective.tools import compute_completude
>>> compute_completude(62, 12, 2)
('19%', 0)
"""
if total_skill:
percentage = gymnast_nb_known_skills / total_skill
completude = f"{int(percentage * 100)}%"
evaluated_level = int(max_level_skill * percentage)
else:
completude = None
evaluated_level = None
return completude, evaluated_level
def compute_statistics_by_type(
nb_skill_by_type, nb_known_skill_by_type, desired_type="level"
):
"""
Calcule les statistiques par niveau.
Args:
nb_skill_by_type (QuerySet): nombre de skill par niveau/rang.
<QuerySet [{'level': 0, 'nb_skill': 23}, {'level': 1, 'nb_skill': 20}]>
ou
<QuerySet [{'rank': 0, 'nb_skill': 23}, {'rank': 1, 'nb_skill': 20}]>
nb_known_skill_by_type (QuerySet): nombre de skill connus par niveau/rang.
<QuerySet [{'level': 0, 'nb_known_skill': 10}, {'level': 1, 'nb_known_skill': 5}]>
ou
<QuerySet [{'rank': 0, 'nb_known_skill': 10}, {'rank': 1, 'nb_known_skill': 5}]>
desired_type (string): type ("level" ou "rank") des Skills désirés.
Returns:
array of list (todo: why not a (list of) dictionnary?)
Examples:
>>> from jarvis.objective.tools import nb_skill_by_type, compute_statistics_by_type
>>> gymnast = Gymnast.objects.get(pk=1)
>>> nb_skill_by_level = nb_skill_by_type(1, "level")
>>> nb_known_skill_by_level = gymnast.nb_known_skill_by_level()
>>> compute_statistics_by_type(nb_skill_by_level, nb_known_skill_by_level, "level")
[(0, 23, 15, 65), (1, 20, 5, 25), …]
>>> from jarvis.objective.tools import nb_skill_by_type, compute_statistics_by_type
>>> gymnast = Gymnast.objects.get(pk=1)
>>> nb_skill_by_rank = nb_skill_by_type(1, "rank")
>>> nb_known_skill_by_rank = gymnast.nb_known_skill_by_rank()
>>> compute_statistics_by_type(nb_skill_by_rank, nb_known_skill_by_rank, "rank")
[(1, 5, 2, 40), (2, 5, 4, 80), …]
"""
if desired_type not in ("level", "rank"):
return None
j = 0
percentages = []
for skill in nb_skill_by_type:
# les deux lignes (nécessaires pour les skill "rank") ci-dessous devraient partir
if desired_type == "rank" and j >= nb_known_skill_by_type.count():
break
tmp = None
if skill[desired_type] == nb_known_skill_by_type[j][desired_type]:
if skill["nb_skill"] != nb_known_skill_by_type[j]["nb_known_skill"]:
tmp = (
skill[desired_type],
skill["nb_skill"],
nb_known_skill_by_type[j]["nb_known_skill"],
int(
(
nb_known_skill_by_type[j]["nb_known_skill"]
/ skill["nb_skill"]
)
* 100
),
)
j += 1
else:
tmp = (skill[desired_type], skill["nb_skill"], 0, 0)
if tmp:
percentages.append(tmp)
return percentages