Пример #1
0
 def get_context_data(self, **kwargs):
     data = super().get_context_data(**kwargs)
     skill_list = Skill.objects.order_by("-priority").all()
     children_list = defaultdict(list)
     problem_list = defaultdict(list)
     problem_set = set()
     for skill in skill_list:
         children_list[skill.parent_id].append(skill.pk)
         problem_list[skill.pk] = skill.parsed_problem_list
         problem_set = problem_set.union(skill.parsed_problem_list)
     problem_set = {
         problem.pk: problem
         for problem in Problem.objects.only("title").filter(
             pk__in=problem_set)
     }
     skill_list = {skill.pk: skill for skill in skill_list}
     attempt_list = set(get_attempted_problem_list(self.request.user.id))
     accept_list = set(get_accept_problem_list(self.request.user.id))
     for problem in problem_set.values():
         if problem.pk in accept_list:
             problem.personal_label = 1
         elif problem.pk in attempt_list:
             problem.personal_label = -1
     data.update(children_list=children_list,
                 problem_list=problem_list,
                 problem_set=problem_set,
                 skill_list=skill_list)
     return data
Пример #2
0
def attach_personal_solve_info(problems, user_id):
    attempt_list = set(get_attempted_problem_list(user_id))
    accept_list = set(get_accept_problem_list(user_id))
    for problem in problems:
        problem.personal_label = 0
        if problem.id in accept_list:
            problem.personal_label = 1
        elif problem.id in attempt_list:
            problem.personal_label = -1
Пример #3
0
def hard_problems(user_id):
  ac_list = get_accept_problem_list(user_id)
  ac_difficulty = sorted(list(Problem.objects.filter(id__in=ac_list).values_list("reward", flat=True)), reverse=True)
  try:
    ac_difficulty = ac_difficulty[:int(0.2 * len(ac_difficulty))]
    difficulty_level = sum(ac_difficulty) / len(ac_difficulty)
  except:
    difficulty_level = 8
  return random_unsolved_problems_with_difficulty(ac_list, difficulty_level)
Пример #4
0
def med_problems(user_id):
  ac_list = get_accept_problem_list(user_id)
  ac_difficulty = sorted(list(Problem.objects.filter(id__in=ac_list).values_list("reward", flat=True)), reverse=True)
  try:
    difficulty_level = sum(ac_difficulty) / len(ac_difficulty)
  except:
    difficulty_level = 4
  if len(ac_difficulty) < 100:
    difficulty_level *= len(ac_difficulty) / 200 + 0.5
  return random_unsolved_problems_with_difficulty(ac_list, difficulty_level)
Пример #5
0
 def get_context_data(self, **kwargs):
   data = super().get_context_data(**kwargs)
   accept_problems = list(Problem.objects.filter(id__in=get_accept_problem_list(self.request.user.pk),
                                                 visible=True).values_list("id", flat=True))
   if len(accept_problems) < 2:
     raise PermissionDenied
   random.shuffle(accept_problems)
   data["problem1"] = Problem.objects.get(id=accept_problems[0])
   data["problem2"] = Problem.objects.get(id=accept_problems[1])
   return data
Пример #6
0
 def get_recommended_problem_list(self):
     if not self.user.is_authenticated:
         return []
     accepted_problem_ids = set(
         get_accept_problem_list(self.user.id, self.contest.id))
     all_problem_ids = set([
         problem.problem_id for problem in self.contest.contest_problem_list
     ])
     recommended_problems = get_next_k_recommended_problems(
         self.user.id, all_problem_ids - accepted_problem_ids, k=7)
     return self.contest.fetch_problem_entities_from_ids(
         recommended_problems)
Пример #7
0
def select_with_tags(user_id, tags_record, max_count_per_tag=1):
  user_accept_all = set(get_accept_problem_list(user_id))
  ret = set()
  for k, _ in tags_record:
    available_problems = TaggedItem.objects.filter(content_type=ContentType.objects.get_for_model(Problem)) \
      .filter(tag_id=k).values_list("object_id", flat=True)
    accept_problems = set(available_problems) & user_accept_all
    if not accept_problems:
      ref_reward = 0.
    else:
      accept_problems_reward = Problem.objects.filter(id__in=accept_problems) \
                                 .order_by("-reward").values_list("reward", flat=True)[:3]
      ref_reward = sum(accept_problems_reward) / len(accept_problems)
    retrieve_list = list(Problem.objects.filter(reward__gte=ref_reward, reward__lte=ref_reward + 2, visible=True,
                                                id__in=set(available_problems) - user_accept_all).
                         values_list("id", flat=True))
    random.shuffle(retrieve_list)
    ret = ret.union(retrieve_list[:min(len(retrieve_list), max_count_per_tag)])
    if len(ret) >= 5:
      break
  return list(ret)
