From ecf67e3c2b68e81733f531b28bf46e08f2fcda95 Mon Sep 17 00:00:00 2001 From: Ross Date: Mon, 10 Nov 2025 10:38:13 +0000 Subject: [PATCH] Enhance exam review summary to include dominant score for top submitted answers --- ...exam_review_question_summary_fragment.html | 17 ++++++++-- anatomy/views.py | 33 +++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/anatomy/templates/anatomy/partials/exam_review_question_summary_fragment.html b/anatomy/templates/anatomy/partials/exam_review_question_summary_fragment.html index 61a650e0..b3a9e558 100644 --- a/anatomy/templates/anatomy/partials/exam_review_question_summary_fragment.html +++ b/anatomy/templates/anatomy/partials/exam_review_question_summary_fragment.html @@ -67,9 +67,20 @@ {% if top_answers %} diff --git a/anatomy/views.py b/anatomy/views.py index 8090f9c2..f77b91df 100644 --- a/anatomy/views.py +++ b/anatomy/views.py @@ -316,8 +316,37 @@ def exam_review_question_summary(request, pk: int, q_index: int): # 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"))} - # top submitted answers (by answer_compare) - top_answers = list(ua_qs.values("answer_compare").annotate(count=Count("id")).order_by("-count")[:10]) + # top submitted answers (by answer_compare) with dominant score per answer + # 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_pct = None