AI Builder Python100

开源 100 天课程:Python + Data + Quant + LLM + Agent

成长路线图

这个仓库不是单纯的语法教程,而是一条从 Python 零基础走向 AI Builder 和 Quant Researcher 的成长路径。

阶段视图

阶段主线能力结果
Day01-Day15Python 基础能写输入、判断、循环、列表、函数和简单数据对象
Day16-Day30函数 + 数据结构能把脚本组织成可运行、可测试、可复查的小工具
Day31-Day45SQL + Linux能使用本地数据库、命令行、API、Web 工具和轻量交付方式
Day46-Day60项目开发能搭建 LLM/RAG/Agent 原型,并记录评估、日志和边界
Day61-Day80数据工程能处理行情数据、指标、回测、结果存储和研究报告
Day81-Day100Agent + Quant 准备能把项目整理成作品集,并进入更系统的 Agent、Quant 和面试题训练

双版本定位

成长资产

公开仓库保留课程、练习、项目说明和精选学习方法。本地 Vault 保留更细的真实过程,例如语法错误、缩进错误、REPL 使用、变量命名误区和算法模式沉淀。

这些真实错误不是噪音,而是长期学习资产。它们会逐步转化为 Debug 能力、工程判断和项目复盘能力。

Day01 - Python 环境与第一段程序

> 阶段一:Python 基础

学习定位

今天只学习一个核心主题:Python 环境与第一段程序 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day02 - 变量、类型与输入输出

> 阶段一:Python 基础

学习定位

今天只学习一个核心主题:变量、类型与输入输出 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day03 - 分支结构与输入验证

> 阶段一:Python 基础

学习定位

今天只学习一个核心主题:分支结构与输入验证 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day04 - 循环、计数器与重复任务

> 阶段一:Python 基础

学习定位

今天只学习一个核心主题:循环、计数器与重复任务 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day05 - 列表与最小算法

> 阶段一:Python 基础

学习定位

今天只学习一个核心主题:列表与最小算法 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day06 - 函数、参数与返回值

> 阶段一:Python 基础

学习定位

今天只学习一个核心主题:函数、参数与返回值 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day07 - 字符串、字典与集合

> 阶段一:Python 基础

学习定位

今天只学习一个核心主题:字符串、字典与集合 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day08 - 文件读写与异常处理

> 阶段一:Python 零基础与语法地基

学习定位

读写文本文件,并处理文件不存在的情况。

今天的目标不是背语法,而是产出:一个能保存学习记录的脚本

前置知识

今日知识地图

核心讲解

今天的关键词是 读写文本文件,并处理文件不存在的情况。学习时不要只看语法表面,而要始终追问三件事:输入是什么、处理逻辑是什么、输出要给谁使用。这个习惯会贯穿数据分析、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("文件不存在,请先生成")

常见错误

工程应用

未来扩展

今天只做最小闭环。后续可以逐步加入测试、日志、配置、页面、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)

执行顺序:

顺序代码发生了什么
1Path("note.txt")创建一个指向文件路径的对象
2write_text(...)把文本写入这个文件
3read_text(...)从这个文件读出文本
4print(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())

pwdPath.cwd() 通常应该对应同一个目录。比如你在桌面运行脚本,Path("log.txt") 就会在桌面生成 log.txt;你在主题目录运行脚本,它就会在主题目录生成。

Path 和 Mac 终端命令的对应关系

你想做的事Mac 终端Python Path
看当前目录pwdPath.cwd()
列出文件lslist(Path.cwd().iterdir())
创建目录mkdir notesPath("notes").mkdir(exist_ok=True)
进入目录cd notesPython 不常用 cd,通常直接写完整 Path
创建文件touch a.mdPath("a.md").write_text("", encoding="utf-8")
查看绝对路径pwd + 文件名Path("a.md").resolve()

终端命令更像“你手动操作文件系统”;Path 更像“让 Python 自动操作文件系统”。工程化脚本的价值就在这里:你不用每天手动 mkdirtouch,可以让 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 适合表格。选择文件格式,就是选择未来如何复查和复用数据。

手写顺序

今天必须真正弄懂

和后续知识的关系

日志、CSV、Markdown 报告、RAG 文档、回测结果都需要文件读写。今天练的是主题的输入输出层。

零基础拆解:文件输入输出和失败处理

这一天到底在练什么

文件让程序有了长期记忆。读文件是输入,写文件是输出,异常处理负责让失败变得可解释。

手写时按这个顺序

最常见卡点

路径错误最常见。先打印 Path.cwd() 看当前目录,再确认文件名、后缀和大小写。

自查问题

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day09 - 模块、包与可复用脚本

> 阶段一:Python 基础

学习定位

今天只学习一个核心主题:模块、包与可复用脚本 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day10 - 学习记录 CLI 基础

> 阶段一:Python 基础

学习定位

今天只学习一个核心主题:学习记录 CLI 基础 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 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,再做边界实验。

前置知识

认知地图

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文件新增多行批量写数据

今天只学这四个点,不学 DictReaderDictWriter。后者留到 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"))

这能跑,但问题是:

csv.writercsv.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 打印打印 rowtype(row)先看结构再计算

Common Errors

错误表现定位方法
忘记 newline=""CSV 中间出现多余空行写文件时固定加上 newline=""
row 当 dictrow["minutes"] 报错reader 输出 list,只能用下标
忘记跳过表头int("minutes") 报错header = next(reader)
数字没转换'35' + '45' 变成字符串拼接minutes = int(row[2])
路径不清楚找不到文件打印 Path.cwd()path.resolve()

