S8_Project_Work / Backend.py
Manikandan-Alagu's picture
Update Backend.py
0068011 verified
import matplotlib.pyplot as plt
from fpdf import FPDF
from datetime import datetime
from huggingfaceModel import generate_dropout_insights
#rom ollamaModel import generate_dropout_insights
import re
import os
def format_key(key):
"""Format keys to be more readable by capitalizing and removing underscores."""
return key.replace("_", " ").title()
def remove_unsupported_characters(text):
"""Removes emojis and unsupported Unicode characters for PDF compatibility."""
return text.encode("ascii", "ignore").decode()
def generate_pdf(input_data, dropout_risk, summary):
"""Generates a structured, professional PDF report for dropout prediction results."""
pdf = FPDF()
pdf.add_page()
# ๐Ÿ”น Check if DejaVuSans font files exist
if os.path.exists("DejaVuSans.ttf") and os.path.exists("DejaVuSans-Bold.ttf") and os.path.exists("DejaVuSans-Oblique.ttf"):
font_name = "DejaVu"
pdf.add_font("DejaVu", "", "Dejavu/DejaVuSans.ttf", uni=True)
pdf.add_font("DejaVu", "B", "Dejavu/DejaVuSans-Bold.ttf", uni=True)
pdf.add_font("DejaVu", "I", "Dejavu/DejaVuSans-Oblique.ttf", uni=True)
else:
font_name = "Arial" # Use default Arial if DejaVu fonts are missing
# ๐Ÿ”น Cover Page
pdf.set_font(font_name, "B", 20)
pdf.cell(200, 15, "AI-DRIVEN DROPOUT PREDICTION AND PREVENTION TOOL", ln=True, align="C")
pdf.set_font(font_name, "I", 12)
pdf.cell(200, 10, "Generated by: AI Dropout Predictor System", ln=True, align="C")
pdf.cell(200, 10, f"Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align="C")
pdf.ln(20)
pdf.set_font(font_name, "B", 16)
pdf.cell(200, 10, "Confidential Report", ln=True, align="C")
pdf.ln(10)
pdf.set_font(font_name, "I", 12)
pdf.cell(200, 10, "This document contains confidential student information and predictive analysis.", ln=True, align="C")
pdf.add_page()
# ๐Ÿ”น Student Information Section
pdf.set_font(font_name, "B", 14)
pdf.cell(200, 10, "Student Information", ln=True, align="L")
pdf.ln(5)
pdf.set_font(font_name, "", 12)
for key, value in input_data.items():
formatted_key = key.replace("_", " ").title()
pdf.cell(90, 8, f"{formatted_key}:", border=1, align="L")
pdf.cell(100, 8, str(value), border=1, align="L")
pdf.ln(8)
pdf.ln(10)
pdf.add_page()
# ๐Ÿ”น Dropout Risk Score Section
pdf.set_font(font_name, "B", 14)
pdf.cell(200, 10, "Predicted Dropout Risk Score", ln=True, align="L")
pdf.ln(5)
pdf.set_font(font_name, "B", 16)
pdf.set_fill_color(240, 240, 240)
pdf.cell(200, 15, f" Dropout Risk Score: {dropout_risk}/10 ", ln=True, align="L", border=1, fill=True)
pdf.ln(10)
# ๐Ÿ”น Dropout Prediction Graph
pdf.set_font(font_name, "B", 14)
pdf.cell(200, 10, "Dropout Risk Analysis Graph", ln=True, align="C")
pdf.ln(5)
if os.path.exists("dropout_plot.png"):
pdf.image("dropout_plot.png", x=50, w=100)
else:
pdf.cell(200, 10, "Graph Unavailable", ln=True, align="C")
pdf.ln(20)
pdf.add_page()
# ๐Ÿ”น Summary Section
pdf.set_font(font_name, "B", 14)
pdf.cell(200, 10, "Summary of Student Data", ln=True, align="C")
pdf.ln(5)
pdf.set_font(font_name, "", 12)
cleaned_summary = remove_unsupported_characters(summary)
pdf.multi_cell(0, 7, cleaned_summary, align="L")
# ๐Ÿ”น Disclaimer
pdf.set_y(-30)
pdf.set_font(font_name, "I", 10)
pdf.cell(200, 10, "Disclaimer:", ln=True, align="L")
pdf.multi_cell(0, 7, "This report is generated using predictive analysis. It does not guarantee actual dropout behavior but serves as a guideline for early intervention.", align="L")
# ๐Ÿ”น Save PDF
pdf_filename = "Dropout_Report.pdf"
pdf.output(pdf_filename)
return pdf_filename
def calculate_risk(value, thresholds, weights):
"""Assigns a risk weight based on threshold conditions."""
for threshold, weight in zip(thresholds, weights):
if value <= threshold:
return weight
return weights[-1]
def predict_dropout(**kwargs):
"""Predicts dropout risk based on multiple risk factors."""
risk_factors = [
calculate_risk(1 if kwargs.get("special_lab") == "Non-Active" else 0, [0, 1], [-0.1, 0.5]),
calculate_risk(kwargs.get("attendance_percentage", 0), [50, 65, 75, 85], [1.0, 0.7, 0.2, -0.2]),
calculate_risk(kwargs.get("formative_assessment", 0), [30, 50, 70, 85], [1.0, 0.7, 0.4, -0.2]),
calculate_risk(kwargs.get("cgpa", 0), [5.0, 6.0, 7.0, 8.5], [1.0, 0.7, 0.4, -0.2]),
calculate_risk(kwargs.get("current_sgpa", 0), [5.0, 6.0, 7.0, 8.5], [1.0, 0.7, 0.4, -0.2]),
calculate_risk(kwargs.get("arrear_count", 0), [1, 3, 6, 10], [0.6, 0.8, 1.0, 1.3]),
calculate_risk(kwargs.get("full_stack_rank", 0), [300, 800, 1200, 1600], [-0.3, -0.1, 0.3, 0.6]),
calculate_risk(kwargs.get("ps_rank", 0), [1, 2, 4, 6], [0.8, 0.6, -0.1, -0.2]),
calculate_risk(kwargs.get("Overall_Skills_Acquired", 0), [1, 4, 8, 12], [0.8, 0.5, -0.1, -0.2]),
calculate_risk(kwargs.get("placement_fa", 0), [40, 60, 80, 95], [1.0, 0.7, -0.1, -0.2]),
calculate_risk(kwargs.get("interim_assessment_status", 0), [50, 70, 85, 95], [1.0, 0.7, -0.1, -0.2]),
calculate_risk(kwargs.get("training_assessment_status", 0), [50, 70, 85, 95], [1.0, 0.7, -0.1, -0.2]),
calculate_risk(kwargs.get("mock_assessment_status", 0), [30, 50, 70, 85], [1.0, 0.7, 0.3, -0.2]),
calculate_risk(kwargs.get("placement_cumulative", 0), [50, 70, 85, 95], [1.0, 0.7, -0.1, -0.2]),
calculate_risk(kwargs.get("placement_Attendence", 0), [50, 70, 85, 95], [1.0, 0.7, -0.1, -0.2]),
*(calculate_risk(kwargs.get(activity, 0), [0, 1, 3], [0.1, -0.2, -0.4]) for activity in [
"Technical_Competition", "Paper_Presentation", "Project_Competition",
"Product_Development", "Patent", "Internship", "Online_Course"
])
]
print(risk_factors)
total_risk = min(10, max(0, sum(risk_factors)))
return total_risk, risk_factors
def generate_plot(dropout_risk):
"""Creates a bar plot for dropout risk."""
fig, ax = plt.subplots()
colors = ['green', 'lightgreen', 'yellow', 'orange', 'red']
labels = ['Very Low Risk', 'Low Risk', 'Moderate Risk', 'High Risk', 'Very High Risk']
index = min(int(dropout_risk // 2), 4)
ax.bar([labels[index]], [dropout_risk], color=colors[index])
ax.set_ylim(0, 10)
ax.set_ylabel('Dropout Risk Score')
ax.set_title('Dropout Risk Prediction')
plt.savefig("dropout_plot.png") # Save before using in PDF
return fig ,labels[index]
def remove_emojis(text):
"""Removes all emojis and unsupported Unicode characters from text."""
emoji_pattern = re.compile("[\U00010000-\U0010ffff]", flags=re.UNICODE)
return emoji_pattern.sub("", text)
def process_and_generate_report(**input_values):
"""Processes input values and generates risk prediction along with a report."""
dropout_risk,risk_factor = predict_dropout(**input_values)
fig, label = generate_plot(dropout_risk)
insights = generate_dropout_insights(input_values,risk_factor,label)
cleaned_insights = remove_emojis(insights)
pdf_filename = generate_pdf(input_values, dropout_risk, cleaned_insights)
return fig, insights, pdf_filename