Exemplo n.º 1
0
def _recursive_group_problems(problems, result_info, categories, div_id):
    if not categories:
        problems.sort(key=attrgetter('short_name'))
        results = [result_info[problem] for problem in problems]
        percentages = [
            100.0 * result['score'] /
            result['max_score'] if result['exists'] else 0.0
            for result in results
        ]

        if len(problems) > 0:
            total_percent_solved = sum(percentages) / len(problems)
        else:
            total_percent_solved = 0.0

        return {
            'div_id': 'problems-' + div_id,
            'subnodes': {},
            'problem_info': zip(problems, results),
            'progress_percentage': total_percent_solved,
            'progress_percentage_rounded': round(total_percent_solved, 1),
            'attempted': any(result['exists'] for result in results)
        }

    node = {
        'div_id': div_id,
        'subnodes': {},
        'problem_info': [],
        'progress_percentage': 0.0,
        'progress_percentage_rounded': 0.0,
        'attempted': False
    }

    category = categories[0]
    iter = groupby(problems,
                   key=lambda problem: \
                           get_prefetched_value(problem, category))

    total_percentage = 0

    for value, group in iter:
        child_id = div_id + '-' + str(value.value)
        child_problems = list(group)
        child = _recursive_group_problems(child_problems, result_info,
                                          categories[1:], child_id)
        node['subnodes'][value] = child
        if child['attempted'] == True:
            node['attempted'] = True
        total_percentage += child['progress_percentage'] * len(child_problems)

    if len(problems) > 0:
        total_percentage /= len(problems)
    else:
        total_percentage = 0.0

    node['progress_percentage'] = total_percentage
    node['progress_percentage_rounded'] = round(total_percentage, 1)

    return node
Exemplo n.º 2
0
def task_archive_tag_view(request, origin_tag):
    origin_tag = OriginTag.objects.filter(name=origin_tag).prefetch_related(
        'localizations',
        'info_categories__localizations',
        'info_categories__parent_tag__localizations',
        'info_categories__values__localizations',
        'info_categories__values__parent_tag__localizations',
    )
    origin_tag = get_object_or_404(origin_tag)

    categories = origin_tag.info_categories.all()
    # We use getparams for filtering by OriginInfo - make sure they are valid
    for getparam in _filter_neutral_get_params(request.GET.keys()):
        if not categories.filter(name=getparam).exists():
            raise Http404

    problems = (origin_tag.problems.all().select_related(
        'problemsite', 'main_problem_instance').prefetch_related(
            'origininfovalue_set__localizations',
            'origininfovalue_set__category'))
    problems = _filter_problems_prefetched(problems, request.GET)

    # We want to achieve something like Django's regroup, but with dynamic keys:

    # 1. Don't use categories with Null order for grouping
    categories = sorted([cat for cat in categories if cat.order],
                        key=lambda cat: cat.order)

    # 2. Stable sort the problem list by each category in reverse order.
    #    This gives the correct order for the final grouping.
    for cat in categories[::-1]:
        problems.sort(
            key=lambda problem: get_prefetched_value(problem, cat).order)

    # 3. Now we can recursively group the problem list by each category.

    user_results = _get_results_info(request, problems)

    problems_root_node = _recursive_group_problems(problems, user_results,
                                                   categories, 'problemgroups')

    navbar_links = navbar_links_registry.template_context(request)
    return TemplateResponse(
        request,
        'problems/task-archive-tag.html',
        {
            'origin_tag': origin_tag,
            'problems': problems_root_node,
            'navbar_links': navbar_links,
        },
    )
Exemplo n.º 3
0
def _recursive_group_problems(problems, categories, div_id):
    if not categories:
        return {
            'div_id': 'problems-' + div_id,
            'subnodes': {},
            'problem_list': list(problems)
        }

    node = {'div_id': div_id, 'subnodes': {}, 'problem_list': []}
    category = categories[0]
    iter = groupby(problems,
                   key=lambda problem: \
                           get_prefetched_value(problem, category))

    for value, group in iter:
        child_id = div_id + '-' + str(value.value)
        node['subnodes'][value] = \
                _recursive_group_problems(list(group), categories[1:], child_id)
    return node