Future Usage

4 小时学习节奏

时间做什么产物
30 分钟画 CSV -> list 的数据流notes.md
60 分钟手打 writer 和 readermain.py
45 分钟改 2 行输入样例records.csv
45 分钟故意制造表头/类型错误errors.md
40 分钟写迁移说明复盘 5 行

今日强化题(带具体代码)

强化题 1:复现最小案例

任务:复制下面代码到 main.py 并运行。

验收:终端打印 JSON,生成 outputs/day011/records.csvsummary.json

强化题 2:替换输入

任务:新增 2 行样例记录,至少一行数值字段大于当前样例。

验收:total_minuteslong_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"]

这一天的核心不是更高级,而是更可读、更稳、更接近真实数据分析。

前置知识

认知地图

工具输入输出适合什么
csv.DictReader(f)带表头的 CSV 文件一行行 dict用字段名读取记录
csv.DictWriter(f, fieldnames=...)文件对象 + 字段名writer 对象按字段名写 CSV
writer.writeheader()fieldnames表头行先写列名
writer.writerow(row)一个 dictCSV 一行写单条记录
writer.writerows(rows)多个 dictCSV 多行批量写记录

What

DictReader / DictWriter 是 CSV 工具里的“字段名版本”。

DictReader: CSV -> dict
DictWriter: dict -> CSV

Day11 的 row[2] 依赖列位置;Day12 的 row["minutes"] 依赖字段名。

真实数据里,字段名比位置更重要。你以后读外部数据、行情、评估集时,通常会关心 datecloselabelquestion 这些字段,而不是“第 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=[...])

部分含义为什么重要
csvCSV 标准库专门处理表格文本
DictWriterdict 写入 CSV 的类把字段名和列顺序绑定起来
f文件对象必须是可写文件,通常 "w" 模式
fieldnames表头字段列表决定 CSV 列名和列顺序
返回值 writer写入器对象继续调用 writeheader()writerow()writerows()

writer.writeheader()

部分含义
writer上一步创建的写入器
writeheader()fieldnames 写成 CSV 第一行
常见错误忘记写表头,后面 DictReader 就不知道字段名

csv.DictReader(f)

部分含义
DictReaderdict 读取器
f可读文件对象
输出每一行是 dict,key 来自表头
常见错误表头字段拼错,row["minutes"]KeyError

和旧知识的连接

Day11Day12升级点
row[2]row["minutes"]从位置意识升级到字段意识
list 行dict 记录字段含义更清楚
手工记列顺序fieldnames 固定表头输出更稳定
打印整行打印 row.keys()Debug 更容易

Common Errors

错误表现定位方法
fieldnames 缺字段写入时报错或字段丢失对比 records[0].keys()
忘记 writeheader()读回来第一行变字段名打开 CSV 看第一行
数字仍是字符串不能正确计算print(type(row["minutes"]))
字段名拼错KeyErrorprint(row.keys())
空值没处理int("") 报错转换前先判断

Future Usage

4 小时学习节奏

时间做什么产物
30 分钟对比 reader 和 DictReadernotes 表格
60 分钟手打 DictWriter / DictReadermain.py
45 分钟改字段名和列顺序errors.md
45 分钟加空值和坏数据skipped 输出
40 分钟写迁移说明review.md

今日强化题(带具体代码)

强化题 1:复现最小案例

任务:复制下面代码到 main.py 并运行。

验收:生成 outputs/day012/records.csvsummary.json

强化题 2:替换输入

任务:新增字段 source,例如 bookvideocodex

验收:你能说明为什么 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/listJSON 字符串打印、日志、网络传输
json.load(f)文件对象Python dict/list读取 .json 文件
json.dump(obj, f)Python dict/list + 文件对象.json 文件保存配置、结果、状态

JSON 与 Python 类型对应

JSONPython
objectdict
arraylist
stringstr
numberint / float
true / falseTrue / False
nullNone

What

JSON 本质是“长得像 dict/list 的文本”。它不是 Python 对象,必须经过解析。

import json

text = '{"name": "item_a", "value": 10}'
data = json.loads(text)
print(data)

text 是字符串,data 是 dict。这个区别非常重要。

Why

JSON 存在的原因是:不同程序、不同语言、不同机器之间需要一种通用结构化格式。

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)

参数含义易错点
objPython 对象不能包含函数、Path、set 等不可序列化对象
f文件对象要用 "w"encoding="utf-8"
返回值None它直接写文件,不返回字符串

Common Errors

错误表现修法
单引号写 JSONJSONDecodeErrorJSON 字符串用双引号
字符串当 dictTypeErrorjson.loads(text)
dumpdumps得到 Nonedump 写文件,dumps 返回字符串
顶层类型看错list/dict 取值方式错print(type(data))
写入 set/Pathnot JSON serializable先转成 list/str

今日强化题(带具体代码)

强化题 1:跑通四个函数

任务:运行下面代码,确认 loads/dumps/load/dump 都出现。

验收:生成 outputs/day013/records.jsonsummary.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 代表当前对象。

认知地图

概念写法含义
classclass Record:定义对象模板
objectRecord(...)创建具体对象
attributeself.value对象自己的数据
methoddef is_valid(self):对象自己的行为
selfself当前这个对象
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

错误表现修法
忘记 selfTypeError实例方法第一个参数写 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_dictto_dict、对象校验。

