def get_students_problem_grades(request, csv=False):
    """
    Get a list of students and grades for a particular problem.
    If 'csv' is False, returns a dict of student's name: username: grade: percent.

    If 'csv' is True, returns a header array, and an array of arrays in the format:
    student names, usernames, grades, percents for CSV download.
    """
    module_state_key = Location.from_deprecated_string(request.GET.get('module_id'))
    csv = request.GET.get('csv')

    # Query for "problem grades" students
    students = models.StudentModule.objects.select_related('student').filter(
        module_state_key=module_state_key,
        module_type__exact='problem',
        grade__isnull=False,
    ).values('student__username', 'student__profile__name', 'grade', 'max_grade').order_by('student__profile__name')

    results = []
    if not csv:
        # Restrict screen list length
        # Adding 1 so can tell if list is larger than MAX_SCREEN_LIST_LENGTH
        # without doing another select.
        for student in students[0:MAX_SCREEN_LIST_LENGTH + 1]:
            student_dict = {
                'name': student['student__profile__name'],
                'username': student['student__username'],
                'grade': student['grade'],
            }

            student_dict['percent'] = 0
            if student['max_grade'] > 0:
                student_dict['percent'] = round(student['grade'] * 100 / student['max_grade'])
            results.append(student_dict)

        max_exceeded = False
        if len(results) > MAX_SCREEN_LIST_LENGTH:
            # Remove the last item so list length is exactly MAX_SCREEN_LIST_LENGTH
            del results[-1]
            max_exceeded = True

        response_payload = {
            'results': results,
            'max_exceeded': max_exceeded,
        }
        return JsonResponse(response_payload)
    else:
        tooltip = request.GET.get('tooltip')
        filename = sanitize_filename(tooltip[:tooltip.rfind(' - ')])

        header = [_("Name").encode('utf-8'), _("Username").encode('utf-8'), _("Grade").encode('utf-8'), _("Percent").encode('utf-8')]
        for student in students:

            percent = 0
            if student['max_grade'] > 0:
                percent = round(student['grade'] * 100 / student['max_grade'])
            results.append([student['student__profile__name'], student['student__username'], student['grade'], percent])

        response = create_csv_response(filename, header, results)
        return response
Example #2
0
    def test_create_csv_response(self):
        header = ['Name', 'Email']
        datarows = [['Jim', '*****@*****.**'], ['Jake', '*****@*****.**'], ['Jeeves', '*****@*****.**']]

        res = create_csv_response('robot.csv', header, datarows)
        self.assertEqual(res['Content-Type'], 'text/csv')
        self.assertEqual(res['Content-Disposition'], u'attachment; filename={0}'.format('robot.csv'))
        self.assertEqual(res.content.strip(), '"Name","Email"\r\n"Jim","*****@*****.**"\r\n"Jake","*****@*****.**"\r\n"Jeeves","*****@*****.**"')
Example #3
0
    def test_create_csv_response_empty(self):
        header = []
        datarows = []

        res = create_csv_response('robot.csv', header, datarows)
        self.assertEqual(res['Content-Type'], 'text/csv')
        self.assertEqual(res['Content-Disposition'], u'attachment; filename={0}'.format('robot.csv'))
        self.assertEqual(res.content.strip(), '')
Example #4
0
    def test_create_csv_response_nodata(self):
        header = ['Name', 'Email']
        datarows = []

        res = create_csv_response('robot.csv', header, datarows)
        self.assertEqual(res['Content-Type'], 'text/csv')
        self.assertEqual(res['Content-Disposition'], 'attachment; filename={0}'.format('robot.csv'))
        self.assertEqual(res.content.strip(), '"Name","Email"')
Example #5
0
    def test_create_csv_response(self):
        header = ['Name', 'Email']
        datarows = [['Jim', '*****@*****.**'], ['Jake', '*****@*****.**'], ['Jeeves', '*****@*****.**']]

        res = create_csv_response('robot.csv', header, datarows)
        self.assertEqual(res['Content-Type'], 'text/csv')
        self.assertEqual(res['Content-Disposition'], u'attachment; filename={0}'.format('robot.csv'))
        self.assertEqual(res.content.strip(), '"Name","Email"\r\n"Jim","*****@*****.**"\r\n"Jake","*****@*****.**"\r\n"Jeeves","*****@*****.**"')
