def get_blank_lti(request, course_id): # pylint: disable=unused-argument """ Respond with CSV output - ID - email - grade (blank) - max_grade (blank) - comments (blank) """ course_id = CourseKey.from_string(course_id) students = User.objects.filter( courseenrollment__course_id=course_id, ).order_by('id') header = [ 'ID', 'Anonymized User ID', 'email', 'grade', 'max_grade', 'comments', ] encoded_header = [unicode(s).encode('utf-8') for s in header] rows = [[ student.id, unique_id_for_user(student, save=False), student.email, '', '', '', ] for student in students] csv_filename = "{course_id}-blank-grade-submission.csv".format( course_id=unicode(course_id).replace('/', '-'), ) return create_csv_response(csv_filename, encoded_header, rows)
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 = BlockUsageLocator.from_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"), _("Username"), _("Grade"), _("Percent")] for student in students: percent = 0 if student['max_grade'] > 0: percent = round(decimal.Decimal(student['grade'] * 100 / student['max_grade']), 1) results.append([student['student__profile__name'], student['student__username'], student['grade'], percent]) response = create_csv_response(filename, header, results) return response
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().decode('utf-8'), '')
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","*****@*****.**"')
def test_create_csv_response_empty(self): header = [] datarows = [] res = create_csv_response('robot.csv', header, datarows) assert res['Content-Type'] == 'text/csv' assert res['Content-Disposition'] == 'attachment; filename={}'.format('robot.csv') assert res.content.strip().decode('utf-8') == ''
def test_create_csv_response(self): header = ['Name', 'Email'] datarows = [['Jim', '*****@*****.**'], ['Jake', '*****@*****.**'], ['Jeeves', '*****@*****.**']] res = create_csv_response('robot.csv', header, datarows) assert res['Content-Type'] == 'text/csv' assert res['Content-Disposition'] == 'attachment; filename={}'.format('robot.csv') assert res.content.strip().decode('utf-8') ==\ '"Name","Email"\r\n"Jim","*****@*****.**"\r\n"Jake","*****@*****.**"\r\n"Jeeves","*****@*****.**"'
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'], u'attachment; filename={0}'.format('robot.csv')) self.assertEqual(res.content.strip(), '"Name","Email"')
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. """ module_state_key = BlockUsageLocator.from_string( request.GET.get('module_id')) csv = request.GET.get('csv') # 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', ).values('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"), _("Username")] 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