tommymarto's picture
Upload 3 files
9ae9be9
raw
history blame
11.7 kB
import os
import gradio as gr
import requests
def clamp(x, minimum, maximum):
return max(minimum, min(x, maximum))
#################################################################################################################################################
# API calls
#################################################################################################################################################
# read secret api key
API_KEY = os.getenv('ApiKey')
base_url = "https://skapi.polyglot-edu.com/"
levels = ["Pre K", "Primary", "Middle School", "High School", "Academic"]
def get_level_mapping(level):
return {
"Academic": 0,
"Pre K": 1,
"Primary": 2,
"Middle School": 3,
"High School": 4,
}[level]
def generate_fill_gaps(original_text, level, number_of_words, number_of_gaps, number_of_distractors, temperature):
"""
Generate a fill-gaps question from a given text.
Parameters
----------
original_text : str
The original text from which to generate the fill-gaps question.
number_of_words : int
The number of words of the generated text.
number_of_gaps : int
The number of gaps to generate.
number_of_distractors : int
The number of distractors to generate for each gap.
temperature : float
The temperature for the generation.
Returns
-------
str
The fill-gaps question.
"""
match number_of_words:
case "β‰ˆ 150 Words":
number_of_words = 150
case "β‰ˆ 250 Words":
number_of_words = 250
case "β‰ˆ 350 Words":
number_of_words = 350
response = requests.post(
base_url + "FillTheGaps/generateexercise",
headers={
"ApiKey": API_KEY
},
json={
"text": original_text,
"level": get_level_mapping(level),
"n_o_w": int(number_of_words),
"n_o_g": int(number_of_gaps),
"n_o_d": int(number_of_distractors),
"temperature": int(temperature) * 0.2
},
timeout=20
)
if response.status_code == 200:
return response.text
raise Exception(f"API call failed with status code {response.status_code} and message {response.text}")
def generate_open_question(original_text, level, temperature):
"""
Generate an open question from a given text.
Parameters
----------
original_text : str
The original text from which to generate the open question.
temperature : float
The temperature for the generation.
Returns
-------
str
The open question.
"""
response = requests.post(
base_url + "QuestionExercise/generateexercise",
headers={
"ApiKey": API_KEY
},
json={
"text": original_text,
"level": get_level_mapping(level),
"temperature": int(temperature) * 0.2
},
timeout=20
)
if response.status_code == 200:
return response.text
raise Exception(f"API call failed with status code {response.status_code} and message {response.text}")
def generate_multiplechoice(original_text, level, number_of_options, number_of_easy_distractors, number_of_distractors, temperature):
"""
Generate a multiple-choice question from a given text.
Parameters
----------
original_text : str
The original text from which to generate the multiple-choice question.
number_of_options : int
The number of options to generate.
number_of_easy_distractors : int
The number of easy distractors to generate for each option.
number_of_distractors : int
The number of distractors to generate for each option.
temperature : float
The temperature for the generation.
Returns
-------
str
The multiple-choice question.
"""
response = requests.post(
base_url + "QuizExercise/generateexercise",
headers={
"ApiKey": API_KEY
},
json={
"text": original_text,
"type": True,
"level": get_level_mapping(level),
"n_o_d": int(number_of_distractors),
"nedd": int(number_of_easy_distractors),
"temperature": int(temperature) * 0.2
},
timeout=20
)
if response.status_code == 200:
return response.text
raise Exception(f"API call failed with status code {response.status_code} and message {response.text}")
#################################################################################################################################################
# Interface building
#################################################################################################################################################
flag_link = "https://www.google.com"
comment_link = "https://www.google.com"
def build_fill_gaps_interface():
"""
Build the fill-gaps interface.
"""
with gr.Blocks(title="Fill-gaps") as demo:
with gr.Row():
with gr.Column(scale=5):
input_field = gr.TextArea(lines=10, max_lines=10, label="Input text (can be a text or a url)")
submit_btn = gr.Button(value="Submit")
with gr.Column(scale=4):
output_text_length = gr.Radio(["β‰ˆ 150 Words", "β‰ˆ 250 Words", "β‰ˆ 350 Words"], label="Output text length", value="β‰ˆ 150 Words")
level = gr.Radio(levels, label="Level", value="Primary")
with gr.Row():
blanks = gr.Number(value=5, minimum=4, maximum=8, step=1, label="Number of blanks")
distractors = gr.Number(value=5, minimum=4, maximum=8, step=1, label="Number of distractors")
temperature = gr.Checkbox(value=False, label="Increase creativity (decreases preciseness)")
def update_numeric(output_text_length, blanks, distractors):
if output_text_length == "β‰ˆ 150 Words":
min_, max_ = 4, 8
elif output_text_length == "β‰ˆ 250 Words":
min_, max_ = 6, 10
elif output_text_length == "β‰ˆ 350 Words":
min_, max_ = 8, 12
return (
gr.Number(value=clamp(blanks, min_, max_), minimum=min_, maximum=max_, label="Number of blanks"),
gr.Number(value=clamp(distractors, 0, blanks), minimum=0, maximum=blanks, label="Number of distractors")
)
def update_blanks(blanks, distractors):
return gr.Number(value=clamp(distractors, 0, blanks), minimum=0, maximum=blanks, label="Number of distractors")
blanks.change(update_blanks, [blanks, distractors], [distractors])
output_text_length.change(update_numeric, [output_text_length, blanks, distractors], [blanks, distractors])
with gr.Row():
output = gr.TextArea(placeholder="Generated text", label="Output")
with gr.Row() as button_row:
upvote_btn = gr.Button(value="πŸ‘ Upvote")
downvote_btn = gr.Button(value="πŸ‘Ž Downvote")
comment_btn = gr.Button(value="πŸ’¬ Comment", link=comment_link)
flag_btn = gr.Button(value="⚠️ Flag", link=flag_link)
submit_btn.click(generate_fill_gaps, [input_field, level, output_text_length, blanks, distractors, temperature], [output])
return demo
def build_multiplechoice_interface():
"""
Build the open question interface.
"""
with gr.Blocks(title="Open Question") as demo:
with gr.Row():
with gr.Column(scale=5):
input_field = gr.TextArea(lines=10, max_lines=10, label="Input text (can be a text or a url)")
submit_btn = gr.Button(value="Submit")
with gr.Column(scale=4):
level = gr.Radio(levels, label="Level", value="Primary")
with gr.Row():
options = gr.Number(value=4, minimum=2, maximum=8, step=1, label="Number of blanks", interactive=False)
easy_distractors = gr.Number(value=1, minimum=0, maximum=8, step=1, label="Number of easy distractors")
distractors = gr.Number(value=1, minimum=0, maximum=8, step=1, label="Number of distractors")
temperature = gr.Checkbox(value=False, label="Increase creativity (decreases preciseness)")
def update_options(options, easy_distractors, distractors):
distractors = clamp(distractors, 0, options)
easy_distractors = clamp(easy_distractors, 0, distractors)
return (
gr.Number(value=easy_distractors, minimum=0, maximum=distractors, label="Number of easy distractors"),
gr.Number(value=distractors, minimum=0, maximum=options, label="Number of distractors")
)
def update_distractors(easy_distractors, distractors):
easy_distractors = clamp(easy_distractors, 0, distractors)
return gr.Number(value=easy_distractors, minimum=0, maximum=distractors, label="Number of easy distractors")
options.change(update_options, [options, easy_distractors, distractors], [easy_distractors, distractors])
distractors.change(update_distractors, [easy_distractors, distractors], [easy_distractors])
with gr.Row():
output = gr.TextArea(placeholder="Generated text", label="Output")
with gr.Row() as button_row:
upvote_btn = gr.Button(value="πŸ‘ Upvote")
downvote_btn = gr.Button(value="πŸ‘Ž Downvote")
comment_btn = gr.Button(value="πŸ’¬ Comment", link=comment_link)
flag_btn = gr.Button(value="⚠️ Flag", link=flag_link)
submit_btn.click(generate_multiplechoice, [input_field, level, options, easy_distractors, distractors, temperature], [output])
return demo
def build_open_question_interface():
"""
Build the multiple-choice interface.
"""
with gr.Blocks(title="Multiple choice") as demo:
with gr.Row():
with gr.Column(scale=5):
input_field = gr.TextArea(lines=10, max_lines=10, label="Input text (can be a text or a url)")
submit_btn = gr.Button(value="Submit")
with gr.Column(scale=4):
level = gr.Radio(levels, label="Level", value="Primary")
with gr.Row():
pass
temperature = gr.Checkbox(value=False, label="Increase creativity (decreases preciseness)")
with gr.Row():
output = gr.TextArea(placeholder="Generated text", label="Output")
with gr.Row() as button_row:
upvote_btn = gr.Button(value="πŸ‘ Upvote")
downvote_btn = gr.Button(value="πŸ‘Ž Downvote")
comment_btn = gr.Button(value="πŸ’¬ Comment", link=comment_link)
flag_btn = gr.Button(value="⚠️ Flag", link=flag_link)
submit_btn.click(generate_open_question, [input_field, level, temperature], [output])
return demo
def build_demo():
return gr.TabbedInterface(
[build_fill_gaps_interface(), build_open_question_interface(), build_multiplechoice_interface()],
["Fill-gaps", "Open question", "Multiple-choice"],
title="Education AI"
)
if __name__ == "__main__":
build_demo().launch(share=False)