成长路线图
这个仓库不是单纯的语法教程,而是一条从 Python 零基础走向 AI Builder 和 Quant Researcher 的成长路径。
阶段视图
| 阶段 | 主线 | 能力结果 |
|---|
| Day01-Day15 | Python 基础 | 能写输入、判断、循环、列表、函数和简单数据对象 |
| Day16-Day30 | 函数 + 数据结构 | 能把脚本组织成可运行、可测试、可复查的小工具 |
| Day31-Day45 | SQL + Linux | 能使用本地数据库、命令行、API、Web 工具和轻量交付方式 |
| Day46-Day60 | 项目开发 | 能搭建 LLM/RAG/Agent 原型,并记录评估、日志和边界 |
| Day61-Day80 | 数据工程 | 能处理行情数据、指标、回测、结果存储和研究报告 |
| Day81-Day100 | Agent + Quant 准备 | 能把项目整理成作品集,并进入更系统的 Agent、Quant 和面试题训练 |
双版本定位
- GitHub 版:公开展示,保持简洁,适合外部访客快速理解路线、项目和练习。
- 本地 Obsidian 版:学习实验室,记录真实错误、调试过程、学习日志和认知变化。
成长资产
公开仓库保留课程、练习、项目说明和精选学习方法。本地 Vault 保留更细的真实过程,例如语法错误、缩进错误、REPL 使用、变量命名误区和算法模式沉淀。
这些真实错误不是噪音,而是长期学习资产。它们会逐步转化为 Debug 能力、工程判断和项目复盘能力。
Day01 - Python 环境与第一段程序
> 阶段一:Python 基础
学习定位
今天只学习一个核心主题:把 Python 环境与第一段程序 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:无
- 下一站:Day02
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Python 环境与第一段程序 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
print(...) | Python 对象 | 终端文本 | 先确认程序真的跑起来 |
type(...) | 任意变量 | 类型名 | 判断字符串、数字、列表有没有混用 |
if / for / def | 条件、序列、参数 | 分支、循环、返回值 | 把重复动作收敛成稳定流程 |
Path | 路径字符串 | 可读写路径对象 | 把学习产物保存下来 |
What
Python 环境与第一段程序 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
import sys
from pathlib import Path
message = "hello Python100"
workspace = Path.cwd()
print(message)
print("python_version =", sys.version.split()[0])
print("current_folder =", workspace)
参数拆解方法
第一次看到 Python 环境与第一段程序 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Python 环境与第一段程序 的最小输入对象 |
| 变量名 | 它保存什么数据 | minutes 保存学习分钟数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先 print(type(...))。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day001/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Python 环境与第一段程序 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 1
TOPIC = "Python 环境与第一段程序"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def build_environment_report():
import sys
return {
"topic": TOPIC,
"python_version": sys.version.split()[0],
"working_directory": str(ROOT),
"first_output": "hello Python100",
}
def main():
report = build_environment_report()
path = write_json("environment_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day01:Python 环境与第一段程序
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Python 环境与第一段程序 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day02 - 变量、类型与输入输出
> 阶段一:Python 基础
学习定位
今天只学习一个核心主题:把 变量、类型与输入输出 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day01
- 下一站:Day03
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 变量、类型与输入输出 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
print(...) | Python 对象 | 终端文本 | 先确认程序真的跑起来 |
type(...) | 任意变量 | 类型名 | 判断字符串、数字、列表有没有混用 |
if / for / def | 条件、序列、参数 | 分支、循环、返回值 | 把重复动作收敛成稳定流程 |
Path | 路径字符串 | 可读写路径对象 | 把学习产物保存下来 |
What
变量、类型与输入输出 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
name = "Claire"
study_minutes = "45"
minutes = int(study_minutes)
profile = {
"name": name,
"minutes": minutes,
"hours": round(minutes / 60, 2),
}
print(profile)
print(type(profile["minutes"]).__name__)
参数拆解方法
第一次看到 变量、类型与输入输出 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 变量、类型与输入输出 的最小输入对象 |
| 变量名 | 它保存什么数据 | minutes 保存学习分钟数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先 print(type(...))。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day002/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 变量、类型与输入输出 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 2
TOPIC = "变量、类型与输入输出"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def build_profile(name, minutes_text, focus):
minutes = int(minutes_text)
return {
"name": name,
"focus": focus,
"minutes": minutes,
"hours": round(minutes / 60, 2),
"minutes_type": type(minutes).__name__,
}
def main():
profile = build_profile("Claire", "50", "Python types")
path = write_json("variable_type_report.json", profile)
print(json.dumps({"saved_to": str(path), **profile}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day02:变量、类型与输入输出
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
变量、类型与输入输出 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day03 - 分支结构与输入验证
> 阶段一:Python 基础
学习定位
今天只学习一个核心主题:把 分支结构与输入验证 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day02
- 下一站:Day04
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 分支结构与输入验证 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
print(...) | Python 对象 | 终端文本 | 先确认程序真的跑起来 |
type(...) | 任意变量 | 类型名 | 判断字符串、数字、列表有没有混用 |
if / for / def | 条件、序列、参数 | 分支、循环、返回值 | 把重复动作收敛成稳定流程 |
Path | 路径字符串 | 可读写路径对象 | 把学习产物保存下来 |
What
分支结构与输入验证 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
score_text = "82"
score = int(score_text)
if score >= 90:
level = "excellent"
elif score >= 60:
level = "pass"
else:
level = "redo"
print({"score": score, "level": level})
参数拆解方法
第一次看到 分支结构与输入验证 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 分支结构与输入验证 的最小输入对象 |
| 变量名 | 它保存什么数据 | minutes 保存学习分钟数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先 print(type(...))。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day003/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 分支结构与输入验证 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 3
TOPIC = "分支结构与输入验证"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def classify_record(record):
minutes = record.get("minutes", 0)
if minutes < 0:
return {**record, "valid": False, "reason": "minutes cannot be negative"}
if minutes >= 60:
level = "deep_work"
elif minutes >= 25:
level = "normal"
else:
level = "too_short"
return {**record, "valid": True, "level": level}
def main():
records = [{"topic": "loop", "minutes": 40}, {"topic": "csv", "minutes": -5}, {"topic": "json", "minutes": 75}]
checked = [classify_record(record) for record in records]
path = write_json("branch_validation_report.json", {"topic": TOPIC, "records": checked})
print(json.dumps({"saved_to": str(path), "records": checked}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day03:分支结构与输入验证
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
分支结构与输入验证 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day04 - 循环、计数器与重复任务
> 阶段一:Python 基础
学习定位
今天只学习一个核心主题:把 循环、计数器与重复任务 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day03
- 下一站:Day05
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 循环、计数器与重复任务 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
print(...) | Python 对象 | 终端文本 | 先确认程序真的跑起来 |
type(...) | 任意变量 | 类型名 | 判断字符串、数字、列表有没有混用 |
if / for / def | 条件、序列、参数 | 分支、循环、返回值 | 把重复动作收敛成稳定流程 |
Path | 路径字符串 | 可读写路径对象 | 把学习产物保存下来 |
What
循环、计数器与重复任务 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
minutes = [25, 0, 40, -5, 30]
total = 0
skipped = []
for value in minutes:
if value < 0:
break
if value == 0:
skipped.append(value)
continue
total += value
print({"total_minutes": total, "skipped": len(skipped)})
参数拆解方法
第一次看到 循环、计数器与重复任务 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 循环、计数器与重复任务 的最小输入对象 |
| 变量名 | 它保存什么数据 | minutes 保存学习分钟数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先 print(type(...))。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day004/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 循环、计数器与重复任务 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 4
TOPIC = "循环、计数器与重复任务"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def summarize_minutes(values):
total = 0
used = []
skipped = []
for value in values:
if value < 0:
break
if value == 0:
skipped.append(value)
continue
total += value
used.append(value)
return {"used": used, "skipped_count": len(skipped), "total_minutes": total}
def main():
report = summarize_minutes([25, 0, 45, 30, -1, 90])
path = write_json("loop_break_continue_report.json", {"topic": TOPIC, **report})
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day04:循环、计数器与重复任务
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
循环、计数器与重复任务 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day05 - 列表与最小算法
> 阶段一:Python 基础
学习定位
今天只学习一个核心主题:把 列表与最小算法 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day04
- 下一站:Day06
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 列表与最小算法 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
print(...) | Python 对象 | 终端文本 | 先确认程序真的跑起来 |
type(...) | 任意变量 | 类型名 | 判断字符串、数字、列表有没有混用 |
if / for / def | 条件、序列、参数 | 分支、循环、返回值 | 把重复动作收敛成稳定流程 |
Path | 路径字符串 | 可读写路径对象 | 把学习产物保存下来 |
What
列表与最小算法 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
scores = [72, 88, 91, 66, 88]
passed = [score for score in scores if score >= 80]
unique_scores = sorted(set(scores), reverse=True)
print({"passed": passed, "best": unique_scores[0], "unique": unique_scores})
参数拆解方法
第一次看到 列表与最小算法 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 列表与最小算法 的最小输入对象 |
| 变量名 | 它保存什么数据 | minutes 保存学习分钟数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先 print(type(...))。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day005/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 列表与最小算法 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 5
TOPIC = "列表与最小算法"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def analyze_scores(scores):
clean_scores = [score for score in scores if isinstance(score, (int, float))]
passed = [score for score in clean_scores if score >= 80]
return {
"count": len(clean_scores),
"best": max(clean_scores),
"passed": passed,
"unique_desc": sorted(set(clean_scores), reverse=True),
}
def main():
result = analyze_scores([72, 88, 91, 66, 88])
path = write_json("list_algorithm_report.json", {"topic": TOPIC, **result})
print(json.dumps({"saved_to": str(path), **result}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day05:列表与最小算法
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
列表与最小算法 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day06 - 函数、参数与返回值
> 阶段一:Python 基础
学习定位
今天只学习一个核心主题:把 函数、参数与返回值 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day05
- 下一站:Day07
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 函数、参数与返回值 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
print(...) | Python 对象 | 终端文本 | 先确认程序真的跑起来 |
type(...) | 任意变量 | 类型名 | 判断字符串、数字、列表有没有混用 |
if / for / def | 条件、序列、参数 | 分支、循环、返回值 | 把重复动作收敛成稳定流程 |
Path | 路径字符串 | 可读写路径对象 | 把学习产物保存下来 |
What
函数、参数与返回值 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
def calc_efficiency(done_tasks, minutes):
if minutes <= 0:
return 0
return round(done_tasks / minutes * 60, 2)
result = calc_efficiency(done_tasks=3, minutes=45)
print({"tasks_per_hour": result})
参数拆解方法
第一次看到 函数、参数与返回值 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 函数、参数与返回值 的最小输入对象 |
| 变量名 | 它保存什么数据 | minutes 保存学习分钟数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先 print(type(...))。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day006/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 函数、参数与返回值 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 6
TOPIC = "函数、参数与返回值"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def efficiency(done_tasks, minutes):
if minutes <= 0:
return 0
return round(done_tasks / minutes * 60, 2)
def build_day_summary(topic, done_tasks, minutes):
return {
"topic": topic,
"done_tasks": done_tasks,
"minutes": minutes,
"tasks_per_hour": efficiency(done_tasks, minutes),
}
def main():
summary = build_day_summary("function practice", done_tasks=4, minutes=50)
path = write_json("function_return_report.json", {"course_topic": TOPIC, **summary})
print(json.dumps({"saved_to": str(path), **summary}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day06:函数、参数与返回值
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
函数、参数与返回值 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day07 - 字符串、字典与集合
> 阶段一:Python 基础
学习定位
今天只学习一个核心主题:把 字符串、字典与集合 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day06
- 下一站:Day08
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 字符串、字典与集合 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
print(...) | Python 对象 | 终端文本 | 先确认程序真的跑起来 |
type(...) | 任意变量 | 类型名 | 判断字符串、数字、列表有没有混用 |
if / for / def | 条件、序列、参数 | 分支、循环、返回值 | 把重复动作收敛成稳定流程 |
Path | 路径字符串 | 可读写路径对象 | 把学习产物保存下来 |
What
字符串、字典与集合 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
text = "csv json csv python agent"
words = text.split()
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
print({"counts": counts, "unique_words": set(words)})
参数拆解方法
第一次看到 字符串、字典与集合 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 字符串、字典与集合 的最小输入对象 |
| 变量名 | 它保存什么数据 | minutes 保存学习分钟数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先 print(type(...))。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day007/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 字符串、字典与集合 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 7
TOPIC = "字符串、字典与集合"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def count_keywords(text):
words = text.lower().split()
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
return {"counts": counts, "unique_words": sorted(set(words))}
def main():
result = count_keywords("csv json csv python agent json")
path = write_json("string_dict_set_report.json", {"topic": TOPIC, **result})
print(json.dumps({"saved_to": str(path), **result}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day07:字符串、字典与集合
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
字符串、字典与集合 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day08 - 文件读写与异常处理
> 阶段一:Python 零基础与语法地基
学习定位
读写文本文件,并处理文件不存在的情况。
今天的目标不是背语法,而是产出:一个能保存学习记录的脚本。
前置知识
- 推荐前置:Day07 字符串和函数
- 上一站:Day07
- 下一站:Day09
今日知识地图
- Path
- read_text/write_text
- try/except
核心讲解
今天的关键词是 读写文本文件,并处理文件不存在的情况。学习时不要只看语法表面,而要始终追问三件事:输入是什么、处理逻辑是什么、输出要给谁使用。这个习惯会贯穿数据分析、Quant、LLM 应用和 Agent tool 设计。
从工程角度看,今天的能力要服务于 日志、报告、配置和本地缓存。也就是说,代码不只是“能跑”,还要能被未来的自己复查:文件名清楚、变量名能表达含义、失败时有可读错误、结果能保存。
难度承接上,今天依赖 Day07 字符串和函数;完成后会自然进入 Day09。如果今天卡住,优先回看 Day07,不要跳到更复杂的库或主题。
知识点结构
定义
读写文本文件,并处理文件不存在的情况,是把一个具体问题拆成可运行、可检查、可复用代码的过程。
为什么存在
它让学习从临时笔记变成长期资产。公开仓库里的每一天都应该能让读者看到:今天学什么、为什么学、怎么运行、如何检查结果。
最小案例
from pathlib import Path
path = Path("learning_log.txt")
path.write_text("Day08: 文件读写\n", encoding="utf-8")
try:
print(path.read_text(encoding="utf-8"))
except FileNotFoundError:
print("文件不存在,请先生成")
常见错误
- 文件路径写错后不检查当前目录。
- 打开文件时忘记指定
encoding="utf-8"。
- 用异常处理掩盖真正的数据问题。
工程应用
- 数据分析脚本
- Quant 研究模块
- LLM 报告助手
- Agent tool / workflow
未来扩展
今天只做最小闭环。后续可以逐步加入测试、日志、配置、页面、API 或主题文档,但不要牺牲可解释性。
基础详细讲解
如果你完全看不懂,先只抓这一句话
今天学的是:程序不仅能在终端显示结果,还能把结果写进文件,下次再读回来。
内存里的数据 -> 写入文件 -> 程序结束后仍然存在
文件里的数据 -> 读取出来 -> 继续处理
前几天你的数据都在代码里,程序一关就没了。文件读写让代码有了“长期记忆”。
文件读写到底发生了什么
from pathlib import Path
path = Path("note.txt")
path.write_text("hello", encoding="utf-8")
content = path.read_text(encoding="utf-8")
print(content)
执行顺序:
| 顺序 | 代码 | 发生了什么 |
|---|
| 1 | Path("note.txt") | 创建一个指向文件路径的对象 |
| 2 | write_text(...) | 把文本写入这个文件 |
| 3 | read_text(...) | 从这个文件读出文本 |
| 4 | print(content) | 在终端显示读到的内容 |
路径为什么容易错
相对路径是相对“你运行命令的目录”,不是永远相对 .py 文件。看不懂路径时,先运行:
from pathlib import Path
print(Path.cwd())
它会告诉你当前工作目录。
Mac 终端、当前目录与 Path
你在 Mac 终端里运行 Python 时,路径会和终端当前所在目录绑定。先记住这条线:
终端当前目录 pwd -> Python 的 Path.cwd() -> 相对路径从这里开始找
在终端里:
pwd
ls
python3 day08_file.py
在 Python 里:
from pathlib import Path
script_folder = Path(__file__).resolve().parent
print("script_folder =", script_folder)
print("run_from =", Path.cwd())
pwd 和 Path.cwd() 通常应该对应同一个目录。比如你在桌面运行脚本,Path("log.txt") 就会在桌面生成 log.txt;你在主题目录运行脚本,它就会在主题目录生成。
Path 和 Mac 终端命令的对应关系
| 你想做的事 | Mac 终端 | Python Path |
|---|
| 看当前目录 | pwd | Path.cwd() |
| 列出文件 | ls | list(Path.cwd().iterdir()) |
| 创建目录 | mkdir notes | Path("notes").mkdir(exist_ok=True) |
| 进入目录 | cd notes | Python 不常用 cd,通常直接写完整 Path |
| 创建文件 | touch a.md | Path("a.md").write_text("", encoding="utf-8") |
| 查看绝对路径 | pwd + 文件名 | Path("a.md").resolve() |
终端命令更像“你手动操作文件系统”;Path 更像“让 Python 自动操作文件系统”。工程化脚本的价值就在这里:你不用每天手动 mkdir、touch,可以让 Python 按规则批量生成。
工程化例子:批量生成每日学习文件
假设你想一次性生成 Day09-Day20 的学习文件,不要手动一个个建。可以这样写:
from pathlib import Path
root = Path("Learning-Journal")
root.mkdir(exist_ok=True)
days = range(9, 21)
for day in days:
file_path = root / f"Day{day:02d}.md"
content = f"""# Day{day:02d} 学习日志
## 今日主题
## 练习记录
## Debug
## 明天要复习
"""
file_path.write_text(content, encoding="utf-8")
print("created", file_path)
这段代码的工程含义:
| 代码 | 含义 |
|---|
root = Path("Learning-Journal") | 定义一个学习日志目录 |
root.mkdir(exist_ok=True) | 如果目录不存在就创建,存在也不报错 |
days = range(9, 21) | 准备要生成的天数,包含 9 到 20 |
root / f"Day{day:02d}.md" | 拼出每天的文件路径 |
write_text(...) | 把模板写进文件 |
print("created", file_path) | 在终端确认生成了什么 |
为什么工程里喜欢 Path,而不是手写字符串路径
不要这样拼路径:
file_path = "Learning-Journal/" + "Day09.md"
更推荐:
from pathlib import Path
file_path = Path("Learning-Journal") / "Day09.md"
print(file_path)
原因是:Path 更清楚、更稳,也更容易迁移。以后你做数据主题,会经常写:
from pathlib import Path
project_root = Path.cwd()
raw_data = project_root / "data" / "raw" / "prices.csv"
report = project_root / "reports" / "summary.md"
print(raw_data)
print(report)
这就是工程化路径管理。
异常处理先这样理解
from pathlib import Path
path = Path("missing_note.txt")
try:
content = path.read_text(encoding="utf-8")
except FileNotFoundError:
content = ""
print({"content": content, "exists": path.exists()})
意思是:先尝试读文件;如果文件不存在,不要让程序直接崩掉,而是给一个可解释的处理方式。
Debug 对照表
| 现象 | 常见原因 | 怎么查 |
|---|
| 文件找不到 | 当前目录不对或文件名写错 | 打印 Path.cwd(),检查文件名和后缀 |
| 中文乱码 | 编码不一致 | 读写都加 encoding="utf-8" |
| 写入后没看到文件 | 文件写到别的目录了 | 搜索文件名,或打印 path.resolve() |
| 读出来是空的 | 文件本来为空或写入失败 | 先打开文件确认内容 |
文件读写与异常处理
程序真正有用,往往从“能读外部文件、能保存结果”开始。文件读写让代码和数据发生连接,异常处理让程序在失败时给出解释,而不是直接中断。
基础知识深讲:文件系统、持久化与异常
程序运行时的数据通常只存在内存里,程序结束就消失。文件读写解决的是持久化问题:把结果保存到硬盘,下次还能读取。学习文件不是为了背 open(),而是理解输入输出从终端扩展到了文件系统。
路径是文件读写最容易混乱的地方。相对路径不是相对文件所在位置,而是相对当前运行命令的工作目录。Path.cwd() 能告诉你当前目录。后面主题里推荐使用 pathlib.Path,因为它能让路径拼接更清楚,例如 root / "data" / "sample.csv"。
异常处理不是“掩盖错误”,而是把失败变成可解释流程。文件不存在、格式不对、权限不足,都应该有明确反馈。try / except 应该包住可能失败的最小代码块;包太大,会让你不知道到底哪一步失败。
读写文件还要区分文本和结构化数据。普通 .txt 适合自由文本,.json 适合字典/列表结构,.csv 适合表格。选择文件格式,就是选择未来如何复查和复用数据。
手写顺序
- 优先使用
Path 管理路径,减少目录混乱。
- 读文件时先确认文件是否存在,再处理内容。
try / except 只包住可能失败的那一小段,错误信息要能帮助定位。
今天必须真正弄懂
- 输入:今天这段代码从哪里拿到数据,是手写值、终端输入、文件,还是函数参数。
- 处理:每一行代码改变了什么状态,例如变量变了、列表多了一个元素、判断走了某个分支。
- 输出:结果给谁看,是终端输出、返回值、文件,还是后面函数继续使用。
和后续知识的关系
日志、CSV、Markdown 报告、RAG 文档、回测结果都需要文件读写。今天练的是主题的输入输出层。
零基础拆解:文件输入输出和失败处理
这一天到底在练什么
文件让程序有了长期记忆。读文件是输入,写文件是输出,异常处理负责让失败变得可解释。
手写时按这个顺序
- 先用
Path("notes.txt") 表示路径。
- 写入一行内容,再读出来打印。
- 把可能失败的读取放进
try/except,记录错误原因。
最常见卡点
路径错误最常见。先打印 Path.cwd() 看当前目录,再确认文件名、后缀和大小写。
自查问题
- 我能解释相对路径相对哪里。
- 我能写入并重新读出一个文本文件。
- 我能处理文件不存在的情况。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 新建 day08_file.py。
2. 用 Path 创建 learning_log.txt。
3. 写入一行学习记录。
4. 读取文件并打印。
5. 删除文件后运行,观察 FileNotFoundError。
6. 用 try/except 输出清晰提示。
7. 写下文件输入和输出分别是什么。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day008/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 文件读写与异常处理 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 8
TOPIC = "文件读写与异常处理"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def safe_write_and_read(filename, content):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / filename
try:
path.write_text(content, encoding="utf-8")
return {"ok": True, "path": str(path), "content": path.read_text(encoding="utf-8").strip()}
except OSError as exc:
return {"ok": False, "error": str(exc)}
def main():
file_result = safe_write_and_read("learning_note.txt", "Day08 file io and exception")
path = write_json("file_exception_report.json", {"topic": TOPIC, "file_result": file_result})
print(json.dumps({"saved_to": str(path), **file_result}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day09 - 模块、包与可复用脚本
> 阶段一:Python 基础
学习定位
今天只学习一个核心主题:把 模块、包与可复用脚本 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day08
- 下一站:Day10
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 模块、包与可复用脚本 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
print(...) | Python 对象 | 终端文本 | 先确认程序真的跑起来 |
type(...) | 任意变量 | 类型名 | 判断字符串、数字、列表有没有混用 |
if / for / def | 条件、序列、参数 | 分支、循环、返回值 | 把重复动作收敛成稳定流程 |
Path | 路径字符串 | 可读写路径对象 | 把学习产物保存下来 |
What
模块、包与可复用脚本 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
def normalize_topic(topic):
return topic.strip().lower().replace(" ", "-")
def build_filename(day, topic):
return f"day{day:03d}-{normalize_topic(topic)}.md"
print(build_filename(9, "Reusable Script"))
参数拆解方法
第一次看到 模块、包与可复用脚本 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 模块、包与可复用脚本 的最小输入对象 |
| 变量名 | 它保存什么数据 | minutes 保存学习分钟数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先 print(type(...))。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day009/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 模块、包与可复用脚本 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 9
TOPIC = "模块、包与可复用脚本"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def normalize_name(name):
return name.strip().lower().replace(" ", "_")
def build_module_plan(functions):
return {
"module": "learning_utils.py",
"functions": [normalize_name(name) for name in functions],
"import_example": "from learning_utils import normalize_name",
}
def main():
plan = build_module_plan(["Clean Topic", "Save Report", "Load Config"])
path = write_json("module_reuse_plan.json", {"topic": TOPIC, **plan})
print(json.dumps({"saved_to": str(path), **plan}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day09:模块、包与可复用脚本
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
模块、包与可复用脚本 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day10 - 学习记录 CLI 基础
> 阶段一:Python 基础
学习定位
今天只学习一个核心主题:把 学习记录 CLI 基础 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day09
- 下一站:Day11
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 学习记录 CLI 基础 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
print(...) | Python 对象 | 终端文本 | 先确认程序真的跑起来 |
type(...) | 任意变量 | 类型名 | 判断字符串、数字、列表有没有混用 |
if / for / def | 条件、序列、参数 | 分支、循环、返回值 | 把重复动作收敛成稳定流程 |
Path | 路径字符串 | 可读写路径对象 | 把学习产物保存下来 |
What
学习记录 CLI 基础 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--minutes", type=int, default=30)
parser.add_argument("--topic", default="csv")
args = parser.parse_args([])
print({"topic": args.topic, "minutes": args.minutes})
参数拆解方法
第一次看到 学习记录 CLI 基础 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 学习记录 CLI 基础 的最小输入对象 |
| 变量名 | 它保存什么数据 | minutes 保存学习分钟数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先 print(type(...))。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day010/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 学习记录 CLI 基础 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 10
TOPIC = "学习记录 CLI 基础"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def parse_cli_like_args(args):
result = {"topic": "unknown", "minutes": 0}
for index, value in enumerate(args):
if value == "--topic" and index + 1 < len(args):
result["topic"] = args[index + 1]
if value == "--minutes" and index + 1 < len(args):
result["minutes"] = int(args[index + 1])
return result
def main():
parsed = parse_cli_like_args(["--topic", "csv", "--minutes", "45"])
path = write_json("cli_learning_record.json", {"course_topic": TOPIC, **parsed})
print(json.dumps({"saved_to": str(path), **parsed}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day10:学习记录 CLI 基础
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
学习记录 CLI 基础 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day11 - CSV 基础 reader / writer
> 阶段二:Python 工程化基本功
学习定位
今天只学习一个核心主题:csv.reader / csv.writer:CSV -> list,list -> CSV。
你已经会 Day10 的本地 CLI,也会 open()、f.write()、列表和循环。今天不是突然背一个新库,而是把“手工写文本”升级成“按表格结构读写数据”。
Day 主线控制在 4 小时以内:先建立 CSV 库认知地图,再写最小 reader / writer,再做边界实验。
前置知识
- 上一站:Day10 CLI 基础
- 下一站:Day12 CSV 进阶 DictReader / DictWriter
- 必须先会:文件路径、
with open(...) as f、列表、循环、int() 类型转换。
认知地图
CSV 可以先理解成“纯文本表格”。
topic,minutes
python,120
sql,90
它看起来像 Excel,但本质还是文本文件:逗号分隔列,换行分隔行。
| 工具 | 输入 | 输出 | 适合什么 |
|---|
csv.reader(f) | CSV 文件对象 | 一行行 list | 读取没有字段名意识的表格 |
csv.writer(f) | CSV 文件对象 | writer 对象 | 把 list 行写进 CSV |
writer.writerow(row) | 一个 list | 文件新增一行 | 写表头或单行数据 |
writer.writerows(rows) | 多个 list | 文件新增多行 | 批量写数据 |
今天只学这四个点,不学 DictReader 和 DictWriter。后者留到 Day12。
What
csv 是 Python 标准库里专门处理 CSV 的工具箱。
reader / writer 是最基础的一对工具:
reader: CSV 文件 -> 一行行 list
writer: list 行 -> CSV 文件
这比手写 "a,b,c\n" 稳,因为 CSV 里会遇到逗号、换行、空字段、引号等细节。库的价值就是替你处理这些格式细节。
Why
昨天如果要保存一组表格记录,你可能会这样写:
from pathlib import Path
path = Path("manual_records.csv")
with path.open("w", encoding="utf-8") as f:
f.write("day,topic,minutes\n")
f.write("11,csv,35\n")
print(path.read_text(encoding="utf-8"))
这能跑,但问题是:
- 字段顺序靠你手工记。
- 值里有逗号时容易乱。
- 多写几行后换行和空格容易出错。
- 读回来时还要自己
split(",")。
csv.writer 和 csv.reader 的意义是:把“文本拼接”升级成“表格行读写”。
How:从旧方法升级到 reader / writer
先看数据流,不直接背 API。
list 行数据
↓
csv.writer(f).writerows(rows)
↓
records.csv
↓
csv.reader(f)
↓
一行行 list
↓
跳过表头、转换 minutes、汇总
最小写入
import csv
from pathlib import Path
path = Path("records.csv")
rows = [
["day", "topic", "minutes"],
["11", "csv reader writer", "35"],
["12", "dict csv", "45"],
]
with path.open("w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(rows)
最小读取
import csv
from pathlib import Path
path = Path("records.csv")
rows = [
["day", "topic", "minutes"],
["11", "csv reader writer", "35"],
]
with path.open("w", newline="", encoding="utf-8") as f:
csv.writer(f).writerows(rows)
with path.open("r", newline="", encoding="utf-8") as f:
reader = csv.reader(f)
for row in reader:
print(row)
你会看到每一行都是 list:
['day', 'topic', 'minutes']
['11', 'csv reader writer', '35']
['12', 'dict csv', '45']
参数拆解方法
第一次看到 csv.writer(f),不要只记函数名,按对象拆。
csv.writer(f)
| 部分 | 含义 | 你要问的问题 |
|---|
csv | 标准库模块 | 这个工具箱管什么?CSV 表格文本。 |
writer | 写 CSV 的函数 | 它把什么写到哪里?把 list 行写进文件。 |
f | 文件对象 | 这个文件是用什么模式打开的?通常是 "w"。 |
newline="" | 换行控制 | 为什么要写?避免部分系统写出多余空行。 |
返回值 writer | 写入器对象 | 后面可以调用 writerow() / writerows()。 |
csv.reader(f)
| 部分 | 含义 | 你要问的问题 |
|---|
reader | 读 CSV 的函数 | 它把 CSV 变成什么?一行行 list。 |
f | 文件对象 | 文件是否存在?编码是否正确? |
| 返回值 | 可迭代对象 | 可以放进 for row in reader。 |
row | 一行数据 | 这一行是 list,不是 dict。取字段要靠下标。 |
和旧知识的连接
| 旧知识 | 今天升级成 | 升级后解决什么 |
|---|
f.write() | csv.writer() | 不手工拼逗号和换行 |
| 字符串 | list 行 | 每一列的位置稳定 |
for 循环 | for row in reader | 一行一行处理文件 |
int() | 字段类型转换 | CSV 读出来默认多是字符串 |
| Debug 打印 | 打印 row 和 type(row) | 先看结构再计算 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
忘记 newline="" | CSV 中间出现多余空行 | 写文件时固定加上 newline="" |
把 row 当 dict | row["minutes"] 报错 | reader 输出 list,只能用下标 |
| 忘记跳过表头 | int("minutes") 报错 | 先 header = next(reader) |
| 数字没转换 | '35' + '45' 变成字符串拼接 | minutes = int(row[2]) |
| 路径不清楚 | 找不到文件 | 打印 Path.cwd() 和 path.resolve() |
Future Usage
- Data:读取外部原始 CSV,先检查表头和前 5 行。
- Quant:读取行情样例,先把价格、成交量从字符串转成数字。
- LLM:把评估样例保存成 CSV,方便批量对比。
- Agent:把 tool 执行日志先落成表格,后续再分析。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 画 CSV -> list 的数据流 | notes.md |
| 60 分钟 | 手打 writer 和 reader | main.py |
| 45 分钟 | 改 2 行输入样例 | records.csv |
| 45 分钟 | 故意制造表头/类型错误 | errors.md |
| 40 分钟 | 写迁移说明 | 复盘 5 行 |
今日强化题(带具体代码)
强化题 1:复现最小案例
任务:复制下面代码到 main.py 并运行。
验收:终端打印 JSON,生成 outputs/day011/records.csv 和 summary.json。
强化题 2:替换输入
任务:新增 2 行样例记录,至少一行数值字段大于当前样例。
验收:total_minutes 和 long_sessions 会变化。
强化题 3:边界检查
任务:把一行 minutes 改成空字符串或 abc。
验收:程序不会崩溃,坏行进入 skipped。
强化题 4:结果保存
任务:保留 CSV 原始记录,同时保存 JSON 汇总。
验收:关闭终端后还能复查两个文件。
强化题 5:迁移说明
任务:写 3 句话说明 CSV reader / writer 如何迁移到 Data、Quant、LLM 或 Agent。
参考代码:main.py
from pathlib import Path
import csv
import json
DAY = 11
TOPIC = "CSV reader / writer"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def write_csv(path: Path):
rows = [
["day", "topic", "minutes"],
["11", "csv reader writer", "35"],
["12", "dict csv preview", "45"],
["13", "json preview", ""],
]
with path.open("w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerows(rows)
def read_csv(path: Path):
valid = []
skipped = []
with path.open("r", newline="", encoding="utf-8") as f:
reader = csv.reader(f)
header = next(reader)
for line_no, row in enumerate(reader, start=2):
try:
minutes = int(row[2])
except (IndexError, ValueError):
skipped.append({"line": line_no, "row": row, "reason": "bad minutes"})
continue
valid.append({"day": row[0], "topic": row[1], "minutes": minutes})
return header, valid, skipped
def main():
ensure_dirs()
csv_path = OUT / "records.csv"
write_csv(csv_path)
header, valid, skipped = read_csv(csv_path)
summary = {
"topic": TOPIC,
"header": header,
"valid_count": len(valid),
"total_minutes": sum(item["minutes"] for item in valid),
"long_sessions": [item for item in valid if item["minutes"] >= 45],
"skipped": skipped,
}
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day11:CSV reader / writer
CSV 的输入是什么:
reader 的输出是什么:
writer 的输入是什么:
我今天最容易错在哪里:
未来会在哪个 IC 使用:
Day12 - CSV 进阶 DictReader / DictWriter
> 阶段二:Python 工程化基本功
学习定位
今天只学习一个核心主题:csv.DictReader / csv.DictWriter:CSV -> dict,dict -> CSV。
Day11 你已经知道 reader 读出来是一行行 list。今天升级成“用字段名读写”,让代码从 row[2] 变成 row["minutes"]。
这一天的核心不是更高级,而是更可读、更稳、更接近真实数据分析。
前置知识
- 上一站:Day11 CSV reader / writer
- 下一站:Day13 JSON 基础 loads / dumps
- 必须先会:dict、字段名、文件读写、
int() 类型转换。
认知地图
| 工具 | 输入 | 输出 | 适合什么 |
|---|
csv.DictReader(f) | 带表头的 CSV 文件 | 一行行 dict | 用字段名读取记录 |
csv.DictWriter(f, fieldnames=...) | 文件对象 + 字段名 | writer 对象 | 按字段名写 CSV |
writer.writeheader() | fieldnames | 表头行 | 先写列名 |
writer.writerow(row) | 一个 dict | CSV 一行 | 写单条记录 |
writer.writerows(rows) | 多个 dict | CSV 多行 | 批量写记录 |
What
DictReader / DictWriter 是 CSV 工具里的“字段名版本”。
DictReader: CSV -> dict
DictWriter: dict -> CSV
Day11 的 row[2] 依赖列位置;Day12 的 row["minutes"] 依赖字段名。
真实数据里,字段名比位置更重要。你以后读外部数据、行情、评估集时,通常会关心 date、close、label、question 这些字段,而不是“第 3 列”。
Why
不用 DictReader 也能读 CSV,但代码会变脆:
row = ["12", "dict csv", "45"]
minutes = int(row[2])
print(minutes)
如果以后表格列顺序变了,row[2] 可能不再是 minutes。
改成字段名后:
row = {"day": "12", "topic": "dict csv", "minutes": "45"}
minutes = int(row["minutes"])
print(minutes)
你一眼能看懂这行在取什么。字段名也是数据分析里的“变量名”,它让数据有语义。
How:从 list 行升级成 dict 行
数据流是:
dict 记录
↓
DictWriter(fieldnames)
↓
带表头 CSV
↓
DictReader
↓
一行行 dict
↓
按字段名取值、校验、汇总
最小写入
import csv
from pathlib import Path
path = Path("records.csv")
records = [
{"day": "11", "topic": "csv reader writer", "minutes": "35"},
{"day": "12", "topic": "dict csv", "minutes": "45"},
]
with path.open("w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["day", "topic", "minutes"])
writer.writeheader()
writer.writerows(records)
最小读取
import csv
from pathlib import Path
path = Path("records.csv")
records = [
{"day": "11", "topic": "csv reader writer", "minutes": "35"},
{"day": "12", "topic": "dict csv", "minutes": "45"},
]
with path.open("w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["day", "topic", "minutes"])
writer.writeheader()
writer.writerows(records)
with path.open("r", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for row in reader:
print(row["topic"], int(row["minutes"]))
参数拆解方法
csv.DictWriter(f, fieldnames=[...])
| 部分 | 含义 | 为什么重要 |
|---|
csv | CSV 标准库 | 专门处理表格文本 |
DictWriter | dict 写入 CSV 的类 | 把字段名和列顺序绑定起来 |
f | 文件对象 | 必须是可写文件,通常 "w" 模式 |
fieldnames | 表头字段列表 | 决定 CSV 列名和列顺序 |
返回值 writer | 写入器对象 | 继续调用 writeheader()、writerow()、writerows() |
writer.writeheader()
| 部分 | 含义 |
|---|
writer | 上一步创建的写入器 |
writeheader() | 把 fieldnames 写成 CSV 第一行 |
| 常见错误 | 忘记写表头,后面 DictReader 就不知道字段名 |
csv.DictReader(f)
| 部分 | 含义 |
|---|
DictReader | dict 读取器 |
f | 可读文件对象 |
| 输出 | 每一行是 dict,key 来自表头 |
| 常见错误 | 表头字段拼错,row["minutes"] 会 KeyError |
和旧知识的连接
| Day11 | Day12 | 升级点 |
|---|
row[2] | row["minutes"] | 从位置意识升级到字段意识 |
| list 行 | dict 记录 | 字段含义更清楚 |
| 手工记列顺序 | fieldnames 固定表头 | 输出更稳定 |
| 打印整行 | 打印 row.keys() | Debug 更容易 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
fieldnames 缺字段 | 写入时报错或字段丢失 | 对比 records[0].keys() |
忘记 writeheader() | 读回来第一行变字段名 | 打开 CSV 看第一行 |
| 数字仍是字符串 | 不能正确计算 | print(type(row["minutes"])) |
| 字段名拼错 | KeyError | print(row.keys()) |
| 空值没处理 | int("") 报错 | 转换前先判断 |
Future Usage
- Data:清洗 CSV 原始数据时,字段名就是变量名。
- Quant:行情字段
date/open/high/low/close/volume 要稳定。
- LLM:评估集字段
question/answer/score 适合 CSV。
- Agent:执行日志里的
step/tool/status/error 可以先用 CSV 复盘。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 对比 reader 和 DictReader | notes 表格 |
| 60 分钟 | 手打 DictWriter / DictReader | main.py |
| 45 分钟 | 改字段名和列顺序 | errors.md |
| 45 分钟 | 加空值和坏数据 | skipped 输出 |
| 40 分钟 | 写迁移说明 | review.md |
今日强化题(带具体代码)
强化题 1:复现最小案例
任务:复制下面代码到 main.py 并运行。
验收:生成 outputs/day012/records.csv 和 summary.json。
强化题 2:替换输入
任务:新增字段 source,例如 book、video、codex。
验收:你能说明为什么 fieldnames 也要同步改。
强化题 3:边界检查
任务:删除一行的 minutes 或把它改成 abc。
验收:坏行进入 skipped,程序继续跑。
强化题 4:结果保存
任务:把有效记录和跳过记录分别保存。
验收:能复查哪些数据被排除。
强化题 5:迁移说明
任务:写 3 句话说明字段意识为什么是 Pandas、SQL、LLM 评估集的基础。
参考代码:main.py
from pathlib import Path
import csv
import json
DAY = 12
TOPIC = "CSV DictReader / DictWriter"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
FIELDS = ["day", "topic", "minutes", "source"]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def write_records(path: Path):
records = [
{"day": "11", "topic": "csv reader writer", "minutes": "35", "source": "course"},
{"day": "12", "topic": "dict csv", "minutes": "45", "source": "course"},
{"day": "12", "topic": "bad row", "minutes": "abc", "source": "manual"},
]
with path.open("w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=FIELDS)
writer.writeheader()
writer.writerows(records)
def load_records(path: Path):
valid = []
skipped = []
with path.open("r", newline="", encoding="utf-8") as f:
reader = csv.DictReader(f)
for line_no, row in enumerate(reader, start=2):
try:
minutes = int(row["minutes"])
except ValueError:
skipped.append({"line": line_no, "row": row, "reason": "minutes is not int"})
continue
row["minutes"] = minutes
valid.append(row)
return valid, skipped
def main():
ensure_dirs()
csv_path = OUT / "records.csv"
write_records(csv_path)
valid, skipped = load_records(csv_path)
summary = {
"topic": TOPIC,
"fields": FIELDS,
"valid_count": len(valid),
"total_minutes": sum(row["minutes"] for row in valid),
"sources": sorted({row["source"] for row in valid}),
"skipped": skipped,
}
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
今日复盘模板
Day12:CSV DictReader / DictWriter
DictReader 的输入是什么:
DictReader 的输出是什么:
fieldnames 决定了什么:
我今天制造了什么错误:
未来会在哪个 IC 使用:
Day13 - JSON 完整学习
> 阶段二:基础 Python 收束
学习定位
今天把 JSON 一次讲完整:JSON 是跨程序传递结构化数据的文本格式;Python 用 json 标准库完成字符串和文件的读写。
前两天你已经学了 CSV。CSV 适合二维表,JSON 适合 dict/list 嵌套结构。今天只聚焦 JSON,不再拆到后面。
认知地图
| 工具 | 输入 | 输出 | 用途 |
|---|
json.loads(text) | JSON 字符串 | Python dict/list | 解析 API 文本、模型输出文本 |
json.dumps(obj) | Python dict/list | JSON 字符串 | 打印、日志、网络传输 |
json.load(f) | 文件对象 | Python dict/list | 读取 .json 文件 |
json.dump(obj, f) | Python dict/list + 文件对象 | .json 文件 | 保存配置、结果、状态 |
JSON 与 Python 类型对应
| JSON | Python |
|---|
| object | dict |
| array | list |
| string | str |
| number | int / float |
| true / false | True / False |
| null | None |
What
JSON 本质是“长得像 dict/list 的文本”。它不是 Python 对象,必须经过解析。
import json
text = '{"name": "item_a", "value": 10}'
data = json.loads(text)
print(data)
text 是字符串,data 是 dict。这个区别非常重要。
Why
JSON 存在的原因是:不同程序、不同语言、不同机器之间需要一种通用结构化格式。
- 配置文件需要保存参数。
- API 需要返回结构化结果。
- LLM 需要输出可校验字段。
- Agent 需要保存 tool 调用状态。
- Quant 实验需要保存参数、指标、错误信息。
How:四个函数一次打通
JSON 字符串 --loads--> Python 对象 --dumps--> JSON 字符串
JSON 文件 --load ---> Python 对象 --dump ---> JSON 文件
字符串读写
import json
text = '{"name": "item_a", "value": 10}'
data = json.loads(text)
print(data["value"])
json_text = json.dumps(data, ensure_ascii=False, indent=2)
print(json_text)
文件读写
from pathlib import Path
import json
path = Path("data.json")
with path.open("w", encoding="utf-8") as f:
json.dump({"items": [{"name": "item_a", "value": 10}]}, f, ensure_ascii=False, indent=2)
with path.open("r", encoding="utf-8") as f:
data = json.load(f)
嵌套路径
data = {"items": [{"name": "item_a", "value": 10}]}
value = data["items"][0]["value"]
print(value)
读法:
dict -> key "items" -> list -> index 0 -> dict -> key "value"
参数拆解方法
json.dumps(obj, ensure_ascii=False, indent=2)
| 参数 | 含义 | 建议 |
|---|
obj | 要转成 JSON 的 Python 对象 | 优先 dict/list |
ensure_ascii=False | 中文正常显示 | 写中文内容时固定加 |
indent=2 | 缩进 2 格 | 人类可读、Git diff 清楚 |
json.dump(obj, f, ensure_ascii=False, indent=2)
| 参数 | 含义 | 易错点 |
|---|
obj | Python 对象 | 不能包含函数、Path、set 等不可序列化对象 |
f | 文件对象 | 要用 "w" 和 encoding="utf-8" |
| 返回值 | None | 它直接写文件,不返回字符串 |
Common Errors
| 错误 | 表现 | 修法 |
|---|
| 单引号写 JSON | JSONDecodeError | JSON 字符串用双引号 |
| 字符串当 dict | TypeError | 先 json.loads(text) |
dump 当 dumps | 得到 None | dump 写文件,dumps 返回字符串 |
| 顶层类型看错 | list/dict 取值方式错 | 先 print(type(data)) |
| 写入 set/Path | not JSON serializable | 先转成 list/str |
今日强化题(带具体代码)
强化题 1:跑通四个函数
任务:运行下面代码,确认 loads/dumps/load/dump 都出现。
验收:生成 outputs/day013/records.json 和 summary.json。
强化题 2:替换输入
任务:新增一条 record,并修改一个嵌套字段。
强化题 3:边界检查
任务:把一条 value 改成 null,观察 skipped。
强化题 4:总结 JSON vs CSV
任务:写 3 句话说明什么时候 JSON 比 CSV 更合适。
参考代码:main.py
from pathlib import Path
import json
DAY = 13
OUT = Path(__file__).resolve().parent / "outputs" / f"day{DAY:03d}"
def parse_json_text(text):
data = json.loads(text)
return data
def validate_records(data):
valid = []
skipped = []
for index, item in enumerate(data.get("records", [])):
value = item.get("metrics", {}).get("value")
if not isinstance(value, (int, float)):
skipped.append({"index": index, "item": item, "reason": "value must be numeric"})
continue
valid.append(item)
return valid, skipped
def main():
OUT.mkdir(parents=True, exist_ok=True)
raw_text = """
{
"metadata": {"source": "demo", "schema_version": 1},
"records": [
{"name": "item_a", "group": "A", "metrics": {"value": 10}},
{"name": "item_b", "group": "A", "metrics": {"value": 15}},
{"name": "item_c", "group": "B", "metrics": {"value": null}}
]
}
"""
data = parse_json_text(raw_text)
valid, skipped = validate_records(data)
with (OUT / "records.json").open("w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
with (OUT / "records.json").open("r", encoding="utf-8") as f:
loaded = json.load(f)
summary = {
"topic": "complete json basics",
"source": loaded["metadata"]["source"],
"valid_count": len(valid),
"total_value": sum(item["metrics"]["value"] for item in valid),
"skipped": skipped,
}
summary_text = json.dumps(summary, ensure_ascii=False, indent=2)
(OUT / "summary.json").write_text(summary_text, encoding="utf-8")
print(summary_text)
if __name__ == "__main__":
main()
今日复盘模板
Day13:JSON 完整学习
loads / dumps 的区别:
load / dump 的区别:
JSON 和 dict/list 的关系:
我今天读懂的一条嵌套路径:
JSON 最常见错误:
Day14 - class、对象、方法与 self
> 阶段二:基础 Python 收束:面向对象
学习定位
今天正式进入 class。目标不是背面向对象术语,而是看懂:class 是模板,对象是实例,属性保存状态,方法保存行为,self 代表当前对象。
认知地图
| 概念 | 写法 | 含义 |
|---|
| class | class Record: | 定义对象模板 |
| object | Record(...) | 创建具体对象 |
| attribute | self.value | 对象自己的数据 |
| method | def is_valid(self): | 对象自己的行为 |
| self | self | 当前这个对象 |
| constructor | __init__ | 创建对象时初始化状态 |
What
dict 可以保存数据:
row = {"name": "item_a", "value": 10}
class 可以把数据和行为放在一起:
class Record:
def __init__(self, name, value):
self.name = name
self.value = value
def is_valid(self):
return self.value >= 0
Why
只用 dict 时,字段和行为分散:
- 字段名容易写错。
- 校验逻辑到处复制。
- 相关函数不知道应该放哪里。
- 程序变大后边界不清楚。
class 的作用是把“某类数据的结构和行为”集中到一个地方。
How:从 JSON/dict 进入 class
dict 数据
↓
__init__ 初始化字段
↓
self 保存状态
↓
方法读取 self 完成计算
↓
to_dict 输出回 JSON
最小正规 class
class Record:
def __init__(self, name, value):
self.name = name
self.value = value
def is_valid(self):
return isinstance(self.value, (int, float))
对象拆解方法
| 代码 | 拆解 |
|---|
Record("item_a", 10) | 调用类名,创建对象 |
__init__(self, name, value) | 创建对象时自动执行 |
self.name = name | 把参数保存到当前对象 |
record.is_valid() | 调用对象方法 |
type(record).__name__ | 查看对象所属类 |
Common Errors
| 错误 | 表现 | 修法 |
|---|
忘记 self | TypeError | 实例方法第一个参数写 self |
写成 _init_ | 初始化不执行 | 前后都是两个下划线 |
| 属性名不一致 | AttributeError | 统一用 self.value |
| 方法忘记 return | 得到 None | 方法输出要明确 |
| 把类当对象 | 没有实例状态 | 用 Record(...) 创建对象 |
今日强化题(带具体代码)
强化题 1:复现 class 完整流程
任务:运行下面代码。
验收:生成 outputs/day014/class_records.json。
强化题 2:替换输入
任务:新增一条 raw dict,再转成对象。
强化题 3:边界检查
任务:把 value 改成字符串,确认错误进入 errors。
参考代码:main.py
from pathlib import Path
import json
DAY = 14
OUT = Path(__file__).resolve().parent / "outputs" / f"day{DAY:03d}"
class Record:
def __init__(self, name, value, group="default"):
if not name:
raise ValueError("name is required")
self.name = name
self.value = value
self.group = group
def is_valid(self):
return isinstance(self.value, (int, float)) and self.value >= 0
def score(self, baseline):
if not self.is_valid() or baseline == 0:
return None
return round(self.value / baseline, 4)
def to_dict(self, baseline):
return {
"class": type(self).__name__,
"name": self.name,
"group": self.group,
"value": self.value,
"valid": self.is_valid(),
"score": self.score(baseline),
}
def build_records(raw_items):
records = []
errors = []
for index, item in enumerate(raw_items):
try:
record = Record(item.get("name"), item.get("value"), item.get("group", "default"))
except ValueError as exc:
errors.append({"index": index, "item": item, "error": str(exc)})
continue
records.append(record)
return records, errors
def main():
OUT.mkdir(parents=True, exist_ok=True)
raw_items = [
{"name": "item_a", "value": 10, "group": "A"},
{"name": "item_b", "value": 15, "group": "A"},
{"name": "item_c", "value": "bad", "group": "B"},
{"name": "", "value": 8, "group": "B"},
]
records, errors = build_records(raw_items)
valid_values = [record.value for record in records if record.is_valid()]
baseline = sum(valid_values) / len(valid_values)
payload = {
"topic": "class object method self",
"baseline": baseline,
"items": [record.to_dict(baseline) for record in records],
"errors": errors,
}
(OUT / "class_records.json").write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(payload, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
今日复盘模板
Day14:class、对象、方法与 self
class 是什么:
对象是什么:
self 代表什么:
__init__ 做什么:
方法和函数的区别:
Day15 - class 正规化与 dataclass
> 阶段二:基础 Python 收束:面向对象
学习定位
今天把 class 学到“够用、正规、能接工程”的水平:dataclass、类型标注、默认值、from_dict、to_dict、对象校验。
学完今天,基础 Python 第一阶段结束。Day16 开始进入数据分析三大库:NumPy、pandas、Matplotlib。
认知地图
| 工具 | 输入 | 输出 | 作用 |
|---|
@dataclass | 字段声明 | 自动生成初始化方法 | 少写样板代码 |
| 类型标注 | value: float | 可读边界 | 告诉人和工具字段类型 |
field(default_factory=list) | 可变默认值 | 独立 list | 避免多个对象共享同一个 list |
@classmethod | dict / 外部数据 | 对象 | 常用于 from_dict |
asdict(obj) | dataclass 对象 | dict | 输出到 JSON/日志 |
What
普通 class:
class Record:
def __init__(self, name, value):
self.name = name
self.value = value
dataclass:
from dataclasses import dataclass
@dataclass
class Record:
name: str
value: float
record = Record(name="item_a", value=10.0)
print(record)
它们都能创建对象。dataclass 更适合“主要保存结构化数据”的类。
Why
当对象字段比较固定时,dataclass 能减少重复代码,并让结构更清楚。
它适合:
- 配置对象。
- 数据记录对象。
- API 输入输出对象。
- LLM/Agent 的结构化结果。
- Quant 参数和指标结果。
How:正规对象边界
raw dict
↓
from_dict 校验和转换
↓
dataclass 对象
↓
方法计算
↓
to_dict / asdict
↓
JSON 保存
参数拆解方法
@dataclass
| 部分 | 含义 |
|---|
@dataclass | 装饰器,让类自动获得 __init__、repr 等方法 |
name: str | 字段名和类型提示 |
tags: list[str] | list 字段,注意默认值 |
field(default_factory=list) | 每个对象独立创建一个空 list |
@classmethod
| 部分 | 含义 |
|---|
cls | 当前类本身 |
from_dict | 从 dict 创建对象的常用命名 |
return cls(...) | 返回这个类的新对象 |
Common Errors
| 错误 | 表现 | 修法 |
|---|
list 默认值写成 [] | 多个对象共享 list | 用 field(default_factory=list) |
| 类型标注当强制校验 | 运行时仍可能传错 | 在 from_dict 里转换和检查 |
asdict 忘记导入 | NameError | from dataclasses import asdict |
| from_dict 不处理缺字段 | 后面才报错 | 在入口统一校验 |
Future Usage
- NumPy/pandas 里用 dataclass 保存分析配置。
- Matplotlib 里用 dataclass 保存图表参数。
- Quant 里用 dataclass 保存策略参数。
- LLM/Agent 里用 dataclass 保存结构化输入输出。
今日强化题(带具体代码)
强化题 1:复现 dataclass 流程
任务:运行下面代码。
验收:生成 outputs/day015/dataclass_records.json。
强化题 2:替换输入
任务:新增一条 raw dict,并添加 tags。
强化题 3:边界检查
任务:把 value 改成无法转成数字的字符串。
强化题 4:总结
任务:写 3 句话说明普通 class 和 dataclass 的区别。
参考代码:main.py
from dataclasses import dataclass, field, asdict
from pathlib import Path
import json
DAY = 15
OUT = Path(__file__).resolve().parent / "outputs" / f"day{DAY:03d}"
@dataclass
class Record:
name: str
value: float
group: str = "default"
tags: list[str] = field(default_factory=list)
@classmethod
def from_dict(cls, data):
if not data.get("name"):
raise ValueError("name is required")
try:
value = float(data.get("value"))
except (TypeError, ValueError):
raise ValueError("value must be numeric")
tags = data.get("tags", [])
if not isinstance(tags, list):
raise ValueError("tags must be list")
return cls(
name=data["name"],
value=value,
group=data.get("group", "default"),
tags=tags,
)
def is_high_value(self, threshold):
return self.value >= threshold
def to_dict(self, threshold):
output = asdict(self)
output["high_value"] = self.is_high_value(threshold)
return output
def build_records(raw_items):
records = []
errors = []
for index, item in enumerate(raw_items):
try:
records.append(Record.from_dict(item))
except ValueError as exc:
errors.append({"index": index, "item": item, "error": str(exc)})
return records, errors
def main():
OUT.mkdir(parents=True, exist_ok=True)
raw_items = [
{"name": "item_a", "value": "10", "group": "A", "tags": ["clean"]},
{"name": "item_b", "value": 18, "group": "A", "tags": ["important"]},
{"name": "item_c", "value": "bad", "group": "B"},
]
records, errors = build_records(raw_items)
values = [record.value for record in records]
threshold = sum(values) / len(values)
payload = {
"topic": "dataclass and typed object boundary",
"threshold": threshold,
"items": [record.to_dict(threshold) for record in records],
"errors": errors,
}
(OUT / "dataclass_records.json").write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(payload, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
今日复盘模板
Day15:class 正规化与 dataclass
dataclass 解决什么重复:
类型标注能做什么、不能做什么:
from_dict 的作用:
to_dict 的作用:
基础 Python 到这里结束,我最稳的 5 个能力:
Day16 - NumPy 数组基础
> 阶段三:数据分析三大库
学习定位
今天开始数据分析库。第一站是 NumPy:它把 Python list 升级成可以高速计算的数组。
认知地图
| 工具 | 输入 | 输出 | 用途 |
|---|
np.array() | list | ndarray | 创建数组 |
.shape | ndarray | 维度 | 看行列结构 |
.dtype | ndarray | 数据类型 | 看数字类型 |
.sum() / .mean() | ndarray | 数值 | 汇总 |
| 切片 | ndarray | 子数组 | 取部分数据 |
What
NumPy 数组不是普通 list。list 更像容器,NumPy array 更像数学对象。
import numpy as np
arr = np.array([1, 2, 3])
print(arr + 10) # [11 12 13]
list 不能这样直接做向量计算。
Why
数据分析、机器学习、深度学习和量化都离不开矩阵和向量。NumPy 是这些库的底层基础。
你先要掌握三件事:
1. 数组长什么样:.shape。
2. 数组里面是什么类型:.dtype。
3. 数组如何整体计算:向量化。
How:list -> array -> 计算
Python list
↓
np.array
↓
ndarray
↓
shape / dtype / slicing
↓
sum / mean / min / max
参数拆解方法
np.array(data, dtype=float)
| 参数 | 含义 | 注意 |
|---|
data | list 或嵌套 list | 每一行长度最好一致 |
dtype | 数组元素类型 | 数据分析常用 float |
| 返回值 | ndarray | 后续可做向量计算 |
Common Errors
| 错误 | 表现 | 修法 |
|---|
| 行长度不一致 | 创建 object 数组或报错 | 保证二维数据列数一致 |
| 字符串混入数字 | dtype 变成字符串 | 先清洗再转换 |
| 轴理解错 | 汇总方向错 | axis=0 按列,axis=1 按行 |
今日强化题(带具体代码)
强化题 1:创建一维和二维数组
验收:输出 shape、dtype、列均值。
强化题 2:替换输入
任务:新增一行二维数据。
强化题 3:边界检查
任务:尝试加入字符串,解释为什么要先清洗。
参考代码:main.py
from pathlib import Path
import json
import numpy as np
DAY = 16
OUT = Path(__file__).resolve().parent / "outputs" / f"day{DAY:03d}"
def describe_array(matrix):
arr = np.array(matrix, dtype=float)
return {
"shape": list(arr.shape),
"dtype": str(arr.dtype),
"column_sum": arr.sum(axis=0).round(4).tolist(),
"column_mean": arr.mean(axis=0).round(4).tolist(),
"first_row": arr[0].tolist(),
}
def main():
OUT.mkdir(parents=True, exist_ok=True)
matrix = [
[10, 1.2, 0],
[12, 1.5, 1],
[9, 1.1, 0],
[15, 1.8, 1],
]
payload = {"topic": "numpy array basics", "summary": describe_array(matrix)}
(OUT / "numpy_array_summary.json").write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(payload, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
今日复盘模板
Day16:NumPy 数组基础
ndarray 和 list 的区别:
shape 表示什么:
dtype 表示什么:
axis=0 和 axis=1 的区别:
Day17 - NumPy 向量化与统计
> 阶段三:数据分析三大库
学习定位
今天学习 NumPy 的核心价值:不用手写循环,对整列数据一次性计算。
认知地图
| 工具 | 输入 | 输出 | 用途 |
|---|
| 向量化 | array | array | 批量计算 |
| 布尔掩码 | 条件 | True/False 数组 | 筛选 |
np.where | 条件和两个值 | array | 条件分支 |
mean/std/quantile | array | 统计量 | 数据体检 |
What
向量化就是把“一个一个算”改成“一整列一起算”。
import numpy as np
prices = np.array([100, 102, 101, 105], dtype=float)
returns = prices[1:] / prices[:-1] - 1
print(returns)
这行代码一次性计算所有相邻收益率。
Why
数据分析和 Quant 中,循环容易慢,也容易写错边界。NumPy 用数组运算表达数学关系,更接近统计学和线性代数。
How:价格 -> 收益率 -> 风险指标
prices
↓
vectorized return
↓
mean / std / drawdown
↓
summary
参数拆解方法
np.where(condition, x, y)
| 参数 | 含义 |
|---|
condition | True/False 数组 |
x | 条件为 True 时取的值 |
y | 条件为 False 时取的值 |
Common Errors
| 错误 | 表现 | 修法 |
|---|
| 数组长度没对齐 | shape mismatch | 检查切片长度 |
| 除以 0 | inf 或 nan | 先检查分母 |
| std 样本口径混乱 | 结果略不同 | 明确 ddof=0/1 |
今日强化题(带具体代码)
强化题 1:计算收益率
验收:生成 numpy_vector_stats.json。
强化题 2:添加阈值标签
任务:修改 risk_threshold。
参考代码:main.py
from pathlib import Path
import json
import numpy as np
DAY = 17
OUT = Path(__file__).resolve().parent / "outputs" / f"day{DAY:03d}"
def analyze_prices(prices, risk_threshold=0.03):
arr = np.array(prices, dtype=float)
returns = arr[1:] / arr[:-1] - 1
labels = np.where(np.abs(returns) >= risk_threshold, "large_move", "normal")
cumulative_max = np.maximum.accumulate(arr)
drawdown = arr / cumulative_max - 1
return {
"prices": arr.round(4).tolist(),
"returns": returns.round(6).tolist(),
"labels": labels.tolist(),
"mean_return": round(float(returns.mean()), 6),
"volatility": round(float(returns.std(ddof=1)), 6),
"max_drawdown": round(float(drawdown.min()), 6),
}
def main():
OUT.mkdir(parents=True, exist_ok=True)
prices = [100, 102, 101, 107, 103, 110]
payload = {"topic": "numpy vectorization and statistics", "summary": analyze_prices(prices)}
(OUT / "numpy_vector_stats.json").write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(payload, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
今日复盘模板
Day17:NumPy 向量化与统计
向量化解决什么问题:
布尔掩码是什么:
np.where 怎么理解:
收益率数组为什么比价格数组少一位:
Day18 - pandas DataFrame 基础
> 阶段三:数据分析三大库
学习定位
今天学习 pandas 的核心对象:DataFrame 是带行列标签的表格。
认知地图
| 工具 | 输入 | 输出 | 用途 |
|---|
pd.DataFrame() | dict/list | DataFrame | 创建表 |
.head() | DataFrame | 前几行 | 看样例 |
.shape | DataFrame | 行列数 | 看规模 |
.dtypes | DataFrame | 每列类型 | 看类型 |
.describe() | 数值列 | 统计摘要 | 快速体检 |
What
pandas DataFrame 可以理解成“有字段名、有行索引的二维表”。
它比 list/dict 更适合做筛选、清洗、分组、聚合、导出。
Why
CSV/JSON 负责保存数据,pandas 负责分析表格数据。
数据分析第一步不是建模,而是体检:
1. 有多少行列?
2. 字段名是什么?
3. 每列类型是什么?
4. 有没有缺失值?
5. 前几行长什么样?
How:dict -> DataFrame -> 体检
records
↓
pd.DataFrame
↓
head / shape / dtypes / describe
↓
summary json
Common Errors
| 错误 | 表现 | 修法 |
|---|
| 数字列读成 object | 不能正常计算 | pd.to_numeric |
| 缺失值没看 | 后续统计偏差 | .isna().sum() |
| 只看 head | 忽略类型和规模 | 固定做五项体检 |
今日强化题(带具体代码)
强化题 1:创建 DataFrame 并体检
验收:生成 pandas_dataframe_profile.json。
参考代码:main.py
from pathlib import Path
import json
import pandas as pd
DAY = 18
OUT = Path(__file__).resolve().parent / "outputs" / f"day{DAY:03d}"
def profile_dataframe(df):
numeric_df = df.select_dtypes(include="number")
return {
"shape": list(df.shape),
"columns": list(df.columns),
"dtypes": {column: str(dtype) for column, dtype in df.dtypes.items()},
"missing": df.isna().sum().to_dict(),
"numeric_summary": numeric_df.describe().round(4).to_dict(),
"head": df.head(3).to_dict(orient="records"),
}
def main():
OUT.mkdir(parents=True, exist_ok=True)
rows = [
{"date": "2026-01-01", "group": "A", "value": 10.0, "flag": 1},
{"date": "2026-01-02", "group": "A", "value": 12.5, "flag": 0},
{"date": "2026-01-03", "group": "B", "value": None, "flag": 1},
{"date": "2026-01-04", "group": "B", "value": 9.5, "flag": 0},
]
df = pd.DataFrame(rows)
payload = {"topic": "pandas dataframe basics", "profile": profile_dataframe(df)}
(OUT / "pandas_dataframe_profile.json").write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(payload, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
今日复盘模板
Day18:pandas DataFrame 基础
DataFrame 是什么:
shape 看什么:
dtypes 看什么:
isna().sum() 看什么:
Day19 - pandas 清洗与筛选
> 阶段三:数据分析三大库
学习定位
今天学习 pandas 的第二步:把脏表格变成可分析表格。
认知地图
| 工具 | 输入 | 输出 | 用途 |
|---|
pd.to_numeric | 字符串列 | 数值列 | 类型转换 |
pd.to_datetime | 日期字符串 | datetime | 时间字段转换 |
.dropna() | DataFrame | 删除缺失后的表 | 去掉关键缺失 |
.fillna() | DataFrame | 填补后的表 | 填补非关键缺失 |
| 布尔筛选 | 条件 | 子表 | 过滤记录 |
What
清洗不是“让数据变漂亮”,而是让后续计算可信。
今天只做四件事:
1. 转日期。
2. 转数字。
3. 处理缺失值。
4. 按条件筛选。
Why
真实数据不会按你的想法出现。常见问题:
- 数字列里混入字符串。
- 日期列还是普通文本。
- 关键字段缺失。
- 异常值进入统计。
不清洗就直接分析,结果看起来能跑,实际不可信。
How:原始表 -> 清洗表
raw df
↓
copy
↓
to_datetime / to_numeric
↓
dropna / fillna
↓
boolean filter
↓
clean df
Common Errors
| 错误 | 表现 | 修法 |
|---|
| 直接改原表 | Debug 不好回退 | 先 df.copy() |
| 类型转换报错 | 无法转数字 | errors="coerce" |
| 过滤条件没括号 | 逻辑错误 | 每个条件加括号 |
| 缺失值全 drop | 样本损失太大 | 区分关键列和非关键列 |
今日强化题(带具体代码)
强化题 1:清洗一张脏表
验收:生成 pandas_cleaning_report.json 和 cleaned.csv。
参考代码:main.py
from pathlib import Path
import json
import pandas as pd
DAY = 19
OUT = Path(__file__).resolve().parent / "outputs" / f"day{DAY:03d}"
def clean_dataframe(df):
cleaned = df.copy()
cleaned["date"] = pd.to_datetime(cleaned["date"], errors="coerce")
cleaned["value"] = pd.to_numeric(cleaned["value"], errors="coerce")
before = len(cleaned)
cleaned = cleaned.dropna(subset=["date", "value"])
cleaned["group"] = cleaned["group"].fillna("unknown")
cleaned = cleaned[(cleaned["value"] >= 0) & (cleaned["value"] <= 100)]
return cleaned, {"before_rows": before, "after_rows": len(cleaned)}
def main():
OUT.mkdir(parents=True, exist_ok=True)
raw = pd.DataFrame([
{"date": "2026-01-01", "group": "A", "value": "10"},
{"date": "bad-date", "group": "A", "value": "12"},
{"date": "2026-01-03", "group": None, "value": "bad"},
{"date": "2026-01-04", "group": "B", "value": "9.5"},
{"date": "2026-01-05", "group": "B", "value": "999"},
])
cleaned, stats = clean_dataframe(raw)
cleaned.to_csv(OUT / "cleaned.csv", index=False)
report = {
"topic": "pandas cleaning and filtering",
"stats": stats,
"dtypes": {column: str(dtype) for column, dtype in cleaned.dtypes.items()},
"records": cleaned.to_dict(orient="records"),
}
(OUT / "pandas_cleaning_report.json").write_text(json.dumps(report, ensure_ascii=False, indent=2, default=str), encoding="utf-8")
print(json.dumps(report, ensure_ascii=False, indent=2, default=str))
if __name__ == "__main__":
main()
今日复盘模板
Day19:pandas 清洗与筛选
to_numeric 做什么:
to_datetime 做什么:
dropna 和 fillna 的区别:
布尔筛选最容易错在哪里:
Day20 - pandas 分组聚合
> 阶段三:数据分析三大库
学习定位
今天学习 pandas 的核心分析动作:按类别分组,再计算指标。
认知地图
| 工具 | 输入 | 输出 | 用途 |
|---|
groupby | 类别字段 | 分组对象 | 按组计算 |
.agg() | 多个指标 | 汇总表 | 一次算多列 |
.sort_values() | 表格 | 排序表 | 找高低 |
.reset_index() | 分组结果 | 普通表 | 方便保存 |
What
分组聚合就是回答:
每个组分别怎么样?
例如每个 group 的样本数、均值、最大值。
Why
数据分析不只看总体,还要比较分组。统计学里的分组均值、组间差异、样本量意识,在 pandas 里主要靠 groupby。
How:明细表 -> 指标表
clean df
↓
groupby("group")
↓
agg count mean max
↓
sort / save
Common Errors
| 错误 | 表现 | 修法 |
|---|
| 分组字段有缺失 | unknown 组消失 | 先 fillna |
| 样本量太小 | 均值不稳 | 同时看 count |
| agg 后多级列名复杂 | 保存不方便 | 手动改列名 |
今日强化题(带具体代码)
强化题 1:生成分组指标表
验收:生成 group_metrics.csv 和 group_metrics.json。
参考代码:main.py
from pathlib import Path
import json
import pandas as pd
DAY = 20
OUT = Path(__file__).resolve().parent / "outputs" / f"day{DAY:03d}"
def build_group_metrics(df):
grouped = (
df.groupby("group", dropna=False)
.agg(
n=("value", "count"),
mean_value=("value", "mean"),
max_value=("value", "max"),
min_value=("value", "min"),
)
.reset_index()
.sort_values("mean_value", ascending=False)
)
grouped["mean_value"] = grouped["mean_value"].round(4)
return grouped
def main():
OUT.mkdir(parents=True, exist_ok=True)
df = pd.DataFrame([
{"group": "A", "value": 10},
{"group": "A", "value": 12},
{"group": "A", "value": 15},
{"group": "B", "value": 8},
{"group": "B", "value": 11},
{"group": "C", "value": 20},
])
metrics = build_group_metrics(df)
metrics.to_csv(OUT / "group_metrics.csv", index=False)
payload = {
"topic": "pandas groupby aggregation",
"metrics": metrics.to_dict(orient="records"),
}
(OUT / "group_metrics.json").write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(payload, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
今日复盘模板
Day20:pandas 分组聚合
groupby 解决什么问题:
agg 的输入输出是什么:
为什么要同时看 n 和 mean:
reset_index 为什么常用:
Day21 - Matplotlib 基础图表
> 阶段三:数据分析三大库
学习定位
今天学习 Matplotlib:把数据变成可复查的图表文件。
本机环境如果 Matplotlib 暂时不可用,参考代码会自动降级保存文本报告,保证学习不中断。
认知地图
| 工具 | 输入 | 输出 | 用途 |
|---|
plt.subplots() | 画布参数 | fig, ax | 创建图 |
ax.plot() | x/y | 折线 | 趋势 |
ax.bar() | 类别/数值 | 柱状图 | 对比 |
fig.savefig() | 路径 | 图片文件 | 保存 |
What
Matplotlib 是 Python 最基础的绘图库。它关注三层:
figure 整张图
axis/ax 一个子图
plot/bar/scatter 图形元素
Why
数据分析不能只给表。图表能更快暴露趋势、异常、分组差异。
How:数据 -> 图表 -> 文件
x/y 数据
↓
fig, ax
↓
ax.plot / ax.bar
↓
title / labels
↓
savefig
Common Errors
| 错误 | 表现 | 修法 |
|---|
| 图只 show 不保存 | 结果不可复查 | 固定 savefig |
| 标签缺失 | 图看不懂 | 加 title/xlabel/ylabel |
| 环境依赖坏 | import 报错 | 先保存 fallback 报告 |
今日强化题(带具体代码)
强化题 1:保存一张趋势图
验收:环境正常时生成 PNG;环境异常时生成 fallback 文本。
参考代码:main.py
from pathlib import Path
import json
DAY = 21
OUT = Path(__file__).resolve().parent / "outputs" / f"day{DAY:03d}"
def save_line_plot(x, y, path):
try:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
except Exception as exc:
fallback = path.with_suffix(".txt")
fallback.write_text(f"matplotlib unavailable: {type(exc).__name__}: {exc}\\nx={x}\\ny={y}\\n", encoding="utf-8")
return {"ok": False, "fallback": str(fallback), "error": str(exc)}
fig, ax = plt.subplots(figsize=(6, 4))
ax.plot(x, y, marker="o")
ax.set_title("Value Trend")
ax.set_xlabel("step")
ax.set_ylabel("value")
ax.grid(True, alpha=0.3)
fig.tight_layout()
fig.savefig(path, dpi=150)
plt.close(fig)
return {"ok": True, "image": str(path)}
def main():
OUT.mkdir(parents=True, exist_ok=True)
x = [1, 2, 3, 4, 5]
y = [10, 12, 9, 15, 18]
result = save_line_plot(x, y, OUT / "line_plot.png")
payload = {"topic": "matplotlib basic line plot", "plot_result": result}
(OUT / "plot_report.json").write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(payload, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
今日复盘模板
Day21:Matplotlib 基础图表
figure 和 ax 是什么:
plot 的输入是什么:
为什么要保存图片:
我的环境是否能正常生成 PNG:
Day22 - Matplotlib 多图与保存
> 阶段三:数据分析三大库
学习定位
今天把 Matplotlib 从“一张图”升级到“多图布局”:同一份数据可以同时展示趋势和分布。
认知地图
| 工具 | 输入 | 输出 | 用途 |
|---|
plt.subplots(1, 2) | 行列数 | 多个 ax | 多图布局 |
ax.hist() | 一列数值 | 直方图 | 分布 |
ax.scatter() | x/y | 散点图 | 关系 |
fig.tight_layout() | figure | 调整布局 | 避免重叠 |
What
多图不是为了花哨,而是为了同时回答多个问题:
Why
单张图容易片面。数据分析里常见组合:
- 折线图看时间趋势。
- 直方图看分布。
- 柱状图看组间对比。
- 散点图看两个变量关系。
How:一份数据,多张图
DataFrame
↓
取列
↓
subplots
↓
plot / hist / scatter
↓
savefig
Common Errors
| 错误 | 表现 | 修法 |
|---|
| 多图标题重叠 | 图难看 | tight_layout() |
| x/y 长度不同 | 报错 | 先检查长度 |
| 图太小 | 字挤在一起 | 设置 figsize |
今日强化题(带具体代码)
强化题 1:保存一张双图
验收:生成 dashboard.png 或 fallback 文本。
参考代码:main.py
from pathlib import Path
import json
import pandas as pd
DAY = 22
OUT = Path(__file__).resolve().parent / "outputs" / f"day{DAY:03d}"
def save_dashboard(df, path):
try:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
except Exception as exc:
fallback = path.with_suffix(".txt")
fallback.write_text(
"matplotlib unavailable\\n"
f"error={type(exc).__name__}: {exc}\\n"
f"data={df.to_dict(orient='records')}\\n",
encoding="utf-8",
)
return {"ok": False, "fallback": str(fallback), "error": str(exc)}
fig, axes = plt.subplots(1, 2, figsize=(9, 4))
axes[0].plot(df["step"], df["value"], marker="o")
axes[0].set_title("Trend")
axes[0].set_xlabel("step")
axes[0].set_ylabel("value")
axes[1].hist(df["value"], bins=4)
axes[1].set_title("Distribution")
axes[1].set_xlabel("value")
axes[1].set_ylabel("count")
fig.tight_layout()
fig.savefig(path, dpi=150)
plt.close(fig)
return {"ok": True, "image": str(path)}
def main():
OUT.mkdir(parents=True, exist_ok=True)
df = pd.DataFrame({
"step": [1, 2, 3, 4, 5, 6],
"value": [10, 13, 9, 16, 14, 18],
})
result = save_dashboard(df, OUT / "dashboard.png")
payload = {
"topic": "matplotlib multi plot and savefig",
"rows": len(df),
"plot_result": result,
}
(OUT / "dashboard_report.json").write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(payload, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
今日复盘模板
Day22:Matplotlib 多图与保存
subplots 的输入输出:
hist 看什么:
plot 看什么:
tight_layout 的作用:
Day23 - NumPy / pandas / Matplotlib 综合
> 阶段三:数据分析三大库
学习定位
今天把三大库串起来:NumPy 做数值计算,pandas 做表格组织,Matplotlib 做图表输出。
认知地图
| 库 | 负责什么 | 输入 | 输出 |
|---|
| NumPy | 数组和指标 | list / array | 数值、数组 |
| pandas | 表格和分组 | records / DataFrame | 清洗表、指标表 |
| Matplotlib | 图表 | x/y 或 DataFrame 列 | PNG / fallback |
What
一个最小数据分析流程通常是:
原始 records
↓ pandas
清洗表格
↓ NumPy
计算指标
↓ pandas
形成指标表
↓ Matplotlib
保存图表
Why
三大库不是互相替代,而是分工:
- NumPy 更接近数学数组。
- pandas 更接近数据表。
- Matplotlib 更接近报告输出。
How:三库综合流水线
records -> DataFrame -> clean -> NumPy metrics -> report -> plot
Common Errors
| 错误 | 表现 | 修法 |
|---|
| 所有事都用 pandas | 数值逻辑不清 | 指标计算可拆到 NumPy |
| 所有事都用 NumPy | 字段名丢失 | 表格阶段用 pandas |
| 图不保存 | 无法复查 | 固定输出文件 |
今日强化题(带具体代码)
强化题 1:跑通三库综合
验收:生成 analysis_report.json、cleaned.csv、图表或 fallback。
参考代码:main.py
from pathlib import Path
import json
import numpy as np
import pandas as pd
DAY = 23
OUT = Path(__file__).resolve().parent / "outputs" / f"day{DAY:03d}"
def clean_data(records):
df = pd.DataFrame(records)
df["date"] = pd.to_datetime(df["date"], errors="coerce")
df["value"] = pd.to_numeric(df["value"], errors="coerce")
df = df.dropna(subset=["date", "value"]).copy()
df = df[df["value"] >= 0]
return df
def compute_metrics(df):
values = df["value"].to_numpy(dtype=float)
return {
"n": int(values.size),
"mean": round(float(np.mean(values)), 4),
"std": round(float(np.std(values, ddof=1)), 4) if values.size > 1 else 0.0,
"max": round(float(np.max(values)), 4),
"min": round(float(np.min(values)), 4),
}
def save_plot(df, path):
try:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
except Exception as exc:
fallback = path.with_suffix(".txt")
fallback.write_text(f"matplotlib unavailable: {type(exc).__name__}: {exc}\\n", encoding="utf-8")
return {"ok": False, "fallback": str(fallback), "error": str(exc)}
fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(df["date"], df["value"], marker="o")
ax.set_title("Cleaned Value Trend")
ax.set_xlabel("date")
ax.set_ylabel("value")
fig.autofmt_xdate()
fig.tight_layout()
fig.savefig(path, dpi=150)
plt.close(fig)
return {"ok": True, "image": str(path)}
def main():
OUT.mkdir(parents=True, exist_ok=True)
raw_records = [
{"date": "2026-01-01", "group": "A", "value": "10"},
{"date": "2026-01-02", "group": "A", "value": "12"},
{"date": "bad-date", "group": "B", "value": "11"},
{"date": "2026-01-04", "group": "B", "value": "-5"},
{"date": "2026-01-05", "group": "B", "value": "18"},
]
df = clean_data(raw_records)
metrics = compute_metrics(df)
group_metrics = df.groupby("group").agg(n=("value", "count"), mean_value=("value", "mean")).reset_index()
df.to_csv(OUT / "cleaned.csv", index=False)
plot_result = save_plot(df, OUT / "trend.png")
report = {
"topic": "numpy pandas matplotlib integrated workflow",
"metrics": metrics,
"group_metrics": group_metrics.round(4).to_dict(orient="records"),
"plot_result": plot_result,
}
(OUT / "analysis_report.json").write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(report, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
今日复盘模板
Day23:三库综合
NumPy 在流程里负责什么:
pandas 在流程里负责什么:
Matplotlib 在流程里负责什么:
今天的输入、处理、输出分别是什么:
Day24 - 缺失值、类型转换与清洗
> 阶段三:数据分析与本地数据系统
学习定位
把脏表变成可计算表。
今天的目标不是背定义,而是产出:一个 clean DataFrame。
前置知识
- 推荐前置:Day23 pandas 读取
- 上一站:Day23
- 下一站:Day25
今日知识地图
- to_datetime
- to_numeric
- dropna
- 数据质量记录
真实任务入口
今天先不从定义开始,而是先看问题:如何用「缺失值、类型转换与清洗」完成 一个 clean DataFrame?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
缺失值、类型转换与清洗 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「to_datetime、to_numeric、dropna」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 缺失值、类型转换与清洗,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day24 - 缺失值、类型转换与清洗
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day24_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):缺失值、类型转换与清洗 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day024_note(input_name, output_name, risk):
return {
"day": "Day24",
"topic": "缺失值、类型转换与清洗",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:缺失值、类型转换与清洗。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 缺失值、类型转换与清洗 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
- DataFrame
- 索引
- 字段类型
- 缺失值
- 聚合
- join
- 滚动窗口
- 向量化
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 先体检数据再分析。
- 清洗步骤要能复盘。
- 图表必须说明数据来源、时间范围和口径。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day024_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day24",
"topic": "缺失值、类型转换与清洗",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 clean DataFrame。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 Quant 指标和报表的输入层。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day024/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 缺失值、类型转换与清洗 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = '缺失值、类型转换与清洗'
DAY = 24
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day25 - 分组聚合与业务指标
> 阶段三:数据分析与本地数据系统
学习定位
按类别计算 count、mean、std。
今天的目标不是背定义,而是产出:一张 summary 表。
前置知识
- 推荐前置:Day24 清洗
- 上一站:Day24
- 下一站:Day26
今日知识地图
- groupby
- agg
- reset_index
- 排序
真实任务入口
今天先不从定义开始,而是先看问题:如何用「分组聚合与业务指标」完成 一张 summary 表?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
分组聚合与业务指标 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「groupby、agg、reset_index」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 分组聚合与业务指标,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day25 - 分组聚合与业务指标
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day25_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):分组聚合与业务指标 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day025_note(input_name, output_name, risk):
return {
"day": "Day25",
"topic": "分组聚合与业务指标",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:分组聚合与业务指标。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 分组聚合与业务指标 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
- DataFrame
- 索引
- 字段类型
- 缺失值
- 聚合
- join
- 滚动窗口
- 向量化
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 先体检数据再分析。
- 清洗步骤要能复盘。
- 图表必须说明数据来源、时间范围和口径。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day025_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day25",
"topic": "分组聚合与业务指标",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一张 summary 表。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 数据分析报表和 Quant 横截面统计。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day025/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 分组聚合与业务指标 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = '分组聚合与业务指标'
DAY = 25
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day26 - 表连接、映射与维表
> 阶段三:数据分析与本地数据系统
学习定位
把事实表和维度表连接起来。
今天的目标不是背定义,而是产出:一张带行业/标签的分析表。
前置知识
- 推荐前置:Day25 聚合
- 上一站:Day25
- 下一站:Day27
今日知识地图
真实任务入口
今天先不从定义开始,而是先看问题:如何用「表连接、映射与维表」完成 一张带行业/标签的分析表?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
表连接、映射与维表 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「merge、left join、维表」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 表连接、映射与维表,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day26 - 表连接、映射与维表
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day26_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):表连接、映射与维表 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day026_note(input_name, output_name, risk):
return {
"day": "Day26",
"topic": "表连接、映射与维表",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:表连接、映射与维表。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 表连接、映射与维表 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
- DataFrame
- 索引
- 字段类型
- 缺失值
- 聚合
- join
- 滚动窗口
- 向量化
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 先体检数据再分析。
- 清洗步骤要能复盘。
- 图表必须说明数据来源、时间范围和口径。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day026_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day26",
"topic": "表连接、映射与维表",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一张带行业/标签的分析表。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 金融行业分类、用户画像和业务维度。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day026/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 表连接、映射与维表 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 26
TOPIC = "表连接、映射与维表"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def join_orders_with_users(orders, users):
user_map = {user["user_id"]: user for user in users}
joined = []
unmatched = []
for order in orders:
user = user_map.get(order["user_id"])
if user is None:
unmatched.append(order)
continue
joined.append({**order, "city": user["city"], "segment": user["segment"]})
return joined, unmatched
def main():
orders = [{"order_id": "o1", "user_id": "u1", "amount": 120}, {"order_id": "o2", "user_id": "u3", "amount": 80}]
users = [{"user_id": "u1", "city": "Beijing", "segment": "new"}, {"user_id": "u2", "city": "Shanghai", "segment": "vip"}]
joined, unmatched = join_orders_with_users(orders, users)
report = {"topic": TOPIC, "joined": joined, "unmatched": unmatched}
path = write_json("join_dimension_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day27 - 时间序列、滚动窗口与移动平均
> 阶段三:数据分析与本地数据系统
学习定位
处理按时间排序的数据和 rolling 指标。
今天的目标不是背定义,而是产出:一张带移动平均的时间序列表。
前置知识
- 推荐前置:Day26 表连接
- 上一站:Day26
- 下一站:Day28
今日知识地图
真实任务入口
今天先不从定义开始,而是先看问题:如何用「时间序列、滚动窗口与移动平均」完成 一张带移动平均的时间序列表?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
时间序列、滚动窗口与移动平均 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「rolling、时间排序、移动平均」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 时间序列、滚动窗口与移动平均,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day27 - 时间序列、滚动窗口与移动平均
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day27_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):时间序列、滚动窗口与移动平均 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day027_note(input_name, output_name, risk):
return {
"day": "Day27",
"topic": "时间序列、滚动窗口与移动平均",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:时间序列、滚动窗口与移动平均。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 时间序列、滚动窗口与移动平均 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
- 日期解析
- 格式化
- 排序
- 时区
- 窗口
- 样本边界
- 未来数据泄漏
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 日期字符串先解析再排序。
- 时间序列处理要明确样本区间。
- Quant 回测里不能用未来数据计算今天信号。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day027_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day27",
"topic": "时间序列、滚动窗口与移动平均",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一张带移动平均的时间序列表。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 行情分析和监控趋势。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day027/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 时间序列、滚动窗口与移动平均 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 27
TOPIC = "时间序列、滚动窗口与移动平均"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def moving_average(values, window):
if window <= 0:
raise ValueError("window must be positive")
result = []
for end in range(window, len(values) + 1):
chunk = values[end - window:end]
result.append(round(sum(chunk) / window, 2))
return result
def main():
prices = [100, 102, 101, 105, 108, 107]
report = {"topic": TOPIC, "prices": prices, "ma3": moving_average(prices, 3)}
path = write_json("rolling_window_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day28 - NumPy 数组与向量化计算
> 阶段三:数据分析与本地数据系统
学习定位
用数组方式计算收益率和统计量。
今天的目标不是背定义,而是产出:一个向量化收益率计算。
前置知识
- 推荐前置:Day27 时间序列
- 上一站:Day27
- 下一站:Day29
今日知识地图
真实任务入口
今天先不从定义开始,而是先看问题:如何用「NumPy 数组与向量化计算」完成 一个向量化收益率计算?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
NumPy 数组与向量化计算 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「np.array、切片、向量化」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 NumPy 数组与向量化计算,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day28 - NumPy 数组与向量化计算
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day28_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):NumPy 数组与向量化计算 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day028_note(input_name, output_name, risk):
return {
"day": "Day28",
"topic": "NumPy 数组与向量化计算",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:NumPy 数组与向量化计算。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 NumPy 数组与向量化计算 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
- DataFrame
- 索引
- 字段类型
- 缺失值
- 聚合
- join
- 滚动窗口
- 向量化
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 先体检数据再分析。
- 清洗步骤要能复盘。
- 图表必须说明数据来源、时间范围和口径。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day028_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day28",
"topic": "NumPy 数组与向量化计算",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个向量化收益率计算。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 高效数值计算和机器学习前置。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day028/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 NumPy 数组与向量化计算 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = 'NumPy 数组与向量化计算'
DAY = 28
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day29 - 统计指标、样本量与置信思维
> 阶段三:数据分析与本地数据系统
学习定位
把均值、波动、标准误写成可解释函数。
今天的目标不是背定义,而是产出:一个统计 summary dict。
前置知识
- 推荐前置:Day28 NumPy
- 上一站:Day28
- 下一站:Day30
今日知识地图
- mean
- std
- standard error
- 样本量
真实任务入口
今天先不从定义开始,而是先看问题:如何用「统计指标、样本量与置信思维」完成 一个统计 summary dict?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
统计指标、样本量与置信思维 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「mean、std、standard error」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 统计指标、样本量与置信思维,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day29 - 统计指标、样本量与置信思维
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day29_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):统计指标、样本量与置信思维 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day029_note(input_name, output_name, risk):
return {
"day": "Day29",
"topic": "统计指标、样本量与置信思维",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:统计指标、样本量与置信思维。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 统计指标、样本量与置信思维 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
- DataFrame
- 索引
- 字段类型
- 缺失值
- 聚合
- join
- 滚动窗口
- 向量化
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 先体检数据再分析。
- 清洗步骤要能复盘。
- 图表必须说明数据来源、时间范围和口径。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day029_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day29",
"topic": "统计指标、样本量与置信思维",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个统计 summary dict。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 A/B 测试、Quant 和模型评估。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day029/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 统计指标、样本量与置信思维 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = '统计指标、样本量与置信思维'
DAY = 29
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day30 - 可视化与 Markdown 报告
> 阶段三:数据分析与本地数据系统
学习定位
保存图表和文字报告。
今天的目标不是背定义,而是产出:一张图和一份 report.md。
前置知识
- 推荐前置:Day29 统计指标
- 上一站:Day29
- 下一站:Day31
今日知识地图
- plot
- savefig
- Markdown
- 结论说明
真实任务入口
今天先不从定义开始,而是先看问题:如何用「可视化与 Markdown 报告」完成 一张图和一份 report.md?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
可视化与 Markdown 报告 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「plot、savefig、Markdown」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 可视化与 Markdown 报告,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day30 - 可视化与 Markdown 报告
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day30_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):可视化与 Markdown 报告 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day030_note(input_name, output_name, risk):
return {
"day": "Day30",
"topic": "可视化与 Markdown 报告",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:可视化与 Markdown 报告。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 可视化与 Markdown 报告 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
- DataFrame
- 索引
- 字段类型
- 缺失值
- 聚合
- join
- 滚动窗口
- 向量化
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 先体检数据再分析。
- 清洗步骤要能复盘。
- 图表必须说明数据来源、时间范围和口径。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day030_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day30",
"topic": "可视化与 Markdown 报告",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一张图和一份 report.md。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 数据报告、策略复盘和作品展示。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day030/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 可视化与 Markdown 报告 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = '可视化与 Markdown 报告'
DAY = 30
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day31 - SQLite 本地数据库
> 阶段三:数据分析与本地数据系统
学习定位
把结构化结果保存到轻量数据库。
今天的目标不是背定义,而是产出:一个 research.db。
前置知识
- 推荐前置:Day30 报告
- 上一站:Day30
- 下一站:Day32
今日知识地图
- sqlite3
- CREATE TABLE
- INSERT
- SELECT
真实任务入口
今天先不从定义开始,而是先看问题:如何用「SQLite 本地数据库」完成 一个 research.db?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
SQLite 本地数据库 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「sqlite3、CREATE TABLE、INSERT」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 SQLite 本地数据库,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day31 - SQLite 本地数据库
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day31_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):SQLite 本地数据库 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day031_note(input_name, output_name, risk):
return {
"day": "Day31",
"topic": "SQLite 本地数据库",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:SQLite 本地数据库。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 SQLite 本地数据库 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
- 表结构
- 主键
- 索引
- join
- 窗口函数
- 事务
- 查询复用
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 本地 SQLite 适合保存实验结果。
- 表名和字段名要稳定。
- 复杂查询先拆成可读步骤。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day031_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day31",
"topic": "SQLite 本地数据库",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 research.db。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 可查询结果仓库和 Agent 数据源。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day031/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 SQLite 本地数据库 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import sqlite3
import json
TOPIC = 'SQLite 本地数据库'
DAY = 31
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
DB = OUT / "learning.db"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def setup_db():
conn = sqlite3.connect(DB)
conn.execute("drop table if exists study_log")
conn.execute("create table study_log(day int, topic text, minutes int)")
conn.executemany(
"insert into study_log values (?, ?, ?)",
[(31, "sqlite", 40), (32, "sql join", 50), (33, "config", 20)],
)
conn.commit()
return conn
def query_summary(conn):
rows = conn.execute(
"select count(*) as n, sum(minutes) as total_minutes from study_log"
).fetchone()
top = conn.execute(
"select topic, minutes from study_log order by minutes desc limit 1"
).fetchone()
return {"topic": TOPIC, "rows": rows[0], "total_minutes": rows[1], "top_topic": top[0]}
def main():
ensure_dirs()
conn = setup_db()
summary = query_summary(conn)
conn.close()
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day32 - SQL 查询、Join 与窗口意识
> 阶段三:数据分析与本地数据系统
学习定位
用 SQL 回答分析问题。
今天的目标不是背定义,而是产出:一个聚合查询和一个 join 查询。
前置知识
- 推荐前置:Day31 SQLite
- 上一站:Day31
- 下一站:Day33
今日知识地图
- SELECT
- WHERE
- GROUP BY
- ORDER BY
- JOIN
真实任务入口
今天先不从定义开始,而是先看问题:如何用「SQL 查询、Join 与窗口意识」完成 一个聚合查询和一个 join 查询?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
SQL 查询、Join 与窗口意识 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「SELECT、WHERE、GROUP BY」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 SQL 查询、Join 与窗口意识,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day32 - SQL 查询、Join 与窗口意识
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day32_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):SQL 查询、Join 与窗口意识 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day032_note(input_name, output_name, risk):
return {
"day": "Day32",
"topic": "SQL 查询、Join 与窗口意识",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:SQL 查询、Join 与窗口意识。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 SQL 查询、Join 与窗口意识 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
- 表结构
- 主键
- 索引
- join
- 窗口函数
- 事务
- 查询复用
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 本地 SQLite 适合保存实验结果。
- 表名和字段名要稳定。
- 复杂查询先拆成可读步骤。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day032_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day32",
"topic": "SQL 查询、Join 与窗口意识",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个聚合查询和一个 join 查询。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 数据分析岗位和本地分析系统。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day032/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 SQL 查询、Join 与窗口意识 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import sqlite3
import json
TOPIC = 'SQL 查询、Join 与窗口意识'
DAY = 32
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
DB = OUT / "learning.db"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def setup_db():
conn = sqlite3.connect(DB)
conn.execute("drop table if exists study_log")
conn.execute("create table study_log(day int, topic text, minutes int)")
conn.executemany(
"insert into study_log values (?, ?, ?)",
[(31, "sqlite", 40), (32, "sql join", 50), (33, "config", 20)],
)
conn.commit()
return conn
def query_summary(conn):
rows = conn.execute(
"select count(*) as n, sum(minutes) as total_minutes from study_log"
).fetchone()
top = conn.execute(
"select topic, minutes from study_log order by minutes desc limit 1"
).fetchone()
return {"topic": TOPIC, "rows": rows[0], "total_minutes": rows[1], "top_topic": top[0]}
def main():
ensure_dirs()
conn = setup_db()
summary = query_summary(conn)
conn.close()
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day33 - 配置文件与环境变量
> 阶段三:数据分析与本地数据系统
学习定位
把路径、参数和模式从代码里拿出来。
今天的目标不是背定义,而是产出:一个 config.json 和环境变量读取。
前置知识
- 推荐前置:Day32 SQL
- 上一站:Day32
- 下一站:Day34
今日知识地图
- json config
- os.environ
- 默认值
- 配置隔离
真实任务入口
今天先不从定义开始,而是先看问题:如何用「配置文件与环境变量」完成 一个 config.json 和环境变量读取?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
配置文件与环境变量 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「json config、os.environ、默认值」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 配置文件与环境变量,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day33 - 配置文件与环境变量
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day33_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师喜欢用 Path 和明确的输入输出路径,是为了减少字符串拼接错误,并让脚本从 Mac 终端、主题根目录、定时任务里运行时更稳定。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):配置文件与环境变量 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day033_note(input_name, output_name, risk):
return {
"day": "Day33",
"topic": "配置文件与环境变量",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:配置文件与环境变量。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 配置文件与环境变量 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
- 类型提示
- 运行时校验
- 配置默认值
- 环境变量
- 路径配置
- 输入边界
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 类型标注不等于运行时检查。
- 公开主题不要把密钥写进配置文件。
- 配置应该让脚本换输入时不用改代码。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day033_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day33",
"topic": "配置文件与环境变量",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 config.json 和环境变量读取。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 开源主题的安全配置边界。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day033/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 配置文件与环境变量 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = '配置文件与环境变量'
DAY = 33
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day34 - 数据校验与错误报告
> 阶段三:数据分析与本地数据系统
学习定位
把字段、类型、行数检查写成函数。
今天的目标不是背定义,而是产出:一个 validate_data() 函数。
前置知识
- 推荐前置:Day33 配置
- 上一站:Day33
- 下一站:Day35
今日知识地图
- required fields
- error list
- fail fast
- 错误报告
真实任务入口
今天先不从定义开始,而是先看问题:如何用「数据校验与错误报告」完成 一个 validate_data() 函数?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
数据校验与错误报告 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「required fields、error list、fail fast」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 数据校验与错误报告,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day34 - 数据校验与错误报告
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day34_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):数据校验与错误报告 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day034_note(input_name, output_name, risk):
return {
"day": "Day34",
"topic": "数据校验与错误报告",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:数据校验与错误报告。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 数据校验与错误报告 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 不要只让代码跑通,要能解释输入输出。
- 每个小能力都要有失败场景。
- 结果要能被未来主题复用。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day034_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day34",
"topic": "数据校验与错误报告",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 validate_data() 函数。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 数据管道和 Agent tool 的防线。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day034/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 数据校验与错误报告 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = '数据校验与错误报告'
DAY = 34
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day35 - 本地指标管道原理
> 阶段三:数据分析与本地数据系统
学习定位
串联读取、清洗、聚合、报告。
今天的目标不是背定义,而是产出:一个本地可复现数据管道。
前置知识
- 推荐前置:Day21-Day34
- 上一站:Day34
- 下一站:Day36
今日知识地图
- pipeline
- validate
- summary
- report
真实任务入口
今天先不从定义开始,而是先看问题:如何用「本地指标管道原理」完成 一个本地可复现数据管道?
这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
本地指标管道原理 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「pipeline、validate、summary」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 本地指标管道原理,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:读取实验数据,检查字段、缺失值和样本量,生成 Markdown 记录。
- 数据分析场景:清洗业务数据,计算指标,保存 CSV、SQLite 或报告。
- Quant 场景:读取行情样例,计算收益率、移动平均、分组指标或风险统计。
- LLM/Agent 场景:把数据检查步骤封装成 tool,让 Agent 调用后返回结构化结果。
4. 怎么做(How)
先看场景流程,再看代码:
原始数据
↓
字段检查
↓
清洗/计算
↓
边界检查
↓
保存结果
↓
写分析说明
from pathlib import Path
# Day35 - 数据分析 阶段复盘-本地指标管道
raw_rows = [{"name": "sample", "value": 1}]
processed = []
for row in raw_rows:
if "value" not in row:
continue
processed.append({"name": row["name"], "value": row["value"]})
Path("outputs").mkdir(exist_ok=True)
Path("outputs/day35_result.txt").write_text(str(processed), encoding="utf-8")
print(processed)
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- 数据分析报告
- SQLite 本地数据系统
- Quant 指标管道
- Agent 数据检查工具
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:数据分析与本地数据系统。
解决什么问题(Problem):本地指标管道原理 的核心不是背概念,而是把原始数据变成可以检查、清洗、计算、保存和复盘的数据资产。
真实科研场景:整理实验数据、论文元数据和指标结果,让每一步处理都有输入、输出和检查记录。
数据分析场景:读取 CSV/Excel/SQLite 数据,完成字段检查、清洗、聚合、统计和报告输出。
Quant 场景:处理行情、收益率、指标和时间序列,形成后续回测或研究报告的基础数据层。
LLM/Agent 场景:为 LLM/RAG 提供干净、结构化、可引用的数据和本地知识材料。
def build_day035_note(input_name, output_name, risk):
return {
"day": "Day35",
"topic": "本地指标管道原理",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:本地指标管道原理。它不只是一个孤立知识点,而是服务于「数据分析与本地数据系统」阶段的一个小能力:把原始数据变成可以检查、保存、复盘的数据资产。
先按这条工程线理解:
读取数据 -> 检查字段 -> 清洗/计算 -> 保存结果 -> 写报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:字段名、数据类型、空值、重复、样例输出。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 本地指标管道原理 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:数据分析与本地数据系统。
阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。
本阶段反复出现的能力:
- 数据体检
- 类型转换
- 缺失值处理
- 聚合统计
- 时间窗口
- SQL 与本地数据库
2. 这个主题必须补齐的知识面
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 不要只让代码跑通,要能解释输入输出。
- 每个小能力都要有失败场景。
- 结果要能被未来主题复用。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day035_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day35",
"topic": "本地指标管道原理",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个本地可复现数据管道。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 进入 Web/API/LLM/Quant 主题的共同地基。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day035/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 本地指标管道原理 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 35
TOPIC = "本地指标管道原理"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def clean_numbers(raw_values):
clean = []
errors = []
for item in raw_values:
try:
clean.append(float(item))
except ValueError:
errors.append({"value": item, "reason": "not numeric"})
return clean, errors
def build_metrics(values):
return {"count": len(values), "mean": round(sum(values) / len(values), 2), "max": max(values)}
def main():
clean, errors = clean_numbers(["12", "18", "bad", "25"])
report = {"topic": TOPIC, "metrics": build_metrics(clean), "errors": errors}
path = write_json("local_metrics_pipeline.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day36 - 自动化文件整理与批处理
> 阶段四:应用接口、自动化与复盘
学习定位
批量处理文件并生成清单。
今天的目标不是背定义,而是产出:一个文件清单 CSV。
前置知识
- 推荐前置:Day35 数据管道
- 上一站:Day35
- 下一站:Day37
今日知识地图
- 批量处理文件并生成清单
- Path glob 扫描 files
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「自动化文件整理与批处理」完成 一个文件清单 CSV?
这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
自动化文件整理与批处理 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「批量处理文件并生成清单、Path glob 扫描 files、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 自动化文件整理与批处理,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把重复的文件整理、数据抓取或报告生成流程自动化。
- 数据分析场景:把本地分析脚本复盘成 API、看板或批处理工具。
- Quant 场景:定时获取数据、保存策略输入、输出可复查的研究文件。
- LLM/Agent 场景:把外部数据获取、失败重试和结果校验做成 Agent 可调用工具。
4. 怎么做(How)
先看场景流程,再看代码:
用户/系统输入
↓
调用核心函数
↓
处理失败
↓
输出 API/页面/文件
↓
写运行说明
# Day36 - 自动化文件整理与批处理
def run_job(config):
if not config.get("input"):
return {"ok": False, "error": "missing input"}
return {"ok": True, "result": f"processed {config['input']}"}
print(run_job({"input": "demo"}))
5. 工程设计思维(Design)
工程师喜欢用 Path 和明确的输入输出路径,是为了减少字符串拼接错误,并让脚本从 Mac 终端、主题根目录、定时任务里运行时更稳定。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- FastAPI 服务
- Streamlit 看板
- 自动化批处理
- Agent 外部工具调用
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:应用复盘与轻量工程。
解决什么问题(Problem):自动化文件整理与批处理 的核心不是背概念,而是把本地脚本整理成别人也能运行、检查和维护的小工具。
真实科研场景:把实验流程包装成批处理、API、看板或轻量容器,方便重复运行和分享。
数据分析场景:把数据处理流程复盘成 CLI、FastAPI、Streamlit、说明文档 或最小 CI。
Quant 场景:把策略研究工具封装成可运行应用,方便复盘参数、图表和结果。
LLM/Agent 场景:为 Agent 或数据助手提供 API、看板、文档和可部署的最小运行方式。
def build_day036_note(input_name, output_name, risk):
return {
"day": "Day36",
"topic": "自动化文件整理与批处理",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:自动化文件整理与批处理。它不只是一个孤立知识点,而是服务于「应用接口、自动化与复盘」阶段的一个小能力:把脚本变成可重复运行的小工具、API 或页面。
先按这条工程线理解:
输入参数 -> 调用函数 -> 处理失败 -> 输出页面/API/文件 -> 写运行说明
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:命令、参数、失败提示、输出位置、说明文档。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 自动化文件整理与批处理 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:应用复盘与轻量工程。
阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。
本阶段反复出现的能力:
- 批处理
- API 调用
- 重试与超时
- FastAPI
- Streamlit
- Docker/CI/说明文档
2. 这个主题必须补齐的知识面
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 不要只让代码跑通,要能解释输入输出。
- 每个小能力都要有失败场景。
- 结果要能被未来主题复用。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day036_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day36",
"topic": "自动化文件整理与批处理",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个文件清单 CSV。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 办公自动化和数据入库前处理。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day036/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 自动化文件整理与批处理 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 36
TOPIC = "自动化文件整理与批处理"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def plan_file_moves(files):
plan = []
for name in files:
suffix = Path(name).suffix.lstrip(".") or "unknown"
plan.append({"source": name, "target_folder": suffix, "target": f"organized/{suffix}/{Path(name).name}"})
return plan
def main():
plan = plan_file_moves(["raw/orders.csv", "raw/profile.json", "notes/debug.md"])
report = {"topic": TOPIC, "move_plan": plan}
path = write_json("file_batch_plan.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day37 - HTTP、API 与 JSON 数据获取
> 阶段四:应用接口、自动化与复盘
学习定位
请求 API 并解析 JSON。
今天的目标不是背定义,而是产出:一个安全的 API client 雏形。
前置知识
- 推荐前置:Day36 文件自动化
- 上一站:Day36
- 下一站:Day38
今日知识地图
- 请求 API 并解析 JSON
- urllib/request timeout JSON
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「HTTP、API 与 JSON 数据获取」完成 一个安全的 API client 雏形?
这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
HTTP、API 与 JSON 数据获取 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「请求 API 并解析 JSON、urllib/request timeout JSON、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 HTTP、API 与 JSON 数据获取,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把重复的文件整理、数据抓取或报告生成流程自动化。
- 数据分析场景:把本地分析脚本复盘成 API、看板或批处理工具。
- Quant 场景:定时获取数据、保存策略输入、输出可复查的研究文件。
- LLM/Agent 场景:把外部数据获取、失败重试和结果校验做成 Agent 可调用工具。
4. 怎么做(How)
先看场景流程,再看代码:
用户/系统输入
↓
调用核心函数
↓
处理失败
↓
输出 API/页面/文件
↓
写运行说明
# Day37 - HTTP、API 与 JSON 数据获取
def run_job(config):
if not config.get("input"):
return {"ok": False, "error": "missing input"}
return {"ok": True, "result": f"processed {config['input']}"}
print(run_job({"input": "demo"}))
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- FastAPI 服务
- Streamlit 看板
- 自动化批处理
- Agent 外部工具调用
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:应用复盘与轻量工程。
解决什么问题(Problem):HTTP、API 与 JSON 数据获取 的核心不是背概念,而是把本地脚本整理成别人也能运行、检查和维护的小工具。
真实科研场景:把实验流程包装成批处理、API、看板或轻量容器,方便重复运行和分享。
数据分析场景:把数据处理流程复盘成 CLI、FastAPI、Streamlit、说明文档 或最小 CI。
Quant 场景:把策略研究工具封装成可运行应用,方便复盘参数、图表和结果。
LLM/Agent 场景:为 Agent 或数据助手提供 API、看板、文档和可部署的最小运行方式。
def build_day037_note(input_name, output_name, risk):
return {
"day": "Day37",
"topic": "HTTP、API 与 JSON 数据获取",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:HTTP、API 与 JSON 数据获取。它不只是一个孤立知识点,而是服务于「应用接口、自动化与复盘」阶段的一个小能力:把脚本变成可重复运行的小工具、API 或页面。
先按这条工程线理解:
输入参数 -> 调用函数 -> 处理失败 -> 输出页面/API/文件 -> 写运行说明
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:命令、参数、失败提示、输出位置、说明文档。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 HTTP、API 与 JSON 数据获取 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:应用复盘与轻量工程。
阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。
本阶段反复出现的能力:
- 批处理
- API 调用
- 重试与超时
- FastAPI
- Streamlit
- Docker/CI/说明文档
2. 这个主题必须补齐的知识面
- 表格字段
- 嵌套结构
- 编码
- 类型转换
- 缺字段处理
- 读写模式
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- CSV 读出来通常都是字符串,要显式转换数字。
- JSON 结构不要嵌套过深,否则后续校验困难。
- 字段名要稳定,避免今天叫 price 明天叫 close。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day037_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day37",
"topic": "HTTP、API 与 JSON 数据获取",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个安全的 API client 雏形。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 行情、LLM、内部服务调用。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day037/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 HTTP、API 与 JSON 数据获取 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
TOPIC = 'HTTP、API 与 JSON 数据获取'
DAY = 37
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def build_payload():
return {
"topic": TOPIC,
"records": [
{"name": "csv", "status": "done", "score": 1},
{"name": "json", "status": "learning", "score": 0},
{"name": "debug", "status": "done", "score": 1},
],
}
def summarize(payload):
records = payload["records"]
done = [r for r in records if r["status"] == "done"]
return {
"topic": payload["topic"],
"total": len(records),
"done": len(done),
"done_names": [r["name"] for r in done],
}
def main():
ensure_dirs()
data_path = OUT / "payload.json"
data_path.write_text(json.dumps(build_payload(), ensure_ascii=False, indent=2), encoding="utf-8")
payload = json.loads(data_path.read_text(encoding="utf-8"))
summary = summarize(payload)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day38 - 可重试 Data Client 与失败处理
> 阶段四:应用接口、自动化与复盘
学习定位
给网络请求加超时、重试、错误返回。
今天的目标不是背定义,而是产出:一个 fetch_json() 客户端。
前置知识
- 推荐前置:Day37 API
- 上一站:Day37
- 下一站:Day39
今日知识地图
- 给网络请求加超时、重试、错误返回
- retry timeout error
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「可重试 Data Client 与失败处理」完成 一个 fetch_json() 客户端?
这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
可重试 Data Client 与失败处理 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「给网络请求加超时、重试、错误返回、retry timeout error、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 可重试 Data Client 与失败处理,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把重复的文件整理、数据抓取或报告生成流程自动化。
- 数据分析场景:把本地分析脚本复盘成 API、看板或批处理工具。
- Quant 场景:定时获取数据、保存策略输入、输出可复查的研究文件。
- LLM/Agent 场景:把外部数据获取、失败重试和结果校验做成 Agent 可调用工具。
4. 怎么做(How)
先看场景流程,再看代码:
用户/系统输入
↓
调用核心函数
↓
处理失败
↓
输出 API/页面/文件
↓
写运行说明
# Day38 - 可重试 Data Client 与失败处理
def run_job(config):
if not config.get("input"):
return {"ok": False, "error": "missing input"}
return {"ok": True, "result": f"processed {config['input']}"}
print(run_job({"input": "demo"}))
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- FastAPI 服务
- Streamlit 看板
- 自动化批处理
- Agent 外部工具调用
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:应用复盘与轻量工程。
解决什么问题(Problem):可重试 Data Client 与失败处理 的核心不是背概念,而是把本地脚本整理成别人也能运行、检查和维护的小工具。
真实科研场景:把实验流程包装成批处理、API、看板或轻量容器,方便重复运行和分享。
数据分析场景:把数据处理流程复盘成 CLI、FastAPI、Streamlit、说明文档 或最小 CI。
Quant 场景:把策略研究工具封装成可运行应用,方便复盘参数、图表和结果。
LLM/Agent 场景:为 Agent 或数据助手提供 API、看板、文档和可部署的最小运行方式。
def build_day038_note(input_name, output_name, risk):
return {
"day": "Day38",
"topic": "可重试 Data Client 与失败处理",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:可重试 Data Client 与失败处理。它不只是一个孤立知识点,而是服务于「应用接口、自动化与复盘」阶段的一个小能力:把脚本变成可重复运行的小工具、API 或页面。
先按这条工程线理解:
输入参数 -> 调用函数 -> 处理失败 -> 输出页面/API/文件 -> 写运行说明
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:命令、参数、失败提示、输出位置、说明文档。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 可重试 Data Client 与失败处理 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:应用复盘与轻量工程。
阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。
本阶段反复出现的能力:
- 批处理
- API 调用
- 重试与超时
- FastAPI
- Streamlit
- Docker/CI/说明文档
2. 这个主题必须补齐的知识面
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 不要只让代码跑通,要能解释输入输出。
- 每个小能力都要有失败场景。
- 结果要能被未来主题复用。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day038_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day38",
"topic": "可重试 Data Client 与失败处理",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 fetch_json() 客户端。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 稳定数据获取层。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day038/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 可重试 Data Client 与失败处理 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 38
TOPIC = "可重试 Data Client 与失败处理"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def request_with_retry(simulated_status, max_retry):
trace = []
for attempt, status in enumerate(simulated_status, start=1):
trace.append({"attempt": attempt, "status": status})
if status == "ok" or attempt > max_retry:
break
return {"success": trace[-1]["status"] == "ok", "trace": trace}
def main():
result = request_with_retry(["timeout", "timeout", "ok"], max_retry=3)
report = {"topic": TOPIC, **result}
path = write_json("retry_client_trace.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day39 - FastAPI 最小服务
> 阶段四:应用接口、自动化与复盘
学习定位
把函数暴露成 HTTP API。
今天的目标不是背定义,而是产出:一个 /health 和 /metrics 服务。
前置知识
- 推荐前置:Day38 client
- 上一站:Day38
- 下一站:Day40
今日知识地图
- 把函数暴露成 HTTP API
- FastAPI health GET
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「FastAPI 最小服务」完成 一个 /health 和 /metrics 服务?
这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
FastAPI 最小服务 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把函数暴露成 HTTP API、FastAPI health GET、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 FastAPI 最小服务,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把重复的文件整理、数据抓取或报告生成流程自动化。
- 数据分析场景:把本地分析脚本复盘成 API、看板或批处理工具。
- Quant 场景:定时获取数据、保存策略输入、输出可复查的研究文件。
- LLM/Agent 场景:把外部数据获取、失败重试和结果校验做成 Agent 可调用工具。
4. 怎么做(How)
先看场景流程,再看代码:
用户/系统输入
↓
调用核心函数
↓
处理失败
↓
输出 API/页面/文件
↓
写运行说明
# Day39 - FastAPI 最小服务
def run_job(config):
if not config.get("input"):
return {"ok": False, "error": "missing input"}
return {"ok": True, "result": f"processed {config['input']}"}
print(run_job({"input": "demo"}))
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- FastAPI 服务
- Streamlit 看板
- 自动化批处理
- Agent 外部工具调用
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:应用复盘与轻量工程。
解决什么问题(Problem):FastAPI 最小服务 的核心不是背概念,而是把本地脚本整理成别人也能运行、检查和维护的小工具。
真实科研场景:把实验流程包装成批处理、API、看板或轻量容器,方便重复运行和分享。
数据分析场景:把数据处理流程复盘成 CLI、FastAPI、Streamlit、说明文档 或最小 CI。
Quant 场景:把策略研究工具封装成可运行应用,方便复盘参数、图表和结果。
LLM/Agent 场景:为 Agent 或数据助手提供 API、看板、文档和可部署的最小运行方式。
def build_day039_note(input_name, output_name, risk):
return {
"day": "Day39",
"topic": "FastAPI 最小服务",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:FastAPI 最小服务。它不只是一个孤立知识点,而是服务于「应用接口、自动化与复盘」阶段的一个小能力:把脚本变成可重复运行的小工具、API 或页面。
先按这条工程线理解:
输入参数 -> 调用函数 -> 处理失败 -> 输出页面/API/文件 -> 写运行说明
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:命令、参数、失败提示、输出位置、说明文档。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 FastAPI 最小服务 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:应用复盘与轻量工程。
阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。
本阶段反复出现的能力:
- 批处理
- API 调用
- 重试与超时
- FastAPI
- Streamlit
- Docker/CI/说明文档
2. 这个主题必须补齐的知识面
- 请求方法
- 状态码
- 超时
- 重试
- 分页
- JSON 解析
- 错误处理
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 网络请求必须设置超时。
- 重试要有次数上限。
- API 返回不可信,进入业务逻辑前要校验。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day039_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day39",
"topic": "FastAPI 最小服务",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 /health 和 /metrics 服务。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 本地服务和 Agent tool HTTP 化。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day039/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 FastAPI 最小服务 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = 'FastAPI 最小服务'
DAY = 39
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day40 - Streamlit 数据看板
> 阶段四:应用接口、自动化与复盘
学习定位
把 CSV 和指标显示成页面。
今天的目标不是背定义,而是产出:一个上传 CSV 的本地看板。
前置知识
- 推荐前置:Day39 API
- 上一站:Day39
- 下一站:Day41
今日知识地图
- 把 CSV 和指标显示成页面
- Streamlit upload dataframe
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「Streamlit 数据看板」完成 一个上传 CSV 的本地看板?
这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
Streamlit 数据看板 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把 CSV 和指标显示成页面、Streamlit upload dataframe、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 Streamlit 数据看板,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把重复的文件整理、数据抓取或报告生成流程自动化。
- 数据分析场景:把本地分析脚本复盘成 API、看板或批处理工具。
- Quant 场景:定时获取数据、保存策略输入、输出可复查的研究文件。
- LLM/Agent 场景:把外部数据获取、失败重试和结果校验做成 Agent 可调用工具。
4. 怎么做(How)
先看场景流程,再看代码:
用户/系统输入
↓
调用核心函数
↓
处理失败
↓
输出 API/页面/文件
↓
写运行说明
# Day40 - Streamlit 数据看板
def run_job(config):
if not config.get("input"):
return {"ok": False, "error": "missing input"}
return {"ok": True, "result": f"processed {config['input']}"}
print(run_job({"input": "demo"}))
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- FastAPI 服务
- Streamlit 看板
- 自动化批处理
- Agent 外部工具调用
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:应用复盘与轻量工程。
解决什么问题(Problem):Streamlit 数据看板 的核心不是背概念,而是把本地脚本整理成别人也能运行、检查和维护的小工具。
真实科研场景:把实验流程包装成批处理、API、看板或轻量容器,方便重复运行和分享。
数据分析场景:把数据处理流程复盘成 CLI、FastAPI、Streamlit、说明文档 或最小 CI。
Quant 场景:把策略研究工具封装成可运行应用,方便复盘参数、图表和结果。
LLM/Agent 场景:为 Agent 或数据助手提供 API、看板、文档和可部署的最小运行方式。
def build_day040_note(input_name, output_name, risk):
return {
"day": "Day40",
"topic": "Streamlit 数据看板",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:Streamlit 数据看板。它不只是一个孤立知识点,而是服务于「应用接口、自动化与复盘」阶段的一个小能力:把脚本变成可重复运行的小工具、API 或页面。
先按这条工程线理解:
输入参数 -> 调用函数 -> 处理失败 -> 输出页面/API/文件 -> 写运行说明
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:命令、参数、失败提示、输出位置、说明文档。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 Streamlit 数据看板 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:应用复盘与轻量工程。
阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。
本阶段反复出现的能力:
- 批处理
- API 调用
- 重试与超时
- FastAPI
- Streamlit
- Docker/CI/说明文档
2. 这个主题必须补齐的知识面
- 页面状态
- 文件上传
- 缓存
- 表格展示
- 图表展示
- 交互控件
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 第一屏要能直接使用。
- 上传数据要做字段检查。
- 缓存会影响调试,必要时清理。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day040_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day40",
"topic": "Streamlit 数据看板",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个上传 CSV 的本地看板。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 作品展示和数据工具 UI。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day040/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Streamlit 数据看板 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = 'Streamlit 数据看板'
DAY = 40
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day41 - Docker 轻量运行说明
> 阶段四:应用接口、自动化与复盘
学习定位
用 Dockerfile 记录运行环境。
今天的目标不是背定义,而是产出:一个轻量 Dockerfile 和 runbook。
前置知识
- 推荐前置:Day40 看板
- 上一站:Day40
- 下一站:Day42
今日知识地图
- 用 Dockerfile 记录运行环境
- Dockerfile slim
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「Docker 轻量运行说明」完成 一个轻量 Dockerfile 和 runbook?
这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
Docker 轻量运行说明 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「用 Dockerfile 记录运行环境、Dockerfile slim、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 Docker 轻量运行说明,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把重复的文件整理、数据抓取或报告生成流程自动化。
- 数据分析场景:把本地分析脚本复盘成 API、看板或批处理工具。
- Quant 场景:定时获取数据、保存策略输入、输出可复查的研究文件。
- LLM/Agent 场景:把外部数据获取、失败重试和结果校验做成 Agent 可调用工具。
4. 怎么做(How)
先看场景流程,再看代码:
用户/系统输入
↓
调用核心函数
↓
处理失败
↓
输出 API/页面/文件
↓
写运行说明
# Day41 - Docker 轻量运行说明
def run_job(config):
if not config.get("input"):
return {"ok": False, "error": "missing input"}
return {"ok": True, "result": f"processed {config['input']}"}
print(run_job({"input": "demo"}))
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- FastAPI 服务
- Streamlit 看板
- 自动化批处理
- Agent 外部工具调用
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:应用复盘与轻量工程。
解决什么问题(Problem):Docker 轻量运行说明 的核心不是背概念,而是把本地脚本整理成别人也能运行、检查和维护的小工具。
真实科研场景:把实验流程包装成批处理、API、看板或轻量容器,方便重复运行和分享。
数据分析场景:把数据处理流程复盘成 CLI、FastAPI、Streamlit、说明文档 或最小 CI。
Quant 场景:把策略研究工具封装成可运行应用,方便复盘参数、图表和结果。
LLM/Agent 场景:为 Agent 或数据助手提供 API、看板、文档和可部署的最小运行方式。
def build_day041_note(input_name, output_name, risk):
return {
"day": "Day41",
"topic": "Docker 轻量运行说明",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:Docker 轻量运行说明。它不只是一个孤立知识点,而是服务于「应用接口、自动化与复盘」阶段的一个小能力:把脚本变成可重复运行的小工具、API 或页面。
先按这条工程线理解:
输入参数 -> 调用函数 -> 处理失败 -> 输出页面/API/文件 -> 写运行说明
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:命令、参数、失败提示、输出位置、说明文档。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 Docker 轻量运行说明 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:应用复盘与轻量工程。
阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。
本阶段反复出现的能力:
- 批处理
- API 调用
- 重试与超时
- FastAPI
- Streamlit
- Docker/CI/说明文档
2. 这个主题必须补齐的知识面
- 运行环境
- CI
- src 布局
- 文档
- 示例
- 复盘清单
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 轻量 Docker 只解决复现,不追求复杂编排。
- CI 先跑 compile/test。
- 开源主题要有最小示例。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day041_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day41",
"topic": "Docker 轻量运行说明",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个轻量 Dockerfile 和 runbook。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 公开主题复现方式。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day041/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Docker 轻量运行说明 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 41
TOPIC = "Docker 轻量运行说明"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def build_runtime_contract(command, data_dir):
return {
"base_image": "python:3.11-slim",
"command": command,
"mounts": [data_dir],
"health_check": "python -m py_compile main.py",
}
def main():
contract = build_runtime_contract("python main.py", "./data")
report = {"topic": TOPIC, "runtime_contract": contract}
path = write_json("docker_runtime_contract.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day42 - 本地记录 Actions 最小 CI
> 阶段四:应用接口、自动化与复盘
学习定位
让 本地记录 自动运行测试。
今天的目标不是背定义,而是产出:一个 Python CI workflow。
前置知识
- 推荐前置:Day41 运行说明
- 上一站:Day41
- 下一站:Day43
今日知识地图
- 让 本地记录 自动运行测试
- yaml workflow pytest
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「本地记录 Actions 最小 CI」完成 一个 Python CI workflow?
这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
本地记录 Actions 最小 CI 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「让 本地记录 自动运行测试、yaml workflow pytest、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 本地记录 Actions 最小 CI,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把重复的文件整理、数据抓取或报告生成流程自动化。
- 数据分析场景:把本地分析脚本复盘成 API、看板或批处理工具。
- Quant 场景:定时获取数据、保存策略输入、输出可复查的研究文件。
- LLM/Agent 场景:把外部数据获取、失败重试和结果校验做成 Agent 可调用工具。
4. 怎么做(How)
先看场景流程,再看代码:
用户/系统输入
↓
调用核心函数
↓
处理失败
↓
输出 API/页面/文件
↓
写运行说明
# Day42 - 本地记录 Actions 最小 CI
def run_job(config):
if not config.get("input"):
return {"ok": False, "error": "missing input"}
return {"ok": True, "result": f"processed {config['input']}"}
print(run_job({"input": "demo"}))
5. 工程设计思维(Design)
工程师写测试,是为了让代码改动后还能确认旧功能没坏。测试不是为了形式,而是保护长期主题继续演化。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- FastAPI 服务
- Streamlit 看板
- 自动化批处理
- Agent 外部工具调用
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:应用复盘与轻量工程。
解决什么问题(Problem):本地记录 Actions 最小 CI 的核心不是背概念,而是把本地脚本整理成别人也能运行、检查和维护的小工具。
真实科研场景:把实验流程包装成批处理、API、看板或轻量容器,方便重复运行和分享。
数据分析场景:把数据处理流程复盘成 CLI、FastAPI、Streamlit、说明文档 或最小 CI。
Quant 场景:把策略研究工具封装成可运行应用,方便复盘参数、图表和结果。
LLM/Agent 场景:为 Agent 或数据助手提供 API、看板、文档和可部署的最小运行方式。
def build_day042_note(input_name, output_name, risk):
return {
"day": "Day42",
"topic": "本地记录 Actions 最小 CI",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:本地记录 Actions 最小 CI。它不只是一个孤立知识点,而是服务于「应用接口、自动化与复盘」阶段的一个小能力:把脚本变成可重复运行的小工具、API 或页面。
先按这条工程线理解:
输入参数 -> 调用函数 -> 处理失败 -> 输出页面/API/文件 -> 写运行说明
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:命令、参数、失败提示、输出位置、说明文档。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 本地记录 Actions 最小 CI 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:应用复盘与轻量工程。
阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。
本阶段反复出现的能力:
- 批处理
- API 调用
- 重试与超时
- FastAPI
- Streamlit
- Docker/CI/说明文档
2. 这个主题必须补齐的知识面
- 目录结构
- 说明文档
- requirements
- git status
- 提交粒度
- 忽略文件
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 模块边界只创建现在用得到的目录。
- 说明文档 要写运行命令和输入输出。
- 提交要小而清楚,不要混入无关改动。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day042_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day42",
"topic": "本地记录 Actions 最小 CI",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 Python CI workflow。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 开源主题质量保护。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day042/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 本地记录 Actions 最小 CI 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 42
TOPIC = "本地记录 Actions 最小 CI"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def summarize_checks(checks):
failed = [item["name"] for item in checks if not item["passed"]]
return {"passed": not failed, "failed": failed, "total": len(checks)}
def main():
checks = [{"name": "py_compile", "passed": True}, {"name": "build_docs", "passed": True}, {"name": "sample_run", "passed": False}]
report = {"topic": TOPIC, "ci": summarize_checks(checks)}
path = write_json("ci_check_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day43 - 模块打包与 src 布局
> 阶段四:应用接口、自动化与复盘
学习定位
把代码放进 src 并支持导入。
今天的目标不是背定义,而是产出:一个 src 包结构。
前置知识
- 推荐前置:Day42 CI
- 上一站:Day42
- 下一站:Day44
今日知识地图
- 把代码放进 src 并支持导入
- src layout
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「模块打包与 src 布局」完成 一个 src 包结构?
这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
模块打包与 src 布局 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把代码放进 src 并支持导入、src layout、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 模块打包与 src 布局,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把重复的文件整理、数据抓取或报告生成流程自动化。
- 数据分析场景:把本地分析脚本复盘成 API、看板或批处理工具。
- Quant 场景:定时获取数据、保存策略输入、输出可复查的研究文件。
- LLM/Agent 场景:把外部数据获取、失败重试和结果校验做成 Agent 可调用工具。
4. 怎么做(How)
先看场景流程,再看代码:
用户/系统输入
↓
调用核心函数
↓
处理失败
↓
输出 API/页面/文件
↓
写运行说明
# Day43 - 模块打包与 src 布局
def run_job(config):
if not config.get("input"):
return {"ok": False, "error": "missing input"}
return {"ok": True, "result": f"processed {config['input']}"}
print(run_job({"input": "demo"}))
5. 工程设计思维(Design)
工程师把逻辑拆成模块,是为了让核心函数可以被 CLI、测试、FastAPI、Streamlit 或 Agent tool 重复调用。入口保护 if __name__ == "__main__" 的设计,是为了避免 import 时自动执行主程序。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- FastAPI 服务
- Streamlit 看板
- 自动化批处理
- Agent 外部工具调用
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:应用复盘与轻量工程。
解决什么问题(Problem):模块打包与 src 布局 的核心不是背概念,而是把本地脚本整理成别人也能运行、检查和维护的小工具。
真实科研场景:把实验流程包装成批处理、API、看板或轻量容器,方便重复运行和分享。
数据分析场景:把数据处理流程复盘成 CLI、FastAPI、Streamlit、说明文档 或最小 CI。
Quant 场景:把策略研究工具封装成可运行应用,方便复盘参数、图表和结果。
LLM/Agent 场景:为 Agent 或数据助手提供 API、看板、文档和可部署的最小运行方式。
def build_day043_note(input_name, output_name, risk):
return {
"day": "Day43",
"topic": "模块打包与 src 布局",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:模块打包与 src 布局。它不只是一个孤立知识点,而是服务于「应用接口、自动化与复盘」阶段的一个小能力:把脚本变成可重复运行的小工具、API 或页面。
先按这条工程线理解:
输入参数 -> 调用函数 -> 处理失败 -> 输出页面/API/文件 -> 写运行说明
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:命令、参数、失败提示、输出位置、说明文档。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 模块打包与 src 布局 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:应用复盘与轻量工程。
阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。
本阶段反复出现的能力:
- 批处理
- API 调用
- 重试与超时
- FastAPI
- Streamlit
- Docker/CI/说明文档
2. 这个主题必须补齐的知识面
- 运行环境
- CI
- src 布局
- 文档
- 示例
- 复盘清单
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 轻量 Docker 只解决复现,不追求复杂编排。
- CI 先跑 compile/test。
- 开源主题要有最小示例。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day043_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day43",
"topic": "模块打包与 src 布局",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 src 包结构。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 长期维护和测试导入。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day043/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 模块打包与 src 布局 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 43
TOPIC = "模块打包与 src 布局"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def inspect_layout(paths):
return {
"src_files": [p for p in paths if p.startswith("src/")],
"tests": [p for p in paths if p.startswith("tests/")],
"has_init": "src/python100/__init__.py" in paths,
}
def main():
paths = ["src/python100/__init__.py", "src/python100/core.py", "tests/test_core.py", "README.md"]
report = {"topic": TOPIC, "layout": inspect_layout(paths)}
path = write_json("src_layout_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day44 - 开源 说明文档、示例与文档
> 阶段四:应用接口、自动化与复盘
学习定位
写别人能看懂的主题入口。
今天的目标不是背定义,而是产出:一个开源 说明文档 草稿。
前置知识
- 推荐前置:Day43 src 布局
- 上一站:Day43
- 下一站:Day45
今日知识地图
- 写别人能看懂的主题入口
- 说明文档 sections
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「开源 说明文档、示例与文档」完成 一个开源 说明文档 草稿?
这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
开源 说明文档、示例与文档 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「写别人能看懂的主题入口、说明文档 sections、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 开源 说明文档、示例与文档,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把重复的文件整理、数据抓取或报告生成流程自动化。
- 数据分析场景:把本地分析脚本复盘成 API、看板或批处理工具。
- Quant 场景:定时获取数据、保存策略输入、输出可复查的研究文件。
- LLM/Agent 场景:把外部数据获取、失败重试和结果校验做成 Agent 可调用工具。
4. 怎么做(How)
先看场景流程,再看代码:
用户/系统输入
↓
调用核心函数
↓
处理失败
↓
输出 API/页面/文件
↓
写运行说明
# Day44 - 开源 说明文档、示例与文档
def run_job(config):
if not config.get("input"):
return {"ok": False, "error": "missing input"}
return {"ok": True, "result": f"processed {config['input']}"}
print(run_job({"input": "demo"}))
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- FastAPI 服务
- Streamlit 看板
- 自动化批处理
- Agent 外部工具调用
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:应用复盘与轻量工程。
解决什么问题(Problem):开源 说明文档、示例与文档 的核心不是背概念,而是把本地脚本整理成别人也能运行、检查和维护的小工具。
真实科研场景:把实验流程包装成批处理、API、看板或轻量容器,方便重复运行和分享。
数据分析场景:把数据处理流程复盘成 CLI、FastAPI、Streamlit、说明文档 或最小 CI。
Quant 场景:把策略研究工具封装成可运行应用,方便复盘参数、图表和结果。
LLM/Agent 场景:为 Agent 或数据助手提供 API、看板、文档和可部署的最小运行方式。
def build_day044_note(input_name, output_name, risk):
return {
"day": "Day44",
"topic": "开源 说明文档、示例与文档",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:开源 说明文档、示例与文档。它不只是一个孤立知识点,而是服务于「应用接口、自动化与复盘」阶段的一个小能力:把脚本变成可重复运行的小工具、API 或页面。
先按这条工程线理解:
输入参数 -> 调用函数 -> 处理失败 -> 输出页面/API/文件 -> 写运行说明
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:命令、参数、失败提示、输出位置、说明文档。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 开源 说明文档、示例与文档 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:应用复盘与轻量工程。
阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。
本阶段反复出现的能力:
- 批处理
- API 调用
- 重试与超时
- FastAPI
- Streamlit
- Docker/CI/说明文档
2. 这个主题必须补齐的知识面
- 目录结构
- 说明文档
- requirements
- git status
- 提交粒度
- 忽略文件
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 模块边界只创建现在用得到的目录。
- 说明文档 要写运行命令和输入输出。
- 提交要小而清楚,不要混入无关改动。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day044_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day44",
"topic": "开源 说明文档、示例与文档",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个开源 说明文档 草稿。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 本地记录 主题展示。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day044/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 开源 说明文档、示例与文档 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 44
TOPIC = "开源 说明文档、示例与文档"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def review_readme(sections):
required = ["Purpose", "Run", "Inputs", "Outputs", "Status"]
missing = [name for name in required if name not in sections]
return {"ready": not missing, "missing": missing, "section_count": len(sections)}
def main():
report = {"topic": TOPIC, "readme_review": review_readme(["Purpose", "Run", "Inputs", "Status"])}
path = write_json("readme_quality_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day45 - CLI、API、页面与 CI 整合原理
> 阶段四:应用接口、自动化与复盘
学习定位
理解 CLI、API、页面、CI 的连接方式。
今天的目标不是背定义,而是产出:一个数据工具的最小原理闭环。
前置知识
- 推荐前置:Day36-Day44
- 上一站:Day44
- 下一站:Day46
今日知识地图
- 理解 CLI、API、页面、CI 的连接方式
- integration checklist
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「应用复盘 阶段复盘:Data Tool」完成 一个数据工具的最小原理闭环?
这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
应用复盘 阶段复盘:Data Tool 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「理解 CLI、API、页面、CI 的连接方式、integration checklist、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 应用复盘 阶段复盘:Data Tool,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把重复的文件整理、数据抓取或报告生成流程自动化。
- 数据分析场景:把本地分析脚本复盘成 API、看板或批处理工具。
- Quant 场景:定时获取数据、保存策略输入、输出可复查的研究文件。
- LLM/Agent 场景:把外部数据获取、失败重试和结果校验做成 Agent 可调用工具。
4. 怎么做(How)
先看场景流程,再看代码:
用户/系统输入
↓
调用核心函数
↓
处理失败
↓
输出 API/页面/文件
↓
写运行说明
# Day45 - 应用复盘 阶段复盘-Data Tool
def run_job(config):
if not config.get("input"):
return {"ok": False, "error": "missing input"}
return {"ok": True, "result": f"processed {config['input']}"}
print(run_job({"input": "demo"}))
5. 工程设计思维(Design)
工程师会多写一层函数、配置、输出文件或 说明文档,是为了让代码不只今天能跑,也能被明天的自己、未来的自己和未来主题继续使用。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- FastAPI 服务
- Streamlit 看板
- 自动化批处理
- Agent 外部工具调用
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:应用复盘与轻量工程。
解决什么问题(Problem):应用复盘 阶段复盘:Data Tool 的核心不是背概念,而是把本地脚本整理成别人也能运行、检查和维护的小工具。
真实科研场景:把实验流程包装成批处理、API、看板或轻量容器,方便重复运行和分享。
数据分析场景:把数据处理流程复盘成 CLI、FastAPI、Streamlit、说明文档 或最小 CI。
Quant 场景:把策略研究工具封装成可运行应用,方便复盘参数、图表和结果。
LLM/Agent 场景:为 Agent 或数据助手提供 API、看板、文档和可部署的最小运行方式。
def build_day045_note(input_name, output_name, risk):
return {
"day": "Day45",
"topic": "应用复盘 阶段复盘:Data Tool",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:应用复盘 阶段复盘:Data Tool。它不只是一个孤立知识点,而是服务于「应用接口、自动化与复盘」阶段的一个小能力:把脚本变成可重复运行的小工具、API 或页面。
先按这条工程线理解:
输入参数 -> 调用函数 -> 处理失败 -> 输出页面/API/文件 -> 写运行说明
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:命令、参数、失败提示、输出位置、说明文档。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 应用复盘 阶段复盘:Data Tool 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:应用复盘与轻量工程。
阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。
本阶段反复出现的能力:
- 批处理
- API 调用
- 重试与超时
- FastAPI
- Streamlit
- Docker/CI/说明文档
2. 这个主题必须补齐的知识面
- 运行环境
- CI
- src 布局
- 文档
- 示例
- 复盘清单
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 轻量 Docker 只解决复现,不追求复杂编排。
- CI 先跑 compile/test。
- 开源主题要有最小示例。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day045_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day45",
"topic": "应用复盘 阶段复盘:Data Tool",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个数据工具的最小原理闭环。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 进入 LLM/Agent/Quant 主题的应用层。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day045/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 CLI、API、页面与 CI 整合原理 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = 'CLI、API、页面与 CI 整合原理'
DAY = 45
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day46 - Prompt 模板与事实边界
> 阶段五:LLM / RAG / Agent 基础
学习定位
把 prompt 写成可复用模板。
今天的目标不是背定义,而是产出:一个 build_prompt() 函数。
前置知识
- 推荐前置:Day45 应用复盘
- 上一站:Day45
- 下一站:Day47
今日知识地图
- 把 prompt 写成可复用模板
- prompt template facts
- 输入输出边界
- 可复盘结果
LLM / Agent 库基础地图
今天先不直接写复杂模型调用。
先知道后面会反复遇到这些库:
| 库 | 解决什么问题 | 输入 | 输出 |
|---|
pydantic | 校验结构化输入输出 | dict / JSON | 带类型约束的对象 |
requests / httpx | 调用模型服务或外部 API | URL + 参数 | 响应数据 |
transformers | 使用 tokenizer、embedding 或生成模型 | 文本 / 模型名 | token、向量或文本 |
torch | 承接深度学习底层张量计算 | 数字、数组、Tensor | Tensor / 模型输出 |
这几类库对 Agent 的意义是:Prompt 只是入口,真正稳定的系统还需要结构化校验、API 调用、模型输入输出和运行日志。
真实任务入口
今天先不从定义开始,而是先看问题:如何用「Prompt 模板与事实边界」完成 一个 build_prompt() 函数?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
Prompt 模板与事实边界 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把 prompt 写成可复用模板、prompt template facts、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 Prompt 模板与事实边界,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day46 - Prompt 模板与事实边界
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师会多写输入契约、结构化输出和日志,是因为模型输出不稳定,Agent 执行链更需要可追踪、可审查、可恢复。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):Prompt 模板与事实边界 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day046_note(input_name, output_name, risk):
return {
"day": "Day46",
"topic": "Prompt 模板与事实边界",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:Prompt 模板与事实边界。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 Prompt 模板与事实边界 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
- 事实边界
- 结构化输出
- 评估集
- 向量检索
- 上下文打包
- 工具契约
- 人工审查
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 模型输出必须校验。
- RAG 回答要保留来源。
- Agent 高风险动作需要人工审查点。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day046_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day46",
"topic": "Prompt 模板与事实边界",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 build_prompt() 函数。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 LLM 报告助手。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day046/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Prompt 模板与事实边界 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
import re
TOPIC = 'Prompt 模板与事实边界'
DAY = 46
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
DOCS = [
{"id": "d1", "text": "Prompt 要写清任务、输入、输出和边界。"},
{"id": "d2", "text": "RAG 需要检索、上下文打包、引用和评估。"},
{"id": "d3", "text": "Agent 工具调用必须有 schema、日志和人工审查。"},
]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def tokenize(text):
return set(re.findall(r"[A-Za-z0-9_]+|[一-鿿]", text.lower()))
def retrieve(query, k=2):
q = tokenize(query)
scored = []
for doc in DOCS:
d = tokenize(doc["text"])
score = len(q & d) / len(q | d) if q and d else 0
scored.append({"id": doc["id"], "score": round(score, 4), "text": doc["text"]})
return sorted(scored, key=lambda x: x["score"], reverse=True)[:k]
def main():
ensure_dirs()
query = TOPIC
hits = retrieve(query)
result = {
"topic": TOPIC,
"query": query,
"hits": hits,
"answer": "先保留来源,再组织回答;没有来源就标记不确定。",
}
(OUT / "llm_agent_trace.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(result, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day47 - 结构化输出与 Schema 校验
> 阶段五:LLM / RAG / Agent 基础
学习定位
让模型输出可被程序检查。
今天的目标不是背定义,而是产出:一个 validate_output() 函数。
前置知识
- 推荐前置:Day46 prompt
- 上一站:Day46
- 下一站:Day48
今日知识地图
- 让模型输出可被程序检查
- schema required fields
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「结构化输出与 Schema 校验」完成 一个 validate_output() 函数?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
结构化输出与 Schema 校验 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「让模型输出可被程序检查、schema required fields、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 结构化输出与 Schema 校验,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day47 - 结构化输出与 Schema 校验
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师会多写输入契约、结构化输出和日志,是因为模型输出不稳定,Agent 执行链更需要可追踪、可审查、可恢复。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):结构化输出与 Schema 校验 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day047_note(input_name, output_name, risk):
return {
"day": "Day47",
"topic": "结构化输出与 Schema 校验",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:结构化输出与 Schema 校验。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 结构化输出与 Schema 校验 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
- 事实边界
- 结构化输出
- 评估集
- 向量检索
- 上下文打包
- 工具契约
- 人工审查
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 模型输出必须校验。
- RAG 回答要保留来源。
- Agent 高风险动作需要人工审查点。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day047_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day47",
"topic": "结构化输出与 Schema 校验",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 validate_output() 函数。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 LLM 到程序的边界。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day047/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 结构化输出与 Schema 校验 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
TOPIC = '结构化输出与 Schema 校验'
DAY = 47
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def build_payload():
return {
"topic": TOPIC,
"records": [
{"name": "csv", "status": "done", "score": 1},
{"name": "json", "status": "learning", "score": 0},
{"name": "debug", "status": "done", "score": 1},
],
}
def summarize(payload):
records = payload["records"]
done = [r for r in records if r["status"] == "done"]
return {
"topic": payload["topic"],
"total": len(records),
"done": len(done),
"done_names": [r["name"] for r in done],
}
def main():
ensure_dirs()
data_path = OUT / "payload.json"
data_path.write_text(json.dumps(build_payload(), ensure_ascii=False, indent=2), encoding="utf-8")
payload = json.loads(data_path.read_text(encoding="utf-8"))
summary = summarize(payload)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day48 - LLM 评估集与评分标准
> 阶段五:LLM / RAG / Agent 基础
学习定位
用固定样例评估 prompt/tool。
今天的目标不是背定义,而是产出:一个小型 eval set。
前置知识
- 推荐前置:Day47 schema
- 上一站:Day47
- 下一站:Day49
今日知识地图
- 用固定样例评估 prompt/tool
- eval cases rubric
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「LLM 评估集与评分标准」完成 一个小型 eval set?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
LLM 评估集与评分标准 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「用固定样例评估 prompt/tool、eval cases rubric、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 LLM 评估集与评分标准,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day48 - LLM 评估集与评分标准
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师会多写输入契约、结构化输出和日志,是因为模型输出不稳定,Agent 执行链更需要可追踪、可审查、可恢复。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):LLM 评估集与评分标准 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day048_note(input_name, output_name, risk):
return {
"day": "Day48",
"topic": "LLM 评估集与评分标准",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:LLM 评估集与评分标准。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 LLM 评估集与评分标准 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
- 事实边界
- 结构化输出
- 评估集
- 向量检索
- 上下文打包
- 工具契约
- 人工审查
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 模型输出必须校验。
- RAG 回答要保留来源。
- Agent 高风险动作需要人工审查点。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day048_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day48",
"topic": "LLM 评估集与评分标准",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个小型 eval set。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 提示词迭代和 Agent 评估。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day048/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 LLM 评估集与评分标准 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
import re
TOPIC = 'LLM 评估集与评分标准'
DAY = 48
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
DOCS = [
{"id": "d1", "text": "Prompt 要写清任务、输入、输出和边界。"},
{"id": "d2", "text": "RAG 需要检索、上下文打包、引用和评估。"},
{"id": "d3", "text": "Agent 工具调用必须有 schema、日志和人工审查。"},
]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def tokenize(text):
return set(re.findall(r"[A-Za-z0-9_]+|[一-鿿]", text.lower()))
def retrieve(query, k=2):
q = tokenize(query)
scored = []
for doc in DOCS:
d = tokenize(doc["text"])
score = len(q & d) / len(q | d) if q and d else 0
scored.append({"id": doc["id"], "score": round(score, 4), "text": doc["text"]})
return sorted(scored, key=lambda x: x["score"], reverse=True)[:k]
def main():
ensure_dirs()
query = TOPIC
hits = retrieve(query)
result = {
"topic": TOPIC,
"query": query,
"hits": hits,
"answer": "先保留来源,再组织回答;没有来源就标记不确定。",
}
(OUT / "llm_agent_trace.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(result, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day49 - Embedding 与余弦相似度
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Embedding 与余弦相似度 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day48
- 下一站:Day50
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Embedding 与余弦相似度 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
document | 原始文本 | 可检索材料 | RAG 的知识来源 |
chunk | 文本片段 | 索引单元 | 控制检索粒度 |
similarity | query 和 chunk | 相似度分数 | 决定引用哪段材料 |
citation | 来源编号 | 可追溯回答 | 防止没有来源的编造 |
What
Embedding 与余弦相似度 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
from math import sqrt
query = [1, 1, 0]
doc_a = [1, 0, 0]
doc_b = [1, 1, 1]
def cosine(left, right):
dot = sum(a * b for a, b in zip(left, right))
left_norm = sqrt(sum(a * a for a in left))
right_norm = sqrt(sum(b * b for b in right))
return round(dot / (left_norm * right_norm), 4)
print({"doc_a": cosine(query, doc_a), "doc_b": cosine(query, doc_b)})
参数拆解方法
第一次看到 Embedding 与余弦相似度 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Embedding 与余弦相似度 的最小输入对象 |
| 检索参数 | 它决定取哪些来源 | top_k 是返回片段数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先看来源是否足够。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day049/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Embedding 与余弦相似度 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 49
TOPIC = "Embedding 与余弦相似度"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
from math import sqrt
def cosine(left, right):
dot = sum(a * b for a, b in zip(left, right))
left_norm = sqrt(sum(a * a for a in left))
right_norm = sqrt(sum(b * b for b in right))
if left_norm == 0 or right_norm == 0:
return 0
return round(dot / (left_norm * right_norm), 4)
def main():
query = [1, 1, 0]
docs = {"csv_doc": [1, 0, 0], "json_doc": [1, 1, 1]}
scores = {name: cosine(query, vector) for name, vector in docs.items()}
report = {"topic": TOPIC, "scores": scores, "best_match": max(scores, key=scores.get)}
path = write_json("embedding_cosine_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day49:Embedding 与余弦相似度
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Embedding 与余弦相似度 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day50 - 本地笔记检索器
> 阶段五:LLM / RAG / Agent 基础
学习定位
从 Markdown 片段里找相关内容。
今天的目标不是背定义,而是产出:一个 top_k 检索函数。
前置知识
- 推荐前置:Day49 similarity
- 上一站:Day49
- 下一站:Day51
今日知识地图
- 从 Markdown 片段里找相关内容
- keyword retrieval
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「本地笔记检索器」完成 一个 top_k 检索函数?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
本地笔记检索器 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「从 Markdown 片段里找相关内容、keyword retrieval、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 本地笔记检索器,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day50 - 本地笔记检索器
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师会多写输入契约、结构化输出和日志,是因为模型输出不稳定,Agent 执行链更需要可追踪、可审查、可恢复。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):本地笔记检索器 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day050_note(input_name, output_name, risk):
return {
"day": "Day50",
"topic": "本地笔记检索器",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:本地笔记检索器。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 本地笔记检索器 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 不要只让代码跑通,要能解释输入输出。
- 每个小能力都要有失败场景。
- 结果要能被未来主题复用。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day050_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day50",
"topic": "本地笔记检索器",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 top_k 检索函数。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 个人知识库 RAG。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day050/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 本地笔记检索器 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
import re
TOPIC = '本地笔记检索器'
DAY = 50
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
DOCS = [
{"id": "d1", "text": "Prompt 要写清任务、输入、输出和边界。"},
{"id": "d2", "text": "RAG 需要检索、上下文打包、引用和评估。"},
{"id": "d3", "text": "Agent 工具调用必须有 schema、日志和人工审查。"},
]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def tokenize(text):
return set(re.findall(r"[A-Za-z0-9_]+|[一-鿿]", text.lower()))
def retrieve(query, k=2):
q = tokenize(query)
scored = []
for doc in DOCS:
d = tokenize(doc["text"])
score = len(q & d) / len(q | d) if q and d else 0
scored.append({"id": doc["id"], "score": round(score, 4), "text": doc["text"]})
return sorted(scored, key=lambda x: x["score"], reverse=True)[:k]
def main():
ensure_dirs()
query = TOPIC
hits = retrieve(query)
result = {
"topic": TOPIC,
"query": query,
"hits": hits,
"answer": "先保留来源,再组织回答;没有来源就标记不确定。",
}
(OUT / "llm_agent_trace.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(result, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day51 - RAG 上下文打包与引用
> 阶段五:LLM / RAG / Agent 基础
学习定位
把检索结果组织成回答上下文。
今天的目标不是背定义,而是产出:一个 context pack。
前置知识
- 推荐前置:Day50 retrieval
- 上一站:Day50
- 下一站:Day52
今日知识地图
- 把检索结果组织成回答上下文
- context citations
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「RAG 上下文打包与引用」完成 一个 context pack?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
RAG 上下文打包与引用 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把检索结果组织成回答上下文、context citations、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 RAG 上下文打包与引用,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day51 - RAG 上下文打包与引用
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师把逻辑拆成模块,是为了让核心函数可以被 CLI、测试、FastAPI、Streamlit 或 Agent tool 重复调用。入口保护 if __name__ == "__main__" 的设计,是为了避免 import 时自动执行主程序。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):RAG 上下文打包与引用 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day051_note(input_name, output_name, risk):
return {
"day": "Day51",
"topic": "RAG 上下文打包与引用",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:RAG 上下文打包与引用。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 RAG 上下文打包与引用 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
- 事实边界
- 结构化输出
- 评估集
- 向量检索
- 上下文打包
- 工具契约
- 人工审查
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 模型输出必须校验。
- RAG 回答要保留来源。
- Agent 高风险动作需要人工审查点。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day051_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day51",
"topic": "RAG 上下文打包与引用",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 context pack。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 有来源的 AI 回答。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day051/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 RAG 上下文打包与引用 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
import re
TOPIC = 'RAG 上下文打包与引用'
DAY = 51
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
DOCS = [
{"id": "d1", "text": "Prompt 要写清任务、输入、输出和边界。"},
{"id": "d2", "text": "RAG 需要检索、上下文打包、引用和评估。"},
{"id": "d3", "text": "Agent 工具调用必须有 schema、日志和人工审查。"},
]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def tokenize(text):
return set(re.findall(r"[A-Za-z0-9_]+|[一-鿿]", text.lower()))
def retrieve(query, k=2):
q = tokenize(query)
scored = []
for doc in DOCS:
d = tokenize(doc["text"])
score = len(q & d) / len(q | d) if q and d else 0
scored.append({"id": doc["id"], "score": round(score, 4), "text": doc["text"]})
return sorted(scored, key=lambda x: x["score"], reverse=True)[:k]
def main():
ensure_dirs()
query = TOPIC
hits = retrieve(query)
result = {
"topic": TOPIC,
"query": query,
"hits": hits,
"answer": "先保留来源,再组织回答;没有来源就标记不确定。",
}
(OUT / "llm_agent_trace.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(result, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day52 - 隐私脱敏与安全边界
> 阶段五:LLM / RAG / Agent 基础
学习定位
在公开仓库和 prompt 前脱敏。
今天的目标不是背定义,而是产出:一个 mask_text() 函数。
前置知识
- 推荐前置:Day51 context
- 上一站:Day51
- 下一站:Day53
今日知识地图
- 在公开仓库和 prompt 前脱敏
- regex masking
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「隐私脱敏与安全边界」完成 一个 mask_text() 函数?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
隐私脱敏与安全边界 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「在公开仓库和 prompt 前脱敏、regex masking、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 隐私脱敏与安全边界,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day52 - 隐私脱敏与安全边界
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师会多写输入契约、结构化输出和日志,是因为模型输出不稳定,Agent 执行链更需要可追踪、可审查、可恢复。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):隐私脱敏与安全边界 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day052_note(input_name, output_name, risk):
return {
"day": "Day52",
"topic": "隐私脱敏与安全边界",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:隐私脱敏与安全边界。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 隐私脱敏与安全边界 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
- 事实边界
- 结构化输出
- 评估集
- 向量检索
- 上下文打包
- 工具契约
- 人工审查
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 模型输出必须校验。
- RAG 回答要保留来源。
- Agent 高风险动作需要人工审查点。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day052_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day52",
"topic": "隐私脱敏与安全边界",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 mask_text() 函数。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 开源安全和 LLM 输入安全。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day052/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 隐私脱敏与安全边界 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 52
TOPIC = "隐私脱敏与安全边界"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def group_mean(records, key, value_key):
groups = {}
for row in records:
groups.setdefault(row[key], []).append(row[value_key])
return {name: round(sum(values) / len(values), 2) for name, values in groups.items()}
def main():
records = [{"channel": "app", "value": 12}, {"channel": "web", "value": 9}, {"channel": "app", "value": 18}]
report = {"topic": TOPIC, "group_mean": group_mean(records, "channel", "value")}
path = write_json("data_transform_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day53 - 缓存、成本与延迟控制
> 阶段五:LLM / RAG / Agent 基础
学习定位
减少重复请求和等待时间。
今天的目标不是背定义,而是产出:一个 dict cache。
前置知识
- 推荐前置:Day52 privacy
- 上一站:Day52
- 下一站:Day54
今日知识地图
- 减少重复请求和等待时间
- cache latency
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「缓存、成本与延迟控制」完成 一个 dict cache?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
缓存、成本与延迟控制 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「减少重复请求和等待时间、cache latency、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 缓存、成本与延迟控制,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day53 - 缓存、成本与延迟控制
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师会多写输入契约、结构化输出和日志,是因为模型输出不稳定,Agent 执行链更需要可追踪、可审查、可恢复。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):缓存、成本与延迟控制 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day053_note(input_name, output_name, risk):
return {
"day": "Day53",
"topic": "缓存、成本与延迟控制",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:缓存、成本与延迟控制。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 缓存、成本与延迟控制 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
- 事实边界
- 结构化输出
- 评估集
- 向量检索
- 上下文打包
- 工具契约
- 人工审查
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 模型输出必须校验。
- RAG 回答要保留来源。
- Agent 高风险动作需要人工审查点。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day053_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day53",
"topic": "缓存、成本与延迟控制",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 dict cache。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 LLM/API 成本控制。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day053/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 缓存、成本与延迟控制 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 53
TOPIC = "缓存、成本与延迟控制"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def group_mean(records, key, value_key):
groups = {}
for row in records:
groups.setdefault(row[key], []).append(row[value_key])
return {name: round(sum(values) / len(values), 2) for name, values in groups.items()}
def main():
records = [{"channel": "app", "value": 12}, {"channel": "web", "value": 9}, {"channel": "app", "value": 18}]
report = {"topic": TOPIC, "group_mean": group_mean(records, "channel", "value")}
path = write_json("data_transform_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day54 - Agent Tool 输入输出契约
> 阶段五:LLM / RAG / Agent 基础
学习定位
把函数设计成 Agent 可调用工具。
今天的目标不是背定义,而是产出:一个 ok/data/error 返回格式。
前置知识
- 推荐前置:Day53 cache
- 上一站:Day53
- 下一站:Day55
今日知识地图
- 把函数设计成 Agent 可调用工具
- tool contract
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「Agent Tool 输入输出契约」完成 一个 ok/data/error 返回格式?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
Agent Tool 输入输出契约 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把函数设计成 Agent 可调用工具、tool contract、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 Agent Tool 输入输出契约,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day54 - Agent Tool 输入输出契约
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师会多写输入契约、结构化输出和日志,是因为模型输出不稳定,Agent 执行链更需要可追踪、可审查、可恢复。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):Agent Tool 输入输出契约 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day054_note(input_name, output_name, risk):
return {
"day": "Day54",
"topic": "Agent Tool 输入输出契约",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:Agent Tool 输入输出契约。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 Agent Tool 输入输出契约 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
- 事实边界
- 结构化输出
- 评估集
- 向量检索
- 上下文打包
- 工具契约
- 人工审查
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 模型输出必须校验。
- RAG 回答要保留来源。
- Agent 高风险动作需要人工审查点。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day054_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day54",
"topic": "Agent Tool 输入输出契约",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 ok/data/error 返回格式。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 Agent 工具层。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day054/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Agent Tool 输入输出契约 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
import re
TOPIC = 'Agent Tool 输入输出契约'
DAY = 54
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
DOCS = [
{"id": "d1", "text": "Prompt 要写清任务、输入、输出和边界。"},
{"id": "d2", "text": "RAG 需要检索、上下文打包、引用和评估。"},
{"id": "d3", "text": "Agent 工具调用必须有 schema、日志和人工审查。"},
]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def tokenize(text):
return set(re.findall(r"[A-Za-z0-9_]+|[一-鿿]", text.lower()))
def retrieve(query, k=2):
q = tokenize(query)
scored = []
for doc in DOCS:
d = tokenize(doc["text"])
score = len(q & d) / len(q | d) if q and d else 0
scored.append({"id": doc["id"], "score": round(score, 4), "text": doc["text"]})
return sorted(scored, key=lambda x: x["score"], reverse=True)[:k]
def main():
ensure_dirs()
query = TOPIC
hits = retrieve(query)
result = {
"topic": TOPIC,
"query": query,
"hits": hits,
"answer": "先保留来源,再组织回答;没有来源就标记不确定。",
}
(OUT / "llm_agent_trace.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(result, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day55 - 工具路由与参数选择
> 阶段五:LLM / RAG / Agent 基础
学习定位
根据任务选择不同工具。
今天的目标不是背定义,而是产出:一个 route_tool() 函数。
前置知识
- 推荐前置:Day54 tool contract
- 上一站:Day54
- 下一站:Day56
今日知识地图
- 根据任务选择不同工具
- router
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「工具路由与参数选择」完成 一个 route_tool() 函数?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
工具路由与参数选择 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「根据任务选择不同工具、router、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 工具路由与参数选择,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day55 - 工具路由与参数选择
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师会多写输入契约、结构化输出和日志,是因为模型输出不稳定,Agent 执行链更需要可追踪、可审查、可恢复。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):工具路由与参数选择 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day055_note(input_name, output_name, risk):
return {
"day": "Day55",
"topic": "工具路由与参数选择",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:工具路由与参数选择。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 工具路由与参数选择 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 不要只让代码跑通,要能解释输入输出。
- 每个小能力都要有失败场景。
- 结果要能被未来主题复用。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day055_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day55",
"topic": "工具路由与参数选择",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 route_tool() 函数。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 多工具 Agent。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day055/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 工具路由与参数选择 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 55
TOPIC = "工具路由与参数选择"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_tool_call(call, schemas):
if call["tool"] not in schemas:
return {"ok": False, "reason": "unknown tool"}
required = schemas[call["tool"]]["required"]
missing = [name for name in required if name not in call["args"]]
return {"ok": not missing, "missing": missing}
def main():
schemas = {"search_notes": {"required": ["query"]}, "save_report": {"required": ["path", "content"]}}
call = {"tool": "search_notes", "args": {"query": "json"}}
review = validate_tool_call(call, schemas)
report = {"topic": TOPIC, "call": call, "review": review, "next_state": "execute" if review["ok"] else "revise"}
path = write_json("agent_tool_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day56 - Agent 计划-执行-观察循环
> 阶段五:LLM / RAG / Agent 基础
学习定位
用状态机理解 Agent 流程。
今天的目标不是背定义,而是产出:一个最小 agent loop。
前置知识
- 推荐前置:Day55 router
- 上一站:Day55
- 下一站:Day57
今日知识地图
- 用状态机理解 Agent 流程
- state loop
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「Agent 计划-执行-观察循环」完成 一个最小 agent loop?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
Agent 计划-执行-观察循环 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「用状态机理解 Agent 流程、state loop、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 Agent 计划-执行-观察循环,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day56 - Agent 计划-执行-观察循环
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师会多写输入契约、结构化输出和日志,是因为模型输出不稳定,Agent 执行链更需要可追踪、可审查、可恢复。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):Agent 计划-执行-观察循环 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day056_note(input_name, output_name, risk):
return {
"day": "Day56",
"topic": "Agent 计划-执行-观察循环",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:Agent 计划-执行-观察循环。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 Agent 计划-执行-观察循环 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
- 事实边界
- 结构化输出
- 评估集
- 向量检索
- 上下文打包
- 工具契约
- 人工审查
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 模型输出必须校验。
- RAG 回答要保留来源。
- Agent 高风险动作需要人工审查点。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day056_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day56",
"topic": "Agent 计划-执行-观察循环",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个最小 agent loop。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 Agent 编排。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day056/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Agent 计划-执行-观察循环 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
import re
TOPIC = 'Agent 计划-执行-观察循环'
DAY = 56
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
DOCS = [
{"id": "d1", "text": "Prompt 要写清任务、输入、输出和边界。"},
{"id": "d2", "text": "RAG 需要检索、上下文打包、引用和评估。"},
{"id": "d3", "text": "Agent 工具调用必须有 schema、日志和人工审查。"},
]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def tokenize(text):
return set(re.findall(r"[A-Za-z0-9_]+|[一-鿿]", text.lower()))
def retrieve(query, k=2):
q = tokenize(query)
scored = []
for doc in DOCS:
d = tokenize(doc["text"])
score = len(q & d) / len(q | d) if q and d else 0
scored.append({"id": doc["id"], "score": round(score, 4), "text": doc["text"]})
return sorted(scored, key=lambda x: x["score"], reverse=True)[:k]
def main():
ensure_dirs()
query = TOPIC
hits = retrieve(query)
result = {
"topic": TOPIC,
"query": query,
"hits": hits,
"answer": "先保留来源,再组织回答;没有来源就标记不确定。",
}
(OUT / "llm_agent_trace.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(result, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day57 - Human-in-the-Loop 审查点
> 阶段五:LLM / RAG / Agent 基础
学习定位
高风险步骤必须人工确认。
今天的目标不是背定义,而是产出:一个 risk gate。
前置知识
- 推荐前置:Day56 loop
- 上一站:Day56
- 下一站:Day58
今日知识地图
- 高风险步骤必须人工确认
- human review
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「Human-in-the-Loop 审查点」完成 一个 risk gate?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
Human-in-the-Loop 审查点 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「高风险步骤必须人工确认、human review、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 Human-in-the-Loop 审查点,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day57 - Human-in-the-Loop 审查点
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师会多写输入契约、结构化输出和日志,是因为模型输出不稳定,Agent 执行链更需要可追踪、可审查、可恢复。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):Human-in-the-Loop 审查点 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day057_note(input_name, output_name, risk):
return {
"day": "Day57",
"topic": "Human-in-the-Loop 审查点",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:Human-in-the-Loop 审查点。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 Human-in-the-Loop 审查点 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 不要只让代码跑通,要能解释输入输出。
- 每个小能力都要有失败场景。
- 结果要能被未来主题复用。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day057_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day57",
"topic": "Human-in-the-Loop 审查点",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 risk gate。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 安全 Agent。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day057/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Human-in-the-Loop 审查点 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
import re
TOPIC = 'Human-in-the-Loop 审查点'
DAY = 57
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
DOCS = [
{"id": "d1", "text": "Prompt 要写清任务、输入、输出和边界。"},
{"id": "d2", "text": "RAG 需要检索、上下文打包、引用和评估。"},
{"id": "d3", "text": "Agent 工具调用必须有 schema、日志和人工审查。"},
]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def tokenize(text):
return set(re.findall(r"[A-Za-z0-9_]+|[一-鿿]", text.lower()))
def retrieve(query, k=2):
q = tokenize(query)
scored = []
for doc in DOCS:
d = tokenize(doc["text"])
score = len(q & d) / len(q | d) if q and d else 0
scored.append({"id": doc["id"], "score": round(score, 4), "text": doc["text"]})
return sorted(scored, key=lambda x: x["score"], reverse=True)[:k]
def main():
ensure_dirs()
query = TOPIC
hits = retrieve(query)
result = {
"topic": TOPIC,
"query": query,
"hits": hits,
"answer": "先保留来源,再组织回答;没有来源就标记不确定。",
}
(OUT / "llm_agent_trace.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(result, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day58 - Agent 日志与可观测性
> 阶段五:LLM / RAG / Agent 基础
学习定位
记录每次工具调用和结果。
今天的目标不是背定义,而是产出:一个 run log。
前置知识
- 推荐前置:Day57 review
- 上一站:Day57
- 下一站:Day59
今日知识地图
- 记录每次工具调用和结果
- agent logging
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「Agent 日志与可观测性」完成 一个 run log?
这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
Agent 日志与可观测性 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「记录每次工具调用和结果、agent logging、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 Agent 日志与可观测性,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:把论文笔记、实验结论和引用来源组织成可检索材料。
- 数据分析场景:让模型输出结构化字段,并用规则检查是否可信。
- Quant 场景:让 LLM 辅助生成研究摘要,但保留数据来源和人工审查。
- LLM/Agent 场景:设计 tool schema、上下文打包、执行日志和人工审查点。
4. 怎么做(How)
先看场景流程,再看代码:
用户问题/本地资料
↓
准备上下文
↓
调用模型或工具
↓
校验结构化输出
↓
记录日志
↓
人工审查
# Day58 - Agent 日志与可观测性
def tool_contract(user_input):
if not user_input:
return {"ok": False, "error": "empty input"}
return {"ok": True, "answer": "结构化输出", "source": "local demo"}
print(tool_contract("demo question"))
5. 工程设计思维(Design)
工程师会多写输入契约、结构化输出和日志,是因为模型输出不稳定,Agent 执行链更需要可追踪、可审查、可恢复。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- LLM 报告助手
- RAG 知识库
- Agent tool / workflow
- 安全审查与日志系统
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:LLM / RAG / Agent 基础。
解决什么问题(Problem):Agent 日志与可观测性 的核心不是背概念,而是把模型调用从“聊天感觉”变成可验证、可评估、可记录的工程流程。
真实科研场景:用结构化上下文、引用、评估集和错误案例管理科研阅读与报告生成。
数据分析场景:把文本、指标和报告材料整理成可检索、可引用、可评估的数据流程。
Quant 场景:让 Quant 报告生成、解释和审查过程保留来源、事实边界和错误记录。
LLM/Agent 场景:定义 Prompt、Schema、工具契约、日志和人工审查点,让 Agent 行为更可控。
def build_day058_note(input_name, output_name, risk):
return {
"day": "Day58",
"topic": "Agent 日志与可观测性",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:Agent 日志与可观测性。它不只是一个孤立知识点,而是服务于「LLM / RAG / Agent 基础」阶段的一个小能力:把模型调用和 Agent 行为变成可验证的工程流程。
先按这条工程线理解:
输入问题 -> 准备上下文 -> 调用模型/工具 -> 校验输出 -> 记录日志
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:上下文来源、结构化输出、引用、评估、错误恢复。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 Agent 日志与可观测性 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:LLM / RAG / Agent 工程。
阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。
本阶段反复出现的能力:
- Prompt 模板
- Schema 校验
- 评估集
- Embedding
- RAG 引用
- Agent 工具契约
2. 这个主题必须补齐的知识面
- 事实边界
- 结构化输出
- 评估集
- 向量检索
- 上下文打包
- 工具契约
- 人工审查
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 模型输出必须校验。
- RAG 回答要保留来源。
- Agent 高风险动作需要人工审查点。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day058_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day58",
"topic": "Agent 日志与可观测性",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 run log。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 Agent Debug 和评估。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day058/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Agent 日志与可观测性 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
import re
TOPIC = 'Agent 日志与可观测性'
DAY = 58
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
DOCS = [
{"id": "d1", "text": "Prompt 要写清任务、输入、输出和边界。"},
{"id": "d2", "text": "RAG 需要检索、上下文打包、引用和评估。"},
{"id": "d3", "text": "Agent 工具调用必须有 schema、日志和人工审查。"},
]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def tokenize(text):
return set(re.findall(r"[A-Za-z0-9_]+|[一-鿿]", text.lower()))
def retrieve(query, k=2):
q = tokenize(query)
scored = []
for doc in DOCS:
d = tokenize(doc["text"])
score = len(q & d) / len(q | d) if q and d else 0
scored.append({"id": doc["id"], "score": round(score, 4), "text": doc["text"]})
return sorted(scored, key=lambda x: x["score"], reverse=True)[:k]
def main():
ensure_dirs()
query = TOPIC
hits = retrieve(query)
result = {
"topic": TOPIC,
"query": query,
"hits": hits,
"answer": "先保留来源,再组织回答;没有来源就标记不确定。",
}
(OUT / "llm_agent_trace.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(result, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day59 - LLM 结构化报告基础
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 LLM 结构化报告基础 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day58
- 下一站:Day60
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 LLM 结构化报告基础 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prompt | 任务说明 | 模型输入 | 控制回答边界 |
schema | 字段规则 | 结构化输出 | 让结果能被程序检查 |
eval_case | 样例问题 | 评分记录 | 判断改动是否真的变好 |
report | 输入、输出、风险 | 审查文本 | 降低幻觉和过度自信 |
What
LLM 结构化报告基础 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
answer = {
"summary": "JSON 适合保存嵌套结构",
"evidence": ["有字段名", "可嵌套", "能被程序解析"],
"risk": "不要把没有来源的判断写成事实",
}
required = ["summary", "evidence", "risk"]
missing = [field for field in required if field not in answer]
print({"valid_report": not missing, "missing": missing})
参数拆解方法
第一次看到 LLM 结构化报告基础 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | LLM 结构化报告基础 的最小输入对象 |
| 输出字段 | 模型必须返回什么结构 | summary 是一句话结论 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先检查字段是否缺失。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day059/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 LLM 结构化报告基础 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 59
TOPIC = "LLM 结构化报告基础"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_structured_answer(answer, required_fields):
missing = [field for field in required_fields if field not in answer]
extra = [field for field in answer if field not in required_fields]
return {"valid": not missing, "missing": missing, "extra": extra}
def main():
answer = {"what": "结构化输出", "why": "便于程序检查", "how": "先定义字段再生成"}
review = validate_structured_answer(answer, ["what", "why", "how"])
report = {"topic": TOPIC, "answer": answer, "review": review}
path = write_json("llm_structure_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day59:LLM 结构化报告基础
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
LLM 结构化报告基础 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day60 - LLM Agent 本地知识助手原理
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 LLM Agent 本地知识助手原理 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day59
- 下一站:Day61
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 LLM Agent 本地知识助手原理 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
tool schema | 工具名和参数 | 可校验调用 | 让 Agent 不乱传参 |
state | 当前任务状态 | 下一步动作 | 把多步任务串起来 |
observation | 工具执行结果 | 反馈信息 | 决定是否重试或停止 |
audit log | 每一步动作 | 审查记录 | 保留人工复盘入口 |
What
LLM Agent 本地知识助手原理 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
notes = {
"csv": "CSV 适合表格",
"json": "JSON 适合嵌套",
"class": "class 适合把数据和行为放在一起",
}
question = "json"
answer = notes.get(question, "没有找到对应笔记")
print({"question": question, "answer": answer, "source": question if question in notes else None})
参数拆解方法
第一次看到 LLM Agent 本地知识助手原理 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | LLM Agent 本地知识助手原理 的最小输入对象 |
| 工具参数 | Agent 调用工具时要传什么 | query 是检索词 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先做 schema 校验。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day060/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 LLM Agent 本地知识助手原理 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 60
TOPIC = "LLM Agent 本地知识助手原理"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_tool_call(call, schemas):
if call["tool"] not in schemas:
return {"ok": False, "reason": "unknown tool"}
required = schemas[call["tool"]]["required"]
missing = [name for name in required if name not in call["args"]]
return {"ok": not missing, "missing": missing}
def main():
schemas = {"search_notes": {"required": ["query"]}, "save_report": {"required": ["path", "content"]}}
call = {"tool": "search_notes", "args": {"query": "json"}}
review = validate_tool_call(call, schemas)
report = {"topic": TOPIC, "call": call, "review": review, "next_state": "execute" if review["ok"] else "revise"}
path = write_json("agent_tool_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day60:LLM Agent 本地知识助手原理
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
LLM Agent 本地知识助手原理 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day61 - 行情数据适配器
> 阶段六:Quant 研究与回测基础
学习定位
统一读取不同行情数据源。
今天的目标不是背定义,而是产出:一个 load_prices() 适配器。
前置知识
- 推荐前置:Day35 数据管道
- 上一站:Day60
- 下一站:Day62
今日知识地图
- 统一读取不同行情数据源
- market adapter
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「行情数据适配器」完成 一个 load_prices() 适配器?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
行情数据适配器 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「统一读取不同行情数据源、market adapter、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 行情数据适配器,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day61 - 行情数据适配器
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):行情数据适配器 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day061_note(input_name, output_name, risk):
return {
"day": "Day61",
"topic": "行情数据适配器",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:行情数据适配器。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 行情数据适配器 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 价格数据
- 收益率
- 波动率
- 回撤
- 信号
- 持仓
- 交易成本
- 风险预算
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 策略研究先保证数据口径。
- 回测要防未来函数。
- 报告要写清样本区间和风险假设。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day061_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day61",
"topic": "行情数据适配器",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 load_prices() 适配器。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 量化研究数据层。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day061/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 行情数据适配器 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from math import sqrt
TOPIC = '行情数据适配器'
DAY = 61
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
PRICES = [100, 101.2, 99.8, 103.5, 102.4, 106.0]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def returns(prices):
return [cur / prev - 1 for prev, cur in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
worst = 0
for price in prices:
peak = max(peak, price)
worst = min(worst, price / peak - 1)
return worst
def sharpe(rs):
avg = sum(rs) / len(rs)
var = sum((r - avg) ** 2 for r in rs) / len(rs)
vol = sqrt(var)
return 0 if vol == 0 else avg / vol * sqrt(252)
def main():
ensure_dirs()
rs = returns(PRICES)
summary = {
"topic": TOPIC,
"total_return": round(PRICES[-1] / PRICES[0] - 1, 4),
"max_drawdown": round(max_drawdown(PRICES), 4),
"sharpe": round(sharpe(rs), 4),
"risk_note": "这里只验证指标口径,不代表真实策略有效。",
}
(OUT / "quant_summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day62 - 收益率、波动率与最大回撤
> 阶段六:Quant 研究与回测基础
学习定位
计算最基础风险收益指标。
今天的目标不是背定义,而是产出:一个 metrics dict。
前置知识
- 推荐前置:Day61 adapter
- 上一站:Day61
- 下一站:Day63
今日知识地图
- 计算最基础风险收益指标
- returns metrics
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「收益率、波动率与最大回撤」完成 一个 metrics dict?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
收益率、波动率与最大回撤 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「计算最基础风险收益指标、returns metrics、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 收益率、波动率与最大回撤,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day62 - 收益率、波动率与最大回撤
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):收益率、波动率与最大回撤 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day062_note(input_name, output_name, risk):
return {
"day": "Day62",
"topic": "收益率、波动率与最大回撤",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:收益率、波动率与最大回撤。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 收益率、波动率与最大回撤 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 价格数据
- 收益率
- 波动率
- 回撤
- 信号
- 持仓
- 交易成本
- 风险预算
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 策略研究先保证数据口径。
- 回测要防未来函数。
- 报告要写清样本区间和风险假设。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day062_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day62",
"topic": "收益率、波动率与最大回撤",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 metrics dict。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 策略研究指标层。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day062/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 收益率、波动率与最大回撤 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from math import sqrt
TOPIC = '收益率、波动率与最大回撤'
DAY = 62
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
PRICES = [100, 101.2, 99.8, 103.5, 102.4, 106.0]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def returns(prices):
return [cur / prev - 1 for prev, cur in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
worst = 0
for price in prices:
peak = max(peak, price)
worst = min(worst, price / peak - 1)
return worst
def sharpe(rs):
avg = sum(rs) / len(rs)
var = sum((r - avg) ** 2 for r in rs) / len(rs)
vol = sqrt(var)
return 0 if vol == 0 else avg / vol * sqrt(252)
def main():
ensure_dirs()
rs = returns(PRICES)
summary = {
"topic": TOPIC,
"total_return": round(PRICES[-1] / PRICES[0] - 1, 4),
"max_drawdown": round(max_drawdown(PRICES), 4),
"sharpe": round(sharpe(rs), 4),
"risk_note": "这里只验证指标口径,不代表真实策略有效。",
}
(OUT / "quant_summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day63 - 交易信号与未来函数防护
> 阶段六:Quant 研究与回测基础
学习定位
用历史数据生成信号并 shift。
今天的目标不是背定义,而是产出:一个 signal/position 表。
前置知识
- 推荐前置:Day62 metrics
- 上一站:Day62
- 下一站:Day64
今日知识地图
- 用历史数据生成信号并 shift
- signal shift
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「交易信号与未来函数防护」完成 一个 signal/position 表?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
交易信号与未来函数防护 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「用历史数据生成信号并 shift、signal shift、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 交易信号与未来函数防护,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day63 - 交易信号与未来函数防护
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师写函数,是为了把一段稳定逻辑从脚本里抽出来。这样可以换输入、写测试、复用到主题里,而不是每次复制粘贴。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):交易信号与未来函数防护 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day063_note(input_name, output_name, risk):
return {
"day": "Day63",
"topic": "交易信号与未来函数防护",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:交易信号与未来函数防护。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 交易信号与未来函数防护 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 价格数据
- 收益率
- 波动率
- 回撤
- 信号
- 持仓
- 交易成本
- 风险预算
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 策略研究先保证数据口径。
- 回测要防未来函数。
- 报告要写清样本区间和风险假设。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day063_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day63",
"topic": "交易信号与未来函数防护",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 signal/position 表。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 策略规则层。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day063/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 交易信号与未来函数防护 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from math import sqrt
TOPIC = '交易信号与未来函数防护'
DAY = 63
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
PRICES = [100, 101.2, 99.8, 103.5, 102.4, 106.0]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def returns(prices):
return [cur / prev - 1 for prev, cur in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
worst = 0
for price in prices:
peak = max(peak, price)
worst = min(worst, price / peak - 1)
return worst
def sharpe(rs):
avg = sum(rs) / len(rs)
var = sum((r - avg) ** 2 for r in rs) / len(rs)
vol = sqrt(var)
return 0 if vol == 0 else avg / vol * sqrt(252)
def main():
ensure_dirs()
rs = returns(PRICES)
summary = {
"topic": TOPIC,
"total_return": round(PRICES[-1] / PRICES[0] - 1, 4),
"max_drawdown": round(max_drawdown(PRICES), 4),
"sharpe": round(sharpe(rs), 4),
"risk_note": "这里只验证指标口径,不代表真实策略有效。",
}
(OUT / "quant_summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day64 - 最小回测引擎
> 阶段六:Quant 研究与回测基础
学习定位
把持仓和收益合成净值曲线。
今天的目标不是背定义,而是产出:一个 equity curve。
前置知识
- 推荐前置:Day63 signal
- 上一站:Day63
- 下一站:Day65
今日知识地图
- 把持仓和收益合成净值曲线
- backtest
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「最小回测引擎」完成 一个 equity curve?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
最小回测引擎 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把持仓和收益合成净值曲线、backtest、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 最小回测引擎,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day64 - 最小回测引擎
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):最小回测引擎 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day064_note(input_name, output_name, risk):
return {
"day": "Day64",
"topic": "最小回测引擎",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:最小回测引擎。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 最小回测引擎 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 价格数据
- 收益率
- 波动率
- 回撤
- 信号
- 持仓
- 交易成本
- 风险预算
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 策略研究先保证数据口径。
- 回测要防未来函数。
- 报告要写清样本区间和风险假设。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day064_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day64",
"topic": "最小回测引擎",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 equity curve。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 回测核心。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day064/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 最小回测引擎 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from math import sqrt
TOPIC = '最小回测引擎'
DAY = 64
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
PRICES = [100, 101.2, 99.8, 103.5, 102.4, 106.0]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def returns(prices):
return [cur / prev - 1 for prev, cur in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
worst = 0
for price in prices:
peak = max(peak, price)
worst = min(worst, price / peak - 1)
return worst
def sharpe(rs):
avg = sum(rs) / len(rs)
var = sum((r - avg) ** 2 for r in rs) / len(rs)
vol = sqrt(var)
return 0 if vol == 0 else avg / vol * sqrt(252)
def main():
ensure_dirs()
rs = returns(PRICES)
summary = {
"topic": TOPIC,
"total_return": round(PRICES[-1] / PRICES[0] - 1, 4),
"max_drawdown": round(max_drawdown(PRICES), 4),
"sharpe": round(sharpe(rs), 4),
"risk_note": "这里只验证指标口径,不代表真实策略有效。",
}
(OUT / "quant_summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day65 - 手续费、滑点与现实约束
> 阶段六:Quant 研究与回测基础
学习定位
给回测加入简单成本。
今天的目标不是背定义,而是产出:一个 cost-adjusted return。
前置知识
- 推荐前置:Day64 backtest
- 上一站:Day64
- 下一站:Day66
今日知识地图
- 给回测加入简单成本
- cost model
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「手续费、滑点与现实约束」完成 一个 cost-adjusted return?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
手续费、滑点与现实约束 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「给回测加入简单成本、cost model、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 手续费、滑点与现实约束,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day65 - 手续费、滑点与现实约束
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):手续费、滑点与现实约束 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day065_note(input_name, output_name, risk):
return {
"day": "Day65",
"topic": "手续费、滑点与现实约束",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:手续费、滑点与现实约束。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 手续费、滑点与现实约束 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 价格数据
- 收益率
- 波动率
- 回撤
- 信号
- 持仓
- 交易成本
- 风险预算
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 策略研究先保证数据口径。
- 回测要防未来函数。
- 报告要写清样本区间和风险假设。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day065_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day65",
"topic": "手续费、滑点与现实约束",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 cost-adjusted return。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 更接近真实交易。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day065/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 手续费、滑点与现实约束 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from math import sqrt
TOPIC = '手续费、滑点与现实约束'
DAY = 65
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
PRICES = [100, 101.2, 99.8, 103.5, 102.4, 106.0]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def returns(prices):
return [cur / prev - 1 for prev, cur in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
worst = 0
for price in prices:
peak = max(peak, price)
worst = min(worst, price / peak - 1)
return worst
def sharpe(rs):
avg = sum(rs) / len(rs)
var = sum((r - avg) ** 2 for r in rs) / len(rs)
vol = sqrt(var)
return 0 if vol == 0 else avg / vol * sqrt(252)
def main():
ensure_dirs()
rs = returns(PRICES)
summary = {
"topic": TOPIC,
"total_return": round(PRICES[-1] / PRICES[0] - 1, 4),
"max_drawdown": round(max_drawdown(PRICES), 4),
"sharpe": round(sharpe(rs), 4),
"risk_note": "这里只验证指标口径,不代表真实策略有效。",
}
(OUT / "quant_summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day66 - 仓位管理与风险预算
> 阶段六:Quant 研究与回测基础
学习定位
限制单资产仓位和总风险。
今天的目标不是背定义,而是产出:一个 position sizing 函数。
前置知识
- 推荐前置:Day65 cost
- 上一站:Day65
- 下一站:Day67
今日知识地图
- 限制单资产仓位和总风险
- position risk
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「仓位管理与风险预算」完成 一个 position sizing 函数?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
仓位管理与风险预算 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「限制单资产仓位和总风险、position risk、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 仓位管理与风险预算,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day66 - 仓位管理与风险预算
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):仓位管理与风险预算 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day066_note(input_name, output_name, risk):
return {
"day": "Day66",
"topic": "仓位管理与风险预算",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:仓位管理与风险预算。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 仓位管理与风险预算 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 价格数据
- 收益率
- 波动率
- 回撤
- 信号
- 持仓
- 交易成本
- 风险预算
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 策略研究先保证数据口径。
- 回测要防未来函数。
- 报告要写清样本区间和风险假设。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day066_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day66",
"topic": "仓位管理与风险预算",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 position sizing 函数。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 策略风控层。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day066/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 仓位管理与风险预算 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from math import sqrt
TOPIC = '仓位管理与风险预算'
DAY = 66
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
PRICES = [100, 101.2, 99.8, 103.5, 102.4, 106.0]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def returns(prices):
return [cur / prev - 1 for prev, cur in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
worst = 0
for price in prices:
peak = max(peak, price)
worst = min(worst, price / peak - 1)
return worst
def sharpe(rs):
avg = sum(rs) / len(rs)
var = sum((r - avg) ** 2 for r in rs) / len(rs)
vol = sqrt(var)
return 0 if vol == 0 else avg / vol * sqrt(252)
def main():
ensure_dirs()
rs = returns(PRICES)
summary = {
"topic": TOPIC,
"total_return": round(PRICES[-1] / PRICES[0] - 1, 4),
"max_drawdown": round(max_drawdown(PRICES), 4),
"sharpe": round(sharpe(rs), 4),
"risk_note": "这里只验证指标口径,不代表真实策略有效。",
}
(OUT / "quant_summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day67 - 组合指标与多资产权重
> 阶段六:Quant 研究与回测基础
学习定位
计算组合收益和权重约束。
今天的目标不是背定义,而是产出:一个 portfolio return。
前置知识
- 推荐前置:Day66 risk
- 上一站:Day66
- 下一站:Day68
今日知识地图
- 计算组合收益和权重约束
- portfolio weights
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「组合指标与多资产权重」完成 一个 portfolio return?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
组合指标与多资产权重 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「计算组合收益和权重约束、portfolio weights、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 组合指标与多资产权重,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day67 - 组合指标与多资产权重
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):组合指标与多资产权重 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day067_note(input_name, output_name, risk):
return {
"day": "Day67",
"topic": "组合指标与多资产权重",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:组合指标与多资产权重。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 组合指标与多资产权重 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 价格数据
- 收益率
- 波动率
- 回撤
- 信号
- 持仓
- 交易成本
- 风险预算
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 策略研究先保证数据口径。
- 回测要防未来函数。
- 报告要写清样本区间和风险假设。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day067_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day67",
"topic": "组合指标与多资产权重",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 portfolio return。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 组合研究。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day067/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 组合指标与多资产权重 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 67
TOPIC = "组合指标与多资产权重"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def portfolio_returns(asset_returns, weights):
days = len(next(iter(asset_returns.values())))
result = []
for day_index in range(days):
daily_return = sum(asset_returns[name][day_index] * weights[name] for name in weights)
result.append(round(daily_return, 4))
return result
def main():
assets = {"stock_a": [0.01, 0.02, -0.01], "stock_b": [0.0, 0.01, 0.015]}
weights = {"stock_a": 0.6, "stock_b": 0.4}
result = portfolio_returns(assets, weights)
report = {"topic": TOPIC, "portfolio_returns": result, "total_return": round(sum(result), 4)}
path = write_json("portfolio_weight_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day68 - 因子分析最小框架
> 阶段六:Quant 研究与回测基础
学习定位
按因子分组观察未来收益。
今天的目标不是背定义,而是产出:一个 factor bucket summary。
前置知识
- 推荐前置:Day67 portfolio
- 上一站:Day67
- 下一站:Day69
今日知识地图
- 按因子分组观察未来收益
- factor analysis
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「因子分析最小框架」完成 一个 factor bucket summary?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
因子分析最小框架 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「按因子分组观察未来收益、factor analysis、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 因子分析最小框架,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day68 - 因子分析最小框架
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):因子分析最小框架 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day068_note(input_name, output_name, risk):
return {
"day": "Day68",
"topic": "因子分析最小框架",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:因子分析最小框架。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 因子分析最小框架 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 价格数据
- 收益率
- 波动率
- 回撤
- 信号
- 持仓
- 交易成本
- 风险预算
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 策略研究先保证数据口径。
- 回测要防未来函数。
- 报告要写清样本区间和风险假设。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day068_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day68",
"topic": "因子分析最小框架",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 factor bucket summary。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 因子研究。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day068/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 因子分析最小框架 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from math import sqrt
TOPIC = '因子分析最小框架'
DAY = 68
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
PRICES = [100, 101.2, 99.8, 103.5, 102.4, 106.0]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def returns(prices):
return [cur / prev - 1 for prev, cur in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
worst = 0
for price in prices:
peak = max(peak, price)
worst = min(worst, price / peak - 1)
return worst
def sharpe(rs):
avg = sum(rs) / len(rs)
var = sum((r - avg) ** 2 for r in rs) / len(rs)
vol = sqrt(var)
return 0 if vol == 0 else avg / vol * sqrt(252)
def main():
ensure_dirs()
rs = returns(PRICES)
summary = {
"topic": TOPIC,
"total_return": round(PRICES[-1] / PRICES[0] - 1, 4),
"max_drawdown": round(max_drawdown(PRICES), 4),
"sharpe": round(sharpe(rs), 4),
"risk_note": "这里只验证指标口径,不代表真实策略有效。",
}
(OUT / "quant_summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day69 - 事件研究 Event Study
> 阶段六:Quant 研究与回测基础
学习定位
观察事件日前后窗口收益。
今天的目标不是背定义,而是产出:一个 event window summary。
前置知识
- 推荐前置:Day68 factor
- 上一站:Day68
- 下一站:Day70
今日知识地图
- 观察事件日前后窗口收益
- event window
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「事件研究 Event Study」完成 一个 event window summary?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
事件研究 Event Study 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「观察事件日前后窗口收益、event window、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 事件研究 Event Study,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day69 - 事件研究 Event Study
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):事件研究 Event Study 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day069_note(input_name, output_name, risk):
return {
"day": "Day69",
"topic": "事件研究 Event Study",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:事件研究 Event Study。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 事件研究 Event Study 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 价格数据
- 收益率
- 波动率
- 回撤
- 信号
- 持仓
- 交易成本
- 风险预算
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 策略研究先保证数据口径。
- 回测要防未来函数。
- 报告要写清样本区间和风险假设。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day069_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day69",
"topic": "事件研究 Event Study",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 event window summary。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 公告/财报分析。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day069/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 事件研究 Event Study 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 69
TOPIC = "事件研究 Event Study"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def event_window_return(returns, start=-1, end=1):
selected = {day: value for day, value in returns.items() if start <= day <= end}
return {"window": selected, "car": round(sum(selected.values()), 4)}
def main():
returns = {-2: -0.01, -1: 0.005, 0: 0.03, 1: 0.012, 2: -0.004}
report = {"topic": TOPIC, **event_window_return(returns)}
path = write_json("event_study_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day70 - Quant 报告与图表输出
> 阶段六:Quant 研究与回测基础
学习定位
把策略指标写成可读报告。
今天的目标不是背定义,而是产出:一份 strategy_report.md。
前置知识
- 推荐前置:Day69 event
- 上一站:Day69
- 下一站:Day71
今日知识地图
- 把策略指标写成可读报告
- quant report
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「Quant 报告与图表输出」完成 一份 strategy_report.md?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
Quant 报告与图表输出 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把策略指标写成可读报告、quant report、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 Quant 报告与图表输出,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day70 - Quant 报告与图表输出
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):Quant 报告与图表输出 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day070_note(input_name, output_name, risk):
return {
"day": "Day70",
"topic": "Quant 报告与图表输出",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:Quant 报告与图表输出。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 Quant 报告与图表输出 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 价格数据
- 收益率
- 波动率
- 回撤
- 信号
- 持仓
- 交易成本
- 风险预算
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 策略研究先保证数据口径。
- 回测要防未来函数。
- 报告要写清样本区间和风险假设。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day070_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day70",
"topic": "Quant 报告与图表输出",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一份 strategy_report.md。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 量化研究复盘。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day070/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Quant 报告与图表输出 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from math import sqrt
TOPIC = 'Quant 报告与图表输出'
DAY = 70
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
PRICES = [100, 101.2, 99.8, 103.5, 102.4, 106.0]
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def returns(prices):
return [cur / prev - 1 for prev, cur in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
worst = 0
for price in prices:
peak = max(peak, price)
worst = min(worst, price / peak - 1)
return worst
def sharpe(rs):
avg = sum(rs) / len(rs)
var = sum((r - avg) ** 2 for r in rs) / len(rs)
vol = sqrt(var)
return 0 if vol == 0 else avg / vol * sqrt(252)
def main():
ensure_dirs()
rs = returns(PRICES)
summary = {
"topic": TOPIC,
"total_return": round(PRICES[-1] / PRICES[0] - 1, 4),
"max_drawdown": round(max_drawdown(PRICES), 4),
"sharpe": round(sharpe(rs), 4),
"risk_note": "这里只验证指标口径,不代表真实策略有效。",
}
(OUT / "quant_summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day71 - 配置驱动的策略实验
> 阶段六:Quant 研究与回测基础
学习定位
用 config 控制窗口、成本、路径。
今天的目标不是背定义,而是产出:一个 config-driven run。
前置知识
- 推荐前置:Day70 report
- 上一站:Day70
- 下一站:Day72
今日知识地图
- 用 config 控制窗口、成本、路径
- strategy config
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「配置驱动的策略实验」完成 一个 config-driven run?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
配置驱动的策略实验 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「用 config 控制窗口、成本、路径、strategy config、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 配置驱动的策略实验,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day71 - 配置驱动的策略实验
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):配置驱动的策略实验 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day071_note(input_name, output_name, risk):
return {
"day": "Day71",
"topic": "配置驱动的策略实验",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:配置驱动的策略实验。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 配置驱动的策略实验 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 类型提示
- 运行时校验
- 配置默认值
- 环境变量
- 路径配置
- 输入边界
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 类型标注不等于运行时检查。
- 公开主题不要把密钥写进配置文件。
- 配置应该让脚本换输入时不用改代码。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day071_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day71",
"topic": "配置驱动的策略实验",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 config-driven run。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 可复现实验。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day071/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 配置驱动的策略实验 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = '配置驱动的策略实验'
DAY = 71
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day72 - 量化函数测试与样例数据
> 阶段六:Quant 研究与回测基础
学习定位
给指标、信号、回测写测试。
今天的目标不是背定义,而是产出:一组 pytest 测试。
前置知识
- 推荐前置:Day71 config
- 上一站:Day71
- 下一站:Day73
今日知识地图
- 给指标、信号、回测写测试
- quant tests
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「量化函数测试与样例数据」完成 一组 pytest 测试?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
量化函数测试与样例数据 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「给指标、信号、回测写测试、quant tests、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 量化函数测试与样例数据,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day72 - 量化函数测试与样例数据
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师写函数,是为了把一段稳定逻辑从脚本里抽出来。这样可以换输入、写测试、复用到主题里,而不是每次复制粘贴。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):量化函数测试与样例数据 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day072_note(input_name, output_name, risk):
return {
"day": "Day72",
"topic": "量化函数测试与样例数据",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:量化函数测试与样例数据。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 量化函数测试与样例数据 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- assert
- 边界测试
- 异常测试
- fixture
- 样例数据
- 回归保护
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 测试不是测所有东西,而是保护最核心的函数。
- 正常输入和异常输入都要覆盖。
- 样例数据要小、稳定、可公开。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day072_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day72",
"topic": "量化函数测试与样例数据",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一组 pytest 测试。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 研究代码可靠性。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day072/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 量化函数测试与样例数据 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = '量化函数测试与样例数据'
DAY = 72
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day73 - SQLite 保存回测结果
> 阶段六:Quant 研究与回测基础
学习定位
把实验结果存入本地数据库。
今天的目标不是背定义,而是产出:一个 results.db。
前置知识
- 推荐前置:Day72 tests
- 上一站:Day72
- 下一站:Day74
今日知识地图
- 把实验结果存入本地数据库
- result store
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「SQLite 保存回测结果」完成 一个 results.db?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
SQLite 保存回测结果 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把实验结果存入本地数据库、result store、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 SQLite 保存回测结果,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day73 - SQLite 保存回测结果
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):SQLite 保存回测结果 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day073_note(input_name, output_name, risk):
return {
"day": "Day73",
"topic": "SQLite 保存回测结果",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:SQLite 保存回测结果。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 SQLite 保存回测结果 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 表结构
- 主键
- 索引
- join
- 窗口函数
- 事务
- 查询复用
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 本地 SQLite 适合保存实验结果。
- 表名和字段名要稳定。
- 复杂查询先拆成可读步骤。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day073_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day73",
"topic": "SQLite 保存回测结果",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 results.db。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 实验追踪。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day073/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 SQLite 保存回测结果 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import sqlite3
import json
TOPIC = 'SQLite 保存回测结果'
DAY = 73
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
DB = OUT / "learning.db"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def setup_db():
conn = sqlite3.connect(DB)
conn.execute("drop table if exists study_log")
conn.execute("create table study_log(day int, topic text, minutes int)")
conn.executemany(
"insert into study_log values (?, ?, ?)",
[(31, "sqlite", 40), (32, "sql join", 50), (33, "config", 20)],
)
conn.commit()
return conn
def query_summary(conn):
rows = conn.execute(
"select count(*) as n, sum(minutes) as total_minutes from study_log"
).fetchone()
top = conn.execute(
"select topic, minutes from study_log order by minutes desc limit 1"
).fetchone()
return {"topic": TOPIC, "rows": rows[0], "total_minutes": rows[1], "top_topic": top[0]}
def main():
ensure_dirs()
conn = setup_db()
summary = query_summary(conn)
conn.close()
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day74 - Streamlit 策略看板
> 阶段六:Quant 研究与回测基础
学习定位
本地展示策略指标和曲线。
今天的目标不是背定义,而是产出:一个 strategy dashboard。
前置知识
- 推荐前置:Day73 store
- 上一站:Day73
- 下一站:Day75
今日知识地图
- 本地展示策略指标和曲线
- strategy dashboard
- 输入输出边界
- 可复盘结果
真实任务入口
今天先不从定义开始,而是先看问题:如何用「Streamlit 策略看板」完成 一个 strategy dashboard?
这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。
先按这条顺序学习:
真实任务
↓
拆解流程
↓
引出问题
↓
引出知识点
↓
解释设计原因
↓
代码实现
↓
未来使用
今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。
工程问题解决结构
1. 是什么(What)
Streamlit 策略看板 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「本地展示策略指标和曲线、strategy dashboard、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。
2. 为什么存在(Why)
如果没有 Streamlit 策略看板,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。
3. 真实工程场景(Real Scenario)
- 科研场景:复现实证研究流程:数据、假设、指标、检验和报告。
- 数据分析场景:把时间序列数据处理成可复查指标和图表。
- Quant 场景:完成行情读取、信号生成、回测、风险评估和研究记录。
- LLM/Agent 场景:让 Agent 调用研究工具时能追踪参数、数据版本和输出解释。
4. 怎么做(How)
先看场景流程,再看代码:
行情/实验数据
↓
指标计算
↓
信号或假设
↓
回测/检验
↓
风险解释
↓
研究报告
# Day74 - Streamlit 策略看板
prices = [100, 101, 99, 103]
returns = []
for i in range(1, len(prices)):
returns.append(prices[i] / prices[i - 1] - 1)
print({"returns": returns, "max_return": max(returns)})
5. 工程设计思维(Design)
工程师会把数据、指标、信号和报告分层,是为了防止未来函数、参数混乱和结果无法复现。Quant 代码最怕看似能跑但研究结论不可追踪。
6. Future Usage(未来使用)
这个知识点以后会反复出现在:
- Quant research starter
- 最小回测引擎
- 策略报告
- 风险监控脚本
- 数据处理脚本
7. 掌握检查
学完今天不要只问“代码跑了吗”,要能回答四个问题:
1. 它是什么?
2. 它为什么存在?
3. 它解决什么问题?
4. 它在未来 Quant / LLM / Agent 主题中怎么使用?
基础优化补充:问题、场景与代码
阶段定位:Quant 研究基础。
解决什么问题(Problem):Streamlit 策略看板 的核心不是背概念,而是把策略想法拆成数据、指标、信号、回测、成本、风险和报告。
真实科研场景:把研究假设变成可追踪实验,记录样本区间、参数、指标和失败案例。
数据分析场景:用数据分析方法清洗行情、计算指标、输出图表和保存实验结果。
Quant 场景:建立从数据适配、收益计算、信号生成到回测报告的最小闭环。
LLM/Agent 场景:让 LLM/Agent 只辅助解释、记录和检查,不替代回测逻辑和风险判断。
def build_day074_note(input_name, output_name, risk):
return {
"day": "Day74",
"topic": "Streamlit 策略看板",
"input": input_name,
"output": output_name,
"risk": risk,
"next_check": "确认输入、处理步骤、输出和失败点是否清楚",
}
工程工作流补充
如果你完全看不懂,先只抓这一句话
今天学的是:Streamlit 策略看板。它不只是一个孤立知识点,而是服务于「Quant 研究与回测基础」阶段的一个小能力:把行情样例变成可复查的研究实验。
先按这条工程线理解:
行情数据 -> 指标计算 -> 信号生成 -> 回测 -> 风险/报告
你不需要一开始把所有细节背下来。先回答五个问题:
1. 今天的输入是什么?
2. 中间处理分几步?
3. 输出保存在哪里?
4. 失败时会在哪一步失败?
5. 这个能力以后能放进哪个主题?
真实工作流怎么想
把今天的主题放进一个真实主题里,它通常不是单独出现的。比如做一个 AI/data/quant 小工具时,你会经历:
| 步骤 | 你要做什么 |
|---|
| 1. 准备输入 | 明确数据、参数、文件、用户问题或样例记录从哪里来 |
| 2. 写核心函数 | 把最重要的一步处理封装成函数,先保证可运行 |
| 3. 检查边界 | 检查空输入、缺字段、类型不对、路径不对、网络失败等情况 |
| 4. 保存结果 | 把输出保存成 Markdown、JSON、CSV、SQLite、日志或网页 |
| 5. 写复盘 | 在 说明文档 或学习日志里写清运行命令、输入输出和下一步 |
执行过程追踪
读今天代码时,不要只看语法,要追踪数据怎么走:
输入
↓
核心处理
↓
中间结果
↓
边界检查
↓
最终输出
当前最应该检查:时间边界、未来函数、手续费、回撤、样例数据。
最容易混的点
| 卡点 | 正确理解 |
|---|
| 只跑通一次就以为学会了 | 至少换 2-3 组样例输入,确认逻辑可复用 |
| 只在终端 print,不保存结果 | 工程主题要留下可复查产物 |
| 报错后直接改代码 | 先记录触发输入、报错行、失败原因,再修复 |
| 函数越写越长 | 先拆成输入读取、核心处理、结果保存三个部分 |
| 说明文档 最后才写 | 先写运行命令,代码按运行命令实现 |
工业化知识百科补充:从会用到会迁移
这一节不是把前面没学完的语法硬塞回来,而是把 Streamlit 策略看板 放进后续 IC 挑战里补厚。你现在已经进入 Day10 之后,学习重点要从“我知道这个语法”升级为“我知道它在工程里解决什么问题、会踩什么坑、怎么迁移到 IC”。
1. 阶段定位
当前阶段:Quant 研究与回测。
阶段目标:把策略想法拆成数据、指标、信号、成本、风险和报告。
本阶段反复出现的能力:
- 行情适配
- 收益风险指标
- 未来函数防护
- 回测引擎
- 交易成本
- 研究报告
2. 这个主题必须补齐的知识面
- 页面状态
- 文件上传
- 缓存
- 表格展示
- 图表展示
- 交互控件
学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。
3. 真实主题里怎么用
- 数据分析:先明确字段、类型、缺失值、样本范围,再写处理逻辑。不要直接对未知数据写复杂代码。
- Quant:任何计算都要关心时间顺序、样本区间、交易成本、未来函数和结果复现。
- LLM/Agent:所有输入输出都要有结构,模型结果要校验,高风险动作要有人类审查点。
4. 常见坑和边界
- 第一屏要能直接使用。
- 上传数据要做字段检查。
- 缓存会影响调试,必要时清理。
- 不要把所有逻辑堆进一个文件或一个函数。先拆出最小核心函数,再决定是否需要 CLI、API、看板或测试。
- 不要用“能跑一次”代表掌握。真正掌握是换一份输入、换一个场景、换一个主题后仍然能迁移。
5. 最小迁移代码模块边界
def day074_engineering_note(input_data):
"""记录今天知识点在工程主题里的使用边界。"""
return {
"day": "Day74",
"topic": "Streamlit 策略看板",
"input_shape": "明确输入来源、字段、类型和边界",
"core_step": "把今天主题压缩成一个可测试的小函数",
"output_shape": "明确输出给终端、文件、API、报告还是下游函数",
"failure_modes": ["空输入", "类型不对", "缺字段", "路径或网络失败"],
"reuse_target": "数据分析 / Quant / LLM-Agent / 能力清单主题",
}
6. 百科式自查问题
1. 这个主题的输入是什么?输入可能为空、缺字段、类型错误吗?
2. 核心处理步骤能不能写成一个小函数?
3. 输出是给人看,还是给下游程序继续用?
4. 失败时怎么记录?是 print、logging、错误报告,还是测试失败?
5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?
6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?
7. 建议扩展练习
- 写一个最小正常样例。
- 写一个边界样例,例如空输入、缺字段、类型错误、路径不存在。
- 写一段 Debug 记录,说明错误现象、定位过程和修复方式。
- 把今天的代码改造成一个函数,并说明输入和输出。
- 思考它未来会放进哪个主题模块:
data_io、transform、analysis、api、app、agent_tool、backtest 或 report。
2 小时学习节奏
- 15 分钟:读定位、前置和知识地图。
- 25 分钟:手打最小案例并运行。
- 35 分钟:完成 7 道简单路线题。
- 35 分钟:完成 5 道基础巩固题。
- 10 分钟:记录 Debug、结果和下一步。
简单路线 7 题
1. 读完“学习定位”,用一句话写下今天要解决的问题。
2. 手打最小案例并运行,确认得到 一个 strategy dashboard。
3. 把示例输入改成 2-3 条虚拟样例,观察输出是否仍然合理。
4. 故意制造一个小错误,记录报错、原因和修复方式。
5. 给输出加一个清晰字段名或标题,避免只看到裸数字。
6. 把今天代码保存到本地练习文件夹,并写下运行命令。
7. 用 3 行话说明它如何服务于 作品展示。
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day074/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Streamlit 策略看板 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
from statistics import mean
TOPIC = 'Streamlit 策略看板'
DAY = 74
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def ensure_dirs():
OUT.mkdir(parents=True, exist_ok=True)
def sample_rows():
return [
{"user": "u1", "group": "A", "value": 12},
{"user": "u2", "group": "A", "value": 18},
{"user": "u3", "group": "B", "value": 9},
{"user": "u4", "group": "B", "value": None},
]
def clean_rows(rows):
cleaned = []
skipped = []
for row in rows:
if row["value"] is None:
skipped.append({"row": row, "reason": "missing value"})
continue
cleaned.append(row)
return cleaned, skipped
def summarize(cleaned, skipped):
values = [row["value"] for row in cleaned]
return {
"topic": TOPIC,
"valid_rows": len(cleaned),
"skipped_rows": len(skipped),
"mean_value": round(mean(values), 2) if values else 0,
"groups": sorted({row["group"] for row in cleaned}),
}
def main():
ensure_dirs()
cleaned, skipped = clean_rows(sample_rows())
summary = summarize(cleaned, skipped)
(OUT / "summary.json").write_text(json.dumps(summary, ensure_ascii=False, indent=2), encoding="utf-8")
(OUT / "skipped.json").write_text(json.dumps(skipped, ensure_ascii=False, indent=2), encoding="utf-8")
print(json.dumps(summary, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
Debug 记录模板
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
复习检查
- [ ] 我能解释今天能力的输入、处理和输出。
- [ ] 我能从零手打最小案例。
- [ ] 我完成了今日强化题,并运行了
main.py 参考代码。
- [ ] 我把结果保存成可复查产物。
参考资料
Day75 - Quant 研究闭环原理
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Quant 研究闭环原理 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day74
- 下一站:Day76
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Quant 研究闭环原理 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prices | 价格序列 | 收益率序列 | 量化研究的最小原料 |
returns | 相邻价格变化 | 日收益率 | 连接统计学和策略评价 |
risk metrics | 收益率列表 | 回撤、波动、胜率 | 判断策略是否只是运气 |
experiment log | 参数和结果 | 研究记录 | 避免回测结果不可复现 |
What
Quant 研究闭环原理 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
research_loop = ["idea", "data", "signal", "backtest", "review"]
trace = []
for step in research_loop:
trace.append({"step": step, "done": step != "review"})
needs_review = any(not item["done"] for item in trace)
print({"trace": trace, "needs_review": needs_review})
参数拆解方法
第一次看到 Quant 研究闭环原理 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Quant 研究闭环原理 的最小输入对象 |
| 指标参数 | 它对应哪段金融含义 | window 是滚动窗口长度 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先防未来函数和除零。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day075/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Quant 研究闭环原理 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 75
TOPIC = "Quant 研究闭环原理"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def calc_returns(prices):
return [round(current / previous - 1, 4) for previous, current in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
drawdowns = []
for price in prices:
peak = max(peak, price)
drawdowns.append(round(price / peak - 1, 4))
return min(drawdowns)
def main():
prices = [100, 102, 101, 105, 103]
report = {"topic": TOPIC, "returns": calc_returns(prices), "max_drawdown": max_drawdown(prices)}
path = write_json("quant_learning_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day75:Quant 研究闭环原理
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Quant 研究闭环原理 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day76 - Quant 研究模块边界
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Quant 研究模块边界 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day75
- 下一站:Day77
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Quant 研究模块边界 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prices | 价格序列 | 收益率序列 | 量化研究的最小原料 |
returns | 相邻价格变化 | 日收益率 | 连接统计学和策略评价 |
risk metrics | 收益率列表 | 回撤、波动、胜率 | 判断策略是否只是运气 |
experiment log | 参数和结果 | 研究记录 | 避免回测结果不可复现 |
What
Quant 研究模块边界 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
modules = {
"data_layer": ["load_prices", "clean_calendar"],
"metric_layer": ["return", "drawdown"],
"report_layer": ["summary", "chart_note"],
}
interfaces = {name: len(functions) for name, functions in modules.items()}
print({"module_count": len(modules), "interfaces": interfaces})
参数拆解方法
第一次看到 Quant 研究模块边界 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Quant 研究模块边界 的最小输入对象 |
| 指标参数 | 它对应哪段金融含义 | window 是滚动窗口长度 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先防未来函数和除零。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day076/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Quant 研究模块边界 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 76
TOPIC = "Quant 研究模块边界"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def calc_returns(prices):
return [round(current / previous - 1, 4) for previous, current in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
drawdowns = []
for price in prices:
peak = max(peak, price)
drawdowns.append(round(price / peak - 1, 4))
return min(drawdowns)
def main():
prices = [100, 102, 101, 105, 103]
report = {"topic": TOPIC, "returns": calc_returns(prices), "max_drawdown": max_drawdown(prices)}
path = write_json("quant_learning_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day76:Quant 研究模块边界
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Quant 研究模块边界 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day77 - Quant 数据层原理
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Quant 数据层原理 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day76
- 下一站:Day78
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Quant 数据层原理 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prices | 价格序列 | 收益率序列 | 量化研究的最小原料 |
returns | 相邻价格变化 | 日收益率 | 连接统计学和策略评价 |
risk metrics | 收益率列表 | 回撤、波动、胜率 | 判断策略是否只是运气 |
experiment log | 参数和结果 | 研究记录 | 避免回测结果不可复现 |
What
Quant 数据层原理 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
raw_prices = [
{"date": "2026-01-01", "close": "100.5"},
{"date": "2026-01-02", "close": "101.2"},
]
normalized = [{"date": row["date"], "close": float(row["close"])} for row in raw_prices]
print({"rows": normalized, "price_type": type(normalized[0]["close"]).__name__})
参数拆解方法
第一次看到 Quant 数据层原理 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Quant 数据层原理 的最小输入对象 |
| 指标参数 | 它对应哪段金融含义 | window 是滚动窗口长度 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先防未来函数和除零。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day077/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Quant 数据层原理 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 77
TOPIC = "Quant 数据层原理"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def calc_returns(prices):
return [round(current / previous - 1, 4) for previous, current in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
drawdowns = []
for price in prices:
peak = max(peak, price)
drawdowns.append(round(price / peak - 1, 4))
return min(drawdowns)
def main():
prices = [100, 102, 101, 105, 103]
report = {"topic": TOPIC, "returns": calc_returns(prices), "max_drawdown": max_drawdown(prices)}
path = write_json("quant_learning_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day77:Quant 数据层原理
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Quant 数据层原理 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day78 - Quant 指标与回测层原理
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Quant 指标与回测层原理 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day77
- 下一站:Day79
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Quant 指标与回测层原理 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prices | 价格序列 | 收益率序列 | 量化研究的最小原料 |
returns | 相邻价格变化 | 日收益率 | 连接统计学和策略评价 |
risk metrics | 收益率列表 | 回撤、波动、胜率 | 判断策略是否只是运气 |
experiment log | 参数和结果 | 研究记录 | 避免回测结果不可复现 |
What
Quant 指标与回测层原理 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
returns = [0.01, -0.02, 0.015, 0.005]
average_return = sum(returns) / len(returns)
loss_days = [value for value in returns if value < 0]
win_rate = round((len(returns) - len(loss_days)) / len(returns), 2)
print({"average_return": round(average_return, 4), "win_rate": win_rate, "loss_days": loss_days})
参数拆解方法
第一次看到 Quant 指标与回测层原理 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Quant 指标与回测层原理 的最小输入对象 |
| 指标参数 | 它对应哪段金融含义 | window 是滚动窗口长度 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先防未来函数和除零。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day078/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Quant 指标与回测层原理 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 78
TOPIC = "Quant 指标与回测层原理"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def calc_returns(prices):
return [round(current / previous - 1, 4) for previous, current in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
drawdowns = []
for price in prices:
peak = max(peak, price)
drawdowns.append(round(price / peak - 1, 4))
return min(drawdowns)
def main():
prices = [100, 102, 101, 105, 103]
report = {"topic": TOPIC, "returns": calc_returns(prices), "max_drawdown": max_drawdown(prices)}
path = write_json("quant_learning_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day78:Quant 指标与回测层原理
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Quant 指标与回测层原理 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day79 - Quant 报告、测试与 CLI 原理
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Quant 报告、测试与 CLI 原理 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day78
- 下一站:Day80
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Quant 报告、测试与 CLI 原理 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prices | 价格序列 | 收益率序列 | 量化研究的最小原料 |
returns | 相邻价格变化 | 日收益率 | 连接统计学和策略评价 |
risk metrics | 收益率列表 | 回撤、波动、胜率 | 判断策略是否只是运气 |
experiment log | 参数和结果 | 研究记录 | 避免回测结果不可复现 |
What
Quant 报告、测试与 CLI 原理 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
cli_args = {"strategy": "ma_cross", "window": 5}
test_result = {"no_future_data": True, "has_report": True, "sample_rows": 20}
ready = all(test_result.values()) and cli_args["window"] > 1
print({"cli_args": cli_args, "test_result": test_result, "ready_to_run": ready})
参数拆解方法
第一次看到 Quant 报告、测试与 CLI 原理 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Quant 报告、测试与 CLI 原理 的最小输入对象 |
| 指标参数 | 它对应哪段金融含义 | window 是滚动窗口长度 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先防未来函数和除零。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day079/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Quant 报告、测试与 CLI 原理 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 79
TOPIC = "Quant 报告、测试与 CLI 原理"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def calc_returns(prices):
return [round(current / previous - 1, 4) for previous, current in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
drawdowns = []
for price in prices:
peak = max(peak, price)
drawdowns.append(round(price / peak - 1, 4))
return min(drawdowns)
def main():
prices = [100, 102, 101, 105, 103]
report = {"topic": TOPIC, "returns": calc_returns(prices), "max_drawdown": max_drawdown(prices)}
path = write_json("quant_learning_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day79:Quant 报告、测试与 CLI 原理
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Quant 报告、测试与 CLI 原理 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day80 - Quant 实验复盘方法
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Quant 实验复盘方法 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day79
- 下一站:Day81
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Quant 实验复盘方法 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prices | 价格序列 | 收益率序列 | 量化研究的最小原料 |
returns | 相邻价格变化 | 日收益率 | 连接统计学和策略评价 |
risk metrics | 收益率列表 | 回撤、波动、胜率 | 判断策略是否只是运气 |
experiment log | 参数和结果 | 研究记录 | 避免回测结果不可复现 |
What
Quant 实验复盘方法 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
experiments = [
{"name": "baseline", "sharpe": 0.7, "drawdown": -0.12},
{"name": "risk_control", "sharpe": 0.9, "drawdown": -0.08},
]
best = max(experiments, key=lambda item: (item["sharpe"], item["drawdown"]))
print({"best_experiment": best["name"], "reason": "higher sharpe and smaller drawdown"})
参数拆解方法
第一次看到 Quant 实验复盘方法 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Quant 实验复盘方法 的最小输入对象 |
| 指标参数 | 它对应哪段金融含义 | window 是滚动窗口长度 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先防未来函数和除零。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day080/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Quant 实验复盘方法 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 80
TOPIC = "Quant 实验复盘方法"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def calc_returns(prices):
return [round(current / previous - 1, 4) for previous, current in zip(prices, prices[1:])]
def max_drawdown(prices):
peak = prices[0]
drawdowns = []
for price in prices:
peak = max(peak, price)
drawdowns.append(round(price / peak - 1, 4))
return min(drawdowns)
def main():
prices = [100, 102, 101, 105, 103]
report = {"topic": TOPIC, "returns": calc_returns(prices), "max_drawdown": max_drawdown(prices)}
path = write_json("quant_learning_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day80:Quant 实验复盘方法
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Quant 实验复盘方法 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day81 - LLM 报告助手模块边界
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 LLM 报告助手模块边界 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day80
- 下一站:Day82
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 LLM 报告助手模块边界 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prompt | 任务说明 | 模型输入 | 控制回答边界 |
schema | 字段规则 | 结构化输出 | 让结果能被程序检查 |
eval_case | 样例问题 | 评分记录 | 判断改动是否真的变好 |
report | 输入、输出、风险 | 审查文本 | 降低幻觉和过度自信 |
What
LLM 报告助手模块边界 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
modules = [
{"name": "load_notes", "input": "folder", "output": "documents"},
{"name": "summarize", "input": "documents", "output": "draft"},
{"name": "review", "input": "draft", "output": "checked_report"},
]
print({"pipeline": [module["name"] for module in modules], "last_output": modules[-1]["output"]})
参数拆解方法
第一次看到 LLM 报告助手模块边界 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | LLM 报告助手模块边界 的最小输入对象 |
| 输出字段 | 模型必须返回什么结构 | summary 是一句话结论 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先检查字段是否缺失。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day081/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 LLM 报告助手模块边界 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 81
TOPIC = "LLM 报告助手模块边界"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_structured_answer(answer, required_fields):
missing = [field for field in required_fields if field not in answer]
extra = [field for field in answer if field not in required_fields]
return {"valid": not missing, "missing": missing, "extra": extra}
def main():
answer = {"what": "结构化输出", "why": "便于程序检查", "how": "先定义字段再生成"}
review = validate_structured_answer(answer, ["what", "why", "how"])
report = {"topic": TOPIC, "answer": answer, "review": review}
path = write_json("llm_structure_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day81:LLM 报告助手模块边界
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
LLM 报告助手模块边界 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day82 - LLM 上下文打包与 Prompt
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 LLM 上下文打包与 Prompt 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day81
- 下一站:Day83
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 LLM 上下文打包与 Prompt 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prompt | 任务说明 | 模型输入 | 控制回答边界 |
schema | 字段规则 | 结构化输出 | 让结果能被程序检查 |
eval_case | 样例问题 | 评分记录 | 判断改动是否真的变好 |
report | 输入、输出、风险 | 审查文本 | 降低幻觉和过度自信 |
What
LLM 上下文打包与 Prompt 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
chunks = ["Day13 JSON type map", "Day14 class self", "Day15 dataclass asdict"]
budget = 35
packed = []
used = 0
for chunk in chunks:
if used + len(chunk) > budget:
break
packed.append(chunk)
used += len(chunk)
print({"packed_context": packed, "used_chars": used, "budget": budget})
参数拆解方法
第一次看到 LLM 上下文打包与 Prompt 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | LLM 上下文打包与 Prompt 的最小输入对象 |
| 输出字段 | 模型必须返回什么结构 | summary 是一句话结论 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先检查字段是否缺失。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day082/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 LLM 上下文打包与 Prompt 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 82
TOPIC = "LLM 上下文打包与 Prompt"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_structured_answer(answer, required_fields):
missing = [field for field in required_fields if field not in answer]
extra = [field for field in answer if field not in required_fields]
return {"valid": not missing, "missing": missing, "extra": extra}
def main():
answer = {"what": "结构化输出", "why": "便于程序检查", "how": "先定义字段再生成"}
review = validate_structured_answer(answer, ["what", "why", "how"])
report = {"topic": TOPIC, "answer": answer, "review": review}
path = write_json("llm_structure_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day82:LLM 上下文打包与 Prompt
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
LLM 上下文打包与 Prompt 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day83 - 结构化解析与审查规则
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 结构化解析与审查规则 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day82
- 下一站:Day84
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 结构化解析与审查规则 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prompt | 任务说明 | 模型输入 | 控制回答边界 |
schema | 字段规则 | 结构化输出 | 让结果能被程序检查 |
eval_case | 样例问题 | 评分记录 | 判断改动是否真的变好 |
report | 输入、输出、风险 | 审查文本 | 降低幻觉和过度自信 |
What
结构化解析与审查规则 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
import json
raw_output = '{"summary": "CSV is table data", "confidence": "high"}'
parsed = json.loads(raw_output)
required = ["summary", "confidence", "sources"]
missing = [field for field in required if field not in parsed]
print({"parsed": parsed, "missing": missing, "needs_repair": bool(missing)})
参数拆解方法
第一次看到 结构化解析与审查规则 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 结构化解析与审查规则 的最小输入对象 |
| 输出字段 | 模型必须返回什么结构 | summary 是一句话结论 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先检查字段是否缺失。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day083/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 结构化解析与审查规则 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 83
TOPIC = "结构化解析与审查规则"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_structured_answer(answer, required_fields):
missing = [field for field in required_fields if field not in answer]
extra = [field for field in answer if field not in required_fields]
return {"valid": not missing, "missing": missing, "extra": extra}
def main():
answer = {"what": "结构化输出", "why": "便于程序检查", "how": "先定义字段再生成"}
review = validate_structured_answer(answer, ["what", "why", "how"])
report = {"topic": TOPIC, "answer": answer, "review": review}
path = write_json("llm_structure_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day83:结构化解析与审查规则
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
结构化解析与审查规则 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day84 - LLM 评估集与样例报告
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 LLM 评估集与样例报告 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day83
- 下一站:Day85
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 LLM 评估集与样例报告 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prompt | 任务说明 | 模型输入 | 控制回答边界 |
schema | 字段规则 | 结构化输出 | 让结果能被程序检查 |
eval_case | 样例问题 | 评分记录 | 判断改动是否真的变好 |
report | 输入、输出、风险 | 审查文本 | 降低幻觉和过度自信 |
What
LLM 评估集与样例报告 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
cases = [
{"id": "c1", "expected": "mention source", "actual": "mention source"},
{"id": "c2", "expected": "say uncertain", "actual": "overconfident"},
]
scores = [{"id": case["id"], "pass": case["expected"] == case["actual"]} for case in cases]
print({"scores": scores, "pass_rate": sum(item["pass"] for item in scores) / len(scores)})
参数拆解方法
第一次看到 LLM 评估集与样例报告 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | LLM 评估集与样例报告 的最小输入对象 |
| 输出字段 | 模型必须返回什么结构 | summary 是一句话结论 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先检查字段是否缺失。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day084/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 LLM 评估集与样例报告 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 84
TOPIC = "LLM 评估集与样例报告"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_structured_answer(answer, required_fields):
missing = [field for field in required_fields if field not in answer]
extra = [field for field in answer if field not in required_fields]
return {"valid": not missing, "missing": missing, "extra": extra}
def main():
answer = {"what": "结构化输出", "why": "便于程序检查", "how": "先定义字段再生成"}
review = validate_structured_answer(answer, ["what", "why", "how"])
report = {"topic": TOPIC, "answer": answer, "review": review}
path = write_json("llm_structure_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day84:LLM 评估集与样例报告
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
LLM 评估集与样例报告 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day85 - LLM 输出限制与公开说明
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 LLM 输出限制与公开说明 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day84
- 下一站:Day86
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 LLM 输出限制与公开说明 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
prompt | 任务说明 | 模型输入 | 控制回答边界 |
schema | 字段规则 | 结构化输出 | 让结果能被程序检查 |
eval_case | 样例问题 | 评分记录 | 判断改动是否真的变好 |
report | 输入、输出、风险 | 审查文本 | 降低幻觉和过度自信 |
What
LLM 输出限制与公开说明 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
draft = {"claim": "这个结论一定正确", "source_count": 0, "has_uncertainty": False}
violations = []
if draft["source_count"] == 0:
violations.append("missing_source")
if "一定" in draft["claim"] and not draft["has_uncertainty"]:
violations.append("overconfident")
print({"violations": violations, "can_publish": not violations})
参数拆解方法
第一次看到 LLM 输出限制与公开说明 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | LLM 输出限制与公开说明 的最小输入对象 |
| 输出字段 | 模型必须返回什么结构 | summary 是一句话结论 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先检查字段是否缺失。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day085/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 LLM 输出限制与公开说明 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 85
TOPIC = "LLM 输出限制与公开说明"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_structured_answer(answer, required_fields):
missing = [field for field in required_fields if field not in answer]
extra = [field for field in answer if field not in required_fields]
return {"valid": not missing, "missing": missing, "extra": extra}
def main():
answer = {"what": "结构化输出", "why": "便于程序检查", "how": "先定义字段再生成"}
review = validate_structured_answer(answer, ["what", "why", "how"])
report = {"topic": TOPIC, "answer": answer, "review": review}
path = write_json("llm_structure_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day85:LLM 输出限制与公开说明
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
LLM 输出限制与公开说明 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day86 - Agent Tool 模块边界
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Agent Tool 模块边界 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day85
- 下一站:Day87
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Agent Tool 模块边界 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
tool schema | 工具名和参数 | 可校验调用 | 让 Agent 不乱传参 |
state | 当前任务状态 | 下一步动作 | 把多步任务串起来 |
observation | 工具执行结果 | 反馈信息 | 决定是否重试或停止 |
audit log | 每一步动作 | 审查记录 | 保留人工复盘入口 |
What
Agent Tool 模块边界 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
tool_contract = {"name": "search_notes", "input": ["query"], "output": ["matches"]}
call = {"name": "search_notes", "args": {"query": "json"}}
missing_args = [arg for arg in tool_contract["input"] if arg not in call["args"]]
print({"tool": call["name"], "missing_args": missing_args, "boundary_ok": not missing_args})
参数拆解方法
第一次看到 Agent Tool 模块边界 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Agent Tool 模块边界 的最小输入对象 |
| 工具参数 | Agent 调用工具时要传什么 | query 是检索词 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先做 schema 校验。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day086/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Agent Tool 模块边界 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 86
TOPIC = "Agent Tool 模块边界"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_tool_call(call, schemas):
if call["tool"] not in schemas:
return {"ok": False, "reason": "unknown tool"}
required = schemas[call["tool"]]["required"]
missing = [name for name in required if name not in call["args"]]
return {"ok": not missing, "missing": missing}
def main():
schemas = {"search_notes": {"required": ["query"]}, "save_report": {"required": ["path", "content"]}}
call = {"tool": "search_notes", "args": {"query": "json"}}
review = validate_tool_call(call, schemas)
report = {"topic": TOPIC, "call": call, "review": review, "next_state": "execute" if review["ok"] else "revise"}
path = write_json("agent_tool_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day86:Agent Tool 模块边界
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Agent Tool 模块边界 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day87 - Agent 工具 Schema 与校验
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Agent 工具 Schema 与校验 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day86
- 下一站:Day88
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Agent 工具 Schema 与校验 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
tool schema | 工具名和参数 | 可校验调用 | 让 Agent 不乱传参 |
state | 当前任务状态 | 下一步动作 | 把多步任务串起来 |
observation | 工具执行结果 | 反馈信息 | 决定是否重试或停止 |
audit log | 每一步动作 | 审查记录 | 保留人工复盘入口 |
What
Agent 工具 Schema 与校验 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
schema = {"query": str, "limit": int}
payload = {"query": "agent memory", "limit": "3"}
errors = []
for key, expected_type in schema.items():
if key not in payload or not isinstance(payload[key], expected_type):
errors.append(key)
print({"payload": payload, "schema_errors": errors})
参数拆解方法
第一次看到 Agent 工具 Schema 与校验 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Agent 工具 Schema 与校验 的最小输入对象 |
| 工具参数 | Agent 调用工具时要传什么 | query 是检索词 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先做 schema 校验。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day087/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Agent 工具 Schema 与校验 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 87
TOPIC = "Agent 工具 Schema 与校验"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_tool_call(call, schemas):
if call["tool"] not in schemas:
return {"ok": False, "reason": "unknown tool"}
required = schemas[call["tool"]]["required"]
missing = [name for name in required if name not in call["args"]]
return {"ok": not missing, "missing": missing}
def main():
schemas = {"search_notes": {"required": ["query"]}, "save_report": {"required": ["path", "content"]}}
call = {"tool": "search_notes", "args": {"query": "json"}}
review = validate_tool_call(call, schemas)
report = {"topic": TOPIC, "call": call, "review": review, "next_state": "execute" if review["ok"] else "revise"}
path = write_json("agent_tool_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day87:Agent 工具 Schema 与校验
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Agent 工具 Schema 与校验 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day88 - Agent 执行、错误恢复与日志
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Agent 执行、错误恢复与日志 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day87
- 下一站:Day89
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Agent 执行、错误恢复与日志 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
tool schema | 工具名和参数 | 可校验调用 | 让 Agent 不乱传参 |
state | 当前任务状态 | 下一步动作 | 把多步任务串起来 |
observation | 工具执行结果 | 反馈信息 | 决定是否重试或停止 |
audit log | 每一步动作 | 审查记录 | 保留人工复盘入口 |
What
Agent 执行、错误恢复与日志 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
steps = ["plan", "call_tool", "observe", "retry", "finish"]
trace = []
for step in steps:
status = "failed" if step == "call_tool" else "ok"
trace.append({"step": step, "status": status})
if status == "failed":
trace.append({"step": "recover", "status": "retry scheduled"})
print({"trace": trace})
参数拆解方法
第一次看到 Agent 执行、错误恢复与日志 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Agent 执行、错误恢复与日志 的最小输入对象 |
| 工具参数 | Agent 调用工具时要传什么 | query 是检索词 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先做 schema 校验。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day088/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Agent 执行、错误恢复与日志 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 88
TOPIC = "Agent 执行、错误恢复与日志"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_tool_call(call, schemas):
if call["tool"] not in schemas:
return {"ok": False, "reason": "unknown tool"}
required = schemas[call["tool"]]["required"]
missing = [name for name in required if name not in call["args"]]
return {"ok": not missing, "missing": missing}
def main():
schemas = {"search_notes": {"required": ["query"]}, "save_report": {"required": ["path", "content"]}}
call = {"tool": "search_notes", "args": {"query": "json"}}
review = validate_tool_call(call, schemas)
report = {"topic": TOPIC, "call": call, "review": review, "next_state": "execute" if review["ok"] else "revise"}
path = write_json("agent_tool_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day88:Agent 执行、错误恢复与日志
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Agent 执行、错误恢复与日志 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day89 - Agent 状态存储与人工审查
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Agent 状态存储与人工审查 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day88
- 下一站:Day90
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Agent 状态存储与人工审查 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
tool schema | 工具名和参数 | 可校验调用 | 让 Agent 不乱传参 |
state | 当前任务状态 | 下一步动作 | 把多步任务串起来 |
observation | 工具执行结果 | 反馈信息 | 决定是否重试或停止 |
audit log | 每一步动作 | 审查记录 | 保留人工复盘入口 |
What
Agent 状态存储与人工审查 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
state = {"task": "整理 JSON 笔记", "risk": "medium", "draft_ready": True}
review_required = state["risk"] in {"medium", "high"}
next_action = "human_review" if review_required else "auto_save"
print({"state": state, "next_action": next_action})
参数拆解方法
第一次看到 Agent 状态存储与人工审查 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Agent 状态存储与人工审查 的最小输入对象 |
| 工具参数 | Agent 调用工具时要传什么 | query 是检索词 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先做 schema 校验。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day089/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Agent 状态存储与人工审查 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 89
TOPIC = "Agent 状态存储与人工审查"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_tool_call(call, schemas):
if call["tool"] not in schemas:
return {"ok": False, "reason": "unknown tool"}
required = schemas[call["tool"]]["required"]
missing = [name for name in required if name not in call["args"]]
return {"ok": not missing, "missing": missing}
def main():
schemas = {"search_notes": {"required": ["query"]}, "save_report": {"required": ["path", "content"]}}
call = {"tool": "search_notes", "args": {"query": "json"}}
review = validate_tool_call(call, schemas)
report = {"topic": TOPIC, "call": call, "review": review, "next_state": "execute" if review["ok"] else "revise"}
path = write_json("agent_tool_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day89:Agent 状态存储与人工审查
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Agent 状态存储与人工审查 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day90 - Agent 工作流端到端原理
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 Agent 工作流端到端原理 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day89
- 下一站:Day91
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 Agent 工作流端到端原理 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
tool schema | 工具名和参数 | 可校验调用 | 让 Agent 不乱传参 |
state | 当前任务状态 | 下一步动作 | 把多步任务串起来 |
observation | 工具执行结果 | 反馈信息 | 决定是否重试或停止 |
audit log | 每一步动作 | 审查记录 | 保留人工复盘入口 |
What
Agent 工作流端到端原理 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
workflow = [
{"stage": "plan", "output": "tool_choice"},
{"stage": "execute", "output": "observation"},
{"stage": "review", "output": "final_answer"},
]
print({"workflow_order": [item["stage"] for item in workflow], "final_output": workflow[-1]["output"]})
参数拆解方法
第一次看到 Agent 工作流端到端原理 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | Agent 工作流端到端原理 的最小输入对象 |
| 工具参数 | Agent 调用工具时要传什么 | query 是检索词 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先做 schema 校验。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day090/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 Agent 工作流端到端原理 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 90
TOPIC = "Agent 工作流端到端原理"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def validate_tool_call(call, schemas):
if call["tool"] not in schemas:
return {"ok": False, "reason": "unknown tool"}
required = schemas[call["tool"]]["required"]
missing = [name for name in required if name not in call["args"]]
return {"ok": not missing, "missing": missing}
def main():
schemas = {"search_notes": {"required": ["query"]}, "save_report": {"required": ["path", "content"]}}
call = {"tool": "search_notes", "args": {"query": "json"}}
review = validate_tool_call(call, schemas)
report = {"topic": TOPIC, "call": call, "review": review, "next_state": "execute" if review["ok"] else "revise"}
path = write_json("agent_tool_review.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day90:Agent 工作流端到端原理
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
Agent 工作流端到端原理 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day91 - RAG 模块边界
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 RAG 模块边界 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day90
- 下一站:Day92
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 RAG 模块边界 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
document | 原始文本 | 可检索材料 | RAG 的知识来源 |
chunk | 文本片段 | 索引单元 | 控制检索粒度 |
similarity | query 和 chunk | 相似度分数 | 决定引用哪段材料 |
citation | 来源编号 | 可追溯回答 | 防止没有来源的编造 |
What
RAG 模块边界 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
rag_parts = {
"loader": "读取文档",
"splitter": "切分片段",
"retriever": "找相关内容",
"answerer": "带来源回答",
}
print({"module_order": list(rag_parts), "has_source_step": "retriever" in rag_parts})
参数拆解方法
第一次看到 RAG 模块边界 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | RAG 模块边界 的最小输入对象 |
| 检索参数 | 它决定取哪些来源 | top_k 是返回片段数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先看来源是否足够。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day091/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 RAG 模块边界 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 91
TOPIC = "RAG 模块边界"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def retrieve(query, documents):
hits = []
for doc in documents:
if query in doc["text"]:
hits.append({"id": doc["id"], "text": doc["text"]})
return hits
def main():
documents = [{"id": "d1", "text": "CSV 适合表格"}, {"id": "d2", "text": "JSON 适合嵌套结构"}]
hits = retrieve("嵌套", documents)
report = {"topic": TOPIC, "answer": hits[0]["text"] if hits else "没有可靠来源", "sources": [hit["id"] for hit in hits]}
path = write_json("rag_source_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day91:RAG 模块边界
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
RAG 模块边界 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day92 - RAG 索引与检索层
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 RAG 索引与检索层 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day91
- 下一站:Day93
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 RAG 索引与检索层 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
document | 原始文本 | 可检索材料 | RAG 的知识来源 |
chunk | 文本片段 | 索引单元 | 控制检索粒度 |
similarity | query 和 chunk | 相似度分数 | 决定引用哪段材料 |
citation | 来源编号 | 可追溯回答 | 防止没有来源的编造 |
What
RAG 索引与检索层 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
chunks = ["csv reader writer", "json nested dict", "class self method"]
index = {}
for chunk_id, chunk in enumerate(chunks):
for token in chunk.split():
index.setdefault(token, []).append(chunk_id)
print({"token": "json", "matching_chunks": index.get("json", [])})
参数拆解方法
第一次看到 RAG 索引与检索层 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | RAG 索引与检索层 的最小输入对象 |
| 检索参数 | 它决定取哪些来源 | top_k 是返回片段数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先看来源是否足够。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day092/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 RAG 索引与检索层 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 92
TOPIC = "RAG 索引与检索层"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def retrieve(query, documents):
hits = []
for doc in documents:
if query in doc["text"]:
hits.append({"id": doc["id"], "text": doc["text"]})
return hits
def main():
documents = [{"id": "d1", "text": "CSV 适合表格"}, {"id": "d2", "text": "JSON 适合嵌套结构"}]
hits = retrieve("嵌套", documents)
report = {"topic": TOPIC, "answer": hits[0]["text"] if hits else "没有可靠来源", "sources": [hit["id"] for hit in hits]}
path = write_json("rag_source_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day92:RAG 索引与检索层
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
RAG 索引与检索层 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day93 - RAG 回答 Prompt 与来源引用
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 RAG 回答 Prompt 与来源引用 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day92
- 下一站:Day94
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 RAG 回答 Prompt 与来源引用 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
document | 原始文本 | 可检索材料 | RAG 的知识来源 |
chunk | 文本片段 | 索引单元 | 控制检索粒度 |
similarity | query 和 chunk | 相似度分数 | 决定引用哪段材料 |
citation | 来源编号 | 可追溯回答 | 防止没有来源的编造 |
What
RAG 回答 Prompt 与来源引用 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
hits = [{"id": "d2", "text": "JSON 适合嵌套结构", "score": 0.82}]
answer = "JSON 适合嵌套结构。"
citations = [hit["id"] for hit in hits if hit["score"] >= 0.5]
print({"answer": answer, "citations": citations, "grounded": bool(citations)})
参数拆解方法
第一次看到 RAG 回答 Prompt 与来源引用 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | RAG 回答 Prompt 与来源引用 的最小输入对象 |
| 检索参数 | 它决定取哪些来源 | top_k 是返回片段数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先看来源是否足够。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day093/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 RAG 回答 Prompt 与来源引用 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 93
TOPIC = "RAG 回答 Prompt 与来源引用"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def retrieve(query, documents):
hits = []
for doc in documents:
if query in doc["text"]:
hits.append({"id": doc["id"], "text": doc["text"]})
return hits
def main():
documents = [{"id": "d1", "text": "CSV 适合表格"}, {"id": "d2", "text": "JSON 适合嵌套结构"}]
hits = retrieve("嵌套", documents)
report = {"topic": TOPIC, "answer": hits[0]["text"] if hits else "没有可靠来源", "sources": [hit["id"] for hit in hits]}
path = write_json("rag_source_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day93:RAG 回答 Prompt 与来源引用
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
RAG 回答 Prompt 与来源引用 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day94 - RAG 评估与错误案例
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 RAG 评估与错误案例 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day93
- 下一站:Day95
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 RAG 评估与错误案例 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
document | 原始文本 | 可检索材料 | RAG 的知识来源 |
chunk | 文本片段 | 索引单元 | 控制检索粒度 |
similarity | query 和 chunk | 相似度分数 | 决定引用哪段材料 |
citation | 来源编号 | 可追溯回答 | 防止没有来源的编造 |
What
RAG 评估与错误案例 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
eval_cases = [
{"answer": "有来源", "sources": ["d1"], "label": "ok"},
{"answer": "确定正确", "sources": [], "label": "hallucination_risk"},
]
error_cases = [case for case in eval_cases if not case["sources"]]
print({"total": len(eval_cases), "error_cases": error_cases})
参数拆解方法
第一次看到 RAG 评估与错误案例 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | RAG 评估与错误案例 的最小输入对象 |
| 检索参数 | 它决定取哪些来源 | top_k 是返回片段数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先看来源是否足够。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day094/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 RAG 评估与错误案例 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 94
TOPIC = "RAG 评估与错误案例"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def retrieve(query, documents):
hits = []
for doc in documents:
if query in doc["text"]:
hits.append({"id": doc["id"], "text": doc["text"]})
return hits
def main():
documents = [{"id": "d1", "text": "CSV 适合表格"}, {"id": "d2", "text": "JSON 适合嵌套结构"}]
hits = retrieve("嵌套", documents)
report = {"topic": TOPIC, "answer": hits[0]["text"] if hits else "没有可靠来源", "sources": [hit["id"] for hit in hits]}
path = write_json("rag_source_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day94:RAG 评估与错误案例
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
RAG 评估与错误案例 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day95 - RAG 限制、复盘与公开说明
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 RAG 限制、复盘与公开说明 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day94
- 下一站:Day96
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 RAG 限制、复盘与公开说明 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
document | 原始文本 | 可检索材料 | RAG 的知识来源 |
chunk | 文本片段 | 索引单元 | 控制检索粒度 |
similarity | query 和 chunk | 相似度分数 | 决定引用哪段材料 |
citation | 来源编号 | 可追溯回答 | 防止没有来源的编造 |
What
RAG 限制、复盘与公开说明 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
limitations = ["资料可能过期", "检索不到不代表不存在", "回答必须保留来源"]
public_note = ";".join(limitations)
print({"limitations": limitations, "public_note": public_note})
参数拆解方法
第一次看到 RAG 限制、复盘与公开说明 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | RAG 限制、复盘与公开说明 的最小输入对象 |
| 检索参数 | 它决定取哪些来源 | top_k 是返回片段数 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先看来源是否足够。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day095/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 RAG 限制、复盘与公开说明 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 95
TOPIC = "RAG 限制、复盘与公开说明"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def retrieve(query, documents):
hits = []
for doc in documents:
if query in doc["text"]:
hits.append({"id": doc["id"], "text": doc["text"]})
return hits
def main():
documents = [{"id": "d1", "text": "CSV 适合表格"}, {"id": "d2", "text": "JSON 适合嵌套结构"}]
hits = retrieve("嵌套", documents)
report = {"topic": TOPIC, "answer": hits[0]["text"] if hits else "没有可靠来源", "sources": [hit["id"] for hit in hits]}
path = write_json("rag_source_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day95:RAG 限制、复盘与公开说明
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
RAG 限制、复盘与公开说明 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day96 - GitHub Pages 与课程网站维护
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 GitHub Pages 与课程网站维护 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day95
- 下一站:Day97
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 GitHub Pages 与课程网站维护 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
index | 课程/项目清单 | 能力地图 | 知道自己学到哪里 |
checklist | 检查项 | 缺口列表 | 维护长期项目质量 |
README | 项目说明 | 公开展示材料 | 让别人能看懂仓库 |
review log | 错误和修复 | 长期记忆 | 降低未来重复踩坑 |
What
GitHub Pages 与课程网站维护 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
site_files = ["index.html", "mobile.html", "Python100-v1.md"]
required = ["index.html", "Python100-v1.md"]
missing = [name for name in required if name not in site_files]
print({"pages_ready": not missing, "missing": missing})
参数拆解方法
第一次看到 GitHub Pages 与课程网站维护 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | GitHub Pages 与课程网站维护 的最小输入对象 |
| 检查项 | 它验证哪个长期资产 | README 是否可运行 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先留下证据文件。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day096/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 GitHub Pages 与课程网站维护 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 96
TOPIC = "GitHub Pages 与课程网站维护"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def build_learning_index(items):
index = {}
for item in items:
key = item["day"]
index[key] = {"topic": item["topic"], "evidence": item["evidence"]}
return index
def main():
items = [{"day": "Day13", "topic": "JSON", "evidence": "json_report"}, {"day": "Day15", "topic": "dataclass", "evidence": "class_report"}]
report = {"topic": TOPIC, "index": build_learning_index(items)}
path = write_json("maintenance_index_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day96:GitHub Pages 与课程网站维护
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
GitHub Pages 与课程网站维护 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day97 - 知识索引与能力清单
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 知识索引与能力清单 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day96
- 下一站:Day98
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 知识索引与能力清单 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
index | 课程/项目清单 | 能力地图 | 知道自己学到哪里 |
checklist | 检查项 | 缺口列表 | 维护长期项目质量 |
README | 项目说明 | 公开展示材料 | 让别人能看懂仓库 |
review log | 错误和修复 | 长期记忆 | 降低未来重复踩坑 |
What
知识索引与能力清单 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
skills = [
{"name": "JSON", "evidence": "Day13 output"},
{"name": "class", "evidence": "Day15 dataclass"},
{"name": "pandas", "evidence": "Day20 groupby"},
]
index = {item["name"]: item["evidence"] for item in skills}
print({"skill_index": index})
参数拆解方法
第一次看到 知识索引与能力清单 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 知识索引与能力清单 的最小输入对象 |
| 检查项 | 它验证哪个长期资产 | README 是否可运行 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先留下证据文件。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day097/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 知识索引与能力清单 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 97
TOPIC = "知识索引与能力清单"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def build_learning_index(items):
index = {}
for item in items:
key = item["day"]
index[key] = {"topic": item["topic"], "evidence": item["evidence"]}
return index
def main():
items = [{"day": "Day13", "topic": "JSON", "evidence": "json_report"}, {"day": "Day15", "topic": "dataclass", "evidence": "class_report"}]
report = {"topic": TOPIC, "index": build_learning_index(items)}
path = write_json("maintenance_index_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day97:知识索引与能力清单
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
知识索引与能力清单 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day98 - 技术讲解脚本与面试表达
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 技术讲解脚本与面试表达 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day97
- 下一站:Day99
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 技术讲解脚本与面试表达 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
index | 课程/项目清单 | 能力地图 | 知道自己学到哪里 |
checklist | 检查项 | 缺口列表 | 维护长期项目质量 |
README | 项目说明 | 公开展示材料 | 让别人能看懂仓库 |
review log | 错误和修复 | 长期记忆 | 降低未来重复踩坑 |
What
技术讲解脚本与面试表达 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
script = {
"problem": "为什么要学 JSON",
"mechanism": "dict/list 可以保存成跨语言格式",
"example": "学习日志保存为 records.json",
}
print(" -> ".join(script.values()))
参数拆解方法
第一次看到 技术讲解脚本与面试表达 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 技术讲解脚本与面试表达 的最小输入对象 |
| 检查项 | 它验证哪个长期资产 | README 是否可运行 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先留下证据文件。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day098/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 技术讲解脚本与面试表达 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 98
TOPIC = "技术讲解脚本与面试表达"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def build_learning_index(items):
index = {}
for item in items:
key = item["day"]
index[key] = {"topic": item["topic"], "evidence": item["evidence"]}
return index
def main():
items = [{"day": "Day13", "topic": "JSON", "evidence": "json_report"}, {"day": "Day15", "topic": "dataclass", "evidence": "class_report"}]
report = {"topic": TOPIC, "index": build_learning_index(items)}
path = write_json("maintenance_index_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day98:技术讲解脚本与面试表达
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
技术讲解脚本与面试表达 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day99 - 错误库、片段库与长期维护
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 错误库、片段库与长期维护 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day98
- 下一站:Day100
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 错误库、片段库与长期维护 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
index | 课程/项目清单 | 能力地图 | 知道自己学到哪里 |
checklist | 检查项 | 缺口列表 | 维护长期项目质量 |
README | 项目说明 | 公开展示材料 | 让别人能看懂仓库 |
review log | 错误和修复 | 长期记忆 | 降低未来重复踩坑 |
What
错误库、片段库与长期维护 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
error_library = [
{"error": "KeyError", "fix": "先检查字段是否存在"},
{"error": "TypeError", "fix": "打印 type 再转换"},
]
snippets = {item["error"]: item["fix"] for item in error_library}
print({"known_errors": snippets})
参数拆解方法
第一次看到 错误库、片段库与长期维护 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | 错误库、片段库与长期维护 的最小输入对象 |
| 检查项 | 它验证哪个长期资产 | README 是否可运行 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先留下证据文件。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day099/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 错误库、片段库与长期维护 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 99
TOPIC = "错误库、片段库与长期维护"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def build_learning_index(items):
index = {}
for item in items:
key = item["day"]
index[key] = {"topic": item["topic"], "evidence": item["evidence"]}
return index
def main():
items = [{"day": "Day13", "topic": "JSON", "evidence": "json_report"}, {"day": "Day15", "topic": "dataclass", "evidence": "class_report"}]
report = {"topic": TOPIC, "index": build_learning_index(items)}
path = write_json("maintenance_index_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day99:错误库、片段库与长期维护
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
错误库、片段库与长期维护 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。
Day100 - AI Builder Python Roadmap 总复盘
> 阶段三以后:专项知识
学习定位
今天只学习一个核心主题:把 AI Builder Python Roadmap 总复盘 学成可运行、可解释、可迁移的知识点。
目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。
Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。
前置知识
- 上一站:Day99
- 下一站:IC50 / 后续路径
- 必须先会:文件路径、函数、列表或字典的基本操作。
认知地图
先看全局,不直接上复杂代码。
| 层级 | 你要回答的问题 | 本日要求 |
|---|
| What | 它是什么 | 用一句话讲清概念 |
| Why | 为什么存在 | 说清不用它会怎样 |
| How | 怎么做 | 写出最小可运行代码 |
| Error | 怎么错 | 能定位 3 类常见错误 |
| Future | 哪里复用 | 连接数据、Quant、LLM、Agent |
工具地图
今天先把 AI Builder Python Roadmap 总复盘 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。
| 工具 / 对象 | 输入 | 输出 | 适用场景 |
|---|
index | 课程/项目清单 | 能力地图 | 知道自己学到哪里 |
checklist | 检查项 | 缺口列表 | 维护长期项目质量 |
README | 项目说明 | 公开展示材料 | 让别人能看懂仓库 |
review log | 错误和修复 | 长期记忆 | 降低未来重复踩坑 |
What
AI Builder Python Roadmap 总复盘 是 Python 工业化学习中的一个小能力。
它的核心是把“人能看懂的东西”变成“程序也能稳定读取、处理和复查的结构”。
学习时不要只看函数名,要同时看三件事:
1. 输入数据长什么样。
2. 输出结果长什么样。
3. 错误发生时从哪里开始查。
Why
如果不先建立这张地图,你会出现一种很常见的卡点:代码每一行好像都认识,但不知道为什么要这样组合。
例如你看到一个新库时,真正要问的不是“这个函数怎么背”,而是:
- 它把什么变成什么?
- 它替我省掉了哪一步手工处理?
- 它的返回值还能继续调用什么?
- 它和前一天学过的知识有什么关系?
How:最小流程
先写一个只验证本日核心概念的最小例子。今天的重点不是功能多,而是你能说清楚:哪一行负责输入,哪一行负责处理,哪一行给出输出。
milestones = ["Python basics", "Data analysis", "Quant concepts", "LLM basics", "Agent workflow"]
finished = {name: True for name in milestones}
next_gap = [name for name, done in finished.items() if not done]
print({"finished_count": sum(finished.values()), "next_gap": next_gap})
参数拆解方法
第一次看到 AI Builder Python Roadmap 总复盘 相关函数、类或配置时,按下面 5 步拆。不要只记名字,要把它放回输入输出关系里。
| 位置 | 要问的问题 | 本日例子 |
|---|
| 对象 | 这次处理的核心对象是什么 | AI Builder Python Roadmap 总复盘 的最小输入对象 |
| 检查项 | 它验证哪个长期资产 | README 是否可运行 |
| 处理动作 | 代码把输入转换成什么 | 清洗、计算、校验、检索或保存 |
| 边界条件 | 什么输入会让结果不可靠 | 空值、错类型、缺字段、窗口太短 |
| 返回值 | 后面还能继续做什么 | 保存 JSON、生成报告、进入 IC 任务 |
本日检查顺序:先看输入形状,再看处理动作,最后看输出文件。先留下证据文件。
和旧知识的连接
新知识不是突然出现的,它通常是旧知识的升级版。
| 旧知识 | 新知识 | 升级点 |
|---|
| 字符串 | 结构化字段 | 从一整段文本变成可定位字段 |
| list | 表格行 | 一行数据可以稳定遍历 |
| dict | 字段记录 | 可以用字段名读取 |
| 文件读写 | 库读写 | 不再手工拼格式 |
| 函数 | 可复用流程 | 同一个处理逻辑可以重复调用 |
Common Errors
| 错误 | 表现 | 定位方法 |
|---|
| 路径错 | 找不到文件 | print(Path.cwd()) 和 path.resolve() |
| 类型错 | 字符串当数字算 | print(type(value)) |
| 返回值没看 | 后续代码接不上 | 先 print(result) |
| 一次写太多 | Debug 找不到点 | 拆成 5 行以内最小复现 |
| 只复制不解释 | 换数据就不会改 | 写 notes 解释输入输出 |
Future Usage
这个知识后面会进入四类场景:
- 数据分析:读取、清洗、聚合、图表、报告。
- Quant:行情、因子、回测、风险指标。
- LLM:上下文、结构化输出、评估样例。
- Agent:Tool 参数、执行日志、状态存储。
4 小时学习节奏
| 时间 | 做什么 | 产物 |
|---|
| 30 分钟 | 读认知地图 | notes 5 行 |
| 60 分钟 | 手打最小代码 | main.py |
| 45 分钟 | 改 2 个输入样例 | output 截图或文本 |
| 45 分钟 | 故意制造错误 | errors.md |
| 40 分钟 | 写复盘 | README 片段 |
今日强化题(带具体代码)
> 每天正文上限控制在 600 行以内。强化题不是口头描述,必须能落到 main.py 运行。
强化题 1:复现最小案例
任务:把下面参考代码复制到 main.py,先不要改,直接运行。
验收:终端能打印 JSON,且本地生成 outputs/day100/。
强化题 2:替换输入
任务:只改输入数据,至少新增 2 条样例。
验收:输出数量、均值、跳过记录或检索结果发生合理变化。
强化题 3:边界检查
任务:制造 1 个坏输入,例如空值、重复值、非法字段或极端价格。
验收:程序不会静默失败;你能在输出或 errors.md 里解释原因。
强化题 4:结果保存
任务:把运行结果保存到 JSON、CSV、Markdown 或 SQLite 中的一种。
验收:关闭终端后,仍能从文件复查今天结果。
强化题 5:迁移说明
任务:写 3 句话说明 AI Builder Python Roadmap 总复盘 会如何迁移到 Data、Quant、LLM 或 Agent。
验收:不是写“以后有用”,而是写清具体场景。
参考代码:main.py
from pathlib import Path
import json
DAY = 100
TOPIC = "AI Builder Python Roadmap 总复盘"
ROOT = Path(__file__).resolve().parent
OUT = ROOT / "outputs" / f"day{DAY:03d}"
def write_json(name, payload):
OUT.mkdir(parents=True, exist_ok=True)
path = OUT / name
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def build_learning_index(items):
index = {}
for item in items:
key = item["day"]
index[key] = {"topic": item["topic"], "evidence": item["evidence"]}
return index
def main():
items = [{"day": "Day13", "topic": "JSON", "evidence": "json_report"}, {"day": "Day15", "topic": "dataclass", "evidence": "class_report"}]
report = {"topic": TOPIC, "index": build_learning_index(items)}
path = write_json("maintenance_index_report.json", report)
print(json.dumps({"saved_to": str(path), **report}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
运行命令
python main.py
Debug 记录要求
错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:
今日复盘模板
Day100:AI Builder Python Roadmap 总复盘
我今天学会了什么:
这个工具的输入是什么:
这个工具的输出是什么:
我遇到的错误:
我是怎么定位的:
未来会在哪个 IC 使用:
加厚理解:具体执行步骤
加厚不是把同一句话重复很多遍,也不是提前做完整项目。
这一节的加厚只做 8 层,每一层都有明确产出。做完这 8 层,才算从“看过知识点”进入“能迁移使用”。
第 1 层:认知地图
回答 3 个问题:
AI Builder Python Roadmap 总复盘 解决什么问题?
- 它的核心对象、函数或概念有哪些?
- 它和前面已经学过的哪个知识点相连?
产出:在 notes.md 写 5 行以内的知识地图。
第 2 层:输入 -> 处理 -> 输出
把本节内容压成一张表:
| 部分 | 你要写清楚什么 |
|---|
| 输入 | 数据、参数、文件、用户输入或模型上下文从哪里来 |
| 处理 | 中间做了哪一步转换、判断、计算或校验 |
| 输出 | 输出到屏幕、文件、数据库、图表、日志还是返回值 |
产出:写出 1 个最小输入和 1 个最小输出。
第 3 层:最小可运行代码
只写一个最小例子,不加复杂功能。
要求:
- 能直接运行。
- 代码不超过 30 行。
- 只验证一个核心概念。
- 运行后能看到明确输出。
产出:main.py。
第 4 层:逐对象拆解
第一次出现的新函数、新类、新参数,必须拆开。
格式:
对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:
产出:notes.md 里的“对象拆解”小节。
第 5 层:错误实验
主动制造 2 个错误,而不是等报错后慌。
例子:
- 路径写错。
- 类型传错。
- 字段名不存在。
- 空数据。
- 编码不对。
- 边界条件为 0 或空列表。
产出:errors.md,记录错误信息、原因和修复方式。
第 6 层:旧知识连接
写清楚它不是凭空出现的新知识。
模板:
昨天/之前我会:
今天升级成:
升级后解决的问题:
产出:3 行连接说明。
第 7 层:迁移场景
至少连接到一个方向:
- Data:它如何帮助数据清洗、分析、可视化或报告。
- Quant:它如何帮助行情、指标、回测、风险或实验记录。
- LLM:它如何帮助 prompt、context、embedding、RAG 或 evaluation。
- Agent:它如何帮助 tool、memory、workflow、logging 或 review。
产出:选择 1 个方向,写 3 句话。
第 8 层:IC100 衔接
找到一个最近的 IC,把今天的知识放进去用一次。
要求:
- 不做大项目。
- 只完成一个小动作。
- 留下 GitHub commit。
- 在 review 里写清今天知识点怎么被用到。
产出:对应 IC 的 review.md 或当天提交说明。
30 分钟加厚执行清单
5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明
判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。