Manikandan-Alagu commited on
Commit
d5000ce
·
verified ·
1 Parent(s): a59c712

Update Backend.py

Browse files
Files changed (1) hide show
  1. 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.4, -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.4, -0.2]),
128
- calculate_risk(kwargs.get("Overall_Skills_Acquired", 0), [1, 4, 8, 12], [0.8, 0.5, 0.3, -0.2]),
129
- calculate_risk(kwargs.get("placement_fa", 0), [40, 60, 80, 95], [1.0, 0.7, 0.3, -0.2]),
130
- calculate_risk(kwargs.get("interim_assessment_status", 0), [50, 70, 85, 95], [1.0, 0.7, 0.3, -0.2]),
131
- calculate_risk(kwargs.get("training_assessment_status", 0), [50, 70, 85, 95], [1.0, 0.7, 0.3, -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.3, -0.2]),
134
- calculate_risk(kwargs.get("placement_Attendence", 0), [50, 70, 85, 95], [1.0, 0.7, 0.3, -0.2]),
135
- *(calculate_risk(kwargs.get(activity, 0), [0, 1, 3], [0.6, -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
 
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