예제 #1
0
def test_detail_view(request, test_id):
    """View details of student performance on specific exams"""

    facility, group_id, context = coach_nav_context(request, "test")
    # get users in this facility and group
    users = get_user_queryset(request, facility, group_id)

    # Get test object
    test_resource = TestResource()
    test_obj = test_resource._read_test(test_id=test_id)

    # get all of the test logs for this specific test object and generated by these specific users
    if group_id:
        test_logs = TestLog.objects.filter(user__group=group_id, test=test_id)

        # Narrow all by ungroup facility user
        if group_id == control_panel_api_resources.UNGROUPED_KEY:
            if facility:
                test_logs = TestLog.objects.filter(user__group__isnull=True)
            else:
                test_logs = TestLog.objects.filter(facility=facility, user__group__isnull=True)
    else:
        # covers the all groups case
        test_logs = TestLog.objects.filter(user__facility=facility, test=test_id)

    results_table, scores_dict = OrderedDict(), OrderedDict()
    # build this up now to use in summary stats section
    ex_ids = set(literal_eval(test_obj.ids))
    for ex in ex_ids:
        scores_dict[ex] = []
    for s in users:
        s.name = s.get_name()
        user_attempts = AttemptLog.objects.filter(user=s, context_type='test', context_id=test_id)
        results_table[s] = []
        attempts_count_total, attempts_count_correct_total = 0, 0
        for ex in ex_ids:
            attempts = [attempt for attempt in user_attempts if attempt.exercise_id == ex]

            attempts_count = len(attempts)
            attempts_count_correct = len([attempt for attempt in attempts if attempt.correct])

            attempts_count_total += attempts_count
            attempts_count_correct_total += attempts_count_correct

            if attempts_count:
                score = round(100 * float(attempts_count_correct)/float(attempts_count), 1)
                scores_dict[ex].append(score)
                display_score = "%d%%" % score
            else:
                score = ''
                display_score = ''

            results_table[s].append({
                'display_score': display_score,
                'raw_score': score,
            })

        # Calc overall score
        if attempts_count_total:
            score = round(100 * float(attempts_count_correct_total)/float(attempts_count_total), 1)
            display_score = "%d%%" % score
            fraction_correct = "(%(correct)d/%(attempts)d)" % ({'correct': attempts_count_correct_total, 'attempts': attempts_count_total})
        else:
            score = ''
            display_score = ''
            fraction_correct = ''

        results_table[s].append({
            'display_score': display_score,
            'raw_score': score,
            'title': fraction_correct,
        })

    # This retrieves stats for individual exercises
    stats_dict = OrderedDict()
    for stat in SUMMARY_STATS:
        stats_dict[stat] = []
        for ex in ex_ids:
            scores_list = scores_dict[ex]
            if scores_list:
                stats_dict[stat].append("%d%%" % return_list_stat(scores_list, stat))
            else:
                stats_dict[stat].append('')

    # replace the exercise ids with their full names
    exercises = get_exercise_cache()
    ex_titles = []
    for ex in ex_ids:
        ex_titles.append(exercises[ex]['title'])

    # provide a list of test options to view for this group/facility combo
    if group_id:
        test_logs = TestLog.objects.filter(user__group=group_id)
    else:
        # covers the all/no groups case
        test_logs = TestLog.objects.filter(user__facility=facility)
    test_objects = test_resource._read_tests()
    unique_test_ids = set([test_log.test for test_log in test_logs])
    test_options = [{'id': obj.test_id, 'url': reverse('test_detail_view', kwargs={'test_id':obj.test_id}), 'title': obj.title} for obj in test_objects if obj.test_id in unique_test_ids]
    context = plotting_metadata_context(request, facility=facility)
    context.update({
        "test_obj": test_obj,
        "ex_cols": ex_titles,
        "results_table": results_table,
        "stats_dict": stats_dict,
        "test_options": test_options,
    })
    return context
