mirror of
https://github.com/frappe/lms.git
synced 2026-05-02 13:39:31 +03:00
Merge pull request #2131 from pateljannat/issues-195
fix: verify quiz answers on server side
This commit is contained in:
@@ -465,7 +465,7 @@ watch(
|
||||
)
|
||||
|
||||
const quizSubmission = createResource({
|
||||
url: 'lms.lms.doctype.lms_quiz.lms_quiz.quiz_summary',
|
||||
url: 'lms.lms.doctype.lms_quiz.lms_quiz.submit_quiz',
|
||||
makeParams(values) {
|
||||
return {
|
||||
quiz: quiz.data.name,
|
||||
@@ -538,7 +538,7 @@ const checkAnswer = () => {
|
||||
url: 'lms.lms.doctype.lms_quiz.lms_quiz.check_answer',
|
||||
params: {
|
||||
question: currentQuestion.value,
|
||||
type: questionDetails.data.type,
|
||||
question_type: questionDetails.data.type,
|
||||
answers: JSON.stringify(answers),
|
||||
},
|
||||
auto: true,
|
||||
@@ -569,10 +569,7 @@ const addToLocalStorage = () => {
|
||||
let quizData = JSON.parse(localStorage.getItem(quiz.data.title))
|
||||
let questionData = {
|
||||
question_name: currentQuestion.value,
|
||||
answer: getAnswers().join(),
|
||||
is_correct: showAnswers.filter((answer) => {
|
||||
return answer != undefined
|
||||
}),
|
||||
answer: getAnswers(),
|
||||
}
|
||||
|
||||
if (quizData) {
|
||||
|
||||
@@ -186,6 +186,7 @@ const upcoming_evals = createListResource({
|
||||
'evaluator_name',
|
||||
'course_title',
|
||||
'member',
|
||||
'member_name',
|
||||
'google_meet_link',
|
||||
],
|
||||
orderBy: 'date',
|
||||
|
||||
@@ -101,7 +101,7 @@ def set_total_marks(questions: list) -> int:
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def quiz_summary(quiz: str, results: str):
|
||||
def submit_quiz(quiz: str, results: str):
|
||||
results = results and json.loads(results)
|
||||
percentage = 0
|
||||
|
||||
@@ -128,14 +128,13 @@ def quiz_summary(quiz: str, results: str):
|
||||
score_out_of = quiz_details.total_marks
|
||||
percentage = (score / score_out_of) * 100 if score_out_of else 0
|
||||
submission = create_submission(quiz, results, score_out_of, quiz_details.passing_percentage)
|
||||
|
||||
save_progress_after_quiz(quiz_details, percentage)
|
||||
|
||||
return {
|
||||
"score": score,
|
||||
"score_out_of": score_out_of,
|
||||
"submission": submission.name,
|
||||
"pass": percentage == quiz_details.passing_percentage,
|
||||
"pass": percentage >= quiz_details.passing_percentage,
|
||||
"percentage": percentage,
|
||||
"is_open_ended": is_open_ended,
|
||||
}
|
||||
@@ -158,21 +157,14 @@ def process_results(results: list, quiz_details: dict):
|
||||
result["marks_out_of"] = question_details.marks
|
||||
|
||||
if question_details.type != "Open Ended":
|
||||
if len(result["is_correct"]) > 0:
|
||||
correct = result["is_correct"][0]
|
||||
for point in result["is_correct"]:
|
||||
correct = correct and point
|
||||
result["is_correct"] = correct
|
||||
else:
|
||||
result["is_correct"] = 0
|
||||
|
||||
correct = verify_answer(question_details.question, result["answer"])
|
||||
result["answer"] = ", ".join(result["answer"])
|
||||
if correct:
|
||||
marks = question_details.marks
|
||||
result["marks"] = question_details.marks
|
||||
else:
|
||||
marks = -quiz_details.marks_to_cut if quiz_details.enable_negative_marking else 0
|
||||
result["marks"] = -quiz_details.marks_to_cut if quiz_details.enable_negative_marking else 0
|
||||
|
||||
result["marks"] = marks
|
||||
score += marks
|
||||
score += result["marks"]
|
||||
|
||||
else:
|
||||
is_open_ended = True
|
||||
@@ -188,6 +180,26 @@ def process_results(results: list, quiz_details: dict):
|
||||
}
|
||||
|
||||
|
||||
def verify_answer(question: str, answer: list):
|
||||
question_details = get_question_details(question)
|
||||
correct = False
|
||||
|
||||
if question_details.multiple:
|
||||
for num in range(1, 5):
|
||||
if question_details[f"option_{num}"] in answer:
|
||||
correct = question_details[f"is_correct_{num}"]
|
||||
if not correct:
|
||||
return False
|
||||
if question_details[f"is_correct_{num}"] and question_details[f"option_{num}"] not in answer:
|
||||
return False
|
||||
return True
|
||||
|
||||
for num in range(1, 5):
|
||||
if question_details[f"option_{num}"] in answer:
|
||||
correct = question_details[f"is_correct_{num}"]
|
||||
return correct
|
||||
|
||||
|
||||
def _save_file(match: re.Match) -> str:
|
||||
data = match.group(1).split("data:")[1]
|
||||
headers, content = data.split(",")
|
||||
@@ -258,22 +270,27 @@ def save_progress_after_quiz(quiz_details: dict, percentage: float):
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def check_answer(question: str, type: str, answers: str):
|
||||
answers = json.loads(answers)
|
||||
if type == "Choices":
|
||||
def check_answer(question: str, question_type: str, answers: str):
|
||||
answers = answers and json.loads(answers)
|
||||
if question_type == "Choices":
|
||||
return check_choice_answers(question, answers)
|
||||
else:
|
||||
return check_input_answers(question, answers[0])
|
||||
|
||||
|
||||
def check_choice_answers(question: str, answers: list):
|
||||
def get_question_details(question: str):
|
||||
fields = ["multiple"]
|
||||
is_correct = []
|
||||
for num in range(1, 5):
|
||||
fields.append(f"option_{cstr(num)}")
|
||||
fields.append(f"is_correct_{cstr(num)}")
|
||||
|
||||
question_details = frappe.db.get_value("LMS Question", question, fields, as_dict=1)
|
||||
return question_details
|
||||
|
||||
|
||||
def check_choice_answers(question: str, answers: list):
|
||||
is_correct = []
|
||||
question_details = get_question_details(question)
|
||||
|
||||
for num in range(1, 5):
|
||||
if question_details[f"option_{num}"] in answers:
|
||||
|
||||
Reference in New Issue
Block a user