学完今天,基础 Python 第一阶段结束。Day16 开始进入数据分析三大库:NumPy、pandas、Matplotlib。

认知地图

工具输入输出作用
@dataclass字段声明自动生成初始化方法少写样板代码
类型标注value: float可读边界告诉人和工具字段类型
field(default_factory=list)可变默认值独立 list避免多个对象共享同一个 list
@classmethoddict / 外部数据对象常用于 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 能减少重复代码,并让结构更清楚。

它适合:

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 默认值写成 []多个对象共享 listfield(default_factory=list)
类型标注当强制校验运行时仍可能传错from_dict 里转换和检查
asdict 忘记导入NameErrorfrom dataclasses import asdict
from_dict 不处理缺字段后面才报错在入口统一校验

Future Usage

今日强化题(带具体代码)

强化题 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()listndarray创建数组
.shapendarray维度看行列结构
.dtypendarray数据类型看数字类型
.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)

参数含义注意
datalist 或嵌套 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 的核心价值:不用手写循环,对整列数据一次性计算

认知地图

工具输入输出用途
向量化arrayarray批量计算
布尔掩码条件True/False 数组筛选
np.where条件和两个值array条件分支
mean/std/quantilearray统计量数据体检

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)

参数含义
conditionTrue/False 数组
x条件为 True 时取的值
y条件为 False 时取的值

Common Errors

错误表现修法
数组长度没对齐shape mismatch检查切片长度
除以 0inf 或 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/listDataFrame创建表
.head()DataFrame前几行看样例
.shapeDataFrame行列数看规模
.dtypesDataFrame每列类型看类型
.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.jsoncleaned.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.csvgroup_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

三大库不是互相替代,而是分工:

How:三库综合流水线

records -> DataFrame -> clean -> NumPy metrics -> report -> plot

Common Errors

错误表现修法
所有事都用 pandas数值逻辑不清指标计算可拆到 NumPy
所有事都用 NumPy字段名丢失表格阶段用 pandas
图不保存无法复查固定输出文件

今日强化题(带具体代码)

强化题 1:跑通三库综合

验收:生成 analysis_report.jsoncleaned.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

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「缺失值、类型转换与清洗」完成 一个 clean DataFrame

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

缺失值、类型转换与清洗 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「to_datetime、to_numeric、dropna」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 缺失值、类型转换与清洗,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day25 - 分组聚合与业务指标

> 阶段三:数据分析与本地数据系统

学习定位

按类别计算 count、mean、std。

今天的目标不是背定义,而是产出:一张 summary 表

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「分组聚合与业务指标」完成 一张 summary 表

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

分组聚合与业务指标 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「groupby、agg、reset_index」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 分组聚合与业务指标,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day26 - 表连接、映射与维表

> 阶段三:数据分析与本地数据系统

学习定位

把事实表和维度表连接起来。

今天的目标不是背定义,而是产出:一张带行业/标签的分析表

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「表连接、映射与维表」完成 一张带行业/标签的分析表

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

表连接、映射与维表 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「merge、left join、维表」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 表连接、映射与维表,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day27 - 时间序列、滚动窗口与移动平均

> 阶段三:数据分析与本地数据系统

学习定位

处理按时间排序的数据和 rolling 指标。

今天的目标不是背定义,而是产出:一张带移动平均的时间序列表

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「时间序列、滚动窗口与移动平均」完成 一张带移动平均的时间序列表

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

时间序列、滚动窗口与移动平均 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「rolling、时间排序、移动平均」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 时间序列、滚动窗口与移动平均,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day28 - NumPy 数组与向量化计算

> 阶段三:数据分析与本地数据系统

学习定位

用数组方式计算收益率和统计量。

今天的目标不是背定义,而是产出:一个向量化收益率计算

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「NumPy 数组与向量化计算」完成 一个向量化收益率计算

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

NumPy 数组与向量化计算 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「np.array、切片、向量化」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 NumPy 数组与向量化计算,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day29 - 统计指标、样本量与置信思维

> 阶段三:数据分析与本地数据系统

学习定位

把均值、波动、标准误写成可解释函数。

今天的目标不是背定义,而是产出:一个统计 summary dict

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「统计指标、样本量与置信思维」完成 一个统计 summary dict

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

统计指标、样本量与置信思维 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「mean、std、standard error」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 统计指标、样本量与置信思维,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day30 - 可视化与 Markdown 报告

> 阶段三:数据分析与本地数据系统

学习定位

保存图表和文字报告。

今天的目标不是背定义,而是产出:一张图和一份 report.md

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「可视化与 Markdown 报告」完成 一张图和一份 report.md

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

可视化与 Markdown 报告 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「plot、savefig、Markdown」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 可视化与 Markdown 报告,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day31 - SQLite 本地数据库

> 阶段三:数据分析与本地数据系统

学习定位

把结构化结果保存到轻量数据库。

今天的目标不是背定义,而是产出:一个 research.db

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「SQLite 本地数据库」完成 一个 research.db

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

SQLite 本地数据库 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「sqlite3、CREATE TABLE、INSERT」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 SQLite 本地数据库,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day32 - SQL 查询、Join 与窗口意识

> 阶段三:数据分析与本地数据系统

学习定位

用 SQL 回答分析问题。

今天的目标不是背定义,而是产出:一个聚合查询和一个 join 查询

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「SQL 查询、Join 与窗口意识」完成 一个聚合查询和一个 join 查询

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

