# 4f 培训内容：字符串与真题文本处理

## 课程定位

- 对象：已学变量、类型转换、条件与循环的 Python 初学者。
- 建议时长：100 分钟；主线是“准确匹配、先清洗、最后格式化”。
- 先修要求：能读懂赋值、`print()`、列表、字典、函数、`if` 与 `for`。
- 参考教材：`../4f.pdf`，对应《Python 快速编程入门（第 3 版）》第 4 章。
- 真题依据：`../../../python真题/` 中名仕、科图、青娅三套题干与代码。
- 课堂材料：`../第04讲_Python字符串与文本处理.ipynb`、`课堂Slides.tex`、`课堂Slides.pdf`、`课后练习.py`。

课程沟通目标：学生能把网页、字段名和分类值当作文本正确处理；匹配前先清理空白，计算完成后再把结果格式化为竞赛要求的字符串。

## Notebook 课堂使用顺序

`第04讲_Python字符串与文本处理.ipynb` 与前面章节保持相同节奏。每个教学单元均按以下顺序推进：

1. **用法、函数或概念**：说明它解决什么问题、输入输出是什么；
2. **代码讲解**：逐行拆解关键表达式和易错位置；
3. **课堂演示（样本代码）**：教师先预测、再运行，并修改一个值复验；
4. **课堂练习（学生填写）**：学生使用不同数据独立补全，避免照抄演示；
5. **结果核验**：根据题目给出的预期值或业务规则检查结果。

普通字符串知识拆成短闭环；科图付款方式、科图女性占比和青娅现金流量筛选也各自形成“讲解-演示-练习”闭环，不等到整章结束后再统一练习。

## 取舍说明

本课程不是教材第四章的逐页复述。三套真题中，字符串没有作为独立算法题出现，但以下能力直接参与作答：

- 科图题使用 `'{:.2f}%'.format(x)` 输出百分比；
- 科图题使用 `x == "女"` 做文本匹配；
- 青娅题使用 `==` 和 `.isin([...])` 精确匹配项目名称；
- 青娅题要求金额保留两位且不足补零；
- 三套题都把 URL、请求头、字段名、文件名和编码写成字符串；
- 网页题中的 `response.text` 是后续 HTML 解析的文本入口。

因此，本课重点讲字符串定义、精确匹配、`strip()`、`replace()`、`split()`、`join()`、f-string、`.format()` 识读，以及 pandas 的 `.str` 文本清洗。教材中的旧式 `%` 格式化、`find()`、大小写全套方法、字符串对齐和文字排版综合案例不作为必做内容。

## 学习目标与验收

| 目标 | 学生可观察行为 | 验收方式 |
|---|---|---|
| 识别文本数据 | 区分 `"125"` 与 `125` | 类型诊断 |
| 准确匹配文本 | 能解释尾部空格为何导致匹配失败 | 性别与项目名筛选 |
| 清理文本 | 使用 `strip()`、`replace()`、`split()`、`join()` | 脏字段修复 |
| 格式化结果 | 使用 f-string 输出两位小数和百分比 | 科图百分比 |
| 保持计算口径 | 先排序或选最大值，最后格式化 | 9.50% 与 10.00% 对比 |
| 处理表格文本 | 区分普通字符串方法与 pandas `.str` 方法 | 真题微案例 |

## 100 分钟流程

| 时间 | 教学环节 | 教师动作 | 学生活动 | 形成性评价 |
|---:|---|---|---|---|
| 0-8 分钟 | 真题导入 | 展示三套题中的文本位置 | 标出字符串 | 能否区分内容与方法考点 |
| 8-20 分钟 | 字符串与数值 | 对比 `"125"`、`125` 与精确匹配 | 预测类型和比较结果 | 是否理解引号的作用 |
| 20-32 分钟 | 清洗后匹配 | 制造前后空格和英文冒号 | 使用 `strip()`、`replace()` | 是否能修复匹配失败 |
| 32-43 分钟 | 分割与拼接 | 用订单编号和字段列表演示 | 拆分并重新拼接 | 是否理解返回类型 |
| 43-58 分钟 | 格式化 | 对比 `.format()` 与 f-string | 输出两位小数和百分比 | 是否能补足尾随 0 |
| 58-68 分钟 | 顺序陷阱 | 对比数值排序和字符串排序 | 判断正确处理顺序 | 是否坚持最后格式化 |
| 68-84 分钟 | 科图微案例 | 计算付款方式占比并取组内最大 | 清洗、聚合、格式化 | 结果是否每组仅一行 |
| 84-94 分钟 | 青娅微案例 | 精确筛选现金流量项目 | `.isin()`、缺失填充、两位输出 | 项目和金额是否正确 |
| 94-100 分钟 | 离场检验 | 提问清洗、匹配、格式化顺序 | 写出三句规则 | 能否迁移到新字段 |

