From 3d39b88e7cae058bdc102fa8c100324df0a541be Mon Sep 17 00:00:00 2001 From: scmmishra Date: Wed, 27 Mar 2019 18:01:14 +0530 Subject: [PATCH] feat: LMS now supports multiple correct choice questions --- erpnext/education/doctype/quiz/quiz.py | 19 +++++++++++++++---- .../doctype/quiz_result/quiz_result.json | 11 +++++++---- erpnext/education/doctype/topic/topic.py | 1 + .../js/education/lms/components/Quiz.vue | 13 +------------ .../components/Quiz/QuizMultipleChoice.vue | 10 ++++++++-- erpnext/www/lms.py | 9 +++++---- 6 files changed, 37 insertions(+), 26 deletions(-) diff --git a/erpnext/education/doctype/quiz/quiz.py b/erpnext/education/doctype/quiz/quiz.py index 4bd7cad453b..e35a4ef96aa 100644 --- a/erpnext/education/doctype/quiz/quiz.py +++ b/erpnext/education/doctype/quiz/quiz.py @@ -9,7 +9,6 @@ from frappe.model.document import Document class Quiz(Document): def validate_quiz_attempts(self, enrollment, quiz_name): - print(enrollment, quiz_name) if self.max_attempts > 0: try: if len(frappe.get_all("Quiz Activity", {'enrollment': enrollment.name, 'quiz': quiz_name})) >= self.max_attempts: @@ -20,12 +19,15 @@ class Quiz(Document): def evaluate(self, response_dict, quiz_name): # self.validate_quiz_attempts(enrollment, quiz_name) - self.get_questions() - answers = {q.name:q.get_answer() for q in self.get_questions()} + questions = [frappe.get_doc('Question', question.question_link) for question in self.question] + answers = {q.name:q.get_answer() for q in questions} correct_answers = {} for key in answers: try: - result = (response_dict[key] == answers[key]) + if isinstance(response_dict[key], list): + result = compare_list_elementwise(response_dict[key], answers[key]) + else: + result = (response_dict[key] == answers[key]) except: result = False correct_answers[key] = result @@ -51,3 +53,12 @@ class Quiz(Document): else: return None +def compare_list_elementwise(*args): + try: + if all(len(args[0]) == len(_arg) for _arg in args[1:]): + return all(all([element in (item) for element in args[0]]) for item in args[1:]) + else: + return False + except TypeError: + frappe.throw("Compare List function takes on list arguments") + diff --git a/erpnext/education/doctype/quiz_result/quiz_result.json b/erpnext/education/doctype/quiz_result/quiz_result.json index db00c9896b7..86505ac756a 100644 --- a/erpnext/education/doctype/quiz_result/quiz_result.json +++ b/erpnext/education/doctype/quiz_result/quiz_result.json @@ -20,6 +20,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "question", "fieldtype": "Link", "hidden": 0, @@ -37,7 +38,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, @@ -53,6 +54,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "selected_option", "fieldtype": "Data", "hidden": 0, @@ -70,7 +72,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, @@ -86,6 +88,7 @@ "bold": 0, "collapsible": 0, "columns": 0, + "fetch_if_empty": 0, "fieldname": "quiz_result", "fieldtype": "Select", "hidden": 0, @@ -103,7 +106,7 @@ "precision": "", "print_hide": 0, "print_hide_if_no_value": 0, - "read_only": 0, + "read_only": 1, "remember_last_selected_value": 0, "report_hide": 0, "reqd": 1, @@ -123,7 +126,7 @@ "issingle": 0, "istable": 1, "max_attachments": 0, - "modified": "2018-10-24 11:57:01.876188", + "modified": "2019-03-27 17:58:54.388848", "modified_by": "Administrator", "module": "Education", "name": "Quiz Result", diff --git a/erpnext/education/doctype/topic/topic.py b/erpnext/education/doctype/topic/topic.py index b890935e3ef..339fc7d8871 100644 --- a/erpnext/education/doctype/topic/topic.py +++ b/erpnext/education/doctype/topic/topic.py @@ -12,5 +12,6 @@ class Topic(Document): topic_content_list = self.get_all_children() content_data = [frappe.get_doc(topic_content.content_type, topic_content.content) for topic_content in topic_content_list] except Exception as e: + frappe.log_error(frappe.get_traceback()) return None return content_data \ No newline at end of file diff --git a/erpnext/public/js/education/lms/components/Quiz.vue b/erpnext/public/js/education/lms/components/Quiz.vue index afb61860f5e..c0d6537a0d7 100644 --- a/erpnext/public/js/education/lms/components/Quiz.vue +++ b/erpnext/public/js/education/lms/components/Quiz.vue @@ -71,18 +71,7 @@ export default { ) }, updateResponse(res) { - if (res.type == 'SingleChoice') { - this.quizResponse[res.question] = (res.option) - } - if (res.type == 'MultipleChoice') { - if (!this.quizResponse[res.question]) { - this.quizResponse[res.question] = [res.option] - } - else { - this.quizResponse[res.question].push(res.option) - } - } - console.log(this.quizResponse) + this.quizResponse[res.question] = res.option }, submitQuiz() { lms.call("evaluate_quiz", diff --git a/erpnext/public/js/education/lms/components/Quiz/QuizMultipleChoice.vue b/erpnext/public/js/education/lms/components/Quiz/QuizMultipleChoice.vue index e216a678d59..10c35f58c7a 100644 --- a/erpnext/public/js/education/lms/components/Quiz/QuizMultipleChoice.vue +++ b/erpnext/public/js/education/lms/components/Quiz/QuizMultipleChoice.vue @@ -3,7 +3,7 @@
{{ question.question }}
- + @@ -16,9 +16,15 @@ export default { props: ['question'], name: 'QuizSingleChoice', + data() { + return { + checked: [] + } + }, methods: { emitResponse(q, o) { - this.$emit('updateResponse', {'question':q , 'option': o, 'type': this.question.type}) + console.log(this.checked) + this.$emit('updateResponse', {'question':q , 'option': this.checked, 'type': this.question.type}) } } }; diff --git a/erpnext/www/lms.py b/erpnext/www/lms.py index c7b31ee09d8..12c742ffb15 100644 --- a/erpnext/www/lms.py +++ b/erpnext/www/lms.py @@ -119,7 +119,10 @@ def evaluate_quiz(course, quiz_response, quiz_name): item['question'] = key item['quiz_result'] = result[key] try: - item['selected_option'] = frappe.get_value('Options', quiz_response[key], 'option') + if isinstance(quiz_response[key], list): + item['selected_option'] = ', '.join(frappe.get_value('Options', res, 'option') for res in quiz_response[key]) + else: + item['selected_option'] = frappe.get_value('Options', quiz_response[key], 'option') except: item['selected_option'] = "Unattempted" result_data.append(item) @@ -139,9 +142,7 @@ def add_quiz_activity(course, quiz_name, result_data, score, status): "result": result_data, "score": score, "status": status - }) - quiz_activity.save() - frappe.db.commit() + }).insert() @frappe.whitelist() def enroll_in_program(program_name):