yasvanthkumar's picture
Update app.py
a9a4755 verified
import gradio as gr
import random
import time
import os
# Quiz questions and answers
questions = [
{
"id": 1,
"question": "Who designed the Eiffel Tower?",
"options": ["Gustave Eiffel", "Alexander Eiffel", "Emily Eiffel", "Robert Eiffel"],
"answer": 0,
"explanation": "The Eiffel Tower was designed by the French engineer Gustave Eiffel.",
"difficulty": "medium",
"image": None
},
{
"id": 2,
"question": "What material is primarily used in reinforced concrete?",
"options": ["Steel", "Wood", "Plastic", "Aluminum"],
"answer": 0,
"explanation": "Steel reinforcement bars (rebar) are used to strengthen concrete.",
"difficulty": "easy",
"image": None
},
{
"id": 3,
"question": "The Golden Gate Bridge is located in which city?",
"options": ["San Francisco", "Los Angeles", "New York", "Chicago"],
"answer": 0,
"explanation": "The Golden Gate Bridge spans the Golden Gate strait in San Francisco.",
"difficulty": "easy",
"image": None
},
{
"id": 4,
"question": "What is the standard height of a residential floor?",
"options": ["3 meters", "2.4 meters", "4 meters", "1.8 meters"],
"answer": 1,
"explanation": "Most residential floors are about 2.4 meters (8 feet) high.",
"difficulty": "medium",
"image": None
},
{
"id": 5,
"question": "Which foundation type is best for unstable soil?",
"options": ["Pile foundation", "Strip foundation", "Raft foundation", "Pad foundation"],
"answer": 0,
"explanation": "Pile foundations transfer building loads to deeper, more stable soil layers.",
"difficulty": "hard",
"image": None
}
]
class QuizApp:
def __init__(self):
self.questions = random.sample(questions, k=min(5, len(questions)))
self.current_question = 0
self.score = 0
self.responses = []
self.start_time = time.time()
def get_current_question(self):
if self.current_question < len(self.questions):
return self.questions[self.current_question]
return None
def submit_answer(self, answer_idx):
question = self.get_current_question()
if question is None:
return False, ""
is_correct = int(answer_idx) == question["answer"]
if is_correct:
self.score += 1
self.responses.append({
"question_id": question["id"],
"answer": answer_idx,
"correct": is_correct,
"explanation": question["explanation"]
})
self.current_question += 1
return is_correct, question["explanation"]
def get_results(self):
total_time = round(time.time() - self.start_time, 1)
return {
"score": self.score,
"total": len(self.questions),
"percentage": (self.score / len(self.questions)) * 100,
"time": total_time
}
def start_quiz():
return QuizApp()
def render_question(quiz):
question = quiz.get_current_question()
if question is None:
return render_results(quiz)
options = []
for idx, option in enumerate(question["options"]):
options.append(gr.Radio(choices=[option], value=None, label=f"Option {idx+1}"))
progress = (quiz.current_question / len(quiz.questions)) * 100
return (
gr.Markdown(f"### Question {quiz.current_question + 1} of {len(quiz.questions)}"),
gr.Markdown(f"**{question['question']}**"),
*options,
gr.Markdown(f"Difficulty: **{question['difficulty'].capitalize()}**"),
gr.HTML(f"""
<div style="height: 10px; background: #eee; border-radius: 5px; margin: 15px 0; overflow: hidden;">
<div style="height: 100%; background: #FFD700; width: {progress}%; border-radius: 5px;"></div>
</div>
"""),
gr.Button("Submit Answer", variant="primary")
)
def next_question(answer_idx, quiz):
if quiz.get_current_question() is None:
return render_results(quiz)
is_correct, explanation = quiz.submit_answer(answer_idx)
feedback = f"{'βœ… Correct!' if is_correct else '❌ Incorrect!'} {explanation}"
if quiz.get_current_question() is None:
return render_results(quiz)
new_ui = render_question(quiz)
return new_ui + (gr.Markdown(feedback),)
def render_results(quiz):
results = quiz.get_results()
response_html = "<div style='margin-top: 20px;'>"
for i, response in enumerate(quiz.responses):
q = next(q for q in questions if q["id"] == response["question_id"])
icon = "βœ…" if response["correct"] else "❌"
response_html += f"""
<div style="background: {'#e8f5e9' if response['correct'] else '#ffebee'};
padding: 10px; border-radius: 8px; margin-bottom: 10px;
border-left: 4px solid {'#4CAF50' if response['correct'] else '#F44336'}">
<h4>{icon} Question {i+1}: {q['question']}</h4>
<p>Your answer: {q['options'][int(response['answer'])]}</p>
<p>Correct answer: {q['options'][q['answer']]}</p>
<p><strong>Explanation:</strong> {response['explanation']}</p>
</div>
"""
response_html += "</div>"
return (
gr.Markdown("# πŸ† Quiz Results"),
gr.Markdown(f"## Your Score: {results['score']}/{results['total']} ({results['percentage']:.1f}%)"),
gr.Markdown(f"**Time taken:** {results['time']} seconds"),
gr.HTML(response_html),
gr.Button("Restart Quiz", variant="primary")
)
def restart_quiz(quiz):
return render_question(QuizApp())
with gr.Blocks(title="πŸ—οΈ Building Construction Quiz") as demo:
quiz_state = gr.State()
with gr.Column():
header = gr.Markdown("# πŸ—οΈ Building Construction Quiz")
question_display = gr.Markdown()
options_display = [gr.Radio(visible=False) for _ in range(4)]
progress_display = gr.HTML()
submit_btn = gr.Button(visible=False)
feedback_display = gr.Markdown()
results_display = gr.Column(visible=False)
demo.load(
fn=start_quiz,
inputs=None,
outputs=[quiz_state]
)
demo.load(
fn=render_question,
inputs=[quiz_state],
outputs=[question_display, *options_display, progress_display, submit_btn]
)
submit_btn.click(
fn=next_question,
inputs=[gr.get_selected(options_display), quiz_state],
outputs=[question_display, *options_display, progress_display, submit_btn, feedback_display]
)
results_display.children[4].click(
fn=restart_quiz,
inputs=[quiz_state],
outputs=[question_display, *options_display, progress_display, submit_btn, feedback_display]
)
if __name__ == "__main__":
demo.launch()