## 核心讲解

### 1. 字符串是竞赛数据，不只是打印文字

URL、HTML、列名、分类值、项目名称、输出文件名和编码都是字符串。字符串可以表示看起来像数字的内容，例如 `"125"`，但它仍不能直接按数值口径计算或排序。

### 2. 精确匹配前先检查空白和符号

`"女"` 与 `"女 "` 不相等，`"加：期初现金"` 与 `"加:期初现金"` 也不相等。处理网页或表格文本时，应先用 `repr()` 观察隐藏空白，再根据业务规则使用 `strip()` 或 pandas 的 `.str.strip()`。符号确实需要统一时再使用 `replace()` 或 `.str.replace()`。

### 3. 字符串方法不会原地修改原值

字符串不可变。`text.strip()`、`text.replace()` 和 `text.upper()` 都会返回新字符串，必须重新赋值或直接使用返回值。

```python
gender = "女 "
gender = gender.strip()
```

### 4. 普通字符串方法和 pandas `.str` 方法要分清

单个文本使用 `text.strip()`；Series 整列文本使用 `series.str.strip()`。不能对整列直接写 `series.strip()`。

```python
df["性别"] = df["性别"].astype(str).str.strip()
```

### 5. 格式化只改变显示，不改变原计算结果

科图参考代码使用 `.format()`，课堂统一推荐更直观的 f-string，同时要求学生能看懂两种写法。

```python
f"{66.6667:.2f}%"
"{:.2f}%".format(66.6667)
```

两者都得到 `66.67%`。格式化之后结果是字符串，不应继续参与求最大值、排序或平均值。

### 6. `round(2)` 与“固定显示两位”不同

`round(12.3, 2)` 仍是数值 `12.3`；`f"{12.3:.2f}"` 才得到文本 `"12.30"`。青娅题若严格要求 CSV 中不足两位用 0 补足，应在所有计算结束后对导出副本进行格式化。

## 真题微案例

### 科图：先算占比和组内最大，再转百分比文本

正确顺序：清洗付款方式 -> 分组计数占比 -> `idxmax()` 选最大 -> 排序 -> 最后格式化占比。

```python
result["占比"] = result["占比"].map(lambda x: f"{x:.2f}%")
```

若先把 `9.5` 与 `10.0` 变成 `"9.50%"` 与 `"10.00%"`，字符串比较会错误地认为 `"9.50%"` 更大。

### 青娅：项目名称精确匹配与固定两位输出

先清理项目列，再使用 `.isin([...])` 选择两个目标项目。金额列保持数值完成填充和计算；若交付格式要求固定两位，再建立导出副本并格式化。

### 名仕：数字文本先转换再计算

名仕题的销量、退单量和售价若来自网页文本，必须先转换为整数或浮点数，再计算实际销量和销售额。这里考的是类型边界，不需要额外学习复杂字符串算法。

## 常见误区与纠偏话术

| 误区 | 纠偏 |
|---|---|
| 字段看起来一样就一定能匹配 | 用 `repr()` 检查空格、换行和全角符号 |
| 调用 `strip()` 后原变量自动改变 | 字符串方法返回新值，需要重新赋值 |
| Series 可以直接 `.strip()` | pandas 整列文本需要 `.str.strip()` |
| `round(2)` 一定显示两个小数位 | `round` 保持数值；固定显示需格式化 |
| 百分比越早加 `%` 越好 | 先计算、比较、排序，最后格式化 |
| `.format()` 和 f-string 都必须背完整语法 | 会读 `.format()`，熟练写 f-string 即可 |
| `split()` 返回字符串 | 它返回子串列表；`join()` 才拼回字符串 |

## 课后练习使用方式

1. 学生只修改 `课后练习.py` 中的 TODO。
2. 每题先预测类型和输出，再运行核对。
3. 真题微案例必须保留“清洗 -> 计算 -> 选择 -> 格式化”的顺序。
4. 完成后确保文件从上到下一次运行不出现异常。

评分建议：文本识别与匹配 20%，文本清洗 25%，格式化 25%，真题微案例 20%，解释处理顺序与代码可读性 10%。
