ENCOA-276, ENCOA-277
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user