예제 #2
0
def test_detail_view(request, test_id):
    """View details of student performance on specific exams"""

    facility, group_id, context = coach_nav_context(request, "test")
    # get users in this facility and group
    users = get_user_queryset(request, facility, group_id)

    # Get test object
    test_resource = TestResource()
    test_obj = test_resource._read_test(test_id=test_id)

    # get all of the test logs for this specific test object and generated by these specific users
    if group_id:
        test_logs = TestLog.objects.filter(user__group=group_id, test=test_id)

        # Narrow all by ungroup facility user
        if group_id == control_panel_api_resources.UNGROUPED_KEY:
            if facility:
                test_logs = TestLog.objects.filter(user__group__isnull=True)
            else:
                test_logs = TestLog.objects.filter(facility=facility,
                                                   user__group__isnull=True)
    else:
        # covers the all groups case
        test_logs = TestLog.objects.filter(user__facility=facility,
                                           test=test_id)

    results_table, scores_dict = OrderedDict(), OrderedDict()
    # build this up now to use in summary stats section
    ex_ids = set(literal_eval(test_obj.ids))
    for ex in ex_ids:
        scores_dict[ex] = []
    for s in users:
        s.name = s.get_name()
        user_attempts = AttemptLog.objects.filter(user=s,
                                                  context_type='test',
                                                  context_id=test_id)
        results_table[s] = []
        attempts_count_total, attempts_count_correct_total = 0, 0
        for ex in ex_ids:
            attempts = [
                attempt for attempt in user_attempts
                if attempt.exercise_id == ex
            ]

            attempts_count = len(attempts)
            attempts_count_correct = len(
                [attempt for attempt in attempts if attempt.correct])

            attempts_count_total += attempts_count
            attempts_count_correct_total += attempts_count_correct

            if attempts_count:
                score = round(
                    100 * float(attempts_count_correct) /
                    float(attempts_count), 1)
                scores_dict[ex].append(score)
                display_score = "%d%%" % score
            else:
                score = ''
                display_score = ''

            results_table[s].append({
                'display_score': display_score,
                'raw_score': score,
            })

        # Calc overall score
        if attempts_count_total:
            score = round(
                100 * float(attempts_count_correct_total) /
                float(attempts_count_total), 1)
            display_score = "%d%%" % score
            fraction_correct = "(%(correct)d/%(attempts)d)" % (
                {
                    'correct': attempts_count_correct_total,
                    'attempts': attempts_count_total
                })
        else:
            score = ''
            display_score = ''
            fraction_correct = ''

        results_table[s].append({
            'display_score': display_score,
            'raw_score': score,
            'title': fraction_correct,
        })

    # This retrieves stats for individual exercises
    stats_dict = OrderedDict()
    for stat in SUMMARY_STATS:
        stats_dict[stat] = []
        for ex in ex_ids:
            scores_list = scores_dict[ex]
            if scores_list:
                stats_dict[stat].append("%d%%" %
                                        return_list_stat(scores_list, stat))
            else:
                stats_dict[stat].append('')

    # replace the exercise ids with their full names
    exercises = get_exercise_cache()
    ex_titles = []
    for ex in ex_ids:
        ex_titles.append(exercises[ex]['title'])

    # provide a list of test options to view for this group/facility combo
    if group_id:
        test_logs = TestLog.objects.filter(user__group=group_id)
    else:
        # covers the all/no groups case
        test_logs = TestLog.objects.filter(user__facility=facility)
    test_objects = test_resource._read_tests()
    unique_test_ids = set([test_log.test for test_log in test_logs])
    test_options = [{
        'id':
        obj.test_id,
        'url':
        reverse('test_detail_view', kwargs={'test_id': obj.test_id}),
        'title':
        obj.title
    } for obj in test_objects if obj.test_id in unique_test_ids]
    context = plotting_metadata_context(request, facility=facility)
    context.update({
        "test_obj": test_obj,
        "ex_cols": ex_titles,
        "results_table": results_table,
        "stats_dict": stats_dict,
        "test_options": test_options,
    })
    return context