SQL 查询、Join 与窗口意识 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「SELECT、WHERE、GROUP BY」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 SQL 查询、Join 与窗口意识,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day33 - 配置文件与环境变量

> 阶段三:数据分析与本地数据系统

学习定位

把路径、参数和模式从代码里拿出来。

今天的目标不是背定义,而是产出:一个 config.json 和环境变量读取

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「配置文件与环境变量」完成 一个 config.json 和环境变量读取

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

配置文件与环境变量 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「json config、os.environ、默认值」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 配置文件与环境变量,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day34 - 数据校验与错误报告

> 阶段三:数据分析与本地数据系统

学习定位

把字段、类型、行数检查写成函数。

今天的目标不是背定义,而是产出:一个 validate_data() 函数

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「数据校验与错误报告」完成 一个 validate_data() 函数

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

数据校验与错误报告 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「required fields、error list、fail fast」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 数据校验与错误报告,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day35 - 本地指标管道原理

> 阶段三:数据分析与本地数据系统

学习定位

串联读取、清洗、聚合、报告。

今天的目标不是背定义,而是产出:一个本地可复现数据管道

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「本地指标管道原理」完成 一个本地可复现数据管道

这个问题在工程里不是孤立练习。它属于 数据分析与本地数据系统 阶段,目标是:把原始数据变成可检查、可保存、可复盘的数据资产。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

本地指标管道原理 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「pipeline、validate、summary」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 本地指标管道原理,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:数据分析与本地数据系统

阶段目标:把原始数据变成结构清楚、指标可信、结果可复查的数据资产。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day36 - 自动化文件整理与批处理

> 阶段四:应用接口、自动化与复盘

学习定位

批量处理文件并生成清单。

今天的目标不是背定义,而是产出:一个文件清单 CSV

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「自动化文件整理与批处理」完成 一个文件清单 CSV

这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

自动化文件整理与批处理 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「批量处理文件并生成清单、Path glob 扫描 files、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 自动化文件整理与批处理,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:应用复盘与轻量工程

阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day37 - HTTP、API 与 JSON 数据获取

> 阶段四:应用接口、自动化与复盘

学习定位

请求 API 并解析 JSON。

今天的目标不是背定义,而是产出:一个安全的 API client 雏形

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「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)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:应用复盘与轻量工程

阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day38 - 可重试 Data Client 与失败处理

> 阶段四:应用接口、自动化与复盘

学习定位

给网络请求加超时、重试、错误返回。

今天的目标不是背定义,而是产出:一个 fetch_json() 客户端

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「可重试 Data Client 与失败处理」完成 一个 fetch_json() 客户端

这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

可重试 Data Client 与失败处理 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「给网络请求加超时、重试、错误返回、retry timeout error、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 可重试 Data Client 与失败处理,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:应用复盘与轻量工程

阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day39 - FastAPI 最小服务

> 阶段四:应用接口、自动化与复盘

学习定位

把函数暴露成 HTTP API。

今天的目标不是背定义,而是产出:一个 /health 和 /metrics 服务

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「FastAPI 最小服务」完成 一个 /health 和 /metrics 服务

这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

FastAPI 最小服务 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把函数暴露成 HTTP API、FastAPI health GET、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 FastAPI 最小服务,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:应用复盘与轻量工程

阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day40 - Streamlit 数据看板

> 阶段四:应用接口、自动化与复盘

学习定位

把 CSV 和指标显示成页面。

今天的目标不是背定义,而是产出:一个上传 CSV 的本地看板

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「Streamlit 数据看板」完成 一个上传 CSV 的本地看板

这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

Streamlit 数据看板 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把 CSV 和指标显示成页面、Streamlit upload dataframe、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 Streamlit 数据看板,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:应用复盘与轻量工程

阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day41 - Docker 轻量运行说明

> 阶段四:应用接口、自动化与复盘

学习定位

用 Dockerfile 记录运行环境。

今天的目标不是背定义,而是产出:一个轻量 Dockerfile 和 runbook

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「Docker 轻量运行说明」完成 一个轻量 Dockerfile 和 runbook

这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

Docker 轻量运行说明 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「用 Dockerfile 记录运行环境、Dockerfile slim、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 Docker 轻量运行说明,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:应用复盘与轻量工程

阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day42 - 本地记录 Actions 最小 CI

> 阶段四:应用接口、自动化与复盘

学习定位

让 本地记录 自动运行测试。

今天的目标不是背定义,而是产出:一个 Python CI workflow

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「本地记录 Actions 最小 CI」完成 一个 Python CI workflow

这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

本地记录 Actions 最小 CI 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「让 本地记录 自动运行测试、yaml workflow pytest、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 本地记录 Actions 最小 CI,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:应用复盘与轻量工程

阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day43 - 模块打包与 src 布局

> 阶段四:应用接口、自动化与复盘

学习定位

把代码放进 src 并支持导入。

今天的目标不是背定义,而是产出:一个 src 包结构

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「模块打包与 src 布局」完成 一个 src 包结构

这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

模块打包与 src 布局 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把代码放进 src 并支持导入、src layout、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 模块打包与 src 布局,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:应用复盘与轻量工程

阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day44 - 开源 说明文档、示例与文档

> 阶段四:应用接口、自动化与复盘

学习定位

写别人能看懂的主题入口。

今天的目标不是背定义,而是产出:一个开源 说明文档 草稿

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「开源 说明文档、示例与文档」完成 一个开源 说明文档 草稿

