# 第3关教案 —— input + 类型转换 + 格式化综合（60分钟）
> **GESP等级：一级 | 考级考点：GESP Python 一级**


> **GESP 考点**：#18 input()函数、#19 int()/float()类型转换、#27 格式化输出（f-string / format）
> **文件**：`01_input_demo.py`、`02_input_practice.py`
> **时长**：60分钟
> **前置**：第2关（格式化输出）。孩子已经知道 f-string 可以嵌入变量、控制小数位数，也用过 `print()` 输出。本关将输入、处理、输出三个环节串联成完整闭环。

---

## GESP 知识映射

| GESP-1 考点 | 本关对应 | 身体锚点 / 记忆钩子 |
|------------|---------|------------------|
| #18 input()函数 | `s = input("边数?")` — 获取键盘输入 | "input 永远给你文字！" |
| #19 int()/float()转换 | `int(s)` / `float(r)` — str → 数字 | "要做数学？拿 int() 包一下！" |
| #27 格式化输出 | f-string: `f"半径={r:.2f}"` | "f-string 里的 {} 是填空格" |
| 程序三要素 | 输入(input) → 处理(process) → 输出(print) | "先问用户、再算数、最后打印" |

---

## 教学目标

- 深刻理解 `input()` 永远返回 `str` 类型，形成"看到 input 就想到 str"的条件反射
- 能正确使用 `int()` 转换整数字符串、使用 `float()` 转换小数字符串
- 能区分 `int()` 和 `float()` 的适用场景（range 用 int，坐标/角度/周长用 float）
- 理解"输入 → 处理 → 输出"的程序三要素框架，能口头描述任意程序的三段结构
- 能用 f-string 格式化输出数值，控制小数位数（如 `{c:.2f}`）
- 能独立完成 "input → int()/float() → 计算 → turtle 绘图 → 格式化打印" 的完整闭环

---

## 教学节奏（60分钟，分钟级分解）

---

### 阶段一：0-10分钟 —— 导入：程序三要素（10分钟）

**引入（3分钟）——从生活场景引出三要素**

> "想一想，你每天做数学题的过程：老师给你题目（**输入**）→ 你在草稿纸上算（**处理**）→ 你写出答案（**输出**）。电脑程序也一样——**输入 → 处理 → 输出**。"

老师板书：

```
输入(input)  →  处理(process)  →  输出(print)
  用户给数据        CPU算算算         屏幕显示结果
```

**推进第一步（4分钟）——回顾第1-2关**

> "第1关我们学了 `print()`——程序输出。第2关我们学了 f-string——格式化输出。但前面两关的输出内容都是代码写死的，不够灵活。今天我们要让程序**问用户**想要什么——这就是 `input()`，程序的耳朵。"

随手演示（不运行代码，只口头）：

```python
# 写死的程序（第1-2关）
print("边数：6")            # 没办法改

# 活的程序（第3关）
s = input("边数？")         # 用户想几边形就几边形
```

**推进第二步（3分钟）——三要素身体动作**

全班起立，老师喊指令：

| 老师说 | 全班做动作 | 全班喊 |
|--------|-----------|--------|
| "输入！" | 双手拢在耳边（听声音） | "input！问用户！" |
| "处理！" | 双手在脑袋两侧画圈（大脑思考） | "int() float() 算算算！" |
| "输出！" | 双手向外推（送出去） | "print！显示结果！" |

三要素连起来做三遍（慢→中→快）。

**记忆钩子**（板书，齐读两遍）：

```
程序三步走：输入 → 处理 → 输出
先问用户、再算数、最后打印
```

---

### 阶段二：10-30分钟 —— 三个知识点逐个突破（20分钟）

---

#### 知识点①（7分钟）：input() 永远返回 str

**引入（1分钟）——悬念**

> "Python 里有一个**最容易被坑**的函数——`input()`。它看起来很简单：问用户一句话，拿到回答。但它的返回值有一个**大坑**，不注意就翻车。打开 `01_input_demo.py` 场景1，我们亲手验证。"

**推进第一步（3分钟）——投影演示**

打开 `01_input_demo.py` 运行场景1部分：

```python
raw = input("请输入一个数字（如 8）：")
print("input() 返回的类型：", type(raw))    # <class 'str'>
```

