Merged in utas-stuff (pull request #8)

Utas stuff
This commit is contained in:
Cristiano Ferreira
2024-06-13 17:32:48 +00:00
3 changed files with 376 additions and 3 deletions

101
app.py
View File

@@ -1013,6 +1013,107 @@ def get_level_exam():
except Exception as e: except Exception as e:
return str(e) return str(e)
@app.route('/level_utas', methods=['GET'])
@jwt_required()
def get_level_utas():
try:
# Formats
mc = {
"id": str(uuid.uuid4()),
"prompt": "Choose the correct word or group of words that completes the sentences.",
"questions": None,
"type": "multipleChoice",
"part": 1
}
umc = {
"id": str(uuid.uuid4()),
"prompt": "Choose the underlined word or group of words that is not correct.",
"questions": None,
"type": "multipleChoice",
"part": 2
}
bs_1 = {
"id": str(uuid.uuid4()),
"prompt": "Read the text and write the correct word for each space.",
"questions": None,
"type": "blankSpaceText",
"part": 3
}
bs_2 = {
"id": str(uuid.uuid4()),
"prompt": "Read the text and write the correct word for each space.",
"questions": None,
"type": "blankSpaceText",
"part": 4
}
reading = {
"id": str(uuid.uuid4()),
"prompt": "Read the text and answer the questions below.",
"questions": None,
"type": "readingExercises",
"part": 5
}
all_mc_questions = []
# PART 1
mc_exercises1 = gen_multiple_choice_blank_space_utas(15, 1, all_mc_questions)
print(json.dumps(mc_exercises1, indent=4))
all_mc_questions.append(mc_exercises1)
# PART 2
mc_exercises2 = gen_multiple_choice_blank_space_utas(15, 16, all_mc_questions)
print(json.dumps(mc_exercises2, indent=4))
all_mc_questions.append(mc_exercises2)
# PART 3
mc_exercises3 = gen_multiple_choice_blank_space_utas(15, 31, all_mc_questions)
print(json.dumps(mc_exercises3, indent=4))
all_mc_questions.append(mc_exercises3)
mc_exercises = mc_exercises1['questions'] + mc_exercises2['questions'] + mc_exercises3['questions']
print(json.dumps(mc_exercises, indent=4))
mc["questions"] = mc_exercises
# Underlined mc
underlined_mc = gen_multiple_choice_underlined_utas(15, 46)
print(json.dumps(underlined_mc, indent=4))
umc["questions"] = underlined_mc
# Blank Space text 1
blank_space_text_1 = gen_blank_space_text_utas(12, 61, 250)
print(json.dumps(blank_space_text_1, indent=4))
bs_1["questions"] = blank_space_text_1
# Blank Space text 2
blank_space_text_2 = gen_blank_space_text_utas(14, 73, 350)
print(json.dumps(blank_space_text_2, indent=4))
bs_2["questions"] = blank_space_text_2
# Reading text
reading_text = gen_reading_passage_utas(87, 10, 4)
print(json.dumps(reading_text, indent=4))
reading["questions"] = reading_text
return {
"exercises": {
"blankSpaceMultipleChoice": mc,
"underlinedMultipleChoice": umc,
"blankSpaceText1": bs_1,
"blankSpaceText2": bs_2,
"readingExercises": reading,
},
"isDiagnostic": False,
"minTimer": 25,
"module": "level"
}
except Exception as e:
return str(e)
@app.route('/fetch_tips', methods=['POST']) @app.route('/fetch_tips', methods=['POST'])
@jwt_required() @jwt_required()

View File

@@ -141,7 +141,6 @@ mti_topics = [
"Poverty Alleviation", "Poverty Alleviation",
"Cybersecurity and Privacy", "Cybersecurity and Privacy",
"Human Rights", "Human Rights",
"Social Justice",
"Food and Agriculture", "Food and Agriculture",
"Cyberbullying and Online Safety", "Cyberbullying and Online Safety",
"Linguistic Diversity", "Linguistic Diversity",
@@ -232,7 +231,6 @@ topics = [
"Meditation Practices", "Meditation Practices",
"Literary Symbolism", "Literary Symbolism",
"Marine Conservation", "Marine Conservation",
"Social Justice Movements",
"Sustainable Tourism", "Sustainable Tourism",
"Ancient Philosophy", "Ancient Philosophy",
"Cold War Era", "Cold War Era",

View File

@@ -1036,7 +1036,7 @@ def gen_multiple_choice_level(quantity: int, start_id=1):
["questions"], ["questions"],
GEN_QUESTION_TEMPERATURE) GEN_QUESTION_TEMPERATURE)
if len(question["questions"]) != 25: if len(question["questions"]) != quantity:
return gen_multiple_choice_level(quantity, start_id) return gen_multiple_choice_level(quantity, start_id)
else: else:
all_exams = get_all("level") all_exams = get_all("level")
@@ -1073,6 +1073,25 @@ def replace_exercise_if_exists(all_exams, current_exercise, current_exam, seen_k
return replace_exercise_if_exists(all_exams, generate_single_mc_level_question(), current_exam, seen_keys) return replace_exercise_if_exists(all_exams, generate_single_mc_level_question(), current_exam, seen_keys)
return current_exercise, seen_keys return current_exercise, seen_keys
def replace_exercise_if_exists_utas(all_exams, current_exercise, current_exam, seen_keys):
# Extracting relevant fields for comparison
key = (current_exercise['prompt'], tuple(sorted(option['text'] for option in current_exercise['options'])))
# Check if the key is in the set
if key in seen_keys:
return replace_exercise_if_exists_utas(all_exams, generate_single_mc_level_question(), current_exam, seen_keys)
else:
seen_keys.add(key)
for exam in all_exams:
if any(
exercise["prompt"] == current_exercise["prompt"] and
any(exercise["options"][0]["text"] == current_option["text"] for current_option in
current_exercise["options"])
for exercise in exam.get("questions", [])
):
return replace_exercise_if_exists_utas(all_exams, generate_single_mc_level_question(), current_exam, seen_keys)
return current_exercise, seen_keys
def generate_single_mc_level_question(): def generate_single_mc_level_question():
messages = [ messages = [
@@ -1109,3 +1128,258 @@ def parse_conversation(conversation_data):
readable_text.append(f"{name}: {text}") readable_text.append(f"{name}: {text}")
return "\n".join(readable_text) return "\n".join(readable_text)
def gen_multiple_choice_blank_space_utas(quantity: int, start_id: int, all_exams):
gen_multiple_choice_for_text = "Generate " + str(
quantity) + " multiple choice blank space questions of 4 options for an english level exam, some easy questions, some intermediate " \
"questions and some advanced questions. Ensure that the questions cover a range of topics such as " \
"verb tense, subject-verb agreement, pronoun usage, sentence structure, and punctuation. Make sure " \
"every question only has 1 correct answer."
messages = [
{
"role": "system",
"content": (
'You are a helpful assistant designed to output JSON on this format: {"questions": [{"id": "9", "options": '
'[{"id": "A", "text": '
'"And"}, {"id": "B", "text": "Cat"}, {"id": "C", "text": '
'"Happy"}, {"id": "D", "text": "Jump"}], '
'"prompt": "Which of the following is a conjunction?", '
'"solution": "A", "variant": "text"}]}')
},
{
"role": "user",
"content": gen_multiple_choice_for_text
}
]
token_count = count_total_tokens(messages)
question = make_openai_call(GPT_4_O, messages, token_count,
["questions"],
GEN_QUESTION_TEMPERATURE)
if len(question["questions"]) != quantity:
return gen_multiple_choice_level(quantity, start_id)
else:
seen_keys = set()
for i in range(len(question["questions"])):
question["questions"][i], seen_keys = replace_exercise_if_exists_utas(all_exams, question["questions"][i],
question,
seen_keys)
return fix_exercise_ids(question, start_id)
def gen_multiple_choice_underlined_utas(quantity: int, start_id: int):
json_format = {
"questions": [
{
"id": "9",
"options": [
{
"id": "A",
"text": "a"
},
{
"id": "B",
"text": "b"
},
{
"id": "C",
"text": "c"
},
{
"id": "D",
"text": "d"
}
],
"prompt": "prompt",
"solution": "A",
"variant": "text"
}
]
}
gen_multiple_choice_for_text = 'Generate ' + str(quantity) + (' multiple choice questions of 4 options for an english '
'level exam, some easy questions, some intermediate '
'questions and some advanced questions.Ensure that '
'the questions cover a range of topics such as verb '
'tense, subject-verb agreement, pronoun usage, '
'sentence structure, and punctuation. Make sure '
'every question only has 1 correct answer.')
messages = [
{
"role": "system",
"content": 'You are a helpful assistant designed to output JSON on this format: ' + str(json_format)
},
{
"role": "user",
"content": gen_multiple_choice_for_text
},
{
"role": "user",
"content": (
'The type of multiple choice is the prompt has wrong words or group of words and the options are to '
'find the wrong word or group of words that are underlined in the prompt. \nExample:\n'
'Prompt: "I <u>complain</u> about my boss <u>all the time</u>, but my colleagues <u>thinks</u> the boss <u>is</u> nice."\n'
'Options:\na: "complain"\nb: "all the time"\nc: "thinks"\nd: "is"')
}
]
token_count = count_total_tokens(messages)
question = make_openai_call(GPT_4_O, messages, token_count,
["questions"],
GEN_QUESTION_TEMPERATURE)
if len(question["questions"]) != quantity:
return gen_multiple_choice_level(quantity, start_id)
else:
return fix_exercise_ids(question, start_id)["questions"]
def gen_blank_space_text_utas(quantity: int, start_id: int, size: int, topic=random.choice(mti_topics)):
json_format = {
"question": {
"words": [
{
"id": "1",
"text": "a"
},
{
"id": "2",
"text": "b"
},
{
"id": "3",
"text": "c"
},
{
"id": "4",
"text": "d"
}
],
"text": "text"
}
}
gen_text = 'Generate a text of at least ' + str(size) + ' words about the topic ' + topic + '.'
messages = [
{
"role": "system",
"content": 'You are a helpful assistant designed to output JSON on this format: ' + str(json_format)
},
{
"role": "user",
"content": gen_text
},
{
"role": "user",
"content": (
'From the generated text choose ' + str(quantity) + ' words (cannot be sequential words) to replace '
'once with {{id}} where id starts on ' + str(start_id) + ' and is '
'incremented for each word. The ids must be ordered throughout the text and the words must be '
'replaced only once. Put the removed words and respective ids on the words array of the json in the correct order.')
}
]
token_count = count_total_tokens(messages)
question = make_openai_call(GPT_4_O, messages, token_count,
["question"],
GEN_QUESTION_TEMPERATURE)
return question["question"]
def gen_reading_passage_utas(start_id, sa_quantity: int, mc_quantity: int, topic=random.choice(mti_topics)):
passage = generate_reading_passage(QuestionType.READING_PASSAGE_1, topic)
short_answer = gen_short_answer_utas(passage["text"], start_id, sa_quantity)
mc_exercises = gen_text_multiple_choice_utas(passage["text"], start_id+sa_quantity, mc_quantity)
return {
"exercises": {
"shortAnswer":short_answer,
"multipleChoice": mc_exercises,
},
"text": {
"content": passage["text"],
"title": passage["title"]
}
}
def gen_short_answer_utas(text: str, start_id: int, sa_quantity: int):
json_format = {"questions": [{"id": 1, "question": "question", "possible_answers": ["answer_1", "answer_2"]}]}
messages = [
{
"role": "system",
"content": 'You are a helpful assistant designed to output JSON on this format: ' + str(json_format)
},
{
"role": "user",
"content": (
'Generate ' + str(sa_quantity) + ' short answer questions, and the possible answers, must have '
'maximum 3 words per answer, about this text:\n"' + text + '"')
},
{
"role": "user",
"content": 'The id starts at ' + str(start_id) + '.'
}
]
token_count = count_total_tokens(messages)
return make_openai_call(GPT_4_O, messages, token_count,
["questions"],
GEN_QUESTION_TEMPERATURE)["questions"]
def gen_text_multiple_choice_utas(text: str, start_id: int, mc_quantity: int):
json_format = {
"questions": [
{
"id": "9",
"options": [
{
"id": "A",
"text": "a"
},
{
"id": "B",
"text": "b"
},
{
"id": "C",
"text": "c"
},
{
"id": "D",
"text": "d"
}
],
"prompt": "prompt",
"solution": "A",
"variant": "text"
}
]
}
messages = [
{
"role": "system",
"content": 'You are a helpful assistant designed to output JSON on this format: ' + str(json_format)
},
{
"role": "user",
"content": 'Generate ' + str(mc_quantity) + ' multiple choice questions of 4 options for this text:\n' + text
},
{
"role": "user",
"content": 'Make sure every question only has 1 correct answer.'
}
]
token_count = count_total_tokens(messages)
question = make_openai_call(GPT_4_O, messages, token_count,
["questions"],
GEN_QUESTION_TEMPERATURE)
if len(question["questions"]) != mc_quantity:
return gen_multiple_choice_level(mc_quantity, start_id)
else:
return fix_exercise_ids(question, start_id)["questions"]