Add related problems

This commit is contained in:
cuom1999 2023-01-27 19:15:37 -06:00
parent 03455fca2c
commit ca13ee4e8d
7 changed files with 116 additions and 84 deletions

View file

@ -65,7 +65,7 @@ class CollabFilter:
return res return res
# return a list of pid # return a list of pid
def problems_neighbors(self, problem, problemset, measure=DOT, limit=None): def problem_neighbors(self, problem, problemset, measure=DOT, limit=None):
pid = problem.id pid = problem.id
if pid >= len(self.problem_embeddings): if pid >= len(self.problem_embeddings):
return None return None
@ -74,7 +74,7 @@ class CollabFilter:
) )
res = [] res = []
for p in problemset: for p in problemset:
if p.id < len(scores): if p < len(scores):
res.append((scores[p.id], p)) res.append((scores[p], p))
res.sort(reverse=True, key=lambda x: x[0]) res.sort(reverse=True, key=lambda x: x[0])
return res[:limit] return res[:limit]

View file

@ -1,6 +1,8 @@
from collections import defaultdict from collections import defaultdict
from math import e from math import e
import os, zipfile import os, zipfile
from datetime import datetime
import random
from django.conf import settings from django.conf import settings
from django.core.cache import cache from django.core.cache import cache
@ -10,6 +12,8 @@ from django.utils import timezone
from django.utils.translation import gettext as _, gettext_noop from django.utils.translation import gettext as _, gettext_noop
from judge.models import Problem, Submission from judge.models import Problem, Submission
from judge.ml.collab_filter import CollabFilter
__all__ = [ __all__ = [
"contest_completed_ids", "contest_completed_ids",
@ -229,3 +233,20 @@ def hot_problems(duration, limit):
cache.set(cache_key, qs, 900) cache.set(cache_key, qs, 900)
return qs return qs
def get_related_problems(profile, problem, limit=8):
if not profile:
return None
problemset = Problem.get_visible_problems(profile.user).values_list("id", flat=True)
problemset = problemset.exclude(id__in=user_completed_ids(profile))
problemset = problemset.exclude(id=problem.id)
cf_model = CollabFilter("collab_filter")
results = cf_model.problem_neighbors(
problem, problemset, CollabFilter.DOT, limit
) + cf_model.problem_neighbors(problem, problemset, CollabFilter.COSINE, limit)
results = list(set([i[1] for i in results]))
seed = datetime.now().strftime("%d%m%Y")
random.Random(seed).shuffle(results)
results = results[:limit]
return [Problem.objects.get(id=i) for i in results]

View file

@ -76,6 +76,7 @@ from judge.utils.problems import (
hot_problems, hot_problems,
user_attempted_ids, user_attempted_ids,
user_completed_ids, user_completed_ids,
get_related_problems,
) )
from judge.utils.strings import safe_float_or_none, safe_int_or_none from judge.utils.strings import safe_float_or_none, safe_int_or_none
from judge.utils.tickets import own_ticket_filter from judge.utils.tickets import own_ticket_filter
@ -352,6 +353,10 @@ class ProblemDetail(
else: else:
context["fileio_input"] = None context["fileio_input"] = None
context["fileio_output"] = None context["fileio_output"] = None
if not self.in_contest:
context["related_problems"] = get_related_problems(
self.profile, self.object
)
return context return context

View file

@ -2,7 +2,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: lqdoj2\n" "Project-Id-Version: lqdoj2\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-01-28 06:34+0700\n" "POT-Creation-Date: 2023-01-28 08:12+0700\n"
"PO-Revision-Date: 2021-07-20 03:44\n" "PO-Revision-Date: 2021-07-20 03:44\n"
"Last-Translator: Icyene\n" "Last-Translator: Icyene\n"
"Language-Team: Vietnamese\n" "Language-Team: Vietnamese\n"
@ -2189,7 +2189,7 @@ msgid "judge"
msgstr "máy chấm" msgstr "máy chấm"
#: judge/models/submission.py:20 judge/models/submission.py:47 #: judge/models/submission.py:20 judge/models/submission.py:47
#: judge/utils/problems.py:116 #: judge/utils/problems.py:120
msgid "Accepted" msgid "Accepted"
msgstr "Accepted" msgstr "Accepted"
@ -2218,7 +2218,7 @@ msgid "Runtime Error"
msgstr "Runtime Error" msgstr "Runtime Error"
#: judge/models/submission.py:27 judge/models/submission.py:41 #: judge/models/submission.py:27 judge/models/submission.py:41
#: judge/models/submission.py:55 judge/utils/problems.py:120 #: judge/models/submission.py:55 judge/utils/problems.py:124
msgid "Compile Error" msgid "Compile Error"
msgstr "Compile Error" msgstr "Compile Error"
@ -2509,19 +2509,19 @@ msgstr ""
msgid "How did you corrupt the interactor path?" msgid "How did you corrupt the interactor path?"
msgstr "How did you corrupt the custom checker path?" msgstr "How did you corrupt the custom checker path?"
#: judge/utils/problems.py:117 #: judge/utils/problems.py:121
msgid "Wrong" msgid "Wrong"
msgstr "Sai" msgstr "Sai"
#: judge/utils/problems.py:123 #: judge/utils/problems.py:127
msgid "Timeout" msgid "Timeout"
msgstr "Quá thời gian" msgstr "Quá thời gian"
#: judge/utils/problems.py:126 #: judge/utils/problems.py:130
msgid "Error" msgid "Error"
msgstr "Lỗi" msgstr "Lỗi"
#: judge/utils/problems.py:143 #: judge/utils/problems.py:147
msgid "Can't pass both queryset and keyword filters" msgid "Can't pass both queryset and keyword filters"
msgstr "" msgstr ""
@ -2964,60 +2964,60 @@ msgstr "Chỉnh sửa %s"
msgid "Pending blogs in %s" msgid "Pending blogs in %s"
msgstr "Bài đang đợi duyệt trong %s" msgstr "Bài đang đợi duyệt trong %s"
#: judge/views/problem.py:131 #: judge/views/problem.py:132
msgid "No such problem" msgid "No such problem"
msgstr "Không có bài nào như vậy" msgstr "Không có bài nào như vậy"
#: judge/views/problem.py:132 #: judge/views/problem.py:133
#, python-format #, python-format
msgid "Could not find a problem with the code \"%s\"." msgid "Could not find a problem with the code \"%s\"."
msgstr "Không tìm thấy bài tập với mã bài \"%s\"." msgstr "Không tìm thấy bài tập với mã bài \"%s\"."
#: judge/views/problem.py:199 #: judge/views/problem.py:200
#, python-brace-format #, python-brace-format
msgid "Editorial for {0}" msgid "Editorial for {0}"
msgstr "Hướng dẫn cho {0}" msgstr "Hướng dẫn cho {0}"
#: judge/views/problem.py:203 #: judge/views/problem.py:204
#, python-brace-format #, python-brace-format
msgid "Editorial for <a href=\"{1}\">{0}</a>" msgid "Editorial for <a href=\"{1}\">{0}</a>"
msgstr "Hướng dẫn cho <a href=\"{1}\">{0}</a>" msgstr "Hướng dẫn cho <a href=\"{1}\">{0}</a>"
#: judge/views/problem.py:458 templates/contest/contest.html:97 #: judge/views/problem.py:461 templates/contest/contest.html:97
#: templates/organization/org-left-sidebar.html:4 #: templates/organization/org-left-sidebar.html:4
#: templates/user/user-about.html:28 templates/user/user-bookmarks.html:34 #: templates/user/user-about.html:28 templates/user/user-bookmarks.html:34
#: templates/user/user-tabs.html:5 templates/user/users-table.html:19 #: templates/user/user-tabs.html:5 templates/user/users-table.html:19
msgid "Problems" msgid "Problems"
msgstr "Bài tập" msgstr "Bài tập"
#: judge/views/problem.py:846 #: judge/views/problem.py:835
msgid "Problem feed" msgid "Problem feed"
msgstr "Bài tập" msgstr "Bài tập"
#: judge/views/problem.py:1084 #: judge/views/problem.py:1073
msgid "Banned from submitting" msgid "Banned from submitting"
msgstr "Bị cấm nộp bài" msgstr "Bị cấm nộp bài"
#: judge/views/problem.py:1086 #: judge/views/problem.py:1075
msgid "" msgid ""
"You have been declared persona non grata for this problem. You are " "You have been declared persona non grata for this problem. You are "
"permanently barred from submitting this problem." "permanently barred from submitting this problem."
msgstr "Bạn đã bị cấm nộp bài này." msgstr "Bạn đã bị cấm nộp bài này."
#: judge/views/problem.py:1109 #: judge/views/problem.py:1098
msgid "Too many submissions" msgid "Too many submissions"
msgstr "Quá nhiều lần nộp" msgstr "Quá nhiều lần nộp"
#: judge/views/problem.py:1111 #: judge/views/problem.py:1100
msgid "You have exceeded the submission limit for this problem." msgid "You have exceeded the submission limit for this problem."
msgstr "Bạn đã vượt quá số lần nộp cho bài này." msgstr "Bạn đã vượt quá số lần nộp cho bài này."
#: judge/views/problem.py:1190 judge/views/problem.py:1195 #: judge/views/problem.py:1179 judge/views/problem.py:1184
#, python-format #, python-format
msgid "Submit to %(problem)s" msgid "Submit to %(problem)s"
msgstr "Nộp bài cho %(problem)s" msgstr "Nộp bài cho %(problem)s"
#: judge/views/problem.py:1218 #: judge/views/problem.py:1207
msgid "Clone Problem" msgid "Clone Problem"
msgstr "Nhân bản bài tập" msgstr "Nhân bản bài tập"
@ -3189,7 +3189,7 @@ msgid "Submission of %(problem)s by %(user)s"
msgstr "Bài nộp của %(user)s cho bài %(problem)s" msgstr "Bài nộp của %(user)s cho bài %(problem)s"
#: judge/views/submission.py:321 judge/views/submission.py:322 #: judge/views/submission.py:321 judge/views/submission.py:322
#: templates/problem/problem.html:173 #: templates/problem/problem.html:169
msgid "All submissions" msgid "All submissions"
msgstr "Tất cả bài nộp" msgstr "Tất cả bài nộp"
@ -3683,7 +3683,7 @@ msgid "You have no ticket"
msgstr "Bạn không có báo cáo" msgstr "Bạn không có báo cáo"
#: templates/blog/list.html:79 templates/problem/list.html:150 #: templates/blog/list.html:79 templates/problem/list.html:150
#: templates/problem/problem.html:399 #: templates/problem/problem.html:384
msgid "Clarifications" msgid "Clarifications"
msgstr "Thông báo" msgstr "Thông báo"
@ -3692,7 +3692,7 @@ msgid "Add"
msgstr "Thêm mới" msgstr "Thêm mới"
#: templates/blog/list.html:105 templates/problem/list.html:172 #: templates/blog/list.html:105 templates/problem/list.html:172
#: templates/problem/problem.html:410 #: templates/problem/problem.html:395
msgid "No clarifications have been made at this time." msgid "No clarifications have been made at this time."
msgstr "Không có thông báo nào." msgstr "Không có thông báo nào."
@ -3816,12 +3816,13 @@ msgid "Hide"
msgstr "Ẩn" msgstr "Ẩn"
#: templates/comments/list.html:137 #: templates/comments/list.html:137
#, python-format
msgid "" msgid ""
"This comment is hidden due to too much negative feedback. Click <a href=" "This comment is hidden due to too much negative feedback. Click <a href="
"\"javascript:comment_show_content(%(id)s)\">here</a> to view it." "\"javascript:comment_show_content(%(id)s)\">here</a> to view it."
msgstr "" msgstr ""
"Bình luận bị ẩn vì nhiều phản hồi tiêu cực. Nhấp vào <a href=" "Bình luận bị ẩn vì nhiều phản hồi tiêu cực. Nhấp vào <a href=\"javascript:"
"\"javascript:comment_show_content(%(id)s)\">đây</a> để mở." "comment_show_content(%(id)s)\">đây</a> để mở."
#: templates/comments/list.html:154 #: templates/comments/list.html:154
msgid "There are no comments at the moment." msgid "There are no comments at the moment."
@ -4517,7 +4518,7 @@ msgstr "Xem YAML"
msgid "Autofill testcases" msgid "Autofill testcases"
msgstr "Tự động điền test" msgstr "Tự động điền test"
#: templates/problem/data.html:490 templates/problem/problem.html:281 #: templates/problem/data.html:490 templates/problem/problem.html:277
msgid "Problem type" msgid "Problem type"
msgid_plural "Problem types" msgid_plural "Problem types"
msgstr[0] "Dạng bài" msgstr[0] "Dạng bài"
@ -4739,136 +4740,128 @@ msgstr "Bạn có chắc muốn tính điểm lại %(count)d bài nộp?"
msgid "Rescore all submissions" msgid "Rescore all submissions"
msgstr "Tính điểm lại các bài nộp" msgstr "Tính điểm lại các bài nộp"
#: templates/problem/problem.html:138 #: templates/problem/problem.html:134
msgid "View as PDF" msgid "View as PDF"
msgstr "Xem PDF" msgstr "Xem PDF"
#: templates/problem/problem.html:147 templates/problem/problem.html:157 #: templates/problem/problem.html:143 templates/problem/problem.html:153
#: templates/problem/problem.html:162 #: templates/problem/problem.html:158
msgid "Submit solution" msgid "Submit solution"
msgstr "Nộp bài" msgstr "Nộp bài"
#: templates/problem/problem.html:150 #: templates/problem/problem.html:146
#, python-format #, python-format
msgid "%(counter)s submission left" msgid "%(counter)s submission left"
msgid_plural "%(counter)s submissions left" msgid_plural "%(counter)s submissions left"
msgstr[0] "Còn %(counter)s lần nộp" msgstr[0] "Còn %(counter)s lần nộp"
#: templates/problem/problem.html:158 #: templates/problem/problem.html:154
msgid "0 submissions left" msgid "0 submissions left"
msgstr "Còn 0 lần nộp" msgstr "Còn 0 lần nộp"
#: templates/problem/problem.html:170 #: templates/problem/problem.html:166
msgid "My submissions" msgid "My submissions"
msgstr "Bài nộp của tôi" msgstr "Bài nộp của tôi"
#: templates/problem/problem.html:174 #: templates/problem/problem.html:170
msgid "Best submissions" msgid "Best submissions"
msgstr "Các bài nộp tốt nhất" msgstr "Các bài nộp tốt nhất"
#: templates/problem/problem.html:178 #: templates/problem/problem.html:174
msgid "Read editorial" msgid "Read editorial"
msgstr "Xem hướng dẫn" msgstr "Xem hướng dẫn"
#: templates/problem/problem.html:183 #: templates/problem/problem.html:179
msgid "Manage tickets" msgid "Manage tickets"
msgstr "Xử lý báo cáo" msgstr "Xử lý báo cáo"
#: templates/problem/problem.html:187 #: templates/problem/problem.html:183
msgid "Edit problem" msgid "Edit problem"
msgstr "Chỉnh sửa bài" msgstr "Chỉnh sửa bài"
#: templates/problem/problem.html:189 #: templates/problem/problem.html:185
msgid "Edit test data" msgid "Edit test data"
msgstr "Chỉnh sửa test" msgstr "Chỉnh sửa test"
#: templates/problem/problem.html:194 #: templates/problem/problem.html:190
msgid "My tickets" msgid "My tickets"
msgstr "Báo cáo của tôi" msgstr "Báo cáo của tôi"
#: templates/problem/problem.html:202 #: templates/problem/problem.html:198
msgid "Manage submissions" msgid "Manage submissions"
msgstr "Quản lý bài nộp" msgstr "Quản lý bài nộp"
#: templates/problem/problem.html:208 #: templates/problem/problem.html:204
msgid "Clone problem" msgid "Clone problem"
msgstr "Nhân bản bài" msgstr "Nhân bản bài"
#: templates/problem/problem.html:215 #: templates/problem/problem.html:211
msgid "Points:" msgid "Points:"
msgstr "Điểm:" msgstr "Điểm:"
#: templates/problem/problem.html:218 templates/problem/problem.html:220 #: templates/problem/problem.html:214 templates/problem/problem.html:216
msgid "(partial)" msgid "(partial)"
msgstr "(thành phần)" msgstr "(thành phần)"
#: templates/problem/problem.html:225 #: templates/problem/problem.html:221
msgid "Time limit:" msgid "Time limit:"
msgstr "Thời gian:" msgstr "Thời gian:"
#: templates/problem/problem.html:237 #: templates/problem/problem.html:233
msgid "Memory limit:" msgid "Memory limit:"
msgstr "Bộ nhớ:" msgstr "Bộ nhớ:"
#: templates/problem/problem.html:249 templates/problem/raw.html:67 #: templates/problem/problem.html:245 templates/problem/raw.html:67
#: templates/submission/status-testcases.html:160 #: templates/submission/status-testcases.html:160
msgid "Input:" msgid "Input:"
msgstr "Input:" msgstr "Input:"
#: templates/problem/problem.html:251 templates/problem/raw.html:67 #: templates/problem/problem.html:247 templates/problem/raw.html:67
msgid "stdin" msgid "stdin"
msgstr "bàn phím" msgstr "bàn phím"
#: templates/problem/problem.html:255 templates/problem/raw.html:70 #: templates/problem/problem.html:251 templates/problem/raw.html:70
#: templates/submission/status-testcases.html:164 #: templates/submission/status-testcases.html:164
msgid "Output:" msgid "Output:"
msgstr "Output:" msgstr "Output:"
#: templates/problem/problem.html:256 templates/problem/raw.html:70 #: templates/problem/problem.html:252 templates/problem/raw.html:70
msgid "stdout" msgid "stdout"
msgstr "màn hình" msgstr "màn hình"
#: templates/problem/problem.html:266 #: templates/problem/problem.html:262
msgid "Author:" msgid "Author:"
msgid_plural "Authors:" msgid_plural "Authors:"
msgstr[0] "Tác giả:" msgstr[0] "Tác giả:"
#: templates/problem/problem.html:294 #: templates/problem/problem.html:290
msgid "Allowed languages" msgid "Allowed languages"
msgstr "Ngôn ngữ cho phép" msgstr "Ngôn ngữ cho phép"
#: templates/problem/problem.html:302 #: templates/problem/problem.html:298
#, python-format #, python-format
msgid "No %(lang)s judge online" msgid "No %(lang)s judge online"
msgstr "Không có máy chấm cho %(lang)s" msgstr "Không có máy chấm cho %(lang)s"
#: templates/problem/problem.html:314 #: templates/problem/problem.html:310
#: templates/status/judge-status-table.html:2 #: templates/status/judge-status-table.html:2
msgid "Judge" msgid "Judge"
msgid_plural "Judges" msgid_plural "Judges"
msgstr[0] "Máy chấm" msgstr[0] "Máy chấm"
#: templates/problem/problem.html:332 #: templates/problem/problem.html:328
msgid "none available" msgid "none available"
msgstr "Bài này chưa có máy chấm" msgstr "Bài này chưa có máy chấm"
#: templates/problem/problem.html:344 #: templates/problem/problem.html:340
#, python-format #, python-format
msgid "This problem has %(length)s clarification(s)" msgid "This problem has %(length)s clarification(s)"
msgstr "Bài này có %(length)s thông báo" msgstr "Bài này có %(length)s thông báo"
#: templates/problem/problem.html:374 #: templates/problem/problem.html:370
msgid "Request clarification" msgid "Request clarification"
msgstr "Yêu cầu làm rõ đề" msgstr "Yêu cầu làm rõ đề"
#: templates/problem/problem.html:387
msgid "View comments"
msgstr "Xem bình luận"
#: templates/problem/problem.html:389
msgid "Be the first to comment"
msgstr "Bình luận đầu tiên"
#: templates/problem/raw.html:73 #: templates/problem/raw.html:73
msgid "Time Limit:" msgid "Time Limit:"
msgstr "Giới hạn thời gian:" msgstr "Giới hạn thời gian:"
@ -4881,6 +4874,10 @@ msgstr "Giới hạn bộ nhớ:"
msgid "Last unsolved" msgid "Last unsolved"
msgstr "Nộp gần đây" msgstr "Nộp gần đây"
#: templates/problem/related_problems.html:3
msgid "Recommended problems"
msgstr "Bài tập gợi ý"
#: templates/problem/search-form.html:2 #: templates/problem/search-form.html:2
msgid "Problem search" msgid "Problem search"
msgstr "Tìm kiếm bài tập" msgstr "Tìm kiếm bài tập"
@ -5767,6 +5764,12 @@ msgstr "Thông tin"
msgid "Check all" msgid "Check all"
msgstr "Chọn tất cả" msgstr "Chọn tất cả"
#~ msgid "View comments"
#~ msgstr "Xem bình luận"
#~ msgid "Be the first to comment"
#~ msgstr "Bình luận đầu tiên"
#, fuzzy #, fuzzy
#~| msgid "Default" #~| msgid "Default"
#~ msgid "default" #~ msgid "default"

View file

@ -114,9 +114,7 @@
}); });
$('.actionbar-comment').on('click', function() { $('.actionbar-comment').on('click', function() {
if ($('#comment-announcement').length) { $('#comment-section').show();
$('#comment-announcement').click();
}
$('#write-comment').click(); $('#write-comment').click();
}) })
}); });

