Skip to content

Commit

Permalink
decrease competition, starts #10
Browse files Browse the repository at this point in the history
  • Loading branch information
wurstbroteater committed Jul 28, 2024
1 parent 0f61465 commit 9565a97
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 17 deletions.
2 changes: 1 addition & 1 deletion quiz/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class UserAnswerAdmin(admin.ModelAdmin):


class QuizAdmin(admin.ModelAdmin):
list_display = ["name"]
list_display = ["id", "name"]
fieldsets = [
(None, {"fields": ["name"]}),
]
Expand Down
65 changes: 49 additions & 16 deletions quiz/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,37 +42,70 @@ def leaderboard_overall_view(request):

def leaderboard_quiz_view(request, quiz_id):
quiz = get_object_or_404(Quiz, id=quiz_id)
return render(request, 'quiz/leaderboard_quiz.html', {'leaderboard_data': _get_leaderboard(quiz)})
leaderboard_data = _get_leaderboard(quiz)
user_progress = _get_user_progress(request.user, quiz)
return render(request, 'quiz/leaderboard_quiz.html', {
'leaderboard_data': leaderboard_data,
'user_progress': user_progress,
})


def _get_leaderboard(quiz):
turns = QuizTurn.objects.filter(quiz=quiz, is_completed=True)
user_scores = list(map(lambda turn: _get_user_score(turn), turns))
user_scores = sorted(user_scores, key=lambda t: t["total_correct"], reverse=True)
distinct_key = "username"
seen_keys = set()
distinct_data = []

distinct_data = {}
for d in user_scores:
k = d[distinct_key]
if k not in seen_keys:
distinct_data.append(d)
seen_keys.add(k)
username = d['username']
if username not in distinct_data:
# extend user_score with best_score_percentage
distinct_data[username] = d | {
'best_score_percentage': max(d['score_percentage'],
distinct_data.get(username, {}).get('best_score_percentage', 0))
}

return {
'quiz': quiz,
'user_scores': distinct_data
'user_scores': list(distinct_data.values()),
'average_score': sum(d['score_percentage'] for d in user_scores) / len(user_scores) if user_scores else 0,
'percentiles': _calculate_percentiles(user_scores)
}


def _get_user_score(turn):
correct_user_answers = (UserAnswer.objects.filter(turn=turn, selected_choice__is_correct=True)
.values('question').distinct().count())
correct_user_answers = UserAnswer.objects.filter(turn=turn, selected_choice__is_correct=True).values(
'question').distinct().count()
total_questions = Question.objects.filter(related_quiz=turn.quiz).count()
return {"total_correct": correct_user_answers,
"total_possible": total_questions,
"score_percentage": correct_user_answers * 100.0 / total_questions,
"username": turn.user.username
}
# print(f"go {turn.user.username}")
return {
"total_correct": correct_user_answers,
"total_possible": total_questions,
"score_percentage": correct_user_answers * 100.0 / total_questions,
"username": turn.user.username
}


def _calculate_percentiles(user_scores):
scores = [d['score_percentage'] for d in user_scores]
scores.sort()
percentiles = {}
for i, score in enumerate(scores):
percentile = (i + 1) / len(scores) * 100
percentiles[score] = percentile
return percentiles


def _get_user_progress(user, quiz):
turns = QuizTurn.objects.filter(user=user, quiz=quiz, is_completed=True)
scores = [_get_user_score(turn)['score_percentage'] for turn in turns]
best_score = max(scores, default=0)
average_score = sum(scores) / len(scores) if scores else 0
return {
'best_score': best_score,
'average_score': round(average_score, 2),
'completed_turns': len(turns)
}


# --------------------------------------- Quiz ----------------------------------
Expand Down
25 changes: 25 additions & 0 deletions templates/quiz/leaderboard_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,30 @@
font-weight: bold;
color: #13A256;
}

.progress-bar {
width: 100%;
background-color: #333;
border-radius: 5px;
overflow: hidden;
height: 20px;
}

.progress {
height: 100%;
background-color: #13A256;
text-align: center;
color: white;
line-height: 20px;
white-space: nowrap;
padding: 0 5px;
}

.user-progress-table {
width: 100%;
margin-bottom: 20px;
border-collapse: collapse;
}

</style>
{% endblock %}
34 changes: 34 additions & 0 deletions templates/quiz/leaderboard_quiz.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,41 @@

{% block title %}{{ leaderboard_data.quiz.name }} - Leaderboard{% endblock %}


{% block content %}
<div id="leaderboard">
<h1>{{ leaderboard_data.quiz.name }} - Leaderboard</h1>

<!-- Your Progress Section -->
<h2>Your Progress</h2>
<table>
<tr>
<th>Best Score</th>
<th>Average Score</th>
<th>Quizzes Completed</th>
</tr>
<tr>
<td>
<div class="progress-bar">
<div class="progress"
style="width: {{ user_progress.best_score }}%;">{{ user_progress.best_score }}%
</div>
</div>
</td>
<td>
<div class="progress-bar">
<div class="progress"
style="width: {{ user_progress.average_score }}%;">{{ user_progress.average_score }}%
</div>
</div>
</td>
<td>{{ user_progress.completed_turns }}</td>
</tr>
</table>

<!-- Existing Leaderboard Section -->
<h2>QUiz Leaderboard</h2>
<p>Average Score for Quiz: {{ leaderboard_data.average_score }}%</p>
<table>
<thead>
<tr>
Expand All @@ -31,3 +63,5 @@ <h1>{{ leaderboard_data.quiz.name }} - Leaderboard</h1>
</table>
</div>
{% endblock %}


0 comments on commit 9565a97

Please sign in to comment.