def _calculate_results_impl(course): """Calculates the result data for a single course. Returns a list of `ResultSection` tuples. Each of those tuples contains the questionnaire, the contributor (or None), a list of (Rating|YesNo|Text|Heading)Result tuples, the average grade and distribution for that section (or None).""" # there will be one section per relevant questionnaire--contributor pair sections = [] # calculate the median values of how many people answered a questionnaire type (lecturer, tutor, ...) questionnaire_med_answers = defaultdict(list) questionnaire_max_answers = {} questionnaire_warning_thresholds = {} for questionnaire, contribution in questionnaires_and_contributions(course): max_answers = max([get_number_of_answers(contribution, question) for question in questionnaire.rating_questions], default=0) questionnaire_max_answers[(questionnaire, contribution)] = max_answers questionnaire_med_answers[questionnaire].append(max_answers) for questionnaire, max_answers in questionnaire_med_answers.items(): questionnaire_warning_thresholds[questionnaire] = max(settings.RESULTS_WARNING_PERCENTAGE * median(max_answers), settings.RESULTS_WARNING_COUNT) for questionnaire, contribution in questionnaires_and_contributions(course): # will contain one object per question results = [] for question in questionnaire.question_set.all(): if question.is_rating_question: answer_counters = get_answers(contribution, question) answers = get_answers_from_answer_counters(answer_counters) total_count = len(answers) average = avg(answers) if total_count > 0 else None counts = get_counts(answer_counters) if total_count > 0 else None warning = total_count > 0 and total_count < questionnaire_warning_thresholds[questionnaire] if question.is_yes_no_question: if not counts: approval_count = None else: if question.is_positive_yes_no_question: approval_count = counts[0] else: approval_count = counts[4] results.append(YesNoResult(question, total_count, average, counts, warning, approval_count)) else: results.append(RatingResult(question, total_count, average, counts, warning)) elif question.is_text_question: answers = get_textanswers(contribution, question, COMMENT_STATES_REQUIRED_FOR_VISIBILITY) results.append(TextResult(question=question, answers=answers)) elif question.is_heading_question: results.append(HeadingResult(question=question)) section_warning = 0 < questionnaire_max_answers[(questionnaire, contribution)] < questionnaire_warning_thresholds[questionnaire] sections.append(ResultSection(questionnaire, contribution.contributor, contribution.label, results, section_warning)) return sections
def _calculate_results_impl(course): """Calculates the result data for a single course. Returns a list of `ResultSection` tuples. Each of those tuples contains the questionnaire, the contributor (or None), a list of single result elements, the average grade and deviation for that section (or None). The result elements are either `RatingResult` or `TextResult` instances.""" # there will be one section per relevant questionnaire--contributor pair sections = [] # calculate the median values of how many people answered a questionnaire type (lecturer, tutor, ...) questionnaire_med_answers = defaultdict(list) questionnaire_max_answers = {} questionnaire_warning_thresholds = {} for questionnaire, contribution in questionnaires_and_contributions(course): max_answers = max([get_number_of_answers(contribution, question) for question in questionnaire.rating_questions], default=0) questionnaire_max_answers[(questionnaire, contribution)] = max_answers questionnaire_med_answers[questionnaire].append(max_answers) for questionnaire, max_answers in questionnaire_med_answers.items(): questionnaire_warning_thresholds[questionnaire] = max(settings.RESULTS_WARNING_PERCENTAGE * median(max_answers), settings.RESULTS_WARNING_COUNT) for questionnaire, contribution in questionnaires_and_contributions(course): # will contain one object per question results = [] for question in questionnaire.question_set.all(): if question.is_rating_question: answer_counters = get_answers(contribution, question) answers = get_answers_from_answer_counters(answer_counters) total_count = len(answers) average = avg(answers) if total_count > 0 else None deviation = pstdev(answers, average) if total_count > 0 else None counts = get_counts(question, answer_counters) warning = total_count > 0 and total_count < questionnaire_warning_thresholds[questionnaire] if question.is_yes_no_question: if question.is_positive_yes_no_question: approval_count = counts[1] else: approval_count = counts[5] results.append(YesNoResult(question, total_count, average, deviation, counts, warning, approval_count)) else: results.append(RatingResult(question, total_count, average, deviation, counts, warning)) elif question.is_text_question: allowed_states = [TextAnswer.PRIVATE, TextAnswer.PUBLISHED] answers = get_textanswers(contribution, question, allowed_states) results.append(TextResult(question=question, answers=answers)) section_warning = questionnaire_max_answers[(questionnaire, contribution)] < questionnaire_warning_thresholds[questionnaire] sections.append(ResultSection(questionnaire, contribution.contributor, contribution.label, results, section_warning)) return sections
def course_comments(request, semester_id, course_id): semester = get_object_or_404(Semester, id=semester_id) course = get_object_or_404(Course, id=course_id) filter = request.GET.get('filter', None) if filter is None: # if no parameter is given take session value filter = request.session.get('filter_comments', False) # defaults to False if no session value exists else: filter = {'true': True, 'false': False}.get(filter.lower()) # convert parameter to boolean request.session['filter_comments'] = filter # store value for session filter_states = [TextAnswer.NOT_REVIEWED] if filter else None course_sections = [] contributor_sections = [] for questionnaire, contribution in questionnaires_and_contributions(course): text_results = [] for question in questionnaire.text_questions: answers = get_textanswers(contribution, question, filter_states) if answers: text_results.append(TextResult(question=question, answers=answers)) if not text_results: continue section_list = course_sections if contribution.is_general else contributor_sections section_list.append(CommentSection(questionnaire, contribution.contributor, contribution.responsible, text_results)) template_data = dict(semester=semester, course=course, course_sections=course_sections, contributor_sections=contributor_sections, filter=filter) return render(request, "staff_course_comments.html", template_data)
def course_preview(request, semester_id, course_id): semester = get_object_or_404(Semester, id=semester_id) course = get_object_or_404(Course, id=course_id) # build forms forms = OrderedDict() for questionnaire, contribution in questionnaires_and_contributions(course): form = QuestionsForm(request.POST or None, contribution=contribution, questionnaire=questionnaire) forms[(contribution, questionnaire)] = form return render_to_response("fsr_course_preview.html", dict(forms=forms.values(), course=course, semester=semester), context_instance=RequestContext(request))
def course_preview(request, semester_id, course_id): semester = get_object_or_404(Semester, id=semester_id) course = get_object_or_404(Course, id=course_id) # build forms forms = SortedDict() for questionnaire, contribution in questionnaires_and_contributions(course): form = QuestionsForm(request.POST or None, contribution=contribution, questionnaire=questionnaire) forms[(contribution, questionnaire)] = form return render_to_response("fsr_course_preview.html", dict(forms=forms.values(), course=course, semester=semester), context_instance=RequestContext(request))
def course_preview(request, course_id): user = request.user course = get_object_or_404(Course, id=course_id) # build forms forms = SortedDict() for questionnaire, contribution in questionnaires_and_contributions(course): form = QuestionsForm(request.POST or None, contribution=contribution, questionnaire=questionnaire) forms[(contribution, questionnaire)] = form return render_to_response("contributor_course_preview.html", dict(forms=forms.values(), course=course), context_instance=RequestContext(request))
def vote(request, course_id): # retrieve course and make sure that the user is allowed to vote course = get_object_or_404(Course, id=course_id) if not course.can_user_vote(request.user): raise PermissionDenied # build forms forms = SortedDict() for questionnaire, contribution in questionnaires_and_contributions( course): form = QuestionsForm(request.POST or None, contribution=contribution, questionnaire=questionnaire) forms[(contribution, questionnaire)] = form if all(form.is_valid() for form in forms.values()): # begin vote operation with transaction.commit_on_success(): for (contribution, questionnaire), form in forms.items(): for question in questionnaire.question_set.all(): identifier = make_form_identifier(contribution, questionnaire, question) value = form.cleaned_data.get(identifier) if type(value) in [str, unicode]: value = value.strip() if value == 6: #no answer value = None # store the answer if one was given if value: question.answer_class.objects.create( contribution=contribution, question=question, answer=value) # remember that the user voted already course.voters.add(request.user) messages.add_message(request, messages.INFO, _("Your vote was recorded.")) return redirect('evap.student.views.index') else: return render_to_response("student_vote.html", dict(forms=forms.values(), course=course), context_instance=RequestContext(request))
def vote(request, course_id): # retrieve course and make sure that the user is allowed to vote course = get_object_or_404(Course, id=course_id) if not course.can_user_vote(request.user): raise PermissionDenied # build forms forms = SortedDict() for questionnaire, contribution in questionnaires_and_contributions(course): form = QuestionsForm(request.POST or None, contribution=contribution, questionnaire=questionnaire) forms[(contribution, questionnaire)] = form if all(form.is_valid() for form in forms.values()): # begin vote operation with transaction.commit_on_success(): for (contribution, questionnaire), form in forms.items(): for question in questionnaire.question_set.all(): identifier = make_form_identifier(contribution, questionnaire, question) value = form.cleaned_data.get(identifier) if type(value) in [str, unicode]: value = value.strip() if value == 6: #no answer value = None # store the answer if one was given if value: question.answer_class.objects.create( contribution=contribution, question=question, answer=value) # remember that the user voted already course.voters.add(request.user) messages.add_message(request, messages.INFO, _("Your vote was recorded.")) return redirect('evap.student.views.index') else: return render_to_response( "student_vote.html", dict(forms=forms.values(), course=course), context_instance=RequestContext(request))
def course_comments(request, semester_id, course_id): semester = get_object_or_404(Semester, id=semester_id) course = get_object_or_404(Course, id=course_id) filter = request.GET.get('filter', None) if filter == None: # if no parameter is given take session value filter = request.session.get( 'filter_comments', False) # defaults to False if no session value exists else: filter = { 'true': True, 'false': False }.get(filter.lower()) # convert parameter to boolean request.session['filter_comments'] = filter # store value for session filter_states = [TextAnswer.NOT_REVIEWED] if filter else None course_sections = [] contributor_sections = [] for questionnaire, contribution in questionnaires_and_contributions( course): text_results = [] for question in questionnaire.text_questions: answers = get_textanswers(contribution, question, filter_states) if answers: text_results.append( TextResult(question=question, answers=answers)) if not text_results: continue section_list = course_sections if contribution.is_general else contributor_sections section_list.append( CommentSection(questionnaire, contribution.contributor, contribution.responsible, text_results)) template_data = dict(semester=semester, course=course, course_sections=course_sections, contributor_sections=contributor_sections, filter=filter) return render(request, "staff_course_comments.html", template_data)
def _calculate_results_impl(course): """Calculates the result data for a single course. Returns a list of `ResultSection` tuples. Each of those tuples contains the questionnaire, the contributor (or None), a list of single result elements, the average grade and deviation for that section (or None). The result elements are either `RatingResult` or `TextResult` instances.""" # there will be one section per relevant questionnaire--contributor pair sections = [] # calculate the median values of how many people answered a questionnaire type (lecturer, tutor, ...) questionnaire_med_answers = defaultdict(list) questionnaire_max_answers = {} questionnaire_warning_thresholds = {} for questionnaire, contribution in questionnaires_and_contributions( course): max_answers = max([ get_number_of_answers(contribution, question) for question in questionnaire.rating_questions ], default=0) questionnaire_max_answers[(questionnaire, contribution)] = max_answers questionnaire_med_answers[questionnaire].append(max_answers) for questionnaire, max_answers in questionnaire_med_answers.items(): questionnaire_warning_thresholds[ questionnaire] = settings.RESULTS_WARNING_PERCENTAGE * median( max_answers) for questionnaire, contribution in questionnaires_and_contributions( course): # will contain one object per question results = [] for question in questionnaire.question_set.all(): if question.is_rating_question: answer_counters = get_answers(contribution, question) answers = get_answers_from_answer_counters(answer_counters) total_count = len(answers) average = avg(answers) if total_count > 0 else None deviation = pstdev(answers, average) if total_count > 0 else None counts = get_counts(answer_counters) warning = total_count > 0 and total_count < questionnaire_warning_thresholds[ questionnaire] results.append( RatingResult(question, total_count, average, deviation, counts, warning)) elif question.is_text_question: allowed_states = [TextAnswer.PRIVATE, TextAnswer.PUBLISHED] answers = get_textanswers(contribution, question, allowed_states) results.append(TextResult(question=question, answers=answers)) section_warning = questionnaire_max_answers[( questionnaire, contribution)] < questionnaire_warning_thresholds[questionnaire] sections.append( ResultSection(questionnaire, contribution.contributor, contribution.label, results, section_warning)) return sections