def user_progression(user, activity): """Return a tuple of two integers `(progression, quality)` where `progression` is the percent of work done and `quality` is the mean of grades over graded exercices. All views using this utilitary function should check the requesting user is allowed to access data. `progression` : percent of graded exercices plus 10% of percent of only built exercices by the `user`. `quality` : average grade obtained by `user` over graded exercices. Quality is zero if no exercice has been graded. """ pl = activity.pl.all() nb_pl_touched = 0 nb_pl_graded = 0 sum_grades = 0 for i in pl: answer = Answer.highest_grade(i, user) if answer is not None: nb_pl_touched += 1 if answer.grade is not None: nb_pl_graded += 1 sum_grades += answer.grade progr = (100 * nb_pl_graded + 10 * (nb_pl_touched - nb_pl_graded)) / len(pl) if pl else 0 average = sum_grades / nb_pl_graded if nb_pl_graded else 0 return (progr, average)
def notes(self, activity, request): user = request.user users = activity.student.all() pl = activity.pl.all() if not user or user not in activity.teacher.all(): return HttpResponseForbidden("Not authorized") csv = "username,firstname,lastname,email," + ''.join( [str(i + 1) + ": " + p.name + "," for i, p in enumerate(pl)]) + "total\n" for u in users: grades = [] for i in pl: answer = Answer.highest_grade(i, u) grades.append(0 if answer is None else max(answer.grade, 0) if answer.grade is not None else 0) csv += ("%s,%s,%s,%s," % (u.username, u.first_name, u.last_name, u.email) + ''.join([str(i) + "," for i in grades]) + str(sum(grades)) + "\n") response = HttpResponse(csv, content_type="text/csv") response['Content-Disposition'] = 'attachment;filename=notes.csv' return response
def teacher_dashboard(self, request, activity, session): """ This method is called when the dashboard of an activity is requested for a teacher. :return: A rendered template of the teacher dashboard """ exos = [] for pl in activity.indexed_pl(): exos.append({'name': pl.json['title'], 'sum_grades': 0}) for state in list(State)[0:-1]: exos[-1][state] = 0 student = list() for user in activity.student.all(): tp = list() for count, pl in enumerate(activity.indexed_pl()): ans_grade = Answer.highest_grade(pl, user) state = State.by_grade(ans_grade.grade if ans_grade else ...) tp.append({'name': pl.json['title'], 'state': state}) if state != State.ERROR: exos[count][state] += 1 if ans_grade and ans_grade.grade is not None: exos[count]['sum_grades'] += ans_grade.grade student.append({ 'lastname': user.last_name, 'object': user, 'id': user.id, 'question': tp, }) for exo in exos: exo['mean'] = exo['sum_grades'] / len(student) if student else 0 exo.pop('sum_grades') # Sort list by student's name student = sorted(student, key=lambda k: k['lastname']) return render( request, 'activity/activity_type/pltp/teacher_dashboard.html', { 'state': [i for i in State if i != State.ERROR], 'course_name': activity.parent.name, 'activity_name': activity.name, 'student': student, 'range_tp': range(len(activity.indexed_pl())), 'course_id': activity.parent.id, 'exos': exos, })
def test_highest_grade(self): self.assertIs(Answer.highest_grade(self.pl, self.user), None) Answer.objects.create(pl=self.pl, user=self.user, grade=10) Answer.objects.create(pl=self.pl, user=self.user, grade=20) self.assertEqual(Answer.highest_grade(self.pl, self.user).grade, 20)