# 教案：第10节 —— while 复杂循环

---

## 元信息

| 项目 | 内容 |
|------|------|
| **课程编号** | G2_第10节 |
| **GESP等级** | **二级**（GESP Python 二级考点） |
| **适用年龄** | 9-11 岁（编程进阶阶段） |
| **核心知识点** | 复杂 while 条件表达式、while 转 for 等价改写、break/continue 综合运用 |
| **记忆钩子** | "while 闷头走直到撞墙，break 撞墙停，continue 跳过坑" |
| **身体锚点** | ① 复杂条件（双手画框） ② break（伸手挡停） ③ continue（跨步跳过） |

---

## 课程目标

1. **掌握** 复杂 while 条件的编写（多条件组合、范围判断）
2. **理解** while 循环与 for 循环的等价转换关系
3. **熟练** 使用 break 跳出循环、continue 跳过本次循环
4. **综合** 运用 break + continue 解决二级真题

---

## 五段式 60 分钟教学流程

---

### 第一段：导入（00:00 - 10:00）—— "回顾 while 三要素"

#### 教师活动

| 时间 | 活动内容 | 教学方式 |
|------|---------|---------|
| 0-3min | 提问："while 三要素是什么？" 引导学生齐声回答"初始值、条件、更新" | 快速回顾 |
| 3-6min | 展示 G1 的乌龟走到边界代码，问："如果想让乌龟在两个墙之间来回走，条件怎么写？" | 设问引导 |
| 6-10min | 引出主题："今天我们要学 while 的'高级模式'——复杂条件、强制退出、跳过某次循环" | 目标宣布 |

#### 导入代码

```python
# 回顾：简单 while
x = 0
while x < 200:
    t.forward(10)
    x = t.xcor()

# 今天要学的：多条件 while
while -200 < x < 200:     # 两个条件同时满足！
    # ...
```

#### 身体锚点

> **【身体锚点 — 条件范围】**  
> 学生站立，左手左伸（-200），右手右伸（+200），说："while 条件就是你的两只手——  
> 你只能在两手之间的范围活动，超出就出界！"

---

### 第二段：知识点精讲（10:00 - 30:00）

#### 2.1 复杂 while 条件（8min）

**单条件 vs 多条件对比：**

| 类型 | 写法 | 示例 |
|------|------|------|
| 单条件 | `while x < 200:` | x 小于 200 就循环 |
| 范围条件 | `while -200 < x < 200:` | x 在 -200 到 200 之间 |
| 复合条件 | `while x > 0 and x < 200:` | 使用 and/or 连接 |
| 取反条件 | `while not x >= 200:` | 使用 not 取反 |

**重点讲解：范围条件**

```python
# Python 特有的链式比较
while -200 < x < 200:
    # 等价于：while x > -200 and x < 200:
    pass
```

**复合条件示例：**

```python
# 同时满足：x 在范围内 且 没超时
x = 0
timeout = 0
while x < 200 and timeout < 50:
    t.forward(10)
    x = t.xcor()
    timeout = timeout + 1

# 满足任一条件就继续：位置没到 或 还没超时
while x < 200 or timeout < 50:
    # ...
```

#### 2.2 while 转 for 等价改写（6min）

**核心思想：** 任何 for 循环都可以改写成 while，反之亦然。

**for → while 转换模板：**

```python
# for 版本
for i in range(5):
    print(i)

# while 版本（等价）
i = 0
while i < 5:
    print(i)
    i = i + 1
```

**二级考点真题举例：**

```
题目：将以下 for 循环改写成 while 循环

for n in range(10, 0, -1):
    print(n)

答案：
n = 10
while n > 0:
    print(n)
    n = n - 1
```

**转换对照表：**

| for 形式 | while 等价 |
|---------|-----------|
| `for i in range(n):` | `i = 0` / `while i < n:` / `i += 1` |
| `for i in range(a, b):` | `i = a` / `while i < b:` / `i += 1` |
| `for i in range(a, b, s):` | `i = a` / `while i < b:` / `i += s` |
| `for i in "hello":` | `index = 0` / `while index < len(s):` / `s[index]` |

#### 2.3 break + continue 综合运用（6min）

**break 详解（强制退出）：**

```python
# break：遇到就退出整个循环
n = 1
while n <= 10:
    if n == 5:
        print("到5了，break退出！")
        break          # 整个循环结束
    print(n)
    n = n + 1
# 输出：1 2 3 4 到5了，break退出！
```

**continue 详解（跳过本次）：**

```python
# continue：遇到就跳过本次循环，进入下一次
n = 1
while n <= 5:
    n = n + 1
    if n == 3:
        print("遇到3，跳过！")
        continue       # 跳过本次，进入下一次循环
    print("处理:", n)
# 输出：处理:2 遇到3，跳过！ 处理:4 处理:5 处理:6
```

**break vs continue 对比：**

| 关键词 | 作用 | 比喻 |
|--------|------|------|
| `break` | **终止**整个循环 | 撞到墙就停 |
| `continue` | **跳过**本次循环 | 遇到坑就跳过去 |

**二级真题示例：**

```python
# 题目：找出 1-20 中不能被 3 整除的数，遇到 15 就停止
n = 0
while n < 20:
    n = n + 1
    if n % 3 == 0:
        continue        # 能被3整除的跳过
    if n == 15:
        break           # 到15就停止
    print(n)
# 输出：1 2 4 5 7 8 10 11 13 14
```

---

### 第三段：演示（30:00 - 40:00）—— "综合案例"

#### 演示 1：while + if 边界反弹（进阶版）