这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

开源 说明文档、示例与文档 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「写别人能看懂的主题入口、说明文档 sections、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 开源 说明文档、示例与文档,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:应用复盘与轻量工程

阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day45 - CLI、API、页面与 CI 整合原理

> 阶段四:应用接口、自动化与复盘

学习定位

理解 CLI、API、页面、CI 的连接方式。

今天的目标不是背定义,而是产出:一个数据工具的最小原理闭环

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「应用复盘 阶段复盘:Data Tool」完成 一个数据工具的最小原理闭环

这个问题在工程里不是孤立练习。它属于 应用接口、自动化与复盘 阶段,目标是:理解本地脚本如何连接接口、页面或自动化工具。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

应用复盘 阶段复盘:Data Tool 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「理解 CLI、API、页面、CI 的连接方式、integration checklist、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 应用复盘 阶段复盘:Data Tool,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 阶段定位

当前阶段:应用复盘与轻量工程

阶段目标:把脚本包装成别人也能运行、能看懂、能维护的小应用。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day46 - Prompt 模板与事实边界

> 阶段五:LLM / RAG / Agent 基础

学习定位

把 prompt 写成可复用模板。

今天的目标不是背定义,而是产出:一个 build_prompt() 函数

前置知识

今日知识地图

LLM / Agent 库基础地图

今天先不直接写复杂模型调用。

先知道后面会反复遇到这些库:

解决什么问题输入输出
pydantic校验结构化输入输出dict / JSON带类型约束的对象
requests / httpx调用模型服务或外部 APIURL + 参数响应数据
transformers使用 tokenizer、embedding 或生成模型文本 / 模型名token、向量或文本
torch承接深度学习底层张量计算数字、数组、TensorTensor / 模型输出

这几类库对 Agent 的意义是:Prompt 只是入口,真正稳定的系统还需要结构化校验、API 调用、模型输入输出和运行日志。

真实任务入口

今天先不从定义开始,而是先看问题:如何用「Prompt 模板与事实边界」完成 一个 build_prompt() 函数

这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

Prompt 模板与事实边界 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把 prompt 写成可复用模板、prompt template facts、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 Prompt 模板与事实边界,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day47 - 结构化输出与 Schema 校验

> 阶段五:LLM / RAG / Agent 基础

学习定位

让模型输出可被程序检查。

今天的目标不是背定义,而是产出:一个 validate_output() 函数

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「结构化输出与 Schema 校验」完成 一个 validate_output() 函数

这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

结构化输出与 Schema 校验 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「让模型输出可被程序检查、schema required fields、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 结构化输出与 Schema 校验,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day48 - LLM 评估集与评分标准

> 阶段五:LLM / RAG / Agent 基础

学习定位

用固定样例评估 prompt/tool。

今天的目标不是背定义,而是产出:一个小型 eval set

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「LLM 评估集与评分标准」完成 一个小型 eval set

这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

LLM 评估集与评分标准 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「用固定样例评估 prompt/tool、eval cases rubric、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 LLM 评估集与评分标准,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day49 - Embedding 与余弦相似度

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Embedding 与余弦相似度 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
What它是什么用一句话讲清概念
Why为什么存在说清不用它会怎样
How怎么做写出最小可运行代码
Error怎么错能定位 3 类常见错误
Future哪里复用连接数据、Quant、LLM、Agent

工具地图

今天先把 Embedding 与余弦相似度 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。

工具 / 对象输入输出适用场景
document原始文本可检索材料RAG 的知识来源
chunk文本片段索引单元控制检索粒度
similarityquery 和 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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day50 - 本地笔记检索器

> 阶段五:LLM / RAG / Agent 基础

学习定位

从 Markdown 片段里找相关内容。

今天的目标不是背定义,而是产出:一个 top_k 检索函数

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「本地笔记检索器」完成 一个 top_k 检索函数

这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

本地笔记检索器 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「从 Markdown 片段里找相关内容、keyword retrieval、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 本地笔记检索器,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day51 - RAG 上下文打包与引用

> 阶段五:LLM / RAG / Agent 基础

学习定位

把检索结果组织成回答上下文。

今天的目标不是背定义,而是产出:一个 context pack

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「RAG 上下文打包与引用」完成 一个 context pack

这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

RAG 上下文打包与引用 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把检索结果组织成回答上下文、context citations、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 RAG 上下文打包与引用,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day52 - 隐私脱敏与安全边界

> 阶段五:LLM / RAG / Agent 基础

学习定位

在公开仓库和 prompt 前脱敏。

今天的目标不是背定义,而是产出:一个 mask_text() 函数

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「隐私脱敏与安全边界」完成 一个 mask_text() 函数

这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

隐私脱敏与安全边界 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「在公开仓库和 prompt 前脱敏、regex masking、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 隐私脱敏与安全边界,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day53 - 缓存、成本与延迟控制

> 阶段五:LLM / RAG / Agent 基础

学习定位

减少重复请求和等待时间。

今天的目标不是背定义,而是产出:一个 dict cache

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「缓存、成本与延迟控制」完成 一个 dict cache

这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

缓存、成本与延迟控制 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「减少重复请求和等待时间、cache latency、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 缓存、成本与延迟控制,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day54 - Agent Tool 输入输出契约

> 阶段五:LLM / RAG / Agent 基础

学习定位

把函数设计成 Agent 可调用工具。