输入 `8`，看到 `<class 'str'>`。

> 老师停顿 5 秒，扫视全班："我明明输入的是数字 8，为什么 Python 说是 str（字符串）？！"

再试：输入 `123` → str！输入 `3.14` → str！输入 `hello` → str！

> "不管你输入什么——数字、小数、文字——`input()` **永远**返回 str。它就像录音机：你说话，它录音，录下来的永远是'声音文件'（字符串），不是'实物'（数字）。"

**推进第二步（3分钟）——亲手验证 + 踩坑**

孩子在自己的电脑 Shell 中执行三行代码：

```python
>>> x = input("随便输一个数字：")    # 输入 50
>>> print(type(x))                  # <class 'str'>
>>> print(x * 2)                    # "5050" 不是 100！
```

> "看到了吗？`x * 2` 不是 100，而是 `"5050"`！为什么？因为 x 是 str，str 的乘法是**重复文字**！`"50" * 2` = `"5050"`。你以为在做数学，Python 却在复制文字！"

**身体锚点 + 口诀（1分钟）**

全班起立，老师喊三遍，全班齐喊三遍：

> **"input 永远给你文字！"**
> **"要做数学？拿 int() 包一下！"**

---

#### 知识点②（8分钟）：int() / float() 类型转换

**引入（1分钟）**

> "既然 `input()` 给了你穿衣服的 str，Python 提供了**脱衣服机器**——`int()` 和 `float()`。它们能把 str 变成真正的数字。"

**推进第一步（4分钟）——int() 脱衣服**

打开 `01_input_demo.py` 场景2，逐行运行：

```python
num = int("6")
print(num, type(num))           # 6 <class 'int'>

# 但 int() 不认小数点！
# int("3.14")   ← 会报错 ValueError！
```

> "`int()` 只认**光膀子的整数**——`"6"` 可以，`"3.14"` 不行。看到小数点就罢工。"

**关键追问（2分钟）**

> "那用户输入 `3.5` 作为半径呢？怎么转？"

引出 `float()`：

```python
r = float("3.14")
print(r, type(r))               # 3.14 <class 'float'>

# float() 比 int() 宽容——连整数也能转
print(float("6"))               # 6.0 <class 'float'>
```

**板书速查表：**

| 输入字符串 | int() 结果 | float() 结果 |
|-----------|-----------|-------------|
| `"6"` | `6` ✅ | `6.0` ✅ |
| `"3.14"` | ❌ 报错 | `3.14` ✅ |
| `"0"` | `0` ✅ | `0.0` ✅ |
| `"abc"` | ❌ 报错 | ❌ 报错 |

**推进第二步（2分钟）——孩子动手验证三行代码**

孩子在 Shell 中执行并在心里默念口诀：

```python
type(input())              # → str    "input永远给你文字！"
type(int(input()))         # → int    "int() 脱衣服！"
type(float(input()))       # → float  "float() 留小数点！"
```

**身体锚点（1分钟）——脱衣服操**

> "全体起立！跟我做——`int()` = **脱衣服机**（双手做脱外套动作，往下一脱）→ 穿衣服变光膀子整数；`float()` = **脱衣服但留小数点**（脱外套后右手食指在空中点一下）。加速三遍！"

---

#### 知识点③（5分钟）：输入 → 处理 → 输出完整链条

**引入（1分钟）**

> "前面的知识点拆开了看，现在我们把它们**串起来**——程序三要素的一条完整链条。"

**推进（4分钟）——三链条演示**

打开 `01_input_demo.py` 场景3，运行并逐行解释：

```python
# ① 输入
user_name = input("你叫什么名字？")

# ② 处理
message = "你好，" + user_name + "！今天我们来用 Python 画画！"

# ③ 输出
print(message)
```

> "这就是程序的完整链条：先问用户（输入）→ 加工数据（处理）→ 告诉用户（输出）。任何程序都可以拆成这三步。"

**追问强化**：随机问 3 个孩子——"你去 ATM 取钱，输入是什么？处理是什么？输出是什么？"

> 预期回答：输入=插卡+输密码+输金额，处理=银行验证余额，输出=出钞+打印凭条。

---