Example #6
0
    def test_create_csv_response_empty(self):
        header = []
        datarows = []

        res = create_csv_response('robot.csv', header, datarows)
        self.assertEqual(res['Content-Type'], 'text/csv')
        self.assertEqual(res['Content-Disposition'], u'attachment; filename={0}'.format('robot.csv'))
        self.assertEqual(res.content.strip(), '')
Example #7
0
    def test_create_csv_response_nodata(self):
        header = ['Name', 'Email']
        datarows = []

        res = create_csv_response('robot.csv', header, datarows)
        self.assertEqual(res['Content-Type'], 'text/csv')
        self.assertEqual(res['Content-Disposition'], 'attachment; filename={0}'.format('robot.csv'))
        self.assertEqual(res.content.strip(), '"Name","Email"')
Example #8
0
def get_students_opened_subsection(request, csv=False):
    """
    Get a list of students that opened a particular subsection.
    If 'csv' is False, returns a dict of student's name: username.

    If 'csv' is True, returns a header array, and an array of arrays in the format:
    student names, usernames for CSV download.
    """
    csv = request.GET.get('csv')
    course_id = request.GET.get('course_id')
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    module_state_key = course_key.make_usage_key_from_deprecated_string(
        request.GET.get('module_id'))

    non_student_list = get_non_student_list(course_key)

    # Query for "opened a subsection" students
    students = models.StudentModule.objects.select_related('student').filter(
        module_state_key__exact=module_state_key,
        module_type__exact='sequential',
    ).exclude(student_id__in=non_student_list).values(
        'student__id', 'student__username',
        'student__profile__name').order_by('student__profile__name')

    results = []

    if not csv:
        # Restrict screen list length
        # Adding 1 so can tell if list is larger than MAX_SCREEN_LIST_LENGTH
        # without doing another select.
        for student in students[0:MAX_SCREEN_LIST_LENGTH + 1]:
            results.append({
                'name': student['student__profile__name'],
                'username': student['student__username'],
            })
        max_exceeded = False
        if len(results) > MAX_SCREEN_LIST_LENGTH:
            # Remove the last item so list length is exactly MAX_SCREEN_LIST_LENGTH
            del results[-1]
            max_exceeded = True
        response_payload = {
            'results': results,
            'max_exceeded': max_exceeded,
        }
        return JsonResponse(response_payload)
    else:
        tooltip = request.GET.get('tooltip')

        # Subsection name is everything after 3rd space in tooltip
        filename = sanitize_filename(' '.join(tooltip.split(' ')[3:]))
        header = [_("Name").encode('utf-8'), _("Username").encode('utf-8')]
        for student in students:
            results.append([
                student['student__profile__name'], student['student__username']
            ])

        response = create_csv_response(filename, header, results)
        return response
def get_students_opened_subsection(request, csv=False):
    """
    Get a list of students that opened a particular subsection.
    If 'csv' is False, returns a dict of student's name: username.

    If 'csv' is True, returns a header array, and an array of arrays in the format:
    student names, usernames for CSV download.
    """
    csv = request.GET.get('csv')
    course_id = request.GET.get('course_id')
    course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
    module_state_key = course_key.make_usage_key_from_deprecated_string(request.GET.get('module_id'))

    non_student_list = get_non_student_list(course_key)

    # Query for "opened a subsection" students
    students = models.StudentModule.objects.select_related('student').filter(
        module_state_key__exact=module_state_key,
        module_type__exact='sequential',
    ).exclude(student_id__in=non_student_list).values('student__id', 'student__username', 'student__profile__name').order_by('student__profile__name')

    results = []

    if not csv:
        # Restrict screen list length
        # Adding 1 so can tell if list is larger than MAX_SCREEN_LIST_LENGTH
        # without doing another select.
        for student in students[0:MAX_SCREEN_LIST_LENGTH + 1]:
            results.append({
                'name': student['student__profile__name'],
                'username': student['student__username'],
            })
        max_exceeded = False
        if len(results) > MAX_SCREEN_LIST_LENGTH:
            # Remove the last item so list length is exactly MAX_SCREEN_LIST_LENGTH
            del results[-1]
            max_exceeded = True
        response_payload = {
            'results': results,
            'max_exceeded': max_exceeded,
        }
        return JsonResponse(response_payload)
    else:
        tooltip = request.GET.get('tooltip')

        # Subsection name is everything after 3rd space in tooltip
        filename = sanitize_filename(' '.join(tooltip.split(' ')[3:]))
        header = [_("Name").encode('utf-8'), _("Username").encode('utf-8')]
        for student in students:
            results.append([student['student__profile__name'], student['student__username']])

        response = create_csv_response(filename, header, results)
        return response
