ranilmukesh commited on
Commit
b113d9d
Β·
2 Parent(s): b4a7702b73b70d

Merge pull request #3 from ranilmukesh/Ui13-03-2026

Browse files

feat: show full list of missing skills in recommendations

Files changed (2) hide show
  1. main.py +66 -70
  2. script.js +2 -1
main.py CHANGED
@@ -346,108 +346,104 @@ async def whatif_analysis(data: StudentData):
346
 
347
  scenarios = []
348
  sid = 1
349
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
350
  if routing_engine and data.skills and data.desired_role:
351
  rec_job, _ = routing_engine.recommend(data.skills)
352
  if rec_job:
353
  transition = routing_engine.get_career_transition_path(rec_job, data.desired_role)
354
  if transition and transition.get("skills_to_learn"):
355
- skills_list = ", ".join(transition["skills_to_learn"][:3])
356
- scenarios.append({
357
- "scenario_id": sid, "title": "Career Path Suggestion", "description": "Learning these skills can help you transition towards your desired role. This suggestion does not directly impact your placement probability, which is based on academic factors.",
358
- "change_summary": f"Learn: {skills_list}",
359
- "original_risk": orig_risk, "modified_risk": orig_risk,
360
- "risk_delta": 0,
361
- "risk_reduction_percent": 0,
362
- "icon": "🧠", "factor_changed": "Skills",
363
- "original_value": "Current Skills", "suggested_value": skills_list
364
- })
365
- sid+=1
 
 
 
 
 
 
 
366
 
367
  # Add Internships
368
  if data.Internships < 3:
369
  mod = orig_dict.copy()
370
  mod['Internships'] += 1
371
- mod_risk = _predict(mod)
372
- scenarios.append({
373
- "scenario_id": sid, "title": "Extra Internship", "description": "What if you did one more internship?",
374
- "change_summary": f"Internships: {data.Internships} β†’ {mod['Internships']}",
375
- "original_risk": orig_risk, "modified_risk": mod_risk,
376
- "risk_delta": orig_risk - mod_risk,
377
- "risk_reduction_percent": ((mod_risk - orig_risk)/orig_risk*100) if orig_risk>0 else 0,
378
- "icon": "πŸ’Ό", "factor_changed": "Internships",
379
- "original_value": str(data.Internships), "suggested_value": str(mod['Internships'])
380
- })
381
- sid+=1
382
 
383
  # Clear Backlogs
384
  if data.HistoryOfBacklogs == 1:
385
  mod = orig_dict.copy()
386
  mod['HistoryOfBacklogs'] = 0
387
- mod_risk = _predict(mod)
388
- scenarios.append({
389
- "scenario_id": sid, "title": "Clear Backlogs", "description": "What if you had no history of backlogs?",
390
- "change_summary": "Backlogs: Yes β†’ No",
391
- "original_risk": orig_risk, "modified_risk": mod_risk,
392
- "risk_delta": orig_risk - mod_risk,
393
- "risk_reduction_percent": ((mod_risk - orig_risk)/orig_risk*100) if orig_risk>0 else 0,
394
- "icon": "βœ…", "factor_changed": "HistoryOfBacklogs",
395
- "original_value": "Yes", "suggested_value": "No"
396
- })
397
- sid+=1
398
 
399
- # Change Stream (Example: If not CS, what if CS?)
400
  if data.Stream != "Computer Science" and "Computer Science" in le_stream.classes_:
401
  mod = orig_dict.copy()
402
  mod['Stream'] = "Computer Science"
403
  mod_risk = _predict(mod)
404
- if (orig_risk - mod_risk) < 0: # Only suggest if it improves chance
405
- scenarios.append({
406
- "scenario_id": sid, "title": "Switch to CS", "description": "What if you switched your stream to Computer Science?",
407
- "change_summary": f"Stream: {data.Stream} β†’ Computer Science",
408
- "original_risk": orig_risk, "modified_risk": mod_risk,
409
- "risk_delta": orig_risk - mod_risk,
410
- "risk_reduction_percent": ((mod_risk - orig_risk)/orig_risk*100) if orig_risk>0 else 0,
411
- "icon": "πŸ’»", "factor_changed": "Stream",
412
- "original_value": data.Stream, "suggested_value": "Computer Science"
413
- })
414
- sid+=1
415
 
