|
import gradio as gr |
|
import random |
|
import string |
|
import time |
|
from collections import defaultdict |
|
|
|
|
|
students = {} |
|
class_data = defaultdict(lambda: {"students": set(), "questions": []}) |
|
|
|
def generate_student_id(): |
|
return ''.join(random.choices(string.ascii_letters + string.digits, k=12)) |
|
|
|
def update_student_state(student_id, class_id, color): |
|
if student_id not in students: |
|
students[student_id] = {"class_id": class_id, "color": "inactive"} |
|
students[student_id]["color"] = color |
|
class_data[class_id]["students"].add(student_id) |
|
return f"Status updated to {color}" |
|
|
|
def submit_question(student_id, class_id, question): |
|
class_data[class_id]["questions"].append({"student_id": student_id, "question": question}) |
|
return "Question submitted successfully" |
|
|
|
def get_class_stats(class_id): |
|
class_students = [s for s in students.values() if s["class_id"] == class_id] |
|
total_students = len(class_students) |
|
active_students = sum(1 for s in class_students if s["color"] != "inactive") |
|
color_counts = {"green": 0, "yellow": 0, "red": 0} |
|
for student in class_students: |
|
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()} |
|
|
|
return { |
|
"total_students": total_students, |
|
"active_students": active_students, |
|
"color_fractions": color_fractions, |
|
"questions": class_data[class_id]["questions"] |
|
} |
|
|
|
def create_student_interface(class_id): |
|
student_id = gr.State(generate_student_id()) |
|
|
|
with gr.Row(): |
|
with gr.Column(scale=2): |
|
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") |
|
] |
|
with gr.Column(scale=1): |
|
status = gr.Textbox(label="Current Status", interactive=False) |
|
|
|
question_input = gr.Textbox(label="Ask a question") |
|
submit_button = gr.Button("Submit Question") |
|
question_status = gr.Textbox(label="Question Status", interactive=False) |
|
|
|
for button, color in zip(color_buttons, ["green", "yellow", "red"]): |
|
button.click( |
|
update_student_state, |
|
inputs=[student_id, gr.State(class_id), gr.State(color)], |
|
outputs=status |
|
) |
|
|
|
submit_button.click( |
|
submit_question, |
|
inputs=[student_id, gr.State(class_id), question_input], |
|
outputs=question_status |
|
) |
|
|
|
return gr.Interface( |
|
fn=lambda: None, |
|
inputs=[], |
|
outputs=[], |
|
title=f"Student Interface - Class {class_id}", |
|
description="Use the buttons to indicate your understanding and ask questions.", |
|
theme="default" |
|
) |
|
|
|
def create_teacher_interface(class_id): |
|
def render_stats(): |
|
stats = get_class_stats(class_id) |
|
color_chart = f""" |
|
<div style="width: 100%; height: 60px; display: flex;"> |
|
<div style="width: {stats['color_fractions']['red']*100}%; background-color: #ff6b6b;"></div> |
|
<div style="width: {stats['color_fractions']['yellow']*100}%; background-color: #feca57;"></div> |
|
<div style="width: {stats['color_fractions']['green']*100}%; background-color: #5cd85c;"></div> |
|
</div> |
|
""" |
|
stats_text = f""" |
|
<h3>Class Statistics</h3> |
|
<p>Total Students: {stats['total_students']}</p> |
|
<p>Active Students: {stats['active_students']}</p> |
|
""" |
|
questions_text = "<h3>Student Questions</h3>" |
|
for q in stats['questions']: |
|
questions_text += f"<p><strong>Student {q['student_id'][:4]}...</strong>: {q['question']}</p>" |
|
|
|
return f"{color_chart}<br>{stats_text}<br>{questions_text}" |
|
|
|
stats_html = gr.HTML() |
|
refresh_button = gr.Button("Refresh Stats") |
|
|
|
refresh_button.click(render_stats, inputs=[], outputs=[stats_html]) |
|
|
|
return gr.Interface( |
|
fn=lambda: None, |
|
inputs=[], |
|
outputs=[], |
|
title=f"Teacher Interface - Class {class_id}", |
|
description="Monitor student understanding and view questions.", |
|
theme="default" |
|
) |
|
|
|
def launch_app(class_id): |
|
student_interface = create_student_interface(class_id) |
|
teacher_interface = create_teacher_interface(class_id) |
|
|
|
app = gr.TabbedInterface( |
|
[student_interface, teacher_interface], |
|
["Student", "Teacher"], |
|
title=f"Fastcups - Class {class_id}", |
|
theme=gr.themes.Soft() |
|
) |
|
app.launch() |
|
|
|
if __name__ == "__main__": |
|
class_id = input("Enter class ID: ") |
|
launch_app(class_id) |