Spaces:
Running
Running
| """Basic metrics for scheduler evaluation. | |
| These helpers avoid heavy dependencies and can be used by scripts. | |
| """ | |
| from __future__ import annotations | |
| from typing import Iterable, List, Tuple | |
| def gini(values: Iterable[float]) -> float: | |
| """Compute the Gini coefficient for a non-negative list of values. | |
| Args: | |
| values: Sequence of non-negative numbers | |
| Returns: | |
| Gini coefficient in [0, 1] | |
| """ | |
| vals = [v for v in values if v is not None] | |
| n = len(vals) | |
| if n == 0: | |
| return 0.0 | |
| if min(vals) < 0: | |
| raise ValueError("Gini expects non-negative values") | |
| sorted_vals = sorted(vals) | |
| cum = 0.0 | |
| for i, x in enumerate(sorted_vals, start=1): | |
| cum += i * x | |
| total = sum(sorted_vals) | |
| if total == 0: | |
| return 0.0 | |
| # Gini formula: (2*sum(i*x_i)/(n*sum(x)) - (n+1)/n) | |
| return (2 * cum) / (n * total) - (n + 1) / n | |
| def utilization(total_scheduled: int, capacity: int) -> float: | |
| """Compute utilization as scheduled/capacity. | |
| Args: | |
| total_scheduled: Number of scheduled hearings | |
| capacity: Total available slots | |
| """ | |
| if capacity <= 0: | |
| return 0.0 | |
| return min(1.0, total_scheduled / capacity) | |
| def urgency_sla(records: List[Tuple[bool, int]], days: int = 7) -> float: | |
| """Compute SLA for urgent cases. | |
| Args: | |
| records: List of tuples (is_urgent, working_day_delay) | |
| days: SLA threshold in working days | |
| Returns: | |
| Proportion of urgent cases within SLA (0..1) | |
| """ | |
| urgent = [delay for is_urgent, delay in records if is_urgent] | |
| if not urgent: | |
| return 1.0 | |
| within = sum(1 for d in urgent if d <= days) | |
| return within / len(urgent) | |