Add run_analysis/src/run_analysis/core.py
This commit is contained in:
commit
b62cff80a1
1 changed files with 78 additions and 0 deletions
78
run_analysis/src/run_analysis/core.py
Normal file
78
run_analysis/src/run_analysis/core.py
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Dict, Any
|
||||
import statistics
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class RunData:
|
||||
"""Repräsentiert ein einzelnes Laufdaten-Objekt."""
|
||||
corr_id: str
|
||||
expires_at_dist_hours: float
|
||||
visibility_lag: float
|
||||
|
||||
@staticmethod
|
||||
def from_dict(data: Dict[str, Any]) -> 'RunData':
|
||||
"""Validiert und erstellt eine RunData-Instanz aus einem Dictionary."""
|
||||
required_fields = ("corr_id", "expires_at_dist_hours", "visibility_lag")
|
||||
for field in required_fields:
|
||||
if field not in data:
|
||||
raise ValueError(f"Missing required field '{field}' in RunData input.")
|
||||
if not isinstance(data["corr_id"], str):
|
||||
raise TypeError("'corr_id' must be a string.")
|
||||
try:
|
||||
exp_val = float(data["expires_at_dist_hours"])
|
||||
vis_val = float(data["visibility_lag"])
|
||||
except (TypeError, ValueError) as e:
|
||||
raise ValueError("Numeric conversion failed for RunData fields.") from e
|
||||
|
||||
return RunData(
|
||||
corr_id=data["corr_id"],
|
||||
expires_at_dist_hours=exp_val,
|
||||
visibility_lag=vis_val
|
||||
)
|
||||
|
||||
|
||||
def analyze_run_data(run_data: List[RunData]) -> Dict[str, Any]:
|
||||
"""Analysiert Run-Daten und extrahiert Fälle mit Δt (visibility_lag) < 0.
|
||||
|
||||
Args:
|
||||
run_data: Liste von RunData-Objekten.
|
||||
|
||||
Returns:
|
||||
Dict mit Übersicht der negativen Δt-Fälle, inklusive Statistiken.
|
||||
"""
|
||||
assert isinstance(run_data, list), "run_data must be a list of RunData instances"
|
||||
if not run_data:
|
||||
return {"total_records": 0, "negative_dt_count": 0, "neg_corr_ids": [], "summary": {}}
|
||||
|
||||
negative_cases = [r for r in run_data if r.visibility_lag < 0]
|
||||
neg_corr_ids = [r.corr_id for r in negative_cases]
|
||||
|
||||
result: Dict[str, Any] = {
|
||||
"total_records": len(run_data),
|
||||
"negative_dt_count": len(negative_cases),
|
||||
"neg_corr_ids": neg_corr_ids,
|
||||
"summary": {}
|
||||
}
|
||||
|
||||
if negative_cases:
|
||||
exp_vals = [r.expires_at_dist_hours for r in negative_cases]
|
||||
vis_vals = [r.visibility_lag for r in negative_cases]
|
||||
try:
|
||||
result["summary"] = {
|
||||
"mean_expires_at_dist_hours": statistics.mean(exp_vals),
|
||||
"mean_visibility_lag": statistics.mean(vis_vals),
|
||||
"min_visibility_lag": min(vis_vals),
|
||||
"max_visibility_lag": max(vis_vals)
|
||||
}
|
||||
except statistics.StatisticsError:
|
||||
result["summary"] = {}
|
||||
|
||||
logger.debug("Analysis complete: %s", result)
|
||||
return result
|
||||
Loading…
Reference in a new issue