def test_problems_list(self): for name, user in self.users.items(): with self.subTest(user=name): with self.subTest(list='accessible problems'): # We only care about consistency between Problem.is_accessible_by and Problem.get_visible_problems problem_codes = [] for problem in Problem.objects.prefetch_related('authors', 'curators', 'testers', 'organizations'): if problem.is_accessible_by(user): problem_codes.append(problem.code) self.assertCountEqual( Problem.get_visible_problems(user).distinct().values_list('code', flat=True), problem_codes, ) with self.subTest(list='editable problems'): # We only care about consistency between Problem.is_editable_by and Problem.get_editable_problems problem_codes = [] for problem in Problem.objects.prefetch_related('authors', 'curators'): if problem.is_editable_by(user): problem_codes.append(problem.code) self.assertCountEqual( Problem.get_editable_problems(user).distinct().values_list('code', flat=True), problem_codes, )
def save(self, user, problemid=None): cd = self.cleaned_data title = cd['title'] description = cd['description'] input = cd['input'] output = cd['output'] program = cd['program'] sample_input1 = cd['sample_input1'] sample_output1 = cd['sample_output1'] sample_input2 = cd['sample_input2'] sample_output2 = cd['sample_output2'] time_limit = cd['time_limit'] memory_limit = cd['memory_limit'] keypoint = cd['keypoint'].split(',') if problemid: problem = Problem.objects.get(pk=problemid) problem.title = title problem.description = description problem.time_limit = time_limit problem.memory_limit = memory_limit problem.input = input problem.output = output problem.sample_input = sample_input1 problem.sample_output = sample_output1 problem.sample_input2 = sample_input2 problem.sample_output2 = sample_output2 #problem.creater = user problem.knowledgePoint1.clear() problem.knowledgePoint1.clear() problem.program = program else: problem = Problem( title=title, description=description, time_limit=time_limit, memory_limit=memory_limit, input=input, output=output, sample_input=sample_input1, sample_output=sample_output1, sample_input2=sample_input2, sample_output2=sample_output2, creater=user, problem_type="编程", program=program ) problem.save() for point in keypoint: problem.knowledgePoint2.add(KnowledgePoint2.objects.get(pk=point)) for point in problem.knowledgePoint2.all(): problem.knowledgePoint1.add(point.upperPoint) for point in problem.knowledgePoint1.all(): problem.classname.add(point.classname) problem.save() return problem
def handle(self, *args, **options): problem = Problem() problem.code = options['code'] problem.name = options['name'] problem.description = options['body'] problem.group = ProblemGroup.objects.get(name=options['group']) problem.types = [ProblemType.objects.get(name=options['type'])] problem.save()
def handle(self, *args, **options): if len(args) != 5: self.usage('create_problem') code, name, body, type, group = args problem = Problem() problem.code = code problem.name = name problem.description = body problem.group = ProblemGroup.objects.get(name=group) problem.types = [ProblemType.objects.get(name=type)] problem.save()
def calculate_points(self, table=_pp_table): from judge.models import Problem public_problems = Problem.get_public_problems() data = (public_problems.filter( submission__user=self, submission__points__isnull=False).annotate(max_points=Max( 'submission__points')).order_by('-max_points').values_list( 'max_points', flat=True).filter(max_points__gt=0)) extradata = (public_problems.filter( submission__user=self, submission__result='AC').values('id').distinct().count()) bonus_function = settings.DMOJ_PP_BONUS_FUNCTION points = sum(data) problems = len(data) pp = sum(x * y for x, y in zip(table, data)) + bonus_function(extradata) if not float_compare_equal(self.points, points) or \ problems != self.problem_count or \ not float_compare_equal(self.performance_points, pp): self.points = points self.problem_count = problems self.performance_points = pp self.save(update_fields=[ 'points', 'problem_count', 'performance_points' ]) for org in self.organizations.get_queryset(): org.calculate_points() return points
def get_unfiltered_queryset(self): queryset = Submission.objects.all() use_straight_join(queryset) join_sql_subquery( queryset, subquery=Problem.get_visible_problems(self.request.user).distinct().only('id').query, params=[], join_fields=[('problem_id', 'id')], alias='visible_problems', ) return ( queryset .select_related('problem', 'user__user', 'language') .order_by('id') .only( 'id', 'problem__code', 'user__user__username', 'date', 'language__key', 'time', 'memory', 'points', 'result', ) )
def calculate_points(self, table=_pp_table): from judge.models import Problem public_problems = Problem.get_public_problems() data = (public_problems.filter( submission__user=self, submission__points__isnull=False).annotate(max_points=Max( 'submission__points')).order_by('-max_points').values_list( 'max_points', flat=True).filter(max_points__gt=0)) extradata = (public_problems.filter( submission__user=self, submission__result='AC').values('id').distinct().count()) bonus_function = settings.DMOJ_PP_BONUS_FUNCTION points = sum(data) problems = len(data) entries = min(len(data), len(table)) pp = sum(map(mul, table[:entries], data[:entries])) + bonus_function(extradata) if self.points != points or problems != self.problem_count or self.performance_points != pp: self.points = points self.problem_count = problems self.performance_points = pp self.save(update_fields=[ 'points', 'problem_count', 'performance_points' ]) return points
def get_unfiltered_queryset(self): return (Problem.get_visible_problems( self.request.user).select_related('group').prefetch_related( Prefetch( 'types', queryset=ProblemType.objects.only('full_name'), to_attr='type_list', ), ).order_by('code').distinct())
def filter_submissions_by_visible_problems(queryset, user): join_sql_subquery( queryset, subquery=str(Problem.get_visible_problems(user).distinct().only('id').query), params=[], join_fields=[('problem_id', 'id')], alias='visible_problems', )
def test_abstract_problem(self): """Abstract methods in a Problem raise exceptions""" collection = Collection() collection.save() problem = Problem(title_md='Dates', text_md='Example with dates', create_sql=' ', insert_sql=' ', collection=collection) self.assertRaises(NotImplementedError, problem.template) self.assertRaises(NotImplementedError, problem.judge, '', None) self.assertRaises(NotImplementedError, problem.problem_type)
def get_queryset(self): queryset = self._get_queryset() if not self.in_contest: join_sql_subquery( queryset, subquery=str(Problem.get_visible_problems(self.request.user).distinct().only('id').query), params=[], join_fields=[('problem_id', 'id')], alias='visible_problems', ) return queryset
def get_context_data(self, **kwargs): context = super(PostList, self).get_context_data(**kwargs) context['title'] = self.title or _('Page %d of Posts') % context['page_obj'].number context['first_page_href'] = reverse('home') context['page_prefix'] = reverse('blog_post_list') context['new_problems'] = Problem.get_public_problems() \ .order_by('-date', '-id')[:settings.DMOJ_BLOG_NEW_PROBLEM_COUNT] context['has_clarifications'] = False if self.request.user.is_authenticated: participation = self.request.profile.current_contest if participation: clarifications = ProblemClarification.objects.filter(problem__in=participation.contest.problems.all()) context['has_clarifications'] = clarifications.count() > 0 context['clarifications'] = clarifications.order_by('-date') context['user_count'] = lazy(Profile.objects.count, int, int) context['problem_count'] = lazy(Problem.get_public_problems().count, int, int) context['submission_count'] = lazy(Submission.objects.count, int, int) context['language_count'] = lazy(Language.objects.count, int, int) now = timezone.now() visible_contests = Contest.get_visible_contests(self.request.user).order_by('start_time') context['current_contests'] = visible_contests.filter(start_time__lte=now, end_time__gt=now) context['future_contests'] = visible_contests.filter(start_time__gt=now) if self.request.user.is_authenticated: context['own_open_tickets'] = Ticket.tickets_list(self.request.user).filter(user=self.request.profile) else: context['own_open_tickets'] = [] # Superusers better be staffs, not the spell-casting kind either. if self.request.user.is_staff: context['open_tickets'] = Ticket.tickets_list(self.request.user)[:10] else: context['open_tickets'] = [] return context
def save(self, user, problemid=None): cd = self.cleaned_data title = cd['title'] description = cd['description'] input = cd['input'] output = cd['output'] program = cd['program'] sample_input1 = cd['sample_input1'] sample_output1 = cd['sample_output1'] sample_input2 = cd['sample_input2'] sample_output2 = cd['sample_output2'] time_limit = cd['time_limit'] memory_limit = cd['memory_limit'] keypoint = cd['keypoint'].split(',') if problemid: problem = Problem.objects.get(pk=problemid) problem.title = title problem.description = description problem.time_limit = time_limit problem.memory_limit = memory_limit problem.input = input problem.output = output problem.sample_input = sample_input1 problem.sample_output = sample_output1 problem.sample_input2 = sample_input2 problem.sample_output2 = sample_output2 #problem.creater = user problem.knowledgePoint1.clear() problem.knowledgePoint2.clear() problem.program = program else: problem = Problem( title=title, description=description, time_limit=time_limit, memory_limit=memory_limit, input=input, output=output, sample_input=sample_input1, sample_output=sample_output1, sample_input2=sample_input2, sample_output2=sample_output2, creater=user, problem_type="编程", program=program ) problem.save() for point in keypoint: problem.knowledgePoint2.add(KnowledgePoint2.objects.get(pk=point)) for point in problem.knowledgePoint2.all(): problem.knowledgePoint1.add(point.upperPoint) for point in problem.knowledgePoint1.all(): problem.classname.add(point.classname) problem.save() return problem
def migrate_problems(db): PROBLEM_MAPPING = { "No": "id", "ID": "slug", "Updated": "updated_on", "State": "state", "Source": "source", "Name": "name", "Description": "description", "Input": "input", "Output": "output", "SampleInput": "sample_input", "SampleOutput": "sample_output", "Note": "note", "JudgeModule": "judge_module", "TimeLimit": "time_limit", "MemoryLimit": "memory_limit", "Accepted": "accepted_count", "Submissions": "submissions_count", } imported = 0 categories = dict([(cat["No"], cat["Name"]) for cat in fetch_all(db, "GDN_ProblemCategory")]) for k, v in categories.items(): print k, v for problem in fetch_all(db, "GDN_Problem", State=3): kwargs = {} kwargs["user"] = User.objects.get(id=problem["Author"]) for k, v in PROBLEM_MAPPING.items(): kwargs[v] = problem[k] new_problem = Problem(**kwargs) new_problem.save() tags = [] for rel in fetch_all(db, "GDN_ProblemCategoryActualRelation", Problem=problem["No"]): if rel["Category"] in categories: tags.append(categories[rel["Category"]]) print new_problem.slug, tags new_problem.tags = ",".join(tags) new_problem.save() # we don't have timestamp information for old problems. patch("new-problem-%d" % new_problem.id, datetime.datetime(2009, 7, 11, 0, 0, 0, 0)) imported += 1 print "imported %d problems." % imported
def get_normal_queryset(self): queryset = Problem.problems_list(self.request.user) if self.profile is not None and self.hide_solved: queryset = queryset.exclude(id__in=Submission.objects.filter(user=self.profile, points=F('problem__points')) .values_list('problem__id', flat=True)) if self.show_types: queryset = queryset.prefetch_related('types') if self.category is not None: queryset = queryset.filter(group__id=self.category) if self.request.user.has_perm('judge.see_private_problem'): filter = None see_restricted = self.request.user.has_perm('judge.see_restricted_problem') if self.problem_visibility == 1: filter = Q(is_public=True) elif self.problem_visibility == 2: filter = Q(is_public=False) if see_restricted: filter &= Q(is_restricted=False) elif self.problem_visibility == 3 and see_restricted: filter = Q(is_restricted=True, is_public=False) elif see_restricted: filter = Q(is_restricted=False) | Q(is_public=True) if filter is not None: queryset = queryset.filter(filter) if self.selected_types: queryset = queryset.filter(types__in=self.selected_types) if 'search' in self.request.GET: self.search_query = query = ' '.join(self.request.GET.getlist('search')).strip() if query: if settings.ENABLE_FTS and self.full_text: queryset = queryset.search(query, queryset.BOOLEAN).extra(order_by=['-relevance']) else: queryset = queryset.filter( Q(code__icontains=query) | Q(name__icontains=query) | Q(translations__name__icontains=query, translations__language=self.request.LANGUAGE_CODE)) self.prepoint_queryset = queryset if self.point_start is not None: queryset = queryset.filter(points__gte=self.point_start) if self.point_end is not None: queryset = queryset.filter(points__lte=self.point_end) return queryset.distinct()
def api_v1_problem_list(request): queryset = Problem.get_visible_problems(request.user) if settings.ENABLE_FTS and 'search' in request.GET: query = ' '.join(request.GET.getlist('search')).strip() if query: queryset = queryset.search(query) queryset = queryset.values_list('code', 'points', 'partial', 'name', 'group__full_name') return JsonResponse({ code: { 'points': points, 'partial': partial, 'name': name, 'group': group, } for code, points, partial, name, group in queryset })
def hot_problems(duration, limit): cache_key = 'hot_problems:%d:%d' % (duration.total_seconds(), limit) qs = cache.get(cache_key) if qs is None: qs = Problem.get_public_problems() \ .filter(submission__date__gt=timezone.now() - duration, points__gt=3, points__lt=25) qs0 = qs.annotate(k=Count('submission__user', distinct=True)).order_by( '-k').values_list('k', flat=True) if not qs0: return [] # make this an aggregate mx = float(qs0[0]) qs = qs.annotate( unique_user_count=Count('submission__user', distinct=True)) # fix braindamage in excluding CE qs = qs.annotate(submission_volume=Count( Case( When(submission__result='AC', then=1), When(submission__result='WA', then=1), When(submission__result='IR', then=1), When(submission__result='RTE', then=1), When(submission__result='TLE', then=1), When(submission__result='OLE', then=1), output_field=FloatField(), ))) qs = qs.annotate(ac_volume=Count( Case( When(submission__result='AC', then=1), output_field=FloatField(), ))) qs = qs.filter(unique_user_count__gt=max(mx / 3.0, 1)) qs = qs.annotate(ordering=ExpressionWrapper( 0.5 * F('points') * (0.4 * F('ac_volume') / F('submission_volume') + 0.6 * F('ac_rate')) + 100 * e**(F('unique_user_count') / mx), output_field=FloatField(), )).order_by('-ordering').defer('description')[:limit] cache.set(cache_key, qs, 900) return qs
def api_v1_problem_list(request): user = get_request_user(request) if not user.is_authenticated: return JsonResponse({}) queryset = Problem.problems_list(user) if settings.ENABLE_FTS and 'search' in request.GET: query = ' '.join(request.GET.getlist('search')).strip() if query: queryset = queryset.search(query) queryset = queryset.values_list('code', 'points', 'partial', 'name', 'group__full_name') return JsonResponse({ code: { 'points': points, 'partial': partial, 'name': name, 'group': group } for code, points, partial, name, group in queryset })
def problem_new(request): if request.method == 'POST': form = ProblemForm(request.POST, request.FILES) if form.is_valid(): problem = Problem() problem.title = form.cleaned_data['title'] testcases = form.files.getlist('testcases') problem.testcase = len(testcases)/2 problem.save() tc = JUDGE_ROOT+'/testcase/{}'.format(problem.pk) if not os.path.exists(tc): os.makedirs(tc) for f in testcases: with open('{}/{}'.format(tc, f.name), 'wb+') as dest: for chunk in f.chunks(): dest.write(chunk) return redirect('judge:problem_list') else: form = ProblemForm() return render(request, 'judge/problem_new.html', {'form': form})
def items(self): return Problem.problems_list(AnonymousUser()).order_by('-date', '-id')[:25]
def handle(self, *args, **options): problem = Problem() problem.code = options['code'] problem.name = options['name'] problem.description = options['body'] problem.save()
def get_queryset(self): return Problem.get_visible_problems(self.request.user) \ .filter(Q(code__icontains=self.term) | Q(name__icontains=self.term)).distinct()
def get_queryset(self, request): return Problem.get_editable_problems( request.user).prefetch_related('authors__user').distinct()
def user_editable_ids(profile): return set( Problem.get_editable_problems(profile.user).values_list('id', flat=True))
def items(self): return Problem.get_public_problems().order_by('-date', '-id')[:25]
def items(self): return Problem.get_public_problems().values_list('code')
def items(self): return Problem.problems_list(AnonymousUser()).values_list('code')
def get_context_data(self, **kwargs): context = super(PostList, self).get_context_data(**kwargs) context['title'] = self.title or _('Page %d of Posts') % context['page_obj'].number context['first_page_href'] = reverse('home') context['page_prefix'] = reverse('blog_post_list') context['comments'] = Comment.most_recent(self.request.user, 10) context['new_problems'] = Problem.get_public_problems() \ .order_by('-date', 'code')[:settings.DMOJ_BLOG_NEW_PROBLEM_COUNT] context['page_titles'] = CacheDict(lambda page: Comment.get_page_title(page)) context['has_clarifications'] = False if self.request.user.is_authenticated: participation = self.request.profile.current_contest if participation: clarifications = ProblemClarification.objects.filter(problem__in=participation.contest.problems.all()) context['has_clarifications'] = clarifications.count() > 0 context['clarifications'] = clarifications.order_by('-date') context['user_count'] = Profile.objects.count context['problem_count'] = Problem.get_public_problems().count context['submission_count'] = lambda: Submission.objects.aggregate(max_id=Max('id'))['max_id'] or 0 context['language_count'] = Language.objects.count context['post_comment_counts'] = { int(page[2:]): count for page, count in Comment.objects .filter(page__in=['b:%d' % post.id for post in context['posts']], hidden=False) .values_list('page').annotate(count=Count('page')).order_by() } now = timezone.now() # Dashboard stuff if self.request.user.is_authenticated: user = self.request.profile context['recently_attempted_problems'] = (Submission.objects.filter(user=user) .exclude(problem__in=user_completed_ids(user)) .values_list('problem__code', 'problem__name', 'problem__points') .annotate(points=Max('points'), latest=Max('date')) .order_by('-latest') [:settings.DMOJ_BLOG_RECENTLY_ATTEMPTED_PROBLEMS_COUNT]) visible_contests = Contest.get_visible_contests(self.request.user).filter(is_visible=True) \ .order_by('start_time') context['current_contests'] = visible_contests.filter(start_time__lte=now, end_time__gt=now) context['future_contests'] = visible_contests.filter(start_time__gt=now) if self.request.user.is_authenticated: context['own_open_tickets'] = ( Ticket.objects.filter(user=self.request.profile, is_open=True).order_by('-id') .prefetch_related('linked_item').select_related('user__user') ) else: context['own_open_tickets'] = [] # Superusers better be staffs, not the spell-casting kind either. if self.request.user.is_staff: tickets = (Ticket.objects.order_by('-id').filter(is_open=True).prefetch_related('linked_item') .select_related('user__user')) context['open_tickets'] = filter_visible_tickets(tickets, self.request.user)[:10] else: context['open_tickets'] = [] context['problem_types'] = ProblemType.objects.all() context['categories'] = ProblemGroup.objects.all() return context
def get_normal_queryset(self): return Problem.get_visible_problems(self.request.user)
def filter_visible_tickets(queryset, user): return queryset.filter( own_ticket_filter(user.profile.id) | Q(content_type=ContentType.objects.get_for_model(GeneralIssue)) | Q(content_type=ContentType.objects.get_for_model(Problem), object_id__in=Problem.get_editable_problems(user))).distinct()
def handle(self, *args, **options): # print(args, options) PATH = options.get('path') print(PATH) languages = Language.objects.all() typee = ProblemType.objects.first() group = ProblemGroup.objects.first() for f in listdir(PATH): problemfile = open(join(PATH, f)) problemjson = json.load(problemfile) print(problemjson['code']) if Problem.objects.filter(code=problemjson['code']).exists(): continue problem = Problem(code=problemjson['code']) print('creating', problem.code) problem.name = problemjson['name'] problem.description = problemjson['description'] problem.points = problemjson['points'] problem.is_public = problemjson[ 'is_public'] if 'is_public' in problemjson else True problem.memory_limit = problemjson[ 'memory_limit'] if 'memory_limit' in problemjson else 65536 problem.time_limit = problemjson[ 'time_limit'] if 'time_limit' in problemjson else 10 problem.group = group problem.save() for l in languages: problem.allowed_languages.add(l) problem.types.add(typee) problem.save()