Пример #8
0
def coming_up_magic_problems(user_id):
  fetch_pool = Problem.objects.filter(visible=True). \
    exclude(pk__in=get_accept_problem_list(user_id)). \
    values_list("id", flat=True)
  recommended_problems = get_next_k_recommended_problems(user_id, fetch_pool, k=5)
  return recommended_problems
Пример #9
0
    def get_queryset(self):
        source = self.request.GET.get('source')
        kw = self.request.GET.get('keyword')
        tg = self.request.GET.get('tag')
        order_c = self.request.GET.get('c', 'id')
        order_a = self.request.GET.get('a', 'descending')
        compare_with = self.request.GET.get('compare', '')

        if order_c not in ['id', 'name', 'rw', 'sol', 'she'
                           ] or order_a not in ['ascending', 'descending']:
            raise PermissionDenied("Invalid order")
        if tg:
            tag = get_object_or_404(Tag, name=tg)
            queryset = TaggedItem.objects.get_by_model(Problem, tag)
            if hasattr(tag, 'taginfo'):
                self.tag_info = {
                    "name": tag.name,
                    "description": tag.taginfo.description
                }
        else:
            queryset = Problem.objects.all()
        if self.request.user.is_authenticated and compare_with and compare_with.isdigit(
        ):
            self.compare_user = get_object_or_404(User, pk=compare_with)
            self.her_attempt = set(get_attempted_problem_list(compare_with))
            self.her_solved = set(get_accept_problem_list(compare_with))
            self.my_attempt = set(
                get_attempted_problem_list(self.request.user.id))
            self.my_solved = set(get_accept_problem_list(self.request.user.id))
            queryset = queryset.filter(pk__in=self.her_attempt
                                       | self.her_solved | self.my_attempt
                                       | self.my_solved)
            self.comparing = True
            self.paginate_by = 200
        else:
            self.comparing = False
        if source:
            queryset = queryset.filter(source=source)
        if not is_admin_or_root(self.request.user):
            queryset = queryset.filter(visible=True)

        if kw:
            q = Q(title__icontains=kw) | Q(source__icontains=kw)
            if kw.isdigit():
                q |= Q(pk__exact=kw)
            queryset = queryset.filter(q)
            if not self.request.user.is_authenticated or self.request.user.show_tags:
                tag = Tag.objects.filter(name=kw)
                if tag.exists():
                    queryset |= TaggedItem.objects.get_by_model(
                        Problem, tag.first())

        ret = queryset.defer("description", "input", "output",
                             "hint").distinct()
        if order_c == 'id':
            if order_a == 'ascending': ret = ret.order_by('id')
            else: ret = ret.order_by('-id')
        elif order_c == 'name':
            if order_a == 'ascending': ret = ret.order_by('title')
            else: ret = ret.order_by('-title')
        elif order_c == 'upd':
            if order_a == 'ascending': ret = ret.order_by('update_time')
            else: ret = ret.order_by('-update_time')
        elif order_c == 'rw':
            if order_a == 'descending': ret = ret.order_by("-reward")
            else: ret = ret.order_by("reward")
        elif order_c == 'sol':
            if order_a == 'descending': ret = ret.order_by("-ac_user_count")
            else: ret = ret.order_by("ac_user_count")
        elif order_c == 'she' and self.comparing:
            if order_a == 'ascending': reverse = False
            else: reverse = True
            ref = {problem_id: 1 for problem_id in self.her_attempt}
            ref.update({problem_id: -1 for problem_id in self.her_solved})
            ref2 = {problem_id: -1 for problem_id in self.my_attempt}
            ref2.update({problem_id: 1 for problem_id in self.my_solved})
            ret = sorted(ret,
                         key=lambda x: (ref2.get(x.id, 0), ref.get(x.id, 0)),
                         reverse=reverse)
        return ret