View file

@ -73,13 +73,9 @@
$('#clarification_header_container').hide(); $('#clarification_header_container').hide();
window.scrollTo(0, document.body.scrollHeight); window.scrollTo(0, document.body.scrollHeight);
}) })
$('#comment-announcement').on('click', function() {
$('#comment-section').show();
$('#comment-announcement').hide();
})
if (window.location.href.includes('#comment')) { if (window.location.href.includes('#comment')) {
$('#comment-announcement').click(); $('#comment-section').show();
} }
{% if not available_judges %} {% if not available_judges %}
@ -380,17 +376,6 @@
<br> <br>
{%- endif -%} {%- endif -%}
{% endif %} {% endif %}
{% if not (contest_problem and contest_problem.contest.use_clarifications) %}
<div id="comment-announcement-container">
<div id="comment-announcement">
{% if has_comments %}
{{_('View comments')}} ({{comment_list.count()}})
{% else %}
{{_('Be the first to comment')}}
{% endif %}
</div>
</div>
{% endif %}
{% endblock %} {% endblock %}
{% block comments %} {% block comments %}
@ -415,6 +400,7 @@
{% include "comments/list.html" %} {% include "comments/list.html" %}
</div> </div>
{% endif %} {% endif %}
{% include "problem/related_problems.html" %}
<iframe name="raw_problem" id="raw_problem"></iframe> <iframe name="raw_problem" id="raw_problem"></iframe>
{% endblock %} {% endblock %}

View file

@ -0,0 +1,19 @@
{% if related_problems %}
<div class="content-description">
<h4>{{_('Recommended problems')}}:</h4>
<ul style="list-style-type: none; margin: 0.3em;">
{% for problem in related_problems %}
<li>
{% if problem.id in completed_problem_ids %}
<i class="solved-problem-color fa fa-check-circle"></i>
{% elif problem.id in attempted_problems %}
<i class="attempted-problem-color fa fa-minus-circle"></i>
{% else %}
<i class="unsolved-problem-color fa fa-minus-circle"></i>
{% endif %}
<a href="{{url('problem_detail', problem.code)}}">{{ problem.name }}</a>
</li>
{% endfor %}
</ul>
</div>
{% endif %}