feat: LMS now supports multiple correct choice questions

This commit is contained in:
scmmishra
2019-03-27 18:01:14 +05:30
parent 43e9375642
commit 3d39b88e7c
6 changed files with 37 additions and 26 deletions

View File

@@ -9,7 +9,6 @@ from frappe.model.document import Document
class Quiz(Document): class Quiz(Document):
def validate_quiz_attempts(self, enrollment, quiz_name): def validate_quiz_attempts(self, enrollment, quiz_name):
print(enrollment, quiz_name)
if self.max_attempts > 0: if self.max_attempts > 0:
try: try:
if len(frappe.get_all("Quiz Activity", {'enrollment': enrollment.name, 'quiz': quiz_name})) >= self.max_attempts: if len(frappe.get_all("Quiz Activity", {'enrollment': enrollment.name, 'quiz': quiz_name})) >= self.max_attempts:
@@ -20,11 +19,14 @@ class Quiz(Document):
def evaluate(self, response_dict, quiz_name): def evaluate(self, response_dict, quiz_name):
# self.validate_quiz_attempts(enrollment, quiz_name) # self.validate_quiz_attempts(enrollment, quiz_name)
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 self.get_questions()} answers = {q.name:q.get_answer() for q in questions}
correct_answers = {} correct_answers = {}
for key in answers: for key in answers:
try: try:
if isinstance(response_dict[key], list):
result = compare_list_elementwise(response_dict[key], answers[key])
else:
result = (response_dict[key] == answers[key]) result = (response_dict[key] == answers[key])
except: except:
result = False result = False
@@ -51,3 +53,12 @@ class Quiz(Document):
else: else:
return None 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")

View File

@@ -20,6 +20,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "question", "fieldname": "question",
"fieldtype": "Link", "fieldtype": "Link",
"hidden": 0, "hidden": 0,
@@ -37,7 +38,7 @@
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 0, "read_only": 1,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 1, "reqd": 1,
@@ -53,6 +54,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "selected_option", "fieldname": "selected_option",
"fieldtype": "Data", "fieldtype": "Data",
"hidden": 0, "hidden": 0,
@@ -70,7 +72,7 @@
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 0, "read_only": 1,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 1, "reqd": 1,
@@ -86,6 +88,7 @@
"bold": 0, "bold": 0,
"collapsible": 0, "collapsible": 0,
"columns": 0, "columns": 0,
"fetch_if_empty": 0,
"fieldname": "quiz_result", "fieldname": "quiz_result",
"fieldtype": "Select", "fieldtype": "Select",
"hidden": 0, "hidden": 0,
@@ -103,7 +106,7 @@
"precision": "", "precision": "",
"print_hide": 0, "print_hide": 0,
"print_hide_if_no_value": 0, "print_hide_if_no_value": 0,
"read_only": 0, "read_only": 1,
"remember_last_selected_value": 0, "remember_last_selected_value": 0,
"report_hide": 0, "report_hide": 0,
"reqd": 1, "reqd": 1,
@@ -123,7 +126,7 @@
"issingle": 0, "issingle": 0,
"istable": 1, "istable": 1,
"max_attachments": 0, "max_attachments": 0,
"modified": "2018-10-24 11:57:01.876188", "modified": "2019-03-27 17:58:54.388848",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Education", "module": "Education",
"name": "Quiz Result", "name": "Quiz Result",

View File

@@ -12,5 +12,6 @@ class Topic(Document):
topic_content_list = self.get_all_children() 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] content_data = [frappe.get_doc(topic_content.content_type, topic_content.content) for topic_content in topic_content_list]
except Exception as e: except Exception as e:
frappe.log_error(frappe.get_traceback())
return None return None
return content_data return content_data

View File

@@ -71,18 +71,7 @@ export default {
) )
}, },
updateResponse(res) { updateResponse(res) {
if (res.type == 'SingleChoice') { this.quizResponse[res.question] = res.option
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)
}, },
submitQuiz() { submitQuiz() {
lms.call("evaluate_quiz", lms.call("evaluate_quiz",

View File

@@ -3,7 +3,7 @@
<h5>{{ question.question }}</h5> <h5>{{ question.question }}</h5>
<div class="options ml-2"> <div class="options ml-2">
<div v-for="option in question.options" :key="option.name" class="form-check pb-1"> <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"> <label class="form-check-label" :for="option.name">
{{ option.option }} {{ option.option }}
</label> </label>
@@ -16,9 +16,15 @@
export default { export default {
props: ['question'], props: ['question'],
name: 'QuizSingleChoice', name: 'QuizSingleChoice',
data() {
return {
checked: []
}
},
methods: { methods: {
emitResponse(q, o) { 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})
} }
} }
}; };

View File

@@ -119,6 +119,9 @@ def evaluate_quiz(course, quiz_response, quiz_name):
item['question'] = key item['question'] = key
item['quiz_result'] = result[key] item['quiz_result'] = result[key]
try: try:
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') item['selected_option'] = frappe.get_value('Options', quiz_response[key], 'option')
except: except:
item['selected_option'] = "Unattempted" item['selected_option'] = "Unattempted"
@@ -139,9 +142,7 @@ def add_quiz_activity(course, quiz_name, result_data, score, status):
"result": result_data, "result": result_data,
"score": score, "score": score,
"status": status "status": status
}) }).insert()
quiz_activity.save()
frappe.db.commit()
@frappe.whitelist() @frappe.whitelist()
def enroll_in_program(program_name): def enroll_in_program(program_name):