Merged in release/async (pull request #53)
ENCOA-312 Approved-by: Tiago Ribeiro
This commit is contained in:
@@ -2,10 +2,12 @@ from .file import FileHelper
|
||||
from .text import TextHelper
|
||||
from .token_counter import count_tokens
|
||||
from .exercises import ExercisesHelper
|
||||
from .difficulty import DifficultyHelper
|
||||
|
||||
__all__ = [
|
||||
"FileHelper",
|
||||
"TextHelper",
|
||||
"count_tokens",
|
||||
"ExercisesHelper",
|
||||
"DifficultyHelper"
|
||||
]
|
||||
|
||||
40
ielts_be/helpers/difficulty.py
Normal file
40
ielts_be/helpers/difficulty.py
Normal file
@@ -0,0 +1,40 @@
|
||||
import math
|
||||
import random
|
||||
from typing import Optional, List, Iterator
|
||||
|
||||
from ielts_be.configs.constants import EducationalContent
|
||||
|
||||
|
||||
class DifficultyHelper:
|
||||
|
||||
def __init__(self, difficulties: Optional[List[str]]):
|
||||
self.difficulties = difficulties
|
||||
self.distributed: Optional[Iterator[str]] = None
|
||||
|
||||
def distribute_for_count(self, count: int) -> None:
|
||||
if not self.difficulties or count == 0:
|
||||
return
|
||||
|
||||
result = []
|
||||
remaining = count
|
||||
difficulties_count = len(self.difficulties)
|
||||
|
||||
for i, diff in enumerate(self.difficulties):
|
||||
if i == difficulties_count - 1:
|
||||
slots = remaining
|
||||
else:
|
||||
slots = math.ceil(remaining / (difficulties_count - i))
|
||||
|
||||
result.extend([diff] * slots)
|
||||
remaining -= slots
|
||||
|
||||
self.distributed = iter(result)
|
||||
|
||||
def pick_difficulty(self, difficulty: Optional[str]) -> str:
|
||||
if difficulty:
|
||||
return difficulty if difficulty != "Random" else random.choice(EducationalContent.DIFFICULTIES)
|
||||
|
||||
if self.distributed:
|
||||
return next(self.distributed)
|
||||
|
||||
return random.choice(EducationalContent.DIFFICULTIES)
|
||||
@@ -8,12 +8,12 @@ import random
|
||||
|
||||
from ielts_be.configs.constants import EducationalContent
|
||||
from ielts_be.dtos.level import LevelExercisesDTO
|
||||
from ielts_be.helpers import DifficultyHelper
|
||||
from ielts_be.repositories import IDocumentStore
|
||||
from ielts_be.services import (
|
||||
ILevelService, ILLMService, IReadingService,
|
||||
IWritingService, IListeningService, ISpeakingService
|
||||
)
|
||||
from ielts_be.utils import pick_difficulty
|
||||
from .exercises import MultipleChoice, BlankSpace, PassageUtas, FillBlanks
|
||||
from .full_exams import CustomLevelModule, LevelUtas
|
||||
from .upload import UploadLevelModule
|
||||
@@ -51,8 +51,7 @@ class LevelService(ILevelService):
|
||||
async def upload_level(self, upload: UploadFile, solutions: Optional[UploadFile] = None) -> Dict:
|
||||
return await self._upload_module.generate_level_from_file(upload, solutions)
|
||||
|
||||
async def _generate_exercise(self, req_exercise, start_id, difficulties):
|
||||
difficulty = pick_difficulty(req_exercise.difficulty, difficulties)
|
||||
async def _generate_exercise(self, req_exercise, start_id, difficulty):
|
||||
if req_exercise.type == "mcBlank":
|
||||
questions = await self._mc.gen_multiple_choice("blank_space", req_exercise.quantity, difficulty, start_id)
|
||||
questions["variant"] = "mcBlank"
|
||||
@@ -95,16 +94,21 @@ class LevelService(ILevelService):
|
||||
return exercise
|
||||
|
||||
async def generate_exercises(self, dto: LevelExercisesDTO):
|
||||
start_ids = []
|
||||
current_id = 1
|
||||
tasks = []
|
||||
|
||||
distributor = DifficultyHelper(dto.difficulty)
|
||||
|
||||
none_count = sum(1 for ex in dto.exercises if ex.difficulty is None)
|
||||
distributor.distribute_for_count(none_count)
|
||||
|
||||
for req_exercise in dto.exercises:
|
||||
start_ids.append(current_id)
|
||||
difficulty = distributor.pick_difficulty(req_exercise.difficulty)
|
||||
tasks.append(
|
||||
self._generate_exercise(req_exercise, current_id, difficulty)
|
||||
)
|
||||
current_id += req_exercise.quantity
|
||||
|
||||
tasks = [
|
||||
self._generate_exercise(req_exercise, start_id, dto.difficulty)
|
||||
for req_exercise, start_id in zip(dto.exercises, start_ids)
|
||||
]
|
||||
questions = await gather(*tasks)
|
||||
questions = [{'id': str(uuid4()), **exercise} for exercise in questions]
|
||||
|
||||
|
||||
@@ -13,15 +13,13 @@ from ielts_be.configs.constants import (
|
||||
NeuralVoices, GPTModels, TemperatureSettings, EducationalContent,
|
||||
FieldsAndExercises
|
||||
)
|
||||
from ielts_be.helpers import FileHelper
|
||||
from ielts_be.helpers import FileHelper, DifficultyHelper
|
||||
from .audio_to_dialog import AudioToDialog
|
||||
from .import_listening import ImportListeningModule
|
||||
from .write_blank_forms import WriteBlankForms
|
||||
from .write_blanks import WriteBlanks
|
||||
from .write_blank_notes import WriteBlankNotes
|
||||
from ..shared import TrueFalse, MultipleChoice
|
||||
from ielts_be.utils import pick_difficulty
|
||||
|
||||
|
||||
class ListeningService(IListeningService):
|
||||
|
||||
@@ -137,6 +135,11 @@ class ListeningService(IListeningService):
|
||||
start_id = 1
|
||||
exercise_tasks = []
|
||||
|
||||
diff_helper = DifficultyHelper(dto.difficulty)
|
||||
|
||||
none_count = sum(1 for ex in dto.exercises if ex.difficulty is None)
|
||||
diff_helper.distribute_for_count(none_count)
|
||||
|
||||
for req_exercise in dto.exercises:
|
||||
exercise_tasks.append(
|
||||
self._generate_exercise(
|
||||
@@ -144,7 +147,7 @@ class ListeningService(IListeningService):
|
||||
"dialog or monologue",
|
||||
dto.text,
|
||||
start_id,
|
||||
pick_difficulty(req_exercise.difficulty, dto.difficulty)
|
||||
diff_helper.pick_difficulty(req_exercise.difficulty)
|
||||
)
|
||||
)
|
||||
start_id += req_exercise.quantity
|
||||
|
||||
@@ -5,9 +5,8 @@ from fastapi import UploadFile
|
||||
|
||||
from ielts_be.configs.constants import GPTModels, FieldsAndExercises, TemperatureSettings
|
||||
from ielts_be.dtos.reading import ReadingDTO
|
||||
from ielts_be.helpers import ExercisesHelper
|
||||
from ielts_be.helpers import ExercisesHelper, DifficultyHelper
|
||||
from ielts_be.services import IReadingService, ILLMService
|
||||
from ielts_be.utils import pick_difficulty
|
||||
from .fill_blanks import FillBlanks
|
||||
from .idea_match import IdeaMatch
|
||||
from .paragraph_match import ParagraphMatch
|
||||
@@ -138,13 +137,18 @@ class ReadingService(IReadingService):
|
||||
exercise_tasks = []
|
||||
start_id = 1
|
||||
|
||||
diff_helper = DifficultyHelper(dto.difficulty)
|
||||
|
||||
none_count = sum(1 for ex in dto.exercises if ex.difficulty is None)
|
||||
diff_helper.distribute_for_count(none_count)
|
||||
|
||||
for req_exercise in dto.exercises:
|
||||
exercise_tasks.append(
|
||||
self._generate_single_exercise(
|
||||
req_exercise,
|
||||
dto.text,
|
||||
start_id,
|
||||
pick_difficulty(req_exercise.difficulty, dto.difficulty)
|
||||
diff_helper.pick_difficulty(req_exercise.difficulty)
|
||||
)
|
||||
)
|
||||
start_id += req_exercise.quantity
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
from .handle_exception import handle_exception
|
||||
from .logger import suppress_loggers
|
||||
from .pick_difficulty import pick_difficulty
|
||||
|
||||
__all__ = [
|
||||
"handle_exception",
|
||||
"suppress_loggers",
|
||||
"pick_difficulty"
|
||||
]
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import random
|
||||
from typing import Optional, List
|
||||
|
||||
from ielts_be.configs.constants import EducationalContent
|
||||
|
||||
|
||||
def pick_difficulty(difficulty: Optional[str], difficulties: Optional[List[str]]) -> str:
|
||||
if difficulty:
|
||||
return difficulty
|
||||
|
||||
if difficulties:
|
||||
return random.choice(difficulties)
|
||||
|
||||
return random.choice(EducationalContent.DIFFICULTIES)
|
||||
Reference in New Issue
Block a user