Endpoint generate reading kinda working.
This commit is contained in:
186
app.py
186
app.py
@@ -1,25 +1,23 @@
|
|||||||
|
import random
|
||||||
|
|
||||||
from flask import Flask, request
|
from flask import Flask, request
|
||||||
from flask_jwt_extended import JWTManager, jwt_required
|
from flask_jwt_extended import JWTManager, jwt_required
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
import firebase_admin
|
from helper.api_messages import *
|
||||||
from firebase_admin import credentials, firestore
|
from helper.constants import *
|
||||||
from helper.api_messages import QuestionType, get_grading_messages, get_question_gen_messages, get_question_tips, \
|
from helper.exercises import *
|
||||||
get_speaking_grading_messages
|
|
||||||
from helper.file_helper import delete_files_older_than_one_day
|
from helper.file_helper import delete_files_older_than_one_day
|
||||||
from helper.firebase_helper import download_firebase_file, upload_file_firebase, upload_file_firebase_get_url, \
|
from helper.firebase_helper import *
|
||||||
save_to_db
|
|
||||||
from helper.heygen_api import create_video
|
from helper.heygen_api import create_video
|
||||||
from helper.speech_to_text_helper import speech_to_text, text_to_speech, has_words, has_10_words
|
from helper.speech_to_text_helper import *
|
||||||
from helper.token_counter import count_tokens
|
from helper.token_counter import count_tokens
|
||||||
from helper.openai_interface import make_openai_call
|
from helper.openai_interface import make_openai_call, make_openai_instruct_call
|
||||||
import os
|
import os
|
||||||
import uuid
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
from templates.question_templates import getListening1Template, getListening2Template, getSpeaking1Template, \
|
from templates.question_templates import *
|
||||||
getSpeaking2Template, getSpeaking3Template
|
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
@@ -32,22 +30,6 @@ jwt = JWTManager(app)
|
|||||||
cred = credentials.Certificate(os.getenv("GOOGLE_APPLICATION_CREDENTIALS"))
|
cred = credentials.Certificate(os.getenv("GOOGLE_APPLICATION_CREDENTIALS"))
|
||||||
firebase_admin.initialize_app(cred)
|
firebase_admin.initialize_app(cred)
|
||||||
|
|
||||||
GRADING_TEMPERATURE = 0.1
|
|
||||||
TIPS_TEMPERATURE = 0.2
|
|
||||||
GEN_QUESTION_TEMPERATURE = 0.9
|
|
||||||
GPT_3_5_TURBO = "gpt-3.5-turbo"
|
|
||||||
GPT_3_5_TURBO_16K = "gpt-3.5-turbo-16k"
|
|
||||||
GRADING_FIELDS = ['comment', 'overall', 'task_response']
|
|
||||||
GEN_FIELDS = ['question']
|
|
||||||
LISTENING_GEN_FIELDS = ['transcript', 'exercise']
|
|
||||||
|
|
||||||
FIREBASE_BUCKET = 'mti-ielts.appspot.com'
|
|
||||||
AUDIO_FILES_PATH = 'download-audio/'
|
|
||||||
FIREBASE_LISTENING_AUDIO_FILES_PATH = 'listening_recordings/'
|
|
||||||
|
|
||||||
VIDEO_FILES_PATH = 'download-video/'
|
|
||||||
FIREBASE_SPEAKING_VIDEO_FILES_PATH = 'speaking_videos/'
|
|
||||||
|
|
||||||
@app.route('/listening_section_1', methods=['GET'])
|
@app.route('/listening_section_1', methods=['GET'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def get_listening_section_1_question():
|
def get_listening_section_1_question():
|
||||||
@@ -61,6 +43,7 @@ def get_listening_section_1_question():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/save_listening_section_1', methods=['POST'])
|
@app.route('/save_listening_section_1', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def save_listening_section_1_question():
|
def save_listening_section_1_question():
|
||||||
@@ -97,6 +80,7 @@ def get_listening_section_2_question():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/save_listening_section_2', methods=['POST'])
|
@app.route('/save_listening_section_2', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def save_listening_section_2_question():
|
def save_listening_section_2_question():
|
||||||
@@ -132,6 +116,7 @@ def get_listening_section_3_question():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/save_listening_section_3', methods=['POST'])
|
@app.route('/save_listening_section_3', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def save_listening_section_3_question():
|
def save_listening_section_3_question():
|
||||||
@@ -167,6 +152,7 @@ def get_listening_section_4_question():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/save_listening_section_4', methods=['POST'])
|
@app.route('/save_listening_section_4', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def save_listening_section_4_question():
|
def save_listening_section_4_question():
|
||||||
@@ -216,6 +202,24 @@ def grade_writing_task_1():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/writing_task1_general', methods=['GET'])
|
||||||
|
@jwt_required()
|
||||||
|
def get_writing_task_1_general_question():
|
||||||
|
try:
|
||||||
|
gen_wt1_question = "Craft a prompt for an IELTS Writing Task 1 General Training exercise that instructs the " \
|
||||||
|
"student to compose a letter. The prompt should present a specific scenario or situation, " \
|
||||||
|
"requiring the student to provide information, advice, or instructions within the letter."
|
||||||
|
token_count = count_tokens(gen_wt1_question)["n_tokens"]
|
||||||
|
response = make_openai_instruct_call(GPT_3_5_TURBO_INSTRUCT, gen_wt1_question, token_count, None,
|
||||||
|
GEN_QUESTION_TEMPERATURE)
|
||||||
|
return {
|
||||||
|
"question": response.strip()
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/save_writing_task_1', methods=['POST'])
|
@app.route('/save_writing_task_1', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def save_writing_task_1_question():
|
def save_writing_task_1_question():
|
||||||
@@ -259,18 +263,26 @@ def grade_writing_task_2():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
@app.route('/writing_task2', methods=['GET'])
|
|
||||||
|
@app.route('/writing_task2_general', methods=['GET'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def get_writing_task_2_question():
|
def get_writing_task_2_general_question():
|
||||||
try:
|
try:
|
||||||
messages = get_question_gen_messages(QuestionType.WRITING_TASK_2)
|
gen_wt2_question = "Craft a comprehensive question for IELTS Writing Task 2 General Training that directs the candidate " \
|
||||||
token_count = reduce(lambda count, item: count + count_tokens(item)['n_tokens'],
|
"to delve into an in-depth analysis of contrasting perspectives on a specific topic. The candidate " \
|
||||||
map(lambda x: x["content"], filter(lambda x: "content" in x, messages)), 0)
|
"should be asked to discuss the strengths and weaknesses of both viewpoints, provide evidence or " \
|
||||||
response = make_openai_call(GPT_3_5_TURBO, messages, token_count, GEN_FIELDS, GEN_QUESTION_TEMPERATURE)
|
"examples, and present a well-rounded argument before concluding with their personal opinion on the " \
|
||||||
return response
|
"subject."
|
||||||
|
token_count = count_tokens(gen_wt2_question)["n_tokens"]
|
||||||
|
response = make_openai_instruct_call(GPT_3_5_TURBO_INSTRUCT, gen_wt2_question, token_count, None,
|
||||||
|
GEN_QUESTION_TEMPERATURE)
|
||||||
|
return {
|
||||||
|
"question": response.strip()
|
||||||
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/save_writing_task_2', methods=['POST'])
|
@app.route('/save_writing_task_2', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def save_writing_task_2_question():
|
def save_writing_task_2_question():
|
||||||
@@ -325,14 +337,19 @@ def grade_speaking_task_1():
|
|||||||
@jwt_required()
|
@jwt_required()
|
||||||
def get_speaking_task_1_question():
|
def get_speaking_task_1_question():
|
||||||
try:
|
try:
|
||||||
messages = get_question_gen_messages(QuestionType.SPEAKING_1)
|
gen_sp1_question = "Craft a thought-provoking question for IELTS Speaking Part 1 that encourages candidates to delve deeply " \
|
||||||
token_count = reduce(lambda count, item: count + count_tokens(item)['n_tokens'],
|
"into personal experiences, preferences, or insights on diverse topics. Instruct the candidate to offer " \
|
||||||
map(lambda x: x["content"], filter(lambda x: "content" in x, messages)), 0)
|
"not only detailed descriptions but also provide nuanced explanations, examples, or anecdotes to enrich " \
|
||||||
response = make_openai_call(GPT_3_5_TURBO, messages, token_count, GEN_FIELDS, GEN_QUESTION_TEMPERATURE)
|
"their response." \
|
||||||
|
"Provide your response in this json format: {'topic': 'topic','question': 'question'}"
|
||||||
|
token_count = count_tokens(gen_sp1_question)["n_tokens"]
|
||||||
|
response = make_openai_instruct_call(GPT_3_5_TURBO_INSTRUCT, gen_sp1_question, token_count, GEN_FIELDS,
|
||||||
|
GEN_QUESTION_TEMPERATURE)
|
||||||
return response
|
return response
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/save_speaking_task_1', methods=['POST'])
|
@app.route('/save_speaking_task_1', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def save_speaking_task_1_question():
|
def save_speaking_task_1_question():
|
||||||
@@ -380,6 +397,7 @@ def save_speaking_task_1_question():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/speaking_task_2', methods=['POST'])
|
@app.route('/speaking_task_2', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def grade_speaking_task_2():
|
def grade_speaking_task_2():
|
||||||
@@ -419,14 +437,20 @@ def grade_speaking_task_2():
|
|||||||
@jwt_required()
|
@jwt_required()
|
||||||
def get_speaking_task_2_question():
|
def get_speaking_task_2_question():
|
||||||
try:
|
try:
|
||||||
messages = get_question_gen_messages(QuestionType.SPEAKING_2)
|
gen_sp2_question = "Create a question for IELTS Speaking Part 2 that encourages candidates to narrate a personal experience " \
|
||||||
token_count = reduce(lambda count, item: count + count_tokens(item)['n_tokens'],
|
"or story related to a randomly selected topic. Include 3 prompts that guide the candidate to describe " \
|
||||||
map(lambda x: x["content"], filter(lambda x: "content" in x, messages)), 0)
|
"specific aspects of the experience, such as details about the situation, their actions, and the " \
|
||||||
response = make_openai_call(GPT_3_5_TURBO, messages, token_count, GEN_FIELDS, GEN_QUESTION_TEMPERATURE)
|
"reasons it left a lasting impression." \
|
||||||
|
"Provide your response in this json format: {'topic': 'topic','question': 'question', " \
|
||||||
|
"'prompts': ['prompt_1', 'prompt_2', 'prompt_3']}"
|
||||||
|
token_count = count_tokens(gen_sp2_question)["n_tokens"]
|
||||||
|
response = make_openai_instruct_call(GPT_3_5_TURBO_INSTRUCT, gen_sp2_question, token_count, GEN_FIELDS,
|
||||||
|
GEN_QUESTION_TEMPERATURE)
|
||||||
return response
|
return response
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/save_speaking_task_2', methods=['POST'])
|
@app.route('/save_speaking_task_2', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def save_speaking_task_2_question():
|
def save_speaking_task_2_question():
|
||||||
@@ -474,6 +498,27 @@ def save_speaking_task_2_question():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/speaking_task_3', methods=['GET'])
|
||||||
|
@jwt_required()
|
||||||
|
def get_speaking_task_3_question():
|
||||||
|
try:
|
||||||
|
gen_sp3_question = "Formulate a set of 3 questions for IELTS Speaking Part 3 that encourage candidates to engage in a " \
|
||||||
|
"meaningful discussion on a particular topic. Provide inquiries, ensuring " \
|
||||||
|
"they explore various aspects, perspectives, and implications related to the topic." \
|
||||||
|
"Provide your response in this json format: {'topic': 'topic','questions': ['question', " \
|
||||||
|
"'question', 'question']}"
|
||||||
|
token_count = count_tokens(gen_sp3_question)["n_tokens"]
|
||||||
|
response = make_openai_instruct_call(GPT_3_5_TURBO_INSTRUCT, gen_sp3_question, token_count, GEN_FIELDS,
|
||||||
|
GEN_QUESTION_TEMPERATURE)
|
||||||
|
# Remove the numbers from the questions only if the string starts with a number
|
||||||
|
response["questions"] = [re.sub(r"^\d+\.\s*", "", question) if re.match(r"^\d+\.", question) else question for
|
||||||
|
question in response["questions"]]
|
||||||
|
return response
|
||||||
|
except Exception as e:
|
||||||
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/speaking_task_3', methods=['POST'])
|
@app.route('/speaking_task_3', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def grade_speaking_task_3():
|
def grade_speaking_task_3():
|
||||||
@@ -508,6 +553,7 @@ def grade_speaking_task_3():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e), 400
|
return str(e), 400
|
||||||
|
|
||||||
|
|
||||||
@app.route('/save_speaking_task_3', methods=['POST'])
|
@app.route('/save_speaking_task_3', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def save_speaking_task_3_question():
|
def save_speaking_task_3_question():
|
||||||
@@ -555,6 +601,61 @@ def save_speaking_task_3_question():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/reading_passage_1', methods=['GET'])
|
||||||
|
@jwt_required()
|
||||||
|
def get_reading_passage_1_question():
|
||||||
|
try:
|
||||||
|
TOTAL_EXERCISES = 13
|
||||||
|
|
||||||
|
# Extract parameters from the URL query string
|
||||||
|
topic = request.args.get('topic', default=random.choice(topics))
|
||||||
|
req_exercises = request.args.getlist('exercises')
|
||||||
|
|
||||||
|
number_of_exercises_q = divide_number_into_parts(TOTAL_EXERCISES, len(req_exercises))
|
||||||
|
|
||||||
|
passage = generate_reading_passage(QuestionType.READING_PASSAGE_1, topic)
|
||||||
|
exercises = []
|
||||||
|
|
||||||
|
for req_exercise in req_exercises:
|
||||||
|
if (req_exercise == "multiple_choice"):
|
||||||
|
mc_question = gen_multiple_choice_exercise(passage["text"], number_of_exercises_q.get())
|
||||||
|
exercises.append(mc_question)
|
||||||
|
|
||||||
|
exercises = fix_exercise_ids(exercises)
|
||||||
|
return {
|
||||||
|
"exercises": exercises,
|
||||||
|
"text": {
|
||||||
|
"content": passage["text"],
|
||||||
|
"title": passage["title"]
|
||||||
|
},
|
||||||
|
}
|
||||||
|
except Exception as e:
|
||||||
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
|
@app.route('/reading_passage_1', methods=['POST'])
|
||||||
|
@jwt_required()
|
||||||
|
def save_reading_passage_1_question():
|
||||||
|
try:
|
||||||
|
# data = request.get_json()
|
||||||
|
# question = data.get('question')
|
||||||
|
question = getListening1Template()
|
||||||
|
file_name = str(uuid.uuid4()) + ".mp3"
|
||||||
|
sound_file_path = AUDIO_FILES_PATH + file_name
|
||||||
|
firebase_file_path = FIREBASE_LISTENING_AUDIO_FILES_PATH + file_name
|
||||||
|
# TODO it's the conversation audio, still work to do on text-to-speech
|
||||||
|
text_to_speech(question["audio"]["conversation"], sound_file_path)
|
||||||
|
file_url = upload_file_firebase_get_url(FIREBASE_BUCKET, firebase_file_path, sound_file_path)
|
||||||
|
question["audio"]["source"] = file_url
|
||||||
|
if save_to_db("listening", question):
|
||||||
|
return question
|
||||||
|
else:
|
||||||
|
raise Exception("Failed to save question: " + question)
|
||||||
|
except Exception as e:
|
||||||
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route('/fetch_tips', methods=['POST'])
|
@app.route('/fetch_tips', methods=['POST'])
|
||||||
@jwt_required()
|
@jwt_required()
|
||||||
def fetch_answer_tips():
|
def fetch_answer_tips():
|
||||||
@@ -576,5 +677,6 @@ def fetch_answer_tips():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
app.run()
|
app.run()
|
||||||
|
|||||||
@@ -2033,7 +2033,7 @@ new_reading_to_insert_1 = {
|
|||||||
],
|
],
|
||||||
"prompt": "Which of the following sources is NOT mentioned as a renewable energy source?",
|
"prompt": "Which of the following sources is NOT mentioned as a renewable energy source?",
|
||||||
"solution": "B",
|
"solution": "B",
|
||||||
"variant": "text",
|
"variant": "text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "11",
|
"id": "11",
|
||||||
@@ -2963,7 +2963,8 @@ new_reading_to_insert_2 = {
|
|||||||
"solutions": [
|
"solutions": [
|
||||||
{
|
{
|
||||||
"id": "24",
|
"id": "24",
|
||||||
"solution": ["Task switching", "Attention management", "Inhibition of distractions", "Cognitive flexibility"]
|
"solution": ["Task switching", "Attention management", "Inhibition of distractions",
|
||||||
|
"Cognitive flexibility"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "25",
|
"id": "25",
|
||||||
@@ -3081,7 +3082,8 @@ new_reading_to_insert_2 = {
|
|||||||
"imperative to strike a balance between the benefits and {{34}} posed by social media "
|
"imperative to strike a balance between the benefits and {{34}} posed by social media "
|
||||||
"in contemporary society.",
|
"in contemporary society.",
|
||||||
"type": "fillBlanks",
|
"type": "fillBlanks",
|
||||||
"words": ["cyberbullying", "internet", "trade", "Privacy", "addictive", "resilience", "connectivity", "echo",
|
"words": ["cyberbullying", "internet", "trade", "Privacy", "addictive", "resilience",
|
||||||
|
"connectivity", "echo",
|
||||||
"challenges", "adaptability", "digital", "Social", "harsh"]
|
"challenges", "adaptability", "digital", "Social", "harsh"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -3638,7 +3640,8 @@ new_reading_to_insert_3 = {
|
|||||||
"solutions": [
|
"solutions": [
|
||||||
{
|
{
|
||||||
"id": "24",
|
"id": "24",
|
||||||
"solution": ["Task switching", "Attention management", "Inhibition of distractions", "Cognitive flexibility"]
|
"solution": ["Task switching", "Attention management", "Inhibition of distractions",
|
||||||
|
"Cognitive flexibility"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "25",
|
"id": "25",
|
||||||
@@ -3756,7 +3759,8 @@ new_reading_to_insert_3 = {
|
|||||||
"imperative to strike a balance between the benefits and {{34}} posed by social media "
|
"imperative to strike a balance between the benefits and {{34}} posed by social media "
|
||||||
"in contemporary society.",
|
"in contemporary society.",
|
||||||
"type": "fillBlanks",
|
"type": "fillBlanks",
|
||||||
"words": ["cyberbullying", "internet", "trade", "Privacy", "addictive", "resilience", "connectivity", "echo",
|
"words": ["cyberbullying", "internet", "trade", "Privacy", "addictive", "resilience",
|
||||||
|
"connectivity", "echo",
|
||||||
"challenges", "adaptability", "digital", "Social", "harsh"]
|
"challenges", "adaptability", "digital", "Social", "harsh"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -5423,6 +5427,657 @@ new_listening_to_insert_2 = {
|
|||||||
"minTimer": 30,
|
"minTimer": 30,
|
||||||
"module": "listening"
|
"module": "listening"
|
||||||
}
|
}
|
||||||
|
new_listening_to_insert_3 = {
|
||||||
|
"parts": [
|
||||||
|
{
|
||||||
|
"audio": {
|
||||||
|
"repeatableTimes": 3,
|
||||||
|
"source": "https://firebasestorage.googleapis.com/v0/b/mti-ielts.appspot.com/o/listening_recordings%2Ftoms_auto_repairs.mp3?alt=media&token=d88b9e6c-8ff3-4a62-9026-283202c1ba85"
|
||||||
|
},
|
||||||
|
"exercises": [
|
||||||
|
{
|
||||||
|
"id": str(uuid.uuid4()),
|
||||||
|
"maxWords": 4,
|
||||||
|
"prompt": "You will hear a conversation between a woman and a mechanic. Answer the questions "
|
||||||
|
"below using no more than four words or a number.",
|
||||||
|
"solutions": [
|
||||||
|
{
|
||||||
|
"id": "1",
|
||||||
|
"solution": ["Tom's Auto Repair"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "2",
|
||||||
|
"solution": ["Sarah", "Sara"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "3",
|
||||||
|
"solution": ["clicking"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "4",
|
||||||
|
"solution": ["engine"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "5",
|
||||||
|
"solution": ["Honda Civic"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "6",
|
||||||
|
"solution": ["2016"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "7",
|
||||||
|
"solution": ["Thursday"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "8",
|
||||||
|
"solution": ["3PM", "3 PM", "3:00 PM"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "9",
|
||||||
|
"solution": ["No"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "10",
|
||||||
|
"solution": ["Car Keys and Documents"]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Auto Repair Shop Name: {{1}}\\n"
|
||||||
|
"Client Name: {{2}}\\n"
|
||||||
|
"Type of noise: {{3}}\\n"
|
||||||
|
"Lights On: {{4}}\\n"
|
||||||
|
"Car: {{5}}\\n"
|
||||||
|
"Year of Manufacturing: {{6}}\\n"
|
||||||
|
"Appointment Day Of Week: {{7}}\\n"
|
||||||
|
"Time of appointment: {{8}}\\n"
|
||||||
|
"Has warranties? {{9}}\\n"
|
||||||
|
"Should bring: {{10}}\\n",
|
||||||
|
"type": "writeBlanks"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"audio": {
|
||||||
|
"repeatableTimes": 3,
|
||||||
|
"source": "https://firebasestorage.googleapis.com/v0/b/mti-ielts.appspot.com/o/listening_recordings%2Ffirst_day_school.mp3?alt=media&token=318ccb58-42fb-465c-b2d7-becd9cb360ee"
|
||||||
|
},
|
||||||
|
"exercises": [
|
||||||
|
{
|
||||||
|
"id": str(uuid.uuid4()),
|
||||||
|
"prompt": "After listening to the monologue, select the appropriate options.",
|
||||||
|
"questions": [
|
||||||
|
{
|
||||||
|
"id": "11",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "To introduce school rules and regulations."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "To welcome students to a new school year."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "To discuss the importance of technology in education."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "To explain the structure of extracurricular clubs."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "What is the primary purpose of the monologue?",
|
||||||
|
"solution": "B",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "12",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "It solely focuses on mathematics and science."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "It promotes critical thinking, creativity, and problem-solving."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "It discourages students from asking questions."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "It limits students' involvement in extracurricular activities."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "In the monologue, what does the speaker emphasize about the school's curriculum?",
|
||||||
|
"solution": "B",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "13",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Drama club."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Astronomy club."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Robotics club."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Literature club."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "Which of the following is NOT mentioned as an extracurricular activity in the monologue?",
|
||||||
|
"solution": "D",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "14",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "To restrict students' individuality."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "To create a sense of unity and belonging."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "To make students look sharp at all times."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "To discourage students from attending extracurricular activities."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "According to the monologue, why does the school have a dress code and uniform?",
|
||||||
|
"solution": "B",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "15",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Families are not supportive of students' education."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Families should not be involved in students' school life."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Families are important in guiding and supporting students."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Families hinder students' ability to make friends."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "What does the monologue suggest about the role of family in a student's life?",
|
||||||
|
"solution": "C",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "16",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Seeking knowledge, asking questions, and embracing diversity."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Following strict rules without question."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Focusing solely on academic achievements."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Avoiding extracurricular activities to prioritize academics."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "According to the monologue, what does the school encourage in students?",
|
||||||
|
"solution": "A",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "17",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Students should focus on academic studies only."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Participation in clubs and activities is discouraged."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Students have a range of opportunities to pursue their passions."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Clubs are only for those interested in music and drama."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "What is the primary message in the section about clubs and extracurricular activities?",
|
||||||
|
"solution": "C",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "18",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "They are essential for exploring the digital world and developing skills."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "They are mainly used for playing games."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "They help students avoid human interaction."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "They limit students' creativity."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "According to the monologue, what is the importance of the school's technology resources?",
|
||||||
|
"solution": "A",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "19",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Bullying is encouraged to toughen up students."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Bullying is not mentioned in the monologue."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Bullying is strictly prohibited with a zero-tolerance policy."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Bullying is seen as a natural part of school life."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "In the monologue, how is the school's approach to bullying described?",
|
||||||
|
"solution": "C",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "20",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Students should avoid making friends and focus solely on academics."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Students should embrace a well-rounded education, involvement in clubs, and respect for one another."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Students should never ask questions and follow rules blindly."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Students should avoid participating in extracurricular activities to prioritize academics."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "What is the speaker's main message to students throughout the monologue?",
|
||||||
|
"solution": "B",
|
||||||
|
"variant": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "multipleChoice",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"audio": {
|
||||||
|
"repeatableTimes": 3,
|
||||||
|
"source": "https://firebasestorage.googleapis.com/v0/b/mti-ielts.appspot.com/o/listening_recordings%2Fgym_training_conversation.mp3?alt=media&token=169757de-dbd9-4aeb-9bd6-3a470898cd34"
|
||||||
|
},
|
||||||
|
"exercises": [
|
||||||
|
{
|
||||||
|
"id": str(uuid.uuid4()),
|
||||||
|
"prompt": "After listening to the conversation, select the appropriate options.",
|
||||||
|
"questions": [
|
||||||
|
{
|
||||||
|
"id": "21",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Upper body strength."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Cardiovascular endurance."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Flexibility."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Core stability."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "What aspect of his fitness is Alex primarily looking to improve?",
|
||||||
|
"solution": "C",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "22",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "By doing only weightlifting."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "With a mix of cardio and flexibility training."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "By following a strict diet without exercise."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "With exclusively long-distance running."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "How is Linda preparing for her 10K run?",
|
||||||
|
"solution": "B",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "23",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Yoga."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Pilates."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "HIIT workouts."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Swimming."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "What type of training is Mark incorporating into his routine?",
|
||||||
|
"solution": "C",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "24",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Bench presses and rows."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Leg curls and lunges."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Bicep curls and tricep dips."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Planks and push-ups."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "What specific strength training exercises is Alex focusing on?",
|
||||||
|
"solution": "A",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "25",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Finishing under 1 hour."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Completing in under 45 minutes."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Finishing under 50 minutes."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Setting a personal best time."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "What is Linda's specific time goal for her upcoming 10K run?",
|
||||||
|
"solution": "C",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "26",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Gaining muscle mass."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Increasing flexibility."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Losing weight and achieving more defined abs and arms."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Improving running endurance."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "Mark's fitness goal includes:",
|
||||||
|
"solution": "C",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "27",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Short-term training plans."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Quick fixes and shortcuts."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Consistency and hard work."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Frequent changes in workout routines."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "What does the trainer emphasize as a key to success in reaching fitness goals?",
|
||||||
|
"solution": "C",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "28",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Increase caloric intake."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Focus on strength training only."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Create a calorie deficit and introduce core-focused workouts."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Avoid exercise altogether."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "What does the trainer suggest for Mark to help him shed pounds?",
|
||||||
|
"solution": "C",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "29",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "It doesn't emphasize the importance of goal setting."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "The conversation shows that setting specific goals is crucial for tracking progress."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "It implies that goals are only necessary for professional athletes."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "The trainer discourages goal setting for a balanced fitness routine."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "How does the conversation highlight the importance of setting goals?",
|
||||||
|
"solution": "B",
|
||||||
|
"variant": "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "30",
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"id": "A",
|
||||||
|
"text": "Promoting quick fixes for weight loss."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "B",
|
||||||
|
"text": "Highlighting the need for exclusive weightlifting."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "C",
|
||||||
|
"text": "Providing personalized advice to help individuals reach their fitness goals."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "D",
|
||||||
|
"text": "Discouraging cardio exercises."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"prompt": "In the conversation, what is the primary focus of the trainer's guidance?",
|
||||||
|
"solution": "C",
|
||||||
|
"variant": "text"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "multipleChoice",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"audio": {
|
||||||
|
"repeatableTimes": 3,
|
||||||
|
"source": "https://firebasestorage.googleapis.com/v0/b/mti-ielts.appspot.com/o/listening_recordings%2Fcultural_appropriation.mp3?alt=media&token=1f298ad9-6c3e-4c49-9337-12f772ae2121"
|
||||||
|
},
|
||||||
|
"exercises": [
|
||||||
|
{
|
||||||
|
"id": str(uuid.uuid4()),
|
||||||
|
"maxWords": 3,
|
||||||
|
"prompt": "You will hear a lecture about international finance. Complete the notes bellow. Write no more "
|
||||||
|
"than 3 words or numbers for each answer.",
|
||||||
|
"solutions": [
|
||||||
|
{
|
||||||
|
"id": "31",
|
||||||
|
"solution": ["culture"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "32",
|
||||||
|
"solution": ["dominant "]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "33",
|
||||||
|
"solution": ["diversity"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "34",
|
||||||
|
"solution": ["borrowing"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "35",
|
||||||
|
"solution": ["Power"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "36",
|
||||||
|
"solution": ["stereotypes"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "37",
|
||||||
|
"solution": ["loss"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "38",
|
||||||
|
"solution": ["understanding"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "39",
|
||||||
|
"solution": ["sensitivity"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "40",
|
||||||
|
"solution": ["respectful "]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"text": "Cultural appropriation is a controversial topic because it involves the adoption or use of elements from another {{31}}.\\n"
|
||||||
|
"Cultural appropriation becomes problematic when elements are borrowed from a marginalized culture by those from a {{32}} culture.\\n"
|
||||||
|
"Cultural exchange is essential for cultural {{33}}, but appropriation raises concerns about respect and understanding.\\n"
|
||||||
|
"Cultural appropriation is more than just cultural {{34}}; it has far-reaching social and ethical implications.\\n"
|
||||||
|
"{{35}} dynamics play a crucial role in cultural appropriation, as the appropriator often hails from a dominant culture.\\n"
|
||||||
|
"When cultural elements are commodified without acknowledging their significance, they risk perpetuating {{36}}.\\n"
|
||||||
|
"Erasure of marginalized cultures is a significant concern because it can lead to the {{37}} of cultural identity.\\n"
|
||||||
|
"The line between cultural appropriation and appreciation is not always clear-cut and depends on intent, context and {{38}}.\\n"
|
||||||
|
"The ongoing debate on cultural appropriation reflects broader conversations on cultural {{39}}.\\n"
|
||||||
|
"Fostering a deeper understanding of cultural appropriation is essential for promoting {{40}} cross-cultural interactions\\n",
|
||||||
|
"type": "writeBlanks"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"isDiagnostic": False,
|
||||||
|
"minTimer": 30,
|
||||||
|
"module": "listening"
|
||||||
|
}
|
||||||
|
|
||||||
# Falta section 3 e 4 do listening
|
# Falta section 3 e 4 do listening
|
||||||
# writing task 1 com imagens ...
|
# writing task 1 com imagens ...
|
||||||
@@ -5435,5 +6090,5 @@ db = firestore.client()
|
|||||||
|
|
||||||
# Add the JSON data to Firestore
|
# Add the JSON data to Firestore
|
||||||
collection_ref = db.collection('listening')
|
collection_ref = db.collection('listening')
|
||||||
document_ref = collection_ref.add(new_listening_to_insert_2)
|
document_ref = collection_ref.add(new_listening_to_insert_3)
|
||||||
print(f"Document added with ID: {document_ref}")
|
print(f"Document added with ID: {document_ref}")
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ class QuestionType(Enum):
|
|||||||
WRITING_TASK_2 = "Writing Task 2"
|
WRITING_TASK_2 = "Writing Task 2"
|
||||||
SPEAKING_1 = "Speaking Task Part 1"
|
SPEAKING_1 = "Speaking Task Part 1"
|
||||||
SPEAKING_2 = "Speaking Task Part 2"
|
SPEAKING_2 = "Speaking Task Part 2"
|
||||||
|
READING_PASSAGE_1 = "Reading Passage 1"
|
||||||
|
READING_PASSAGE_2 = "Reading Passage 2"
|
||||||
|
READING_PASSAGE_3 = "Reading Passage 3"
|
||||||
|
|
||||||
|
class ExerciseType(Enum):
|
||||||
|
MULTIPLE_CHOICE = "multiple choice"
|
||||||
|
|
||||||
|
|
||||||
def get_grading_messages(question_type: QuestionType, question: str, answer: str, context: str = None):
|
def get_grading_messages(question_type: QuestionType, question: str, answer: str, context: str = None):
|
||||||
|
|||||||
120
helper/constants.py
Normal file
120
helper/constants.py
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
GRADING_TEMPERATURE = 0.1
|
||||||
|
TIPS_TEMPERATURE = 0.2
|
||||||
|
GEN_QUESTION_TEMPERATURE = 0.7
|
||||||
|
GPT_3_5_TURBO = "gpt-3.5-turbo"
|
||||||
|
GPT_3_5_TURBO_16K = "gpt-3.5-turbo-16k"
|
||||||
|
GPT_3_5_TURBO_INSTRUCT = "gpt-3.5-turbo-instruct"
|
||||||
|
GRADING_FIELDS = ['comment', 'overall', 'task_response']
|
||||||
|
GEN_FIELDS = ['topic']
|
||||||
|
GEN_TEXT_FIELDS = ['title']
|
||||||
|
LISTENING_GEN_FIELDS = ['transcript', 'exercise']
|
||||||
|
|
||||||
|
FIREBASE_BUCKET = 'mti-ielts.appspot.com'
|
||||||
|
AUDIO_FILES_PATH = 'download-audio/'
|
||||||
|
FIREBASE_LISTENING_AUDIO_FILES_PATH = 'listening_recordings/'
|
||||||
|
|
||||||
|
VIDEO_FILES_PATH = 'download-video/'
|
||||||
|
FIREBASE_SPEAKING_VIDEO_FILES_PATH = 'speaking_videos/'
|
||||||
|
|
||||||
|
topics = [
|
||||||
|
"Art and Creativity",
|
||||||
|
"History of Ancient Civilizations",
|
||||||
|
"Environmental Conservation",
|
||||||
|
"Space Exploration",
|
||||||
|
"Artificial Intelligence",
|
||||||
|
"Climate Change",
|
||||||
|
"World Religions",
|
||||||
|
"The Human Brain",
|
||||||
|
"Renewable Energy",
|
||||||
|
"Cultural Diversity",
|
||||||
|
"Modern Technology Trends",
|
||||||
|
"Women's Rights",
|
||||||
|
"Sustainable Agriculture",
|
||||||
|
"Globalization",
|
||||||
|
"Natural Disasters",
|
||||||
|
"Cybersecurity",
|
||||||
|
"Philosophy of Ethics",
|
||||||
|
"Robotics",
|
||||||
|
"Health and Wellness",
|
||||||
|
"Literature and Classics",
|
||||||
|
"World Geography",
|
||||||
|
"Music and Its Influence",
|
||||||
|
"Human Rights",
|
||||||
|
"Social Media Impact",
|
||||||
|
"Food Sustainability",
|
||||||
|
"Economics and Markets",
|
||||||
|
"Human Evolution",
|
||||||
|
"Political Systems",
|
||||||
|
"Mental Health Awareness",
|
||||||
|
"Quantum Physics",
|
||||||
|
"Biodiversity",
|
||||||
|
"Education Reform",
|
||||||
|
"Animal Rights",
|
||||||
|
"The Industrial Revolution",
|
||||||
|
"Future of Work",
|
||||||
|
"Film and Cinema",
|
||||||
|
"Genetic Engineering",
|
||||||
|
"Ancient Mythology",
|
||||||
|
"Climate Policy",
|
||||||
|
"Space Travel",
|
||||||
|
"Renewable Energy Sources",
|
||||||
|
"Cultural Heritage Preservation",
|
||||||
|
"Modern Art Movements",
|
||||||
|
"Immigration Issues",
|
||||||
|
"Sustainable Transportation",
|
||||||
|
"The History of Medicine",
|
||||||
|
"Artificial Neural Networks",
|
||||||
|
"Climate Adaptation",
|
||||||
|
"Philosophy of Existence",
|
||||||
|
"Augmented Reality",
|
||||||
|
"Yoga and Meditation",
|
||||||
|
"Literary Genres",
|
||||||
|
"World Oceans",
|
||||||
|
"Gender Equality",
|
||||||
|
"Social Networking",
|
||||||
|
"Sustainable Fashion",
|
||||||
|
"International Trade",
|
||||||
|
"Prehistoric Era",
|
||||||
|
"Democracy and Governance",
|
||||||
|
"Postcolonial Literature",
|
||||||
|
"Geopolitics",
|
||||||
|
"Psychology and Behavior",
|
||||||
|
"Nanotechnology",
|
||||||
|
"Endangered Species",
|
||||||
|
"Education Technology",
|
||||||
|
"Renaissance Art",
|
||||||
|
"Renewable Energy Policy",
|
||||||
|
"Cultural Festivals",
|
||||||
|
"Modern Architecture",
|
||||||
|
"Climate Resilience",
|
||||||
|
"Artificial Life",
|
||||||
|
"Fitness and Nutrition",
|
||||||
|
"Classic Literature Adaptations",
|
||||||
|
"World History Wars",
|
||||||
|
"Ethical Dilemmas",
|
||||||
|
"Internet of Things (IoT)",
|
||||||
|
"Meditation Practices",
|
||||||
|
"Literary Symbolism",
|
||||||
|
"Marine Conservation",
|
||||||
|
"Social Justice Movements",
|
||||||
|
"Sustainable Tourism",
|
||||||
|
"International Finance",
|
||||||
|
"Ancient Philosophy",
|
||||||
|
"Cold War Era",
|
||||||
|
"Behavioral Economics",
|
||||||
|
"Space Colonization",
|
||||||
|
"Clean Energy Initiatives",
|
||||||
|
"Cultural Exchange",
|
||||||
|
"Modern Sculpture",
|
||||||
|
"Climate Mitigation",
|
||||||
|
"Artificial Intelligence Ethics",
|
||||||
|
"Mindfulness",
|
||||||
|
"Literary Criticism",
|
||||||
|
"Wildlife Conservation",
|
||||||
|
"Political Activism",
|
||||||
|
"Renewable Energy Innovations",
|
||||||
|
"History of Mathematics",
|
||||||
|
"Human-Computer Interaction",
|
||||||
|
"Global Health",
|
||||||
|
"Cultural Appropriation"
|
||||||
|
]
|
||||||
72
helper/exercises.py
Normal file
72
helper/exercises.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import queue
|
||||||
|
|
||||||
|
from helper.api_messages import QuestionType
|
||||||
|
from helper.openai_interface import make_openai_instruct_call
|
||||||
|
from helper.token_counter import count_tokens
|
||||||
|
from helper.constants import *
|
||||||
|
|
||||||
|
def divide_number_into_parts(number, parts):
|
||||||
|
if number < parts:
|
||||||
|
return None
|
||||||
|
|
||||||
|
part_size = number // parts
|
||||||
|
remaining = number % parts
|
||||||
|
|
||||||
|
q = queue.Queue()
|
||||||
|
|
||||||
|
for i in range(parts):
|
||||||
|
if i < remaining:
|
||||||
|
q.put(part_size + 1)
|
||||||
|
else:
|
||||||
|
q.put(part_size)
|
||||||
|
|
||||||
|
return q
|
||||||
|
|
||||||
|
def fix_exercise_ids(exercises):
|
||||||
|
# Initialize the starting ID for the first exercise
|
||||||
|
current_id = 1
|
||||||
|
|
||||||
|
# Iterate through exercises
|
||||||
|
for exercise in exercises:
|
||||||
|
questions = exercise["questions"]
|
||||||
|
|
||||||
|
# Iterate through questions and update the "id" value
|
||||||
|
for question in questions:
|
||||||
|
question["id"] = str(current_id)
|
||||||
|
current_id += 1
|
||||||
|
|
||||||
|
return exercises
|
||||||
|
|
||||||
|
|
||||||
|
def generate_reading_passage(type: QuestionType, topic: str):
|
||||||
|
gen_reading_passage_1 = "Generate an extensive text for IELTS " + type.READING_PASSAGE_1.value + ", of at least 1500 words, on the topic " \
|
||||||
|
"of " + topic + ". The passage should offer a substantial amount of " \
|
||||||
|
"information, analysis, or narrative " \
|
||||||
|
"relevant to the chosen subject matter. This text passage aims to serve as the primary reading " \
|
||||||
|
"section of an IELTS test, providing an in-depth and comprehensive exploration of the topic." \
|
||||||
|
"Provide your response in this json format: {'title': 'title of the text', 'text': 'generated text'}"
|
||||||
|
token_count = count_tokens(gen_reading_passage_1)["n_tokens"]
|
||||||
|
return make_openai_instruct_call(GPT_3_5_TURBO_INSTRUCT, gen_reading_passage_1, token_count, GEN_TEXT_FIELDS,
|
||||||
|
GEN_QUESTION_TEMPERATURE)
|
||||||
|
|
||||||
|
def gen_multiple_choice_exercise(text: str, quantity: int):
|
||||||
|
gen_multiple_choice_for_text = "Generate" + str(quantity) + "multiple choice questions for this text: " \
|
||||||
|
"'" + text + "'\n" \
|
||||||
|
"Use this format: 'questions': [{'id': '9', 'options': [{'id': 'A', 'text': " \
|
||||||
|
"'Economic benefits'}, {'id': 'B', 'text': 'Government regulations'}, {'id': 'C', 'text': " \
|
||||||
|
"'Concerns about climate change'}, {'id': 'D', 'text': 'Technological advancement'}], " \
|
||||||
|
"'prompt': 'What is the main reason for the shift towards renewable energy sources?', " \
|
||||||
|
"'solution': 'C', 'variant': 'text'}]"
|
||||||
|
token_count = count_tokens(gen_multiple_choice_for_text)["n_tokens"]
|
||||||
|
mc_questions = make_openai_instruct_call(GPT_3_5_TURBO_INSTRUCT, gen_multiple_choice_for_text, token_count,
|
||||||
|
None,
|
||||||
|
GEN_QUESTION_TEMPERATURE)
|
||||||
|
parse_mc_questions = "Parse this '" + mc_questions + "' into this json format: 'questions': [{'id': '9', 'options': [{'id': 'A', 'text': " \
|
||||||
|
"'Economic benefits'}, {'id': 'B', 'text': 'Government regulations'}, {'id': 'C', 'text': " \
|
||||||
|
"'Concerns about climate change'}, {'id': 'D', 'text': 'Technological advancement'}], " \
|
||||||
|
"'prompt': 'What is the main reason for the shift towards renewable energy sources?', " \
|
||||||
|
"'solution': 'C', 'variant': 'text'}]"
|
||||||
|
token_count = count_tokens(parse_mc_questions)["n_tokens"]
|
||||||
|
return make_openai_instruct_call(GPT_3_5_TURBO_INSTRUCT, parse_mc_questions, token_count,
|
||||||
|
["questions"],
|
||||||
|
GEN_QUESTION_TEMPERATURE)
|
||||||
@@ -8,7 +8,6 @@ from dotenv import load_dotenv
|
|||||||
load_dotenv()
|
load_dotenv()
|
||||||
openai.api_key = os.getenv("OPENAI_API_KEY")
|
openai.api_key = os.getenv("OPENAI_API_KEY")
|
||||||
|
|
||||||
|
|
||||||
MAX_TOKENS = 4097
|
MAX_TOKENS = 4097
|
||||||
TOP_P = 0.9
|
TOP_P = 0.9
|
||||||
FREQUENCY_PENALTY = 0.5
|
FREQUENCY_PENALTY = 0.5
|
||||||
@@ -16,6 +15,7 @@ FREQUENCY_PENALTY = 0.5
|
|||||||
TRY_LIMIT = 1
|
TRY_LIMIT = 1
|
||||||
|
|
||||||
try_count = 0
|
try_count = 0
|
||||||
|
|
||||||
def process_response(input_string, quotation_check_field):
|
def process_response(input_string, quotation_check_field):
|
||||||
if '{' in input_string:
|
if '{' in input_string:
|
||||||
try:
|
try:
|
||||||
@@ -24,25 +24,42 @@ def process_response(input_string, quotation_check_field):
|
|||||||
# Extract everything after the first '{' (inclusive)
|
# Extract everything after the first '{' (inclusive)
|
||||||
result = input_string[index:]
|
result = input_string[index:]
|
||||||
if re.search(r"'" + quotation_check_field + "':\s*'(.*?)'", result, re.DOTALL | re.MULTILINE):
|
if re.search(r"'" + quotation_check_field + "':\s*'(.*?)'", result, re.DOTALL | re.MULTILINE):
|
||||||
parsed_string = result.replace("\"", "\\\"")
|
json_obj = json.loads(parse_string(result))
|
||||||
pattern = r"(?<!\w)'|'(?!\w)"
|
|
||||||
parsed_string = re.sub(pattern, '"', parsed_string)
|
|
||||||
parsed_string = parsed_string.replace("\\\"", "'")
|
|
||||||
parsed_string = parsed_string.replace("\n\n", " ")
|
|
||||||
|
|
||||||
json_obj = json.loads(parsed_string)
|
|
||||||
return json_obj
|
return json_obj
|
||||||
else:
|
else:
|
||||||
json_obj = json.loads(result)
|
parsed_string = result.replace("\n\n", " ")
|
||||||
|
json_obj = json.loads(parsed_string)
|
||||||
return json_obj
|
return json_obj
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Invalid JSON string! Exception: {e}")
|
print(f"Invalid JSON string! Exception: {e}")
|
||||||
else:
|
else:
|
||||||
return input_string
|
return input_string
|
||||||
|
|
||||||
|
def parse_string(to_parse: str):
|
||||||
|
parsed_string = to_parse.replace("\"", "\\\"")
|
||||||
|
pattern = r"(?<!\w)'|'(?!\w)"
|
||||||
|
parsed_string = re.sub(pattern, '"', parsed_string)
|
||||||
|
parsed_string = parsed_string.replace("\\\"", "'")
|
||||||
|
parsed_string = parsed_string.replace("\n\n", " ")
|
||||||
|
return parsed_string
|
||||||
|
|
||||||
|
|
||||||
|
def remove_special_chars_and_escapes(input_string):
|
||||||
|
parsed_string = input_string.replace("\\\"", "'")
|
||||||
|
parsed_string = parsed_string.replace("\n\n", " ")
|
||||||
|
# Define a regular expression pattern to match special characters and escapes
|
||||||
|
pattern = r'(\\[nrt])|[^a-zA-Z0-9\s]'
|
||||||
|
|
||||||
|
# Use re.sub() to replace the matched patterns with an empty string
|
||||||
|
cleaned_string = re.sub(pattern, '', parsed_string)
|
||||||
|
|
||||||
|
return cleaned_string
|
||||||
|
|
||||||
|
|
||||||
def check_fields(obj, fields):
|
def check_fields(obj, fields):
|
||||||
return all(field in obj for field in fields)
|
return all(field in obj for field in fields)
|
||||||
|
|
||||||
|
|
||||||
def make_openai_call(model, messages, token_count, fields_to_check, temperature):
|
def make_openai_call(model, messages, token_count, fields_to_check, temperature):
|
||||||
global try_count
|
global try_count
|
||||||
result = openai.ChatCompletion.create(
|
result = openai.ChatCompletion.create(
|
||||||
@@ -69,4 +86,26 @@ def make_openai_call(model, messages, token_count, fields_to_check, temperature)
|
|||||||
try_count = 0
|
try_count = 0
|
||||||
return processed_response
|
return processed_response
|
||||||
|
|
||||||
|
def make_openai_instruct_call(model, message: str, token_count, fields_to_check, temperature):
|
||||||
|
global try_count
|
||||||
|
response = openai.Completion.create(
|
||||||
|
model=model,
|
||||||
|
prompt=message,
|
||||||
|
max_tokens=int(4097 - token_count - 300),
|
||||||
|
temperature=0.7
|
||||||
|
)["choices"][0]["text"]
|
||||||
|
|
||||||
|
if fields_to_check is None:
|
||||||
|
return remove_special_chars_and_escapes(response)
|
||||||
|
|
||||||
|
processed_response = process_response(response, fields_to_check[0])
|
||||||
|
|
||||||
|
if check_fields(processed_response, fields_to_check) is False and try_count < TRY_LIMIT:
|
||||||
|
try_count = try_count + 1
|
||||||
|
return make_openai_instruct_call(model, message, token_count, fields_to_check, temperature)
|
||||||
|
elif try_count >= TRY_LIMIT:
|
||||||
|
try_count = 0
|
||||||
|
return remove_special_chars_and_escapes(response)
|
||||||
|
else:
|
||||||
|
try_count = 0
|
||||||
|
return processed_response
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ from helper.token_counter import count_tokens
|
|||||||
load_dotenv()
|
load_dotenv()
|
||||||
openai.api_key = os.getenv("OPENAI_API_KEY")
|
openai.api_key = os.getenv("OPENAI_API_KEY")
|
||||||
|
|
||||||
|
# https://chat.openai.com/share/195c4549-f67c-4353-be44-65c4d5ad5b05
|
||||||
|
|
||||||
question = "The average standard of people's health is likely to be lower in the future than it is now. To what extent do " \
|
question = "The average standard of people's health is likely to be lower in the future than it is now. To what extent do " \
|
||||||
"you agree or disagree with this statement?"
|
"you agree or disagree with this statement?"
|
||||||
answer = "I completely disagree with the written statement. I believe that most of the people in the world have more information " \
|
answer = "I completely disagree with the written statement. I believe that most of the people in the world have more information " \
|
||||||
@@ -32,6 +34,31 @@ answer = "I completely disagree with the written statement. I believe that most
|
|||||||
# map(lambda x: x["content"], filter(lambda x: "content" in x, messages)), 0)
|
# map(lambda x: x["content"], filter(lambda x: "content" in x, messages)), 0)
|
||||||
# response = make_openai_call("gpt-4", messages, token_count, GRADING_FIELDS, GRADING_TEMPERATURE)
|
# response = make_openai_call("gpt-4", messages, token_count, GRADING_FIELDS, GRADING_TEMPERATURE)
|
||||||
|
|
||||||
|
gen_wt1_question = "Craft a prompt for an IELTS Writing Task 1 General Training exercise that instructs the student to " \
|
||||||
|
"compose a letter. The prompt should present a specific scenario or situation, requiring the student " \
|
||||||
|
"to provide information, advice, or instructions within the letter."
|
||||||
|
|
||||||
|
gen_wt2_question = "Craft a comprehensive question for IELTS Writing Task 2 General Training that directs the candidate " \
|
||||||
|
"to delve into an in-depth analysis of contrasting perspectives on a specific topic. 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."
|
||||||
|
gen_sp1_question = "Craft a thought-provoking question for IELTS Speaking Part 1 that encourages candidates to delve deeply " \
|
||||||
|
"into personal experiences, preferences, or insights on diverse topics. Instruct the candidate to offer " \
|
||||||
|
"not only detailed descriptions but also provide nuanced explanations, examples, or anecdotes to enrich " \
|
||||||
|
"their response." \
|
||||||
|
"Provide your response in this json format: {'topic': 'topic','question': 'question'}"
|
||||||
|
gen_sp2_question = "Create a question for IELTS Speaking Part 2 that encourages candidates to narrate a personal experience " \
|
||||||
|
"or story related to a randomly selected topic. Include 3 prompts that guide the candidate to describe " \
|
||||||
|
"specific aspects of the experience, such as details about the situation, their actions, and the " \
|
||||||
|
"reasons it left a lasting impression." \
|
||||||
|
"Provide your response in this json format: {'topic': 'topic','question': 'question', " \
|
||||||
|
"'prompts': ['prompt_1', 'prompt_2', 'prompt_3']}"
|
||||||
|
gen_sp3_question = "Formulate a set of 3 questions for IELTS Speaking Part 3 that encourage candidates to engage in a " \
|
||||||
|
"meaningful discussion on a particular topic. Provide inquiries, ensuring " \
|
||||||
|
"they explore various aspects, perspectives, and implications related to the topic." \
|
||||||
|
"Provide your response in this json format: {'topic': 'topic','questions': ['question_1', " \
|
||||||
|
"'question_2', 'question_3']}"
|
||||||
grade_wt2_message = "You are a IELTS examiner. " \
|
grade_wt2_message = "You are a IELTS examiner. " \
|
||||||
"The question you have to grade is of type Writing Task 2 and is the following:" + question + \
|
"The question you have to grade is of type Writing Task 2 and is the following:" + question + \
|
||||||
"Assess this answer according to the IELTS grading system. It is mandatory for you to provide your response" \
|
"Assess this answer according to the IELTS grading system. It is mandatory for you to provide your response" \
|
||||||
@@ -40,7 +67,6 @@ grade_wt2_message = "You are a IELTS examiner. " \
|
|||||||
"'Coherence and Cohesion': 6.5, 'Lexical Resource': 7.5, 'Grammatical Range and Accuracy': 6.0}} " \
|
"'Coherence and Cohesion': 6.5, 'Lexical Resource': 7.5, 'Grammatical Range and Accuracy': 6.0}} " \
|
||||||
"Evaluate this answer according to ielts grading system: " + answer
|
"Evaluate this answer according to ielts grading system: " + answer
|
||||||
|
|
||||||
|
|
||||||
topics = [
|
topics = [
|
||||||
"Art and Creativity",
|
"Art and Creativity",
|
||||||
"History of Ancient Civilizations",
|
"History of Ancient Civilizations",
|
||||||
@@ -145,7 +171,8 @@ topics = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
gen_listening2_message = "You are an IELTS program designed to assist with language learning. Your task is to provide a detailed " \
|
gen_listening2_message = "You are an IELTS program designed to assist with language learning. Your task is to provide a detailed " \
|
||||||
"transcript of a monologue on the subject of " + random.choice(topics) + ". Ensure that the transcript is comprehensive " \
|
"transcript of a monologue on the subject of " + random.choice(
|
||||||
|
topics) + ". Ensure that the transcript is comprehensive " \
|
||||||
"and covers the topic " \
|
"and covers the topic " \
|
||||||
"thoroughly.After the transcript, you should generate a fill in the blanks " \
|
"thoroughly.After the transcript, you should generate a fill in the blanks " \
|
||||||
"exercise with six statements related to the content of the monologue. The blank spaces in the exercise should " \
|
"exercise with six statements related to the content of the monologue. The blank spaces in the exercise should " \
|
||||||
@@ -158,17 +185,73 @@ gen_listening2_message = "You are an IELTS program designed to assist with langu
|
|||||||
"'2': 'Answer to fill the blank space in statement 2.', '3': 'Answer to fill the blank space in statement 3.'," \
|
"'2': 'Answer to fill the blank space in statement 2.', '3': 'Answer to fill the blank space in statement 3.'," \
|
||||||
"'4': 'Answer to fill the blank space in statement 4.', '5': 'Answer to fill the blank space in statement 5.'," \
|
"'4': 'Answer to fill the blank space in statement 4.', '5': 'Answer to fill the blank space in statement 5.'," \
|
||||||
"'6': 'Answer to fill the blank space in statement 6.' } } }"
|
"'6': 'Answer to fill the blank space in statement 6.' } } }"
|
||||||
|
gen_reading_passage_1 = "Generate an extensive text for IELTS Reading Passage 1, of at least 1500 words, on the topic " \
|
||||||
|
"of " + random.choice(topics) + ". The passage should offer a substantial amount of " \
|
||||||
|
"information, analysis, or narrative " \
|
||||||
|
"relevant to the chosen subject matter. This text passage aims to serve as the primary reading " \
|
||||||
|
"section of an IELTS test, providing an in-depth and comprehensive exploration of the topic." \
|
||||||
|
"Provide your response in this json format: {'title': 'title of the text', 'text': 'generated text'}"
|
||||||
|
gen_reading_passage_2 = "Generate an extensive text for IELTS Reading Passage 2, of at least 1500 words, on the topic " \
|
||||||
|
"of " + random.choice(topics) + ". The passage should offer a substantial amount of " \
|
||||||
|
"information, analysis, or narrative " \
|
||||||
|
"relevant to the chosen subject matter. This text passage aims to serve as the primary reading " \
|
||||||
|
"section of an IELTS test, providing an in-depth and comprehensive exploration of the topic." \
|
||||||
|
"Provide your response in this json format: {'title': 'title of the text', 'text': 'generated text'}"
|
||||||
|
gen_reading_passage_3 = "Generate an extensive text for IELTS Reading Passage 2, of at least 1500 words, on the topic " \
|
||||||
|
"of " + random.choice(topics) + ". The passage should offer a substantial amount of " \
|
||||||
|
"information, analysis, or narrative " \
|
||||||
|
"relevant to the chosen subject matter. This text passage aims to serve as the primary reading " \
|
||||||
|
"section of an IELTS test, providing an in-depth and comprehensive exploration of the topic." \
|
||||||
|
"Provide your response in this json format: {'title': 'title of the text', 'text': 'generated text'}"
|
||||||
|
|
||||||
token_count = count_tokens(gen_listening2_message)["n_tokens"]
|
sample_text = "In recent years, there has been a significant shift towards renewable energy sources as societies " \
|
||||||
|
"strive to reduce their dependence on fossil fuels and combat the effects of climate change. Renewable " \
|
||||||
|
"energy, derived from sources such as sunlight, wind, and water, offers a promising alternative to " \
|
||||||
|
"traditional energy generation methods.\\nSolar power, harnessed from the sun's rays, has gained immense " \
|
||||||
|
"popularity. Photovoltaic cells, commonly known as solar panels, capture sunlight and convert it into " \
|
||||||
|
"electricity. This technology has become more efficient and affordable, contributing to a growing number " \
|
||||||
|
"of solar installations on rooftops and solar farms. Solar energy not only reduces greenhouse gas " \
|
||||||
|
"emissions but also grants individuals and businesses the ability to generate their own power.\\nSimilarly, " \
|
||||||
|
"wind energy has emerged as a reliable and clean source of electricity. Wind turbines, often found in " \
|
||||||
|
"wind farms, harness the kinetic energy of moving air to turn blades and generate electricity. These " \
|
||||||
|
"structures are strategically placed in areas with consistent wind patterns, contributing to the overall " \
|
||||||
|
"energy grid. Wind power has the advantage of scalability, with both small and large installations being " \
|
||||||
|
"feasible options.\\nHydropower, generated from flowing water in rivers and dams, is another vital renewable " \
|
||||||
|
"energy source. The force of water is used to turn turbines, which then produce electricity. While hydropower " \
|
||||||
|
"has a long history, advancements in technology have led to more efficient and environmentally friendly " \
|
||||||
|
"designs. However, the construction of dams for hydropower can have significant ecological and social " \
|
||||||
|
"impacts, requiring careful consideration.\\nGeothermal energy, originating from the Earth's heat, is " \
|
||||||
|
"also gaining attention. This energy source is harnessed through underground steam and hot water reservoirs, " \
|
||||||
|
"which are tapped for electricity generation and heating. Geothermal power plants have a relatively small " \
|
||||||
|
"environmental footprint and provide a consistent source of energy, making them a viable option in regions " \
|
||||||
|
"with suitable geological conditions.\\nIn conclusion, the transition to renewable energy sources marks a " \
|
||||||
|
"pivotal step towards sustainable and environmentally conscious energy generation. Solar, wind, hydropower, " \
|
||||||
|
"and geothermal energy offer diverse options that can collectively contribute to reducing carbon emissions " \
|
||||||
|
"and combating climate change. As technology continues to evolve and economies adapt, the potential for " \
|
||||||
|
"widespread adoption of renewable energy remains promising."
|
||||||
|
gen_multiple_choice_for_text = "Generate 10 multiple choice questions for this text: '" + sample_text + "'\n" \
|
||||||
|
"Parse those questions to this format: 'questions': [{'id': '9', 'options': [{'id': 'A', 'text': " \
|
||||||
|
"'Economic benefits'}, {'id': 'B', 'text': 'Government regulations'}, {'id': 'C', 'text': " \
|
||||||
|
"'Concerns about climate change'}, {'id': 'D', 'text': 'Technological advancement'}], " \
|
||||||
|
"'prompt': 'What is the main reason for the shift towards renewable energy sources?', " \
|
||||||
|
"'solution': 'C', 'variant': 'text'}]"
|
||||||
|
|
||||||
|
mc_questions = "questions: 1. What is the main reason for the shift towards renewable energy sources? - A. Economic benefits - B. Government regulations - C. Concerns about climate change - D. Technological advancement 2. Which of the following is NOT a renewable energy source mentioned in the text? - A. Solar power - B. Coal - C. Wind energy - D. Hydropower 3. What is the term used to describe the conversion of sunlight into electricity? - A. Solar power - B. Photovoltaic cells - C. Wind turbines - D. Hydropower 4. Which of the following is a benefit of solar energy? - A. Reduced greenhouse gas emissions - B. Increased dependence on fossil fuels - C. Higher energy costs - D. Limited availability 5. How do wind turbines generate electricity? - A. By harnessing the sun's rays - B. By using the force of water - C. By capturing wind - D. By tapping into underground reservoirs 6. What is the advantage of wind power over other renewable energy sources? - A. It is more affordable - B. It is more scalable - C. It has a smaller environmental footprint - D. It is easier to construct 7. Which renewable energy source has a long history but has recently seen advancements in technology? - A. Solar energy - B. Hydropower - C. Wind energy - D. Geothermal energy 8. What is the main drawback of constructing dams for hydropower? - A. Limited availability of suitable locations - B. High cost of construction - C. Negative impacts on the environment - D. Technological limitations 9. What is the source of geothermal energy? - A. The sun's rays - B. Moving air - C. Flowing water - D. The Earth's heat 10. How does geothermal energy differ from other renewable energy sources mentioned in the text? - A. It has a smaller environmental footprint - B. It is more expensive to harness - C. It is not affected by geographical conditions - D. It provides a consistent source of energy."
|
||||||
|
parse_mc_questions = "Parse this '" + mc_questions + "' into this json format: 'questions': [{'id': '9', 'options': [{'id': 'A', 'text': " \
|
||||||
|
"'Economic benefits'}, {'id': 'B', 'text': 'Government regulations'}, {'id': 'C', 'text': " \
|
||||||
|
"'Concerns about climate change'}, {'id': 'D', 'text': 'Technological advancement'}], " \
|
||||||
|
"'prompt': 'What is the main reason for the shift towards renewable energy sources?', " \
|
||||||
|
"'solution': 'C', 'variant': 'text'}]"
|
||||||
|
|
||||||
|
token_count = count_tokens(parse_mc_questions)["n_tokens"]
|
||||||
|
|
||||||
response = openai.Completion.create(
|
response = openai.Completion.create(
|
||||||
model="gpt-3.5-turbo-instruct",
|
model="gpt-3.5-turbo-instruct",
|
||||||
prompt=gen_listening2_message,
|
prompt=parse_mc_questions,
|
||||||
max_tokens=int(4097 - token_count - 300),
|
max_tokens=int(4097 - token_count - 300),
|
||||||
temperature=0.7
|
temperature=0.7
|
||||||
)["choices"][0]["text"]
|
)
|
||||||
|
|
||||||
# processed = process_response(response, "comment")
|
# processed = process_response(response, "comment")
|
||||||
processed = process_response(response, "transcript")
|
processed = process_response(response["choices"][0]["text"], "transcript")
|
||||||
print(processed)
|
print(processed)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user