Spaces:
Running
Running
| import gradio as gr | |
| import matplotlib as mpl | |
| from quiz import BenchmarkQuiz, BENCHMARKS, QuestionData | |
| mpl.rcParams["figure.dpi"] = 300 | |
| def update_quiz_screen(quiz: BenchmarkQuiz, 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 = BenchmarkQuiz() | |
| 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(quiz, question_data), | |
| quiz_state: quiz, | |
| } | |
| def next_question_handler(quiz, 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"]), | |
| quiz_state: quiz, | |
| } | |
| else: | |
| return {**update_quiz_screen(quiz, result["question_data"]), quiz_state: quiz} | |
| def previous_question_handler(quiz): | |
| question_data = quiz.previous_question() | |
| return {**update_quiz_screen(quiz, question_data), quiz_state: quiz} | |
| 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("# Kepptu við risamállíkönin!") | |
| gr.Markdown( | |
| "Veldu þér einn af flokkunum að neðan og þreyttu stutta útgáfu af prófi sem við leggjum fyrir risamállíkönin. " | |
| "Eftir að þú hefur lokið prófinu færðu að sjá hvar þú stendur miðað við líkönin." | |
| ) | |
| 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("") | |
| quiz_state = gr.State() | |
| 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, | |
| quiz_state, | |
| ], | |
| ) | |
| next_button.click( | |
| fn=next_question_handler, | |
| inputs=[quiz_state, 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], | |
| quiz_state, | |
| ], | |
| ) | |
| previous_button.click( | |
| fn=previous_question_handler, | |
| inputs=[quiz_state], | |
| outputs=[ | |
| quiz_screen, | |
| question_number, | |
| question_text, | |
| answer_input, | |
| free_text_input, | |
| next_button, | |
| previous_button, | |
| quiz_state, | |
| ], | |
| ) | |
| reset_btn.click( | |
| fn=reset_quiz_handler, | |
| inputs=[], | |
| outputs=[start_screen, quiz_screen, score_screen, next_button], | |
| ) | |
| demo.launch() | |