{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 流程控制\n",
    "\n",
    "Python 不仅仅需要可以求值的 [表达式](intro/basic-type) 与 [函数](function)，还需要一些结构用于表达循环和控制等。\n",
    "\n",
    "Python **语句** 就是告诉你的程序应该做什么的句子。\n",
    "\n",
    "- 程序由模块构成。\n",
    "- 模块包含语句。\n",
    "- 语句包含表达式。\n",
    "- 表达式建立并处理对象。\n",
    "\n",
    "## 真值测试\n",
    "\n",
    "- 所有的对象都有一个固有的布尔值：真或假。\n",
    "- 任何非零的数字或非空的对象都是真。\n",
    "- `0`、空对象和特殊对象 `None` 被视为假。\n",
    "- 比较和相等测试是递归地应用于数据结构。\n",
    "- 比较和相等测试返回 `True` 或 `False`。\n",
    "- 布尔运算符 `and` 和 `or` 返回一个真或假的操作对象。\n",
    "- 一旦知道结果，布尔运算符就会停止评估（\"短路\"）。\n",
    "\n",
    "真值判定|结果\n",
    ":-|:-\n",
    "`X and Y`|如果 `X` 和 `Y` 都为真，则为真。\n",
    "`X or Y`|如果 `X` 或 `Y` 为真，则为真。\n",
    "`not X`|如果 `X` 是假的，则为真。\n",
    "\n",
    "### 比较、相等和真值\n",
    "\n",
    "- `==` 操作符测试值的相等性。\n",
    "- `is` 表达式测试对象的一致性。\n",
    "\n",
    "真值判断："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, True)"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "S1 = 'spam'\n",
    "S2 = 'spam'\n",
    "\n",
    "S1 == S2, S1 is S2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "比较："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(True, False, False, False)"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "L1 = [1, ('a', 3)] \n",
    "L2 = [1, ('a', 3)]\n",
    "\n",
    "L1 == L2, L1 is L2, L1 < L2, L1 > L2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bool('')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 短路计算\n",
    "\n",
    "- `or`: 从左到右求算操作对象，然后返回第一个为真的操作对象。\n",
    "- `and`: 从左到右求算操作对象，然后返回第一个为假的操作对象。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(2, 3)"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2 or 3, 3 or 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 40,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[] or 3"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{}"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[] or {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(3, 2)"
      ]
     },
     "execution_count": 42,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "2 and 3, 3 and 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[] and {}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[]"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "3 and []"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 断言\n",
    "\n",
    "用于测试推断："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "ename": "AssertionError",
     "evalue": "num 应该为正数！",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mAssertionError\u001b[0m                            Traceback (most recent call last)",
      "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_10012/2608566952.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[0mnum\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m-\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[1;32massert\u001b[0m \u001b[0mnum\u001b[0m \u001b[1;33m>\u001b[0m \u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;34m'num 应该为正数！'\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mAssertionError\u001b[0m: num 应该为正数！"
     ]
    }
   ],
   "source": [
    "num = -1\n",
    "assert num > 0, 'num 应该为正数！'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `if` 条件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "平年\n"
     ]
    }
   ],
   "source": [
    "year = 1990\n",
    "if year % 4 == 0:\n",
    "    if year % 400 == 0:\n",
    "        print('闰年')\n",
    "    elif year % 100 == 0:\n",
    "        print('平年')\n",
    "    else:\n",
    "        print('闰年')\n",
    "else:\n",
    "    print('平年')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用 `and` 与 `or` 的短路逻辑简化表达式："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "平年\n"
     ]
    }
   ],
   "source": [
    "year = 1990\n",
    "if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0:\n",
    "    print('闰年')\n",
    "else:\n",
    "    print('平年')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`if` 的短路（short-ciecuit）计算：`A = Y if X else Z`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "平年\n"
     ]
    }
   ],
   "source": [
    "year = 1990\n",
    "print('闰年') if (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 else print('平年')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'t'"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'t' if 'spam' else 'f'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `for` 循环\n",
    "\n",
    "遍历序列对象：\n",
    "\n",
    "\n",
    "```python\n",
    "for target in object:                 # 将对象项目分配给目标   \n",
    "    statements                        # 循环体\n",
    "```\n",
    "\n",
    "- `pass` / `...`：空占位语句"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(5):\n",
    "    ...  # 等价于 pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 7]"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(range(1, 10, 6))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10!=3628800\n"
     ]
    }
   ],
   "source": [
    "# 阶乘\n",
    "x = 1\n",
    "for i in range(1, 11):\n",
    "    x *= i\n",
    "print(f'10!={x}')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python 的 `for` 语句迭代列表或字符串等任意序列，元素的迭代顺序与在序列中出现的顺序一致。例如："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "# 可以是 Python 的可迭代容器\n",
    "seq = [1, 2, 3, 4, 5] \n",
    "for i in seq:\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 循环的技巧\n",
    "\n",
    "在序列中循环时，用 {func}`enumerate` 函数可以同时取出位置索引和对应的值："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 苹果\n",
      "1 相机\n",
      "2 飞机\n"
     ]
    }
   ],
   "source": [
    "for i, v in enumerate(['苹果', '相机', '飞机']):\n",
    "    print(i, v)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "同时循环两个或多个序列时，用 {func}`zip` 函数可以将其内的元素一一匹配："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你的 名字 是什么？ 答案是 Judy。\n",
      "你的 缺点 是什么？ 答案是 比较懒。\n",
      "你的 最喜爱的颜色 是什么？ 答案是 天空蓝。\n"
     ]
    }
   ],
   "source": [
    "questions = ['名字', '缺点', '最喜爱的颜色']\n",
    "answers = ['Judy', '比较懒', '天空蓝']\n",
    "for q, a in zip(questions, answers):\n",
    "    print(f'你的 {q} 是什么？ 答案是 {a}。')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "逆向循环序列时，先正向定位序列，然后调用 {func}`reversed` 函数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9\n",
      "7\n",
      "5\n",
      "3\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "for i in reversed(range(1, 10, 2)):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "按指定顺序循环序列，可以用 {func}`sorted` 函数，在不改动原序列的基础上，重新返回一个序列："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pear\n",
      "apple\n",
      "apple\n",
      "orange\n",
      "orange\n",
      "banana\n"
     ]
    }
   ],
   "source": [
    "basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']\n",
    "for i in sorted(basket, key=len):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用 {func}`set` 去除序列中的重复元素。使用 {func}`sorted` 加 {func}`set` 则按排序后的顺序，循环遍历序列中的唯一元素："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "apple\n",
      "banana\n",
      "orange\n",
      "pear\n"
     ]
    }
   ],
   "source": [
    "basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']\n",
    "for f in sorted(set(basket)):\n",
    "    print(f)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 序列和其他类型的比较\n",
    "\n",
    "序列对象可以与相同序列类型的其他对象比较。这种比较使用 字典式 顺序：\n",
    "\n",
    "- 首先，比较首个元素，如果不相等，则可确定比较结果；如果相等，则比较之后的元素，以此类推，直到其中一个序列结束。\n",
    "- 如果要比较的两个元素本身是相同类型的序列，则递归地执行字典式顺序比较。\n",
    "- 如果两个序列中所有的对应元素都相等，则两个序列相等。\n",
    "- 如果一个序列是另一个的初始子序列，则较短的序列可被视为较小（较少）的序列。\n",
    "- 对于字符串来说，字典式顺序使用 Unicode 码位序号排序单个字符。\n",
    "\n",
    "下面列出了一些比较相同类型序列的例子："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 71,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(1, 2, 3) < (1, 2, 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[1, 2, 3] < [1, 2, 4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 73,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "'ABC' < 'C' < 'Pascal' < 'Python' # 支持链式比较"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 74,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(1, 2, 3, 4) < (1, 2, 4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(1, 2) < (1, 2, -1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(1, 2, 3) == (1.0, 2.0, 3.0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(1, 2, ('aa', 'ab'))   < (1, 2, ('abc', 'a'), 4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `while` 循环\n",
    "\n",
    "`while` 循环结构：\n",
    "\n",
    "```python\n",
    "初值条件\n",
    "while test:  # 循环测试\n",
    "    statements  # 循环体\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "spam pam am m "
     ]
    }
   ],
   "source": [
    "x = 'spam'\n",
    "while x: # 直至耗尽 x\n",
    "    print(x, end=' ')\n",
    "    x = x[1:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "28\n",
      "55\n",
      "82\n"
     ]
    }
   ],
   "source": [
    "x = 1  # 初值条件\n",
    "while x <= 100:  # 终止条件\n",
    "    print(x)\n",
    "    x += 27"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Callataz 猜想\n",
    "\n",
    "```{note}\n",
    "任意取一个正整数 $n$，如果 $n$ 是一个偶数，则除以 $2$ 得到 $n/2$；\n",
    "如果 $n$ 是一个奇数，则乘以 $3$ 加 $1$ 得到 $3n+1$，重复以上操作，我们将得到一串数字。\n",
    "\n",
    "Collatz 猜想：任何正整数 $n$ 参照以上规则，都将回归 $1$。\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def collatz_guess(num):\n",
    "    assert num > 0, 'num 必须为正数'\n",
    "    while num != 1:\n",
    "        if num % 2 == 0:\n",
    "            # 保证 num 在接下来的运算为整数\n",
    "            num //= 2\n",
    "        else:\n",
    "            num *= 3 \n",
    "            num += 1\n",
    "    return num\n",
    "\n",
    "collatz_guess(75)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 斐波那契数列\n",
    "\n",
    "```{note}\n",
    "斐波那契数列：\n",
    "\n",
    "$$\n",
    "\\begin{cases}\n",
    "f_0 = f_1 = 1\\\\\n",
    "f_{n+2} = f_{n} + f_{n+1}, & n \\in \\mathbb{N}\n",
    "\\end{cases}\n",
    "$$\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 \n"
     ]
    }
   ],
   "source": [
    "def fib(n): # 写出斐波那契数列，直到n\n",
    "    \"\"\"打印直到 n 的斐波那契数列\"\"\"\n",
    "    a, b = 0, 1\n",
    "    while a < n:\n",
    "        print(a, end=' ')\n",
    "        a, b = b, a+b\n",
    "    print()\n",
    "\n",
    "fib(2000)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```{note}\n",
    "1. 第一行中的 **多重赋值**：变量 `a` 和 `b` 同时获得新值 `0` 和 `1`。\n",
    "2. 最后一行又用了一次多重赋值，这体现在右表达式在赋值前就已经求值了。**右表达式求值顺序为从左到右。**\n",
    "```\n",
    "\n",
    "## `continue`\n",
    "\n",
    "`continue`：跳到最近所在循环的开头处（来到循环的首行）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "8 6 4 2 0 "
     ]
    }
   ],
   "source": [
    "x = 10\n",
    "while x:\n",
    "    x -= 1\n",
    "    if x % 2 != 0:\n",
    "        continue  # 跳过打印\n",
    "    print(x, end=' ')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2 是偶数\n",
      "3 是奇数\n",
      "4 是偶数\n",
      "5 是奇数\n",
      "6 是偶数\n",
      "7 是奇数\n"
     ]
    }
   ],
   "source": [
    "for num in range(2, 8):\n",
    "    if num % 2 == 0:\n",
    "        print(f\"{num} 是偶数\")\n",
    "        continue\n",
    "    print(f\"{num} 是奇数\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## `else` 子句\n",
    "\n",
    "- `break`：跳出所在的最内层循环（跳过整个循环语句）\n",
    "- `else`：只有当循环正常离开时才会执行（也就是没有碰到 `break` 语句）\n",
    "\n",
    "和循环 `else` 子句结合，`break` 语句通常可以忽略所需要的搜索状态标志位。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def fator(y):\n",
    "    '''仅仅打印 y 的首个因子'''\n",
    "    x = y // 2\n",
    "    while x > 1:\n",
    "        if y % x == 0:\n",
    "            print(y, '有因子', x)\n",
    "            break\n",
    "        x -= 1\n",
    "    else:  # 没有碰到 break 才会执行\n",
    "        print(y, '是质数！')\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "7 是质数！\n",
      "88 有因子 44\n",
      "45 有因子 15\n"
     ]
    }
   ],
   "source": [
    "fator(7), fator(88), fator(45);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "看一个更复杂的例子："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2 是质数！\n",
      "3 是质数！\n",
      "4 = 2 x 2\n",
      "5 是质数！\n",
      "6 = 2 x 3\n",
      "7 是质数！\n",
      "8 = 2 x 4\n",
      "9 = 3 x 3\n"
     ]
    }
   ],
   "source": [
    "for n in range(2, 10):\n",
    "    for x in range(2, n):\n",
    "        if n % x == 0:\n",
    "            print(n, '=', x, 'x', n//x)\n",
    "            break\n",
    "    else:\n",
    "        # 循环失败，没有找到一个因子\n",
    "        print(n, '是质数！')\n"
   ]
  }
 ],
 "metadata": {
  "interpreter": {
   "hash": "5bd0e00e2a19143fe511974294bb108c565eeab444c74caa312a526033b1280c"
  },
  "kernelspec": {
   "display_name": "Python 3.9.5 64-bit ('jupyter-book': conda)",
   "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.10.0"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
