import gradio as gr import os import pandas as pd from datetime import datetime import calendar from db import Database from UserDetail import UserDetail import image import encdec import plotly.graph_objects as go import plotly.express as px # Initialize database db = Database() # Custom CSS for beautiful styling custom_css = """ .gradio-container { font-family: 'Arial', sans-serif; } .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 2rem; border-radius: 15px; color: white; text-align: center; margin-bottom: 2rem; } .success-box { background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); padding: 1rem; border-radius: 10px; color: white; text-align: center; } .error-box { background: #ff6b6b; padding: 1rem; border-radius: 10px; color: white; } """ # ============================================ # HOME PAGE # ============================================ def show_home(): """Display home page with statistics""" stats = db.get_statistics() html = f"""

šŸŽ“ Suthukeny Government High School

AI-Powered Student Management & Performance Analysis System

{stats['total_students']}

Total Students

{len(stats['class_wise'])}

Active Classes

{stats['students_with_marks']}

Students with Records

✨ Key Features

šŸ“– How to Use

  1. Register Student: Upload photo and enter details
  2. Student Login: Use face recognition to access profile
  3. Update Marks: Teachers enter monthly exam scores
  4. View Reports: Analyze performance with charts
  5. Manage Students: Edit or update student information

Suthukeny Government High School

Empowering Education Through Technology šŸš€

""" return html # ============================================ # STUDENT REGISTRATION # ============================================ def register_student(photo, name, dob, class_std, section, father_name, mother_name, address, phone, email, blood_group): """Register a new student with face recognition""" try: # Validation if photo is None: return "āŒ Please upload a student photo", None, None if not name or not dob or not class_std or not section: return "āŒ Please fill all required fields (Name, DOB, Class, Section)", None, None # Generate student ID student_id = db.generate_student_id(class_std) # Save image and create face encoding success, message = image.save_image_from_path(photo, student_id) if not success: return f"āŒ {message}", None, None # Create user detail object user_detail = UserDetail( student_id, name, str(dob), class_std, section, father_name or "", mother_name or "", address or "", phone or "", email or "", blood_group or "" ) # Insert into database success, db_message = db.insert_student(user_detail) if success: # Create student card HTML card_html = f"""

āœ… Registration Successful!

Student ID: {student_id}

Student registered successfully with face recognition!

Student Information

Name: {name}

Class: {class_std}-{section}

DOB: {dob}

Father: {father_name}

Mother: {mother_name}

Blood Group: {blood_group}

""" return card_html, photo, f"Student ID: {student_id}" else: image.delete_image(student_id) return f"āŒ {db_message}", None, None except Exception as e: return f"āŒ Error: {str(e)}", None, None # ============================================ # STUDENT LOGIN # ============================================ def login_with_face(photo): """Login student using face recognition""" try: if photo is None: return "āŒ Please capture your photo", None # Save temporary image temp_path = image.save_temp_image_from_path(photo) if not temp_path: return "āŒ Failed to process image", None # Recognize face is_match, student_id, confidence, message = image.recognize_face(temp_path) # Clean up image.delete_temp_image() if is_match: # Get student details student = db.get_student(student_id) if student: # Create profile HTML profile_html = f"""

šŸ‘‹ Welcome, {student.student_name}!

Student ID: {student.student_id} | Class: {student.class_std}-{student.section}

Match Confidence: {confidence:.1f}%

šŸ“‹ Personal Information

Name: {student.student_name}

Date of Birth: {student.dob}

Class: {student.class_std}-{student.section}

Father's Name: {student.father_name or 'Not specified'}

Mother's Name: {student.mother_name or 'Not specified'}

Address: {student.address or 'Not specified'}

Phone: {student.phone or 'Not specified'}

Email: {student.email or 'Not specified'}

Blood Group: {student.blood_group or 'Not specified'}

""" # Get marks marks_records = db.get_student_marks(student_id) if marks_records: marks_html = "

šŸ“Š Recent Performance

" for record in marks_records[:3]: # Show last 3 exams marks_html += f"""

{record[0]} {record[1]}

Total: {record[12]}/500 | Percentage: {record[13]:.1f}%

{record[2]}: {record[3]} | {record[4]}: {record[5]} | {record[6]}: {record[7]} | {record[8]}: {record[9]} | {record[10]}: {record[11]}

