Enhance exam review summary to include dominant score for top submitted answers
This commit is contained in:
@@ -67,9 +67,20 @@
|
||||
{% if top_answers %}
|
||||
<ul class="list-group">
|
||||
{% for a in top_answers %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-start">
|
||||
<div>{{ a.answer_compare }}</div>
|
||||
<div class="small text-muted">{{ a.count }}</div>
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<div class="flex-grow-1">{{ a.answer_compare }}</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>
|
||||
{% endfor %}
|
||||
</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'
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user