### 阶段三：30-40分钟 —— 演示：input + turtle 画多边形（10分钟）

**引入（1分钟）**

> "现在我们用 input 控制 turtle——用户输入边数，turtle 画出对应的多边形。这是 input + int + turtle 的经典搭配。"

**推进第一步（3分钟）——投影演示完整代码**

打开 `01_input_demo.py` 场景4，逐行投影讲解：

```python
s = input("边数？(如 3、4、5、6)：")    # ① input → str
n = int(s)                               # ② int() 脱衣服

for i in range(n):                       # ③ range(n) 现在 n 是 int，能用了！
    t.forward(60)
    t.right(360 / n)
```

输入 `6` → 画出六边形！输入 `5` → 五边形！输入 `3` → 三角形！

**关键教学时刻（3分钟）——追问**

> "如果我把 `int(s)` 去掉，`range(s)` 会怎么样？"

当场演示：`range("6")` 报错 `TypeError: 'str' object cannot be interpreted as an integer`

> "每个步骤都不多余：input() 要 str → int() 转成 int → range() 接受 int → turtle 画图。链条一步断，程序就崩溃。"

**身体锚点（3分钟）——链条传递游戏**

全班站成一列，老师扮演 `input`，第一个孩子扮演 `int()`，第二个扮演 `range()`，第三个扮演 `for`，第四个扮演 `forward+right`。

1. 老师（input）拍第一个孩子肩膀说 `"6"`（str）
2. 第一个孩子（int()）做脱衣服动作，拍第二个孩子肩膀说 `6`（int）
3. 第二个孩子（range()）做循环手势（手画圈），拍第三个人...
4. 链条到最后一个孩子，做向前+转圈的动作（画六边形）

> "看到了吗？多一个人加进来，这链条里每个人都有自己要干的事。少一个？链条断了！"

**记忆钩子（齐读一遍）**

```
input → int() → range() → turtle
先问用户要边数，int() 脱衣变数字，
range 拿来控制火，turtle 画出多边形！
```

---

### 阶段四：40-55分钟 —— 实操三练（15分钟）

**引入（30秒）**

> "打开 `02_input_practice.py`，三道实操题，从简单到综合，每个人在自己的电脑上完成。"

---

#### 实操①：input + int + 画多边形（5分钟，练习文件 上半部分）

做完的孩子举手示意，老师逐行核对填空。

**填空答案**：
- 填空2（`int(s)` 或 `int(s)`）— 把 str 边数转成 int
- 填空5（`int(length)`）— 边长也是 str，必须转

**巡视检查点**：检查每个孩子是否都对 input 结果做了 `int()` 转换。**最常见错误**：忘记 `int()` 或只转了一个。

**追加追问（对早完成的孩子）**：
- "如果不转 `int(s)`，`range(s)` 会怎样？" → TypeError
- "颜色名用转 `int()` 吗？" → 不用，颜色名本身是 str！
- "`360 / n` 返回 int 还是 float？" → float（除法永远返回 float）

---

#### 实操②：input + float 画圆并算周长（5分钟，练习文件 下半部分）

**填空答案**：
- 填空7（`float(r_str)`）— 半径可能是小数，用 float
- 填空8（`2 * pi * r` 或 `2 * 3.1416 * r`）— 周长公式

**巡视检查点**：注意孩子是否用 `int()` 替代 `float()` 转半径。强调："半径可能是 `5.5`，`int()` 会报错——半径用 `float()`！"

**关键追问**："为什么半径用 float() 而不是 int()？"
> 预期回答：①半径可能是小数（如 5.5）；②turtle 的 circle() 接受 float；③周长结果可能带小数

---

#### 实操③：格式化输出（5分钟，练习文件 末尾部分）

**填空答案**：
- `f"作品名称：{name}"` — 直接嵌入字符串变量
- `f"多边形边数：{sides}"` — 嵌入整数
- `f"圆的半径：{radius:.2f}"` — 保留 2 位小数
- `f"圆周长：{2 * 3.1416 * radius:.2f}"` — 表达式+格式化

**巡视检查点**：`.2f` 的写法是否正确（小数点前不要空格，如 `:.2f` 不是 `: .2f`）

