{% extends "base.html" %} {% block title %}Détail – {{ student.full_name }}{% endblock %} {% block head %} {% endblock %} {% block body %}

{{ student.full_name }}

{{ student.email }}

{% if assessment %}

Démarré : {{ assessment.started_at[:16].replace('T',' ') }} {% if assessment.submitted_at %} · Soumis : {{ assessment.submitted_at[:16].replace('T',' ') }} {% endif %}

{% endif %}
{% if grade %}
{{ "%.1f"|format(grade.quiz_score) }}/12
QCM
{{ "%.1f"|format(grade.usecase_score) }}/8
Cas pratiques
{{ "%.1f"|format(grade.total_score) }}/20
Note finale
{% else %}
Pas encore de note
{% endif %}
{% if grade %}

Ajustement manuel de la note

✓ Sauvegardé
{% endif %}
{% if not assessment %}
📭

Cet étudiant n'a pas encore démarré l'évaluation.

{% else %}

Partie 1 – QCM

{% for qa in quiz_answers %}
Q{{ loop.index }} {{ qa.topic }}
{% if qa.is_correct %} ✓ Correct {% else %} ✗ Incorrect {% endif %}

{{ qa.question }}

{% for choice, label in [(qa.choice_a,'A'),(qa.choice_b,'B'),(qa.choice_c,'C'),(qa.choice_d,'D')] %}
{% if label == qa.student_answer %}{% endif %} {{ choice }}
{% endfor %}
{% if not qa.is_correct %}
💡 {{ qa.explanation }}
{% endif %}
{% endfor %}

Partie 2 – Cas Pratiques

Correct coché Faux coché Oublié Correct ignoré
{% for uca in uc_list %}
Cas {{ loop.index }} {{ uca.topic }}
{% set score_pct = (uca.auto_score / uca.max_score * 100)|int if uca.max_score > 0 else 0 %}
{{ "%.2f"|format(uca.auto_score) }}/{{ uca.max_score|int }}
Contexte : {{ uca.scenario }}

{{ uca.question }}

Réponses cochées vs attendues

{% if uca.propositions %} {% for item in uca.propositions %} {% if item.result == 'tp' %} {# True positive: checked AND correct → green #}
{{ item.text }} ✓ Correct coché
{% elif item.result == 'fp' %} {# False positive: checked but NOT correct → red (penalty) #}
{{ item.text }} ✗ Faux coché (−pénalité)
{% elif item.result == 'fn' %} {# False negative: NOT checked but WAS correct → orange (missed) #}
{{ item.text }} ⚠ Oublié (attendu)
{% else %} {# True negative: NOT checked AND NOT correct → neutral/slate #}
{{ item.text }} Correct ignoré
{% endif %} {% endfor %} {% set tp_count = uca.propositions | selectattr('result', 'equalto', 'tp') | list | length %} {% set fp_count = uca.propositions | selectattr('result', 'equalto', 'fp') | list | length %} {% set fn_count = uca.propositions | selectattr('result', 'equalto', 'fn') | list | length %} {% set correct_count = uca.propositions | selectattr('correct', 'equalto', true) | list | length %}
✓ {{ tp_count }}/{{ correct_count }} corrects cochés {% if fp_count > 0 %} ✗ {{ fp_count }} faux positif{% if fp_count > 1 %}s{% endif %} {% endif %} {% if fn_count > 0 %} ⚠ {{ fn_count }} oublié{% if fn_count > 1 %}s{% endif %} {% endif %}
{% else %}
(Aucune réponse fournie)
{% endif %}
📖 Réponse modèle (instructeur)
{{ uca.model_answer }}
{% endfor %}
{% endif %}
{% endblock %}