""" marks_html += "
" profile_html += marks_html return profile_html, student_id else: return "āŒ Student record not found", None else: return f"āŒ {message}\n\nšŸ’” Tip: Ensure good lighting and face the camera directly", None except Exception as e: return f"āŒ Error: {str(e)}", None # ============================================ # MARKS MANAGEMENT # ============================================ def get_students_in_class(class_std, section): """Get list of students in a class""" students = db.get_all_students(class_filter=class_std) class_students = [s for s in students if s[4] == section] if class_students: return gr.Dropdown(choices=[f"{s[1]} ({s[0]})" for s in class_students], label="Select Student") else: return gr.Dropdown(choices=[], label="No students in this class") def save_marks(class_std, section, student_display, exam_month, exam_year, subj1_name, subj1_marks, subj2_name, subj2_marks, subj3_name, subj3_marks, subj4_name, subj4_marks, subj5_name, subj5_marks): """Save student marks""" try: if not student_display: return "āŒ Please select a student" # Extract student ID from display string student_id = student_display.split("(")[-1].strip(")") # Validate inputs subject_names = [subj1_name, subj2_name, subj3_name, subj4_name, subj5_name] marks_list = [subj1_marks, subj2_marks, subj3_marks, subj4_marks, subj5_marks] if any(not s.strip() for s in subject_names): return "āŒ Please enter names for all subjects" # Save marks success, message = db.insert_marks( student_id, exam_month, exam_year, subject_names, marks_list ) if success: total = sum(marks_list) percentage = (total / 500) * 100 return f"""

āœ… Marks Saved Successfully!

Total: {total}/500 | Percentage: {percentage:.2f}%

""" else: return f"āŒ {message}" except Exception as e: return f"āŒ Error: {str(e)}" # ============================================ # REPORTS # ============================================ def generate_class_report(class_std, exam_year): """Generate class performance report""" try: performance = db.get_class_performance( class_std, exam_year=exam_year if exam_year != "All" else None ) if not performance: return "šŸ“ No performance data available for selected filters", None # Create DataFrame df = pd.DataFrame(performance, columns=[ 'Student ID', 'Name', 'Month', 'Year', 'Total', 'Percentage' ]) # Calculate average avg_percentage = df['Percentage'].mean() # Create report HTML report_html = f"""

šŸ“Š Class {class_std} Performance Report

Average: {avg_percentage:.1f}%

""" # Create bar chart fig = go.Figure(data=[ go.Bar( x=df['Name'], y=df['Percentage'], marker=dict( color=df['Percentage'], colorscale='RdYlGn', showscale=True ), text=df['Percentage'].round(1), textposition='auto', ) ]) fig.update_layout( title=f"Class {class_std} Student Performance", xaxis_title="Student", yaxis_title="Percentage", height=500 ) return report_html, fig except Exception as e: return f"āŒ Error: {str(e)}", None # ============================================ # ADMIN PANEL # ============================================ def admin_login(password): """Verify admin password""" if password == encdec.get_admin_password(): stats = db.get_statistics() html = f"""

āœ… Admin Access Granted

šŸ“Š System Statistics

Total Students: {stats['total_students']}

Active Classes: {len(stats['class_wise'])}

Students with Marks: {stats['students_with_marks']}

Class Distribution:

āš ļø Data Management

Use with caution! Data operations are permanent.

""" return html else: return """

āŒ Incorrect Password

