Make ioi16 related files cleaner

This commit is contained in:
cuom1999 2023-01-02 17:22:45 -06:00
parent e10a8aca5c
commit 07d5ad2216
14 changed files with 145 additions and 92 deletions

View file

@ -68,7 +68,7 @@ class ContestProblemInlineForm(ModelForm):
class Meta: class Meta:
widgets = { widgets = {
"problem": AdminHeavySelect2Widget(data_view="problem_select2"), "problem": AdminHeavySelect2Widget(data_view="problem_select2"),
"frozen_subtasks": TextInput(attrs={"size": "3"}), "hidden_subtasks": TextInput(attrs={"size": "3"}),
"points": TextInput(attrs={"size": "1"}), "points": TextInput(attrs={"size": "1"}),
"order": TextInput(attrs={"size": "1"}), "order": TextInput(attrs={"size": "1"}),
"output_prefix_override": TextInput(attrs={"size": "1"}), "output_prefix_override": TextInput(attrs={"size": "1"}),
@ -85,7 +85,7 @@ class ContestProblemInline(admin.TabularInline):
"partial", "partial",
"is_pretested", "is_pretested",
"max_submissions", "max_submissions",
"frozen_subtasks", "hidden_subtasks",
"output_prefix_override", "output_prefix_override",
"order", "order",
"rejudge_column", "rejudge_column",

View file

@ -16,6 +16,9 @@ class BaseContestFormat(metaclass=ABCMeta):
self.config = config self.config = config
self.contest = contest self.contest = contest
# Use in ioi16 to display ranking with hidden subtasks
self.has_hidden_subtasks = False
@abstractproperty @abstractproperty
def name(self): def name(self):
""" """
@ -98,9 +101,9 @@ class BaseContestFormat(metaclass=ABCMeta):
return "partial-score" return "partial-score"
def handle_frozen_state(self, participation, format_data): def handle_frozen_state(self, participation, format_data):
frozen_subtasks = {} hidden_subtasks = {}
if hasattr(self, "get_frozen_subtasks"): if hasattr(self, "get_hidden_subtasks"):
frozen_subtasks = self.get_frozen_subtasks() hidden_subtasks = self.get_hidden_subtasks()
queryset = participation.submissions.values("problem_id").annotate( queryset = participation.submissions.values("problem_id").annotate(
time=Max("submission__date") time=Max("submission__date")
@ -113,7 +116,7 @@ class BaseContestFormat(metaclass=ABCMeta):
and result["time"] and result["time"]
>= self.contest.freeze_after + participation.start >= self.contest.freeze_after + participation.start
) )
if is_after_freeze or frozen_subtasks.get(problem): if is_after_freeze or hidden_subtasks.get(problem):
format_data[problem]["frozen"] = True format_data[problem]["frozen"] = True
else: else:
format_data[problem] = {"time": 0, "points": 0, "frozen": True} format_data[problem] = {"time": 0, "points": 0, "frozen": True}

View file

@ -14,14 +14,18 @@ class NewIOIContestFormat(IOIContestFormat):
cumtime: Specify True if time penalties are to be computed. Defaults to False. cumtime: Specify True if time penalties are to be computed. Defaults to False.
""" """
def get_frozen_subtasks(self): def __init__(self, contest, config):
queryset = self.contest.contest_problems.values_list("id", "frozen_subtasks") super().__init__(contest, config)
self.has_hidden_subtasks = True
def get_hidden_subtasks(self):
queryset = self.contest.contest_problems.values_list("id", "hidden_subtasks")
res = {} res = {}
for problem_id, frozen_subtasks in queryset: for problem_id, hidden_subtasks in queryset:
subtasks = set() subtasks = set()
if frozen_subtasks: if hidden_subtasks:
frozen_subtasks = frozen_subtasks.split(",") hidden_subtasks = hidden_subtasks.split(",")
for i in frozen_subtasks: for i in hidden_subtasks:
try: try:
subtasks.add(int(i)) subtasks.add(int(i))
except Exception as e: except Exception as e:
@ -100,7 +104,7 @@ class NewIOIContestFormat(IOIContestFormat):
return cursor.fetchall() return cursor.fetchall()
def update_participation(self, participation): def update_participation(self, participation):
frozen_subtasks = self.get_frozen_subtasks() hidden_subtasks = self.get_hidden_subtasks()
def calculate_format_data(participation, include_frozen): def calculate_format_data(participation, include_frozen):
format_data = {} format_data = {}
@ -127,7 +131,7 @@ class NewIOIContestFormat(IOIContestFormat):
"total_points": 0, "total_points": 0,
} }
if ( if (
subtask not in frozen_subtasks.get(problem_id, set()) subtask not in hidden_subtasks.get(problem_id, set())
or include_frozen or include_frozen
): ):
format_data[problem_id]["points"] += subtask_points format_data[problem_id]["points"] += subtask_points

