ENCOA-256: Some more changes to level prompt and added mc to reading

This commit is contained in:
Carlos-Mesquita
2024-12-04 04:18:23 +00:00
parent 4e05c4d913
commit 68cab80851
7 changed files with 48 additions and 22 deletions

View File

@@ -47,6 +47,7 @@ class ReadingExerciseType(str, Enum):
trueFalse = "trueFalse"
paragraphMatch = "paragraphMatch"
ideaMatch = "ideaMatch"
multipleChoice = "multipleChoice"
class ListeningExerciseType(str, Enum):

View File

@@ -35,7 +35,7 @@ class UploadLevelModule:
#completion: Coroutine[Any, Any, Exam] = (
# self._png_completion(path_id) if file_has_images else self._html_completion(path_id)
#)
response = await self._html_completion(path_id)
response = await self._html_completion(path_id, solutions is not None)
FileHelper.remove_directory(f'./tmp/{path_id}')
@@ -69,16 +69,26 @@ class UploadLevelModule:
]
}
async def _html_completion(self, path_id: str) -> Exam:
async def _html_completion(self, path_id: str, solutions_provided: bool) -> Exam:
async with aiofiles.open(f'./tmp/{path_id}/exercises.html', 'r', encoding='utf-8') as f:
html = await f.read()
solutions = []
if solutions_provided:
async with aiofiles.open(f'./tmp/{path_id}/solutions.html', 'r', encoding='utf-8') as f:
solutions_html = await f.read()
solutions.append({
"role": "user",
"content": f'The solutions to the question sheet are the following:\n\n{solutions_html}'
})
return await self._llm.pydantic_prediction(
[self._gpt_instructions_html(),
{
"role": "user",
"content": html
}
},
*solutions
],
LevelMapper.map_to_exam_model,
str(self._level_json_schema())
@@ -122,8 +132,10 @@ class UploadLevelModule:
'IMPORTANT: As stated earlier your job is to structure the questions into PARTS not SECTION, this means '
'that if there is for example: Section 1, Part 1 and Part 2, Section 2, Part 1 and Part 2, you MUST '
'place in the parts array 4 parts NOT 2 parts with the exercises of both parts! You must strictly '
'adhere to this instruction, do not mistake sections for parts!\n'
'place in the parts array 4 parts NOT 2 parts with the exercises of both parts! If there are no sections '
'and only Parts then group them by parts, and when I say parts I mean it in the fucking literal sense of the'
' word Part x which is in the html. '
'You must strictly adhere to this instruction, do not mistake sections for parts!\n'
'The templates for the exercises are the following:\n'
'- blank space multiple choice, underline multiple choice and reading passage multiple choice: '
@@ -164,17 +176,17 @@ class UploadLevelModule:
"prompt": "Click a blank to select the appropriate word for it.",
"text": (
"<The whole text for the exercise with replacements for blank spaces and their "
"ids with {{<question id>}} with 2 newlines between paragraphs>"
"ids with {{<question id/number>}} with 2 newlines between paragraphs>"
),
"solutions": [
{
"id": "<question id>",
"id": "<question number>",
"solution": "<the option that holds the solution>"
}
],
"words": [
{
"id": "<question id>",
"id": "<question number>",
"options": {
"A": "<a option>",
"B": "<b option>",
@@ -198,7 +210,7 @@ class UploadLevelModule:
self._multiple_choice_png(),
{"type": "blanksPassage", "text": (
"<The whole text for the exercise with replacements for blank spaces and their "
"ids with {{<question id>}} with 2 newlines between paragraphs>"
"ids with {{<question number>}} with 2 newlines between paragraphs>"
)},
{"type": "passage", "context": (
"<reading passages without paragraphs or line numbers, with 2 newlines between paragraphs>"

View File

@@ -14,11 +14,10 @@ from app.configs.constants import (
)
from app.helpers import FileHelper
from .import_listening import ImportListeningModule
from .multiple_choice import MultipleChoice
from .write_blank_forms import WriteBlankForms
from .write_blanks import WriteBlanks
from .write_blank_notes import WriteBlankNotes
from ..shared import TrueFalse
from ..shared import TrueFalse, MultipleChoice
class ListeningService(IListeningService):
@@ -128,7 +127,7 @@ class ListeningService(IListeningService):
if req_exercise.type == "multipleChoice" or req_exercise.type == "multipleChoice3Options":
n_options = 4 if req_exercise.type == "multipleChoice" else 3
question = await self._multiple_choice.gen_multiple_choice(
dialog_type, text, req_exercise.quantity, start_id, difficulty, n_options
text, req_exercise.quantity, start_id, difficulty, n_options
)
self._logger.info(f"Added multiple choice: {question}")
return question

View File

@@ -10,7 +10,7 @@ from app.services.abc import IReadingService, ILLMService
from .fill_blanks import FillBlanks
from .idea_match import IdeaMatch
from .paragraph_match import ParagraphMatch
from ..shared import TrueFalse
from ..shared import TrueFalse, MultipleChoice
from .import_reading import ImportReadingModule
from .write_blanks import WriteBlanks
@@ -24,6 +24,7 @@ class ReadingService(IReadingService):
self._paragraph_match = ParagraphMatch(llm)
self._true_false = TrueFalse(llm)
self._write_blanks = WriteBlanks(llm)
self._multiple_choice = MultipleChoice(llm)
self._logger = getLogger(__name__)
self._import = ImportReadingModule(llm)
@@ -119,6 +120,12 @@ class ReadingService(IReadingService):
question["variant"] = "ideaMatch"
self._logger.info(f"Added idea match: {question}")
return question
elif req_exercise.type == "multipleChoice":
question = await self._multiple_choice.gen_multiple_choice(
text, req_exercise.quantity, start_id, difficulty, 4
)
self._logger.info(f"Added multiple choice: {question}")
return question
async def generate_reading_exercises(self, dto: ReadingDTO):
exercise_tasks = []

View File

@@ -98,7 +98,11 @@ class ImportReadingModule:
]
}
],
"text": "<numbered questions with format in square brackets: [<question text>{{<question number>}}\\\\n] notice how there is a double backslash before the n -> I want an escaped newline in your output> ",
"text": (
"<numbered questions with format in square brackets: [<question text>{{<question number>}}\\\\n] "
"- notice how there the question number inside {{}} -> the text MUST always contain the question number in that format "
"- and notice how there is a double backslash before the n -> I want an escaped newline in your output> "
),
"type": "writeBlanks",
"prompt": "<specific instructions for this exercise section>"
}
@@ -192,13 +196,14 @@ class ImportReadingModule:
+ (
"Solutions were not provided - analyze the passage carefully to determine correct answers."
if not solutions else
"Use the provided solutions to fill in all answer fields accurately."
"Use the provided solutions to fill in all answer fields accurately, if word answers have all letters "
"uppercase convert them to lowercase before assigning them."
)
+
"Pay extra attention to fillblanks exercises the solution and option wording must match in case!"
"There can't be options in lowercase and solutions in uppercase!"
"Pay extra attention to fillblanks exercises the solution and option wording must match in case! "
"There can't be options in lowercase and solutions in uppercase! "
"Also PAY ATTENTION TO SECTIONS, these most likely indicate parts, and in each section/part there "
"should be a text, if there isn't a title for it choose a reasonable one based on its contents."
"should be a text, if there isn't a title for it choose a reasonable one based on its contents. "
)
return {

View File

@@ -1,5 +1,7 @@
from .true_false import TrueFalse
from .multiple_choice import MultipleChoice
__all__ = [
"TrueFalse"
]
"TrueFalse",
"MultipleChoice"
]

View File

@@ -11,7 +11,7 @@ class MultipleChoice:
self._llm = llm
async def gen_multiple_choice(
self, dialog_type: str, text: str, quantity: int, start_id: int, difficulty: str, n_options: int = 4
self, text: str, quantity: int, start_id: int, difficulty: str, n_options: int = 4
):
messages = [
{
@@ -27,7 +27,7 @@ class MultipleChoice:
"role": "user",
"content": (
f'Generate {quantity} {difficulty} difficulty multiple choice questions of {n_options} '
f'options for this {dialog_type}:\n"' + text + '"')
f'options for this text:\n"' + text + '"')
}
]