**追加追问**："`:.2f` 是什么意思？"
> 预期回答：冒号后是格式说明，`.2` 表示 2 位小数，`f` 表示浮点数

---

### 阶段五：55-60分钟 —— 小测 + 收尾（5分钟）

**小测问题（投影，全班写在纸上，30秒思考+30秒举手回答）**

> **"为什么要用 `int()` 包 `input()`？"**

**参考答案（孩子口述要点）**：
1. `input()` 永远返回 str（字符串）
2. str 不能直接做数学运算（如加减乘除）
3. str 不能直接给 `range()` 用（会报 TypeError）
4. `int()` 把 str 转成 int，才能参与数学运算和 range()

**记忆钩子（板书，全班齐读三遍）**

```
★★★ input 永远给你文字！★★★
★★★ 要做数学？int() 包一下！★★★
```

**全班快速问答（1分钟，3秒内齐答）**

| 老师问 | 全班答 |
|--------|--------|
| `input()` 返回什么类型？ | "str！永远str！" |
| 怎么把 str 变整数？ | "int() 包一下！" |
| 怎么把 str 变小数？ | "float() 包一下！" |
| 程序三要素是什么？ | "输入→处理→输出！" |
| 输入 6，`int("6")` 结果？ | "6（int）" |
| 输入 3.14，`int("3.14")` 结果？ | "报错！int不认小数点！" |

**过渡钩子（1分钟）——引出下一课**

> "今天我们学了程序三要素——输入、处理、输出。也学会了用 int()/float() 把用户输入转换成数字，控制 turtle 画画。但如果我们输入的不是数字呢？比如用户输入 `"abc"` 当边数——`int("abc")` 会怎样？下一课——**异常处理**——让程序即使遇到错误输入也不崩溃！"

---

## 课堂练习

### 练3-1：补全代码——画多边形（input + int）

```python
import turtle
t = turtle.Turtle()

s = input("请输入边数（3~10）：")
n = _______(s)          # 填空：把 str 转成 int

color_name = input("请输入颜色：")
length = input("请输入边长：")
length = _______(length)  # 填空：边长转 int

t.color(color_name)
for i in range(n):
    t.forward(length)
    t.right(360 / n)

turtle.done()
```

> 答案：`int`、`int`

---

### 练3-2：画圆 + 算周长（input + float）

```python
import turtle
t = turtle.Turtle()

r_str = input("请输入圆的半径：")
r = _______(r_str)                  # 填空：str → float

C = 2 * 3.1416 * r
print(f"圆的周长是：{_______:.2f}")   # 填空：格式化输出，保留2位小数

t.circle(r)
turtle.done()
```

> 答案：`float`、`C`

---

### 练3-3：辨析题——选择正确的转换方式

分别判断以下情况应该用 `int()` 还是 `float()`：

| 场景 | 用什么转换？ |
|------|------------|
| 用户输入边数（只能是整数） | `___()` |
| 用户输入圆的半径（可能带小数） | `___()` |
| 用户输入边长（可能是整数也可能是小数） | `___()` |
| 用户输入角度（可能是 36.5） | `___()` |
| 用户输入旋转圈数（只能是整数） | `___()` |

> 答案：int / float / float / float / int

---

## 课堂练习答案

| 练习 | 答案 |
|------|------|
| 练3-1 | 填空1：`int`；填空2：`int`。完整链路：input→str→int()→int→range()→turtle |
| 练3-2 | 填空1：`float`；填空2：`C`。注意：半径可能是小数，必须用 float() 而不是 int() |
| 练3-3 | int / float / float / float / int。核心判断标准：确定是整数的用 int，可能有小数的用 float |

---

## 易错点

