Exemple #1
0
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
Exemple #2
0
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
Exemple #3
0
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)
Exemple #4
0
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))
Exemple #5
0
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))
Exemple #6
0
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))
Exemple #7
0
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))
Exemple #8
0
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))
Exemple #9
0
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)
Exemple #10
0
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