Spaces:
Sleeping
Sleeping
Update Backend.py
Browse files- Backend.py +175 -175
Backend.py
CHANGED
|
@@ -1,176 +1,176 @@
|
|
| 1 |
-
import matplotlib.pyplot as plt
|
| 2 |
-
from fpdf import FPDF
|
| 3 |
-
from datetime import datetime
|
| 4 |
-
from huggingfaceModel import generate_dropout_insights
|
| 5 |
-
#rom ollamaModel import generate_dropout_insights
|
| 6 |
-
import re
|
| 7 |
-
import os
|
| 8 |
-
|
| 9 |
-
def format_key(key):
|
| 10 |
-
"""Format keys to be more readable by capitalizing and removing underscores."""
|
| 11 |
-
return key.replace("_", " ").title()
|
| 12 |
-
|
| 13 |
-
def remove_unsupported_characters(text):
|
| 14 |
-
"""Removes emojis and unsupported Unicode characters for PDF compatibility."""
|
| 15 |
-
return text.encode("ascii", "ignore").decode()
|
| 16 |
-
|
| 17 |
-
def generate_pdf(input_data, dropout_risk, summary):
|
| 18 |
-
"""Generates a structured, professional PDF report for dropout prediction results."""
|
| 19 |
-
|
| 20 |
-
pdf = FPDF()
|
| 21 |
-
pdf.add_page()
|
| 22 |
-
|
| 23 |
-
# 🔹 Check if DejaVuSans font files exist
|
| 24 |
-
if os.path.exists("DejaVuSans.ttf") and os.path.exists("DejaVuSans-Bold.ttf") and os.path.exists("DejaVuSans-Oblique.ttf"):
|
| 25 |
-
font_name = "DejaVu"
|
| 26 |
-
pdf.add_font("DejaVu", "", "Dejavu/DejaVuSans.ttf", uni=True)
|
| 27 |
-
pdf.add_font("DejaVu", "B", "Dejavu/DejaVuSans-Bold.ttf", uni=True)
|
| 28 |
-
pdf.add_font("DejaVu", "I", "Dejavu/DejaVuSans-Oblique.ttf", uni=True)
|
| 29 |
-
else:
|
| 30 |
-
font_name = "Arial" # Use default Arial if DejaVu fonts are missing
|
| 31 |
-
|
| 32 |
-
# 🔹 Cover Page
|
| 33 |
-
pdf.set_font(font_name, "B", 20)
|
| 34 |
-
pdf.cell(200, 15, "AI-DRIVEN DROPOUT PREDICTION AND PREVENTION TOOL", ln=True, align="C")
|
| 35 |
-
|
| 36 |
-
pdf.set_font(font_name, "I", 12)
|
| 37 |
-
pdf.cell(200, 10, "Generated by: AI Dropout Predictor System", ln=True, align="C")
|
| 38 |
-
pdf.cell(200, 10, f"Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align="C")
|
| 39 |
-
|
| 40 |
-
pdf.ln(20)
|
| 41 |
-
pdf.set_font(font_name, "B", 16)
|
| 42 |
-
pdf.cell(200, 10, "Confidential Report", ln=True, align="C")
|
| 43 |
-
|
| 44 |
-
pdf.ln(10)
|
| 45 |
-
pdf.set_font(font_name, "I", 12)
|
| 46 |
-
pdf.cell(200, 10, "This document contains confidential student information and predictive analysis.", ln=True, align="C")
|
| 47 |
-
|
| 48 |
-
pdf.add_page()
|
| 49 |
-
|
| 50 |
-
# 🔹 Student Information Section
|
| 51 |
-
pdf.set_font(font_name, "B", 14)
|
| 52 |
-
pdf.cell(200, 10, "Student Information", ln=True, align="L")
|
| 53 |
-
pdf.ln(5)
|
| 54 |
-
|
| 55 |
-
pdf.set_font(font_name, "", 12)
|
| 56 |
-
for key, value in input_data.items():
|
| 57 |
-
formatted_key = key.replace("_", " ").title()
|
| 58 |
-
pdf.cell(90, 8, f"{formatted_key}:", border=1, align="L")
|
| 59 |
-
pdf.cell(100, 8, str(value), border=1, align="L")
|
| 60 |
-
pdf.ln(8)
|
| 61 |
-
|
| 62 |
-
pdf.ln(10)
|
| 63 |
-
pdf.add_page()
|
| 64 |
-
|
| 65 |
-
# 🔹 Dropout Risk Score Section
|
| 66 |
-
pdf.set_font(font_name, "B", 14)
|
| 67 |
-
pdf.cell(200, 10, "Predicted Dropout Risk Score", ln=True, align="L")
|
| 68 |
-
pdf.ln(5)
|
| 69 |
-
|
| 70 |
-
pdf.set_font(font_name, "B", 16)
|
| 71 |
-
pdf.set_fill_color(240, 240, 240)
|
| 72 |
-
pdf.cell(200, 15, f" Dropout Risk Score: {dropout_risk}/10 ", ln=True, align="L", border=1, fill=True)
|
| 73 |
-
|
| 74 |
-
pdf.ln(10)
|
| 75 |
-
|
| 76 |
-
# 🔹 Dropout Prediction Graph
|
| 77 |
-
pdf.set_font(font_name, "B", 14)
|
| 78 |
-
pdf.cell(200, 10, "Dropout Risk Analysis Graph", ln=True, align="C")
|
| 79 |
-
pdf.ln(5)
|
| 80 |
-
|
| 81 |
-
if os.path.exists("dropout_plot.png"):
|
| 82 |
-
pdf.image("dropout_plot.png", x=50, w=100)
|
| 83 |
-
else:
|
| 84 |
-
pdf.cell(200, 10, "Graph Unavailable", ln=True, align="C")
|
| 85 |
-
|
| 86 |
-
pdf.ln(20)
|
| 87 |
-
pdf.add_page()
|
| 88 |
-
|
| 89 |
-
# 🔹 Summary Section
|
| 90 |
-
pdf.set_font(font_name, "B", 14)
|
| 91 |
-
pdf.cell(200, 10, "Summary of Student Data", ln=True, align="C")
|
| 92 |
-
pdf.ln(5)
|
| 93 |
-
|
| 94 |
-
pdf.set_font(font_name, "", 12)
|
| 95 |
-
cleaned_summary = remove_unsupported_characters(summary)
|
| 96 |
-
pdf.multi_cell(0, 7, cleaned_summary, align="L")
|
| 97 |
-
|
| 98 |
-
# 🔹 Disclaimer
|
| 99 |
-
pdf.set_y(-30)
|
| 100 |
-
pdf.set_font(font_name, "I", 10)
|
| 101 |
-
pdf.cell(200, 10, "Disclaimer:", ln=True, align="L")
|
| 102 |
-
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")
|
| 103 |
-
|
| 104 |
-
# 🔹 Save PDF
|
| 105 |
-
pdf_filename = "Dropout_Report.pdf"
|
| 106 |
-
pdf.output(pdf_filename)
|
| 107 |
-
|
| 108 |
-
return pdf_filename
|
| 109 |
-
|
| 110 |
-
def calculate_risk(value, thresholds, weights):
|
| 111 |
-
"""Assigns a risk weight based on threshold conditions."""
|
| 112 |
-
for threshold, weight in zip(thresholds, weights):
|
| 113 |
-
if value <= threshold:
|
| 114 |
-
return weight
|
| 115 |
-
return weights[-1]
|
| 116 |
-
|
| 117 |
-
def predict_dropout(**kwargs):
|
| 118 |
-
"""Predicts dropout risk based on multiple risk factors."""
|
| 119 |
-
risk_factors = [
|
| 120 |
-
calculate_risk(1 if kwargs.get("special_lab") == "Non-Active" else 0, [0, 1], [-0.1, 0.5]),
|
| 121 |
-
calculate_risk(kwargs.get("attendance_percentage", 0), [50, 65, 75, 85], [1.0, 0.7, 0.
|
| 122 |
-
calculate_risk(kwargs.get("formative_assessment", 0), [30, 50, 70, 85], [1.0, 0.7, 0.4, -0.2]),
|
| 123 |
-
calculate_risk(kwargs.get("cgpa", 0), [5.0, 6.0, 7.0, 8.5], [1.0, 0.7, 0.4, -0.2]),
|
| 124 |
-
calculate_risk(kwargs.get("current_sgpa", 0), [5.0, 6.0, 7.0, 8.5], [1.0, 0.7, 0.4, -0.2]),
|
| 125 |
-
calculate_risk(kwargs.get("arrear_count", 0), [1, 3, 6, 10], [0.6, 0.8, 1.0, 1.3]),
|
| 126 |
-
calculate_risk(kwargs.get("full_stack_rank", 0), [300, 800, 1200, 1600], [-0.3, 0.1, 0.3, 0.6]),
|
| 127 |
-
calculate_risk(kwargs.get("ps_rank", 0), [1, 2, 4, 6], [0.8, 0.6, 0.
|
| 128 |
-
calculate_risk(kwargs.get("Overall_Skills_Acquired", 0), [1, 4, 8, 12], [0.8, 0.5, 0.
|
| 129 |
-
calculate_risk(kwargs.get("placement_fa", 0), [40, 60, 80, 95], [1.0, 0.7, 0.
|
| 130 |
-
calculate_risk(kwargs.get("interim_assessment_status", 0), [50, 70, 85, 95], [1.0, 0.7, 0.
|
| 131 |
-
calculate_risk(kwargs.get("training_assessment_status", 0), [50, 70, 85, 95], [1.0, 0.7, 0.
|
| 132 |
-
calculate_risk(kwargs.get("mock_assessment_status", 0), [30, 50, 70, 85], [1.0, 0.7, 0.3, -0.2]),
|
| 133 |
-
calculate_risk(kwargs.get("placement_cumulative", 0), [50, 70, 85, 95], [1.0, 0.7, 0.
|
| 134 |
-
calculate_risk(kwargs.get("placement_Attendence", 0), [50, 70, 85, 95], [1.0, 0.7, 0.
|
| 135 |
-
*(calculate_risk(kwargs.get(activity, 0), [0, 1, 3], [0.
|
| 136 |
-
"Technical_Competition", "Paper_Presentation", "Project_Competition",
|
| 137 |
-
"Product_Development", "Patent", "Internship", "Online_Course"
|
| 138 |
-
])
|
| 139 |
-
]
|
| 140 |
-
print(risk_factors)
|
| 141 |
-
|
| 142 |
-
total_risk = min(10, max(0, sum(risk_factors)))
|
| 143 |
-
return total_risk, risk_factors
|
| 144 |
-
|
| 145 |
-
def generate_plot(dropout_risk):
|
| 146 |
-
"""Creates a bar plot for dropout risk."""
|
| 147 |
-
fig, ax = plt.subplots()
|
| 148 |
-
colors = ['green', 'lightgreen', 'yellow', 'orange', 'red']
|
| 149 |
-
labels = ['Very Low Risk', 'Low Risk', 'Moderate Risk', 'High Risk', 'Very High Risk']
|
| 150 |
-
index = min(int(dropout_risk // 2), 4)
|
| 151 |
-
|
| 152 |
-
ax.bar([labels[index]], [dropout_risk], color=colors[index])
|
| 153 |
-
ax.set_ylim(0, 10)
|
| 154 |
-
ax.set_ylabel('Dropout Risk Score')
|
| 155 |
-
ax.set_title('Dropout Risk Prediction')
|
| 156 |
-
|
| 157 |
-
plt.savefig("dropout_plot.png") # Save before using in PDF
|
| 158 |
-
return fig
|
| 159 |
-
|
| 160 |
-
def remove_emojis(text):
|
| 161 |
-
"""Removes all emojis and unsupported Unicode characters from text."""
|
| 162 |
-
emoji_pattern = re.compile("[\U00010000-\U0010ffff]", flags=re.UNICODE)
|
| 163 |
-
return emoji_pattern.sub("", text)
|
| 164 |
-
|
| 165 |
-
def process_and_generate_report(**input_values):
|
| 166 |
-
|
| 167 |
-
"""Processes input values and generates risk prediction along with a report."""
|
| 168 |
-
|
| 169 |
-
dropout_risk,risk_factor = predict_dropout(**input_values)
|
| 170 |
-
insights = generate_dropout_insights(input_values,risk_factor)
|
| 171 |
-
cleaned_insights = remove_emojis(insights)
|
| 172 |
-
fig = generate_plot(dropout_risk)
|
| 173 |
-
pdf_filename = generate_pdf(input_values, dropout_risk, cleaned_insights)
|
| 174 |
-
|
| 175 |
-
|
| 176 |
return fig, insights, pdf_filename
|
|
|
|
| 1 |
+
import matplotlib.pyplot as plt
|
| 2 |
+
from fpdf import FPDF
|
| 3 |
+
from datetime import datetime
|
| 4 |
+
from huggingfaceModel import generate_dropout_insights
|
| 5 |
+
#rom ollamaModel import generate_dropout_insights
|
| 6 |
+
import re
|
| 7 |
+
import os
|
| 8 |
+
|
| 9 |
+
def format_key(key):
|
| 10 |
+
"""Format keys to be more readable by capitalizing and removing underscores."""
|
| 11 |
+
return key.replace("_", " ").title()
|
| 12 |
+
|
| 13 |
+
def remove_unsupported_characters(text):
|
| 14 |
+
"""Removes emojis and unsupported Unicode characters for PDF compatibility."""
|
| 15 |
+
return text.encode("ascii", "ignore").decode()
|
| 16 |
+
|
| 17 |
+
def generate_pdf(input_data, dropout_risk, summary):
|
| 18 |
+
"""Generates a structured, professional PDF report for dropout prediction results."""
|
| 19 |
+
|
| 20 |
+
pdf = FPDF()
|
| 21 |
+
pdf.add_page()
|
| 22 |
+
|
| 23 |
+
# 🔹 Check if DejaVuSans font files exist
|
| 24 |
+
if os.path.exists("DejaVuSans.ttf") and os.path.exists("DejaVuSans-Bold.ttf") and os.path.exists("DejaVuSans-Oblique.ttf"):
|
| 25 |
+
font_name = "DejaVu"
|
| 26 |
+
pdf.add_font("DejaVu", "", "Dejavu/DejaVuSans.ttf", uni=True)
|
| 27 |
+
pdf.add_font("DejaVu", "B", "Dejavu/DejaVuSans-Bold.ttf", uni=True)
|
| 28 |
+
pdf.add_font("DejaVu", "I", "Dejavu/DejaVuSans-Oblique.ttf", uni=True)
|
| 29 |
+
else:
|
| 30 |
+
font_name = "Arial" # Use default Arial if DejaVu fonts are missing
|
| 31 |
+
|
| 32 |
+
# 🔹 Cover Page
|
| 33 |
+
pdf.set_font(font_name, "B", 20)
|
| 34 |
+
pdf.cell(200, 15, "AI-DRIVEN DROPOUT PREDICTION AND PREVENTION TOOL", ln=True, align="C")
|
| 35 |
+
|
| 36 |
+
pdf.set_font(font_name, "I", 12)
|
| 37 |
+
pdf.cell(200, 10, "Generated by: AI Dropout Predictor System", ln=True, align="C")
|
| 38 |
+
pdf.cell(200, 10, f"Date: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}", ln=True, align="C")
|
| 39 |
+
|
| 40 |
+
pdf.ln(20)
|
| 41 |
+
pdf.set_font(font_name, "B", 16)
|
| 42 |
+
pdf.cell(200, 10, "Confidential Report", ln=True, align="C")
|
| 43 |
+
|
| 44 |
+
pdf.ln(10)
|
| 45 |
+
pdf.set_font(font_name, "I", 12)
|
| 46 |
+
pdf.cell(200, 10, "This document contains confidential student information and predictive analysis.", ln=True, align="C")
|
| 47 |
+
|
| 48 |
+
pdf.add_page()
|
| 49 |
+
|
| 50 |
+
# 🔹 Student Information Section
|
| 51 |
+
pdf.set_font(font_name, "B", 14)
|
| 52 |
+
pdf.cell(200, 10, "Student Information", ln=True, align="L")
|
| 53 |
+
pdf.ln(5)
|
| 54 |
+
|
| 55 |
+
pdf.set_font(font_name, "", 12)
|
| 56 |
+
for key, value in input_data.items():
|
| 57 |
+
formatted_key = key.replace("_", " ").title()
|
| 58 |
+
pdf.cell(90, 8, f"{formatted_key}:", border=1, align="L")
|
| 59 |
+
pdf.cell(100, 8, str(value), border=1, align="L")
|
| 60 |
+
pdf.ln(8)
|
| 61 |
+
|
| 62 |
+
pdf.ln(10)
|
| 63 |
+
pdf.add_page()
|
| 64 |
+
|
| 65 |
+
# 🔹 Dropout Risk Score Section
|
| 66 |
+
pdf.set_font(font_name, "B", 14)
|
| 67 |
+
pdf.cell(200, 10, "Predicted Dropout Risk Score", ln=True, align="L")
|
| 68 |
+
pdf.ln(5)
|
| 69 |
+
|
| 70 |
+
pdf.set_font(font_name, "B", 16)
|
| 71 |
+
pdf.set_fill_color(240, 240, 240)
|
| 72 |
+
pdf.cell(200, 15, f" Dropout Risk Score: {dropout_risk}/10 ", ln=True, align="L", border=1, fill=True)
|
| 73 |
+
|
| 74 |
+
pdf.ln(10)
|
| 75 |
+
|
| 76 |
+
# 🔹 Dropout Prediction Graph
|
| 77 |
+
pdf.set_font(font_name, "B", 14)
|
| 78 |
+
pdf.cell(200, 10, "Dropout Risk Analysis Graph", ln=True, align="C")
|
| 79 |
+
pdf.ln(5)
|
| 80 |
+
|
| 81 |
+
if os.path.exists("dropout_plot.png"):
|
| 82 |
+
pdf.image("dropout_plot.png", x=50, w=100)
|
| 83 |
+
else:
|
| 84 |
+
pdf.cell(200, 10, "Graph Unavailable", ln=True, align="C")
|
| 85 |
+
|
| 86 |
+
pdf.ln(20)
|
| 87 |
+
pdf.add_page()
|
| 88 |
+
|
| 89 |
+
# 🔹 Summary Section
|
| 90 |
+
pdf.set_font(font_name, "B", 14)
|
| 91 |
+
pdf.cell(200, 10, "Summary of Student Data", ln=True, align="C")
|
| 92 |
+
pdf.ln(5)
|
| 93 |
+
|
| 94 |
+
pdf.set_font(font_name, "", 12)
|
| 95 |
+
cleaned_summary = remove_unsupported_characters(summary)
|
| 96 |
+
pdf.multi_cell(0, 7, cleaned_summary, align="L")
|
| 97 |
+
|
| 98 |
+
# 🔹 Disclaimer
|
| 99 |
+
pdf.set_y(-30)
|
| 100 |
+
pdf.set_font(font_name, "I", 10)
|
| 101 |
+
pdf.cell(200, 10, "Disclaimer:", ln=True, align="L")
|
| 102 |
+
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")
|
| 103 |
+
|
| 104 |
+
# 🔹 Save PDF
|
| 105 |
+
pdf_filename = "Dropout_Report.pdf"
|
| 106 |
+
pdf.output(pdf_filename)
|
| 107 |
+
|
| 108 |
+
return pdf_filename
|
| 109 |
+
|
| 110 |
+
def calculate_risk(value, thresholds, weights):
|
| 111 |
+
"""Assigns a risk weight based on threshold conditions."""
|
| 112 |
+
for threshold, weight in zip(thresholds, weights):
|
| 113 |
+
if value <= threshold:
|
| 114 |
+
return weight
|
| 115 |
+
return weights[-1]
|
| 116 |
+
|
| 117 |
+
def predict_dropout(**kwargs):
|
| 118 |
+
"""Predicts dropout risk based on multiple risk factors."""
|
| 119 |
+
risk_factors = [
|
| 120 |
+
calculate_risk(1 if kwargs.get("special_lab") == "Non-Active" else 0, [0, 1], [-0.1, 0.5]),
|
| 121 |
+
calculate_risk(kwargs.get("attendance_percentage", 0), [50, 65, 75, 85], [1.0, 0.7, 0.2, -0.2]),
|
| 122 |
+
calculate_risk(kwargs.get("formative_assessment", 0), [30, 50, 70, 85], [1.0, 0.7, 0.4, -0.2]),
|
| 123 |
+
calculate_risk(kwargs.get("cgpa", 0), [5.0, 6.0, 7.0, 8.5], [1.0, 0.7, 0.4, -0.2]),
|
| 124 |
+
calculate_risk(kwargs.get("current_sgpa", 0), [5.0, 6.0, 7.0, 8.5], [1.0, 0.7, 0.4, -0.2]),
|
| 125 |
+
calculate_risk(kwargs.get("arrear_count", 0), [1, 3, 6, 10], [0.6, 0.8, 1.0, 1.3]),
|
| 126 |
+
calculate_risk(kwargs.get("full_stack_rank", 0), [300, 800, 1200, 1600], [-0.3, -0.1, 0.3, 0.6]),
|
| 127 |
+
calculate_risk(kwargs.get("ps_rank", 0), [1, 2, 4, 6], [0.8, 0.6, -0.1, -0.2]),
|
| 128 |
+
calculate_risk(kwargs.get("Overall_Skills_Acquired", 0), [1, 4, 8, 12], [0.8, 0.5, -0.1, -0.2]),
|
| 129 |
+
calculate_risk(kwargs.get("placement_fa", 0), [40, 60, 80, 95], [1.0, 0.7, -0.1, -0.2]),
|
| 130 |
+
calculate_risk(kwargs.get("interim_assessment_status", 0), [50, 70, 85, 95], [1.0, 0.7, -0.1, -0.2]),
|
| 131 |
+
calculate_risk(kwargs.get("training_assessment_status", 0), [50, 70, 85, 95], [1.0, 0.7, -0.1, -0.2]),
|
| 132 |
+
calculate_risk(kwargs.get("mock_assessment_status", 0), [30, 50, 70, 85], [1.0, 0.7, 0.3, -0.2]),
|
| 133 |
+
calculate_risk(kwargs.get("placement_cumulative", 0), [50, 70, 85, 95], [1.0, 0.7, -0.1, -0.2]),
|
| 134 |
+
calculate_risk(kwargs.get("placement_Attendence", 0), [50, 70, 85, 95], [1.0, 0.7, -0.1, -0.2]),
|
| 135 |
+
*(calculate_risk(kwargs.get(activity, 0), [0, 1, 3], [0.1, -0.2, -0.4]) for activity in [
|
| 136 |
+
"Technical_Competition", "Paper_Presentation", "Project_Competition",
|
| 137 |
+
"Product_Development", "Patent", "Internship", "Online_Course"
|
| 138 |
+
])
|
| 139 |
+
]
|
| 140 |
+
print(risk_factors)
|
| 141 |
+
|
| 142 |
+
total_risk = min(10, max(0, sum(risk_factors)))
|
| 143 |
+
return total_risk, risk_factors
|
| 144 |
+
|
| 145 |
+
def generate_plot(dropout_risk):
|
| 146 |
+
"""Creates a bar plot for dropout risk."""
|
| 147 |
+
fig, ax = plt.subplots()
|
| 148 |
+
colors = ['green', 'lightgreen', 'yellow', 'orange', 'red']
|
| 149 |
+
labels = ['Very Low Risk', 'Low Risk', 'Moderate Risk', 'High Risk', 'Very High Risk']
|
| 150 |
+
index = min(int(dropout_risk // 2), 4)
|
| 151 |
+
|
| 152 |
+
ax.bar([labels[index]], [dropout_risk], color=colors[index])
|
| 153 |
+
ax.set_ylim(0, 10)
|
| 154 |
+
ax.set_ylabel('Dropout Risk Score')
|
| 155 |
+
ax.set_title('Dropout Risk Prediction')
|
| 156 |
+
|
| 157 |
+
plt.savefig("dropout_plot.png") # Save before using in PDF
|
| 158 |
+
return fig
|
| 159 |
+
|
| 160 |
+
def remove_emojis(text):
|
| 161 |
+
"""Removes all emojis and unsupported Unicode characters from text."""
|
| 162 |
+
emoji_pattern = re.compile("[\U00010000-\U0010ffff]", flags=re.UNICODE)
|
| 163 |
+
return emoji_pattern.sub("", text)
|
| 164 |
+
|
| 165 |
+
def process_and_generate_report(**input_values):
|
| 166 |
+
|
| 167 |
+
"""Processes input values and generates risk prediction along with a report."""
|
| 168 |
+
|
| 169 |
+
dropout_risk,risk_factor = predict_dropout(**input_values)
|
| 170 |
+
insights = generate_dropout_insights(input_values,risk_factor)
|
| 171 |
+
cleaned_insights = remove_emojis(insights)
|
| 172 |
+
fig = generate_plot(dropout_risk)
|
| 173 |
+
pdf_filename = generate_pdf(input_values, dropout_risk, cleaned_insights)
|
| 174 |
+
|
| 175 |
+
|
| 176 |
return fig, insights, pdf_filename
|