""" # ============================================ # CREATE GRADIO INTERFACE # ============================================ with gr.Blocks(css=custom_css, title="Suthukeny Govt High School", theme=gr.themes.Soft()) as app: gr.Markdown(""" # šŸŽ“ Suthukeny Government High School ## AI-Powered Student Management & Performance Analysis System """) with gr.Tabs(): # HOME TAB with gr.Tab("šŸ  Home"): home_output = gr.HTML(show_home()) gr.Button("šŸ”„ Refresh Statistics").click( fn=show_home, outputs=home_output ) # REGISTRATION TAB with gr.Tab("šŸ“ Register Student"): gr.Markdown("### Register New Student") gr.Markdown("Upload a clear, front-facing photo of the student") with gr.Row(): with gr.Column(scale=1): reg_photo = gr.Image(type="filepath", label="Student Photo", sources=["upload", "webcam"]) with gr.Column(scale=2): with gr.Group(): gr.Markdown("#### Required Information") reg_name = gr.Textbox(label="Student Name *", placeholder="Enter full name") with gr.Row(): reg_dob = gr.Textbox(label="Date of Birth * (YYYY-MM-DD)", placeholder="2010-01-01") reg_class = gr.Dropdown(choices=["6", "7", "8", "9", "10", "11", "12"], label="Class *") reg_section = gr.Dropdown(choices=["A", "B", "C"], label="Section *") with gr.Group(): gr.Markdown("#### Family Information") with gr.Row(): reg_father = gr.Textbox(label="Father's Name", placeholder="Optional") reg_mother = gr.Textbox(label="Mother's Name", placeholder="Optional") with gr.Group(): gr.Markdown("#### Contact Information") reg_address = gr.Textbox(label="Address", placeholder="Optional", lines=2) with gr.Row(): reg_phone = gr.Textbox(label="Phone", placeholder="Optional") reg_email = gr.Textbox(label="Email", placeholder="Optional") reg_blood = gr.Dropdown(choices=["", "A+", "A-", "B+", "B-", "AB+", "AB-", "O+", "O-"], label="Blood Group") reg_button = gr.Button("āœ… Register Student", variant="primary", size="lg") reg_output = gr.HTML() reg_photo_display = gr.Image(label="Registered Student", visible=False) reg_id_display = gr.Textbox(label="Student ID", visible=False) reg_button.click( fn=register_student, inputs=[reg_photo, reg_name, reg_dob, reg_class, reg_section, reg_father, reg_mother, reg_address, reg_phone, reg_email, reg_blood], outputs=[reg_output, reg_photo_display, reg_id_display] ) # LOGIN TAB with gr.Tab("šŸ” Student Login"): gr.Markdown("### Face Recognition Login") gr.Markdown("šŸ“ø Position your face in the center and click capture") with gr.Row(): with gr.Column(scale=1): login_photo = gr.Image(type="filepath", label="Capture Your Face", sources=["webcam"]) login_button = gr.Button("šŸ” Login with Face", variant="primary", size="lg") with gr.Column(scale=2): login_output = gr.HTML() login_student_id = gr.Textbox(label="Logged in Student ID", visible=False) login_button.click( fn=login_with_face, inputs=login_photo, outputs=[login_output, login_student_id] ) # MARKS ENTRY TAB with gr.Tab("šŸ“Š Marks Entry"): gr.Markdown("### Enter Student Marks") with gr.Row(): marks_class = gr.Dropdown(choices=["6", "7", "8", "9", "10", "11", "12"], label="Class") marks_section = gr.Dropdown(choices=["A", "B", "C"], label="Section") marks_student = gr.Dropdown(label="Select Student", choices=[]) # Update student dropdown when class/section changes marks_class.change( fn=get_students_in_class, inputs=[marks_class, marks_section], outputs=marks_student ) marks_section.change( fn=get_students_in_class, inputs=[marks_class, marks_section], outputs=marks_student ) with gr.Row(): marks_month = gr.Dropdown( choices=list(calendar.month_name)[1:], label="Exam Month", value=calendar.month_name[datetime.now().month] ) marks_year = gr.Dropdown( choices=[str(y) for y in range(datetime.now().year - 1, datetime.now().year + 2)], label="Exam Year", value=str(datetime.now().year) ) gr.Markdown("#### Enter Marks (Out of 100)") with gr.Row(): with gr.Column(): subj1_name = gr.Textbox(label="Subject 1 Name", value="Tamil") subj1_marks = gr.Number(label="Marks", value=0, minimum=0, maximum=100) with gr.Column(): subj2_name = gr.Textbox(label="Subject 2 Name", value="English") subj2_marks = gr.Number(label="Marks", value=0, minimum=0, maximum=100) with gr.Row(): with gr.Column(): subj3_name = gr.Textbox(label="Subject 3 Name", value="Mathematics") subj3_marks = gr.Number(label="Marks", value=0, minimum=0, maximum=100) with gr.Column(): subj4_name = gr.Textbox(label="Subject 4 Name", value="Science") subj4_marks = gr.Number(label="Marks", value=0, minimum=0, maximum=100) with gr.Row(): with gr.Column(): subj5_name = gr.Textbox(label="Subject 5 Name", value="Social Science") subj5_marks = gr.Number(label="Marks", value=0, minimum=0, maximum=100) with gr.Column(): save_marks_btn = gr.Button("šŸ’¾ Save Marks", variant="primary", size="lg") marks_output = gr.HTML() save_marks_btn.click( fn=save_marks, inputs=[marks_class, marks_section, marks_student, marks_month, marks_year, subj1_name, subj1_marks, subj2_name, subj2_marks, subj3_name, subj3_marks, subj4_name, subj4_marks, subj5_name, subj5_marks], outputs=marks_output ) # REPORTS TAB with gr.Tab("šŸ“ˆ Reports"): gr.Markdown("### Performance Reports") with gr.Row(): report_class = gr.Dropdown(choices=["6", "7", "8", "9", "10", "11", "12"], label="Select Class", value="6") report_year = gr.Dropdown(choices=["All"] + [str(y) for y in range(datetime.now().year - 2, datetime.now().year + 1)], label="Exam Year", value=str(datetime.now().year)) report_btn = gr.Button("šŸ“Š Generate Report", variant="primary") report_output = gr.HTML() report_chart = gr.Plot() report_btn.click( fn=generate_class_report, inputs=[report_class, report_year], outputs=[report_output, report_chart] ) # ADMIN TAB with gr.Tab("šŸ”§ Admin Panel"): gr.Markdown("### Admin Access") gr.Markdown("āš ļø Authorized personnel only") admin_password = gr.Textbox(label="Admin Password", type="password") admin_login_btn = gr.Button("šŸ” Login", variant="primary") admin_output = gr.HTML() admin_login_btn.click( fn=admin_login, inputs=admin_password, outputs=admin_output ) gr.Markdown(""" ---

Suthukeny Government High School

Empowering Education Through Technology šŸš€

""") # Launch the app if __name__ == "__main__": app.launch(server_name="0.0.0.0", server_port=7860)