feat: LMS now supports multiple correct choice questions
diff --git a/erpnext/education/doctype/quiz/quiz.py b/erpnext/education/doctype/quiz/quiz.py
index 4bd7cad..e35a4ef 100644
--- a/erpnext/education/doctype/quiz/quiz.py
+++ b/erpnext/education/doctype/quiz/quiz.py
@@ -9,7 +9,6 @@
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 @@
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 @@
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 db00c98..86505ac 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 b890935..339fc7d 100644
--- a/erpnext/education/doctype/topic/topic.py
+++ b/erpnext/education/doctype/topic/topic.py
@@ -12,5 +12,6 @@
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 afb6186..c0d6537 100644
--- a/erpnext/public/js/education/lms/components/Quiz.vue
+++ b/erpnext/public/js/education/lms/components/Quiz.vue
@@ -71,18 +71,7 @@
)
},
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 e216a67..10c35f5 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 @@
<h5>{{ question.question }}</h5>
<div class="options ml-2">
<div v-for="option in question.options" :key="option.name" class="form-check pb-1">
- <input class="form-check-input" type="checkbox" :name="question.name" :id="option.name" :value="option.name" @change="emitResponse(question.name, option.name)">
+ <input v-model="checked" class="form-check-input" type="checkbox" :name="question.name" :id="option.name" :value="option.name" @change="emitResponse(question.name, option.name)">
<label class="form-check-label" :for="option.name">
{{ option.option }}
</label>
@@ -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 c7b31ee..12c742f 100644
--- a/erpnext/www/lms.py
+++ b/erpnext/www/lms.py
@@ -119,7 +119,10 @@
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 @@
"result": result_data,
"score": score,
"status": status
- })
- quiz_activity.save()
- frappe.db.commit()
+ }).insert()
@frappe.whitelist()
def enroll_in_program(program_name):