import gradio as gr
import random
import string
import time
from collections import defaultdict
def generate_student_id():
return ''.join(random.choices(string.ascii_letters + string.digits, k=12))
def update_student_state(students, class_id, student_id, color):
if class_id not in students:
students[class_id] = {}
students[class_id][student_id] = {"color": color}
return students, f"Status updated to {color}"
def submit_question(questions, class_id, student_id, question):
if class_id not in questions:
questions[class_id] = []
questions[class_id].append({"student_id": student_id, "question": question})
return questions, "Question submitted successfully"
def get_class_stats(students, questions, class_id):
if class_id not in students:
return "No data available for this class."
class_students = students[class_id]
total_students = len(class_students)
active_students = sum(1 for s in class_students.values() if s["color"] != "inactive")
color_counts = {"green": 0, "yellow": 0, "red": 0}
for student in class_students.values():
if student["color"] in color_counts:
color_counts[student["color"]] += 1
color_fractions = {color: count / (active_students or 1) for color, count in color_counts.items()}
color_chart = f"""
"""
stats_text = f"""
Class Statistics
Total Students: {total_students}
Active Students: {active_students}
"""
questions_text = "Student Questions
"
for q in questions.get(class_id, []):
questions_text += f"Student {q['student_id'][:4]}...: {q['question']}
"
return f"{color_chart}
{stats_text}
{questions_text}"
def create_interface():
with gr.Blocks(theme=gr.themes.Soft()) as app:
students = gr.State({})
questions = gr.State({})
class_id = gr.State("")
student_id = gr.State("")
gr.Markdown("# Fastcups")
with gr.Tab("Setup"):
class_input = gr.Textbox(label="Enter Class ID")
setup_button = gr.Button("Set Class ID")
with gr.Tab("Student"):
gr.Markdown("## Student Interface")
status = gr.Textbox(label="Current Status", interactive=False)
with gr.Row():
color_buttons = [
gr.Button("🟢 I'm following along", variant="primary"),
gr.Button("🟡 I need clarification", variant="secondary"),
gr.Button("🔴 I'm lost, please stop", variant="stop")
]
question_input = gr.Textbox(label="Ask a question")
submit_button = gr.Button("Submit Question")
question_status = gr.Textbox(label="Question Status", interactive=False)
with gr.Tab("Teacher"):
gr.Markdown("## Teacher Interface")
stats_html = gr.HTML()
refresh_button = gr.Button("Refresh Stats")
def setup_class(class_id_input):
return class_id_input, generate_student_id()
setup_button.click(setup_class, inputs=[class_input], outputs=[class_id, student_id])
for button, color in zip(color_buttons, ["green", "yellow", "red"]):
button.click(
update_student_state,
inputs=[students, class_id, student_id, gr.State(color)],
outputs=[students, status]
)
submit_button.click(
submit_question,
inputs=[questions, class_id, student_id, question_input],
outputs=[questions, question_status]
)
refresh_button.click(
get_class_stats,
inputs=[students, questions, class_id],
outputs=[stats_html]
)
# Auto-refresh every 5 seconds
gr.HTML('')
return app
if __name__ == "__main__":
app = create_interface()
app.launch()