{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d1df0d84",
   "metadata": {
    "updated_for": "精简不常用知识点"
   },
   "source": [
    "# 第 2 讲｜Python 数值计算：数据类型与运算符\n",
    "\n",
    "**对象：** 已会变量、输入输出的 Python 初学者  \n",
    "**课堂目标：** 掌握数字类型、显式转换、常用运算符与优先级，并完成时间间隔和 BMI 两个实训。  \n",
    "**参考：** 《Python 快速编程入门（第 3 版）》第 2.5-2.7 节。\n",
    "\n",
    "> 学习主线：确认数字的表示 → 选择正确运算 → 用括号表达口径 → 用边界样例验证结果。\n",
    "\n",
    "\n",
    "> **课堂节奏：** 每个知识点先运行“课堂演示（样本代码）”，再由学生在紧随其后的“课堂练习（学生填写）”中补全答案。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "386c0025",
   "metadata": {},
   "source": [
    "## 1. 先预测：外观相近的内容，类型和运算相同吗？\n",
    "\n",
    "    10        # 整数 int\n",
    "    10.0      # 浮点数 float\n",
    "    \"10\"      # 字符串 str\n",
    "\n",
    "前两个都是数值，第三个是文本。屏幕显示相近，不代表类型和可用运算相同。\n",
    "\n",
    "本节先使用 type(x) 观察一个值的类型：把任意值放进括号，type(x) 会返回它属于哪一类，\n",
    "例如 int、float 或 str。它只用于检查，不改变原来的值。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dbbdc8c1",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "069cdd91",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.495171Z",
     "iopub.status.busy": "2026-07-22T11:47:12.494904Z",
     "iopub.status.idle": "2026-07-22T11:47:12.502971Z",
     "shell.execute_reply": "2026-07-22T11:47:12.502582Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10 == 10.0： True\n",
      "10 == '10'： False\n"
     ]
    }
   ],
   "source": [
    "# values = [10, 10.0, \"10\"]\n",
    "# for value in values:\n",
    "#     print(value, type(value))\n",
    "\n",
    "print(\"10 == 10.0：\", 10 == 10.0)\n",
    "print(\"10 == '10'：\", 10 == \"10\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1cd85bb4",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "b346ef7b",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.504955Z",
     "iopub.status.busy": "2026-07-22T11:47:12.504728Z",
     "iopub.status.idle": "2026-07-22T11:47:12.506890Z",
     "shell.execute_reply": "2026-07-22T11:47:12.506541Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'int'>\n",
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "# 目标：比较整数、浮点数和字符串的类型与相等结果。\n",
    "integer_value = 8\n",
    "float_value = 8.0\n",
    "text_value = \"8\"\n",
    "print(type(integer_value))\n",
    "print(integer_value == float_value)  # 请预测并运行\n",
    "print(integer_value == text_value)   # 请预测并运行"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "175628a4",
   "metadata": {},
   "source": [
    "## 2. 整数 `int`：用于计数、页码和库存\n",
    "\n",
    "整数不带小数部分，适合表示商品数量、页码和库存变化。下划线可让大数字更易读，\n",
    "不会改变数值本身。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a0757bd5",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "6416a030",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.508775Z",
     "iopub.status.busy": "2026-07-22T11:47:12.508610Z",
     "iopub.status.idle": "2026-07-22T11:47:12.511709Z",
     "shell.execute_reply": "2026-07-22T11:47:12.511306Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10 <class 'int'>\n",
      "-3 <class 'int'>\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "order_count = 10\n",
    "stock_change = -3\n",
    "annual_sales = 1_250_000\n",
    "\n",
    "print(order_count, type(order_count))\n",
    "print(stock_change, type(stock_change))\n",
    "print(annual_sales == 1250000)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6de1b83a",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "aa15c5ce",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.513678Z",
     "iopub.status.busy": "2026-07-22T11:47:12.513513Z",
     "iopub.status.idle": "2026-07-22T11:47:12.515666Z",
     "shell.execute_reply": "2026-07-22T11:47:12.515294Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：建立三个整数变量，分别表示页码、库存变化和年访问量。\n",
    "# page_number =              # 请填写整数\n",
    "# stock_change =             # 请填写正数或负数整数\n",
    "# annual_visits =            # 请填写一个带下划线的大整数\n",
    "# print(page_number, stock_change, annual_visits)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "59c5beab",
   "metadata": {},
   "source": [
    "## 3. 浮点数 float：适合一般小数计算，但存在存储近似\n",
    "\n",
    "科学记数法 3.14e-3 表示 $3.14 \\times 10^{-3}$。许多常见小数只能近似存储，因此比较计算结果时不宜总用严格相等。\n",
    "\n",
    "本节演示两个新工具，先认识用途：\n",
    "\n",
    "- isclose(a, b)：比较两个数是否足够接近，返回布尔值；它来自 math 模块。\n",
    "- Decimal(\"数字文本\")：根据数字文本创建更精确的十进制数；它来自 decimal 模块。\n",
    "\n",
    "两者都只用于观察浮点误差的处理方式，日常基础计算仍可使用 float。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "501bfc9f",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "35acdaf4",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.517566Z",
     "iopub.status.busy": "2026-07-22T11:47:12.517432Z",
     "iopub.status.idle": "2026-07-22T11:47:12.521088Z",
     "shell.execute_reply": "2026-07-22T11:47:12.520704Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "普通浮点： 0.30000000000000004\n"
     ]
    }
   ],
   "source": [
    "from math import isclose\n",
    "from decimal import Decimal\n",
    "\n",
    "result = 0.1 + 0.2\n",
    "print(\"普通浮点：\", result)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "cbcfc82f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "严格等于 0.3： False\n",
      "足够接近 0.3： True\n",
      "Decimal： 0.3\n"
     ]
    }
   ],
   "source": [
    "print(\"严格等于 0.3：\", result == 0.3)\n",
    "print(\"足够接近 0.3：\", isclose(result, 0.3))\n",
    "print(\"Decimal：\", Decimal(\"0.1\") + Decimal(\"0.2\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "4da13ca3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(Decimal(\"0.1\") + Decimal(\"0.2\")) == 0.3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b3c5b92d",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ebb38504",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.523137Z",
     "iopub.status.busy": "2026-07-22T11:47:12.522946Z",
     "iopub.status.idle": "2026-07-22T11:47:12.525205Z",
     "shell.execute_reply": "2026-07-22T11:47:12.524830Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：计算 0.1 + 0.2，并使用 isclose 判断是否接近 0.3。\n",
    "# from math import isclose\n",
    "# result =                  # 请填写加法\n",
    "# print(result)\n",
    "# print(isclose(result,     ))  # 请填写比较目标"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a8ba749a",
   "metadata": {},
   "source": [
    "## 4. 布尔值 bool：判断条件的结果只有真或假\n",
    "\n",
    "布尔值只有 True 和 False，常由比较表达式产生。\n",
    "\n",
    "bool(x) 是一个转换函数：把值 x 转换为真值或假值。常见假值有 None、数值零、空字符串、空列表、空字典；非空字符串 \"False\" 仍然是真值。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "35350f35",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "0212d1ee",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.527230Z",
     "iopub.status.busy": "2026-07-22T11:47:12.527056Z",
     "iopub.status.idle": "2026-07-22T11:47:12.529849Z",
     "shell.execute_reply": "2026-07-22T11:47:12.529418Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "bool(None) = False\n",
      "bool(0) = False\n",
      "bool(0.0) = False\n",
      "bool('') = False\n",
      "bool([]) = False\n",
      "bool({}) = False\n",
      "bool('False') = True\n",
      "bool(1) = True\n"
     ]
    }
   ],
   "source": [
    "candidates = [None, 0, 0.0, \"\", [], {}, \"False\", 1]\n",
    "for value in candidates:\n",
    "    print(f\"bool({value!r}) = {bool(value)}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f14c10fd",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# bool(\"apple\") vs bool(\"\")\n",
    "# bool(1) vs bool(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "db2718c9",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "53ec1ab4",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.532268Z",
     "iopub.status.busy": "2026-07-22T11:47:12.532080Z",
     "iopub.status.idle": "2026-07-22T11:47:12.534206Z",
     "shell.execute_reply": "2026-07-22T11:47:12.533822Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 -> False\n",
      " -> False\n",
      "0 -> True\n",
      "[] -> False\n",
      "[0] -> True\n"
     ]
    }
   ],
   "source": [
    "# 目标：预测下列值转换为 bool 后的结果，再取消注释运行。\n",
    "values = [0, \"\", \"0\", [], [0]]\n",
    "for value in values:\n",
    "    print(value, \"->\", bool(value))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "e6c34328",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "int(float(\"4.27\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4e7702ea",
   "metadata": {},
   "source": [
    "## 5. 显式类型转换：先验证输入，再计算\n",
    "\n",
    "| 函数 | 输入 | 返回结果 | 易错点 |\n",
    "|---|---|---|---|\n",
    "| int(x) | 数字或整数文本 | 整数 | 浮点转整数直接截去小数部分 |\n",
    "| float(x) | 数字或小数文本 | 浮点数 | 文本必须符合数字格式 |\n",
    "| bool(x) | 任意值 | 布尔值 | 非空字符串通常为真 |\n",
    "\n",
    "这些函数都把括号里的值转换为新的类型，原变量本身不会自动改变。转换文本时，先考虑失败路径：不符合格式的文本会引发 ValueError。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d39c6b5",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "d8cdab26",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.536097Z",
     "iopub.status.busy": "2026-07-22T11:47:12.535945Z",
     "iopub.status.idle": "2026-07-22T11:47:12.538702Z",
     "shell.execute_reply": "2026-07-22T11:47:12.538333Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "42 -> 42.0\n",
      "3.14 -> 3.14\n",
      "abc -> 不是可转换的数字\n",
      "int(3.9) = 3\n",
      "int(True) = 1\n"
     ]
    }
   ],
   "source": [
    "samples = [\"42\", \"3.14\", \"abc\"]\n",
    "for text in samples:\n",
    "    try:\n",
    "        number = float(text)\n",
    "        print(text, \"->\", number)\n",
    "    except ValueError:\n",
    "        print(text, \"-> 不是可转换的数字\")\n",
    "\n",
    "print(\"int(3.9) =\", int(3.9))\n",
    "print(\"int(True) =\", int(True))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6dfcddf1",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "9d384614",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.540573Z",
     "iopub.status.busy": "2026-07-22T11:47:12.540418Z",
     "iopub.status.idle": "2026-07-22T11:47:12.542453Z",
     "shell.execute_reply": "2026-07-22T11:47:12.542057Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：将数量文本和单价文本转换后计算销售额。\n",
    "# quantity_text = \"5\"\n",
    "# price_text = \"12.8\"\n",
    "# quantity =                # 请填写 int 转换\n",
    "# price =                   # 请填写 float 转换\n",
    "# total =                   # 请填写计算\n",
    "# print(f\"销售额：{total:.2f} 元\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37f44edd",
   "metadata": {},
   "source": [
    "## 6. 算术运算符：商、整商和余数要分清\n",
    "\n",
    "| 运算 | 含义 | `17` 与 `5` 的结果 |\n",
    "|---|---|---:|\n",
    "| `+ - *` | 加、减、乘 | `22, 12, 85` |\n",
    "| `/` | 普通除法 | `3.4` |\n",
    "| `//` | 向下取整除法 | `3` |\n",
    "| `%` | 余数 | `2` |\n",
    "| `**` | 幂 | `1419857` |\n",
    "\n",
    "分钟换算、分页、奇偶判断都经常同时用到 `//` 和 `%`。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "17b43773",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "4ccdb570",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.544198Z",
     "iopub.status.busy": "2026-07-22T11:47:12.544048Z",
     "iopub.status.idle": "2026-07-22T11:47:12.546938Z",
     "shell.execute_reply": "2026-07-22T11:47:12.546508Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a / b  = 3.4\n",
      "a // b = 3\n",
      "a % b  = 2\n",
      "a ** b = 1419857\n",
      "2 小时 5 分钟\n"
     ]
    }
   ],
   "source": [
    "a, b = 17, 5\n",
    "print(\"a / b  =\", a / b)\n",
    "print(\"a // b =\", a // b)\n",
    "print(\"a % b  =\", a % b)\n",
    "print(\"a ** b =\", a ** b)\n",
    "\n",
    "total_minutes = 125\n",
    "print(total_minutes // 60, \"小时\", total_minutes % 60, \"分钟\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d8e1da1",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "19fee2b0",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.548669Z",
     "iopub.status.busy": "2026-07-22T11:47:12.548522Z",
     "iopub.status.idle": "2026-07-22T11:47:12.550358Z",
     "shell.execute_reply": "2026-07-22T11:47:12.550060Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：把 367 分钟拆成小时和分钟。\n",
    "total_minutes = 367\n",
    "hours =                   # 请填写整除\n",
    "minutes =                 # 请填写余数\n",
    "print(hours, \"小时\", minutes, \"分钟\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "f476e34c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(6, 7)\n"
     ]
    }
   ],
   "source": [
    "def time_calculator(minutes):\n",
    "    hours = minutes // 60\n",
    "    minutes = minutes % 60\n",
    "    return hours, minutes\n",
    "\n",
    "print(time_calculator(367))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b09b5fd0",
   "metadata": {},
   "source": [
    "## 7. 赋值与复合赋值：更新“当前状态”\n",
    "\n",
    "```python\n",
    "stock = 100\n",
    "stock -= 8\n",
    "stock += 20\n",
    "```\n",
    "\n",
    "多变量赋值支持交换：`a, b = b, a`。复合赋值前变量必须已经存在；`/=` 通常会让结果成为浮点数。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "09f15c7d",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当前库存： 92\n",
      "stock 92\n"
     ]
    }
   ],
   "source": [
    "stock = 100\n",
    "# -= \n",
    "stock = stock - 8\n",
    "print(\"当前库存：\", stock)\n",
    "# stock -= 8\n",
    "print(\"stock\", stock)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e5896294",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "stock: 没有\n",
      "stock: 100\n"
     ]
    }
   ],
   "source": [
    "stock = \"没有\"\n",
    "print(\"stock:\", stock)\n",
    "\n",
    "stock = 100\n",
    "print(\"stock:\", stock)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0c658c7d",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "b4cd4f46",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.551917Z",
     "iopub.status.busy": "2026-07-22T11:47:12.551782Z",
     "iopub.status.idle": "2026-07-22T11:47:12.553996Z",
     "shell.execute_reply": "2026-07-22T11:47:12.553710Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当前库存： 112\n",
      "交换后： B A\n"
     ]
    }
   ],
   "source": [
    "stock = 100\n",
    "stock -= 8\n",
    "stock += 20\n",
    "print(\"当前库存：\", stock)\n",
    "\n",
    "a, b = \"A\", \"B\"\n",
    "a, b = b, a\n",
    "print(\"交换后：\", a, b)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e11e51f5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ABC DEF XYZ\n"
     ]
    }
   ],
   "source": [
    "a, b, c = \"ABC\", \"DEF\", \"XYZ\"\n",
    "print(a, b, c)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20fdcca5",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "fda6879e",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.555885Z",
     "iopub.status.busy": "2026-07-22T11:47:12.555638Z",
     "iopub.status.idle": "2026-07-22T11:47:12.557651Z",
     "shell.execute_reply": "2026-07-22T11:47:12.557355Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：库存从 50 件开始，先入库 12 件，再出库 7 件。\n",
    "# stock = 50\n",
    "# stock +=                 # 请填写入库数量\n",
    "# stock -=                 # 请填写出库数量\n",
    "# print(\"当前库存：\", stock)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7ad8cd7c",
   "metadata": {},
   "source": [
    "## 8. 比较与逻辑：把业务条件写成布尔表达式\n",
    "\n",
    "比较运算符：`== != > < >= <=`  \n",
    "逻辑运算符：`and or not`\n",
    "\n",
    "```python\n",
    "is_target = (\n",
    "    quantity >= 100\n",
    "    and unit_price < 200\n",
    "    and not is_discontinued\n",
    ")\n",
    "```\n",
    "\n",
    "用 99、100、101 测试阈值，可发现 `>` 与 `>=` 的边界差异。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "c21dcb00",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "True or False"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9669e36f",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7deafaa4",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.559400Z",
     "iopub.status.busy": "2026-07-22T11:47:12.559237Z",
     "iopub.status.idle": "2026-07-22T11:47:12.562163Z",
     "shell.execute_reply": "2026-07-22T11:47:12.561734Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "99 > 100： False >= 100： False\n",
      "100 > 100： False >= 100： True\n",
      "101 > 100： True >= 100： True\n",
      "最终条件： True\n"
     ]
    }
   ],
   "source": [
    "# for quantity in [99, 100, 101]:\n",
    "#     strict = quantity > 100\n",
    "#     inclusive = quantity >= 100\n",
    "#     print(quantity, \"> 100：\", strict, \">= 100：\", inclusive)\n",
    "\n",
    "quantity = 101\n",
    "unit_price = 199.0\n",
    "is_discontinued = False\n",
    "is_target = quantity >= 100 and unit_price < 200 and not is_discontinued\n",
    "print(\"最终条件：\", is_target)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce112c2e",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3f84cca3",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.563979Z",
     "iopub.status.busy": "2026-07-22T11:47:12.563807Z",
     "iopub.status.idle": "2026-07-22T11:47:12.565724Z",
     "shell.execute_reply": "2026-07-22T11:47:12.565400Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：判断一个商品是否满足销量至少 100、单价低于 200、且未停售。\n",
    "quantity = 100\n",
    "unit_price = 199.0\n",
    "is_discontinued = False\n",
    "is_target = (quantity >=100 \n",
    "             and unit_price<200 \n",
    "             and not is_discontinued\n",
    "             )\n",
    "print(\"是否目标商品：\", is_target)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "80d0e88c",
   "metadata": {},
   "source": [
    "## 9. 成员运算符：判断“是否属于集合”\n",
    "\n",
    "`in` 和 `not in` 可用于字符串、列表、元组、集合和字典。对字典使用 `in` 时默认检查键。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "238f82d2",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c9159292",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.567453Z",
     "iopub.status.busy": "2026-07-22T11:47:12.567306Z",
     "iopub.status.idle": "2026-07-22T11:47:12.570064Z",
     "shell.execute_reply": "2026-07-22T11:47:12.569684Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "allowed_channels = [\"直播\", \"短视频\", \"搜索\"] # 列表\n",
    "channel = \"直播\"\n",
    "print(channel in allowed_channels)\n",
    "\n",
    "# 键值对（key-value pairs）\n",
    "# order = {\"product\": \"双肩包\", \"quantity\": 3} # 字典\n",
    "# print(\"product\" in order)\n",
    "# # print(\"双肩包\" in order)          # 默认不检查字典的值\n",
    "# print(\"双肩包\" in order.values())\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "cd539935",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['product', 'quantity'])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "order.keys()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f8c3dc2c",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "56407465",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.571922Z",
     "iopub.status.busy": "2026-07-22T11:47:12.571784Z",
     "iopub.status.idle": "2026-07-22T11:47:12.573677Z",
     "shell.execute_reply": "2026-07-22T11:47:12.573405Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：判断渠道是否在允许集合中，并判断字典是否含有 price 这个键。\n",
    "# allowed_channels = {\"直播\", \"搜索\"}\n",
    "# channel = \"短视频\"\n",
    "# product = {\"name\": \"水杯\", \"price\": 39.9}\n",
    "# print(                    )  # 请填写成员判断\n",
    "# print(                    )  # 请填写字典键判断"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f717b594",
   "metadata": {},
   "source": [
    "## 10. 运算符优先级：业务公式主动加括号\n",
    "\n",
    "常用顺序：括号 → 幂 → 乘除/整除/取余 → 加减 → 比较 → `not` → `and` → `or`。\n",
    "\n",
    "```python\n",
    "net_sales = (sales_quantity - return_quantity) * unit_price\n",
    "```\n",
    "\n",
    "不要依赖读者背优先级。括号既控制计算，也表达业务口径。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b74f624",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "89b48a46",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.575112Z",
     "iopub.status.busy": "2026-07-22T11:47:12.574993Z",
     "iopub.status.idle": "2026-07-22T11:47:12.577296Z",
     "shell.execute_reply": "2026-07-22T11:47:12.577007Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "先扣退单再乘单价： 23283.0\n",
      "缺少括号后的另一种含义： -1467.0\n"
     ]
    }
   ],
   "source": [
    "sales_quantity = 125\n",
    "return_quantity = 8\n",
    "unit_price = 199.0\n",
    "\n",
    "correct = (sales_quantity - return_quantity) * unit_price\n",
    "wrong_scope = sales_quantity - return_quantity * unit_price\n",
    "print(\"先扣退单再乘单价：\", correct)\n",
    "print(\"缺少括号后的另一种含义：\", wrong_scope)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e76725a5",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "eda2c84f",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.578756Z",
     "iopub.status.busy": "2026-07-22T11:47:12.578643Z",
     "iopub.status.idle": "2026-07-22T11:47:12.580300Z",
     "shell.execute_reply": "2026-07-22T11:47:12.580056Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：用括号写出先扣退单、再乘单价的净销售额公式。\n",
    "# sales_quantity = 80\n",
    "# return_quantity = 5\n",
    "# unit_price = 99.0\n",
    "# net_sales =               # 请填写表达式\n",
    "# print(f\"净销售额：{net_sales:.2f} 元\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b89b0199",
   "metadata": {},
   "source": [
    "## 11. 实训一：时间间隔计算器\n",
    "\n",
    "统一转换成“从 0:00 起经过的分钟数”，再做差。若允许跨午夜，可对一天总分钟数取模。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d56346f8",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "5597f9db",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.581757Z",
     "iopub.status.busy": "2026-07-22T11:47:12.581648Z",
     "iopub.status.idle": "2026-07-22T11:47:12.584090Z",
     "shell.execute_reply": "2026-07-22T11:47:12.583831Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "17:10 -> 18:15： (1, 5)\n",
      "23:50 -> 00:20： (0, 30)\n"
     ]
    }
   ],
   "source": [
    "def time_interval(start_hour, start_minute, end_hour, end_minute):\n",
    "    start_total = start_hour * 60 + start_minute\n",
    "    end_total = end_hour * 60 + end_minute\n",
    "    interval = (end_total - start_total) % (24 * 60)\n",
    "    return interval // 60, interval % 60\n",
    "\n",
    "print(\"17:10 -> 18:15：\", time_interval(17, 10, 18, 15))\n",
    "print(\"23:50 -> 00:20：\", time_interval(23, 50, 0, 20))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "06d40e45",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "871bb32d",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.585497Z",
     "iopub.status.busy": "2026-07-22T11:47:12.585387Z",
     "iopub.status.idle": "2026-07-22T11:47:12.587079Z",
     "shell.execute_reply": "2026-07-22T11:47:12.586829Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：补全函数，计算 22:45 到次日 00:20 的时间间隔。\n",
    "# def time_interval(start_hour, start_minute, end_hour, end_minute):\n",
    "#     start_total =          # 请填写\n",
    "#     end_total =            # 请填写\n",
    "#     interval =             # 请填写允许跨午夜的差值\n",
    "#     return interval // 60, interval % 60\n",
    "#\n",
    "# print(time_interval(22, 45, 0, 20))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6fcd82d3",
   "metadata": {},
   "source": [
    "## 12. 实训二：BMI 计算\n",
    "\n",
    "公式：`BMI = 体重(kg) / 身高(m) ** 2`。\n",
    "\n",
    "本练习只用于学习数值输入、幂和除法，不提供医学诊断。真实健康判断应由专业人员结合更多信息完成。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37169e46",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "a26dacd5",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.588611Z",
     "iopub.status.busy": "2026-07-22T11:47:12.588503Z",
     "iopub.status.idle": "2026-07-22T11:47:12.590673Z",
     "shell.execute_reply": "2026-07-22T11:47:12.590387Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "BMI 计算结果：20.76\n"
     ]
    }
   ],
   "source": [
    "def calculate_bmi(weight_kg, height_m):\n",
    "    if height_m <= 0:\n",
    "        raise ValueError(\"身高必须大于 0\")\n",
    "    return weight_kg / (height_m ** 2)\n",
    "\n",
    "bmi = calculate_bmi(60, 1.70)\n",
    "print(f\"BMI 计算结果：{bmi:.2f}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "66f45793",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "d2722859",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.592068Z",
     "iopub.status.busy": "2026-07-22T11:47:12.591956Z",
     "iopub.status.idle": "2026-07-22T11:47:12.593588Z",
     "shell.execute_reply": "2026-07-22T11:47:12.593333Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：补全 BMI 函数，并在身高不大于 0 时抛出 ValueError。\n",
    "# def calculate_bmi(weight_kg, height_m):\n",
    "#     if height_m <= 0:\n",
    "#         # 请填写异常语句\n",
    "#     return                # 请填写公式\n",
    "#\n",
    "# print(f\"{calculate_bmi(52, 1.60):.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fe5b8415",
   "metadata": {},
   "source": [
    "## 13. 综合微案例：把运算符连成业务口径\n",
    "\n",
    "目标：计算净销售额，并判断商品是否进入重点清单。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e845365d",
   "metadata": {},
   "source": [
    "### 课堂演示（样本代码）\n",
    "\n",
    "先由教师运行下方样本代码，带领学生观察变量、计算过程和输出结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "f58314d4",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.594979Z",
     "iopub.status.busy": "2026-07-22T11:47:12.594891Z",
     "iopub.status.idle": "2026-07-22T11:47:12.597382Z",
     "shell.execute_reply": "2026-07-22T11:47:12.597142Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "净销售数量： 117\n",
      "净销售额：23283.00\n",
      "是否进入重点清单： True\n"
     ]
    }
   ],
   "source": [
    "sales_quantity = 125\n",
    "return_quantity = 8\n",
    "unit_price = 199.0\n",
    "channel = \"直播\"\n",
    "allowed_channels = {\"直播\", \"搜索\"}\n",
    "\n",
    "net_quantity = sales_quantity - return_quantity\n",
    "net_sales = net_quantity * unit_price\n",
    "low_return = return_quantity / sales_quantity <= 0.10\n",
    "is_priority = (\n",
    "    net_sales >= 20_000\n",
    "    and low_return\n",
    "    and channel in allowed_channels\n",
    ")\n",
    "\n",
    "print(\"净销售数量：\", net_quantity)\n",
    "print(f\"净销售额：{net_sales:.2f}\")\n",
    "print(\"是否进入重点清单：\", is_priority)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "03bed12f",
   "metadata": {},
   "source": [
    "### 课堂练习（学生填写）\n",
    "\n",
    "根据刚才的样本代码独立补全下方空位；完成后再运行并检查结果。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "cab24585",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-22T11:47:12.598759Z",
     "iopub.status.busy": "2026-07-22T11:47:12.598651Z",
     "iopub.status.idle": "2026-07-22T11:47:12.600357Z",
     "shell.execute_reply": "2026-07-22T11:47:12.600106Z"
    }
   },
   "outputs": [],
   "source": [
    "# 目标：计算净销售额，并判断商品是否进入重点清单。\n",
    "# sales_quantity = 150\n",
    "# return_quantity = 6\n",
    "# unit_price = 199.0\n",
    "# channel = \"搜索\"\n",
    "# allowed_channels = {\"直播\", \"搜索\"}\n",
    "# net_quantity =             # 请填写\n",
    "# net_sales =                # 请填写\n",
    "# low_return =               # 请填写退单率条件\n",
    "# is_priority = (            # 请填写多条件判断\n",
    "# )\n",
    "# print(net_sales, is_priority)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37751374",
   "metadata": {},
   "source": [
    "## 14. 易错清单与离场检验\n",
    "\n",
    "- `/`、`//`、`%` 含义混淆；\n",
    "- 数字文本未转换；\n",
    "- `int(3.9)` 被误以为四舍五入；\n",
    "- `bool(\"False\")` 被误以为 `False`；\n",
    "- `=` 与 `==` 混用；\n",
    "- `>` 与 `>=` 边界不清；\n",
    "- 多步公式缺少括号；\n",
    "- 分母可能为 0。\n",
    "\n",
    "**离场任务：** 用一句话解释 `125 // 60` 与 `125 % 60` 如何共同得到“2 小时 5 分钟”，并写出可运行表达式。\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
}
