NDOJ/judge/views/stats.py

103 lines
2.8 KiB
Python
Raw Permalink Normal View History

2020-01-21 06:35:58 +00:00
from itertools import chain, repeat
from operator import itemgetter
from django.conf import settings
from django.db.models import Case, Count, FloatField, IntegerField, Value, When
from django.db.models.expressions import CombinedExpression
from django.http import JsonResponse
from django.shortcuts import render
from django.utils.translation import gettext as _
from judge.models import Language, Submission
2022-05-14 17:57:27 +00:00
from judge.utils.stats import (
chart_colors,
get_bar_chart,
get_pie_chart,
highlight_colors,
)
2020-01-21 06:35:58 +00:00
2022-05-14 17:57:27 +00:00
ac_count = Count(
Case(When(submission__result="AC", then=Value(1)), output_field=IntegerField())
)
2020-01-21 06:35:58 +00:00
def repeat_chain(iterable):
return chain.from_iterable(repeat(iterable))
2022-05-14 17:57:27 +00:00
def language_data(
request, language_count=Language.objects.annotate(count=Count("submission"))
):
languages = (
language_count.filter(count__gt=0)
.values("key", "name", "count")
.order_by("-count")
)
2020-01-21 06:35:58 +00:00
num_languages = min(len(languages), settings.DMOJ_STATS_LANGUAGE_THRESHOLD)
2022-05-14 17:57:27 +00:00
other_count = sum(map(itemgetter("count"), languages[num_languages:]))
return JsonResponse(
{
"labels": list(map(itemgetter("name"), languages[:num_languages]))
+ ["Other"],
"datasets": [
{
"backgroundColor": chart_colors[:num_languages] + ["#FDB45C"],
"highlightBackgroundColor": highlight_colors[:num_languages]
+ ["#FFC870"],
"data": list(map(itemgetter("count"), languages[:num_languages]))
+ [other_count],
},
],
},
safe=False,
)
2020-01-21 06:35:58 +00:00
def ac_language_data(request):
return language_data(request, Language.objects.annotate(count=ac_count))
def status_data(request, statuses=None):
if not statuses:
2022-05-14 17:57:27 +00:00
statuses = (
Submission.objects.values("result")
.annotate(count=Count("result"))
.values("result", "count")
.order_by("-count")
)
2020-01-21 06:35:58 +00:00
data = []
for status in statuses:
2022-05-14 17:57:27 +00:00
res = status["result"]
2020-01-21 06:35:58 +00:00
if not res:
continue
2022-05-14 17:57:27 +00:00
count = status["count"]
2020-01-21 06:35:58 +00:00
data.append((str(Submission.USER_DISPLAY_CODES[res]), count))
return JsonResponse(get_pie_chart(data), safe=False)
def ac_rate(request):
2022-05-14 17:57:27 +00:00
rate = CombinedExpression(
ac_count / Count("submission"), "*", Value(100.0), output_field=FloatField()
)
data = (
Language.objects.annotate(total=Count("submission"), ac_rate=rate)
.filter(total__gt=0)
.order_by("total")
.values_list("name", "ac_rate")
)
2020-01-21 06:35:58 +00:00
return JsonResponse(get_bar_chart(list(data)))
def language(request):
2022-05-14 17:57:27 +00:00
return render(
request,
"stats/language.html",
{
"title": _("Language statistics"),
"tab": "language",
},
)