import gradio as gr import matplotlib as mpl from quiz import BenchmarkQuiz, BENCHMARKS, QuestionData mpl.rcParams["figure.dpi"] = 300 quiz = BenchmarkQuiz() def update_quiz_screen(question_data: QuestionData): quiz_state = quiz.state return { quiz_screen: gr.update(visible=True), question_number: gr.update(value=question_data.question_num), question_text: gr.update(value=question_data.question), answer_input: gr.update( value=quiz_state.user_answers[quiz_state.current_question], choices=question_data.options, visible=BENCHMARKS[quiz_state.benchmark_name]["type"] == "multiple_choice", label=question_data.instruction, ), free_text_input: gr.update( value=quiz_state.user_answers[quiz_state.current_question], visible=BENCHMARKS[quiz_state.benchmark_name]["type"] == "free_text", label=question_data.instruction, ), next_button: gr.update( value=question_data.next_button_text, ), previous_button: gr.update(visible=question_data.previous_button_visibility), } def update_score_screen(plot, results_data): updates = { score_screen: gr.update(visible=True), score_plot: gr.update(value=plot), results_container: gr.update(visible=True), } for i, result in enumerate(results_data): updates[result_cards[i]] = gr.update( visible=True, elem_classes=[ "correct-answer" if result["points"] == 1.0 else "semi-correct-answer" if result["points"] == 0.5 else "incorrect-answer" ], ) emoji = "✅" if result["points"] == 1.0 else "❌" if result["points"] == 0.0 else "🔶" markdown_string = f"### {emoji} Spurning {result['question_num']}" markdown_string += f"\n{result['question']}" markdown_string += ( f"\n\nValkostir:\n" + "\n".join([f"- {option}" for option in result["options"]]) if result["options"] else "" ) markdown_string += f"\n\n**Þitt svar:** {result['user_answer']}" markdown_string += f"\n\n**Rétt svar:** {result['correct_answer']}" markdown_string += f"\n\n**Stig:** {result['points']}" updates[result_cards[i].children[0]] = gr.update(value=markdown_string) return updates def start_quiz_handler(benchmark_name): quiz.start_quiz(benchmark_name) question_data = quiz.update_question() return { start_screen: gr.update(visible=False), score_screen: gr.update(visible=False), **update_quiz_screen(question_data), } def next_question_handler(answer_input, free_text_input): answer = ( answer_input if BENCHMARKS[quiz.state.benchmark_name]["type"] == "multiple_choice" else free_text_input ) result = quiz.next_question(answer) if result["completed"]: return { quiz_screen: gr.update(visible=False), **update_score_screen(result["plot"], result["results_data"]), } else: return update_quiz_screen(result["question_data"]) def previous_question_handler(): question_data = quiz.previous_question() return update_quiz_screen(question_data) def reset_quiz_handler(): return { start_screen: gr.update(visible=True), quiz_screen: gr.update(visible=False), score_screen: gr.update(visible=False), next_button: gr.update(visible=True), } demo = gr.Blocks( theme=gr.themes.Soft(), title="Mælipróf", css=""" .correct-answer, .correct-answer .block { background-color: #d4edda !important; border-color: #c3e6cb !important; } .incorrect-answer, .incorrect-answer .block { background-color: #f8d7da !important; border-color: #f5c6cb !important; } .semi-correct-answer, .semi-correct-answer .block { background-color: #fff3cd !important; border-color: #ffeeba !important; } .correct-answer, .incorrect-answer, .semi-correct-answer { border-radius: 5px; padding: 10px; margin-bottom: 10px; } """, ) with demo: start_screen = gr.Column(visible=True) with start_screen: gr.Markdown("# Veldu mælipróf") benchmark_buttons = { name: gr.Button(info["name"]) for name, info in BENCHMARKS.items() } quiz_screen = gr.Column(visible=False) with quiz_screen: question_number = gr.Markdown() question_text = gr.Markdown() answer_input = gr.Radio(choices=[], visible=False) free_text_input = gr.Textbox(visible=False) with gr.Row(): previous_button = gr.Button("Fyrri") next_button = gr.Button("Næsta") score_screen = gr.Column(visible=False) with score_screen: gr.Markdown(f"## Niðurstöður") score_plot = gr.Plot() reset_btn = gr.Button("Byrja upp á nýtt") results_container = gr.Column(visible=False) with results_container: result_cards = [gr.Group(visible=False) for _ in range(5)] for card in result_cards: with card: gr.Markdown("") for benchmark_name, button in benchmark_buttons.items(): button.click( fn=start_quiz_handler, inputs=[gr.State(benchmark_name)], outputs=[ start_screen, quiz_screen, score_screen, question_number, question_text, answer_input, free_text_input, next_button, previous_button, ], ) next_button.click( fn=next_question_handler, inputs=[answer_input, free_text_input], outputs=[ quiz_screen, score_screen, question_number, question_text, answer_input, free_text_input, next_button, previous_button, score_plot, results_container, *result_cards, *[child for card in result_cards for child in card.children], ], ) previous_button.click( fn=previous_question_handler, inputs=[], outputs=[ quiz_screen, question_number, question_text, answer_input, free_text_input, next_button, previous_button, ], ) reset_btn.click( fn=reset_quiz_handler, inputs=[], outputs=[start_screen, quiz_screen, score_screen, next_button], ) demo.launch()