ENCOA-276, ENCOA-277

This commit is contained in:
Carlos-Mesquita
2024-12-21 19:27:14 +00:00
parent 0262971b11
commit 09d6242360
25 changed files with 375 additions and 86 deletions

View File

@@ -8,7 +8,7 @@ from ielts_be.dtos.exams.listening import (
WriteBlanksExercise,
ListeningExam,
ListeningSection,
WriteBlanksVariant, WriteBlankSolution, WriteBlanksQuestionExercise, WriteBlankQuestion
WriteBlanksVariant, WriteBlankSolution, WriteBlanksQuestionExercise, WriteBlankQuestion, Dialog
)
class ListeningQuestionSection(BaseModel):
@@ -109,4 +109,74 @@ class ListeningMapper:
parts=final_parts,
minTimer=response.get('minTimer'),
module="listening"
)
)
@staticmethod
def validate_speaker(participant: Dict[str, str]) -> None:
required_fields = ["name", "gender", "text"]
for field in required_fields:
if field not in participant:
raise ValueError(f"Missing required field '{field}' in speaker")
if not isinstance(participant[field], str):
raise ValueError(f"Field '{field}' must be a string")
@classmethod
def validate_conversation(cls,conversation: List[Dict[str, str]]) -> None:
if not isinstance(conversation, list):
raise ValueError("Conversation must be a list")
if not conversation:
raise ValueError("Conversation cannot be empty")
for participant in conversation:
cls.validate_speaker(participant)
@staticmethod
def validate_monologue(monologue: str) -> None:
if not isinstance(monologue, str):
raise ValueError("Monologue must be a string")
if not monologue.strip():
raise ValueError("Monologue cannot be empty")
@staticmethod
def extract_section_number(section_key: str) -> str:
return ''.join([char for char in section_key if char.isdigit()])
@classmethod
def map_to_dialog_model(cls, response: Dict[str, Any]) -> Dict[str, Optional[Union[List[Dict[str, str]], str]]]:
if not isinstance(response, dict):
raise ValueError("Response must be a dictionary")
if "sections" not in response:
raise ValueError("Response must contain 'sections' key")
if not isinstance(response["sections"], list):
raise ValueError("Sections must be a list")
result = {}
for section in response["sections"]:
if not isinstance(section, dict) or len(section) != 1:
raise ValueError("Each section must be a dictionary with exactly one key")
section_key = next(iter(section))
section_number = cls.extract_section_number(section_key)
section_content = section[section_key]
if not isinstance(section_content, dict):
raise ValueError(f"Content for section {section_key} must be a dictionary")
if not section_content:
result[section_number] = None
continue
dialog_type = next(iter(section_content))
if dialog_type not in ["conversation", "monologue"]:
raise ValueError(f"Invalid dialog type '{dialog_type}' in section {section_key}")
if dialog_type == "conversation":
cls.validate_conversation(section_content["conversation"])
result[section_number] = section_content["conversation"]
else:
cls.validate_monologue(section_content["monologue"])
result[section_number] = section_content["monologue"]
return result