Merged in speaking-improvements (pull request #9)

Speaking improvements
This commit is contained in:
Cristiano Ferreira
2024-06-17 13:06:15 +00:00
3 changed files with 359 additions and 165 deletions

478
app.py
View File

@@ -397,10 +397,10 @@ def get_writing_task_2_general_question():
{ {
"role": "user", "role": "user",
"content": ( "content": (
'Craft a comprehensive question of ' + difficulty + 'difficulty like the ones for IELTS Writing Task 2 General Training that directs the candidate ' 'Craft a comprehensive question of ' + difficulty + 'difficulty like the ones for IELTS Writing Task 2 General Training that directs the candidate '
'to delve into an in-depth analysis of contrasting perspectives on the topic of "' + topic + '". ' 'to delve into an in-depth analysis of contrasting perspectives on the topic of "' + topic + '". '
'The candidate should be asked to discuss the strengths and weaknesses of both viewpoints, provide evidence or ' 'The candidate should be asked to discuss the strengths and weaknesses of both viewpoints, provide evidence or '
'examples, and present a well-rounded argument before concluding with their personal opinion on the subject.') 'examples, and present a well-rounded argument before concluding with their personal opinion on the subject.')
} }
] ]
token_count = count_total_tokens(messages) token_count = count_total_tokens(messages)
@@ -419,48 +419,56 @@ def get_writing_task_2_general_question():
def grade_speaking_task_1(): def grade_speaking_task_1():
request_id = uuid.uuid4() request_id = uuid.uuid4()
delete_files_older_than_one_day(AUDIO_FILES_PATH) delete_files_older_than_one_day(AUDIO_FILES_PATH)
sound_file_name = AUDIO_FILES_PATH + str(uuid.uuid4())
logging.info("POST - speaking_task_1 - Received request to grade speaking task 1. " logging.info("POST - speaking_task_1 - Received request to grade speaking task 1. "
"Use this id to track the logs: " + str(request_id) + " - Request data: " + str(request.get_json())) "Use this id to track the logs: " + str(request_id) + " - Request data: " + str(request.get_json()))
try: try:
data = request.get_json() data = request.get_json()
question = data.get('question') answers = data.get('answers')
answer_firebase_path = data.get('answer') text_answers = []
perfect_answers = []
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Downloading file " + answer_firebase_path)
download_firebase_file(FIREBASE_BUCKET, answer_firebase_path, sound_file_name)
logging.info("POST - speaking_task_1 - " + str( logging.info("POST - speaking_task_1 - " + str(
request_id) + " - Downloaded file " + answer_firebase_path + " to " + sound_file_name) request_id) + " - Received " + str(len(answers)) + " total answers.")
answer = speech_to_text(sound_file_name) for item in answers:
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Transcripted answer: " + answer) sound_file_name = AUDIO_FILES_PATH + str(uuid.uuid4())
if has_x_words(answer, 20): logging.info("POST - speaking_task_1 - " + str(request_id) + " - Downloading file " + item["answer"])
messages = [ download_firebase_file(FIREBASE_BUCKET, item["answer"], sound_file_name)
{ logging.info("POST - speaking_task_1 - " + str(
"role": "system", request_id) + " - Downloaded file " + item["answer"] + " to " + sound_file_name)
"content": (
'You are a helpful assistant designed to output JSON on this format: ' answer_text = speech_to_text(sound_file_name)
'{"comment": "comment about answer quality", "overall": 0.0, ' logging.info("POST - speaking_task_1 - " + str(request_id) + " - Transcripted answer: " + answer_text)
'"task_response": {"Fluency and Coherence": 0.0, "Lexical Resource": 0.0, '
'"Grammatical Range and Accuracy": 0.0, "Pronunciation": 0.0}}') text_answers.append(answer_text)
}, item["answer"] = answer_text
{ os.remove(sound_file_name)
"role": "user",
"content": ( if not has_x_words(answer_text, 20):
'Evaluate the given Speaking Part 1 response based on the IELTS grading system, ensuring a ' logging.info("POST - speaking_task_1 - " + str(
'strict assessment that penalizes errors. Deduct points for deviations from the task, and ' request_id) + " - The answer had less words than threshold 20 to be graded. Answer: " + answer_text)
'assign a score of 0 if the response fails to address the question. Additionally, provide ' return {
'detailed commentary highlighting both strengths and weaknesses in the response.' "comment": "The audio recorded does not contain enough english words to be graded.",
'\n Question: "' + question + '" \n Answer: "' + answer + '"') "overall": 0,
"task_response": {
"Fluency and Coherence": {
"grade": 0.0,
"comment": ""
},
"Lexical Resource": {
"grade": 0.0,
"comment": ""
},
"Grammatical Range and Accuracy": {
"grade": 0.0,
"comment": ""
},
"Pronunciation": {
"grade": 0.0,
"comment": ""
}
}
} }
]
token_count = count_total_tokens(messages)
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Requesting grading of the answer.")
response = make_openai_call(GPT_3_5_TURBO, messages, token_count, ["comment"],
GRADING_TEMPERATURE)
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Answer graded: " + str(response))
perfect_answer_messages = [ perfect_answer_messages = [
{ {
@@ -472,49 +480,111 @@ def grade_speaking_task_1():
"role": "user", "role": "user",
"content": ( "content": (
'Provide a perfect answer according to ielts grading system to the following ' 'Provide a perfect answer according to ielts grading system to the following '
'Speaking Part 1 question: "' + question + '"') 'Speaking Part 1 question: "' + item["question"] + '"')
},
{
"role": "user",
"content": 'The answer must be 2 or 3 sentences long.'
} }
] ]
token_count = count_total_tokens(perfect_answer_messages) token_count = count_total_tokens(perfect_answer_messages)
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Requesting perfect answer.")
response['perfect_answer'] = make_openai_call(GPT_3_5_TURBO,
perfect_answer_messages,
token_count,
["answer"],
GEN_QUESTION_TEMPERATURE)["answer"]
logging.info("POST - speaking_task_1 - " + str( logging.info("POST - speaking_task_1 - " + str(
request_id) + " - Perfect answer: " + response['perfect_answer']) request_id) + " - Requesting perfect answer for question: " + item["question"])
perfect_answers.append(make_openai_call(GPT_4_O,
perfect_answer_messages,
token_count,
["answer"],
GEN_QUESTION_TEMPERATURE))
response['transcript'] = answer json_format = {
"comment": "comment about answers quality",
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Requesting fixed text.") "overall": 0.0,
response['fixed_text'] = get_speaking_corrections(answer) "task_response": {
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Fixed text: " + response['fixed_text']) "Fluency and Coherence": {
"grade": 0.0,
if response["overall"] == "0.0" or response["overall"] == 0.0: "comment": "comment about fluency and coherence"
response["overall"] = round((response["task_response"]["Fluency and Coherence"] + },
response["task_response"]["Lexical Resource"] + response["task_response"][ "Lexical Resource": {
"Grammatical Range and Accuracy"] + response["task_response"][ "grade": 0.0,
"Pronunciation"]) / 4, 1) "comment": "comment about lexical resource"
},
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Final response: " + str(response)) "Grammatical Range and Accuracy": {
return response "grade": 0.0,
else: "comment": "comment about grammatical range and accuracy"
logging.info("POST - speaking_task_1 - " + str( },
request_id) + " - The answer had less words than threshold 20 to be graded. Answer: " + answer) "Pronunciation": {
return { "grade": 0.0,
"comment": "The audio recorded does not contain enough english words to be graded.", "comment": "comment about pronunciation on the transcribed answers"
"overall": 0,
"task_response": {
"Fluency and Coherence": 0,
"Lexical Resource": 0,
"Grammatical Range and Accuracy": 0,
"Pronunciation": 0
} }
} }
}
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Formatting answers and questions for prompt.")
formatted_text = ""
for i, entry in enumerate(answers, start=1):
formatted_text += f"**Question {i}:**\n{entry['question']}\n\n"
formatted_text += f"**Answer {i}:**\n{entry['answer']}\n\n"
logging.info("POST - speaking_task_1 - " + str(
request_id) + " - Formatted answers and questions for prompt: " + formatted_text)
grade_message = (
'Evaluate the given Speaking Part 1 response based on the IELTS grading system, ensuring a '
'strict assessment that penalizes errors. Deduct points for deviations from the task, and '
'assign a score of 0 if the response fails to address the question. Additionally, provide '
'detailed commentary highlighting both strengths and weaknesses in the response.'
"\n\n The questions and answers are: \n\n'" + formatted_text)
messages = [
{
"role": "system",
"content": (
'You are a helpful assistant designed to output JSON on this format: ' + str(json_format))
},
{
"role": "user",
"content": grade_message
},
{
"role": "user",
"content": 'Address the student as "you". If the answers are not 2 or 3 sentences long, warn the '
'student that they should be.'
},
{
"role": "user",
"content": 'For pronunciations act as if you heard the answers and they were transcripted as you heard them.'
},
{
"role": "user",
"content": 'The comments must be long, detailed, justify the grading and suggest improvements.'
}
]
token_count = count_total_tokens(messages)
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Requesting grading of the answer.")
response = make_openai_call(GPT_4_O, messages, token_count, ["comment"],
GRADING_TEMPERATURE)
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Answers graded: " + str(response))
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Adding perfect answers to response.")
for i, answer in enumerate(perfect_answers, start=1):
response['perfect_answer_' + str(i)] = answer
logging.info("POST - speaking_task_1 - " + str(
request_id) + " - Adding transcript and fixed texts to response.")
for i, answer in enumerate(text_answers, start=1):
response['transcript_' + str(i)] = answer
response['fixed_text_' + str(i)] = get_speaking_corrections(answer)
if response["overall"] == "0.0" or response["overall"] == 0.0:
response["overall"] = round((response["task_response"]["Fluency and Coherence"] +
response["task_response"]["Lexical Resource"] + response["task_response"][
"Grammatical Range and Accuracy"] + response["task_response"][
"Pronunciation"]) / 4, 1)
logging.info("POST - speaking_task_1 - " + str(request_id) + " - Final response: " + str(response))
return response
except Exception as e: except Exception as e:
os.remove(sound_file_name)
return str(e), 400 return str(e), 400
@@ -522,37 +592,53 @@ def grade_speaking_task_1():
@jwt_required() @jwt_required()
def get_speaking_task_1_question(): def get_speaking_task_1_question():
difficulty = request.args.get("difficulty", default=random.choice(difficulties)) difficulty = request.args.get("difficulty", default=random.choice(difficulties))
topic = request.args.get("topic", default=random.choice(mti_topics)) first_topic = request.args.get("first_topic", default=random.choice(mti_topics))
second_topic = request.args.get("second_topic", default=random.choice(mti_topics))
json_format = {
"first_topic": "topic 1",
"second_topic": "topic 2",
"questions": [
"Introductory question, should start with a greeting and introduce a question about the first topic.",
"Follow up question about the first topic",
"Follow up question about the first topic",
"Question about second topic",
"Follow up question about the second topic",
]
}
try: try:
messages = [ messages = [
{ {
"role": "system", "role": "system",
"content": ( "content": (
'You are a helpful assistant designed to output JSON on this format: ' 'You are a helpful assistant designed to output JSON on this format: ' + str(json_format))
'{"topic": "topic", "question": "question"}')
}, },
{ {
"role": "user", "role": "user",
"content": ( "content": (
'Craft a thought-provoking question of ' + difficulty + ' difficulty for IELTS Speaking Part 1 ' 'Craft 5 thought-provoking questions of ' + difficulty + ' difficulty for IELTS Speaking Part 1 '
'that encourages candidates to delve deeply into ' 'that encourages candidates to delve deeply into '
'personal experiences, preferences, or insights on the topic ' 'personal experiences, preferences, or insights on the topic '
'of "' + topic + '". Instruct the candidate ' 'of "' + first_topic + '" and the topic of "' + second_topic + '". Instruct the candidate '
'to offer not only detailed ' 'to offer not only detailed '
'descriptions but also provide ' 'descriptions but also provide '
'nuanced explanations, examples, ' 'nuanced explanations, examples, '
'or anecdotes to enrich their response. ' 'or anecdotes to enrich their response. '
'Make sure that the generated question ' 'Make sure that the generated question '
'does not contain forbidden subjects in ' 'does not contain forbidden subjects in '
'muslim countries.') 'muslim countries.')
},
{
"role": "user",
"content": 'The questions should lead to the usage of 4 verb tenses (present perfect, present, past and future).'
} }
] ]
token_count = count_total_tokens(messages) token_count = count_total_tokens(messages)
response = make_openai_call(GPT_4_O, messages, token_count, ["topic"], response = make_openai_call(GPT_4_O, messages, token_count, ["first_topic"],
GEN_QUESTION_TEMPERATURE) GEN_QUESTION_TEMPERATURE)
response["type"] = 1 response["type"] = 1
response["difficulty"] = difficulty response["difficulty"] = difficulty
response["topic"] = topic
return response return response
except Exception as e: except Exception as e:
return str(e) return str(e)
@@ -579,15 +665,35 @@ def grade_speaking_task_2():
answer = speech_to_text(sound_file_name) answer = speech_to_text(sound_file_name)
logging.info("POST - speaking_task_2 - " + str(request_id) + " - Transcripted answer: " + answer) logging.info("POST - speaking_task_2 - " + str(request_id) + " - Transcripted answer: " + answer)
json_format = {
"comment": "extensive comment about answer quality",
"overall": 0.0,
"task_response": {
"Fluency and Coherence": {
"grade": 0.0,
"comment": "extensive comment about fluency and coherence, use examples to justify the grade awarded."
},
"Lexical Resource": {
"grade": 0.0,
"comment": "extensive comment about lexical resource, use examples to justify the grade awarded."
},
"Grammatical Range and Accuracy": {
"grade": 0.0,
"comment": "extensive comment about grammatical range and accuracy, use examples to justify the grade awarded."
},
"Pronunciation": {
"grade": 0.0,
"comment": "extensive comment about pronunciation on the transcribed answer, use examples to justify the grade awarded."
}
}
}
if has_x_words(answer, 20): if has_x_words(answer, 20):
messages = [ messages = [
{ {
"role": "system", "role": "system",
"content": ( "content": (
'You are a helpful assistant designed to output JSON on this format: ' 'You are a helpful assistant designed to output JSON on this format: ' + str(json_format))
'{"comment": "comment about answer quality", "overall": 0.0, '
'"task_response": {"Fluency and Coherence": 0.0, "Lexical Resource": 0.0, '
'"Grammatical Range and Accuracy": 0.0, "Pronunciation": 0.0}}')
}, },
{ {
"role": "user", "role": "user",
@@ -597,13 +703,17 @@ def grade_speaking_task_2():
'assign a score of 0 if the response fails to address the question. Additionally, provide ' 'assign a score of 0 if the response fails to address the question. Additionally, provide '
'detailed commentary highlighting both strengths and weaknesses in the response.' 'detailed commentary highlighting both strengths and weaknesses in the response.'
'\n Question: "' + question + '" \n Answer: "' + answer + '"') '\n Question: "' + question + '" \n Answer: "' + answer + '"')
},
{
"role": "user",
"content": 'Address the student as "you"'
} }
] ]
token_count = count_total_tokens(messages) token_count = count_total_tokens(messages)
logging.info("POST - speaking_task_2 - " + str(request_id) + " - Requesting grading of the answer.") logging.info("POST - speaking_task_2 - " + str(request_id) + " - Requesting grading of the answer.")
response = make_openai_call(GPT_3_5_TURBO, messages, token_count,["comment"], response = make_openai_call(GPT_3_5_TURBO, messages, token_count, ["comment"],
GRADING_TEMPERATURE) GRADING_TEMPERATURE)
logging.info("POST - speaking_task_2 - " + str(request_id) + " - Answer graded: " + str(response)) logging.info("POST - speaking_task_2 - " + str(request_id) + " - Answer graded: " + str(response))
perfect_answer_messages = [ perfect_answer_messages = [
@@ -651,10 +761,22 @@ def grade_speaking_task_2():
"comment": "The audio recorded does not contain enough english words to be graded.", "comment": "The audio recorded does not contain enough english words to be graded.",
"overall": 0, "overall": 0,
"task_response": { "task_response": {
"Fluency and Coherence": 0, "Fluency and Coherence": {
"Lexical Resource": 0, "grade": 0.0,
"Grammatical Range and Accuracy": 0, "comment": ""
"Pronunciation": 0 },
"Lexical Resource": {
"grade": 0.0,
"comment": ""
},
"Grammatical Range and Accuracy": {
"grade": 0.0,
"comment": ""
},
"Pronunciation": {
"grade": 0.0,
"comment": ""
}
} }
} }
except Exception as e: except Exception as e:
@@ -667,28 +789,43 @@ def grade_speaking_task_2():
def get_speaking_task_2_question(): def get_speaking_task_2_question():
difficulty = request.args.get("difficulty", default=random.choice(difficulties)) difficulty = request.args.get("difficulty", default=random.choice(difficulties))
topic = request.args.get("topic", default=random.choice(mti_topics)) topic = request.args.get("topic", default=random.choice(mti_topics))
json_format = {
"topic": "topic",
"question": "question",
"prompts": [
"prompt_1",
"prompt_2",
"prompt_3"
],
"suffix": "And explain why..."
}
try: try:
messages = [ messages = [
{ {
"role": "system", "role": "system",
"content": ( "content": 'You are a helpful assistant designed to output JSON on this format: ' + str(json_format)
'You are a helpful assistant designed to output JSON on this format: '
'{"topic": "topic", "question": "question", "prompts": ["prompt_1", "prompt_2", "prompt_3"]}')
}, },
{ {
"role": "user", "role": "user",
"content": ( "content": (
'Create a question of ' + difficulty + ' difficulty for IELTS Speaking Part 2 ' 'Create a question of medium difficulty for IELTS Speaking Part 2 '
'that encourages candidates to narrate a ' 'that encourages candidates to narrate a '
'personal experience or story related to the topic ' 'personal experience or story related to the topic '
'of "' + topic + '". Include 3 prompts that ' 'of "' + random.choice(mti_topics) + '". Include 3 prompts that '
'guide the candidate to describe ' 'guide the candidate to describe '
'specific aspects of the experience, ' 'specific aspects of the experience, '
'such as details about the situation, ' 'such as details about the situation, '
'their actions, and the reasons it left a ' 'their actions, and the reasons it left a '
'lasting impression. Make sure that the ' 'lasting impression. Make sure that the '
'generated question does not contain ' 'generated question does not contain '
'forbidden subjects in muslim countries.') 'forbidden subjects in muslim countries.')
},
{
"role": "user",
"content": 'The prompts must not be questions. Also include a suffix like the ones in the IELTS exams '
'that start with "And explain why".'
} }
] ]
token_count = count_total_tokens(messages) token_count = count_total_tokens(messages)
@@ -706,21 +843,32 @@ def get_speaking_task_2_question():
def get_speaking_task_3_question(): def get_speaking_task_3_question():
difficulty = request.args.get("difficulty", default=random.choice(difficulties)) difficulty = request.args.get("difficulty", default=random.choice(difficulties))
topic = request.args.get("topic", default=random.choice(mti_topics)) topic = request.args.get("topic", default=random.choice(mti_topics))
json_format = {
"topic": "topic",
"questions": [
"Introductory question, should start with a greeting and introduce a question about the topic.",
"Follow up question about the topic",
"Follow up question about the topic",
"Follow up question about the topic",
"Follow up question about the topic"
]
}
try: try:
messages = [ messages = [
{ {
"role": "system", "role": "system",
"content": ( "content": (
'You are a helpful assistant designed to output JSON on this format: ' 'You are a helpful assistant designed to output JSON on this format: ' + str(json_format))
'{"topic": "topic", "questions": ["question", "question", "question"]}')
}, },
{ {
"role": "user", "role": "user",
"content": ( "content": (
'Formulate a set of 3 questions of ' + difficulty + ' difficulty for IELTS Speaking Part 3 that encourage candidates to engage in a ' 'Formulate a set of 5 questions of hard difficulty for IELTS Speaking Part 3 that encourage candidates to engage in a '
'meaningful discussion on the topic of "' + topic + '". Provide inquiries, ensuring ' 'meaningful discussion on the topic of "' + random.choice(
'they explore various aspects, perspectives, and implications related to the topic.' mti_topics) + '". Provide inquiries, ensuring '
'Make sure that the generated question does not contain forbidden subjects in muslim countries.') 'they explore various aspects, perspectives, and implications related to the topic.'
'Make sure that the generated question does not contain forbidden subjects in muslim countries.')
} }
] ]
@@ -772,10 +920,22 @@ def grade_speaking_task_3():
"comment": "The audio recorded does not contain enough english words to be graded.", "comment": "The audio recorded does not contain enough english words to be graded.",
"overall": 0, "overall": 0,
"task_response": { "task_response": {
"Fluency and Coherence": 0, "Fluency and Coherence": {
"Lexical Resource": 0, "grade": 0.0,
"Grammatical Range and Accuracy": 0, "comment": ""
"Pronunciation": 0 },
"Lexical Resource": {
"grade": 0.0,
"comment": ""
},
"Grammatical Range and Accuracy": {
"grade": 0.0,
"comment": ""
},
"Pronunciation": {
"grade": 0.0,
"comment": ""
}
} }
} }
@@ -801,22 +961,28 @@ def grade_speaking_task_3():
["answer"], ["answer"],
GEN_QUESTION_TEMPERATURE)) GEN_QUESTION_TEMPERATURE))
messages = [ json_format = {
{ "comment": "extensive comment about answer quality",
"role": "system", "overall": 0.0,
"content": ( "task_response": {
'You are a helpful assistant designed to output JSON on this format: ' "Fluency and Coherence": {
'{"comment": "comment about answer quality", "overall": 0.0, ' "grade": 0.0,
'"task_response": {"Fluency and Coherence": 0.0, "Lexical Resource": 0.0, ' "comment": "extensive comment about fluency and coherence, use examples to justify the grade awarded."
'"Grammatical Range and Accuracy": 0.0, "Pronunciation": 0.0}}') },
"Lexical Resource": {
"grade": 0.0,
"comment": "extensive comment about lexical resource, use examples to justify the grade awarded."
},
"Grammatical Range and Accuracy": {
"grade": 0.0,
"comment": "extensive comment about grammatical range and accuracy, use examples to justify the grade awarded."
},
"Pronunciation": {
"grade": 0.0,
"comment": "extensive comment about pronunciation on the transcribed answer, use examples to justify the grade awarded."
}
} }
] }
message = (
"Evaluate the given Speaking Part 3 response based on the IELTS grading system, ensuring a "
"strict assessment that penalizes errors. Deduct points for deviations from the task, and "
"assign a score of 0 if the response fails to address the question. Additionally, provide detailed "
"commentary highlighting both strengths and weaknesses in the response."
"\n\n The questions and answers are: \n\n'")
logging.info("POST - speaking_task_3 - " + str(request_id) + " - Formatting answers and questions for prompt.") logging.info("POST - speaking_task_3 - " + str(request_id) + " - Formatting answers and questions for prompt.")
formatted_text = "" formatted_text = ""
@@ -826,17 +992,41 @@ def grade_speaking_task_3():
logging.info("POST - speaking_task_3 - " + str( logging.info("POST - speaking_task_3 - " + str(
request_id) + " - Formatted answers and questions for prompt: " + formatted_text) request_id) + " - Formatted answers and questions for prompt: " + formatted_text)
message += formatted_text grade_message = (
"Evaluate the given Speaking Part 3 response based on the IELTS grading system, ensuring a "
"strict assessment that penalizes errors. Deduct points for deviations from the task, and "
"assign a score of 0 if the response fails to address the question. Additionally, provide detailed "
"commentary highlighting both strengths and weaknesses in the response."
"\n\n The questions and answers are: \n\n'")
messages.append({ messages = [
"role": "user", {
"content": message "role": "system",
}) "content": (
'You are a helpful assistant designed to output JSON on this format: ' + str(json_format))
},
{
"role": "user",
"content": grade_message
},
{
"role": "user",
"content": 'Address the student as "you" and pay special attention to coherence between the answers.'
},
{
"role": "user",
"content": 'For pronunciations act as if you heard the answers and they were transcripted as you heard them.'
},
{
"role": "user",
"content": 'The comments must be long, detailed, justify the grading and suggest improvements.'
}
]
token_count = count_total_tokens(messages) token_count = count_total_tokens(messages)
logging.info("POST - speaking_task_3 - " + str(request_id) + " - Requesting grading of the answers.") logging.info("POST - speaking_task_3 - " + str(request_id) + " - Requesting grading of the answers.")
response = make_openai_call(GPT_3_5_TURBO, messages, token_count, ["comment"], GRADING_TEMPERATURE) response = make_openai_call(GPT_4_O, messages, token_count, ["comment"], GRADING_TEMPERATURE)
logging.info("POST - speaking_task_3 - " + str(request_id) + " - Answers graded: " + str(response)) logging.info("POST - speaking_task_3 - " + str(request_id) + " - Answers graded: " + str(response))
logging.info("POST - speaking_task_3 - " + str(request_id) + " - Adding perfect answers to response.") logging.info("POST - speaking_task_3 - " + str(request_id) + " - Adding perfect answers to response.")

