Skip to content
Snippets Groups Projects
Commit f08b1728 authored by yazSpaz's avatar yazSpaz
Browse files

fixed 0 score showing for new attempts

parent 773f074d
No related branches found
No related tags found
No related merge requests found
...@@ -317,7 +317,6 @@ def getTestDetails(): ...@@ -317,7 +317,6 @@ def getTestDetails():
student_attempts_map[student_id] = attempt student_attempts_map[student_id] = attempt
filtered_attempts = list(student_attempts_map.values()) filtered_attempts = list(student_attempts_map.values())
print(filtered_attempts)
return jsonify({ return jsonify({
'mcq_questions': mcq_questions, 'mcq_questions': mcq_questions,
...@@ -336,47 +335,59 @@ def getStudentQuestions(): ...@@ -336,47 +335,59 @@ def getStudentQuestions():
# Retrieve the question attempts for this test attempt # Retrieve the question attempts for this test attempt
question_attempts = TestAttempt.getQuestionAttempts(test_attempt_id, db) question_attempts = TestAttempt.getQuestionAttempts(test_attempt_id, db)
# Retrieve the correct answers and questions from the database for MCQ and FIB questions # Retrieve all test questions with their details in one unified query
mcq_data = TestDAO.getMCQQuestionsByTest(test_id, db) # List of MCQ questions test_questions_stmt = text("""
fib_data = TestDAO.getFIBQuestionsByTest(test_id, db) # List of FIB questions SELECT tq.question_id, tq.question_type,
mcq.question AS mcq_question, mcq.answer AS mcq_answer,
fib.question AS fib_question, fib.answer AS fib_answer
FROM test_questions tq
LEFT JOIN MCQ mcq ON tq.question_type = 'MCQ' AND tq.question_id = mcq.id
LEFT JOIN FIB fib ON tq.question_type = 'FIB' AND tq.question_id = fib.id
WHERE tq.test_id = :test_id
""")
# Ensure we get a dictionary mapping question IDs to answers and questions question_rows = db.session.execute(test_questions_stmt, {"test_id": test_id}).fetchall()
mcq_questions = {mcq["id"]: {"answer": mcq["answer"], "question": mcq["question"], "id": mcq["id"]} for mcq in mcq_data} if isinstance(mcq_data, list) else {}
fib_questions = {fib["id"]: {"answer": fib["answer"], "question": fib["question"], "id": fib["id"]} for fib in fib_data} if isinstance(fib_data, list) else {} # Map questions by (type, id)
question_lookup = {}
for row in question_rows:
q_id = row[0]
q_type = row[1]
question = row[2] if q_type == "MCQ" else row[4]
answer = row[3] if q_type == "MCQ" else row[5]
question_lookup[(q_type, q_id)] = {
"question": question,
"answer": answer,
"id": q_id,
"type": q_type
}
# Convert objects to dictionaries manually before returning # Build response
serialized_attempts = [] serialized_attempts = []
for attempt in question_attempts: for attempt in question_attempts:
correct_answer = None
student_answer = None
question_type = None
original_question_id = None # This will hold the original question ID
question_text = None # This will hold the question content
# Check if the attempt corresponds to an MCQ question
if attempt.mcq_id: if attempt.mcq_id:
correct_answer = mcq_questions.get(attempt.mcq_id, {}).get("answer") key = ("MCQ", attempt.mcq_id)
question_text = mcq_questions.get(attempt.mcq_id, {}).get("question")
question_type = "mcq"
original_question_id = mcq_questions.get(attempt.mcq_id, {}).get("id") # Ensure the correct ID is used from mcq_questions
# Check if the attempt corresponds to a FIB question
elif attempt.fib_id: elif attempt.fib_id:
correct_answer = fib_questions.get(attempt.fib_id, {}).get("answer") key = ("FIB", attempt.fib_id)
question_text = fib_questions.get(attempt.fib_id, {}).get("question") else:
question_type = "fib" continue # Skip if no valid question ID
original_question_id = fib_questions.get(attempt.fib_id, {}).get("id") # Ensure the correct ID is used from fib_questions
question_data = question_lookup.get(key, {})
serialized_attempts.append({ serialized_attempts.append({
"id": original_question_id, # Use the original question ID (from MCQ or FIB) "id": question_data.get("id"),
"test_attempt_id": attempt.test_attempt_id, "test_attempt_id": attempt.test_attempt_id,
"correct_answer": correct_answer, "correct_answer": question_data.get("answer"),
"student_answer": attempt.student_answer, "student_answer": attempt.student_answer,
"question_type": question_type, # Add question type "question_type": question_data.get("type", "").lower(),
"question": question_text # Add question text "question": question_data.get("question")
}) })
return jsonify({"question_attempts": serialized_attempts}) return jsonify({"question_attempts": serialized_attempts})
@routes_bp.route('/createTests', methods=['GET', 'POST']) @routes_bp.route('/createTests', methods=['GET', 'POST'])
def createTests(): def createTests():
tests = TestORM.query.all() tests = TestORM.query.all()
...@@ -1116,8 +1127,8 @@ def attemptTest(): ...@@ -1116,8 +1127,8 @@ def attemptTest():
def attemptFormative(id): def attemptFormative(id):
student_id = session["user_id"] student_id = session["user_id"]
test_id = id test_id = id
if request.method == 'POST': if request.method == 'POST':
# answer sent from front end
answers = request.form.to_dict(flat=True) answers = request.form.to_dict(flat=True)
result = { result = {
...@@ -1142,7 +1153,7 @@ def attemptFormative(id): ...@@ -1142,7 +1153,7 @@ def attemptFormative(id):
'C': row.option_c, 'C': row.option_c,
'D': row.option_d 'D': row.option_d
} }
# keep original option letter
user_letter = user_answer.strip().upper() user_letter = user_answer.strip().upper()
user_option_value = options_map.get(user_letter, '') user_option_value = options_map.get(user_letter, '')
is_correct = user_letter == row.answer.strip().upper() is_correct = user_letter == row.answer.strip().upper()
...@@ -1150,10 +1161,10 @@ def attemptFormative(id): ...@@ -1150,10 +1161,10 @@ def attemptFormative(id):
result["mcq"].append({ result["mcq"].append({
"question_id": qid, "question_id": qid,
"your_answer": user_option_value, "your_answer": user_option_value,
"your_answer_letter": user_letter, # save the option letter "your_answer_letter": user_letter,
"answer": options_map.get(row.answer.strip().upper(), ''), "answer": options_map.get(row.answer.strip().upper(), ''),
"is_correct": is_correct, "is_correct": is_correct,
"feedback": row.feedback if row.feedback != '' else '' "feedback": row.feedback if row.feedback else ''
}) })
total_questions += 1 total_questions += 1
...@@ -1170,7 +1181,7 @@ def attemptFormative(id): ...@@ -1170,7 +1181,7 @@ def attemptFormative(id):
"your_answer": user_answer, "your_answer": user_answer,
"answer": row.answer, "answer": row.answer,
"is_correct": is_correct, "is_correct": is_correct,
"feedback": row.feedback if row.feedback != '' else '' "feedback": row.feedback if row.feedback else ''
}) })
total_questions += 1 total_questions += 1
...@@ -1180,43 +1191,67 @@ def attemptFormative(id): ...@@ -1180,43 +1191,67 @@ def attemptFormative(id):
# Calculate score # Calculate score
score = round((correct_answers / total_questions) * 100, 2) if total_questions > 0 else 0.0 score = round((correct_answers / total_questions) * 100, 2) if total_questions > 0 else 0.0
# Save to TestAttempt # Create test_attempt record
new_attempt = TestAttempt( new_attempt = TestAttempt(
student_id=student_id, student_id=student_id,
test_id=test_id, test_id=test_id,
score=score, score=score,
time_taken=0 # Set time_taken to 0, you can modify this if needed time_taken=0
) )
new_attempt.attempt_date = datetime.now() new_attempt.attempt_date = datetime.now()
db.session.add(new_attempt) db.session.add(new_attempt)
db.session.commit() db.session.commit() # Commit to generate ID for test_attempt
# Get the latest TestAttempt (top 1 by id descending) for key, user_answer in answers.items():
latest_attempt = TestAttempt.query.filter_by(student_id=student_id, test_id=test_id).order_by(TestAttempt.id.desc()).first() if '_' in key:
qtype, qid = key.split('_')
qid = int(qid)
# Insert QuestionAttempt records if qtype == 'mcq':
for mcq_data in result["mcq"]: row = MCQ.query.get(qid)
qa = QuestionAttempt( if row:
test_attempt_id=latest_attempt.id, options_map = {
student_answer=mcq_data["your_answer_letter"], # Store the original option letter (A/B/C/D) 'A': row.option_a,
mcq_id=mcq_data["question_id"] 'B': row.option_b,
) 'C': row.option_c,
db.session.add(qa) 'D': row.option_d
}
user_letter = user_answer.strip().upper()
user_option_value = options_map.get(user_letter, '')
is_correct = user_letter == row.answer.strip().upper()
attempt = QuestionAttempt(
test_attempt_id=new_attempt.id,
mcq_id=qid,
fib_id=None,
student_answer=mcq[user_letter]
)
db.session.add(attempt)
db.session.commit()
elif qtype == 'fib':
row = FIB.query.get(qid)
if row:
is_correct = user_answer.strip().lower() == row.answer.strip().lower()
attempt = QuestionAttempt(
test_attempt_id=new_attempt.id,
mcq_id=None,
fib_id=qid,
student_answer=user_answer
)
db.session.add(attempt)
db.session.commit()
for fib_data in result["fib"]:
qa = QuestionAttempt(
test_attempt_id=latest_attempt.id,
student_answer=fib_data["your_answer"],
fib_id=fib_data["question_id"]
)
db.session.add(qa)
db.session.commit()
# Save to session, redirect to feedback page
# Store feedback in session and redirect
session["formative_result"] = result session["formative_result"] = result
return redirect(url_for("routes.formative_answer")) return redirect(url_for("routes.formative_answer"))
# GET method: Render the test page # GET method: Render the test page
sql_test = text("SELECT * FROM tests WHERE id = :id") sql_test = text("SELECT * FROM tests WHERE id = :id")
test = db.engine.connect().execute(sql_test, {"id": id}).fetchone() test = db.engine.connect().execute(sql_test, {"id": id}).fetchone()
......
No preview for this file type
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment