diff --git a/ThinkPythonNotebooks.zip b/ThinkPythonNotebooks.zip index deb0379..f5c7866 100644 Binary files a/ThinkPythonNotebooks.zip and b/ThinkPythonNotebooks.zip differ diff --git a/ThinkPythonSolutions/.github/workflows/tests.yml b/ThinkPythonSolutions/.github/workflows/tests.yml new file mode 100644 index 0000000..a3f677c --- /dev/null +++ b/ThinkPythonSolutions/.github/workflows/tests.yml @@ -0,0 +1,37 @@ +name: tests + +on: + push: + branches: [v3] + pull_request: + schedule: + # Run on the first of every month + - cron: "0 0 1 * *" + workflow_dispatch: + +jobs: + tests: + name: Tests (${{ matrix.os }}, Python ${{ matrix.python-version }}) + runs-on: ${{ matrix.os }} + strategy: + matrix: + # don't test on windows + os: [ubuntu-latest, macos-latest] + python-version: ["3.10"] + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements-dev.txt + + - name: Run tests + run: | + make tests diff --git a/blank/chap00.ipynb b/blank/chap00.ipynb index a21a38a..55b62c2 100644 --- a/blank/chap00.ipynb +++ b/blank/chap00.ipynb @@ -217,6 +217,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -235,7 +251,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap01.ipynb b/blank/chap01.ipynb index 1fb365f..7b758f0 100644 --- a/blank/chap01.ipynb +++ b/blank/chap01.ipynb @@ -161,9 +161,9 @@ "source": [ "Notice that the result of the division is `42.0` rather than `42`. That's because there are two types of numbers in Python: \n", "\n", - "* **integers**, which represent whole numbers, and \n", + "* **integers**, which represent numbers with no fractional or decimal part, and \n", "\n", - "* **floating-point numbers**, which represent numbers with a decimal point.\n", + "* **floating-point numbers**, which represent integers and numbers with a decimal point.\n", "\n", "If you add, subtract, or multiply two integers, the result is an integer.\n", "But if you divide two integers, the result is a floating-point number.\n", @@ -311,7 +311,7 @@ "## Arithmetic functions\n", "\n", "In addition to the arithmetic operators, Python provides a few **functions** that work with numbers.\n", - "For example, the `round` function takes a floating-point number and rounds it off to the nearest whole number." + "For example, the `round` function takes a floating-point number and rounds it off to the nearest integer." ] }, { @@ -533,7 +533,7 @@ "source": [ "The other arithmetic operators don't work with strings.\n", "\n", - "Python provides a function called `len` that computes the length of a string.`" + "Python provides a function called `len` that computes the length of a string." ] }, { @@ -877,10 +877,10 @@ "A symbol, like `+` and `*`, that denotes an arithmetic operation like addition or multiplication.\n", "\n", "**integer:**\n", - "A type that represents whole numbers.\n", + "A type that represents numbers with no fractional or decimal part.\n", "\n", "**floating-point:**\n", - "A type that represents numbers with fractional parts.\n", + "A type that represents integers and numbers with decimal parts.\n", "\n", "**integer division:**\n", "An operator, `//`, that divides two numbers and rounds down to an integer.\n", @@ -979,7 +979,7 @@ "\n", "* I also mentioned the order of operations. For more details, ask \"What is the order of operations in Python?\"\n", "\n", - "* The `round` function, which we used to round a floating-point number to the nearest whole number, can take a second argument. Try asking \"What are the arguments of the round function?\" or \"How do I round pi off to three decimal places?\"\n", + "* The `round` function, which we used to round a floating-point number to the nearest integer, can take a second argument. Try asking \"What are the arguments of the round function?\" or \"How do I round pi off to three decimal places?\"\n", "\n", "* There's one more arithmetic operator I didn't mention; try asking \"What is the modulus operator in Python?\"" ] @@ -1162,6 +1162,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { diff --git a/blank/chap02.ipynb b/blank/chap02.ipynb index d41d5d1..345e793 100644 --- a/blank/chap02.ipynb +++ b/blank/chap02.ipynb @@ -18,7 +18,23 @@ "tags": [] }, "outputs": [], - "source": [] + "source": [ + "from os.path import basename, exists\n", + "\n", + "def download(url):\n", + " filename = basename(url)\n", + " if not exists(filename):\n", + " from urllib.request import urlretrieve\n", + "\n", + " local, _ = urlretrieve(url, filename)\n", + " print(\"Downloaded \" + str(local))\n", + " return filename\n", + "\n", + "download('https://github.com/AllenDowney/ThinkPython/raw/v3/thinkpython.py');\n", + "download('https://github.com/AllenDowney/ThinkPython/raw/v3/diagram.py');\n", + "\n", + "import thinkpython" + ] }, { "cell_type": "markdown", @@ -172,7 +188,17 @@ "tags": [] }, "outputs": [], - "source": [] + "source": [ + "import math\n", + "\n", + "from diagram import make_binding, Frame\n", + "\n", + "binding = make_binding(\"message\", 'And now for something completely different')\n", + "binding2 = make_binding(\"n\", 17)\n", + "binding3 = make_binding(\"pi\", 3.141592653589793)\n", + "\n", + "frame = Frame([binding2, binding3, binding])" + ] }, { "cell_type": "code", @@ -182,7 +208,15 @@ "tags": [] }, "outputs": [], - "source": [] + "source": [ + "from diagram import diagram, adjust\n", + "\n", + "\n", + "width, height, x, y = [3.62, 1.01, 0.6, 0.76]\n", + "ax = diagram(width, height)\n", + "bbox = frame.draw(ax, x, y, dy=-0.25)\n", + "# adjust(x, y, bbox)" + ] }, { "cell_type": "markdown", @@ -429,7 +463,7 @@ "id": "cff0414b", "metadata": {}, "source": [ - "Similarly, an import statement has an effect -- it imports a module so we can use the values and functions it contains -- but it has no visible effect." + "Similarly, an import statement has an effect -- it imports a module so we can use the variables and functions it contains -- but it has no visible effect." ] }, { @@ -875,7 +909,7 @@ "A special word used to specify the structure of a program.\n", "\n", "**import statement:**\n", - "A statement that reads a module file and creates a module object.\n", + "A statement that reads a module file so we can use the variables and functions it contains.\n", "\n", "**module:**\n", "A file that contains Python code, including function definitions and sometimes other statements.\n", @@ -918,13 +952,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 43, "id": "c9e6cab4", "metadata": { "tags": [] }, "outputs": [], - "source": [] + "source": [ + "# This cell tells Jupyter to provide detailed debugging information\n", + "# when a runtime error occurs. Run it before working on the exercises.\n", + "\n", + "%xmode Verbose" + ] }, { "cell_type": "markdown", @@ -982,7 +1021,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 44, "id": "18de7d96", "metadata": {}, "outputs": [], @@ -1003,7 +1042,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 52, "id": "de812cff", "metadata": {}, "outputs": [], @@ -1028,7 +1067,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 46, "id": "b4ada618", "metadata": {}, "outputs": [], @@ -1036,7 +1075,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 47, "id": "4424940f", "metadata": {}, "outputs": [], @@ -1044,7 +1083,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 48, "id": "50e8393a", "metadata": {}, "outputs": [], @@ -1057,6 +1096,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { diff --git a/blank/chap03.ipynb b/blank/chap03.ipynb index 7b19564..a2b6766 100644 --- a/blank/chap03.ipynb +++ b/blank/chap03.ipynb @@ -18,7 +18,23 @@ "tags": [] }, "outputs": [], - "source": [] + "source": [ + "from os.path import basename, exists\n", + "\n", + "def download(url):\n", + " filename = basename(url)\n", + " if not exists(filename):\n", + " from urllib.request import urlretrieve\n", + "\n", + " local, _ = urlretrieve(url, filename)\n", + " print(\"Downloaded \" + str(local))\n", + " return filename\n", + "\n", + "download('https://github.com/AllenDowney/ThinkPython/raw/v3/thinkpython.py');\n", + "download('https://github.com/AllenDowney/ThinkPython/raw/v3/diagram.py');\n", + "\n", + "import thinkpython" + ] }, { "cell_type": "markdown", @@ -483,7 +499,26 @@ "tags": [] }, "outputs": [], - "source": [] + "source": [ + "from diagram import make_frame, Stack\n", + "\n", + "d1 = dict(line1=line1, line2=line2)\n", + "frame1 = make_frame(d1, name='__main__', dy=-0.3, loc='left')\n", + "\n", + "d2 = dict(part1=line1, part2=line2, cat=line1+line2)\n", + "frame2 = make_frame(d2, name='cat_twice', dy=-0.3, \n", + " offsetx=0.03, loc='left')\n", + "\n", + "d3 = dict(string=line1+line2)\n", + "frame3 = make_frame(d3, name='print_twice', \n", + " offsetx=0.04, offsety=-0.3, loc='left')\n", + "\n", + "d4 = {\"?\": line1+line2}\n", + "frame4 = make_frame(d4, name='print', \n", + " offsetx=-0.22, offsety=0, loc='left')\n", + "\n", + "stack = Stack([frame1, frame2, frame3, frame4], dy=-0.8)" + ] }, { "cell_type": "code", @@ -493,7 +528,15 @@ "tags": [] }, "outputs": [], - "source": [] + "source": [ + "from diagram import diagram, adjust\n", + "\n", + "\n", + "width, height, x, y = [3.77, 2.9, 1.1, 2.65]\n", + "ax = diagram(width, height)\n", + "bbox = stack.draw(ax, x, y)\n", + "# adjust(x, y, bbox)" + ] }, { "cell_type": "markdown", @@ -543,7 +586,12 @@ "tags": [] }, "outputs": [], - "source": [] + "source": [ + "# This cell tells Jupyter to provide detailed debugging information\n", + "# when a runtime error occurs, including a traceback.\n", + "\n", + "%xmode Verbose" + ] }, { "cell_type": "code", @@ -673,7 +721,12 @@ "tags": [] }, "outputs": [], - "source": [] + "source": [ + "# This cell tells Jupyter to provide detailed debugging information\n", + "# when a runtime error occurs. Run it before working on the exercises.\n", + "\n", + "%xmode Verbose" + ] }, { "cell_type": "markdown", @@ -739,9 +792,15 @@ "cell_type": "code", "execution_count": 30, "id": "f142ce6a", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], - "source": [] + "source": [ + "print_right(\"Monty\")\n", + "print_right(\"Python's\")\n", + "print_right(\"Flying Circus\")" + ] }, { "cell_type": "markdown", @@ -766,10 +825,13 @@ "execution_count": 32, "id": "b8146a0d", "metadata": { - "scrolled": true + "scrolled": true, + "tags": [] }, "outputs": [], - "source": [] + "source": [ + "triangle('L', 5)" + ] }, { "cell_type": "markdown", @@ -794,10 +856,13 @@ "execution_count": 34, "id": "73b0c0f6", "metadata": { - "scrolled": true + "scrolled": true, + "tags": [] }, "outputs": [], - "source": [] + "source": [ + "rectangle('H', 5, 4)" + ] }, { "cell_type": "markdown", @@ -839,7 +904,9 @@ { "cell_type": "markdown", "id": "ee0076dd", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ "Use this function call to display the first verse." ] @@ -848,14 +915,20 @@ "cell_type": "code", "execution_count": 37, "id": "47a91c7d", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], - "source": [] + "source": [ + "bottle_verse(99)" + ] }, { "cell_type": "markdown", "id": "42c237c6", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ "If you want to print the whole song, you can use this `for` loop, which counts down from `99` to `1`.\n", "You don't have to completely understand this example---we'll learn more about `for` loops and the `range` function later." @@ -869,7 +942,11 @@ "tags": [] }, "outputs": [], - "source": [] + "source": [ + "for n in range(99, 0, -1):\n", + " bottle_verse(n)\n", + " print()" + ] }, { "cell_type": "code", @@ -878,6 +955,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { diff --git a/blank/chap04.ipynb b/blank/chap04.ipynb index 6b5fca9..23e5490 100644 --- a/blank/chap04.ipynb +++ b/blank/chap04.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "id": "df64b7da", "metadata": { "tags": [] @@ -22,7 +22,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "id": "320fc8bc", "metadata": { "tags": [] @@ -55,7 +55,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "id": "8f5a8a45", "metadata": {}, "outputs": [], @@ -71,7 +71,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "b3f255cd", "metadata": {}, "outputs": [], @@ -94,7 +94,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "234fde81", "metadata": {}, "outputs": [], @@ -110,7 +110,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "1e768880", "metadata": {}, "outputs": [], @@ -127,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "6d874b03", "metadata": {}, "outputs": [], @@ -144,7 +144,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "1bb57a0c", "metadata": {}, "outputs": [], @@ -171,7 +171,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "9a9e455f", "metadata": {}, "outputs": [], @@ -187,7 +187,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "cc27ad66", "metadata": {}, "outputs": [], @@ -207,7 +207,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "ad5f1128", "metadata": {}, "outputs": [], @@ -223,7 +223,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "193bbe5e", "metadata": {}, "outputs": [], @@ -243,7 +243,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "def8a5f1", "metadata": {}, "outputs": [], @@ -259,7 +259,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "b283e795", "metadata": {}, "outputs": [], @@ -273,12 +273,12 @@ "Adding a parameter to a function is called **generalization** because it makes the function more general: with the previous version, the square is always the same size; with this version it can be any size.\n", "\n", "If we add another parameter, we can make it even more general.\n", - "The following function draws regular polygons with a given of sides." + "The following function draws regular polygons with a given number of sides." ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "id": "171974ed", "metadata": {}, "outputs": [], @@ -296,7 +296,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "id": "71f7d9d2", "metadata": {}, "outputs": [], @@ -313,7 +313,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "id": "8ff2a5f4", "metadata": { "tags": [] @@ -346,7 +346,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "id": "7f2a5f28", "metadata": {}, "outputs": [], @@ -368,7 +368,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "id": "75258056", "metadata": {}, "outputs": [], @@ -404,7 +404,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "id": "381edd23", "metadata": {}, "outputs": [], @@ -422,7 +422,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "id": "2f4eecc0", "metadata": {}, "outputs": [], @@ -438,7 +438,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 23, "id": "539466f6", "metadata": {}, "outputs": [], @@ -456,7 +456,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 24, "id": "8e09f456", "metadata": {}, "outputs": [], @@ -473,7 +473,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 25, "id": "80d6eadd", "metadata": {}, "outputs": [], @@ -505,7 +505,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 26, "id": "1571ee71", "metadata": { "tags": [] @@ -515,7 +515,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 27, "id": "f4e37360", "metadata": { "tags": [] @@ -576,7 +576,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 28, "id": "baf964ba", "metadata": {}, "outputs": [], @@ -592,7 +592,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 29, "id": "e2e006d5", "metadata": {}, "outputs": [], @@ -621,7 +621,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 30, "id": "b68f3682", "metadata": {}, "outputs": [], @@ -718,7 +718,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 31, "id": "9f94061e", "metadata": { "tags": [] @@ -742,7 +742,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 32, "id": "6f9a0106", "metadata": {}, "outputs": [], @@ -761,7 +761,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 33, "id": "c54ba660", "metadata": {}, "outputs": [], @@ -779,7 +779,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 34, "id": "1311ee08", "metadata": { "tags": [] @@ -792,14 +792,14 @@ "id": "8b8faaf6", "metadata": {}, "source": [ - "## Exercise\n", + "### Exercise\n", "\n", "Write a function called `rhombus` that draws a rhombus with a given side length and a given interior angle. For example, here's a rhombus with side length `50` and an interior angle of `60` degrees." ] }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 35, "id": "3db6f106", "metadata": {}, "outputs": [], @@ -817,7 +817,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 36, "id": "1d845de9", "metadata": { "tags": [] @@ -837,7 +837,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 37, "id": "895005cb", "metadata": {}, "outputs": [], @@ -845,7 +845,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 38, "id": "7e7d34b0", "metadata": {}, "outputs": [], @@ -853,7 +853,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 39, "id": "481396f9", "metadata": {}, "outputs": [], @@ -871,7 +871,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 40, "id": "c8dfebc9", "metadata": { "tags": [] @@ -881,19 +881,21 @@ }, { "cell_type": "markdown", - "id": "feae252c", + "id": "991ab59d", "metadata": {}, "source": [ "### Exercise\n", "\n", "Write an appropriately general set of functions that can draw shapes like this.\n", "\n", + "![](https://github.com/AllenDowney/ThinkPython/raw/v3/jupyturtle_pie.png)\n", + "\n", "Hint: Write a function called `triangle` that draws one triangular segment, and then a function called `draw_pie` that uses `triangle`." ] }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 41, "id": "8be6442e", "metadata": {}, "outputs": [], @@ -901,7 +903,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 42, "id": "be1b7ed8", "metadata": {}, "outputs": [], @@ -919,7 +921,17 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": null, + "id": "c519ca39", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 51, "id": "89ce198a", "metadata": { "tags": [] @@ -929,19 +941,21 @@ }, { "cell_type": "markdown", - "id": "7c665dd1", + "id": "9c78b76f", "metadata": {}, "source": [ "### Exercise\n", "\n", "Write an appropriately general set of functions that can draw flowers like this.\n", "\n", + "![](https://github.com/AllenDowney/ThinkPython/raw/v3/jupyturtle_flower.png)\n", + "\n", "Hint: Use `arc` to write a function called `petal` that draws one flower petal." ] }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 44, "id": "0f0e7498", "metadata": {}, "outputs": [], @@ -949,7 +963,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 45, "id": "6c0d0bff", "metadata": {}, "outputs": [], @@ -972,7 +986,17 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": null, + "id": "04193da5", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 53, "id": "4cfea3b0", "metadata": { "tags": [] @@ -1029,7 +1053,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 47, "id": "46d3151c", "metadata": {}, "outputs": [], @@ -1037,19 +1061,27 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 48, "id": "186c7fbc", "metadata": {}, "outputs": [], "source": [] }, { - "cell_type": "code", - "execution_count": null, - "id": "979f5ad4", - "metadata": {}, - "outputs": [], - "source": [] + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { diff --git a/blank/chap05.ipynb b/blank/chap05.ipynb index 4653cec..9f9ad19 100644 --- a/blank/chap05.ipynb +++ b/blank/chap05.ipynb @@ -144,7 +144,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 1, "id": "db33a44d", "metadata": {}, "outputs": [], @@ -1506,6 +1506,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { diff --git a/blank/chap06.ipynb b/blank/chap06.ipynb index e4f4834..7fadc4e 100644 --- a/blank/chap06.ipynb +++ b/blank/chap06.ipynb @@ -31,7 +31,7 @@ "When you call one of these functions, it returns a value you can assign to a variable or use as part of an expression.\n", "\n", "The functions we have written so far are different.\n", - "Some use the `print` function to display values, and some use `Turtle` functions to draw figures.\n", + "Some use the `print` function to display values, and some use turtle functions to draw figures.\n", "But they don't return values we assign to variables or use in expressions.\n", "\n", "In this chapter, we'll see how to write functions that return values." @@ -797,7 +797,7 @@ "n! &= n~(n-1)!\n", "\\end{aligned}$$ \n", "\n", - "This definition says that the factorial of 0 is 1, and the factorial of any other value, $n$, is $n$ multiplied by the factorial of $n-1$.\n", + "This definition says that the factorial of $0$ is $1$, and the factorial of any other value, $n$, is $n$ multiplied by the factorial of $n-1$.\n", "\n", "If you can write a recursive definition of something, you can write a Python program to evaluate it. \n", "Following an incremental development process, we'll start with a function that take `n` as a parameter and always returns `0`." @@ -816,7 +816,7 @@ "id": "ee1f63b8", "metadata": {}, "source": [ - "Now let's add the first part of the definition -- if the argument happens to be 0, all we have to do is return 1:" + "Now let's add the first part of the definition -- if the argument happens to be `0`, all we have to do is return `1`:" ] }, { @@ -833,7 +833,7 @@ "metadata": {}, "source": [ "Now let's fill in the second part -- if `n` is not `0`, we have to make a recursive\n", - "call to find the factorial of $n-1$ and then multiply the result by $n$:" + "call to find the factorial of `n-1` and then multiply the result by `n`:" ] }, { @@ -963,7 +963,7 @@ "metadata": {}, "source": [ "If you try to follow the flow of execution here, even for small values of $n$, your head explodes.\n", - "But according to the leap of faith, if you assume that the two recursive calls work correctly, you can be confident that the last return statement is correct.\n", + "But according to the leap of faith, if you assume that the two recursive calls work correctly, you can be confident that the last `return` statement is correct.\n", "\n", "As an aside, this way of computing Fibonacci numbers is very inefficient.\n", "In [Chapter 10](section_memos) I'll explain why and suggest a way to improve it." @@ -1127,7 +1127,7 @@ "metadata": {}, "source": [ "`space` is a string of space characters that controls the indentation of\n", - "the output. Here is the result of `factorial(4)` :" + "the output. Here is the result of `factorial(3)` :" ] }, { @@ -1654,6 +1654,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1673,7 +1689,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap07.ipynb b/blank/chap07.ipynb index 98a51b9..22ea459 100644 --- a/blank/chap07.ipynb +++ b/blank/chap07.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "f0c8eb18", "metadata": { "tags": [] @@ -50,7 +50,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "id": "6b8569b8-1576-45d2-99f6-c7a2c7e100c4", "metadata": {}, "outputs": [], @@ -68,7 +68,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "6cb5b573-601c-42f5-a940-f1a4d244f990", "metadata": {}, "outputs": [], @@ -87,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "id": "7040a890-6619-4ad2-b0bf-b094a5a0e43d", "metadata": {}, "outputs": [], @@ -103,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "id": "40fd553c-693c-4ffc-8e49-1d7de3c4d4a7", "metadata": {}, "outputs": [], @@ -119,7 +119,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "id": "8a34174b-5a77-482a-8480-14cfdff16339", "metadata": {}, "outputs": [], @@ -135,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "id": "0909121d-5218-49ca-b03e-258206f00e40", "metadata": {}, "outputs": [], @@ -151,7 +151,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "id": "3c4d8138-ddf6-46fe-a940-a7042617ceb1", "metadata": {}, "outputs": [], @@ -159,7 +159,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "id": "5c463051-b737-49ab-a1d7-4be66fd8331f", "metadata": {}, "outputs": [], @@ -188,7 +188,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "id": "a7b7ac52-64a6-4dd9-98f5-b772a5e0f161", "metadata": { "tags": [] @@ -207,7 +207,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, "id": "1ad13ce7-99be-4412-8e0b-978fe6de25f2", "metadata": {}, "outputs": [], @@ -223,7 +223,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "id": "dc2054e6-d8e8-4a06-a1ea-5cfcf4ccf1e0", "metadata": {}, "outputs": [], @@ -246,7 +246,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "id": "eaea1520-0fb3-4ef3-be6e-9e1cdcccf39f", "metadata": {}, "outputs": [], @@ -262,7 +262,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 14, "id": "f602bfb6-7a93-4fb8-ade6-6784155a6f1a", "metadata": {}, "outputs": [], @@ -281,7 +281,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 15, "id": "cf3b8b7e-5fc7-4bb1-b628-09277bdc5a0d", "metadata": { "tags": [] @@ -314,7 +314,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 16, "id": "6bf8a104", "metadata": {}, "outputs": [], @@ -330,7 +330,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 17, "id": "0fe7ae60", "metadata": {}, "outputs": [], @@ -346,7 +346,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 18, "id": "8a09bc24", "metadata": { "tags": [] @@ -356,7 +356,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 19, "id": "36a45674-7f41-4850-98f1-2548574ce958", "metadata": { "tags": [] @@ -378,7 +378,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 20, "id": "ba2ab90b", "metadata": { "tags": [] @@ -388,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 21, "id": "88496dc4", "metadata": {}, "outputs": [], @@ -406,9 +406,11 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 22, "id": "4a0c46b9", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [] }, @@ -423,7 +425,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 23, "id": "2220d826", "metadata": {}, "outputs": [], @@ -434,7 +436,25 @@ "id": "374fb3d5", "metadata": {}, "source": [ - "Increasing the value of a variable is called an **increment**; decreasing the value is called a **decrement**." + "Increasing the value of a variable is called an **increment**; decreasing the value is called a **decrement**.\n", + "Because these operations are so common, Python provides **augmented assignment operators** that update a variable more concisely.\n", + "For example, the `+=` operator increments a variable by the given amount." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "d8e1ac5a", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "3f4eedf1", + "metadata": {}, + "source": [ + "There are augmented assignment operators for the other arithmetic operators, including `-=` and `*=`." ] }, { @@ -449,7 +469,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 25, "id": "0afd8f88", "metadata": {}, "outputs": [], @@ -467,7 +487,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 26, "id": "8686b2eb-c610-4d29-a942-2ef8f53e5e36", "metadata": {}, "outputs": [], @@ -485,7 +505,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 27, "id": "89a05280", "metadata": {}, "outputs": [], @@ -501,7 +521,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 28, "id": "9d29b5e9", "metadata": {}, "outputs": [], @@ -517,7 +537,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 29, "id": "304dfd86", "metadata": {}, "outputs": [], @@ -544,7 +564,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 30, "id": "fe6431b7", "metadata": {}, "outputs": [], @@ -560,7 +580,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 31, "id": "85d3fba6", "metadata": {}, "outputs": [], @@ -576,7 +596,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 32, "id": "2d653847", "metadata": {}, "outputs": [], @@ -593,7 +613,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 33, "id": "a92a81bc", "metadata": {}, "outputs": [], @@ -609,7 +629,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 34, "id": "d15f83a4", "metadata": {}, "outputs": [], @@ -625,7 +645,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 35, "id": "e7958af4", "metadata": {}, "outputs": [], @@ -633,7 +653,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 36, "id": "020a57a7", "metadata": {}, "outputs": [], @@ -641,7 +661,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 37, "id": "0b979b20", "metadata": {}, "outputs": [], @@ -660,7 +680,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 38, "id": "bd29ff63", "metadata": {}, "outputs": [], @@ -676,7 +696,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 39, "id": "9369fb05", "metadata": {}, "outputs": [], @@ -692,7 +712,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 40, "id": "eb32713a", "metadata": {}, "outputs": [], @@ -703,12 +723,12 @@ "id": "b2acc611", "metadata": {}, "source": [ - "`uses_only` converts `word` and `letters` to lowercase, so it works with any combination of cases. " + "`uses_any` converts `word` and `letters` to lowercase, so it works with any combination of cases. " ] }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 41, "id": "7e65a9fb", "metadata": {}, "outputs": [], @@ -742,7 +762,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 42, "id": "3982e7d3", "metadata": {}, "outputs": [], @@ -766,7 +786,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 43, "id": "40ef00d3", "metadata": {}, "outputs": [], @@ -783,7 +803,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 44, "id": "f37cfd36", "metadata": {}, "outputs": [], @@ -804,7 +824,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 45, "id": "58c916cc", "metadata": {}, "outputs": [], @@ -820,7 +840,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 46, "id": "7a325745", "metadata": {}, "outputs": [], @@ -887,7 +907,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 47, "id": "bc58db59", "metadata": { "tags": [] @@ -1115,7 +1135,7 @@ "\n", "* Each puzzle includes at least one \"pangram\" which uses every letter. These are worth 7 extra points!\n", "\n", - "Write a function called `score_word` that takes a word and a string of available lessons and returns its score.\n", + "Write a function called `score_word` that takes a word and a string of available letters and returns its score.\n", "You can assume that the word is acceptable.\n", "\n", "Again, here's an outline of the function with doctests." @@ -1274,18 +1294,34 @@ { "cell_type": "code", "execution_count": 71, - "id": "6980de57", + "id": "a3ea747d", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", - "execution_count": null, - "id": "102df097", + "execution_count": 72, + "id": "6980de57", "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1305,7 +1341,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap08.ipynb b/blank/chap08.ipynb index 5532116..00a2a91 100644 --- a/blank/chap08.ipynb +++ b/blank/chap08.ipynb @@ -877,7 +877,7 @@ "id": "a8eab0f6", "metadata": {}, "source": [ - "It also provides a function called `group` that returns the part of the text that matched the pattern." + "It also provides a method called `group` that returns the part of the text that matched the pattern." ] }, { @@ -893,7 +893,7 @@ "id": "b6962a7d", "metadata": {}, "source": [ - "And it provides a function called `span` that returns the index in the text where the pattern starts and ends." + "And it provides a method called `span` that returns the index in the text where the pattern starts and ends." ] }, { @@ -1303,10 +1303,7 @@ "Replacement of a string, or part of a string, with another string.\n", "\n", "**shell command:**\n", - "A statement in a shell language, which is a language used to interact with an operating system.\n", - "\n", - "**raw string:**\n", - "A Python string that is preceded by the letter `r`, which indicates that backslashes that appear in the string should not be considered part of a special sequence." + "A statement in a shell language, which is a language used to interact with an operating system." ] }, { @@ -1358,7 +1355,7 @@ "\n", "And if you want to see something more complicated, try asking for a regular expression that matches any legal URL.\n", "\n", - "A regular expression often has the letter `r` before the quotation mark, which indicates that it is a **raw string**.\n", + "A regular expression often has the letter `r` before the quotation mark, which indicates that it is a \"raw string\".\n", "For more information, ask a virtual assistant, \"What is a raw string in Python?\"" ] }, @@ -1445,12 +1442,12 @@ "Each attempt has to be recognized as a word, not including proper nouns.\n", "After each attempt, you get information about which of the letters you guessed appear in the target word, and which ones are in the correct position.\n", "\n", - "For example, suppose the target word is `MOWER` and you guess `TRIED`. You would learn that `E` is in the word and in the correct position, `R` is in the word but not in the correct position, and `T`, `I`, and `D` are not in the word.\n", + "For example, suppose the target word is `MOWER` and you guess `TRIED`.\n", + "You would learn that `E` is in the word and in the correct position, `R` is in the word but not in the correct position, and `T`, `I`, and `D` are not in the word.\n", "\n", "As a different example, suppose you have guessed the words `SPADE` and `CLERK`, and you've learned that `E` is in the word, but not in either of those positions, and none of the other letters appear in the word.\n", - "\n", "Of the words in the word list, how many could be the target word?\n", - "Write a function called `check_word` that takes a five-letter word and checks whether it could be the target word." + "Write a function called `check_word` that takes a five-letter word and checks whether it could be the target word, given these guesses." ] }, { @@ -1537,8 +1534,9 @@ "\n", "In particular, he says it is \"shameless in its repetition of the same adjective,\" and mentions in particular the number of times \"its characters either shudder or turn pale.\"\n", "\n", - "To see whether his objection is valid, let's count the number number of times the word `pale` appears in any form, including `pale`, `pales`, `paled`, and `paleness`, as well as the related word `pallor`. \n", - "Use a single regular expression that matches all of these words and no others." + "To see whether his objection is valid, let's count the number number of lines that contain the word `pale` in any form, including `pale`, `pales`, `paled`, and `paleness`, as well as the related word `pallor`. \n", + "Use a single regular expression that matches any of these words.\n", + "As an additional challenge, make sure that it doesn't match any other words, like `impale` -- you might want to ask a virtual assistant for help." ] }, { @@ -1583,7 +1581,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 83, "id": "08294921", "metadata": {}, "outputs": [], @@ -1591,29 +1589,45 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 84, "id": "3eb8f83f", "metadata": {}, "outputs": [], "source": [] }, + { + "cell_type": "code", + "execution_count": 85, + "id": "b6bffe8a", + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", - "id": "71d2148f", + "id": "7db56337", "metadata": { "tags": [] }, "source": [ - "By my count, these words appear `223` times in a book that contains about `461,000` words. Mr. Eco might have a point." + "By this count, these words appear on `223` lines of the book, so Mr. Eco might have a point." ] }, { - "cell_type": "code", - "execution_count": null, - "id": "32d539d9", - "metadata": {}, - "outputs": [], - "source": [] + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { diff --git a/blank/chap09.ipynb b/blank/chap09.ipynb index 58d005b..c4cae84 100644 --- a/blank/chap09.ipynb +++ b/blank/chap09.ipynb @@ -1047,7 +1047,7 @@ "id": "e5288e08", "metadata": {}, "source": [ - "In this example, the parameter `lst` and the variable `letters` are aliases for the same object, so the stack diagram looks like this:" + "In this example, the parameter `lst` and the variable `letters` are aliases for the same object, so the state diagram looks like this:" ] }, { @@ -1319,7 +1319,7 @@ "### Ask a virtual assistant\n", "\n", "In this chapter, I used the words \"contrafibularities\" and \"anaspeptic\", but they are not actually English words.\n", - "They were used in the British television show *Black Adder*, Season 2, Episode 2, \"Ink and Incapability\".\n", + "They were used in the British television show *Black Adder*, Season 3, Episode 2, \"Ink and Incapability\".\n", "\n", "However, when I asked ChatGPT 3.5 (August 3, 2023 version) where those words came from, it initially claimed they are from Monty Python, and later claimed they are from the Tom Stoppard play *Rosencrantz and Guildenstern Are Dead*.\n", "\n", @@ -1633,6 +1633,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { diff --git a/blank/chap10.ipynb b/blank/chap10.ipynb index 3cc321f..56d77c9 100644 --- a/blank/chap10.ipynb +++ b/blank/chap10.ipynb @@ -893,7 +893,7 @@ "source": [ "Furthermore, the run time increases quickly.\n", "To understand why, consider the following figure, which shows the **call graph** for\n", - "`fibonacci` with `n=3`:" + "`fibonacci` with `n=4`:" ] }, { @@ -1008,7 +1008,7 @@ "\n", "As you work with bigger datasets it can become unwieldy to debug by printing and checking the output by hand. Here are some suggestions for debugging large datasets:\n", "\n", - "1) Scale down the input: If possible, reduce the size of the dataset. For example if the\n", + "1. Scale down the input: If possible, reduce the size of the dataset. For example if the\n", " program reads a text file, start with just the first 10 lines, or\n", " with the smallest example you can find. You can either edit the\n", " files themselves, or (better) modify the program so it reads only\n", @@ -1492,6 +1492,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1511,7 +1527,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap11.ipynb b/blank/chap11.ipynb index 916cd43..d80bc23 100644 --- a/blank/chap11.ipynb +++ b/blank/chap11.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "id": "295ac6d7", "metadata": { "tags": [] @@ -54,7 +54,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "id": "fb0bdca2", "metadata": {}, "outputs": [], @@ -70,7 +70,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "id": "5a6da881", "metadata": {}, "outputs": [], @@ -86,7 +86,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "e2596ca7", "metadata": {}, "outputs": [], @@ -102,7 +102,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "a0d350a6", "metadata": {}, "outputs": [], @@ -119,7 +119,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "c9100ee4", "metadata": {}, "outputs": [], @@ -136,7 +136,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "44bd3d83", "metadata": {}, "outputs": [], @@ -155,7 +155,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "92e55b2c", "metadata": {}, "outputs": [], @@ -171,7 +171,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "38ee5c2a", "metadata": {}, "outputs": [], @@ -187,7 +187,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "2e0e311a", "metadata": {}, "outputs": [], @@ -203,7 +203,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "8bb7d715", "metadata": {}, "outputs": [], @@ -219,7 +219,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "e653e00f", "metadata": {}, "outputs": [], @@ -235,7 +235,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "8969188d", "metadata": {}, "outputs": [], @@ -251,7 +251,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "65d7ebaa", "metadata": {}, "outputs": [], @@ -277,7 +277,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "id": "b4970fe0", "metadata": { "tags": [] @@ -295,7 +295,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "id": "772738cc", "metadata": { "tags": [] @@ -316,7 +316,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "id": "37e67042", "metadata": {}, "outputs": [], @@ -332,7 +332,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "id": "d809a490", "metadata": {}, "outputs": [], @@ -348,7 +348,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "id": "dfc42a8b", "metadata": {}, "outputs": [], @@ -364,7 +364,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "id": "2debf30c", "metadata": {}, "outputs": [], @@ -382,7 +382,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "id": "1e94ea37", "metadata": {}, "outputs": [], @@ -399,7 +399,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 23, "id": "99c96c7f", "metadata": {}, "outputs": [], @@ -416,7 +416,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 24, "id": "b67881ed", "metadata": {}, "outputs": [], @@ -432,7 +432,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 25, "id": "b4515e2b", "metadata": {}, "outputs": [], @@ -449,7 +449,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 26, "id": "8e5b4a14", "metadata": { "tags": [] @@ -468,7 +468,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 27, "id": "2389d6de", "metadata": {}, "outputs": [], @@ -484,7 +484,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 28, "id": "5512edec", "metadata": {}, "outputs": [], @@ -503,7 +503,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 29, "id": "651ab417", "metadata": {}, "outputs": [], @@ -521,7 +521,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 30, "id": "2c0b7d47", "metadata": {}, "outputs": [], @@ -554,7 +554,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 31, "id": "fff80eaa", "metadata": {}, "outputs": [], @@ -570,7 +570,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 32, "id": "4a0eb2a9", "metadata": {}, "outputs": [], @@ -578,7 +578,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 33, "id": "d74ba1b6", "metadata": {}, "outputs": [], @@ -594,7 +594,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 34, "id": "dad3b3bb", "metadata": {}, "outputs": [], @@ -611,7 +611,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 35, "id": "fbd90b0e", "metadata": {}, "outputs": [], @@ -627,7 +627,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 36, "id": "5a101efb", "metadata": {}, "outputs": [], @@ -649,7 +649,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 37, "id": "0a33e2d0", "metadata": {}, "outputs": [], @@ -666,7 +666,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 38, "id": "336a08ca", "metadata": {}, "outputs": [], @@ -683,7 +683,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 39, "id": "991810bc", "metadata": { "tags": [] @@ -702,7 +702,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 40, "id": "f25ebee1", "metadata": {}, "outputs": [], @@ -719,7 +719,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 41, "id": "7ad64412", "metadata": {}, "outputs": [], @@ -739,7 +739,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 42, "id": "b2863701", "metadata": {}, "outputs": [], @@ -747,7 +747,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 43, "id": "cc1afa29", "metadata": {}, "outputs": [], @@ -774,7 +774,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 44, "id": "ad3e6f81", "metadata": {}, "outputs": [], @@ -791,7 +791,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 45, "id": "9ce313ce", "metadata": {}, "outputs": [], @@ -807,7 +807,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 46, "id": "321d9c30", "metadata": {}, "outputs": [], @@ -824,7 +824,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 47, "id": "7eb73d5d", "metadata": {}, "outputs": [], @@ -842,7 +842,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 48, "id": "9529baa8", "metadata": {}, "outputs": [], @@ -858,7 +858,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 49, "id": "dbde77b8", "metadata": {}, "outputs": [], @@ -875,7 +875,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 50, "id": "dbb7d0b3", "metadata": {}, "outputs": [], @@ -891,7 +891,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 51, "id": "49e3fd8e", "metadata": {}, "outputs": [], @@ -909,7 +909,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 52, "id": "9e4f3e51", "metadata": {}, "outputs": [], @@ -925,7 +925,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 53, "id": "c1dcb46d", "metadata": {}, "outputs": [], @@ -945,7 +945,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 54, "id": "aed20c28", "metadata": {}, "outputs": [], @@ -961,7 +961,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 55, "id": "4d9e73b3", "metadata": {}, "outputs": [], @@ -979,7 +979,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 56, "id": "2077dfa9", "metadata": {}, "outputs": [], @@ -995,7 +995,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 57, "id": "b3d40516", "metadata": {}, "outputs": [], @@ -1014,7 +1014,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 58, "id": "8288c28f", "metadata": {}, "outputs": [], @@ -1030,7 +1030,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 59, "id": "bbbade35", "metadata": {}, "outputs": [], @@ -1049,7 +1049,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 60, "id": "a4c31795", "metadata": {}, "outputs": [], @@ -1065,7 +1065,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 61, "id": "f3d3619a", "metadata": {}, "outputs": [], @@ -1083,7 +1083,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 62, "id": "f078c8a6", "metadata": {}, "outputs": [], @@ -1100,7 +1100,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 63, "id": "54030d8f", "metadata": {}, "outputs": [], @@ -1132,7 +1132,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 64, "id": "ef158f81", "metadata": {}, "outputs": [], @@ -1150,7 +1150,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 65, "id": "d3607b8d", "metadata": {}, "outputs": [], @@ -1170,7 +1170,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 66, "id": "692d9cf8", "metadata": {}, "outputs": [], @@ -1199,7 +1199,7 @@ "Lists, dictionaries and tuples are **data structures**.\n", "In this chapter we are starting to see compound data structures, like lists of tuples, or dictionaries that contain tuples as keys and lists as values.\n", "Compound data structures are useful, but they are prone to errors caused when a data structure has the wrong type, size, or structure.\n", - "For example, if a function expects a list if integers and you give it a plain old integer\n", + "For example, if a function expects a list of integers and you give it a plain old integer\n", "(not in a list), it probably won't work.\n", "\n", "To help debug these kinds of errors, I wrote a module called `structshape` that provides a function, also called `structshape`, that takes any kind of data structure as an argument and returns a string that summarizes its structure.\n", @@ -1209,7 +1209,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 67, "id": "e9f03e91", "metadata": { "tags": [] @@ -1227,7 +1227,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 68, "id": "90ab624a", "metadata": {}, "outputs": [], @@ -1243,7 +1243,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 69, "id": "6794330f", "metadata": {}, "outputs": [], @@ -1259,7 +1259,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 70, "id": "54cd185b", "metadata": {}, "outputs": [], @@ -1276,7 +1276,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 71, "id": "04028afd", "metadata": {}, "outputs": [], @@ -1292,7 +1292,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 72, "id": "b5d45c88", "metadata": {}, "outputs": [], @@ -1308,7 +1308,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 73, "id": "15131907", "metadata": {}, "outputs": [], @@ -1359,7 +1359,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 74, "id": "c65d68d2", "metadata": { "tags": [] @@ -1400,7 +1400,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 75, "id": "4416fe4a", "metadata": {}, "outputs": [], @@ -1416,7 +1416,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 76, "id": "e6eda0e4", "metadata": { "tags": [] @@ -1434,7 +1434,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 77, "id": "4fae1acc", "metadata": { "tags": [] @@ -1464,7 +1464,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 78, "id": "855c7ed2", "metadata": {}, "outputs": [], @@ -1480,7 +1480,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 79, "id": "3c921f68", "metadata": {}, "outputs": [], @@ -1497,7 +1497,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 80, "id": "b029b0da", "metadata": {}, "outputs": [], @@ -1534,7 +1534,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 81, "id": "1cc07036", "metadata": { "tags": [] @@ -1544,7 +1544,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 82, "id": "96560a0e", "metadata": {}, "outputs": [], @@ -1552,7 +1552,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 83, "id": "c026c6d1", "metadata": { "tags": [] @@ -1562,7 +1562,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 84, "id": "5814999d", "metadata": { "tags": [] @@ -1582,7 +1582,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 85, "id": "9464d140", "metadata": { "tags": [] @@ -1614,7 +1614,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 86, "id": "4309d0b5", "metadata": { "tags": [] @@ -1624,7 +1624,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 87, "id": "52228828", "metadata": {}, "outputs": [], @@ -1642,7 +1642,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 88, "id": "3bf2aa0d", "metadata": { "tags": [] @@ -1662,7 +1662,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 89, "id": "e4fbf5d9", "metadata": { "tags": [] @@ -1672,7 +1672,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 90, "id": "817ec689", "metadata": { "tags": [] @@ -1724,7 +1724,7 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 91, "id": "941719c1", "metadata": { "tags": [] @@ -1734,7 +1734,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 92, "id": "d2ec641b", "metadata": { "tags": [] @@ -1754,7 +1754,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 93, "id": "7ae29f73", "metadata": { "tags": [] @@ -1764,7 +1764,7 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 94, "id": "013819a5", "metadata": {}, "outputs": [], @@ -1783,7 +1783,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 95, "id": "fbf9ede3", "metadata": { "tags": [] @@ -1803,7 +1803,7 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 96, "id": "55435050", "metadata": { "tags": [] @@ -1823,7 +1823,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 97, "id": "6a9320c2", "metadata": { "tags": [] @@ -1855,7 +1855,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 98, "id": "3d5a75f8", "metadata": { "tags": [] @@ -1865,7 +1865,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 99, "id": "a9816dde", "metadata": {}, "outputs": [], @@ -1873,7 +1873,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 100, "id": "753a23c1", "metadata": { "tags": [] @@ -1899,7 +1899,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 101, "id": "57649075", "metadata": {}, "outputs": [], @@ -1959,7 +1959,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 102, "id": "c19bf833", "metadata": {}, "outputs": [], @@ -1967,7 +1967,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 103, "id": "2d9764d6", "metadata": {}, "outputs": [], @@ -1975,7 +1975,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 104, "id": "5e4f5d8e", "metadata": {}, "outputs": [], @@ -1983,7 +1983,7 @@ }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 105, "id": "27d311dd", "metadata": {}, "outputs": [], @@ -1991,19 +1991,27 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 106, "id": "68c27c7e", "metadata": {}, "outputs": [], "source": [] }, { - "cell_type": "code", - "execution_count": null, - "id": "a34c2014", - "metadata": {}, - "outputs": [], - "source": [] + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -2023,7 +2031,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap12.ipynb b/blank/chap12.ipynb index 345db38..220b664 100644 --- a/blank/chap12.ipynb +++ b/blank/chap12.ipynb @@ -27,7 +27,7 @@ "source": [ "# Text Analysis and Generation\n", "\n", - "At this point we have covered Python's core data structures -- lists, dictionaries, and tuples -- and and some algorithms that use them.\n", + "At this point we have covered Python's core data structures -- lists, dictionaries, and tuples -- and some algorithms that use them.\n", "In this chapter, we'll use them to explore text analysis and Markov generation:\n", "\n", "* Text analysis is a way to describe the statistical relationships between the words in a document, like the probability that one word is followed by another, and\n", @@ -1735,7 +1735,7 @@ "id": "83ed6c7e", "metadata": {}, "source": [ - "Now write a loop that generates `50` more words following these steps:\n", + "Now write a loop that generates 50 more words following these steps:\n", "\n", "1. In `successor_map`, look up the list of words that can follow `bigram`.\n", "\n", @@ -1771,6 +1771,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1790,7 +1806,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap13.ipynb b/blank/chap13.ipynb index b7c5279..69616a9 100644 --- a/blank/chap13.ipynb +++ b/blank/chap13.ipynb @@ -283,7 +283,7 @@ "id": "f652aaac", "metadata": {}, "source": [ - "To write this data to a file, you can use the `write` method, which we saw in [Chapter 8](section_writing_files).\n", + "To write this data to a file, you can use the `write` method, which we saw in Chapter 8.\n", "The argument of `write` has to be a string, so if we want to put other values in a file, we have to convert them to strings.\n", "The easiest way to do that is with the built-in function `str`.\n", "\n", @@ -664,7 +664,7 @@ "id": "e9b252a7", "metadata": {}, "source": [ - "If you make another assignment to an existing key, `dbm` replaces the old value." + "If you make another assignment to an existing key, `shelve` replaces the old value." ] }, { @@ -680,7 +680,7 @@ "id": "003eacbc", "metadata": {}, "source": [ - "Some dictionary methods, like `keys`, `values` and `items`, also work with database objects." + "Some dictionary methods, like `keys`, `values` and `items`, also work with shelf objects." ] }, { @@ -1055,7 +1055,7 @@ "id": "a8e480f0", "metadata": {}, "source": [ - "The `HASH` object provides an `update` function that takes the contents of the file as an argument." + "The `HASH` object provides an `update` method that takes the contents of the file as an argument." ] }, { @@ -1167,42 +1167,7 @@ "id": "897c66bf", "metadata": {}, "source": [ - "The order of the results depends on details of the operating system.\n", - "\n", - "Here is a more general version of `walk` that takes as a second parameter a function object.\n", - "Instead of printing the path of the files it discovers, it calls this function and passes the path as a parameter." - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "49e52d49", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "id": "7db28cf6", - "metadata": {}, - "source": [ - "Here's an example where we pass `print` as an argument, so when `walk` calls `visit_func`, it prints the paths of the files it discovers." - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "id": "6a86db4e", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "id": "1c6faa6d", - "metadata": {}, - "source": [ - "The parameter is called `visit_func` because it suggests that as we \"walk\" around the directory, we \"visit\" each file." + "The order of the results depends on details of the operating system." ] }, { @@ -1212,14 +1177,15 @@ "source": [ "## Debugging\n", "\n", - "When you are reading and writing files, you might run into problems with\n", - "whitespace. These errors can be hard to debug because spaces, tabs and\n", - "newlines are normally invisible:" + "When you are reading and writing files, you might run into problems with whitespace.\n", + "These errors can be hard to debug because whitespace characters are normally invisible.\n", + "For example, here's a string that contains spaces, a tab represented by the sequence `\\t`, and a newline represented by the sequence `\\n`.\n", + "When we print it, we don't see the whitespace characters." ] }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 65, "id": "15d7425a", "metadata": {}, "outputs": [], @@ -1230,14 +1196,13 @@ "id": "49bbebe6", "metadata": {}, "source": [ - "The built-in function `repr` can help. It takes any object as an\n", - "argument and returns a string representation of the object. For strings,\n", - "it represents whitespace characters with backslash sequences:" + "The built-in function `repr` can help. It takes any object as an argument and returns a string representation of the object.\n", + "For strings, it represents whitespace characters with backslash sequences." ] }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 66, "id": "61feff85", "metadata": {}, "outputs": [], @@ -1306,7 +1271,7 @@ "A database whose contents are organized like a dictionary with keys that correspond to values.\n", "\n", "**binary mode:**\n", - "A way of writing a file so the contents are interpreted as sequence of bytes rather than a sequence of characters.\n", + "A way of opening a file so the contents are interpreted as sequence of bytes rather than a sequence of characters.\n", "\n", "**hash function:**\n", "A function that takes and object and computes an integer, which is sometimes called a digest.\n", @@ -1325,7 +1290,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 67, "id": "bd885ba1", "metadata": { "tags": [] @@ -1390,7 +1355,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 68, "id": "1e598e70", "metadata": {}, "outputs": [], @@ -1398,7 +1363,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 69, "id": "d3774d1a", "metadata": {}, "outputs": [], @@ -1414,7 +1379,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 70, "id": "3b80dfd8", "metadata": { "tags": [] @@ -1424,7 +1389,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 71, "id": "4b67579f", "metadata": { "tags": [] @@ -1434,7 +1399,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 72, "id": "1d990225", "metadata": { "tags": [] @@ -1457,7 +1422,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 73, "id": "1c2fff95", "metadata": {}, "outputs": [], @@ -1475,7 +1440,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 74, "id": "8008cde6", "metadata": { "tags": [] @@ -1485,7 +1450,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 75, "id": "a6b5e51a", "metadata": { "tags": [] @@ -1505,7 +1470,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 76, "id": "ffefe13e", "metadata": { "tags": [] @@ -1515,7 +1480,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 77, "id": "7eb54fbc", "metadata": { "tags": [] @@ -1525,7 +1490,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 78, "id": "ac784df7", "metadata": { "tags": [] @@ -1569,7 +1534,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 79, "id": "03b6acf9", "metadata": {}, "outputs": [], @@ -1587,7 +1552,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 80, "id": "21c33092", "metadata": { "tags": [] @@ -1605,7 +1570,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 81, "id": "31c056a9", "metadata": {}, "outputs": [], @@ -1616,12 +1581,12 @@ "id": "08223a21", "metadata": {}, "source": [ - "3. Write a function called `process_path` that takes a path, uses `is_image` to check whether it's an image file, and uses `add_path` to add it to the shelf." + "3. Write a version of `walk` called `walk_images` that takes a directory and walks through the files in the directory and its subdirectories. For each file, it should use `is_image` to check whether it's an image file and `add_path` to add it to the shelf." ] }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 87, "id": "e54d6993", "metadata": {}, "outputs": [], @@ -1637,7 +1602,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 88, "id": "c31ba5b6", "metadata": { "tags": [] @@ -1656,7 +1621,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 89, "id": "d7c7e679", "metadata": {}, "outputs": [], @@ -1669,6 +1634,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1688,7 +1669,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap14.ipynb b/blank/chap14.ipynb index d532526..38aaffc 100644 --- a/blank/chap14.ipynb +++ b/blank/chap14.ipynb @@ -242,7 +242,7 @@ "id": "bcbea13a", "metadata": {}, "source": [ - "We'll use this f-string to write a function that displays the value of time objects.\n", + "We'll use this f-string to write a function that displays the value of a `Time`object.\n", "You can pass an object as an argument in the usual way.\n", "For example, the following function takes a `Time` object as an argument. " ] @@ -585,12 +585,11 @@ "source": [ "`add_time` is a **pure function** because it does not modify any of the objects passed to it as arguments and its only effect is to return a value.\n", "\n", - "Anything that can be done with modifiers can also be done with pure functions.\n", + "Anything that can be done with impure functions can also be done with pure functions.\n", "In fact, some programming languages only allow pure functions.\n", - "Programs that use pure functions might be less error-prone than programs that use modifiers.\n", - "But modifiers are sometimes convenient and can be more efficient.\n", + "Programs that use pure functions might be less error-prone, but impure functions are sometimes convenient and can be more efficient.\n", "\n", - "In general, I suggest you write pure functions whenever it is reasonable and resort to modifiers only if there is a compelling advantage.\n", + "In general, I suggest you write pure functions whenever it is reasonable and resort to impure functions only if there is a compelling advantage.\n", "This approach might be called a **functional programming style**." ] }, @@ -623,7 +622,7 @@ "The result is not a valid time.\n", "The problem is that `increment_time` does not deal with cases where the number of seconds or minutes adds up to more than `60`.\n", "\n", - "Here's an improved version that checks whether `second` exceeds `60` -- if so, it increments `minute` -- then checks whether `minute` exceeds `60` -- if so, it increments `hour`." + "Here's an improved version that checks whether `second` exceeds or equals `60` -- if so, it increments `minute` -- then checks whether `minute` exceeds or equals `60` -- if so, it increments `hour`." ] }, { @@ -676,7 +675,7 @@ "source": [ "The result is not a valid time.\n", "So let's try a different approach, using the `divmod` function.\n", - "We'll make a copy of `start` and modify it by incrementing the `minutes` field." + "We'll make a copy of `start` and modify it by incrementing the `minute` attribute." ] }, { @@ -1072,7 +1071,7 @@ "\n", "* \"What is the difference between a variable and an attribute?\"\n", "\n", - "* \"What are the pros and cons of pure functions compared to modifiers?\"\n", + "* \"What are the pros and cons of pure functions compared to impure functions?\"\n", "\n", "Because we are just getting started with object oriented programming, the code in this chapter is not idiomatic -- it is not the kind of code experienced programmers write.\n", "If you ask a virtual assistant for help with the exercises, you will probably see features we have not covered yet.\n", @@ -1416,6 +1415,22 @@ "id": "d6f1cc2f", "metadata": {}, "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1435,7 +1450,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap15.ipynb b/blank/chap15.ipynb index b889679..2ffde33 100644 --- a/blank/chap15.ipynb +++ b/blank/chap15.ipynb @@ -84,7 +84,7 @@ "id": "8da4079c", "metadata": {}, "source": [ - "To call this function, you have to pass a `Time` object as an argument.\n", + "To call this method, you have to pass a `Time` object as an argument.\n", "Here's the function we'll use to make a `Time` object." ] }, @@ -284,7 +284,7 @@ "id": "d2f4fd5a", "metadata": {}, "source": [ - "The result is a new object that represents `9:40`." + "The result is a new object that represents 9:40." ] }, { @@ -724,7 +724,7 @@ "## Glossary\n", "\n", "**object-oriented language:**\n", - "A language that provides features to support object-oriented programming, notably user-defined types and inheritance.\n", + "A language that provides features to support object-oriented programming, notably user-defined types.\n", "\n", "**method:**\n", "A function that is defined inside a class definition and is invoked on instances of that class.\n", @@ -809,7 +809,7 @@ "\n", "2. Write an `__init__` method that takes `year`, `month`, and `day` as parameters and assigns the parameters to attributes. Create an object that represents June 22, 1933.\n", "\n", - "2. Write `__str__` method that uses a format string to format the attributes and returns the result. If you test it with the `Date` you created, the result should be `1933-06-22`.\n", + "2. Write `__str__` method that uses an f-string to format the attributes and returns the result. If you test it with the `Date` you created, the result should be `1933-06-22`.\n", "\n", "3. Write a method called `is_after` that takes two `Date` objects and returns `True` if the first comes after the second. Create a second object that represents September 17, 1933, and check whether it comes after the first object.\n", "\n", @@ -881,6 +881,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -900,7 +916,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap16.ipynb b/blank/chap16.ipynb index 06b929c..4309183 100644 --- a/blank/chap16.ipynb +++ b/blank/chap16.ipynb @@ -436,8 +436,8 @@ "id": "c008d3dd", "metadata": {}, "source": [ - "It's not possible to override the `is` operator -- it always checks whether the objects are **identical**.\n", - "But for programmer-defined types, you can override the `==` operator so it checks whether the objects are **equivalent**.\n", + "It's not possible to override the `is` operator -- it always checks whether the objects are identical.\n", + "But for programmer-defined types, you can override the `==` operator so it checks whether the objects are equivalent.\n", "And you can define what equivalent means." ] }, @@ -915,7 +915,7 @@ "\n", "To avoid sharing objects, you can use deep copy, as we did in this chapter.\n", "\n", - "To avoid modifying objects, consider replacing modifiers like `translate` with pure functions like `translated`.\n", + "To avoid modifying objects, consider replacing impure functions like `translate` with pure functions like `translated`.\n", "For example, here's a version of `translated` that creates a new `Point` and never modifies its attributes." ] }, @@ -936,7 +936,7 @@ "They are beyond the scope of this book, but if you are curious, ask a virtual assistant, \"How do I make a Python object immutable?\"\n", "\n", "Creating a new object takes more time than modifying an existing one, but the difference seldom matters in practice.\n", - "Programs that avoid shared objects and modifiers are often easier to develop, test, and debug -- and the best kind of debugging is the kind you don't have to do." + "Programs that avoid shared objects and impure functions are often easier to develop, test, and debug -- and the best kind of debugging is the kind you don't have to do." ] }, { @@ -946,12 +946,6 @@ "source": [ "## Glossary\n", "\n", - "**identical:**\n", - "Being the same object (which implies equivalence).\n", - "\n", - "**equivalent:**\n", - "Having the same value.\n", - "\n", "**shallow copy:**\n", "A copy operation that does not copy nested objects.\n", "\n", @@ -1514,6 +1508,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1533,7 +1543,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap17.ipynb b/blank/chap17.ipynb index d257eb0..bc6b43e 100644 --- a/blank/chap17.ipynb +++ b/blank/chap17.ipynb @@ -110,7 +110,7 @@ "id": "d63f798a", "metadata": {}, "source": [ - "The first element of `rank_names` is `None` because there is no card with rank zero. By including `None` as a place-keeper, we get a list with the nice property that the index 2 maps to the string `'2'`, and so on.\n", + "The first element of `rank_names` is `None` because there is no card with rank zero. By including `None` as a place-keeper, we get a list with the nice property that the index `2` maps to the string `'2'`, and so on.\n", "\n", "Class variables are associated with the class, rather than an instance of the class, so we can access them like this." ] @@ -342,7 +342,7 @@ "metadata": {}, "source": [ "They don't, so it returns `False`.\n", - "We can change this behavior by defining a special method called `__eq__`." + "We can change this behavior by defining the special method `__eq__`." ] }, { @@ -410,7 +410,7 @@ "metadata": {}, "source": [ "If we use the `!=` operator, Python invokes a special method called `__ne__`, if it exists.\n", - "Otherwise it invokes`__eq__` and inverts the result -- so if `__eq__` returns `True`, the result of the `!=` operator is `False`. " + "Otherwise it invokes`__eq__` and inverts the result -- so if `__eq__` returns `True`, the result of the `!=` operator is `False`." ] }, { @@ -492,7 +492,7 @@ "Tuple comparison compares the first elements from each tuple, which represent the suits.\n", "If they are the same, it compares the second elements, which represent the ranks.\n", "\n", - "Now if we use the `<` operator, it invokes the `__lt__` operator." + "Now if we use the `<` operator, it invokes the `__lt__` method." ] }, { @@ -1253,7 +1253,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 64, "id": "e281457a", "metadata": { "tags": [] @@ -1300,7 +1300,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 65, "id": "47d9ce31", "metadata": {}, "outputs": [], @@ -1319,7 +1319,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 66, "id": "7bb54059", "metadata": {}, "outputs": [], @@ -1346,7 +1346,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 67, "id": "72a410d7", "metadata": { "tags": [] @@ -1356,7 +1356,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 68, "id": "b09cceb1", "metadata": { "tags": [] @@ -1376,7 +1376,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 69, "id": "e185c2f7", "metadata": { "tags": [] @@ -1398,7 +1398,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 70, "id": "2558ddd1", "metadata": {}, "outputs": [], @@ -1446,7 +1446,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 71, "id": "7aa25f29", "metadata": { "tags": [] @@ -1456,7 +1456,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 72, "id": "72c769d5", "metadata": { "tags": [] @@ -1476,7 +1476,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 73, "id": "e1c4f474", "metadata": { "tags": [] @@ -1496,7 +1496,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 74, "id": "c91e3bdb", "metadata": { "tags": [] @@ -1516,7 +1516,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 75, "id": "a60e233d", "metadata": { "tags": [] @@ -1536,7 +1536,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 76, "id": "ae5063e2", "metadata": { "tags": [] @@ -1556,7 +1556,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 77, "id": "940928ba", "metadata": { "tags": [] @@ -1591,7 +1591,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 78, "id": "6513ef14", "metadata": { "tags": [] @@ -1601,7 +1601,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 79, "id": "8a220d67", "metadata": { "tags": [] @@ -1622,7 +1622,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 80, "id": "5a422cae", "metadata": { "tags": [] @@ -1642,7 +1642,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 81, "id": "24483b99", "metadata": { "tags": [] @@ -1662,7 +1662,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 82, "id": "69f7cea9", "metadata": { "tags": [] @@ -1693,7 +1693,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 83, "id": "88bd35fb", "metadata": { "tags": [] @@ -1703,7 +1703,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 84, "id": "5e602773", "metadata": { "tags": [] @@ -1713,7 +1713,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 85, "id": "997b120d", "metadata": { "tags": [] @@ -1733,7 +1733,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 86, "id": "23704ab4", "metadata": { "tags": [] @@ -1743,7 +1743,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 87, "id": "7d8d2fdb", "metadata": { "tags": [] @@ -1764,7 +1764,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 88, "id": "4c5727d9", "metadata": { "tags": [] @@ -1784,7 +1784,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 89, "id": "7e65e951", "metadata": { "tags": [] @@ -1804,7 +1804,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 90, "id": "758fc922", "metadata": { "tags": [] @@ -1826,14 +1826,16 @@ { "cell_type": "markdown", "id": "00464353", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ "You can use the following outline to get started." ] }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 91, "id": "15a81a40", "metadata": { "tags": [] @@ -1843,7 +1845,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 92, "id": "bc7ca211", "metadata": { "tags": [] @@ -1853,7 +1855,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 93, "id": "20b65d89", "metadata": { "tags": [] @@ -1871,7 +1873,7 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 94, "id": "57e616be", "metadata": {}, "outputs": [], @@ -1879,7 +1881,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 95, "id": "b8d87fd8", "metadata": {}, "outputs": [], @@ -1887,7 +1889,7 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 96, "id": "3016e99a", "metadata": {}, "outputs": [], @@ -1895,7 +1897,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 97, "id": "852e3b11", "metadata": {}, "outputs": [], @@ -1924,7 +1926,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 98, "id": "1f95601d", "metadata": { "tags": [] @@ -1934,7 +1936,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 99, "id": "420ca0fd", "metadata": { "tags": [] @@ -1954,7 +1956,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 100, "id": "1e4957cb", "metadata": { "tags": [] @@ -1964,7 +1966,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 101, "id": "4dc8b899", "metadata": { "tags": [] @@ -1974,7 +1976,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 102, "id": "86229763", "metadata": { "tags": [] @@ -1984,7 +1986,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 103, "id": "7f1b3664", "metadata": { "tags": [] @@ -2005,7 +2007,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 104, "id": "85b47651", "metadata": {}, "outputs": [], @@ -2023,12 +2025,12 @@ "`put_in_pouch` takes any object and appends it to `contents`.\n", "\n", "Now let's see how this class works.\n", - "We'll create two `Kangaroo` objects with the names Kanga and Roo." + "We'll create two `Kangaroo` objects with the names `'Kanga'` and `'Roo'`." ] }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 105, "id": "13f1e1f3", "metadata": {}, "outputs": [], @@ -2044,7 +2046,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 106, "id": "e882e2d6", "metadata": {}, "outputs": [], @@ -2060,7 +2062,7 @@ }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 107, "id": "724805bb", "metadata": {}, "outputs": [], @@ -2076,7 +2078,7 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 108, "id": "3f6cff16", "metadata": {}, "outputs": [], @@ -2100,6 +2102,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -2119,7 +2137,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap18.ipynb b/blank/chap18.ipynb index 42783f3..6a069c1 100644 --- a/blank/chap18.ipynb +++ b/blank/chap18.ipynb @@ -293,7 +293,7 @@ "source": [ "The result is a set that contains the words in the document that don't appear in the word list.\n", "\n", - "The comparison operators work with sets.\n", + "The relational operators work with sets.\n", "For example, `<=` checks whether one set is a subset of another, including the possibility that they are equal." ] }, @@ -358,7 +358,7 @@ "If you are familiar with the mathematical idea of a \"multiset\", a `Counter` is a\n", "natural way to represent a multiset.\n", "\n", - "The `Counter` class is defined in a standard module called `collections`, so you have to import it.\n", + "The `Counter` class is defined in a module called `collections`, so you have to import it.\n", "Then you can use the class object as a function and pass as an argument a string, list, or any other kind of sequence." ] }, @@ -1263,7 +1263,7 @@ "id": "71e3b049", "metadata": {}, "source": [ - "You can call this function with any number of positional arguments." + "You can call this function with any number of arguments." ] }, { @@ -1513,7 +1513,7 @@ "metadata": {}, "source": [ "`run_unittest` does not take `TestExample` as an argument -- instead, it searches for classes that inherit from `TestCase`.\n", - "Then is searches for methods that begin with `test` and runs them.\n", + "Then it searches for methods that begin with `test` and runs them.\n", "This process is called **test discovery**.\n", "\n", "Here's what happens when we call `run_unittest`." @@ -1636,7 +1636,7 @@ "\n", "* \"How does `unittest` do test discovery?\"\n", "\n", - "\"Along with `assertequal`, what are the most commonly used methods in `unittest.TestCase`?\"\n", + "\"Along with `assertEqual`, what are the most commonly used methods in `unittest.TestCase`?\"\n", "\n", "\"What are the pros and cons of `doctest` and `unittest`?\"\n", "\n", @@ -2045,6 +2045,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -2064,7 +2080,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/blank/chap19.ipynb b/blank/chap19.ipynb index 190c3e6..4d86fb8 100644 --- a/blank/chap19.ipynb +++ b/blank/chap19.ipynb @@ -146,6 +146,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { diff --git a/chapters/chap00.ipynb b/chapters/chap00.ipynb index ff1fcfa..e7c283c 100644 --- a/chapters/chap00.ipynb +++ b/chapters/chap00.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "id": "d9724920", @@ -58,7 +50,7 @@ "\n", "Writing this book, I tried to be careful with the vocabulary.\n", "I define each term when it first appears.\n", - "And there is a glossary that the end of each chapter that reviews the terms that were introduced.\n", + "And there is a glossary at the end of each chapter that reviews the terms that were introduced.\n", "\n", "I also tried to be concise.\n", "The less mental effort it takes to read the book, the more capacity you will have for programming.\n", @@ -179,9 +171,9 @@ "\n", "If you are teaching with this book, here are some resources you might find useful.\n", "\n", - "* You can find notebooks with solutions to the exercises from , along with links to the additional resources below.\n", + "* You can find notebooks with solutions to the exercises at , along with links to the additional resources below.\n", "\n", - "* Quizzes for each chapter, and a summative quiz for the whole book, are available from [COMING SOON]\n", + "* Quizzes for each chapter, and a summative quiz for the whole book, are available on request.\n", "\n", "* *Teaching and Learning with Jupyter* is an online book with suggestions for using Jupyter effectively in the classroom. You can read the book at \n", "\n", @@ -225,6 +217,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -243,7 +251,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap01.ipynb b/chapters/chap01.ipynb index 12c68a7..bd3875d 100644 --- a/chapters/chap01.ipynb +++ b/chapters/chap01.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "id": "a14edb7e", @@ -177,9 +169,9 @@ "source": [ "Notice that the result of the division is `42.0` rather than `42`. That's because there are two types of numbers in Python: \n", "\n", - "* **integers**, which represent whole numbers, and \n", + "* **integers**, which represent numbers with no fractional or decimal part, and \n", "\n", - "* **floating-point numbers**, which represent numbers with a decimal point.\n", + "* **floating-point numbers**, which represent integers and numbers with a decimal point.\n", "\n", "If you add, subtract, or multiply two integers, the result is an integer.\n", "But if you divide two integers, the result is a floating-point number.\n", @@ -341,7 +333,7 @@ "## Arithmetic functions\n", "\n", "In addition to the arithmetic operators, Python provides a few **functions** that work with numbers.\n", - "For example, the `round` function takes a floating-point number and rounds it off to the nearest whole number." + "For example, the `round` function takes a floating-point number and rounds it off to the nearest integer." ] }, { @@ -589,7 +581,7 @@ "source": [ "The other arithmetic operators don't work with strings.\n", "\n", - "Python provides a function called `len` that computes the length of a string.`" + "Python provides a function called `len` that computes the length of a string." ] }, { @@ -969,10 +961,10 @@ "A symbol, like `+` and `*`, that denotes an arithmetic operation like addition or multiplication.\n", "\n", "**integer:**\n", - "A type that represents whole numbers.\n", + "A type that represents numbers with no fractional or decimal part.\n", "\n", "**floating-point:**\n", - "A type that represents numbers with fractional parts.\n", + "A type that represents integers and numbers with decimal parts.\n", "\n", "**integer division:**\n", "An operator, `//`, that divides two numbers and rounds down to an integer.\n", @@ -1071,7 +1063,7 @@ "\n", "* I also mentioned the order of operations. For more details, ask \"What is the order of operations in Python?\"\n", "\n", - "* The `round` function, which we used to round a floating-point number to the nearest whole number, can take a second argument. Try asking \"What are the arguments of the round function?\" or \"How do I round pi off to three decimal places?\"\n", + "* The `round` function, which we used to round a floating-point number to the nearest integer, can take a second argument. Try asking \"What are the arguments of the round function?\" or \"How do I round pi off to three decimal places?\"\n", "\n", "* There's one more arithmetic operator I didn't mention; try asking \"What is the modulus operator in Python?\"" ] @@ -1272,6 +1264,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1291,7 +1299,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap02.ipynb b/chapters/chap02.ipynb index 2bf4929..fb2369f 100644 --- a/chapters/chap02.ipynb +++ b/chapters/chap02.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 1, @@ -515,7 +507,7 @@ "id": "cff0414b", "metadata": {}, "source": [ - "Similarly, an import statement has an effect -- it imports a module so we can use the values and functions it contains -- but it has no visible effect." + "Similarly, an import statement has an effect -- it imports a module so we can use the variables and functions it contains -- but it has no visible effect." ] }, { @@ -1017,7 +1009,7 @@ "A special word used to specify the structure of a program.\n", "\n", "**import statement:**\n", - "A statement that reads a module file and creates a module object.\n", + "A statement that reads a module file so we can use the variables and functions it contains.\n", "\n", "**module:**\n", "A file that contains Python code, including function definitions and sometimes other statements.\n", @@ -1036,7 +1028,6 @@ "\n", "**argument:**\n", "A value provided to a function when the function is called.\n", - "Each argument is assigned to the corresponding parameter in the function.\n", "\n", "**comment:**\n", "Text included in a program that provides information about the program but has no effect on its execution.\n", @@ -1061,7 +1052,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 43, "id": "c9e6cab4", "metadata": { "tags": [] @@ -1087,7 +1078,7 @@ "\n", "You might have noticed that `int`, `float`, and `str` are not Python keywords.\n", "They are variables that represent types, and they can be used as functions.\n", - "So it is *legal* to have a variable or function with one of those names, but it is strongly discouraged. Ask an assistant \"Why is it bad to use int, float, and string as variable names?\"\n", + "So it is *legal* to have a variable or function with one of those names, but it is strongly discouraged. Ask an assistant \"Why is it bad to use int, float, and str as variable names?\"\n", "\n", "Also ask, \"What are the built-in functions in Python?\"\n", "If you are curious about any of them, ask for more information.\n", @@ -1130,7 +1121,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 44, "id": "18de7d96", "metadata": {}, "outputs": [], @@ -1153,7 +1144,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 52, "id": "de812cff", "metadata": {}, "outputs": [], @@ -1180,7 +1171,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 46, "id": "b4ada618", "metadata": {}, "outputs": [], @@ -1190,7 +1181,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 47, "id": "4424940f", "metadata": {}, "outputs": [], @@ -1200,7 +1191,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 48, "id": "50e8393a", "metadata": {}, "outputs": [], @@ -1215,6 +1206,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1234,7 +1241,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" }, "vscode": { "interpreter": { diff --git a/chapters/chap03.ipynb b/chapters/chap03.ipynb index 7a5107a..5f2cb1d 100644 --- a/chapters/chap03.ipynb +++ b/chapters/chap03.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 1, @@ -420,7 +412,7 @@ "The first line is a header that ends with a colon.\n", "The second line is the body, which has to be indented.\n", "\n", - "The first line starts with the keyword `for`, a new variable named `i`, and another keyword, `in`. \n", + "The header starts with the keyword `for`, a new variable named `i`, and another keyword, `in`. \n", "It uses the `range` function to create a sequence of two values, which are `0` and `1`.\n", "In Python, when we start counting, we usually start from `0`.\n", "\n", @@ -588,13 +580,13 @@ "frame2 = make_frame(d2, name='cat_twice', dy=-0.3, \n", " offsetx=0.03, loc='left')\n", "\n", - "d3 = dict(s = line1+line2)\n", + "d3 = dict(string=line1+line2)\n", "frame3 = make_frame(d3, name='print_twice', \n", - " offsetx=-0.28, offsety=-0.3, loc='left')\n", + " offsetx=0.04, offsety=-0.3, loc='left')\n", "\n", "d4 = {\"?\": line1+line2}\n", "frame4 = make_frame(d4, name='print', \n", - " offsetx=-0.28, offsety=0, loc='left')\n", + " offsetx=-0.22, offsety=0, loc='left')\n", "\n", "stack = Stack([frame1, frame2, frame3, frame4], dy=-0.8)" ] @@ -611,10 +603,13 @@ "from diagram import diagram, adjust\n", "\n", "\n", - "width, height, x, y = [3.8, 2.91, 1.15, 2.66]\n", + "width, height, x, y = [3.77, 2.9, 1.1, 2.65]\n", "ax = diagram(width, height)\n", "bbox = stack.draw(ax, x, y)\n", - "#adjust(x, y, bbox)" + "# adjust(x, y, bbox)\n", + "\n", + "import matplotlib.pyplot as plt\n", + "plt.savefig('chap03_stack_diagram.png', dpi=300)" ] }, { @@ -881,7 +876,9 @@ "cell_type": "code", "execution_count": 30, "id": "f142ce6a", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "print_right(\"Monty\")\n", @@ -914,7 +911,8 @@ "execution_count": 32, "id": "b8146a0d", "metadata": { - "scrolled": true + "scrolled": true, + "tags": [] }, "outputs": [], "source": [ @@ -946,7 +944,8 @@ "execution_count": 34, "id": "73b0c0f6", "metadata": { - "scrolled": true + "scrolled": true, + "tags": [] }, "outputs": [], "source": [ @@ -997,7 +996,9 @@ { "cell_type": "markdown", "id": "ee0076dd", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ "Use this function call to display the first verse." ] @@ -1006,7 +1007,9 @@ "cell_type": "code", "execution_count": 37, "id": "47a91c7d", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "bottle_verse(99)" @@ -1015,7 +1018,9 @@ { "cell_type": "markdown", "id": "42c237c6", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ "If you want to print the whole song, you can use this `for` loop, which counts down from `99` to `1`.\n", "You don't have to completely understand this example---we'll learn more about `for` loops and the `range` function later." @@ -1042,6 +1047,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1061,7 +1082,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap04.ipynb b/chapters/chap04.ipynb index 7a09336..7117af6 100644 --- a/chapters/chap04.ipynb +++ b/chapters/chap04.ipynb @@ -2,25 +2,17 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, { "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "id": "df64b7da", "metadata": { "tags": [] @@ -45,7 +37,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "id": "320fc8bc", "metadata": { "tags": [] @@ -83,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "id": "8f5a8a45", "metadata": {}, "outputs": [], @@ -101,7 +93,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "b3f255cd", "metadata": {}, "outputs": [], @@ -127,7 +119,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "234fde81", "metadata": {}, "outputs": [], @@ -145,7 +137,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "1e768880", "metadata": {}, "outputs": [], @@ -165,7 +157,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "6d874b03", "metadata": {}, "outputs": [], @@ -184,7 +176,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "1bb57a0c", "metadata": {}, "outputs": [], @@ -216,7 +208,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "9a9e455f", "metadata": {}, "outputs": [], @@ -246,7 +238,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "cc27ad66", "metadata": {}, "outputs": [], @@ -271,7 +263,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "ad5f1128", "metadata": {}, "outputs": [], @@ -292,7 +284,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "193bbe5e", "metadata": {}, "outputs": [], @@ -315,7 +307,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "def8a5f1", "metadata": {}, "outputs": [], @@ -336,7 +328,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "b283e795", "metadata": {}, "outputs": [], @@ -354,12 +346,12 @@ "Adding a parameter to a function is called **generalization** because it makes the function more general: with the previous version, the square is always the same size; with this version it can be any size.\n", "\n", "If we add another parameter, we can make it even more general.\n", - "The following function draws regular polygons with a given of sides." + "The following function draws regular polygons with a given number of sides." ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "id": "171974ed", "metadata": {}, "outputs": [], @@ -383,7 +375,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "id": "71f7d9d2", "metadata": {}, "outputs": [], @@ -403,7 +395,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "id": "8ff2a5f4", "metadata": { "tags": [] @@ -439,7 +431,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "id": "7f2a5f28", "metadata": {}, "outputs": [], @@ -469,7 +461,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "id": "75258056", "metadata": {}, "outputs": [], @@ -508,7 +500,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "id": "381edd23", "metadata": {}, "outputs": [], @@ -531,7 +523,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "id": "2f4eecc0", "metadata": {}, "outputs": [], @@ -551,7 +543,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 23, "id": "539466f6", "metadata": {}, "outputs": [], @@ -576,7 +568,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 24, "id": "8e09f456", "metadata": {}, "outputs": [], @@ -596,7 +588,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 25, "id": "80d6eadd", "metadata": {}, "outputs": [], @@ -633,7 +625,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 26, "id": "1571ee71", "metadata": { "tags": [] @@ -654,7 +646,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 27, "id": "f4e37360", "metadata": { "tags": [] @@ -693,7 +685,6 @@ "\n", "2. Once you get the program working, identify a coherent piece of it,\n", " encapsulate the piece in a function and give it a name.\n", - " Copy and paste working code to avoid retyping (and re-debugging).\n", "\n", "3. Generalize the function by adding appropriate parameters.\n", "\n", @@ -723,7 +714,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 28, "id": "baf964ba", "metadata": {}, "outputs": [], @@ -745,7 +736,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 29, "id": "e2e006d5", "metadata": {}, "outputs": [], @@ -777,7 +768,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 30, "id": "b68f3682", "metadata": {}, "outputs": [], @@ -885,7 +876,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 31, "id": "9f94061e", "metadata": { "tags": [] @@ -914,7 +905,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 32, "id": "6f9a0106", "metadata": {}, "outputs": [], @@ -944,7 +935,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 33, "id": "c54ba660", "metadata": {}, "outputs": [], @@ -964,7 +955,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 34, "id": "1311ee08", "metadata": { "tags": [] @@ -980,14 +971,14 @@ "id": "8b8faaf6", "metadata": {}, "source": [ - "## Exercise\n", + "### Exercise\n", "\n", "Write a function called `rhombus` that draws a rhombus with a given side length and a given interior angle. For example, here's a rhombus with side length `50` and an interior angle of `60` degrees." ] }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 35, "id": "3db6f106", "metadata": {}, "outputs": [], @@ -1007,7 +998,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 36, "id": "1d845de9", "metadata": { "tags": [] @@ -1030,7 +1021,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 37, "id": "895005cb", "metadata": {}, "outputs": [], @@ -1040,7 +1031,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 38, "id": "7e7d34b0", "metadata": {}, "outputs": [], @@ -1050,7 +1041,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 39, "id": "481396f9", "metadata": {}, "outputs": [], @@ -1070,7 +1061,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 40, "id": "c8dfebc9", "metadata": { "tags": [] @@ -1089,19 +1080,21 @@ }, { "cell_type": "markdown", - "id": "feae252c", + "id": "991ab59d", "metadata": {}, "source": [ "### Exercise\n", "\n", "Write an appropriately general set of functions that can draw shapes like this.\n", "\n", + "![](https://github.com/AllenDowney/ThinkPython/raw/v3/jupyturtle_pie.png)\n", + "\n", "Hint: Write a function called `triangle` that draws one triangular segment, and then a function called `draw_pie` that uses `triangle`." ] }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 41, "id": "8be6442e", "metadata": {}, "outputs": [], @@ -1111,7 +1104,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 42, "id": "be1b7ed8", "metadata": {}, "outputs": [], @@ -1131,14 +1124,14 @@ }, { "cell_type": "code", - "execution_count": 42, - "id": "89ce198a", + "execution_count": null, + "id": "c519ca39", "metadata": { "tags": [] }, "outputs": [], "source": [ - "make_turtle(delay=0)\n", + "turtle = make_turtle(delay=0)\n", "jump(-80)\n", "\n", "size = 40\n", @@ -1149,21 +1142,35 @@ "draw_pie(7, size)" ] }, + { + "cell_type": "code", + "execution_count": 51, + "id": "89ce198a", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, { "cell_type": "markdown", - "id": "7c665dd1", + "id": "9c78b76f", "metadata": {}, "source": [ "### Exercise\n", "\n", "Write an appropriately general set of functions that can draw flowers like this.\n", "\n", + "![](https://github.com/AllenDowney/ThinkPython/raw/v3/jupyturtle_flower.png)\n", + "\n", "Hint: Use `arc` to write a function called `petal` that draws one flower petal." ] }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 44, "id": "0f0e7498", "metadata": {}, "outputs": [], @@ -1173,7 +1180,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 45, "id": "6c0d0bff", "metadata": {}, "outputs": [], @@ -1198,8 +1205,8 @@ }, { "cell_type": "code", - "execution_count": 45, - "id": "4cfea3b0", + "execution_count": null, + "id": "04193da5", "metadata": { "tags": [] }, @@ -1207,7 +1214,7 @@ "source": [ "from jupyturtle import render\n", "\n", - "make_turtle(auto_render=False)\n", + "turtle = make_turtle(auto_render=False)\n", "\n", "jump(-60)\n", "n = 7\n", @@ -1224,6 +1231,18 @@ "render()" ] }, + { + "cell_type": "code", + "execution_count": 53, + "id": "4cfea3b0", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# Solution goes here" + ] + }, { "cell_type": "markdown", "id": "9d9f35d1", @@ -1273,7 +1292,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 47, "id": "46d3151c", "metadata": {}, "outputs": [], @@ -1283,7 +1302,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 48, "id": "186c7fbc", "metadata": {}, "outputs": [], @@ -1292,12 +1311,20 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "id": "979f5ad4", - "metadata": {}, - "outputs": [], - "source": [] + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1317,7 +1344,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap05.ipynb b/chapters/chap05.ipynb index e9b6f80..23e5094 100644 --- a/chapters/chap05.ipynb +++ b/chapters/chap05.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 1, @@ -88,8 +80,8 @@ "id": "3f224403", "metadata": {}, "source": [ - "But we don't normally write hours with decimal points. Floor division\n", - "returns the integer number of hours, rounding down:" + "But we don't normally write hours with decimal points.\n", + "Integer division returns the integer number of hours, rounding down:" ] }, { @@ -144,7 +136,7 @@ }, { "cell_type": "markdown", - "id": "f2344fc0", + "id": "18c1e0d0", "metadata": {}, "source": [ "The modulus operator is more useful than it might seem.\n", @@ -152,15 +144,42 @@ "\n", "Also, it can extract the right-most digit or digits from a number.\n", "For example, `x % 10` yields the right-most digit of `x` (in base 10).\n", - "Similarly, `x % 100` yields the last two digits.\n", - "\n", + "Similarly, `x % 100` yields the last two digits." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5bd341f7", + "metadata": {}, + "outputs": [], + "source": [ + "x = 123\n", + "x % 10" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "367fce0c", + "metadata": {}, + "outputs": [], + "source": [ + "x % 100" + ] + }, + { + "cell_type": "markdown", + "id": "f2344fc0", + "metadata": {}, + "source": [ "Finally, the modulus operator can do \"clock arithmetic\".\n", "For example, if an event starts at 11 AM and lasts three hours, we can use the modulus operator to figure out what time it ends." ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 1, "id": "db33a44d", "metadata": {}, "outputs": [], @@ -179,18 +198,6 @@ "The event would end at 2 PM." ] }, - { - "cell_type": "code", - "execution_count": 7, - "id": "367fce0c", - "metadata": {}, - "outputs": [], - "source": [ - "a = 25 // 10\n", - "b = 25 % 10\n", - "a, b" - ] - }, { "cell_type": "markdown", "id": "5ed1b58b", @@ -1168,7 +1175,7 @@ "metadata": {}, "source": [ "The error message indicates line 5, but there is nothing wrong with that line.\n", - "The problem is in line 4, which uses floor division instead of floating-point division -- as a result, the value of `ratio` is `0`.\n", + "The problem is in line 4, which uses integer division instead of floating-point division -- as a result, the value of `ratio` is `0`.\n", "When we call `math.log10`, we get a `ValueError` with the message `math domain error`, because `0` is not in the \"domain\" of valid arguments for `math.log10`, because the logarithm of `0` is undefined.\n", "\n", "In general, you should take the time to read error messages carefully, but don't assume that everything they say is correct." @@ -1414,7 +1421,7 @@ "id": "054c3197", "metadata": {}, "source": [ - "Use floor division and the modulus operator to compute the number of days since January 1, 1970 and the current time of day in hours, minutes, and seconds." + "Use integer division and the modulus operator to compute the number of days since January 1, 1970 and the current time of day in hours, minutes, and seconds." ] }, { @@ -1687,7 +1694,7 @@ "\n", "The exception is if `x` is less than `5` -- in that case, you can just draw a straight line with length `x`.\n", "\n", - "Write a function called `koch` that takes `x` as a parameter and draws a Koch curve with the given length.\n" + "Write a function called `koch` that takes `x` as an argument and draws a Koch curve with the given length.\n" ] }, { @@ -1799,6 +1806,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1818,7 +1841,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap06.ipynb b/chapters/chap06.ipynb index 9763962..a8d03c3 100644 --- a/chapters/chap06.ipynb +++ b/chapters/chap06.ipynb @@ -2,25 +2,17 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, { "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 87, + "execution_count": 5, "id": "56b1c184", "metadata": { "tags": [] @@ -55,7 +47,7 @@ "When you call one of these functions, it returns a value you can assign to a variable or use as part of an expression.\n", "\n", "The functions we have written so far are different.\n", - "Some use the `print` function to display values, and some use `Turtle` functions to draw figures.\n", + "Some use the `print` function to display values, and some use turtle functions to draw figures.\n", "But they don't return values we assign to variables or use in expressions.\n", "\n", "In this chapter, we'll see how to write functions that return values." @@ -74,7 +66,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 6, "id": "e0e1dd91", "metadata": {}, "outputs": [], @@ -94,7 +86,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 7, "id": "5aaf62d2", "metadata": {}, "outputs": [], @@ -112,7 +104,7 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 8, "id": "741f7386", "metadata": {}, "outputs": [], @@ -130,7 +122,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 9, "id": "e56d39c4", "metadata": {}, "outputs": [], @@ -148,7 +140,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 10, "id": "50a9a9be", "metadata": {}, "outputs": [], @@ -172,7 +164,7 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 11, "id": "d70fd9b5", "metadata": {}, "outputs": [], @@ -190,7 +182,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 12, "id": "ef20ba8c", "metadata": {}, "outputs": [], @@ -208,7 +200,7 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 13, "id": "0a4670f4", "metadata": {}, "outputs": [], @@ -226,7 +218,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 14, "id": "6e6460b9", "metadata": {}, "outputs": [], @@ -244,7 +236,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 15, "id": "77613df9", "metadata": { "tags": [] @@ -277,7 +269,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 16, "id": "89c083f8", "metadata": {}, "outputs": [], @@ -296,7 +288,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 17, "id": "737b67ca", "metadata": {}, "outputs": [], @@ -315,7 +307,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 18, "id": "9b4fa14f", "metadata": {}, "outputs": [], @@ -333,7 +325,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 19, "id": "50f96bcb", "metadata": {}, "outputs": [], @@ -352,7 +344,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 20, "id": "6712f2df", "metadata": {}, "outputs": [], @@ -372,7 +364,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 21, "id": "0ec1afd3", "metadata": {}, "outputs": [], @@ -394,7 +386,7 @@ }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 22, "id": "c82334b6", "metadata": {}, "outputs": [], @@ -412,7 +404,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 23, "id": "595ec598", "metadata": {}, "outputs": [], @@ -440,7 +432,7 @@ }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 24, "id": "236c59e6", "metadata": {}, "outputs": [], @@ -467,7 +459,7 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 25, "id": "2f60639c", "metadata": {}, "outputs": [], @@ -489,7 +481,7 @@ }, { "cell_type": "code", - "execution_count": 108, + "execution_count": 26, "id": "c9dae6c8", "metadata": {}, "outputs": [], @@ -509,7 +501,7 @@ }, { "cell_type": "code", - "execution_count": 109, + "execution_count": 27, "id": "c8c4edee", "metadata": {}, "outputs": [], @@ -563,7 +555,7 @@ }, { "cell_type": "code", - "execution_count": 110, + "execution_count": 28, "id": "bbcab1ed", "metadata": {}, "outputs": [], @@ -585,7 +577,7 @@ }, { "cell_type": "code", - "execution_count": 111, + "execution_count": 29, "id": "923d96db", "metadata": {}, "outputs": [], @@ -609,7 +601,7 @@ }, { "cell_type": "code", - "execution_count": 112, + "execution_count": 30, "id": "9374cfe3", "metadata": {}, "outputs": [], @@ -635,7 +627,7 @@ }, { "cell_type": "code", - "execution_count": 113, + "execution_count": 31, "id": "405af839", "metadata": {}, "outputs": [], @@ -653,7 +645,7 @@ }, { "cell_type": "code", - "execution_count": 114, + "execution_count": 32, "id": "e52b3b04", "metadata": {}, "outputs": [], @@ -676,7 +668,7 @@ }, { "cell_type": "code", - "execution_count": 115, + "execution_count": 33, "id": "38eebbf3", "metadata": {}, "outputs": [], @@ -694,7 +686,7 @@ }, { "cell_type": "code", - "execution_count": 116, + "execution_count": 34, "id": "b4536ea0", "metadata": {}, "outputs": [], @@ -717,7 +709,7 @@ }, { "cell_type": "code", - "execution_count": 117, + "execution_count": 35, "id": "325efb93", "metadata": {}, "outputs": [], @@ -737,7 +729,7 @@ }, { "cell_type": "code", - "execution_count": 118, + "execution_count": 36, "id": "3cd982ce", "metadata": {}, "outputs": [], @@ -761,7 +753,7 @@ }, { "cell_type": "code", - "execution_count": 119, + "execution_count": 37, "id": "c734f5b2", "metadata": {}, "outputs": [], @@ -779,7 +771,7 @@ }, { "cell_type": "code", - "execution_count": 120, + "execution_count": 38, "id": "094a242f", "metadata": {}, "outputs": [], @@ -821,7 +813,7 @@ }, { "cell_type": "code", - "execution_count": 121, + "execution_count": 39, "id": "64207948", "metadata": {}, "outputs": [], @@ -843,7 +835,7 @@ }, { "cell_type": "code", - "execution_count": 122, + "execution_count": 40, "id": "c367cdae", "metadata": {}, "outputs": [], @@ -853,7 +845,7 @@ }, { "cell_type": "code", - "execution_count": 123, + "execution_count": 41, "id": "837f4f95", "metadata": {}, "outputs": [], @@ -872,7 +864,7 @@ }, { "cell_type": "code", - "execution_count": 124, + "execution_count": 42, "id": "e411354f", "metadata": {}, "outputs": [], @@ -891,7 +883,7 @@ }, { "cell_type": "code", - "execution_count": 125, + "execution_count": 43, "id": "925e7d4f", "metadata": {}, "outputs": [], @@ -910,7 +902,7 @@ }, { "cell_type": "code", - "execution_count": 126, + "execution_count": 44, "id": "62178e75", "metadata": {}, "outputs": [], @@ -949,7 +941,7 @@ "n! &= n~(n-1)!\n", "\\end{aligned}$$ \n", "\n", - "This definition says that the factorial of 0 is 1, and the factorial of any other value, $n$, is $n$ multiplied by the factorial of $n-1$.\n", + "This definition says that the factorial of $0$ is $1$, and the factorial of any other value, $n$, is $n$ multiplied by the factorial of $n-1$.\n", "\n", "If you can write a recursive definition of something, you can write a Python program to evaluate it. \n", "Following an incremental development process, we'll start with a function that take `n` as a parameter and always returns `0`." @@ -957,7 +949,7 @@ }, { "cell_type": "code", - "execution_count": 127, + "execution_count": 45, "id": "23e37c79", "metadata": {}, "outputs": [], @@ -971,12 +963,12 @@ "id": "ee1f63b8", "metadata": {}, "source": [ - "Now let's add the first part of the definition -- if the argument happens to be 0, all we have to do is return 1:" + "Now let's add the first part of the definition -- if the argument happens to be `0`, all we have to do is return `1`:" ] }, { "cell_type": "code", - "execution_count": 128, + "execution_count": 46, "id": "5ea57d9f", "metadata": {}, "outputs": [], @@ -994,12 +986,12 @@ "metadata": {}, "source": [ "Now let's fill in the second part -- if `n` is not `0`, we have to make a recursive\n", - "call to find the factorial of $n-1$ and then multiply the result by $n$:" + "call to find the factorial of `n-1` and then multiply the result by `n`:" ] }, { "cell_type": "code", - "execution_count": 129, + "execution_count": 47, "id": "b66e670b", "metadata": {}, "outputs": [], @@ -1047,7 +1039,7 @@ }, { "cell_type": "code", - "execution_count": 130, + "execution_count": 48, "id": "455f0457", "metadata": { "tags": [] @@ -1071,7 +1063,7 @@ " loc='left', dx=1.2)\n", " frames.append(frame)\n", " \n", - "binding1 = make_binding('n', n)\n", + "binding1 = make_binding('n', 0)\n", "frame = Frame([binding1], name='factorial', value=1, \n", " shim=1.2, loc='left', dx=1.4)\n", "frames.append(frame)\n", @@ -1081,7 +1073,7 @@ }, { "cell_type": "code", - "execution_count": 131, + "execution_count": 49, "id": "a75ccd9b", "metadata": { "tags": [] @@ -1150,7 +1142,7 @@ }, { "cell_type": "code", - "execution_count": 132, + "execution_count": 50, "id": "cad75752", "metadata": {}, "outputs": [], @@ -1170,7 +1162,7 @@ "metadata": {}, "source": [ "If you try to follow the flow of execution here, even for small values of $n$, your head explodes.\n", - "But according to the leap of faith, if you assume that the two recursive calls work correctly, you can be confident that the last return statement is correct.\n", + "But according to the leap of faith, if you assume that the two recursive calls work correctly, you can be confident that the last `return` statement is correct.\n", "\n", "As an aside, this way of computing Fibonacci numbers is very inefficient.\n", "In [Chapter 10](section_memos) I'll explain why and suggest a way to improve it." @@ -1188,7 +1180,7 @@ }, { "cell_type": "code", - "execution_count": 133, + "execution_count": 51, "id": "5e4b5f1d", "metadata": { "tags": [] @@ -1205,8 +1197,7 @@ "id": "0bec7ba4", "metadata": {}, "source": [ - "It looks like an infinite recursion. How can that be? The function has a\n", - "base case -- when `n == 0`.\n", + "It looks like an infinite recursion. How can that be? The function has base cases when `n == 1` or `n == 0`.\n", "But if `n` is not an integer, we can *miss* the base case and recurse forever.\n", "\n", "In this example, the initial value of `n` is `1.5`.\n", @@ -1220,7 +1211,7 @@ }, { "cell_type": "code", - "execution_count": 134, + "execution_count": 52, "id": "3f607dff", "metadata": {}, "outputs": [], @@ -1230,7 +1221,7 @@ }, { "cell_type": "code", - "execution_count": 135, + "execution_count": 53, "id": "ab638bfe", "metadata": {}, "outputs": [], @@ -1248,7 +1239,7 @@ }, { "cell_type": "code", - "execution_count": 136, + "execution_count": 54, "id": "73aafac0", "metadata": {}, "outputs": [], @@ -1278,7 +1269,7 @@ }, { "cell_type": "code", - "execution_count": 137, + "execution_count": 55, "id": "be881cb7", "metadata": {}, "outputs": [], @@ -1297,7 +1288,7 @@ }, { "cell_type": "code", - "execution_count": 138, + "execution_count": 56, "id": "fa83014f", "metadata": {}, "outputs": [], @@ -1346,7 +1337,7 @@ }, { "cell_type": "code", - "execution_count": 139, + "execution_count": 57, "id": "1d50479e", "metadata": {}, "outputs": [], @@ -1370,12 +1361,12 @@ "metadata": {}, "source": [ "`space` is a string of space characters that controls the indentation of\n", - "the output. Here is the result of `factorial(4)` :" + "the output. Here is the result of `factorial(3)` :" ] }, { "cell_type": "code", - "execution_count": 140, + "execution_count": 58, "id": "798db5c4", "metadata": {}, "outputs": [], @@ -1432,7 +1423,7 @@ }, { "cell_type": "code", - "execution_count": 142, + "execution_count": 59, "id": "e0f15ca4", "metadata": { "tags": [] @@ -1457,7 +1448,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 60, "id": "90b4979f", "metadata": {}, "outputs": [], @@ -1479,7 +1470,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 61, "id": "9217f038", "metadata": {}, "outputs": [], @@ -1503,7 +1494,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 62, "id": "3168489b", "metadata": {}, "outputs": [], @@ -1542,7 +1533,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 63, "id": "62267fa3", "metadata": {}, "outputs": [], @@ -1552,7 +1543,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 64, "id": "5f8fa829", "metadata": {}, "outputs": [], @@ -1562,7 +1553,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 65, "id": "3d129b03", "metadata": {}, "outputs": [], @@ -1572,7 +1563,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 66, "id": "030179b6", "metadata": {}, "outputs": [], @@ -1582,7 +1573,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 67, "id": "d737b468", "metadata": {}, "outputs": [], @@ -1592,7 +1583,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 68, "id": "77a74879", "metadata": {}, "outputs": [], @@ -1602,7 +1593,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 69, "id": "0521d267", "metadata": {}, "outputs": [], @@ -1612,7 +1603,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 70, "id": "468a31e9", "metadata": {}, "outputs": [], @@ -1622,7 +1613,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 71, "id": "abbe3ebf", "metadata": {}, "outputs": [], @@ -1632,7 +1623,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 72, "id": "651295e4", "metadata": {}, "outputs": [], @@ -1653,7 +1644,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 73, "id": "0a4ee482", "metadata": {}, "outputs": [], @@ -1673,7 +1664,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 74, "id": "956ed6d7", "metadata": { "tags": [] @@ -1685,7 +1676,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 75, "id": "a994eaa6", "metadata": { "tags": [] @@ -1697,7 +1688,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 76, "id": "4318028d", "metadata": { "tags": [] @@ -1709,7 +1700,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 77, "id": "05208c8b", "metadata": { "tags": [] @@ -1742,7 +1733,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 78, "id": "7eb85c5c", "metadata": {}, "outputs": [], @@ -1762,7 +1753,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 79, "id": "687a3e5a", "metadata": { "tags": [] @@ -1774,7 +1765,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 80, "id": "c49e9749", "metadata": { "tags": [] @@ -1786,7 +1777,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 81, "id": "8497dec4", "metadata": { "tags": [] @@ -1808,7 +1799,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 82, "id": "76be4d15", "metadata": { "tags": [] @@ -1847,7 +1838,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 83, "id": "0bcba5fe", "metadata": {}, "outputs": [], @@ -1867,7 +1858,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 84, "id": "4b6656e6", "metadata": { "tags": [] @@ -1879,7 +1870,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 85, "id": "36d9e92a", "metadata": { "tags": [] @@ -1891,7 +1882,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 86, "id": "1d944b42", "metadata": { "tags": [] @@ -1903,7 +1894,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 87, "id": "63ec57c9", "metadata": { "tags": [] @@ -1933,7 +1924,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 88, "id": "4e067bfb", "metadata": {}, "outputs": [], @@ -1953,7 +1944,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 89, "id": "2a7c1c21", "metadata": { "tags": [] @@ -1965,7 +1956,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 90, "id": "5df00229", "metadata": { "tags": [] @@ -1982,6 +1973,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -2001,7 +2008,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap07.ipynb b/chapters/chap07.ipynb index e026e3e..9d9c634 100644 --- a/chapters/chap07.ipynb +++ b/chapters/chap07.ipynb @@ -2,25 +2,17 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, { "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "f0c8eb18", "metadata": { "tags": [] @@ -74,7 +66,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "id": "6b8569b8-1576-45d2-99f6-c7a2c7e100c4", "metadata": {}, "outputs": [], @@ -95,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "id": "6cb5b573-601c-42f5-a940-f1a4d244f990", "metadata": {}, "outputs": [], @@ -117,7 +109,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "id": "7040a890-6619-4ad2-b0bf-b094a5a0e43d", "metadata": {}, "outputs": [], @@ -137,7 +129,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "id": "40fd553c-693c-4ffc-8e49-1d7de3c4d4a7", "metadata": {}, "outputs": [], @@ -158,7 +150,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "id": "8a34174b-5a77-482a-8480-14cfdff16339", "metadata": {}, "outputs": [], @@ -180,7 +172,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "id": "0909121d-5218-49ca-b03e-258206f00e40", "metadata": {}, "outputs": [], @@ -202,7 +194,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "id": "3c4d8138-ddf6-46fe-a940-a7042617ceb1", "metadata": {}, "outputs": [], @@ -212,7 +204,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "id": "5c463051-b737-49ab-a1d7-4be66fd8331f", "metadata": {}, "outputs": [], @@ -243,7 +235,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "id": "a7b7ac52-64a6-4dd9-98f5-b772a5e0f161", "metadata": { "tags": [] @@ -264,7 +256,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, "id": "1ad13ce7-99be-4412-8e0b-978fe6de25f2", "metadata": {}, "outputs": [], @@ -282,7 +274,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "id": "dc2054e6-d8e8-4a06-a1ea-5cfcf4ccf1e0", "metadata": {}, "outputs": [], @@ -307,7 +299,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "id": "eaea1520-0fb3-4ef3-be6e-9e1cdcccf39f", "metadata": {}, "outputs": [], @@ -326,7 +318,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 14, "id": "f602bfb6-7a93-4fb8-ade6-6784155a6f1a", "metadata": {}, "outputs": [], @@ -348,7 +340,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 15, "id": "cf3b8b7e-5fc7-4bb1-b628-09277bdc5a0d", "metadata": { "tags": [] @@ -385,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 16, "id": "6bf8a104", "metadata": {}, "outputs": [], @@ -404,7 +396,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 17, "id": "0fe7ae60", "metadata": {}, "outputs": [], @@ -423,7 +415,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 18, "id": "8a09bc24", "metadata": { "tags": [] @@ -437,7 +429,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 19, "id": "36a45674-7f41-4850-98f1-2548574ce958", "metadata": { "tags": [] @@ -466,7 +458,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 20, "id": "ba2ab90b", "metadata": { "tags": [] @@ -478,7 +470,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 21, "id": "88496dc4", "metadata": {}, "outputs": [], @@ -499,14 +491,16 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 22, "id": "4a0c46b9", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "%%expect NameError\n", "\n", - "y = y + 1" + "z = z + 1" ] }, { @@ -520,14 +514,14 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 23, "id": "2220d826", "metadata": {}, "outputs": [], "source": [ - "y = 0\n", - "y = y + 1\n", - "y" + "z = 0\n", + "z = z + 1\n", + "z" ] }, { @@ -535,7 +529,28 @@ "id": "374fb3d5", "metadata": {}, "source": [ - "Increasing the value of a variable is called an **increment**; decreasing the value is called a **decrement**." + "Increasing the value of a variable is called an **increment**; decreasing the value is called a **decrement**.\n", + "Because these operations are so common, Python provides **augmented assignment operators** that update a variable more concisely.\n", + "For example, the `+=` operator increments a variable by the given amount." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "d8e1ac5a", + "metadata": {}, + "outputs": [], + "source": [ + "z += 2\n", + "z" + ] + }, + { + "cell_type": "markdown", + "id": "3f4eedf1", + "metadata": {}, + "source": [ + "There are augmented assignment operators for the other arithmetic operators, including `-=` and `*=`." ] }, { @@ -550,7 +565,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 25, "id": "0afd8f88", "metadata": {}, "outputs": [], @@ -559,7 +574,7 @@ "\n", "for line in open('words.txt'):\n", " word = line.strip()\n", - " total = total + 1" + " total += 1" ] }, { @@ -574,7 +589,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 26, "id": "8686b2eb-c610-4d29-a942-2ef8f53e5e36", "metadata": {}, "outputs": [], @@ -594,7 +609,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 27, "id": "89a05280", "metadata": {}, "outputs": [], @@ -606,7 +621,7 @@ " word = line.strip()\n", " total = total + 1\n", " if has_e(word):\n", - " count = count + 1" + " count += 1" ] }, { @@ -619,7 +634,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 28, "id": "9d29b5e9", "metadata": {}, "outputs": [], @@ -637,7 +652,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 29, "id": "304dfd86", "metadata": {}, "outputs": [], @@ -666,7 +681,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 30, "id": "fe6431b7", "metadata": {}, "outputs": [], @@ -685,7 +700,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 31, "id": "85d3fba6", "metadata": {}, "outputs": [], @@ -707,7 +722,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 32, "id": "2d653847", "metadata": {}, "outputs": [], @@ -727,7 +742,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 33, "id": "a92a81bc", "metadata": {}, "outputs": [], @@ -745,7 +760,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 34, "id": "d15f83a4", "metadata": {}, "outputs": [], @@ -763,7 +778,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 35, "id": "e7958af4", "metadata": {}, "outputs": [], @@ -774,7 +789,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 36, "id": "020a57a7", "metadata": {}, "outputs": [], @@ -784,7 +799,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 37, "id": "0b979b20", "metadata": {}, "outputs": [], @@ -800,12 +815,12 @@ "## Search\n", "\n", "Based on this simpler version of `has_e`, let's write a more general function called `uses_any` that takes a second parameter that is a string of letters.\n", - "If returns `True` if the word uses any of the letters and `False` otherwise." + "It returns `True` if the word uses any of the letters and `False` otherwise." ] }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 38, "id": "bd29ff63", "metadata": {}, "outputs": [], @@ -827,7 +842,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 39, "id": "9369fb05", "metadata": {}, "outputs": [], @@ -845,7 +860,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 40, "id": "eb32713a", "metadata": {}, "outputs": [], @@ -858,12 +873,12 @@ "id": "b2acc611", "metadata": {}, "source": [ - "`uses_only` converts `word` and `letters` to lowercase, so it works with any combination of cases. " + "`uses_any` converts `word` and `letters` to lowercase, so it works with any combination of cases. " ] }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 41, "id": "7e65a9fb", "metadata": {}, "outputs": [], @@ -899,7 +914,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 42, "id": "3982e7d3", "metadata": {}, "outputs": [], @@ -936,7 +951,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 43, "id": "40ef00d3", "metadata": {}, "outputs": [], @@ -958,7 +973,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 44, "id": "f37cfd36", "metadata": {}, "outputs": [], @@ -981,7 +996,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 45, "id": "58c916cc", "metadata": {}, "outputs": [], @@ -1011,7 +1026,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 46, "id": "7a325745", "metadata": {}, "outputs": [], @@ -1061,7 +1076,7 @@ " A variable used to count something, usually initialized to zero and then incremented.\n", "\n", "**linear search:**\n", - "A computational pattern that searches through a sequence of elements and stops what it finds what it is looking for.\n", + "A computational pattern that searches through a sequence of elements and stops when it finds what it is looking for.\n", "\n", "**pass:**\n", "If a test runs and the result is as expected, the test passes.\n", @@ -1080,7 +1095,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 47, "id": "bc58db59", "metadata": { "tags": [] @@ -1388,7 +1403,7 @@ "\n", "* Each puzzle includes at least one \"pangram\" which uses every letter. These are worth 7 extra points!\n", "\n", - "Write a function called `score_word` that takes a word and a string of available lessons and returns its score.\n", + "Write a function called `score_word` that takes a word and a string of available letters and returns its score.\n", "You can assume that the word is acceptable.\n", "\n", "Again, here's an outline of the function with doctests." @@ -1457,6 +1472,7 @@ "source": [ "available = 'ACDLORT'\n", "required = 'R'\n", + "\n", "total = 0\n", "\n", "file_object = open('words.txt')\n", @@ -1597,20 +1613,46 @@ { "cell_type": "code", "execution_count": 71, - "id": "6980de57", + "id": "a3ea747d", "metadata": {}, "outputs": [], "source": [ - "# Solution goes here" + "# Here's what I got from ChatGPT 4o December 26, 2024\n", + "# It's correct, but it makes multiple calls to uses_any \n", + "\n", + "def uses_all(s1, s2):\n", + " \"\"\"Checks if all characters in s2 are in s1, allowing repeats.\"\"\"\n", + " for char in s2:\n", + " if not uses_any(s1, char):\n", + " return False\n", + " return True\n" ] }, { "cell_type": "code", - "execution_count": null, - "id": "102df097", + "execution_count": 72, + "id": "6980de57", "metadata": {}, "outputs": [], - "source": [] + "source": [ + "# Solution goes here" + ] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1630,7 +1672,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap08.ipynb b/chapters/chap08.ipynb index fa28c8b..0108312 100644 --- a/chapters/chap08.ipynb +++ b/chapters/chap08.ipynb @@ -2,25 +2,17 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, { "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "361d390a", "metadata": { "tags": [] @@ -75,7 +67,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 2, "id": "9b53c1fe", "metadata": {}, "outputs": [], @@ -95,7 +87,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 3, "id": "2cb1d58c", "metadata": {}, "outputs": [], @@ -114,7 +106,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 4, "id": "4ce1eb16", "metadata": {}, "outputs": [], @@ -134,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 5, "id": "11201ba9", "metadata": {}, "outputs": [], @@ -153,7 +145,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 6, "id": "fc4383d0", "metadata": {}, "outputs": [], @@ -171,7 +163,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 7, "id": "aec20975", "metadata": { "tags": [] @@ -193,7 +185,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 8, "id": "796ce317", "metadata": {}, "outputs": [], @@ -212,7 +204,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 9, "id": "3ccb4a64", "metadata": { "tags": [] @@ -234,7 +226,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 10, "id": "2cf99de6", "metadata": {}, "outputs": [], @@ -253,7 +245,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 11, "id": "3dedf6fa", "metadata": {}, "outputs": [], @@ -282,7 +274,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 12, "id": "386b9df2", "metadata": {}, "outputs": [], @@ -303,7 +295,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 13, "id": "05f9743d", "metadata": { "tags": [] @@ -318,7 +310,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 14, "id": "b09d8356", "metadata": { "tags": [] @@ -364,7 +356,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 15, "id": "00592313", "metadata": {}, "outputs": [], @@ -382,7 +374,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 16, "id": "01684797", "metadata": {}, "outputs": [], @@ -400,7 +392,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 17, "id": "c7551ded", "metadata": {}, "outputs": [], @@ -421,7 +413,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 18, "id": "b5c5ce3e", "metadata": { "tags": [] @@ -444,7 +436,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 19, "id": "69ccd380", "metadata": { "tags": [] @@ -473,7 +465,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 20, "id": "280d27a1", "metadata": {}, "outputs": [], @@ -493,7 +485,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 21, "id": "8fa4a4cf", "metadata": {}, "outputs": [], @@ -514,7 +506,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 22, "id": "b754d462", "metadata": {}, "outputs": [], @@ -536,7 +528,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 23, "id": "44374eb8", "metadata": {}, "outputs": [], @@ -552,7 +544,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 24, "id": "a46f7035", "metadata": {}, "outputs": [], @@ -572,7 +564,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 25, "id": "a691f9e2", "metadata": {}, "outputs": [], @@ -605,7 +597,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 26, "id": "fa6140a6", "metadata": {}, "outputs": [], @@ -641,7 +633,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 27, "id": "e3f1dc18", "metadata": { "tags": [] @@ -664,7 +656,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 28, "id": "bd2d5175", "metadata": {}, "outputs": [], @@ -686,7 +678,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 29, "id": "b9c9318c", "metadata": {}, "outputs": [], @@ -705,7 +697,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 30, "id": "a9417d4c", "metadata": {}, "outputs": [], @@ -727,7 +719,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 31, "id": "f2336825", "metadata": {}, "outputs": [], @@ -749,7 +741,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 32, "id": "d1b286ee", "metadata": {}, "outputs": [], @@ -771,7 +763,7 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 33, "id": "b4ecf365", "metadata": {}, "outputs": [], @@ -793,7 +785,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 34, "id": "a99dc11c", "metadata": {}, "outputs": [], @@ -814,7 +806,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 35, "id": "dfd6b264", "metadata": {}, "outputs": [], @@ -833,7 +825,7 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 36, "id": "4eda555c", "metadata": {}, "outputs": [], @@ -852,7 +844,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 37, "id": "5e1e8c74", "metadata": {}, "outputs": [], @@ -870,7 +862,7 @@ "id": "34c93df3", "metadata": {}, "source": [ - "The `endswidth` method checks whether a string ends with a given sequence of characters." + "The `endswith` method checks whether a string ends with a given sequence of characters." ] }, { @@ -888,7 +880,7 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 38, "id": "63ebaafb", "metadata": {}, "outputs": [], @@ -910,7 +902,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 39, "id": "9973e6e8", "metadata": {}, "outputs": [], @@ -934,7 +926,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 40, "id": "02e06ff1", "metadata": {}, "outputs": [], @@ -956,7 +948,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 41, "id": "1450e82c", "metadata": {}, "outputs": [], @@ -978,7 +970,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 42, "id": "a57b64c6", "metadata": { "tags": [] @@ -1010,7 +1002,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 43, "id": "a6069027", "metadata": {}, "outputs": [], @@ -1028,7 +1020,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 44, "id": "e3c19abe", "metadata": {}, "outputs": [], @@ -1047,7 +1039,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 45, "id": "db588abb", "metadata": {}, "outputs": [], @@ -1069,7 +1061,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 46, "id": "924524a6", "metadata": {}, "outputs": [], @@ -1082,12 +1074,12 @@ "id": "a8eab0f6", "metadata": {}, "source": [ - "It also provides a function called `group` that returns the part of the text that matched the pattern." + "It also provides a method called `group` that returns the part of the text that matched the pattern." ] }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 47, "id": "c72b860c", "metadata": {}, "outputs": [], @@ -1100,12 +1092,12 @@ "id": "b6962a7d", "metadata": {}, "source": [ - "And it provides a function called `span` that returns the index in the text where the pattern starts and ends." + "And it provides a method called `span` that returns the index in the text where the pattern starts and ends." ] }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 48, "id": "7c2f556c", "metadata": {}, "outputs": [], @@ -1123,7 +1115,7 @@ }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 49, "id": "d5242ef6", "metadata": {}, "outputs": [], @@ -1142,7 +1134,7 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 50, "id": "18c09b63", "metadata": {}, "outputs": [], @@ -1160,7 +1152,7 @@ }, { "cell_type": "code", - "execution_count": 108, + "execution_count": 51, "id": "fedb7d95", "metadata": {}, "outputs": [], @@ -1182,7 +1174,7 @@ }, { "cell_type": "code", - "execution_count": 109, + "execution_count": 52, "id": "d7cbe2c2", "metadata": {}, "outputs": [], @@ -1206,12 +1198,12 @@ }, { "cell_type": "code", - "execution_count": 147, + "execution_count": 53, "id": "96c64f83", "metadata": {}, "outputs": [], "source": [ - "pattern = r'Mina|Murray'\n", + "pattern = 'Mina|Murray'\n", "result = find_first(pattern)\n", "result.string" ] @@ -1227,7 +1219,7 @@ }, { "cell_type": "code", - "execution_count": 111, + "execution_count": 54, "id": "d0d2e926", "metadata": {}, "outputs": [], @@ -1251,7 +1243,7 @@ }, { "cell_type": "code", - "execution_count": 112, + "execution_count": 55, "id": "d7e8c5b4", "metadata": {}, "outputs": [], @@ -1269,7 +1261,7 @@ }, { "cell_type": "code", - "execution_count": 113, + "execution_count": 56, "id": "be63c5b0", "metadata": {}, "outputs": [], @@ -1288,7 +1280,7 @@ }, { "cell_type": "code", - "execution_count": 114, + "execution_count": 57, "id": "37595ac5", "metadata": {}, "outputs": [], @@ -1311,7 +1303,7 @@ }, { "cell_type": "code", - "execution_count": 115, + "execution_count": 58, "id": "18237bea", "metadata": {}, "outputs": [], @@ -1330,7 +1322,7 @@ }, { "cell_type": "code", - "execution_count": 116, + "execution_count": 59, "id": "ce65805f", "metadata": {}, "outputs": [], @@ -1352,7 +1344,7 @@ }, { "cell_type": "code", - "execution_count": 117, + "execution_count": 60, "id": "af770664", "metadata": {}, "outputs": [], @@ -1370,7 +1362,7 @@ }, { "cell_type": "code", - "execution_count": 118, + "execution_count": 61, "id": "ed67bde7", "metadata": {}, "outputs": [], @@ -1393,7 +1385,7 @@ }, { "cell_type": "code", - "execution_count": 119, + "execution_count": 62, "id": "52dd938c", "metadata": {}, "outputs": [], @@ -1412,7 +1404,7 @@ }, { "cell_type": "code", - "execution_count": 120, + "execution_count": 63, "id": "d2e309a2", "metadata": { "tags": [] @@ -1430,13 +1422,15 @@ }, { "cell_type": "code", - "execution_count": 121, + "execution_count": 64, "id": "3d8b2a9f", "metadata": { "tags": [] }, "outputs": [], "source": [ + "# Here's the pattern I used (which uses some features we haven't seen)\n", + "\n", "names = r'(?= 8 and is_interlocking(word):\n", + " first = word[0::2]\n", + " second = word[1::2]\n", + " print(word, first, second)" ] }, { @@ -1830,6 +1816,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1849,7 +1851,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap11.ipynb b/chapters/chap11.ipynb index 456393d..e10980c 100644 --- a/chapters/chap11.ipynb +++ b/chapters/chap11.ipynb @@ -2,25 +2,17 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, { "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "id": "295ac6d7", "metadata": { "tags": [] @@ -78,7 +70,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "id": "fb0bdca2", "metadata": {}, "outputs": [], @@ -97,7 +89,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "id": "5a6da881", "metadata": {}, "outputs": [], @@ -116,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "e2596ca7", "metadata": {}, "outputs": [], @@ -135,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "a0d350a6", "metadata": {}, "outputs": [], @@ -155,7 +147,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "c9100ee4", "metadata": {}, "outputs": [], @@ -175,7 +167,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "44bd3d83", "metadata": {}, "outputs": [], @@ -197,7 +189,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "92e55b2c", "metadata": {}, "outputs": [], @@ -215,7 +207,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "38ee5c2a", "metadata": {}, "outputs": [], @@ -233,7 +225,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "2e0e311a", "metadata": {}, "outputs": [], @@ -251,7 +243,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "id": "8bb7d715", "metadata": {}, "outputs": [], @@ -269,7 +261,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "id": "e653e00f", "metadata": {}, "outputs": [], @@ -287,7 +279,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "id": "8969188d", "metadata": {}, "outputs": [], @@ -305,7 +297,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "id": "65d7ebaa", "metadata": {}, "outputs": [], @@ -333,7 +325,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "id": "b4970fe0", "metadata": { "tags": [] @@ -354,7 +346,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "id": "772738cc", "metadata": { "tags": [] @@ -379,7 +371,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "id": "37e67042", "metadata": {}, "outputs": [], @@ -399,7 +391,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "id": "d809a490", "metadata": {}, "outputs": [], @@ -417,7 +409,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "id": "dfc42a8b", "metadata": {}, "outputs": [], @@ -436,14 +428,13 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "id": "2debf30c", "metadata": {}, "outputs": [], "source": [ "t = tuple('abc')\n", - "s = [1, 2, 3]\n", - "d = {t: s}\n", + "d = {'key': t}\n", "d" ] }, @@ -459,7 +450,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "id": "1e94ea37", "metadata": {}, "outputs": [], @@ -478,7 +469,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 23, "id": "99c96c7f", "metadata": {}, "outputs": [], @@ -497,7 +488,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 24, "id": "b67881ed", "metadata": {}, "outputs": [], @@ -516,7 +507,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 25, "id": "b4515e2b", "metadata": {}, "outputs": [], @@ -535,7 +526,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 26, "id": "8e5b4a14", "metadata": { "tags": [] @@ -557,7 +548,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 27, "id": "2389d6de", "metadata": {}, "outputs": [], @@ -577,7 +568,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 28, "id": "5512edec", "metadata": {}, "outputs": [], @@ -598,7 +589,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 29, "id": "651ab417", "metadata": {}, "outputs": [], @@ -622,7 +613,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 30, "id": "2c0b7d47", "metadata": {}, "outputs": [], @@ -658,7 +649,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 31, "id": "fff80eaa", "metadata": {}, "outputs": [], @@ -676,7 +667,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 32, "id": "4a0eb2a9", "metadata": {}, "outputs": [], @@ -687,7 +678,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 33, "id": "d74ba1b6", "metadata": {}, "outputs": [], @@ -705,7 +696,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 34, "id": "dad3b3bb", "metadata": {}, "outputs": [], @@ -725,7 +716,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 35, "id": "fbd90b0e", "metadata": {}, "outputs": [], @@ -743,7 +734,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 36, "id": "5a101efb", "metadata": {}, "outputs": [], @@ -768,7 +759,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 37, "id": "0a33e2d0", "metadata": {}, "outputs": [], @@ -788,7 +779,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 38, "id": "336a08ca", "metadata": {}, "outputs": [], @@ -807,7 +798,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 39, "id": "991810bc", "metadata": { "tags": [] @@ -830,7 +821,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 40, "id": "f25ebee1", "metadata": {}, "outputs": [], @@ -849,7 +840,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 41, "id": "7ad64412", "metadata": {}, "outputs": [], @@ -876,7 +867,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 42, "id": "b2863701", "metadata": {}, "outputs": [], @@ -886,7 +877,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 43, "id": "cc1afa29", "metadata": {}, "outputs": [], @@ -915,7 +906,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 44, "id": "ad3e6f81", "metadata": {}, "outputs": [], @@ -935,7 +926,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 45, "id": "9ce313ce", "metadata": {}, "outputs": [], @@ -953,7 +944,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 46, "id": "321d9c30", "metadata": {}, "outputs": [], @@ -973,7 +964,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 47, "id": "7eb73d5d", "metadata": {}, "outputs": [], @@ -998,7 +989,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 48, "id": "9529baa8", "metadata": {}, "outputs": [], @@ -1017,7 +1008,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 49, "id": "dbde77b8", "metadata": {}, "outputs": [], @@ -1036,7 +1027,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 50, "id": "dbb7d0b3", "metadata": {}, "outputs": [], @@ -1056,7 +1047,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 51, "id": "49e3fd8e", "metadata": {}, "outputs": [], @@ -1076,7 +1067,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 52, "id": "9e4f3e51", "metadata": {}, "outputs": [], @@ -1094,7 +1085,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 53, "id": "c1dcb46d", "metadata": {}, "outputs": [], @@ -1117,7 +1108,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 54, "id": "aed20c28", "metadata": {}, "outputs": [], @@ -1135,7 +1126,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 55, "id": "4d9e73b3", "metadata": {}, "outputs": [], @@ -1155,7 +1146,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 56, "id": "2077dfa9", "metadata": {}, "outputs": [], @@ -1180,7 +1171,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 57, "id": "b3d40516", "metadata": {}, "outputs": [], @@ -1202,7 +1193,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 58, "id": "8288c28f", "metadata": {}, "outputs": [], @@ -1221,7 +1212,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 59, "id": "bbbade35", "metadata": {}, "outputs": [], @@ -1242,7 +1233,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 60, "id": "a4c31795", "metadata": {}, "outputs": [], @@ -1261,7 +1252,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 61, "id": "f3d3619a", "metadata": {}, "outputs": [], @@ -1282,7 +1273,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 62, "id": "f078c8a6", "metadata": {}, "outputs": [], @@ -1301,7 +1292,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 63, "id": "54030d8f", "metadata": {}, "outputs": [], @@ -1335,7 +1326,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 64, "id": "ef158f81", "metadata": {}, "outputs": [], @@ -1356,7 +1347,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 65, "id": "d3607b8d", "metadata": {}, "outputs": [], @@ -1385,7 +1376,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 66, "id": "692d9cf8", "metadata": {}, "outputs": [], @@ -1416,7 +1407,7 @@ "Lists, dictionaries and tuples are **data structures**.\n", "In this chapter we are starting to see compound data structures, like lists of tuples, or dictionaries that contain tuples as keys and lists as values.\n", "Compound data structures are useful, but they are prone to errors caused when a data structure has the wrong type, size, or structure.\n", - "For example, if a function expects a list if integers and you give it a plain old integer\n", + "For example, if a function expects a list of integers and you give it a plain old integer\n", "(not in a list), it probably won't work.\n", "\n", "To help debug these kinds of errors, I wrote a module called `structshape` that provides a function, also called `structshape`, that takes any kind of data structure as an argument and returns a string that summarizes its structure.\n", @@ -1426,7 +1417,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 67, "id": "e9f03e91", "metadata": { "tags": [] @@ -1446,7 +1437,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 68, "id": "90ab624a", "metadata": {}, "outputs": [], @@ -1464,7 +1455,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 69, "id": "6794330f", "metadata": {}, "outputs": [], @@ -1483,7 +1474,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 70, "id": "54cd185b", "metadata": {}, "outputs": [], @@ -1503,7 +1494,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 71, "id": "04028afd", "metadata": {}, "outputs": [], @@ -1522,7 +1513,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 72, "id": "b5d45c88", "metadata": {}, "outputs": [], @@ -1542,7 +1533,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 73, "id": "15131907", "metadata": {}, "outputs": [], @@ -1596,7 +1587,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 74, "id": "c65d68d2", "metadata": { "tags": [] @@ -1642,7 +1633,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 75, "id": "4416fe4a", "metadata": {}, "outputs": [], @@ -1664,7 +1655,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 76, "id": "e6eda0e4", "metadata": { "tags": [] @@ -1684,7 +1675,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 77, "id": "4fae1acc", "metadata": { "tags": [] @@ -1716,7 +1707,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 78, "id": "855c7ed2", "metadata": {}, "outputs": [], @@ -1736,7 +1727,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 79, "id": "3c921f68", "metadata": {}, "outputs": [], @@ -1755,7 +1746,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 80, "id": "b029b0da", "metadata": {}, "outputs": [], @@ -1794,7 +1785,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 81, "id": "1cc07036", "metadata": { "tags": [] @@ -1814,7 +1805,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 82, "id": "96560a0e", "metadata": {}, "outputs": [], @@ -1824,7 +1815,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 83, "id": "c026c6d1", "metadata": { "tags": [] @@ -1836,7 +1827,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 84, "id": "5814999d", "metadata": { "tags": [] @@ -1858,7 +1849,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 85, "id": "9464d140", "metadata": { "tags": [] @@ -1897,7 +1888,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 86, "id": "4309d0b5", "metadata": { "tags": [] @@ -1910,7 +1901,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 87, "id": "52228828", "metadata": {}, "outputs": [], @@ -1930,7 +1921,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 88, "id": "3bf2aa0d", "metadata": { "tags": [] @@ -1952,7 +1943,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 89, "id": "e4fbf5d9", "metadata": { "tags": [] @@ -1964,7 +1955,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 90, "id": "817ec689", "metadata": { "tags": [] @@ -2019,7 +2010,7 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 91, "id": "941719c1", "metadata": { "tags": [] @@ -2031,7 +2022,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 92, "id": "d2ec641b", "metadata": { "tags": [] @@ -2053,7 +2044,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 93, "id": "7ae29f73", "metadata": { "tags": [] @@ -2066,7 +2057,7 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 94, "id": "013819a5", "metadata": {}, "outputs": [], @@ -2087,7 +2078,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 95, "id": "fbf9ede3", "metadata": { "tags": [] @@ -2111,7 +2102,7 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 96, "id": "55435050", "metadata": { "tags": [] @@ -2135,7 +2126,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 97, "id": "6a9320c2", "metadata": { "tags": [] @@ -2176,7 +2167,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 98, "id": "3d5a75f8", "metadata": { "tags": [] @@ -2198,7 +2189,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 99, "id": "a9816dde", "metadata": {}, "outputs": [], @@ -2208,7 +2199,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 100, "id": "753a23c1", "metadata": { "tags": [] @@ -2241,7 +2232,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 101, "id": "57649075", "metadata": {}, "outputs": [], @@ -2303,7 +2294,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 102, "id": "c19bf833", "metadata": {}, "outputs": [], @@ -2313,7 +2304,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 103, "id": "2d9764d6", "metadata": {}, "outputs": [], @@ -2323,7 +2314,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 104, "id": "5e4f5d8e", "metadata": {}, "outputs": [], @@ -2333,7 +2324,7 @@ }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 105, "id": "27d311dd", "metadata": {}, "outputs": [], @@ -2343,7 +2334,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 106, "id": "68c27c7e", "metadata": {}, "outputs": [], @@ -2352,12 +2343,20 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "id": "a34c2014", - "metadata": {}, - "outputs": [], - "source": [] + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -2377,7 +2376,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap12.ipynb b/chapters/chap12.ipynb index 071a104..f2d5d23 100644 --- a/chapters/chap12.ipynb +++ b/chapters/chap12.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 1, @@ -51,7 +43,7 @@ "source": [ "# Text Analysis and Generation\n", "\n", - "At this point we have covered Python's core data structures -- lists, dictionaries, and tuples -- and and some algorithms that use them.\n", + "At this point we have covered Python's core data structures -- lists, dictionaries, and tuples -- and some algorithms that use them.\n", "In this chapter, we'll use them to explore text analysis and Markov generation:\n", "\n", "* Text analysis is a way to describe the statistical relationships between the words in a document, like the probability that one word is followed by another, and\n", @@ -88,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "4cd1c980", "metadata": { "tags": [] @@ -111,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "52ebfe94", "metadata": { "tags": [] @@ -124,7 +116,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "49cfc352", "metadata": { "tags": [] @@ -150,7 +142,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "44e53ce6", "metadata": {}, "outputs": [], @@ -160,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "50d1fafa", "metadata": { "tags": [] @@ -181,7 +173,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "id": "16d24028", "metadata": {}, "outputs": [], @@ -209,7 +201,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 8, "id": "1668e6bd", "metadata": {}, "outputs": [], @@ -249,7 +241,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "id": "ed5f0a43", "metadata": {}, "outputs": [], @@ -269,7 +261,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "id": "a9df2aeb", "metadata": {}, "outputs": [], @@ -291,7 +283,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 11, "id": "b138b123", "metadata": {}, "outputs": [], @@ -313,7 +305,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "id": "fe65df44", "metadata": {}, "outputs": [], @@ -332,7 +324,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "id": "b47a87cf", "metadata": {}, "outputs": [], @@ -355,7 +347,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 14, "id": "348949be", "metadata": {}, "outputs": [], @@ -374,7 +366,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 15, "id": "06121901", "metadata": {}, "outputs": [], @@ -393,7 +385,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 16, "id": "881ed9f8", "metadata": {}, "outputs": [], @@ -411,7 +403,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 17, "id": "ab5d2fed", "metadata": {}, "outputs": [], @@ -429,7 +421,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 18, "id": "2fdfb936", "metadata": {}, "outputs": [], @@ -454,7 +446,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 19, "id": "3104d191", "metadata": {}, "outputs": [], @@ -482,7 +474,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 20, "id": "4fba7d1c", "metadata": {}, "outputs": [], @@ -510,7 +502,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 21, "id": "4be34c95", "metadata": {}, "outputs": [], @@ -528,12 +520,12 @@ "\n", "* `key=second_element` means the items will be sorted according to the frequencies of the words.\n", "\n", - "* `reverse=True` means they items will be sorted in reverse order, with the most frequent words first." + "* `reverse=True` means the items will be sorted in reverse order, with the most frequent words first." ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 22, "id": "8efe7c4c", "metadata": {}, "outputs": [], @@ -551,7 +543,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 23, "id": "79c17341", "metadata": {}, "outputs": [], @@ -582,7 +574,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 24, "id": "838bcb4f", "metadata": {}, "outputs": [], @@ -601,7 +593,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 25, "id": "90c45e7e", "metadata": {}, "outputs": [], @@ -625,7 +617,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 26, "id": "e106be95", "metadata": {}, "outputs": [], @@ -643,7 +635,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 27, "id": "8101a510", "metadata": {}, "outputs": [], @@ -663,7 +655,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 28, "id": "c046117b", "metadata": { "tags": [] @@ -705,7 +697,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 29, "id": "edd8ff1c", "metadata": { "tags": [] @@ -725,7 +717,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 30, "id": "67ef3e08", "metadata": {}, "outputs": [], @@ -738,12 +730,12 @@ "id": "22becbab", "metadata": {}, "source": [ - "The we'll store the words as keys in a dictionary so we can use the `in` operator to check quickly whether a word is valid." + "Then we'll store the words as keys in a dictionary so we can use the `in` operator to check quickly whether a word is valid." ] }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 31, "id": "471d58e9", "metadata": {}, "outputs": [], @@ -763,7 +755,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 32, "id": "4d4c3538", "metadata": {}, "outputs": [], @@ -786,7 +778,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 33, "id": "8b42e014", "metadata": {}, "outputs": [], @@ -804,7 +796,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 34, "id": "f48be152", "metadata": {}, "outputs": [], @@ -825,7 +817,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 35, "id": "5716f967", "metadata": {}, "outputs": [], @@ -846,7 +838,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 36, "id": "b37219f5", "metadata": {}, "outputs": [], @@ -888,7 +880,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 37, "id": "75b548a9", "metadata": {}, "outputs": [], @@ -898,7 +890,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 38, "id": "2bfa31ae", "metadata": { "tags": [] @@ -921,7 +913,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 39, "id": "6f5d5c1c", "metadata": {}, "outputs": [], @@ -940,7 +932,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 40, "id": "1445068b", "metadata": {}, "outputs": [], @@ -960,7 +952,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 41, "id": "4fc47ecd", "metadata": { "tags": [] @@ -982,7 +974,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 42, "id": "91ae9d4c", "metadata": {}, "outputs": [], @@ -1001,7 +993,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 43, "id": "8bf595c1", "metadata": {}, "outputs": [], @@ -1024,7 +1016,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 44, "id": "22953b65", "metadata": {}, "outputs": [], @@ -1042,7 +1034,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 45, "id": "1c7cdf4d", "metadata": {}, "outputs": [], @@ -1060,7 +1052,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 46, "id": "a7a3aa42", "metadata": {}, "outputs": [], @@ -1079,7 +1071,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 47, "id": "c4286fb3", "metadata": {}, "outputs": [], @@ -1119,7 +1111,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 48, "id": "d8ee02f6", "metadata": {}, "outputs": [], @@ -1139,7 +1131,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 49, "id": "bfdb1de1", "metadata": {}, "outputs": [], @@ -1166,7 +1158,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 50, "id": "2e73df79", "metadata": {}, "outputs": [], @@ -1184,7 +1176,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 51, "id": "495ad429", "metadata": {}, "outputs": [], @@ -1214,7 +1206,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 52, "id": "c1224061", "metadata": {}, "outputs": [], @@ -1236,7 +1228,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 53, "id": "4296485a", "metadata": {}, "outputs": [], @@ -1255,7 +1247,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 54, "id": "e03fd803", "metadata": { "tags": [] @@ -1267,7 +1259,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 55, "id": "f6ee1840", "metadata": {}, "outputs": [], @@ -1290,7 +1282,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 56, "id": "d6c65d79", "metadata": {}, "outputs": [], @@ -1320,7 +1312,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 57, "id": "3171d592", "metadata": {}, "outputs": [], @@ -1343,7 +1335,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 58, "id": "3321e6a4", "metadata": {}, "outputs": [], @@ -1361,7 +1353,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 59, "id": "e4e55c71", "metadata": {}, "outputs": [], @@ -1380,7 +1372,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 60, "id": "f25dcb5e", "metadata": {}, "outputs": [], @@ -1399,7 +1391,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 61, "id": "990354a0", "metadata": {}, "outputs": [], @@ -1421,7 +1413,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 62, "id": "b9371452", "metadata": {}, "outputs": [], @@ -1449,7 +1441,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 63, "id": "8c3f45c2", "metadata": {}, "outputs": [], @@ -1472,7 +1464,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 64, "id": "641990a3", "metadata": {}, "outputs": [], @@ -1495,7 +1487,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 65, "id": "9322a49a", "metadata": {}, "outputs": [], @@ -1517,7 +1509,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 66, "id": "45a60c52", "metadata": {}, "outputs": [], @@ -1541,7 +1533,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 67, "id": "3e86102c", "metadata": { "tags": [] @@ -1561,7 +1553,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 68, "id": "e49d52f7", "metadata": {}, "outputs": [], @@ -1598,7 +1590,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 69, "id": "15108884", "metadata": {}, "outputs": [], @@ -1610,7 +1602,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 70, "id": "747a41be", "metadata": { "tags": [] @@ -1634,7 +1626,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 71, "id": "5a4682dc", "metadata": {}, "outputs": [], @@ -1655,7 +1647,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 72, "id": "36ee0f76", "metadata": {}, "outputs": [], @@ -1790,7 +1782,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 73, "id": "05752b6d", "metadata": { "tags": [] @@ -1815,7 +1807,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 74, "id": "a4365ac0", "metadata": {}, "outputs": [], @@ -1835,7 +1827,7 @@ "metadata": {}, "source": [ "Dictionaries provide a method called `setdefault` that we can use to do the same thing more concisely.\n", - "Ask a virtual assistant how it works, or copy `add_word` into a virtual assistant and ask \"Can you rewrite this using `setdefault`?\"\n", + "Ask a virtual assistant how it works, or copy `add_bigram` into a virtual assistant and ask \"Can you rewrite this using `setdefault`?\"\n", "\n", "In this chapter we implemented Markov chain text analysis and generation.\n", "If you are curious, you can ask a virtual assistant for more information on the topic.\n", @@ -1858,7 +1850,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 75, "id": "f38a61ff", "metadata": {}, "outputs": [], @@ -1868,7 +1860,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 76, "id": "d047e546", "metadata": {}, "outputs": [], @@ -1888,7 +1880,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 77, "id": "6b8932ee", "metadata": { "tags": [] @@ -1916,7 +1908,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 78, "id": "44c3f0d8", "metadata": { "tags": [] @@ -1940,7 +1932,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 79, "id": "3fcf85f4", "metadata": {}, "outputs": [], @@ -1958,7 +1950,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 80, "id": "d9e554e3", "metadata": {}, "outputs": [], @@ -1983,7 +1975,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 81, "id": "8c2ee21c", "metadata": { "tags": [] @@ -2011,7 +2003,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 82, "id": "b13384e3", "metadata": { "tags": [] @@ -2031,7 +2023,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 83, "id": "62c2177f", "metadata": {}, "outputs": [], @@ -2065,7 +2057,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 84, "id": "64e11f26", "metadata": { "tags": [] @@ -2089,7 +2081,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 85, "id": "fe2d93fa", "metadata": {}, "outputs": [], @@ -2104,7 +2096,7 @@ "id": "83ed6c7e", "metadata": {}, "source": [ - "Now write a loop that generates `50` more words following these steps:\n", + "Now write a loop that generates 50 more words following these steps:\n", "\n", "1. In `successor_map`, look up the list of words that can follow `bigram`.\n", "\n", @@ -2117,7 +2109,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 86, "id": "22210a5c", "metadata": {}, "outputs": [], @@ -2142,6 +2134,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -2161,7 +2169,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap13.ipynb b/chapters/chap13.ipynb index 9e76060..ba90420 100644 --- a/chapters/chap13.ipynb +++ b/chapters/chap13.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 1, @@ -351,7 +343,7 @@ "id": "f652aaac", "metadata": {}, "source": [ - "To write this data to a file, you can use the `write` method, which we saw in [Chapter 8](section_writing_files).\n", + "To write this data to a file, you can use the `write` method, which we saw in Chapter 8.\n", "The argument of `write` has to be a string, so if we want to put other values in a file, we have to convert them to strings.\n", "The easiest way to do that is with the built-in function `str`.\n", "\n", @@ -809,7 +801,7 @@ "id": "e9b252a7", "metadata": {}, "source": [ - "If you make another assignment to an existing key, `dbm` replaces the old value." + "If you make another assignment to an existing key, `shelve` replaces the old value." ] }, { @@ -828,7 +820,7 @@ "id": "003eacbc", "metadata": {}, "source": [ - "Some dictionary methods, like `keys`, `values` and `items`, also work with database objects." + "Some dictionary methods, like `keys`, `values` and `items`, also work with shelf objects." ] }, { @@ -1268,7 +1260,7 @@ "id": "a8e480f0", "metadata": {}, "source": [ - "The `HASH` object provides an `update` function that takes the contents of the file as an argument." + "The `HASH` object provides an `update` method that takes the contents of the file as an argument." ] }, { @@ -1406,53 +1398,7 @@ "id": "897c66bf", "metadata": {}, "source": [ - "The order of the results depends on details of the operating system.\n", - "\n", - "Here is a more general version of `walk` that takes as a second parameter a function object.\n", - "Instead of printing the path of the files it discovers, it calls this function and passes the path as a parameter." - ] - }, - { - "cell_type": "code", - "execution_count": 65, - "id": "49e52d49", - "metadata": {}, - "outputs": [], - "source": [ - "def walk(dirname, visit_func):\n", - " for name in os.listdir(dirname):\n", - " path = os.path.join(dirname, name)\n", - "\n", - " if os.path.isfile(path):\n", - " visit_func(path)\n", - " else:\n", - " walk(path, visit_func)" - ] - }, - { - "cell_type": "markdown", - "id": "7db28cf6", - "metadata": {}, - "source": [ - "Here's an example where we pass `print` as an argument, so when `walk` calls `visit_func`, it prints the paths of the files it discovers." - ] - }, - { - "cell_type": "code", - "execution_count": 66, - "id": "6a86db4e", - "metadata": {}, - "outputs": [], - "source": [ - "walk('photos', print)" - ] - }, - { - "cell_type": "markdown", - "id": "1c6faa6d", - "metadata": {}, - "source": [ - "The parameter is called `visit_func` because it suggests that as we \"walk\" around the directory, we \"visit\" each file." + "The order of the results depends on details of the operating system." ] }, { @@ -1462,14 +1408,15 @@ "source": [ "## Debugging\n", "\n", - "When you are reading and writing files, you might run into problems with\n", - "whitespace. These errors can be hard to debug because spaces, tabs and\n", - "newlines are normally invisible:" + "When you are reading and writing files, you might run into problems with whitespace.\n", + "These errors can be hard to debug because whitespace characters are normally invisible.\n", + "For example, here's a string that contains spaces, a tab represented by the sequence `\\t`, and a newline represented by the sequence `\\n`.\n", + "When we print it, we don't see the whitespace characters." ] }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 65, "id": "15d7425a", "metadata": {}, "outputs": [], @@ -1483,14 +1430,13 @@ "id": "49bbebe6", "metadata": {}, "source": [ - "The built-in function `repr` can help. It takes any object as an\n", - "argument and returns a string representation of the object. For strings,\n", - "it represents whitespace characters with backslash sequences:" + "The built-in function `repr` can help. It takes any object as an argument and returns a string representation of the object.\n", + "For strings, it represents whitespace characters with backslash sequences." ] }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 66, "id": "61feff85", "metadata": {}, "outputs": [], @@ -1561,7 +1507,7 @@ "A database whose contents are organized like a dictionary with keys that correspond to values.\n", "\n", "**binary mode:**\n", - "A way of writing a file so the contents are interpreted as sequence of bytes rather than a sequence of characters.\n", + "A way of opening a file so the contents are interpreted as sequence of bytes rather than a sequence of characters.\n", "\n", "**hash function:**\n", "A function that takes and object and computes an integer, which is sometimes called a digest.\n", @@ -1580,7 +1526,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 67, "id": "bd885ba1", "metadata": { "tags": [] @@ -1641,26 +1587,31 @@ { "cell_type": "markdown", "id": "85844afb", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "Here's an outline of the function to get you started." ] }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 68, "id": "1e598e70", "metadata": {}, "outputs": [], "source": [ - "# Solution goes here" + "def replace_all(old, new, source_path, dest_path):\n", + " # read the contents of the source file\n", + " reader = open(source_path)\n", + "\n", + " # replace the old string with the new\n", + " \n", + " # write the result into the destination file\n", + " " ] }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 69, "id": "d3774d1a", "metadata": {}, "outputs": [], @@ -1678,7 +1629,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 70, "id": "3b80dfd8", "metadata": { "tags": [] @@ -1691,7 +1642,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 71, "id": "4b67579f", "metadata": { "tags": [] @@ -1706,7 +1657,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 72, "id": "1d990225", "metadata": { "tags": [] @@ -1731,7 +1682,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 73, "id": "1c2fff95", "metadata": {}, "outputs": [], @@ -1751,7 +1702,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 74, "id": "8008cde6", "metadata": { "tags": [] @@ -1763,7 +1714,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 75, "id": "a6b5e51a", "metadata": { "tags": [] @@ -1789,7 +1740,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 76, "id": "ffefe13e", "metadata": { "tags": [] @@ -1801,7 +1752,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 77, "id": "7eb54fbc", "metadata": { "tags": [] @@ -1815,7 +1766,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 78, "id": "ac784df7", "metadata": { "tags": [] @@ -1861,7 +1812,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 79, "id": "03b6acf9", "metadata": {}, "outputs": [], @@ -1881,7 +1832,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 80, "id": "21c33092", "metadata": { "tags": [] @@ -1906,7 +1857,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 81, "id": "31c056a9", "metadata": {}, "outputs": [], @@ -1919,12 +1870,12 @@ "id": "08223a21", "metadata": {}, "source": [ - "3. Write a function called `process_path` that takes a path, uses `is_image` to check whether it's an image file, and uses `add_path` to add it to the shelf." + "3. Write a version of `walk` called `walk_images` that takes a directory and walks through the files in the directory and its subdirectories. For each file, it should use `is_image` to check whether it's an image file and `add_path` to add it to the shelf." ] }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 87, "id": "e54d6993", "metadata": {}, "outputs": [], @@ -1942,7 +1893,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 88, "id": "c31ba5b6", "metadata": { "tags": [] @@ -1950,7 +1901,7 @@ "outputs": [], "source": [ "db = shelve.open('photos/digests', 'n')\n", - "walk('photos', process_path)\n", + "walk_images('photos')\n", "\n", "for digest, paths in db.items():\n", " if len(paths) > 1:\n", @@ -1968,7 +1919,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 89, "id": "d7c7e679", "metadata": {}, "outputs": [], @@ -1983,6 +1934,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -2002,7 +1969,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap14.ipynb b/chapters/chap14.ipynb index 603c237..f0f9998 100644 --- a/chapters/chap14.ipynb +++ b/chapters/chap14.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 1, @@ -301,7 +293,7 @@ "id": "bcbea13a", "metadata": {}, "source": [ - "We'll use this f-string to write a function that displays the value of time objects.\n", + "We'll use this f-string to write a function that displays the value of a `Time`object.\n", "You can pass an object as an argument in the usual way.\n", "For example, the following function takes a `Time` object as an argument. " ] @@ -367,7 +359,7 @@ "metadata": {}, "source": [ "It might be surprising that the parameters have the same names as the attributes, but that's a common way to write a function like this.\n", - "Here's how we use `make_time` to create a `Time` object.`" + "Here's how we use `make_time` to create a `Time` object." ] }, { @@ -725,12 +717,11 @@ "source": [ "`add_time` is a **pure function** because it does not modify any of the objects passed to it as arguments and its only effect is to return a value.\n", "\n", - "Anything that can be done with modifiers can also be done with pure functions.\n", + "Anything that can be done with impure functions can also be done with pure functions.\n", "In fact, some programming languages only allow pure functions.\n", - "Programs that use pure functions might be less error-prone than programs that use modifiers.\n", - "But modifiers are sometimes convenient and can be more efficient.\n", + "Programs that use pure functions might be less error-prone, but impure functions are sometimes convenient and can be more efficient.\n", "\n", - "In general, I suggest you write pure functions whenever it is reasonable and resort to modifiers only if there is a compelling advantage.\n", + "In general, I suggest you write pure functions whenever it is reasonable and resort to impure functions only if there is a compelling advantage.\n", "This approach might be called a **functional programming style**." ] }, @@ -767,7 +758,7 @@ "The result is not a valid time.\n", "The problem is that `increment_time` does not deal with cases where the number of seconds or minutes adds up to more than `60`.\n", "\n", - "Here's an improved version that checks whether `second` exceeds `60` -- if so, it increments `minute` -- then checks whether `minute` exceeds `60` -- if so, it increments `hour`." + "Here's an improved version that checks whether `second` exceeds or equals `60` -- if so, it increments `minute` -- then checks whether `minute` exceeds or equals `60` -- if so, it increments `hour`." ] }, { @@ -839,7 +830,7 @@ "source": [ "The result is not a valid time.\n", "So let's try a different approach, using the `divmod` function.\n", - "We'll make a copy of `start` and modify it by incrementing the `minutes` field." + "We'll make a copy of `start` and modify it by incrementing the `minute` attribute." ] }, { @@ -916,7 +907,7 @@ " \n", " carry, time.second = divmod(time.second, 60)\n", " carry, time.minute = divmod(time.minute + carry, 60)\n", - " carry, time.hour = divmod(time.hour + carry, 60)" + " carry, time.hour = divmod(time.hour + carry, 24)" ] }, { @@ -990,7 +981,7 @@ "metadata": {}, "source": [ "The result is the number of seconds since the beginning of the day.\n", - "For example, `01:01:01` is `1` hour, `1` minute and `1` second from the beginning of the day, with is the sum of `3600` seconds, `60` seconds, and `1` second." + "For example, `01:01:01` is `1` hour, `1` minute and `1` second from the beginning of the day, which is the sum of `3600` seconds, `60` seconds, and `1` second." ] }, { @@ -1303,7 +1294,7 @@ "\n", "* \"What is the difference between a variable and an attribute?\"\n", "\n", - "* \"What are the pros and cons of pure functions compared to modifiers?\"\n", + "* \"What are the pros and cons of pure functions compared to impure functions?\"\n", "\n", "Because we are just getting started with object oriented programming, the code in this chapter is not idiomatic -- it is not the kind of code experienced programmers write.\n", "If you ask a virtual assistant for help with the exercises, you will probably see features we have not covered yet.\n", @@ -1316,14 +1307,6 @@ "Also, in this chapter we saw one example of a format specifier. For more information, ask \"What format specifiers can be used in a Python f-string?\"" ] }, - { - "cell_type": "markdown", - "id": "c85eab62", - "metadata": {}, - "source": [ - "## Exercises\n" - ] - }, { "cell_type": "markdown", "id": "bcdab7d6", @@ -1714,6 +1697,22 @@ "id": "d6f1cc2f", "metadata": {}, "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1733,7 +1732,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap15.ipynb b/chapters/chap15.ipynb index 1d7a9e3..f7dfa60 100644 --- a/chapters/chap15.ipynb +++ b/chapters/chap15.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 1, @@ -122,7 +114,7 @@ "id": "8da4079c", "metadata": {}, "source": [ - "To call this function, you have to pass a `Time` object as an argument.\n", + "To call this method, you have to pass a `Time` object as an argument.\n", "Here's the function we'll use to make a `Time` object." ] }, @@ -363,7 +355,7 @@ "id": "d2f4fd5a", "metadata": {}, "source": [ - "The result is a new object that represents `9:40`." + "The result is a new object that represents 9:40." ] }, { @@ -381,7 +373,7 @@ "id": "e6a18c76", "metadata": {}, "source": [ - "Now that we have `Time.from_seconds`, we can use it to write `add_time` as a method.\n", + "Now that we have `Time.int_to_time`, we can use it to write `add_time` as a method.\n", "Here's the function from the previous chapter." ] }, @@ -417,7 +409,7 @@ "\n", " def add_time(self, hours, minutes, seconds):\n", " duration = make_time(hours, minutes, seconds)\n", - " seconds = time_to_int(self) + time_to_int(duration)\n", + " seconds = Time.time_to_int(self) + Time.time_to_int(duration)\n", " return Time.int_to_time(seconds)" ] }, @@ -439,7 +431,7 @@ "outputs": [], "source": [ "end = start.add_time(1, 32, 0)\n", - "print_time(end)" + "end.print_time()" ] }, { @@ -612,7 +604,7 @@ "id": "e01e9673", "metadata": {}, "source": [ - "## The __init__ method\n", + "## The init method\n", "\n", "The most special of the special methods is `__init__`, so-called because it initializes the attributes of a new object.\n", "An `__init__` method for the `Time` class might look like this:" @@ -844,7 +836,7 @@ "\n", " def is_after(self, other):\n", " assert self.is_valid(), 'self is not a valid Time'\n", - " assert other.is_valid(), 'self is not a valid Time'\n", + " assert other.is_valid(), 'other is not a valid Time'\n", " return self.time_to_int() > other.time_to_int()" ] }, @@ -898,7 +890,7 @@ "## Glossary\n", "\n", "**object-oriented language:**\n", - "A language that provides features to support object-oriented programming, notably user-defined types and inheritance.\n", + "A language that provides features to support object-oriented programming, notably user-defined types.\n", "\n", "**method:**\n", "A function that is defined inside a class definition and is invoked on instances of that class.\n", @@ -932,7 +924,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 36, "id": "3115ea33", "metadata": { "tags": [] @@ -968,7 +960,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 37, "id": "133d7679", "metadata": {}, "outputs": [], @@ -991,16 +983,16 @@ "\n", "2. Write an `__init__` method that takes `year`, `month`, and `day` as parameters and assigns the parameters to attributes. Create an object that represents June 22, 1933.\n", "\n", - "2. Write `__str__` method that uses a format string to format the attributes and returns the result. If you test it with the `Date` you created, the result should be `1933-06-22`.\n", + "3. Write `__str__` method that uses an f-string to format the attributes and returns the result. If you test it with the `Date` you created, the result should be `1933-06-22`.\n", "\n", - "3. Write a method called `is_after` that takes two `Date` objects and returns `True` if the first comes after the second. Create a second object that represents September 17, 1933, and check whether it comes after the first object.\n", + "4. Write a method called `is_after` that takes two `Date` objects and returns `True` if the first comes after the second. Create a second object that represents September 17, 1933, and check whether it comes after the first object.\n", "\n", "Hint: You might find it useful write a method called `to_tuple` that returns a tuple that contains the attributes of a `Date` object in year-month-day order." ] }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 38, "id": "3c9f3777-4869-481e-9f4e-4223d6028913", "metadata": {}, "outputs": [], @@ -1020,7 +1012,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 39, "id": "fd4b2521-aa71-45da-97eb-ce62ce2714ad", "metadata": { "tags": [] @@ -1033,7 +1025,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 40, "id": "ee3f1294-cad1-406b-a574-045ad2b84294", "metadata": { "tags": [] @@ -1046,7 +1038,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 41, "id": "ac093f7b-83cf-4488-8842-5c71bcfa35ec", "metadata": { "tags": [] @@ -1058,7 +1050,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 42, "id": "7e7cb5e1-631f-4b1e-874f-eb16d4792625", "metadata": { "tags": [] @@ -1075,6 +1067,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1094,7 +1102,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap16.ipynb b/chapters/chap16.ipynb index d1f0ddb..eb84e1c 100644 --- a/chapters/chap16.ipynb +++ b/chapters/chap16.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 1, @@ -242,7 +234,7 @@ "id": "a7a635ee", "metadata": {}, "source": [ - "In the same way that the built in function `sort` modifies a list, and the `sorted` function creates a new list, now we have a `translate` method that modifies a `Point` and a `translated` method that creates a new one.\n", + "In the same way that the `sort` method modifies a list and the `sorted` function creates a new list, now we have a `translate` method that modifies a `Point` and a `translated` method that creates a new one.\n", "\n", "Here's an example:" ] @@ -568,8 +560,8 @@ "id": "c008d3dd", "metadata": {}, "source": [ - "It's not possible to override the `is` operator -- it always checks whether the objects are **identical**.\n", - "But for programmer-defined types, you can override the `==` operator so it checks whether the objects are **equivalent**.\n", + "It's not possible to override the `is` operator -- it always checks whether the objects are identical.\n", + "But for programmer-defined types, you can override the `==` operator so it checks whether the objects are equivalent.\n", "And you can define what equivalent means." ] }, @@ -1194,7 +1186,7 @@ "\n", "To avoid sharing objects, you can use deep copy, as we did in this chapter.\n", "\n", - "To avoid modifying objects, consider replacing modifiers like `translate` with pure functions like `translated`.\n", + "To avoid modifying objects, consider replacing impure functions like `translate` with pure functions like `translated`.\n", "For example, here's a version of `translated` that creates a new `Point` and never modifies its attributes." ] }, @@ -1220,7 +1212,7 @@ "They are beyond the scope of this book, but if you are curious, ask a virtual assistant, \"How do I make a Python object immutable?\"\n", "\n", "Creating a new object takes more time than modifying an existing one, but the difference seldom matters in practice.\n", - "Programs that avoid shared objects and modifiers are often easier to develop, test, and debug -- and the best kind of debugging is the kind you don't have to do." + "Programs that avoid shared objects and impure functions are often easier to develop, test, and debug -- and the best kind of debugging is the kind you don't have to do." ] }, { @@ -1230,12 +1222,6 @@ "source": [ "## Glossary\n", "\n", - "**identical:**\n", - "Being the same object (which implies equivalence).\n", - "\n", - "**equivalent:**\n", - "Having the same value.\n", - "\n", "**shallow copy:**\n", "A copy operation that does not copy nested objects.\n", "\n", @@ -1293,9 +1279,7 @@ { "cell_type": "markdown", "id": "2e488e0f", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "You can use the following outline to get started." ] @@ -1304,9 +1288,7 @@ "cell_type": "code", "execution_count": 49, "id": "92c07380", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "%%add_method_to Line\n", @@ -1324,22 +1306,13 @@ }, "outputs": [], "source": [ - "%%add_method_to Line\n", - "\n", - "def __eq__(self, other):\n", - " if (self.p1 == other.p1) and (self.p2 == other.p2):\n", - " return True\n", - " if (self.p1 == other.p2) and (self.p2 == other.p1):\n", - " return True\n", - " return False" + "# Solution goes here" ] }, { "cell_type": "markdown", "id": "3a44e45a", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "You can use these examples to test your code." ] @@ -1348,9 +1321,7 @@ "cell_type": "code", "execution_count": 51, "id": "aa086dd1", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "start1 = Point(0, 0)\n", @@ -1361,9 +1332,7 @@ { "cell_type": "markdown", "id": "e825f049", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "This example should be `True` because the `Line` objects refer to `Point` objects that are equivalent, in the same order." ] @@ -1372,9 +1341,7 @@ "cell_type": "code", "execution_count": 52, "id": "857cba26", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "line_a = Line(start1, end)\n", @@ -1396,9 +1363,7 @@ "cell_type": "code", "execution_count": 53, "id": "b45def0a", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "line_c = Line(end, start1)\n", @@ -1408,9 +1373,7 @@ { "cell_type": "markdown", "id": "8c9c787b", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "Equivalence should always be transitive -- that is, if `line_a` and `line_b` are equivalent, and `line_a` and `line_c` are equivalent, then `line_b` and `line_c` should also be equivalent." ] @@ -1419,9 +1382,7 @@ "cell_type": "code", "execution_count": 54, "id": "9784300c", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "line_b == line_c # should be True" @@ -1430,9 +1391,7 @@ { "cell_type": "markdown", "id": "d4f385fa", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "This example should be `False` because the `Line` objects refer to `Point` objects that are not equivalent." ] @@ -1441,9 +1400,7 @@ "cell_type": "code", "execution_count": 55, "id": "5435c8e4", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "line_d = Line(start1, start2)\n", @@ -1463,9 +1420,7 @@ { "cell_type": "markdown", "id": "b8c52d19", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "You can use the following outline to get started." ] @@ -1474,9 +1429,7 @@ "cell_type": "code", "execution_count": 56, "id": "f377afbb", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "%%add_method_to Line\n", @@ -1494,20 +1447,13 @@ }, "outputs": [], "source": [ - "%%add_method_to Line\n", - "\n", - " def midpoint(self):\n", - " mid_x = (self.p1.x + self.p2.x) / 2\n", - " mid_y = (self.p1.y + self.p2.y) / 2\n", - " return Point(mid_x, mid_y)" + "# Solution goes here" ] }, { "cell_type": "markdown", "id": "4df69a9f", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "You can use the following examples to test your code and draw the result." ] @@ -1516,9 +1462,7 @@ "cell_type": "code", "execution_count": 58, "id": "0d603aa3", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "start = Point(0, 0)\n", @@ -1532,9 +1476,7 @@ "cell_type": "code", "execution_count": 59, "id": "647d0982", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "mid1 = line1.midpoint()\n", @@ -1545,9 +1487,7 @@ "cell_type": "code", "execution_count": 60, "id": "e351bea3", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "mid2 = line2.midpoint()\n", @@ -1558,9 +1498,7 @@ "cell_type": "code", "execution_count": 61, "id": "5ad5a076", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "line3 = Line(mid1, mid2)" @@ -1570,9 +1508,7 @@ "cell_type": "code", "execution_count": 62, "id": "8effaff0", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "make_turtle()\n", @@ -1594,9 +1530,7 @@ { "cell_type": "markdown", "id": "c586a3ed", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "You can use the following outline to get started." ] @@ -1605,9 +1539,7 @@ "cell_type": "code", "execution_count": 63, "id": "d94a6350", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "%%add_method_to Rectangle\n", @@ -1625,20 +1557,13 @@ }, "outputs": [], "source": [ - "%%add_method_to Rectangle\n", - "\n", - " def midpoint(self):\n", - " mid_x = self.corner.x + self.width / 2\n", - " mid_y = self.corner.y + self.height / 2\n", - " return Point(mid_x, mid_y)" + "# Solution goes here" ] }, { "cell_type": "markdown", "id": "d186c84b", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "You can use the following example to test your code." ] @@ -1647,9 +1572,7 @@ "cell_type": "code", "execution_count": 65, "id": "4aec759c", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "corner = Point(30, 20)\n", @@ -1660,9 +1583,7 @@ "cell_type": "code", "execution_count": 66, "id": "7ec3339d", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "mid = rectangle.midpoint()\n", @@ -1673,9 +1594,7 @@ "cell_type": "code", "execution_count": 67, "id": "326dbf24", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "diagonal = Line(corner, mid)" @@ -1685,9 +1604,7 @@ "cell_type": "code", "execution_count": 68, "id": "4da710d4", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "make_turtle()\n", @@ -1715,9 +1632,7 @@ { "cell_type": "markdown", "id": "29e994c6", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "You can use this outline to get started." ] @@ -1726,9 +1641,7 @@ "cell_type": "code", "execution_count": 69, "id": "30cc0726", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "%%add_method_to Rectangle\n", @@ -1746,24 +1659,13 @@ }, "outputs": [], "source": [ - "%%add_method_to Rectangle\n", - "\n", - " def make_cross(self):\n", - " midpoints = []\n", - "\n", - " for line in self.make_lines():\n", - " midpoints.append(line.midpoint())\n", - "\n", - " p1, p2, p3, p4 = midpoints\n", - " return Line(p1, p3), Line(p2, p4)" + "# Solution goes here" ] }, { "cell_type": "markdown", "id": "970fcbca", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "You can use the following example to test your code." ] @@ -1772,9 +1674,7 @@ "cell_type": "code", "execution_count": 71, "id": "2afd718c", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "corner = Point(30, 20)\n", @@ -1785,9 +1685,7 @@ "cell_type": "code", "execution_count": 72, "id": "b7bdb467", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "lines = rectangle.make_cross()" @@ -1797,9 +1695,7 @@ "cell_type": "code", "execution_count": 73, "id": "9d09b2c3", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "make_turtle()\n", @@ -1823,9 +1719,7 @@ { "cell_type": "markdown", "id": "cb1b24a3", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "You can use the following function, which is a version of the `circle` function we wrote in Chapter 4." ] @@ -1834,9 +1728,7 @@ "cell_type": "code", "execution_count": 74, "id": "b3d2328f", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "from jupyturtle import make_turtle, forward, left, right\n", @@ -1866,9 +1758,7 @@ { "cell_type": "markdown", "id": "b4325143", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "You can use the following example to test your code.\n", "We'll start with a square `Rectangle` with width and height `100`." @@ -1878,9 +1768,7 @@ "cell_type": "code", "execution_count": 76, "id": "49074ed5", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "corner = Point(20, 20)\n", @@ -1890,9 +1778,7 @@ { "cell_type": "markdown", "id": "2cdecfa9", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "The following code should create a `Circle` that fits inside the square." ] @@ -1901,9 +1787,7 @@ "cell_type": "code", "execution_count": 77, "id": "d65a9163", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "center = rectangle.midpoint()\n", @@ -1916,9 +1800,7 @@ { "cell_type": "markdown", "id": "37e94d98", - "metadata": { - "tags": [] - }, + "metadata": {}, "source": [ "If everything worked correctly, the following code should draw the circle inside the square (touching on all four sides)." ] @@ -1927,9 +1809,7 @@ "cell_type": "code", "execution_count": 78, "id": "e3b23b4d", - "metadata": { - "tags": [] - }, + "metadata": {}, "outputs": [], "source": [ "make_turtle(delay=0.01)\n", @@ -1939,12 +1819,20 @@ ] }, { - "cell_type": "code", - "execution_count": null, - "id": "48abaaae", - "metadata": {}, - "outputs": [], - "source": [] + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -1964,7 +1852,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap17.ipynb b/chapters/chap17.ipynb index f62b69f..c26b8b7 100644 --- a/chapters/chap17.ipynb +++ b/chapters/chap17.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 1, @@ -141,7 +133,7 @@ "id": "d63f798a", "metadata": {}, "source": [ - "The first element of `rank_names` is `None` because there is no card with rank zero. By including `None` as a place-keeper, we get a list with the nice property that the index 2 maps to the string `'2'`, and so on.\n", + "The first element of `rank_names` is `None` because there is no card with rank zero. By including `None` as a place-keeper, we get a list with the nice property that the index `2` maps to the string `'2'`, and so on.\n", "\n", "Class variables are associated with the class, rather than an instance of the class, so we can access them like this." ] @@ -436,7 +428,7 @@ "metadata": {}, "source": [ "They don't, so it returns `False`.\n", - "We can change this behavior by defining a special method called `__eq__`." + "We can change this behavior by defining the special method `__eq__`." ] }, { @@ -516,7 +508,7 @@ "metadata": {}, "source": [ "If we use the `!=` operator, Python invokes a special method called `__ne__`, if it exists.\n", - "Otherwise it invokes`__eq__` and inverts the result -- so if `__eq__` returns `True`, the result of the `!=` operator is `False`. " + "Otherwise it invokes`__eq__` and inverts the result -- so if `__eq__` returns `True`, the result of the `!=` operator is `False`." ] }, { @@ -616,7 +608,7 @@ "Tuple comparison compares the first elements from each tuple, which represent the suits.\n", "If they are the same, it compares the second elements, which represent the ranks.\n", "\n", - "Now if we use the `<` operator, it invokes the `__lt__` operator." + "Now if we use the `<` operator, it invokes the `__lt__` method." ] }, { @@ -1465,8 +1457,7 @@ "outputs": [], "source": [ "def find_defining_class(obj, method_name):\n", - " \"\"\"\n", - " \"\"\"\n", + " \"\"\"Find the class where the given method is defined.\"\"\"\n", " for typ in type(obj).mro():\n", " if method_name in vars(typ):\n", " return typ\n", @@ -1545,7 +1536,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 64, "id": "e281457a", "metadata": { "tags": [] @@ -1597,7 +1588,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 65, "id": "47d9ce31", "metadata": {}, "outputs": [], @@ -1619,7 +1610,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 66, "id": "7bb54059", "metadata": {}, "outputs": [], @@ -1653,7 +1644,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 67, "id": "72a410d7", "metadata": { "tags": [] @@ -1668,7 +1659,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 68, "id": "b09cceb1", "metadata": { "tags": [] @@ -1690,7 +1681,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 69, "id": "e185c2f7", "metadata": { "tags": [] @@ -1714,7 +1705,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 70, "id": "2558ddd1", "metadata": {}, "outputs": [], @@ -1749,7 +1740,7 @@ "* `get_rank_counts` does the same thing with the ranks of the cards, returning a dictionary that maps from each rank code to the number of times it appears.\n", "\n", "All of the exercises that follow can be done using only the Python features we have learned so far, but some of them are more difficult than most of the previous exercises.\n", - "I encourage you to ask an AI for help.\n", + "I encourage you to ask a virtual assistant for help.\n", "\n", "For problems like this, it often works well to ask for general advice about strategies and algorithms.\n", "Then you can either write the code yourself or ask for code.\n", @@ -1779,7 +1770,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 71, "id": "7aa25f29", "metadata": { "tags": [] @@ -1795,7 +1786,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 72, "id": "72c769d5", "metadata": { "tags": [] @@ -1817,7 +1808,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 73, "id": "e1c4f474", "metadata": { "tags": [] @@ -1846,7 +1837,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 74, "id": "c91e3bdb", "metadata": { "tags": [] @@ -1868,7 +1859,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 75, "id": "a60e233d", "metadata": { "tags": [] @@ -1890,7 +1881,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 76, "id": "ae5063e2", "metadata": { "tags": [] @@ -1923,7 +1914,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 77, "id": "940928ba", "metadata": { "tags": [] @@ -1943,7 +1934,7 @@ "Write a method called `has_straight` that checks whether a hand contains a straight, which is a set of five cards with consecutive ranks.\n", "For example, if a hand contains ranks `5`, `6`, `7`, `8`, and `9`, it contains a straight.\n", "\n", - "An Ace can come before a two or after a King, so `Ace`, `2`, `3`, `4`, `5` is a straight and so it `10`, `Jack`, `Queen`, `King`, `Ace`.\n", + "An Ace can come before a two or after a King, so `Ace`, `2`, `3`, `4`, `5` is a straight and so is `10`, `Jack`, `Queen`, `King`, `Ace`.\n", "But a straight cannot \"wrap around\", so `King`, `Ace`, `2`, `3`, `4` is not a straight." ] }, @@ -1960,7 +1951,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 78, "id": "6513ef14", "metadata": { "tags": [] @@ -1981,7 +1972,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 79, "id": "8a220d67", "metadata": { "tags": [] @@ -2004,7 +1995,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 80, "id": "5a422cae", "metadata": { "tags": [] @@ -2026,7 +2017,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 81, "id": "24483b99", "metadata": { "tags": [] @@ -2048,7 +2039,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 82, "id": "69f7cea9", "metadata": { "tags": [] @@ -2081,7 +2072,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 83, "id": "88bd35fb", "metadata": { "tags": [] @@ -2097,7 +2088,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 84, "id": "5e602773", "metadata": { "tags": [] @@ -2109,7 +2100,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 85, "id": "997b120d", "metadata": { "tags": [] @@ -2131,7 +2122,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 86, "id": "23704ab4", "metadata": { "tags": [] @@ -2143,7 +2134,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 87, "id": "7d8d2fdb", "metadata": { "tags": [] @@ -2166,7 +2157,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 88, "id": "4c5727d9", "metadata": { "tags": [] @@ -2193,7 +2184,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 89, "id": "7e65e951", "metadata": { "tags": [] @@ -2215,7 +2206,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 90, "id": "758fc922", "metadata": { "tags": [] @@ -2239,14 +2230,16 @@ { "cell_type": "markdown", "id": "00464353", - "metadata": {}, + "metadata": { + "tags": [] + }, "source": [ "You can use the following outline to get started." ] }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 91, "id": "15a81a40", "metadata": { "tags": [] @@ -2261,7 +2254,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 92, "id": "bc7ca211", "metadata": { "tags": [] @@ -2273,7 +2266,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 93, "id": "20b65d89", "metadata": { "tags": [] @@ -2293,7 +2286,7 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 94, "id": "57e616be", "metadata": {}, "outputs": [], @@ -2305,7 +2298,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 95, "id": "b8d87fd8", "metadata": {}, "outputs": [], @@ -2315,7 +2308,7 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 96, "id": "3016e99a", "metadata": {}, "outputs": [], @@ -2325,7 +2318,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 97, "id": "852e3b11", "metadata": {}, "outputs": [], @@ -2356,7 +2349,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 98, "id": "1f95601d", "metadata": { "tags": [] @@ -2371,7 +2364,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 99, "id": "420ca0fd", "metadata": { "tags": [] @@ -2393,7 +2386,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 100, "id": "1e4957cb", "metadata": { "tags": [] @@ -2408,7 +2401,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 101, "id": "4dc8b899", "metadata": { "tags": [] @@ -2420,7 +2413,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 102, "id": "86229763", "metadata": { "tags": [] @@ -2432,7 +2425,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 103, "id": "7f1b3664", "metadata": { "tags": [] @@ -2455,7 +2448,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 104, "id": "85b47651", "metadata": {}, "outputs": [], @@ -2501,12 +2494,12 @@ "`put_in_pouch` takes any object and appends it to `contents`.\n", "\n", "Now let's see how this class works.\n", - "We'll create two `Kangaroo` objects with the names Kanga and Roo." + "We'll create two `Kangaroo` objects with the names `'Kanga'` and `'Roo'`." ] }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 105, "id": "13f1e1f3", "metadata": {}, "outputs": [], @@ -2525,7 +2518,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 106, "id": "e882e2d6", "metadata": {}, "outputs": [], @@ -2545,7 +2538,7 @@ }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 107, "id": "724805bb", "metadata": {}, "outputs": [], @@ -2563,7 +2556,7 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 108, "id": "3f6cff16", "metadata": {}, "outputs": [], @@ -2589,6 +2582,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -2608,7 +2617,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap18.ipynb b/chapters/chap18.ipynb index e1760e2..3027822 100644 --- a/chapters/chap18.ipynb +++ b/chapters/chap18.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": 1, @@ -411,7 +403,7 @@ "source": [ "The result is a set that contains the words in the document that don't appear in the word list.\n", "\n", - "The comparison operators work with sets.\n", + "The relational operators work with sets.\n", "For example, `<=` checks whether one set is a subset of another, including the possibility that they are equal." ] }, @@ -487,7 +479,7 @@ "If you are familiar with the mathematical idea of a \"multiset\", a `Counter` is a\n", "natural way to represent a multiset.\n", "\n", - "The `Counter` class is defined in a standard module called `collections`, so you have to import it.\n", + "The `Counter` class is defined in a module called `collections`, so you have to import it.\n", "Then you can use the class object as a function and pass as an argument a string, list, or any other kind of sequence." ] }, @@ -1589,7 +1581,7 @@ "id": "71e3b049", "metadata": {}, "source": [ - "You can call this function with any number of positional arguments." + "You can call this function with any number of arguments." ] }, { @@ -1669,7 +1661,7 @@ "id": "07be77f3", "metadata": {}, "source": [ - "In this example, the value of `kwargs` is printed, but otherwise is has no effect.\n", + "In this example, the value of `kwargs` is printed, but otherwise it has no effect.\n", "\n", "But the `**` operator can also be used in an argument list to unpack a dictionary.\n", "For example, here's a version of `mean` that packs any keyword arguments it gets and then unpacks them as keyword arguments for `sum`." @@ -1897,7 +1889,7 @@ "metadata": {}, "source": [ "`run_unittest` does not take `TestExample` as an argument -- instead, it searches for classes that inherit from `TestCase`.\n", - "Then is searches for methods that begin with `test` and runs them.\n", + "Then it searches for methods that begin with `test` and runs them.\n", "This process is called **test discovery**.\n", "\n", "Here's what happens when we call `run_unittest`." @@ -2021,7 +2013,6 @@ "### Ask a virtual assistant\n", "\n", "There are a few topics in this chapter you might want to learn about.\n", - "Here are some question to ask an AI.\n", "\n", "* \"What are the methods and operators of Python's set class?\"\n", "\n", @@ -2035,11 +2026,11 @@ "\n", "* \"How does `unittest` do test discovery?\"\n", "\n", - "\"Along with `assertequal`, what are the most commonly used methods in `unittest.TestCase`?\"\n", + "* \"Along with `assertEqual`, what are the most commonly used methods in `unittest.TestCase`?\"\n", "\n", - "\"What are the pros and cons of `doctest` and `unittest`?\"\n", + "* \"What are the pros and cons of `doctest` and `unittest`?\"\n", "\n", - "For the following exercises, consider asking an AI for help, but as always, remember to test the results." + "For the following exercises, consider asking a virtual assistant for help, but as always, remember to test the results." ] }, { @@ -2072,7 +2063,7 @@ "metadata": {}, "source": [ "Write a version of this function that uses `set` operations instead of a `for` loop.\n", - "Hint: ask an AI \"How do I compute the intersection of Python sets?\"" + "Hint: ask a VA, \"How do I compute the intersection of Python sets?\"" ] }, { @@ -2572,6 +2563,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { @@ -2591,7 +2598,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.10.11" } }, "nbformat": 4, diff --git a/chapters/chap19.ipynb b/chapters/chap19.ipynb index 45f9084..4d86fb8 100644 --- a/chapters/chap19.ipynb +++ b/chapters/chap19.ipynb @@ -2,22 +2,14 @@ "cells": [ { "cell_type": "markdown", - "id": "b112e25b", + "id": "1331faa1", "metadata": {}, "source": [ - "You can order print and electronic versions of *Think Python 3e* from\n", + "You can order print and ebook versions of *Think Python 3e* from\n", "[Bookshop.org](https://bookshop.org/a/98697/9781098155438) and\n", "[Amazon](https://www.amazon.com/_/dp/1098155432?smid=ATVPDKIKX0DER&_encoding=UTF8&tag=oreilly20-20&_encoding=UTF8&tag=greenteapre01-20&linkCode=ur2&linkId=e2a529f94920295d27ec8a06e757dc7c&camp=1789&creative=9325)." ] }, - { - "cell_type": "code", - "execution_count": null, - "id": "3466e1f6", - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "markdown", "id": "171aca73", @@ -154,6 +146,22 @@ "metadata": {}, "outputs": [], "source": [] + }, + { + "cell_type": "markdown", + "id": "a7f4edf8", + "metadata": { + "tags": [] + }, + "source": [ + "[Think Python: 3rd Edition](https://allendowney.github.io/ThinkPython/index.html)\n", + "\n", + "Copyright 2024 [Allen B. Downey](https://allendowney.com)\n", + "\n", + "Code license: [MIT License](https://mit-license.org/)\n", + "\n", + "Text license: [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-nc-sa/4.0/)" + ] } ], "metadata": { diff --git a/jb/_config.yml b/jb/_config.yml index 245575a..f0b261f 100644 --- a/jb/_config.yml +++ b/jb/_config.yml @@ -1,5 +1,5 @@ # Book settings -title: Think Python, 3rd edition +title: Think Python author: Allen B. Downey latex: @@ -14,6 +14,19 @@ repository: html: use_repository_button: true + extra_footer: | +
+ + Creative Commons License + +
+ This work is licensed under a + + Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License + . +
+ parse: # myst_extended_syntax: true # instead enable individual features below myst_enable_extensions: # https://myst-parser.readthedocs.io/en/latest/using/syntax-optional.html diff --git a/jb/_toc.yml b/jb/_toc.yml index e5e3fd4..6a5c362 100644 --- a/jb/_toc.yml +++ b/jb/_toc.yml @@ -1,23 +1,31 @@ format: jb-book root: index -chapters: -- file: chap00 -- file: chap01 -- file: chap02 -- file: chap03 -- file: chap04 -- file: chap05 -- file: chap06 -- file: chap07 -- file: chap08 -- file: chap09 -- file: chap10 -- file: chap11 -- file: chap12 -- file: chap13 -- file: chap14 -- file: chap15 -- file: chap16 -- file: chap17 -- file: chap18 -- file: chap19 +parts: +- caption: Front Matter + chapters: + - file: chap00 +- caption: Chapters + numbered: True + chapters: + - file: chap01 + - file: chap02 + - file: chap03 + - file: chap04 + - file: chap05 + - file: chap06 + - file: chap07 + - file: chap08 + - file: chap09 + - file: chap10 + - file: chap11 + - file: chap12 + - file: chap13 + - file: chap14 + - file: chap15 + - file: chap16 + - file: chap17 + - file: chap18 + - file: chap19 +- caption: End Matter + chapters: + - file: blank diff --git a/jupyturtle_flower.png b/jupyturtle_flower.png new file mode 100644 index 0000000..30a7ab2 Binary files /dev/null and b/jupyturtle_flower.png differ diff --git a/jupyturtle_flower.svg b/jupyturtle_flower.svg new file mode 100644 index 0000000..33236db --- /dev/null +++ b/jupyturtle_flower.svg @@ -0,0 +1,1930 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/jupyturtle_pie.png b/jupyturtle_pie.png new file mode 100644 index 0000000..472eb5c Binary files /dev/null and b/jupyturtle_pie.png differ diff --git a/jupyturtle_pie.svg b/jupyturtle_pie.svg new file mode 100644 index 0000000..5c7c117 --- /dev/null +++ b/jupyturtle_pie.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/thinkpython.py b/thinkpython.py index 02ff181..3f08885 100644 --- a/thinkpython.py +++ b/thinkpython.py @@ -2,21 +2,6 @@ import io import re -from IPython.core.magic import register_cell_magic -from IPython.core.magic_arguments import argument, magic_arguments, parse_argstring - - -def traceback(mode): - """Set the traceback mode. - - mode: string - """ - with contextlib.redirect_stdout(io.StringIO()): - get_ipython().run_cell(f'%xmode {mode}') - - -traceback('Minimal') - def extract_function_name(text): """Find a function definition and return its name. @@ -34,61 +19,75 @@ def extract_function_name(text): return None -@register_cell_magic -def add_method_to(args, cell): +# the functions that define cell magic commands are only defined +# if we're running in Jupyter. - # get the name of the function defined in this cell - func_name = extract_function_name(cell) - if func_name is None: - return f"This cell doesn't define any new functions." +try: + from IPython.core.magic import register_cell_magic + from IPython.core.magic_arguments import argument, magic_arguments, parse_argstring - # get the class we're adding it to - namespace = get_ipython().user_ns - class_name = args - cls = namespace.get(class_name, None) - if cls is None: - return f"Class '{class_name}' not found." + @register_cell_magic + def add_method_to(args, cell): - # save the old version of the function if it was already defined - old_func = namespace.get(func_name, None) - if old_func is not None: - del namespace[func_name] + # get the name of the function defined in this cell + func_name = extract_function_name(cell) + if func_name is None: + return f"This cell doesn't define any new functions." - # Execute the cell to define the function - get_ipython().run_cell(cell) + # get the class we're adding it to + namespace = get_ipython().user_ns + class_name = args + cls = namespace.get(class_name, None) + if cls is None: + return f"Class '{class_name}' not found." - # get the newly defined function - new_func = namespace.get(func_name, None) - if new_func is None: - return f"This cell didn't define {func_name}." + # save the old version of the function if it was already defined + old_func = namespace.get(func_name, None) + if old_func is not None: + del namespace[func_name] - # add the function to the class and remove it from the namespace - setattr(cls, func_name, new_func) - del namespace[func_name] - - # restore the old function to the namespace - if old_func is not None: - namespace[func_name] = old_func - - -@register_cell_magic -def expect_error(line, cell): - try: + # Execute the cell to define the function get_ipython().run_cell(cell) - except Exception as e: - get_ipython().run_cell('%tb') - + # get the newly defined function + new_func = namespace.get(func_name, None) + if new_func is None: + return f"This cell didn't define {func_name}." -@magic_arguments() -@argument('exception', help='Type of exception to catch') -@register_cell_magic -def expect(line, cell): - args = parse_argstring(expect, line) - exception = eval(args.exception) - try: - get_ipython().run_cell(cell) - except exception as e: - get_ipython().run_cell("%tb") - + # add the function to the class and remove it from the namespace + setattr(cls, func_name, new_func) + del namespace[func_name] + # restore the old function to the namespace + if old_func is not None: + namespace[func_name] = old_func + + @register_cell_magic + def expect_error(line, cell): + try: + get_ipython().run_cell(cell) + except Exception as e: + get_ipython().run_cell("%tb") + + @magic_arguments() + @argument("exception", help="Type of exception to catch") + @register_cell_magic + def expect(line, cell): + args = parse_argstring(expect, line) + exception = eval(args.exception) + try: + get_ipython().run_cell(cell) + except exception as e: + get_ipython().run_cell("%tb") + + def traceback(mode): + """Set the traceback mode. + + mode: string + """ + with contextlib.redirect_stdout(io.StringIO()): + get_ipython().run_cell(f"%xmode {mode}") + + traceback("Minimal") +except (ImportError, NameError): + print("Warning: IPython is not available, cell magic not defined.")