# G2-16 课后练习 —— 函数动机
> **GESP等级：二级 | 考级考点：GESP Python 二级**

**姓名：__________  日期：__________**

---

| 建议用时 | 20-30分钟 |
| GESP考点 | #30 函数定义与调用 |

---

## 第一部分：基础巩固（3道必做题）

---

### 第1题：选词填空（理解def基础语法）

**难度：** ⭐

**GESP考点：【#30 函数定义与调用】**

> 小明刚开始学函数，总是写错。请帮他补全下面的代码！

**题1a：** 定义函数时，下面哪个是正确写法？

```python
# 选项A
def draw_square()    ← 缺少什么？

# 选项B
def draw_square():   ← 正确的！

# 选项C
def draw_square()    ← 缺少什么？
```

A和C缺少了什么符号？→ _____

**从下面选一个：**
- ○ 分号 `;`
- ○ 冒号 `:`  ✅
- ○ 句号 `.`
- ○ 逗号 `,`

---

**题1b：** 下面的代码中，函数体应该怎样排版？

```python
def draw_square():
for i in range(4):      ← 这行有问题吗？
    t.forward(100)
    t.right(90)
```

问题出在哪？→ _____

**从下面选一个：**
- ○ `for` 那一行需要缩进 ✅（函数体必须缩进）
- ○ `forward` 那一行不要缩进
- ○ 完全没有问题
- ○ 函数名写错了

---

**题1c：** 调用函数的正确写法是？

```python
def say_hello():
    print("你好！")

# 下面哪个是正确调用？
# A. def say_hello()
# B. say_hello()
# C. say_hello
# D. def say_hello
```

正确答案：_____（B）

**解释：** 调用函数只需要函数名 + 小括号，不需要再写 `def`！

---

**题1d：** 下面的代码会输出什么？

```python
def say_hello():
    print("你好！")

# 注意：下面没有调用函数！
print("程序结束")
```

输出结果：_____

- ○ "你好！" 然后 "程序结束"
- ○ "程序结束" ✅（因为只定义了函数，没调用，函数体不执行）
- ○ "你好！"
- ○ 什么都不输出

> 💡 **记忆钩子：** 光定义不调用 = 白写！函数体里的代码只有在调用时才会执行。

---

### 第2题：判断"定义"还是"调用"

**难度：** ⭐

**GESP考点：【#30 函数定义与调用】**

> 请判断下面的每一行代码是"定义"还是"调用"。

```python
# 代码①
def draw_square():       → 这是：_______
    for i in range(4):
        t.forward(100)
        t.right(90)

# 代码②
draw_square()            → 这是：_______

# 代码③
def draw_triangle():     → 这是：_______
    for i in range(3):
        t.forward(100)
        t.left(120)

# 代码④
draw_triangle()          → 这是：_______

# 代码⑤
print("hello")           → 这是：_______
```

| 序号 | 是"定义"还是"调用"？ | 判断依据 |
|------|---------------------|---------|
| ① | _____ | 有 `def`、有 `:`、有缩进 |
| ② | _____ | 没有 `def`、没有 `:`、直接写函数名+括号 |
| ③ | _____ | 有 `def`、有 `:`、有缩进 |
| ④ | _____ | 没有 `def`、没有 `:`、直接写函数名+括号 |
| ⑤ | _____ | 也是调用——调用的是内置函数 `print` |

---

### 第3题：预测输出（理解定义vs调用的执行流程）

**难度：** ⭐⭐

**GESP考点：【#30 函数定义与调用】**

> 读下面的代码，写出运行后会输出什么。

**题3a：**

```python
def greet():
    print("你好呀！")

print("开始")
greet()
print("结束")
```

输出：
```
___________
___________
___________
```

**题3b：**

```python
def draw_line():
    print("-----")

print("第1行")
draw_line()
print("第2行")
draw_line()
print("第3行")
```

输出：
```
___________
___________
___________
___________
___________
```

**题3c（进阶）：**

```python
def show_a():
    print("A")

def show_b():
    print("B")

show_a()
show_b()
show_a()
```

输出：
```
_____
_____
_____
```

**题3d（挑战）：**

```python
def step1():
    print("第1步：打开冰箱门")

def step2():
    print("第2步：把大象放进冰箱")

def step3():
    print("第3步：关上冰箱门")

print("开始放大象！")
step1()
step2()
step3()
print("完成！")
```

输出：
```
___________________
___________________
___________________
___________________
___________________
```

---

