update yearly ac rate
This commit is contained in:
@@ -9,6 +9,7 @@ from ..views.admin import (
|
|||||||
ProblemVisibleAPI,
|
ProblemVisibleAPI,
|
||||||
StuckProblemsAPI,
|
StuckProblemsAPI,
|
||||||
TestCaseAPI,
|
TestCaseAPI,
|
||||||
|
TopACTrendAPI,
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@@ -16,6 +17,7 @@ urlpatterns = [
|
|||||||
path("problem", ProblemAPI.as_view()),
|
path("problem", ProblemAPI.as_view()),
|
||||||
path("problem/visible", ProblemVisibleAPI.as_view()),
|
path("problem/visible", ProblemVisibleAPI.as_view()),
|
||||||
path("problem/stuck", StuckProblemsAPI.as_view()),
|
path("problem/stuck", StuckProblemsAPI.as_view()),
|
||||||
|
path("problem/top_ac_trend", TopACTrendAPI.as_view()),
|
||||||
path("problem/flowchart", ProblemFlowchartAIGen.as_view()),
|
path("problem/flowchart", ProblemFlowchartAIGen.as_view()),
|
||||||
path("contest/problem", ContestProblemAPI.as_view()),
|
path("contest/problem", ContestProblemAPI.as_view()),
|
||||||
path("contest_problem/make_public", MakeContestProblemPublicAPIView.as_view()),
|
path("contest_problem/make_public", MakeContestProblemPublicAPIView.as_view()),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from wsgiref.util import FileWrapper
|
|||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.db.models import Count, Q
|
from django.db.models import Count, Q
|
||||||
|
from django.db.models.functions import ExtractYear
|
||||||
from django.http import StreamingHttpResponse
|
from django.http import StreamingHttpResponse
|
||||||
|
|
||||||
from account.decorators import ensure_created_by, problem_permission_required, super_admin_required
|
from account.decorators import ensure_created_by, problem_permission_required, super_admin_required
|
||||||
@@ -547,3 +548,59 @@ class StuckProblemsAPI(APIView):
|
|||||||
for r in rows
|
for r in rows
|
||||||
]
|
]
|
||||||
return self.success(result)
|
return self.success(result)
|
||||||
|
|
||||||
|
|
||||||
|
class TopACTrendAPI(APIView):
|
||||||
|
@super_admin_required
|
||||||
|
def get(self, request):
|
||||||
|
from collections import defaultdict
|
||||||
|
from submission.models import JudgeStatus
|
||||||
|
|
||||||
|
top_problems = list(
|
||||||
|
Submission.objects.filter(contest_id__isnull=True)
|
||||||
|
.values("problem_id", "problem___id", "problem__title")
|
||||||
|
.annotate(total=Count("id"))
|
||||||
|
.order_by("-total")[:10]
|
||||||
|
)
|
||||||
|
if not top_problems:
|
||||||
|
return self.success([])
|
||||||
|
|
||||||
|
top_ids = [r["problem_id"] for r in top_problems]
|
||||||
|
problem_meta = {
|
||||||
|
r["problem_id"]: (r["problem___id"], r["problem__title"])
|
||||||
|
for r in top_problems
|
||||||
|
}
|
||||||
|
|
||||||
|
yearly_rows = (
|
||||||
|
Submission.objects.filter(contest_id__isnull=True, problem_id__in=top_ids)
|
||||||
|
.annotate(year=ExtractYear("create_time"))
|
||||||
|
.values("problem_id", "year")
|
||||||
|
.annotate(
|
||||||
|
total=Count("id"),
|
||||||
|
accepted=Count("id", filter=Q(result=JudgeStatus.ACCEPTED)),
|
||||||
|
)
|
||||||
|
.order_by("problem_id", "year")
|
||||||
|
)
|
||||||
|
|
||||||
|
by_problem: dict[int, list] = defaultdict(list)
|
||||||
|
for r in yearly_rows:
|
||||||
|
by_problem[r["problem_id"]].append(
|
||||||
|
{
|
||||||
|
"year": r["year"],
|
||||||
|
"total": r["total"],
|
||||||
|
"accepted": r["accepted"],
|
||||||
|
"ac_rate": round(r["accepted"] / r["total"] * 100, 1)
|
||||||
|
if r["total"]
|
||||||
|
else 0,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
result = [
|
||||||
|
{
|
||||||
|
"problem_id": problem_meta[pid][0],
|
||||||
|
"problem_title": problem_meta[pid][1],
|
||||||
|
"yearly": by_problem[pid],
|
||||||
|
}
|
||||||
|
for pid in top_ids
|
||||||
|
]
|
||||||
|
return self.success(result)
|
||||||
|
|||||||
Reference in New Issue
Block a user