From e24cf31104dda53acf752414987183517b40f695 Mon Sep 17 00:00:00 2001 From: Alexander Hess Date: Tue, 28 Jan 2020 10:48:37 +0100 Subject: [PATCH] Restructure *.ipynb files - split review and exercises into files on their own - update the contents overviews to include links to reviews and exercises --- ...t_up.ipynb => 00_start_up_00_content.ipynb | 35 +- ...cises.ipynb => 00_start_up_10_review.ipynb | 81 +- 00_start_up_20_exercises.ipynb | 115 ++ ...ents.ipynb => 01_elements_00_content.ipynb | 199 ++-- ...cises.ipynb => 01_elements_10_review.ipynb | 96 +- 01_elements_20_exercises.ipynb | 139 +++ ...ons.ipynb => 02_functions_00_content.ipynb | 564 +++++---- ...ises.ipynb => 02_functions_10_review.ipynb | 192 +-- 02_functions_20_exercises.ipynb | 234 ++++ ....ipynb => 03_conditionals_00_content.ipynb | 357 +++--- 03_conditionals_10_review.ipynb | 214 ++++ ...pynb => 03_conditionals_20_exercises.ipynb | 195 +--- ...ion.ipynb => 04_iteration_00_content.ipynb | 162 ++- 04_iteration_10_review.ipynb | 281 +++++ ...s.ipynb => 04_iteration_20_exercises.ipynb | 310 +---- ...mbers.ipynb => 05_numbers_00_content.ipynb | 1032 ++++++++--------- 05_numbers_10_review.ipynb | 347 ++++++ 05_numbers_20_exercises.ipynb | 412 +++++++ 05_numbers_review_and_exercises.ipynb | 706 ----------- 06_text.ipynb => 06_text_00_content.ipynb | 586 ++++++---- ...exercises.ipynb => 06_text_10_review.ipynb | 8 +- ...ces.ipynb => 07_sequences_00_content.ipynb | 109 +- 07_sequences_10_review.ipynb | 397 +++++++ ...s.ipynb => 07_sequences_20_exercises.ipynb | 438 +------ ...ings.ipynb => 08_mappings_00_content.ipynb | 175 +-- 08_mappings_10_review.ipynb | 261 +++++ ...es.ipynb => 08_mappings_20_exercises.ipynb | 242 +--- README.md | 51 +- 28 files changed, 4335 insertions(+), 3603 deletions(-) rename 00_start_up.ipynb => 00_start_up_00_content.ipynb (94%) rename 00_start_up_review_and_exercises.ipynb => 00_start_up_10_review.ipynb (60%) create mode 100644 00_start_up_20_exercises.ipynb rename 01_elements.ipynb => 01_elements_00_content.ipynb (97%) rename 01_elements_review_and_exercises.ipynb => 01_elements_10_review.ipynb (64%) create mode 100644 01_elements_20_exercises.ipynb rename 02_functions.ipynb => 02_functions_00_content.ipynb (91%) rename 02_functions_review_and_exercises.ipynb => 02_functions_10_review.ipynb (50%) create mode 100644 02_functions_20_exercises.ipynb rename 03_conditionals.ipynb => 03_conditionals_00_content.ipynb (95%) create mode 100644 03_conditionals_10_review.ipynb rename 03_conditionals_review_and_exercises.ipynb => 03_conditionals_20_exercises.ipynb (53%) rename 04_iteration.ipynb => 04_iteration_00_content.ipynb (96%) create mode 100644 04_iteration_10_review.ipynb rename 04_iteration_review_and_exercises.ipynb => 04_iteration_20_exercises.ipynb (64%) rename 05_numbers.ipynb => 05_numbers_00_content.ipynb (96%) create mode 100644 05_numbers_10_review.ipynb create mode 100644 05_numbers_20_exercises.ipynb delete mode 100644 05_numbers_review_and_exercises.ipynb rename 06_text.ipynb => 06_text_00_content.ipynb (90%) rename 06_text_review_and_exercises.ipynb => 06_text_10_review.ipynb (94%) rename 07_sequences.ipynb => 07_sequences_00_content.ipynb (97%) create mode 100644 07_sequences_10_review.ipynb rename 07_sequences_review_and_exercises.ipynb => 07_sequences_20_exercises.ipynb (70%) rename 08_mappings.ipynb => 08_mappings_00_content.ipynb (96%) create mode 100644 08_mappings_10_review.ipynb rename 08_mappings_review_and_exercises.ipynb => 08_mappings_20_exercises.ipynb (56%) diff --git a/00_start_up.ipynb b/00_start_up_00_content.ipynb similarity index 94% rename from 00_start_up.ipynb rename to 00_start_up_00_content.ipynb index 9aed12d..6e3d84a 100644 --- a/00_start_up.ipynb +++ b/00_start_up_00_content.ipynb @@ -152,9 +152,9 @@ } }, "source": [ - "To \"read\" this book in the most meaningful way, a working installation of **Python 3.6** or higher is needed.\n", + "To \"read\" this book in the most meaningful way, a working installation of **Python 3.7** or higher is expected.\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", + "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-10* with Python 3.7 at the time of this writing) for your operating system.\n", "\n", "Then, among others, you find an entry \"Jupyter Notebook\" in your start menu like below. Click on it to open a new tab in your web browser where you can switch between folders as you could in your computer's default file browser." ] @@ -330,7 +330,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Python 3.7.3\r\n" + "Python 3.7.4\n" ] } ], @@ -649,7 +649,7 @@ } }, "source": [ - "Even popular news and media outlets notice the recent popularity of Python: [Economist](https://www.economist.com/graphic-detail/2018/07/26/python-is-becoming-the-worlds-most-popular-coding-language), [Huffington Post](https://www.huffingtonpost.com/entry/why-python-is-the-best-programming-language-with-which_us_59ef8f62e4b04809c05011b9), [TechRepublic](https://www.techrepublic.com/article/why-python-is-so-popular-with-developers-3-reasons-the-language-has-exploded/), and [QZ](https://qz.com/1408660/the-rise-of-python-as-seen-through-a-decade-of-stack-overflow/)." + "[IEEE Sprectrum](https://spectrum.ieee.org/computing/software/the-top-programming-languages-2019) provides a more recent comparison of programming language's popularity. Even news and media outlets notice the recent popularity of Python: [Economist](https://www.economist.com/graphic-detail/2018/07/26/python-is-becoming-the-worlds-most-popular-coding-language), [Huffington Post](https://www.huffingtonpost.com/entry/why-python-is-the-best-programming-language-with-which_us_59ef8f62e4b04809c05011b9), [TechRepublic](https://www.techrepublic.com/article/why-python-is-so-popular-with-developers-3-reasons-the-language-has-exploded/), and [QZ](https://qz.com/1408660/the-rise-of-python-as-seen-through-a-decade-of-stack-overflow/)." ] }, { @@ -771,14 +771,14 @@ } }, "source": [ - "**Part 1: Expressing Logic**\n", + "**Part A: Expressing Logic**\n", "\n", "- What is a programming language? What kind of words exist?\n", - " 1. [Elements of a Program](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb)\n", - " 2. [Functions & Modularization](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions.ipynb)\n", + " - *Chapter 1*: [Elements of a Program](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb)\n", + " - *Chapter 2*: [Functions & Modularization](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb)\n", "- What is the flow of execution? How can we form sentences from words?\n", - " 3. [Conditionals & Exceptions](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals.ipynb)\n", - " 4. [Recursion & Looping](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb)" + " - *Chapter 3*: [Conditionals & Exceptions](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_content.ipynb)\n", + " - *Chapter 4*: [Recursion & Looping](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb)" ] }, { @@ -789,15 +789,16 @@ } }, "source": [ - "**Part 2: Managing Data and Memory**\n", + "**Part B: Managing Data and Memory**\n", "\n", "- How is data stored in memory?\n", - " 5. [Bits & Numbers](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers.ipynb)\n", - " 6. [Bytes & Text](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb)\n", - " 7. [Sequential Data](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb)\n", - " 8. [Mappings & Sets](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings.ipynb)\n", + " - *Chapter 5*: [Bits & Numbers](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_00_content.ipynb)\n", + " - *Chapter 6*: [Bytes & Text](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text_00_content.ipynb)\n", + " - *Chapter 7*: [Sequential Data](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb)\n", + " - *Chapter 8*: [Mappings & Sets](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_00_content.ipynb)\n", + " - *Chapter 9*: [Arrays & Dataframes](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/09_arrays_00_content.ipynb)\n", "- How can we create custom data types?\n", - " 9. Object-Orientation" + " - *Chapter 10*: Object-Orientation" ] }, { @@ -863,7 +864,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "livereveal": { "auto_select": "code", @@ -891,5 +892,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/00_start_up_review_and_exercises.ipynb b/00_start_up_10_review.ipynb similarity index 60% rename from 00_start_up_review_and_exercises.ipynb rename to 00_start_up_10_review.ipynb index 109a2fc..e8cb215 100644 --- a/00_start_up_review_and_exercises.ipynb +++ b/00_start_up_10_review.ipynb @@ -11,14 +11,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Content Review" + "## Review" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Read [Chapter 0](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up.ipynb) of the book. Then work through the ten review questions." + "Read [Chapter 0](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up_00_content.ipynb) of the book. Then, work through the questions below." ] }, { @@ -32,14 +32,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Answer the following questions briefly with *at most* 300 characters per question!" + "Answer the following questions *briefly*!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1**: Describe the difference between the terms *programming* and *computer science*!" + "**Q1**: Describe the difference between the terms **programming** and **computer science**!" ] }, { @@ -53,7 +53,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q2**: Explain what is a *pull request* and elaborate on how this concept fits a *distributed* organization of work!" + "**Q2**: Explain what is a **pull request** and elaborate on how this concept fits a *distributed* organization of work!" ] }, { @@ -67,7 +67,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q3**: In what sense are open-source communities democracies? How are they near-\"perfect\" [meritocracies](https://en.wikipedia.org/wiki/Meritocracy)? How is open-source software development similar to academia?" + "**Q3**: In what sense are **open-source** communities democracies? How are they near-perfect [meritocracies](https://en.wikipedia.org/wiki/Meritocracy)? How is open-source software development similar to academia?" ] }, { @@ -81,7 +81,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q4**: What is a significant advantage of a \"slow\" programming language like Python over a faster one like C?" + "**Q4**: What is a *significant* advantage of a \"slow\" programming language like Python over a faster one like C?" ] }, { @@ -182,69 +182,6 @@ "**Q10**: The primary purpose of PEPs is to regulate how code should be documented and styled." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## \"Coding\" Exercises" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Mastering Markdown" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Briefly review GitHub's guide on [Mastering Markdown](https://guides.github.com/features/mastering-markdown/) and create nicely formatted \"text\" cells below!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11**: Check the latest [Bundesliga standings](https://www.bundesliga.com/en/bundesliga/table) and provide a table of the top three teams with the following four columns: rank, team name, games played, and points scored. Render the rank in **bold**, make the team name a clickable link (to the team's website), and put both the games played and points scored in *italics*. The header row should be visually different from the three rows with the teams' information." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q12**: The quote \"Education is what remains after one has forgotten what one has learned in school\" is attributed to Albert Einstein. Display the author and his quote appropriately!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q13**: Integrate this image (https://i.ytimg.com/vi/-BoSRlzy9c4/maxresdefault.jpg) of the delicious dessert **milk rice** into this notebook." - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -269,7 +206,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "toc": { "base_numbering": 1, @@ -286,5 +223,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/00_start_up_20_exercises.ipynb b/00_start_up_20_exercises.ipynb new file mode 100644 index 0000000..afd7f26 --- /dev/null +++ b/00_start_up_20_exercises.ipynb @@ -0,0 +1,115 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Chapter 0: Start up" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## \"Coding\" Exercises" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 0](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up_00_content.ipynb) of the book. Then, work through the exercises below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Mastering Markdown" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Briefly review GitHub's guide on [Mastering Markdown](https://guides.github.com/features/mastering-markdown/) and create nicely formatted \"text\" cells below!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1**: Check the latest [Bundesliga standings](https://www.bundesliga.com/en/bundesliga/table) and provide a table of the top three teams with the following four columns: rank, team name, games played, and points scored. Render the rank in **bold**, make the team name a clickable link (to the team's website), and put both the games played and points scored in *italics*. The header row should be visually different from the three rows with the teams' information." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q2**: The quote \"Education is what remains after one has forgotten what one has learned in school\" is attributed to Albert Einstein. Display the author and his quote appropriately!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q3**: Integrate this image (https://i.ytimg.com/vi/-BoSRlzy9c4/maxresdefault.jpg) of the delicious dessert **milk rice** into this notebook." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": true, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": false, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/01_elements.ipynb b/01_elements_00_content.ipynb similarity index 97% rename from 01_elements.ipynb rename to 01_elements_00_content.ipynb index 07d6774..38b63b1 100644 --- a/01_elements.ipynb +++ b/01_elements_00_content.ipynb @@ -936,9 +936,9 @@ "source": [ "Python is a so-called **object-oriented** language, which is a paradigm of organizing a program's memory.\n", "\n", - "An **object** may be viewed as a \"bag\" of $0$s and $1$s in a distinct memory location. The concrete $0$s and $1$s in a bag portray the idea of the object's **value**, and there exist different **types** of bags that each come with associated rules as to how the $0$s and $1$s are interpreted and may be worked with.\n", + "An **object** may be viewed as a \"bag\" of $0$s and $1$s in a given memory location. The $0$s and $1$s in a bag make up the object's **value**. There exist different **types** of bags: Each type comes with distinct rules how the $0$s and $1$s are interpreted and may be worked with.\n", "\n", - "So, an object *always* has **three** main characteristics. Let's look at the following examples and work them out." + "So, an object *always* has *three* main characteristics. Let's look at the following examples and work them out." ] }, { @@ -990,7 +990,7 @@ { "data": { "text/plain": [ - "140398796190992" + "140173037405648" ] }, "execution_count": 28, @@ -1014,7 +1014,7 @@ { "data": { "text/plain": [ - "140398796375888" + "140173037405584" ] }, "execution_count": 29, @@ -1038,7 +1038,7 @@ { "data": { "text/plain": [ - "140398796056176" + "140173037234160" ] }, "execution_count": 30, @@ -1082,7 +1082,7 @@ } }, "source": [ - "`a` and `d` indeed have the same value as is checked with the **equality operator** `==`. The resulting `True` (and the `False` further below) is yet another data type, a so-called **boolean**. We look into them closely in [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals.ipynb#Boolean-Expressions)." + "`a` and `d` indeed have the same value as is checked with the **equality operator** `==`. The resulting `True` (and the `False` further below) is yet another data type, a so-called **boolean**. We look into them closely in [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_content.ipynb#Boolean-Expressions)." ] }, { @@ -1259,7 +1259,7 @@ "source": [ "Different types imply different behaviors for the objects. The `b` object, for example, can be \"asked\" if it could also be interpreted as an `int` with the [is_integer()](https://docs.python.org/3/library/stdtypes.html#float.is_integer) \"functionality\" that comes with every `float` object.\n", "\n", - "Formally, we call such type-specific functionalities **methods** (to differentiate them from functions) and we formally introduce them in Chapter 9. For now, it suffices to know that we access them using the **dot operator** `.`. Of course, `b` could be converted into an `int`, which the boolean value `True` tells us." + "Formally, we call such type-specific functionalities **methods** (to differentiate them from functions) and we formally introduce them in Chapter 10. For now, it suffices to know that we access them using the **dot operator** `.`. Of course, `b` could be converted into an `int`, which the boolean value `True` tells us." ] }, { @@ -1448,7 +1448,7 @@ } }, "source": [ - "Almost trivially, every object also has a value to which it \"evaluates\" when referenced. We think of the value as the **conceptual idea** of what the $0$s and $1$s in memory mean to humans as machines cannot see beyond $0$s and $1$s.\n", + "Almost trivially, every object also has a value to which it \"evaluates\" when referenced. We think of the value as the **conceptual idea** of what the $0$s and $1$s in the bag mean to *humans* as machines cannot see beyond $0$s and $1$s.\n", "\n", "For built-in data types, Python prints out the object's value as a so-called **[literal](https://docs.python.org/3/reference/lexical_analysis.html#literals)**: This means that we can copy and paste the output back into a code cell to create a *new* object with the *same* value." ] @@ -1854,7 +1854,7 @@ " " ], "text/plain": [ - "" + "" ] }, "execution_count": 52, @@ -1875,7 +1875,7 @@ } }, "source": [ - "For example, while the above code to calculate the average of the even numbers in `[7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]` is correct, a Pythonista would rewrite 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](https://docs.python.org/3/library/functions.html) (cf., [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions.ipynb#Built-in-Functions)) as well as a so-called **list comprehension** (cf., [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#List-Comprehensions)). 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 in `[7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]` is correct, a Pythonista would rewrite 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](https://docs.python.org/3/library/functions.html) (cf., [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb#Built-in-Functions)) as well as a so-called **list comprehension** (cf., [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#List-Comprehensions)). Pythonic code runs faster in many cases and is less error-prone." ] }, { @@ -2077,7 +2077,7 @@ "\n", "At the same time, for a beginner's course, it is often easier to code linearly.\n", "\n", - "In real data science projects, one would probably employ a mixed approach and put reusable code into so-called Python modules (i.e., *.py* files; cf., [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions.ipynb#Local-Modules-and-Packages)) and then use Jupyter notebooks to build up a linear report or storyline for a business argument to be made." + "In real data science projects, one would probably employ a mixed approach and put reusable code into so-called Python modules (i.e., *.py* files; cf., [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb#Local-Modules-and-Packages)) and then use Jupyter notebooks to build up a linear report or storyline for a business argument to be made." ] }, { @@ -2367,7 +2367,7 @@ } }, "source": [ - "Some variables magically exist when we start a Python process or are added by Jupyter. We may safely ignore the former until Chapter 9 and the latter for good." + "Some variables magically exist when we start a Python process or are added by Jupyter. We may safely ignore the former until Chapter 10 and the latter for good." ] }, { @@ -2818,7 +2818,7 @@ "source": [ "Let's change the first element of `x`.\n", "\n", - "[Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#The-list-Type) discusses lists in more depth. For now, let's view a `list` object as some sort of **container** that holds an arbitrary number of references to other objects and treat the brackets `[]` attached to it as just another operator, called the **indexing operator**. `x[0]` instructs Python to first follow the reference from the global list of all names to the `x` object. Then, it follows the first reference 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", + "[Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#The-list-Type) discusses lists in more depth. For now, let's view a `list` object as some sort of **container** that holds an arbitrary number of references to other objects and treat the brackets `[]` attached to it as just another operator, called the **indexing operator**. `x[0]` instructs Python to first follow the reference from the global list of all names to the `x` object. Then, it follows the first reference 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](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)." ] @@ -3182,65 +3182,6 @@ "__name__" ] }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "### The big Picture" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "This PyCon talk by [Ned Batchelder](https://nedbatchelder.com/), a well-known Pythonista and the organizer of the [Python User Group](https://www.meetup.com/bostonpython/) in Boston, summarizes all situations where some sort of assignment is done in Python. The content is intermediate, and, thus, it might be worthwhile to come back to this talk at a later point in time. However, the contents should be known by everyone claiming to be proficient in Python." - ] - }, - { - "cell_type": "code", - "execution_count": 95, - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [ - { - "data": { - "image/jpeg": "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\n", - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "execution_count": 95, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from IPython.display import YouTubeVideo\n", - "YouTubeVideo(\"_AEJHKGk9ns\", width=\"60%\")" - ] - }, { "cell_type": "markdown", "metadata": { @@ -3271,7 +3212,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 95, "metadata": { "slideshow": { "slide_type": "slide" @@ -3284,7 +3225,7 @@ "123" ] }, - "execution_count": 96, + "execution_count": 95, "metadata": {}, "output_type": "execute_result" } @@ -3295,7 +3236,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 96, "metadata": {}, "outputs": [ { @@ -3304,7 +3245,7 @@ "42" ] }, - "execution_count": 97, + "execution_count": 96, "metadata": {}, "output_type": "execute_result" } @@ -3322,7 +3263,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 97, "metadata": { "slideshow": { "slide_type": "-" @@ -3335,7 +3276,7 @@ "165" ] }, - "execution_count": 98, + "execution_count": 97, "metadata": {}, "output_type": "execute_result" } @@ -3357,7 +3298,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 98, "metadata": { "slideshow": { "slide_type": "-" @@ -3370,7 +3311,7 @@ "4492125" ] }, - "execution_count": 99, + "execution_count": 98, "metadata": {}, "output_type": "execute_result" } @@ -3392,7 +3333,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 99, "metadata": { "slideshow": { "slide_type": "-" @@ -3405,7 +3346,7 @@ "3" ] }, - "execution_count": 100, + "execution_count": 99, "metadata": {}, "output_type": "execute_result" } @@ -3427,7 +3368,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 100, "metadata": { "slideshow": { "slide_type": "-" @@ -3440,7 +3381,7 @@ "104" ] }, - "execution_count": 101, + "execution_count": 100, "metadata": {}, "output_type": "execute_result" } @@ -3473,7 +3414,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 101, "metadata": { "slideshow": { "slide_type": "slide" @@ -3487,7 +3428,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 102, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3500,7 +3441,7 @@ "'Hi class'" ] }, - "execution_count": 103, + "execution_count": 102, "metadata": {}, "output_type": "execute_result" } @@ -3522,7 +3463,7 @@ }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 103, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3535,7 +3476,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": 104, + "execution_count": 103, "metadata": {}, "output_type": "execute_result" } @@ -3570,7 +3511,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 104, "metadata": { "slideshow": { "slide_type": "slide" @@ -3583,7 +3524,7 @@ }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 105, "metadata": { "slideshow": { "slide_type": "-" @@ -3607,7 +3548,7 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 106, "metadata": { "slideshow": { "slide_type": "skip" @@ -3654,7 +3595,7 @@ }, { "cell_type": "code", - "execution_count": 108, + "execution_count": 107, "metadata": { "slideshow": { "slide_type": "slide" @@ -3682,7 +3623,7 @@ }, { "cell_type": "code", - "execution_count": 109, + "execution_count": 108, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3695,7 +3636,7 @@ }, { "cell_type": "code", - "execution_count": 110, + "execution_count": 109, "metadata": { "slideshow": { "slide_type": "-" @@ -3751,7 +3692,7 @@ " - distinct and well-contained areas/parts of the memory that hold the actual data\n", " - the concept by which Python manages the memory for us\n", " - can be classified into objects of the same **type** (i.e., same abstract \"structure\" but different concrete data)\n", - " - built-in objects (incl. **literals**) vs. user-defined objects (cf., Chapter 9)\n", + " - built-in objects (incl. **literals**) vs. user-defined objects (cf., Chapter 10)\n", " - e.g., `1`, `1.0`, and `\"one\"` are three different objects of distinct types that are also literals (i.e., by the way we type them into the command line Python knows what the value and type are)\n", "\n", "\n", @@ -3786,18 +3727,76 @@ " - ignored by Python\n", "\n", "\n", - "- functions (cf., [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions.ipynb))\n", + "- functions (cf., [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb))\n", " - named sequences of instructions\n", " - the smaller parts in a larger program\n", " - make a program more modular and thus easier to understand\n", " - include [built-in functions](https://docs.python.org/3/library/functions.html) like [print()](https://docs.python.org/3/library/functions.html#print), [sum()](https://docs.python.org/3/library/functions.html#sum), or [len()](https://docs.python.org/3/library/functions.html#len)\n", "\n", "\n", - "- flow control (cf., [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals.ipynb))\n", + "- flow control (cf., [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_content.ipynb))\n", " - expression of **business logic** or an **algorithm**\n", " - conditional execution of parts of a program (e.g., `if` statements)\n", " - repetitive execution of parts of a program (e.g., `for`-loops)" ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "## Further Resources" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "This PyCon 2015 talk by [Ned Batchelder](https://nedbatchelder.com/), a well-known Pythonista and the organizer of the [Python User Group](https://www.meetup.com/bostonpython/) in Boston, summarizes all situations where some sort of assignment is done in Python. The content is intermediate, and, thus, it might be worthwhile to come back to this talk at a later point in time. However, the contents should be known by everyone claiming to be proficient in Python." + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [ + { + "data": { + "image/jpeg": "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\n", + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "execution_count": 110, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "YouTubeVideo(\"_AEJHKGk9ns\", width=\"60%\")" + ] } ], "metadata": { @@ -3816,7 +3815,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "livereveal": { "auto_select": "code", @@ -3844,5 +3843,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/01_elements_review_and_exercises.ipynb b/01_elements_10_review.ipynb similarity index 64% rename from 01_elements_review_and_exercises.ipynb rename to 01_elements_10_review.ipynb index 21ba4c5..1c2ee76 100644 --- a/01_elements_review_and_exercises.ipynb +++ b/01_elements_10_review.ipynb @@ -19,7 +19,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Read [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb) of the book. Then work through the ten review questions." + "Read [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb) of the book. Then, work through the questions below." ] }, { @@ -33,7 +33,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Answer the following questions briefly with *at most* 300 characters per question!" + "Answer the following questions *briefly*!" ] }, { @@ -152,7 +152,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q8**: The **Zen of Python** has a high opinion on Indian genius programmers." + "**Q8**: The **Zen of Python** talks about Indian genius programmers." ] }, { @@ -189,92 +189,6 @@ "source": [ " " ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Coding Exercises" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Printing Output" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11.1**: Read about the [print()](https://docs.python.org/3/library/functions.html#print) built-in. How can you use it to print both `greeting` and `audience` *without* concatenating the two strings with the `+` operator?\n", - "\n", - "Hint: The `*objects` in the documentation implies that we can insert several comma-seperated variables." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "greeting = \"Hello\"\n", - "audience = \"World\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(...)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11.2**: What does the `sep=\" \"` mean in the documentation? Use it to print out the three names in `first`, `second`, and `third` on one line seperated by commas with one [print()](https://docs.python.org/3/library/functions.html#print) statement." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "first = \"Anthony\"\n", - "second = \"Berta\"\n", - "third = \"Christian\"" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "print(...)" - ] - }, - { - "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." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "for number in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:\n", - " print(...)" - ] } ], "metadata": { @@ -293,7 +207,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "toc": { "base_numbering": 1, @@ -310,5 +224,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/01_elements_20_exercises.ipynb b/01_elements_20_exercises.ipynb new file mode 100644 index 0000000..e34097c --- /dev/null +++ b/01_elements_20_exercises.ipynb @@ -0,0 +1,139 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# Chapter 1: Elements of a Program" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Coding Exercises" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb) of the book. Then, work through the exercises below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Printing Output" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.1**: Read about the [print()](https://docs.python.org/3/library/functions.html#print) built-in. How can you use it to print both `greeting` and `audience` *without* concatenating the two strings with the `+` operator?\n", + "\n", + "Hint: The `*objects` in the documentation implies that we can insert several comma-seperated variables." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "greeting = \"Hello\"\n", + "audience = \"World\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(...)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.2**: What does the `sep=\" \"` mean in the documentation? Use it to print out the three names in `first`, `second`, and `third` on one line seperated by commas with one [print()](https://docs.python.org/3/library/functions.html#print) statement." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "first = \"Anthony\"\n", + "second = \"Berta\"\n", + "third = \"Christian\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(...)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.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." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for number in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:\n", + " print(...)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": true, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": false, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/02_functions.ipynb b/02_functions_00_content.ipynb similarity index 91% rename from 02_functions.ipynb rename to 02_functions_00_content.ipynb index 39d7084..d0000d8 100644 --- a/02_functions.ipynb +++ b/02_functions_00_content.ipynb @@ -19,7 +19,7 @@ } }, "source": [ - "In [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Example:-Averaging-Even-Numbers), we typed the code to calculate the average of the even numbers in a list into several code cells. Then, we executed them one after another. We had no way of **reusing** the code except for either executing cells multiple times or copying and pasting their contents into other cells. And, whenever we find ourselves doing repetitive manual work, we can be sure that there must be a way of automating what we are doing.\n", + "In [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Example:-Averaging-Even-Numbers), we typed the code to calculate the average of the even numbers in a list into several code cells. Then, we executed them one after another. We had no way of **reusing** the code except for either executing cells multiple times or copying and pasting their contents into other cells. And, whenever we find ourselves doing repetitive manual work, we can be sure that there must be a way of automating what we are doing.\n", "\n", "At the same time, we executed built-in functions (e.g., [print()](https://docs.python.org/3/library/functions.html#print), [sum()](https://docs.python.org/3/library/functions.html#sum), [len()](https://docs.python.org/3/library/functions.html#len), [id()](https://docs.python.org/3/library/functions.html#id), or [type()](https://docs.python.org/3/library/functions.html#type)) that obviously must be reusing the same parts inside core Python every time we use them.\n", "\n", @@ -45,7 +45,7 @@ } }, "source": [ - "So-called **[user-defined functions](https://docs.python.org/3/reference/compound_stmts.html#function-definitions)** may be created with the `def` statement. To extend an already familiar example, we reuse the introductory example from [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Best-Practices) in its final Pythonic version and transform it into the function `average_evens()` below. \n", + "So-called **[user-defined functions](https://docs.python.org/3/reference/compound_stmts.html#function-definitions)** may be created with the `def` statement. To extend an already familiar example, we reuse the introductory example from [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Best-Practices) in its final Pythonic version and transform it into the function `average_evens()` below. \n", "\n", "A function's **name** must be chosen according to the same naming rules as ordinary variables as Python manages function names like variables. In this book, we further adopt the convention of ending function names with parentheses `()` in text cells for faster comprehension when reading (i.e., `average_evens()` vs. `average_evens`). These are *not* part of the name but must always be written out in the `def` statement for syntactic reasons.\n", "\n", @@ -57,7 +57,7 @@ "\n", "A function may come with an *explicit* **return value** (i.e., \"result\" or \"output\") specified with the `return` statement (cf., [reference](https://docs.python.org/3/reference/simple_stmts.html#the-return-statement)): Functions that have one are considered **fruitful**; otherwise, they are **void**. Functions of the latter kind are still useful because of their **side effects** as, for example, the built-in [print()](https://docs.python.org/3/library/functions.html#print) function. Strictly speaking, they also have an *implicit* return value of `None`.\n", "\n", - "A function should define a **docstring** that describes what it does in a short subject line, what parameters it expects (i.e., their types), and what it returns (if anything). A docstring is a syntactically valid multi-line string (i.e., type `str`) defined within **triple-double quotes** `\"\"\"`. Strings are covered in depth in [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb#The-str-Type). Widely adopted standards as to how to format a docstring are [PEP 257](https://www.python.org/dev/peps/pep-0257/) and section 3.8 in [Google's Python Style Guide](https://github.com/google/styleguide/blob/gh-pages/pyguide.md)." + "A function should define a **docstring** that describes what it does in a short subject line, what parameters it expects (i.e., their types), and what it returns (if anything). A docstring is a syntactically valid multi-line string (i.e., type `str`) defined within **triple-double quotes** `\"\"\"`. Strings are covered in depth in [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text_00_content.ipynb#The-str-Type). Widely adopted standards as to how to format a docstring are [PEP 257](https://www.python.org/dev/peps/pep-0257/) and section 3.8 in [Google's Python Style Guide](https://github.com/google/styleguide/blob/gh-pages/pyguide.md)." ] }, { @@ -142,7 +142,7 @@ { "data": { "text/plain": [ - "140384699277792" + "140371816700960" ] }, "execution_count": 3, @@ -241,7 +241,27 @@ "slide_type": "skip" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[0;31mSignature:\u001b[0m \u001b[0maverage_evens\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnumbers\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mDocstring:\u001b[0m\n", + "Calculate the average of all even numbers in a list.\n", + "\n", + "Args:\n", + " numbers (list): a list of numbers; may be integers or floats\n", + "\n", + "Returns:\n", + " float: average\n", + "\u001b[0;31mFile:\u001b[0m ~/repos/intro-to-python/\n", + "\u001b[0;31mType:\u001b[0m function\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "average_evens?" ] @@ -265,7 +285,32 @@ "slide_type": "skip" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[0;31mSignature:\u001b[0m \u001b[0maverage_evens\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnumbers\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mSource:\u001b[0m \n", + "\u001b[0;32mdef\u001b[0m \u001b[0maverage_evens\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnumbers\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0;34m\"\"\"Calculate the average of all even numbers in a list.\u001b[0m\n", + "\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m Args:\u001b[0m\n", + "\u001b[0;34m numbers (list): a list of numbers; may be integers or floats\u001b[0m\n", + "\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m Returns:\u001b[0m\n", + "\u001b[0;34m float: average\u001b[0m\n", + "\u001b[0;34m \"\"\"\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0mevens\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mn\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mn\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mnumbers\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m%\u001b[0m \u001b[0;36m2\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0maverage\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mevens\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mevens\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0maverage\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mFile:\u001b[0m ~/repos/intro-to-python/\n", + "\u001b[0;31mType:\u001b[0m function\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "average_evens??" ] @@ -337,12 +382,71 @@ } }, "source": [ - "The return value is commonly assigned to a variable for later reference. Otherwise, we would lose access to it in memory right away." + "If we are ever unsure if a variable references a `function` object that may be called, we can verify that with the built-in [callable()](https://docs.python.org/3/library/functions.html#callable) function that takes any object as its only argument and tells us `True` if that is **callable** and `False` otherwise." ] }, { "cell_type": "code", "execution_count": 10, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "callable(average_evens)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "callable(nums)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "The return value is commonly assigned to a variable for later reference. Otherwise, we would lose access to it in memory right away." + ] + }, + { + "cell_type": "code", + "execution_count": 12, "metadata": { "slideshow": { "slide_type": "fragment" @@ -355,7 +459,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 13, "metadata": { "slideshow": { "slide_type": "-" @@ -368,7 +472,7 @@ "7.0" ] }, - "execution_count": 11, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -412,7 +516,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "metadata": { "slideshow": { "slide_type": "slide" @@ -426,7 +530,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[0mnumbers\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[0mnumbers\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'numbers' is not defined" ] } @@ -437,7 +541,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "metadata": { "slideshow": { "slide_type": "-" @@ -451,7 +555,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[0mevens\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[0mevens\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'evens' is not defined" ] } @@ -462,7 +566,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": { "slideshow": { "slide_type": "skip" @@ -476,7 +580,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[0maverage\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[0maverage\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'average' is not defined" ] } @@ -520,7 +624,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "metadata": { "slideshow": { "slide_type": "slide" @@ -555,7 +659,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "metadata": { "slideshow": { "slide_type": "slide" @@ -568,7 +672,7 @@ "[7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]" ] }, - "execution_count": 16, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } @@ -590,7 +694,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "metadata": { "slideshow": { "slide_type": "-" @@ -603,7 +707,7 @@ "7.0" ] }, - "execution_count": 17, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -625,7 +729,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "metadata": { "slideshow": { "slide_type": "-" @@ -638,7 +742,7 @@ "7.0" ] }, - "execution_count": 18, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -657,7 +761,7 @@ "source": [ "[PythonTutor](http://pythontutor.com/visualize.html#code=nums%20%3D%20%5B1,%202,%203,%204,%205,%206,%207,%208,%209,%2010,%2011,%2012%5D%0A%0Adef%20average_wrong%28numbers%29%3A%0A%20%20%20%20evens%20%3D%20%5Bn%20for%20n%20in%20nums%20if%20n%20%25%202%20%3D%3D%200%5D%0A%20%20%20%20average%20%3D%20sum%28evens%29%20/%20len%28evens%29%0A%20%20%20%20return%20average%0A%0Arv%20%3D%20average_wrong%28%5B123,%20456,%20789%5D%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false) is again helpful at visualizing the error interactively: Creating the `list` object `evens` eventually references takes *16* computational steps, namely two for managing the list comprehension, one for setting up an empty `list` object, *twelve* for filling it with elements derived from `nums` in the global scope (i.e., that is the error), and one to make `evens` reference it (cf., steps 6-21).\n", "\n", - "The frames logic shown by PythonTutor is the mechanism by which Python not only manages the names inside *one* function call but also for *many* potentially *simultaneous* calls, as revealed in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Trivial-Example:-Countdown). It is the reason why we may reuse the same names for the parameters and variables inside both `average_evens()` and `average_wrong()` without Python mixing them up. So, as we already read in the [Zen of Python](https://www.python.org/dev/peps/pep-0020/), \"namespaces are one honking great idea\" (cf., `import this`), and a frame is just a special kind of namespace." + "The frames logic shown by PythonTutor is the mechanism by which Python not only manages the names inside *one* function call but also for *many* potentially *simultaneous* calls, as revealed in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#Trivial-Example:-Countdown). It is the reason why we may reuse the same names for the parameters and variables inside both `average_evens()` and `average_wrong()` without Python mixing them up. So, as we already read in the [Zen of Python](https://www.python.org/dev/peps/pep-0020/), \"namespaces are one honking great idea\" (cf., `import this`), and a frame is just a special kind of namespace." ] }, { @@ -686,7 +790,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "metadata": { "slideshow": { "slide_type": "slide" @@ -722,7 +826,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "metadata": { "slideshow": { "slide_type": "slide" @@ -735,7 +839,7 @@ "[7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]" ] }, - "execution_count": 20, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -757,7 +861,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, "metadata": { "slideshow": { "slide_type": "-" @@ -770,7 +874,7 @@ "3.0" ] }, - "execution_count": 21, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -792,7 +896,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 24, "metadata": { "slideshow": { "slide_type": "-" @@ -805,7 +909,7 @@ "6.0" ] }, - "execution_count": 22, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } @@ -827,7 +931,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 25, "metadata": { "slideshow": { "slide_type": "-" @@ -840,7 +944,7 @@ "[7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]" ] }, - "execution_count": 23, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -892,7 +996,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 26, "metadata": { "slideshow": { "slide_type": "slide" @@ -905,7 +1009,7 @@ "12" ] }, - "execution_count": 24, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -916,7 +1020,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 27, "metadata": { "slideshow": { "slide_type": "-" @@ -929,7 +1033,7 @@ "78" ] }, - "execution_count": 25, + "execution_count": 27, "metadata": {}, "output_type": "execute_result" } @@ -951,7 +1055,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 28, "metadata": { "slideshow": { "slide_type": "slide" @@ -964,7 +1068,7 @@ "7.0" ] }, - "execution_count": 26, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -975,7 +1079,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 29, "metadata": { "slideshow": { "slide_type": "-" @@ -988,7 +1092,7 @@ "7" ] }, - "execution_count": 27, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -999,7 +1103,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 30, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1012,7 +1116,7 @@ "7" ] }, - "execution_count": 28, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -1034,7 +1138,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 31, "metadata": { "slideshow": { "slide_type": "slide" @@ -1047,7 +1151,7 @@ "7" ] }, - "execution_count": 29, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -1058,7 +1162,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 32, "metadata": { "slideshow": { "slide_type": "-" @@ -1071,7 +1175,7 @@ "8" ] }, - "execution_count": 30, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -1093,7 +1197,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 33, "metadata": { "slideshow": { "slide_type": "slide" @@ -1107,7 +1211,7 @@ "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[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"seven\"\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[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"seven\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mValueError\u001b[0m: invalid literal for int() with base 10: 'seven'" ] } @@ -1129,7 +1233,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 34, "metadata": { "slideshow": { "slide_type": "skip" @@ -1142,7 +1246,7 @@ "42.0" ] }, - "execution_count": 32, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -1170,12 +1274,12 @@ } }, "source": [ - "So far, we have only specified one parameter in each of our user-defined functions. In [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#%28Arithmetic%29-Operators), however, we saw the built-in function [divmod()](https://docs.python.org/3/library/functions.html#divmod) take two arguments. And, the order of the numbers passed in mattered! Whenever we call a function and list its arguments in a comma separated manner, we say that we pass in the arguments by position or refer to them as **positional arguments**." + "So far, we have only specified one parameter in each of our user-defined functions. In [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#%28Arithmetic%29-Operators), however, we saw the built-in function [divmod()](https://docs.python.org/3/library/functions.html#divmod) take two arguments. And, the order of the numbers passed in mattered! Whenever we call a function and list its arguments in a comma separated manner, we say that we pass in the arguments by position or refer to them as **positional arguments**." ] }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 35, "metadata": { "slideshow": { "slide_type": "slide" @@ -1188,7 +1292,7 @@ "(4, 2)" ] }, - "execution_count": 33, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -1199,7 +1303,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 36, "metadata": { "slideshow": { "slide_type": "-" @@ -1212,7 +1316,7 @@ "(0, 10)" ] }, - "execution_count": 34, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -1234,7 +1338,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 37, "metadata": { "slideshow": { "slide_type": "slide" @@ -1271,7 +1375,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 38, "metadata": { "slideshow": { "slide_type": "slide" @@ -1284,7 +1388,7 @@ "14.0" ] }, - "execution_count": 36, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -1306,54 +1410,6 @@ "Luckily, we may also reference the formal parameter names as **keyword arguments**. We can even combine positional and keyword arguments in the same function call. Each of the following does the *same*." ] }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "14.0" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scaled_average_evens(nums, scalar=2)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "14.0" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "scaled_average_evens(numbers=nums, scalar=2)" - ] - }, { "cell_type": "code", "execution_count": 39, @@ -1374,6 +1430,54 @@ "output_type": "execute_result" } ], + "source": [ + "scaled_average_evens(nums, scalar=2)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "14.0" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "scaled_average_evens(numbers=nums, scalar=2)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "14.0" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "scaled_average_evens(scalar=2, numbers=nums)" ] @@ -1391,7 +1495,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 42, "metadata": { "slideshow": { "slide_type": "slide" @@ -1400,10 +1504,10 @@ "outputs": [ { "ename": "SyntaxError", - "evalue": "positional argument follows keyword argument (, line 1)", + "evalue": "positional argument follows keyword argument (, 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 scaled_average_evens(numbers=nums, 2)\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m positional argument follows keyword argument\n" + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m scaled_average_evens(numbers=nums, 2)\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m positional argument follows keyword argument\n" ] } ], @@ -1439,7 +1543,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 43, "metadata": { "slideshow": { "slide_type": "slide" @@ -1450,7 +1554,13 @@ "def scaled_average_evens(numbers, scalar):\n", " \"\"\"Calculate a scaled average of all even numbers in a list.\n", "\n", - " ...\n", + " Args:\n", + " numbers (list): a list of numbers; may be integers or floats\n", + " scalar (float): the scalar that multiplies the average\n", + " of the even numbers\n", + "\n", + " Returns:\n", + " float: scaled average\n", " \"\"\"\n", " evens = [n for n in numbers if n % 2 == 0]\n", " average = sum(evens) / len(evens)\n", @@ -1459,7 +1569,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 44, "metadata": { "slideshow": { "slide_type": "-" @@ -1470,7 +1580,11 @@ "def average_evens(numbers):\n", " \"\"\"Calculate the average of all even numbers in a list.\n", "\n", - " ...\n", + " Args:\n", + " numbers (list): a list of numbers; may be integers or floats\n", + "\n", + " Returns:\n", + " float: average\n", " \"\"\"\n", " return scaled_average_evens(numbers, scalar=1) # refactored to use the logic in scaled_average_evens()" ] @@ -1488,7 +1602,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 45, "metadata": { "slideshow": { "slide_type": "-" @@ -1501,7 +1615,7 @@ "7.0" ] }, - "execution_count": 43, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -1523,7 +1637,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 46, "metadata": { "slideshow": { "slide_type": "slide" @@ -1562,7 +1676,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 47, "metadata": { "slideshow": { "slide_type": "slide" @@ -1575,7 +1689,7 @@ "7.0" ] }, - "execution_count": 45, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -1586,7 +1700,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 48, "metadata": { "slideshow": { "slide_type": "-" @@ -1599,7 +1713,7 @@ "14.0" ] }, - "execution_count": 46, + "execution_count": 48, "metadata": {}, "output_type": "execute_result" } @@ -1610,7 +1724,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 49, "metadata": { "slideshow": { "slide_type": "-" @@ -1623,7 +1737,7 @@ "14.0" ] }, - "execution_count": 47, + "execution_count": 49, "metadata": {}, "output_type": "execute_result" } @@ -1658,7 +1772,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 50, "metadata": { "slideshow": { "slide_type": "slide" @@ -1695,7 +1809,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 51, "metadata": { "slideshow": { "slide_type": "slide" @@ -1708,7 +1822,7 @@ "7.0" ] }, - "execution_count": 49, + "execution_count": 51, "metadata": {}, "output_type": "execute_result" } @@ -1719,7 +1833,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 52, "metadata": { "slideshow": { "slide_type": "-" @@ -1732,7 +1846,7 @@ "14.0" ] }, - "execution_count": 50, + "execution_count": 52, "metadata": {}, "output_type": "execute_result" } @@ -1754,7 +1868,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 53, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1768,7 +1882,7 @@ "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[0maverage_evens\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnums\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\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[0maverage_evens\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnums\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: average_evens() takes 1 positional argument but 2 were given" ] } @@ -1811,7 +1925,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 54, "metadata": { "slideshow": { "slide_type": "slide" @@ -1824,7 +1938,7 @@ "(x)>" ] }, - "execution_count": 52, + "execution_count": 54, "metadata": {}, "output_type": "execute_result" } @@ -1850,7 +1964,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 55, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1874,7 +1988,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 56, "metadata": { "slideshow": { "slide_type": "-" @@ -1887,7 +2001,7 @@ "13" ] }, - "execution_count": 54, + "execution_count": 56, "metadata": {}, "output_type": "execute_result" } @@ -1909,7 +2023,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 57, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1922,7 +2036,7 @@ "42" ] }, - "execution_count": 55, + "execution_count": 57, "metadata": {}, "output_type": "execute_result" } @@ -1941,7 +2055,7 @@ "source": [ "The main point of having functions without a name is to use them in a situation where we know ahead of time that we use the function only *once*.\n", "\n", - "Popular applications of lambda expressions occur in combination with the **map-filter-reduce** paradigm or when we do \"number crunching\" with **arrays** and **data frames**. We look at both in detail in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb)." + "Popular applications of lambda expressions occur in combination with the **map-filter-reduce** paradigm or when we do \"number crunching\" with **arrays** and **data frames**. We look at both in detail in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb)." ] }, { @@ -2026,7 +2140,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 58, "metadata": { "slideshow": { "slide_type": "slide" @@ -2050,7 +2164,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 59, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2060,10 +2174,10 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 57, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -2074,7 +2188,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 60, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2084,10 +2198,10 @@ { "data": { "text/plain": [ - "140384754610488" + "140371899337520" ] }, - "execution_count": 58, + "execution_count": 60, "metadata": {}, "output_type": "execute_result" } @@ -2098,7 +2212,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 61, "metadata": { "slideshow": { "slide_type": "-" @@ -2111,7 +2225,7 @@ "module" ] }, - "execution_count": 59, + "execution_count": 61, "metadata": {}, "output_type": "execute_result" } @@ -2137,7 +2251,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 62, "metadata": { "slideshow": { "slide_type": "slide" @@ -2205,7 +2319,7 @@ " 'trunc']" ] }, - "execution_count": 60, + "execution_count": 62, "metadata": {}, "output_type": "execute_result" } @@ -2227,7 +2341,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 63, "metadata": { "slideshow": { "slide_type": "slide" @@ -2240,7 +2354,7 @@ "3.141592653589793" ] }, - "execution_count": 61, + "execution_count": 63, "metadata": {}, "output_type": "execute_result" } @@ -2251,7 +2365,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 64, "metadata": { "slideshow": { "slide_type": "-" @@ -2264,7 +2378,7 @@ "2.718281828459045" ] }, - "execution_count": 62, + "execution_count": 64, "metadata": {}, "output_type": "execute_result" } @@ -2275,7 +2389,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 65, "metadata": { "slideshow": { "slide_type": "slide" @@ -2288,7 +2402,7 @@ "" ] }, - "execution_count": 63, + "execution_count": 65, "metadata": {}, "output_type": "execute_result" } @@ -2299,7 +2413,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 66, "metadata": { "slideshow": { "slide_type": "-" @@ -2324,7 +2438,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 67, "metadata": { "slideshow": { "slide_type": "-" @@ -2337,7 +2451,7 @@ "1.4142135623730951" ] }, - "execution_count": 65, + "execution_count": 67, "metadata": {}, "output_type": "execute_result" } @@ -2356,14 +2470,14 @@ "source": [ "Observe how the arguments passed to functions do not need to be just variables or simple literals. Instead, we may pass in any *expression* that evaluates to a *new* object of the type the function expects.\n", "\n", - "So just as a reminder from the expression vs. statement discussion in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Expressions): An expression is *any* syntactically correct combination of variables and literals with operators. And the call operator `()` is yet another operator. So both of the next two code cells are just expressions! They have no permanent side effects in memory. We may execute them as often as we want *without* changing the state of the program (i.e., this Jupyter notebook).\n", + "So just as a reminder from the expression vs. statement discussion in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Expressions): An expression is *any* syntactically correct combination of variables and literals with operators. And the call operator `()` is yet another operator. So both of the next two code cells are just expressions! They have no permanent side effects in memory. We may execute them as often as we want *without* changing the state of the program (i.e., this Jupyter notebook).\n", "\n", "So, regarding the very next cell in particular: Although the `2 ** 2` creates a *new* object `4` in memory that is then immediately passed into the [math.sqrt()](https://docs.python.org/3/library/math.html#math.sqrt) function, once that function call returns, \"all is lost\" and the newly created `4` object is forgotten again, as well as the return value of [math.sqrt()](https://docs.python.org/3/library/math.html#math.sqrt)." ] }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 68, "metadata": { "slideshow": { "slide_type": "-" @@ -2376,7 +2490,7 @@ "2.0" ] }, - "execution_count": 66, + "execution_count": 68, "metadata": {}, "output_type": "execute_result" } @@ -2398,7 +2512,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 69, "metadata": { "slideshow": { "slide_type": "-" @@ -2411,7 +2525,7 @@ "10.0" ] }, - "execution_count": 67, + "execution_count": 69, "metadata": {}, "output_type": "execute_result" } @@ -2435,7 +2549,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 70, "metadata": { "slideshow": { "slide_type": "skip" @@ -2448,7 +2562,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 71, "metadata": { "slideshow": { "slide_type": "skip" @@ -2461,7 +2575,7 @@ "4.0" ] }, - "execution_count": 69, + "execution_count": 71, "metadata": {}, "output_type": "execute_result" } @@ -2494,7 +2608,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 72, "metadata": { "slideshow": { "slide_type": "slide" @@ -2507,7 +2621,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 73, "metadata": { "slideshow": { "slide_type": "-" @@ -2517,10 +2631,10 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 71, + "execution_count": 73, "metadata": {}, "output_type": "execute_result" } @@ -2537,12 +2651,12 @@ } }, "source": [ - "Besides the usual dunder-style attributes, the built-in [dir()](https://docs.python.org/3/library/functions.html#dir) function lists some attributes in an upper case naming convention and many others starting with a *single* underscore `_`. To understand the former, we must wait until Chapter 9, while the latter is explained further below." + "Besides the usual dunder-style attributes, the built-in [dir()](https://docs.python.org/3/library/functions.html#dir) function lists some attributes in an upper case naming convention and many others starting with a *single* underscore `_`. To understand the former, we must wait until Chapter 10, while the latter is explained further below." ] }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 74, "metadata": { "slideshow": { "slide_type": "slide" @@ -2616,7 +2730,7 @@ " 'weibullvariate']" ] }, - "execution_count": 72, + "execution_count": 74, "metadata": {}, "output_type": "execute_result" } @@ -2638,7 +2752,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 75, "metadata": { "slideshow": { "slide_type": "slide" @@ -2651,7 +2765,7 @@ "" ] }, - "execution_count": 73, + "execution_count": 75, "metadata": {}, "output_type": "execute_result" } @@ -2662,7 +2776,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 76, "metadata": { "slideshow": { "slide_type": "-" @@ -2687,7 +2801,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 77, "metadata": { "slideshow": { "slide_type": "-" @@ -2697,10 +2811,10 @@ { "data": { "text/plain": [ - "0.17184403163109208" + "0.64575874518665" ] }, - "execution_count": 75, + "execution_count": 77, "metadata": {}, "output_type": "execute_result" } @@ -2722,7 +2836,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 78, "metadata": { "slideshow": { "slide_type": "slide" @@ -2732,10 +2846,10 @@ { "data": { "text/plain": [ - ">" + ">" ] }, - "execution_count": 76, + "execution_count": 78, "metadata": {}, "output_type": "execute_result" } @@ -2746,7 +2860,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 79, "metadata": { "slideshow": { "slide_type": "-" @@ -2771,7 +2885,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 80, "metadata": { "slideshow": { "slide_type": "-" @@ -2781,10 +2895,10 @@ { "data": { "text/plain": [ - "2" + "12" ] }, - "execution_count": 78, + "execution_count": 80, "metadata": {}, "output_type": "execute_result" } @@ -2808,7 +2922,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 81, "metadata": { "slideshow": { "slide_type": "slide" @@ -2821,7 +2935,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 82, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2834,7 +2948,7 @@ "0.6394267984578837" ] }, - "execution_count": 80, + "execution_count": 82, "metadata": {}, "output_type": "execute_result" } @@ -2845,7 +2959,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 83, "metadata": { "slideshow": { "slide_type": "-" @@ -2858,7 +2972,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 84, "metadata": { "slideshow": { "slide_type": "-" @@ -2871,7 +2985,7 @@ "0.6394267984578837" ] }, - "execution_count": 82, + "execution_count": 84, "metadata": {}, "output_type": "execute_result" } @@ -2927,16 +3041,16 @@ } }, "source": [ - "[numpy](http://www.numpy.org/) is the de-facto standard in the Python world for handling **array-like** data. That is a fancy word for data that can be put into a matrix or vector format. We look at it in depth in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb).\n", + "[numpy](http://www.numpy.org/) is the de-facto standard in the Python world for handling **array-like** data. That is a fancy word for data that can be put into a matrix or vector format. We look at it in depth in [Chapter 9](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/09_arrays_00_content.ipynb).\n", "\n", - "As [numpy](http://www.numpy.org/) is *not* in the [standard library](https://docs.python.org/3/library/index.html), it must be *manually* installed, for example, with the [pip](https://pip.pypa.io/en/stable/) tool. As mentioned in [Chapter 0](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up.ipynb#Markdown-vs.-Code-Cells), to execute terminal commands from within a Jupyter notebook, we start a code cell with an exclamation mark.\n", + "As [numpy](http://www.numpy.org/) is *not* in the [standard library](https://docs.python.org/3/library/index.html), it must be *manually* installed, for example, with the [pip](https://pip.pypa.io/en/stable/) tool. As mentioned in [Chapter 0](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up_00_content.ipynb#Markdown-vs.-Code-Cells), to execute terminal commands from within a Jupyter notebook, we start a code cell with an exclamation mark.\n", "\n", "If you are running this notebook with an installation of the [Anaconda Distribution](https://www.anaconda.com/distribution/), then [numpy](http://www.numpy.org/) is probably already installed. Running the cell below confirms that." ] }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 85, "metadata": { "slideshow": { "slide_type": "slide" @@ -2947,7 +3061,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Requirement already satisfied: numpy in /home/webartifex/.pyenv/versions/anaconda3-2019.07/lib/python3.7/site-packages (1.16.4)\r\n" + "Requirement already satisfied: numpy in /home/webartifex/.pyenv/versions/anaconda3-2019.10/lib/python3.7/site-packages (1.17.2)\n" ] } ], @@ -2968,7 +3082,7 @@ }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 86, "metadata": { "slideshow": { "slide_type": "slide" @@ -2992,7 +3106,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 87, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3002,10 +3116,10 @@ { "data": { "text/plain": [ - "" + "" ] }, - "execution_count": 85, + "execution_count": 87, "metadata": {}, "output_type": "execute_result" } @@ -3027,7 +3141,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 88, "metadata": { "slideshow": { "slide_type": "slide" @@ -3040,7 +3154,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 89, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3053,7 +3167,7 @@ "array([ 7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4])" ] }, - "execution_count": 87, + "execution_count": 89, "metadata": {}, "output_type": "execute_result" } @@ -3064,7 +3178,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 90, "metadata": { "slideshow": { "slide_type": "-" @@ -3077,7 +3191,7 @@ "numpy.ndarray" ] }, - "execution_count": 88, + "execution_count": 90, "metadata": {}, "output_type": "execute_result" } @@ -3101,7 +3215,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 91, "metadata": { "slideshow": { "slide_type": "slide" @@ -3114,7 +3228,7 @@ "array([14, 22, 16, 10, 6, 24, 4, 12, 18, 20, 2, 8])" ] }, - "execution_count": 89, + "execution_count": 91, "metadata": {}, "output_type": "execute_result" } @@ -3136,7 +3250,7 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 92, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3149,7 +3263,7 @@ "[7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4, 7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]" ] }, - "execution_count": 90, + "execution_count": 92, "metadata": {}, "output_type": "execute_result" } @@ -3171,7 +3285,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 93, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3184,7 +3298,7 @@ "78" ] }, - "execution_count": 91, + "execution_count": 93, "metadata": {}, "output_type": "execute_result" } @@ -3195,7 +3309,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 94, "metadata": { "slideshow": { "slide_type": "-" @@ -3208,7 +3322,7 @@ "7" ] }, - "execution_count": 92, + "execution_count": 94, "metadata": {}, "output_type": "execute_result" } @@ -3247,7 +3361,7 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 95, "metadata": { "slideshow": { "slide_type": "slide" @@ -3260,7 +3374,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 96, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3273,7 +3387,7 @@ "" ] }, - "execution_count": 94, + "execution_count": 96, "metadata": {}, "output_type": "execute_result" } @@ -3299,7 +3413,7 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 97, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3324,7 +3438,7 @@ " 'average_odds']" ] }, - "execution_count": 95, + "execution_count": 97, "metadata": {}, "output_type": "execute_result" } @@ -3346,7 +3460,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 98, "metadata": { "slideshow": { "slide_type": "slide" @@ -3379,7 +3493,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 99, "metadata": { "slideshow": { "slide_type": "slide" @@ -3392,7 +3506,7 @@ "7.0" ] }, - "execution_count": 97, + "execution_count": 99, "metadata": {}, "output_type": "execute_result" } @@ -3403,7 +3517,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 100, "metadata": { "slideshow": { "slide_type": "-" @@ -3416,7 +3530,7 @@ "14.0" ] }, - "execution_count": 98, + "execution_count": 100, "metadata": {}, "output_type": "execute_result" } @@ -3433,7 +3547,7 @@ } }, "source": [ - "Packages are a generalization of modules, and we look at one in detail in Chapter 9. You may, however, already look at a [sample package](https://github.com/webartifex/intro-to-python/tree/master/sample_package) in the repository, which is nothing but a folder with *.py* files in it.\n", + "Packages are a generalization of modules, and we look at one in detail in Chapter 10. You may, however, already look at a [sample package](https://github.com/webartifex/intro-to-python/tree/master/sample_package) in the repository, which is nothing but a folder with *.py* files in it.\n", "\n", "As a further reading on modules and packages, we refer to the [official tutorial](https://docs.python.org/3/tutorial/modules.html)." ] @@ -3494,7 +3608,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "livereveal": { "auto_select": "code", @@ -3522,5 +3636,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/02_functions_review_and_exercises.ipynb b/02_functions_10_review.ipynb similarity index 50% rename from 02_functions_review_and_exercises.ipynb rename to 02_functions_10_review.ipynb index ca631a7..a320a3d 100644 --- a/02_functions_review_and_exercises.ipynb +++ b/02_functions_10_review.ipynb @@ -18,7 +18,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Read [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions.ipynb) of the book. Then work through the ten review questions." + "Read [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb) of the book. Then, work through the questions below." ] }, { @@ -32,14 +32,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Answer the following questions briefly with *at most* 300 characters per question!" + "Answer the following questions *briefly*!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q1**: What property of the `def` statement makes it a **statement**? Is there a way to use an **expression** to create a function?" + "**Q1**: What behavior of the `def` statement makes it a **statement**? Is there a way to use an **expression** to create a function?" ] }, { @@ -182,188 +182,6 @@ "**Q10**: The [standard library](https://docs.python.org/3/library/index.html) is a collection of numerical tools often used in scientific computing, for example, advanced mathematical functions or utilities for simulation." ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Coding Exercises" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Volume of a Sphere" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11.1**: The [volume of a sphere](https://en.wikipedia.org/wiki/Sphere) is defined as $\\frac{4}{3} * \\pi * r^3$. Calculate this value for $r=10.0$ and round it to 10 digits after the comma. Use the [standard library](https://docs.python.org/3/library/index.html) to obtain a good approximation of $\\pi$." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "r = ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11.2**: Encapsulate the logic into a function `sphere_volume()` that takes one *positional* argument `radius` and one *keyword-only* argument `digits` defaulting to `5`. The volume should be returned as a `float` object under *all* circumstances. Document your work appropriately in a docstring according to [Google's Python Style Guide](https://github.com/google/styleguide/blob/gh-pages/pyguide.md)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def sphere_volume(...):\n", - " ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11.3**: Evaluate the function with `radius = 100.0` and 1, 5, 10, 15, and 20 digits respectively." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "radius = ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sphere_volume(...)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sphere_volume(...)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sphere_volume(...)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sphere_volume(...)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "sphere_volume(...)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11.4**: What observation do you make?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11.5**: Using the [range()](https://docs.python.org/3/library/functions.html#func-range) built-in, write a `for`-loop and calculate the volume of a sphere with `radius = 42.0` for all `digits` from `1` through `20`. Print out each volume on a separate line.\n", - "\n", - "Note: This is the first task where you need to use the built-in [print()](https://docs.python.org/3/library/functions.html#print) function." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "radius = ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "for ... in ...:\n", - " ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11.6**: What lesson do you learn about the `float` type?" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -388,7 +206,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "toc": { "base_numbering": 1, @@ -405,5 +223,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/02_functions_20_exercises.ipynb b/02_functions_20_exercises.ipynb new file mode 100644 index 0000000..0f449e4 --- /dev/null +++ b/02_functions_20_exercises.ipynb @@ -0,0 +1,234 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Chapter 2: Functions & Modularization" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Coding Exercises" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb) of the book. Then, work through the exercises below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Volume of a Sphere" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.1**: The [volume of a sphere](https://en.wikipedia.org/wiki/Sphere) is defined as $\\frac{4}{3} * \\pi * r^3$. Calculate this value for $r=10.0$ and round it to 10 digits after the comma. Use the [standard library](https://docs.python.org/3/library/index.html) to obtain a good approximation of $\\pi$." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import ..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "r = ..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.2**: Encapsulate the logic into a function `sphere_volume()` that takes one *positional* argument `radius` and one *keyword-only* argument `digits` defaulting to `5`. The volume should be returned as a `float` object under *all* circumstances. Document your work appropriately in a docstring according to [Google's Python Style Guide](https://github.com/google/styleguide/blob/gh-pages/pyguide.md)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def sphere_volume(...):\n", + " ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.3**: Evaluate the function with `radius = 100.0` and 1, 5, 10, 15, and 20 digits respectively." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "radius = ..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sphere_volume(...)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sphere_volume(...)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sphere_volume(...)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sphere_volume(...)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sphere_volume(...)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.4**: What observation do you make?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.5**: Using the [range()](https://docs.python.org/3/library/functions.html#func-range) built-in, write a `for`-loop and calculate the volume of a sphere with `radius = 42.0` for all `digits` from `1` through `20`. Print out each volume on a separate line.\n", + "\n", + "Note: This is the first task where you need to use the built-in [print()](https://docs.python.org/3/library/functions.html#print) function." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "radius = ..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for ... in ...:\n", + " ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.6**: What lesson do you learn about the `float` type?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": true, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": false, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/03_conditionals.ipynb b/03_conditionals_00_content.ipynb similarity index 95% rename from 03_conditionals.ipynb rename to 03_conditionals_00_content.ipynb index 9ffe09e..a9113a3 100644 --- a/03_conditionals.ipynb +++ b/03_conditionals_00_content.ipynb @@ -19,7 +19,7 @@ } }, "source": [ - "We analyzed every aspect of the `average_evens()` function in [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions.ipynb) except for the `if`-related parts. While it seems to do what we expect it to, there is a whole lot more we learn from taking it apart. In particular, the `if` may occur within both a **statement** or an **expression**, analogous as to how a noun in a natural language is *either* the subject of *or* an object in a sentence. What is common to both usages is that it leads to code being executed for *parts* of the input only. It is our first way of **controlling** the **flow of execution** in a program.\n", + "We analyzed every aspect of the `average_evens()` function in [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb) except for the `if`-related parts. While it seems to do what we expect it to, there is a whole lot more we learn from taking it apart. In particular, the `if` may occur within both a **statement** or an **expression**, analogous as to how a noun in a natural language is *either* the subject of *or* an object in a sentence. What is common to both usages is that it leads to code being executed for *parts* of the input only. It is our first way of **controlling** the **flow of execution** in a program.\n", "\n", "After deconstructing `if` in the first part of this chapter, we take a close look at a similar concept, namely handling **exceptions**." ] @@ -139,7 +139,7 @@ } }, "source": [ - "There are, however, cases where even well-behaved Python does not make us happy. [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers.ipynb#Imprecision) provides more insights into this \"bug.\"" + "There are, however, cases where even well-behaved Python does not make us happy. [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_00_content.ipynb#Imprecision) provides more insights into this \"bug.\"" ] }, { @@ -189,7 +189,7 @@ { "data": { "text/plain": [ - "93918328484832" + "94426021241472" ] }, "execution_count": 5, @@ -213,7 +213,7 @@ { "data": { "text/plain": [ - "93918328484800" + "94426021241440" ] }, "execution_count": 6, @@ -281,7 +281,7 @@ } }, "source": [ - "Let's not confuse the boolean `False` with `None`, another built-in object! We saw the latter before in [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions.ipynb#Function-Definition) as the *implicit* return value of a function without a `return` statement.\n", + "Let's not confuse the boolean `False` with `None`, another built-in object! We saw the latter before in [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb#Function-Definition) as the *implicit* return value of a function without a `return` statement.\n", "\n", "We might think of `None` in a boolean context indicating a \"maybe\" or even an \"unknown\" answer; however, for Python, there are no \"maybe\" or \"unknown\" objects, as we see further below!\n", "\n", @@ -313,7 +313,7 @@ { "data": { "text/plain": [ - "93918328471792" + "94426021228432" ] }, "execution_count": 10, @@ -357,7 +357,7 @@ } }, "source": [ - "`True`, `False`, and `None` have the property that they each exist in memory only *once*. Objects designed this way are so-called **singletons**. This **[design pattern](https://en.wikipedia.org/wiki/Design_Patterns)** was originally developed to keep a program's memory usage at a minimum. It may only be employed in situations where we know that an object does *not* mutate its value (i.e., to reuse the bag analogy from [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Objects-vs.-Types-vs.-Values), no flipping of $0$s and $1$s in the bag is allowed). In languages \"closer\" to the memory like C, we would have to code this singleton logic ourselves, but Python has this built in for *some* types.\n", + "`True`, `False`, and `None` have the property that they each exist in memory only *once*. Objects designed this way are so-called **singletons**. This **[design pattern](https://en.wikipedia.org/wiki/Design_Patterns)** was originally developed to keep a program's memory usage at a minimum. It may only be employed in situations where we know that an object does *not* mutate its value (i.e., to reuse the bag analogy from [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Objects-vs.-Types-vs.-Values), no flipping of $0$s and $1$s in the bag is allowed). In languages \"closer\" to the memory like C, we would have to code this singleton logic ourselves, but Python has this built in for *some* types.\n", "\n", "We verify this with either the `is` operator or by comparing memory addresses." ] @@ -1116,6 +1116,65 @@ "bool([False])" ] }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "With `str` objects, the empty `\"\"` evaluates to `False`, and any other to `True`." + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bool(\"\")" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "bool(\"Lorem ipsum dolor sit amet, ...\")" + ] + }, { "cell_type": "markdown", "metadata": { @@ -1162,7 +1221,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 38, "metadata": { "slideshow": { "slide_type": "slide" @@ -1187,75 +1246,12 @@ "With the `or` operator, the first truthy sub-expression is returned." ] }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Arg: 0\n", - "Arg: 1\n" - ] - }, - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "expr(0) or expr(1)" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": { - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Arg: 1\n" - ] - }, - { - "data": { - "text/plain": [ - "1" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "expr(1) or expr(2) # 2 is not evaluated due to short-circuiting" - ] - }, { "cell_type": "code", "execution_count": 39, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "slide" } }, "outputs": [ @@ -1278,6 +1274,69 @@ "output_type": "execute_result" } ], + "source": [ + "expr(0) or expr(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Arg: 1\n" + ] + }, + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "expr(1) or expr(2) # 2 is not evaluated due to short-circuiting" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Arg: 0\n", + "Arg: 1\n" + ] + }, + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "expr(0) or expr(1) or expr(2) # 2 is not evaluated due to short-circuiting" ] @@ -1295,7 +1354,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 42, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1317,7 +1376,7 @@ "0" ] }, - "execution_count": 40, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -1339,7 +1398,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 43, "metadata": { "slideshow": { "slide_type": "slide" @@ -1359,7 +1418,7 @@ "0" ] }, - "execution_count": 41, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" } @@ -1370,7 +1429,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 44, "metadata": { "slideshow": { "slide_type": "-" @@ -1391,7 +1450,7 @@ "0" ] }, - "execution_count": 42, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -1402,7 +1461,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 45, "metadata": { "slideshow": { "slide_type": "-" @@ -1423,7 +1482,7 @@ "0" ] }, - "execution_count": 43, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -1445,7 +1504,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 46, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1466,7 +1525,7 @@ "2" ] }, - "execution_count": 44, + "execution_count": 46, "metadata": {}, "output_type": "execute_result" } @@ -1522,7 +1581,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 47, "metadata": { "code_folding": [], "slideshow": { @@ -1536,7 +1595,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 48, "metadata": { "code_folding": [], "slideshow": { @@ -1578,7 +1637,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 49, "metadata": { "slideshow": { "slide_type": "slide" @@ -1591,7 +1650,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 50, "metadata": { "slideshow": { "slide_type": "-" @@ -1616,7 +1675,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 51, "metadata": { "slideshow": { "slide_type": "skip" @@ -1653,7 +1712,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 52, "metadata": { "slideshow": { "slide_type": "slide" @@ -1696,7 +1755,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 53, "metadata": { "slideshow": { "slide_type": "slide" @@ -1769,7 +1828,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 54, "metadata": { "slideshow": { "slide_type": "slide" @@ -1793,7 +1852,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 55, "metadata": { "slideshow": { "slide_type": "-" @@ -1807,60 +1866,12 @@ " y = x ** 2" ] }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": { - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "9" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "y" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "On the contrary, the `if` expression fits into one line. The main downside is a potential loss in readability, in particular, if the functional relationship is not that simple. Also, some practitioners do *not* like that the condition is in the middle of the expression." - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [], - "source": [ - "y = 0 if x <= 0 else x ** 2" - ] - }, { "cell_type": "code", "execution_count": 56, "metadata": { "slideshow": { - "slide_type": "skip" + "slide_type": "-" } }, "outputs": [ @@ -1887,7 +1898,7 @@ } }, "source": [ - "In this example, however, the most elegant solution is to use the built-in [max()](https://docs.python.org/3/library/functions.html#max) function." + "On the contrary, the `if` expression fits into one line. The main downside is a potential loss in readability, in particular, if the functional relationship is not that simple. Also, some practitioners do *not* like that the condition is in the middle of the expression." ] }, { @@ -1900,7 +1911,7 @@ }, "outputs": [], "source": [ - "y = max(0, x) ** 2" + "y = 0 if x <= 0 else x ** 2" ] }, { @@ -1927,6 +1938,54 @@ "y" ] }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "In this example, however, the most elegant solution is to use the built-in [max()](https://docs.python.org/3/library/functions.html#max) function." + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "y = max(0, x) ** 2" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y" + ] + }, { "cell_type": "markdown", "metadata": { @@ -1955,7 +2014,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 61, "metadata": { "slideshow": { "slide_type": "slide" @@ -1968,7 +2027,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 62, "metadata": { "slideshow": { "slide_type": "-" @@ -2007,7 +2066,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 63, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2046,7 +2105,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 64, "metadata": { "slideshow": { "slide_type": "slide" @@ -2057,7 +2116,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Oops. Division by 0. How does that work?\n", + "Yes, division worked smoothly.\n", "I am always printed\n" ] } @@ -2119,7 +2178,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "livereveal": { "auto_select": "code", @@ -2147,5 +2206,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/03_conditionals_10_review.ipynb b/03_conditionals_10_review.ipynb new file mode 100644 index 0000000..de1a419 --- /dev/null +++ b/03_conditionals_10_review.ipynb @@ -0,0 +1,214 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# Chapter 3: Conditionals & Exceptions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Content Review" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_content.ipynb) of the book. Then, work through the questions below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Essay Questions " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Answer the following questions *briefly*!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1**: What is the **singleton** design pattern? How many objects does the expression `[True, False, True, False]` generate in memory?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q2**: What do we mean when we talk about **truthy** and **falsy** expressions?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q3**: Describe in your own words the concept of **short-circuiting**! What does it imply for an individual sub-expression in a boolean expression?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q4**: Explain how the conceptual difference between a **statement** and an **expression** relates to the difference between a **conditional statement** and a **conditional expression**." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q5**: Why is the use of **temporary variables** encouraged in Python?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q6**: What does the `finally`-clause enforce in this code snippet? How can a `try` statement be useful *without* an `except`-clause?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```python\n", + "try:\n", + " print(\"Make a request to a service on the internet\")\n", + "finally:\n", + " print(\"This could be clean-up code\")\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### True / False Questions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Motivate your answer with *one short* sentence!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q7**: The objects `True`, `False`, and `None` represent the idea of *yes*, *no*, and *maybe* answers in a natural language.\n", + "\n", + "Hint: you also respond with a code cell." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q8**: The `try` statement is useful for handling **syntax** errors." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": true, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": false, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/03_conditionals_review_and_exercises.ipynb b/03_conditionals_20_exercises.ipynb similarity index 53% rename from 03_conditionals_review_and_exercises.ipynb rename to 03_conditionals_20_exercises.ipynb index 90b4ff9..23692a3 100644 --- a/03_conditionals_review_and_exercises.ipynb +++ b/03_conditionals_20_exercises.ipynb @@ -8,174 +8,6 @@ "# Chapter 3: Conditionals & Exceptions" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Content Review" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Read [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals.ipynb) of the book. Then work through the eight review questions." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Essay Questions " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Answer the following questions briefly with *at most* 300 characters per question!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q1**: What is the **singleton** design pattern? How many objects does the expression `[True, False, True, False]` generate in memory?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q2**: What do we mean when we talk about **truthy** and **falsy** expressions?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q3**: Describe in your own words the concept of **short-circuiting**! What does it imply for an individual sub-expression in a boolean expression?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q4**: Explain how the conceptual difference between a **statement** and an **expression** relates to the difference between a **conditional statement** and a **conditional expression**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q5**: Why is the use of **temporary variables** encouraged in Python?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q6**: What does the `finally`-clause enforce in this code snippet? How can a `try` statement be useful *without* an `except`-clause?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```python\n", - "try:\n", - " print(\"Make a request to a service on the internet\")\n", - "finally:\n", - " print(\"This could be clean-up code\")\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### True / False Questions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Motivate your answer with *one short* sentence!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q7**: The objects `True`, `False`, and `None` represent the idea of *yes*, *no*, and *maybe* answers in a natural language.\n", - "\n", - "Hint: you also respond with a code cell." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q8**: The `try` statement is useful for handling **syntax** errors." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -183,6 +15,13 @@ "## Coding Exercises" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_content.ipynb) of the book. Then, work through the exercises below." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -194,7 +33,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q9.1**: Write a function `discounted_price()` that takes the positional arguments `unit_price` (of type `float`) and `quantity` (of type `int`) and implements a discount scheme for a line item in a customer order as follows:\n", + "**Q1.1**: Write a function `discounted_price()` that takes the positional arguments `unit_price` (of type `float`) and `quantity` (of type `int`) and implements a discount scheme for a line item in a customer order as follows:\n", "\n", "- if the unit price is over 100 dollars, grant 10% relative discount\n", "- if a customer orders more than 10 items, one in every five items is for free\n", @@ -218,7 +57,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q9.2**: Calculate the final price for the following line items of an order:\n", + "**Q1.2**: Calculate the final price for the following line items of an order:\n", "- $7$ smartphones @ $99.00$ USD\n", "- $3$ workstations @ $999.00$ USD\n", "- $19$ GPUs @ $879.95$ USD\n", @@ -265,7 +104,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q9.3**: Calculate the last two line items with order quantities of $20$ and $15$. What do you observe?" + "**Q1.3**: Calculate the last two line items with order quantities of $20$ and $15$. What do you observe?" ] }, { @@ -297,7 +136,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q9.4**: Looking at the `if`-`else`-logic in the function, why do you think the four example line items in **Q9.2** were chosen as they were?" + "**Q1.4**: Looking at the `if`-`else`-logic in the function, why do you think the four example line items in **Q9.2** were chosen as they were?" ] }, { @@ -327,7 +166,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q10.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(...))`)." + "**Q2.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(...))`)." ] }, { @@ -343,9 +182,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q10.2**: Loop over the `numbers` list and replace numbers for which one of the two (or both) conditions apply with text strings `\"Fizz\"`, `\"Buzz\"`, or `\"FizzBuzz\"` using the indexing operator `[]` and the assignment statement `=`.\n", + "**Q2.2**: Loop over the `numbers` list and replace numbers for which one of the two (or both) conditions apply with text strings `\"Fizz\"`, `\"Buzz\"`, or `\"FizzBuzz\"` using the indexing operator `[]` and the assignment statement `=`.\n", "\n", - "In [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb), we saw that Python starts indexing with `0` as the first element. Keep that in mind.\n", + "In [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb), we saw that Python starts indexing with `0` as the first element. Keep that in mind.\n", "\n", "So in each iteration of the `for`-loop, you have to determine an `index` variable as well as check the actual `number` for its divisors.\n", "\n", @@ -366,7 +205,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q10.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." + "**Q2.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." ] }, { @@ -396,7 +235,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "toc": { "base_numbering": 1, @@ -413,5 +252,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/04_iteration.ipynb b/04_iteration_00_content.ipynb similarity index 96% rename from 04_iteration.ipynb rename to 04_iteration_00_content.ipynb index aabaaef..ba6467d 100644 --- a/04_iteration.ipynb +++ b/04_iteration_00_content.ipynb @@ -839,9 +839,9 @@ "source": [ "This implementation is *highly* **inefficient** as small Fibonacci numbers already take a very long time to compute. The reason for this is **exponential growth** in the number of function calls. As [PythonTutor](http://pythontutor.com/visualize.html#code=def%20fibonacci%28i%29%3A%0A%20%20%20%20if%20i%20%3D%3D%200%3A%0A%20%20%20%20%20%20%20%20return%200%0A%20%20%20%20elif%20i%20%3D%3D%201%3A%0A%20%20%20%20%20%20%20%20return%201%0A%20%20%20%20return%20fibonacci%28i%20-%201%29%20%2B%20fibonacci%28i%20-%202%29%0A%0Arv%20%3D%20fibonacci%285%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false) shows, `fibonacci()` is called again and again with the same `i` arguments.\n", "\n", - "To understand this in detail, we would have to study algorithms and data structures (e.g., with [this book](https://www.amazon.de/Introduction-Algorithms-Press-Thomas-Cormen/dp/0262033844/ref=sr_1_1?__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91&crid=1JNE8U0VZGU0O&qid=1569837169&s=gateway&sprefix=algorithms+an%2Caps%2C180&sr=8-1)), a discipline within computer science, and dive into the analysis of **[time complexity of algorithms](https://en.wikipedia.org/wiki/Time_complexity)**.\n", + "To understand this in detail, we have to study algorithms and data structures (e.g., with [this book](https://www.amazon.de/Introduction-Algorithms-Press-Thomas-Cormen/dp/0262033844/ref=sr_1_1?__mk_de_DE=%C3%85M%C3%85%C5%BD%C3%95%C3%91&crid=1JNE8U0VZGU0O&qid=1569837169&s=gateway&sprefix=algorithms+an%2Caps%2C180&sr=8-1)), a discipline within computer science, and dive into the analysis of **[time complexity of algorithms](https://en.wikipedia.org/wiki/Time_complexity)**.\n", "\n", - "Luckily, in the Fibonacci case, the inefficiency can be resolved with a **caching** (i.e., \"reuse\") strategy from the field of **[dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming)**, namely **[memoization](https://en.wikipedia.org/wiki/Memoization)**. We do so in [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings.ipynb#Memoization), after introducing the [dictionaries](https://docs.python.org/3/library/stdtypes.html#dict) data type.\n", + "Luckily, in the Fibonacci case, the inefficiency can be resolved with a **caching** (i.e., \"reuse\") strategy from the field of **[dynamic programming](https://en.wikipedia.org/wiki/Dynamic_programming)**, namely **[memoization](https://en.wikipedia.org/wiki/Memoization)**. We do so in [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_00_content.ipynb#Memoization), after introducing the `dict` data type.\n", "\n", "Let's measure the average run times for `fibonacci()` and varying `i` arguments with the `%%timeit` [cell magic](https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-timeit) that comes with Jupyter." ] @@ -859,7 +859,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "37.5 µs ± 4.26 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" + "49.8 µs ± 20.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], @@ -881,7 +881,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "1.49 ms ± 22.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" + "1.63 ms ± 14.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n" ] } ], @@ -903,7 +903,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "199 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" + "202 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" ] } ], @@ -925,7 +925,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "2.04 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" + "2.25 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" ] } ], @@ -947,7 +947,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "5.33 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" + "5.79 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" ] } ], @@ -4538,7 +4538,7 @@ } }, "source": [ - "##### Efficiency of Algorithms (revisited)" + "##### Efficiency of Algorithms (continued)" ] }, { @@ -4565,7 +4565,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "4.6 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" + "5.14 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" ] } ], @@ -4877,7 +4877,7 @@ } }, "source": [ - "For sequences of integers, the [range()](https://docs.python.org/3/library/functions.html#func-range) built-in makes the `for` statement even more convenient: It creates a `list`-like object of type `range` that generates integers \"on the fly,\" and we look closely at the underlying effects in memory in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#Mapping)." + "For sequences of integers, the [range()](https://docs.python.org/3/library/functions.html#func-range) built-in makes the `for` statement even more convenient: It creates a `list`-like object of type `range` that generates integers \"on the fly,\" and we look closely at the underlying effects in memory in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#Mapping)." ] }, { @@ -5008,11 +5008,11 @@ "\n", "Now, just as we classify objects by data type, we also classify these data types (e.g., `int`, `float`, `str`, or `list`) into **abstract concepts**.\n", "\n", - "We did this already in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Who-am-I?-And-how-many?) when we described a `list` object as \"some sort of container that holds [...] references to other objects\". So, abstractly speaking, **containers** are any objects that are \"composed\" of other objects and also \"manage\" how these objects are organized. `list` objects, for example, have the property that they model an order associated with their elements. There exist, however, other container types, many of which do *not* come with an order. So, containers primarily \"contain\" other objects and have *nothing* to do with looping.\n", + "We did this already in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Who-am-I?-And-how-many?) when we described a `list` object as \"some sort of container that holds [...] references to other objects\". So, abstractly speaking, **containers** are any objects that are \"composed\" of other objects and also \"manage\" how these objects are organized. `list` objects, for example, have the property that they model an order associated with their elements. There exist, however, other container types, many of which do *not* come with an order. So, containers primarily \"contain\" other objects and have *nothing* to do with looping.\n", "\n", "On the contrary, the abstract concept of **iterables** is all about looping: Any object that we can loop over is, by definition, an iterable. So, `range` objects, for example, are iterables, even though they hold no references to other objects. Moreover, looping does *not* have to occur in a *predictable* order, although this is the case for both `list` and `range` objects.\n", "\n", - "Typically, containers are iterables, and iterables are containers. Yet, only because these two concepts coincide often, we must not think of them as the same. In [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#Collections-vs.-Sequences), we formalize these two concepts and introduce many more. Finally, Chapter 9 gives an explanation how abstract concepts are implemented and play together.\n", + "Typically, containers are iterables, and iterables are containers. Yet, only because these two concepts coincide often, we must not think of them as the same. In [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#Collections-vs.-Sequences), we formalize these two concepts and introduce many more. Finally, Chapter 10 gives an explanation how abstract concepts are implemented and play together.\n", "\n", "Let's continue with `first_names` below as an example an illustrate what iterable containers are." ] @@ -5399,7 +5399,7 @@ } }, "source": [ - "##### Efficiency of Algorithms (revisited)" + "##### Efficiency of Algorithms (continued)" ] }, { @@ -5574,7 +5574,7 @@ } }, "source": [ - "Let's say we have a `samples` list 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 above a `threshold` of `100`." ] }, { @@ -5587,7 +5587,7 @@ }, "outputs": [], "source": [ - "samples = [3, 7, 2, 9, 11, 4, 7, 9, 4, 5]" + "numbers = [7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]" ] }, { @@ -5611,7 +5611,7 @@ } }, "source": [ - "A first naive implementation could look like this: We loop over *every* element in `samples` 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 search condition." ] }, { @@ -5627,22 +5627,22 @@ "name": "stdout", "output_type": "stream", "text": [ - "3 7 2 9 11 4 7 9 4 5 => at least one sample's square is above 100\n" + "7 11 8 5 3 12 2 6 9 10 1 4 => at least one number's square is above 100\n" ] } ], "source": [ "is_above = False\n", "\n", - "for sample in samples:\n", - " print(sample, end=\" \") # added for didactical purposes\n", - " if sample ** 2 > threshold:\n", + "for number in numbers:\n", + " print(number, end=\" \") # added for didactical purposes\n", + " if number ** 2 > threshold:\n", " is_above = True\n", "\n", "if is_above:\n", - " print(\"=> at least one sample's square is above\", threshold)\n", + " print(\"=> at least one number's square is above\", threshold)\n", "else:\n", - " print(\"=> no sample's square is above\", threshold)" + " print(\"=> no number's square is above\", threshold)" ] }, { @@ -5653,7 +5653,7 @@ } }, "source": [ - "This implementation is *inefficient* as even if the *first* element in `samples` has a square greater than `100`, we loop until the last element: This could take a long time for a big list.\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* clear right away.\n", "\n", @@ -5673,23 +5673,23 @@ "name": "stdout", "output_type": "stream", "text": [ - "3 7 2 9 11 => at least one sample's square is above 100\n" + "7 11 => at least one number's square is above 100\n" ] } ], "source": [ "is_above = False\n", "\n", - "for sample in samples:\n", - " print(sample, end=\" \") # added for didactical purposes\n", - " if sample ** 2 > threshold:\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 sample's square is above\", threshold)\n", + " print(\"=> at least one number's square is above\", threshold)\n", "else:\n", - " print(\"=> no sample's square is above\", threshold)" + " print(\"=> no number's square is above\", threshold)" ] }, { @@ -5751,23 +5751,23 @@ "name": "stdout", "output_type": "stream", "text": [ - "3 7 2 9 11 => at least one sample's square is above 100\n" + "7 11 => at least one number's square is above 100\n" ] } ], "source": [ - "for sample in samples:\n", - " print(sample, end=\" \") # added for didactical purposes\n", - " if sample ** 2 > threshold:\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", "else:\n", " is_above = False\n", "\n", "if is_above:\n", - " print(\"=> at least one sample's square is above\", threshold)\n", + " print(\"=> at least one number's square is above\", threshold)\n", "else:\n", - " print(\"=> no sample's square is above\", threshold)" + " print(\"=> no number's square is above\", threshold)" ] }, { @@ -5794,18 +5794,18 @@ "name": "stdout", "output_type": "stream", "text": [ - "3 7 2 9 11 => at least one sample's square is above 100\n" + "7 11 => at least one number's square is above 100\n" ] } ], "source": [ - "for sample in samples:\n", - " print(sample, end=\" \") # added for didactical purposes\n", - " if sample ** 2 > threshold:\n", - " print(\"=> at least one sample's square is above\", threshold)\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", " break\n", "else:\n", - " print(\"=> no sample's square is above\", threshold)" + " print(\"=> no number's square is above\", threshold)" ] }, { @@ -5816,7 +5816,7 @@ } }, "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 `samples`. There is *no way* to optimize this **[linear search](https://en.wikipedia.org/wiki/Linear_search)** further, at least as long as we model `samples` as a `list` object. More advanced data types, however, exist that mitigate that downside." + "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." ] }, { @@ -5832,20 +5832,20 @@ "name": "stdout", "output_type": "stream", "text": [ - "3 7 2 9 11 4 7 9 4 5 => no sample's square is above 200\n" + "7 11 8 5 3 12 2 6 9 10 1 4 => no number's square is above 200\n" ] } ], "source": [ "threshold = 200\n", "\n", - "for sample in samples:\n", - " print(sample, end=\" \") # added for didactical purposes\n", - " if sample ** 2 > threshold:\n", - " print(\"=> at least one sample's square is above\", threshold)\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", " break\n", "else:\n", - " print(\"=> no sample's square is above\", threshold)" + " print(\"=> no number's square is above\", threshold)" ] }, { @@ -5867,17 +5867,17 @@ } }, "source": [ - "Often, we process some iterable with numeric data, for example, a list of `numbers` as in this book's introductory example in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Example:-Averaging-Even-Numbers) or, more realistically, data from a CSV file with many rows and columns.\n", + "Often, we process some iterable with numeric data, for example, a list of `numbers` as in this book's introductory example in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Example:-Averaging-Even-Numbers) or, more realistically, data from a CSV file with many rows and columns.\n", "\n", "Processing numeric data usually comes down to operations that may be grouped into one of the following three categories:\n", "\n", - "- **mapping**: transform a sample according to some functional relationship $y = f(x)$\n", - "- **filtering**: throw away individual samples (e.g., statistical outliers)\n", - "- **reducing**: collect individual samples into summary statistics\n", + "- **mapping**: transform a number according to some functional relationship $y = f(x)$\n", + "- **filtering**: throw away individual numbers (e.g., statistical outliers in a sample)\n", + "- **reducing**: collect individual numbers into summary statistics\n", "\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.ipynb#The-Map-Filter-Reduce-Paradigm) after introducing more advanced data types that are needed to work with \"big\" data.\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_content.ipynb#The-Map-Filter-Reduce-Paradigm) after introducing more advanced data types that are needed to work with \"big\" data.\n", "\n", - "In the remainder of this section, we focus on *filtering out* some samples within a `for`-loop." + "Here, we focus on *filtering out* some numbers with a `for`-loop." ] }, { @@ -6074,7 +6074,7 @@ } }, "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.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", + "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_content.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", @@ -6236,13 +6236,31 @@ } }, "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Guess if the coin comes up as heads or tails: Tails\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "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": [ - "Guess if the coin comes up as heads or tails: Tails\n", - "Ooops, it was tails\n", - "Guess if the coin comes up as heads or tails: heads\n", "Yes, it was heads\n" ] } @@ -6402,13 +6420,31 @@ } }, "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "Guess if the coin comes up as heads or tails: invalid\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Make sure to enter your guess correctly!\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": [ - "Guess if the coin comes up as heads or tails: invalid\n", - "Make sure to enter your guess correctly!\n", - "Guess if the coin comes up as heads or tails: Heads\n", "Yes, it was heads\n" ] } @@ -6485,7 +6521,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "livereveal": { "auto_select": "code", @@ -6513,5 +6549,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/04_iteration_10_review.ipynb b/04_iteration_10_review.ipynb new file mode 100644 index 0000000..808e309 --- /dev/null +++ b/04_iteration_10_review.ipynb @@ -0,0 +1,281 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# Chapter 4: Recursion & Looping" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Content Review" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb) of the book. Then, work through the questions below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Essay Questions " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Answer the following questions *briefly*!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1**: Solving a problem by **recursion** is not only popular in computer science and math. Name some examples from the fields of business or economics where problems are also solved in a **backward** fashion!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q2**: Explain what **duck typing** means! Why can it cause problems? Why is it [not a bug but a feature](https://www.urbandictionary.com/define.php?term=It%27s%20not%20a%20bug%2C%20it%27s%20a%20feature)?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q3**: What is **syntactic sugar**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q4**: Describe in your own words why the **recursive** version of `fibonacci()`, the \"Easy at first Glance\" example in the chapter, is computationally **inefficient**! Why does the **iterative** version of `fibonacci()`, the \"Hard at first Glance\" example, run so much faster?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q5**: What is the conceptual difference between a **container** and a **list**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q6**: What is a good use case for the `for`-loop's optional `else`-clause?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### True / False Questions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Motivate your answer with *one short* sentence!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q7**: When a **recursion** does **not** reach the base case, this is an example of the **early exit** strategy." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q8**: Any programming language **without** looping constructs like the `for` or `while` statements is **not** Turing complete." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q9**: A **recursive** formulation is the same as a **circular** one: The terms are **synonyms**." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q10**: Formulating a computational problem as a **recursion** results in an **efficient** implementation." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q11**: Whereas a **recursion** may accidentally result in a **never-ending** program, `while`-loops and `for`-loops are guaranteed to **terminate**." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q12**: Before writing **any** kind of **loop**, we **always** need to think about a **stopping criterion** ahead of time." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q13**: **Container** types such as `list` objects are characterized by their **support** for **being looped over**, for example as in:" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```python\n", + "for element in container:\n", + " # do something for every element\n", + " ...\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": true, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": false, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/04_iteration_review_and_exercises.ipynb b/04_iteration_20_exercises.ipynb similarity index 64% rename from 04_iteration_review_and_exercises.ipynb rename to 04_iteration_20_exercises.ipynb index 9e2b28f..81f6928 100644 --- a/04_iteration_review_and_exercises.ipynb +++ b/04_iteration_20_exercises.ipynb @@ -8,255 +8,6 @@ "# Chapter 4: Recursion & Looping" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Content Review" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Read [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb) of the book. Then work through the fourteen review questions." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Essay Questions " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Answer the following questions briefly with *at most* 300 characters per question!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q1**: What is so \"special\" about the number **7919**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q2**: Solving a problem by **recursion** is not only popular in computer science and math. Name some examples from the fields of business or economics where problems are also solved in a **backward** fashion!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q3**: Explain what **duck typing** means! Why can it cause problems? Why is it [not a bug but a feature](https://www.urbandictionary.com/define.php?term=It%27s%20not%20a%20bug%2C%20it%27s%20a%20feature)?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q4**: What is **syntactic sugar**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q5**: Describe in your own words why the **recursive** version of `fibonacci()`, the \"Easy at first Glance\" example in the chapter, is computationally **inefficient**! Why does the **iterative** version of `fibonacci()`, the \"Hard at first Glance\" example, run so much faster?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q6**: What is the conceptual difference between a **container** and a **list**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q7**: What is a good use case for the `for`-loop's optional `else`-clause?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### True / False Questions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Motivate your answer with *one short* sentence!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q8**: When a **recursion** does **not** reach the base case, this is an example of the **early exit** strategy." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q9**: Any programming language **without** looping constructs like the `for` or `while` statements is **not** Turing complete." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q10**: A **recursive** formulation is the same as a **circular** one: The terms are **synonyms**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11**: Formulating a computational problem as a **recursion** results in an **efficient** implementation." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q12**: Whereas a **recursion** may accidentally result in a **never-ending** program, `while`-loops and `for`-loops are guaranteed to **terminate**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q13**: Before writing **any** kind of **loop**, we **always** need to think about a **stopping criterion** ahead of time." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q14**: **Container** types such as `list` objects are characterized by their **support** for **being looped over**, for example as in:" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```python\n", - "for element in container:\n", - " # do something for every element\n", - " ...\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -264,6 +15,13 @@ "## Coding Exercises" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb) of the book. Then, work through the exercises below." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -330,7 +88,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.1**: Explain for the $n = 3$ case why it can be solved as a **recursion**!" + "**Q1.1**: Explain for the $n = 3$ case why it can be solved as a **recursion**!" ] }, { @@ -344,7 +102,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.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 **Q15.1**?" + "**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**?" ] }, { @@ -358,7 +116,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.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$?" + "**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$?" ] }, { @@ -372,7 +130,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.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 **Q15.1**?" + "**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**?" ] }, { @@ -439,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 **Q15.5** to **Q15.7** into the subsequent code cell and finalize `sol()`! No need to write a docstring or validate the input here." + "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." ] }, { @@ -464,14 +222,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.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!" + "**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!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.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", + "**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", "\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?" ] @@ -480,7 +238,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.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", + "**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", "\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!" ] @@ -489,7 +247,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.8**: Execute the code cells below and confirm that the printed moves are correct!" + "**Q1.8**: Execute the code cells below and confirm that the printed moves are correct!" ] }, { @@ -543,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 **Q15.9** and **Q15.10** into the subsequent code cell and finalize `hanoi()`! No need to write a docstring or validate the input here." + "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." ] }, { @@ -565,14 +323,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.9**: Copy the base case from `sol()`!" + "**Q1.9**: Copy the base case from `sol()`!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.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", + "**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", "\n", "Figure out how the arguments are passed on in the two recursive `hanoi()` calls!\n", "\n", @@ -583,7 +341,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.11**: Execute the code cells below and confirm that the printed moves are correct!" + "**Q1.11**: Execute the code cells below and confirm that the printed moves are correct!" ] }, { @@ -653,11 +411,11 @@ "\n", "In such cases, we could modify a recursive function to return a count value to be passed up the recursion tree.\n", "\n", - "This is similar to what we do in the recursive versions of `factorial()` and `fibonacci()` in [Chapter 4](https://github.com/webartifex/intro-to-python/blob/master/04_iteration.ipynb), where we pass up an intermediate result.\n", + "This is similar to what we do in the recursive versions of `factorial()` and `fibonacci()` in [Chapter 4](https://github.com/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb), where we pass up an intermediate result.\n", "\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 **Q15.12** to **Q15.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 **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." ] }, { @@ -682,21 +440,21 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.12**: Copy the base case from `hanoi()`! What count should be returned when it is reached?" + "**Q1.12**: Copy the base case from `hanoi()`! What count should be returned when it is reached?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.13**: Initialize the variable `moves` with an appropriate count! This is the number of moves that corresponds to **one** recursive function call." + "**Q1.13**: 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": [ - "**Q15.14**: `moves` is updated with the counts passed up from the two recursive calls.\n", + "**Q1.14**: `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()`!" ] @@ -705,7 +463,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.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 **Q15.2**." + "**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**." ] }, { @@ -733,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", - "**Q15.16**: Execute the code cells below and see for yourself!" + "**Q1.16**: Execute the code cells below and see for yourself!" ] }, { @@ -779,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 **Q15.17** and **Q15.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 **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." ] }, { @@ -809,14 +567,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.17**: Copy the base case from the original `hanoi()`!" + "**Q1.17**: Copy the base case from the original `hanoi()`!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.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", + "**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", "\n", "Then, copy the `print()` statement from `hanoi()` and adjust it to print out `count` as well!" ] @@ -825,7 +583,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.19**: Execute the code cells below and confirm that the order numbers are correct!" + "**Q1.19**: Execute the code cells below and confirm that the order numbers are correct!" ] }, { @@ -882,7 +640,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q15.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?" + "**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?" ] }, { @@ -909,7 +667,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "toc": { "base_numbering": 1, @@ -926,5 +684,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/05_numbers.ipynb b/05_numbers_00_content.ipynb similarity index 96% rename from 05_numbers.ipynb rename to 05_numbers_00_content.ipynb index 48d8623..1f7ebc2 100644 --- a/05_numbers.ipynb +++ b/05_numbers_00_content.ipynb @@ -21,15 +21,15 @@ "source": [ "After learning about the basic building blocks of expressing and structuring the business logic in programs, we focus our attention on the **data types** Python offers us, both built-in and available via the [standard library](https://docs.python.org/3/library/index.html) or third-party packages.\n", "\n", - "We start with the \"simple\" ones: Numeric types in this chapter and textual data in [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb). An important fact that holds for all objects of these types is that they are **immutable**. To reuse the bag analogy from [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Objects-vs.-Types-vs.-Values), this means that the $0$s and $1$s making up an object's *value* cannot be changed once the bag is created in memory, implying that any operation with or method on the object creates a *new* object in a *different* memory location.\n", + "We start with the \"simple\" ones: Numeric types in this chapter and textual data in [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text_00_content.ipynb). An important fact that holds for all objects of these types is that they are **immutable**. To reuse the bag analogy from [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Objects-vs.-Types-vs.-Values), this means that the $0$s and $1$s making up an object's *value* cannot be changed once the bag is created in memory, implying that any operation with or method on the object creates a *new* object in a *different* memory location.\n", "\n", - "[Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb) and [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings.ipynb) then cover the more \"complex\" data types, including, for example, the `list` type. Finally, Chapter 9 completes the picture by introducing language constructs to create custom types.\n", + "[Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb), [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_00_content.ipynb), and [Chapter 9](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/09_arrays_00_content.ipynb) then cover the more \"complex\" data types, including, for example, the `list` type. Finally, Chapter 10 completes the picture by introducing language constructs to create custom types.\n", "\n", "We have already seen many hints indicating that numbers are not as trivial to work with as it seems at first sight:\n", "\n", - "- [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#%28Data%29-Type-%2F-%22Behavior%22) reveals that numbers may come in *different* data types (i.e., `int` vs. `float` so far),\n", - "- [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals.ipynb#Boolean-Expressions) raises questions regarding the **limited precision** of `float` numbers (e.g., `42 == 42.000000000000001` evaluates to `True`), and\n", - "- [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Infinite-Recursion) shows that sometimes a `float` \"walks\" and \"quacks\" like an `int`, whereas the reverse is true in other cases.\n", + "- [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#%28Data%29-Type-%2F-%22Behavior%22) reveals that numbers may come in *different* data types (i.e., `int` vs. `float` so far),\n", + "- [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_content.ipynb#Boolean-Expressions) raises questions regarding the **limited precision** of `float` numbers (e.g., `42 == 42.000000000000001` evaluates to `True`), and\n", + "- [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#Infinite-Recursion) shows that sometimes a `float` \"walks\" and \"quacks\" like an `int`, whereas the reverse is true in other cases.\n", "\n", "This chapter introduces all the [built-in numeric types](https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex): `int`, `float`, and `complex`. To mitigate the limited precision of floating-point numbers, we also look at two replacements for the `float` type in the [standard library](https://docs.python.org/3/library/index.html), namely the `Decimal` type in the [decimals](https://docs.python.org/3/library/decimal.html#decimal.Decimal) and the `Fraction` type in the [fractions](https://docs.python.org/3/library/fractions.html#fractions.Fraction) module." ] @@ -53,7 +53,7 @@ } }, "source": [ - "The simplest numeric type is the `int` type: It behaves like an [integer in ordinary math](https://en.wikipedia.org/wiki/Integer) (i.e., the set $\\mathbb{Z}$) and supports operators in the way we saw in the section on arithmetic operators in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#%28Arithmetic%29-Operators)." + "The simplest numeric type is the `int` type: It behaves like an [integer in ordinary math](https://en.wikipedia.org/wiki/Integer) (i.e., the set $\\mathbb{Z}$) and supports operators in the way we saw in the section on arithmetic operators in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#%28Arithmetic%29-Operators)." ] }, { @@ -92,7 +92,7 @@ { "data": { "text/plain": [ - "140673805309168" + "140166838695792" ] }, "execution_count": 2, @@ -1481,7 +1481,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 47, "metadata": { "slideshow": { "slide_type": "slide" @@ -1494,7 +1494,7 @@ "'0b1011 & 0b1101'" ] }, - "execution_count": 42, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -1505,7 +1505,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 48, "metadata": { "slideshow": { "slide_type": "-" @@ -1518,7 +1518,7 @@ "'0b1001'" ] }, - "execution_count": 43, + "execution_count": 48, "metadata": {}, "output_type": "execute_result" } @@ -1540,7 +1540,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 49, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1553,7 +1553,7 @@ "9" ] }, - "execution_count": 44, + "execution_count": 49, "metadata": {}, "output_type": "execute_result" } @@ -1564,7 +1564,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 50, "metadata": { "slideshow": { "slide_type": "-" @@ -1577,7 +1577,7 @@ "9" ] }, - "execution_count": 45, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } @@ -1599,7 +1599,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 51, "metadata": { "slideshow": { "slide_type": "slide" @@ -1612,7 +1612,7 @@ "'0b1001 | 0b1101'" ] }, - "execution_count": 46, + "execution_count": 51, "metadata": {}, "output_type": "execute_result" } @@ -1623,7 +1623,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 52, "metadata": { "slideshow": { "slide_type": "-" @@ -1636,7 +1636,7 @@ "'0b1101'" ] }, - "execution_count": 47, + "execution_count": 52, "metadata": {}, "output_type": "execute_result" } @@ -1658,7 +1658,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 53, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1671,7 +1671,7 @@ "13" ] }, - "execution_count": 48, + "execution_count": 53, "metadata": {}, "output_type": "execute_result" } @@ -1682,7 +1682,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 54, "metadata": { "slideshow": { "slide_type": "-" @@ -1695,7 +1695,7 @@ "13" ] }, - "execution_count": 49, + "execution_count": 54, "metadata": {}, "output_type": "execute_result" } @@ -1717,7 +1717,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 55, "metadata": { "slideshow": { "slide_type": "slide" @@ -1730,7 +1730,7 @@ "'0b1001 ^ 0b1101'" ] }, - "execution_count": 50, + "execution_count": 55, "metadata": {}, "output_type": "execute_result" } @@ -1741,7 +1741,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 56, "metadata": { "slideshow": { "slide_type": "-" @@ -1754,7 +1754,7 @@ "'0b100'" ] }, - "execution_count": 51, + "execution_count": 56, "metadata": {}, "output_type": "execute_result" } @@ -1776,7 +1776,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 57, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1789,7 +1789,7 @@ "4" ] }, - "execution_count": 52, + "execution_count": 57, "metadata": {}, "output_type": "execute_result" } @@ -1800,7 +1800,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 58, "metadata": { "slideshow": { "slide_type": "-" @@ -1813,7 +1813,7 @@ "4" ] }, - "execution_count": 53, + "execution_count": 58, "metadata": {}, "output_type": "execute_result" } @@ -1837,7 +1837,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 59, "metadata": { "slideshow": { "slide_type": "slide" @@ -1850,7 +1850,7 @@ "'-0b1001'" ] }, - "execution_count": 54, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -1861,7 +1861,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 60, "metadata": { "slideshow": { "slide_type": "-" @@ -1874,7 +1874,7 @@ "'-0b1001'" ] }, - "execution_count": 55, + "execution_count": 60, "metadata": {}, "output_type": "execute_result" } @@ -1896,7 +1896,7 @@ }, { "cell_type": "code", - "execution_count": 56, + "execution_count": 61, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1909,7 +1909,7 @@ "-1" ] }, - "execution_count": 56, + "execution_count": 61, "metadata": {}, "output_type": "execute_result" } @@ -1933,7 +1933,7 @@ }, { "cell_type": "code", - "execution_count": 57, + "execution_count": 62, "metadata": { "slideshow": { "slide_type": "slide" @@ -1946,7 +1946,7 @@ "'0b1001'" ] }, - "execution_count": 57, + "execution_count": 62, "metadata": {}, "output_type": "execute_result" } @@ -1957,7 +1957,7 @@ }, { "cell_type": "code", - "execution_count": 58, + "execution_count": 63, "metadata": { "slideshow": { "slide_type": "-" @@ -1970,7 +1970,7 @@ "'0b100100'" ] }, - "execution_count": 58, + "execution_count": 63, "metadata": {}, "output_type": "execute_result" } @@ -1981,7 +1981,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 64, "metadata": { "slideshow": { "slide_type": "-" @@ -1994,7 +1994,7 @@ "36" ] }, - "execution_count": 59, + "execution_count": 64, "metadata": {}, "output_type": "execute_result" } @@ -2016,7 +2016,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 65, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2029,7 +2029,7 @@ "'0b10'" ] }, - "execution_count": 60, + "execution_count": 65, "metadata": {}, "output_type": "execute_result" } @@ -2040,7 +2040,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 66, "metadata": { "slideshow": { "slide_type": "-" @@ -2053,7 +2053,7 @@ "2" ] }, - "execution_count": 61, + "execution_count": 66, "metadata": {}, "output_type": "execute_result" } @@ -2092,7 +2092,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 67, "metadata": { "slideshow": { "slide_type": "slide" @@ -2105,7 +2105,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 68, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2115,10 +2115,10 @@ { "data": { "text/plain": [ - "140673805486768" + "140166567715664" ] }, - "execution_count": 63, + "execution_count": 68, "metadata": {}, "output_type": "execute_result" } @@ -2129,7 +2129,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 69, "metadata": { "slideshow": { "slide_type": "-" @@ -2142,7 +2142,7 @@ "float" ] }, - "execution_count": 64, + "execution_count": 69, "metadata": {}, "output_type": "execute_result" } @@ -2153,7 +2153,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 70, "metadata": { "slideshow": { "slide_type": "-" @@ -2166,7 +2166,7 @@ "1.23" ] }, - "execution_count": 65, + "execution_count": 70, "metadata": {}, "output_type": "execute_result" } @@ -2188,7 +2188,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 71, "metadata": { "slideshow": { "slide_type": "skip" @@ -2201,7 +2201,7 @@ "0.123456789" ] }, - "execution_count": 66, + "execution_count": 71, "metadata": {}, "output_type": "execute_result" } @@ -2223,7 +2223,7 @@ }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 72, "metadata": { "slideshow": { "slide_type": "slide" @@ -2236,7 +2236,7 @@ "1.0" ] }, - "execution_count": 67, + "execution_count": 72, "metadata": {}, "output_type": "execute_result" } @@ -2247,7 +2247,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 73, "metadata": { "slideshow": { "slide_type": "-" @@ -2260,7 +2260,7 @@ "1.0" ] }, - "execution_count": 68, + "execution_count": 73, "metadata": {}, "output_type": "execute_result" } @@ -2271,7 +2271,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 74, "metadata": { "slideshow": { "slide_type": "skip" @@ -2284,7 +2284,7 @@ "1.0" ] }, - "execution_count": 69, + "execution_count": 74, "metadata": {}, "output_type": "execute_result" } @@ -2306,7 +2306,7 @@ }, { "cell_type": "code", - "execution_count": 70, + "execution_count": 75, "metadata": { "slideshow": { "slide_type": "slide" @@ -2319,7 +2319,7 @@ "0.3333333333333333" ] }, - "execution_count": 70, + "execution_count": 75, "metadata": {}, "output_type": "execute_result" } @@ -2341,7 +2341,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 76, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2354,7 +2354,7 @@ "42.0" ] }, - "execution_count": 71, + "execution_count": 76, "metadata": {}, "output_type": "execute_result" } @@ -2365,7 +2365,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 77, "metadata": { "slideshow": { "slide_type": "-" @@ -2378,7 +2378,7 @@ "42.0" ] }, - "execution_count": 72, + "execution_count": 77, "metadata": {}, "output_type": "execute_result" } @@ -2411,7 +2411,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 78, "metadata": { "slideshow": { "slide_type": "slide" @@ -2424,7 +2424,7 @@ "1.23" ] }, - "execution_count": 73, + "execution_count": 78, "metadata": {}, "output_type": "execute_result" } @@ -2446,7 +2446,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 79, "metadata": { "slideshow": { "slide_type": "skip" @@ -2455,10 +2455,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 1.23 e0\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 1.23 e0\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], @@ -2468,7 +2468,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 80, "metadata": { "slideshow": { "slide_type": "skip" @@ -2477,10 +2477,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 1.23e 0\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 1.23e 0\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], @@ -2490,7 +2490,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 81, "metadata": { "slideshow": { "slide_type": "skip" @@ -2499,10 +2499,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 1.23e0.0\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 1.23e0.0\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], @@ -2523,7 +2523,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 82, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2537,7 +2537,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[0me1\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[0me1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'e1' is not defined" ] } @@ -2559,7 +2559,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 83, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2572,7 +2572,7 @@ "10.0" ] }, - "execution_count": 78, + "execution_count": 83, "metadata": {}, "output_type": "execute_result" } @@ -2605,7 +2605,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 84, "metadata": { "slideshow": { "slide_type": "slide" @@ -2618,166 +2618,13 @@ "nan" ] }, - "execution_count": 79, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "float(\"nan\") # also works as float(\"NaN\")" - ] - }, - { - "cell_type": "code", - "execution_count": 80, - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "inf" - ] - }, - "execution_count": 80, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "float(\"+inf\") # also works as float(\"+infinity\")" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "metadata": { - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "inf" - ] - }, - "execution_count": 81, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "float(\"inf\") # by omitting the plus sign we mean positive infinity" - ] - }, - { - "cell_type": "code", - "execution_count": 82, - "metadata": { - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "-inf" - ] - }, - "execution_count": 82, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "float(\"-inf\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "`nan` objects *never* compare equal to *anything*, not even to themselves. This happens in accordance with the [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) standard." - ] - }, - { - "cell_type": "code", - "execution_count": 83, - "metadata": { - "slideshow": { - "slide_type": "slide" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 83, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "float(\"nan\") == float(\"nan\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "On the contrary, as two values go to infinity, there is no such concept as difference and *everything* compares equal." - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "float(\"inf\") == float(\"inf\")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "Adding `42` to `inf` makes no difference." + "float(\"nan\") # also works as float(\"NaN\")" ] }, { @@ -2801,12 +2648,106 @@ } ], "source": [ - "float(\"inf\") + 42" + "float(\"+inf\") # also works as float(\"+infinity\")" ] }, { "cell_type": "code", "execution_count": 86, + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "inf" + ] + }, + "execution_count": 86, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "float(\"inf\") # by omitting the plus sign we mean positive infinity" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "-inf" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "float(\"-inf\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "`nan` objects *never* compare equal to *anything*, not even to themselves. This happens in accordance with the [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) standard." + ] + }, + { + "cell_type": "code", + "execution_count": 88, + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 88, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "float(\"nan\") == float(\"nan\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "On the contrary, as two values go to infinity, there is no such concept as difference and *everything* compares equal." + ] + }, + { + "cell_type": "code", + "execution_count": 89, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2819,7 +2760,66 @@ "True" ] }, - "execution_count": 86, + "execution_count": 89, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "float(\"inf\") == float(\"inf\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "Adding `42` to `inf` makes no difference." + ] + }, + { + "cell_type": "code", + "execution_count": 90, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "inf" + ] + }, + "execution_count": 90, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "float(\"inf\") + 42" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 91, "metadata": {}, "output_type": "execute_result" } @@ -2841,7 +2841,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 92, "metadata": { "slideshow": { "slide_type": "skip" @@ -2854,7 +2854,7 @@ "inf" ] }, - "execution_count": 87, + "execution_count": 92, "metadata": {}, "output_type": "execute_result" } @@ -2865,7 +2865,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 93, "metadata": { "slideshow": { "slide_type": "skip" @@ -2878,7 +2878,7 @@ "True" ] }, - "execution_count": 88, + "execution_count": 93, "metadata": {}, "output_type": "execute_result" } @@ -2900,7 +2900,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 94, "metadata": { "slideshow": { "slide_type": "skip" @@ -2913,7 +2913,7 @@ "inf" ] }, - "execution_count": 89, + "execution_count": 94, "metadata": {}, "output_type": "execute_result" } @@ -2924,7 +2924,7 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 95, "metadata": { "slideshow": { "slide_type": "skip" @@ -2937,7 +2937,7 @@ "True" ] }, - "execution_count": 90, + "execution_count": 95, "metadata": {}, "output_type": "execute_result" } @@ -2959,7 +2959,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 96, "metadata": { "slideshow": { "slide_type": "skip" @@ -2972,7 +2972,7 @@ "inf" ] }, - "execution_count": 91, + "execution_count": 96, "metadata": {}, "output_type": "execute_result" } @@ -2983,7 +2983,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 97, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2996,7 +2996,7 @@ "True" ] }, - "execution_count": 92, + "execution_count": 97, "metadata": {}, "output_type": "execute_result" } @@ -3018,7 +3018,7 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 98, "metadata": { "slideshow": { "slide_type": "slide" @@ -3031,7 +3031,7 @@ "nan" ] }, - "execution_count": 93, + "execution_count": 98, "metadata": {}, "output_type": "execute_result" } @@ -3042,7 +3042,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 99, "metadata": { "slideshow": { "slide_type": "-" @@ -3055,7 +3055,7 @@ "nan" ] }, - "execution_count": 94, + "execution_count": 99, "metadata": {}, "output_type": "execute_result" } @@ -3085,12 +3085,12 @@ "source": [ "`float` objects are *inherently* imprecise, and there is *nothing* we can do about it! In particular, arithmetic operations with two `float` objects may result in \"weird\" rounding \"errors\" that are strictly deterministic and occur in accordance with the [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) standard.\n", "\n", - "For example, let's add `1e0` to `1e15` and `1e16`, respectively. In the latter case, the `1e0` somehow gets \"lost\"." + "For example, let's add `1e0` to `1e15` and `1e16`, respectively. In the latter case, the `1e0` somehow gets \"lost.\"" ] }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 100, "metadata": { "slideshow": { "slide_type": "skip" @@ -3103,7 +3103,7 @@ "1000000000000001.0" ] }, - "execution_count": 95, + "execution_count": 100, "metadata": {}, "output_type": "execute_result" } @@ -3114,7 +3114,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 101, "metadata": { "slideshow": { "slide_type": "skip" @@ -3127,7 +3127,7 @@ "1e+16" ] }, - "execution_count": 96, + "execution_count": 101, "metadata": {}, "output_type": "execute_result" } @@ -3149,7 +3149,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 102, "metadata": { "slideshow": { "slide_type": "slide" @@ -3162,7 +3162,7 @@ "1000000000000001.0" ] }, - "execution_count": 97, + "execution_count": 102, "metadata": {}, "output_type": "execute_result" } @@ -3173,7 +3173,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 103, "metadata": { "slideshow": { "slide_type": "-" @@ -3186,7 +3186,7 @@ "1e+16" ] }, - "execution_count": 98, + "execution_count": 103, "metadata": {}, "output_type": "execute_result" } @@ -3208,7 +3208,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 104, "metadata": { "slideshow": { "slide_type": "slide" @@ -3221,7 +3221,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 105, "metadata": { "slideshow": { "slide_type": "-" @@ -3234,7 +3234,7 @@ "2.0000000000000004" ] }, - "execution_count": 100, + "execution_count": 105, "metadata": {}, "output_type": "execute_result" } @@ -3245,7 +3245,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 106, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3258,7 +3258,7 @@ "0.30000000000000004" ] }, - "execution_count": 101, + "execution_count": 106, "metadata": {}, "output_type": "execute_result" } @@ -3280,7 +3280,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 107, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3293,7 +3293,7 @@ "False" ] }, - "execution_count": 102, + "execution_count": 107, "metadata": {}, "output_type": "execute_result" } @@ -3304,7 +3304,7 @@ }, { "cell_type": "code", - "execution_count": 103, + "execution_count": 108, "metadata": { "slideshow": { "slide_type": "-" @@ -3317,7 +3317,7 @@ "False" ] }, - "execution_count": 103, + "execution_count": 108, "metadata": {}, "output_type": "execute_result" } @@ -3339,7 +3339,7 @@ }, { "cell_type": "code", - "execution_count": 104, + "execution_count": 109, "metadata": { "slideshow": { "slide_type": "slide" @@ -3352,7 +3352,7 @@ }, { "cell_type": "code", - "execution_count": 105, + "execution_count": 110, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3365,7 +3365,7 @@ "True" ] }, - "execution_count": 105, + "execution_count": 110, "metadata": {}, "output_type": "execute_result" } @@ -3376,7 +3376,7 @@ }, { "cell_type": "code", - "execution_count": 106, + "execution_count": 111, "metadata": { "slideshow": { "slide_type": "-" @@ -3389,7 +3389,7 @@ "True" ] }, - "execution_count": 106, + "execution_count": 111, "metadata": {}, "output_type": "execute_result" } @@ -3413,7 +3413,7 @@ }, { "cell_type": "code", - "execution_count": 107, + "execution_count": 112, "metadata": { "slideshow": { "slide_type": "slide" @@ -3426,7 +3426,7 @@ "'0.10000000000000000555111512312578270211815834045410'" ] }, - "execution_count": 107, + "execution_count": 112, "metadata": {}, "output_type": "execute_result" } @@ -3437,7 +3437,7 @@ }, { "cell_type": "code", - "execution_count": 108, + "execution_count": 113, "metadata": { "slideshow": { "slide_type": "-" @@ -3450,7 +3450,7 @@ "'0.20000000000000001110223024625156540423631668090820'" ] }, - "execution_count": 108, + "execution_count": 113, "metadata": {}, "output_type": "execute_result" } @@ -3461,7 +3461,7 @@ }, { "cell_type": "code", - "execution_count": 109, + "execution_count": 114, "metadata": { "slideshow": { "slide_type": "-" @@ -3474,7 +3474,7 @@ "'0.29999999999999998889776975374843459576368331909180'" ] }, - "execution_count": 109, + "execution_count": 114, "metadata": {}, "output_type": "execute_result" } @@ -3485,7 +3485,7 @@ }, { "cell_type": "code", - "execution_count": 110, + "execution_count": 115, "metadata": { "slideshow": { "slide_type": "slide" @@ -3498,7 +3498,7 @@ "'0.33333333333333331482961625624739099293947219848633'" ] }, - "execution_count": 110, + "execution_count": 115, "metadata": {}, "output_type": "execute_result" } @@ -3524,7 +3524,7 @@ }, { "cell_type": "code", - "execution_count": 111, + "execution_count": 116, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3537,7 +3537,7 @@ }, { "cell_type": "code", - "execution_count": 112, + "execution_count": 117, "metadata": { "slideshow": { "slide_type": "-" @@ -3550,7 +3550,7 @@ "0.33333" ] }, - "execution_count": 112, + "execution_count": 117, "metadata": {}, "output_type": "execute_result" } @@ -3561,7 +3561,7 @@ }, { "cell_type": "code", - "execution_count": 113, + "execution_count": 118, "metadata": { "slideshow": { "slide_type": "-" @@ -3574,7 +3574,7 @@ "'0.33333000000000001517008740847813896834850311279297'" ] }, - "execution_count": 113, + "execution_count": 118, "metadata": {}, "output_type": "execute_result" } @@ -3596,7 +3596,7 @@ }, { "cell_type": "code", - "execution_count": 114, + "execution_count": 119, "metadata": { "slideshow": { "slide_type": "slide" @@ -3609,7 +3609,7 @@ "'0.12500000000000000000000000000000000000000000000000'" ] }, - "execution_count": 114, + "execution_count": 119, "metadata": {}, "output_type": "execute_result" } @@ -3620,7 +3620,7 @@ }, { "cell_type": "code", - "execution_count": 115, + "execution_count": 120, "metadata": { "slideshow": { "slide_type": "-" @@ -3633,7 +3633,7 @@ "'0.25000000000000000000000000000000000000000000000000'" ] }, - "execution_count": 115, + "execution_count": 120, "metadata": {}, "output_type": "execute_result" } @@ -3644,7 +3644,7 @@ }, { "cell_type": "code", - "execution_count": 116, + "execution_count": 121, "metadata": { "slideshow": { "slide_type": "-" @@ -3657,7 +3657,7 @@ "True" ] }, - "execution_count": 116, + "execution_count": 121, "metadata": {}, "output_type": "execute_result" } @@ -3689,7 +3689,7 @@ "\n", "$$float = (-1)^{sign} * 1.fraction * 2^{exponent-1023}$$\n", "\n", - "A $1.$ is implicitly prepended as the first digit, and both, $fraction$ and $exponent$, are stored in base $2$ representation (i.e., they both are interpreted like integers above). As $exponent$ is consequently non-negative, between $0_{10}$ and $2047_{10}$ to be precise, the $-1023$ centers the entire $2^{exponent-1023}$ term around $1$ and allows the period within the $1.fraction$ part be shifted into either direction by the same amount. Floating-point numbers received their name as the period, formally called the **[radix point](https://en.wikipedia.org/wiki/Radix_point)**, \"floats\" along the significant digits. As an aside, an $exponent$ of all $0$s or all $1$s is used to model the special values `nan` or `inf`.\n", + "A $1.$ is implicitly prepended as the first digit, and both, $fraction$ and $exponent$, are stored in base $2$ representation (i.e., they both are interpreted like integers above). As $exponent$ is consequently non-negative, between $0_{10}$ and $2047_{10}$ to be precise, the $-1023$, called the exponent bias, centers the entire $2^{exponent-1023}$ term around $1$ and allows the period within the $1.fraction$ part be shifted into either direction by the same amount. Floating-point numbers received their name as the period, formally called the **[radix point](https://en.wikipedia.org/wiki/Radix_point)**, \"floats\" along the significant digits. As an aside, an $exponent$ of all $0$s or all $1$s is used to model the special values `nan` or `inf`.\n", "\n", "As the standard defines the exponent part to come as a power of $2$, we now see why `0.125` is a *precise* float: It can be represented as a power of $2$, i.e., $0.125 = (-1)^0 * 1.0 * 2^{1020-1023} = 2^{-3} = \\frac{1}{8}$. In other words, the floating-point representation of $0.125_{10}$ is $0_2$, $1111111100_2 = 1020_{10}$, and $0_2$ for the three groups, respectively." ] @@ -3726,7 +3726,7 @@ }, { "cell_type": "code", - "execution_count": 117, + "execution_count": 122, "metadata": { "slideshow": { "slide_type": "slide" @@ -3739,7 +3739,7 @@ }, { "cell_type": "code", - "execution_count": 118, + "execution_count": 123, "metadata": { "slideshow": { "slide_type": "-" @@ -3752,7 +3752,7 @@ "'0x1.0000000000000p-3'" ] }, - "execution_count": 118, + "execution_count": 123, "metadata": {}, "output_type": "execute_result" } @@ -3774,7 +3774,7 @@ }, { "cell_type": "code", - "execution_count": 119, + "execution_count": 124, "metadata": { "slideshow": { "slide_type": "-" @@ -3787,7 +3787,7 @@ "(1, 8)" ] }, - "execution_count": 119, + "execution_count": 124, "metadata": {}, "output_type": "execute_result" } @@ -3798,7 +3798,7 @@ }, { "cell_type": "code", - "execution_count": 120, + "execution_count": 125, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3811,7 +3811,7 @@ "'0x1.555475a31a4bep-2'" ] }, - "execution_count": 120, + "execution_count": 125, "metadata": {}, "output_type": "execute_result" } @@ -3822,7 +3822,7 @@ }, { "cell_type": "code", - "execution_count": 121, + "execution_count": 126, "metadata": { "slideshow": { "slide_type": "-" @@ -3835,7 +3835,7 @@ "(3002369727582815, 9007199254740992)" ] }, - "execution_count": 121, + "execution_count": 126, "metadata": {}, "output_type": "execute_result" } @@ -3857,7 +3857,7 @@ }, { "cell_type": "code", - "execution_count": 122, + "execution_count": 127, "metadata": { "slideshow": { "slide_type": "slide" @@ -3870,7 +3870,7 @@ }, { "cell_type": "code", - "execution_count": 123, + "execution_count": 128, "metadata": { "slideshow": { "slide_type": "-" @@ -3883,7 +3883,7 @@ "'0x0.0p+0'" ] }, - "execution_count": 123, + "execution_count": 128, "metadata": {}, "output_type": "execute_result" } @@ -3894,7 +3894,7 @@ }, { "cell_type": "code", - "execution_count": 124, + "execution_count": 129, "metadata": { "slideshow": { "slide_type": "-" @@ -3907,7 +3907,7 @@ "(0, 1)" ] }, - "execution_count": 124, + "execution_count": 129, "metadata": {}, "output_type": "execute_result" } @@ -3924,12 +3924,12 @@ } }, "source": [ - "As seen in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#%28Data%29-Type-%2F-%22Behavior%22), the [is_integer()](https://docs.python.org/3/library/stdtypes.html#float.is_integer) method tells us if a `float` can be casted as an `int` object without any loss in precision." + "As seen in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#%28Data%29-Type-%2F-%22Behavior%22), the [is_integer()](https://docs.python.org/3/library/stdtypes.html#float.is_integer) method tells us if a `float` can be casted as an `int` object without any loss in precision." ] }, { "cell_type": "code", - "execution_count": 125, + "execution_count": 130, "metadata": { "slideshow": { "slide_type": "skip" @@ -3942,7 +3942,7 @@ "False" ] }, - "execution_count": 125, + "execution_count": 130, "metadata": {}, "output_type": "execute_result" } @@ -3953,7 +3953,7 @@ }, { "cell_type": "code", - "execution_count": 126, + "execution_count": 131, "metadata": { "slideshow": { "slide_type": "skip" @@ -3966,7 +3966,7 @@ "True" ] }, - "execution_count": 126, + "execution_count": 131, "metadata": {}, "output_type": "execute_result" } @@ -3990,7 +3990,7 @@ }, { "cell_type": "code", - "execution_count": 127, + "execution_count": 132, "metadata": { "slideshow": { "slide_type": "skip" @@ -4003,7 +4003,7 @@ }, { "cell_type": "code", - "execution_count": 128, + "execution_count": 133, "metadata": { "slideshow": { "slide_type": "skip" @@ -4016,7 +4016,7 @@ "sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)" ] }, - "execution_count": 128, + "execution_count": 133, "metadata": {}, "output_type": "execute_result" } @@ -4051,7 +4051,7 @@ }, { "cell_type": "code", - "execution_count": 129, + "execution_count": 134, "metadata": { "slideshow": { "slide_type": "slide" @@ -4075,7 +4075,7 @@ }, { "cell_type": "code", - "execution_count": 130, + "execution_count": 135, "metadata": { "slideshow": { "slide_type": "fragment" @@ -4088,7 +4088,7 @@ "Context(prec=28, rounding=ROUND_HALF_EVEN, Emin=-999999, Emax=999999, capitals=1, clamp=0, flags=[], traps=[InvalidOperation, DivisionByZero, Overflow])" ] }, - "execution_count": 130, + "execution_count": 135, "metadata": {}, "output_type": "execute_result" } @@ -4110,7 +4110,7 @@ }, { "cell_type": "code", - "execution_count": 131, + "execution_count": 136, "metadata": { "slideshow": { "slide_type": "slide" @@ -4123,7 +4123,7 @@ "Decimal('42')" ] }, - "execution_count": 131, + "execution_count": 136, "metadata": {}, "output_type": "execute_result" } @@ -4134,7 +4134,7 @@ }, { "cell_type": "code", - "execution_count": 132, + "execution_count": 137, "metadata": { "slideshow": { "slide_type": "-" @@ -4147,7 +4147,7 @@ "Decimal('0.1')" ] }, - "execution_count": 132, + "execution_count": 137, "metadata": {}, "output_type": "execute_result" } @@ -4158,7 +4158,7 @@ }, { "cell_type": "code", - "execution_count": 133, + "execution_count": 138, "metadata": { "slideshow": { "slide_type": "-" @@ -4171,7 +4171,7 @@ "Decimal('1E+5')" ] }, - "execution_count": 133, + "execution_count": 138, "metadata": {}, "output_type": "execute_result" } @@ -4193,7 +4193,7 @@ }, { "cell_type": "code", - "execution_count": 134, + "execution_count": 139, "metadata": { "slideshow": { "slide_type": "fragment" @@ -4206,7 +4206,7 @@ "Decimal('0.1000000000000000055511151231257827021181583404541015625')" ] }, - "execution_count": 134, + "execution_count": 139, "metadata": {}, "output_type": "execute_result" } @@ -4228,7 +4228,7 @@ }, { "cell_type": "code", - "execution_count": 135, + "execution_count": 140, "metadata": { "slideshow": { "slide_type": "slide" @@ -4241,7 +4241,7 @@ "Decimal('0.3')" ] }, - "execution_count": 135, + "execution_count": 140, "metadata": {}, "output_type": "execute_result" } @@ -4252,7 +4252,7 @@ }, { "cell_type": "code", - "execution_count": 136, + "execution_count": 141, "metadata": { "slideshow": { "slide_type": "-" @@ -4265,7 +4265,7 @@ "True" ] }, - "execution_count": 136, + "execution_count": 141, "metadata": {}, "output_type": "execute_result" } @@ -4287,7 +4287,7 @@ }, { "cell_type": "code", - "execution_count": 137, + "execution_count": 142, "metadata": { "slideshow": { "slide_type": "fragment" @@ -4300,7 +4300,7 @@ "Decimal('0.30000')" ] }, - "execution_count": 137, + "execution_count": 142, "metadata": {}, "output_type": "execute_result" } @@ -4311,7 +4311,7 @@ }, { "cell_type": "code", - "execution_count": 138, + "execution_count": 143, "metadata": { "slideshow": { "slide_type": "-" @@ -4324,7 +4324,7 @@ "True" ] }, - "execution_count": 138, + "execution_count": 143, "metadata": {}, "output_type": "execute_result" } @@ -4346,7 +4346,7 @@ }, { "cell_type": "code", - "execution_count": 139, + "execution_count": 144, "metadata": { "slideshow": { "slide_type": "slide" @@ -4359,7 +4359,7 @@ "Decimal('42')" ] }, - "execution_count": 139, + "execution_count": 144, "metadata": {}, "output_type": "execute_result" } @@ -4370,7 +4370,7 @@ }, { "cell_type": "code", - "execution_count": 140, + "execution_count": 145, "metadata": { "slideshow": { "slide_type": "-" @@ -4383,7 +4383,7 @@ "Decimal('42')" ] }, - "execution_count": 140, + "execution_count": 145, "metadata": {}, "output_type": "execute_result" } @@ -4394,7 +4394,7 @@ }, { "cell_type": "code", - "execution_count": 141, + "execution_count": 146, "metadata": { "slideshow": { "slide_type": "slide" @@ -4407,7 +4407,7 @@ "Decimal('0.1')" ] }, - "execution_count": 141, + "execution_count": 146, "metadata": {}, "output_type": "execute_result" } @@ -4429,7 +4429,7 @@ }, { "cell_type": "code", - "execution_count": 142, + "execution_count": 147, "metadata": { "slideshow": { "slide_type": "fragment" @@ -4442,7 +4442,7 @@ "'0.10000000000000000000000000000000000000000000000000'" ] }, - "execution_count": 142, + "execution_count": 147, "metadata": {}, "output_type": "execute_result" } @@ -4453,7 +4453,7 @@ }, { "cell_type": "code", - "execution_count": 143, + "execution_count": 148, "metadata": { "slideshow": { "slide_type": "-" @@ -4466,7 +4466,7 @@ "'0.10000000000000000555111512312578270211815834045410'" ] }, - "execution_count": 143, + "execution_count": 148, "metadata": {}, "output_type": "execute_result" } @@ -4488,7 +4488,7 @@ }, { "cell_type": "code", - "execution_count": 144, + "execution_count": 149, "metadata": { "slideshow": { "slide_type": "slide" @@ -4502,7 +4502,7 @@ "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[0;36m1.0\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mDecimal\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;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;36m1.0\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mDecimal\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;31mTypeError\u001b[0m: unsupported operand type(s) for *: 'float' and 'decimal.Decimal'" ] } @@ -4524,7 +4524,7 @@ }, { "cell_type": "code", - "execution_count": 145, + "execution_count": 150, "metadata": { "slideshow": { "slide_type": "slide" @@ -4537,7 +4537,7 @@ "Decimal('2')" ] }, - "execution_count": 145, + "execution_count": 150, "metadata": {}, "output_type": "execute_result" } @@ -4548,7 +4548,7 @@ }, { "cell_type": "code", - "execution_count": 146, + "execution_count": 151, "metadata": { "slideshow": { "slide_type": "-" @@ -4561,7 +4561,7 @@ "Decimal('1.414213562373095048801688724')" ] }, - "execution_count": 146, + "execution_count": 151, "metadata": {}, "output_type": "execute_result" } @@ -4585,7 +4585,7 @@ }, { "cell_type": "code", - "execution_count": 147, + "execution_count": 152, "metadata": { "slideshow": { "slide_type": "fragment" @@ -4598,7 +4598,7 @@ "Decimal('1.999999999999999999999999999')" ] }, - "execution_count": 147, + "execution_count": 152, "metadata": {}, "output_type": "execute_result" } @@ -4624,7 +4624,7 @@ }, { "cell_type": "code", - "execution_count": 148, + "execution_count": 153, "metadata": { "slideshow": { "slide_type": "fragment" @@ -4637,7 +4637,7 @@ "Decimal('2.0000')" ] }, - "execution_count": 148, + "execution_count": 153, "metadata": {}, "output_type": "execute_result" } @@ -4655,7 +4655,7 @@ }, { "cell_type": "code", - "execution_count": 149, + "execution_count": 154, "metadata": {}, "outputs": [ { @@ -4665,7 +4665,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mInvalidOperation\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[0mtwo\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquantize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mDecimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"0.1\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m**\u001b[0m \u001b[0;36m28\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[0mtwo\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquantize\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mDecimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"0.1\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m**\u001b[0m \u001b[0;36m28\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mInvalidOperation\u001b[0m: []" ] } @@ -4687,7 +4687,7 @@ }, { "cell_type": "code", - "execution_count": 150, + "execution_count": 155, "metadata": { "slideshow": { "slide_type": "skip" @@ -4700,7 +4700,7 @@ "True" ] }, - "execution_count": 150, + "execution_count": 155, "metadata": {}, "output_type": "execute_result" } @@ -4722,7 +4722,7 @@ }, { "cell_type": "code", - "execution_count": 151, + "execution_count": 156, "metadata": { "slideshow": { "slide_type": "fragment" @@ -4735,7 +4735,7 @@ "True" ] }, - "execution_count": 151, + "execution_count": 156, "metadata": {}, "output_type": "execute_result" } @@ -4757,7 +4757,7 @@ }, { "cell_type": "code", - "execution_count": 152, + "execution_count": 157, "metadata": { "slideshow": { "slide_type": "skip" @@ -4770,7 +4770,7 @@ "Decimal('NaN')" ] }, - "execution_count": 152, + "execution_count": 157, "metadata": {}, "output_type": "execute_result" } @@ -4781,7 +4781,7 @@ }, { "cell_type": "code", - "execution_count": 153, + "execution_count": 158, "metadata": { "slideshow": { "slide_type": "skip" @@ -4794,7 +4794,7 @@ "False" ] }, - "execution_count": 153, + "execution_count": 158, "metadata": {}, "output_type": "execute_result" } @@ -4805,7 +4805,7 @@ }, { "cell_type": "code", - "execution_count": 154, + "execution_count": 159, "metadata": { "slideshow": { "slide_type": "skip" @@ -4818,7 +4818,7 @@ "Decimal('Infinity')" ] }, - "execution_count": 154, + "execution_count": 159, "metadata": {}, "output_type": "execute_result" } @@ -4829,7 +4829,7 @@ }, { "cell_type": "code", - "execution_count": 155, + "execution_count": 160, "metadata": { "slideshow": { "slide_type": "skip" @@ -4842,7 +4842,7 @@ "Decimal('-Infinity')" ] }, - "execution_count": 155, + "execution_count": 160, "metadata": {}, "output_type": "execute_result" } @@ -4853,7 +4853,7 @@ }, { "cell_type": "code", - "execution_count": 156, + "execution_count": 161, "metadata": { "slideshow": { "slide_type": "skip" @@ -4866,7 +4866,7 @@ "Decimal('Infinity')" ] }, - "execution_count": 156, + "execution_count": 161, "metadata": {}, "output_type": "execute_result" } @@ -4877,7 +4877,7 @@ }, { "cell_type": "code", - "execution_count": 157, + "execution_count": 162, "metadata": { "slideshow": { "slide_type": "skip" @@ -4890,7 +4890,7 @@ "True" ] }, - "execution_count": 157, + "execution_count": 162, "metadata": {}, "output_type": "execute_result" } @@ -4912,7 +4912,7 @@ }, { "cell_type": "code", - "execution_count": 158, + "execution_count": 163, "metadata": { "slideshow": { "slide_type": "skip" @@ -4926,7 +4926,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mInvalidOperation\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[0mDecimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"inf\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mDecimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"-inf\"\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[0mDecimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"inf\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mDecimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"-inf\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mInvalidOperation\u001b[0m: []" ] } @@ -4937,7 +4937,7 @@ }, { "cell_type": "code", - "execution_count": 159, + "execution_count": 164, "metadata": { "slideshow": { "slide_type": "skip" @@ -4951,7 +4951,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mInvalidOperation\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[0mDecimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"inf\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mDecimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"inf\"\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[0mDecimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"inf\"\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0mDecimal\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"inf\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mInvalidOperation\u001b[0m: []" ] } @@ -4997,7 +4997,7 @@ }, { "cell_type": "code", - "execution_count": 160, + "execution_count": 165, "metadata": { "slideshow": { "slide_type": "slide" @@ -5021,7 +5021,7 @@ }, { "cell_type": "code", - "execution_count": 161, + "execution_count": 166, "metadata": { "slideshow": { "slide_type": "fragment" @@ -5034,7 +5034,7 @@ "Fraction(1, 3)" ] }, - "execution_count": 161, + "execution_count": 166, "metadata": {}, "output_type": "execute_result" } @@ -5045,7 +5045,7 @@ }, { "cell_type": "code", - "execution_count": 162, + "execution_count": 167, "metadata": { "slideshow": { "slide_type": "-" @@ -5058,7 +5058,7 @@ "Fraction(1, 3)" ] }, - "execution_count": 162, + "execution_count": 167, "metadata": {}, "output_type": "execute_result" } @@ -5069,7 +5069,7 @@ }, { "cell_type": "code", - "execution_count": 163, + "execution_count": 168, "metadata": { "slideshow": { "slide_type": "-" @@ -5082,7 +5082,7 @@ "Fraction(3333333333, 10000000000)" ] }, - "execution_count": 163, + "execution_count": 168, "metadata": {}, "output_type": "execute_result" } @@ -5093,7 +5093,7 @@ }, { "cell_type": "code", - "execution_count": 164, + "execution_count": 169, "metadata": { "slideshow": { "slide_type": "-" @@ -5106,7 +5106,7 @@ "Fraction(3333333333, 10000000000)" ] }, - "execution_count": 164, + "execution_count": 169, "metadata": {}, "output_type": "execute_result" } @@ -5128,7 +5128,7 @@ }, { "cell_type": "code", - "execution_count": 165, + "execution_count": 170, "metadata": { "slideshow": { "slide_type": "slide" @@ -5141,7 +5141,7 @@ "Fraction(3, 2)" ] }, - "execution_count": 165, + "execution_count": 170, "metadata": {}, "output_type": "execute_result" } @@ -5152,7 +5152,7 @@ }, { "cell_type": "code", - "execution_count": 166, + "execution_count": 171, "metadata": { "slideshow": { "slide_type": "-" @@ -5165,7 +5165,7 @@ "Fraction(3, 2)" ] }, - "execution_count": 166, + "execution_count": 171, "metadata": {}, "output_type": "execute_result" } @@ -5187,7 +5187,7 @@ }, { "cell_type": "code", - "execution_count": 167, + "execution_count": 172, "metadata": { "slideshow": { "slide_type": "slide" @@ -5200,7 +5200,7 @@ "Fraction(1, 10)" ] }, - "execution_count": 167, + "execution_count": 172, "metadata": {}, "output_type": "execute_result" } @@ -5222,7 +5222,7 @@ }, { "cell_type": "code", - "execution_count": 168, + "execution_count": 173, "metadata": { "slideshow": { "slide_type": "-" @@ -5235,7 +5235,7 @@ "Fraction(3602879701896397, 36028797018963968)" ] }, - "execution_count": 168, + "execution_count": 173, "metadata": {}, "output_type": "execute_result" } @@ -5257,7 +5257,7 @@ }, { "cell_type": "code", - "execution_count": 169, + "execution_count": 174, "metadata": { "slideshow": { "slide_type": "slide" @@ -5270,7 +5270,7 @@ "Fraction(7, 4)" ] }, - "execution_count": 169, + "execution_count": 174, "metadata": {}, "output_type": "execute_result" } @@ -5281,7 +5281,7 @@ }, { "cell_type": "code", - "execution_count": 170, + "execution_count": 175, "metadata": { "slideshow": { "slide_type": "-" @@ -5294,7 +5294,7 @@ "Fraction(1, 2)" ] }, - "execution_count": 170, + "execution_count": 175, "metadata": {}, "output_type": "execute_result" } @@ -5305,7 +5305,7 @@ }, { "cell_type": "code", - "execution_count": 171, + "execution_count": 176, "metadata": { "slideshow": { "slide_type": "-" @@ -5318,7 +5318,7 @@ "Fraction(1, 1)" ] }, - "execution_count": 171, + "execution_count": 176, "metadata": {}, "output_type": "execute_result" } @@ -5329,7 +5329,7 @@ }, { "cell_type": "code", - "execution_count": 172, + "execution_count": 177, "metadata": { "slideshow": { "slide_type": "-" @@ -5342,7 +5342,7 @@ "Fraction(1, 1)" ] }, - "execution_count": 172, + "execution_count": 177, "metadata": {}, "output_type": "execute_result" } @@ -5364,7 +5364,7 @@ }, { "cell_type": "code", - "execution_count": 173, + "execution_count": 178, "metadata": { "slideshow": { "slide_type": "slide" @@ -5377,7 +5377,7 @@ "0.1" ] }, - "execution_count": 173, + "execution_count": 178, "metadata": {}, "output_type": "execute_result" } @@ -5388,7 +5388,7 @@ }, { "cell_type": "code", - "execution_count": 174, + "execution_count": 179, "metadata": { "slideshow": { "slide_type": "fragment" @@ -5401,7 +5401,7 @@ "'0.10000000000000000555111512312578270211815834045410'" ] }, - "execution_count": 174, + "execution_count": 179, "metadata": {}, "output_type": "execute_result" } @@ -5475,7 +5475,7 @@ }, { "cell_type": "code", - "execution_count": 175, + "execution_count": 180, "metadata": { "slideshow": { "slide_type": "slide" @@ -5488,7 +5488,7 @@ }, { "cell_type": "code", - "execution_count": 176, + "execution_count": 181, "metadata": { "slideshow": { "slide_type": "fragment" @@ -5498,10 +5498,10 @@ { "data": { "text/plain": [ - "140673804641712" + "140166567772848" ] }, - "execution_count": 176, + "execution_count": 181, "metadata": {}, "output_type": "execute_result" } @@ -5512,7 +5512,7 @@ }, { "cell_type": "code", - "execution_count": 177, + "execution_count": 182, "metadata": { "slideshow": { "slide_type": "-" @@ -5525,7 +5525,7 @@ "complex" ] }, - "execution_count": 177, + "execution_count": 182, "metadata": {}, "output_type": "execute_result" } @@ -5536,7 +5536,7 @@ }, { "cell_type": "code", - "execution_count": 178, + "execution_count": 183, "metadata": { "slideshow": { "slide_type": "-" @@ -5549,7 +5549,7 @@ "1j" ] }, - "execution_count": 178, + "execution_count": 183, "metadata": {}, "output_type": "execute_result" } @@ -5571,7 +5571,7 @@ }, { "cell_type": "code", - "execution_count": 179, + "execution_count": 184, "metadata": { "slideshow": { "slide_type": "slide" @@ -5584,7 +5584,7 @@ "True" ] }, - "execution_count": 179, + "execution_count": 184, "metadata": {}, "output_type": "execute_result" } @@ -5606,7 +5606,7 @@ }, { "cell_type": "code", - "execution_count": 180, + "execution_count": 185, "metadata": { "slideshow": { "slide_type": "slide" @@ -5619,7 +5619,7 @@ "(2+0.5j)" ] }, - "execution_count": 180, + "execution_count": 185, "metadata": {}, "output_type": "execute_result" } @@ -5641,7 +5641,7 @@ }, { "cell_type": "code", - "execution_count": 181, + "execution_count": 186, "metadata": { "slideshow": { "slide_type": "-" @@ -5654,7 +5654,7 @@ "(2+0.5j)" ] }, - "execution_count": 181, + "execution_count": 186, "metadata": {}, "output_type": "execute_result" } @@ -5665,7 +5665,7 @@ }, { "cell_type": "code", - "execution_count": 182, + "execution_count": 187, "metadata": { "slideshow": { "slide_type": "-" @@ -5678,7 +5678,7 @@ "(2+0j)" ] }, - "execution_count": 182, + "execution_count": 187, "metadata": {}, "output_type": "execute_result" } @@ -5689,7 +5689,7 @@ }, { "cell_type": "code", - "execution_count": 183, + "execution_count": 188, "metadata": { "slideshow": { "slide_type": "skip" @@ -5702,7 +5702,7 @@ "(2+0.5j)" ] }, - "execution_count": 183, + "execution_count": 188, "metadata": {}, "output_type": "execute_result" } @@ -5713,7 +5713,7 @@ }, { "cell_type": "code", - "execution_count": 184, + "execution_count": 189, "metadata": { "slideshow": { "slide_type": "skip" @@ -5726,7 +5726,7 @@ "(2+0.5j)" ] }, - "execution_count": 184, + "execution_count": 189, "metadata": {}, "output_type": "execute_result" } @@ -5748,7 +5748,7 @@ }, { "cell_type": "code", - "execution_count": 185, + "execution_count": 190, "metadata": { "slideshow": { "slide_type": "slide" @@ -5762,7 +5762,7 @@ }, { "cell_type": "code", - "execution_count": 186, + "execution_count": 191, "metadata": { "slideshow": { "slide_type": "fragment" @@ -5775,7 +5775,7 @@ "(4+6j)" ] }, - "execution_count": 186, + "execution_count": 191, "metadata": {}, "output_type": "execute_result" } @@ -5786,7 +5786,7 @@ }, { "cell_type": "code", - "execution_count": 187, + "execution_count": 192, "metadata": { "slideshow": { "slide_type": "-" @@ -5799,7 +5799,7 @@ "(-2-2j)" ] }, - "execution_count": 187, + "execution_count": 192, "metadata": {}, "output_type": "execute_result" } @@ -5810,7 +5810,7 @@ }, { "cell_type": "code", - "execution_count": 188, + "execution_count": 193, "metadata": { "slideshow": { "slide_type": "skip" @@ -5823,7 +5823,7 @@ "(40+2j)" ] }, - "execution_count": 188, + "execution_count": 193, "metadata": {}, "output_type": "execute_result" } @@ -5834,7 +5834,7 @@ }, { "cell_type": "code", - "execution_count": 189, + "execution_count": 194, "metadata": { "slideshow": { "slide_type": "skip" @@ -5847,7 +5847,7 @@ "-4j" ] }, - "execution_count": 189, + "execution_count": 194, "metadata": {}, "output_type": "execute_result" } @@ -5858,7 +5858,7 @@ }, { "cell_type": "code", - "execution_count": 190, + "execution_count": 195, "metadata": { "slideshow": { "slide_type": "skip" @@ -5871,7 +5871,7 @@ "(5+10j)" ] }, - "execution_count": 190, + "execution_count": 195, "metadata": {}, "output_type": "execute_result" } @@ -5882,7 +5882,7 @@ }, { "cell_type": "code", - "execution_count": 191, + "execution_count": 196, "metadata": { "slideshow": { "slide_type": "skip" @@ -5895,7 +5895,7 @@ "(0.5+0.6666666666666666j)" ] }, - "execution_count": 191, + "execution_count": 196, "metadata": {}, "output_type": "execute_result" } @@ -5906,7 +5906,7 @@ }, { "cell_type": "code", - "execution_count": 192, + "execution_count": 197, "metadata": { "slideshow": { "slide_type": "fragment" @@ -5919,7 +5919,7 @@ "(-5+10j)" ] }, - "execution_count": 192, + "execution_count": 197, "metadata": {}, "output_type": "execute_result" } @@ -5930,7 +5930,7 @@ }, { "cell_type": "code", - "execution_count": 193, + "execution_count": 198, "metadata": { "slideshow": { "slide_type": "-" @@ -5943,7 +5943,7 @@ "(0.44+0.08j)" ] }, - "execution_count": 193, + "execution_count": 198, "metadata": {}, "output_type": "execute_result" } @@ -5965,7 +5965,7 @@ }, { "cell_type": "code", - "execution_count": 194, + "execution_count": 199, "metadata": { "slideshow": { "slide_type": "slide" @@ -5978,7 +5978,7 @@ "5.0" ] }, - "execution_count": 194, + "execution_count": 199, "metadata": {}, "output_type": "execute_result" } @@ -6000,7 +6000,7 @@ }, { "cell_type": "code", - "execution_count": 195, + "execution_count": 200, "metadata": { "slideshow": { "slide_type": "fragment" @@ -6013,7 +6013,7 @@ "1.0" ] }, - "execution_count": 195, + "execution_count": 200, "metadata": {}, "output_type": "execute_result" } @@ -6024,7 +6024,7 @@ }, { "cell_type": "code", - "execution_count": 196, + "execution_count": 201, "metadata": { "slideshow": { "slide_type": "-" @@ -6037,7 +6037,7 @@ "2.0" ] }, - "execution_count": 196, + "execution_count": 201, "metadata": {}, "output_type": "execute_result" } @@ -6059,7 +6059,7 @@ }, { "cell_type": "code", - "execution_count": 197, + "execution_count": 202, "metadata": { "slideshow": { "slide_type": "fragment" @@ -6072,7 +6072,7 @@ "(1-2j)" ] }, - "execution_count": 197, + "execution_count": 202, "metadata": {}, "output_type": "execute_result" } @@ -6111,7 +6111,7 @@ } }, "source": [ - "Analogous to the discussion of *containers* and *iterables* in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Containers-vs.-Iterables), we contrast the *concrete* numeric data types in this chapter with the *abstract* ideas behind [numbers in mathematics](https://en.wikipedia.org/wiki/Number).\n", + "Analogous to the discussion of *containers* and *iterables* in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#Containers-vs.-Iterables), we contrast the *concrete* numeric data types in this chapter with the *abstract* ideas behind [numbers in mathematics](https://en.wikipedia.org/wiki/Number).\n", "\n", "The figure below summarizes five *major* sets of [numbers in mathematics](https://en.wikipedia.org/wiki/Number) as we know them from high school:\n", "\n", @@ -6151,16 +6151,16 @@ "\n", "The abstract concepts behind the four outer-most mathematical sets are formalized in Python since [PEP 3141](https://www.python.org/dev/peps/pep-3141/) in 2007. The [numbers](https://docs.python.org/3/library/numbers.html) module in the [standard library](https://docs.python.org/3/library/index.html) defines what programmers call the **[numerical tower](https://en.wikipedia.org/wiki/Numerical_tower)**, a collection of five **[abstract data types](https://en.wikipedia.org/wiki/Abstract_data_type)**, or **abstract base classes** (ABCs) as they are called in Python jargon:\n", "\n", - "- `numbers.Number`: \"any number\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Number))\n", - "- `numbers.Complex`: \"all complex numbers\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Complex))\n", - "- `numbers.Real`: \"all real numbers\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Real))\n", - "- `numbers.Rational`: \"all rational numbers\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Rational))\n", - "- `numbers.Integral`: \"all integers\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Integral))" + "- `Number`: \"any number\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Number))\n", + "- `Complex`: \"all complex numbers\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Complex))\n", + "- `Real`: \"all real numbers\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Real))\n", + "- `Rational`: \"all rational numbers\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Rational))\n", + "- `Integral`: \"all integers\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Integral))" ] }, { "cell_type": "code", - "execution_count": 198, + "execution_count": 203, "metadata": { "slideshow": { "slide_type": "slide" @@ -6173,7 +6173,7 @@ }, { "cell_type": "code", - "execution_count": 199, + "execution_count": 204, "metadata": { "slideshow": { "slide_type": "-" @@ -6201,7 +6201,7 @@ " 'abstractmethod']" ] }, - "execution_count": 199, + "execution_count": 204, "metadata": {}, "output_type": "execute_result" } @@ -6227,7 +6227,7 @@ }, { "cell_type": "code", - "execution_count": 200, + "execution_count": 205, "metadata": { "scrolled": true, "slideshow": { @@ -6338,7 +6338,7 @@ }, { "cell_type": "code", - "execution_count": 201, + "execution_count": 206, "metadata": { "slideshow": { "slide_type": "skip" @@ -6505,7 +6505,7 @@ }, { "cell_type": "code", - "execution_count": 202, + "execution_count": 207, "metadata": { "slideshow": { "slide_type": "slide" @@ -6518,7 +6518,7 @@ "42" ] }, - "execution_count": 202, + "execution_count": 207, "metadata": {}, "output_type": "execute_result" } @@ -6529,7 +6529,7 @@ }, { "cell_type": "code", - "execution_count": 203, + "execution_count": 208, "metadata": { "slideshow": { "slide_type": "-" @@ -6542,7 +6542,7 @@ "Decimal('0.1')" ] }, - "execution_count": 203, + "execution_count": 208, "metadata": {}, "output_type": "execute_result" } @@ -6553,7 +6553,7 @@ }, { "cell_type": "code", - "execution_count": 204, + "execution_count": 209, "metadata": { "slideshow": { "slide_type": "-" @@ -6566,7 +6566,7 @@ "5.0" ] }, - "execution_count": 204, + "execution_count": 209, "metadata": {}, "output_type": "execute_result" } @@ -6588,7 +6588,7 @@ }, { "cell_type": "code", - "execution_count": 205, + "execution_count": 210, "metadata": { "slideshow": { "slide_type": "fragment" @@ -6601,7 +6601,7 @@ "42" ] }, - "execution_count": 205, + "execution_count": 210, "metadata": {}, "output_type": "execute_result" } @@ -6612,7 +6612,7 @@ }, { "cell_type": "code", - "execution_count": 206, + "execution_count": 211, "metadata": { "slideshow": { "slide_type": "-" @@ -6625,7 +6625,7 @@ "0" ] }, - "execution_count": 206, + "execution_count": 211, "metadata": {}, "output_type": "execute_result" } @@ -6647,7 +6647,7 @@ }, { "cell_type": "code", - "execution_count": 207, + "execution_count": 212, "metadata": { "slideshow": { "slide_type": "-" @@ -6661,7 +6661,7 @@ "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[0mround\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m4\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m3j\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[0mround\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m4\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m3j\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: type complex doesn't define __round__ method" ] } @@ -6683,7 +6683,7 @@ }, { "cell_type": "code", - "execution_count": 208, + "execution_count": 213, "metadata": { "slideshow": { "slide_type": "slide" @@ -6707,7 +6707,7 @@ }, { "cell_type": "code", - "execution_count": 209, + "execution_count": 214, "metadata": { "slideshow": { "slide_type": "-" @@ -6720,7 +6720,7 @@ "0" ] }, - "execution_count": 209, + "execution_count": 214, "metadata": {}, "output_type": "execute_result" } @@ -6742,7 +6742,7 @@ }, { "cell_type": "code", - "execution_count": 210, + "execution_count": 215, "metadata": { "slideshow": { "slide_type": "fragment" @@ -6756,7 +6756,7 @@ "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[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0.9\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1j\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[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0.9\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1j\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: type complex doesn't define __trunc__ method" ] } @@ -6780,7 +6780,7 @@ }, { "cell_type": "code", - "execution_count": 211, + "execution_count": 216, "metadata": { "slideshow": { "slide_type": "slide" @@ -6793,7 +6793,7 @@ "True" ] }, - "execution_count": 211, + "execution_count": 216, "metadata": {}, "output_type": "execute_result" } @@ -6804,7 +6804,7 @@ }, { "cell_type": "code", - "execution_count": 212, + "execution_count": 217, "metadata": { "slideshow": { "slide_type": "fragment" @@ -6817,7 +6817,7 @@ "True" ] }, - "execution_count": 212, + "execution_count": 217, "metadata": {}, "output_type": "execute_result" } @@ -6828,7 +6828,7 @@ }, { "cell_type": "code", - "execution_count": 213, + "execution_count": 218, "metadata": { "slideshow": { "slide_type": "-" @@ -6841,7 +6841,7 @@ "True" ] }, - "execution_count": 213, + "execution_count": 218, "metadata": {}, "output_type": "execute_result" } @@ -6852,7 +6852,7 @@ }, { "cell_type": "code", - "execution_count": 214, + "execution_count": 219, "metadata": { "slideshow": { "slide_type": "-" @@ -6865,7 +6865,7 @@ "True" ] }, - "execution_count": 214, + "execution_count": 219, "metadata": {}, "output_type": "execute_result" } @@ -6887,7 +6887,7 @@ }, { "cell_type": "code", - "execution_count": 215, + "execution_count": 220, "metadata": { "slideshow": { "slide_type": "slide" @@ -6900,7 +6900,7 @@ "False" ] }, - "execution_count": 215, + "execution_count": 220, "metadata": {}, "output_type": "execute_result" } @@ -6922,7 +6922,7 @@ }, { "cell_type": "code", - "execution_count": 216, + "execution_count": 221, "metadata": { "slideshow": { "slide_type": "fragment" @@ -6935,7 +6935,7 @@ "True" ] }, - "execution_count": 216, + "execution_count": 221, "metadata": {}, "output_type": "execute_result" } @@ -6946,7 +6946,7 @@ }, { "cell_type": "code", - "execution_count": 217, + "execution_count": 222, "metadata": { "slideshow": { "slide_type": "-" @@ -6959,7 +6959,7 @@ "False" ] }, - "execution_count": 217, + "execution_count": 222, "metadata": {}, "output_type": "execute_result" } @@ -7005,7 +7005,7 @@ }, { "cell_type": "code", - "execution_count": 218, + "execution_count": 223, "metadata": { "slideshow": { "slide_type": "slide" @@ -7055,7 +7055,7 @@ }, { "cell_type": "code", - "execution_count": 219, + "execution_count": 224, "metadata": { "slideshow": { "slide_type": "slide" @@ -7068,7 +7068,7 @@ "1" ] }, - "execution_count": 219, + "execution_count": 224, "metadata": {}, "output_type": "execute_result" } @@ -7079,7 +7079,7 @@ }, { "cell_type": "code", - "execution_count": 220, + "execution_count": 225, "metadata": { "slideshow": { "slide_type": "-" @@ -7092,7 +7092,7 @@ "6" ] }, - "execution_count": 220, + "execution_count": 225, "metadata": {}, "output_type": "execute_result" } @@ -7103,7 +7103,7 @@ }, { "cell_type": "code", - "execution_count": 221, + "execution_count": 226, "metadata": { "slideshow": { "slide_type": "fragment" @@ -7116,7 +7116,7 @@ "6" ] }, - "execution_count": 221, + "execution_count": 226, "metadata": {}, "output_type": "execute_result" } @@ -7138,7 +7138,7 @@ }, { "cell_type": "code", - "execution_count": 222, + "execution_count": 227, "metadata": { "slideshow": { "slide_type": "slide" @@ -7152,8 +7152,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, strict)\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnumbers\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mReal\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 17\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mstrict\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 18\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"n is not an integer-like value; it has decimals\"\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 19\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrunc\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[1;32m 20\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[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, strict)\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnumbers\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mReal\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 17\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mstrict\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 18\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"n is not an integer-like value; it has decimals\"\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 19\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrunc\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[1;32m 20\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[0;31mTypeError\u001b[0m: n is not an integer-like value; it has decimals" ] } @@ -7175,7 +7175,7 @@ }, { "cell_type": "code", - "execution_count": 223, + "execution_count": 228, "metadata": { "slideshow": { "slide_type": "fragment" @@ -7188,7 +7188,7 @@ "6" ] }, - "execution_count": 223, + "execution_count": 228, "metadata": {}, "output_type": "execute_result" } @@ -7210,7 +7210,7 @@ }, { "cell_type": "code", - "execution_count": 224, + "execution_count": 229, "metadata": { "slideshow": { "slide_type": "slide" @@ -7224,8 +7224,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;36m1\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2j\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, strict)\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrunc\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[1;32m 20\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[0;32m---> 21\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 22\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 23\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;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;36m1\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2j\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, strict)\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0mn\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrunc\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[1;32m 20\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[0;32m---> 21\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 22\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 23\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;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mTypeError\u001b[0m: Factorial is only defined for integers" ] } @@ -7287,7 +7287,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "livereveal": { "auto_select": "code", @@ -7315,5 +7315,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/05_numbers_10_review.ipynb b/05_numbers_10_review.ipynb new file mode 100644 index 0000000..819d668 --- /dev/null +++ b/05_numbers_10_review.ipynb @@ -0,0 +1,347 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# Chapter 5: Bits & Numbers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Content Review" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_00_content.ipynb) of the book. Then, work through the questions below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Essay Questions " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Answer the following questions briefly with *at most* 300 characters per question!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1**: In what way is the **binary representation** of `int` objects *similar* to the **decimal system** taught in elementary school?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q2**: Why may objects of type `bool` be regarded a **numeric type** as well?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q3**: Why is it *inefficient* to store `bool` objects in bits resembling a **hexadecimal representation**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q4**: Colors are commonly expressed in the **hexadecimal system** in websites (cf., the [HTML](https://en.wikipedia.org/wiki/HTML) and [CSS](https://en.wikipedia.org/wiki/Cascading_Style_Sheets) formats).\n", + "\n", + "For example, $#000000$, $#ff9900$, and $#ffffff$ turn out to be black, orange, and white. The six digits are read in *pairs of two* from left to right, and the *three pairs* correspond to the proportions of red, green, and blue mixed together. They reach from $0_{16} = 0_{10}$ for $0$% to $\\text{ff}_{16} = 255_{10}$ for $100$% (cf., this [article](https://en.wikipedia.org/wiki/RGB_color_model) for an in-depth discussion).\n", + "\n", + "In percent, what are the proportions of red, green, and blue that make up orange? Calculate the three percentages separately! How many **bytes** are needed to encode a color? How many **bits** are that?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q5**: What does it mean for a code fragment to **fail silently**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q6**: Explain why the mathematical set of all real numbers $\\mathbb{R}$ can only be **approximated** by floating-point numbers on a computer!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q7**: How do we deal with a `float` object's imprecision if we need to **check for equality**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q8**: What data type, built-in or from the [standard library](https://docs.python.org/3/library/index.html), is best suited to represent the [transcendental numbers](https://en.wikipedia.org/wiki/Transcendental_number) $\\pi$ and $\\text{e}$?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q9**: How can **abstract base classes**, for example, as defined in the **numerical tower**, be helpful in enabling **duck typing**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### True / False Questions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Motivate your answer with *one short* sentence!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q10**: The precision of `int` objects depends on how we choose to represent them in memory. For example, using a **hexadecimal representation** gives us $16^8$ digits whereas with a **binary representation** an `int` object can have *at most* $2^8$ digits." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q11**: With the built-in [round()](https://docs.python.org/3/library/functions.html#round) function, we obtain a *precise* representation for any `float` object if we can live with *less than* $15$ digits of precision." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q12**: As most currencies operate with $2$ or $3$ decimals (e.g., EUR $9.99$), the `float` type's limitation of *at most* $15$ digits is *not* a problem in practice." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q13**: The [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) standard's **special values** provide no benefit in practice as we could always use a **[sentinel](https://en.wikipedia.org/wiki/Sentinel_value)** value (i.e., a \"dummy\"). For example, instead of `nan`, we can always use `0` to indicate a *missing* value." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q14**: The following code fragment raises an `InvalidOperation` exception. That is an example of code **failing loudly**.\n", + "```python\n", + "float(\"inf\") + float(\"-inf\")\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q15**: Python provides a `scientific` type (e.g., `1.23e4`) that is useful mainly to model problems in the domains of physics or astrophysics." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q16**: From a practitioner's point of view, the built-in [format()](https://docs.python.org/3/library/functions.html#format) function does the *same* as the built-in [round()](https://docs.python.org/3/library/functions.html#round) function." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q17**: The `Decimal` type from the [decimal](https://docs.python.org/3/library/decimal.html) module in the [standard library](https://docs.python.org/3/library/index.html) allows us to model the set of the real numbers $\\mathbb{R}$ *precisely*." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q18**: The `Fraction` type from the [fractions](https://docs.python.org/3/library/fractions.html) module in the [standard library](https://docs.python.org/3/library/index.html) allows us to model the set of the rational numbers $\\mathbb{Q}$ *precisely*." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": true, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": false, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/05_numbers_20_exercises.ipynb b/05_numbers_20_exercises.ipynb new file mode 100644 index 0000000..d00ef2e --- /dev/null +++ b/05_numbers_20_exercises.ipynb @@ -0,0 +1,412 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# Chapter 5: Bits & Numbers" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Coding Exercises" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_00_content.ipynb) of the book. Then, work through the exercises below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Discounting Customer Orders (revisited)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1** in [Chapter 2's Exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_20_exercises.ipynb#Volume-of-a-Sphere) section already revealed that we must consider the effects of the `float` type's imprecision.\n", + "\n", + "This becomes even more important when we deal with numeric data modeling accounting or finance data (cf., [this comment](https://stackoverflow.com/a/24976426) on \"falsehoods programmers believe about money\").\n", + "\n", + "In addition to the *inherent imprecision* of numbers in general, the topic of **[rounding numbers](https://en.wikipedia.org/wiki/Rounding)** is also not as trivial as we might expect! [This article](https://realpython.com/python-rounding/) summarizes everything the data science practitioner needs to know.\n", + "\n", + "In this exercise, we revisit **Q1** from [Chapter 3's Exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_20_exercises.ipynb#Discounting-Customer-Orders) section, and make the `discounted_price()` function work *correctly* for real-life sales data." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.1**: Execute the code cells below! What results would you have *expected*, and why?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "round(1.5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "round(2.5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "round(2.675, 2)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.2**: The built-in [round()](https://docs.python.org/3/library/functions.html#round) function implements the \"**[round half to even](https://en.wikipedia.org/wiki/Rounding#Round_half_to_even)**\" strategy. Describe in one or two sentences what that means!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.3**: For the revised `discounted_price()` function, we have to tackle *two* issues: First, we have to replace the built-in `float` type with a data type that allows us to control the precision. Second, the discounted price should be rounded according to a more human-friendly rounding strategy, namely \"**[round half away from zero](https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero)**.\"\n", + "\n", + "Describe in one or two sentences how \"**[round half away from zero](https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero)**\" is more in line with how humans think of rounding!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.4**: We use the `Decimal` type from the [decimal](https://docs.python.org/3/library/decimal.html) module in the [standard library](https://docs.python.org/3/library/index.html) to tackle *both* issues simultaneously.\n", + "\n", + "Assign `euro` a numeric object such that both `Decimal(\"1.5\")` and `Decimal(\"2.5\")` are rounded to `Decimal(\"2\")` (i.e., no decimal) with the [quantize()](https://docs.python.org/3/library/decimal.html#decimal.Decimal.quantize) method!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from decimal import Decimal" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "euro = ..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Decimal(\"1.5\").quantize(...)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Decimal(\"2.5\").quantize(...)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.5**: Obviously, the two preceding code cells still [round half to even](https://en.wikipedia.org/wiki/Rounding#Round_half_to_even).\n", + "\n", + "The [decimal](https://docs.python.org/3/library/decimal.html) module defines a `ROUND_HALF_UP` flag that we can pass as the second argument to the [quantize()](https://docs.python.org/3/library/decimal.html#decimal.Decimal.quantize) method. Then, it [rounds half away from zero](https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero).\n", + "\n", + "Add `ROUND_HALF_UP` to the code cells! `Decimal(\"2.5\")` should now be rounded to `Decimal(\"3\")`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "from decimal import ROUND_HALF_UP" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Decimal(\"1.5\").quantize(...)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Decimal(\"2.5\").quantize(...)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.6**: Instead of `euro`, define `cents` such that rounding occurs to *two* decimals! `Decimal(\"2.675\")` should now be rounded to `Decimal(\"2.68\")`. Do *not* forget to include the `ROUND_HALF_UP` flag!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "cents = ..." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "Decimal(\"2.675\").quantize(...)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.7**: Rewrite the function `discounted_price()` from [Chapter 3's Exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_20_exercises.ipynb#Discounting-Customer-Orders) section!\n", + "\n", + "It takes the *positional* arguments `unit_price` and `quantity` and implements a discount scheme for a line item in a customer order as follows:\n", + "\n", + "- if the unit price is over 100 dollars, grant 10% relative discount\n", + "- if a customer orders more than 10 items, one in every five items is for free\n", + "\n", + "Only one of the two discounts is granted, whichever is better for the customer.\n", + "\n", + "The function then returns the overall price for the line item as a `Decimal` number with a precision of *two* decimals.\n", + "\n", + "Enable **duck typing** by allowing the function to be called with various numeric types as the arguments, in particular, `quantity` may be a non-integer as well: Use an appropriate **abstract base class** from the [numbers](https://docs.python.org/3/library/numbers.html) module in the [standard library](https://docs.python.org/3/library/index.html) to verify the arguments' types and also that they are both positive!\n", + "\n", + "It is considered a *best practice* to only round towards the *end* of the calculations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numbers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def discounted_price(...):\n", + " ..." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1.8**: Execute the code cells below and verify the final price for the following four test cases:\n", + "\n", + "- $7$ smartphones @ $99.00$ USD\n", + "- $3$ workstations @ $999.00$ USD\n", + "- $19$ GPUs @ $879.95$ USD\n", + "- $14$ Raspberry Pis @ $35.00$ USD\n", + "\n", + "The output should now *always* be a `Decimal` number with *two* decimals!" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "discounted_price(99, 7)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "discounted_price(999, 3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "discounted_price(879.95, 19)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "discounted_price(35, 14)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This also works if `quantity` is passed in as a `float` type." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "discounted_price(99, 7.0)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Decimals beyond the first two are gracefully discarded (i.e., *without* rounding errors accumulating)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "discounted_price(99.0001, 7)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The basic input validation ensures that the user of `discounted_price()` does not pass in invalid data. Here, the `\"abc\"` creates a `TypeError`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "discounted_price(\"abc\", 7)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A `-1` passed in as `unit_price` results in a `ValueError`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "discounted_price(-1, 7)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": true, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": false, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/05_numbers_review_and_exercises.ipynb b/05_numbers_review_and_exercises.ipynb deleted file mode 100644 index 2ae8301..0000000 --- a/05_numbers_review_and_exercises.ipynb +++ /dev/null @@ -1,706 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "# Chapter 5: Bits & Numbers" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Content Review" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Read [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers.ipynb) of the book. Then work through the eighteen review questions." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Essay Questions " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Answer the following questions briefly with *at most* 300 characters per question!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q1**: In what way is the **binary representation** of `int` objects *similar* to the **decimal system** taught in elementary school?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q2**: Why may objects of type `bool` be regarded a **numeric type** as well?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q3**: Why is it *inefficient* to store `bool` objects in bits resembling a **hexadecimal representation**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q4**: Colors are commonly expressed in the **hexadecimal system** in websites (cf., the [HTML](https://en.wikipedia.org/wiki/HTML) and [CSS](https://en.wikipedia.org/wiki/Cascading_Style_Sheets) formats).\n", - "\n", - "For example, $#000000$, $#ff9900$, and $#ffffff$ turn out to be black, orange, and white. The six digits are read in *pairs of two* from left to right, and the *three pairs* correspond to the proportions of red, green, and blue mixed together. They reach from $0_{16} = 0_{10}$ for $0$% to $\\text{ff}_{16} = 255_{10}$ for $100$% (cf., this [article](https://en.wikipedia.org/wiki/RGB_color_model) for an in-depth discussion).\n", - "\n", - "In percent, what are the proportions of red, green, and blue that make up orange? Calculate the three percentages separately! How many **bytes** are needed to encode a color? How many **bits** are that?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q5**: What does it mean for a code fragment to **fail silently**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q6**: Explain why the mathematical set of all real numbers $\\mathbb{R}$ can only be **approximated** by floating-point numbers on a computer!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q7**: How do we deal with a `float` object's imprecision if we need to **check for equality**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q8**: What data type, built-in or from the [standard library](https://docs.python.org/3/library/index.html), is best suited to represent the [transcendental numbers](https://en.wikipedia.org/wiki/Transcendental_number) $\\pi$ and $\\text{e}$?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q9**: How can **abstract base classes**, for example, as defined in the **numerical tower**, be helpful in enabling **duck typing**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### True / False Questions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Motivate your answer with *one short* sentence!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q10**: The precision of `int` objects depends on how we choose to represent them in memory. For example, using a **hexadecimal representation** gives us $16^8$ digits whereas with a **binary representation** an `int` object can have *at most* $2^8$ digits." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11**: With the built-in [round()](https://docs.python.org/3/library/functions.html#round) function, we obtain a *precise* representation for any `float` object if we can live with *less than* $15$ digits of precision." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q12**: As most currencies operate with $2$ or $3$ decimals (e.g., EUR $9.99$), the `float` type's limitation of *at most* $15$ digits is *not* a problem in practice." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q13**: The [IEEE 754](https://en.wikipedia.org/wiki/IEEE_754) standard's **special values** provide no benefit in practice as we could always use a **[sentinel](https://en.wikipedia.org/wiki/Sentinel_value)** value (i.e., a \"dummy\"). For example, instead of `nan`, we can always use `0` to indicate a *missing* value." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q14**: The following code fragment raises an `InvalidOperation` exception. That is an example of code **failing loudly**.\n", - "```python\n", - "float(\"inf\") + float(\"-inf\")\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q15**: Python provides a `scientific` type (e.g., `1.23e4`) that is useful mainly to model problems in the domains of physics or astrophysics." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q16**: From a practitioner's point of view, the built-in [format()](https://docs.python.org/3/library/functions.html#format) function does the *same* as the built-in [round()](https://docs.python.org/3/library/functions.html#round) function." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q17**: The `Decimal` type from the [decimal](https://docs.python.org/3/library/decimal.html) module in the [standard library](https://docs.python.org/3/library/index.html) allows us to model the set of the real numbers $\\mathbb{R}$ *precisely*." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q18**: The `Fraction` type from the [fractions](https://docs.python.org/3/library/fractions.html) module in the [standard library](https://docs.python.org/3/library/index.html) allows us to model the set of the rational numbers $\\mathbb{Q}$ *precisely*." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Coding Exercises" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Discounting Customer Orders (revisited)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11** in [Chapter 2's Review & Exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_review_and_exercises.ipynb#Volume-of-a-Sphere) section already revealed that we must consider the effects of the `float` type's imprecision.\n", - "\n", - "This becomes even more important when we deal with numeric data modeling accounting or finance data (cf., [this comment](https://stackoverflow.com/a/24976426) on \"falsehoods programmers believe about money\").\n", - "\n", - "In addition to the *inherent imprecision* of numbers in general, the topic of **[rounding numbers](https://en.wikipedia.org/wiki/Rounding)** is also not as trivial as we might expect! [This article](https://realpython.com/python-rounding/) summarizes everything the data science practitioner needs to know.\n", - "\n", - "In this exercise, we revisit **Q9** from [Chapter 3's Review & Exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_review_and_exercises.ipynb#Discounting-Customer-Orders) section, and make the `discounted_price()` function work *correctly* for real-life sales data." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q19.1**: Execute the code cells below! What results would you have *expected*, and why?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "round(1.5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "round(2.5)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "round(2.675, 2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q19.2**: The built-in [round()](https://docs.python.org/3/library/functions.html#round) function implements the \"**[round half to even](https://en.wikipedia.org/wiki/Rounding#Round_half_to_even)**\" strategy. Describe in one or two sentences what that means!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q19.3**: For the revised `discounted_price()` function, we have to tackle *two* issues: First, we have to replace the built-in `float` type with a data type that allows us to control the precision. Second, the discounted price should be rounded according to a more human-friendly rounding strategy, namely \"**[round half away from zero](https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero)**.\"\n", - "\n", - "Describe in one or two sentences how \"**[round half away from zero](https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero)**\" is more in line with how humans think of rounding!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q19.4**: We use the `Decimal` type from the [decimal](https://docs.python.org/3/library/decimal.html) module in the [standard library](https://docs.python.org/3/library/index.html) to tackle *both* issues simultaneously.\n", - "\n", - "Assign `euro` a numeric object such that both `Decimal(\"1.5\")` and `Decimal(\"2.5\")` are rounded to `Decimal(\"2\")` (i.e., no decimal) with the [quantize()](https://docs.python.org/3/library/decimal.html#decimal.Decimal.quantize) method!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from decimal import Decimal" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "euro = ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Decimal(\"1.5\").quantize(...)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Decimal(\"2.5\").quantize(...)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q19.5**: Obviously, the two preceding code cells still [round half to even](https://en.wikipedia.org/wiki/Rounding#Round_half_to_even).\n", - "\n", - "The [decimal](https://docs.python.org/3/library/decimal.html) module defines a `ROUND_HALF_UP` flag that we can pass as the second argument to the [quantize()](https://docs.python.org/3/library/decimal.html#decimal.Decimal.quantize) method. Then, it [rounds half away from zero](https://en.wikipedia.org/wiki/Rounding#Round_half_away_from_zero).\n", - "\n", - "Add `ROUND_HALF_UP` to the code cells! `Decimal(\"2.5\")` should now be rounded to `Decimal(\"3\")`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "from decimal import ROUND_HALF_UP" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Decimal(\"1.5\").quantize(...)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Decimal(\"2.5\").quantize(...)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q19.6**: Instead of `euro`, define `cents` such that rounding occurs to *two* decimals! `Decimal(\"2.675\")` should now be rounded to `Decimal(\"2.68\")`. Do *not* forget to include the `ROUND_HALF_UP` flag!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "cents = ..." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "Decimal(\"2.675\").quantize(...)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q19.7**: Rewrite the function `discounted_price()` from [Chapter 3's Review & Exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_review_and_exercises.ipynb#Discounting-Customer-Orders) section!\n", - "\n", - "It takes the *positional* arguments `unit_price` and `quantity` and implements a discount scheme for a line item in a customer order as follows:\n", - "\n", - "- if the unit price is over 100 dollars, grant 10% relative discount\n", - "- if a customer orders more than 10 items, one in every five items is for free\n", - "\n", - "Only one of the two discounts is granted, whichever is better for the customer.\n", - "\n", - "The function then returns the overall price for the line item as a `Decimal` number with a precision of *two* decimals.\n", - "\n", - "Enable **duck typing** by allowing the function to be called with various numeric types as the arguments, in particular, `quantity` may be a non-integer as well: Use an appropriate **abstract base class** from the [numbers](https://docs.python.org/3/library/numbers.html) module in the [standard library](https://docs.python.org/3/library/index.html) to verify the arguments' types and also that they are both positive!\n", - "\n", - "It is considered a *best practice* to only round towards the *end* of the calculations." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import numbers" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def discounted_price(...):\n", - " ..." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q19.8**: Execute the code cells below and verify the final price for the following four test cases:\n", - "\n", - "- $7$ smartphones @ $99.00$ USD\n", - "- $3$ workstations @ $999.00$ USD\n", - "- $19$ GPUs @ $879.95$ USD\n", - "- $14$ Raspberry Pis @ $35.00$ USD\n", - "\n", - "The output should now *always* be a `Decimal` number with *two* decimals!" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "discounted_price(99, 7)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "discounted_price(999, 3)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "discounted_price(879.95, 19)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "discounted_price(35, 14)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This also works if `quantity` is passed in as a `float` type." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "discounted_price(99, 7.0)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Decimals beyond the first two are gracefully discarded (i.e., *without* rounding errors accumulating)." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "discounted_price(99.0001, 7)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The basic input validation ensures that the user of `discounted_price()` does not pass in invalid data. Here, the `\"abc\"` creates a `TypeError`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "discounted_price(\"abc\", 7)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "A `-1` passed in as `unit_price` results in a `ValueError`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "discounted_price(-1, 7)" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.7.3" - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": false, - "sideBar": true, - "skip_h1_title": true, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": {}, - "toc_section_display": false, - "toc_window_display": false - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/06_text.ipynb b/06_text_00_content.ipynb similarity index 90% rename from 06_text.ipynb rename to 06_text_00_content.ipynb index 3fbbcb5..912142e 100644 --- a/06_text.ipynb +++ b/06_text_00_content.ipynb @@ -54,7 +54,7 @@ }, "outputs": [], "source": [ - "text = \"Lorem ipsum dolor sit amet, consectetur ...\"" + "text = \"Lorem ipsum dolor sit amet, ...\"" ] }, { @@ -80,7 +80,7 @@ { "data": { "text/plain": [ - "139674889049360" + "140483431254256" ] }, "execution_count": 2, @@ -124,7 +124,7 @@ } }, "source": [ - "A `str` object evaluates to itself in a literal notation with enclosing **single quotes** `'` by default. In [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Value), we already specified the double quotes `\"` convention we stick to in this book. Yet, single quotes `'` and double quotes `\"` are *perfect* substitutes for all `str` objects that do *not* contain any of the two symbols in it. We could use the reverse convention, as well.\n", + "A `str` object evaluates to itself in a literal notation with enclosing **single quotes** `'` by default. In [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Value), we already specified the double quotes `\"` convention we stick to in this book. Yet, single quotes `'` and double quotes `\"` are *perfect* substitutes for all `str` objects that do *not* contain any of the two symbols in it. We could use the reverse convention, as well.\n", "\n", "As [this discussion](https://stackoverflow.com/questions/56011/single-quotes-vs-double-quotes-in-python) shows, many programmers have *strong* opinions about that and make up *new* conventions for their projects. Consequently, the discussion was \"closed as not constructive\" by the moderators." ] @@ -141,7 +141,7 @@ { "data": { "text/plain": [ - "'Lorem ipsum dolor sit amet, consectetur ...'" + "'Lorem ipsum dolor sit amet, ...'" ] }, "execution_count": 4, @@ -161,7 +161,7 @@ } }, "source": [ - "As the single quote `'` is often used in the English language as a shortener, we could make an argument in favor of using the double quotes `\"`: There are possibly fewer situations like in the two code cells below, in which we must revert to using a `\\` to **escape** a single quote `'` in a text (cf., the [Special Characters](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb#Special-Characters) section further below). However, double quotes `\"` are often used as well. So, this argument is somewhat not convincing.\n", + "As the single quote `'` is often used in the English language as a shortener, we could make an argument in favor of using the double quotes `\"`: There are possibly fewer situations like in the two code cells below, in which we must revert to using a `\\` to **escape** a single quote `'` in a text (cf., the [Special Characters](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text_00_content.ipynb#Special-Characters) section further below). However, double quotes `\"` are often used as well. So, this argument is somewhat not convincing.\n", "\n", "Many proponents of the single quote `'` usage claim that double quotes `\"` make more **visual noise** on the screen. This argument is also not convincing. On the contrary, one could claim that *two* single quotes `''` look so similar to *one* double quote `\"` that it might not be apparent right away what we are looking at. By sticking to double quotes `\"`, we avoid such danger of confusion.\n", "\n", @@ -182,7 +182,7 @@ { "data": { "text/plain": [ - "\"It's cool that strings are so versatile!\"" + "'It\\'s cool that \"strings\" are versatile'" ] }, "execution_count": 5, @@ -191,7 +191,7 @@ } ], "source": [ - "\"It's cool that strings are so versatile!\"" + "\"It's cool that \\\"strings\\\" are versatile\"" ] }, { @@ -206,7 +206,7 @@ { "data": { "text/plain": [ - "\"It's cool that strings are so versatile!\"" + "'It\\'s cool that \"strings\" are versatile'" ] }, "execution_count": 6, @@ -215,7 +215,7 @@ } ], "source": [ - "'It\\'s cool that strings are so versatile!'" + "'It\\'s cool that \"strings\" are versatile'" ] }, { @@ -615,7 +615,7 @@ } }, "source": [ - "To use constructs familiar from [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals.ipynb#The-try-Statement) to explain what `with open(...) as file:` does, below is a formulation with a `try` statement *equivalent* to the `with` statement above. The `finally`-branch is always executed, even if an exception is raised in the `for`-loop. So, `file` is sure to be closed too, with a somewhat less expressive formulation." + "To use constructs familiar from [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_content.ipynb#The-try-Statement) to explain what `with open(...) as file:` does, below is a formulation with a `try` statement *equivalent* to the `with` statement above. The `finally`-branch is *always* executed, even if an exception is raised in the `for`-loop. So, `file` is sure to be closed too, with a somewhat less expressive formulation." ] }, { @@ -737,7 +737,7 @@ } }, "source": [ - "A **sequence** is yet another *abstract* concept (cf., the \"*Containers vs. Iterables*\" section in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Containers-vs.-Iterables)).\n", + "A **sequence** is yet another *abstract* concept (cf., the \"*Containers vs. Iterables*\" section in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#Containers-vs.-Iterables)).\n", "\n", "It unifies *four* [orthogonal](https://en.wikipedia.org/wiki/Orthogonality) (i.e., \"independent\") behaviors into one idea: Any data type, such as `str`, is considered a sequence if it simultaneously\n", "\n", @@ -746,9 +746,9 @@ "3. comes with a *predictable* **order** of its\n", "4. **finite** number of \"things.\"\n", "\n", - "[Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#Collections-vs.-Sequences) formalizes sequences in great detail. Here, we keep our focus on the `str` type that historically received its name as it models a \"**[string of characters](https://en.wikipedia.org/wiki/String_%28computer_science%29)**,\" and a \"string\" is more formally called a sequence in the computer science literature.\n", + "[Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#Collections-vs.-Sequences) formalizes sequences in great detail. Here, we keep our focus on the `str` type that historically received its name as it models a \"**[string of characters](https://en.wikipedia.org/wiki/String_%28computer_science%29)**,\" and a \"string\" is more formally called a sequence in the computer science literature.\n", "\n", - "Behaving like a sequence, `str` objects may be treated like `list` objects in many cases. For example, the built-in [len()](https://docs.python.org/3/library/functions.html#len) function tells us how many elements (i.e., characters) make up `text`. [len()](https://docs.python.org/3/library/functions.html#len) would not work with an *infinite* object: As anything modeled in a program must fit into a computer's finite memory at runtime, there cannot exist objects containing a truly infinite number of elements; however, [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#Iterators-vs.-Iterables) introduces iterable data types that can be used to model an *infinite* series of elements and that, consequently, have no concept of \"length.\"" + "Behaving like a sequence, `str` objects may be treated like `list` objects in many cases. For example, the built-in [len()](https://docs.python.org/3/library/functions.html#len) function tells us how many elements (i.e., characters) make up `text`. [len()](https://docs.python.org/3/library/functions.html#len) would not work with an *infinite* object: As anything modeled in a program must fit into a computer's finite memory at runtime, there cannot exist objects containing a truly infinite number of elements; however, [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#Iterators-vs.-Iterables) introduces iterable data types that can be used to model an *infinite* series of elements and that, consequently, have no concept of \"length.\"" ] }, { @@ -763,7 +763,7 @@ { "data": { "text/plain": [ - "43" + "31" ] }, "execution_count": 23, @@ -799,7 +799,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "L o r e m i p s u m d o l o r s i t a m e t , c o n s e c t e t u r . . . " + "L o r e m i p s u m d o l o r s i t a m e t , . . . " ] } ], @@ -912,7 +912,7 @@ } }, "source": [ - "As `str` objects have the additional property of being *ordered*, we may **index** into them to obtain individual characters with the **indexing operator** `[]`. This is analogous to how we obtained individual elements of a `list` object in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Who-am-I?-And-how-many?)." + "As `str` objects have the additional property of being *ordered*, we may **index** into them to obtain individual characters with the **indexing operator** `[]`. This is analogous to how we obtained individual elements of a `list` object in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Who-am-I?-And-how-many?)." ] }, { @@ -1031,7 +1031,7 @@ } ], "source": [ - "text[42] # = len(text) - 1" + "text[30] # = len(text) - 1" ] }, { @@ -1061,13 +1061,13 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mIndexError\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[0mtext\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m43\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;31m# = len(text)\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[0mtext\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m31\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;31m# = len(text)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mIndexError\u001b[0m: string index out of range" ] } ], "source": [ - "text[43] # = len(text)" + "text[31] # = len(text)" ] }, { @@ -1078,7 +1078,21 @@ } }, "source": [ - "We may use *negative* indexes to start counting from the end of the `str` object. That only works because sequences are *finite*." + "We may use *negative* indexes to start counting from the end of the `str` object, as shown in the figure below. That only works because sequences are *finite*." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "| Slot | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11| 12| 13| 14| 15| 16| 17| 18| 19| 20| 21| 22| 23| 24| 25| 26| 27| 28| 29| 30|\n", + "|:---------:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|\n", + "|**Reverse**|-31|-30|-29|-28|-27|-26|-25|-24|-23|-22|-21|-20|-19|-18|-17|-16|-15|-14|-13|-12|-11|-10|-9 |-8 |-7 |-6 |-5 |-4 |-3 |-2 |-1 |\n", + "| **Char** |`L`|`o`|`r`|`e`|`m`|` `|`i`|`p`|`s`|`u`|`m`|` `|`d`|`o`|`l`|`o`|`r`|` `|`s`|`i`|`t`|` `|`a`|`m`|`e`|`t`|`,`|` `|`.`|`.`|`.`|" ] }, { @@ -1086,7 +1100,7 @@ "execution_count": 33, "metadata": { "slideshow": { - "slide_type": "slide" + "slide_type": "-" } }, "outputs": [ @@ -1105,17 +1119,6 @@ "text[-1]" ] }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "One reason why programmers like to start counting at 0 is that a positive index and its *corresponding* negative index always add up to the length of the sequence." - ] - }, { "cell_type": "code", "execution_count": 34, @@ -1128,7 +1131,7 @@ { "data": { "text/plain": [ - "'i'" + "'L'" ] }, "execution_count": 34, @@ -1137,7 +1140,18 @@ } ], "source": [ - "text[6]" + "text[-31] # = -len(text)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "One reason why programmers like to start counting at 0 is that a positive index and its *corresponding* negative index always add up to the length of the sequence. Here, `6` and `25` add to `31`." ] }, { @@ -1145,7 +1159,7 @@ "execution_count": 35, "metadata": { "slideshow": { - "slide_type": "-" + "slide_type": "fragment" } }, "outputs": [ @@ -1161,7 +1175,31 @@ } ], "source": [ - "text[-37]" + "text[6]" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'i'" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "text[-25]" ] }, { @@ -1192,7 +1230,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 37, "metadata": { "slideshow": { "slide_type": "slide" @@ -1205,7 +1243,7 @@ "'Lorem'" ] }, - "execution_count": 36, + "execution_count": 37, "metadata": {}, "output_type": "execute_result" } @@ -1222,14 +1260,14 @@ } }, "source": [ - "Whereas the *start* is always included in the result, the *end* is not. Counter-intuitive at first, this makes working with individual slices easier as they add up to the original `str` object again.\n", + "Whereas the *start* is always included in the result, the *end* is not. Counter-intuitive at first, this makes working with individual slices easier as they \"add\" up to the original `str` object again (cf., the \"*String Operations*\" sub-section below regarding the overloaded `+` operator). Because the *end* is *not* included, we end the second slice below with `len(text)` or `31` below.\n", "\n", - "So, as the *end* is *not* included, we must end the second slice with `len(text)` or `43` below." + "Not including the *end* has another advantage: The difference \"*end* minus *start*\" tells us how many elements the resulting slice has. Above, for example, `5 - 0` implies that `\"Lorem\"` consists of `5` characters. So, colloquially, `0:5` means \"taking the first five characters.\" That rule only works if both *start* and *end* are *positive*." ] }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 38, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1239,10 +1277,10 @@ { "data": { "text/plain": [ - "'Lorem ipsum dolor sit amet, consectetur ...'" + "'Lorem ipsum dolor sit amet, ...'" ] }, - "execution_count": 37, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -1259,12 +1297,12 @@ } }, "source": [ - "For convenience, the indexes do not need to lie within the range from `0` to `len(text)` when slicing." + "By combining a *positive* start with a *negative* end index, we specify both ends of the slice *relative* to the ends of the entire `str` object. So, colloquially, `6:-5` below means \"drop the first six and last five characters.\" The length of the resulting slice can *not* be calculated from the indexes and depends only on the length of the original `str` object." ] }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 39, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1274,10 +1312,45 @@ { "data": { "text/plain": [ - "'Lorem ipsum dolor sit amet, consectetur ...'" + "'ipsum dolor sit amet'" ] }, - "execution_count": 38, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "text[6:-5]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "For convenience, the indexes do not need to lie within the range from `0` to `len(text)` when slicing. So, no `IndexError` is raised here." + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'Lorem ipsum dolor sit amet, ...'" + ] + }, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -1294,12 +1367,12 @@ } }, "source": [ - "Commonly, we leave out the `0` for the *start* and the *end* if it is equal to the \"length.\"" + "If left out, *start* defaults to `0` and *end* to the \"length\" of the `str` object. Here, we take a \"full\" slice that is essentially a copy of the original `str` object." ] }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 41, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1309,16 +1382,16 @@ { "data": { "text/plain": [ - "'Lorem ipsum dolor sit amet, consectetur ...'" + "'Lorem ipsum dolor sit amet, ...'" ] }, - "execution_count": 39, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "text[:5] + text[5:]" + "text[:]" ] }, { @@ -1329,12 +1402,12 @@ } }, "source": [ - "Slicing makes it easy to obtain shorter versions of the original `str` object." + "Slicing (and indexing) makes it easy to obtain shorter versions of the original `str` object." ] }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 42, "metadata": { "slideshow": { "slide_type": "skip" @@ -1347,13 +1420,13 @@ "'Lorem ipsum dolor sit amet.'" ] }, - "execution_count": 40, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "text[:26] + text[42]" + "text[:26] + text[30]" ] }, { @@ -1369,7 +1442,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 43, "metadata": { "slideshow": { "slide_type": "slide" @@ -1379,10 +1452,10 @@ { "data": { "text/plain": [ - "'Lrmismdlrstae,cnettr..'" + "'Lrmismdlrstae,..'" ] }, - "execution_count": 41, + "execution_count": 43, "metadata": {}, "output_type": "execute_result" } @@ -1404,7 +1477,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 44, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1414,10 +1487,10 @@ { "data": { "text/plain": [ - "'... rutetcesnoc ,tema tis rolod muspi meroL'" + "'... ,tema tis rolod muspi meroL'" ] }, - "execution_count": 42, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -1445,16 +1518,16 @@ } }, "source": [ - "Whereas elements of a `list` object *may* be *re-assigned*, as shortly hinted at in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Who-am-I?-And-how-many?), this is *not* allowed for `str` objects. Once created, they *cannot* be *changed*. Formally, we say that they are **immutable**. In that regard, `str` objects and all the numeric types in [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers.ipynb) are alike.\n", + "Whereas elements of a `list` object *may* be *re-assigned*, as shortly hinted at in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Who-am-I?-And-how-many?), this is *not* allowed for `str` objects. Once created, they *cannot* be *changed*. Formally, we say that they are **immutable**. In that regard, `str` objects and all the numeric types in [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_00_content.ipynb) are alike.\n", "\n", - "On the contrary, objects that may be changed after creation, are called **mutable**. We already saw in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Who-am-I?-And-how-many?) how mutable objects are more difficult to reason about for a beginner, in particular, if more than *one* variable references it. Yet, mutability does have its place in a programmer's toolbox, and we revisit this idea in the next chapters.\n", + "On the contrary, objects that may be changed after creation, are called **mutable**. We already saw in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Who-am-I?-And-how-many?) how mutable objects are more difficult to reason about for a beginner, in particular, if more than *one* variable references it. Yet, mutability does have its place in a programmer's toolbox, and we revisit this idea in the next chapters.\n", "\n", "The `TypeError` indicates that `str` objects are *immutable*: Assignment to an index or a slice are *not* supported." ] }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 45, "metadata": { "slideshow": { "slide_type": "slide" @@ -1468,7 +1541,7 @@ "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[0mtext\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\"Z\"\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[0mtext\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\"Z\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment" ] } @@ -1479,7 +1552,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 46, "metadata": { "slideshow": { "slide_type": "-" @@ -1493,7 +1566,7 @@ "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[0mtext\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"random\"\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[0mtext\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m\"random\"\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment" ] } @@ -1528,7 +1601,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 47, "metadata": { "slideshow": { "slide_type": "slide" @@ -1538,10 +1611,10 @@ { "data": { "text/plain": [ - "'Lorem ipsum dolor sit amet, consectetur ...'" + "'Lorem ipsum dolor sit amet, ...'" ] }, - "execution_count": 45, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -1552,7 +1625,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 48, "metadata": { "slideshow": { "slide_type": "-" @@ -1565,7 +1638,7 @@ "22" ] }, - "execution_count": 46, + "execution_count": 48, "metadata": {}, "output_type": "execute_result" } @@ -1576,7 +1649,7 @@ }, { "cell_type": "code", - "execution_count": 47, + "execution_count": 49, "metadata": { "slideshow": { "slide_type": "-" @@ -1589,7 +1662,7 @@ "-1" ] }, - "execution_count": 47, + "execution_count": 49, "metadata": {}, "output_type": "execute_result" } @@ -1600,7 +1673,7 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 50, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1613,7 +1686,7 @@ "12" ] }, - "execution_count": 48, + "execution_count": 50, "metadata": {}, "output_type": "execute_result" } @@ -1635,7 +1708,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 51, "metadata": { "slideshow": { "slide_type": "slide" @@ -1648,7 +1721,7 @@ "1" ] }, - "execution_count": 49, + "execution_count": 51, "metadata": {}, "output_type": "execute_result" } @@ -1659,7 +1732,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 52, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1672,7 +1745,7 @@ "13" ] }, - "execution_count": 50, + "execution_count": 52, "metadata": {}, "output_type": "execute_result" } @@ -1683,7 +1756,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 53, "metadata": { "slideshow": { "slide_type": "skip" @@ -1696,7 +1769,7 @@ "-1" ] }, - "execution_count": 51, + "execution_count": 53, "metadata": {}, "output_type": "execute_result" } @@ -1718,7 +1791,7 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 54, "metadata": { "slideshow": { "slide_type": "slide" @@ -1731,7 +1804,7 @@ "1" ] }, - "execution_count": 52, + "execution_count": 54, "metadata": {}, "output_type": "execute_result" } @@ -1753,7 +1826,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 55, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1766,7 +1839,7 @@ "2" ] }, - "execution_count": 53, + "execution_count": 55, "metadata": {}, "output_type": "execute_result" } @@ -1788,7 +1861,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 56, "metadata": { "slideshow": { "slide_type": "skip" @@ -1801,7 +1874,7 @@ "2" ] }, - "execution_count": 54, + "execution_count": 56, "metadata": {}, "output_type": "execute_result" } @@ -1823,7 +1896,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 57, "metadata": { "slideshow": { "slide_type": "slide" @@ -1834,43 +1907,6 @@ "example = \"random\"" ] }, - { - "cell_type": "code", - "execution_count": 56, - "metadata": { - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "139674947440512" - ] - }, - "execution_count": 56, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "id(example)" - ] - }, - { - "cell_type": "code", - "execution_count": 57, - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [], - "source": [ - "lower = example.lower()" - ] - }, { "cell_type": "code", "execution_count": 58, @@ -1883,7 +1919,7 @@ { "data": { "text/plain": [ - "139674887826488" + "140483525349552" ] }, "execution_count": 58, @@ -1891,6 +1927,43 @@ "output_type": "execute_result" } ], + "source": [ + "id(example)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [], + "source": [ + "lower = example.lower()" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "140483422704176" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "id(lower)" ] @@ -1908,7 +1981,7 @@ }, { "cell_type": "code", - "execution_count": 59, + "execution_count": 61, "metadata": { "slideshow": { "slide_type": "fragment" @@ -1921,7 +1994,7 @@ "False" ] }, - "execution_count": 59, + "execution_count": 61, "metadata": {}, "output_type": "execute_result" } @@ -1932,7 +2005,7 @@ }, { "cell_type": "code", - "execution_count": 60, + "execution_count": 62, "metadata": { "slideshow": { "slide_type": "-" @@ -1945,7 +2018,7 @@ "True" ] }, - "execution_count": 60, + "execution_count": 62, "metadata": {}, "output_type": "execute_result" } @@ -1969,7 +2042,7 @@ }, { "cell_type": "code", - "execution_count": 61, + "execution_count": 63, "metadata": { "slideshow": { "slide_type": "slide" @@ -1985,7 +2058,6 @@ "dolor\n", "sit\n", "amet,\n", - "consectetur\n", "...\n" ] } @@ -2008,7 +2080,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 64, "metadata": { "slideshow": { "slide_type": "slide" @@ -2021,7 +2093,7 @@ }, { "cell_type": "code", - "execution_count": 63, + "execution_count": 65, "metadata": { "slideshow": { "slide_type": "-" @@ -2034,7 +2106,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 66, "metadata": { "slideshow": { "slide_type": "-" @@ -2047,7 +2119,7 @@ "'This will become a sentence'" ] }, - "execution_count": 64, + "execution_count": 66, "metadata": {}, "output_type": "execute_result" } @@ -2069,7 +2141,7 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 67, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2082,7 +2154,7 @@ "'a b c d e'" ] }, - "execution_count": 65, + "execution_count": 67, "metadata": {}, "output_type": "execute_result" } @@ -2104,7 +2176,7 @@ }, { "cell_type": "code", - "execution_count": 66, + "execution_count": 68, "metadata": { "slideshow": { "slide_type": "slide" @@ -2117,7 +2189,7 @@ "'This is a sentence'" ] }, - "execution_count": 66, + "execution_count": 68, "metadata": {}, "output_type": "execute_result" } @@ -2145,12 +2217,12 @@ } }, "source": [ - "As mentioned in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Operator-Overloading), the `+` and `*` operators are *overloaded* and used for **string concatenation**. They always create *new* `str` objects. That has nothing to do with the `str` type's immutability, but is the default behavior of operators." + "As mentioned in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Operator-Overloading), the `+` and `*` operators are *overloaded* and used for **string concatenation**. They always create *new* `str` objects. That has nothing to do with the `str` type's immutability, but is the default behavior of operators." ] }, { "cell_type": "code", - "execution_count": 67, + "execution_count": 69, "metadata": { "slideshow": { "slide_type": "slide" @@ -2163,7 +2235,7 @@ "'Hello Lore'" ] }, - "execution_count": 67, + "execution_count": 69, "metadata": {}, "output_type": "execute_result" } @@ -2174,7 +2246,7 @@ }, { "cell_type": "code", - "execution_count": 68, + "execution_count": 70, "metadata": { "slideshow": { "slide_type": "-" @@ -2187,7 +2259,7 @@ "'Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum '" ] }, - "execution_count": 68, + "execution_count": 70, "metadata": {}, "output_type": "execute_result" } @@ -2220,7 +2292,7 @@ }, { "cell_type": "code", - "execution_count": 69, + "execution_count": 71, "metadata": { "slideshow": { "slide_type": "slide" @@ -2233,65 +2305,6 @@ "B = \"Banana\"" ] }, - { - "cell_type": "code", - "execution_count": 70, - "metadata": { - "slideshow": { - "slide_type": "fragment" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 70, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "A < B" - ] - }, - { - "cell_type": "code", - "execution_count": 71, - "metadata": { - "slideshow": { - "slide_type": "-" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "False" - ] - }, - "execution_count": 71, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "a < B" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "slideshow": { - "slide_type": "skip" - } - }, - "source": [ - "One way to fix this is to only compare lower-cased `str` objects." - ] - }, { "cell_type": "code", "execution_count": 72, @@ -2312,6 +2325,65 @@ "output_type": "execute_result" } ], + "source": [ + "A < B" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": { + "slideshow": { + "slide_type": "-" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "False" + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "a < B" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "One way to fix this is to only compare lower-cased `str` objects." + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "slideshow": { + "slide_type": "fragment" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "a < B.lower()" ] @@ -2329,7 +2401,7 @@ }, { "cell_type": "code", - "execution_count": 73, + "execution_count": 75, "metadata": { "slideshow": { "slide_type": "slide" @@ -2425,7 +2497,7 @@ }, { "cell_type": "code", - "execution_count": 74, + "execution_count": 76, "metadata": { "slideshow": { "slide_type": "slide" @@ -2439,7 +2511,7 @@ }, { "cell_type": "code", - "execution_count": 75, + "execution_count": 77, "metadata": { "slideshow": { "slide_type": "-" @@ -2452,7 +2524,7 @@ "'Hello Alexander! Good morning.'" ] }, - "execution_count": 75, + "execution_count": 77, "metadata": {}, "output_type": "execute_result" } @@ -2474,7 +2546,7 @@ }, { "cell_type": "code", - "execution_count": 76, + "execution_count": 78, "metadata": { "slideshow": { "slide_type": "slide" @@ -2487,7 +2559,7 @@ }, { "cell_type": "code", - "execution_count": 77, + "execution_count": 79, "metadata": { "slideshow": { "slide_type": "-" @@ -2500,7 +2572,7 @@ "'Pi is 3.14'" ] }, - "execution_count": 77, + "execution_count": 79, "metadata": {}, "output_type": "execute_result" } @@ -2511,7 +2583,7 @@ }, { "cell_type": "code", - "execution_count": 78, + "execution_count": 80, "metadata": { "slideshow": { "slide_type": "-" @@ -2524,7 +2596,7 @@ "'Pi is 3.142'" ] }, - "execution_count": 78, + "execution_count": 80, "metadata": {}, "output_type": "execute_result" } @@ -2557,7 +2629,7 @@ }, { "cell_type": "code", - "execution_count": 79, + "execution_count": 81, "metadata": { "slideshow": { "slide_type": "slide" @@ -2570,7 +2642,7 @@ "'Hello Alexander! Good morning.'" ] }, - "execution_count": 79, + "execution_count": 81, "metadata": {}, "output_type": "execute_result" } @@ -2592,7 +2664,7 @@ }, { "cell_type": "code", - "execution_count": 80, + "execution_count": 82, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2605,7 +2677,7 @@ "'Good morning, Alexander'" ] }, - "execution_count": 80, + "execution_count": 82, "metadata": {}, "output_type": "execute_result" } @@ -2627,7 +2699,7 @@ }, { "cell_type": "code", - "execution_count": 81, + "execution_count": 83, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2640,7 +2712,7 @@ "'Hello Alexander! Good morning.'" ] }, - "execution_count": 81, + "execution_count": 83, "metadata": {}, "output_type": "execute_result" } @@ -2662,7 +2734,7 @@ }, { "cell_type": "code", - "execution_count": 82, + "execution_count": 84, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2675,7 +2747,7 @@ "'Pi is 3.14'" ] }, - "execution_count": 82, + "execution_count": 84, "metadata": {}, "output_type": "execute_result" } @@ -2703,14 +2775,14 @@ } }, "source": [ - "The `%` operator that we saw in the context of modulo division in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#%28Arithmetic%29-Operators) is overloaded with string interpolation when its first operand is a `str` object. The second operand consists of all expressions to be filled in. Format specifiers work with a `%` instead of curly braces and according to a different set of rules referred to as **[printf-style string formatting](https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting)**. So, `{:.2f}` becomes `%.2f`.\n", + "The `%` operator that we saw in the context of modulo division in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#%28Arithmetic%29-Operators) is overloaded with string interpolation when its first operand is a `str` object. The second operand consists of all expressions to be filled in. Format specifiers work with a `%` instead of curly braces and according to a different set of rules referred to as **[printf-style string formatting](https://docs.python.org/3/library/stdtypes.html#printf-style-string-formatting)**. So, `{:.2f}` becomes `%.2f`.\n", "\n", "This way of string interpolation is the oldest and originates from the [C language](https://en.wikipedia.org/wiki/C_%28programming_language%29). It is still widely spread, but we should use one of the other two ways instead. We show it here mainly for completeness sake." ] }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 85, "metadata": { "slideshow": { "slide_type": "skip" @@ -2723,7 +2795,7 @@ "'Pi is 3.14'" ] }, - "execution_count": 83, + "execution_count": 85, "metadata": {}, "output_type": "execute_result" } @@ -2740,12 +2812,12 @@ } }, "source": [ - "To insert more than one expression, we must list them in order and between parenthesis `(` and `)`. As [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#The-tuple-Type) reveals, this literal syntax creates an object of type `tuple`. Also, to format an expression as text, we use the format specifier `%s`." + "To insert more than one expression, we must list them in order and between parenthesis `(` and `)`. As [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#The-tuple-Type) reveals, this literal syntax creates an object of type `tuple`. Also, to format an expression as text, we use the format specifier `%s`." ] }, { "cell_type": "code", - "execution_count": 84, + "execution_count": 86, "metadata": { "slideshow": { "slide_type": "skip" @@ -2758,7 +2830,7 @@ "'Hello Alexander! Good morning.'" ] }, - "execution_count": 84, + "execution_count": 86, "metadata": {}, "output_type": "execute_result" } @@ -2793,7 +2865,7 @@ }, { "cell_type": "code", - "execution_count": 85, + "execution_count": 87, "metadata": { "slideshow": { "slide_type": "slide" @@ -2816,7 +2888,7 @@ }, { "cell_type": "code", - "execution_count": 86, + "execution_count": 88, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2848,7 +2920,7 @@ }, { "cell_type": "code", - "execution_count": 87, + "execution_count": 89, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2880,7 +2952,7 @@ }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 90, "metadata": { "slideshow": { "slide_type": "skip" @@ -2893,7 +2965,7 @@ "'This is a sentence\\nthat is printed\\non three lines.'" ] }, - "execution_count": 88, + "execution_count": 90, "metadata": {}, "output_type": "execute_result" } @@ -2928,7 +3000,7 @@ }, { "cell_type": "code", - "execution_count": 89, + "execution_count": 91, "metadata": { "slideshow": { "slide_type": "slide" @@ -2961,7 +3033,7 @@ }, { "cell_type": "code", - "execution_count": 90, + "execution_count": 92, "metadata": { "slideshow": { "slide_type": "fragment" @@ -2970,10 +3042,10 @@ "outputs": [ { "ename": "SyntaxError", - "evalue": "(unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \\UXXXXXXXX escape (, line 1)", + "evalue": "(unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \\UXXXXXXXX escape (, 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 print(\"C:\\Users\\Administrator\\Desktop\\Project_Folder\")\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \\UXXXXXXXX escape\n" + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m print(\"C:\\Users\\Administrator\\Desktop\\Project_Folder\")\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \\UXXXXXXXX escape\n" ] } ], @@ -2994,7 +3066,7 @@ }, { "cell_type": "code", - "execution_count": 91, + "execution_count": 93, "metadata": { "slideshow": { "slide_type": "slide" @@ -3015,7 +3087,7 @@ }, { "cell_type": "code", - "execution_count": 92, + "execution_count": 94, "metadata": { "slideshow": { "slide_type": "-" @@ -3047,7 +3119,7 @@ }, { "cell_type": "code", - "execution_count": 93, + "execution_count": 95, "metadata": { "slideshow": { "slide_type": "slide" @@ -3068,7 +3140,7 @@ }, { "cell_type": "code", - "execution_count": 94, + "execution_count": 96, "metadata": { "slideshow": { "slide_type": "-" @@ -3111,7 +3183,7 @@ }, { "cell_type": "code", - "execution_count": 95, + "execution_count": 97, "metadata": { "slideshow": { "slide_type": "slide" @@ -3120,10 +3192,10 @@ "outputs": [ { "ename": "SyntaxError", - "evalue": "EOL while scanning string literal (, line 1)", + "evalue": "EOL while scanning string literal (, 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 \"\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m EOL while scanning string literal\n" + "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m \"\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m EOL while scanning string literal\n" ] } ], @@ -3146,7 +3218,7 @@ }, { "cell_type": "code", - "execution_count": 96, + "execution_count": 98, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3173,7 +3245,7 @@ }, { "cell_type": "code", - "execution_count": 97, + "execution_count": 99, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3186,7 +3258,7 @@ "'\\nI am a multi-line string\\nconsisting of 4 lines.\\n'" ] }, - "execution_count": 97, + "execution_count": 99, "metadata": {}, "output_type": "execute_result" } @@ -3208,7 +3280,7 @@ }, { "cell_type": "code", - "execution_count": 98, + "execution_count": 100, "metadata": { "slideshow": { "slide_type": "fragment" @@ -3243,7 +3315,7 @@ }, { "cell_type": "code", - "execution_count": 99, + "execution_count": 101, "metadata": { "slideshow": { "slide_type": "slide" @@ -3279,7 +3351,7 @@ }, { "cell_type": "code", - "execution_count": 100, + "execution_count": 102, "metadata": { "slideshow": { "slide_type": "slide" @@ -3293,7 +3365,7 @@ }, { "cell_type": "code", - "execution_count": 101, + "execution_count": 103, "metadata": { "slideshow": { "slide_type": "-" @@ -3306,7 +3378,7 @@ "\"Lorem Ipsum is simply dummy text of the printing and typesetting industry.\\nLorem Ipsum has been the industry's standard dummy text ever since the 1500s\\nwhen an unknown printer took a galley of type and scrambled it to make a type\\nspecimen book. It has survived not only five centuries but also the leap into\\nelectronic typesetting, remaining essentially unchanged. It was popularised in\\nthe 1960s with the release of Letraset sheets.\\n\"" ] }, - "execution_count": 101, + "execution_count": 103, "metadata": {}, "output_type": "execute_result" } @@ -3317,7 +3389,7 @@ }, { "cell_type": "code", - "execution_count": 102, + "execution_count": 104, "metadata": { "slideshow": { "slide_type": "-" @@ -3383,7 +3455,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "livereveal": { "auto_select": "code", @@ -3411,5 +3483,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/06_text_review_and_exercises.ipynb b/06_text_10_review.ipynb similarity index 94% rename from 06_text_review_and_exercises.ipynb rename to 06_text_10_review.ipynb index 40ac8c4..fe9588e 100644 --- a/06_text_review_and_exercises.ipynb +++ b/06_text_10_review.ipynb @@ -19,7 +19,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Read [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb) of the book. Then work through the eight review questions." + "Read [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text_00_content.ipynb) of the book. Then, work through the questions below." ] }, { @@ -33,7 +33,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Answer the following questions briefly with *at most* 300 characters per question!" + "Answer the following questions *briefly*!" ] }, { @@ -184,7 +184,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "toc": { "base_numbering": 1, @@ -201,5 +201,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/07_sequences.ipynb b/07_sequences_00_content.ipynb similarity index 97% rename from 07_sequences.ipynb rename to 07_sequences_00_content.ipynb index f20b670..924467a 100644 --- a/07_sequences.ipynb +++ b/07_sequences_00_content.ipynb @@ -19,11 +19,11 @@ } }, "source": [ - "We studied numbers (cf., [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers.ipynb)) and textual data (cf., [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb)) first, mainly because objects of the presented data types are \"simple,\" for two reasons: First, they are *immutable*, and, as we saw in the \"*Who am I? And how many?*\" section in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Who-am-I?-And-how-many?), mutable objects can quickly become hard to reason about. Second, they are \"flat\" in the sense that they are *not* composed of other objects.\n", + "We studied numbers (cf., [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_00_content.ipynb)) and textual data (cf., [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text_00_content.ipynb)) first, mainly because objects of the presented data types are \"simple,\" for two reasons: First, they are *immutable*, and, as we saw in the \"*Who am I? And how many?*\" section in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Who-am-I?-And-how-many?), mutable objects can quickly become hard to reason about. Second, they are \"flat\" in the sense that they are *not* composed of other objects.\n", "\n", "The `str` type is a bit of a corner case in this regard. While one could argue that a longer `str` object, for example, `\"text\"`, is composed of individual characters, this is *not* the case in memory as the literal `\"text\"` only creates *one* object (i.e., one \"bag\" of $0$s and $1$s modeling all characters).\n", "\n", - "This chapter and [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings.ipynb) introduce various \"complex\" data types. While some are mutable and others are not, they all share that they are primarily used to \"manage,\" or structure, the memory in a program. Unsurprisingly, computer scientists refer to the ideas and theories behind these data types as **[data structures](https://en.wikipedia.org/wiki/Data_structure)**.\n", + "This chapter, [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_00_content.ipynb), and [Chapter 9](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/09_arrays_00_content.ipynb) introduce various \"complex\" data types. While some are mutable and others are not, they all share that they are primarily used to \"manage,\" or structure, the memory in a program. Unsurprisingly, computer scientists refer to the ideas and theories behind these data types as **[data structures](https://en.wikipedia.org/wiki/Data_structure)**.\n", "\n", "In this chapter, we focus on data types that model all kinds of sequential data. Examples of such data are [spreadsheets](https://en.wikipedia.org/wiki/Spreadsheet) or [matrices](https://en.wikipedia.org/wiki/Matrix_%28mathematics%29)/[vectors](https://en.wikipedia.org/wiki/Vector_%28mathematics_and_physics%29). Such formats share the property that they are composed of smaller units that come in a sequence of, for example, rows/columns/cells or elements/entries." ] @@ -47,9 +47,9 @@ } }, "source": [ - "[Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb#A-\"String\"-of-Characters) already describes the *sequence* properties of `str` objects. Here, we take a step back and study these properties on their own before looking at bigger ideas.\n", + "[Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text_00_content.ipynb#A-\"String\"-of-Characters) already describes the *sequence* properties of `str` objects. Here, we take a step back and study these properties on their own before looking at bigger ideas.\n", "\n", - "The [collections.abc](https://docs.python.org/3/library/collections.abc.html) module in the [standard library](https://docs.python.org/3/library/index.html) defines a variety of **abstract base classes** (ABCs). We saw ABCs already in [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers.ipynb#The-Numerical-Tower), where we use the ones from the [numbers](https://docs.python.org/3/library/numbers.html) module in the [standard library](https://docs.python.org/3/library/index.html) to classify Python's numeric data types according to mathematical ideas. Now, we take the ABCs from the [collections.abc](https://docs.python.org/3/library/collections.abc.html) module to classify the data types in this chapter and [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings.ipynb) according to their behavior in various contexts.\n", + "The [collections.abc](https://docs.python.org/3/library/collections.abc.html) module in the [standard library](https://docs.python.org/3/library/index.html) defines a variety of **abstract base classes** (ABCs). We saw ABCs already in [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_00_content.ipynb#The-Numerical-Tower), where we use the ones from the [numbers](https://docs.python.org/3/library/numbers.html) module in the [standard library](https://docs.python.org/3/library/index.html) to classify Python's numeric data types according to mathematical ideas. Now, we take the ABCs from the [collections.abc](https://docs.python.org/3/library/collections.abc.html) module to classify the data types in this chapter and [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_00_content.ipynb) according to their behavior in various contexts.\n", "\n", "As an illustration, consider `numbers` and `text` below, two objects of *different* types." ] @@ -65,7 +65,7 @@ "outputs": [], "source": [ "numbers = [7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]\n", - "text = \"Lorem ipsum dolor sit amet, consectetur ...\"" + "text = \"Lorem ipsum dolor sit amet, ...\"" ] }, { @@ -114,7 +114,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "L o r e m i p s u m d o l o r s i t a m e t , c o n s e c t e t u r . . . " + "L o r e m i p s u m d o l o r s i t a m e t , . . . " ] } ], @@ -131,7 +131,7 @@ } }, "source": [ - "In [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Containers-vs.-Iterables), we referred to such types as *iterables*. That is *not* a proper [English](https://dictionary.cambridge.org/spellcheck/english-german/?q=iterable) word, even if it may sound like one at first sight. Yet, it is an official term in the Python world formalized with the `Iterable` ABC in the [collections.abc](https://docs.python.org/3/library/collections.abc.html) module.\n", + "In [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#Containers-vs.-Iterables), we referred to such types as *iterables*. That is *not* a proper [English](https://dictionary.cambridge.org/spellcheck/english-german/?q=iterable) word, even if it may sound like one at first sight. Yet, it is an official term in the Python world formalized with the `Iterable` ABC in the [collections.abc](https://docs.python.org/3/library/collections.abc.html) module.\n", "\n", "For the data science practitioner, it is worthwhile to know such terms as, for example, the documentation on the [built-ins](https://docs.python.org/3/library/functions.html) uses them extensively: In simple words, any built-in that takes an argument called \"*iterable*\" may be called with *any* object that supports being looped over. Already familiar [built-ins](https://docs.python.org/3/library/functions.html) include [enumerate()](https://docs.python.org/3/library/functions.html#enumerate), [sum()](https://docs.python.org/3/library/functions.html#sum), or [zip()](https://docs.python.org/3/library/functions.html#zip). So, they do *not* require the argument to be of a certain data type (e.g., `list`); instead, any *iterable* type works." ] @@ -181,7 +181,7 @@ } }, "source": [ - "As in the context of *goose typing* in [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers.ipynb#Goose-Typing), we can use ABCs with the built-in [isinstance()](https://docs.python.org/3/library/functions.html#isinstance) function to check if an object supports a behavior.\n", + "As in the context of *goose typing* in [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_00_content.ipynb#Goose-Typing), we can use ABCs with the built-in [isinstance()](https://docs.python.org/3/library/functions.html#isinstance) function to check if an object supports a behavior.\n", "\n", "So, let's \"ask\" Python if it can loop over `numbers` or `text`." ] @@ -536,7 +536,7 @@ { "data": { "text/plain": [ - "43" + "31" ] }, "execution_count": 17, @@ -767,7 +767,7 @@ "name": "stdout", "output_type": "stream", "text": [ - ". . . r u t e t c e s n o c , t e m a t i s r o l o d m u s p i m e r o L " + ". . . , t e m a t i s r o l o d m u s p i m e r o L " ] } ], @@ -1028,7 +1028,7 @@ { "data": { "text/plain": [ - "140157873498184" + "140417317434464" ] }, "execution_count": 34, @@ -1074,7 +1074,7 @@ "source": [ "Alternatively, we use the [list()](https://docs.python.org/3/library/functions.html#func-list) built-in to create a `list` object out of an iterable we pass to it as the argument.\n", "\n", - "For example, we can wrap the [range()](https://docs.python.org/3/library/functions.html#func-range) built-in with [list()](https://docs.python.org/3/library/functions.html#func-list): As described in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Containers-vs.-Iterables), `range` objects, like `range(1, 13)` below, are iterable and generate `int` objects \"on the fly\" (i.e., one by one). The [list()](https://docs.python.org/3/library/functions.html#func-list) around it acts like a `for`-loop and **materializes** twelve `int` objects in memory that then become the elements of the newly created `list` object. [PythonTutor](http://www.pythontutor.com/visualize.html#code=r%20%3D%20range%281,%2013%29%0Al%20%3D%20list%28range%281,%2013%29%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false) shows this difference visually." + "For example, we can wrap the [range()](https://docs.python.org/3/library/functions.html#func-range) built-in with [list()](https://docs.python.org/3/library/functions.html#func-list): As described in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#Containers-vs.-Iterables), `range` objects, like `range(1, 13)` below, are iterable and generate `int` objects \"on the fly\" (i.e., one by one). The [list()](https://docs.python.org/3/library/functions.html#func-list) around it acts like a `for`-loop and **materializes** twelve `int` objects in memory that then become the elements of the newly created `list` object. [PythonTutor](http://www.pythontutor.com/visualize.html#code=r%20%3D%20range%281,%2013%29%0Al%20%3D%20list%28range%281,%2013%29%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false) shows this difference visually." ] }, { @@ -1299,11 +1299,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "[] \t140157882223304 \t\n", - "10 \t93987402609984 \t\n", - "20.0 \t140157882328912 \t\n", - "Thirty \t140157873509520 \t\n", - "[40, 50] \t140157873031176 \t\n" + "[] \t140417315676720 \t\n", + "10 \t94860849595456 \t\n", + "20.0 \t140417316476784 \t\n", + "Thirty \t140417315739568 \t\n", + "[40, 50] \t140417315720800 \t\n" ] } ], @@ -2017,7 +2017,7 @@ { "data": { "text/plain": [ - "140157882223304" + "140417315676720" ] }, "execution_count": 65, @@ -2041,7 +2041,7 @@ { "data": { "text/plain": [ - "140157882223304" + "140417315676720" ] }, "execution_count": 66, @@ -2065,7 +2065,7 @@ { "data": { "text/plain": [ - "140157882223304" + "140417315676720" ] }, "execution_count": 67, @@ -2191,7 +2191,7 @@ { "data": { "text/plain": [ - "140157882223304" + "140417315676720" ] }, "execution_count": 72, @@ -2215,7 +2215,7 @@ { "data": { "text/plain": [ - "140157873029448" + "140417376809600" ] }, "execution_count": 73, @@ -2392,7 +2392,7 @@ { "data": { "text/plain": [ - "140157873498184" + "140417317434464" ] }, "execution_count": 79, @@ -2401,7 +2401,7 @@ } ], "source": [ - "id(nested)" + "id(nested) # same memory location as before" ] }, { @@ -2678,7 +2678,7 @@ "source": [ "The `list` type is an essential data structure in any real-world Python application, and many typical `list`-related algorithms from computer science theory are already built into it at the C level (cf., the [documentation](https://docs.python.org/3/library/stdtypes.html#mutable-sequence-types) or the [tutorial](https://docs.python.org/3/tutorial/datastructures.html#more-on-lists) for a full overview; unfortunately, not all methods have direct links). So, understanding and applying the built-in methods of the `list` type not only speeds up the development process but also makes programs significantly faster.\n", "\n", - "In contrast to the `str` type's methods in [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb#String-Methods) (e.g., [upper()](https://docs.python.org/3/library/stdtypes.html#str.upper) or [lower()](https://docs.python.org/3/library/stdtypes.html#str.lower)), the `list` type's methods that mutate an object do so *in place*. That means they *never* create *new* `list` objects and return `None` to indicate that. So, we must *never* assign the return value of `list` methods to the variable holding the list!\n", + "In contrast to the `str` type's methods in [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text_00_content.ipynb#String-Methods) (e.g., [upper()](https://docs.python.org/3/library/stdtypes.html#str.upper) or [lower()](https://docs.python.org/3/library/stdtypes.html#str.lower)), the `list` type's methods that mutate an object do so *in place*. That means they *never* create *new* `list` objects and return `None` to indicate that. So, we must *never* assign the return value of `list` methods to the variable holding the list!\n", "\n", "Let's look at the following `names` example." ] @@ -3016,7 +3016,7 @@ "source": [ "The [sort()](https://docs.python.org/3/library/stdtypes.html#list.sort) method and the [sorted()](https://docs.python.org/3/library/functions.html#sorted) function sort the elements in `names` in alphabetical order, forward or backward. However, that does *not* hold in general.\n", "\n", - "We mention above that `list` objects may contain objects of *any* type and even of *mixed* types. Because of that, the sorting is **[delegated](https://en.wikipedia.org/wiki/Delegation_(object-oriented_programming))** to the elements in a `list` object. In a way, Python \"asks\" the elements in a `list` object to sort themselves. As `names` contains only `str` objects, they are sorted according the the comparison rules explained in [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb#String-Comparison).\n", + "We mention above that `list` objects may contain objects of *any* type and even of *mixed* types. Because of that, the sorting is **[delegated](https://en.wikipedia.org/wiki/Delegation_(object-oriented_programming))** to the elements in a `list` object. In a way, Python \"asks\" the elements in a `list` object to sort themselves. As `names` contains only `str` objects, they are sorted according the the comparison rules explained in [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text_00_content.ipynb#String-Comparison).\n", "\n", "To customize the sorting, we pass a keyword-only `key` argument to [sort()](https://docs.python.org/3/library/stdtypes.html#list.sort) or [sorted()](https://docs.python.org/3/library/functions.html#sorted), which must be a `function` object accepting *one* positional argument. Then, the elements in the `list` object are passed to that one by one, and the return values are used as the **sort keys**. The `key` argument is also a popular use case for `lambda` expressions.\n", "\n", @@ -4150,7 +4150,7 @@ "\n", "The revised `add_xyz()` function below is more natural to reason about as it does *not* modify the passed in `arg` internally. This approach is following the **[functional programming](https://en.wikipedia.org/wiki/Functional_programming)** paradigm that is going through a \"renaissance\" currently. Two essential characteristics of functional programming are that a function *never* changes its inputs and *always* returns the same output given the same inputs.\n", "\n", - "For a beginner, it is probably better to stick to this idea and not change any arguments as the original `add_xyz()` above. However, functions that modify and return the argument passed in are an important aspect of object-oriented programming, as explained in Chapter 9." + "For a beginner, it is probably better to stick to this idea and not change any arguments as the original `add_xyz()` above. However, functions that modify and return the argument passed in are an important aspect of object-oriented programming, as explained in Chapter 10." ] }, { @@ -4511,7 +4511,7 @@ { "data": { "text/plain": [ - "140157873009144" + "140417315626832" ] }, "execution_count": 158, @@ -5227,7 +5227,6 @@ "cell_type": "code", "execution_count": 184, "metadata": { - "scrolled": false, "slideshow": { "slide_type": "skip" } @@ -6154,7 +6153,7 @@ } }, "source": [ - "Unpacking allows us to rewrite the iterative `fibonacci()` function from [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#\"Hard-at-first-Glance\"-Example:-Fibonacci-Numbers-%28revisited%29) in a concise way, now also supporting *goose typing* with the [numbers](https://docs.python.org/3/library/numbers.html) module from the [standard library](https://docs.python.org/3/library/index.html)." + "Unpacking allows us to rewrite the iterative `fibonacci()` function from [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#\"Hard-at-first-Glance\"-Example:-Fibonacci-Numbers-%28revisited%29) in a concise way, now also supporting *goose typing* with the [numbers](https://docs.python.org/3/library/numbers.html) module from the [standard library](https://docs.python.org/3/library/index.html)." ] }, { @@ -6577,7 +6576,7 @@ } }, "source": [ - "In the \"*Packing & Unpacking with Functions*\" [exercise](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_review_and_exercises.ipynb#Packing-&-Unpacking-with-Functions) at the end of this chapter, we look at `product()` in more detail.\n", + "In the \"*Packing & Unpacking with Functions*\" [exercise](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_review_and_exercises_00_content.ipynb#Packing-&-Unpacking-with-Functions) at the end of this chapter, we look at `product()` in more detail.\n", "\n", "While we needed to unpack `one_hundred` above to avoid the semantic error, unpacking an argument in a function call may also be a convenience in general.\n", "\n", @@ -6699,7 +6698,7 @@ "source": [ "We implicitly assume that the first element represents the $x$ and the second the $y$ coordinate. While that follows intuitively from convention in math, we should at least add comments somewhere in the code to document this assumption.\n", "\n", - "A better way is to create a *custom* data type. While that is covered in depth in Chapter 9, the [collections](https://docs.python.org/3/library/collections.html) module in the [standard library](https://docs.python.org/3/library/index.html) provides a [namedtuple()](https://docs.python.org/3/library/collections.html#collections.namedtuple) **factory function** that creates \"simple\" custom data types on top of the standard `tuple` type." + "A better way is to create a *custom* data type. While that is covered in depth in Chapter 10, the [collections](https://docs.python.org/3/library/collections.html) module in the [standard library](https://docs.python.org/3/library/index.html) provides a [namedtuple()](https://docs.python.org/3/library/collections.html#collections.namedtuple) **factory function** that creates \"simple\" custom data types on top of the standard `tuple` type." ] }, { @@ -6762,7 +6761,7 @@ { "data": { "text/plain": [ - "140157466523464" + "140416708056240" ] }, "execution_count": 238, @@ -6915,7 +6914,7 @@ { "data": { "text/plain": [ - "140157872590424" + "140417315422528" ] }, "execution_count": 243, @@ -7354,7 +7353,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 258, @@ -7654,7 +7653,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 269, @@ -7875,7 +7874,7 @@ } }, "source": [ - "Using the [map()](https://docs.python.org/3/library/functions.html#map) and [filter()](https://docs.python.org/3/library/functions.html#filter) built-ins, we can quickly switch the order: Filter first and then transform the remaining elements. This variant equals the \"*A simple Filter*\" example from [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Example:-A-simple-Filter). On the contrary, code with `for`-loops and `if` statements is more tedious to adapt. Additionally, `map` and `filter` objects are optimized at the C level and, therefore, a lot faster as well." + "Using the [map()](https://docs.python.org/3/library/functions.html#map) and [filter()](https://docs.python.org/3/library/functions.html#filter) built-ins, we can quickly switch the order: Filter first and then transform the remaining elements. This variant equals the \"*A simple Filter*\" example from [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#Example:-A-simple-Filter). On the contrary, code with `for`-loops and `if` statements is more tedious to adapt. Additionally, `map` and `filter` objects are optimized at the C level and, therefore, a lot faster as well." ] }, { @@ -8209,7 +8208,7 @@ "\n", "Often, such functions are used *only once* in a program. However, the primary purpose of functions is to *reuse* them. In such cases, it makes more sense to define them \"anonymously\" right at the position where the first argument goes.\n", "\n", - "As mentioned in [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions.ipynb#Anonymous-Functions), Python provides `lambda` expressions to create `function` objects *without* a name referencing them.\n", + "As mentioned in [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb#Anonymous-Functions), Python provides `lambda` expressions to create `function` objects *without* a name referencing them.\n", "\n", "So, the above `add()` function could be rewritten as a `lambda` expression like so ..." ] @@ -8423,7 +8422,7 @@ "source": [ "For [map()](https://docs.python.org/3/library/functions.html#map) and [filter()](https://docs.python.org/3/library/functions.html#filter), Python provides a nice syntax appealing to people who like mathematics.\n", "\n", - "Consider again the \"*A simple Filter*\" example from [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Example:-A-simple-Filter), written with combined `for` and `if` statements. So, the mapping and filtering steps happen simultaneously." + "Consider again the \"*A simple Filter*\" example from [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#Example:-A-simple-Filter), written with combined `for` and `if` statements. So, the mapping and filtering steps happen simultaneously." ] }, { @@ -8488,7 +8487,7 @@ } }, "source": [ - "**List comprehensions**, or **list-comps** for short, are *expressions* to derive *new* `list` objects out of *existing* ones (cf., [reference](https://docs.python.org/3/reference/expressions.html#displays-for-lists-sets-and-dictionaries)). A single *expression* like below can replace the compound `for` *statement* from above." + "**List comprehensions**, or **listcomps** for short, are *expressions* to derive *new* `list` objects out of *existing* ones (cf., [reference](https://docs.python.org/3/reference/expressions.html#displays-for-lists-sets-and-dictionaries)). A single *expression* like below can replace the compound `for` *statement* from above." ] }, { @@ -9108,7 +9107,7 @@ { "data": { "text/plain": [ - " at 0x7f790c3a55e8>" + " at 0x7fb57436f3d0>" ] }, "execution_count": 312, @@ -9263,7 +9262,7 @@ { "data": { "text/plain": [ - " at 0x7f790c3a5a20>" + " at 0x7fb57436f650>" ] }, "execution_count": 317, @@ -9728,7 +9727,7 @@ { "data": { "text/plain": [ - " at 0x7f790c3a5b10>" + " at 0x7fb57436fad0>" ] }, "execution_count": 333, @@ -10074,7 +10073,7 @@ } }, "source": [ - "[all()](https://docs.python.org/3/library/functions.html#all) can be viewed as syntactic sugar replacing a `for`-loop: Internally, [all()](https://docs.python.org/3/library/functions.html#all) implements the *short-circuiting* strategy from [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals.ipynb#Short-Circuiting), and we mimic that by testing for the *opposite* condition in the `if` statement and leaving the `for`-loop early with the `break` statement. In the worst case, if `threshold` were, for example, `150`, we would loop over *all* elements in the *iterable*, which must be *finite* for the code to work. So, [all()](https://docs.python.org/3/library/functions.html#all) is a *linear search* in disguise." + "[all()](https://docs.python.org/3/library/functions.html#all) can be viewed as syntactic sugar replacing a `for`-loop: Internally, [all()](https://docs.python.org/3/library/functions.html#all) implements the *short-circuiting* strategy from [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_content.ipynb#Short-Circuiting), and we mimic that by testing for the *opposite* condition in the `if` statement and leaving the `for`-loop early with the `break` statement. In the worst case, if `threshold` were, for example, `150`, we would loop over *all* elements in the *iterable*, which must be *finite* for the code to work. So, [all()](https://docs.python.org/3/library/functions.html#all) is a *linear search* in disguise." ] }, { @@ -10388,13 +10387,13 @@ } }, "source": [ - "With the new concepts in this chapter, let's rewrite the book's introductory \"*Averaging Even Numbers*\" example in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Example:-Averaging-Even-Numbers) such that it efficiently handles a large sequence of numbers.\n", + "With the new concepts in this chapter, let's rewrite the book's introductory \"*Averaging Even Numbers*\" example in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Example:-Averaging-Even-Numbers) such that it efficiently handles a large sequence of numbers.\n", "\n", "We assume the `average_evens()` function below is called with a *finite* and *iterable* object, which generates a \"stream\" of numeric objects that can be cast as `int` objects because the idea of even and odd numbers only makes sense in the context of whole numbers.\n", "\n", "The generator expression `(int(n) for n in numbers)` implements the type casting, and when it is evaluated, *nothing* happens except that a `generator` object is stored in `integers`. Then, with the [reduce()](https://docs.python.org/3/library/functools.html#functools.reduce) function from the [functools](https://docs.python.org/3/library/functools.html) module, we *simultaneously* add up *and* count the even numbers produced by the inner generator expression `((n, 1) for n in integers if n % 2 == 0)`. That results in a `generator` object producing `tuple` objects consisting of the next *even* number in line and `1`. Two such `tuple` objects are then iteratively passed to the `lambda` expression as the `x` and `y` arguments. `x` represents the total and the count of the even numbers processed so far, while `y`'s first element, `y[0]`, is the next even number to be added to the running total. The result of the [reduce()](https://docs.python.org/3/library/functools.html#functools.reduce) function is again a `tuple` object, namely the final `total` and `count`. Lastly, we calculate the simple average.\n", "\n", - "In summary, the implementation of `average_evens()` does *not* keep materialized `list` objects internally like its predecessors from [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions.ipynb), but processes the elements of the `numbers` argument on a one-by-one basis." + "In summary, the implementation of `average_evens()` does *not* keep materialized `list` objects internally like its predecessors from [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb), but processes the elements of the `numbers` argument on a one-by-one basis." ] }, { @@ -11014,7 +11013,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 375, @@ -11110,7 +11109,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 379, @@ -11318,7 +11317,7 @@ } }, "source": [ - "In [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#The-for-Statement), we argue that the `for` statement is syntactic sugar, replacing the `while` statement in many scenarios. In particular, a `for`-loop saves us two tasks: Managing an index variable *and* obtaining the individual elements by indexing. In this sub-section, we look at a more realistic picture, using the new terminology as well.\n", + "In [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#The-for-Statement), we argue that the `for` statement is syntactic sugar, replacing the `while` statement in many scenarios. In particular, a `for`-loop saves us two tasks: Managing an index variable *and* obtaining the individual elements by indexing. In this sub-section, we look at a more realistic picture, using the new terminology as well.\n", "\n", "Let's print out the elements of a `list` object as the *iterable* to be looped over." ] @@ -11460,7 +11459,7 @@ "source": [ "Now that we know the concept of an *iterator*, let's compare some of the built-ins introduced in this chapter in detail and make sure we understand what is going on in memory. This sub-section is thus a great summary of this chapter as well.\n", "\n", - "We use two simple examples, `numbers` and `memoryless`, to guide us through the discussion. `numbers` creates *thirteen* objects in memory and `memoryless` only *one* (cf., [PythonTutor](http://www.pythontutor.com/visualize.html#code=numbers%20%3D%20%5B7,%2011,%208,%205,%203,%2012,%202,%206,%209,%2010,%201,%204%5D%0Amemoryless%20%3D%20range%281,%2013%29&cumulative=false&curInstr=2&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false))" + "We use two simple examples, `numbers` and `memoryless`, to guide us through the discussion. `numbers` creates *thirteen* objects in memory and `memoryless` only *one* (cf., [PythonTutor](http://www.pythontutor.com/visualize.html#code=numbers%20%3D%20%5B7,%2011,%208,%205,%203,%2012,%202,%206,%209,%2010,%201,%204%5D%0Amemoryless%20%3D%20range%281,%2013%29&cumulative=false&curInstr=2&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false))." ] }, { @@ -11499,7 +11498,7 @@ "source": [ "The [sorted()](https://docs.python.org/3/library/functions.html#sorted) function takes a *finite* and *iterable* object as its argument and *materializes* its elements into a *new* `list` object that is returned.\n", "\n", - "The argument may already be materialized, as is the case with `numbers`, but could also be an *iterator* that generates *new* objects, such as `memoryless`. In both cases, we end up with materialized `list` objects with the elements sorted in *forward* order (cf., [PythonTutor](http://www.pythontutor.com/visualize.html#code=numbers%20%3D%20%5B7,%2011,%208,%205,%203,%2012,%202,%206,%209,%2010,%201,%204%5D%0Amemoryless%20%3D%20range%281,%2013%29%0Aresult1%20%3D%20sorted%28numbers%29%0Aresult2%20%3D%20sorted%28memoryless%29&cumulative=false&curInstr=4&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false))." + "The argument may already be materialized, as is the case with `numbers`, but may also be an *iterable* without any objects in it, such as `memoryless`. In both cases, we end up with materialized `list` objects with the elements sorted in *forward* order (cf., [PythonTutor](http://www.pythontutor.com/visualize.html#code=numbers%20%3D%20%5B7,%2011,%208,%205,%203,%2012,%202,%206,%209,%2010,%201,%204%5D%0Amemoryless%20%3D%20range%281,%2013%29%0Aresult1%20%3D%20sorted%28numbers%29%0Aresult2%20%3D%20sorted%28memoryless%29&cumulative=false&curInstr=4&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false))." ] }, { @@ -11693,7 +11692,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 397, @@ -11717,7 +11716,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 398, @@ -12216,7 +12215,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "livereveal": { "auto_select": "code", @@ -12244,5 +12243,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/07_sequences_10_review.ipynb b/07_sequences_10_review.ipynb new file mode 100644 index 0000000..a2d2f5c --- /dev/null +++ b/07_sequences_10_review.ipynb @@ -0,0 +1,397 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# Chapter 7: Sequential Data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Content Review" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb) of the book. Then, work through the questions below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Essay Questions " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Answer the following questions *briefly*!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1**: We have seen **containers** and **iterables** before in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#Containers-vs.-Iterables). How do they relate to **sequences**? " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q2**: What are **abstract base classes**? How can we make use of the ones from the [collections.abc](https://docs.python.org/3/library/collections.abc.html) module in the [standard library](https://docs.python.org/3/library/index.html)?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q3**: How are the *abstract behaviors* of **reversibility** and **finiteness** essential for *indexing* and *slicing* sequences?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q4**: Explain the difference between **mutable** and **immutable** objects in Python with the examples of the `list` and `tuple` types!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q5**: What is the difference between a **shallow** and a **deep** copy of an object? How can one of them become a \"problem?\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q6**: Many **list methods** change `list` objects \"**in place**.\" What do we mean by that?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q7.1**: `tuple` objects have *two* primary usages. First, they can be used in place of `list` objects where **mutability** is *not* required. Second, we use them to model data **records**.\n", + "\n", + "Describe why `tuple` objects are a suitable replacement for `list` objects in general!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q7.2**: What do we mean by a **record**? How are `tuple` objects suitable to model records? How can we integrate a **semantic meaning** when working with records into our code?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q8**: How is (iterable) **packing** and **unpacking** useful in the context of **function definitions** and **calls**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q9**: With the [map()](https://docs.python.org/3/library/functions.html#map) and [filter()](https://docs.python.org/3/library/functions.html#filter) built-ins and the [reduce()](https://docs.python.org/3/library/functools.html#functools.reduce) function from the [functools](https://docs.python.org/3/library/functools.html) module in the [standard library](https://docs.python.org/3/library/index.html), we can replace many tedious `for`-loops and `if` statements. What are some advantages of doing so?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q10**: Looking at the `lambda` expression inside [reduce()](https://docs.python.org/3/library/functools.html#functools.reduce) below, what \"simple\" [built-in function](https://docs.python.org/3/library/functions.html) is mimicked here?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```python\n", + "from functools import reduce\n", + "\n", + "numbers = [7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]\n", + "\n", + "reduce(lambda x, y: x if x > y else y, numbers)\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q11**: What is the primary use case of **list comprehensions**? Why do we describe them as **eager**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q12**: **Generator expressions** may replace `list` objects and list comprehensions in many scenarios. When evaluated, they create a **lazy** `generator` object that does *not* **materialize** its elements right away. What do we mean by that? What does it mean for a `generator` object to be **exhausted**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q13**: What does it mean for the **boolean reducers**, the built-in [all()](https://docs.python.org/3/library/functions.html#all) and [any()](https://docs.python.org/3/library/functions.html#any) functions, to follow the **short-circuiting** strategy?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q14**: What is an **iterator**? How does it relate to an **iterable**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### True / False Questions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Motivate your answer with *one short* sentence!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q15**: `sequence` objects are *not* part of core Python but may be imported from the [standard library](https://docs.python.org/3/library/index.html)." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q16**: The built-in [sort()](https://docs.python.org/3/library/stdtypes.html#list.sort) function takes a *finite* **iterable** as its argument an returns a *new* `list` object. On the contrary, the [sorted()](https://docs.python.org/3/library/functions.html#sorted) method on `list` objects *mutates* them *in place*." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q17**: Passing **mutable** objects as arguments to functions is not problematic because functions operate in a **local** scope without affecting the **global** scope." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q18**: `lambda` expressions are useful in the context of the **map-filter-reduce** paradigm, where we often do *not* re-use a `function` object more than once." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q19**: Using **generator expressions** in place of **list comprehensions** wherever possible is a good practice as it makes our programs use memory more efficiently." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q20**: Just as **list comprehensions** create `list` objects, **tuple comprehensions** create `tuple` objects." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": true, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": false, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/07_sequences_review_and_exercises.ipynb b/07_sequences_20_exercises.ipynb similarity index 70% rename from 07_sequences_review_and_exercises.ipynb rename to 07_sequences_20_exercises.ipynb index 68582b2..b2a8169 100644 --- a/07_sequences_review_and_exercises.ipynb +++ b/07_sequences_20_exercises.ipynb @@ -8,357 +8,6 @@ "# Chapter 7: Sequential Data" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Content Review" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Read [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb) of the book. Then work through the twenty review questions." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Essay Questions " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Answer the following questions briefly with *at most* 300 characters per question!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q1**: We have seen **containers** and **iterables** before in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Containers-vs.-Iterables). How do they relate to **sequences**? " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q2**: What are **abstract base classes**? How can we make use of the ones from the [collections.abc](https://docs.python.org/3/library/collections.abc.html) module in the [standard library](https://docs.python.org/3/library/index.html)?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q3**: How are the *abstract behaviors* of **reversibility** and **finiteness** essential for *indexing* and *slicing* sequences?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q4**: Explain the difference between **mutable** and **immutable** objects in Python with the examples of the `list` and `tuple` types!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q5**: What is the difference between a **shallow** and a **deep** copy of an object? How can one of them become a \"problem?\"" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q6**: Many **list methods** change `list` objects \"**in place**.\" What do we mean by that?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q7.1**: `tuple` objects have *two* primary usages. First, they can be used in place of `list` objects where **mutability** is *not* required. Second, we use them to model data **records**.\n", - "\n", - "Describe why `tuple` objects are a suitable replacement for `list` objects in general!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q7.2**: What do we mean by a **record**? How are `tuple` objects suitable to model records? How can we integrate a **semantic meaning** when working with records into our code?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q8**: How is (iterable) **packing** and **unpacking** useful in the context of **function definitions** and **calls**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q9**: With the [map()](https://docs.python.org/3/library/functions.html#map) and [filter()](https://docs.python.org/3/library/functions.html#filter) built-ins and the [reduce()](https://docs.python.org/3/library/functools.html#functools.reduce) function from the [functools](https://docs.python.org/3/library/functools.html) module in the [standard library](https://docs.python.org/3/library/index.html), we can replace many tedious `for`-loops and `if` statements. What are some advantages of doing so?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q10**: Looking at the `lambda` expression inside [reduce()](https://docs.python.org/3/library/functools.html#functools.reduce) below, what \"simple\" [built-in function](https://docs.python.org/3/library/functions.html) is mimicked here?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```python\n", - "from functools import reduce\n", - "\n", - "numbers = [7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]\n", - "\n", - "reduce(lambda x, y: x if x > y else y, numbers)\n", - "```" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11**: What is the primary use case of **list comprehensions**? Why do we describe them as **eager**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q12**: **Generator expressions** may replace `list` objects and list comprehensions in many scenarios. When evaluated, they create a **lazy** `generator` object that does *not* **materialize** its elements right away. What do we mean by that? What does it mean for a `generator` object to be **exhausted**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q13**: What does it mean for the **boolean reducers**, the built-in [all()](https://docs.python.org/3/library/functions.html#all) and [any()](https://docs.python.org/3/library/functions.html#any) functions, to follow the **short-circuiting** strategy?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q14**: What is an **iterator**? How does it relate to an **iterable**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### True / False Questions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Motivate your answer with *one short* sentence!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q15**: `sequence` objects are *not* part of core Python but may be imported from the [standard library](https://docs.python.org/3/library/index.html)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q16**: The built-in [sort()](https://docs.python.org/3/library/stdtypes.html#list.sort) function takes a *finite* **iterable** as its argument an returns a *new* `list` object. On the contrary, the [sorted()](https://docs.python.org/3/library/functions.html#sorted) method on `list` objects *mutates* them *in place*." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q17**: Passing **mutable** objects as arguments to functions is not problematic because functions operate in a **local** scope without affecting the **global** scope." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q18**: `lambda` expressions are useful in the context of the **map-filter-reduce** paradigm, where we often do *not* re-use a `function` object more than once." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q19**: Using **generator expressions** in place of **list comprehensions** wherever possible is a good practice as it makes our programs use memory more efficiently." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q20**: Just as **list comprehensions** create `list` objects, **tuple comprehensions** create `tuple` objects." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -366,6 +15,13 @@ "## Coding Exercises" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb) of the book. Then, work through the exercises below." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -377,7 +33,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q21.1**: Write a function `nested_sum()` that takes a `list` object as its argument, which contains other `list` objects with numbers, and adds up the numbers! Use `nested_numbers` below to test your function!\n", + "**Q1.1**: Write a function `nested_sum()` that takes a `list` object as its argument, which contains other `list` objects with numbers, and adds up the numbers! Use `nested_numbers` below to test your function!\n", "\n", "Hint: You need at least one `for`-loop." ] @@ -414,7 +70,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q21.2**: Provide a one-line expression to obtain the *same* result as `nested_sum()`!\n", + "**Q1.2**: Provide a one-line expression to obtain the *same* result as `nested_sum()`!\n", "\n", "Hints: Use a *list comprehension*, or maybe even a *generator expression*. You may want to use the built-in [sum()](https://docs.python.org/3/library/functions.html#sum) function several times." ] @@ -432,9 +88,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q21.3**: Generalize `nested_sum()` into a function `mixed_sum()` that can process a \"mixed\" `list` object, which contains numbers and other `list` objects with numbers! Use `mixed_numbers` below for testing!\n", + "**Q1.3**: Generalize `nested_sum()` into a function `mixed_sum()` that can process a \"mixed\" `list` object, which contains numbers and other `list` objects with numbers! Use `mixed_numbers` below for testing!\n", "\n", - "Hints: Use the built-in [isinstance()](https://docs.python.org/3/library/functions.html#isinstance) function to check how an element is to be processed. Get extra credit for adhering to *goose typing*, as explained in [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers.ipynb#Goose-Typing)." + "Hints: Use the built-in [isinstance()](https://docs.python.org/3/library/functions.html#isinstance) function to check how an element is to be processed. Get extra credit for adhering to *goose typing*, as explained in [Chapter 5](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_00_content.ipynb#Goose-Typing)." ] }, { @@ -478,7 +134,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q21.4.1**: Write a function `cum_sum()` that takes a `list` object with numbers as its argument and returns a *new* `list` object with the **cumulative sums** of these numbers! So, `sum_up` below, `[1, 2, 3, 4, 5]`, should return `[1, 3, 6, 10, 15]`.\n", + "**Q1.4.1**: Write a function `cum_sum()` that takes a `list` object with numbers as its argument and returns a *new* `list` object with the **cumulative sums** of these numbers! So, `sum_up` below, `[1, 2, 3, 4, 5]`, should return `[1, 3, 6, 10, 15]`.\n", "\n", "Hint: The idea behind is similar to the [cumulative distribution function](https://en.wikipedia.org/wiki/Cumulative_distribution_function) from statistics." ] @@ -515,7 +171,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q21.4.2**: We should always make sure that our functions also work in corner cases. What happens if your implementation of `cum_sum()` is called with an empty list `[]`? Make sure it handles that case *without* crashing! What would be a good return value in this corner case? Describe everything in the docstring.\n", + "**Q1.4.2**: We should always make sure that our functions also work in corner cases. What happens if your implementation of `cum_sum()` is called with an empty list `[]`? Make sure it handles that case *without* crashing! What would be a good return value in this corner case? Describe everything in the docstring.\n", "\n", "Hint: It is possible to write this without any extra input validation." ] @@ -540,7 +196,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "In the \"*Function Definitions & Calls*\" section in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#Function-Definitions-&-Calls), we define the following function `product()`. In this exercise, you will improve it by making it more \"user-friendly.\"" + "In the \"*Function Definitions & Calls*\" section in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#Function-Definitions-&-Calls), we define the following function `product()`. In this exercise, you will improve it by making it more \"user-friendly.\"" ] }, { @@ -565,7 +221,7 @@ "source": [ "The `*` in the function's header line *packs* all *positional* arguments passed to `product()` into one *iterable* called `args`.\n", "\n", - "**Q22.1**: What is the data type of `args` within the function's body?" + "**Q2.1**: What is the data type of `args` within the function's body?" ] }, { @@ -620,7 +276,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q22.2**: What line in the body of `product()` causes this exception? What is the exact problem?" + "**Q2.2**: What line in the body of `product()` causes this exception? What is the exact problem?" ] }, { @@ -634,7 +290,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "In [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#Function-Definitions-&-Calls), we also pass a `list` object, like `one_hundred`, to `product()`, and *no* exception is raised." + "In [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#Function-Definitions-&-Calls), we also pass a `list` object, like `one_hundred`, to `product()`, and *no* exception is raised." ] }, { @@ -659,7 +315,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q22.3**: What is wrong with that? What *kind* of error (cf., [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Formal-vs.-Natural-Languages)) is that conceptually? Describe precisely what happens to the passed in `one_hundred` in every line within `product()`!" + "**Q2.3**: What is wrong with that? What *kind* of error (cf., [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Formal-vs.-Natural-Languages)) is that conceptually? Describe precisely what happens to the passed in `one_hundred` in every line within `product()`!" ] }, { @@ -723,7 +379,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q22.4**: Describe why no error occurs by going over every line in `product()`!" + "**Q2.4**: Describe why no error occurs by going over every line in `product()`!" ] }, { @@ -762,7 +418,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q22.5**: What line causes troubles now? What is the exact problem?" + "**Q2.5**: What line causes troubles now? What is the exact problem?" ] }, { @@ -776,7 +432,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q22.6**: Replace the `None` in `product()` above with something reasonable that does *not* cause exceptions! Ensure that `product(42)` and `product(2, 5, 10)` return a correct result.\n", + "**Q2.6**: Replace the `None` in `product()` above with something reasonable that does *not* cause exceptions! Ensure that `product(42)` and `product(2, 5, 10)` return a correct result.\n", "\n", "Hints: It is ok if `product()` returns a result *different* from the `None` above. Look at the documentation of the built-in [sum()](https://docs.python.org/3/library/functions.html#sum) function for some inspiration." ] @@ -835,9 +491,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q22.7**: Rewrite `product()` so that it takes a *keyword-only* argument `start`, defaulting to the above *default* or *start* value, and use `start` internally instead of `result`!\n", + "**Q2.7**: Rewrite `product()` so that it takes a *keyword-only* argument `start`, defaulting to the above *default* or *start* value, and use `start` internally instead of `result`!\n", "\n", - "Hint: Remember that a *keyword-only* argument is any parameter specified in a function's header line after the first (and only) `*` (cf., [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions.ipynb#Keyword-only-Arguments))." + "Hint: Remember that a *keyword-only* argument is any parameter specified in a function's header line after the first (and only) `*` (cf., [Chapter 2](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb#Keyword-only-Arguments))." ] }, { @@ -946,7 +602,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q22.8**: What is a **collection**? How is that different from a **sequence**?" + "**Q2.8**: What is a **collection**? How is that different from a **sequence**?" ] }, { @@ -960,7 +616,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q22.9**: Rewrite the latest version of `product()` to check if the *only* positional argument is a *collection* type! If so, its elements are multiplied together. Otherwise, the logic remains the same.\n", + "**Q2.9**: Rewrite the latest version of `product()` to check if the *only* positional argument is a *collection* type! If so, its elements are multiplied together. Otherwise, the logic remains the same.\n", "\n", "Hints: Use the built-in [len()](https://docs.python.org/3/library/functions.html#len) and [isinstance()](https://docs.python.org/3/library/functions.html#isinstance) functions to check if there is only *one* positional argument and if it is a *collection* type. Use the *abstract base class* `Collection` from the [collections.abc](https://docs.python.org/3/library/collections.abc.html) module in the [standard library](https://docs.python.org/3/library/index.html). You may want to *re-assign* `args` inside the body." ] @@ -1041,7 +697,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Side Note**: Above, we make `product()` work with a single *collection* type argument instead of a *sequence* type to keep it more generic: For example, we can pass in a `set` object, like `{2, 5, 10}` below, and `product()` continues to work correctly. The `set` type is introducted in [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings.ipynb#The-set-Type), and one essential difference to the `list` type is that objects of type `set` have *no* order regarding their elements. So, even though `[2, 5, 10]` and `{2, 5, 10}` look almost the same, the order implied in the literal notation gets lost in memory!" + "**Side Note**: Above, we make `product()` work with a single *collection* type argument instead of a *sequence* type to keep it more generic: For example, we can pass in a `set` object, like `{2, 5, 10}` below, and `product()` continues to work correctly. The `set` type is introducted in [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_00_content.ipynb#The-set-Type), and one essential difference to the `list` type is that objects of type `set` have *no* order regarding their elements. So, even though `[2, 5, 10]` and `{2, 5, 10}` look almost the same, the order implied in the literal notation gets lost in memory!" ] }, { @@ -1091,7 +747,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q22.10**: Adapt the latest version of `product()` to also raise a `TypeError` if called *without* any *positional* arguments!" + "**Q2.10**: Adapt the latest version of `product()` to also raise a `TypeError` if called *without* any *positional* arguments!" ] }, { @@ -1279,7 +935,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q22.11**: What line causes the `TypeError`? What line is really the problem in the latest implementation of `product()`? Describe what happens on each line in the function's body until the exception is raised!" + "**Q2.11**: What line causes the `TypeError`? What line is really the problem in the latest implementation of `product()`? Describe what happens on each line in the function's body until the exception is raised!" ] }, { @@ -1293,7 +949,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q22.12**: Adapt `product()` one last time to make it work with *iterators* as well!\n", + "**Q2.12**: Adapt `product()` one last time to make it work with *iterators* as well!\n", "\n", "Hints: This task is as easy as replacing `Collection` with something else. Which of the three behaviors of *collections* do *iterators* also exhibit? You may want to look at the documentations on the built-in [max()](https://docs.python.org/3/library/functions.html#max), [min()](https://docs.python.org/3/library/functions.html#min), and [sum()](https://docs.python.org/3/library/functions.html#sum) functions: What kind of argument do they take?" ] @@ -1442,7 +1098,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.1**: `list` objects are **sequences**. What *four* behaviors do they always come with?" + "**Q3.1**: `list` objects are **sequences**. What *four* behaviors do they always come with?" ] }, { @@ -1456,7 +1112,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.2**: Write a function `mean()` that calculates the simple arithmetic mean of a given `sequence` with numbers!\n", + "**Q3.2**: Write a function `mean()` that calculates the simple arithmetic mean of a given `sequence` with numbers!\n", "\n", "Hints: You can solve this task with [built-in functions](https://docs.python.org/3/library/functions.html) only. A `for`-loop is *not* needed." ] @@ -1493,7 +1149,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.3**: Write a function `std()` that calculates the [standard deviation](https://en.wikipedia.org/wiki/Standard_deviation) of a `sequence` of numbers! Integrate your `mean()` version from before and the [sqrt()](https://docs.python.org/3/library/math.html#math.sqrt) function from the [math](https://docs.python.org/3/library/math.html) module in the [standard library](https://docs.python.org/3/library/index.html) provided to you below. Make sure `std()` calls `mean()` only *once* internally! Repeated calls to `mean()` would be a waste of computational resources.\n", + "**Q3.3**: Write a function `std()` that calculates the [standard deviation](https://en.wikipedia.org/wiki/Standard_deviation) of a `sequence` of numbers! Integrate your `mean()` version from before and the [sqrt()](https://docs.python.org/3/library/math.html#math.sqrt) function from the [math](https://docs.python.org/3/library/math.html) module in the [standard library](https://docs.python.org/3/library/index.html) provided to you below. Make sure `std()` calls `mean()` only *once* internally! Repeated calls to `mean()` would be a waste of computational resources.\n", "\n", "Hints: Parts of the code are probably too long to fit within the suggested 79 characters per line. So, use *temporary variables* inside your function. Instead of a `for`-loop, you may want to use a *list comprehension* or, even better, a memoryless *generator expression*." ] @@ -1539,7 +1195,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.4**: Complete `standardize()` below that takes a `sequence` of numbers and returns a `list` object with the **[z-scores](https://en.wikipedia.org/wiki/Standard_score)** of these numbers! A z-score is calculated by subtracting the mean and dividing by the standard deviation. Re-use `mean()` and `std()` from before. Again, ensure that `standardize()` calls `mean()` and `std()` only *once*! Further, round all z-scores with the built-in [round()](https://docs.python.org/3/library/functions.html#round) function and pass on the keyword-only argument `digits` to it.\n", + "**Q3.4**: Complete `standardize()` below that takes a `sequence` of numbers and returns a `list` object with the **[z-scores](https://en.wikipedia.org/wiki/Standard_score)** of these numbers! A z-score is calculated by subtracting the mean and dividing by the standard deviation. Re-use `mean()` and `std()` from before. Again, ensure that `standardize()` calls `mean()` and `std()` only *once*! Further, round all z-scores with the built-in [round()](https://docs.python.org/3/library/functions.html#round) function and pass on the keyword-only argument `digits` to it.\n", "\n", "Hint: You may want to use a *list comprehension* instead of a `for`-loop." ] @@ -1610,7 +1266,7 @@ "source": [ "Even though `standardize()` calls `mean()` and `std()` only once each, `mean()` is called *twice*! That is so because `std()` internally also re-uses `mean()`!\n", "\n", - "**Q23.5.1**: Rewrite `std()` to take an optional keyword-only argument `seq_mean`, defaulting to `None`. If provided, `seq_mean` is used instead of the result of calling `mean()`. Otherwise, the latter is called.\n", + "**Q3.5.1**: Rewrite `std()` to take an optional keyword-only argument `seq_mean`, defaulting to `None`. If provided, `seq_mean` is used instead of the result of calling `mean()`. Otherwise, the latter is called.\n", "\n", "Hint: You must check if `seq_mean` is still the default value." ] @@ -1654,7 +1310,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.5.2**: Now, rewrite `standardize()` to pass on the return value of `mean()` to `std()`! In summary, `standardize()` calculates the z-scores for the numbers in the `sequence` with as few computational steps as possible." + "**Q3.5.2**: Now, rewrite `standardize()` to pass on the return value of `mean()` to `std()`! In summary, `standardize()` calculates the z-scores for the numbers in the `sequence` with as few computational steps as possible." ] }, { @@ -1689,7 +1345,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.6**: With both `sample` and `z_scores` being materialized `list` objects, we can loop over pairs consisting of a number from `sample` and its corresponding z-score. Write a `for`-loop that prints out all the \"outliers,\" as which we define numbers with an absolute z-score above `1.96`. There are *four* of them in the `sample`.\n", + "**Q3.6**: With both `sample` and `z_scores` being materialized `list` objects, we can loop over pairs consisting of a number from `sample` and its corresponding z-score. Write a `for`-loop that prints out all the \"outliers,\" as which we define numbers with an absolute z-score above `1.96`. There are *four* of them in the `sample`.\n", "\n", "Hint: Use the [abs()](https://docs.python.org/3/library/functions.html#abs) and [zip()](https://docs.python.org/3/library/functions.html#zip) built-ins." ] @@ -1798,7 +1454,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.7**: What happens if you call `mean()` with `data` as the argument? What is the problem?\n", + "**Q3.7**: What happens if you call `mean()` with `data` as the argument? What is the problem?\n", "\n", "Hints: If you try it out, you may have to press the \"Stop\" button in the toolbar at the top. Your computer should *not* crash, but you will *have to* restart this Jupyter notebook with \"Kernel\" > \"Restart\" and import `data` again." ] @@ -1823,7 +1479,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.8**: Write a function `take_sample()` that takes an `iterator` as its argument, like `data`, and creates a *materialized* `list` object out of its first `n` elements, defaulting to `1_000`!\n", + "**Q3.8**: Write a function `take_sample()` that takes an `iterator` as its argument, like `data`, and creates a *materialized* `list` object out of its first `n` elements, defaulting to `1_000`!\n", "\n", "Hints: [next()](https://docs.python.org/3/library/functions.html#next) and the [range()](https://docs.python.org/3/library/functions.html#func-range) built-in may be helpful. You may want to use a *list comprehension* instead of a `for`-loop and write a one-liner. Audacious students may want to look at [isclice()](https://docs.python.org/3/library/itertools.html#itertools.islice) in the [itertools](https://docs.python.org/3/library/itertools.html) module in the [standard library](https://docs.python.org/3/library/index.html)." ] @@ -1885,7 +1541,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.9**: Convert `standardize()` into a *new* function `standardized()` that implements the *same* logic but works on a possibly *infinite* stream of data, provided as an `iterable`, instead of a *finite* `sequence`.\n", + "**Q3.9**: Convert `standardize()` into a *new* function `standardized()` that implements the *same* logic but works on a possibly *infinite* stream of data, provided as an `iterable`, instead of a *finite* `sequence`.\n", "\n", "To calculate a z-score, we need the stream's overall mean and standard deviation, and that is *impossible* to calculate if we do not know how long the stream is, and, in particular, if it is *infinite*. So, `standardized()` first takes a sample from the `iterable` internally, and uses the sample's mean and standard deviation to calculate the z-scores.\n", "\n", @@ -1949,7 +1605,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.10.1**: `standardized()` allows us to go over an *infinite* stream of z-scores. What we want to do instead is to loop over the stream's raw numbers and skip the outliers. In the remainder of this exercise, you look at the parts that make up the `skip_outliers()` function below to achieve precisely that.\n", + "**Q3.10.1**: `standardized()` allows us to go over an *infinite* stream of z-scores. What we want to do instead is to loop over the stream's raw numbers and skip the outliers. In the remainder of this exercise, you look at the parts that make up the `skip_outliers()` function below to achieve precisely that.\n", "\n", "The first steps in `skip_outliers()` are the same as in `standardized()`: We take a `sample` from the stream of `data` and calculate its statistics." ] @@ -1969,9 +1625,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.10.2**: Just as in `standardized()`, write a *generator expression* that produces z-scores one by one! However, instead of just generating a z-score, the resulting `generator` object should produce `tuple` objects consisting of a \"raw\" number from `data` and its z-score.\n", + "**Q3.10.2**: Just as in `standardized()`, write a *generator expression* that produces z-scores one by one! However, instead of just generating a z-score, the resulting `generator` object should produce `tuple` objects consisting of a \"raw\" number from `data` and its z-score.\n", "\n", - "Hint: Look at the revisited \"*Averaging Even Numbers*\" example in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#Example:-Averaging-Even-Numbers-%28revisited%29) for some inspiration, which also contains a generator expression producing `tuple` objects." + "Hint: Look at the revisited \"*Averaging Even Numbers*\" example in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#Example:-Averaging-Even-Numbers-%28revisited%29) for some inspiration, which also contains a generator expression producing `tuple` objects." ] }, { @@ -2003,7 +1659,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.10.3**: Write another generator expression that loops over `standardizer`. It contains an `if`-clause that keeps only numbers with an absolute z-score below the `threshold_z`. If you fancy, use *tuple unpacking*." + "**Q3.10.3**: Write another generator expression that loops over `standardizer`. It contains an `if`-clause that keeps only numbers with an absolute z-score below the `threshold_z`. If you fancy, use *tuple unpacking*." ] }, { @@ -2044,7 +1700,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.10.4**: Lastly, put everything together in the `skip_outliers()` function! Make sure you refer to `iterable` inside the function and not the global `data`." + "**Q3.10.4**: Lastly, put everything together in the `skip_outliers()` function! Make sure you refer to `iterable` inside the function and not the global `data`." ] }, { @@ -2109,7 +1765,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q23.11**: You implemented the functions `mean()`, `std()`, `standardize()`, `standardized()`, and `skip_outliers()`. Which of them are **eager**, and which are **lazy**? How do these two concepts relate to **finite** and **infinite** data?" + "**Q3.11**: You implemented the functions `mean()`, `std()`, `standardize()`, `standardized()`, and `skip_outliers()`. Which of them are **eager**, and which are **lazy**? How do these two concepts relate to **finite** and **infinite** data?" ] }, { @@ -2136,7 +1792,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "toc": { "base_numbering": 1, @@ -2153,5 +1809,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/08_mappings.ipynb b/08_mappings_00_content.ipynb similarity index 96% rename from 08_mappings.ipynb rename to 08_mappings_00_content.ipynb index d42237b..2e19dbe 100644 --- a/08_mappings.ipynb +++ b/08_mappings_00_content.ipynb @@ -19,9 +19,9 @@ } }, "source": [ - "While [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb) focuses on one special kind of *collection* types, namely *sequences*, this chapter introduces two more: **Mappings** and **sets**. We present the data types belonging to these two groups in one chapter as they share the *same* underlying implementation at the C Level, known as **[hash tables](https://en.wikipedia.org/wiki/Hash_table)**.\n", + "While [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb) focuses on one special kind of *collection* types, namely *sequences*, this chapter introduces two more kinds: **Mappings** and **sets**. We present the data types belonging to these two groups in one chapter as they share the *same* underlying implementation at the C Level, known as **[hash tables](https://en.wikipedia.org/wiki/Hash_table)**.\n", "\n", - "The most important mapping type in this chapter is the `dict` type that we have not yet seen before (cf, [documentation](https://docs.python.org/3/library/stdtypes.html#dict)). It is an essential part in a data science practitioner's toolbox for two reasons: First, Python employs `dict` objects basically \"everywhere\" internally. So, we must understand how they work to become better at Python in general. Second, after the many concepts related to *sequential* data, the ideas behind *mappings* enhance our general problem solving skills. As a concrete example, we look at the concept of **memoization** to complete our picture of *recursion*, as depicted in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Recursion). We end this chapter with a discussion of *set* types." + "The most important mapping type in this chapter is the `dict` type that we have not yet seen before (cf, [documentation](https://docs.python.org/3/library/stdtypes.html#dict)). It is an essential part in a data science practitioner's toolbox for two reasons: First, Python employs `dict` objects basically \"everywhere\" internally. So, we must understand how they work to become better at Python in general. Second, after the many concepts related to *sequential* data, the ideas behind *mappings* enhance our general problem solving skills. As a concrete example, we look at the concept of **memoization** to complete our picture of *recursion*, as depicted in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#Recursion). We end this chapter with a discussion of *set* types." ] }, { @@ -45,7 +45,7 @@ "source": [ "A *mapping* is a one-to-one correspondence from a set of **keys** to a set of **values**. In other words, a *mapping* is a *collection* of **key-value pairs**, also called **items** for short.\n", "\n", - "In the context of mappings, the term *value* has a meaning different from the general *value* that *every* object has: In the \"bag\" analogy from [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Value), we descibe an object's value to be the concrete $0$s and $1$s it contains. Here, the terms *key* and *value* mean the *role* an object takes within a mapping. Both, *keys* and *values*, are real *objects* with a distinct *value*. So, the student should always remember the double meaning of the term *value* in this chapter!\n", + "In the context of mappings, the term *value* has a meaning different from the general *value* that *every* object has: In the \"bag\" analogy from [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Value), we descibe an object's value to be the concrete $0$s and $1$s it contains. Here, the terms *key* and *value* mean the *role* an object takes within a mapping. Both, *keys* and *values*, are real *objects* with a distinct *value*. So, the student should always remember the double meaning of the term *value* in this chapter!\n", "\n", "Let's continue with an example. To create a `dict` object, we commonly use the literal notation, `{..: .., ..: .., ...}`, and list all the items. `to_words` below maps the `int` objects `0`, `1`, and `2` to their English word equivalents, `\"zero\"`, `\"one\"`, and `\"two\"`, and `from_words` does the opposite. A stylistic side note: Pythonistas often expand `dict` or `list` definitions by writing each item or element on a line on their own. The commas `,` after the *last* items are *not* a mistake, as well, although they *may* be left out. Besides easier reading, such style has actual technical advantages (cf., [source](https://www.python.org/dev/peps/pep-0008/#when-to-use-trailing-commas)) that we do not go into detail about here." ] @@ -107,7 +107,7 @@ { "data": { "text/plain": [ - "139752734794304" + "139953979690352" ] }, "execution_count": 3, @@ -502,7 +502,7 @@ } }, "source": [ - "In [Chapter 0](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up.ipynb#Isn't-C-a-lot-faster?), we argue that a major advantage of using Python is that it takes care of the memory managment for us. In line with that, we have never talked about the C level implementation thus far in the book. However, the `dict` type, among others, exhibits some behaviors that may seem \"weird\" for a beginner. To built a solid intuition that enables the student to better \"predict\" how `dict` objects behave, we describe the underlying implementation details on a conceptual level (i.e., without C code).\n", + "In [Chapter 0](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up_00_content.ipynb#Isn't-C-a-lot-faster?), we argue that a major advantage of using Python is that it takes care of the memory managment for us. In line with that, we have never talked about the C level implementation thus far in the book. However, the `dict` type, among others, exhibits some behaviors that may seem \"weird\" for a beginner. To built a solid intuition that enables the student to better \"predict\" how `dict` objects behave, we describe the underlying implementation details on a conceptual level (i.e., without C code).\n", "\n", "The first unintuitive behavior is that we may *not* use a *mutable* object as a key. That results in a `TypeError`." ] @@ -597,10 +597,10 @@ } }, "source": [ - "| Bucket | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |\n", - "| :---: |:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n", - "| Key |*...*|*...*|*...*|*...*|*...*|*...*|*...*|*...*|\n", - "| Value |*...*|*...*|*...*|*...*|*...*|*...*|*...*|*...*|" + "| Bucket | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |\n", + "| :---: |:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n", + "| **Key** |*...*|*...*|*...*|*...*|*...*|*...*|*...*|*...*|\n", + "|**Value**|*...*|*...*|*...*|*...*|*...*|*...*|*...*|*...*|" ] }, { @@ -628,7 +628,7 @@ { "data": { "text/plain": [ - "-2242252796476499076" + "-1033934764475250610" ] }, "execution_count": 17, @@ -707,7 +707,7 @@ } }, "source": [ - "The [glossary](https://docs.python.org/3/glossary.html#term-hashable) states a second requirement for hashability, namely that \"objects which *compare equal* must have the *same* hash value.\" The purpose of this is to ensure that if we put, for example, `1` as a key in a `dict` object, we can look it up later with `1.0`. In other words, we can look up keys by their object's value (i.e., in the meaning of [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Value)). The converse statement does *not* hold: Two objects *may* (accidentally) have the *same* hash value and *not* compare equal." + "The [glossary](https://docs.python.org/3/glossary.html#term-hashable) states a second requirement for hashability, namely that \"objects which *compare equal* must have the *same* hash value.\" The purpose of this is to ensure that if we put, for example, `1` as a key in a `dict` object, we can look it up later with `1.0`. In other words, we can look up keys by their object's value (i.e., in the meaning of [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb#Value)). The converse statement does *not* hold: Two objects *may* (accidentally) have the *same* hash value and *not* compare equal." ] }, { @@ -951,12 +951,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "zero\t-2242252796476499076\t0b...010010000100\t100\t4\n", - "one\t6742734203392562231\t0b...010000110111\t111\t7\n", - "two\t8400825950927958036\t0b...000000010100\t100\t4\n", - "three\t-7473701886709619306\t0b...101001101010\t010\t2\n", - "four\t5854090567539607813\t0b...100100000101\t101\t5\n", - "five\t5010767421024509913\t0b...111111011001\t001\t1\n" + "zero\t-1033934764475250610\t0b...011110110010\t010\t2\n", + "one\t-3496683303036773129\t0b...001100001001\t001\t1\n", + "two\t-4468022785493412346\t0b...100111111010\t010\t2\n", + "three\t1491334499222274950\t0b...001110000110\t110\t6\n", + "four\t490235692124377396\t0b...000100110100\t100\t4\n", + "five\t-550474145318920636\t0b...000110111100\t100\t4\n" ] } ], @@ -983,10 +983,10 @@ } }, "source": [ - "| Bucket | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |\n", - "| :---: | :---: |:---:| :---: | :---: |:---:| :---: |:---:| :---: |\n", - "| Key |`\"one\"`|*...*|`\"two\"`|`\"four\"`|*...*|`\"three\"`|*...*|`\"zero\"`|\n", - "| Value | `1` |*...*| `2` | `4` |*...*| `3` |*...*| `0` |" + "| Bucket | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |\n", + "| :---: | :---: |:---:| :---: | :---: |:---:| :---: |:---:| :---: |\n", + "| **Key** |`\"one\"`|*...*|`\"two\"`|`\"four\"`|*...*|`\"three\"`|*...*|`\"zero\"`|\n", + "|**Value**| `1` |*...*| `2` | `4` |*...*| `3` |*...*| `0` |" ] }, { @@ -1008,10 +1008,10 @@ } }, "source": [ - "| Bucket | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |\n", - "| :---: | :---: |:---:|:---:|:---:|:---:|:---:|:---:| :---: |:---:|:---:| :---: | :---: |:---:| :---: |:---:| :---: |\n", - "| Key |`\"one\"`|*...*|*...*|*...*|*...*|*...*|*...*|`\"five\"`|*...*|*...*|`\"two\"`|`\"four\"`|*...*|`\"three\"`|*...*|`\"zero\"`|\n", - "| Value | `1` |*...*|*...*|*...*|*...*|*...*|*...*| `5` |*...*|*...*| `2` | `4` |*...*| `3` |*...*| `0` |" + "| Bucket | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |\n", + "| :---: | :---: |:---:|:---:|:---:|:---:|:---:|:---:| :---: |:---:|:---:| :---: | :---: |:---:| :---: |:---:| :---: |\n", + "| **Key** |`\"one\"`|*...*|*...*|*...*|*...*|*...*|*...*|`\"five\"`|*...*|*...*|`\"two\"`|`\"four\"`|*...*|`\"three\"`|*...*|`\"zero\"`|\n", + "|**Value**| `1` |*...*|*...*|*...*|*...*|*...*|*...*| `5` |*...*|*...*| `2` | `4` |*...*| `3` |*...*| `0` |" ] }, { @@ -1038,12 +1038,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "zero\t-2242252796476499076\t0b...010010000100\t0100\t4\n", - "one\t6742734203392562231\t0b...010000110111\t0111\t7\n", - "two\t8400825950927958036\t0b...000000010100\t0100\t4\n", - "three\t-7473701886709619306\t0b...101001101010\t1010\t10\n", - "four\t5854090567539607813\t0b...100100000101\t0101\t5\n", - "five\t5010767421024509913\t0b...111111011001\t1001\t9\n" + "zero\t-1033934764475250610\t0b...011110110010\t0010\t2\n", + "one\t-3496683303036773129\t0b...001100001001\t1001\t9\n", + "two\t-4468022785493412346\t0b...100111111010\t1010\t10\n", + "three\t1491334499222274950\t0b...001110000110\t0110\t6\n", + "four\t490235692124377396\t0b...000100110100\t0100\t4\n", + "five\t-550474145318920636\t0b...000110111100\t1100\t12\n" ] } ], @@ -1070,7 +1070,7 @@ } }, "source": [ - "### Mappings are Collections without \"Predictable Order\"" + "### Mappings are Collections without \"Predictable\" Order" ] }, { @@ -1081,7 +1081,7 @@ } }, "source": [ - "In [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#Collections-vs.-Sequences), we show how *sequences* are a special kind of *collections*. The latter can be described as iterable containers with a finite number of elements.\n", + "In [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#Collections-vs.-Sequences), we show how *sequences* are a special kind of *collections*. The latter can be described as iterable containers with a finite number of elements.\n", "\n", "The `dict` type is a special kind of a *collection*, as well, as revealed with the `Collection` ABC from the [collections.abc](https://docs.python.org/3/library/collections.abc.html) module in the [standard library](https://docs.python.org/3/library/index.html)." ] @@ -1291,12 +1291,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "Python 3.7.3\r\n" + "Python 3.7.4\n" ] } ], "source": [ - "!python --version # the order in the for-loops is predictable for Python 3.7 or higher only" + "!python --version # the order in the for-loops is predictable only for Python 3.7 or higher" ] }, { @@ -1811,7 +1811,7 @@ }, "outputs": [], "source": [ - "haystack = [random.randint(99, 9999) for _ in range(10_000_000)] + [42]" + "needle = 42" ] }, { @@ -1824,7 +1824,8 @@ }, "outputs": [], "source": [ - "needle = 42" + "haystack = [random.randint(99, 9999) for _ in range(10_000_000)]\n", + "haystack.append(needle)" ] }, { @@ -1863,7 +1864,7 @@ { "data": { "text/plain": [ - "[8126, 7370, 3735, 213, 7922, 1434, 8557, 9609, 9704, 9564, 9601, 3444]" + "[8126, 7370, 3735, 213, 7922, 1434, 8557, 9609, 9704, 9564]" ] }, "execution_count": 57, @@ -1872,7 +1873,7 @@ } ], "source": [ - "haystack[:12]" + "haystack[:10]" ] }, { @@ -1887,7 +1888,7 @@ { "data": { "text/plain": [ - "[5842, 1894, 7237, 886, 5945, 4014, 4998, 2055, 3531, 6919, 7875, 1944]" + "[7237, 886, 5945, 4014, 4998, 2055, 3531, 6919, 7875, 1944]" ] }, "execution_count": 58, @@ -1896,7 +1897,7 @@ } ], "source": [ - "haystack[-12:]" + "haystack[-10:]" ] }, { @@ -1923,7 +1924,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "4.37 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" + "4.32 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" ] } ], @@ -1965,7 +1966,7 @@ } }, "source": [ - "Because the hash table implementation is *extremely* fast, we search the `needle` not `10` but `10_000` times. The code cell still runs in only a fraction of the time its counterpart does above." + "To show the *massive* effect of the hash table implementation, we search the `needle` not `10` but `10_000_000` times. The code cell still runs in only a fraction of the time its counterpart does above." ] }, { @@ -1981,7 +1982,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "426 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" + "419 ms ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)\n" ] } ], @@ -2447,7 +2448,7 @@ { "data": { "text/plain": [ - "139752734711240" + "139953979638320" ] }, "execution_count": 75, @@ -2638,7 +2639,7 @@ } }, "source": [ - "`dict` objects come with many methods bound on them, many of which are standardized by the `Mapping` and `MutableMapping` ABCs from the [collections.abc](https://docs.python.org/3/library/collections.abc.html) module. While the former requires a data type adhering to it to implement the [keys()](https://docs.python.org/3/library/stdtypes.html#dict.keys), [values()](https://docs.python.org/3/library/stdtypes.html#dict.values), [items()](https://docs.python.org/3/library/stdtypes.html#dict.items), and [get()](https://docs.python.org/3/library/stdtypes.html#dict.get) methods, which *never* mutate an object, the latter formalizes the [update()](https://docs.python.org/3/library/stdtypes.html#dict.update), [pop()](https://docs.python.org/3/library/stdtypes.html#dict.pop), [popitem()](https://docs.python.org/3/library/stdtypes.html#dict.popitem), [clear()](https://docs.python.org/3/library/stdtypes.html#dict.clear), and [setdefault()](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) methods, which *may* do so." + "`dict` objects come with many methods bound on them (cf., [documentation](https://docs.python.org/3/library/stdtypes.html#dict)), many of which are standardized by the `Mapping` and `MutableMapping` ABCs from the [collections.abc](https://docs.python.org/3/library/collections.abc.html) module. While the former requires a data type adhering to it to implement the [keys()](https://docs.python.org/3/library/stdtypes.html#dict.keys), [values()](https://docs.python.org/3/library/stdtypes.html#dict.values), [items()](https://docs.python.org/3/library/stdtypes.html#dict.items), and [get()](https://docs.python.org/3/library/stdtypes.html#dict.get) methods, which *never* mutate an object, the latter formalizes the [update()](https://docs.python.org/3/library/stdtypes.html#dict.update), [pop()](https://docs.python.org/3/library/stdtypes.html#dict.pop), [popitem()](https://docs.python.org/3/library/stdtypes.html#dict.popitem), [clear()](https://docs.python.org/3/library/stdtypes.html#dict.clear), and [setdefault()](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) methods, which *may* do so." ] }, { @@ -2929,7 +2930,7 @@ } }, "source": [ - "Above, we see how the look-up operator fails *loudly* if a key is not in a `dict` object. For example, `to_words` does *not* have a key `0` any more." + "Above, we see how the look-up operator fails *loudly* with a `KeyError` if a key is *not* in a `dict` object. For example, `to_words` does *not* have a key `0` any more." ] }, { @@ -3768,7 +3769,7 @@ } }, "source": [ - "Just as a single `*` symbol is used for packing and unpacking iterables in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#Packing-&-Unpacking), a double `**` symbol implements packing and unpacking for mappings.\n", + "Just as a single `*` symbol is used for packing and unpacking iterables in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#Packing-&-Unpacking), a double `**` symbol implements packing and unpacking for mappings.\n", "\n", "Let's say we have `to_words` and `more_words` as below and want to merge the items together into a *new* `dict` object." ] @@ -3815,7 +3816,7 @@ } }, "source": [ - "By *unpacking* the items with `**`, the newly created `dict` objects is first filled with the items from `to_words` and then from `more_words`. The item with the key `2` from `more_words` overwrites its counterpart from `to_words` as it is mentioned last." + "By *unpacking* the items with `**`, the newly created `dict` object is first filled with the items from `to_words` and then from `more_words`. The item with the key `2` from `more_words` overwrites its counterpart from `to_words` as it is mentioned last." ] }, { @@ -4194,7 +4195,7 @@ } }, "source": [ - "Analogous to list comprehensions in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb#List-Comprehensions), **dictionary comprehensions**, or **dictcomps** for short, are a concise literal notation to derive new `dict` objects out of existing ones.\n", + "Analogous to list comprehensions in [Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb#List-Comprehensions), **dictionary comprehensions**, or **dictcomps** for short, are a concise literal notation to derive new `dict` objects out of existing ones.\n", "\n", "For example, let's derive `from_words` from `to_words` below by swapping the keys and values." ] @@ -4409,7 +4410,7 @@ } }, "source": [ - "The *recursive* implementation of the [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number) in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#\"Easy-at-first-Glance\"-Example:-Fibonacci-Numbers) takes long to compute for large Fibonacci numbers as the number of function calls grows exponentially.\n", + "The *recursive* implementation of the [Fibonacci numbers](https://en.wikipedia.org/wiki/Fibonacci_number) in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#\"Easy-at-first-Glance\"-Example:-Fibonacci-Numbers) takes long to compute for large Fibonacci numbers as the number of function calls grows exponentially.\n", "\n", "The graph below visualizes what the problem is and also suggests a solution: Instead of calculating the return value of the `fibonacci()` function for the *same* argument over and over again, it makes sense to **cache** the result and reuse it. This concept is called **[memoization](https://en.wikipedia.org/wiki/Memoization)** in the computer science literature." ] @@ -4563,7 +4564,7 @@ } }, "source": [ - "Now, calling `fibonacci()` has the *side effect* of growing the `memo` in the *global scope*. So, subsequent calls to `fibonacci()` need not calculate any Fibonacci number with an index `i` smaller than the maximum `i` used so far." + "Now, calling `fibonacci()` has the *side effect* of growing the `memo` in the *global scope*. So, subsequent calls to `fibonacci()` need not calculate any Fibonacci number with an index `i` smaller than the maximum `i` used so far. Because of that, this `fibonacci()` is *not* a *pure* function." ] }, { @@ -4663,8 +4664,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "The slowest run took 195.30 times longer than the fastest. This could mean that an intermediate result is being cached.\n", - "18.9 µs ± 44.4 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + "The slowest run took 183.70 times longer than the fastest. This could mean that an intermediate result is being cached.\n", + "21.4 µs ± 50.4 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], @@ -4686,8 +4687,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "The slowest run took 1919.60 times longer than the fastest. This could mean that an intermediate result is being cached.\n", - "346 µs ± 844 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + "The slowest run took 1974.48 times longer than the fastest. This could mean that an intermediate result is being cached.\n", + "580 µs ± 1.41 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], @@ -4727,12 +4728,12 @@ "\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[0mget_ipython\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_cell_magic\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'timeit'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'-n 1'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'fibonacci(9999) # = 10,000th number\\n'\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~/.pyenv/versions/anaconda3-2019.07/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mrun_cell_magic\u001b[0;34m(self, magic_name, line, cell)\u001b[0m\n\u001b[1;32m 2356\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuiltin_trap\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2357\u001b[0m \u001b[0margs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mmagic_arg_s\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcell\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2358\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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 2359\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2360\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m\u001b[0m in \u001b[0;36mtimeit\u001b[0;34m(self, line, cell, local_ns)\u001b[0m\n", - "\u001b[0;32m~/.pyenv/versions/anaconda3-2019.07/lib/python3.7/site-packages/IPython/core/magic.py\u001b[0m in \u001b[0;36m\u001b[0;34m(f, *a, **k)\u001b[0m\n\u001b[1;32m 185\u001b[0m \u001b[0;31m# but it's overkill for just that one bit of state.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 186\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmagic_deco\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\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--> 187\u001b[0;31m \u001b[0mcall\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mlambda\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mk\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 188\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 189\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcallable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\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~/.pyenv/versions/anaconda3-2019.07/lib/python3.7/site-packages/IPython/core/magics/execution.py\u001b[0m in \u001b[0;36mtimeit\u001b[0;34m(self, line, cell, local_ns)\u001b[0m\n\u001b[1;32m 1160\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1161\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1162\u001b[0;31m \u001b[0mall_runs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtimer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrepeat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrepeat\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnumber\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 1163\u001b[0m \u001b[0mbest\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall_runs\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mnumber\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1164\u001b[0m \u001b[0mworst\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall_runs\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mnumber\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.pyenv/versions/anaconda3-2019.07/lib/python3.7/timeit.py\u001b[0m in \u001b[0;36mrepeat\u001b[0;34m(self, repeat, number)\u001b[0m\n\u001b[1;32m 202\u001b[0m \u001b[0mr\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 203\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrepeat\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--> 204\u001b[0;31m \u001b[0mt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtimeit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnumber\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 205\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 206\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.pyenv/versions/anaconda3-2019.07/lib/python3.7/site-packages/IPython/core/magics/execution.py\u001b[0m in \u001b[0;36mtimeit\u001b[0;34m(self, number)\u001b[0m\n\u001b[1;32m 167\u001b[0m \u001b[0mgc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdisable\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 168\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 169\u001b[0;31m \u001b[0mtiming\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minner\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mit\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtimer\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 170\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 171\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mgcold\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/.pyenv/versions/anaconda3-2019.10/lib/python3.7/site-packages/IPython/core/interactiveshell.py\u001b[0m in \u001b[0;36mrun_cell_magic\u001b[0;34m(self, magic_name, line, cell)\u001b[0m\n\u001b[1;32m 2357\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbuiltin_trap\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2358\u001b[0m \u001b[0margs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mmagic_arg_s\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcell\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 2359\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\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 2360\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2361\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m\u001b[0m in \u001b[0;36mtimeit\u001b[0;34m(self, line, cell, local_ns)\u001b[0m\n", + "\u001b[0;32m~/.pyenv/versions/anaconda3-2019.10/lib/python3.7/site-packages/IPython/core/magic.py\u001b[0m in \u001b[0;36m\u001b[0;34m(f, *a, **k)\u001b[0m\n\u001b[1;32m 185\u001b[0m \u001b[0;31m# but it's overkill for just that one bit of state.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 186\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mmagic_deco\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\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--> 187\u001b[0;31m \u001b[0mcall\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mlambda\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mk\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 188\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 189\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcallable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\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~/.pyenv/versions/anaconda3-2019.10/lib/python3.7/site-packages/IPython/core/magics/execution.py\u001b[0m in \u001b[0;36mtimeit\u001b[0;34m(self, line, cell, local_ns)\u001b[0m\n\u001b[1;32m 1160\u001b[0m \u001b[0;32mbreak\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1161\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1162\u001b[0;31m \u001b[0mall_runs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtimer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrepeat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrepeat\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnumber\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 1163\u001b[0m \u001b[0mbest\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmin\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall_runs\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mnumber\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1164\u001b[0m \u001b[0mworst\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mall_runs\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mnumber\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/.pyenv/versions/anaconda3-2019.10/lib/python3.7/timeit.py\u001b[0m in \u001b[0;36mrepeat\u001b[0;34m(self, repeat, number)\u001b[0m\n\u001b[1;32m 202\u001b[0m \u001b[0mr\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 203\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrepeat\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--> 204\u001b[0;31m \u001b[0mt\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtimeit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnumber\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 205\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mt\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 206\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mr\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/.pyenv/versions/anaconda3-2019.10/lib/python3.7/site-packages/IPython/core/magics/execution.py\u001b[0m in \u001b[0;36mtimeit\u001b[0;34m(self, number)\u001b[0m\n\u001b[1;32m 167\u001b[0m \u001b[0mgc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdisable\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 168\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 169\u001b[0;31m \u001b[0mtiming\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minner\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mit\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtimer\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 170\u001b[0m \u001b[0;32mfinally\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 171\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mgcold\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;36minner\u001b[0;34m(_it, _timer)\u001b[0m\n", "\u001b[0;32m\u001b[0m in \u001b[0;36mfibonacci\u001b[0;34m(i, debug)\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34mf\"fibonacci({i}) is calculated\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 25\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 26\u001b[0;31m \u001b[0mrecurse\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfibonacci\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mi\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdebug\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdebug\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mfibonacci\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mi\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdebug\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mdebug\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 27\u001b[0m \u001b[0mmemo\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrecurse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 28\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mrecurse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "... last 1 frames repeated, from the frame below ...\n", @@ -4844,8 +4845,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "The slowest run took 25077.61 times longer than the fastest. This could mean that an intermediate result is being cached.\n", - "2.36 ms ± 5.77 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + "The slowest run took 27724.52 times longer than the fastest. This could mean that an intermediate result is being cached.\n", + "3.11 ms ± 7.61 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], @@ -4994,7 +4995,7 @@ } }, "source": [ - "Because `fibonacci()` is now independent from *global state*, the same eleven recursive function calls are made each time." + "Because `fibonacci()` is now independent from *global state*, the same eleven recursive function calls are made each time. So, this `fibonacci()` is a *pure* function." ] }, { @@ -5073,7 +5074,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "330 µs ± 18.7 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + "138 µs ± 5.01 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], @@ -5095,7 +5096,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "3.53 ms ± 75.2 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + "1.55 ms ± 56.7 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], @@ -5130,7 +5131,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "15.5 ms ± 572 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + "20.8 ms ± 8.09 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" ] } ], @@ -5193,7 +5194,7 @@ } }, "source": [ - "The [OrderedDict](https://docs.python.org/3/library/collections.html#collections.OrderedDict) type may be used to create a `dict`-like object with the added feature that *explicitly* remembers the *insertion* order of its items.\n", + "The [OrderedDict](https://docs.python.org/3/library/collections.html#collections.OrderedDict) type may be used to create a `dict`-like object with the added feature of *explicitly* remembering the *insertion* order of its items.\n", "\n", "Let's look at a quick example: We create an `OrderedDict` object by passing an iterable of $2$-element iterables, one of the three ways to use [dict()](https://docs.python.org/3/library/functions.html#func-dict)." ] @@ -6360,8 +6361,8 @@ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mKeyError\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[0mchain\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m10\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~/.pyenv/versions/anaconda3-2019.07/lib/python3.7/collections/__init__.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 912\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 913\u001b[0m \u001b[0;32mpass\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 914\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__missing__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# support subclasses that define __missing__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 915\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 916\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdefault\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\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~/.pyenv/versions/anaconda3-2019.07/lib/python3.7/collections/__init__.py\u001b[0m in \u001b[0;36m__missing__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 904\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 905\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__missing__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\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--> 906\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\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 907\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 908\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__getitem__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\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~/.pyenv/versions/anaconda3-2019.10/lib/python3.7/collections/__init__.py\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 914\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 915\u001b[0m \u001b[0;32mpass\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 916\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m__missing__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# support subclasses that define __missing__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 917\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 918\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdefault\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\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~/.pyenv/versions/anaconda3-2019.10/lib/python3.7/collections/__init__.py\u001b[0m in \u001b[0;36m__missing__\u001b[0;34m(self, key)\u001b[0m\n\u001b[1;32m 906\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 907\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__missing__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\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--> 908\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mKeyError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\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 909\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 910\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__getitem__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\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;31mKeyError\u001b[0m: 10" ] } @@ -6430,7 +6431,7 @@ { "data": { "text/plain": [ - "139751998783784" + "139953088728672" ] }, "execution_count": 207, @@ -6929,7 +6930,7 @@ } ], "source": [ - "1.0 in numbers" + "2.0 in numbers" ] }, { @@ -7421,7 +7422,7 @@ { "data": { "text/plain": [ - "139751998783784" + "139953088728672" ] }, "execution_count": 243, @@ -8041,7 +8042,7 @@ } }, "source": [ - "This section provides some conference talks that go into great detail regarding the workings of the `dict` type." + "Next, we list some conference talks that go into great detail regarding the workings of the `dict` type." ] }, { @@ -8068,7 +8069,7 @@ " " ], "text/plain": [ - "" + "" ] }, "execution_count": 261, @@ -8105,7 +8106,7 @@ " " ], "text/plain": [ - "" + "" ] }, "execution_count": 262, @@ -8141,7 +8142,7 @@ " " ], "text/plain": [ - "" + "" ] }, "execution_count": 263, @@ -8152,6 +8153,20 @@ "source": [ "YouTubeVideo(\"npw4s1QTmPg\", width=\"60%\")" ] + }, + { + "cell_type": "markdown", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "The `dict` type's order has been worked on in many PEPs in recent years:\n", + "- [PEP 412](https://www.python.org/dev/peps/pep-0412/): Key-Sharing Dictionary\n", + "- [PEP 468](https://www.python.org/dev/peps/pep-0468/): Preserving the order of \\*\\*kwargs in a function\n", + "- [PEP 520](https://www.python.org/dev/peps/pep-0520/): Preserving Class Attribute Definition Order" + ] } ], "metadata": { @@ -8170,7 +8185,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "livereveal": { "auto_select": "code", @@ -8198,5 +8213,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/08_mappings_10_review.ipynb b/08_mappings_10_review.ipynb new file mode 100644 index 0000000..471bd41 --- /dev/null +++ b/08_mappings_10_review.ipynb @@ -0,0 +1,261 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "# Chapter 8: Mappings & Sets" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Content Review" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_00_content.ipynb) of the book. Then, work through the questions below." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Essay Questions " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Answer the following questions *briefly*!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q1**: `dict` objects are well-suited **to model** discrete mathematical **functions** and to approximate continuous ones. What property of dictionaries is the basis for that claim, and how does it relate to functions in the mathematical sense?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q2**: Explain why **hash tables** are a **trade-off** between **computational speed** and **memory** usage!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q3:** The `dict` type is an **iterable** that **contains** a **finite** number of key-value pairs. Despite that, why is it *not* considered a **sequence**?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q4**: Whereas *key* **look-ups** in a `dict` object run in so-called **[constant time](https://en.wikipedia.org/wiki/Time_complexity#Constant_time)** (i.e., *extremely* fast), that does not hold for *reverse* look-ups. Why is that?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q5**: Why is it conceptually correct that the Python core developers do not implement **slicing** with the `[]` operator for `dict` objects?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q6**: **Memoization** is an essential concept to know to solve problems in the real world. Together with the idea of **recursion**, it enables us to solve problems in a \"backwards\" fashion *effectively*.\n", + "\n", + "\n", + "Compare the **recursive** formulation of `fibonacci()` in [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_00_content.ipynb#\"Easy-at-third-Glance\"-Example:-Fibonacci-Numbers-%28revisited%29), the \"*Easy at third Glance*\" example, with the **iterative** version in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb#\"Hard-at-first-Glance\"-Example:-Fibonacci-Numbers-%28revisited%29), the \"*Hard at first Glance*\" example!\n", + "\n", + "How are they similar and how do they differ?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q7**: How are the `set` and the `dict` type related? How could we use the latter to mimic the former?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### True / False Questions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Motivate your answer with *one short* sentence!" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q8**: We may *not* put `dict` objects inside other `dict` objects because they are **mutable**." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q9**: **Mutable** objects (e.g., `list`) may generally *not* be used as keys in a `dict` object. However, if we collect, for example, `list` objects in a `tuple` object, the composite object becomes **hashable**." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q10**: **Mutability** of a `dict` object works until the underlying hash table becomes too crowded. Then, we cannot insert any items any more making the `dict` object effectively **immutable**. Luckily, that almost never happens in practice." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q11**: A `dict` object's [update()](https://docs.python.org/3/library/stdtypes.html#dict.update) method only inserts key-value pairs whose key is *not* yet in the `dict` object. So, it does *not* overwrite anything." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Q12**: The `set` type is both a mapping and a sequence." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + " " + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.4" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": true, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": false, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/08_mappings_review_and_exercises.ipynb b/08_mappings_20_exercises.ipynb similarity index 56% rename from 08_mappings_review_and_exercises.ipynb rename to 08_mappings_20_exercises.ipynb index c05004e..0f3f1a5 100644 --- a/08_mappings_review_and_exercises.ipynb +++ b/08_mappings_20_exercises.ipynb @@ -8,221 +8,6 @@ "# Chapter 8: Mappings & Sets" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Content Review" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Read [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings.ipynb) of the book. Then work through the twelve review questions." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Essay Questions " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Answer the following questions briefly with *at most* 300 characters per question!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q1**: `dict` objects are well-suited **to model** discrete mathematical **functions** and to approximate continuous ones. What property of dictionaries is the basis for that claim, and how does it relate to functions in the mathematical sense?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q2**: Explain why **hash tables** are a **trade-off** between **computational speed** and **memory** usage!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q3:** The `dict` type is an **iterable** that **contains** a **finite** number of key-value pairs. Despite that, why is it *not* considered a **sequence**?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q4**: Whereas *key* **look-ups** in a `dict` object run in so-called **[constant time](https://en.wikipedia.org/wiki/Time_complexity#Constant_time)** (i.e., *extremely* fast), that does not hold for *reverse* look-ups. Why is that?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q5**: Why is it conceptually correct that the Python core developers do not implement **slicing** with the `[]` operator for `dict` objects?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q6**: **Memoization** is an essential concept to know to solve problems in the real world. Together with the idea of **recursion**, it enables us to solve problems in a \"backwards\" fashion *effectively*.\n", - "\n", - "\n", - "Compare the **recursive** formulation of `fibonacci()` in [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings.ipynb#\"Easy-at-third-Glance\"-Example:-Fibonacci-Numbers-%28revisited%29), the \"*Easy at third Glance*\" example, with the **iterative** version in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#\"Hard-at-first-Glance\"-Example:-Fibonacci-Numbers-%28revisited%29), the \"*Hard at first Glance*\" example!\n", - "\n", - "How are they similar and how do they differ?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q7**: How are the `set` and the `dict` type related? How could we use the latter to mimic the former?" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### True / False Questions" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Motivate your answer with *one short* sentence!" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q8**: We may *not* put `dict` objects inside other `dict` objects because they are **mutable**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q9**: **Mutable** objects (e.g., `list`) may generally *not* be used as keys in a `dict` object. However, if we collect, for example, `list` objects in a `tuple` object, the composite object becomes **hashable**." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q10**: **Mutability** of a `dict` object works until the underlying hash table becomes too crowded. Then, we cannot insert any items any more making the `dict` object effectively **immutable**. Luckily, that almost never happens in practice." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q11**: A `dict` object's [update()](https://docs.python.org/3/library/stdtypes.html#dict.update) method only inserts key-value pairs whose key is *not* yet in the `dict` object. So, it does *not* overwrite anything." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Q12**: The `set` type is both a mapping and a sequence." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - " " - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -230,6 +15,13 @@ "## Coding Exercises" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Read [Chapter 8](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_00_content.ipynb) of the book. Then, work through the exercises below." + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -291,7 +83,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q13.1**: Write a dictionary comprehension to derive a new `dict` object, called `brazilian_players`, that maps a Brazilian player's name to his position!" + "**Q1.1**: Write a dictionary comprehension to derive a new `dict` object, called `brazilian_players`, that maps a Brazilian player's name to his position!" ] }, { @@ -316,7 +108,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q13.2**: Generalize the code fragment into a `get_players()` function: Passed a `team` name, it returns a `dict` object like `brazilian_players`. Verify that the function works for the German team!" + "**Q1.2**: Generalize the code fragment into a `get_players()` function: Passed a `team` name, it returns a `dict` object like `brazilian_players`. Verify that the function works for the German team!" ] }, { @@ -344,7 +136,7 @@ "source": [ "Often, we are given a `dict` object like the one returned from `get_players()`: It is characterized by the observation that a large set of unique keys (i.e., the players' names) is mapped onto a smaller set of non-unique values (i.e., the positions).\n", "\n", - "**Q13.3**: Create a generic `invert()` function that swaps the keys and values of a `mapping` argument passed to it and returns them in a *new* `dict` object! Ensure that *no* key gets lost. Verify your implementation with the `brazilian_players` dictionary!\n", + "**Q1.3**: Create a generic `invert()` function that swaps the keys and values of a `mapping` argument passed to it and returns them in a *new* `dict` object! Ensure that *no* key gets lost. Verify your implementation with the `brazilian_players` dictionary!\n", "\n", "Hints: Think of this as a grouping operation. The *new* values are `list` or `tuple` objects that hold the original keys. You may want to use either the the [defaultdict](https://docs.python.org/3/library/collections.html#collections.defaultdict) type from the [collections](https://docs.python.org/3/library/collections.html) module in the [standard library](https://docs.python.org/3/library/index.html) or the [setdefault()](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) method of the ordinary `dict` type." ] @@ -372,7 +164,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q13.4**: Write a `score_at_minute()` function: It takes two arguments, `team` and `minute`, and returns the number of goals the `team` has scored up until this time in the game.\n", + "**Q1.4**: Write a `score_at_minute()` function: It takes two arguments, `team` and `minute`, and returns the number of goals the `team` has scored up until this time in the game.\n", "\n", "Hints: The function may reference the global `players` for simplicity. Earn bonus points if you can write this in a one-line expression using some *reduction* function and a *generator expression*." ] @@ -441,7 +233,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q13.5**: Write a `goals_by_player()` function: It takes an argument like the global `players`, and returns a `dict` object mapping the players to the number of goals they scored.\n", + "**Q1.5**: Write a `goals_by_player()` function: It takes an argument like the global `players`, and returns a `dict` object mapping the players to the number of goals they scored.\n", "\n", "Hints: Do *not* \"hard code\" the names of the teams! Earn bonus points if you can solve it in a single dictionary comprehension." ] @@ -469,7 +261,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q13.6**: Write a *dictionary comprehension* to filter out the players who did *not* score from the preceding result. Then, write a *set comprehension* that does the same but discards the number of goals scored.\n", + "**Q1.6**: Write a *dictionary comprehension* to filter out the players who did *not* score from the preceding result. Then, write a *set comprehension* that does the same but discards the number of goals scored.\n", "\n", "Hints: Reference the `goals_by_player()` function from before." ] @@ -496,7 +288,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q13.7**: Write a `all_goals()` function: It takes one argument like the global `players` and returns a `list` object containing $2$-element `tuple` objects, where the first element is the minute a player scored and the second his name. The list should be sorted by the time.\n", + "**Q1.7**: Write a `all_goals()` function: It takes one argument like the global `players` and returns a `list` object containing $2$-element `tuple` objects, where the first element is the minute a player scored and the second his name. The list should be sorted by the time.\n", "\n", "Hints: You may want to use either the built-in [sorted()](https://docs.python.org/3/library/functions.html#sorted) function or the `list` type's [sort()](https://docs.python.org/3/library/stdtypes.html#list.sort) method. Earn bonus points if you can write a one-line expression with a *generator expression*." ] @@ -524,7 +316,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "**Q13.8**: Lastly, write a `summary()` function: It takes one argument like the global `players` and prints out a concise report of the goals, the score at the half, and the final result.\n", + "**Q1.8**: Lastly, write a `summary()` function: It takes one argument like the global `players` and prints out a concise report of the goals, the score at the half, and the final result.\n", "\n", "Hints: Use the `all_goals()` and `score_at_minute()` functions from before.\n", "\n", @@ -575,7 +367,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.3" + "version": "3.7.4" }, "toc": { "base_numbering": 1, @@ -592,5 +384,5 @@ } }, "nbformat": 4, - "nbformat_minor": 2 + "nbformat_minor": 4 } diff --git a/README.md b/README.md index a227cb2..0da3f5e 100644 --- a/README.md +++ b/README.md @@ -13,23 +13,52 @@ studies** in the "field" of **data science**. The "chapters" are written in [Jupyter notebooks](https://jupyter-notebook.readthedocs.io/en/stable/) which are a de-facto standard for exchanging code and results among data science professionals and researchers. -As such they can be viewed in a plain web browser: +They can be viewed in a plain web browser with the help of +[nbviewer](https://nbviewer.jupyter.org/): -- [00 - Start up](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up.ipynb) -- [01 - Elements of a Program](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb) -- [02 - Functions & Modularization](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions.ipynb) -- [03 - Conditionals & Exceptions](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals.ipynb) -- [04 - Recursion & Looping](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb) -- [05 - Bits & Numbers](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers.ipynb) -- [06 - Bytes & Text](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb) -- [07 - Sequential Data](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb) -- [08 - Mappings & Sets](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings.ipynb) +- *Introduction*: Start up + ([content](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up_00_content.ipynb) + | [review](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up_10_review.ipynb) + | [exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up_20_exercises.ipynb)) +- **Part A: Expressing Logic** + - *Chapter 1*: Elements of a Program + ([content](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_00_content.ipynb) + | [review](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_10_review.ipynb) + | [exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements_20_exercises.ipynb)) + - *Chapter 2*: Functions & Modularization + ([content](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_00_content.ipynb) + | [review](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_10_review.ipynb) + | [exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/02_functions_20_exercises.ipynb)) + - *Chapter 3*: Conditionals & Exceptions + ([content](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_content.ipynb) + | [review](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_10_review.ipynb) + | [exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_20_exercises.ipynb)) + - *Chapter 4*: Recursion & Looping + ([content](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_00_content.ipynb) + | [review](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_10_review.ipynb) + | [exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_20_exercises.ipynb)) +- **Part B: Managing Data and Memory** + - *Chapter 5*: Bits & Numbers + ([content](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_00_content.ipynb) + | [review](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_10_review.ipynb) + | [exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/05_numbers_20_exercises.ipynb)) + - *Chapter 6*: Bytes & Text + ([content](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text_00_content.ipynb) + | [review](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text_10_review.ipynb)) + - *Chapter 7*: Sequential Data + ([content](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_00_content.ipynb) + | [review](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_10_review.ipynb) + | [exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences_20_exercises.ipynb)) + - *Chapter 8*: Mappings & Sets + ([content](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_00_content.ipynb) + | [review](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_10_review.ipynb) + | [exercises](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mappings_20_exercises.ipynb)) However, it is recommended that students **install Python and Jupyter locally** and run the code in the notebooks on their own. This way, the student can play with the code and learn more efficiently. Precise **installation instructions** are either in the [00th notebook]( -https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up.ipynb) +https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/00_start_up_00_content.ipynb) or further below. Feedback is encouraged and will be incorporated.