## 第二部分：进阶挑战（2道选做题）

---

### 第4题：改错大挑战

**难度：** ⭐⭐⭐

**GESP考点：【#30 函数定义与调用】**

> 下面每题都有错误，请找出并改正。

**题4a：漏了冒号**

```python
def draw_square()
    for i in range(4):
        t.forward(100)
        t.right(90)
```

错误：___________
改正：___________

---

**题4b：忘记缩进**

```python
def draw_square():
for i in range(4):
    t.forward(100)
    t.right(90)
```

错误：___________
改正：___________

---

**题4c：调用时多写了 def**

```python
def draw_square():
    for i in range(4):
        t.forward(100)
        t.right(90)

def draw_square()    # 调用——写错了吧？
```

错误：___________
改正：___________

---

**题4d：先调用后定义**

```python
draw_square()    # 还没定义就调用了！

def draw_square():
    for i in range(4):
        t.forward(100)
        t.right(90)
```

错误：___________
改正：___________

---

**题4e：定义后忘记调用**

```python
def draw_square():
    for i in range(4):
        t.forward(100)
        t.right(90)

print("我想画一个正方形")
# 后面没有调用 draw_square()
```

问题：___________
改正：___________

---

### 第5题：创意挑战——设计你的专属函数

**难度：** ⭐⭐⭐

**GESP考点：【#30 函数定义与调用】**

> 发挥创意，自己设计一个函数！

**题目：** 从下面的主题中选一个（或自己想一个），定义一个函数，并在主程序中调用它。

**选项A：画一个房子**
- 定义 `draw_house()` 画一个简单的房子（正方形+三角形屋顶）
- 提示：先画一个正方形做墙，再在上面画一个三角形做屋顶

**选项B：画一个笑脸**
- 定义 `draw_face()` 画一个笑脸
- 提示：画两个小圆当眼睛，一个弧线当嘴巴

**选项C：画一个螺旋**
- 定义 `draw_spiral()` 画一个螺旋
- 提示：边长逐渐增加，如 `length = 10, 20, 30, ...`

**选项D：你的创意**
- 函数名：_____
- 画什么：_____

```python
import turtle

t = turtle.Turtle()
t.speed(5)

# 请在这里定义你的函数（在下面写）








# 请在这里调用你的函数

```

---

## 完成情况表

请家长/学生勾选完成情况：

|------|------|------|---------|---------|
| 第1题 | 选词填空 | ⭐ | ✅ / ❌ | |
| 第2题 | 判断定义/调用 | ⭐ | ✅ / ❌ | |
| 第3题 | 预测输出 | ⭐⭐ | ✅ / ❌ | |
| 第4题 | 改错挑战 | ⭐⭐⭐ | ✅ / ❌（选做） | |
| 第5题 | 创意挑战 | ⭐⭐⭐ | ✅ / ❌（选做） | |

---

## 家长辅导小贴士

1. **def的核心比喻——"写菜谱"：**
   - `def` 定义函数 = 写一份菜谱（步骤写下来存着）
   - 调用函数 = 按照菜谱做菜（真正去执行）
   - 光写不调用 = 只写了菜谱但从来没做过——没用！
   - 这个比喻是本节课的核心记忆点，孩子忘了就提醒："菜谱写了吗？做菜了吗？"

2. **定义和调用的区别：**
   - 定义必须有 `def` 关键字 + 函数名 + `():` + 缩进的函数体
   - 调用只需要函数名 + `()`，没有 `def`、没有冒号、没有缩进
   - 判断方法：看开头是不是 `def`，是就是定义，不是就是调用

3. **常见的三个"坑"：**
   - 忘记冒号 `:` → SyntaxError（语法错误）
   - 忘记缩进函数体 → IndentationError（缩进错误）
   - 先调用后定义 → NameError（名字没找到）

4. **逐行理解执行流程：**
   - Python读到 `def` 开头的一行，知道这是在定义函数——它把函数体"记住"但不执行
   - 读到 `函数名()` 时，才跳去执行函数体里的代码
   - 函数执行完毕，回到调用处继续往后执行
   - 一个函数可以调用任意多次

5. **辅导时可以问的问题：**
   - "这一段是定义还是调用？怎么判断的？"
   - "如果没有写调用，程序会画出正方形吗？为什么？"
   - "定义一次，可以调用几次？试试看！"
   - "改错题的四个错误分别是什么？"


---

**自我评价：** □ 全都会了  □ 大部分会了  □ 还要再练练
