ranilmukesh commited on
Commit
5f63ae0
·
1 Parent(s): 3025689

feat: update hostel and backlog handling in forms and backend logic

Browse files
Files changed (4) hide show
  1. index.html +2 -2
  2. llm.py +16 -2
  3. main.py +21 -7
  4. script.js +16 -5
index.html CHANGED
@@ -187,7 +187,7 @@
187
  </span>
188
  <span class="checkbox-text">
189
  <span class="checkbox-title">Hostel Accommodation</span>
190
- <span class="checkbox-desc">Currently living in a hostel</span>
191
  </span>
192
  </label>
193
  </div>
@@ -205,7 +205,7 @@
205
  </span>
206
  <span class="checkbox-text">
207
  <span class="checkbox-title">Academic Backlogs</span>
208
- <span class="checkbox-desc">Any history of backlogs</span>
209
  </span>
210
  </label>
211
  </div>
 
187
  </span>
188
  <span class="checkbox-text">
189
  <span class="checkbox-title">Hostel Accommodation</span>
190
+ <span class="checkbox-desc">Checked = Yes (1), Unchecked = No (0)</span>
191
  </span>
192
  </label>
193
  </div>
 
205
  </span>
206
  <span class="checkbox-text">
207
  <span class="checkbox-title">Academic Backlogs</span>
208
+ <span class="checkbox-desc">Checked = Yes (1), Unchecked = No (0)</span>
209
  </span>
210
  </label>
211
  </div>
llm.py CHANGED
@@ -38,6 +38,20 @@ _chat_db = SqliteDb(db_file="tmp/placement_chat.db")
38
  _sessions: dict = {}
39
 
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  def build_system_context(
42
  student_data: dict,
43
  prediction: dict,
@@ -59,8 +73,8 @@ def build_system_context(
59
  f"Stream: {student_data.get('Stream', 'N/A')}",
60
  f"Internships: {student_data.get('Internships', 'N/A')}",
61
  f"CGPA: {student_data.get('CGPA', 'N/A')}",
62
- f"Hostel: {'Yes' if student_data.get('Hostel') else 'No'}",
63
- f"History of Backlogs: {'Yes' if student_data.get('HistoryOfBacklogs') else 'No'}",
64
  f"Skills: {', '.join(student_data.get('skills', []))}",
65
  f"Desired Role: {student_data.get('desired_role', 'Not Specified')}"
66
  ]
 
38
  _sessions: dict = {}
39
 
40
 
41
+ def _binary_to_yes_no(value) -> str:
42
+ """Map binary-encoded values to dataset semantics: 0 = No, 1 = Yes."""
43
+ if isinstance(value, str):
44
+ normalized = value.strip().lower()
45
+ if normalized in {"1", "true", "yes"}:
46
+ return "Yes"
47
+ if normalized in {"0", "false", "no", ""}:
48
+ return "No"
49
+ try:
50
+ return "Yes" if int(value) == 1 else "No"
51
+ except Exception:
52
+ return "No"
53
+
54
+
55
  def build_system_context(
56
  student_data: dict,
57
  prediction: dict,
 
73
  f"Stream: {student_data.get('Stream', 'N/A')}",
74
  f"Internships: {student_data.get('Internships', 'N/A')}",
75
  f"CGPA: {student_data.get('CGPA', 'N/A')}",
76
+ f"Hostel: {_binary_to_yes_no(student_data.get('Hostel'))}",
77
+ f"History of Backlogs: {_binary_to_yes_no(student_data.get('HistoryOfBacklogs'))}",
78
  f"Skills: {', '.join(student_data.get('skills', []))}",
79
  f"Desired Role: {student_data.get('desired_role', 'Not Specified')}"
80
  ]
main.py CHANGED
@@ -157,8 +157,8 @@ class StudentData(BaseModel):
157
  Stream: str = Field(..., description="Stream of study")
158
  Internships: int = Field(..., ge=0)
159
  CGPA: float = Field(..., ge=0, le=10)
160
- Hostel: int = Field(..., description="1 if hostel, 0 if not")
161
- HistoryOfBacklogs: int = Field(..., description="1 if backlogs, 0 if not")
162
  skills: List[str] = Field(default=[], description="List of user skills for routing")
163
  desired_role: Optional[str] = Field(default=None, description="User's desired job role")
164
 
@@ -191,6 +191,16 @@ class OptionsResponse(BaseModel):
191
  skills: List[str]
192
  jobs: List[str]
193
 
 
 
 
 
 
 
 
 
 
 
194
  def prepare_input(data: StudentData) -> pd.DataFrame:
195
  try:
196
  g = le_gender.transform([data.Gender])[0]
@@ -205,8 +215,8 @@ def prepare_input(data: StudentData) -> pd.DataFrame:
205
  'Stream': s,
206
  'Internships': data.Internships,
207
  'CGPA': data.CGPA,
208
- 'Hostel': data.Hostel,
209
- 'HistoryOfBacklogs': data.HistoryOfBacklogs
210
  }])