416
  # Stay in Hostel
417
  if data.Hostel == 0:
418
  mod = orig_dict.copy()
419
  mod['Hostel'] = 1
420
  mod_risk = _predict(mod)
421
- if (orig_risk - mod_risk) < 0: # Only suggest if it improves chance
422
- scenarios.append({
423
- "scenario_id": sid, "title": "Stay in Hostel", "description": "What if you stayed in a hostel? (More peer interactions)",
424
- "change_summary": "Hostel: No β†’ Yes",
425
- "original_risk": orig_risk, "modified_risk": mod_risk,
426
- "risk_delta": orig_risk - mod_risk,
427
- "risk_reduction_percent": ((mod_risk - orig_risk)/orig_risk*100) if orig_risk>0 else 0,
428
- "icon": "🏒", "factor_changed": "Hostel",
429
- "original_value": "No", "suggested_value": "Yes"
430
- })
431
- sid+=1
432
-
433
- import math
434
- for s in scenarios:
435
- # Invert delta so positive = 'improvement' for the JS UI
436
- s['risk_delta'] = s['modified_risk'] - s['original_risk']
437
-
438
  scenarios.sort(key=lambda x: x['risk_delta'], reverse=True)
439
 
440
- # Calculate TRUE COMBINED risk by applying all positive changes together
441
  best_case = orig_dict.copy()
 
442
  if data.Internships < 3: best_case['Internships'] += 1
443
  if data.HistoryOfBacklogs == 1: best_case['HistoryOfBacklogs'] = 0
444
 
445
- # Optional stream switch if it was a scenario that improved things
446
- if data.Stream != "Computer Science" and "Computer Science" in le_stream.classes_:
447
- # re-check if it's better
448
- if _predict(best_case.copy()) < _predict({**best_case, 'Stream': 'Computer Science'}):
449
- best_case['Stream'] = 'Computer Science'
450
-
451
  combined_risk = _predict(best_case)
452
  combined_level, _ = get_placement_level(combined_risk / 100)
453
 
 
346
 
347
  scenarios = []
348
  sid = 1
349
+
350
+ def add_scenario(mod_dict, title, description, change_summary, icon, factor_changed, original_value, suggested_value, mod_risk=None):
351
+ nonlocal sid
352
+ if mod_risk is None:
353
+ mod_risk = _predict(mod_dict)
354
+ scenarios.append({
355
+ "scenario_id": sid,
356
+ "title": title,
357
+ "description": description,
358
+ "change_summary": change_summary,
359
+ "original_risk": orig_risk,
360
+ "modified_risk": mod_risk,
361
+ "risk_delta": mod_risk - orig_risk,
362
+ "risk_reduction_percent": ((mod_risk - orig_risk) / (orig_risk if orig_risk > 0 else 1) * 100),
363
+ "icon": icon,
364
+ "factor_changed": factor_changed,
365
+ "original_value": str(original_value),
366
+ "suggested_value": str(suggested_value)
367
+ })
368
+ sid += 1
369
+
370
+ # PR Specific: Career Path Suggestion (from Routing Engine)
371
  if routing_engine and data.skills and data.desired_role:
372
  rec_job, _ = routing_engine.recommend(data.skills)
373
  if rec_job:
374
  transition = routing_engine.get_career_transition_path(rec_job, data.desired_role)
375
  if transition and transition.get("skills_to_learn"):
376
+ # Show full list of skills to learn (do not truncate to 3)
377
+ skills_list = ", ".join(transition["skills_to_learn"])
378
+ add_scenario(
379
+ orig_dict, "Career Path Suggestion",
380
+ "Learning these skills can help you transition towards your desired role.",
381
+ f"Learn: {skills_list}", "🧠", "Skills",
382
+ "Current Skills", skills_list, mod_risk=orig_risk
383
+ )
384
+
385
+ # Increase CGPA
386
+ if data.CGPA < 9.0:
387
+ mod = orig_dict.copy()
388
+ mod['CGPA'] = min(data.CGPA + 1.0, 10.0)
389
+ add_scenario(
390
+ mod, "+1.0 CGPA", "What if you improved your CGPA?",
391
+ f"CGPA: {data.CGPA} β†’ {mod['CGPA']}", "πŸ“š", "CGPA",
392
+ str(data.CGPA), str(mod['CGPA'])
393
+ )
394
 
