NDOJ/judge/views/stats.py
2020-01-21 15:35:58 +09:00

68 lines
2.5 KiB
Python

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
from judge.utils.stats import chart_colors, get_bar_chart, get_pie_chart, highlight_colors
ac_count = Count(Case(When(submission__result='AC', then=Value(1)), output_field=IntegerField()))
def repeat_chain(iterable):
return chain.from_iterable(repeat(iterable))
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')
num_languages = min(len(languages), settings.DMOJ_STATS_LANGUAGE_THRESHOLD)
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)
def ac_language_data(request):
return language_data(request, Language.objects.annotate(count=ac_count))
def status_data(request, statuses=None):
if not statuses:
statuses = (Submission.objects.values('result').annotate(count=Count('result'))
.values('result', 'count').order_by('-count'))
data = []
for status in statuses:
res = status['result']
if not res:
continue
count = status['count']
data.append((str(Submission.USER_DISPLAY_CODES[res]), count))
return JsonResponse(get_pie_chart(data), safe=False)
def ac_rate(request):
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')
return JsonResponse(get_bar_chart(list(data)))
def language(request):
return render(request, 'stats/language.html', {
'title': _('Language statistics'), 'tab': 'language',
})