refactor(arch): redesign the code structure
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
"""评估与统计:从自身动作日志离线复算虚拟时刻与统计量。
|
||||
|
||||
"演练统计"验收要求:总时间与分项耗时可独立复算 [题面/计划 §6]。
|
||||
recompute_virtual_time 是回放测试与本模块共用的唯一复算实现,
|
||||
客户端日志格式为 SessionLog 中 accepted 事件的 {path, request, response}。
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from ..config import CostConfig
|
||||
from ..protocol.rules import CLEAR_SUCCESS
|
||||
from ..protocol.timing import clear_cost, measure_cost
|
||||
|
||||
|
||||
def recompute_virtual_time(events: list[dict],
|
||||
cost: CostConfig = CostConfig()) -> dict:
|
||||
"""从动作日志复算逐步虚拟时刻。
|
||||
|
||||
events 每项形如 {path, request, response}(accepted=true)。
|
||||
返回逐步表与最终时刻;任何一步与服务器响应偏差超过容差记入 mismatches。
|
||||
"""
|
||||
position = (0.0, 0.0)
|
||||
channel = 1
|
||||
virtual = 0.0
|
||||
steps, mismatches = [], []
|
||||
for index, event in enumerate(events):
|
||||
path, request = event["path"], event["request"]
|
||||
response = event["response"]
|
||||
if response.get("accepted") is not True:
|
||||
mismatches.append({"index": index, "issue": "响应未被接受"})
|
||||
continue
|
||||
if path == "/enter":
|
||||
position, channel, virtual = (0.0, 0.0), 1, response["virtual_time_s"]
|
||||
elif path == "/measure":
|
||||
pos = (request["position"]["x"], request["position"]["y"])
|
||||
predicted = measure_cost(position, pos, channel, request["channel"], cost)
|
||||
position, channel = pos, request["channel"]
|
||||
virtual += predicted.total_s
|
||||
elif path == "/clear":
|
||||
pos = (request["position"]["x"], request["position"]["y"])
|
||||
success = response.get("clear_result") == CLEAR_SUCCESS
|
||||
predicted = clear_cost(position, pos, success, cost)
|
||||
position = pos
|
||||
virtual += predicted.total_s
|
||||
elif path == "/exit":
|
||||
pass # /exit 不推进虚拟时钟 [题面]
|
||||
else:
|
||||
mismatches.append({"index": index, "issue": f"未知路径 {path}"})
|
||||
continue
|
||||
delta = response["virtual_time_s"] - virtual
|
||||
if abs(delta) > 1e-6:
|
||||
mismatches.append({"index": index, "path": path,
|
||||
"recomputed_s": virtual,
|
||||
"recorded_s": response["virtual_time_s"],
|
||||
"gap_s": delta})
|
||||
steps.append({"index": index, "path": path,
|
||||
"predicted_s": round(virtual, 9),
|
||||
"recorded_s": response["virtual_time_s"]})
|
||||
return {"steps": steps, "final_virtual_time_s": virtual,
|
||||
"mismatches": mismatches}
|
||||
|
||||
|
||||
def summarize(events: list[dict]) -> dict:
|
||||
"""动作计数摘要:检测/清除/移动距离等基础统计。"""
|
||||
position = (0.0, 0.0)
|
||||
measures, clears, cleared, distance_m = 0, 0, 0, 0.0
|
||||
for event in events:
|
||||
request = event["request"]
|
||||
if event["path"] in ("/measure", "/clear"):
|
||||
pos = (request["position"]["x"], request["position"]["y"])
|
||||
distance_m += ((pos[0] - position[0]) ** 2
|
||||
+ (pos[1] - position[1]) ** 2) ** 0.5
|
||||
position = pos
|
||||
if event["path"] == "/measure":
|
||||
measures += 1
|
||||
elif event["path"] == "/clear":
|
||||
clears += 1
|
||||
if event["response"].get("clear_result") == CLEAR_SUCCESS:
|
||||
cleared += 1
|
||||
return {"measures": measures, "clears": clears, "cleared": cleared,
|
||||
"distance_m": distance_m}
|
||||
Reference in New Issue
Block a user