tututz commited on
Commit
b237d30
·
verified ·
1 Parent(s): 3e82ac1

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +53 -12
main.py CHANGED
@@ -21,7 +21,7 @@ from .explanation_builder import build_explanation_from_rules
21
  app = FastAPI(
22
  title="GCOMPRO",
23
  description="API Prediksi Risiko Akademik dan Rekomendasi Mata Kuliah.",
24
- version="1.5.0"
25
  )
26
 
27
  # ======================================================================
@@ -60,7 +60,7 @@ class PredictionResponse(BaseModel):
60
  class RecommendationRequest(BaseModel):
61
  current_semester: int
62
  courses_passed: List[str]
63
- mk_pilihan_failed: List[str] = []
64
 
65
  class PrerequisiteInfo(BaseModel):
66
  code: str
@@ -81,6 +81,38 @@ class CourseRecommendation(BaseModel):
81
  # 3. Variabel Global & Pemuatan Model/Data
82
  # ======================================================================
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
  # --- Variabel Global untuk API Prediksi Risiko (App 1) ---
85
  ml_model = None
86
  MODEL_FEATURES = [
@@ -160,11 +192,9 @@ def on_startup():
160
  # 4. Helper Function (Untuk API Rekomendasi)
161
  # ======================================================================
162
 
163
- # <--- [UPDATE] Parameter mk_pilihan_failed_list ditambahkan
164
  def get_recommendations_logic(current_semester: int, courses_passed_list: List[str], mk_pilihan_failed_list: List[str]) -> List[Dict[str, Any]]:
165
  """
166
- Logika rekomendasi dengan penanganan khusus untuk MK Pilihan Gagal.
167
- MK Gagal akan 'membajak' slot MK_PILIHAN yang tersedia di graf.
168
  """
169
  passed_set = set(courses_passed_list)
170
  all_courses_set = set(course_details_map.keys())
@@ -191,6 +221,7 @@ def get_recommendations_logic(current_semester: int, courses_passed_list: List[s
191
 
192
  raw_candidates.append(candidate_data)
193
 
 
194
  elective_slots = []
195
  regular_candidates = []
196
 
@@ -204,18 +235,29 @@ def get_recommendations_logic(current_semester: int, courses_passed_list: List[s
204
  # Urutkan slot pilihan agar mengisi dari semester terkecil (misal sem 7 dulu)
205
  elective_slots.sort(key=lambda x: x["semester_plan"])
206
 
 
207
  processed_electives = []
208
  failed_idx = 0
209
 
210
  # Prioritaskan mengisi slot dengan MK yang gagal
211
  while failed_idx < len(mk_pilihan_failed_list) and len(elective_slots) > 0:
212
- slot = elective_slots.pop(0) # Ambil slot
213
  failed_code = mk_pilihan_failed_list[failed_idx]
214
 
215
- # Modifikasi slot menjadi MK spesifik
 
 
 
 
 
 
 
 
 
216
  slot["code"] = failed_code
217
- slot["name"] = f"MK Pilihan (Mengulang: {failed_code})"
218
- slot["priority_score"] += 1
 
219
  slot["is_retake_elective"] = True
220
 
221
  processed_electives.append(slot)
@@ -343,10 +385,9 @@ async def recommend_courses(request: RecommendationRequest):
343
  elif course["semester_plan"] > request.current_semester:
344
  reason = f"Akselerasi (Semester {course['semester_plan']})"
345
 
346
- # Note: Untuk MK Pilihan Gagal, kode sudah berubah jadi spesifik (misal EL4092).
347
- # Prereq map mungkin return kosong ([]) jika kode spesifik tidak ada di graf JSON.
348
- # Ini aman, karena biasanya MK Pilihan prasyaratnya umum/tidak strict di graf.
349
  prereq_codes = prereq_map.get(course["code"], [])
 
 
350
 
351
  prereq_details_list = []
352
  for p_code in prereq_codes:
 
21
  app = FastAPI(
22
  title="GCOMPRO",
23
  description="API Prediksi Risiko Akademik dan Rekomendasi Mata Kuliah.",
24
+ version="1.6.0"
25
  )
26
 
27
  # ======================================================================
 
60
  class RecommendationRequest(BaseModel):
61
  current_semester: int
62
  courses_passed: List[str]
63
+ mk_pilihan_failed: List[str] = [] # <--- Berisi kode spesifik (misal: "AAK4ABB3")
64
 
65
  class PrerequisiteInfo(BaseModel):
66
  code: str
 
81
  # 3. Variabel Global & Pemuatan Model/Data
82
  # ======================================================================
83
 
84
+ # <--- [UPDATE] DATABASE HARDCODE MATA KULIAH PILIHAN
85
+ # Ini digunakan untuk lookup nama resmi saat user mengirim kode MK Pilihan yang gagal
86
+ ELECTIVE_COURSES_DB = {
87
+ "AAK4ABB3": {"name": "New Generation Network", "sks": 3},
88
+ "AAK4BBB3": {"name": "Software Defined Network", "sks": 3},
89
+ "AAK4CBB3": {"name": "Rekayasa Jaringan", "sks": 3},
90
+ "AAK4DBB3": {"name": "Aplikasi Cyber Security", "sks": 3},
91
+ "AAK4EBB3": {"name": "Manajemen Telekomunikasi dan Transformasi Digital", "sks": 3},
92
+ "AAK4FBB3": {"name": "Adaptive Network", "sks": 3},
93
+ "AAK4GBB3": {"name": "Cloud Computing", "sks": 3},
94
+ "AAK4HBB3": {"name": "Koding dan Kompresi", "sks": 3},
95
+ "AAK4IBB3": {"name": "Steganografi dan Watermarking", "sks": 3},
96
+ "AAK4JBB3": {"name": "Mobile Application", "sks": 3},
97
+ "AAK4KBB3": {"name": "Speech Signal Processing", "sks": 3},
98
+ "AAK4LBB3": {"name": "Komunikasi Akses Wireless", "sks": 3},
99
+ "AAK4MBB3": {"name": "Wireless Optical Communication", "sks": 3},
100
+ "AAK4NBB3": {"name": "Broadband Optical Network", "sks": 3},
101
+ "AAK4OBB3": {"name": "Sistem Komunikasi Satelit", "sks": 3},
102
+ "AAK4PBB3": {"name": "Rekayasa Radio", "sks": 3},
103
+ "AAK4QBB3": {"name": "Radar, Navigasi dan Remote Sensing", "sks": 3},
104
+ "AAK4RBB3": {"name": "5G and Beyond", "sks": 3},
105
+ "AAK4SBB3": {"name": "Software Defined Radio", "sks": 3},
106
+ "AAK4TBB3": {"name": "Robotic Process Automation", "sks": 3},
107
+ "AAK4UBB3": {"name": "Rekayasa Frekuensi Radio dalam Komunikasi Selular", "sks": 3},
108
+ "AAK4VBB3": {"name": "Teknologi Radio Access Network (RAN)", "sks": 3},
109
+ "AAK4WBB3": {"name": "Internet of Things: Protokol, Platform, dan AI", "sks": 3},
110
+ "AAK4XBB3": {"name": "Jaringan Core Telekomunikasi", "sks": 3},
111
+ "AAK4YBB3": {"name": "Ethical Hacking", "sks": 3},
112
+ "AAK4ZBB3": {"name": "Keamanan Komunikasi Data", "sks": 3},
113
+ "AAK47BB3": {"name": "Rekayasa Penyiaran Digital", "sks": 3}
114
+ }
115
+
116
  # --- Variabel Global untuk API Prediksi Risiko (App 1) ---
117
  ml_model = None
118
  MODEL_FEATURES = [
 
192
  # 4. Helper Function (Untuk API Rekomendasi)
193
  # ======================================================================
194
 
 
195
  def get_recommendations_logic(current_semester: int, courses_passed_list: List[str], mk_pilihan_failed_list: List[str]) -> List[Dict[str, Any]]:
196
  """
197
+ Logika rekomendasi dengan injeksi data MK Pilihan dari Database Hardcode.
 
198
  """
199
  passed_set = set(courses_passed_list)
200
  all_courses_set = set(course_details_map.keys())
 
221
 
222
  raw_candidates.append(candidate_data)
223
 
224
+ # Tahap 2: Pisahkan Slot MK Pilihan vs MK Wajib
225
  elective_slots = []
226
  regular_candidates = []
227
 
 
235
  # Urutkan slot pilihan agar mengisi dari semester terkecil (misal sem 7 dulu)
236
  elective_slots.sort(key=lambda x: x["semester_plan"])
237
 
238
+ # <--- [UPDATE] Tahap 3: Suntikkan MK Pilihan Gagal + Lookup Database
239
  processed_electives = []
240
  failed_idx = 0
241
 
242
  # Prioritaskan mengisi slot dengan MK yang gagal
243
  while failed_idx < len(mk_pilihan_failed_list) and len(elective_slots) > 0:
244
+ slot = elective_slots.pop(0) # Ambil slot template (misal MK_PILIHAN1)
245
  failed_code = mk_pilihan_failed_list[failed_idx]
246
 
247
+ # <--- [UPDATE] Lookup detail mata kuliah dari ELECTIVE_COURSES_DB
248
+ if failed_code in ELECTIVE_COURSES_DB:
249
+ real_name = ELECTIVE_COURSES_DB[failed_code]["name"]
250
+ real_sks = ELECTIVE_COURSES_DB[failed_code]["sks"]
251
+ else:
252
+ # Fallback jika kode tidak ada di DB (safety net)
253
+ real_name = "Mata Kuliah Pilihan (Unknown)"
254
+ real_sks = 3
255
+
256
+ # Modifikasi slot menjadi MK spesifik dengan data asli
257
  slot["code"] = failed_code
258
+ slot["name"] = f"{real_name} (Mengulang)" # Ubah nama jadi nama asli
259
+ slot["sks"] = real_sks
260
+ slot["priority_score"] += 100.0 # Boost score agar prioritas #1
261
  slot["is_retake_elective"] = True
262
 
263
  processed_electives.append(slot)
 
385
  elif course["semester_plan"] > request.current_semester:
386
  reason = f"Akselerasi (Semester {course['semester_plan']})"
387
 
 
 
 
388
  prereq_codes = prereq_map.get(course["code"], [])
389
+ # Jika kode MK Pilihan diganti (misal AAK4ABB3), prereq_map.get("AAK4ABB3") akan None/Empty
390
+ # Ini benar karena MK Pilihan umumnya tidak punya prereq di graf ini (hanya placeholder)
391
 
392
  prereq_details_list = []
393
  for p_code in prereq_codes: