109 lines
4.2 KiB
Python
109 lines
4.2 KiB
Python
from repositories import UserAnswerRepository, QuizRepository, UserRepository
|
|
from schemas.requests import UserAnswerSchema
|
|
from models import UserAnswerEntity
|
|
from models.entities import AnswerItemEntity
|
|
from exception import ValidationException
|
|
|
|
|
|
class AnswerService:
|
|
def __init__(
|
|
self,
|
|
answer_repository: UserAnswerRepository,
|
|
quiz_repository: QuizRepository,
|
|
user_repositroy: UserRepository,
|
|
):
|
|
self.answer_repository = answer_repository
|
|
self.quiz_repository = quiz_repository
|
|
self.user_repositroy = user_repositroy
|
|
|
|
def get_answer_by_id(self, answer_id):
|
|
return self.answer_repository.get_answer_by_id(answer_id)
|
|
|
|
def get_answer(self, quiz_id, user_id, session_id):
|
|
if quiz_id is not None:
|
|
return self.answer_repository
|
|
|
|
def create_answer(self, answer_data: UserAnswerSchema):
|
|
quiz_data = self.quiz_repository.get_by_id(answer_data.quiz_id)
|
|
if not quiz_data:
|
|
raise ValidationException(message="Quiz not found")
|
|
user_data = self.user_repositroy.get_user_by_id(answer_data.user_id)
|
|
if not user_data:
|
|
raise ValidationException(message="user is not registered")
|
|
total_quiz_played = quiz_data.total_user_playing + 1
|
|
self.quiz_repository.update_user_playing(
|
|
quiz_id=quiz_data.id, total_user=total_quiz_played
|
|
)
|
|
|
|
question_map = {q.index: q for q in quiz_data.question_listings}
|
|
|
|
answer_item_Entity = []
|
|
total_correct = 0
|
|
for user_answer in answer_data.answers:
|
|
question = question_map.get(user_answer.question_index)
|
|
if question is None:
|
|
raise ValueError(
|
|
f"Question index {user_answer.question_index} tidak ditemukan di kuis."
|
|
)
|
|
|
|
correct = False
|
|
if question.type == "fill_the_blank":
|
|
correct = (
|
|
user_answer.answer.strip().lower()
|
|
== question.target_answer.strip().lower()
|
|
)
|
|
elif question.type == "true_false":
|
|
correct = user_answer.answer == question.target_answer
|
|
elif question.type == "option":
|
|
try:
|
|
answer_index = int(user_answer.answer)
|
|
if 0 <= answer_index < len(question.options):
|
|
correct = str(answer_index) == question.target_answer
|
|
else:
|
|
raise ValueError(
|
|
f"Index jawaban tidak valid untuk soal {question.index}"
|
|
)
|
|
except ValueError:
|
|
raise ValueError(
|
|
f"Jawaban bukan index valid untuk soal {question.index}"
|
|
)
|
|
else:
|
|
raise ValueError(f"Tipe soal tidak dikenali: {question.type}")
|
|
|
|
user_answer.is_correct = correct
|
|
if correct:
|
|
total_correct += 1
|
|
|
|
answer_item_Entity.append(
|
|
AnswerItemEntity(
|
|
question_index=user_answer.question_index,
|
|
answer=user_answer.answer,
|
|
is_correct=user_answer.is_correct,
|
|
time_spent=user_answer.time_spent,
|
|
)
|
|
)
|
|
total_questions = len(quiz_data.question_listings)
|
|
total_score = (
|
|
total_correct * 100 // total_questions
|
|
) # contoh perhitungan: nilai 100 dibagi rata
|
|
|
|
# Buat entitas yang akan disimpan
|
|
answer_entity = UserAnswerEntity(
|
|
session_id=answer_data.session_id,
|
|
quiz_id=answer_data.quiz_id,
|
|
user_id=answer_data.user_id,
|
|
answered_at=answer_data.answered_at,
|
|
answers=answer_item_Entity,
|
|
total_correct=total_correct,
|
|
total_questions=total_questions,
|
|
total_score=total_score,
|
|
)
|
|
|
|
return self.answer_repository.create(answer_entity)
|
|
|
|
def update_answer(self, answer_id, answer_data):
|
|
return self.answer_repository.update(answer_id, answer_data)
|
|
|
|
def delete_answer(self, answer_id):
|
|
return self.answer_repository.delete_by_id(answer_id)
|