HarshitaSuri's picture
Update app.py
88c9604 verified
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()