今天的目标不是背定义,而是产出:一个 ok/data/error 返回格式

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「Agent Tool 输入输出契约」完成 一个 ok/data/error 返回格式

这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

Agent Tool 输入输出契约 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把函数设计成 Agent 可调用工具、tool contract、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 Agent Tool 输入输出契约,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day55 - 工具路由与参数选择

> 阶段五:LLM / RAG / Agent 基础

学习定位

根据任务选择不同工具。

今天的目标不是背定义,而是产出:一个 route_tool() 函数

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「工具路由与参数选择」完成 一个 route_tool() 函数

这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

工具路由与参数选择 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「根据任务选择不同工具、router、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 工具路由与参数选择,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day56 - Agent 计划-执行-观察循环

> 阶段五:LLM / RAG / Agent 基础

学习定位

用状态机理解 Agent 流程。

今天的目标不是背定义,而是产出:一个最小 agent loop

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「Agent 计划-执行-观察循环」完成 一个最小 agent loop

这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

Agent 计划-执行-观察循环 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「用状态机理解 Agent 流程、state loop、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 Agent 计划-执行-观察循环,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day57 - Human-in-the-Loop 审查点

> 阶段五:LLM / RAG / Agent 基础

学习定位

高风险步骤必须人工确认。

今天的目标不是背定义,而是产出:一个 risk gate

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「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)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day58 - Agent 日志与可观测性

> 阶段五:LLM / RAG / Agent 基础

学习定位

记录每次工具调用和结果。

今天的目标不是背定义,而是产出:一个 run log

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「Agent 日志与可观测性」完成 一个 run log

这个问题在工程里不是孤立练习。它属于 LLM / RAG / Agent 基础 阶段,目标是:把模型调用、上下文、结构化输出和审查规则做成稳定流程。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

Agent 日志与可观测性 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「记录每次工具调用和结果、agent logging、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 Agent 日志与可观测性,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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 工程

阶段目标:把模型调用变成有输入边界、事实边界、评估和日志的工程流程。

本阶段反复出现的能力:

2. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day59 - LLM 结构化报告基础

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:LLM 结构化报告基础 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day60 - LLM Agent 本地知识助手原理

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:LLM Agent 本地知识助手原理 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day61 - 行情数据适配器

> 阶段六:Quant 研究与回测基础

学习定位

统一读取不同行情数据源。

今天的目标不是背定义,而是产出:一个 load_prices() 适配器

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「行情数据适配器」完成 一个 load_prices() 适配器

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

行情数据适配器 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「统一读取不同行情数据源、market adapter、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 行情数据适配器,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day62 - 收益率、波动率与最大回撤

> 阶段六:Quant 研究与回测基础

学习定位

计算最基础风险收益指标。

今天的目标不是背定义,而是产出:一个 metrics dict

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「收益率、波动率与最大回撤」完成 一个 metrics dict

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

收益率、波动率与最大回撤 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「计算最基础风险收益指标、returns metrics、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 收益率、波动率与最大回撤,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day63 - 交易信号与未来函数防护

> 阶段六:Quant 研究与回测基础

学习定位

用历史数据生成信号并 shift。

今天的目标不是背定义,而是产出:一个 signal/position 表

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「交易信号与未来函数防护」完成 一个 signal/position 表

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

交易信号与未来函数防护 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「用历史数据生成信号并 shift、signal shift、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 交易信号与未来函数防护,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day64 - 最小回测引擎

> 阶段六:Quant 研究与回测基础

学习定位

把持仓和收益合成净值曲线。

今天的目标不是背定义,而是产出:一个 equity curve

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「最小回测引擎」完成 一个 equity curve

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

最小回测引擎 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把持仓和收益合成净值曲线、backtest、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 最小回测引擎,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day65 - 手续费、滑点与现实约束

> 阶段六:Quant 研究与回测基础

学习定位

给回测加入简单成本。

今天的目标不是背定义,而是产出:一个 cost-adjusted return

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「手续费、滑点与现实约束」完成 一个 cost-adjusted return

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

手续费、滑点与现实约束 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「给回测加入简单成本、cost model、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 手续费、滑点与现实约束,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day66 - 仓位管理与风险预算

> 阶段六:Quant 研究与回测基础

学习定位

限制单资产仓位和总风险。

今天的目标不是背定义,而是产出:一个 position sizing 函数

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「仓位管理与风险预算」完成 一个 position sizing 函数

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

仓位管理与风险预算 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「限制单资产仓位和总风险、position risk、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 仓位管理与风险预算,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day67 - 组合指标与多资产权重

> 阶段六:Quant 研究与回测基础

学习定位

计算组合收益和权重约束。

今天的目标不是背定义,而是产出:一个 portfolio return

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「组合指标与多资产权重」完成 一个 portfolio return

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

组合指标与多资产权重 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「计算组合收益和权重约束、portfolio weights、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 组合指标与多资产权重,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day68 - 因子分析最小框架

> 阶段六:Quant 研究与回测基础

学习定位

按因子分组观察未来收益。

今天的目标不是背定义,而是产出:一个 factor bucket summary

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「因子分析最小框架」完成 一个 factor bucket summary

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

因子分析最小框架 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「按因子分组观察未来收益、factor analysis、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 因子分析最小框架,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day69 - 事件研究 Event Study

> 阶段六:Quant 研究与回测基础

学习定位

观察事件日前后窗口收益。

今天的目标不是背定义,而是产出:一个 event window summary

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「事件研究 Event Study」完成 一个 event window summary

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

