Spaces:
Sleeping
Sleeping
| import pandas as pd | |
| import gradio as gr | |
| from openpyxl import Workbook | |
| from openpyxl.styles import PatternFill | |
| import matplotlib.pyplot as plt | |
| import smtplib | |
| from email.mime.text import MIMEText | |
| import uuid | |
| def read_csv(file): | |
| return pd.read_csv(file) | |
| def assess_risk(row): | |
| attendance = row.get("Attendance (%)", 0) | |
| marks = row.get("Marks (%)", 0) | |
| fees_paid = str(row.get("Fees Paid", "")).strip().lower() | |
| if attendance < 60 and marks < 50 and fees_paid != "yes": | |
| return "High Risk" | |
| elif attendance < 60 or marks < 50 or fees_paid != "yes": | |
| return "Moderate Risk" | |
| else: | |
| return "Safe" | |
| def send_email(to_emails, subject, body, smtp_user, smtp_pass, smtp_host="smtp.gmail.com", smtp_port=587): | |
| msg = MIMEText(body) | |
| msg["Subject"] = subject | |
| msg["From"] = smtp_user | |
| msg["To"] = to_emails | |
| try: | |
| server = smtplib.SMTP(smtp_host, smtp_port) | |
| server.starttls() | |
| server.login(smtp_user, smtp_pass) | |
| server.sendmail(smtp_user, to_emails.split(","), msg.as_string()) | |
| server.quit() | |
| return "β Email sent successfully." | |
| except Exception as e: | |
| return f"β Email failed: {e}" | |
| def generate_report(attendance_file, tests_file, fees_file, notify_emails, smtp_user, smtp_pass): | |
| # Load CSVs | |
| att = read_csv(attendance_file) | |
| tst = read_csv(tests_file) | |
| fee = read_csv(fees_file) | |
| # Merge | |
| df = att.merge(tst, on="Roll Number", how="outer").merge(fee, on="Roll Number", how="outer") | |
| df["Name"] = df["Name"].fillna("") | |
| df["Risk"] = df.apply(assess_risk, axis=1) | |
| # Excel report | |
| wb = Workbook() | |
| ws = wb.active | |
| ws.title = "Dropout Risk Report" | |
| headers = list(df.columns) | |
| ws.append(headers) | |
| fills = { | |
| "Safe": PatternFill(start_color="C6EFCE", end_color="C6EFCE", fill_type="solid"), | |
| "Moderate Risk": PatternFill(start_color="FFEB9C", end_color="FFEB9C", fill_type="solid"), | |
| "High Risk": PatternFill(start_color="FFC7CE", end_color="FFC7CE", fill_type="solid") | |
| } | |
| for _, row in df.iterrows(): | |
| ws.append(list(row)) | |
| risk = row["Risk"] | |
| fill = fills.get(risk, None) | |
| if fill: | |
| risk_col = headers.index("Risk") + 1 | |
| ws.cell(row=ws.max_row, column=risk_col).fill = fill | |
| excel_path = f"risk_report_{uuid.uuid4().hex}.xlsx" | |
| wb.save(excel_path) | |
| # Risk chart | |
| risk_counts = df["Risk"].value_counts() | |
| fig, ax = plt.subplots() | |
| ax.bar(risk_counts.index, risk_counts.values, color=["green", "orange", "red"]) | |
| ax.set_title("Dropout Risk Distribution") | |
| ax.set_ylabel("Number of Students") | |
| chart_path = f"risk_chart_{uuid.uuid4().hex}.png" | |
| fig.savefig(chart_path) | |
| plt.close(fig) | |
| # Email notification | |
| email_status = "" | |
| if notify_emails and smtp_user and smtp_pass: | |
| email_status = send_email( | |
| to_emails=notify_emails, | |
| subject="Dropout Risk Report", | |
| body="The latest dropout risk report has been generated.", | |
| smtp_user=smtp_user, | |
| smtp_pass=smtp_pass | |
| ) | |
| return excel_path, chart_path, email_status | |
| # Gradio UI | |
| with gr.Blocks() as demo: | |
| gr.Markdown("## π Student Dropout Risk Generator") | |
| with gr.Row(): | |
| attendance = gr.File(label="Upload Attendance CSV") | |
| tests = gr.File(label="Upload Tests CSV") | |
| fees = gr.File(label="Upload Fees CSV") | |
| with gr.Accordion("π§ Email Notification (Optional)", open=False): | |
| notify_emails = gr.Textbox(label="Notify Emails (comma-separated)") | |
| smtp_user = gr.Textbox(label="SMTP Email") | |
| smtp_pass = gr.Textbox(label="SMTP Password", type="password") | |
| run_btn = gr.Button("Generate Report") | |
| excel_output = gr.File(label="Download Risk Report (.xlsx)") | |
| chart_output = gr.Image(label="Risk Distribution Chart") | |
| email_status_output = gr.Textbox(label="Email Status") | |
| run_btn.click( | |
| generate_report, | |
| inputs=[attendance, tests, fees, notify_emails, smtp_user, smtp_pass], | |
| outputs=[excel_output, chart_output, email_status_output] | |
| ) | |
| demo.launch() | |