```python
import turtle
t = turtle.Turtle()

dx = 5
x = 0
count = 0

while -200 < x < 200:        # 复杂条件：在范围内
    t.setx(t.xcor() + dx)
    x = t.xcor()

    if x >= 200:
        dx = -dx
        count = count + 1
        print(f"碰右墙！反弹（第{count}次）")

    if x <= -200:
        dx = -dx
        count = count + 1
        print(f"碰左墙！反弹（第{count}次）")
```

**教学要点：**
- while 条件用范围判断 `-200 < x < 200`
- 内部嵌套 if 实现反弹逻辑
- 反弹次数计数器跟踪循环状态

#### 演示 2：break + continue 综合应用

```python
# 模拟"接水果游戏"：水果从 5 个位置掉落
# 遇到腐烂水果（3号位置）跳过
# 接到 5 个好水果就结束

caught = 0
position = 0

while position < 10:     # 10 个掉落位置
    position = position + 1

    if position == 3:    # 3号位置是烂水果
        print(f"位置{position}: 🍂 腐烂了，跳过！")
        continue

    if position == 7:    # 7号位置是炸弹
        print(f"位置{position}: 💣 炸弹！游戏结束！")
        break

    caught = caught + 1
    print(f"位置{position}: 🍎 接住！已接{caught}个")

    if caught >= 5:      # 接到5个好水果就赢
        print("🎉 赢了！接到5个好水果！")
        break
```

#### 演示 3：while 等价改写演示

```python
# 同一逻辑的 for 和 while 版本对比

print("=== for 版本 ===")
for i in range(5, 0, -1):
    print(f"倒数 {i}")

print("\n=== while 等价版本 ===")
i = 5
while i > 0:
    print(f"倒数 {i}")
    i = i - 1
```

---

### 第四段：实操练习（40:00 - 55:00）

#### 练习 1：复杂条件实现（5min）

```
题目：补全代码，让乌龟在 x ∈ [-150, 150] 范围内来回走动，
     碰到边界反弹，反弹 4 次后退出。
```

**参考答案：**
```python
dx = 5
x = 0
bounce_count = 0

while -150 < x < 150 and bounce_count < 4:
    t.setx(t.xcor() + dx)
    x = t.xcor()
    if x >= 150 or x <= -150:
        dx = -dx
        bounce_count = bounce_count + 1
```

#### 练习 2：for 转 while（5min）

```
题目：将下面的 for 循环改写成 while 循环

for i in range(1, 11):
    if i % 2 == 0:
        print(i, "是偶数")
```

**参考答案：**
```python
i = 1
while i <= 10:
    if i % 2 == 0:
        print(i, "是偶数")
    i = i + 1
```

#### 练习 3：break + continue 填空（5min）

```
题目：补全代码，打印 1-10 中所有的奇数，到 9 后停止

n = 0
while n < 10:
    n = n + 1
    if n % 2 == 0:
        ____   # 偶数跳过
    if n == 9:
        ____   # 到9结束
    print(n)
```

**答案：** `continue`、`break`

---

### 第五段：小测（55:00 - 60:00）

#### 题目 1（选择）
`while -5 < x < 5:` 的意思是？
A. x 大于 -5 或者 x 小于 5  
B. x 大于 -5 并且 x 小于 5  
C. x 等于 -5 或 x 等于 5  
D. x 不等于 -5 且 x 不等于 5  

**答案：B**

#### 题目 2（选择）
以下代码输出什么？
```python
n = 0
while n < 5:
    n = n + 1
    if n == 3:
        continue
    print(n)
```
A. 1 2 3 4 5  
B. 1 2 4 5  
C. 1 2 3  
D. 1 2  

**答案：B**（3被continue跳过）

#### 题目 3（选择）
break 和 continue 的区别是？
A. 功能完全相同  
B. break 终止循环，continue 跳过本次  
C. break 跳过本次，continue 终止循环  
D. 两者都不能用在 while 中  

**答案：B**

#### 题目 4（填空）
用 while 改写 `for i in range(1, 6): print(i)`

**答案：**
```python
i = 1
while i <= 5:
    print(i)
    i = i + 1
```

#### 题目 5（简答）
什么情况下必须用 while 而不是 for？

**答案：** 当不知道循环次数，只知道循环结束条件时，必须用 while。

---

## 板书设计

```
┌─────────────────────────────────────────────────────────────┐
│           第10节  while 复杂循环                             │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  复杂条件：                                                   │
│  while -200 < x < 200:    ← 范围判断                         │
│  while x > 0 and y < 10:  ← 复合条件                        │
│                                                              │
│  break vs continue：                                         │
│    break    → 终止整个循环（撞墙停）                          │
│    continue → 跳过本次循环（跳坑）                            │
│                                                              │
│  for ↔ while 等价转换：                                       │
│  for i in range(5)  ⟺  i=0; while i<5: ... i+=1            │
│                                                              │
│  记忆钩子：                                                   │
│  "while 闷头走直到撞墙，break 撞墙停，continue 跳过坑"         │
└─────────────────────────────────────────────────────────────┘
```

---

## 课后延伸

| 项目 | 内容 |
|------|------|
| 课后练习 | 课后练习_第10节.md |
| 预习内容 | 第10节 —— 列表基础 |
| 拓展挑战 | 用 while + break/continue 实现"猜数字"游戏 |
| 二级真题 | 完成课后练习中的二级真题部分 |

---

## 教学反思

| 维度 | 记录 |
|------|------|
| 学生掌握率 | 预计 70% 学生能独立完成 for↔while 转换 |
| 常见困惑 | continue 跳过循环后 n 的更新位置容易搞混 |
| 改进方向 | 增加 continue 的执行流程图，可视化"跳过"的路径 |
| 备注 | 二级真题部分需额外准备 2-3 道作为补充练习 |