事件研究 Event Study 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「观察事件日前后窗口收益、event window、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 事件研究 Event Study,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day70 - Quant 报告与图表输出

> 阶段六:Quant 研究与回测基础

学习定位

把策略指标写成可读报告。

今天的目标不是背定义,而是产出:一份 strategy_report.md

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「Quant 报告与图表输出」完成 一份 strategy_report.md

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

Quant 报告与图表输出 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把策略指标写成可读报告、quant report、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 Quant 报告与图表输出,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day71 - 配置驱动的策略实验

> 阶段六:Quant 研究与回测基础

学习定位

用 config 控制窗口、成本、路径。

今天的目标不是背定义,而是产出:一个 config-driven run

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「配置驱动的策略实验」完成 一个 config-driven run

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

配置驱动的策略实验 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「用 config 控制窗口、成本、路径、strategy config、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 配置驱动的策略实验,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day72 - 量化函数测试与样例数据

> 阶段六:Quant 研究与回测基础

学习定位

给指标、信号、回测写测试。

今天的目标不是背定义,而是产出:一组 pytest 测试

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「量化函数测试与样例数据」完成 一组 pytest 测试

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

量化函数测试与样例数据 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「给指标、信号、回测写测试、quant tests、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 量化函数测试与样例数据,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day73 - SQLite 保存回测结果

> 阶段六:Quant 研究与回测基础

学习定位

把实验结果存入本地数据库。

今天的目标不是背定义,而是产出:一个 results.db

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「SQLite 保存回测结果」完成 一个 results.db

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

SQLite 保存回测结果 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「把实验结果存入本地数据库、result store、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 SQLite 保存回测结果,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 这个主题必须补齐的知识面

学习时不要把这些点当成孤立词条。更好的读法是:每个概念都对应一种工程压力,例如输入变多、数据变脏、文件变大、结果要复现、输出要交给别人、模型回答需要校验。

3. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day74 - Streamlit 策略看板

> 阶段六:Quant 研究与回测基础

学习定位

本地展示策略指标和曲线。

今天的目标不是背定义,而是产出:一个 strategy dashboard

前置知识

今日知识地图

真实任务入口

今天先不从定义开始,而是先看问题:如何用「Streamlit 策略看板」完成 一个 strategy dashboard

这个问题在工程里不是孤立练习。它属于 Quant 研究与回测基础 阶段,目标是:把行情、指标、信号、回测和风险解释串成研究闭环。

先按这条顺序学习:

真实任务
  ↓
拆解流程
  ↓
引出问题
  ↓
引出知识点
  ↓
解释设计原因
  ↓
代码实现
  ↓
未来使用

今天你真正要掌握的不是“会背哪个语法”,而是能回答:它解决什么问题、为什么需要它、怎么落到代码、以后在哪个主题会再次出现。

工程问题解决结构

1. 是什么(What)

Streamlit 策略看板 是用 Python 解决工程任务时的一组小工具。最简定义:它帮助你把「本地展示策略指标和曲线、strategy dashboard、输入输出边界」放进可运行流程里。先把它当成解决问题的方法,不要先背术语。

2. 为什么存在(Why)

如果没有 Streamlit 策略看板,代码通常会变成一次性脚本:逻辑散、结果难复查、报错难定位、以后练习里也难复用。它存在的意义是把真实任务拆成更清楚的步骤,让你知道哪里输入、哪里处理、哪里输出。

3. 真实工程场景(Real Scenario)

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(未来使用)

这个知识点以后会反复出现在:

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. 真实主题里怎么用

4. 常见坑和边界

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. 失败时怎么记录?是 printlogging、错误报告,还是测试失败?

5. 如果迁移到 Quant / LLM / Agent 主题,最大的风险是什么?

6. 这个能力是否需要 说明文档、样例数据或测试来长期保存?

7. 建议扩展练习

2 小时学习节奏

简单路线 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 记录模板

错误现象:
触发输入:
定位过程:
修复方式:
以后如何避免:

复习检查

参考资料

Day75 - Quant 研究闭环原理

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Quant 研究闭环原理 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day76 - Quant 研究模块边界

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Quant 研究模块边界 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day77 - Quant 数据层原理

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Quant 数据层原理 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day78 - Quant 指标与回测层原理

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Quant 指标与回测层原理 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day79 - Quant 报告、测试与 CLI 原理

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Quant 报告、测试与 CLI 原理 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day80 - Quant 实验复盘方法

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Quant 实验复盘方法 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day81 - LLM 报告助手模块边界

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:LLM 报告助手模块边界 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day82 - LLM 上下文打包与 Prompt

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:LLM 上下文打包与 Prompt 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day83 - 结构化解析与审查规则

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:结构化解析与审查规则 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day84 - LLM 评估集与样例报告

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:LLM 评估集与样例报告 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day85 - LLM 输出限制与公开说明

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:LLM 输出限制与公开说明 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day86 - Agent Tool 模块边界

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Agent Tool 模块边界 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day87 - Agent 工具 Schema 与校验

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Agent 工具 Schema 与校验 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day88 - Agent 执行、错误恢复与日志

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Agent 执行、错误恢复与日志 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day89 - Agent 状态存储与人工审查

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Agent 状态存储与人工审查 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day90 - Agent 工作流端到端原理

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:Agent 工作流端到端原理 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day91 - RAG 模块边界

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:RAG 模块边界 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
What它是什么用一句话讲清概念
Why为什么存在说清不用它会怎样
How怎么做写出最小可运行代码
Error怎么错能定位 3 类常见错误
Future哪里复用连接数据、Quant、LLM、Agent