211
  # Extract columns naturally based on dict order which matches train features order
212
  return df
@@ -359,6 +369,10 @@ async def whatif_analysis(data: StudentData):
359
  return float(model.predict_proba(df_processed)[0][1]) * 100
360
 
361
  orig_dict = data.model_dump()
 
 
 
 
362
  orig_risk = _predict(orig_dict)
363
  orig_level, _ = get_placement_level(orig_risk / 100)
364
 
@@ -421,7 +435,7 @@ async def whatif_analysis(data: StudentData):
421
  )
422
 
423
  # Clear Backlogs
424
- if data.HistoryOfBacklogs == 1:
425
  mod = orig_dict.copy()
426
  mod['HistoryOfBacklogs'] = 0
427
  add_scenario(
@@ -443,7 +457,7 @@ async def whatif_analysis(data: StudentData):
443
  )
444
 
445
  # Stay in Hostel
446
- if data.Hostel == 0:
447
  mod = orig_dict.copy()
448
  mod['Hostel'] = 1
449
  mod_risk = _predict(mod)
@@ -460,7 +474,7 @@ async def whatif_analysis(data: StudentData):
460
  best_case = orig_dict.copy()
461
  if data.CGPA < 9.0: best_case['CGPA'] = min(data.CGPA + 1.0, 10.0)
462
  if data.Internships < 3: best_case['Internships'] += 1
463
- if data.HistoryOfBacklogs == 1: best_case['HistoryOfBacklogs'] = 0
464
 
465
  combined_risk = _predict(best_case)
466
  combined_level, _ = get_placement_level(combined_risk / 100)
 
157
  Stream: str = Field(..., description="Stream of study")
158
  Internships: int = Field(..., ge=0)
159
  CGPA: float = Field(..., ge=0, le=10)
160
+ Hostel: int = Field(..., ge=0, le=1, description="0 = day scholar (not in hostel), 1 = lives in hostel")
161
+ HistoryOfBacklogs: int = Field(..., ge=0, le=1, description="0 = no history of backlogs, 1 = history of backlogs")
162
  skills: List[str] = Field(default=[], description="List of user skills for routing")
163
  desired_role: Optional[str] = Field(default=None, description="User's desired job role")
164
 
 
191
  skills: List[str]
192
  jobs: List[str]
193
 
194
+
195
+ def normalize_backlogs_value(value: int) -> int:
196
+ """Normalize backlog input to strict dataset encoding: 0 = No, 1 = Yes."""
197
+ return 1 if int(value) == 1 else 0
198
+
199
+
200
+ def normalize_hostel_value(value: int) -> int:
201
+ """Normalize hostel input to strict dataset encoding: 0 = No, 1 = Yes."""
202
+ return 1 if int(value) == 1 else 0
203
+
204
  def prepare_input(data: StudentData) -> pd.DataFrame:
205
  try:
206
  g = le_gender.transform([data.Gender])[0]
 
215
  'Stream': s,
216
  'Internships': data.Internships,
217
  'CGPA': data.CGPA,
218
+ 'Hostel': normalize_hostel_value(data.Hostel),
219
+ 'HistoryOfBacklogs': normalize_backlogs_value(data.HistoryOfBacklogs)
220
  }])
221
  # Extract columns naturally based on dict order which matches train features order
222
  return df
 
369
  return float(model.predict_proba(df_processed)[0][1]) * 100
370
 
371
  orig_dict = data.model_dump()
372
+ orig_dict['Hostel'] = normalize_hostel_value(orig_dict.get('Hostel', 0))
373
+ orig_dict['HistoryOfBacklogs'] = normalize_backlogs_value(orig_dict.get('HistoryOfBacklogs', 0))
374
+ current_hostel = orig_dict['Hostel']
375
+ current_backlogs = orig_dict['HistoryOfBacklogs']
376
  orig_risk = _predict(orig_dict)
377
  orig_level, _ = get_placement_level(orig_risk / 100)
378
 
 
435
  )
436
 