| 错误 | 原因 | 纠正 |
|------|------|------|
| `int(input())` 后用户输入小数 | int() 不认小数点，触发 ValueError | 小数用 float()，"int()只认光膀子整数" |
| 忘记转换直接 `range(input())` | input 返回 str，range 要 int | 指口诀："要做数学？int()包一下！" |
| 颜色名用了 `int()` 转换 | 颜色名本身就是 str，不需要转 | "颜色名穿引号就是 str——str 不需要再转 str！" |
| 半径用了 `int()` 而不是 `float()` | 以为输入的是整数 | 演示 `int("5.5")` 报错，"半径可能是小数，用 float" |
| f-string 格式化写错：`{r: .2f}` | 冒号和点之间多了一个空格 | "`:.2f` 中间没有空格！紧挨着写" |
| 误以为 `input()` 能自动识别数字 | 来自 Scratch 经验（答录积木自动转） | "Python 的 input 比 Scratch 诚实——它永远给你原始文字" |
| 360 / n 的结果类型搞混 | 以为整数除整数=整数 | "Python 除法永远返回 float——记得这个特性" |
| 多个 input 只转换了其中一个 | 输入多个值，忘了其他也要转 | "每个用 input 拿来的数字都要 int()/float() 包一下" |
| 忘记给 f-string 加前缀 f | 写了 `"名字：{name}"` 而不是 `f"名字：{name}"` | "f-string 的 f 是身份证——没有 f，{} 就是普通文字" |

---

## 板书设计（白板布局建议）

```
┌──────────────────────────────────────────────────────────────────┐
│       第3关：input + 类型转换 + 格式化综合（GESP #18 #19 #27）    │
│                                                                  │
│  ┌─── 程序三要素 ──────────────────────────┐                    │
│  │  输入(input)  →  处理(process)  →  输出(print)               │
│  │  input()问用户    int()/float()转     print()/f-string       │
│  └──────────────────────────────────────────┘                    │
│                                                                  │
│  ⚠️ input() 永远返回 str！                                        │
│  你打 6 → "6"(str)  你打 3.14 → "3.14"(str)                     │
│                                                                  │
│  🔧 类型转换（脱衣服机器）                                        │
│  int("6")  → 6    ✅  只认光膀子整数                              │
│  int("3.14") → ❌  报错！不认小数点！                            │
│  float("6")  → 6.0 ✅  连整数也认识                              │
│  float("3.14") → 3.14 ✅  认识小数点                             │
│                                                                  │
│  ✨ 格式化输出（f-string）                                        │
│  f"半径={r:.2f}"  →  "半径=5.50"   保留2位小数                   │
│                                                                  │
│  ┌─── 完整链条 ──────────────────────────┐                      │
│  │  input → int() → range() → turtle    │                      │
│  │  input → float() → 计算 → f-string   │                      │
│  └──────────────────────────────────────────┘                    │
│                                                                  │
│  ★★★ 记忆钩子 ★★★                                                │
│  程序三步走：输入 → 处理 → 输出                                   │
│  input终身str！做数学？int()包一下！                              │
│  int()脱衣服，float()留小数点                                  │
│  f-string 里的 {} 是填空格                                      │
└──────────────────────────────────────────────────────────────────┘
```

---

## 教学节奏总览

| 时间 | 阶段 | 核心内容 | 身体锚点 | 记忆钩子 |
|------|------|---------|---------|---------|
| 0-3min | 导入三要素 | 输入→处理→输出 | 拢耳→画圈→前推三动作 | "输入→处理→输出" |
| 3-7min | 三要素深化 | 回顾 print / f-string，引出 input | 对比写死 vs 活的程序 | "先问用户、再算数、最后打印" |
| 7-10min | 三要素动作操 | 三要素连起来全班做 | 三动作加速喊 | "程序三步走" |
| 10-17min | input()陷阱 | 投屏演示 type(input())→str；多轮验证；孩子亲手踩坑 | 夸张停顿5秒 | "input永远给你文字！" |
| 17-20min | 口诀齐喊 | 全班齐喊三遍 | 起立喊 | "做数学？int()包一下！" |
| 20-25min | int()转换 | int("6")→6；int("3.14")→报错；脱衣服机 | 脱外套动作 | "int()脱衣服" |
| 25-28min | float()转换 | float("3.14")→3.14；float("6")→6.0；Shell三行验证 | 脱外套+点小数点 | "float()留小数点" |
| 28-30min | 三链条演示 | input→处理→print完整程序 | 三要素动作串烧 | "每个程序都是这三步" |
| 30-40min | 画多边形演示 | input→int→range→turtle；链条传递游戏 | 链条传递游戏 | "链条一步断，程序就崩溃" |
| 40-45min | 实操① | input+int+画多边形 | 自己动手 | "input→int→range→turtle" |
| 45-50min | 实操② | input+float+画圆+算周长 | 自己动手 | "半径用float()" |
| 50-55min | 实操③ | f-string格式化输出 | 自己动手 | "`:.2f`保留两位" |
| 55-57min | 小测 | "为什么要用int()包input()？" | — | 四层原因的深度理解 |
| 57-59min | 快速问答 | 7个反问全班齐答 | 3秒内齐答 | — |
| 59-60min | 过渡 | 引出异常处理 | — | "如果输入abc呢？" |

