Enhance exam review summary to include dominant score for top submitted answers
This commit is contained in:
@@ -67,9 +67,20 @@
|
|||||||
{% if top_answers %}
|
{% if top_answers %}
|
||||||
<ul class="list-group">
|
<ul class="list-group">
|
||||||
{% for a in top_answers %}
|
{% for a in top_answers %}
|
||||||
<li class="list-group-item d-flex justify-content-between align-items-start">
|
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||||
<div>{{ a.answer_compare }}</div>
|
<div class="flex-grow-1">{{ a.answer_compare }}</div>
|
||||||
<div class="small text-muted">{{ a.count }}</div>
|
<div class="d-flex align-items-center">
|
||||||
|
{% if a.dominant_score == '2' %}
|
||||||
|
<span class="badge bg-success">Correct</span>
|
||||||
|
{% elif a.dominant_score == '1' %}
|
||||||
|
<span class="badge bg-warning text-dark">Half</span>
|
||||||
|
{% elif a.dominant_score == '0' %}
|
||||||
|
<span class="badge bg-danger">Incorrect</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="badge bg-secondary">Unmarked</span>
|
||||||
|
{% endif %}
|
||||||
|
<div class="small text-muted me-2">{{ a.count }}</div>
|
||||||
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
+31
-2
@@ -316,8 +316,37 @@ def exam_review_question_summary(request, pk: int, q_index: int):
|
|||||||
# simpler: compute via values and normalise unmarked -> 'empty'
|
# simpler: compute via values and normalise unmarked -> 'empty'
|
||||||
score_counts = {str(row["score"]) if row["score"] is not None else "empty": row["count"] for row in ua_qs.values("score").annotate(count=Count("id"))}
|
score_counts = {str(row["score"]) if row["score"] is not None else "empty": row["count"] for row in ua_qs.values("score").annotate(count=Count("id"))}
|
||||||
|
|
||||||
# top submitted answers (by answer_compare)
|
# top submitted answers (by answer_compare) with dominant score per answer
|
||||||
top_answers = list(ua_qs.values("answer_compare").annotate(count=Count("id")).order_by("-count")[:10])
|
# First, get counts grouped by answer_compare and score
|
||||||
|
grouped = ua_qs.values("answer_compare", "score").annotate(count=Count("id"))
|
||||||
|
|
||||||
|
# Aggregate totals and score breakdown per answer_compare
|
||||||
|
answer_map = {}
|
||||||
|
for row in grouped:
|
||||||
|
ans = row["answer_compare"]
|
||||||
|
sc = str(row["score"]) if row["score"] is not None else "empty"
|
||||||
|
cnt = row["count"]
|
||||||
|
if ans not in answer_map:
|
||||||
|
answer_map[ans] = {"total": 0, "score_counts": {}}
|
||||||
|
answer_map[ans]["total"] += cnt
|
||||||
|
answer_map[ans]["score_counts"][sc] = answer_map[ans]["score_counts"].get(sc, 0) + cnt
|
||||||
|
|
||||||
|
# Build list sorted by total count desc, and choose a dominant score per answer
|
||||||
|
top_answers = []
|
||||||
|
for ans, meta in answer_map.items():
|
||||||
|
# pick dominant score by highest count; tie-break prefer higher numeric score
|
||||||
|
score_counts = meta["score_counts"]
|
||||||
|
# sort by (count desc, score desc) where 'empty' maps to -1
|
||||||
|
def score_key(item):
|
||||||
|
s, c = item
|
||||||
|
s_val = -1 if s == "empty" else int(s)
|
||||||
|
return (c, s_val)
|
||||||
|
|
||||||
|
dominant = max(score_counts.items(), key=score_key)[0]
|
||||||
|
top_answers.append({"answer_compare": ans, "count": meta["total"], "dominant_score": dominant})
|
||||||
|
|
||||||
|
top_answers.sort(key=lambda x: x["count"], reverse=True)
|
||||||
|
top_answers = top_answers[:10]
|
||||||
|
|
||||||
correct_count = None
|
correct_count = None
|
||||||
correct_pct = None
|
correct_pct = None
|
||||||
|
|||||||
Reference in New Issue
Block a user