|
import os |
|
import gradio as gr |
|
import requests |
|
|
|
def clamp(x, minimum, maximum): |
|
return max(minimum, min(x, maximum)) |
|
|
|
|
|
|
|
|
|
|
|
|
|
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}") |
|
|
|
|
|
|
|
|
|
|
|
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) |
|
|