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_jwt_extended import JWTManager, jwt_required
|
||||
from functools import reduce
|
||||
import firebase_admin
|
||||
from firebase_admin import credentials, firestore
|
||||
from helper.api_messages import QuestionType, get_grading_messages, get_question_gen_messages, get_question_tips, \
|
||||
get_speaking_grading_messages
|
||||
from helper.api_messages import *
|
||||
from helper.constants import *
|
||||
from helper.exercises import *
|
||||
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, \
|
||||
save_to_db
|
||||
from helper.firebase_helper import *
|
||||
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.openai_interface import make_openai_call
|
||||
from helper.openai_interface import make_openai_call, make_openai_instruct_call
|
||||
import os
|
||||
import uuid
|
||||
import re
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
from templates.question_templates import getListening1Template, getListening2Template, getSpeaking1Template, \
|
||||
getSpeaking2Template, getSpeaking3Template
|
||||
from templates.question_templates import *
|
||||
|
||||
load_dotenv()
|
||||
|
||||
@@ -32,22 +30,6 @@ jwt = JWTManager(app)
|
||||
cred = credentials.Certificate(os.getenv("GOOGLE_APPLICATION_CREDENTIALS"))
|
||||
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'])
|
||||
@jwt_required()
|
||||
def get_listening_section_1_question():
|
||||
@@ -61,6 +43,7 @@ def get_listening_section_1_question():
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
@app.route('/save_listening_section_1', methods=['POST'])
|
||||
@jwt_required()
|
||||
def save_listening_section_1_question():
|
||||
@@ -97,6 +80,7 @@ def get_listening_section_2_question():
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
@app.route('/save_listening_section_2', methods=['POST'])
|
||||
@jwt_required()
|
||||
def save_listening_section_2_question():
|
||||
@@ -132,6 +116,7 @@ def get_listening_section_3_question():
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
@app.route('/save_listening_section_3', methods=['POST'])
|
||||
@jwt_required()
|
||||
def save_listening_section_3_question():
|
||||
@@ -167,6 +152,7 @@ def get_listening_section_4_question():
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
@app.route('/save_listening_section_4', methods=['POST'])
|
||||
@jwt_required()
|
||||
def save_listening_section_4_question():
|
||||
@@ -216,6 +202,24 @@ def grade_writing_task_1():
|
||||
except Exception as 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'])
|
||||
@jwt_required()
|
||||
def save_writing_task_1_question():
|
||||
@@ -259,18 +263,26 @@ def grade_writing_task_2():
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
@app.route('/writing_task2', methods=['GET'])
|
||||
|
||||
@app.route('/writing_task2_general', methods=['GET'])
|
||||
@jwt_required()
|
||||
def get_writing_task_2_question():
|
||||
def get_writing_task_2_general_question():
|
||||
try:
|
||||
messages = get_question_gen_messages(QuestionType.WRITING_TASK_2)
|
||||
token_count = reduce(lambda count, item: count + count_tokens(item)['n_tokens'],
|
||||
map(lambda x: x["content"], filter(lambda x: "content" in x, messages)), 0)
|
||||
response = make_openai_call(GPT_3_5_TURBO, messages, token_count, GEN_FIELDS, GEN_QUESTION_TEMPERATURE)
|
||||
return response
|
||||
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."
|
||||
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:
|
||||
return str(e)
|
||||
|
||||
|
||||
@app.route('/save_writing_task_2', methods=['POST'])
|
||||
@jwt_required()
|
||||
def save_writing_task_2_question():
|
||||
@@ -325,14 +337,19 @@ def grade_speaking_task_1():
|
||||
@jwt_required()
|
||||
def get_speaking_task_1_question():
|
||||
try:
|
||||
messages = get_question_gen_messages(QuestionType.SPEAKING_1)
|
||||
token_count = reduce(lambda count, item: count + count_tokens(item)['n_tokens'],
|
||||
map(lambda x: x["content"], filter(lambda x: "content" in x, messages)), 0)
|
||||
response = make_openai_call(GPT_3_5_TURBO, messages, token_count, GEN_FIELDS, GEN_QUESTION_TEMPERATURE)
|
||||
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'}"
|
||||
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
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
@app.route('/save_speaking_task_1', methods=['POST'])
|
||||
@jwt_required()
|
||||
def save_speaking_task_1_question():
|
||||
@@ -380,6 +397,7 @@ def save_speaking_task_1_question():
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
@app.route('/speaking_task_2', methods=['POST'])
|
||||
@jwt_required()
|
||||
def grade_speaking_task_2():
|
||||
@@ -419,14 +437,20 @@ def grade_speaking_task_2():
|
||||
@jwt_required()
|
||||
def get_speaking_task_2_question():
|
||||
try:
|
||||
messages = get_question_gen_messages(QuestionType.SPEAKING_2)
|
||||
token_count = reduce(lambda count, item: count + count_tokens(item)['n_tokens'],
|
||||
map(lambda x: x["content"], filter(lambda x: "content" in x, messages)), 0)
|
||||
response = make_openai_call(GPT_3_5_TURBO, messages, token_count, GEN_FIELDS, GEN_QUESTION_TEMPERATURE)
|
||||
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']}"
|
||||
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
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
@app.route('/save_speaking_task_2', methods=['POST'])
|
||||
@jwt_required()
|
||||
def save_speaking_task_2_question():
|
||||
@@ -474,6 +498,27 @@ def save_speaking_task_2_question():
|
||||
except Exception as 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'])
|
||||
@jwt_required()
|
||||
def grade_speaking_task_3():
|
||||
@@ -508,6 +553,7 @@ def grade_speaking_task_3():
|
||||
except Exception as e:
|
||||
return str(e), 400
|
||||
|
||||
|
||||
@app.route('/save_speaking_task_3', methods=['POST'])
|
||||
@jwt_required()
|
||||
def save_speaking_task_3_question():
|
||||
@@ -555,6 +601,61 @@ def save_speaking_task_3_question():
|
||||
except Exception as 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'])
|
||||
@jwt_required()
|
||||
def fetch_answer_tips():
|
||||
@@ -576,5 +677,6 @@ def fetch_answer_tips():
|
||||
except Exception as e:
|
||||
return str(e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
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?",
|
||||
"solution": "B",
|
||||
"variant": "text",
|
||||
"variant": "text"
|
||||
},
|
||||
{
|
||||
"id": "11",
|
||||
@@ -2963,7 +2963,8 @@ new_reading_to_insert_2 = {
|
||||
"solutions": [
|
||||
{
|
||||
"id": "24",
|
||||
"solution": ["Task switching", "Attention management", "Inhibition of distractions", "Cognitive flexibility"]
|
||||
"solution": ["Task switching", "Attention management", "Inhibition of distractions",
|
||||
"Cognitive flexibility"]
|
||||
},
|
||||
{
|
||||
"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 "
|
||||
"in contemporary society.",
|
||||
"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"]
|
||||
},
|
||||
{
|
||||
@@ -3638,7 +3640,8 @@ new_reading_to_insert_3 = {
|
||||
"solutions": [
|
||||
{
|
||||
"id": "24",
|
||||
"solution": ["Task switching", "Attention management", "Inhibition of distractions", "Cognitive flexibility"]
|
||||
"solution": ["Task switching", "Attention management", "Inhibition of distractions",
|
||||
"Cognitive flexibility"]
|
||||
},
|
||||
{
|
||||
"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 "
|
||||
"in contemporary society.",
|
||||
"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"]
|
||||
},
|
||||
{
|
||||
@@ -5423,6 +5427,657 @@ new_listening_to_insert_2 = {
|
||||
"minTimer": 30,
|
||||
"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
|
||||
# writing task 1 com imagens ...
|
||||
@@ -5435,5 +6090,5 @@ db = firestore.client()
|
||||
|
||||
# Add the JSON data to Firestore
|
||||
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}")
|
||||
|
||||
@@ -12,6 +12,12 @@ class QuestionType(Enum):
|
||||
WRITING_TASK_2 = "Writing Task 2"
|
||||
SPEAKING_1 = "Speaking Task Part 1"
|
||||
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):
|
||||
|
||||
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()
|
||||
openai.api_key = os.getenv("OPENAI_API_KEY")
|
||||
|
||||
|
||||
MAX_TOKENS = 4097
|
||||
TOP_P = 0.9
|
||||
FREQUENCY_PENALTY = 0.5
|
||||
@@ -16,6 +15,7 @@ FREQUENCY_PENALTY = 0.5
|
||||
TRY_LIMIT = 1
|
||||
|
||||
try_count = 0
|
||||
|
||||
def process_response(input_string, quotation_check_field):
|
||||
if '{' in input_string:
|
||||
try:
|
||||
@@ -24,25 +24,42 @@ def process_response(input_string, quotation_check_field):
|
||||
# Extract everything after the first '{' (inclusive)
|
||||
result = input_string[index:]
|
||||
if re.search(r"'" + quotation_check_field + "':\s*'(.*?)'", result, re.DOTALL | re.MULTILINE):
|
||||
parsed_string = result.replace("\"", "\\\"")
|
||||
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)
|
||||
json_obj = json.loads(parse_string(result))
|
||||
return json_obj
|
||||
else:
|
||||
json_obj = json.loads(result)
|
||||
parsed_string = result.replace("\n\n", " ")
|
||||
json_obj = json.loads(parsed_string)
|
||||
return json_obj
|
||||
except Exception as e:
|
||||
print(f"Invalid JSON string! Exception: {e}")
|
||||
else:
|
||||
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):
|
||||
return all(field in obj for field in fields)
|
||||
|
||||
|
||||
def make_openai_call(model, messages, token_count, fields_to_check, temperature):
|
||||
global try_count
|
||||
result = openai.ChatCompletion.create(
|
||||
@@ -69,4 +86,26 @@ def make_openai_call(model, messages, token_count, fields_to_check, temperature)
|
||||
try_count = 0
|
||||
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()
|
||||
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 " \
|
||||
"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 " \
|
||||
@@ -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)
|
||||
# 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. " \
|
||||
"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" \
|
||||
@@ -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}} " \
|
||||
"Evaluate this answer according to ielts grading system: " + answer
|
||||
|
||||
|
||||
topics = [
|
||||
"Art and Creativity",
|
||||
"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 " \
|
||||
"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 " \
|
||||
"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 " \
|
||||
@@ -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.'," \
|
||||
"'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.' } } }"
|
||||
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(
|
||||
model="gpt-3.5-turbo-instruct",
|
||||
prompt=gen_listening2_message,
|
||||
prompt=parse_mc_questions,
|
||||
max_tokens=int(4097 - token_count - 300),
|
||||
temperature=0.7
|
||||
)["choices"][0]["text"]
|
||||
)
|
||||
|
||||
# processed = process_response(response, "comment")
|
||||
processed = process_response(response, "transcript")
|
||||
processed = process_response(response["choices"][0]["text"], "transcript")
|
||||
print(processed)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user