diff --git a/01-data-model/README.md b/01-data-model/README.md index 18e2865..bd6d547 100644 --- a/01-data-model/README.md +++ b/01-data-model/README.md @@ -1,25 +1,68 @@ -# The Python Data Model +# Python 数据模型 -Sample code for Chapter 1 of _Fluent Python 2e_ by Luciano Ramalho (O'Reilly, 2020) +_Luciano Ramalho 著《流畅的 Python(第2版)》(O'Reilly, 2020)_ 第一章的示例代码 -## Running the tests +## 运行测试 -### Doctests +### Doctest -Use Python's standard ``doctest`` module to check stand-alone doctest file: +使用 Python 标准库中的 ``doctest`` 模块检查独立的 doctest 文件: $ python3 -m doctest frenchdeck.doctest -v -And to check doctests embedded in a module: +检查嵌入在模块中的 doctest: $ python3 -m doctest vector2d.py -v ### Jupyter Notebook -Install ``pytest`` and the ``nbval`` plugin: +安装 ``pytest`` 及其 ``nbval`` 插件: $ pip install pytest nbval -Run: +运行: $ pytest --nbval + +--- + +## 相关解释 + +### 1. `python3 -m doctest frenchdeck.doctest -v` 是什么写法? + +这是在命令行中运行 Python 的一种方式: +- `python3` 表示使用 Python 3 解释器。 +- `-m doctest` 表示用 doctest 这个标准库模块来运行。 +- `frenchdeck.doctest` 是要检查的文件名。 +- `-v` 表示 verbose(详细)模式,会输出更多信息。 + +这条命令的意思是:用 doctest 模块检查 frenchdeck.doctest 文件中的测试,并详细输出结果。 + +### 2. doctest 是什么模块? + +doctest 是 Python 标准库中的一个模块。它可以自动查找文档字符串(docstring)中的代码示例,并运行这些示例,检查它们的输出是否和文档中写的一致。这样可以保证文档中的代码示例是正确的。 + +#### docstring 是什么? +docstring(文档字符串)是写在 Python 函数、类、模块开头的字符串,用于描述该对象的用途和用法。通常用三引号括起来,紧跟在定义后面。例如: + +```python +def add(a, b): + """返回 a 和 b 的和""" + return a + b +``` + +docstring 一般是开发者手写的,也可以通过一些文档生成工具自动生成模板,但内容通常需要人工补充和完善。 + +### 3. doctest 如何进行检查? + +doctest 会扫描指定的文件或模块,查找形如 Python 交互式命令行(>>>)的代码块,然后执行这些代码,并把实际输出和文档中写的期望输出进行对比。如果一致,测试通过;否则会报告错误。 + +### 4. "嵌入" 是什么? + +这里的“嵌入”指的是 doctest 代码示例直接写在 Python 源代码文件的文档字符串(docstring)里,而不是单独放在 .doctest 文件中。这样可以让文档和代码保持同步。 + +### 5. `pytest --nbval` 又是什么? + +pytest 是一个流行的 Python 测试框架。nbval 是 pytest 的一个插件,可以让 pytest 检查 Jupyter Notebook(.ipynb 文件)中的代码单元格。 + +`pytest --nbval` 这条命令会自动运行当前目录下所有的 Jupyter Notebook 文件,检查每个代码单元格的输出是否和 notebook 文件中保存的输出一致。如果不一致,就会报告错误。这有助于保证 notebook 文档的可重复性和正确性。 diff --git a/01-data-model/data-model.ipynb b/01-data-model/data-model.ipynb index 5b30397..83d38db 100644 --- a/01-data-model/data-model.ipynb +++ b/01-data-model/data-model.ipynb @@ -19,6 +19,38 @@ "## A Pythonic Card Deck" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 相关问题讲解\n", + "\n", + "1. **collections 是什么?**\n", + "\n", + " collections 是 Python 标准库中的一个模块,提供了许多有用的集合类,比如 namedtuple、deque、Counter、OrderedDict 等。这里用到的 namedtuple 可以用来创建类似元组的对象,并且可以通过属性名访问元素。\n", + "\n", + "2. **[str(n) for n in range(2, 11)] + list('JQKA') 中 [] 是列表吗? 列表可以相加?**\n", + "\n", + " - `[]` 是列表的定义方式,`[str(n) for n in range(2, 11)]` 是列表推导式,生成字符串 '2' 到 '10' 的列表。\n", + " - `list('JQKA')` 会把字符串 'JQKA' 拆成 ['J', 'Q', 'K', 'A']。\n", + " - 两个列表可以用 `+` 号相加,结果是拼接成一个新列表。\n", + "\n", + "3. **ranks、suits 是 FrenchDeck 这个类的属性吗?**\n", + "\n", + " 是的,`ranks` 和 `suits` 都是 FrenchDeck 类的类属性(class attribute),它们属于类本身,而不是某个实例。" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### 补充说明\n", + "\n", + "- `_cards` 不是类属性,而是 FrenchDeck 实例的属性(实例属性),它在 `__init__` 方法中通过 `self._cards = ...` 定义,每个实例都有自己的 `_cards`。\n", + "- `ranks` 和 `suits` 是在类体内直接定义的,属于 FrenchDeck 类本身(类属性),所有实例共享。\n", + "- 实例对象也可以通过 `self.ranks` 和 `self.suits` 访问类属性(如果实例没有同名属性时会自动查找类属性)。" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -28,7 +60,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -38,7 +70,7 @@ "\n", "class FrenchDeck:\n", " ranks = [str(n) for n in range(2, 11)] + list('JQKA')\n", - " suits = 'spades diamonds clubs hearts'.split()\n", + " suits = '♠️ ♥️ ♣️ ♦️'.split()\n", "\n", " def __init__(self):\n", " self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks]\n", @@ -52,28 +84,28 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Card(rank='7', suit='diamonds')" + "Card(rank='7', suit='♣️')" ] }, - "execution_count": 2, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "beer_card = Card('7', 'diamonds')\n", + "beer_card = Card('7', '♣️')\n", "beer_card" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -82,7 +114,7 @@ "52" ] }, - "execution_count": 3, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -94,16 +126,56 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Card(rank='2', suit='spades')" + "['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']" ] }, - "execution_count": 4, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "deck.ranks" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['♠️', '♥️', '♣️', '♦️']" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "deck.suits" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Card(rank='2', suit='♠️')" + ] + }, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -114,16 +186,16 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Card(rank='A', suit='hearts')" + "Card(rank='A', suit='♦️')" ] }, - "execution_count": 5, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -134,16 +206,16 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Card(rank='6', suit='diamonds')" + "Card(rank='3', suit='♣️')" ] }, - "execution_count": 6, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -157,18 +229,18 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[Card(rank='2', suit='spades'),\n", - " Card(rank='3', suit='spades'),\n", - " Card(rank='4', suit='spades')]" + "[Card(rank='2', suit='♠️'),\n", + " Card(rank='3', suit='♠️'),\n", + " Card(rank='4', suit='♠️')]" ] }, - "execution_count": 7, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -179,19 +251,19 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "[Card(rank='A', suit='spades'),\n", - " Card(rank='A', suit='diamonds'),\n", - " Card(rank='A', suit='clubs'),\n", - " Card(rank='A', suit='hearts')]" + "[Card(rank='A', suit='♠️'),\n", + " Card(rank='A', suit='♥️'),\n", + " Card(rank='A', suit='♣️'),\n", + " Card(rank='A', suit='♦️')]" ] }, - "execution_count": 8, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -202,65 +274,65 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Card(rank='2', suit='spades')\n", - "Card(rank='3', suit='spades')\n", - "Card(rank='4', suit='spades')\n", - "Card(rank='5', suit='spades')\n", - "Card(rank='6', suit='spades')\n", - "Card(rank='7', suit='spades')\n", - "Card(rank='8', suit='spades')\n", - "Card(rank='9', suit='spades')\n", - "Card(rank='10', suit='spades')\n", - "Card(rank='J', suit='spades')\n", - "Card(rank='Q', suit='spades')\n", - "Card(rank='K', suit='spades')\n", - "Card(rank='A', suit='spades')\n", - "Card(rank='2', suit='diamonds')\n", - "Card(rank='3', suit='diamonds')\n", - "Card(rank='4', suit='diamonds')\n", - "Card(rank='5', suit='diamonds')\n", - "Card(rank='6', suit='diamonds')\n", - "Card(rank='7', suit='diamonds')\n", - "Card(rank='8', suit='diamonds')\n", - "Card(rank='9', suit='diamonds')\n", - "Card(rank='10', suit='diamonds')\n", - "Card(rank='J', suit='diamonds')\n", - "Card(rank='Q', suit='diamonds')\n", - "Card(rank='K', suit='diamonds')\n", - "Card(rank='A', suit='diamonds')\n", - "Card(rank='2', suit='clubs')\n", - "Card(rank='3', suit='clubs')\n", - "Card(rank='4', suit='clubs')\n", - "Card(rank='5', suit='clubs')\n", - "Card(rank='6', suit='clubs')\n", - "Card(rank='7', suit='clubs')\n", - "Card(rank='8', suit='clubs')\n", - "Card(rank='9', suit='clubs')\n", - "Card(rank='10', suit='clubs')\n", - "Card(rank='J', suit='clubs')\n", - "Card(rank='Q', suit='clubs')\n", - "Card(rank='K', suit='clubs')\n", - "Card(rank='A', suit='clubs')\n", - "Card(rank='2', suit='hearts')\n", - "Card(rank='3', suit='hearts')\n", - "Card(rank='4', suit='hearts')\n", - "Card(rank='5', suit='hearts')\n", - "Card(rank='6', suit='hearts')\n", - "Card(rank='7', suit='hearts')\n", - "Card(rank='8', suit='hearts')\n", - "Card(rank='9', suit='hearts')\n", - "Card(rank='10', suit='hearts')\n", - "Card(rank='J', suit='hearts')\n", - "Card(rank='Q', suit='hearts')\n", - "Card(rank='K', suit='hearts')\n", - "Card(rank='A', suit='hearts')\n" + "Card(rank='2', suit='♠️')\n", + "Card(rank='3', suit='♠️')\n", + "Card(rank='4', suit='♠️')\n", + "Card(rank='5', suit='♠️')\n", + "Card(rank='6', suit='♠️')\n", + "Card(rank='7', suit='♠️')\n", + "Card(rank='8', suit='♠️')\n", + "Card(rank='9', suit='♠️')\n", + "Card(rank='10', suit='♠️')\n", + "Card(rank='J', suit='♠️')\n", + "Card(rank='Q', suit='♠️')\n", + "Card(rank='K', suit='♠️')\n", + "Card(rank='A', suit='♠️')\n", + "Card(rank='2', suit='♥️')\n", + "Card(rank='3', suit='♥️')\n", + "Card(rank='4', suit='♥️')\n", + "Card(rank='5', suit='♥️')\n", + "Card(rank='6', suit='♥️')\n", + "Card(rank='7', suit='♥️')\n", + "Card(rank='8', suit='♥️')\n", + "Card(rank='9', suit='♥️')\n", + "Card(rank='10', suit='♥️')\n", + "Card(rank='J', suit='♥️')\n", + "Card(rank='Q', suit='♥️')\n", + "Card(rank='K', suit='♥️')\n", + "Card(rank='A', suit='♥️')\n", + "Card(rank='2', suit='♣️')\n", + "Card(rank='3', suit='♣️')\n", + "Card(rank='4', suit='♣️')\n", + "Card(rank='5', suit='♣️')\n", + "Card(rank='6', suit='♣️')\n", + "Card(rank='7', suit='♣️')\n", + "Card(rank='8', suit='♣️')\n", + "Card(rank='9', suit='♣️')\n", + "Card(rank='10', suit='♣️')\n", + "Card(rank='J', suit='♣️')\n", + "Card(rank='Q', suit='♣️')\n", + "Card(rank='K', suit='♣️')\n", + "Card(rank='A', suit='♣️')\n", + "Card(rank='2', suit='♦️')\n", + "Card(rank='3', suit='♦️')\n", + "Card(rank='4', suit='♦️')\n", + "Card(rank='5', suit='♦️')\n", + "Card(rank='6', suit='♦️')\n", + "Card(rank='7', suit='♦️')\n", + "Card(rank='8', suit='♦️')\n", + "Card(rank='9', suit='♦️')\n", + "Card(rank='10', suit='♦️')\n", + "Card(rank='J', suit='♦️')\n", + "Card(rank='Q', suit='♦️')\n", + "Card(rank='K', suit='♦️')\n", + "Card(rank='A', suit='♦️')\n" ] } ], @@ -271,65 +343,65 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Card(rank='A', suit='hearts')\n", - "Card(rank='K', suit='hearts')\n", - "Card(rank='Q', suit='hearts')\n", - "Card(rank='J', suit='hearts')\n", - "Card(rank='10', suit='hearts')\n", - "Card(rank='9', suit='hearts')\n", - "Card(rank='8', suit='hearts')\n", - "Card(rank='7', suit='hearts')\n", - "Card(rank='6', suit='hearts')\n", - "Card(rank='5', suit='hearts')\n", - "Card(rank='4', suit='hearts')\n", - "Card(rank='3', suit='hearts')\n", - "Card(rank='2', suit='hearts')\n", - "Card(rank='A', suit='clubs')\n", - "Card(rank='K', suit='clubs')\n", - "Card(rank='Q', suit='clubs')\n", - "Card(rank='J', suit='clubs')\n", - "Card(rank='10', suit='clubs')\n", - "Card(rank='9', suit='clubs')\n", - "Card(rank='8', suit='clubs')\n", - "Card(rank='7', suit='clubs')\n", - "Card(rank='6', suit='clubs')\n", - "Card(rank='5', suit='clubs')\n", - "Card(rank='4', suit='clubs')\n", - "Card(rank='3', suit='clubs')\n", - "Card(rank='2', suit='clubs')\n", - "Card(rank='A', suit='diamonds')\n", - "Card(rank='K', suit='diamonds')\n", - "Card(rank='Q', suit='diamonds')\n", - "Card(rank='J', suit='diamonds')\n", - "Card(rank='10', suit='diamonds')\n", - "Card(rank='9', suit='diamonds')\n", - "Card(rank='8', suit='diamonds')\n", - "Card(rank='7', suit='diamonds')\n", - "Card(rank='6', suit='diamonds')\n", - "Card(rank='5', suit='diamonds')\n", - "Card(rank='4', suit='diamonds')\n", - "Card(rank='3', suit='diamonds')\n", - "Card(rank='2', suit='diamonds')\n", - "Card(rank='A', suit='spades')\n", - "Card(rank='K', suit='spades')\n", - "Card(rank='Q', suit='spades')\n", - "Card(rank='J', suit='spades')\n", - "Card(rank='10', suit='spades')\n", - "Card(rank='9', suit='spades')\n", - "Card(rank='8', suit='spades')\n", - "Card(rank='7', suit='spades')\n", - "Card(rank='6', suit='spades')\n", - "Card(rank='5', suit='spades')\n", - "Card(rank='4', suit='spades')\n", - "Card(rank='3', suit='spades')\n", - "Card(rank='2', suit='spades')\n" + "Card(rank='A', suit='♦️')\n", + "Card(rank='K', suit='♦️')\n", + "Card(rank='Q', suit='♦️')\n", + "Card(rank='J', suit='♦️')\n", + "Card(rank='10', suit='♦️')\n", + "Card(rank='9', suit='♦️')\n", + "Card(rank='8', suit='♦️')\n", + "Card(rank='7', suit='♦️')\n", + "Card(rank='6', suit='♦️')\n", + "Card(rank='5', suit='♦️')\n", + "Card(rank='4', suit='♦️')\n", + "Card(rank='3', suit='♦️')\n", + "Card(rank='2', suit='♦️')\n", + "Card(rank='A', suit='♣️')\n", + "Card(rank='K', suit='♣️')\n", + "Card(rank='Q', suit='♣️')\n", + "Card(rank='J', suit='♣️')\n", + "Card(rank='10', suit='♣️')\n", + "Card(rank='9', suit='♣️')\n", + "Card(rank='8', suit='♣️')\n", + "Card(rank='7', suit='♣️')\n", + "Card(rank='6', suit='♣️')\n", + "Card(rank='5', suit='♣️')\n", + "Card(rank='4', suit='♣️')\n", + "Card(rank='3', suit='♣️')\n", + "Card(rank='2', suit='♣️')\n", + "Card(rank='A', suit='♥️')\n", + "Card(rank='K', suit='♥️')\n", + "Card(rank='Q', suit='♥️')\n", + "Card(rank='J', suit='♥️')\n", + "Card(rank='10', suit='♥️')\n", + "Card(rank='9', suit='♥️')\n", + "Card(rank='8', suit='♥️')\n", + "Card(rank='7', suit='♥️')\n", + "Card(rank='6', suit='♥️')\n", + "Card(rank='5', suit='♥️')\n", + "Card(rank='4', suit='♥️')\n", + "Card(rank='3', suit='♥️')\n", + "Card(rank='2', suit='♥️')\n", + "Card(rank='A', suit='♠️')\n", + "Card(rank='K', suit='♠️')\n", + "Card(rank='Q', suit='♠️')\n", + "Card(rank='J', suit='♠️')\n", + "Card(rank='10', suit='♠️')\n", + "Card(rank='9', suit='♠️')\n", + "Card(rank='8', suit='♠️')\n", + "Card(rank='7', suit='♠️')\n", + "Card(rank='6', suit='♠️')\n", + "Card(rank='5', suit='♠️')\n", + "Card(rank='4', suit='♠️')\n", + "Card(rank='3', suit='♠️')\n", + "Card(rank='2', suit='♠️')\n" ] } ], @@ -340,7 +412,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -349,18 +421,18 @@ "True" ] }, - "execution_count": 11, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "Card('Q', 'hearts') in deck" + "Card('Q', '♠️') in deck" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -369,7 +441,7 @@ "False" ] }, - "execution_count": 12, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -380,70 +452,71 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Card(rank='2', suit='clubs')\n", - "Card(rank='2', suit='diamonds')\n", - "Card(rank='2', suit='hearts')\n", - "Card(rank='2', suit='spades')\n", - "Card(rank='3', suit='clubs')\n", - "Card(rank='3', suit='diamonds')\n", - "Card(rank='3', suit='hearts')\n", - "Card(rank='3', suit='spades')\n", - "Card(rank='4', suit='clubs')\n", - "Card(rank='4', suit='diamonds')\n", - "Card(rank='4', suit='hearts')\n", - "Card(rank='4', suit='spades')\n", - "Card(rank='5', suit='clubs')\n", - "Card(rank='5', suit='diamonds')\n", - "Card(rank='5', suit='hearts')\n", - "Card(rank='5', suit='spades')\n", - "Card(rank='6', suit='clubs')\n", - "Card(rank='6', suit='diamonds')\n", - "Card(rank='6', suit='hearts')\n", - "Card(rank='6', suit='spades')\n", - "Card(rank='7', suit='clubs')\n", - "Card(rank='7', suit='diamonds')\n", - "Card(rank='7', suit='hearts')\n", - "Card(rank='7', suit='spades')\n", - "Card(rank='8', suit='clubs')\n", - "Card(rank='8', suit='diamonds')\n", - "Card(rank='8', suit='hearts')\n", - "Card(rank='8', suit='spades')\n", - "Card(rank='9', suit='clubs')\n", - "Card(rank='9', suit='diamonds')\n", - "Card(rank='9', suit='hearts')\n", - "Card(rank='9', suit='spades')\n", - "Card(rank='10', suit='clubs')\n", - "Card(rank='10', suit='diamonds')\n", - "Card(rank='10', suit='hearts')\n", - "Card(rank='10', suit='spades')\n", - "Card(rank='J', suit='clubs')\n", - "Card(rank='J', suit='diamonds')\n", - "Card(rank='J', suit='hearts')\n", - "Card(rank='J', suit='spades')\n", - "Card(rank='Q', suit='clubs')\n", - "Card(rank='Q', suit='diamonds')\n", - "Card(rank='Q', suit='hearts')\n", - "Card(rank='Q', suit='spades')\n", - "Card(rank='K', suit='clubs')\n", - "Card(rank='K', suit='diamonds')\n", - "Card(rank='K', suit='hearts')\n", - "Card(rank='K', suit='spades')\n", - "Card(rank='A', suit='clubs')\n", - "Card(rank='A', suit='diamonds')\n", - "Card(rank='A', suit='hearts')\n", - "Card(rank='A', suit='spades')\n" + "Card(rank='2', suit='♦️')\n", + "Card(rank='2', suit='♣️')\n", + "Card(rank='2', suit='♥️')\n", + "Card(rank='2', suit='♠️')\n", + "Card(rank='3', suit='♦️')\n", + "Card(rank='3', suit='♣️')\n", + "Card(rank='3', suit='♥️')\n", + "Card(rank='3', suit='♠️')\n", + "Card(rank='4', suit='♦️')\n", + "Card(rank='4', suit='♣️')\n", + "Card(rank='4', suit='♥️')\n", + "Card(rank='4', suit='♠️')\n", + "Card(rank='5', suit='♦️')\n", + "Card(rank='5', suit='♣️')\n", + "Card(rank='5', suit='♥️')\n", + "Card(rank='5', suit='♠️')\n", + "Card(rank='6', suit='♦️')\n", + "Card(rank='6', suit='♣️')\n", + "Card(rank='6', suit='♥️')\n", + "Card(rank='6', suit='♠️')\n", + "Card(rank='7', suit='♦️')\n", + "Card(rank='7', suit='♣️')\n", + "Card(rank='7', suit='♥️')\n", + "Card(rank='7', suit='♠️')\n", + "Card(rank='8', suit='♦️')\n", + "Card(rank='8', suit='♣️')\n", + "Card(rank='8', suit='♥️')\n", + "Card(rank='8', suit='♠️')\n", + "Card(rank='9', suit='♦️')\n", + "Card(rank='9', suit='♣️')\n", + "Card(rank='9', suit='♥️')\n", + "Card(rank='9', suit='♠️')\n", + "Card(rank='10', suit='♦️')\n", + "Card(rank='10', suit='♣️')\n", + "Card(rank='10', suit='♥️')\n", + "Card(rank='10', suit='♠️')\n", + "Card(rank='J', suit='♦️')\n", + "Card(rank='J', suit='♣️')\n", + "Card(rank='J', suit='♥️')\n", + "Card(rank='J', suit='♠️')\n", + "Card(rank='Q', suit='♦️')\n", + "Card(rank='Q', suit='♣️')\n", + "Card(rank='Q', suit='♥️')\n", + "Card(rank='Q', suit='♠️')\n", + "Card(rank='K', suit='♦️')\n", + "Card(rank='K', suit='♣️')\n", + "Card(rank='K', suit='♥️')\n", + "Card(rank='K', suit='♠️')\n", + "Card(rank='A', suit='♦️')\n", + "Card(rank='A', suit='♣️')\n", + "Card(rank='A', suit='♥️')\n", + "Card(rank='A', suit='♠️')\n" ] } ], "source": [ - "suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)\n", + "# suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0)\n", + "suit_values = {'♠️': 3, '♥️': 2, '♣️': 1, '♦️': 0}\n", "\n", "def spades_high(card):\n", " rank_value = FrenchDeck.ranks.index(card.rank)\n", @@ -467,9 +540,23 @@ "#### Example 1-2. A simple two-dimensional vector class" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 相关讲解\n", + "\n", + "- `!r` 是 Python 格式化字符串(f-string)中的格式说明符,表示用 `repr()` 的方式显示变量的值。例如:`f\"{value!r}\"` 等价于 `f\"{repr(value)}\"`。\n", + "- `__repr__` 方法用于定义对象的“官方”字符串表示,通常用于调试和开发,要求尽量准确、清晰地反映对象内容。\n", + "- f-string 默认用 `str()` 格式化变量,只有加上 `!r` 才会用 `repr()` 格式化。\n", + "- 例如:\n", + " - `f\"{value}\"` 等价于 `str(value)`\n", + " - `f\"{value!r}\"` 等价于 `repr(value)`" + ] + }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -501,7 +588,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 45, "metadata": {}, "outputs": [ { @@ -510,7 +597,7 @@ "Vector(4, 5)" ] }, - "execution_count": 15, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -523,7 +610,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 36, "metadata": {}, "outputs": [ { @@ -532,7 +619,7 @@ "5.0" ] }, - "execution_count": 16, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -544,7 +631,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 37, "metadata": {}, "outputs": [ { @@ -553,7 +640,7 @@ "Vector(9, 12)" ] }, - "execution_count": 17, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -564,7 +651,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 38, "metadata": {}, "outputs": [ { @@ -573,7 +660,7 @@ "15.0" ] }, - "execution_count": 18, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -581,11 +668,31 @@ "source": [ "abs(v * 3)" ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bool(v)" + ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -599,7 +706,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.0" + "version": "3.12.3" } }, "nbformat": 4, diff --git a/02-array-seq/array-seq.ipynb b/02-array-seq/array-seq.ipynb index afdbf6b..3a60197 100644 --- a/02-array-seq/array-seq.ipynb +++ b/02-array-seq/array-seq.ipynb @@ -39,20 +39,22 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [ { "data": { - "text/plain": "[36, 162, 163, 165, 8364, 164]" + "text/plain": [ + "[65, 97, 36, 162, 163, 165, 8364, 164]" + ] }, - "execution_count": 1, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "symbols = '$¢£¥€¤'\n", + "symbols = 'Aa$¢£¥€¤'\n", "codes = []\n", "\n", "for symbol in symbols:\n", @@ -70,20 +72,22 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": {}, "outputs": [ { "data": { - "text/plain": "[36, 162, 163, 165, 8364, 164]" + "text/plain": [ + "[36, 162, 163, 165, 8364, 164, 65, 97]" + ] }, - "execution_count": 2, + "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "symbols = '$¢£¥€¤'\n", + "symbols = '$¢£¥€¤Aa'\n", "\n", "codes = [ord(symbol) for symbol in symbols]\n", "\n", @@ -99,14 +103,16 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": {}, "outputs": [ { "data": { - "text/plain": "'ABC'" + "text/plain": [ + "'ABC'" + ] }, - "execution_count": 3, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -119,14 +125,16 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": {}, "outputs": [ { "data": { - "text/plain": "[65, 66, 67]" + "text/plain": [ + "[65, 66, 67]" + ] }, - "execution_count": 4, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -137,13 +145,21 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [ { "data": { - "text/plain": "67" + "text/plain": [ + "67" + ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -151,13 +167,7 @@ "source": [ "codes = [last := ord(c) for c in x]\n", "last" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } + ] }, { "cell_type": "markdown", @@ -168,14 +178,16 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { - "text/plain": "[162, 163, 165, 8364, 164]" + "text/plain": [ + "[162, 163, 165, 8364, 164]" + ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -188,14 +200,16 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { - "text/plain": "[162, 163, 165, 8364, 164]" + "text/plain": [ + "[162, 163, 165, 8364, 164]" + ] }, - "execution_count": 7, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -214,14 +228,21 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { - "text/plain": "[('black', 'S'),\n ('black', 'M'),\n ('black', 'L'),\n ('white', 'S'),\n ('white', 'M'),\n ('white', 'L')]" + "text/plain": [ + "[('black', 'S'),\n", + " ('black', 'M'),\n", + " ('black', 'L'),\n", + " ('white', 'S'),\n", + " ('white', 'M'),\n", + " ('white', 'L')]" + ] }, - "execution_count": 8, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -235,7 +256,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -259,20 +280,27 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { - "text/plain": "[('black', 'S'),\n ('black', 'M'),\n ('black', 'L'),\n ('white', 'S'),\n ('white', 'M'),\n ('white', 'L')]" + "text/plain": [ + "[('black', 'S'),\n", + " ('white', 'S'),\n", + " ('black', 'M'),\n", + " ('white', 'M'),\n", + " ('black', 'L'),\n", + " ('white', 'L')]" + ] }, - "execution_count": 10, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "shirts = [(color, size) for size in sizes\n", + "tshirts = [(color, size) for size in sizes\n", " for color in colors]\n", "tshirts" ] @@ -291,7 +319,9 @@ "outputs": [ { "data": { - "text/plain": "(36, 162, 163, 165, 8364, 164)" + "text/plain": [ + "(36, 162, 163, 165, 8364, 164)" + ] }, "execution_count": 11, "metadata": {}, @@ -305,14 +335,36 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 21, "metadata": {}, "outputs": [ { "data": { - "text/plain": "array('I', [36, 162, 163, 165, 8364, 164])" + "text/plain": [ + "[36, 162, 163, 165, 8364, 164]" + ] }, - "execution_count": 12, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "list(ord(symbol) for symbol in symbols)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array('I', [36, 162, 163, 165, 8364, 164])" + ] + }, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -332,7 +384,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 27, "metadata": {}, "outputs": [ { @@ -352,38 +404,45 @@ "colors = ['black', 'white']\n", "sizes = ['S', 'M', 'L']\n", "\n", - "for tshirt in ('%s %s' % (c, s) for c in colors for s in sizes):\n", + "# for tshirt in ('%s %s' % (c, s) for c in colors for s in sizes):\n", + "# print(tshirt)\n", + "for tshirt in (f'{c} {s}' for c in colors for s in sizes):\n", " print(tshirt)" ] }, { "cell_type": "markdown", - "source": [ - "## Tuples Are Not Just Immutable Lists" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } }, - "execution_count": 73 + "source": [ + "## Tuples Are Not Just Immutable Lists" + ] }, { "cell_type": "markdown", - "source": [ - "#### Example 2-7. Tuples used as records" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [ + "#### Example 2-7. Tuples used as records" + ] }, { "cell_type": "code", "execution_count": 14, + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [ { "name": "stdout", @@ -402,17 +461,17 @@ "\n", "for passport in sorted(traveler_ids):\n", " print('%s/%s' % passport)" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 15, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 15, + }, "outputs": [ { "name": "stdout", @@ -427,33 +486,35 @@ "source": [ "for country, _ in traveler_ids:\n", " print(country)" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } + ] }, { "cell_type": "markdown", - "source": [ - "### Tuples as Immutable Lists" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [ + "### Tuples as Immutable Lists" + ] }, { "cell_type": "code", "execution_count": 16, + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [ { "data": { - "text/plain": "True" + "text/plain": [ + "True" + ] }, "execution_count": 16, "metadata": {}, @@ -464,21 +525,23 @@ "a = (10, 'alpha', [1, 2])\n", "b = (10, 'alpha', [1, 2])\n", "a == b" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 17, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 17, + }, "outputs": [ { "data": { - "text/plain": "False" + "text/plain": [ + "False" + ] }, "execution_count": 17, "metadata": {}, @@ -488,21 +551,23 @@ "source": [ "b[-1].append(99)\n", "a == b" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 18, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 18, + }, "outputs": [ { "data": { - "text/plain": "(10, 'alpha', [1, 2, 99])" + "text/plain": [ + "(10, 'alpha', [1, 2, 99])" + ] }, "execution_count": 18, "metadata": {}, @@ -511,21 +576,23 @@ ], "source": [ "b" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 19, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 19, + }, "outputs": [ { "data": { - "text/plain": "True" + "text/plain": [ + "True" + ] }, "execution_count": 19, "metadata": {}, @@ -544,21 +611,23 @@ "tf = (10, 'alpha', (1, 2)) # Contains no mutable items\n", "tm = (10, 'alpha', [1, 2]) # Contains a mutable item (list)\n", "fixed(tf)" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 20, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 20, + }, "outputs": [ { "data": { - "text/plain": "False" + "text/plain": [ + "False" + ] }, "execution_count": 20, "metadata": {}, @@ -567,33 +636,35 @@ ], "source": [ "fixed(tm)" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } + ] }, { "cell_type": "markdown", - "source": [ - "## Unpacking sequences and iterables" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [ + "## Unpacking sequences and iterables" + ] }, { "cell_type": "code", "execution_count": 21, + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [ { "data": { - "text/plain": "33.9425" + "text/plain": [ + "33.9425" + ] }, "execution_count": 21, "metadata": {}, @@ -604,21 +675,23 @@ "lax_coordinates = (33.9425, -118.408056)\n", "latitude, longitude = lax_coordinates # unpacking\n", "latitude" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 22, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 22, + }, "outputs": [ { "data": { - "text/plain": "-118.408056" + "text/plain": [ + "-118.408056" + ] }, "execution_count": 22, "metadata": {}, @@ -627,21 +700,23 @@ ], "source": [ "longitude" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 23, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 23, + }, "outputs": [ { "data": { - "text/plain": "(2, 4)" + "text/plain": [ + "(2, 4)" + ] }, "execution_count": 23, "metadata": {}, @@ -650,21 +725,23 @@ ], "source": [ "divmod(20, 8)" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 24, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 24, + }, "outputs": [ { "data": { - "text/plain": "(2, 4)" + "text/plain": [ + "(2, 4)" + ] }, "execution_count": 24, "metadata": {}, @@ -674,21 +751,23 @@ "source": [ "t = (20, 8)\n", "divmod(*t)" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 25, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 25, + }, "outputs": [ { "data": { - "text/plain": "(2, 4)" + "text/plain": [ + "(2, 4)" + ] }, "execution_count": 25, "metadata": {}, @@ -698,21 +777,23 @@ "source": [ "quotient, remainder = divmod(*t)\n", "quotient, remainder" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 26, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 26, + }, "outputs": [ { "data": { - "text/plain": "'id_rsa.pub'" + "text/plain": [ + "'id_rsa.pub'" + ] }, "execution_count": 26, "metadata": {}, @@ -724,33 +805,35 @@ "\n", "_, filename = os.path.split('/home/luciano/.ssh/id_rsa.pub')\n", "filename" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } + ] }, { "cell_type": "markdown", - "source": [ - "### Using * to grab excess items" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [ + "### Using * to grab excess items" + ] }, { "cell_type": "code", "execution_count": 27, + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [ { "data": { - "text/plain": "(0, 1, [2, 3, 4])" + "text/plain": [ + "(0, 1, [2, 3, 4])" + ] }, "execution_count": 27, "metadata": {}, @@ -760,21 +843,23 @@ "source": [ "a, b, *rest = range(5)\n", "a, b, rest" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 28, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 28, + }, "outputs": [ { "data": { - "text/plain": "(0, 1, [2])" + "text/plain": [ + "(0, 1, [2])" + ] }, "execution_count": 28, "metadata": {}, @@ -784,21 +869,23 @@ "source": [ "a, b, *rest = range(3)\n", "a, b, rest" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 29, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 29, + }, "outputs": [ { "data": { - "text/plain": "(0, 1, [])" + "text/plain": [ + "(0, 1, [])" + ] }, "execution_count": 29, "metadata": {}, @@ -808,21 +895,23 @@ "source": [ "a, b, *rest = range(2)\n", "a, b, rest" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 30, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 30, + }, "outputs": [ { "data": { - "text/plain": "(0, [1, 2], 3, 4)" + "text/plain": [ + "(0, [1, 2], 3, 4)" + ] }, "execution_count": 30, "metadata": {}, @@ -832,21 +921,23 @@ "source": [ "a, *body, c, d = range(5)\n", "a, body, c, d" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 31, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 31, + }, "outputs": [ { "data": { - "text/plain": "([0, 1], 2, 3, 4)" + "text/plain": [ + "([0, 1], 2, 3, 4)" + ] }, "execution_count": 31, "metadata": {}, @@ -856,33 +947,35 @@ "source": [ "*head, b, c, d = range(5)\n", "head, b, c, d" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } + ] }, { "cell_type": "markdown", - "source": [ - "### Unpacking with * in function calls and sequence literals" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [ + "### Unpacking with * in function calls and sequence literals" + ] }, { "cell_type": "code", "execution_count": 32, + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [ { "data": { - "text/plain": "(1, 2, 3, 4, (5, 6))" + "text/plain": [ + "(1, 2, 3, 4, (5, 6))" + ] }, "execution_count": 32, "metadata": {}, @@ -895,21 +988,23 @@ "\n", "\n", "fun(*[1, 2], 3, *range(4, 7))" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 33, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 33, + }, "outputs": [ { "data": { - "text/plain": "(0, 1, 2, 3, 4)" + "text/plain": [ + "(0, 1, 2, 3, 4)" + ] }, "execution_count": 33, "metadata": {}, @@ -918,21 +1013,23 @@ ], "source": [ "*range(4), 4" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 34, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 34, + }, "outputs": [ { "data": { - "text/plain": "[0, 1, 2, 3, 4]" + "text/plain": [ + "[0, 1, 2, 3, 4]" + ] }, "execution_count": 34, "metadata": {}, @@ -941,21 +1038,23 @@ ], "source": [ "[*range(4), 4]" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 35, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 35, + }, "outputs": [ { "data": { - "text/plain": "{0, 1, 2, 3, 4, 5, 6, 7}" + "text/plain": [ + "{0, 1, 2, 3, 4, 5, 6, 7}" + ] }, "execution_count": 35, "metadata": {}, @@ -964,45 +1063,45 @@ ], "source": [ "{*range(4), 4, *(5, 6, 7)}" - ], + ] + }, + { + "cell_type": "markdown", "metadata": { "collapsed": false, "pycharm": { - "name": "#%%\n" + "name": "#%% md\n" } - } - }, - { - "cell_type": "markdown", + }, "source": [ "### Nested unpacking\n", "#### Example 2-8. Unpacking nested tuples to access the longitude\n", "\n", "[02-array-seq/metro_lat_lon.py](02-array-seq/metro_lat_lon.py)" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%% md\n" - } - } + ] }, { "cell_type": "markdown", - "source": [ - "## Pattern Matching with Sequences\n", - "#### Example 2-9. Method from an imaginary Robot class" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [ + "## Pattern Matching with Sequences\n", + "#### Example 2-9. Method from an imaginary Robot class" + ] }, { "cell_type": "code", "execution_count": 36, + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [], "source": [ "# def handle_command(self, message):\n", @@ -1017,30 +1116,30 @@ "# self.leds[ident].set_color(ident, red, green, blue)\n", "# case _:\n", "# raise InvalidCommand(message)" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } + ] }, { "cell_type": "markdown", - "source": [ - "#### Example 2-10. Destructuring nested tuples—requires Python ≥ 3.10.\n", - "[02-array-seq/match_lat_lon.py](02-array-seq/match_lat_lon.py)" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [ + "#### Example 2-10. Destructuring nested tuples—requires Python ≥ 3.10.\n", + "[02-array-seq/match_lat_lon.py](02-array-seq/match_lat_lon.py)" + ] }, { "cell_type": "code", "execution_count": 37, + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [ { "name": "stdout", @@ -1069,57 +1168,51 @@ " case [name, _, _, (lat, lon)] if lon <= 0:\n", " print(f'{name:15} | {lat:9.4f} | {lon:9.4f}')\n", "main()" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } + ] }, { "cell_type": "markdown", - "source": [], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [] }, { "cell_type": "markdown", - "source": [ - "### Pattern Matching Sequences in an Interpreter\n", - "#### Example 2-11. Matching patterns without match/case.\n", - "[02-array-seq/lispy/py3.9/lis.py](02-array-seq/lispy/py3.9/lis.py)" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [ + "### Pattern Matching Sequences in an Interpreter\n", + "#### Example 2-11. Matching patterns without match/case.\n", + "[02-array-seq/lispy/py3.9/lis.py](02-array-seq/lispy/py3.9/lis.py)" + ] }, { "cell_type": "markdown", - "source": [ - "#### Example 2-12. Pattern matching with match/case—requires Python ≥ 3.10.\n", - "[02-array-seq/lispy/py3.10/lis.py](02-array-seq/lispy/py3.10/lis.py)" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [ + "#### Example 2-12. Pattern matching with match/case—requires Python ≥ 3.10.\n", + "[02-array-seq/lispy/py3.10/lis.py](02-array-seq/lispy/py3.10/lis.py)" + ] }, { "cell_type": "markdown", - "source": [], "metadata": { "collapsed": false - } + }, + "source": [] }, { "cell_type": "markdown", @@ -1142,7 +1235,9 @@ "outputs": [ { "data": { - "text/plain": "[10, 20]" + "text/plain": [ + "[10, 20]" + ] }, "execution_count": 38, "metadata": {}, @@ -1162,7 +1257,9 @@ "outputs": [ { "data": { - "text/plain": "[30, 40, 50, 60]" + "text/plain": [ + "[30, 40, 50, 60]" + ] }, "execution_count": 39, "metadata": {}, @@ -1180,7 +1277,9 @@ "outputs": [ { "data": { - "text/plain": "[10, 20, 30]" + "text/plain": [ + "[10, 20, 30]" + ] }, "execution_count": 40, "metadata": {}, @@ -1198,7 +1297,9 @@ "outputs": [ { "data": { - "text/plain": "[40, 50, 60]" + "text/plain": [ + "[40, 50, 60]" + ] }, "execution_count": 41, "metadata": {}, @@ -1223,7 +1324,9 @@ "outputs": [ { "data": { - "text/plain": "'bye'" + "text/plain": [ + "'bye'" + ] }, "execution_count": 42, "metadata": {}, @@ -1242,7 +1345,9 @@ "outputs": [ { "data": { - "text/plain": "'elcycib'" + "text/plain": [ + "'elcycib'" + ] }, "execution_count": 43, "metadata": {}, @@ -1260,7 +1365,9 @@ "outputs": [ { "data": { - "text/plain": "'eccb'" + "text/plain": [ + "'eccb'" + ] }, "execution_count": 44, "metadata": {}, @@ -1330,7 +1437,9 @@ "outputs": [ { "data": { - "text/plain": "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]" + "text/plain": [ + "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]" + ] }, "execution_count": 46, "metadata": {}, @@ -1349,7 +1458,9 @@ "outputs": [ { "data": { - "text/plain": "[0, 1, 20, 30, 5, 6, 7, 8, 9]" + "text/plain": [ + "[0, 1, 20, 30, 5, 6, 7, 8, 9]" + ] }, "execution_count": 47, "metadata": {}, @@ -1368,7 +1479,9 @@ "outputs": [ { "data": { - "text/plain": "[0, 1, 20, 30, 5, 8, 9]" + "text/plain": [ + "[0, 1, 20, 30, 5, 8, 9]" + ] }, "execution_count": 48, "metadata": {}, @@ -1387,7 +1500,9 @@ "outputs": [ { "data": { - "text/plain": "[0, 1, 20, 11, 5, 22, 9]" + "text/plain": [ + "[0, 1, 20, 11, 5, 22, 9]" + ] }, "execution_count": 49, "metadata": {}, @@ -1433,7 +1548,9 @@ "outputs": [ { "data": { - "text/plain": "[0, 1, 100, 22, 9]" + "text/plain": [ + "[0, 1, 100, 22, 9]" + ] }, "execution_count": 51, "metadata": {}, @@ -1459,7 +1576,9 @@ "outputs": [ { "data": { - "text/plain": "[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]" + "text/plain": [ + "[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]" + ] }, "execution_count": 52, "metadata": {}, @@ -1478,7 +1597,9 @@ "outputs": [ { "data": { - "text/plain": "'abcdabcdabcdabcdabcd'" + "text/plain": [ + "'abcdabcdabcdabcdabcd'" + ] }, "execution_count": 53, "metadata": {}, @@ -1510,7 +1631,9 @@ "outputs": [ { "data": { - "text/plain": "[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]" + "text/plain": [ + "[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]" + ] }, "execution_count": 54, "metadata": {}, @@ -1529,7 +1652,9 @@ "outputs": [ { "data": { - "text/plain": "[['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']]" + "text/plain": [ + "[['_', '_', '_'], ['_', '_', 'X'], ['_', '_', '_']]" + ] }, "execution_count": 55, "metadata": {}, @@ -1555,7 +1680,9 @@ "outputs": [ { "data": { - "text/plain": "[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]" + "text/plain": [ + "[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]" + ] }, "execution_count": 56, "metadata": {}, @@ -1574,7 +1701,9 @@ "outputs": [ { "data": { - "text/plain": "[['_', '_', 'O'], ['_', '_', 'O'], ['_', '_', 'O']]" + "text/plain": [ + "[['_', '_', 'O'], ['_', '_', 'O'], ['_', '_', 'O']]" + ] }, "execution_count": 57, "metadata": {}, @@ -1600,7 +1729,9 @@ "outputs": [ { "data": { - "text/plain": "[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]" + "text/plain": [ + "[['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]" + ] }, "execution_count": 58, "metadata": {}, @@ -1622,7 +1753,9 @@ "outputs": [ { "data": { - "text/plain": "[['_', '_', '_'], ['_', '_', '_'], ['X', '_', '_']]" + "text/plain": [ + "[['_', '_', '_'], ['_', '_', '_'], ['X', '_', '_']]" + ] }, "execution_count": 59, "metadata": {}, @@ -1658,7 +1791,9 @@ "outputs": [ { "data": { - "text/plain": "140694277263808" + "text/plain": [ + "140694277263808" + ] }, "execution_count": 61, "metadata": {}, @@ -1677,7 +1812,9 @@ "outputs": [ { "data": { - "text/plain": "[1, 2, 3, 1, 2, 3]" + "text/plain": [ + "[1, 2, 3, 1, 2, 3]" + ] }, "execution_count": 62, "metadata": {}, @@ -1696,7 +1833,9 @@ "outputs": [ { "data": { - "text/plain": "True" + "text/plain": [ + "True" + ] }, "execution_count": 63, "metadata": {}, @@ -1724,7 +1863,9 @@ "outputs": [ { "data": { - "text/plain": "140694329335488" + "text/plain": [ + "140694329335488" + ] }, "execution_count": 65, "metadata": {}, @@ -1743,7 +1884,9 @@ "outputs": [ { "data": { - "text/plain": "False" + "text/plain": [ + "False" + ] }, "execution_count": 66, "metadata": {}, @@ -1786,15 +1929,15 @@ }, { "cell_type": "markdown", - "source": [ - "#### Example 2-17. The unexpected result: item t2 is changed and an exception is raised" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [ + "#### Example 2-17. The unexpected result: item t2 is changed and an exception is raised" + ] }, { "cell_type": "code", @@ -1803,7 +1946,9 @@ "outputs": [ { "data": { - "text/plain": "(1, 2, [30, 40, 50, 60])" + "text/plain": [ + "(1, 2, [30, 40, 50, 60])" + ] }, "execution_count": 68, "metadata": {}, @@ -1863,7 +2008,9 @@ "outputs": [ { "data": { - "text/plain": "['apple', 'banana', 'grape', 'raspberry']" + "text/plain": [ + "['apple', 'banana', 'grape', 'raspberry']" + ] }, "execution_count": 70, "metadata": {}, @@ -1882,7 +2029,9 @@ "outputs": [ { "data": { - "text/plain": "['grape', 'raspberry', 'apple', 'banana']" + "text/plain": [ + "['grape', 'raspberry', 'apple', 'banana']" + ] }, "execution_count": 71, "metadata": {}, @@ -1900,7 +2049,9 @@ "outputs": [ { "data": { - "text/plain": "['raspberry', 'grape', 'banana', 'apple']" + "text/plain": [ + "['raspberry', 'grape', 'banana', 'apple']" + ] }, "execution_count": 72, "metadata": {}, @@ -1918,7 +2069,9 @@ "outputs": [ { "data": { - "text/plain": "['grape', 'apple', 'banana', 'raspberry']" + "text/plain": [ + "['grape', 'apple', 'banana', 'raspberry']" + ] }, "execution_count": 73, "metadata": {}, @@ -1936,7 +2089,9 @@ "outputs": [ { "data": { - "text/plain": "['raspberry', 'banana', 'grape', 'apple']" + "text/plain": [ + "['raspberry', 'banana', 'grape', 'apple']" + ] }, "execution_count": 74, "metadata": {}, @@ -1954,7 +2109,9 @@ "outputs": [ { "data": { - "text/plain": "['grape', 'raspberry', 'apple', 'banana']" + "text/plain": [ + "['grape', 'raspberry', 'apple', 'banana']" + ] }, "execution_count": 75, "metadata": {}, @@ -1972,7 +2129,9 @@ "outputs": [ { "data": { - "text/plain": "['apple', 'banana', 'grape', 'raspberry']" + "text/plain": [ + "['apple', 'banana', 'grape', 'raspberry']" + ] }, "execution_count": 76, "metadata": {}, @@ -2012,7 +2171,9 @@ "outputs": [ { "data": { - "text/plain": "0.8190492979077034" + "text/plain": [ + "0.8190492979077034" + ] }, "execution_count": 77, "metadata": {}, @@ -2045,7 +2206,9 @@ "outputs": [ { "data": { - "text/plain": "0.8190492979077034" + "text/plain": [ + "0.8190492979077034" + ] }, "execution_count": 79, "metadata": {}, @@ -2068,7 +2231,9 @@ "outputs": [ { "data": { - "text/plain": "True" + "text/plain": [ + "True" + ] }, "execution_count": 80, "metadata": {}, @@ -2088,23 +2253,31 @@ }, { "cell_type": "markdown", - "source": [ - "#### Example 2-20. Handling 6 bytes memory of as 1×6, 2×3, and 3×2 views" - ], "metadata": { "collapsed": false, "pycharm": { "name": "#%% md\n" } - } + }, + "source": [ + "#### Example 2-20. Handling 6 bytes memory of as 1×6, 2×3, and 3×2 views" + ] }, { "cell_type": "code", "execution_count": 81, + "metadata": { + "collapsed": false, + "pycharm": { + "name": "#%%\n" + } + }, "outputs": [ { "data": { - "text/plain": "[0, 1, 2, 3, 4, 5]" + "text/plain": [ + "[0, 1, 2, 3, 4, 5]" + ] }, "execution_count": 81, "metadata": {}, @@ -2115,21 +2288,23 @@ "octets = array('B', range(6))\n", "m1 = memoryview(octets)\n", "m1.tolist()" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 82, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 82, + }, "outputs": [ { "data": { - "text/plain": "[[0, 1, 2], [3, 4, 5]]" + "text/plain": [ + "[[0, 1, 2], [3, 4, 5]]" + ] }, "execution_count": 82, "metadata": {}, @@ -2139,21 +2314,23 @@ "source": [ "m2 = m1.cast('B', [2, 3])\n", "m2.tolist()" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 83, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 83, + }, "outputs": [ { "data": { - "text/plain": "[[0, 1], [2, 3], [4, 5]]" + "text/plain": [ + "[[0, 1], [2, 3], [4, 5]]" + ] }, "execution_count": 83, "metadata": {}, @@ -2163,21 +2340,23 @@ "source": [ "m3 = m1.cast('B', [3, 2])\n", "m3.tolist()" - ], + ] + }, + { + "cell_type": "code", + "execution_count": 84, "metadata": { "collapsed": false, "pycharm": { "name": "#%%\n" } - } - }, - { - "cell_type": "code", - "execution_count": 84, + }, "outputs": [ { "data": { - "text/plain": "array('B', [0, 1, 2, 33, 22, 5])" + "text/plain": [ + "array('B', [0, 1, 2, 33, 22, 5])" + ] }, "execution_count": 84, "metadata": {}, @@ -2188,13 +2367,7 @@ "m2[1,1] = 22\n", "m3[1,1] = 33\n", "octets" - ], - "metadata": { - "collapsed": false, - "pycharm": { - "name": "#%%\n" - } - } + ] }, { "cell_type": "markdown", @@ -2210,7 +2383,9 @@ "outputs": [ { "data": { - "text/plain": "5" + "text/plain": [ + "5" + ] }, "execution_count": 85, "metadata": {}, @@ -2230,7 +2405,9 @@ "outputs": [ { "data": { - "text/plain": "-2" + "text/plain": [ + "-2" + ] }, "execution_count": 86, "metadata": {}, @@ -2248,7 +2425,9 @@ "outputs": [ { "data": { - "text/plain": "[254, 255, 255, 255, 0, 0, 1, 0, 2, 0]" + "text/plain": [ + "[254, 255, 255, 255, 0, 0, 1, 0, 2, 0]" + ] }, "execution_count": 87, "metadata": {}, @@ -2267,7 +2446,9 @@ "outputs": [ { "data": { - "text/plain": "array('h', [-2, -1, 1024, 1, 2])" + "text/plain": [ + "array('h', [-2, -1, 1024, 1, 2])" + ] }, "execution_count": 88, "metadata": {}, @@ -2300,7 +2481,9 @@ "outputs": [ { "data": { - "text/plain": "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])" + "text/plain": [ + "array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])" + ] }, "execution_count": 89, "metadata": {}, @@ -2321,7 +2504,9 @@ "outputs": [ { "data": { - "text/plain": "numpy.ndarray" + "text/plain": [ + "numpy.ndarray" + ] }, "execution_count": 90, "metadata": {}, @@ -2339,7 +2524,9 @@ "outputs": [ { "data": { - "text/plain": "(12,)" + "text/plain": [ + "(12,)" + ] }, "execution_count": 91, "metadata": {}, @@ -2357,7 +2544,11 @@ "outputs": [ { "data": { - "text/plain": "array([[ 0, 1, 2, 3],\n [ 4, 5, 6, 7],\n [ 8, 9, 10, 11]])" + "text/plain": [ + "array([[ 0, 1, 2, 3],\n", + " [ 4, 5, 6, 7],\n", + " [ 8, 9, 10, 11]])" + ] }, "execution_count": 92, "metadata": {}, @@ -2376,7 +2567,9 @@ "outputs": [ { "data": { - "text/plain": "array([ 8, 9, 10, 11])" + "text/plain": [ + "array([ 8, 9, 10, 11])" + ] }, "execution_count": 93, "metadata": {}, @@ -2394,7 +2587,9 @@ "outputs": [ { "data": { - "text/plain": "9" + "text/plain": [ + "9" + ] }, "execution_count": 94, "metadata": {}, @@ -2412,7 +2607,9 @@ "outputs": [ { "data": { - "text/plain": "array([1, 5, 9])" + "text/plain": [ + "array([1, 5, 9])" + ] }, "execution_count": 95, "metadata": {}, @@ -2430,7 +2627,12 @@ "outputs": [ { "data": { - "text/plain": "array([[ 0, 4, 8],\n [ 1, 5, 9],\n [ 2, 6, 10],\n [ 3, 7, 11]])" + "text/plain": [ + "array([[ 0, 4, 8],\n", + " [ 1, 5, 9],\n", + " [ 2, 6, 10],\n", + " [ 3, 7, 11]])" + ] }, "execution_count": 96, "metadata": {}, @@ -2475,7 +2677,9 @@ "outputs": [ { "data": { - "text/plain": "array([0.06078257, 0.61741189, 0.84349987])" + "text/plain": [ + "array([0.06078257, 0.61741189, 0.84349987])" + ] }, "execution_count": 99, "metadata": {}, @@ -2493,7 +2697,9 @@ "outputs": [ { "data": { - "text/plain": "array([0.03039128, 0.30870594, 0.42174994])" + "text/plain": [ + "array([0.03039128, 0.30870594, 0.42174994])" + ] }, "execution_count": 100, "metadata": {}, @@ -2512,7 +2718,9 @@ "outputs": [ { "data": { - "text/plain": "True" + "text/plain": [ + "True" + ] }, "execution_count": 101, "metadata": {}, @@ -2545,7 +2753,9 @@ "outputs": [ { "data": { - "text/plain": "memmap([0.06078257, 0.61741189, 0.84349987])" + "text/plain": [ + "memmap([0.06078257, 0.61741189, 0.84349987])" + ] }, "execution_count": 103, "metadata": {}, @@ -2577,7 +2787,9 @@ "outputs": [ { "data": { - "text/plain": "deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + "text/plain": [ + "deque([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] }, "execution_count": 104, "metadata": {}, @@ -2598,7 +2810,9 @@ "outputs": [ { "data": { - "text/plain": "deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6])" + "text/plain": [ + "deque([7, 8, 9, 0, 1, 2, 3, 4, 5, 6])" + ] }, "execution_count": 105, "metadata": {}, @@ -2617,7 +2831,9 @@ "outputs": [ { "data": { - "text/plain": "deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])" + "text/plain": [ + "deque([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])" + ] }, "execution_count": 106, "metadata": {}, @@ -2636,7 +2852,9 @@ "outputs": [ { "data": { - "text/plain": "deque([-1, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + "text/plain": [ + "deque([-1, 1, 2, 3, 4, 5, 6, 7, 8, 9])" + ] }, "execution_count": 107, "metadata": {}, @@ -2655,7 +2873,9 @@ "outputs": [ { "data": { - "text/plain": "deque([3, 4, 5, 6, 7, 8, 9, 11, 22, 33])" + "text/plain": [ + "deque([3, 4, 5, 6, 7, 8, 9, 11, 22, 33])" + ] }, "execution_count": 108, "metadata": {}, @@ -2674,7 +2894,9 @@ "outputs": [ { "data": { - "text/plain": "deque([40, 30, 20, 10, 3, 4, 5, 6, 7, 8])" + "text/plain": [ + "deque([40, 30, 20, 10, 3, 4, 5, 6, 7, 8])" + ] }, "execution_count": 109, "metadata": {}, @@ -2743,7 +2965,9 @@ "outputs": [ { "data": { - "text/plain": "[0, '1', 5, 6, '9', 14, 19, '23', 28, '28']" + "text/plain": [ + "[0, '1', 5, 6, '9', 14, 19, '23', 28, '28']" + ] }, "execution_count": 112, "metadata": {}, @@ -2763,7 +2987,9 @@ "outputs": [ { "data": { - "text/plain": "[0, '1', 14, 19, '23', 28, '28', 5, 6, '9']" + "text/plain": [ + "[0, '1', 14, 19, '23', 28, '28', 5, 6, '9']" + ] }, "execution_count": 113, "metadata": {}, @@ -2784,7 +3010,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -2798,9 +3024,9 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.0" + "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 2 -} \ No newline at end of file +} diff --git a/02-array-seq/memoryviews.ipynb b/02-array-seq/memoryviews.ipynb index 860d474..a85ac95 100644 --- a/02-array-seq/memoryviews.ipynb +++ b/02-array-seq/memoryviews.ipynb @@ -14,15 +14,14 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "3.7.1 (default, Dec 14 2018, 13:28:58) \n", - "[Clang 4.0.1 (tags/RELEASE_401/final)]\n" + "3.12.3 (main, Jun 18 2025, 17:59:45) [GCC 13.3.0]\n" ] } ], @@ -33,16 +32,16 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 2, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -54,7 +53,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -63,7 +62,7 @@ "[35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]" ] }, - "execution_count": 3, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -216,7 +215,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -230,7 +229,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.1" + "version": "3.12.3" } }, "nbformat": 4,