farwew commited on
Commit
6e84df1
·
verified ·
1 Parent(s): c06f559

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -0
app.py CHANGED
@@ -312,3 +312,82 @@ def reload_data():
312
  except Exception as e:
313
  raise HTTPException(status_code=500, detail=f"Reload failed: {e}")
314
  return {"status": "reloaded"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
  except Exception as e:
313
  raise HTTPException(status_code=500, detail=f"Reload failed: {e}")
314
  return {"status": "reloaded"}
315
+
316
+
317
+
318
+ # ----------------------------------------------------
319
+ # ENDPOINT 7 — TREN IPS PER ANGKATAN / SEMESTER
320
+ # ----------------------------------------------------
321
+ @app.get("/tren_ips")
322
+ def tren_ips(reload: bool = False):
323
+ if reload:
324
+ load_data_cached.cache_clear()
325
+
326
+ try:
327
+ df = load_data_cached()
328
+ except Exception as e:
329
+ raise HTTPException(500, str(e))
330
+
331
+ final = get_final_records(df)
332
+ final["total_bobot"] = final["sks"] * final["nilai_numerik"]
333
+
334
+ # hitung IPS per (angkatan, semester)
335
+ grouped = final.groupby(["Tahun angkatan", "id_smt"]).agg(
336
+ total_bobot=("total_bobot", "sum"),
337
+ total_sks=("sks", "sum")
338
+ ).reset_index()
339
+
340
+ grouped["ips"] = grouped.apply(
341
+ lambda r: (r["total_bobot"] / r["total_sks"]) if r["total_sks"] > 0 else 0.0,
342
+ axis=1
343
+ )
344
+
345
+ result = {}
346
+ for angkatan, d in grouped.groupby("Tahun angkatan"):
347
+ d_sorted = d.sort_values("id_smt")
348
+ result[str(angkatan)] = d_sorted["ips"].round(3).tolist()
349
+
350
+ return result
351
+
352
+
353
+ # ----------------------------------------------------
354
+ # ENDPOINT 8 — DISTRIBUSI POPULASI PER ANGKATAN
355
+ # ----------------------------------------------------
356
+ @app.get("/distribusi_populasi")
357
+ def distribusi_populasi(reload: bool = False, min_sks: int = 110):
358
+ if reload:
359
+ load_data_cached.cache_clear()
360
+
361
+ try:
362
+ df = load_data_cached()
363
+ except Exception as e:
364
+ raise HTTPException(500, str(e))
365
+
366
+ final = get_final_records(df)
367
+
368
+ # total mahasiswa per angkatan
369
+ total_mhs = df.groupby("Tahun angkatan")["kode_mhs"].nunique()
370
+
371
+ # eligible per angkatan
372
+ sks_per_mhs = final.groupby("kode_mhs")["sks"].sum()
373
+ eligible = sks_per_mhs[sks_per_mhs > min_sks]
374
+
375
+ angkatan_map = df.set_index("kode_mhs")["Tahun angkatan"].to_dict()
376
+
377
+ eligible_count = {}
378
+ for mhs in eligible.index:
379
+ ang = angkatan_map.get(mhs)
380
+ if ang is not None:
381
+ eligible_count.setdefault(ang, 0)
382
+ eligible_count[ang] += 1
383
+
384
+ # bentuk response
385
+ final_result = {}
386
+ for angkatan in sorted(total_mhs.index):
387
+ final_result[str(angkatan)] = {
388
+ "total": int(total_mhs[angkatan]),
389
+ "eligible": int(eligible_count.get(angkatan, 0))
390
+ }
391
+
392
+ return final_result
393
+