Пример #10
0
    def get_context_data(self, **kwargs):
        data = super(ProblemList, self).get_context_data(**kwargs)
        data['keyword'] = self.request.GET.get('keyword')
        current_problem_set = [problem.pk for problem in data['problem_list']]
        for problem in data['problem_list']:
            problem.personal_label = 0
        data['show_tags'] = True
        if self.request.user.is_authenticated:
            # Get AC / Wrong
            if self.comparing:
                attempt_list = self.my_attempt
                accept_list = self.my_solved
                for problem in data['problem_list']:
                    if problem.id in self.her_solved:
                        problem.her_label = 1
                    elif problem.id in self.her_attempt:
                        problem.her_label = -1
                    else:
                        problem.her_label = 0
                data['comparing'] = True
                data['compare_user'] = self.compare_user
            else:
                attempt_list = set(
                    get_attempted_problem_list(self.request.user.id))
                accept_list = set(get_accept_problem_list(
                    self.request.user.id))
            for problem in data['problem_list']:
                if problem.id in accept_list:
                    problem.personal_label = 1
                elif problem.id in attempt_list:
                    problem.personal_label = -1

            # get recent unsolved problems
            unsolved_problem_set = set(
                get_attempted_problem_list(self.request.user.id)) - set(
                    get_accept_problem_list(self.request.user.id))
            data['unsolved_submissions'] = unsolved_submissions = []
            for s in self.request.user.submission_set.select_related("problem"). \
                    exclude(status=SubmissionStatus.ACCEPTED).filter(
                problem_id__in=unsolved_problem_set, problem__visible=True). \
                    defer("code", "status_message", "status_detail"):
                if s.problem_id not in unsolved_problem_set:
                    continue
                if s.contest_id:
                    s.contest.add_contest_problem_to_submissions([s])
                unsolved_submissions.append(s)
                unsolved_problem_set.remove(s.problem_id)
                if len(unsolved_submissions) >= 5:
                    break

            if not self.request.user.show_tags:
                data['show_tags'] = False

        # Get Accepted of all users
        problem_ids = list(map(lambda x: x.id, data['problem_list']))

        # Get tags
        tagged_items = list(
            TaggedItem.objects.filter(
                content_type=ContentType.objects.get_for_model(Problem)).
            filter(object_id__in=current_problem_set).select_related("tag"))
        for problem in data['problem_list']:
            items = list(
                filter(lambda x: x.object_id == problem.pk, tagged_items))
            if items:
                problem.my_tags = map(lambda x: x.tag.name, items)
        if hasattr(self, "tag_info"):
            data["tag_info"] = self.tag_info

        data['tags'] = Tag.objects.usage_for_model(Problem, counts=True)

        return data
Пример #11
0
    def get_context_data(self, **kwargs):
        data = super(DashboardView, self).get_context_data(**kwargs)

        if self.registered:
            data['registered'] = True
        if self.user.is_authenticated and self.contest.access_level == 30 and self.contest.status == -1:
            if self.contest.contestparticipant_set.filter(
                    user=self.user).exists():
                data['public_register'] = 1
            else:
                data['public_register'] = -1

        # tags
        data['tagged_contest_problem_list'] = data['contest_problem_list']
        if self.contest.contest_type == 1:
            tagged_items = list(
                TaggedItem.objects.filter(
                    content_type=ContentType.objects.get_for_model(Problem)).
                filter(object_id__in=list(
                    map(lambda x: x.problem_id,
                        data['contest_problem_list']))).select_related("tag"))
            tag_filter = self.request.GET.get("tag")
            if tag_filter:
                data['tagged_contest_problem_list'] = []
            for contest_problem in data['contest_problem_list']:
                items = list(
                    filter(lambda x: x.object_id == contest_problem.problem_id,
                           tagged_items))
                if items:
                    contest_problem.tags = list(
                        map(lambda x: x.tag.name, items))
                if tag_filter and hasattr(
                        contest_problem,
                        "tags") and tag_filter in contest_problem.tags:
                    data['tagged_contest_problem_list'].append(contest_problem)

        data['has_permission'] = super(DashboardView, self).test_func()
        for problem in data['contest_problem_list']:
            problem.personal_label = 0
        if data['has_permission'] and self.user.is_authenticated:
            # problem red and green status
            attempt_list = set(
                get_attempted_problem_list(self.request.user.id,
                                           self.contest.id))
            accept_list = set(
                get_accept_problem_list(self.request.user.id, self.contest.id))
            for problem in data['contest_problem_list']:
                if problem.problem_id in accept_list:
                    problem.personal_label = 1
                elif problem.problem_id in attempt_list:
                    problem.personal_label = -1
                else:
                    problem.personal_label = 0
            if self.contest.contest_type == 1:
                all_accept_list = set(
                    get_accept_problem_list(self.request.user.id))
                for problem in data['contest_problem_list']:
                    if problem.problem_id in all_accept_list and problem.personal_label <= 0:
                        problem.personal_label = 2

            # show display rank
            if self.contest.contest_type == 0:
                if self.participant is not None:
                    self_displayed_rank_template = 'display_rank_cp_%d' % self.participant.pk
                    data["rank"] = cache.get(self_displayed_rank_template)
                    if data["rank"] is None:
                        if self.virtual_progress is not None:
                            data["rank"] = get_participant_score(
                                self.contest, self.user.pk,
                                self.virtual_progress)
                        else:
                            data["rank"] = get_participant_score(
                                self.contest, self.user.pk)
                        if self.contest.common_status_access_level < 0:
                            data["rank"].pop("actual_rank", None)
                        cache.set(self_displayed_rank_template, data["rank"],
                                  15)
                    if data["rank"] is not None:
                        data["rank"].update(user=self.participant)

        # make sure problem status is correct (for VP purpose)
        if self.virtual_progress is not None:
            calculate_problems(self.contest, self.contest.contest_problem_list,
                               self.virtual_progress)
        # `contest.contest_problem_list` is data["contest_problem_list"]. Same thing.
        if self.contest.scoring_method == "oi":
            data['enable_scoring'] = True
            for problem in data['contest_problem_list']:
                problem.max_score = int(
                    round(problem.max_score / 100 * problem.weight))
                problem.avg_score = round(
                    problem.avg_score / 100 * problem.weight, 1)

        data['authors'] = self.contest.authors.all()

        # color settings
        data['level_colors'] = ["", "green", "teal", "blue", "orange", "red"]

        return data
Пример #12
0
    def get_context_data(self, **kwargs):
        data = super(DashboardView, self).get_context_data(**kwargs)

        if self.registered:
            data['registered'] = True
        if self.user.is_authenticated and self.contest.access_level == 30 and self.contest.status == -1:
            if self.contest.contestparticipant_set.filter(user=self.user).exists():
                data['public_register'] = 1
            else:
                data['public_register'] = -1

        # tags
        data['tagged_contest_problem_list'] = data['contest_problem_list']
        if self.contest.always_running:
            tagged_items = list(TaggedItem.objects.filter(content_type=ContentType.objects.get_for_model(Problem))
                                .filter(object_id__in=list(map(lambda x: x.problem_id, data['contest_problem_list'])))
                                .select_related("tag"))
            tag_filter = self.request.GET.get("tag")
            if tag_filter:
                data['tagged_contest_problem_list'] = []
            for contest_problem in data['contest_problem_list']:
                items = list(filter(lambda x: x.object_id == contest_problem.problem_id, tagged_items))
                if items:
                    contest_problem.tags = list(map(lambda x: x.tag.name, items))
                if tag_filter and hasattr(contest_problem, "tags") and tag_filter in contest_problem.tags:
                    data['tagged_contest_problem_list'].append(contest_problem)

        data['has_permission'] = super(DashboardView, self).test_func()
        for problem in data['contest_problem_list']:
            problem.personal_label = 0
        if data['has_permission'] and self.user.is_authenticated:
            attempt_list = set(get_attempted_problem_list(self.request.user.id, self.contest.id))
            accept_list = set(get_accept_problem_list(self.request.user.id, self.contest.id))
            for problem in data['contest_problem_list']:
                if problem.problem_id in accept_list:
                    problem.personal_label = 1
                elif problem.problem_id in attempt_list:
                    problem.personal_label = -1
                else:
                    problem.personal_label = 0
            if self.contest.always_running:
                all_accept_list = set(get_accept_problem_list(self.request.user.id))
                for problem in data['contest_problem_list']:
                    if problem.problem_id in all_accept_list and problem.personal_label <= 0:
                        problem.personal_label = 2
            if self.privileged:
                clarifications = self.contest.contestclarification_set.all()
            else:
                q = Q(important=True)
                if self.user.is_authenticated:
                    q |= Q(author=self.user)
                clarifications = self.contest.contestclarification_set.filter(q).select_related("author").distinct()
            data["clarifications"] = clarifications
            if not self.contest.always_running:
                try:
                    user_as_participant = self.contest.contestparticipant_set.select_related('user').get(user_id=self.user.pk)
                    self_displayed_rank_template = 'display_rank_cp_%d' % user_as_participant.pk
                    data["rank"] = cache.get(self_displayed_rank_template)
                    if data["rank"] is None:
                        data["rank"] = get_participant_score(self.contest, self.user.pk)
                        if self.contest.common_status_access_level < 0:
                            data["rank"].pop("actual_rank", None)
                        cache.set(self_displayed_rank_template, data["rank"], 15)
                    if data["rank"] is not None:
                        data["rank"].update(user=user_as_participant)
                except ContestParticipant.DoesNotExist:
                    pass

        problem_ids = list(map(lambda x: x.problem_id, data['contest_problem_list']))
        if self.contest.scoring_method != "oi":
            accept_count = get_many_problem_accept_count(problem_ids, self.contest.id)
            for problem in data['contest_problem_list']:
                problem.accept_count = accept_count[problem.problem_id]
        else:
            data['enable_scoring'] = True
            user_count = get_many_problem_tried_count(problem_ids, self.contest.id)
            max_score = get_many_problem_max_score(problem_ids, self.contest.id)
            avg_score = get_many_problem_avg_score(problem_ids, self.contest.id)
            for problem in data['contest_problem_list']:
                problem.user_count = user_count[problem.problem_id]
                problem.max_score = int(round(max_score[problem.problem_id] / 100 * problem.weight))
                problem.avg_score = round(avg_score[problem.problem_id] / 100 * problem.weight, 1)

        data['authors'] = self.contest.authors.all()

        # color settings
        data['level_colors'] = ["", "green", "teal", "blue", "orange", "red"]

        return data