Compare commits

...

2 Commits

Author SHA1 Message Date
Gregory Trullemans 1fed0bb5db Adding views method for skill : prerequisiteless
continuous-integration/drone/push Build is passing Details
2022-01-14 20:06:29 +01:00
Gregory Trullemans aa9f847134 Update JS for DAG presentation 2022-01-13 21:16:00 +01:00
5 changed files with 82 additions and 18 deletions

View File

@ -3,6 +3,8 @@
{% block header %}
<style>
svg {
/* width: 50%;
height: 50%; */
width: 25%;
height: 25%;
}
@ -40,7 +42,7 @@
+ (string.split(/¾/g).length - 1)
+ (string.split(/B/g).length - 1)
+ (string.split(/O/g).length - 1);
return string.length + number_of_big_char - (number_of_spaces + (number_of_small_char / 2));
return string.length + (number_of_big_char / 2) - (number_of_spaces + (number_of_small_char / 2));
}
(async () => {
@ -58,7 +60,7 @@
]
const dag = d3.dagStratify()(data);
const nodeRadius = 20;
const nodeRadius = 30;
const layout = d3
//
// Base layout
@ -165,7 +167,7 @@
// .attr("font-size", function(d) { return Math.min(2 * d.r, (2 * d.r - 8) / this.getComputedTextLength() * 24) + "px"; })
// .attr("font-size", function(d) {return (1 / d.data.id.length) * 60;})
// .attr("font-size", set_font_size(d.data.id))
.attr("font-size", function(d) {return (1 / compute_font_size(d.data.id)) * 60;})
.attr("font-size", function(d) {return (1 / compute_font_size(d.data.id)) * 80;})
.attr("font-weight", "bold")
.attr("font-family", "sans-serif")
.attr("text-anchor", "middle")

View File

@ -13,13 +13,15 @@ from ultron.objective.models import Educative, PrerequisiteClosure
class Command(BaseCommand):
def handle(self, *args, **options):
educative_list = Educative.objects.all()
count = 0
for educative in educative_list:
count += 1
print(str(count) + ' - Traitement de ' + str(educative.long_label))
breadcrumb = educative.breadcrumb()
for path in range(0, len(breadcrumb)):
tree = set(PrerequisiteClosure.objects.filter(descendant=educative, path=path))
for position, ancestor in enumerate(breadcrumb[path]):
tree_path, _ = PrerequisiteClosure.objects.get_or_create(
ancestor=ancestor, descendant=educative, level=position, path=path

60
ultron/objective/tests.py Normal file
View File

@ -0,0 +1,60 @@
from django.test import TestCase
from ultron.objective.models import Educative
class EducativeTestCase(TestCase):
def setUp(self):
"""
Structure finale :
1 -> 2
1 -> 6
3 -> 4 -> 5 -> 6 -> 7
1 -> 2 -> 9
3 -> 4 -> 5 -> 6 -> 7 -> 9
"""
# 1 et 3 Eductative sans pre-requis
educ_1 = Educative.objects.create(long_label="1/2 vrille", difficulty=0.1, level=1, rank=1)
educ_3 = Educative.objects.create(long_label="4 pattes", difficulty=0.1, level=1, rank=1)
educ_2 = Educative.objects.create(long_label="tour", difficulty=0.2, level=1, rank=2)
educ_2.prerequisites.add(educ_1)
educ_4 = Educative.objects.create(long_label="Ventre", difficulty=0.1, level=1, rank=1)
educ_4.prerequisites.add(educ_3)
educ_5 = Educative.objects.create(long_label="3/4 Avant /", difficulty=0.3, level=1, rank=1)
educ_5.prerequisites.add(educ_4)
educ_6 = Educative.objects.create(long_label="Avant /", difficulty=0.6, level=1, rank=1)
educ_6.prerequisites.add(educ_5)
educ_7 = Educative.objects.create(long_label="Barani /", difficulty=0.6, level=1, rank=1)
educ_7.prerequisites.add(educ_6)
educ_7.prerequisites.add(educ_1)
# educ_8 = Educative.objects.create(long_label="3/4 Avant vrille", difficulty=0.5, level=1, rank=1)
# educ_8.prerequisites.add(educ_6)
# educ_8.prerequisites.add(educ_2)
educ_9 = Educative.objects.create(long_label="Rudy", difficulty=0.8, level=1, rank=1)
educ_9.prerequisites.add(educ_2)
educ_9.prerequisites.add(educ_7)
def test_educative_breadcrumb(self):
# Cas "None" d'un objet qui n'a pas de prerequis
educ_1 = Educative.objects.get(long_label="1/2 vrille")
self.assertEqual(educ_1.breadcrumb(), [[educ_1]])
# Cas simplise : un objet avec un seul encetre
educ_2 = Educative.objects.get(long_label="tour")
self.assertEqual(educ_2.breadcrumb(), [[educ_2, educ_1]])
# Cas simple : chaque skill n'a qu'un seul encetre
educ_3 = Educative.objects.get(long_label="4 pattes")
educ_4 = Educative.objects.get(long_label="Ventre")
educ_5 = Educative.objects.get(long_label="3/4 Avant /")
educ_6 = Educative.objects.get(long_label="Avant /")
educ_7 = Educative.objects.get(long_label="Barani /")
self.assertEqual(educ_7.breadcrumb(), [[educ_7, educ_1], [educ_7, educ_6, educ_5, educ_4, educ_3]])
# Cas plus complexe : l'éduc 8 a deux encetres qui ont chacun une lignée d'encêtres
educ_9 = Educative.objects.get(long_label="Rudy")
self.assertEqual(educ_9.breadcrumb(), [[educ_9, educ_7, educ_1], [educ_9, educ_7, educ_6, educ_5, educ_4, educ_3], [educ_9, educ_2, educ_1]])

View File

@ -12,6 +12,7 @@ skill_urlpatterns = [
path(r"search/", views.skill_listing),
path(r"<int:skill_id>/", views.skill_details, name="skill_details"),
path(r"<int:skill_id>/tree/", views.skill_tree, name="skill_tree"),
path(r"prerequisiteless/", views.skill_without_prerequisite_listing, name="skill_without_prerequisite"),
path(r"", views.skill_listing, name="skill_list"),
]

View File

@ -36,11 +36,20 @@ def skill_lookup(request):
{"ID": x.id, "Name": str(x), "Notation": x.notation} for x in model_results
]
# json = simplejson.dumps(results)
# return HttpResponse(json, content_type="application/json")
return JsonResponse(results, safe=False)
@login_required
@require_http_methods(["GET"])
def skill_without_prerequisite_listing(request):
"""
Récupère la liste des skills suivant un pattern si celui-ci est définit.
"""
skill_list = Skill.objects.filter(prerequisites=None)
context = {"skill_list": skill_list}
return render(request, "objectives/skills/list.html", context)
@login_required
@require_http_methods(["GET"])
def skill_listing(request, field=None, expression=None, value=None, level=None):
@ -61,7 +70,7 @@ def skill_listing(request, field=None, expression=None, value=None, level=None):
kwargs = {"{0}__{1}".format(field, expression): value}
skill_list = Skill.objects.filter(**kwargs)
elif level is not None:
skill_list = Skill.objects.filter
skill_list = Skill.objects.filter(level=level)
else:
skill_list = Skill.objects.all()
@ -76,19 +85,9 @@ def skill_tree(request, skill_id):
"""
skill = get_object_or_404(Skill, pk=skill_id)
node_dict = {}
# node_list[skill] = list(skill.prerequisites.all())
skill_closure = PrerequisiteClosure.objects.filter(descendant=skill)
for closure in skill_closure:
node_dict[closure.ancestor] = closure.ancestor.prerequisites.all()
# if closure.descendant != closure.ancestor:
# print(closure)
# print(node_dict)
# edge_list = {}
# for skill in node_list.values():
# edge_list[skill.long_label] = list(skill.prerequisites.all())
# print(edge_list)
context = {"skill": skill, "node_dict": node_dict}
return render(request, "objectives/skills/tree.html", context)