68 lines
2.5 KiB
Python
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',
|
|
})
|