395
  # Add Internships
396
  if data.Internships < 3:
397
  mod = orig_dict.copy()
398
  mod['Internships'] += 1
399
+ add_scenario(
400
+ mod, "Extra Internship", "What if you did one more internship?",
401
+ f"Internships: {data.Internships} β†’ {mod['Internships']}", "πŸ’Ό", "Internships",
402
+ str(data.Internships), str(mod['Internships'])
403
+ )
 
 
 
 
 
 
404
 
405
  # Clear Backlogs
406
  if data.HistoryOfBacklogs == 1:
407
  mod = orig_dict.copy()
408
  mod['HistoryOfBacklogs'] = 0
409
+ add_scenario(
410
+ mod, "Clear Backlogs", "What if you had no history of backlogs?",
411
+ "Backlogs: Yes β†’ No", "βœ…", "HistoryOfBacklogs",
412
+ "Yes", "No"
413
+ )
 
 
 
 
 
 
414
 
415
+ # Change Stream
416
  if data.Stream != "Computer Science" and "Computer Science" in le_stream.classes_:
417
  mod = orig_dict.copy()
418
  mod['Stream'] = "Computer Science"
419
  mod_risk = _predict(mod)
420
+ if mod_risk > orig_risk:
421
+ add_scenario(
422
+ mod, "Switch to CS", "What if you switched your stream to Computer Science?",
423
+ f"Stream: {data.Stream} β†’ Computer Science", "πŸ’»", "Stream",
424
+ data.Stream, "Computer Science", mod_risk=mod_risk
425
+ )
 
 
 
 
 
426
 
427
  # Stay in Hostel
428
  if data.Hostel == 0:
429
  mod = orig_dict.copy()
430
  mod['Hostel'] = 1
431
  mod_risk = _predict(mod)
432
+ if mod_risk > orig_risk:
433
+ add_scenario(
434
+ mod, "Stay in Hostel", "What if you stayed in a hostel?",
435
+ "Hostel: No β†’ Yes", "🏒", "Hostel",
436
+ "No", "Yes", mod_risk=mod_risk
437
+ )
438
+
 
 
 
 
 
 
 
 
 
 
439
  scenarios.sort(key=lambda x: x['risk_delta'], reverse=True)
440
 
441
+ # Combined Best Case
442
  best_case = orig_dict.copy()
443
+ if data.CGPA < 9.0: best_case['CGPA'] = min(data.CGPA + 1.0, 10.0)
444
  if data.Internships < 3: best_case['Internships'] += 1
445
  if data.HistoryOfBacklogs == 1: best_case['HistoryOfBacklogs'] = 0
446
 
 
 
 
 
 
 
447
  combined_risk = _predict(best_case)
448
  combined_level, _ = get_placement_level(combined_risk / 100)
449
 
script.js CHANGED
@@ -555,7 +555,8 @@ function getRecommendations(riskLevel) {
555
  const skillsRec = currentPrediction?.missing_skills && currentPrediction.missing_skills.length > 0 ? {
556
  icon: 'πŸ› οΈ',
557
  title: 'Skill Gaps',
558
- text: `Focus on mastering: ${currentPrediction.missing_skills.slice(0, 5).join(', ')}${currentPrediction.missing_skills.length > 5 ? '...' : ''}`
 
559
  } : null;
560
 
561
  let base = [
 
555
  const skillsRec = currentPrediction?.missing_skills && currentPrediction.missing_skills.length > 0 ? {
556
  icon: 'πŸ› οΈ',
557
  title: 'Skill Gaps',
558
+ // Show full list of missing skills rather than truncating
559
+ text: `Focus on mastering: ${currentPrediction.missing_skills.join(', ')}`
560
  } : null;
561
 
562
  let base = [