View file

@ -0,0 +1,28 @@
# Generated by Django 3.2.16 on 2023-01-02 22:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("judge", "0143_auto_20221229_0153"),
]
operations = [
migrations.RemoveField(
model_name="contestproblem",
name="frozen_subtasks",
),
migrations.AddField(
model_name="contestproblem",
name="hidden_subtasks",
field=models.CharField(
blank=True,
help_text="Separated by commas, e.g: 2, 3",
max_length=20,
null=True,
verbose_name="hidden subtasks",
),
),
]

View file

@ -786,9 +786,9 @@ class ContestProblem(models.Model):
MinValueValidator(0, _("Why include a problem you " "can't submit to?")) MinValueValidator(0, _("Why include a problem you " "can't submit to?"))
], ],
) )
frozen_subtasks = models.CharField( hidden_subtasks = models.CharField(
help_text=_("Only for format new IOI. Separated by commas, e.g: 2, 3"), help_text=_("Separated by commas, e.g: 2, 3"),
verbose_name=_("frozen subtasks"), verbose_name=_("hidden subtasks"),
null=True, null=True,
blank=True, blank=True,
max_length=20, max_length=20,

View file

@ -295,7 +295,7 @@ class ContestMixin(object):
context["meta_description"] = self.object.summary or metadata[0] context["meta_description"] = self.object.summary or metadata[0]
context["og_image"] = self.object.og_image or metadata[1] context["og_image"] = self.object.og_image or metadata[1]
context["has_moss_api_key"] = settings.MOSS_API_KEY is not None context["has_moss_api_key"] = settings.MOSS_API_KEY is not None
context["can_use_resolver"] = self.object.format_name == "ioi16" context["can_use_resolver"] = self.object.format.has_hidden_subtasks
context["logo_override_image"] = self.object.logo_override_image context["logo_override_image"] = self.object.logo_override_image
if ( if (
not context["logo_override_image"] not context["logo_override_image"]
@ -989,7 +989,7 @@ def contest_ranking_ajax(request, contest, participation=None):
raise Http404() raise Http404()
if show_final: if show_final:
if not request.user.is_superuser or contest.format_name != "ioi16": if not request.user.is_superuser or not contest.format.has_hidden_subtasks:
raise Http404() raise Http404()
queryset = contest.users.filter(virtual__gte=0) queryset = contest.users.filter(virtual__gte=0)

View file

@ -18,7 +18,7 @@ class Resolver(TemplateView):
for order, problem_id in problems: for order, problem_id in problems:
id_to_order[str(problem_id)] = order id_to_order[str(problem_id)] = order
frozen_subtasks = self.contest.format.get_frozen_subtasks() hidden_subtasks = self.contest.format.get_hidden_subtasks()
num_problems = len(problems) num_problems = len(problems)
problem_sub = [0] * num_problems problem_sub = [0] * num_problems
sub_frozen = [0] * num_problems sub_frozen = [0] * num_problems
@ -122,10 +122,10 @@ class Resolver(TemplateView):
self.contest.points_precision, self.contest.points_precision,
) )
for i in frozen_subtasks: for i in hidden_subtasks:
order = id_to_order[i] order = id_to_order[i]
if frozen_subtasks[i]: if hidden_subtasks[i]:
sub_frozen[order - 1] = min(frozen_subtasks[i]) sub_frozen[order - 1] = min(hidden_subtasks[i])
else: else:
sub_frozen[order - 1] = problem_sub[order - 1] + 1 sub_frozen[order - 1] = problem_sub[order - 1] + 1
return { return {
@ -143,6 +143,6 @@ class Resolver(TemplateView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
if request.user.is_superuser: if request.user.is_superuser:
self.contest = Contest.objects.get(key=kwargs.get("contest")) self.contest = Contest.objects.get(key=kwargs.get("contest"))
if self.contest.format_name == "ioi16": if self.contest.format.has_hidden_subtasks:
return super(Resolver, self).get(request, *args, **kwargs) return super(Resolver, self).get(request, *args, **kwargs)
return HttpResponseForbidden() return HttpResponseForbidden()

View file

@ -226,16 +226,18 @@ class SubmissionStatus(SubmissionDetailBase):
return True return True
return False return False
def get_frozen_subtasks(self): def get_hidden_subtasks(self):
if self.request.user.is_superuser: if self.request.user.is_superuser:
return set() return set()
submission = self.object submission = self.object
contest = submission.contest_object contest = submission.contest_object
if contest and contest.format_name == "ioi16": if contest and contest.format.has_hidden_subtasks:
contest_problem = contest.contest_problems.get(problem=submission.problem) try:
return contest.format.get_frozen_subtasks().get( return contest.format.get_hidden_subtasks().get(
str(contest_problem.id), set() str(submission.contest.problem.id), set()
) )
except Exception:
pass
return set() return set()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -250,7 +252,7 @@ class SubmissionStatus(SubmissionDetailBase):
context["highlighted_source"] = highlight_code( context["highlighted_source"] = highlight_code(
submission.source.source, submission.language.pygments, linenos=False submission.source.source, submission.language.pygments, linenos=False
) )
context["frozen_subtasks"] = self.get_frozen_subtasks() context["hidden_subtasks"] = self.get_hidden_subtasks()
contest = submission.contest_or_none contest = submission.contest_or_none
prefix_length = 0 prefix_length = 0
@ -437,6 +439,13 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
hidden_codes += ["IE"] hidden_codes += ["IE"]
return [(key, value) for key, value in all_statuses if key not in hidden_codes] return [(key, value) for key, value in all_statuses if key not in hidden_codes]
def should_show_result_data(self):
return not (
self.in_contest
and self.contest.format.has_hidden_subtasks
and not self.request.user.is_superuser
)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(SubmissionsListBase, self).get_context_data(**kwargs) context = super(SubmissionsListBase, self).get_context_data(**kwargs)
authenticated = self.request.user.is_authenticated authenticated = self.request.user.is_authenticated
@ -458,10 +467,13 @@ class SubmissionsListBase(DiggPaginatorMixin, TitleMixin, ListView):
context["all_statuses"] = self.get_searchable_status_codes() context["all_statuses"] = self.get_searchable_status_codes()
context["selected_statuses"] = self.selected_statuses context["selected_statuses"] = self.selected_statuses
context["results_json"] = mark_safe(json.dumps(self.get_result_data())) if self.should_show_result_data():
context["results_colors_json"] = mark_safe( context["results_json"] = mark_safe(json.dumps(self.get_result_data()))
json.dumps(settings.DMOJ_STATS_SUBMISSION_RESULT_COLORS) context["results_colors_json"] = mark_safe(
) json.dumps(settings.DMOJ_STATS_SUBMISSION_RESULT_COLORS)
)
else:
context["results_json"] = None
context["page_suffix"] = suffix = ( context["page_suffix"] = suffix = (
("?" + self.request.GET.urlencode()) if self.request.GET else "" ("?" + self.request.GET.urlencode()) if self.request.GET else ""
@ -856,13 +868,13 @@ class UserContestSubmissionsAjax(UserContestSubmissions):
return None return None
def get_best_subtask_points(self): def get_best_subtask_points(self):
if self.contest.format_name == "ioi16": if self.contest.format.has_hidden_subtasks:
contest_problem = self.contest.contest_problems.get(problem=self.problem) contest_problem = self.contest.contest_problems.get(problem=self.problem)
best_subtasks = {} best_subtasks = {}
total_points = 0 total_points = 0
problem_points = 0 problem_points = 0
achieved_points = 0 achieved_points = 0
frozen_subtasks = self.contest.format.get_frozen_subtasks() hidden_subtasks = self.contest.format.get_hidden_subtasks()
for ( for (
problem_id, problem_id,
@ -882,7 +894,7 @@ class UserContestSubmissionsAjax(UserContestSubmissions):
problem_points = pp problem_points = pp
submission = Submission.objects.get(id=sub_id) submission = Submission.objects.get(id=sub_id)
if ( if (
subtask in frozen_subtasks.get(str(problem_id), set()) subtask in hidden_subtasks.get(str(problem_id), set())
and not self.request.user.is_superuser and not self.request.user.is_superuser
): ):
best_subtasks[subtask] = { best_subtasks[subtask] = {
@ -930,7 +942,7 @@ class UserContestSubmissionsAjax(UserContestSubmissions):
filtered_submissions = [] filtered_submissions = []
# Only show this for some users when using ioi16 # Only show this for some users when using ioi16
if self.contest.format_name != "ioi16" or self.request.user.is_superuser: if self.contest.format.has_hidden_subtasks or self.request.user.is_superuser:
for s in context["submissions"]: for s in context["submissions"]:
if not hasattr(s, "contest"): if not hasattr(s, "contest"):
continue continue

View file

@ -842,7 +842,7 @@ select {
} }
.background-d6e8f7 { .background-d6e8f7 {
background-color: d6e8f7; background-color: #d6e8f7;
} }
.background-bisque { .background-bisque {

View file

@ -1786,6 +1786,9 @@ noscript #noscript {
.blue { .blue {
color: rgb(51, 125, 255); color: rgb(51, 125, 255);
} }
.background-d6e8f7 {
background-color: rgb(38, 41, 43);
}
.background-bisque { .background-bisque {
background-color: rgb(86, 47, 0); background-color: rgb(86, 47, 0);
} }

View file

@ -3,7 +3,7 @@
{% include "problem/left-sidebar.html" %} {% include "problem/left-sidebar.html" %}
{% endblock %} {% endblock %}
{% set in_ioi16 = request.in_contest_mode and request.participation.contest.format_name == "ioi16" %} {% set has_hidden_subtasks = request.in_contest_mode and request.participation.contest.format.has_hidden_subtasks %}
{% block middle_content %} {% block middle_content %}
<div id="content-left" class="problems"> <div id="content-left" class="problems">
@ -11,7 +11,7 @@
<thead> <thead>
<tr> <tr>
{% if request.in_contest_mode %} {% if request.in_contest_mode %}
{% if request.user.is_authenticated and not in_ioi16 %} {% if request.user.is_authenticated and not has_hidden_subtasks %}
<th class="solved"><i class="fa fa-check"></i></th> <th class="solved"><i class="fa fa-check"></i></th>
{% endif %} {% endif %}
<th class="problem">{{ _('Problem') }}</th> <th class="problem">{{ _('Problem') }}</th>
@ -20,7 +20,7 @@
<th>{{ _('Types') }}</th> <th>{{ _('Types') }}</th>
{% endif %} {% endif %}
<th class="points">{{ _('Points') }}</th> <th class="points">{{ _('Points') }}</th>
{% if not in_ioi16 %} {% if not has_hidden_subtasks %}
<th class="users">{{ _('Users') }}</th> <th class="users">{{ _('Users') }}</th>
{% endif %} {% endif %}
{% else %} {% else %}
@ -64,7 +64,7 @@
<tbody> <tbody>
{% for problem in object_list %} {% for problem in object_list %}
<tr> <tr>
{% if request.user.is_authenticated and not in_ioi16 %} {% if request.user.is_authenticated and not has_hidden_subtasks %}
{% if problem.id in completed_problem_ids %} {% if problem.id in completed_problem_ids %}
<td solved="1"> <td solved="1">
<a href="{{ url('user_submissions', problem.code, request.user.username) }}"> <a href="{{ url('user_submissions', problem.code, request.user.username) }}">
@ -115,7 +115,7 @@
{% if not request.in_contest_mode %} {% if not request.in_contest_mode %}
<td class="ac-rate">{{ problem.ac_rate|floatformat(0) }}%</td> <td class="ac-rate">{{ problem.ac_rate|floatformat(0) }}%</td>
{% endif %} {% endif %}
{% if not in_ioi16 %} {% if not has_hidden_subtasks %}
<td class="users"> <td class="users">
<a href="{{ url('ranked_submissions', problem.code) }}"> <a href="{{ url('ranked_submissions', problem.code) }}">
{% if not request.in_contest_mode or not hide_contest_scoreboard %} {% if not request.in_contest_mode or not hide_contest_scoreboard %}

View file

@ -23,7 +23,9 @@
window.show_problem = 0; window.show_problem = 0;
{% endif %} {% endif %}
{% endif %} {% endif %}
window.results_json = {{ results_json }}; {% if results_json %}
window.results_json = {{ results_json }};
{% endif %}
</script> </script>
{% compress js %} {% compress js %}
@ -85,49 +87,51 @@
}); });
// Draw the statistics graph. // Draw the statistics graph.
var chart = null; {% if results_json %}
function stats_graph(raw_data) { var chart = null;
var colors = {{ results_colors_json }}; function stats_graph(raw_data) {
var colors = {{ results_colors_json }};
var ctx = $('#status-graph').find('canvas')[0].getContext('2d'); var ctx = $('#status-graph').find('canvas')[0].getContext('2d');
var font = $('body').css('font-family'); var font = $('body').css('font-family');
if (chart !== null) { if (chart !== null) {
chart.destroy(); chart.destroy();
}
chart = new Chart(ctx, {
type: 'pie',
data: {
datasets: [{
data: raw_data.categories.map(function(entry) {
return entry.count;
}),
backgroundColor: raw_data.categories.map(function(entry) {
return colors[entry.code];
}),
}],
labels: raw_data.categories.map(function(entry) {
return entry.name;
}),
},
options: {
animation: false,
scaleFontFamily: font,
tooltips: {
titleFontFamily: font,
bodyFontFamily: font,
},
legend: {
display: false,
},
},
});
$('#total-submission-count').text(raw_data.total);
} }
chart = new Chart(ctx, {
type: 'pie', $(function () {
data: { stats_graph(window.results_json);
datasets: [{
data: raw_data.categories.map(function(entry) {
return entry.count;
}),
backgroundColor: raw_data.categories.map(function(entry) {
return colors[entry.code];
}),
}],
labels: raw_data.categories.map(function(entry) {
return entry.name;
}),
},
options: {
animation: false,
scaleFontFamily: font,
tooltips: {
titleFontFamily: font,
bodyFontFamily: font,
},
legend: {
display: false,
},
},
}); });
{% endif %}
$('#total-submission-count').text(raw_data.total);
}
$(function () {
stats_graph(window.results_json);
});
function load_dynamic_update(last_msg) { function load_dynamic_update(last_msg) {
var _collect = function (e) { var _collect = function (e) {
@ -323,8 +327,7 @@
{% endblock %} {% endblock %}
{% block right_sidebar %} {% block right_sidebar %}
{% set hide_sidebar = request.in_contest_mode and request.participation.contest.format_name == "ioi16" and not request.user.is_superuser %} {% if results_json %}
{% if not hide_sidebar %}
<div class="right-sidebar"> <div class="right-sidebar">
<div class="submission"> <div class="submission">
<div class="sidebox"> <div class="sidebox">

View file

@ -1,5 +1,5 @@
{% set can_view = submission_layout(submission, profile_id, request.user, editable_problem_ids, completed_problem_ids) %} {% set can_view = submission_layout(submission, profile_id, request.user, editable_problem_ids, completed_problem_ids) %}
{% set hidden = submission.contest_object and submission.contest_object.format_name == "ioi16" and not request.user.is_superuser %} {% set hidden = submission.contest_object and submission.contest_object.format.has_hidden_subtasks and not request.user.is_superuser %}
{% if hidden %} {% if hidden %}
<div class="sub-result TLE"> <div class="sub-result TLE">
<div class="score"> <div class="score">

View file

@ -26,7 +26,7 @@
{% endif %} {% endif %}
{% for batch in batches %} {% for batch in batches %}
{% if batch.id not in frozen_subtasks %} {% if batch.id not in hidden_subtasks %}
<div style="margin-top: 0.5em;"> <div style="margin-top: 0.5em;">
{% if batch.id %} {% if batch.id %}
<b>{{ _('Batch ') }}#{{ batch.id }} ({{batch.points|floatformat}} / {{batch.total|floatformat}}): </b> <b>{{ _('Batch ') }}#{{ batch.id }} ({{batch.points|floatformat}} / {{batch.total|floatformat}}): </b>
@ -52,7 +52,7 @@
<br> <br>
<table class="testcases-table"> <table class="testcases-table">
{% if submission.is_graded and submission.result != 'AB' and not frozen_subtasks %} {% if submission.is_graded and submission.result != 'AB' and not hidden_subtasks %}
<thead> <thead>
<tr id="overall-row" class="case-row overall-result-{{submission.result}}"> <tr id="overall-row" class="case-row overall-result-{{submission.result}}">
<td><span class="col-title">{{_('Overall: ')}}</span> <td><span class="col-title">{{_('Overall: ')}}</span>
@ -90,7 +90,7 @@
<tbody> <tbody>
{% for batch in batches %} {% for batch in batches %}
{% if batch.id not in frozen_subtasks %} {% if batch.id not in hidden_subtasks %}
{% if batch.id %} {% if batch.id %}
{% set batch_AC = (batch.points == batch.total) %} {% set batch_AC = (batch.points == batch.total) %}
<tr class="case-row background-{{'d6e8f7' if batch.points == batch.total else 'bisque'}}"> <tr class="case-row background-{{'d6e8f7' if batch.points == batch.total else 'bisque'}}">