Jarvis/jarvis/objective/validators.py

145 lines
3.7 KiB
Python

import re
from jarvis.core.global_vars import ROUTINE_TYPE_CHOICE
# Subset function
def number_of_skill_from_subset(subset, educative=None):
"""Calcule le nombre de sauts par rapport à un subset.
Commence par vérifier que le subset est valide (car on ne sait jamais).
"""
if not is_valid_subset(subset):
return 0, 0, 0
subset = subset.replace("[", "").replace("]", "")
ranks = subset.split("-")
if ranks[0] == "":
start = 1
else:
start = int(ranks[0])
if ranks[1] == "":
if educative is not None:
end = educative.jumps.all().count()
else:
end = 10
else:
end = int(ranks[1])
number_of_skill = (end - start) + 1
return start, end, number_of_skill
# Difficulty function
def difficulty_from_regexp(educative, start, end):
"""Calcule la difficulté sur base du champs regexp d'un object."""
difficulty = 0
list_of_skill = educative.skill_links.filter(rank__gte=start, rank__lte=end)
# .aggregate(total=Sum("value"))
for routine_skill in list_of_skill:
difficulty += routine_skill.skill.difficulty
return difficulty
# Validation functions
def is_valid_regexp_one_arg(argument):
"""Vérifie une regexp avec un paramètre."""
if argument == "WC":
return True
if re.match(r"[1-9]+\|", argument):
return True
if not is_valid_dot(argument):
return False
value = argument.replace(".", "")
is_valid_routine = is_valid_routine_type(value)
if is_valid_routine:
return True
return is_valid_subset(argument)
def is_valid_regexp_two_args(routine, subset):
"""Vérifie une regexp avec deux paramètres."""
if not is_valid_dot(routine):
return False
routine_type = routine.replace(".", "")
is_valid_routine = is_valid_routine_type(routine_type)
if is_valid_routine:
return is_valid_subset(subset)
return False
def is_valid_dot(pattern):
"""Reçoit une chaine de caratère et vérifie que si elle contient un point (.), il se trouve
soit à la première position soit à la dernière position.
"""
if len(re.findall("\.", pattern)) > 1:
return False
if re.search("\.", pattern):
last_place = len(pattern) - 1
if pattern[0] != "." and pattern[last_place] != ".":
return False
return True
def is_valid_routine_type(routine_type):
"""Recoit une chaine de caractère et vérifie si elle est présente dans la liste
ROUTINE_TYPE_CHOICE (Educative vide !)
"""
is_valid_routine = False
for item in ROUTINE_TYPE_CHOICE:
if item[1] == routine_type:
is_valid_routine = True
break
return is_valid_routine
def is_valid_subset(subset):
"""Reçoit la description d'un subset sous forme de string et vérifie qu'elle est conforme.
Format attendu : [X-Y]
X ou Y peuvent être vide mais pas en même temps.
X est un entier >= 2
Y est un entier >= 2 OU Y > X si X est non vide
"""
if re.match(r"^\[(([2-9]+\-{1})|([2-9]+\-{1}[2-9]+)|(\-{1}[2-9]+))\]$", subset):
value = subset.replace("[", "").replace("]", "")
ranks = value.split("-")
if ranks[0] == "" or ranks[1] == "":
return True
if int(ranks[0]) < int(ranks[1]):
return True
return False
def is_valid_regexp(regexp):
"""Vérifie une regexp pour la classe TrainingRound."""
if not regexp:
return True
arguments = regexp.split(" ")
if len(arguments) >= 3:
return False
if len(arguments) == 2:
return is_valid_regexp_two_args(arguments[0], arguments[1])
return is_valid_regexp_one_arg(arguments[0])