예제 #3
0
def test_view(request):
    """Test view gets data server-side and displays exam results"""
    facility, group_id, context = coach_nav_context(request, "test")
    # Get students
    users = get_user_queryset(request, facility, group_id)

    # Get the TestLog objects generated by this group of students
    # TODO(cpauya): what about queryset for ungrouped students?
    test_logs = None
    if group_id:
        test_logs = TestLog.objects.filter(user__group=group_id)
        # Narrow all by ungroup facility user
        if group_id == control_panel_api_resources.UNGROUPED_KEY:
            test_logs = TestLog.objects.filter(user__group__isnull=True)
            if facility:
                TestLog.objects.filter(user__facility=facility, user__group__isnull=True)
            else:
                TestLog.objects.filter(user__group__isnull=True)

    elif facility:
        test_logs = TestLog.objects.filter(user__facility=facility)

    else:
        # filter by all facilities and groups for the user
        (groups, facilities, ungrouped_available) = get_accessible_objects_from_logged_in_user(request, facility=facility)
        if facilities:
            facility_ids = facilities.values_list("id", flat=True)
            test_logs = TestLog.objects.filter(user__facility__id__in=facility_ids)

    # Get list of all test objects
    test_resource = TestResource()
    tests_list = test_resource._read_tests()

    # Get completed test objects (used as columns)
    completed_test_ids = set([item.test for item in test_logs])
    test_objects = [test for test in tests_list if test.test_id in completed_test_ids]

    # Create the table
    results_table = OrderedDict()
    for s in users:
        s.name = s.get_name()
        user_test_logs = [log for log in test_logs if log.user == s]
        results_table[s] = []
        for t in test_objects:
            log_object = next((log for log in user_test_logs if log.test == t.test_id), '')
            # The template expects a status and a score to display
            if log_object:
                test_object = log_object.get_test_object()
                score = round(100 * float(log_object.total_correct) / float(test_object.total_questions), 1)
                display_score = "%(score)d%% (%(correct)d/%(total_questions)d)" % {'score': score, 'correct': log_object.total_correct, 'total_questions': test_object.total_questions}
                if log_object.complete:
                    # Case: completed => we show % score
                    if score >= 80:
                        status = _("pass")
                    elif score >= 60:
                        status = _("borderline")
                    else:
                        status = _("fail" )
                    results_table[s].append({
                        "status": status,
                        "cell_display": display_score,
                        "title": status.title(),
                    })
                else:
                    # Case: has started, but has not finished => we display % score & # remaining in title
                    n_remaining = test_object.total_questions - log_object.index
                    status = _("incomplete")
                    results_table[s].append({
                        "status": status,
                        "cell_display": display_score,
                        "title": status.title() + ": " + ungettext("%(n_remaining)d problem remaining",
                                                                   n_remaining) % {'n_remaining': n_remaining},
                    })
            else:
                # Case: has not started
                status = _("not started")
                results_table[s].append({
                    "status": status,
                    "cell_display": "",
                    "title": status.title(),
                })

        # This retrieves stats for students
        score_list = [round(100 * float(result.total_correct) / float(result.get_test_object().total_questions), 1) for result in user_test_logs]
        for stat in SUMMARY_STATS:
            if score_list:
                results_table[s].append({
                    "status": "statistic",
                    "cell_display": "%d%%" % return_list_stat(score_list, stat),
                })
            else:
                results_table[s].append({
                    "status": "statistic",
                    "cell_display": "",
                })

    # This retrieves stats for tests
    stats_dict = OrderedDict()
    for stat in SUMMARY_STATS:
        stats_dict[stat] = []
        for test_obj in test_objects:
            # get the logs for this test across all users and then add summary stats
            log_scores = [round(100 * float(test_log.total_correct) / float(test_log.get_test_object().total_questions), 1) for test_log in test_logs if test_log.test == test_obj.test_id]
            stats_dict[stat].append("%d%%" % return_list_stat(log_scores, stat))

    context.update(plotting_metadata_context(request, facility=facility))
    context.update({
        "results_table": results_table,
        "test_columns": test_objects,
        "summary_stats": SUMMARY_STATS,
        "stats_dict": stats_dict,
    })

    return context
