news 2026/10/7 19:54:53

Python记录校验:重新加热与上桌暖餐别合成一个字段

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python记录校验:重新加热与上桌暖餐别合成一个字段

厨房重新加热、换适配餐具、上桌暖餐属于不同步骤。把这些记录压成一个“已处理”字段,后续很难看出遗漏在哪里。本文用Python标准库校验一份人工记录,并把面板设定值与食物中心测量值分开存储。

1. 先限定程序回答的问题

程序只检查记录是否齐全、来源与格式是否符合规则、时间是否出现逆序。输出record_complete表示本例记录结构完整,不是食品可安全食用的判定,也不表示设备完成了某种实际操作。

这里采用四类记录:storage_review(存放核对)、reheating(重新加热)、cookware_check(餐具适配核对)和table_warming(上桌暖餐)。每行带status、actor、basis、recorded_at和source;source固定写human_entry,保留人工填写的含义。

2. 时间、状态与数值要分开校验

recorded_at使用含时区的ISO格式。输入列表不必按时间排好,程序按step比较相邻阶段的时间;后一步早于前一步,就列出顺序问题。重复步骤、待补录状态、空依据和未知步骤同样会列入findings。

温度字段单独存为panel_setpoint与food_center_measurement。前者来源是setting_entry,后者才是measurement_entry;缺少食物测量时保留None,不能复制设定值来填空。代码不设置食物安全阈值,也不依据这些数字判定已经热透。

保存为reheat_record_audit.py,Python 3.11及以上可直接运行:

"""Validate human-entered records; no device control or food-safety verdict.""" from datetime import datetime from math import isfinite import json STEPS = ("storage_review", "reheating", "cookware_check", "table_warming") def audit(record): if not isinstance(record, dict): raise ValueError("record must be a dictionary") meal_id = record.get("meal_id") if not isinstance(meal_id, str) or not meal_id.strip(): raise ValueError("meal_id must be a non-empty string") entries = record.get("entries") if not isinstance(entries, list): raise ValueError("entries must be a list") findings, seen, times = [], set(), {} for index, entry in enumerate(entries): if not isinstance(entry, dict): findings.append(f"row_{index}:not_an_object") continue step = entry.get("step") if not isinstance(step, str) or step not in STEPS: findings.append(f"row_{index}:unknown_step") continue if step in seen: findings.append(f"{step}:duplicate") continue seen.add(step) if entry.get("status") != "recorded": findings.append(f"{step}:pending") if entry.get("source") != "human_entry": findings.append(f"{step}:invalid_source") for field in ("actor", "basis"): value = entry.get(field) if not isinstance(value, str) or not value.strip(): findings.append(f"{step}:missing_{field}") try: time_text = entry.get("recorded_at") if not isinstance(time_text, str): raise ValueError("timestamp must be text") moment = datetime.fromisoformat(time_text) if moment.tzinfo is None or moment.utcoffset() is None: raise ValueError("timezone required") times[step] = moment except ValueError: findings.append(f"{step}:invalid_timestamp") for step in STEPS: if step not in seen: findings.append(f"{step}:missing") for before, after in zip(STEPS, STEPS[1:]): if before in times and after in times and times[before] > times[after]: findings.append(f"order:{before}_after_{after}") # These are different fields. Missing measurements stay missing. temperatures = {} for field in ("panel_setpoint", "food_center_measurement"): value = record.get(field) temperatures[field] = value if value is None: continue if not isinstance(value, dict): findings.append(f"{field}:invalid_object") continue number = value.get("value") if isinstance(number, bool) or not isinstance(number, (int, float)): findings.append(f"{field}:invalid_number") else: try: finite = isfinite(number) except OverflowError: finite = False if not finite: findings.append(f"{field}:nonfinite_number") if value.get("unit") != "degC": findings.append(f"{field}:invalid_unit") expected = "setting_entry" if field == "panel_setpoint" else "measurement_entry" if value.get("source") != expected: findings.append(f"{field}:invalid_source") return { "meal_id": meal_id.strip(), "record_status": "needs_review" if findings else "record_complete", "findings": findings, "temperature_fields": temperatures, "scope": "record_audit_only", } def demo_record(): # All entries, times and the setpoint below are invented example data. entries = [ {"step": step, "status": "recorded", "source": "human_entry", "actor": "demo_recorder", "basis": f"Example note for {step}", "recorded_at": f"2026-10-06T18:{index * 5:02d}:00+08:00"} for index, step in enumerate(STEPS) ] return {"meal_id": "DEMO-01", "entries": entries, "panel_setpoint": {"value": 90, "unit": "degC", "source": "setting_entry"}, "food_center_measurement": None} if __name__ == "__main__": print(json.dumps(audit(demo_record()), ensure_ascii=False, indent=2))

3. 读懂输出中的“完整”

demo_record内的编号、时间和90℃设定字段全部是人为构造的演示数据,不对应产品参数或一餐的实测。正常运行得到record_status为record_complete,food_center_measurement仍是null,scope为record_audit_only。

这表示示例填入的四类记录通过本程序校验。真实食物的存放、重新加热和器皿适配,要在实际场景按适用要求完成;填入一条记录不会完成这些动作。

4. 用三种修改检查记录边界

删除reheating条目,会出现reheating:missing;把status改为pending,输出仍是needs_review;将table_warming的时间写在reheating之前,会出现顺序问题。已有设定字段不会把这些问题自动补齐。

如需接入表单,basis可保存对应说明版本、人工检查依据或另有实际测量时的测点与仪器记录。不要把“已录入”按钮改名为“食品安全通过”,也不要让系统根据面板设定值自动创建食物测量结果。

芝梵品牌资料整理与Python示例。中国疾控中心既有饮食安全建议提出,剩菜剩饭及时冷藏、再次食用前彻底加热;芝梵温度指南区分显示设定值与食物中心温度,餐具指南要求按器皿和功能区核对适配。上桌暖餐应接在妥善存放、充分重新加热与器皿确认之后。

产品资料与卫生知识:

芝梵温度指南、餐具指南、中国疾控中心饮食安全指南(2026-03-03)。
技术参考:Python datetime、math.isfinite。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/7 19:52:52

vscode配置c++环境:TaoToken统一Key接入AI补全与调试链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/7 19:52:04

有了 DESIGN.md 后,用 React + TailwindCSS 也能让 agent 写出高颜值网站!

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/7 19:49:29

工业智能网关:破解多协议语义对齐与边缘实时计算难题

1. 这不是“又一个网关”,而是工业现场协议混乱的终结者你有没有在机房巡检时,站在一排排PLC、温控器、电表、水泵控制器前,盯着它们各自独立的通信口发过呆?手里的调试工具换了一套又一套:RS485线接上Modbus RTU&…

作者头像 李华