def post_metrics_data_csv(request):
    """
    Generate a list of opened subsections or problems for the entire course for CSV download.
    Returns a header array, and an array of arrays in the format:
    section, subsection, count of students for subsections
    or section, problem, name, count of students, percent of students, score for problems.
    """

    data = json.loads(request.POST['data'])
    sections = json.loads(data['sections'])
    tooltips = json.loads(data['tooltips'])
    course_id = data['course_id']
    data_type = data['data_type']

    results = []
    if data_type == 'subsection':
        header = [_("Section"), _("Subsection"), _("Opened by this number of students")]
        filename = sanitize_filename(_('subsections') + '_' + course_id)
    elif data_type == 'problem':
        header = [
            _("Section"), _("Problem"), _("Name"), _("Count of Students"),
            _("Percent of Students"), _("Score"),
        ]
        filename = sanitize_filename(_('problems') + '_' + course_id)

    for index, section in enumerate(sections):
        results.append([section])

        # tooltips array is array of dicts for subsections and
        # array of array of dicts for problems.
        if data_type == 'subsection':
            for tooltip_dict in tooltips[index]:
                num_students = tooltip_dict['num_students']
                subsection = tooltip_dict['subsection_name']
                # Append to results offsetting 1 column to the right.
                results.append(['', subsection, num_students])

        elif data_type == 'problem':
            for tooltip in tooltips[index]:
                for tooltip_dict in tooltip:
                    label = tooltip_dict['label']
                    problem_name = tooltip_dict['problem_name']
                    count_grade = tooltip_dict['count_grade']
                    student_count_percent = tooltip_dict['student_count_percent']
                    percent = tooltip_dict['percent']
                    # Append to results offsetting 1 column to the right.
                    results.append(['', label, problem_name, count_grade, student_count_percent, percent])

    response = create_csv_response(filename, header, results)
    return response
def post_metrics_data_csv(request):
    """
    Generate a list of opened subsections or problems for the entire course for CSV download.
    Returns a header array, and an array of arrays in the format:
    section, subsection, count of students for subsections
    or section, problem, name, count of students, percent of students, score for problems.
    """

    data = json.loads(request.POST['data'])
    sections = json.loads(data['sections'])
    tooltips = json.loads(data['tooltips'])
    course_id = data['course_id']
    data_type = data['data_type']

    results = []
    if data_type == 'subsection':
        header = [_("Section"), _("Subsection"), _("Opened by this number of students")]
        filename = sanitize_filename(_('subsections') + '_' + course_id)
    elif data_type == 'problem':
        header = [
            _("Section"), _("Problem"), _("Name"), _("Count of Students"),
            _("Percent of Students"), _("Score"),
        ]
        filename = sanitize_filename(_('problems') + '_' + course_id)

    for index, section in enumerate(sections):
        results.append([section])

        # tooltips array is array of dicts for subsections and
        # array of array of dicts for problems.
        if data_type == 'subsection':
            for tooltip_dict in tooltips[index]:
                num_students = tooltip_dict['num_students']
                subsection = tooltip_dict['subsection_name']
                # Append to results offsetting 1 column to the right.
                results.append(['', subsection, num_students])

        elif data_type == 'problem':
            for tooltip in tooltips[index]:
                for tooltip_dict in tooltip:
                    label = tooltip_dict['label']
                    problem_name = tooltip_dict['problem_name']
                    count_grade = tooltip_dict['count_grade']
                    student_count_percent = tooltip_dict['student_count_percent']
                    percent = tooltip_dict['percent']
                    # Append to results offsetting 1 column to the right.
                    results.append(['', label, problem_name, count_grade, student_count_percent, percent])

    response = create_csv_response(filename, header, results)
    return response