TestGen / app.py
vladyslav
Added 3 new questions for feedback
9f10b71
raw
history blame
11.2 kB
import json
import os
import random
import gradio as gr
from dotenv import load_dotenv
from constants import MODELS, MODELS_PATH, BOOKS
from utils import save_results
load_dotenv()
if os.getenv("ENV_TYPE") == "dev":
MODELS["Test"] = "test"
MODELS_PATH["Test"] = "test"
BOOKS["Test"] = "test.json"
questions_data = []
current_question_index = 0
answers_log = [] # Log for saving answers
def get_question():
global questions_data, current_question_index
question = questions_data[current_question_index]
question_text = f"# Питання:\n## {question['question']}"
answers = [answer['answer'] for answer in question['answers']]
random.shuffle(answers)
return question_text, answers
def load_questions(model, book, student_name, class_name):
global questions_data, current_question_index
current_question_index = 0
answers_log.clear()
if not model or not book or not student_name or not class_name:
return "# Будь ласка, заповніть усі поля!", []
model_path = MODELS_PATH[model]
book_filename = BOOKS[book]
file_path = os.path.join("questions", model_path, book_filename)
if not os.path.exists(file_path):
return f"Файл за шляхом {file_path} не знайдено.", []
with open(file_path, "r", encoding="utf-8") as file:
questions_data = json.load(file)
if questions_data:
return get_question()
else:
return "У файлі немає питань.", []
def get_next_question(selected_answer):
global current_question_index, answers_log
if not selected_answer:
question_text, answers = get_question()
return (
question_text, # question_radio
gr.update(choices=answers, value=None, interactive=True, visible=True), # answer_radio
gr.update(visible=True), # next_button
gr.update(visible=False), # feedback_input
gr.update(visible=False), # rating_slider
gr.update(visible=False), # submit_feedback_button
gr.update(visible=False), # rating_text
gr.update(visible=False), # question_correct
gr.update(visible=False), # text_coverage
gr.update(visible=False), # interesting_question
)
# Writing answer in log
answers_log.append({
"selected": selected_answer,
"isCorrect": any(answer['answer'] == selected_answer and answer['isCorrect'] for answer in
questions_data[current_question_index]['answers'])
})
# Move to the next question
current_question_index += 1
if current_question_index < len(questions_data):
question_text, answers = get_question()
return (
question_text, # question_radio
gr.update(choices=answers, value=None, interactive=True, visible=True), # answer_radio
gr.update(visible=True), # next_button
gr.update(visible=False), # feedback_input
gr.update(visible=False), # rating_slider
gr.update(visible=False), # submit_feedback_button
gr.update(visible=False), # rating_text
gr.update(visible=False), # question_correct
gr.update(visible=False), # text_coverage
gr.update(visible=False), # interesting_question
)
else:
# All questions are completed — ask for feedback
question_text = "# Дякуємо за участь у тесті! Залиште, будь ласка, свій відгук і оцініть тест."
return (
question_text, # question_radio
gr.update(visible=False, value=None), # answer_radio
gr.update(visible=False), # next_button
gr.update(visible=True), # feedback_input
gr.update(visible=True), # rating_slider
gr.update(visible=True), # submit_feedback_button
gr.update(visible=True), # rating_text
gr.update(visible=True), # question_correct
gr.update(visible=True), # text_coverage
gr.update(visible=True), # interesting_question
)
def summarize_results(student_name,
class_name,
model,
book,
feedback,
rating,
question_correct,
text_coverage,
interesting_question):
global questions_data, answers_log
questions = []
if not feedback or not question_correct or not text_coverage or not interesting_question or not rating:
return (
"# Залиште відгук про тест!", # question_output
gr.update(visible=True), # feedback_input
gr.update(visible=True), # rating_slider
gr.update(visible=True), # submit_feedback_button
gr.update(visible=True), # question_correct
gr.update(visible=True), # text_coverage
gr.update(visible=True), # interesting_question
gr.update(visible=True), # rating_text
)
for question, answer in zip(questions_data, answers_log):
questions.append({
"question": question,
"answer": answer
})
save_results(
student_name,
class_name,
MODELS[model],
book,
questions,
feedback,
rating,
question_correct,
text_coverage,
interesting_question
)
correct_answers_count = sum(1 for answer in answers_log if answer['isCorrect'])
total_questions = len(questions_data)
grade_12 = (correct_answers_count / total_questions) * 12
summary = (
f"# Усі питання пройдено!\n\n"
f"## Ви відповіли правильно на {correct_answers_count} з {total_questions} питань.\n\n"
f"## Оцінка за 12-бальною шкалою: {grade_12:.2f}.\n\n"
)
return (
summary, # question_output
gr.update(visible=False, value=""), # feedback_input
gr.update(visible=False, value=None), # rating_slider
gr.update(visible=False), # submit_feedback_button
gr.update(visible=False, value=""), # question_correct
gr.update(visible=False, value=""), # text_coverage
gr.update(visible=False, value=""), # interesting_question
gr.update(visible=False), # rating_text
)
with gr.Blocks() as demo:
with gr.Column():
gr.Markdown("# Оберіть модель та книгу, щоб завантажити питання")
student_name_input = gr.Textbox(label="Ваше ім'я")
class_name_input = gr.Textbox(label="Ваш клас")
model_radio = gr.Radio(list(MODELS.keys()), label="Оберіть модель")
book_radio = gr.Radio(list(BOOKS.keys()), label="Оберіть книгу")
load_button = gr.Button("Завантажити питання")
question_output = gr.Markdown(label="Питання")
answer_radio = gr.Radio([], label="Варіанти відповіді", interactive=True, visible=False)
next_button = gr.Button("Наступне питання", visible=False)
question_correct_input = gr.Textbox(label="Чи коректно поставлено запитання і варіанти відповідей?",
visible=False)
text_coverage_input = gr.Textbox(label="Рівномірність покриття тексту", visible=False)
interesting_question_input = gr.Textbox(label="Цікавість запитань", visible=False)
feedback_input = gr.Textbox(label="Ваш відгук про тест", visible=False)
rating_text = gr.Markdown(
"### Шкала оцінювання:\n\n#### -2 — дуже погано\n\n#### -1 — погано\n\n#### 0 — задовільно\n\n#### 1 — добре\n\n#### 2 — відмінно",
visible=False)
rating_buttons = gr.Radio([-2, -1, 0, 1, 2], label="Оцініть тест", visible=False, interactive=True)
submit_feedback_button = gr.Button("Завершити тест", visible=False)
def update_question(model, book, student_name, class_name):
question, answers = load_questions(model, book, student_name, class_name)
is_field_filled = len(answers) > 0
return (
question, # question_output
gr.update(choices=answers, interactive=True, visible=is_field_filled), # answer_radio
gr.update(visible=is_field_filled), # next_button
gr.update(visible=False, value=""), # feedback_input
gr.update(visible=False, value=None), # rating_buttons
gr.update(visible=False), # submit_feedback_button
gr.update(visible=False), # rating_text
gr.update(visible=False, value=""), # question_correct
gr.update(visible=False, value=""), # text_coverage
gr.update(visible=False, value=""), # interesting_question
)
load_button.click(
update_question,
inputs=[
model_radio,
book_radio,
student_name_input,
class_name_input,
],
outputs=[
question_output,
answer_radio,
next_button,
feedback_input,
rating_buttons,
submit_feedback_button,
rating_text,
question_correct_input,
text_coverage_input,
interesting_question_input,
]
)
next_button.click(
get_next_question,
inputs=[answer_radio],
outputs=[
question_output,
answer_radio,
next_button,
feedback_input,
rating_buttons,
submit_feedback_button,
rating_text,
question_correct_input,
text_coverage_input,
interesting_question_input,
]
)
submit_feedback_button.click(
summarize_results,
inputs=[
student_name_input,
class_name_input,
model_radio,
book_radio,
feedback_input,
rating_buttons,
question_correct_input,
text_coverage_input,
interesting_question_input,
],
outputs=[
question_output,
feedback_input,
rating_buttons,
submit_feedback_button,
question_correct_input,
text_coverage_input,
interesting_question_input,
rating_text,
]
)
if __name__ == "__main__":
demo.launch()