diff --git a/00_start_up.ipynb b/00_start_up.ipynb index 7551dcd..506c6ad 100644 --- a/00_start_up.ipynb +++ b/00_start_up.ipynb @@ -19,7 +19,7 @@ } }, "source": [ - "This course is set up to be a *thorough* introduction to programming in [Python](https://www.python.org/).\n", + "This book is set up to be a *thorough* introduction to programming in [Python](https://www.python.org/).\n", "\n", "It teaches the concepts behind and the syntax of the core Python language as defined by the [Python Software Foundation](https://www.python.org/psf/) in the official [language reference](https://docs.python.org/3/reference/index.html) and introduces additions to the language as distributed with the [standard library](https://docs.python.org/3/library/index.html) that come with every installation.\n", "\n", @@ -58,10 +58,10 @@ "source": [ "To be suitable for *total beginners*, there are *no* formal prerequisites. It is only expected that the student has:\n", "\n", - "- a *solid* understanding of the **English language** (i.e., usage of *technical* terms with *narrow* and *distinct* meanings),\n", - "- knowledge of **basic mathematics** from high school (i.e., addition, subtraction, multiplication, division, and a little bit of calculus and statistics),\n", - "- the ability to **think conceptually** and **reason logically** (i.e., *not* just memorizing), and\n", - "- the willingness to **invest 2-4 hours a day for a month** (cf., \"ABC\"-rule at the end)" + "- a *solid* understanding of the **English language**,\n", + "- knowledge of **basic mathematics** from high school,\n", + "- the ability to **think conceptually** and **reason logically**, and\n", + "- the willingness to **invest 2-4 hours a day for a month**." ] }, { @@ -83,7 +83,7 @@ } }, "source": [ - "The course's **main goal** is to **prepare** the student **for further studies** in the \"field\" of **data science**." + "The **main goal** of this introduction is to **prepare** the student **for further studies** in the \"field\" of **data science**." ] }, { @@ -94,7 +94,7 @@ } }, "source": [ - "This includes but is not limited to more advanced courses on topics such as:\n", + "This includes but is not limited to topics such as:\n", "- linear algebra\n", "- statistics & econometrics\n", "- data cleaning & wrangling\n", @@ -154,7 +154,7 @@ } }, "source": [ - "To follow this course, a working installation of **Python 3.6** or higher is needed.\n", + "To follow this book, a working installation of **Python 3.6** or higher is needed.\n", "\n", "A popular and beginner friendly way is to install the [Anaconda Distribution](https://www.anaconda.com/distribution/) that not only ships Python and the standard library but comes pre-packaged with a lot of third-party libraries from the so-called \"scientific stack\". Just go to the [download](https://www.anaconda.com/download/) page and install the latest version (i.e., *2019-07* with Python 3.7 at the time of this writing) for your operating system.\n", "\n", @@ -180,7 +180,7 @@ } }, "source": [ - "To download the course's materials as a ZIP file, open the accompanying [GitHub repository](https://github.com/webartifex/intro-to-python) in a web browser and click on the green \"Clone or download\" button on the right. Then, unpack the ZIP file into a folder of your choosing (ideally somewhere within your personal user folder so that the files show up right away)." + "To download the materials accompanying this book as a ZIP file, open this [GitHub repository](https://github.com/webartifex/intro-to-python) in a web browser and click on the green \"Clone or download\" button on the right. Then, unpack the ZIP file into a folder of your choosing (ideally somewhere within your personal user folder so that the files show up right away)." ] }, { @@ -252,7 +252,7 @@ "\n", "Furthermore, Jupyter notebooks have become a de-facto standard for communicating and exchanging results in the data science community (both in academia and business) and often provide a more intuitive alternative to terminal based ways of running Python (e.g., the default [Python interpreter](https://docs.python.org/3/tutorial/interpreter.html) as shown above or a more advanced interactive version like [IPython](https://ipython.org/)) or even a full-fledged [Integrated Development Environment](https://en.wikipedia.org/wiki/Integrated_development_environment) (e.g., the commercial [PyCharm](https://www.jetbrains.com/pycharm/) or the free [Spyder](https://github.com/spyder-ide/spyder)).\n", "\n", - "In particular, they allow to mix plain English text with Python code cells. The plain text can be formatted using the [Markdown](https://guides.github.com/features/mastering-markdown/) language and mathematical expressions can be typeset with [LaTeX](https://www.overleaf.com/learn/latex/Free_online_introduction_to_LaTeX_%28part_1%29). Lastly, we can include pictures, plots, and even videos. Because of these features, the notebooks developed for this course come in a self-contained \"tutorial\" style that enables students to learn and review the material on their own." + "In particular, they allow to mix plain English text with Python code cells. The plain text can be formatted using the [Markdown](https://guides.github.com/features/mastering-markdown/) language and mathematical expressions can be typeset with [LaTeX](https://www.overleaf.com/learn/latex/Free_online_introduction_to_LaTeX_%28part_1%29). Lastly, we can include pictures, plots, and even videos. Because of these features, the notebooks developed for this book come in a self-contained \"tutorial\" style that enables students to learn and review the material on their own." ] }, { @@ -295,7 +295,15 @@ "slide_type": "slide" } }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello world\n" + ] + } + ], "source": [ "print(\"Hello world\")" ] @@ -351,7 +359,8 @@ } }, "source": [ - "For this course *programming* is \"defined\" as\n", + "In this book *programming* is \"defined\" as:\n", + "\n", "- a **structured** way of **problem solving**\n", "- by **expressing** the steps of a **computation / process**\n", "- and thereby **documenting** the process in a formal way\n", @@ -369,7 +378,8 @@ } }, "source": [ - "That is different from *computer science*, which is\n", + "That is different from *computer science*, which is:\n", + "\n", "- a field of study comparable to (applied) **mathematics** that\n", "- asks **abstract** questions (\"Is something computable at all?\"),\n", "- develops and analyses **algorithms** and **data structures**,\n", @@ -419,6 +429,8 @@ } }, "source": [ + "Here is a brief history of and some background on Python:\n", + "\n", "- [Guido van Rossum](https://en.wikipedia.org/wiki/Guido_van_Rossum) (Python’s **[Benevolent Dictator for Life](https://en.wikipedia.org/wiki/Benevolent_dictator_for_life)**) was bored during a week around Christmas 1989 and started Python as a hobby project \"that would keep \\[him\\] occupied\" for some days\n", "- the idea was to create a **general-purpose scripting** language that would allow fast **prototyping** and would **run on every operating system**\n", "- Python grew through the 90s as van Rossum promoted it via his \"Computer Programming for Everybody\" initiative that had the **goal to encourage a basic level of coding literacy** as an equal knowledge alongside English literacy and math skills\n", @@ -427,17 +439,6 @@ "- the language is named after the sketch comedy group [Monty Python](https://en.wikipedia.org/wiki/Monty_Python)" ] }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "#### Summary" - ] - }, { "cell_type": "markdown", "metadata": { diff --git a/00_start_up_review_and_exercises.ipynb b/00_start_up_review_and_exercises.ipynb index 26eb93c..e1a435f 100644 --- a/00_start_up_review_and_exercises.ipynb +++ b/00_start_up_review_and_exercises.ipynb @@ -18,7 +18,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Read chapter 0 of the book. Then work through the ten review questions." + "Read Chapter 0 of the book. Then work through the ten review questions." ] }, { diff --git a/01_elements_of_a_program.ipynb b/01_elements_of_a_program.ipynb index 66c8e64..c771c87 100644 --- a/01_elements_of_a_program.ipynb +++ b/01_elements_of_a_program.ipynb @@ -120,7 +120,7 @@ "\n", "Lastly, the `average` is calculated as the ratio of the final **values** of `total` and `count`. Overall, we divide the sum of all even numbers by the count of all even numbers, which is exactly what we are looking for.\n", "\n", - "We also observe how the lines of code \"within\" the `for` and `if` **statements** are *indented* and *aligned* with multiples of four spaces: This shows immediately how the lines relate to each other." + "We also observe how the lines of code \"within\" the `for` and `if` **statements** are *indented* and *aligned* with multiples of **four spaces**: This shows immediately how the lines relate to each other." ] }, { @@ -152,7 +152,7 @@ } }, "source": [ - "Yet, we do not see any **output** and obtain the value of `average` by simply referencing it again." + "We do not see any **output** yet but can obtain the value of `average` by simply referencing it again." ] }, { @@ -200,9 +200,7 @@ "source": [ "Note how only two of the previous four code cells generate an **output** while two remained \"silent\" (i.e., there is no \"**Out[...]**\" after running the cell).\n", "\n", - "By default, Jupyter notebooks show the value of a cell's last so-called **expression**. This output can be suppressed by ending the last line with a semicolon.\n", - "\n", - "To visualize something before the end of the cell, we can use the [print()](https://docs.python.org/3/library/functions.html#print) built-in function." + "By default, Jupyter notebooks show the value of a cell's last so-called **expression**. This output can be suppressed by ending the last line with a semicolon `;`." ] }, { @@ -243,6 +241,17 @@ "\"I am invisible!\";" ] }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "To visualize something before the end of the cell, we can use the [print()](https://docs.python.org/3/library/functions.html#print) built-in **function**." + ] + }, { "cell_type": "code", "execution_count": 7, @@ -266,6 +275,39 @@ "print(\"I am feeling great :-)\")" ] }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "Outside Jupyter notebooks, the semicolon `;` is actually used as a **seperator** between several statements that would otherwise have to be on a line on their own. However, it as *not* considered good practice to use it as it makes code less readable." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hello, World!\n", + "I am feeling great :-)\n" + ] + } + ], + "source": [ + "print(\"Hello, World!\"); print(\"I am feeling great :-)\")" + ] + }, { "cell_type": "markdown", "metadata": { @@ -285,7 +327,7 @@ } }, "source": [ - "Python comes with basic mathematical operators built in. **Operators** are built-in **tokens** that have a special meaning to the Python interpreter. Most operators either \"operate\" with the object immediately following them (= **unary** operators; e.g., negation) or somehow \"process\" the two objects \"around\" them (= **binary** operators; e.g., addition). But we will see some exceptions from that as well.\n", + "Python comes with basic mathematical operators built in. **[Operators](https://docs.python.org/3/reference/lexical_analysis.html#operators)** are built-in **tokens** that have a special meaning to the Python interpreter. Most operators either \"operate\" with the object immediately following them (= **unary** operators; e.g., negation) or somehow \"process\" the two objects \"around\" them (= **binary** operators; e.g., addition). But we will see some exceptions from that as well.\n", "\n", "By definition, operators have **no** permanent **side effects** in the computer's memory. Although the code cells in this section do indeed lead to *new* objects being created in memory, they are immediately \"forgotten\" as they are not stored in a **variable** (like `numbers` above). We will revisit this idea further below when we compare **expressions** with **statements**.\n", "\n", @@ -294,7 +336,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": { "slideshow": { "slide_type": "slide" @@ -307,7 +349,7 @@ "90" ] }, - "execution_count": 8, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } @@ -318,7 +360,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": { "slideshow": { "slide_type": "-" @@ -331,7 +373,7 @@ "8" ] }, - "execution_count": 9, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -353,7 +395,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": { "slideshow": { "slide_type": "fragment" @@ -366,7 +408,7 @@ "-1" ] }, - "execution_count": 10, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -388,7 +430,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": { "slideshow": { "slide_type": "slide" @@ -401,7 +443,7 @@ "42" ] }, - "execution_count": 11, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -412,7 +454,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": { "slideshow": { "slide_type": "-" @@ -425,7 +467,7 @@ "42.0" ] }, - "execution_count": 12, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -447,7 +489,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 14, "metadata": { "slideshow": { "slide_type": "slide" @@ -460,7 +502,7 @@ "42" ] }, - "execution_count": 13, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } @@ -471,7 +513,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 15, "metadata": { "slideshow": { "slide_type": "-" @@ -484,7 +526,7 @@ "42" ] }, - "execution_count": 14, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -506,7 +548,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 16, "metadata": { "slideshow": { "slide_type": "slide" @@ -519,7 +561,7 @@ "1" ] }, - "execution_count": 15, + "execution_count": 16, "metadata": {}, "output_type": "execute_result" } @@ -541,7 +583,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 17, "metadata": { "slideshow": { "slide_type": "fragment" @@ -554,7 +596,7 @@ "0" ] }, - "execution_count": 16, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -576,7 +618,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 18, "metadata": { "slideshow": { "slide_type": "fragment" @@ -589,7 +631,7 @@ "3" ] }, - "execution_count": 17, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -600,7 +642,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 19, "metadata": { "slideshow": { "slide_type": "-" @@ -613,7 +655,7 @@ "23" ] }, - "execution_count": 18, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -630,12 +672,12 @@ } }, "source": [ - "The [divmod()](https://docs.python.org/3/library/functions.html#divmod) built-in **function** combines the integer and modulo divisions into one operation. However, this is not an operator any more (but a function). Also observe that [divmod()](https://docs.python.org/3/library/functions.html#divmod) returns a \"pair\" of integers." + "The [divmod()](https://docs.python.org/3/library/functions.html#divmod) built-in function combines the integer and modulo divisions into one operation. However, this is not an operator any more (but a function). Also observe that [divmod()](https://docs.python.org/3/library/functions.html#divmod) returns a \"pair\" of integers." ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 20, "metadata": { "slideshow": { "slide_type": "fragment" @@ -648,7 +690,7 @@ "(4, 2)" ] }, - "execution_count": 19, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -670,7 +712,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 21, "metadata": { "slideshow": { "slide_type": "slide" @@ -683,7 +725,7 @@ "8" ] }, - "execution_count": 20, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -705,7 +747,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 22, "metadata": { "slideshow": { "slide_type": "fragment" @@ -718,7 +760,7 @@ "18" ] }, - "execution_count": 21, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -740,7 +782,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 23, "metadata": { "slideshow": { "slide_type": "-" @@ -753,7 +795,7 @@ "18" ] }, - "execution_count": 22, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -764,7 +806,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 24, "metadata": { "slideshow": { "slide_type": "-" @@ -777,7 +819,7 @@ "81" ] }, - "execution_count": 23, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -799,7 +841,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 25, "metadata": { "slideshow": { "slide_type": "skip" @@ -812,7 +854,7 @@ "18" ] }, - "execution_count": 24, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -840,7 +882,7 @@ } }, "source": [ - "## Objects vs. Values vs. Types" + "## Objects vs. Types vs. Values" ] }, { @@ -860,7 +902,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 26, "metadata": { "slideshow": { "slide_type": "slide" @@ -897,7 +939,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 27, "metadata": { "slideshow": { "slide_type": "slide" @@ -907,31 +949,7 @@ { "data": { "text/plain": [ - "140382247181072" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "id(a)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": { - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "140382247352144" + "139867825605456" ] }, "execution_count": 27, @@ -940,7 +958,7 @@ } ], "source": [ - "id(b)" + "id(a)" ] }, { @@ -955,7 +973,7 @@ { "data": { "text/plain": [ - "140382247028656" + "139867825776440" ] }, "execution_count": 28, @@ -963,6 +981,30 @@ "output_type": "execute_result" } ], + "source": [ + "id(b)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "139867825460912" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "id(c)" ] @@ -975,12 +1017,12 @@ } }, "source": [ - "These addresses are really not that meaningful for anything other than checking if two variables actually point at the same object. This may be helpful as different objects can of course have the same value." + "These addresses are really not that meaningful for anything other than checking if two variables actually **point** at the same object. This may be helpful as different objects can of course have the same value." ] }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 30, "metadata": { "slideshow": { "slide_type": "slide" @@ -1004,7 +1046,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 31, "metadata": { "slideshow": { "slide_type": "-" @@ -1017,7 +1059,7 @@ "True" ] }, - "execution_count": 30, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -1039,7 +1081,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 32, "metadata": { "slideshow": { "slide_type": "-" @@ -1052,7 +1094,7 @@ "False" ] }, - "execution_count": 31, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -1080,12 +1122,12 @@ } }, "source": [ - "The [type()](https://docs.python.org/3/library/functions.html#type) built-in function shows an object's type. For example, `a` is an integer (`int`) while `b` is a so-called [floating-point number](https://en.wikipedia.org/wiki/Floating-point_arithmetic) (`float`)." + "The [type()](https://docs.python.org/3/library/functions.html#type) built-in function shows an object's type. For example, `a` is an integer (i.e., `int`) while `b` is a so-called [floating-point number](https://en.wikipedia.org/wiki/Floating-point_arithmetic) (i.e., `float`)." ] }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 33, "metadata": { "slideshow": { "slide_type": "slide" @@ -1098,7 +1140,7 @@ "int" ] }, - "execution_count": 32, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -1109,7 +1151,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 34, "metadata": { "slideshow": { "slide_type": "-" @@ -1122,7 +1164,7 @@ "float" ] }, - "execution_count": 33, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -1148,7 +1190,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 35, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1161,7 +1203,7 @@ "True" ] }, - "execution_count": 34, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -1183,7 +1225,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 36, "metadata": { "slideshow": { "slide_type": "-" @@ -1197,7 +1239,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mAttributeError\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[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_integer\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[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_integer\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;31mAttributeError\u001b[0m: 'int' object has no attribute 'is_integer'" ] } @@ -1214,12 +1256,12 @@ } }, "source": [ - "The `c` object is a so-called **string** type `str`, which we can view as Python's way of representing \"text\". Strings also come with their own behaviors, for example, to convert a text to lower or upper case." + "The `c` object is a so-called **string** type (i.e., `str`), which we can view as Python's way of representing \"text\". Strings also come with their own behaviors, for example, to convert a text to lower or upper case." ] }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 37, "metadata": { "slideshow": { "slide_type": "slide" @@ -1232,7 +1274,7 @@ "str" ] }, - "execution_count": 36, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -1243,7 +1285,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 38, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1256,7 +1298,7 @@ "'python rocks'" ] }, - "execution_count": 37, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -1267,7 +1309,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 39, "metadata": { "slideshow": { "slide_type": "-" @@ -1280,7 +1322,7 @@ "'PYTHON ROCKS'" ] }, - "execution_count": 38, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -1291,7 +1333,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 40, "metadata": { "slideshow": { "slide_type": "skip" @@ -1304,7 +1346,7 @@ "'Python Rocks'" ] }, - "execution_count": 39, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -1339,7 +1381,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 41, "metadata": { "slideshow": { "slide_type": "slide" @@ -1352,7 +1394,7 @@ "789" ] }, - "execution_count": 40, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -1363,7 +1405,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 42, "metadata": { "slideshow": { "slide_type": "-" @@ -1376,7 +1418,7 @@ "42.0" ] }, - "execution_count": 41, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -1393,12 +1435,12 @@ } }, "source": [ - "In this book, we follow the convention of creating strings with **double quotes** `\"` instead of the **single quotes** `'` to which Python defaults in its literal output. Both types of quotes can be used interchangebly." + "In this book, we follow the convention of creating strings with **double quotes** `\"` instead of the **single quotes** `'` to which Python defaults in its literal output for `str` objects. Both types of quotes can be used interchangebly." ] }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 43, "metadata": { "slideshow": { "slide_type": "-" @@ -1411,13 +1453,13 @@ "'Python rocks'" ] }, - "execution_count": 42, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "c" + "c # we defined c = \"Python rocks\" with double quotes \" above" ] }, { @@ -1463,14 +1505,14 @@ } }, "source": [ - "If we do not follow the rules, the code cannot be **parsed** correctly, i.e., the program does not even start to run but raises a **syntax error** (indicated as `SyntaxError`). Computers are very dumb in the sense that the slightest syntax error leads to the machine not understanding our code.\n", + "If we do not follow the rules, the code cannot be **parsed** correctly, i.e., the program does not even start to run but **raises** a **syntax error** indicated as `SyntaxError` in the output. Computers are very dumb in the sense that the slightest syntax error leads to the machine not understanding our code.\n", "\n", "For example, if we wanted to write an accounting program that adds up currencies, we would have to model dollar prices as `float` objects as the dollar symbol cannot be read by Python." ] }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 44, "metadata": { "slideshow": { "slide_type": "slide" @@ -1479,10 +1521,10 @@ "outputs": [ { "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", + "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m 3.99 $ + 10.40 $\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m 3.99 $ + 10.40 $\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], @@ -1503,7 +1545,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 45, "metadata": { "slideshow": { "slide_type": "slide" @@ -1512,10 +1554,10 @@ "outputs": [ { "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", + "evalue": "invalid syntax (, line 1)", "output_type": "error", "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m for number in numbers\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m for number in numbers\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], @@ -1532,12 +1574,12 @@ } }, "source": [ - "... and relies on whitespace / indentation unlike many other programming languages. A `IndentationError` is just a special type of a `SyntaxError`." + "... and relies on whitespace (i.e., indentation) unlike many other programming languages. An `IndentationError` is just a special type of a `SyntaxError`." ] }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 46, "metadata": { "slideshow": { "slide_type": "slide" @@ -1546,10 +1588,10 @@ "outputs": [ { "ename": "IndentationError", - "evalue": "expected an indented block (, line 2)", + "evalue": "expected an indented block (, line 2)", "output_type": "error", "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m print(number)\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block\n" + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m print(number)\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block\n" ] } ], @@ -1579,14 +1621,14 @@ "source": [ "Syntax errors as above are easy to find as the code will not even run to begin with.\n", "\n", - "However, there are also so-called **runtime errors** (also called **exceptions**) that occur if the code would run given correct input.\n", + "However, there are also so-called **runtime errors**, often called **exceptions**, that occur whenever otherwise (i.e., syntactically) correct code does not run because of invalid input.\n", "\n", "This example does not work because just like in the \"real\" world, Python does not know how to divide by $0$. The syntactically correct code leads to a `ZeroDivisionError`." ] }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 47, "metadata": { "slideshow": { "slide_type": "slide" @@ -1600,7 +1642,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mZeroDivisionError\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[0;36m1\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m0\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[0;36m1\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mZeroDivisionError\u001b[0m: division by zero" ] } @@ -1628,14 +1670,14 @@ } }, "source": [ - "So-called **semantic errors**, on the contrary, can be very hard to spot as they do *not* crash the program. The only way to find such errors is to run the program with test input for which we know the answer already and can then verify it. However, testing software is a whole discipline on its own and often very hard to do in practice.\n", + "So-called **semantic errors**, on the contrary, can be very hard to spot as they do *not* crash the program. The only way to find such errors is to run a program with test input for which we know the answer already and can thus check the output. However, testing software is a whole discipline on its own and often very hard to do in practice.\n", "\n", - "The cell below copies our introductory example from above with a \"tiny\" error." + "The cell below copies our introductory example from above with a \"tiny\" error. How fast could you have spotted it without the comment?" ] }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 48, "metadata": { "code_folding": [], "slideshow": { @@ -1657,7 +1699,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 49, "metadata": { "slideshow": { "slide_type": "-" @@ -1670,7 +1712,7 @@ "3.0" ] }, - "execution_count": 48, + "execution_count": 49, "metadata": {}, "output_type": "execute_result" } @@ -1687,7 +1729,7 @@ } }, "source": [ - "Finding errors is is called **debugging**. For the history of the term, check this [link](https://en.wikipedia.org/wiki/Debugging)." + "Finding errors in a systematic way is called **debugging**. For the history of the term, see this [article](https://en.wikipedia.org/wiki/Debugging)." ] }, { @@ -1709,14 +1751,14 @@ } }, "source": [ - "Adhering to just syntax rules is therefore *never* enough. Over time, **best practices** and common **style guides** were created to make it less likely for a developer to mess up a program and also to allow \"onboarding\" him as a contributor to an established code base (often called **legacy code**) faster. These rules are not enforced by Python itself: Badly styled and un-readable code will still run. At the very least, Python programs should be styled according to [PEP 8](https://www.python.org/dev/peps/pep-0008/) and documented \"inline\" (i.e., in the code itself) according to [PEP 257](https://www.python.org/dev/peps/pep-0257/).\n", + "Adhering to just syntax rules is therefore *never* enough. Over time, **best practices** and common **style guides** were created to make it less likely for a developer to mess up a program and also to allow \"onboarding\" him as a contributor to an established code base, often called **legacy code**, faster. These rules are not enforced by Python itself: Badly styled and un-readable code will still run. At the very least, Python programs should be styled according to [PEP 8](https://www.python.org/dev/peps/pep-0008/) and documented \"inline\" (i.e., in the code itself) according to [PEP 257](https://www.python.org/dev/peps/pep-0257/).\n", "\n", "An easier to read version of PEP 8 can be found [here](https://pep8.org/). The video below features a well known \"[Pythonista](https://en.wiktionary.org/wiki/Pythonista)\" talking about the importance of code style." ] }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 50, "metadata": { "slideshow": { "slide_type": "skip" @@ -1738,10 +1780,10 @@ " " ], "text/plain": [ - "" + "" ] }, - "execution_count": 49, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } @@ -1759,12 +1801,12 @@ } }, "source": [ - "For example, while the above code to calculate the average of the even numbers from 1 through 10 is correct, a Pythonista would re-write it in a more \"Pythonic\" way and use the [sum()](https://docs.python.org/3/library/functions.html#sum) and [len()](https://docs.python.org/3/library/functions.html#len) (= \"length\") built-in functions. Pythonic code runs faster in many cases and is less error prone." + "For example, while the above code to calculate the average of the even numbers from 1 through 10 is correct, a Pythonista would re-write it in a more \"Pythonic\" way and use the [sum()](https://docs.python.org/3/library/functions.html#sum) and [len()](https://docs.python.org/3/library/functions.html#len) (= \"length\") built-in functions (cf., Chapter 2) as well as a so-called **list comprehension** (cf., Chapter 7). Pythonic code runs faster in many cases and is less error prone." ] }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 51, "metadata": { "slideshow": { "slide_type": "slide" @@ -1777,7 +1819,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 52, "metadata": { "slideshow": { "slide_type": "-" @@ -1785,12 +1827,12 @@ }, "outputs": [], "source": [ - "evens = [n for n in numbers if n % 2 == 0] # example for a so-called list comprehension" + "evens = [n for n in numbers if n % 2 == 0] # example of a so-called list comprehension" ] }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 53, "metadata": { "slideshow": { "slide_type": "-" @@ -1803,7 +1845,7 @@ "[2, 4, 6, 8, 10]" ] }, - "execution_count": 52, + "execution_count": 53, "metadata": {}, "output_type": "execute_result" } @@ -1814,7 +1856,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 54, "metadata": { "slideshow": { "slide_type": "-" @@ -1827,7 +1869,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 55, "metadata": { "slideshow": { "slide_type": "-" @@ -1840,7 +1882,7 @@ "6.0" ] }, - "execution_count": 54, + "execution_count": 55, "metadata": {}, "output_type": "execute_result" } @@ -1862,7 +1904,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 56, "metadata": { "slideshow": { "slide_type": "slide" @@ -1961,7 +2003,7 @@ "\n", "At the same time, for a beginner's course it is often easier to just code in a linear fashion.\n", "\n", - "In real data science projects one would probably employ a mixed approach and put re-usable code into so-called Python modules (= \\*.py files) and then use Jupyter notebooks to built up a linear report or story line for a business argument to be made." + "In real data science projects one would probably employ a mixed approach and put re-usable code into so-called Python modules (i.e., *.py* files; cf., Chapter 2) and then use Jupyter notebooks to built up a linear report or story line for a business argument to be made." ] }, { @@ -1972,7 +2014,7 @@ } }, "source": [ - "## Variables / Names" + "## Variables vs. Names vs. Identifiers" ] }, { @@ -1983,12 +2025,14 @@ } }, "source": [ - "**Variables** are created with the **assignment statement** `=`. As its name suggests, it is *not* an operator, mainly because of its side effect of making a **name** \"point\" to an object in memory." + "**Variables** are created with the **[assignment statement](https://docs.python.org/3/reference/simple_stmts.html#assignment-statements)** `=`, which is *not* an operator, mainly because of its side effect of making a **[name](https://docs.python.org/3/reference/lexical_analysis.html#identifiers)** point to an object in memory.\n", + "\n", + "We will read the terms **variable**, **name**, and **identifier** used interchangebly in many Python related texts. In this book, we adopt the following convention: First, we treat *name* and *identifier* as perfect synonyms but only use the term *name* in the text for clarity. Second, whereas *name* only refers to a string of letters, numbers, and some other symbols, a *variable* refers to the combination of a *name* and a *pointer* to some object in memory." ] }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 57, "metadata": { "slideshow": { "slide_type": "slide" @@ -2008,14 +2052,12 @@ } }, "source": [ - "When referenced, a variable just evaluates to the value of the object it points to. Colloquially, we could say that `a` evaluates to `20.0` here but this would not be an accurate description of what is really going on in memory.\n", - "\n", - "We will see some more colloquial jargons in this section but should always remind ourselves what we better said instead." + "When referenced, a variable evaluates to the value of the object it points to. Colloquially, we could say that `a` evaluates to `20.0` here but this would not be a full description of what is really going on in memory. We will see some more colloquial jargons in this section but should always relate this to what Python actually does in memory." ] }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 58, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2028,7 +2070,7 @@ "20.0" ] }, - "execution_count": 57, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -2050,7 +2092,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 59, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2058,12 +2100,12 @@ }, "outputs": [], "source": [ - "a = 20" + "a = 20 # this makes a point to an object of a different type" ] }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 60, "metadata": { "slideshow": { "slide_type": "-" @@ -2076,7 +2118,7 @@ "20" ] }, - "execution_count": 59, + "execution_count": 60, "metadata": {}, "output_type": "execute_result" } @@ -2093,12 +2135,12 @@ } }, "source": [ - "If we want to re-assign a variable while referencing its \"old\" (i.e., current) object, we can also **update** it using a so-called **augmented assignment statement** (*not* operator). This implicitly inserts the current \"value\" as the first token on the right-hand side." + "If we want to re-assign a variable while referencing its \"old\" (i.e., current) object, we can also **update** it using a so-called **[augmented assignment statement](https://docs.python.org/3/reference/simple_stmts.html#augmented-assignment-statements)** (*not* operator), originally introduced with [PEP 203](https://www.python.org/dev/peps/pep-0203/). This implicitly inserts the currently mapped object as the first operand on the right-hand side." ] }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 61, "metadata": { "slideshow": { "slide_type": "slide" @@ -2111,7 +2153,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 62, "metadata": { "slideshow": { "slide_type": "-" @@ -2124,7 +2166,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 63, "metadata": { "slideshow": { "slide_type": "-" @@ -2137,7 +2179,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 64, "metadata": { "slideshow": { "slide_type": "-" @@ -2150,7 +2192,7 @@ "42" ] }, - "execution_count": 63, + "execution_count": 64, "metadata": {}, "output_type": "execute_result" } @@ -2167,12 +2209,12 @@ } }, "source": [ - "Variables can be **de-referenced** (i.e., \"deleted\") with the `del` statement. This does *not* \"delete\" the object to which a variable points to. It merely removes the variable from the \"list of all variables\"." + "Variables can be **[de-referenced](https://docs.python.org/3/reference/simple_stmts.html#the-del-statement)** (i.e., \"deleted\") with the `del` statement. This does *not* delete the object to which a variable points to. It merely removes the variable from the \"list of all variables\"." ] }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 65, "metadata": { "slideshow": { "slide_type": "slide" @@ -2185,7 +2227,7 @@ "789" ] }, - "execution_count": 64, + "execution_count": 65, "metadata": {}, "output_type": "execute_result" } @@ -2196,7 +2238,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 66, "metadata": { "slideshow": { "slide_type": "-" @@ -2215,12 +2257,12 @@ } }, "source": [ - "If we refer to an unknown name, a runtime exception occurs, namely a `NameError`." + "If we refer to an unknown name, a runtime error occurs, namely a `NameError`." ] }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 67, "metadata": { "slideshow": { "slide_type": "-" @@ -2234,7 +2276,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\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[0mb\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[0mb\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'b' is not defined" ] } @@ -2251,12 +2293,12 @@ } }, "source": [ - "Some names magically exist when we start Python. In this introductory book, we can safely ignore such variables." + "Some variables magically exist when we start Python. In this introductory book, we can safely ignore them." ] }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 68, "metadata": { "slideshow": { "slide_type": "skip" @@ -2269,7 +2311,7 @@ "'__main__'" ] }, - "execution_count": 67, + "execution_count": 68, "metadata": {}, "output_type": "execute_result" } @@ -2291,7 +2333,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 69, "metadata": { "slideshow": { "slide_type": "slide" @@ -2321,15 +2363,15 @@ " '_22',\n", " '_23',\n", " '_24',\n", - " '_26',\n", + " '_25',\n", " '_27',\n", " '_28',\n", - " '_30',\n", + " '_29',\n", " '_31',\n", " '_32',\n", " '_33',\n", " '_34',\n", - " '_36',\n", + " '_35',\n", " '_37',\n", " '_38',\n", " '_39',\n", @@ -2337,17 +2379,17 @@ " '_40',\n", " '_41',\n", " '_42',\n", - " '_48',\n", + " '_43',\n", " '_49',\n", " '_5',\n", - " '_52',\n", - " '_54',\n", - " '_57',\n", - " '_59',\n", - " '_63',\n", + " '_50',\n", + " '_53',\n", + " '_55',\n", + " '_58',\n", + " '_60',\n", " '_64',\n", - " '_67',\n", - " '_8',\n", + " '_65',\n", + " '_68',\n", " '_9',\n", " '__',\n", " '___',\n", @@ -2425,6 +2467,7 @@ " '_i66',\n", " '_i67',\n", " '_i68',\n", + " '_i69',\n", " '_i7',\n", " '_i8',\n", " '_i9',\n", @@ -2447,7 +2490,7 @@ " 'total']" ] }, - "execution_count": 68, + "execution_count": 69, "metadata": {}, "output_type": "execute_result" } @@ -2477,20 +2520,7 @@ "source": [ "It is important to understand that *several* variables can point to the *same* object in memory. This can be counter-intuitive in the beginning and lead to many hard to track down bugs.\n", "\n", - "This makes `b` point to whatever object `a` points to." - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "outputs": [], - "source": [ - "b = a # this is different from b == a" + "This makes `b` point to whatever object `a` is pointing to." ] }, { @@ -2498,23 +2528,12 @@ "execution_count": 70, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "slide" } }, - "outputs": [ - { - "data": { - "text/plain": [ - "42" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "a" + "b = a" ] }, { @@ -2537,6 +2556,30 @@ "output_type": "execute_result" } ], + "source": [ + "a" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "42" + ] + }, + "execution_count": 72, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "b" ] @@ -2549,14 +2592,14 @@ } }, "source": [ - "For \"simple\" types like `int` or `float` this will never cause confusion.\n", + "For \"simple\" types like `int` or `float` this will never cause troubles.\n", "\n", "Let's \"change the value\" of `a`. Really, let's create a *new* `123` object and make `a` point to it." ] }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 73, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2569,7 +2612,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 74, "metadata": { "slideshow": { "slide_type": "-" @@ -2582,7 +2625,7 @@ "123" ] }, - "execution_count": 73, + "execution_count": 74, "metadata": {}, "output_type": "execute_result" } @@ -2604,7 +2647,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 75, "metadata": { "slideshow": { "slide_type": "-" @@ -2617,7 +2660,7 @@ "42" ] }, - "execution_count": 74, + "execution_count": 75, "metadata": {}, "output_type": "execute_result" } @@ -2634,12 +2677,12 @@ } }, "source": [ - "However, if a name points to an object of a more \"complex\" object, for example, of type `list`, \"weird\" things can happen." + "However, if a variable points to an object of a more \"complex\" type (e.g., `list`), \"weird\" things can happen." ] }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 76, "metadata": { "slideshow": { "slide_type": "slide" @@ -2652,7 +2695,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 77, "metadata": { "slideshow": { "slide_type": "skip" @@ -2665,7 +2708,7 @@ "list" ] }, - "execution_count": 76, + "execution_count": 77, "metadata": {}, "output_type": "execute_result" } @@ -2676,7 +2719,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 78, "metadata": { "slideshow": { "slide_type": "-" @@ -2697,14 +2740,14 @@ "source": [ "Let's change the first element of `x`.\n", "\n", - "Chapter 7 discusses lists in more depth. For now, let's just view a list as some sort of **container** object that holds an arbitrary number of pointers to other objects and treat the brackets `[...]` attached to `x` as just another operator, called the **indexing operator**. `x[0]` instructs Python to first \"follow\" the pointer from the \"global\" directory of all names to the list object. Then, it follows the first pointer it finds there to the `1` object. The indexing operator must be an operator as we merely read the first element an do not change anything in memory.\n", + "Chapter 7 discusses lists in more depth. For now, let's just view a `list` object as some sort of **container** that holds an arbitrary number of pointers to other objects and treat brackets `[]` attached to it as just another operator, called the **indexing operator**. `x[0]` instructs Python to first follow the pointer from the \"global\" directory of all names to the `x` object. Then, it follows the first pointer it finds there to the `1` object. The indexing operator must be an operator as we merely read the first element and do not change anything in memory.\n", "\n", - "Note how Python **begins counting at 0**. This is not the case for many other languages, for example, MATLAB, R, or Stata. To understand why this makes sense, see this short [note](https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html) by one of the all-time greats in computer science, the late [Edsger Dijkstra](https://en.wikipedia.org/wiki/Edsger_W._Dijkstra)." + "Note how Python **begins counting at 0**. This is not the case for many other languages, for example, [MATLAB](https://en.wikipedia.org/wiki/MATLAB), [R](https://en.wikipedia.org/wiki/R_%28programming_language%29), or [Stata](https://en.wikipedia.org/wiki/Stata). To understand why this makes sense, see this short [note](https://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html) by one of the all-time greats in computer science, the late [Edsger Dijkstra](https://en.wikipedia.org/wiki/Edsger_W._Dijkstra)." ] }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 79, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2717,7 +2760,7 @@ "1" ] }, - "execution_count": 78, + "execution_count": 79, "metadata": {}, "output_type": "execute_result" } @@ -2734,12 +2777,12 @@ } }, "source": [ - "To change the first entry in the list, we use the assignment statement `=` again. Here, this does actually *not* create a *new* variable but only changes the object to which the first pointer in the `x` list points to. As we only change parts of the `x` list, we say that we change its **state**." + "To change the first entry in the list, we use the assignment statement `=` again. Here, this does actually *not* create a *new* variable (or overwrite an existing one) but only changes the object to which the first pointer in the `x` list points to. As we only change parts of the `x` object, we say that we **mutate** (i.e., change) its **state**." ] }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 80, "metadata": { "slideshow": { "slide_type": "slide" @@ -2752,7 +2795,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 81, "metadata": { "slideshow": { "slide_type": "-" @@ -2765,7 +2808,7 @@ "[99, 2, 3]" ] }, - "execution_count": 80, + "execution_count": 81, "metadata": {}, "output_type": "execute_result" } @@ -2782,12 +2825,12 @@ } }, "source": [ - "The changes made to `x` can also be seen through the `y` variable." + "The changes made to the object `x` is pointing to can also be seen through the `y` variable!" ] }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 82, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2800,7 +2843,7 @@ "[99, 2, 3]" ] }, - "execution_count": 81, + "execution_count": 82, "metadata": {}, "output_type": "execute_result" } @@ -2823,7 +2866,7 @@ "\n", "In the second case, `x[0] = 99` creates a *new* integer object `99` and merely changes the first pointer in the `x` list.\n", "\n", - "In general, the assignment statement (re-)creates a variable and makes it point to whatever object is on the right-hand side *if* the left-hand side is a *pure* variable name. Otherwise, it changes some object on the left-hand side (this is strictly not a must but we should expect it).\n", + "In general, the assignment statement creates (or overwrites) a variable and makes it point to whatever object is on the right-hand side *only if* the left-hand side is a *pure* name (i.e., it contains no operators like the indexing operator in the example). Otherwise, it mutates some already existing object. And we always have to expect that the latter might have more than one variable pointing at it.\n", "\n", "In the beginning, visualizing the memory with a tool like [PythonTutor](http://pythontutor.com/visualize.html#code=x%20%3D%20%5B1,%202,%203%5D%0Ay%20%3D%20x%0Ax%5B0%5D%20%3D%2099%0Adel%20x,%20y%0Ax%20%3D%20%5B1,%202,%203%5D%0Ay%20%3D%20x.copy%28%29%0Ax%5B0%5D%20%3D%2099&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false) will assist in understanding what is going on." ] @@ -2880,7 +2923,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 83, "metadata": { "slideshow": { "slide_type": "slide" @@ -2893,7 +2936,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 84, "metadata": { "slideshow": { "slide_type": "-" @@ -2906,7 +2949,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 85, "metadata": { "slideshow": { "slide_type": "-" @@ -2919,7 +2962,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 86, "metadata": { "slideshow": { "slide_type": "-" @@ -2943,7 +2986,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 87, "metadata": { "slideshow": { "slide_type": "skip" @@ -2956,7 +2999,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 88, "metadata": { "slideshow": { "slide_type": "skip" @@ -2969,7 +3012,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 89, "metadata": { "slideshow": { "slide_type": "skip" @@ -2977,12 +3020,12 @@ }, "outputs": [], "source": [ - "name = \"Alexander\" # name of what ?" + "name = \"Alexander\" # name of what?" ] }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 90, "metadata": { "slideshow": { "slide_type": "skip" @@ -2991,10 +3034,10 @@ "outputs": [ { "ename": "SyntaxError", - "evalue": "can't assign to operator (, line 1)", + "evalue": "can't assign to operator (, line 1)", "output_type": "error", "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m address@work = \"Burgplatz 2, Vallendar\"\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m can't assign to operator\n" + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m address@work = \"Burgplatz 2, Vallendar\"\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m can't assign to operator\n" ] } ], @@ -3015,7 +3058,7 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 91, "metadata": { "slideshow": { "slide_type": "skip" @@ -3034,12 +3077,12 @@ } }, "source": [ - "Variables with leading and trailing double underscores (referred to as **dunder** in Python \"slang\") are used for important built-in variables. Do *not* use this style for custom variables!" + "Variables with leading and trailing double underscores, referred to as **dunder** in Python \"slang\", are used for important built-in variables. Do *not* use this style for custom variables!" ] }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 92, "metadata": { "slideshow": { "slide_type": "skip" @@ -3052,7 +3095,7 @@ "'__main__'" ] }, - "execution_count": 91, + "execution_count": 92, "metadata": {}, "output_type": "execute_result" } @@ -3085,7 +3128,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 93, "metadata": { "slideshow": { "slide_type": "skip" @@ -3107,10 +3150,10 @@ " " ], "text/plain": [ - "" + "" ] }, - "execution_count": 92, + "execution_count": 93, "metadata": {}, "output_type": "execute_result" } @@ -3139,18 +3182,18 @@ } }, "source": [ - "An **expression** is any syntactically correct **combination** of **variables** and **literals** with **operators**. See the [language reference](https://docs.python.org/3/reference/expressions.html) for a full list.\n", + "An **[expression](https://docs.python.org/3/reference/expressions.html)** is any syntactically correct **combination** of **variables** and **literals** with **operators**.\n", "\n", "In simple words, anything that can be used on the right-hand side of an assignment statement without creating a `SyntaxError` is an expression.\n", "\n", - "What we said about individual operators above (namely that they have *no* side effects) should have been put here to begin with. The examples in the section on operators were actually all expressions.\n", + "What we said about individual operators above, namely that they have *no* side effects, should have been put here to begin with. The examples in the section on operators above were actually all expressions!\n", "\n", "The simplest possible expression contains only one variable (or literal)." ] }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 94, "metadata": { "slideshow": { "slide_type": "slide" @@ -3163,7 +3206,7 @@ "123" ] }, - "execution_count": 93, + "execution_count": 94, "metadata": {}, "output_type": "execute_result" } @@ -3174,7 +3217,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 95, "metadata": { "slideshow": { "slide_type": "-" @@ -3187,7 +3230,7 @@ "165" ] }, - "execution_count": 94, + "execution_count": 95, "metadata": {}, "output_type": "execute_result" } @@ -3204,12 +3247,12 @@ } }, "source": [ - "The definition of an expression is **recursive**. So here the sub-expression `a + b` is combined with the literal `3` by the operator `**` to form another expression." + "The definition of an expression is **recursive**. So here the sub-expression `a + b` is combined with the literal `3` by the operator `**` to form the full expression." ] }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 96, "metadata": { "slideshow": { "slide_type": "-" @@ -3222,7 +3265,7 @@ "4492125" ] }, - "execution_count": 95, + "execution_count": 96, "metadata": {}, "output_type": "execute_result" } @@ -3239,12 +3282,12 @@ } }, "source": [ - "As before, the bracket operator `[...]` can be used for indexing." + "Here, the variable `y` is combined with the literal `2` by the indexing operator `[]`. The resulting expression evaluates to the " ] }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 97, "metadata": { "slideshow": { "slide_type": "-" @@ -3257,7 +3300,7 @@ "3" ] }, - "execution_count": 96, + "execution_count": 97, "metadata": {}, "output_type": "execute_result" } @@ -3274,12 +3317,12 @@ } }, "source": [ - "When not used as a **delimiter**, parentheses also constitute an operator, namely the **call operator** `(...)`. We have seen this syntax above when we \"called\" (i.e., executed) built-in functions and methods." + "When not used as a **delimiter**, parentheses also constitute an operator, namely the **call operator** `()`. We have seen this syntax above when we \"called\" (i.e., executed) built-in functions and methods." ] }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 98, "metadata": { "slideshow": { "slide_type": "-" @@ -3292,7 +3335,7 @@ "104" ] }, - "execution_count": 97, + "execution_count": 98, "metadata": {}, "output_type": "execute_result" } @@ -3325,7 +3368,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 99, "metadata": { "slideshow": { "slide_type": "slide" @@ -3339,7 +3382,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 100, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3352,7 +3395,7 @@ "'Hi class'" ] }, - "execution_count": 99, + "execution_count": 100, "metadata": {}, "output_type": "execute_result" } @@ -3374,7 +3417,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 101, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3387,7 +3430,7 @@ "'Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi '" ] }, - "execution_count": 100, + "execution_count": 101, "metadata": {}, "output_type": "execute_result" } @@ -3415,14 +3458,14 @@ } }, "source": [ - "A **statement** is anything that changes the state of the program's memory or has some other side effect. Statements do not just evaluate to a value like expressions; instead, they create or change values. See the [language reference](https://docs.python.org/3/reference/simple_stmts.html) for a full list.\n", + "A **[statement](https://docs.python.org/3/reference/simple_stmts.html)** is anything that changes the state of the program's memory or has some other side effect. Statements do not just evaluate to a value like expressions; instead, they create or change values.\n", "\n", "Most notably of course are the `=` and `del` statements." ] }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 102, "metadata": { "slideshow": { "slide_type": "slide" @@ -3435,7 +3478,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 103, "metadata": { "slideshow": { "slide_type": "-" @@ -3459,7 +3502,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 104, "metadata": { "slideshow": { "slide_type": "skip" @@ -3506,7 +3549,7 @@ }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 105, "metadata": { "slideshow": { "slide_type": "slide" @@ -3534,7 +3577,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 106, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3547,7 +3590,7 @@ }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 107, "metadata": { "slideshow": { "slide_type": "-" @@ -3655,7 +3698,7 @@ "\n", "- flow control (cf., Chapter 3)\n", " - expression of **logic** or an **algorithm**\n", - " - conditional execution of a small **branch** within a program (i.e., `if`-statements)\n", + " - conditional execution of a small **branch** within a program (i.e., `if` statements)\n", " - repetitive execution of parts of a program (i.e., `for`-loops and `while`-loops)" ] } diff --git a/01_elements_of_a_program_review_and_exercises.ipynb b/01_elements_of_a_program_review_and_exercises.ipynb index 088001b..2207ccc 100644 --- a/01_elements_of_a_program_review_and_exercises.ipynb +++ b/01_elements_of_a_program_review_and_exercises.ipynb @@ -19,7 +19,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Read chapter 1 of the book. Then work through the ten review questions." + "Read Chapter 1 of the book. Then work through the ten review questions." ] }, { @@ -180,7 +180,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q10**: [PEP 8](https://www.python.org/dev/peps/pep-0008/) suggests that developers use **$8$ spaces** per level of indentation." + "**Q10**: [PEP 8](https://www.python.org/dev/peps/pep-0008/) suggests that developers use **8 spaces** per level of indentation." ] }, { @@ -263,7 +263,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q11.3**: Lastly, what does the `end=\"\\n\"` mean in the documentation? Use it in the `for`-loop to print the numbers $1$ through $10$ in just one line." + "**Q11.3**: Lastly, what does the `end=\"\\n\"` mean in the documentation? Use it in the `for`-loop to print the numbers 1 through 10 in just one line." ] }, { @@ -298,7 +298,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q11.1**: First, create a list `numbers` with the numbers from $1$ through $100$. You could type all numbers manually but there is of course a smarter way. The built-in [range()](https://docs.python.org/3/library/functions.html#func-range) may be useful here. Read how it works in the documentation. To make the output of [range()](https://docs.python.org/3/library/functions.html#func-range) a `list` object, you have to \"wrap\" it with the [list()](https://docs.python.org/3/library/functions.html#func-list) built-in (i.e., `list(range(...))`)." + "**Q11.1**: First, create a list `numbers` with the numbers from 1 through 100. You could type all numbers manually but there is of course a smarter way. The built-in [range()](https://docs.python.org/3/library/functions.html#func-range) may be useful here. Read how it works in the documentation. To make the output of [range()](https://docs.python.org/3/library/functions.html#func-range) a `list` object, you have to \"wrap\" it with the [list()](https://docs.python.org/3/library/functions.html#func-list) built-in (i.e., `list(range(...))`)." ] }, { @@ -335,7 +335,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q11.3**: Create a loop that prints out either the number or any of the Fizz Buzz substitutes. Do it in such a way that we do not end up with $100$ lines of output here." + "**Q11.3**: Create a loop that prints out either the number or any of the Fizz Buzz substitutes. Do it in such a way that we do not end up with 100 lines of output here." ] }, {