예제 #4
0
def test_view(request):
    """Test view gets data server-side and displays exam results"""
    facility, group_id, context = coach_nav_context(request, "test")
    # Get students
    users = get_user_queryset(request, facility, group_id)

    # Get the TestLog objects generated by this group of students
    # TODO(cpauya): what about queryset for ungrouped students?
    test_logs = None
    if group_id:
        test_logs = TestLog.objects.filter(user__group=group_id)
        # Narrow all by ungroup facility user
        if group_id == control_panel_api_resources.UNGROUPED_KEY:
            test_logs = TestLog.objects.filter(user__group__isnull=True)
            if facility:
                TestLog.objects.filter(user__facility=facility,
                                       user__group__isnull=True)
            else:
                TestLog.objects.filter(user__group__isnull=True)

    elif facility:
        test_logs = TestLog.objects.filter(user__facility=facility)

    else:
        # filter by all facilities and groups for the user
        (groups, facilities,
         ungrouped_available) = get_accessible_objects_from_logged_in_user(
             request, facility=facility)
        if facilities:
            facility_ids = facilities.values_list("id", flat=True)
            test_logs = TestLog.objects.filter(
                user__facility__id__in=facility_ids)

    # Get list of all test objects
    test_resource = TestResource()
    tests_list = test_resource._read_tests()

    # Get completed test objects (used as columns)
    completed_test_ids = set([item.test for item in test_logs])
    test_objects = [
        test for test in tests_list if test.test_id in completed_test_ids
    ]

    # Create the table
    results_table = OrderedDict()
    for s in users:
        s.name = s.get_name()
        user_test_logs = [log for log in test_logs if log.user == s]
        results_table[s] = []
        for t in test_objects:
            log_object = next(
                (log for log in user_test_logs if log.test == t.test_id), '')
            # The template expects a status and a score to display
            if log_object:
                test_object = log_object.get_test_object()
                score = round(
                    100 * float(log_object.total_correct) /
                    float(test_object.total_questions), 1)
                display_score = "%(score)d%% (%(correct)d/%(total_questions)d)" % {
                    'score': score,
                    'correct': log_object.total_correct,
                    'total_questions': test_object.total_questions
                }
                if log_object.complete:
                    # Case: completed => we show % score
                    if score >= 80:
                        status = _("pass")
                    elif score >= 60:
                        status = _("borderline")
                    else:
                        status = _("fail")
                    results_table[s].append({
                        "status": status,
                        "cell_display": display_score,
                        "title": status.title(),
                    })
                else:
                    # Case: has started, but has not finished => we display % score & # remaining in title
                    n_remaining = test_object.total_questions - log_object.index
                    status = _("incomplete")
                    results_table[s].append({
                        "status": status,
                        "cell_display": display_score,
                        "title": status.title() + ": " +
                        ungettext("%(n_remaining)d problem remaining",
                                  n_remaining) % {
                                      'n_remaining': n_remaining
                                  },
                    })
            else:
                # Case: has not started
                status = _("not started")
                results_table[s].append({
                    "status": status,
                    "cell_display": "",
                    "title": status.title(),
                })

        # This retrieves stats for students
        score_list = [
            round(
                100 * float(result.total_correct) /
                float(result.get_test_object().total_questions), 1)
            for result in user_test_logs
        ]
        for stat in SUMMARY_STATS:
            if score_list:
                results_table[s].append({
                    "status":
                    "statistic",
                    "cell_display":
                    "%d%%" % return_list_stat(score_list, stat),
                })
            else:
                results_table[s].append({
                    "status": "statistic",
                    "cell_display": "",
                })

    # This retrieves stats for tests
    stats_dict = OrderedDict()
    for stat in SUMMARY_STATS:
        stats_dict[stat] = []
        for test_obj in test_objects:
            # get the logs for this test across all users and then add summary stats
            log_scores = [
                round(
                    100 * float(test_log.total_correct) /
                    float(test_log.get_test_object().total_questions), 1)
                for test_log in test_logs if test_log.test == test_obj.test_id
            ]
            stats_dict[stat].append("%d%%" %
                                    return_list_stat(log_scores, stat))

    context.update(plotting_metadata_context(request, facility=facility))
    context.update({
        "results_table": results_table,
        "test_columns": test_objects,
        "summary_stats": SUMMARY_STATS,
        "stats_dict": stats_dict,
    })

    return context