chronaxis.results.analysis_outcome
源码基线:8904c2f744951857659abd40aaa3535d57faf53c
1"""说明一次执行为何有或没有业务结果,不保存逐条输入或重复时间记录。23执行层在原有规则推进、指标写出时累计少量状态;本模块只冻结并校验这些事实,4供清单和CLI共用。事件存在与指标是否完整分别表示,不能以completed代替业务有效性。5"""6from dataclasses import dataclass, asdict78from ..core.validation import require_identifier91011@dataclass(frozen=True)12class RuleOutcome:13 """一条规则的结果概况;未知可与已生成事件并存。"""1415 rule_id: str16 status: str17 event_count: int18 has_unknown: bool19 unobserved_signals: tuple[str, ...] = ()2021 def __post_init__(self):22 """参数: 无。返回: None。异常: TypeError/ValueError,状态或计数不合法。"""23 require_identifier(self.rule_id, 'rule_id')24 if self.status not in ('no_observation', 'insufficient_data', 'events_found',25 'duration_not_met', 'condition_not_met', 'no_event'):26 raise ValueError('规则结果状态无效')27 if type(self.event_count) is not int or self.event_count < 0 or type(self.has_unknown) is not bool:28 raise TypeError('规则结果需要非负事件计数和布尔未知标记')29 if type(self.unobserved_signals) is not tuple or len(set(self.unobserved_signals)) != len(self.unobserved_signals):30 raise TypeError('未观测信号需要无重复tuple')31 for name in self.unobserved_signals:32 require_identifier(name, 'unobserved_signal')33 if (self.status == 'events_found') != (self.event_count > 0):34 raise ValueError('规则结果状态与事件计数不一致')3536 def to_dict(self):37 """参数: 无。返回: 小型JSON对象。异常: 无;不读取结果或输入。"""38 return asdict(self)394041@dataclass(frozen=True)42class AnalysisOutcome:43 """规则状态与指标行计数;不根据事件数推断能量正确或数据完整。"""4445 rules: tuple[RuleOutcome, ...] = ()46 complete: int = 047 partial: int = 048 indeterminate: int = 049 no_observation: int = 05051 def __post_init__(self):52 """参数: 无。返回: None。异常: TypeError/ValueError,重复规则或错误计数。"""53 if type(self.rules) is not tuple or any(type(item) is not RuleOutcome for item in self.rules):54 raise TypeError('分析概况需要RuleOutcome tuple')55 if len({item.rule_id for item in self.rules}) != len(self.rules):56 raise ValueError('分析概况规则重复')57 for value in (self.complete, self.partial, self.indeterminate, self.no_observation):58 if type(value) is not int or value < 0:59 raise ValueError('指标概况计数需要非负整数')60 if self.no_observation > self.complete + self.partial + self.indeterminate:61 raise ValueError('无观测指标数不能超过指标总数')6263 def to_dict(self):64 """参数: 无。返回: 清单/CLI同用的JSON对象。异常: 无。"""65 return dict(rules=[item.to_dict() for item in self.rules], calculations=dict(66 complete=self.complete, partial=self.partial, indeterminate=self.indeterminate,67 no_observation=self.no_observation))68