import gradio as gr import pandas as pd import json import os from datetime import datetime print("🚀 Teacher Assistant - Starting...") # ============ DATA STORAGE ============ DATA_DIR = "data" os.makedirs(DATA_DIR, exist_ok=True) STUDENTS_FILE = os.path.join(DATA_DIR, "students.json") EXAMS_FILE = os.path.join(DATA_DIR, "exams.json") GRADES_FILE = os.path.join(DATA_DIR, "grades.json") def load_json(filepath): if os.path.exists(filepath): try: with open(filepath, 'r') as f: return json.load(f) except: return {} return {} def save_json(data, filepath): with open(filepath, 'w') as f: json.dump(data, f, indent=2) # Initialize files for file in [STUDENTS_FILE, EXAMS_FILE, GRADES_FILE]: if not os.path.exists(file): save_json({}, file) # ============ TAB 1: QUESTION GENERATOR ============ def create_exam(topic, num_q, q_type): if not topic: return "Enter a topic", "", "" questions = [] answers = [] for i in range(num_q): if q_type == "Multiple Choice": q = f"Q{i+1}: What is important about {topic}?" a = f"A) Option A\nB) Option B\nC) Option C\nD) Option D" ans = f"Answer: C" elif q_type == "True or False": q = f"Q{i+1}: {topic} is important. (True/False)" a = "" ans = f"Answer: True" elif q_type == "Identification": q = f"Q{i+1}: Define {topic}." a = "" ans = f"Answer: [Definition]" elif q_type == "Essay": q = f"Q{i+1}: Discuss {topic}." a = "\n[Essay space]" ans = f"Answer: [Essay rubric]" else: # Matching Type q = f"Q{i+1}: Match terms about {topic}." a = "\n1. Term1 → A. Def1\n2. Term2 → B. Def2\n3. Term3 → C. Def3" ans = f"Answer: 1-A, 2-B, 3-C" questions.append(q + a) answers.append(ans) exam_id = f"EXAM-{datetime.now().strftime('%H%M%S')}" exam_data = { "id": exam_id, "topic": topic, "questions": questions, "answers": answers, "date": datetime.now().isoformat() } exams = load_json(EXAMS_FILE) exams[exam_id] = exam_data save_json(exams, EXAMS_FILE) return "\n\n".join(questions), "\n\n".join(answers), exam_id def download_exam(questions, exam_id): if not questions: return None filename = f"{exam_id}.txt" with open(filename, 'w') as f: f.write(f"EXAM: {exam_id}\n\n{questions}") return filename # ============ TAB 2: STUDENT MANAGEMENT ============ def add_student(s_id, f_name, l_name, s_class): if not s_id or not f_name: return "Fill required fields" students = load_json(STUDENTS_FILE) if s_id in students: return "Student exists" student = { "id": s_id, "name": f"{f_name} {l_name}", "class": s_class, "added": datetime.now().isoformat(), "exams": 0, "avg": 0 } students[s_id] = student save_json(students, STUDENTS_FILE) return f"Added {f_name} {l_name}" def get_students(): students = load_json(STUDENTS_FILE) if not students: return pd.DataFrame(columns=["ID", "Name", "Class", "Exams", "Avg"]) rows = [] for sid, data in students.items(): rows.append([sid, data["name"], data["class"], data["exams"], f"{data['avg']:.1f}%"]) return pd.DataFrame(rows, columns=["ID", "Name", "Class", "Exams", "Avg"]) def remove_student(s_id): students = load_json(STUDENTS_FILE) if s_id in students: name = students[s_id]["name"] del students[s_id] save_json(students, STUDENTS_FILE) return f"Removed {name}" return "Student not found" # ============ TAB 3: GRADING ============ def add_grade(s_id, e_id, score): if not s_id or not e_id: return "Fill all fields", 0, "N/A" students = load_json(STUDENTS_FILE) if s_id not in students: return "Student not found", 0, "N/A" # Calculate grade if score >= 90: grade = "A" elif score >= 80: grade = "B" elif score >= 70: grade = "C" elif score >= 60: grade = "D" else: grade = "F" # Update student student = students[s_id] student["exams"] += 1 if student["avg"] == 0: student["avg"] = score else: student["avg"] = (student["avg"] + score) / 2 save_json(students, STUDENTS_FILE) # Save grade grade_id = f"GRADE-{datetime.now().strftime('%H%M%S')}" grade_data = { "id": grade_id, "student": student["name"], "exam": e_id, "score": score, "grade": grade, "date": datetime.now().isoformat() } grades = load_json(GRADES_FILE) grades[grade_id] = grade_data save_json(grades, GRADES_FILE) return f"Grade saved for {student['name']}", score, grade def get_grades(): grades = load_json(GRADES_FILE) if not grades: return pd.DataFrame(columns=["Student", "Exam", "Score", "Grade", "Date"]) rows = [] for gid, data in grades.items(): rows.append([data["student"], data["exam"], f"{data['score']}%", data["grade"], data["date"][:10]]) return pd.DataFrame(rows, columns=["Student", "Exam", "Score", "Grade", "Date"]) # ============ TAB 4: ANALYTICS ============ def get_report(): students = load_json(STUDENTS_FILE) grades = load_json(GRADES_FILE) if not students: return "No data", pd.DataFrame() total_students = len(students) total_grades = len(grades) # Simple report report = f""" Students: {total_students} Grades: {total_grades} """ # Create simple table rows = [] for sid, data in students.items(): rows.append([sid, data["name"], data["class"], data["exams"], f"{data['avg']:.1f}%"]) df = pd.DataFrame(rows, columns=["ID", "Name", "Class", "Exams", "Average"]) return report, df # ============ TAB 5: SETTINGS ============ def save_setting(school, default_q): setting = { "school": school, "questions": default_q, "updated": datetime.now().isoformat() } setting_file = os.path.join(DATA_DIR, "settings.json") save_json(setting, setting_file) return f"Saved settings for {school}" def create_backup(): backup = { "students": load_json(STUDENTS_FILE), "exams": load_json(EXAMS_FILE), "grades": load_json(GRADES_FILE), "date": datetime.now().isoformat() } filename = f"backup_{datetime.now().strftime('%H%M%S')}.json" with open(filename, 'w') as f: json.dump(backup, f, indent=2) return f"Backup created", filename # ============ CREATE APP ============ def create_app(): """Create the Gradio app - SIMPLE VERSION""" with gr.Blocks() as app: # Header gr.Markdown("# 🍎 Teacher Assistant") gr.Markdown("Simple tool for teachers") with gr.Tabs(): # TAB 1: Create Exam with gr.TabItem("📝 Create Exam"): with gr.Row(): col1 = gr.Column() col2 = gr.Column() with col1: topic = gr.Textbox(label="Topic") num_q = gr.Slider(1, 20, value=5, label="Questions") q_type = gr.Dropdown(["Multiple Choice", "True or False", "Identification", "Essay", "Matching Type"], label="Type") btn = gr.Button("Create") with col2: questions = gr.Textbox(label="Questions", lines=10) answers = gr.Textbox(label="Answers", lines=5) exam_id = gr.Textbox(label="Exam ID") download = gr.Button("Download") btn.click(create_exam, [topic, num_q, q_type], [questions, answers, exam_id]) download.click(download_exam, [questions, exam_id], gr.File(label="File")) # TAB 2: Students with gr.TabItem("👥 Students"): with gr.Row(): col1 = gr.Column() col2 = gr.Column() with col1: s_id = gr.Textbox(label="Student ID") f_name = gr.Textbox(label="First Name") l_name = gr.Textbox(label="Last Name") s_class = gr.Textbox(label="Class") add_btn = gr.Button("Add Student") status = gr.Markdown("") with col2: table = gr.Dataframe(headers=["ID", "Name", "Class", "Exams", "Avg"]) refresh = gr.Button("Refresh") del_id = gr.Textbox(label="Delete ID") del_btn = gr.Button("Delete") del_status = gr.Markdown("") add_btn.click(add_student, [s_id, f_name, l_name, s_class], status).then(get_students, None, table) refresh.click(get_students, None, table) del_btn.click(remove_student, del_id, del_status).then(get_students, None, table) # TAB 3: Grades with gr.TabItem("✅ Grades"): with gr.Row(): col1 = gr.Column() col2 = gr.Column() with col1: g_sid = gr.Textbox(label="Student ID") g_eid = gr.Textbox(label="Exam ID") g_score = gr.Slider(0, 100, label="Score") g_btn = gr.Button("Add Grade") g_status = gr.Markdown("") score_disp = gr.Number(label="Score") grade_disp = gr.Textbox(label="Grade") with col2: grades_table = gr.Dataframe(headers=["Student", "Exam", "Score", "Grade", "Date"]) g_refresh = gr.Button("Refresh") g_btn.click(add_grade, [g_sid, g_eid, g_score], [g_status, score_disp, grade_disp]).then(get_grades, None, grades_table) g_refresh.click(get_grades, None, grades_table) # TAB 4: Analytics with gr.TabItem("📊 Analytics"): with gr.Row(): col1 = gr.Column() col2 = gr.Column() with col1: report_btn = gr.Button("Generate Report") report_text = gr.Markdown("") with col2: report_table = gr.Dataframe(headers=["ID", "Name", "Class", "Exams", "Average"]) report_btn.click(get_report, None, [report_text, report_table]) # TAB 5: Settings with gr.TabItem("⚙️ Settings"): with gr.Row(): col1 = gr.Column() col2 = gr.Column() with col1: school_name = gr.Textbox(label="School", value="My School") default_q = gr.Slider(1, 20, value=10, label="Default Questions") save_btn = gr.Button("Save") save_status = gr.Markdown("") with col2: backup_btn = gr.Button("Create Backup") backup_status = gr.Markdown("") backup_file = gr.File(label="Download") save_btn.click(save_setting, [school_name, default_q], save_status) backup_btn.click(create_backup, None, [backup_status, backup_file]) return app # ============ MAIN ============ if __name__ == "__main__": print("App starting...") print(f"Students: {len(load_json(STUDENTS_FILE))}") print(f"Exams: {len(load_json(EXAMS_FILE))}") print(f"Grades: {len(load_json(GRADES_FILE))}") app = create_app() app.launch(server_name="0.0.0.0", server_port=7860)