Rajan Sharma commited on
Commit
7aeab5c
·
verified ·
1 Parent(s): c044be1

Create decision_math.py

Browse files
Files changed (1) hide show
  1. decision_math.py +34 -0
decision_math.py ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # decision_math.py
2
+ from typing import Dict
3
+
4
+ def free_staffed_beds(staffed_capacity: int, current_occupied: int) -> int:
5
+ return max(0, staffed_capacity - current_occupied)
6
+
7
+ def beds_needed_to_clear(ed_waiting: int, free_now: int, surge_buffer: int = 0) -> int:
8
+ return max(0, ed_waiting - free_now) + max(0, surge_buffer)
9
+
10
+ def discharge_goal(today_ready: int, by_noon_ratio: float = 0.6) -> int:
11
+ return max(0, int(round(today_ready * by_noon_ratio)))
12
+
13
+ def compute_operational_numbers(snapshot: Dict) -> Dict:
14
+ # snapshot should already include most fields; compute some derivations
15
+ staffed_capacity = int(snapshot.get("beds_total", 0) * (snapshot.get("staffed_ratio", 1.0)))
16
+ current_occupied = int(snapshot.get("beds_total", 0) * snapshot.get("occupied_pct", 0))
17
+ free_now = free_staffed_beds(staffed_capacity or snapshot.get("beds_total", 0), current_occupied)
18
+ ed_waiting = int(snapshot.get("ed_admits_waiting", 0))
19
+
20
+ # simple surge buffer for next 12h if forecast exists
21
+ forecast = snapshot.get("forecast_admits_next_24h", {})
22
+ surge_buffer = int(round((forecast.get("respiratory", 0) + forecast.get("other", 0)) * 0.4))
23
+
24
+ need_now = beds_needed_to_clear(ed_waiting, free_now, surge_buffer=surge_buffer)
25
+ noon_goal = discharge_goal(int(snapshot.get("discharge_ready_today", 0)))
26
+
27
+ return {
28
+ "staffed_capacity": staffed_capacity or snapshot.get("beds_total", 0),
29
+ "current_occupied": current_occupied,
30
+ "free_staffed_beds_now": free_now,
31
+ "beds_needed_to_clear_now_plus_buffer": need_now,
32
+ "target_noon_discharges": noon_goal,
33
+ "surge_buffer_estimate": surge_buffer,
34
+ }