TIF_E41211115_Genso_quiz_ba.../app/services/answer_service.py

152 lines
5.6 KiB
Python

from app.repositories import UserAnswerRepository, QuizRepository, UserRepository
from app.schemas.requests import UserAnswerSchema
from app.schemas.response import AnsweredQuizResponse
from app.models import UserAnswerEntity
from app.models.entities import AnswerItemEntity
from app.exception import ValidationException
from app.helpers import DatetimeUtil
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":
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}"
)
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)
def get_answer_session(self, session_id: str, user_id: str) -> AnsweredQuizResponse:
answer_data: UserAnswerEntity = (
self.answer_repository.get_by_userid_and_sessionid(
session_id=session_id,
user_id=user_id,
)
)
if not answer_data:
return None
quiz = self.quiz_repository.get_by_id(answer_data.quiz_id)
question_listings = quiz.question_listings # List[QuestionItemEntity]
# Mapping question_index ke QuestionItemEntity
question_map = {q.index: q for q in question_listings}
answers_data = []
for ans in answer_data.answers:
question_entity = question_map.get(ans.question_index)
question_fields = question_entity.dict() if question_entity else {}
answers_data.append(
{
**question_fields, # Langsung unpack semua field QuestionItemEntity ke dalam dictionary
"answer": ans.answer,
"is_correct": ans.is_correct,
"time_spent": ans.time_spent,
}
)
data = AnsweredQuizResponse(
id=str(answer_data.id),
session_id=answer_data.session_id,
quiz_id=answer_data.quiz_id,
user_id=answer_data.user_id,
answered_at=DatetimeUtil.to_string(answer_data.answered_at),
answers=answers_data,
total_score=answer_data.total_score,
total_correct=answer_data.total_correct,
)
return data