View File

@@ -29,26 +29,32 @@ GET_HEADER = {
def create_videos_and_save_to_db(exercises, template, id): def create_videos_and_save_to_db(exercises, template, id):
avatar = random.choice(list(AvatarEnum))
# Speaking 1 # Speaking 1
# Using list comprehension to find the element with the desired value in the 'type' field # Using list comprehension to find the element with the desired value in the 'type' field
found_exercises_1 = [element for element in exercises if element.get('type') == 1] found_exercises_1 = [element for element in exercises if element.get('type') == 1]
# Check if any elements were found # Check if any elements were found
if found_exercises_1: if found_exercises_1:
exercise_1 = found_exercises_1[0] exercise_1 = found_exercises_1[0]
sp1_questions = []
app.app.logger.info('Creating video for speaking part 1') app.app.logger.info('Creating video for speaking part 1')
sp1_result = create_video(exercise_1["question"], random.choice(list(AvatarEnum))) for question in exercise_1["questions"]:
if sp1_result is not None: sp1_result = create_video(question, avatar)
sound_file_path = VIDEO_FILES_PATH + sp1_result if sp1_result is not None:
firebase_file_path = FIREBASE_SPEAKING_VIDEO_FILES_PATH + sp1_result sound_file_path = VIDEO_FILES_PATH + sp1_result
url = upload_file_firebase_get_url(FIREBASE_BUCKET, firebase_file_path, sound_file_path) firebase_file_path = FIREBASE_SPEAKING_VIDEO_FILES_PATH + sp1_result
sp1_video_path = firebase_file_path url = upload_file_firebase_get_url(FIREBASE_BUCKET, firebase_file_path, sound_file_path)
sp1_video_url = url video = {
template["exercises"][0]["text"] = exercise_1["question"] "text": question,
template["exercises"][0]["title"] = exercise_1["topic"] "video_path": firebase_file_path,
template["exercises"][0]["video_url"] = sp1_video_url "video_url": url
template["exercises"][0]["video_path"] = sp1_video_path }
else: sp1_questions.append(video)
app.app.logger.error("Failed to create video for part 1 question: " + exercise_1["question"]) else:
app.app.logger.error("Failed to create video for part 1 question: " + exercise_1["question"])
template["exercises"][0]["prompts"] = sp1_questions
template["exercises"][0]["first_title"] = exercise_1["first_topic"]
template["exercises"][0]["second_title"] = exercise_1["second_topic"]
# Speaking 2 # Speaking 2
# Using list comprehension to find the element with the desired value in the 'type' field # Using list comprehension to find the element with the desired value in the 'type' field
@@ -57,7 +63,7 @@ def create_videos_and_save_to_db(exercises, template, id):
if found_exercises_2: if found_exercises_2:
exercise_2 = found_exercises_2[0] exercise_2 = found_exercises_2[0]
app.app.logger.info('Creating video for speaking part 2') app.app.logger.info('Creating video for speaking part 2')
sp2_result = create_video(exercise_2["question"], random.choice(list(AvatarEnum))) sp2_result = create_video(exercise_2["question"], avatar)
if sp2_result is not None: if sp2_result is not None:
sound_file_path = VIDEO_FILES_PATH + sp2_result sound_file_path = VIDEO_FILES_PATH + sp2_result
firebase_file_path = FIREBASE_SPEAKING_VIDEO_FILES_PATH + sp2_result firebase_file_path = FIREBASE_SPEAKING_VIDEO_FILES_PATH + sp2_result
@@ -79,7 +85,6 @@ def create_videos_and_save_to_db(exercises, template, id):
if found_exercises_3: if found_exercises_3:
exercise_3 = found_exercises_3[0] exercise_3 = found_exercises_3[0]
sp3_questions = [] sp3_questions = []
avatar = random.choice(list(AvatarEnum))
app.app.logger.info('Creating videos for speaking part 3') app.app.logger.info('Creating videos for speaking part 3')
for question in exercise_3["questions"]: for question in exercise_3["questions"]:
result = create_video(question, avatar) result = create_video(question, avatar)

View File

@@ -1136,12 +1136,11 @@ def getSpeakingTemplate():
"exercises": [ "exercises": [
{ {
"id": str(uuid.uuid4()), "id": str(uuid.uuid4()),
"prompts": [], "prompts": ["questions"],
"text": "text", "text": "Listen carefully and respond.",
"title": "topic", "first_title": "first_topic",
"video_url": "sp1_video_url", "second_title": "second_topic",
"video_path": "sp1_video_path", "type": "interactiveSpeaking"
"type": "speaking"
}, },
{ {
"id": str(uuid.uuid4()), "id": str(uuid.uuid4()),