---

## GESP衔接

本关完成 Python 程序三要素框架的建立，孩子已能：

- 深刻理解 `input()` 永远返回 `str`——从亲手踩坑的体验中建立不可磨灭的记忆
- 正确区分 `int()` 和 `float()` 的适用场景——整型用 int、浮点用 float
- 完成 "input → 类型转换 → 计算 → turtle → 格式化输出" 的完整数据流闭环
- 用 f-string 格式化输出数值，控制小数位数

> **GESP一级考试中**，#18 input()函数是基础必考项。常见考题：①input()返回值的类型判断；②含 input() 的代码段结果预测（如 `input()` 后直接 `*` 运算的结果）；③选择合适的类型转换函数（int 还是 float）；④格式化输出的 f-string 填空（`:.2f` 的含义）。本关的躯体验证 + 身体锚点 + 口诀 + 实操四重保障，直接覆盖所有考法。

> **长线价值**："输入→处理→输出"的三要素框架将贯穿整个编程学习。无论以后学函数、学类、学 Web——任何程序都可以拆成这三个环节。本关建立的"看完 input 立刻 int()/float()"的肌肉记忆，是避免无数类型错误的护身符。

---

## 教员备忘

- **本关最关键的时刻**：阶段一导入（0-10分钟）的三要素动作操 + 阶段二 input 陷阱演示（10-17分钟）。三要素框架是孩子理解程序思维的基础，input 陷阱是孩子第一次遇到"看起来是数字其实是文字"的认知冲突。两个关键点缺一不可。

- **本关最容易拖堂的部分**：阶段四实操三练（40-55分钟）。如果时间不够，优先保证实操①（画多边形——核心链路），实操②（圆+周长）和实操③（格式化）可以合并或让早完成的孩子带一下同桌。实操①是整节课的"毕业作品"，必须人人完成。

- **链条传递游戏的操作要点**（30-35分钟）：选择 4-5 个孩子，分别扮演 input / int() / range() / for / turtle。每个角色做动作并说出自己的"台词"。全班观看后追问："如果 int() 这个孩子走神了（忘记转换），链条会怎样？"——全班答："断了！程序报错！"

- **格式化输出的度**：本关不要求孩子完全理解 f-string 的全部语法，只需掌握 `{变量:.2f}` 模式。不要展开 `{变量:>10}` 等高级格式化——那是第2关的内容。如果孩子问，说"以后会学更多格式控制"即可。

- **与第1-2关的关系**：
  - 第1关（print）→ 输出模块。第2关（格式化）→ 输出美化。本关（input+综合）→ 输入模块 + 完整三要素闭环。
  - 三者合在一起，孩子理解了程序从输入到输出的完整流程。

- **孩子提问应答**：
  - "为什么 input 不能像 Scratch 一样自动检测数字？" → "Scratch 有问'数字'和问'文字'两个积木。Python 的 input 是通用的——它把选择权给你，你要数字就自己 int()。"
  - "int('6') 和 int(6) 有区别吗？" → "int('6') 从字符串转整数，int(6) 本身已经是整数所以不变。但关键是——你永远不应该对数字用 int()，int() 专治 str。"
  - "float 有什么用？不是整数就够了？" → "圆的半径 5.5、圆周率 3.1416、坐标 100.5——这些都是 float，生活中到处都是小数。"
  - "f-string 的 f 是什么意思？" → "f = format（格式化）。告诉 Python：花括号 {} 里是变量，不是普通文字。"

- **时间弹性**：①阶段一超时→阶段三（演示画多边形）加速，直接在代码中演示，不单独做链条传递游戏；②阶段二知识点讲太久→实操②③合并，一起完成；③整体拖堂→小测改为口头问答（保留核心问题），练习卡带回家做。
