feat: quiz validations and marks
This commit is contained in:
@@ -32,11 +32,11 @@
|
||||
"column_break_lknb",
|
||||
"explanation_4",
|
||||
"section_break_hkfe",
|
||||
"possible_answer_1",
|
||||
"possible_answer_3",
|
||||
"possibility_1",
|
||||
"possibility_3",
|
||||
"column_break_wpjr",
|
||||
"possible_answer_2",
|
||||
"possible_answer_4"
|
||||
"possibility_2",
|
||||
"possibility_4"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -167,34 +167,34 @@
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "possible_answer_1",
|
||||
"fieldname": "column_break_wpjr",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "possibility_1",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 1",
|
||||
"mandatory_depends_on": "eval: doc.type == 'User Input'"
|
||||
},
|
||||
{
|
||||
"fieldname": "possible_answer_3",
|
||||
"fieldname": "possibility_3",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 3"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_wpjr",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "possible_answer_2",
|
||||
"fieldname": "possibility_2",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 2"
|
||||
},
|
||||
{
|
||||
"fieldname": "possible_answer_4",
|
||||
"fieldname": "possibility_4",
|
||||
"fieldtype": "Small Text",
|
||||
"label": "Possible Answer 4"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2023-10-10 16:03:38.776125",
|
||||
"modified": "2023-10-16 11:39:39.757008",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Question",
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
"column_break_gaac",
|
||||
"max_attempts",
|
||||
"show_submission_history",
|
||||
"section_break_hsiv",
|
||||
"passing_percentage",
|
||||
"column_break_rocd",
|
||||
"total_marks",
|
||||
"section_break_sbjx",
|
||||
"questions",
|
||||
"section_break_3",
|
||||
@@ -90,11 +94,30 @@
|
||||
"fieldname": "show_submission_history",
|
||||
"fieldtype": "Check",
|
||||
"label": "Show Submission History"
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_hsiv",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "passing_percentage",
|
||||
"fieldtype": "Int",
|
||||
"label": "Passing Percentage"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_rocd",
|
||||
"fieldtype": "Column Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "total_marks",
|
||||
"fieldtype": "Int",
|
||||
"label": "Total Marks",
|
||||
"read_only": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2023-07-04 15:26:24.457745",
|
||||
"modified": "2023-10-16 17:21:33.932981",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Quiz",
|
||||
|
||||
@@ -5,7 +5,7 @@ import json
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cstr
|
||||
from frappe.utils import cstr, comma_and
|
||||
from lms.lms.doctype.lms_question.lms_question import validate_correct_answers
|
||||
from lms.lms.utils import (
|
||||
generate_slug,
|
||||
@@ -15,6 +15,17 @@ from lms.lms.utils import (
|
||||
|
||||
|
||||
class LMSQuiz(Document):
|
||||
def validate(self):
|
||||
self.validate_duplicate_questions()
|
||||
|
||||
def validate_duplicate_questions(self):
|
||||
questions = [row.question for row in self.questions]
|
||||
rows = [i + 1 for i, x in enumerate(questions) if questions.count(x) > 1]
|
||||
if len(rows):
|
||||
frappe.throw(
|
||||
_("Rows {0} have the duplicate questions.").format(frappe.bold(comma_and(rows)))
|
||||
)
|
||||
|
||||
def autoname(self):
|
||||
if not self.name:
|
||||
self.name = generate_slug(self.title, "LMS Quiz")
|
||||
@@ -44,11 +55,13 @@ def quiz_summary(quiz, results):
|
||||
|
||||
for result in results:
|
||||
correct = result["is_correct"][0]
|
||||
result["question"] = frappe.db.get_value(
|
||||
question_name = frappe.db.get_value(
|
||||
"LMS Quiz Question",
|
||||
{"parent": quiz, "idx": result["question_index"] + 1},
|
||||
["question"],
|
||||
)
|
||||
result["question_name"] = question_name
|
||||
result["question"] = frappe.db.get_value("LMS Question", question_name, "question")
|
||||
|
||||
for point in result["is_correct"]:
|
||||
correct = correct and point
|
||||
@@ -184,9 +197,7 @@ def check_choice_answers(question, answers):
|
||||
fields.append(f"option_{cstr(num)}")
|
||||
fields.append(f"is_correct_{cstr(num)}")
|
||||
|
||||
question_details = frappe.db.get_value(
|
||||
"LMS Quiz Question", question, fields, as_dict=1
|
||||
)
|
||||
question_details = frappe.db.get_value("LMS Question", question, fields, as_dict=1)
|
||||
|
||||
for num in range(1, 5):
|
||||
if question_details[f"option_{num}"] in answers:
|
||||
|
||||
@@ -5,22 +5,34 @@
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"question"
|
||||
"question",
|
||||
"marks"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "question",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"in_preview": 1,
|
||||
"label": "Question",
|
||||
"options": "LMS Question",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"default": "1",
|
||||
"fieldname": "marks",
|
||||
"fieldtype": "Int",
|
||||
"in_list_view": 1,
|
||||
"in_preview": 1,
|
||||
"label": "Marks",
|
||||
"non_negative": 1,
|
||||
"reqd": 1
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2023-10-10 15:42:51.791902",
|
||||
"modified": "2023-10-16 19:51:03.893143",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Quiz Question",
|
||||
|
||||
@@ -6,8 +6,11 @@
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"question",
|
||||
"answer",
|
||||
"is_correct"
|
||||
"section_break_fztv",
|
||||
"question_name",
|
||||
"is_correct",
|
||||
"column_break_flus",
|
||||
"answer"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
@@ -31,12 +34,26 @@
|
||||
"in_list_view": 1,
|
||||
"label": "Is Correct",
|
||||
"read_only": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "section_break_fztv",
|
||||
"fieldtype": "Section Break"
|
||||
},
|
||||
{
|
||||
"fieldname": "question_name",
|
||||
"fieldtype": "Link",
|
||||
"label": "Question Name",
|
||||
"options": "LMS Question"
|
||||
},
|
||||
{
|
||||
"fieldname": "column_break_flus",
|
||||
"fieldtype": "Column Break"
|
||||
}
|
||||
],
|
||||
"index_web_pages_for_search": 1,
|
||||
"istable": 1,
|
||||
"links": [],
|
||||
"modified": "2022-11-24 11:15:45.931119",
|
||||
"modified": "2023-10-16 15:25:03.380843",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Quiz Result",
|
||||
|
||||
@@ -73,4 +73,5 @@ lms.patches.v1_0.change_naming_for_batch_course #14-09-2023
|
||||
execute:frappe.permissions.reset_perms("LMS Enrollment")
|
||||
lms.patches.v1_0.create_student_role
|
||||
lms.patches.v1_0.mark_confirmation_for_batch_students
|
||||
lms.patches.v1_0.create_quiz_questions
|
||||
lms.patches.v1_0.create_quiz_questions
|
||||
lms.patches.v1_0.add_default_marks #16-10-2023
|
||||
16
lms/patches/v1_0/add_default_marks.py
Normal file
16
lms/patches/v1_0/add_default_marks.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
questions = frappe.get_all("LMS Quiz Question", pluck="name")
|
||||
|
||||
for question in questions:
|
||||
frappe.db.set_value("LMS Quiz Question", question, "marks", 1)
|
||||
|
||||
quizzes = frappe.get_all("LMS Quiz", pluck="name")
|
||||
|
||||
for quiz in quizzes:
|
||||
questions_count = frappe.db.count("LMS Quiz Question", {"parent": quiz})
|
||||
frappe.db.set_value(
|
||||
"LMS Quiz", quiz, {"total_marks": questions_count, "passing_percentage": 100}
|
||||
)
|
||||
@@ -3,31 +3,21 @@ import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc("lms", "doctype", "lms_question")
|
||||
frappe.reload_doc("lms", "doctype", "lms_quiz_question")
|
||||
|
||||
fields = ["name", "question", "type", "multiple"]
|
||||
for num in range(1, 5):
|
||||
fields.append(f"option_{num}")
|
||||
fields.append(f"is_correct_{num}")
|
||||
fields.append(f"explanation_{num}")
|
||||
fields.append(f"possibility_{num}")
|
||||
|
||||
questions = frappe.get_all(
|
||||
"LMS Quiz Question",
|
||||
fields=[
|
||||
"name",
|
||||
"question",
|
||||
"type",
|
||||
"multiple",
|
||||
"option_1",
|
||||
"is_correct_1",
|
||||
"explanation_1",
|
||||
"option_2",
|
||||
"is_correct_2",
|
||||
"explanation_2",
|
||||
"option_3",
|
||||
"is_correct_3",
|
||||
"explanation_3",
|
||||
"option_4",
|
||||
"is_correct_4",
|
||||
"explanation_4",
|
||||
],
|
||||
fields=fields,
|
||||
)
|
||||
|
||||
for question in questions:
|
||||
print(question.name)
|
||||
doc = frappe.new_doc("LMS Question")
|
||||
doc.update(
|
||||
{
|
||||
@@ -44,9 +34,10 @@ def execute():
|
||||
f"option_{num}": question[f"option_{num}"],
|
||||
f"is_correct_{num}": question[f"is_correct_{num}"],
|
||||
f"explanation_{num}": question[f"explanation_{num}"],
|
||||
f"possibility_{num}": question[f"possibility_{num}"],
|
||||
}
|
||||
)
|
||||
|
||||
doc.save()
|
||||
|
||||
print(doc.name)
|
||||
frappe.db.set_value("LMS Quiz Question", question.name, "question", doc.name)
|
||||
|
||||
@@ -109,7 +109,28 @@ def quiz_renderer(quiz_name):
|
||||
)
|
||||
+"</div>"
|
||||
|
||||
quiz = frappe.get_doc("LMS Quiz", quiz_name)
|
||||
quiz = frappe.db.get_value(
|
||||
"LMS Quiz",
|
||||
quiz_name,
|
||||
["name", "title", "max_attempts", "show_answers", "show_submission_history"],
|
||||
as_dict=True,
|
||||
)
|
||||
quiz.questions = []
|
||||
fields = ["name", "question", "type", "multiple"]
|
||||
for num in range(1, 5):
|
||||
fields.append(f"option_{num}")
|
||||
fields.append(f"is_correct_{num}")
|
||||
fields.append(f"explanation_{num}")
|
||||
fields.append(f"possibility_{num}")
|
||||
|
||||
questions = frappe.get_all(
|
||||
"LMS Quiz Question", {"parent": quiz.name}, pluck="question", order_by="idx"
|
||||
)
|
||||
|
||||
for question in questions:
|
||||
details = frappe.db.get_value("LMS Question", question, fields, as_dict=1)
|
||||
quiz.questions.append(details)
|
||||
|
||||
no_of_attempts = frappe.db.count(
|
||||
"LMS Quiz Submission", {"owner": frappe.session.user, "quiz": quiz_name}
|
||||
)
|
||||
|
||||
@@ -51,7 +51,8 @@
|
||||
data-multi="{{ question.multiple }}" data-qt-index="{{ loop.index }}">
|
||||
<div>
|
||||
<div class="question-number">
|
||||
{{ _("Question ") }}{{ loop.index }}: {{ instruction }}</div>
|
||||
{{ _("Question ") }}{{ loop.index }}: {{ instruction }}
|
||||
</div>
|
||||
<div class="question-text">
|
||||
{{ question.question }}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user