工具地图

今天先把 RAG 模块边界 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。

工具 / 对象输入输出适用场景
document原始文本可检索材料RAG 的知识来源
chunk文本片段索引单元控制检索粒度
similarityquery 和 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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day92 - RAG 索引与检索层

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:RAG 索引与检索层 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
What它是什么用一句话讲清概念
Why为什么存在说清不用它会怎样
How怎么做写出最小可运行代码
Error怎么错能定位 3 类常见错误
Future哪里复用连接数据、Quant、LLM、Agent

工具地图

今天先把 RAG 索引与检索层 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。

工具 / 对象输入输出适用场景
document原始文本可检索材料RAG 的知识来源
chunk文本片段索引单元控制检索粒度
similarityquery 和 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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day93 - RAG 回答 Prompt 与来源引用

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:RAG 回答 Prompt 与来源引用 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
What它是什么用一句话讲清概念
Why为什么存在说清不用它会怎样
How怎么做写出最小可运行代码
Error怎么错能定位 3 类常见错误
Future哪里复用连接数据、Quant、LLM、Agent

工具地图

今天先把 RAG 回答 Prompt 与来源引用 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。

工具 / 对象输入输出适用场景
document原始文本可检索材料RAG 的知识来源
chunk文本片段索引单元控制检索粒度
similarityquery 和 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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day94 - RAG 评估与错误案例

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:RAG 评估与错误案例 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
What它是什么用一句话讲清概念
Why为什么存在说清不用它会怎样
How怎么做写出最小可运行代码
Error怎么错能定位 3 类常见错误
Future哪里复用连接数据、Quant、LLM、Agent

工具地图

今天先把 RAG 评估与错误案例 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。

工具 / 对象输入输出适用场景
document原始文本可检索材料RAG 的知识来源
chunk文本片段索引单元控制检索粒度
similarityquery 和 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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day95 - RAG 限制、复盘与公开说明

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:RAG 限制、复盘与公开说明 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
What它是什么用一句话讲清概念
Why为什么存在说清不用它会怎样
How怎么做写出最小可运行代码
Error怎么错能定位 3 类常见错误
Future哪里复用连接数据、Quant、LLM、Agent

工具地图

今天先把 RAG 限制、复盘与公开说明 放进一张工具地图里。你只需要抓住“输入 -> 处理 -> 输出”,不用先背完整 API。

工具 / 对象输入输出适用场景
document原始文本可检索材料RAG 的知识来源
chunk文本片段索引单元控制检索粒度
similarityquery 和 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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day96 - GitHub Pages 与课程网站维护

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:GitHub Pages 与课程网站维护 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day97 - 知识索引与能力清单

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:知识索引与能力清单 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day98 - 技术讲解脚本与面试表达

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:技术讲解脚本与面试表达 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day99 - 错误库、片段库与长期维护

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:错误库、片段库与长期维护 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。

Day100 - AI Builder Python Roadmap 总复盘

> 阶段三以后:专项知识

学习定位

今天只学习一个核心主题:AI Builder Python Roadmap 总复盘 学成可运行、可解释、可迁移的知识点

目标不是背 API,而是建立认知地图:这个工具解决什么问题、输入是什么、输出是什么、出错时怎么定位。

Day 主线控制在 4 小时以内,但内容保持足够厚:先理解,再写最小代码,再做小练习。

前置知识

认知地图

先看全局,不直接上复杂代码。

层级你要回答的问题本日要求
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

这个知识后面会进入四类场景:

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 个问题:

产出:在 notes.md 写 5 行以内的知识地图。

第 2 层:输入 -> 处理 -> 输出

把本节内容压成一张表:

部分你要写清楚什么
输入数据、参数、文件、用户输入或模型上下文从哪里来
处理中间做了哪一步转换、判断、计算或校验
输出输出到屏幕、文件、数据库、图表、日志还是返回值

产出:写出 1 个最小输入和 1 个最小输出。

第 3 层:最小可运行代码

只写一个最小例子,不加复杂功能。

要求:

产出:main.py

第 4 层:逐对象拆解

第一次出现的新函数、新类、新参数,必须拆开。

格式:

对象/函数:
它是什么:
输入是什么:
输出是什么:
为什么不用旧方法:
最容易错在哪里:

产出:notes.md 里的“对象拆解”小节。

第 5 层:错误实验

主动制造 2 个错误,而不是等报错后慌。

例子:

产出:errors.md,记录错误信息、原因和修复方式。

第 6 层:旧知识连接

写清楚它不是凭空出现的新知识。

模板:

昨天/之前我会:
今天升级成:
升级后解决的问题:

产出:3 行连接说明。

第 7 层:迁移场景

至少连接到一个方向:

产出:选择 1 个方向,写 3 句话。

第 8 层:IC100 衔接

找到一个最近的 IC,把今天的知识放进去用一次。

要求:

产出:对应 IC 的 review.md 或当天提交说明。

30 分钟加厚执行清单

5 分钟:写认知地图
5 分钟:写输入 -> 处理 -> 输出
10 分钟:跑最小代码
5 分钟:制造并修复 1 个错误
5 分钟:写 IC100 迁移说明

判断标准:如果这 30 分钟做不完,说明加厚范围太大,需要砍掉内容,而不是继续堆字数。