1818# Data structures
1919# ---------------------------------------------------------------------------
2020
21+
2122@dataclass (frozen = True , slots = True )
2223class PISprintSlot :
2324 """One sprint slot inside a PI."""
25+
2426 index : int # 1-based (1 … sprints_per_pi)
2527 name : str
2628 start_date : date
@@ -34,6 +36,7 @@ class PISprintSlot:
3436@dataclass (slots = True )
3537class PISnapshot :
3638 """Complete PI-level snapshot for the presentation layer."""
39+
3740 name : str
3841 start_date : date
3942 end_date : date
@@ -50,6 +53,7 @@ class PISnapshot:
5053# Business-day helpers
5154# ---------------------------------------------------------------------------
5255
56+
5357def _to_wd_set (working_days : list [int ] | frozenset [int ] | None ) -> frozenset [int ]:
5458 if working_days is None :
5559 return DEFAULT_WORKING_DAYS
@@ -104,6 +108,7 @@ def count_working_days(start: date, end: date, working_days: list[int] | None =
104108# Sprint boundary computation
105109# ---------------------------------------------------------------------------
106110
111+
107112def compute_sprint_boundaries (
108113 pi_start : date ,
109114 sprint_length : int = 10 ,
@@ -139,6 +144,7 @@ def compute_sprint_boundaries(
139144# PI snapshot computation
140145# ---------------------------------------------------------------------------
141146
147+
142148def compute_pi_snapshot (
143149 name : str ,
144150 pi_start_iso : str ,
@@ -192,19 +198,23 @@ def compute_pi_snapshot(
192198 elapsed = total_wd if today > s_end else 0
193199 remaining = 0 if today > s_end else total_wd
194200
195- slots .append (PISprintSlot (
196- index = i ,
197- name = f"{ sprint_name_prefix } { i } " ,
198- start_date = s_start ,
199- end_date = s_end ,
200- is_current = is_current ,
201- working_days_total = total_wd ,
202- working_days_elapsed = elapsed ,
203- working_days_remaining = remaining ,
204- ))
201+ slots .append (
202+ PISprintSlot (
203+ index = i ,
204+ name = f"{ sprint_name_prefix } { i } " ,
205+ start_date = s_start ,
206+ end_date = s_end ,
207+ is_current = is_current ,
208+ working_days_total = total_wd ,
209+ working_days_elapsed = elapsed ,
210+ working_days_remaining = remaining ,
211+ )
212+ )
205213
206214 total_wd = count_working_days (pi_start , pi_end , wd_list )
207- elapsed_wd = count_working_days (pi_start , min (today , pi_end ), wd_list ) if today >= pi_start else 0
215+ elapsed_wd = (
216+ count_working_days (pi_start , min (today , pi_end ), wd_list ) if today >= pi_start else 0
217+ )
208218 remaining_wd = max (0 , total_wd - elapsed_wd )
209219 progress = (elapsed_wd / total_wd * 100 ) if total_wd > 0 else 0.0
210220
0 commit comments