From 8dea642ce98ca70814f5e80830b10f3439b2ae06 Mon Sep 17 00:00:00 2001 From: Alexander Hess Date: Tue, 10 Mar 2020 15:27:49 +0100 Subject: [PATCH] Streamline presentation --- 04_iteration_00_lecture.ipynb | 694 ++++++++++++++++---------------- 04_iteration_02_exercises.ipynb | 76 ++-- 2 files changed, 388 insertions(+), 382 deletions(-) diff --git a/04_iteration_00_lecture.ipynb b/04_iteration_00_lecture.ipynb index 0c95c8a..1a72c7b 100644 --- a/04_iteration_00_lecture.ipynb +++ b/04_iteration_00_lecture.ipynb @@ -562,7 +562,7 @@ "execution_count": 15, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ @@ -597,7 +597,7 @@ "execution_count": 16, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ @@ -613,7 +613,7 @@ } ], "source": [ - "gcd(2, 7919)" + "gcd(7, 7919)" ] }, { @@ -721,7 +721,7 @@ } ], "source": [ - "math.gcd(2, 7919)" + "math.gcd(7, 7919)" ] }, { @@ -859,7 +859,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "49.8 µs ± 20.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" + "37.3 µs ± 1.25 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], @@ -873,7 +873,7 @@ "execution_count": 24, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ @@ -881,13 +881,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "1.63 ms ± 14.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" + "11.4 ms ± 144 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], "source": [ "%%timeit -n 100\n", - "fibonacci(20)" + "fibonacci(24)" ] }, { @@ -895,7 +895,7 @@ "execution_count": 25, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ @@ -903,40 +903,18 @@ "name": "stdout", "output_type": "stream", "text": [ - "202 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" + "3.63 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" ] } ], "source": [ "%%timeit -n 1 -r 1\n", - "fibonacci(30)" + "fibonacci(36)" ] }, { "cell_type": "code", "execution_count": 26, - "metadata": { - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2.25 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" - ] - } - ], - "source": [ - "%%timeit -n 1 -r 1\n", - "fibonacci(35)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, "metadata": { "slideshow": { "slide_type": "skip" @@ -947,7 +925,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "5.79 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" + "5.93 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" ] } ], @@ -982,7 +960,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 27, "metadata": { "slideshow": { "slide_type": "slide" @@ -997,7 +975,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 28, "metadata": { "slideshow": { "slide_type": "slide" @@ -1011,10 +989,10 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mRecursionError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mrun_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m\u001b[0m in \u001b[0;36mrun_forever\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mrun_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\"\"\"Also a pointless function should have a docstring.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mrun_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mrun_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36mrun_forever\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mrun_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\"\"\"Also a pointless function should have a docstring.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mrun_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "... last 1 frames repeated, from the frame below ...\n", - "\u001b[0;32m\u001b[0m in \u001b[0;36mrun_forever\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mrun_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\"\"\"Also a pointless function should have a docstring.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mrun_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36mrun_forever\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mrun_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;34m\"\"\"Also a pointless function should have a docstring.\"\"\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mrun_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mRecursionError\u001b[0m: maximum recursion depth exceeded" ] } @@ -1036,7 +1014,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 29, "metadata": { "slideshow": { "slide_type": "slide" @@ -4010,7 +3988,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mRecursionError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mcountdown\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3.1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mcountdown\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3.1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mcountdown\u001b[0;34m(n)\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mcountdown\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "... last 1 frames repeated, from the frame below ...\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mcountdown\u001b[0;34m(n)\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 11\u001b[0;31m \u001b[0mcountdown\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", @@ -4035,7 +4013,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 30, "metadata": { "slideshow": { "slide_type": "slide" @@ -4049,7 +4027,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mRecursionError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfactorial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3.1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfactorial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3.1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mfactorial\u001b[0;34m(n)\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# = base case\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mfactorial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "... last 1 frames repeated, from the frame below ...\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mfactorial\u001b[0;34m(n)\u001b[0m\n\u001b[1;32m 10\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# = base case\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 11\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 12\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mfactorial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", @@ -4118,7 +4096,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 31, "metadata": { "slideshow": { "slide_type": "slide" @@ -4161,7 +4139,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 32, "metadata": { "slideshow": { "slide_type": "slide" @@ -4174,7 +4152,7 @@ "1" ] }, - "execution_count": 33, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -4185,26 +4163,26 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 33, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ { "data": { "text/plain": [ - "3628800" + "6" ] }, - "execution_count": 34, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "factorial(10)" + "factorial(3)" ] }, { @@ -4220,7 +4198,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 34, "metadata": { "slideshow": { "slide_type": "slide" @@ -4234,8 +4212,8 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfactorial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3.1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m\u001b[0m in \u001b[0;36mfactorial\u001b[0;34m(n)\u001b[0m\n\u001b[1;32m 13\u001b[0m \"\"\"\n\u001b[1;32m 14\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 15\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Factorial is only defined for integers\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 16\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 17\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Factorial is not defined for negative integers\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfactorial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3.1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36mfactorial\u001b[0;34m(n)\u001b[0m\n\u001b[1;32m 13\u001b[0m \"\"\"\n\u001b[1;32m 14\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mint\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 15\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Factorial is only defined for integers\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 16\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 17\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Factorial is not defined for negative integers\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mTypeError\u001b[0m: Factorial is only defined for integers" ] } @@ -4246,7 +4224,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 35, "metadata": { "slideshow": { "slide_type": "slide" @@ -4260,8 +4238,8 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfactorial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m42\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;32m\u001b[0m in \u001b[0;36mfactorial\u001b[0;34m(n)\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Factorial is only defined for integers\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 17\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Factorial is not defined for negative integers\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 18\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# = base case\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mfactorial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m42\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36mfactorial\u001b[0;34m(n)\u001b[0m\n\u001b[1;32m 15\u001b[0m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Factorial is only defined for integers\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 17\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Factorial is not defined for negative integers\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 18\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# = base case\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mValueError\u001b[0m: Factorial is not defined for negative integers" ] } @@ -4353,7 +4331,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 36, "metadata": { "code_folding": [], "slideshow": { @@ -4381,12 +4359,12 @@ " print(n)\n", " n -= 1\n", "\n", - " print(\"Happy new Year!\") # = base case" + " print(\"Happy new Year!\")" ] }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 37, "metadata": { "slideshow": { "slide_type": "slide" @@ -4445,7 +4423,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 38, "metadata": { "code_folding": [], "slideshow": { @@ -4484,7 +4462,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 39, "metadata": { "slideshow": { "slide_type": "slide" @@ -4497,7 +4475,7 @@ "4" ] }, - "execution_count": 40, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -4508,10 +4486,10 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 40, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ @@ -4521,13 +4499,13 @@ "1" ] }, - "execution_count": 41, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "gcd(2, 7919)" + "gcd(7, 7919)" ] }, { @@ -4554,7 +4532,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 41, "metadata": { "slideshow": { "slide_type": "slide" @@ -4565,7 +4543,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "5.14 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" + "5.24 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" ] } ], @@ -4637,7 +4615,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 42, "metadata": { "code_folding": [], "slideshow": { @@ -4669,11 +4647,11 @@ " while n != 1:\n", " print(n, end=\" \")\n", " if n % 2 == 0:\n", - " n //= 2 # //= instead of /= so that n remains an int\n", + " n //= 2 # //= to preserve the int type\n", " else:\n", " n = 3 * n + 1\n", "\n", - " print(n) # = base case" + " print(1)" ] }, { @@ -4689,7 +4667,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 43, "metadata": { "slideshow": { "slide_type": "slide" @@ -4710,10 +4688,10 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 44, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ @@ -4731,10 +4709,10 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 45, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ @@ -4752,7 +4730,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 46, "metadata": { "slideshow": { "slide_type": "skip" @@ -4799,7 +4777,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 47, "metadata": { "slideshow": { "slide_type": "slide" @@ -4812,10 +4790,10 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 48, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ @@ -4829,10 +4807,12 @@ ], "source": [ "index = 0\n", + "\n", "while index < len(elements):\n", " element = elements[index]\n", " print(element, end=\" \")\n", " index += 1\n", + "\n", "del index" ] }, @@ -4849,7 +4829,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 49, "metadata": { "slideshow": { "slide_type": "fragment" @@ -4882,10 +4862,10 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 50, "metadata": { "slideshow": { - "slide_type": "fragment" + "slide_type": "slide" } }, "outputs": [ @@ -4904,7 +4884,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 51, "metadata": { "slideshow": { "slide_type": "fragment" @@ -4917,7 +4897,7 @@ "range" ] }, - "execution_count": 52, + "execution_count": 51, "metadata": {}, "output_type": "execute_result" } @@ -4939,7 +4919,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 52, "metadata": { "slideshow": { "slide_type": "slide" @@ -4961,7 +4941,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 53, "metadata": { "slideshow": { "slide_type": "fragment" @@ -5019,7 +4999,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 54, "metadata": { "slideshow": { "slide_type": "slide" @@ -5043,7 +5023,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 55, "metadata": { "slideshow": { "slide_type": "fragment" @@ -5056,7 +5036,7 @@ "True" ] }, - "execution_count": 56, + "execution_count": 55, "metadata": {}, "output_type": "execute_result" } @@ -5067,10 +5047,10 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 56, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ @@ -5080,7 +5060,7 @@ "False" ] }, - "execution_count": 57, + "execution_count": 56, "metadata": {}, "output_type": "execute_result" } @@ -5102,7 +5082,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 57, "metadata": { "slideshow": { "slide_type": "skip" @@ -5115,7 +5095,7 @@ "[0, 1, 2, 3, 4]" ] }, - "execution_count": 58, + "execution_count": 57, "metadata": {}, "output_type": "execute_result" } @@ -5126,7 +5106,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 58, "metadata": { "slideshow": { "slide_type": "skip" @@ -5139,7 +5119,7 @@ "True" ] }, - "execution_count": 59, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -5161,7 +5141,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 59, "metadata": { "slideshow": { "slide_type": "slide" @@ -5194,7 +5174,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 60, "metadata": { "slideshow": { "slide_type": "fragment" @@ -5205,13 +5185,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "0 > Achim 1 > Berthold 2 > Carl 3 > Diedrich 4 > Eckardt " + "1 > Achim 2 > Berthold 3 > Carl 4 > Diedrich 5 > Eckardt " ] } ], "source": [ - "for i, name in enumerate(first_names):\n", - " print(i, name, sep=\" > \", end=\" \")" + "for i, name in enumerate(first_names, start=1):\n", + " print(i, \">\", name, end=\" \")" ] }, { @@ -5227,7 +5207,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 61, "metadata": { "slideshow": { "slide_type": "skip" @@ -5244,7 +5224,7 @@ ], "source": [ "for i, name in enumerate(first_names, start=1):\n", - " print(i, name, sep=\" > \", end=\" \")" + " print(i, \">\", name, end=\" \")" ] }, { @@ -5260,7 +5240,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 62, "metadata": { "slideshow": { "slide_type": "skip" @@ -5273,7 +5253,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 63, "metadata": { "slideshow": { "slide_type": "skip" @@ -5321,7 +5301,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 64, "metadata": { "code_folding": [], "slideshow": { @@ -5351,7 +5331,7 @@ " a = 0\n", " b = 1\n", " print(a, b, sep=\" \", end=\" \") # added for didactical purposes\n", - " for _ in range(i - 1): # the index variable is not needed\n", + " for _ in range(i - 1):\n", " temp = a + b\n", " a = b\n", " b = temp\n", @@ -5362,7 +5342,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 65, "metadata": { "slideshow": { "slide_type": "slide" @@ -5382,7 +5362,7 @@ "144" ] }, - "execution_count": 66, + "execution_count": 65, "metadata": {}, "output_type": "execute_result" } @@ -5415,7 +5395,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 66, "metadata": { "slideshow": { "slide_type": "slide" @@ -5435,7 +5415,7 @@ "218922995834555169026" ] }, - "execution_count": 67, + "execution_count": 66, "metadata": {}, "output_type": "execute_result" } @@ -5468,7 +5448,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 67, "metadata": { "slideshow": { "slide_type": "slide" @@ -5495,7 +5475,7 @@ " raise ValueError(\"Factorial is not defined for negative integers\")\n", "\n", " product = 1 # because 0! = 1\n", - " for i in range(1, n + 1): # loop starts at 1 as 0! is already covered\n", + " for i in range(1, n + 1):\n", " product *= i\n", " print(product, end=\" \") # added for didactical purposes\n", "\n", @@ -5504,12 +5484,43 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 68, "metadata": { "slideshow": { "slide_type": "slide" } }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1 2 6 " + ] + }, + { + "data": { + "text/plain": [ + "6" + ] + }, + "execution_count": 68, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "factorial(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 69, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, "outputs": [ { "name": "stdout", @@ -5541,7 +5552,7 @@ } }, "source": [ - "### The `break` Statement" + "### Customizing `for`- and `while`-loops" ] }, { @@ -5552,7 +5563,7 @@ } }, "source": [ - "The remainder of this chapter introduces more syntactic sugar: None of the language constructs introduced below are needed but contribute to making Python the expressive and easy to read language that it is." + "This section introduces additional syntax to customize `for` and `while` statements in our code even further. They are mostly syntactic sugar in that they do not change how a program runs but make its code more readable. We illustrate them for the `for` statement only. However, everything presented in this section also works for the `while` statement." ] }, { @@ -5563,7 +5574,7 @@ } }, "source": [ - "#### Example: Searching an Iterable" + "#### Example: Is the square of a number in `[7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]` greater than `100`?" ] }, { @@ -5574,7 +5585,7 @@ } }, "source": [ - "Let's say we have a list of `numbers` and want to check if the square of at least one of its elements is above a `threshold` of `100`." + "Let's say we have a list of `numbers` and want to check if the square of at least one of its elements is greater than `100`. So, conceptually, we are asking the question if a list of numbers as a whole satisfies a certain condition." ] }, { @@ -5590,19 +5601,6 @@ "numbers = [7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]" ] }, - { - "cell_type": "code", - "execution_count": 71, - "metadata": { - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [], - "source": [ - "threshold = 100 # is the square of an element in numbers greater than this?" - ] - }, { "cell_type": "markdown", "metadata": { @@ -5611,12 +5609,16 @@ } }, "source": [ - "A first naive implementation could look like this: We loop over *every* element in `numbers` and set an **indicator variable** `is_above`, initialized as `False`, to `True` once we encounter an element satisfying the search condition." + "A first naive implementation could look like this: We loop over *every* element in `numbers` and set an **indicator variable** `is_above`, initialized as `False`, to `True` once we encounter an element satisfying the condition.\n", + "\n", + "This implementation is *inefficient* as even if the *first* element in `numbers` has a square greater than `100`, we loop until the last element: This could take a long time for a big list.\n", + "\n", + "Moreover, we must initialize `is_above` *before* the `for`-loop and write an `if`-`else`-logic *after* it to check for the result. The actual business logic is *not* conveyed in a clear way." ] }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 71, "metadata": { "slideshow": { "slide_type": "fragment" @@ -5627,7 +5629,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "7 11 8 5 3 12 2 6 9 10 1 4 => at least one number's square is above 100\n" + "7 11 8 5 3 12 2 6 9 10 1 4 => at least one number satisfies the condition\n" ] } ], @@ -5636,13 +5638,24 @@ "\n", "for number in numbers:\n", " print(number, end=\" \") # added for didactical purposes\n", - " if number ** 2 > threshold:\n", + " if number ** 2 > 100:\n", " is_above = True\n", "\n", "if is_above:\n", - " print(\"=> at least one number's square is above\", threshold)\n", + " print(\"=> at least one number satisfies the condition\")\n", "else:\n", - " print(\"=> no number's square is above\", threshold)" + " print(\"=> no number satisfies the condition\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "#### The `break` Statement" ] }, { @@ -5653,11 +5666,74 @@ } }, "source": [ - "This implementation is *inefficient* as even if the *first* element in `numbers` has a square greater than `100`, we loop until the last element: This could take a long time for a big list.\n", + "Python provides the `break` statement (cf., [reference](https://docs.python.org/3/reference/simple_stmts.html#the-break-statement)) that lets us stop a loop prematurely at any iteration. It is yet another means of controlling the flow of execution, and we say that we \"break out of a loop.\"" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "7 11 => at least one number satisfies the condition\n" + ] + } + ], + "source": [ + "is_above = False\n", "\n", - "Moreover, we must initialize `is_above` *before* the `for`-loop and write an `if`-`else`-logic *after* it to check for the result. The actual business logic is *not* clear right away.\n", + "for number in numbers:\n", + " print(number, end=\" \") # added for didactical purposes\n", + " if number ** 2 > 100:\n", + " is_above = True\n", + " break\n", "\n", - "Luckily, Python provides the `break` statement (cf., [reference](https://docs.python.org/3/reference/simple_stmts.html#the-break-statement)) that lets us stop the `for`-loop in any iteration of the loop. Conceptually, it is yet another means of controlling the flow of execution." + "if is_above:\n", + " print(\"=> at least one number satisfies the condition\")\n", + "else:\n", + " print(\"=> no number satisfies the condition\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "This is a computational improvement. However, the code still consists of *three* sections: Some initialization *before* the `for`-loop, the loop itself, and some finalizing logic. We prefer to convey the program's idea in *one* compound statement instead." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "#### The `else`-clause" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "To express the logic in a prettier way, we add an `else`-clause at the end of the `for`-loop (cf., [reference](https://docs.python.org/3/reference/compound_stmts.html#the-for-statement)). The `else`-clause is executed *only if* the `for`-loop is *not* stopped with a `break` statement *prematurely* (i.e., *before* reaching the *last* iteration in the loop). The word \"else\" implies a somewhat unintuitive meaning and may have better been named a `then`-clause. In most use cases, however, the `else`-clause logically goes together with some `if` statement in the loop's body.\n", + "\n", + "Overall, the code's expressive power increases. Not many programming languages support an optional `else`-branching for the `for` and `while` statements, which turns out to be very useful in practice." ] }, { @@ -5673,101 +5749,23 @@ "name": "stdout", "output_type": "stream", "text": [ - "7 11 => at least one number's square is above 100\n" - ] - } - ], - "source": [ - "is_above = False\n", - "\n", - "for number in numbers:\n", - " print(number, end=\" \") # added for didactical purposes\n", - " if number ** 2 > threshold:\n", - " is_above = True\n", - " break\n", - "\n", - "if is_above:\n", - " print(\"=> at least one number's square is above\", threshold)\n", - "else:\n", - " print(\"=> no number's square is above\", threshold)" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "This is a computational improvement. However, the code still consists of *three* logical sections: Some initialization *before* the `for`-loop, the loop itself, and some finalizing logic. We prefer to convey the program's idea in *one* compound statement instead." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "source": [ - "### The `for`-`else`-Clause" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "To express the logic in a prettier way, we add an `else`-clause at the end of the `for`-loop (cf., [reference](https://docs.python.org/3/reference/compound_stmts.html#the-for-statement)). The `else`-clause is executed *iff* the `for`-loop is *not* stopped with a `break` statement **prematurely** (i.e., *before* reaching the *last* iteration in the loop). The word \"else\" implies a somewhat unintuitive meaning and had better been named a `then`-clause. In most scenarios, however, the `else`-clause logically goes together with some `if` statement in the `for`-loop's body.\n", - "\n", - "Overall, the code's expressive power increases. Not many programming languages support a `for`-`else`-branching, which turns out to be very useful in practice." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "#### Example: Searching an Iterable (revisited)" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "7 11 => at least one number's square is above 100\n" + "7 11 => at least one number satisfies the condition\n" ] } ], "source": [ "for number in numbers:\n", " print(number, end=\" \") # added for didactical purposes\n", - " if number ** 2 > threshold:\n", + " if number ** 2 > 100:\n", " is_above = True\n", " break\n", "else:\n", " is_above = False\n", "\n", "if is_above:\n", - " print(\"=> at least one number's square is above\", threshold)\n", + " print(\"=> at least one number satisfies the condition\")\n", "else:\n", - " print(\"=> no number's square is above\", threshold)" + " print(\"=> no number satisfies the condition\")" ] }, { @@ -5783,7 +5781,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 74, "metadata": { "slideshow": { "slide_type": "slide" @@ -5794,18 +5792,18 @@ "name": "stdout", "output_type": "stream", "text": [ - "7 11 => at least one number's square is above 100\n" + "7 11 => at least one number satisfies the condition\n" ] } ], "source": [ "for number in numbers:\n", " print(number, end=\" \") # added for didactical purposes\n", - " if number ** 2 > threshold:\n", - " print(\"=> at least one number's square is above\", threshold)\n", + " if number ** 2 > 100:\n", + " print(\"=> at least one number satisfies the condition\")\n", " break\n", "else:\n", - " print(\"=> no number's square is above\", threshold)" + " print(\"=> no number satisfies the condition\")" ] }, { @@ -5816,12 +5814,12 @@ } }, "source": [ - "Of course, if we set the `threshold` an element's square has to pass higher, for example, to `200`, we have to loop over all `numbers`. There is *no way* to optimize this **[linear search](https://en.wikipedia.org/wiki/Linear_search)** further, at least as long as we model `numbers` as a `list` object. More advanced data types, however, exist that mitigate that downside." + "Of course, if we choose the number an element's square has to pass to be larger, for example, to `200`, we have to loop over all `numbers`. There is *no way* to optimize this **[linear search](https://en.wikipedia.org/wiki/Linear_search)** further." ] }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 75, "metadata": { "slideshow": { "slide_type": "skip" @@ -5832,31 +5830,29 @@ "name": "stdout", "output_type": "stream", "text": [ - "7 11 8 5 3 12 2 6 9 10 1 4 => no number's square is above 200\n" + "7 11 8 5 3 12 2 6 9 10 1 4 => no number satisfies the condition\n" ] } ], "source": [ - "threshold = 200\n", - "\n", "for number in numbers:\n", " print(number, end=\" \") # added for didactical purposes\n", - " if number ** 2 > threshold:\n", - " print(\"=> at least one number's square is above\", threshold)\n", + " if number ** 2 > 200:\n", + " print(\"=> at least one number satisfies the condition\")\n", " break\n", "else:\n", - " print(\"=> no number's square is above\", threshold)" + " print(\"=> no number satisfies the condition\")" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { - "slide_type": "slide" + "slide_type": "skip" } }, "source": [ - "### The `continue` Statement" + "#### A first Glance at the Map-Filter-Reduce Paradigm" ] }, { @@ -5877,7 +5873,7 @@ "\n", "We study this **map-filter-reduce** paradigm extensively in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_lecture.ipynb#The-Map-Filter-Reduce-Paradigm) after introducing more advanced data types that are needed to work with \"big\" data.\n", "\n", - "Here, we focus on *filtering out* some numbers with a `for`-loop." + "Here, we focus on *filtering out* some numbers in a `for`-loop." ] }, { @@ -5909,7 +5905,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 76, "metadata": { "slideshow": { "slide_type": "slide" @@ -5922,10 +5918,10 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 77, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ @@ -5933,7 +5929,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "8 > 65 12 > 145 2 > 5 6 > 37 10 > 101 4 > 17 " + "8 -> 65 12 -> 145 2 -> 5 6 -> 37 10 -> 101 4 -> 17 " ] }, { @@ -5942,7 +5938,7 @@ "370" ] }, - "execution_count": 78, + "execution_count": 77, "metadata": {}, "output_type": "execute_result" } @@ -5953,7 +5949,7 @@ "for number in numbers:\n", " if number % 2 == 0: # only keep even numbers\n", " square = (number ** 2) + 1\n", - " print(number, square, sep=\" > \", end=\" \") # added for didactical purposes\n", + " print(number, \"->\", square, end=\" \") # added for didactical purposes\n", " total += square\n", "\n", "total" @@ -5982,7 +5978,7 @@ } }, "source": [ - "#### Example: Nested Filters" + "#### Example: Several Filters" ] }, { @@ -6004,31 +6000,20 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 78, "metadata": { "slideshow": { "slide_type": "slide" } }, - "outputs": [ - { - "data": { - "text/plain": [ - "[7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]" - ] - }, - "execution_count": 79, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "numbers" + "numbers = [7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]" ] }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 79, "metadata": { "slideshow": { "slide_type": "-" @@ -6039,7 +6024,84 @@ "name": "stdout", "output_type": "stream", "text": [ - "8 > 65 12 > 145 4 > 17 " + "8 -> 65 12 -> 145 4 -> 17 " + ] + }, + { + "data": { + "text/plain": [ + "227" + ] + }, + "execution_count": 79, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "total = 0\n", + "\n", + "for i, number in enumerate(numbers, start=1):\n", + " if i % 3 == 0: # only keep every third number\n", + " if number % 2 == 0: # only keep even numbers\n", + " square = (number ** 2) + 1\n", + " print(number, \"->\", square, end=\" \") # added for didactical purposes \n", + " total += square\n", + "\n", + "total" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "With already three levels of indentation, less horizontal space is available for the actual code block. Of course, one could flatten the two `if` statements with the logical `and` operator, as shown in [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_lecture.ipynb#The-if-Statement). Then, however, we trade off horizontal space against a more \"complex\" `if` logic, and this is *not* a real improvement." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "#### The `continue` Statement" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "A Pythonista would instead make use of the `continue` statement (cf., [reference](https://docs.python.org/3/reference/simple_stmts.html#the-continue-statement)) that causes a loop to jump into the next iteration skipping the rest of the code block.\n", + "\n", + "The revised code fragment below occupies more vertical space and less horizontal space: A *good* trade-off.\n", + "\n", + "One caveat is that we need to negate the conditions in the `if` statements. Conceptually, we are now filtering \"out\" and not \"in.\"" + ] + }, + { + "cell_type": "code", + "execution_count": 80, + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8 -> 65 12 -> 145 4 -> 17 " ] }, { @@ -6053,72 +6115,6 @@ "output_type": "execute_result" } ], - "source": [ - "total = 0\n", - "\n", - "for i, number in enumerate(numbers, start=1):\n", - " if i % 3 == 0: # only keep every third number\n", - " if number % 2 == 0: # only keep even numbers\n", - " square = (number ** 2) + 1\n", - " print(number, square, sep=\" > \", end=\" \") # added for didactical purposes \n", - " total += square\n", - "\n", - "total" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "With already three levels of indentation, less horizontal space is available for the actual code block. Of course, one could flatten the two `if` statements with the logical `and` operator, as shown in [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_lecture.ipynb#The-if-Statement). Then, however, we trade off horizontal space against a more \"complex\" `if` logic, and this is *not* a real improvement.\n", - "\n", - "A Pythonista would instead make use of the `continue` statement (cf., [reference](https://docs.python.org/3/reference/simple_stmts.html#the-continue-statement)) that causes a loop to jump into the next iteration skipping the rest of the code block.\n", - "\n", - "The revised code fragment below occupies more vertical space and less horizontal space: A *good* trade-off." - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "#### Example: Nested Filters (revisited)" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "8 > 65 12 > 145 4 > 17 " - ] - }, - { - "data": { - "text/plain": [ - "227" - ] - }, - "execution_count": 81, - "metadata": {}, - "output_type": "execute_result" - } - ], "source": [ "total = 0\n", "\n", @@ -6129,7 +6125,7 @@ " continue\n", "\n", " square = (number ** 2) + 1\n", - " print(number, square, sep=\" > \", end=\" \") # added for didactical purposes \n", + " print(number, \"->\", square, end=\" \") # added for didactical purposes \n", " total += square\n", "\n", "total" @@ -6143,11 +6139,7 @@ } }, "source": [ - "This is yet another illustration of why programming is an art. The two preceding code cells do the *same* with *identical* time complexity. However, the latter is arguably easier to read for a human, even more so when the business logic grows beyond two nested filters.\n", - "\n", - "The idea behind the `continue` statement is conceptually similar to the early exit pattern we saw above.\n", - "\n", - "Both the `break` and `continue` statements, as well as the optional `else`-clause, are not only supported with `for`-loops but also `while`-loops." + "This is yet another illustration of why programming is an art. The two preceding code cells do the *same* with *identical* time complexity. However, the latter is arguably easier to read for a human, even more so when the business logic grows beyond two filters." ] }, { @@ -6202,7 +6194,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 81, "metadata": { "slideshow": { "slide_type": "slide" @@ -6215,10 +6207,10 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 82, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [], @@ -6228,7 +6220,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 83, "metadata": { "code_folding": [], "slideshow": { @@ -6240,7 +6232,7 @@ "name": "stdin", "output_type": "stream", "text": [ - "Guess if the coin comes up as heads or tails: Tails\n" + "Guess if the coin comes up as heads or tails: Heads\n" ] }, { @@ -6250,6 +6242,20 @@ "Ooops, it was tails\n" ] }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Guess if the coin comes up as heads or tails: Heads\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Ooops, it was heads\n" + ] + }, { "name": "stdin", "output_type": "stream", @@ -6325,7 +6331,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 84, "metadata": { "slideshow": { "slide_type": "slide" @@ -6362,7 +6368,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 85, "metadata": { "slideshow": { "slide_type": "slide" @@ -6400,7 +6406,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 86, "metadata": { "slideshow": { "slide_type": "skip" @@ -6413,7 +6419,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 87, "metadata": { "slideshow": { "slide_type": "slide" diff --git a/04_iteration_02_exercises.ipynb b/04_iteration_02_exercises.ipynb index 5858e2d..ab80178 100644 --- a/04_iteration_02_exercises.ipynb +++ b/04_iteration_02_exercises.ipynb @@ -19,7 +19,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Read [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_lecture.ipynb) of the book. Then, work through the exercises below." + "Read [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_lecture.ipynb) of the book. Then, work through the exercises below. The `...` indicate where you need to fill in your answers. You should not need to create any additional code cells. Occasionally, the `...` mean that you have to write more than one line of code." ] }, { @@ -88,7 +88,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.1**: Explain for the $n = 3$ case why it can be solved as a **recursion**!" + "**Q1**: Explain for the $n = 3$ case why it can be solved as a **recursion**!" ] }, { @@ -102,7 +102,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.2**: How does the number of minimal moves needed to solve a problem with three spots and $n$ disks grow as a function of $n$? How does this relate to the answer to **Q1.1**?" + "**Q2**: How does the number of minimal moves needed to solve a problem with three spots and $n$ disks grow as a function of $n$? How does this relate to the answer to **Q1**?" ] }, { @@ -116,7 +116,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.3**: The **[Towers of Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi)** problem is of **exponential growth**. What does that mean? What does that imply for large $n$?" + "**Q3**: The **[Towers of Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi)** problem is of **exponential growth**. What does that mean? What does that imply for large $n$?" ] }, { @@ -130,7 +130,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.4**: The video introduces the recursive relationship $Sol(4, 1, 3) = Sol(3, 1, 2) ~ \\bigoplus ~ Sol(1, 1, 3) ~ \\bigoplus ~ Sol(3, 2, 3)$. The $\\bigoplus$ is to be interpreted as some sort of \"plus\" operation. How does this \"plus\" operation work? How does this way of expressing the problem relate to the answer to **Q1.1**?" + "**Q4**: The video introduces the recursive relationship $Sol(4, 1, 3) = Sol(3, 1, 2) ~ \\bigoplus ~ Sol(1, 1, 3) ~ \\bigoplus ~ Sol(3, 2, 3)$. The $\\bigoplus$ is to be interpreted as some sort of \"plus\" operation. How does this \"plus\" operation work? How does this way of expressing the problem relate to the answer to **Q1**?" ] }, { @@ -197,7 +197,7 @@ "\n", "Once completed, `sol()` should print out all the moves in the correct order. With **printing a move**, we mean a line like \"1 -> 3\", short for \"Move the top-most disk from spot 1 to spot 3\".\n", "\n", - "Write your answers to **Q1.5** to **Q1.7** into the subsequent code cell and finalize `sol()`! No need to write a docstring or validate the input here." + "Write your answers to **Q5** to **Q7** into the subsequent code cell and finalize `sol()`! No need to write a docstring or validate the input here." ] }, { @@ -208,13 +208,13 @@ "source": [ "def sol(disks, origin, destination):\n", "\n", - " # answer to Q15.5\n", + " # answer to Q5\n", " # ...\n", "\n", - " # answer to Q15.6\n", + " # answer to Q6\n", " # ...\n", "\n", - " # answer to Q15.7\n", + " # answer to Q7\n", " # ..." ] }, @@ -222,14 +222,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.5**: What is the `disks` argument when the function reaches its **base case**? Check for the base case with a simple `if` statement and return from the function using the **early exit** pattern!" + "**Q5**: What is the `disks` argument when the function reaches its **base case**? Check for the base case with a simple `if` statement and return from the function using the **early exit** pattern!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.6**: If not in the base case, `sol()` needs to determine the `intermediate` spot given concrete `origin` and `destination` arguments. For example, if called with `origin=1` and `destination=2`, `intermediate` must be `3`.\n", + "**Q6**: If not in the base case, `sol()` needs to determine the `intermediate` spot given concrete `origin` and `destination` arguments. For example, if called with `origin=1` and `destination=2`, `intermediate` must be `3`.\n", "\n", "Add **one** compound `if` statement to `sol()` that has a branch for **every** possible `origin`-`destination` pair that sets a variable `intermediate` to the correct temporary spot. **How many** branches will there be?" ] @@ -238,7 +238,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.7**: `sol()` needs to call itself **two more times** with the correct 2-pairs chosen from the three available spots `origin`, `intermediate`, and `destination`.\n", + "**Q7**: `sol()` needs to call itself **two more times** with the correct 2-pairs chosen from the three available spots `origin`, `intermediate`, and `destination`.\n", "\n", "In between the two recursive function calls, write a `print()` statement that prints out from where to where the \"remaining and largest\" disk has to be moved!" ] @@ -247,7 +247,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.8**: Execute the code cells below and confirm that the printed moves are correct!" + "**Q8**: Execute the code cells below and confirm that the printed moves are correct!" ] }, { @@ -301,7 +301,7 @@ "\n", "Let's create a more concise `hanoi()` function that, in addition to a positional `disks` argument, takes three keyword-only arguments `origin`, `intermediate`, and `destination` with default values `\"left\"`, `\"center\"`, and `\"right\"`.\n", "\n", - "Write your answers to **Q1.9** and **Q1.10** into the subsequent code cell and finalize `hanoi()`! No need to write a docstring or validate the input here." + "Write your answers to **Q9** and **Q10** into the subsequent code cell and finalize `hanoi()`! No need to write a docstring or validate the input here." ] }, { @@ -312,10 +312,10 @@ "source": [ "def hanoi(disks, *, origin=\"left\", intermediate=\"center\", destination=\"right\"):\n", "\n", - " # answer to Q15.9\n", + " # answer to Q9\n", " # ...\n", "\n", - " # answer to Q15.10\n", + " # answer to Q10\n", " # ..." ] }, @@ -323,14 +323,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.9**: Copy the base case from `sol()`!" + "**Q9**: Copy the base case from `sol()`!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.10**: Instead of conditional logic, `hanoi()` calls itself **two times** with the **three** arguments `origin`, `intermediate`, and `destination` passed on in a **different** order.\n", + "**Q10**: Instead of conditional logic, `hanoi()` calls itself **two times** with the **three** arguments `origin`, `intermediate`, and `destination` passed on in a **different** order.\n", "\n", "Figure out how the arguments are passed on in the two recursive `hanoi()` calls!\n", "\n", @@ -341,7 +341,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.11**: Execute the code cells below and confirm that the printed moves are correct!" + "**Q11**: Execute the code cells below and confirm that the printed moves are correct!" ] }, { @@ -415,7 +415,7 @@ "\n", "Let's create a `hanoi_moves()` function that follows the same internal logic as `hanoi()`, but, instead of printing out the moves, returns the number of steps done so far in the recursion.\n", "\n", - "Write your answers to **Q1.12** to **Q1.14** into the subsequent code cell and finalize `hanoi_moves()`! No need to write a docstring or validate the input here." + "Write your answers to **Q12** to **Q14** into the subsequent code cell and finalize `hanoi_moves()`! No need to write a docstring or validate the input here." ] }, { @@ -426,12 +426,12 @@ "source": [ "def hanoi_moves(disks, *, origin=\"left\", intermediate=\"center\", destination=\"right\"):\n", "\n", - " # answer to Q15.12\n", + " # answer to Q12\n", " # ...\n", "\n", - " moves = ... # <- answer to Q15.13\n", - " moves += hanoi_moves(...) # <- answer to Q15.14 between the ()\n", - " moves += hanoi_moves(...) # <- answer to Q15.14 between the ()\n", + " moves = ... # <- answer to Q13\n", + " moves += hanoi_moves(...) # <- answer to Q14 between the ()\n", + " moves += hanoi_moves(...) # <- answer to Q14 between the ()\n", "\n", " return moves" ] @@ -440,21 +440,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.12**: Copy the base case from `hanoi()`! What count should be returned when it is reached?" + "**Q12**: Copy the base case from `hanoi()`! What count should be returned when it is reached?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.13**: Initialize the variable `moves` with an appropriate count! This is the number of moves that corresponds to **one** recursive function call." + "**Q13**: Initialize the variable `moves` with an appropriate count! This is the number of moves that corresponds to **one** recursive function call." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.14**: `moves` is updated with the counts passed up from the two recursive calls.\n", + "**Q14**: `moves` is updated with the counts passed up from the two recursive calls.\n", "\n", "Complete the two recursive function calls with the same arguments as in `hanoi()`!" ] @@ -463,7 +463,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.15**: Write a `for`-loop that prints out the **minimum number** of moves needed to solve Towers of Hanoi for any number of `disks` from `1` through `20` to confirm your answer to **Q1.2**." + "**Q15**: Write a `for`-loop that prints out the **minimum number** of moves needed to solve Towers of Hanoi for any number of `disks` from `1` through `20` to confirm your answer to **Q2**." ] }, { @@ -491,7 +491,7 @@ "\n", "With `disks` in the range from `24` through `26`, the computation time roughly doubles for each increase of `disks` by 1.\n", "\n", - "**Q1.16**: Execute the code cells below and see for yourself!" + "**Q16**: Execute the code cells below and see for yourself!" ] }, { @@ -537,7 +537,7 @@ "source": [ "The above `hanoi()` prints the optimal solution's moves in the correct order but fails to label each move with an order number. This can be built in by passing on one more argument `offset` down the recursion tree. As the logic gets a bit \"involved,\" `hanoi_ordered()` below is almost finished.\n", "\n", - "Write your answers to **Q1.17** and **Q1.18** into the subsequent code cell and finalize `hanoi_ordered()`! No need to write a docstring or validate the input here." + "Write your answers to **Q17** and **Q18** into the subsequent code cell and finalize `hanoi_ordered()`! No need to write a docstring or validate the input here." ] }, { @@ -548,7 +548,7 @@ "source": [ "def hanoi_ordered(disks, *, origin=\"left\", intermediate=\"center\", destination=\"right\", offset=None):\n", "\n", - " # answer to Q15.17\n", + " # answer to Q17\n", " # ...\n", "\n", " total = (2 ** disks - 1)\n", @@ -558,23 +558,23 @@ " if offset is not None:\n", " count += offset\n", "\n", - " hanoi_ordered(..., offset=offset) # <- answer to Q15.18\n", - " # ... <- answer to Q15.18\n", - " hanoi_ordered(..., offset=count) # <- answer to Q15.18" + " hanoi_ordered(..., offset=offset) # <- answer to Q18\n", + " # ... <- answer to Q18\n", + " hanoi_ordered(..., offset=count) # <- answer to Q18" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.17**: Copy the base case from the original `hanoi()`!" + "**Q17**: Copy the base case from the original `hanoi()`!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.18**: Complete the two recursive function calls with the same arguments as in `hanoi()` or `hanoi_moves()`! Do not change the already filled in `offset` arguments!\n", + "**Q18**: Complete the two recursive function calls with the same arguments as in `hanoi()` or `hanoi_moves()`! Do not change the already filled in `offset` arguments!\n", "\n", "Then, copy the `print()` statement from `hanoi()` and adjust it to print out `count` as well!" ] @@ -583,7 +583,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.19**: Execute the code cells below and confirm that the order numbers are correct!" + "**Q19**: Execute the code cells below and confirm that the order numbers are correct!" ] }, { @@ -640,7 +640,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1.20**: Conducting your own research on the internet (max. 15 minutes), what can you say about generalizing the **[Towers of Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi)** problem to a setting with **more than three** landing spots?" + "**Q20**: Conducting your own research on the internet (max. 15 minutes), what can you say about generalizing the **[Towers of Hanoi](https://en.wikipedia.org/wiki/Tower_of_Hanoi)** problem to a setting with **more than three** landing spots?" ] }, {