{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b0217281",
   "metadata": {},
   "source": [
    "# 第 3 讲｜Python 流程控制：条件判断与循环\n",
    "\n",
    "**对象：** 已会变量、输入输出、比较和逻辑运算的 Python 初学者。  \n",
    "**课堂目标：** 用条件语句做选择，用循环完成重复任务，并能在合适时结束或跳过循环。  \n",
    "**参考：** Python 快速编程入门（第 3 版）第 3 章，参考文件 3f.pdf。\n",
    "\n",
    "本课以固定样例演示，避免课堂中等待键盘输入；课后练习再把规则补完整。\n",
    "\n",
    "> **课堂节奏：** 每个知识点先运行“课堂演示（样本代码）”，再由学生在紧随其后的“课堂练习（学生填写）”中补全答案。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "539ac900",
   "metadata": {},
   "source": [
    "## 1. 流程控制先回答三个问题\n",
    "\n",
    "1. 条件成立时做什么，不成立时做什么？\n",
    "2. 哪件事需要重复做？重复到什么时候？\n",
    "3. 什么时候应当提前结束，或跳过本轮？\n",
    "\n",
    "条件表达式会得到 True 或 False。if 会根据这个结果决定是否执行缩进的代码块。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe688fc2",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "24cce307",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.532543Z",
     "iopub.status.busy": "2026-07-26T07:23:08.532371Z",
     "iopub.status.idle": "2026-07-26T07:23:08.538754Z",
     "shell.execute_reply": "2026-07-26T07:23:08.538273Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "分数： 58\n",
      "是否及格： False\n"
     ]
    }
   ],
   "source": [
    "score = 58\n",
    "print(\"分数：\", score)\n",
    "print(\"是否及格：\", score >= 60)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "41c4af29",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "f8aef43f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.541177Z",
     "iopub.status.busy": "2026-07-26T07:23:08.541016Z",
     "iopub.status.idle": "2026-07-26T07:23:08.543035Z",
     "shell.execute_reply": "2026-07-26T07:23:08.542750Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "60.0\n"
     ]
    }
   ],
   "source": [
    "# 目标：预测条件结果，并补全成立时的输出。\n",
    "score = 40\n",
    "# print(score >= 60)\n",
    "if score < 60:\n",
    "    # 请填写输出语句\n",
    "    print(score*1.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f1231da9",
   "metadata": {},
   "source": [
    "## 2. if：条件成立才进入缩进代码块\n",
    "\n",
    "    if score >= 60:\n",
    "        print(\"考试及格\")\n",
    "\n",
    "冒号标记条件开始；缩进决定哪些语句属于这个分支。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1f99994f",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "0d1e6e63",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.544758Z",
     "iopub.status.busy": "2026-07-26T07:23:08.544618Z",
     "iopub.status.idle": "2026-07-26T07:23:08.547381Z",
     "shell.execute_reply": "2026-07-26T07:23:08.547014Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "分数： 58\n",
      "本次评估结束\n",
      "\n",
      "分数： 88\n",
      "考试及格\n",
      "本次评估结束\n"
     ]
    }
   ],
   "source": [
    "score = 58\n",
    "print(\"分数：\", score)\n",
    "if score >= 60:\n",
    "    print(\"考试及格\")\n",
    "print(\"本次评估结束\")\n",
    "\n",
    "print()\n",
    "score = 88\n",
    "print(\"分数：\", score)\n",
    "if score >= 60:\n",
    "    print(\"考试及格\")\n",
    "print(\"本次评估结束\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "623bd8a9",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "9d0d8e98",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.549771Z",
     "iopub.status.busy": "2026-07-26T07:23:08.549599Z",
     "iopub.status.idle": "2026-07-26T07:23:08.551489Z",
     "shell.execute_reply": "2026-07-26T07:23:08.551202Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：分别测试 55 分和 75 分，观察 if 只处理条件成立的情况。\n",
    "# score = 55\n",
    "# if score >= 60:\n",
    "#     print(\"考试及格\")\n",
    "#\n",
    "# score = 75\n",
    "# if score >= 60:\n",
    "#     # 请填写输出语句"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "71c22623",
   "metadata": {},
   "source": [
    "## 3. if-else：两种结果都要处理\n",
    "\n",
    "当规则覆盖成立和不成立两种情况时，用 else 保证程序都有反馈。\n",
    "\n",
    "下面会用到上一阶段已学过的函数：\n",
    "\n",
    "- def 函数名(参数)：定义一段可重复调用的代码；\n",
    "- return 结果：把函数计算的结果交回给调用处。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d1d6ed34",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "39"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def add(a,b):\n",
    "    return a+b\n",
    "\n",
    "results = add(6,4)\n",
    "\n",
    "results*5+4"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9f87a2e",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "7c8bb825",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.553056Z",
     "iopub.status.busy": "2026-07-26T07:23:08.552916Z",
     "iopub.status.idle": "2026-07-26T07:23:08.555540Z",
     "shell.execute_reply": "2026-07-26T07:23:08.555113Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "59 -> 不及格\n"
     ]
    }
   ],
   "source": [
    "def pass_or_fail(score):\n",
    "    if score >= 60:\n",
    "        return \"及格\"\n",
    "    else:\n",
    "        return \"不及格\"\n",
    "\n",
    "# 和下面的函数等价： \n",
    "# def pass_or_fail(score):\n",
    "#     if score >= 60:\n",
    "#         return \"及格\"\n",
    "#     return \"不及格\"\n",
    "\n",
    "\n",
    "print(59, \"->\", pass_or_fail(59))\n",
    "# print(60, \"->\", pass_or_fail(60))\n",
    "# print(100, \"->\", pass_or_fail(100))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "98625720",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "及格\n"
     ]
    }
   ],
   "source": [
    "results = pass_or_fail(60)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "58fe9557",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "254333d2",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.557785Z",
     "iopub.status.busy": "2026-07-26T07:23:08.557626Z",
     "iopub.status.idle": "2026-07-26T07:23:08.559440Z",
     "shell.execute_reply": "2026-07-26T07:23:08.559166Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：补全函数，使其返回及格或不及格。\n",
    "# def pass_or_fail(score):\n",
    "#     if score < 60:\n",
    "#         return             # 请填写\n",
    "#     else:\n",
    "#         return             # 请填写\n",
    "\n",
    "# print(pass_or_fail(58))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "69601f47",
   "metadata": {},
   "source": [
    "## 4. if-elif-else：多分支按顺序匹配\n",
    "\n",
    "高分阈值必须先判断。分支一旦命中，后续 elif 和 else 不再执行。\n",
    "\n",
    "- 大于等于 85：优秀\n",
    "- 大于等于 75：良好\n",
    "- 大于等于 60：中等\n",
    "- 其他：差"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4bd2e8e9",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "6dec4ff1",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "a4511e59",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.561039Z",
     "iopub.status.busy": "2026-07-26T07:23:08.560913Z",
     "iopub.status.idle": "2026-07-26T07:23:08.564465Z",
     "shell.execute_reply": "2026-07-26T07:23:08.563977Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "59 -> 差\n",
      "60 -> 中等\n",
      "74 -> 中等\n",
      "75 -> 良好\n",
      "84 -> 良好\n",
      "85 -> 优秀\n"
     ]
    }
   ],
   "source": [
    "def grade(score):\n",
    "    if score >= 85:\n",
    "        return \"优秀\"\n",
    "    elif score >= 75:\n",
    "        return \"良好\"\n",
    "    elif score >= 60:\n",
    "        return \"中等\"\n",
    "    else:\n",
    "        return \"差\"\n",
    "\n",
    "\n",
    "print(59, \"->\", grade(59))\n",
    "print(60, \"->\", grade(60))\n",
    "print(74, \"->\", grade(74))\n",
    "print(75, \"->\", grade(75))\n",
    "print(84, \"->\", grade(84))\n",
    "print(85, \"->\", grade(85))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b2fae478",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a\n"
     ]
    }
   ],
   "source": [
    "print(\"a\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "62e2cc78",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a b\n"
     ]
    }
   ],
   "source": [
    "print(\"a\",\"b\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "84bdb659",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "8009f137",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.566557Z",
     "iopub.status.busy": "2026-07-26T07:23:08.566416Z",
     "iopub.status.idle": "2026-07-26T07:23:08.568338Z",
     "shell.execute_reply": "2026-07-26T07:23:08.568075Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：按 >=85、>=75、>=60、其他的规则补全等级函数。\n",
    "# def grade(score):\n",
    "#     # 请填写 if、elif、else 分支\n",
    "#     return \"请修改\"\n",
    "#\n",
    "# print(grade(75))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "196584ee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'语文优秀'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def grade(score:int, subject:str) -> str:\n",
    "    if score >= 85:\n",
    "        if subject == \"语文\":\n",
    "            return \"语文优秀\"\n",
    "        else:\n",
    "            return \"优秀\"\n",
    "    elif score >= 75:\n",
    "        return \"良好\"\n",
    "    elif score >= 60:\n",
    "        return \"中等\"\n",
    "    else:\n",
    "        return \"差\"\n",
    "\n",
    "grade(98, \"语文\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21686bd8",
   "metadata": {},
   "source": [
    "## 5. 条件嵌套：只有外层成立，才检查内层\n",
    "\n",
    "计算某月天数时，先按月份分类；只有 2 月才需要判断闰年。\n",
    "闰年规则：能被 400 整除，或能被 4 整除但不能被 100 整除。\n",
    "\n",
    "本例对非法月份直接返回一段提示文本，不额外引入异常处理。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c89a7b4d",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "2c99e0e9",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.570053Z",
     "iopub.status.busy": "2026-07-26T07:23:08.569930Z",
     "iopub.status.idle": "2026-07-26T07:23:08.573636Z",
     "shell.execute_reply": "2026-07-26T07:23:08.573199Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2025 年 3 月： 31\n"
     ]
    }
   ],
   "source": [
    "# def days_in_month(year, month):\n",
    "#     if (month == 1 or month == 3 or month == 5 or month == 7 \n",
    "#         or month == 8 or month == 10 or month == 12):\n",
    "#         return 31\n",
    "#     elif month == 4 or month == 6 or month == 9 or month == 11:\n",
    "#         return 30\n",
    "#     elif month == 2:\n",
    "#         # 这一年是不是闰年\n",
    "#         is_leap = year % 400 == 0 \n",
    "#         if is_leap:\n",
    "#             return 29\n",
    "#         return 28\n",
    "#     else:\n",
    "#         return \"月份必须在 1 到 12 之间\"\n",
    "\n",
    "def days_in_month(year, month):\n",
    "    if month in [1,3,5,7,8,10,12]:\n",
    "        return 31\n",
    "    elif month in [4,6,9,11]:\n",
    "        return 30\n",
    "    elif month == 2:\n",
    "        # 这一年是不是闰年\n",
    "        is_leap = year % 400 == 0 \n",
    "        if is_leap:\n",
    "            return 29\n",
    "        return 28\n",
    "    else:\n",
    "        return \"月份必须在 1 到 12 之间\"\n",
    "\n",
    "\n",
    "# print(\"2024 年 2 月：\", days_in_month(2024, 2))\n",
    "# print(\"2023 年 2 月：\", days_in_month(2023, 2))\n",
    "print(\"2025 年 3 月：\", days_in_month(2025, 3))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f7409704",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "7 in [1,3,5,7,8,10,12]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3c4afd6",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "24a5a93a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.575552Z",
     "iopub.status.busy": "2026-07-26T07:23:08.575398Z",
     "iopub.status.idle": "2026-07-26T07:23:08.577323Z",
     "shell.execute_reply": "2026-07-26T07:23:08.576967Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：补全 2 月的天数判断；只返回 29 或 28。\n",
    "# year = 2024\n",
    "# is_leap = year % 400 == 0 or (\n",
    "#     year % 4 == 0 and year % 100 != 0\n",
    "# )\n",
    "# if is_leap:\n",
    "#     days =               # 请填写\n",
    "# else:\n",
    "#     days =               # 请填写\n",
    "# print(days)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "037491e9",
   "metadata": {},
   "source": [
    "## 6. while：条件为真就继续\n",
    "\n",
    "while 适合不知道要执行多少次、但知道何时停止的任务。\n",
    "循环中必须改变参与条件的变量，否则可能无法停止。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cff89d96",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "d8e6c9ee",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.579116Z",
     "iopub.status.busy": "2026-07-26T07:23:08.578946Z",
     "iopub.status.idle": "2026-07-26T07:23:08.581528Z",
     "shell.execute_reply": "2026-07-26T07:23:08.581087Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 到 20 的和： 210\n",
      "循环结束时 current： 21\n"
     ]
    }
   ],
   "source": [
    "current = 1\n",
    "total = 0\n",
    "while current <= 20:\n",
    "    total += current\n",
    "    current += 1\n",
    "\n",
    "print(\"1 到 20 的和：\", total)\n",
    "print(\"循环结束时 current：\", current)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd9744ff",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "71db2916",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.583441Z",
     "iopub.status.busy": "2026-07-26T07:23:08.583296Z",
     "iopub.status.idle": "2026-07-26T07:23:08.585109Z",
     "shell.execute_reply": "2026-07-26T07:23:08.584850Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：使用 while 计算 1 到 5 的和。\n",
    "# current = 1\n",
    "# total = 0\n",
    "# while current <= 5:\n",
    "#     # 请填写累加和更新\n",
    "#     #\n",
    "# print(total)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1fb9d95",
   "metadata": {},
   "source": [
    "## 7. for 与 range：逐个访问，次数清楚\n",
    "\n",
    "for 适合遍历字符串、列表等对象。range(stop) 产生 0 到 stop-1；\n",
    "range(start, stop) 产生 start 到 stop-1。右边界不包含在结果中。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "49cdf74a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[0, 1, 2]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(3)) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "3eb84b6b",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[3, 4, 5, 6, 7, 8]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(3,9))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e6ff64a9",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "aff07d7a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.586708Z",
     "iopub.status.busy": "2026-07-26T07:23:08.586560Z",
     "iopub.status.idle": "2026-07-26T07:23:08.589212Z",
     "shell.execute_reply": "2026-07-26T07:23:08.588717Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "遍历字符串：\n",
      "P\n",
      "y\n",
      "t\n",
      "h\n",
      "o\n",
      "n\n"
     ]
    }
   ],
   "source": [
    "print(\"遍历字符串：\")\n",
    "for letter in \"Python\":\n",
    "    print(letter)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "065d9061",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "遍历列表：\n",
      "0\n",
      "4\n",
      "8\n",
      "12\n",
      "8.4\n"
     ]
    }
   ],
   "source": [
    "print(\"遍历列表：\")\n",
    "for element in [0,1,2,3,2.1]:\n",
    "    print(element*4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "96dc4c01",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "range(2, 6)：\n",
      "2 3 4 5 "
     ]
    }
   ],
   "source": [
    "print(\"\\n\\nrange(2, 6)：\")\n",
    "for number in range(2, 6):\n",
    "    print(number, end=\" \")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "e0975f0e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "range(2, 6)：\n",
      "2 3 4 5 "
     ]
    }
   ],
   "source": [
    "print(\"\\n\\nrange(2, 6)：\")\n",
    "for number in [2,3,4,5]:\n",
    "    print(number, end=\" \")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eddef966",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "f7523315",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.591317Z",
     "iopub.status.busy": "2026-07-26T07:23:08.591092Z",
     "iopub.status.idle": "2026-07-26T07:23:08.593097Z",
     "shell.execute_reply": "2026-07-26T07:23:08.592813Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：使用 range(1, 6) 输出 1 到 5。\n",
    "# for number in range(1, 6):\n",
    "#     # 请填写输出语句\n",
    "#     #"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "90a5a59b",
   "metadata": {},
   "source": [
    "## 8. 循环嵌套：外层控制行，内层控制列\n",
    "\n",
    "输出棋盘、乘法表、二维数据时，经常需要两层循环。\n",
    "先说清每层的职责，再写代码。\n",
    "\n",
    "print(内容, end=\" \") 会让下一次输出仍留在同一行；不写 end 时，print 默认会在输出后换行。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5c29746e",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "6080368c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.594708Z",
     "iopub.status.busy": "2026-07-26T07:23:08.594578Z",
     "iopub.status.idle": "2026-07-26T07:23:08.597239Z",
     "shell.execute_reply": "2026-07-26T07:23:08.596900Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "+ - + - + \n",
      "- + - + - \n",
      "+ - + - + \n",
      "- + - + - \n",
      "+ - + - + \n"
     ]
    }
   ],
   "source": [
    "def draw_board(size):\n",
    "    for row in range(size):\n",
    "        for col in range(size):\n",
    "            if (row + col) % 2 == 0:\n",
    "                print(\"+\", end=\" \")\n",
    "            else:\n",
    "                print(\"-\", end=\" \")\n",
    "        print()\n",
    "\n",
    "\n",
    "draw_board(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "0546cd37",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "+ - + \n",
      "- + - \n"
     ]
    }
   ],
   "source": [
    "def draw_board(a,b):\n",
    "    for row in range(a):\n",
    "        for col in range(b):\n",
    "            if (row + col) % 2 == 0:\n",
    "                print(\"+\", end=\" \")\n",
    "            else:\n",
    "                print(\"-\", end=\" \")\n",
    "        print()\n",
    "\n",
    "\n",
    "draw_board(2,3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8914c6c",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "5b78003c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.599585Z",
     "iopub.status.busy": "2026-07-26T07:23:08.599406Z",
     "iopub.status.idle": "2026-07-26T07:23:08.601252Z",
     "shell.execute_reply": "2026-07-26T07:23:08.600971Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "* * * \n",
      "* * * \n",
      "* * * \n",
      "* * * \n"
     ]
    }
   ],
   "source": [
    "# 目标：用两层 for 循环输出 3 行、每行 3 个星号。\n",
    "for row in range(4):\n",
    "    for col in range(3):\n",
    "        print(\"*\", end=\" \")\n",
    "    print()\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "89427e52",
   "metadata": {},
   "source": [
    "## 9. break 与 continue：一个结束循环，一个跳过本轮\n",
    "\n",
    "- break：立即结束当前这一层循环。\n",
    "- continue：跳过当前轮余下代码，直接进入下一轮。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5f2e1d85",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "ee1ef626",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.602941Z",
     "iopub.status.busy": "2026-07-26T07:23:08.602805Z",
     "iopub.status.idle": "2026-07-26T07:23:08.605429Z",
     "shell.execute_reply": "2026-07-26T07:23:08.605017Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "continue：\n",
      "P y t h n "
     ]
    }
   ],
   "source": [
    "# print(\"break：\")\n",
    "# for letter in \"Python\":\n",
    "#     if letter == \"o\":\n",
    "#         break\n",
    "#     print(letter, end=\" \")\n",
    "\n",
    "print(\"\\ncontinue：\")\n",
    "for letter in \"Python\":\n",
    "    if letter == \"o\":\n",
    "        continue\n",
    "    print(letter, end=\" \")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b8eb27b5",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "bc1bc913",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.607559Z",
     "iopub.status.busy": "2026-07-26T07:23:08.607386Z",
     "iopub.status.idle": "2026-07-26T07:23:08.609194Z",
     "shell.execute_reply": "2026-07-26T07:23:08.608937Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：遍历 Python，遇到 o 时跳过本轮，输出其他字符。\n",
    "# for letter in \"Python\":\n",
    "#     if letter == \"o\":\n",
    "#         # 请填写 continue\n",
    "#     print(letter, end=\" \")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa0fe5f1",
   "metadata": {},
   "source": [
    "## 10. 实训一：会员等级评定\n",
    "\n",
    "同时满足消费金额和积分门槛才升级。规则从高到低判断，避免低等级先被命中。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb17b486",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "12e6d03f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.610807Z",
     "iopub.status.busy": "2026-07-26T07:23:08.610673Z",
     "iopub.status.idle": "2026-07-26T07:23:08.613501Z",
     "shell.execute_reply": "2026-07-26T07:23:08.613145Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "消费 600、积分 5200： 白金会员\n",
      "消费 250、积分 100： 普通会员\n",
      "消费 100、积分 500： 非会员\n"
     ]
    }
   ],
   "source": [
    "def member_level(amount, points):\n",
    "    if amount >= 500 and points >= 5000:\n",
    "        return \"白金会员\"\n",
    "    if amount >= 200 or points >= 2000:\n",
    "        return \"普通会员\"\n",
    "    return \"非会员\"\n",
    "\n",
    "\n",
    "print(\"消费 600、积分 5200：\", member_level(600, 5200))\n",
    "print(\"消费 250、积分 100：\", member_level(250, 100))\n",
    "print(\"消费 100、积分 500：\", member_level(100, 500))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "82206759",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "2b6fc05c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.615733Z",
     "iopub.status.busy": "2026-07-26T07:23:08.615567Z",
     "iopub.status.idle": "2026-07-26T07:23:08.617436Z",
     "shell.execute_reply": "2026-07-26T07:23:08.617123Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：补全白金和普通会员的判断。\n",
    "# def member_level(amount, points):\n",
    "#     if amount >= 500 and points >= 5000:\n",
    "#         return \"白金会员\"\n",
    "#     return                 # 请填写\n",
    "#\n",
    "# print(member_level(600, 5200))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5686a282",
   "metadata": {},
   "source": [
    "## 11. 实训二：物流费用计算\n",
    "\n",
    "先验证地区和重量，再确定首重价与续重价。为练习条件分支，本例直接用 if-elif 判断三个地区，\n",
    "不使用字典查表。超过 2 kg 的部分按完整或不足 1 kg 都计为 1 kg。\n",
    "\n",
    "int(小数) 用于取小数的整数部分，例如 int(1.8) 的结果是 1。这里先取超出重量的整数部分，\n",
    "再用条件判断是否还需要加 1 kg。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d57d90f",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "dc554dbe",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.619071Z",
     "iopub.status.busy": "2026-07-26T07:23:08.618916Z",
     "iopub.status.idle": "2026-07-26T07:23:08.622313Z",
     "shell.execute_reply": "2026-07-26T07:23:08.621925Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "01，1.5 kg -> 13 元\n",
      "02，2 kg -> 12 元\n",
      "03，3.2 kg -> 22 元\n"
     ]
    }
   ],
   "source": [
    "def shipping_fee(region_code, weight_kg):\n",
    "    if weight_kg <= 0:\n",
    "        return \"重量必须大于 0\"\n",
    "\n",
    "    if region_code == \"01\":\n",
    "        first_price, extra_price = 13, 3\n",
    "    elif region_code == \"02\":\n",
    "        first_price, extra_price = 12, 2\n",
    "    elif region_code == \"03\":\n",
    "        first_price, extra_price = 14, 4\n",
    "    else:\n",
    "        return \"地区编号只能是 01、02 或 03\"\n",
    "\n",
    "    if weight_kg <= 2:\n",
    "        return first_price\n",
    "\n",
    "    extra_kg = int(weight_kg - 2)\n",
    "    if weight_kg - 2 > extra_kg:\n",
    "        extra_kg += 1\n",
    "    return first_price + extra_kg * extra_price\n",
    "\n",
    "\n",
    "print(\"01，1.5 kg ->\", shipping_fee(\"01\", 1.5), \"元\")\n",
    "print(\"02，2 kg ->\", shipping_fee(\"02\", 2), \"元\")\n",
    "print(\"03，3.2 kg ->\", shipping_fee(\"03\", 3.2), \"元\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f129a9da",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "3beab648",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.624308Z",
     "iopub.status.busy": "2026-07-26T07:23:08.624167Z",
     "iopub.status.idle": "2026-07-26T07:23:08.626066Z",
     "shell.execute_reply": "2026-07-26T07:23:08.625759Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：华东地区首重 13 元、续重每 kg 3 元。补全 3.2 kg 的费用。\n",
    "# weight_kg = 3.2\n",
    "# first_price = 13\n",
    "# extra_price = 3\n",
    "# extra_kg = 2\n",
    "# fee =                      # 请填写\n",
    "# print(fee)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b15b85a",
   "metadata": {},
   "source": [
    "## 12. 实训三：限制三次的登录检测\n",
    "\n",
    "循环次数明确时可用 for range(3)。成功后立即结束；三次都失败才给出锁定提示。\n",
    "\n",
    "本例的 attempts 中每一项都由用户名和密码组成。for user, password in attempts\n",
    "表示每次循环把这一项中的两个值分别放进 user 和 password。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a837d11",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "10b414ff",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.627572Z",
     "iopub.status.busy": "2026-07-26T07:23:08.627476Z",
     "iopub.status.idle": "2026-07-26T07:23:08.630864Z",
     "shell.execute_reply": "2026-07-26T07:23:08.630506Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "第 1 次：用户名或密码错误，还剩 2 次\n",
      "第 2 次：用户名或密码错误，还剩 1 次\n",
      "第 3 次：登录成功\n"
     ]
    }
   ],
   "source": [
    "def login_check(attempts):\n",
    "    expected_user = \"admin\"\n",
    "    expected_password = \"python\"\n",
    "    attempt_no = 0\n",
    "\n",
    "    for user, password in attempts:\n",
    "        attempt_no += 1\n",
    "        if user == expected_user and password == expected_password:\n",
    "            return f\"第 {attempt_no} 次：登录成功\"\n",
    "\n",
    "        remaining = 3 - attempt_no\n",
    "        if remaining > 0:\n",
    "            print(f\"第 {attempt_no} 次：用户名或密码错误，还剩 {remaining} 次\")\n",
    "\n",
    "    return \"输入错误次数过多，请稍后再试\"\n",
    "\n",
    "\n",
    "attempts = [(\"admin\", \"123\"), (\"guest\", \"python\"), (\"admin\", \"python\")]\n",
    "print(login_check(attempts))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "25fdd12c",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "29a7c75f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.633014Z",
     "iopub.status.busy": "2026-07-26T07:23:08.632857Z",
     "iopub.status.idle": "2026-07-26T07:23:08.634686Z",
     "shell.execute_reply": "2026-07-26T07:23:08.634411Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：补全三次机会的核心判断；成功时立即结束。\n",
    "# attempts = [(\"admin\", \"123\"), (\"admin\", \"python\")]\n",
    "# attempt_no = 0\n",
    "# for user, password in attempts:\n",
    "#     attempt_no += 1\n",
    "#     if user == \"admin\" and password == \"python\":\n",
    "#         # 请填写成功提示和结束循环\n",
    "#         #"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4b53c795",
   "metadata": {},
   "source": [
    "## 13. 拓展：按条件选择房贷年利率\n",
    "\n",
    "教材阶段案例的完整月供公式较长。课堂只练习其中最重要的流程控制部分：\n",
    "根据贷款类型和期限，用条件分支选择年利率。完整公式作为课后拓展阅读。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fecb9090",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，观察条件、循环变量和输出如何变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "fc97f979",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.636416Z",
     "iopub.status.busy": "2026-07-26T07:23:08.636273Z",
     "iopub.status.idle": "2026-07-26T07:23:08.639100Z",
     "shell.execute_reply": "2026-07-26T07:23:08.638710Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "商业贷款 3 年： 0.0475\n",
      "公积金贷款 10 年： 0.031\n"
     ]
    }
   ],
   "source": [
    "def annual_rate(loan_type, years):\n",
    "    if loan_type == \"商业\":\n",
    "        if years <= 5:\n",
    "            return 0.0475\n",
    "        return 0.0490\n",
    "    elif loan_type == \"公积金\":\n",
    "        if years <= 5:\n",
    "            return 0.0260\n",
    "        return 0.0310\n",
    "    return \"贷款类型只能是商业或公积金\"\n",
    "\n",
    "\n",
    "print(\"商业贷款 3 年：\", annual_rate(\"商业\", 3))\n",
    "print(\"公积金贷款 10 年：\", annual_rate(\"公积金\", 10))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b04ae0bf",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "f923fe96",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-26T07:23:08.641298Z",
     "iopub.status.busy": "2026-07-26T07:23:08.641132Z",
     "iopub.status.idle": "2026-07-26T07:23:08.643041Z",
     "shell.execute_reply": "2026-07-26T07:23:08.642770Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：补全公积金贷款的利率判断。\n",
    "# loan_type = \"公积金\"\n",
    "# years = 10\n",
    "# if loan_type == \"公积金\":\n",
    "#     if years <= 5:\n",
    "#         rate =              # 请填写\n",
    "#     else:\n",
    "#         rate =              # 请填写\n",
    "# print(rate)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e7d02d8b",
   "metadata": {},
   "source": [
    "## 14. 离场检验\n",
    "\n",
    "- 多分支为什么应先判断高阈值？\n",
    "- range(2, 6) 会产生哪些数？\n",
    "- break 和 continue 分别改变什么？\n",
    "- 写循环前，能否说清初值、条件、更新？"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "vix",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.8"
  },
  "updated_for": "每个知识点采用课堂演示与学生留空练习，移除未讲解的复杂用法"
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
