From 7f28b418b616823f542faea8311e881faf6286c2 Mon Sep 17 00:00:00 2001 From: adityacp Date: Tue, 26 Jan 2021 14:38:46 +0530 Subject: Refactor question statistics for a quiz --- yaksh/models.py | 65 +++++++------ yaksh/templates/yaksh/statistics_question.html | 123 ++++++++++--------------- yaksh/templatetags/custom_filters.py | 4 +- yaksh/test_views.py | 8 +- yaksh/views.py | 11 ++- 5 files changed, 99 insertions(+), 112 deletions(-) (limited to 'yaksh') diff --git a/yaksh/models.py b/yaksh/models.py index 3e3e2d1..bbb6900 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -2063,36 +2063,45 @@ class AnswerPaperManager(models.Manager): def get_question_statistics(self, questionpaper_id, attempt_number, course_id, status='completed'): ''' Return dict with question object as key and list as value - The list contains two value, first the number of times a question - was answered correctly, and second the number of times a question - appeared in a quiz''' + The list contains four values, first total attempts, second correct + attempts, third correct percentage, fourth per test case answers + a question + ''' question_stats = {} - questions_answered = self.get_all_questions_answered(questionpaper_id, - attempt_number, - course_id) - questions = self.get_all_questions(questionpaper_id, attempt_number, - course_id) - per_answer_stats = self.get_per_answer_stats( - questionpaper_id, attempt_number, course_id + qp = QuestionPaper.objects.get(id=questionpaper_id) + all_questions = qp.get_question_bank() + que_ids = [que.id for que in all_questions] + papers = self.filter( + question_paper_id=questionpaper_id, course_id=course_id, + attempt_number=attempt_number + ).values_list("id", flat=True) + answers = Answer.objects.filter( + answerpaper__id__in=papers, question_id__in=que_ids + ).order_by("id").values( + "answerpaper__id", "question_id", "correct", "answer" ) - all_questions = Question.objects.filter( - id__in=set(questions), - active=True - ).order_by('type') - for question in all_questions: - if question.id in questions_answered: - question_stats[question] = { - 'answered': [questions_answered[question.id], - questions[question.id]], - 'per_answer': per_answer_stats[question], - } - - else: - question_stats[question] = { - 'answered': [0, questions[question.id]], - 'per_answer': per_answer_stats[question], - } - + def _get_per_tc_data(answers, q_type): + tc = [] + for answer in answers["answer"]: + ans = literal_eval(answer) if answer else None + tc.extend(ans) if q_type == "mcc" else tc.append(str(ans)) + return dict(Counter(tc)) + df = pd.DataFrame(answers) + if not df.empty: + for question in all_questions: + que = df[df["question_id"]==question.id].groupby( + "answerpaper__id").tail(1) + if not que.empty: + total_attempts = que.shape[0] + correct_attempts = que[que["correct"]==True].shape[0] + per_tc_ans = {} + if question.type in ["mcq", "mcc"]: + per_tc_ans = _get_per_tc_data(que, question.type) + question_stats[question] = ( + total_attempts, correct_attempts, + round((correct_attempts/total_attempts)*100), + per_tc_ans + ) return question_stats def _get_answerpapers_for_quiz(self, questionpaper_id, course_id, diff --git a/yaksh/templates/yaksh/statistics_question.html b/yaksh/templates/yaksh/statistics_question.html index d70256b..588e131 100644 --- a/yaksh/templates/yaksh/statistics_question.html +++ b/yaksh/templates/yaksh/statistics_question.html @@ -18,10 +18,25 @@
Total number of participants: {{ total }}
Question | Type | Total | Answered Correctly | |||
---|---|---|---|---|---|---|
Question | +Type | +Total attempts | +Answered Correctly | +|||
@@ -40,7 +55,7 @@
Description:
- + {{ question.description|safe }} @@ -55,87 +70,49 @@{{ question.get_type_display }} - {% if question.type in 'mcq mcc' %} - - Options: - --
+
+
+
+
+
+ {% if percent %} {{percent|floatformat}} {% else %} 0 {% endif %}%
+
+
+
+ {% if percent %}
+
+
+ {% endif %}
+ {% endfor %} - |
- {{ question.type }} | -{{data.answered.1}} | {{ data.answered.0 }} ({% widthratio data.answered.0 data.answered.1 100 %}%) | - - +{{ question.get_type_display }} | +{{data.0}} out of {{total}} | +{{ data.1 }} out of {{data.0}} ({{data.2}}%) |