437
  # Clear Backlogs
438
+ if current_backlogs == 1:
439
  mod = orig_dict.copy()
440
  mod['HistoryOfBacklogs'] = 0
441
  add_scenario(
 
457
  )
458
 
459
  # Stay in Hostel
460
+ if current_hostel == 0:
461
  mod = orig_dict.copy()
462
  mod['Hostel'] = 1
463
  mod_risk = _predict(mod)
 
474
  best_case = orig_dict.copy()
475
  if data.CGPA < 9.0: best_case['CGPA'] = min(data.CGPA + 1.0, 10.0)
476
  if data.Internships < 3: best_case['Internships'] += 1
477
+ if current_backlogs == 1: best_case['HistoryOfBacklogs'] = 0
478
 
479
  combined_risk = _predict(best_case)
480
  combined_level, _ = get_placement_level(combined_risk / 100)
script.js CHANGED
@@ -44,6 +44,18 @@ let currentFormData = null;
44
  let availableSkills = [];
45
  let selectedSkills = [];
46
 
 
 
 
 
 
 
 
 
 
 
 
 
47
  /**
48
  * Initialize the application
49
  */
@@ -270,8 +282,8 @@ function collectFormData() {
270
  Stream: document.getElementById('stream').value,
271
  Internships: parseInt(document.getElementById('internships').value) || 0,
272
  CGPA: parseFloat(document.getElementById('cgpa').value) || 0,
273
- Hostel: document.getElementById('hostel').checked ? 1 : 0,
274
- HistoryOfBacklogs: document.getElementById('backlogs').checked ? 1 : 0,
275
  skills: document.getElementById('skills').value.split(',').map(s => s.trim()).filter(s => s),
276
  desired_role: document.getElementById('desired_role').value || null
277
  };
@@ -950,7 +962,7 @@ function initSimulator() {
950
 
951
  // Toggle Setup
952
  const toggle = document.getElementById('simBacklogToggle');
953
- toggle.checked = (currentFormData.HistoryOfBacklogs === 1);
954
  toggle.onchange = () => { triggerSimulate(); };
955
  }
956
 
@@ -990,8 +1002,7 @@ async function simulateRisk() {
990
  simulatedData.Internships = parseInt(document.getElementById('simInternNum').value);
991
  simulatedData.CGPA = parseFloat(document.getElementById('simCGPANum').value);
992
 
993
- const hasBacklog = document.getElementById('simBacklogToggle').checked;
994
- simulatedData.HistoryOfBacklogs = hasBacklog ? 1 : 0;
995
 
996
  try {
997
  const response = await fetchPrediction(simulatedData);
 
44
  let availableSkills = [];
45
  let selectedSkills = [];
46
 
47
+ function encodeBacklogsFromCheckbox(checkboxId = 'backlogs') {
48
+ return document.getElementById(checkboxId).checked ? 1 : 0;
49
+ }
50
+
51
+ function decodeBacklogsToChecked(value) {
52
+ return Number(value) === 1;
53
+ }
54
+
55
+ function encodeHostelFromCheckbox(checkboxId = 'hostel') {
56
+ return document.getElementById(checkboxId).checked ? 1 : 0;
57
+ }
58
+
59
  /**
60
  * Initialize the application
61
  */
 
282
  Stream: document.getElementById('stream').value,
283
  Internships: parseInt(document.getElementById('internships').value) || 0,
284
  CGPA: parseFloat(document.getElementById('cgpa').value) || 0,
285
+ Hostel: encodeHostelFromCheckbox('hostel'),
286
+ HistoryOfBacklogs: encodeBacklogsFromCheckbox('backlogs'),
287
  skills: document.getElementById('skills').value.split(',').map(s => s.trim()).filter(s => s),
288
  desired_role: document.getElementById('desired_role').value || null
289
  };
 
962
 
963
  // Toggle Setup
964
  const toggle = document.getElementById('simBacklogToggle');
965
+ toggle.checked = decodeBacklogsToChecked(currentFormData.HistoryOfBacklogs);
966
  toggle.onchange = () => { triggerSimulate(); };
967
  }
968
 
 
1002
  simulatedData.Internships = parseInt(document.getElementById('simInternNum').value);
1003
  simulatedData.CGPA = parseFloat(document.getElementById('simCGPANum').value);
1004
 
1005
+ simulatedData.HistoryOfBacklogs = encodeBacklogsFromCheckbox('simBacklogToggle');
 
1006
 
1007
  try {
1008
  const response = await fetchPrediction(simulatedData);