intro-to-python/01_elements_00_content.ipynb
Alexander Hess e1a0dd7924 Make links look nice with images
- rename all *_00_lecture.ipynb files into *_00_content.ipynb
- add links to YouTube videos at the end of the chapters
- add links to mybinder for all chapters and exercises
- remove the old chapter 8 on mappings & sets
- update the README.md and make it look nicer
2020-04-02 16:17:54 +02:00

3936 lines
180 KiB
Text

{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"**Important**: Click on \"*Kernel*\" > \"*Restart Kernel and Clear All Outputs*\" *before* reading this chapter in [JupyterLab <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_jp.png\">](https://jupyterlab.readthedocs.io/en/stable/) (e.g., in the cloud on [MyBinder <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_mb.png\">](https://mybinder.org/v2/gh/webartifex/intro-to-python/master?urlpath=lab/tree/01_elements_00_content.ipynb))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"\n",
"# Chapter 1: Elements of a Program"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Do you remember how you first learned to speak in your mother tongue? Probably not. No one's memory goes back that far. Your earliest memory as a child should probably be around the age of three or four years old when you could already say simple things and interact with your environment. Although you did not know any grammar rules yet, other people just understood what you said. At least most of the time.\n",
"\n",
"It is intuitively best to take the very mindset of a small child when learning a new language. And a programming language is no different from that. This first chapter introduces simplistic examples and we accept them as they are *without* knowing any of the \"grammar\" rules yet. Then, we analyze them in parts and slowly build up our understanding.\n",
"\n",
"Consequently, if parts of this chapter do not make sense right away, let's not worry too much. Besides introducing the basic elements, it also serves as an outlook for what is to come. So, many terms and concepts used here are deconstructed in great detail in the following chapters."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Example: Averaging all even Numbers in a List"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"As our introductory example, we want to calculate the *average* of all *evens* in a **list** of whole numbers: `[7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]`.\n",
"\n",
"While we are used to finding an [analytical solution](https://math.stackexchange.com/questions/935405/what-s-the-difference-between-analytical-and-numerical-approaches-to-problems/935446#935446) in math (i.e., derive some equation with \"pen and paper\"), we solve this task *programmatically* instead.\n",
"\n",
"We start by creating a list called `numbers` that holds all the individual numbers between **brackets** `[` and `]`."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"scrolled": true,
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"numbers = [7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"To verify that something happened in our computer's memory, we **reference** `numbers`."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"[7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"numbers"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"So far, so good. Let's see how the desired **computation** could be expressed as a **sequence of instructions** in the next code cell.\n",
"\n",
"Intuitively, the line `for number in numbers` describes a \"loop\" over all the numbers in the `numbers` list, one at a time.\n",
"\n",
"The `if number % 2 == 0` may look confusing at first sight. Both `%` and `==` must have an unintuitive meaning here. Luckily, the **comment** in the same line after the `#` symbol has the answer: The program does something only for an even `number`.\n",
"\n",
"In particular, it increases `count` by `1` and adds the current `number` onto the [running <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](https://en.wikipedia.org/wiki/Running_total) `total`. Both `count` and `number` are **initialized** to `0` and the single `=` symbol reads as \"... is *set* equal to ...\". It cannot indicate a mathematical equation as, for example, `count` is generally *not* equal to `count + 1`.\n",
"\n",
"Lastly, the `average` is calculated as the ratio of the final **values** of `total` and `count`. Overall, we divide the sum of all even numbers by their count: This is nothing but the definition of an average.\n",
"\n",
"The lines of code \"within\" the `for` and `if` **statements** are **indented** and aligned with multiples of *four spaces*: This shows immediately how the lines relate to each other."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"count = 0 # initialize variables to keep track of the\n",
"total = 0 # running total and the count of even numbers\n",
"\n",
"for number in numbers:\n",
" if number % 2 == 0: # only work with even numbers\n",
" count = count + 1\n",
" total = total + number\n",
"\n",
"average = total / count"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"We do not see any **output** yet but obtain the value of `average` by referencing it again."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"7.0"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"average"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Output in a Jupyter Notebook"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Only two of the previous four code cells generate an **output** while two remained \"silent\" (i.e., nothing appears below the cell after running it).\n",
"\n",
"By default, Jupyter notebooks only show the value of the **expression** in the last line of a code cell. And, this output may also be suppressed by ending the last line with a semicolon `;`."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'I am feeling great :-)'"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\"Hello, World!\"\n",
"\"I am feeling great :-)\""
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"\"I am invisible!\";"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"To see any output other than that, we use the built-in [print() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#print) **function**. Here, the parentheses `()` indicate that we **call** (i.e., \"execute\") code written somewhere else."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello, World!\n",
"I am feeling great :-)\n"
]
}
],
"source": [
"print(\"Hello, World!\")\n",
"print(\"I am feeling great :-)\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Outside Jupyter notebooks, the semicolon `;` is used as a **separator** between statements that must otherwise be on a line on their own. However, it is *not* considered good practice to use it as it makes code less readable."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello, World!\n",
"I am feeling great :-)\n"
]
}
],
"source": [
"print(\"Hello, World!\"); print(\"I am feeling great :-)\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## (Arithmetic) Operators"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Python comes with many built-in **[operators <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/reference/lexical_analysis.html#operators)**: They are **tokens** (i.e., \"symbols\") that have a special meaning to the Python interpreter.\n",
"\n",
"The arithmetic operators either \"operate\" with the number immediately following them, so-called **unary** operators (e.g., negation), or \"process\" the two numbers \"around\" them, so-called **binary** operators (e.g., addition).\n",
"\n",
"By definition, operators on their own have *no* permanent **side effects** in the computer's memory. Although the code cells in this section do indeed create *new* numbers in memory (e.g., `77 + 13` creates `90`), they are immediately \"forgotten\" as they are not stored in a **variable** like `numbers` or `average` above. We develop this thought further at the end of this chapter when we compare **expressions** with **statements**.\n",
"\n",
"Let's see some examples of operators. We start with the binary `+` and the `-` operators for addition and subtraction. Binary operators mimic what mathematicians call [infix notation <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](https://en.wikipedia.org/wiki/Infix_notation) and have the expected meaning."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"90"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"77 + 13"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"8"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"101 - 93"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The `-` operator may be used as a unary operator as well. Then, it unsurprisingly flips the sign of a number."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"-1"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"-1"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"When we compare the output of the `*` and `/` operators for multiplication and division, we note the subtle *difference* between the `42` and the `42.0`: They are the *same* number represented as a *different* **data type**."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"42"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2 * 21"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"42.0"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"84 / 2"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The so-called **floor division operator** `//` always \"rounds\" to an integer and is thus also called **integer division operator**. It is an example of an arithmetic operator we commonly do not know from high school mathematics."
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"42"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"84 // 2"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"42"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"85 // 2"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Even though it appears that the `//` operator **truncates** (i.e., \"cuts off\") the decimals so as to effectively \"round down\" (i.e., the `42.5` became `42` in the previous code cell), this is *not* the case: The result is always \"rounded\" towards minus infinity!"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"-43"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"-85 // 2"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"To obtain the remainder of a division, we use the **modulo operator** `%`."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"1"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"85 % 2"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The remainder is `0` *only if* a number is *divisible* by another.\n",
"\n",
"A popular convention in both computer science and mathematics is to abbreviate \"only if\" as \"iff\", which is short for \"**[if and only if <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](https://en.wikipedia.org/wiki/If_and_only_if)**.\" The iff means that a remainder of `0` implies that a number is divisible by another but also that a number's being divisible by another implies a remainder of `0`. The implication goes in *both* directions!\n",
"\n",
"So, `49` is divisible by `7`."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"0"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"49 % 7"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Modulo division is also useful if we want to extract the last couple of digits in a large integer."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"9"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"789 % 10"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"89"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"789 % 100"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The built-in [divmod() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#divmod) function combines the integer and modulo divisions into one step. However, grammatically this is *not* an operator but a function. Also, [divmod() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#divmod) returns a \"pair\" of integers and not a single one."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"text/plain": [
"(4, 2)"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"divmod(42, 10)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Raising a number to a power is performed with the **exponentiation operator** `**`. It is different from the `^` operator other programming languages may use and that also exists in Python with a *different* meaning."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"8"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2 ** 3"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The standard [order of precedence <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/reference/expressions.html#operator-precedence) from mathematics applies (i.e., [PEMDAS](http://mathworld.wolfram.com/PEMDAS.html) rule) when several operators are combined."
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"18"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3 ** 2 * 2 "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Parentheses help avoid confusion and take the role of a **delimiter** here."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"18"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(3 ** 2) * 2"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"81"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3 ** (2 * 2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Some programmers also use \"style\" conventions. For example, we might play with the **whitespace**, which is an umbrella term that refers to any non-printable sign like spaces, tabs, or the like. However, this is *not* a good practice and parentheses convey a much clearer picture."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"text/plain": [
"18"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3**2 * 2 # bad style; it is better to use parentheses here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"There exist many non-mathematical operators that are introduced throughout this book, together with the concepts they implement. They often come in a form different from the unary and binary ones mentioned above."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Operator Overloading"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Python **overloads** certain operators. For example, you may not only \"add\" numbers but also strings: This is called **string concatenation**."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"greeting = \"Hi \"\n",
"audience = \"class\""
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'Hi class'"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"greeting + audience"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Duplicate strings using multiplication."
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'Hi Hi Hi Hi Hi Hi Hi Hi Hi Hi '"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"10 * greeting"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Objects vs. Types vs. Values"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"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 given memory location. The $0$s and $1$s in a bag make up the object's **value**. There exist different **types** of bags, and each type comes with its own 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."
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"a = 42\n",
"b = 42.0\n",
"c = \"Python rocks\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Identity / \"Memory Location\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The built-in [id() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#id) function shows an object's \"address\" in memory."
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"94194112985152"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"id(a)"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"140586628675056"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"id(b)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"140586628487280"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"id(c)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"These addresses are *not* meaningful for anything other than checking if two variables reference the *same* object.\n",
"\n",
"Obviously, `a` and `b` have the same *value* as revealed by the **equality operator** `==`: We say `a` and `b` \"evaluate equal.\" The resulting `True` - and the `False` further below - is yet another data type, a so-called **boolean**. We look into them in [Chapter 3 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_nb.png\">](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_content.ipynb#Boolean-Expressions)."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a == b"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"On the contrary, `a` and `b` are *different* objects as the **identity operator** `is` shows: They are stored at *different* addresses in the memory."
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a is b"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"If we want to check the opposite case, we use the negated version of the `is` operator, namely `is not`."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a is not b"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### (Data) Type / \"Behavior\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The [type() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#type) built-in shows an object's type. For example, `a` is an integer (i.e., `int`) while `b` is a so-called [floating-point number <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](https://en.wikipedia.org/wiki/Floating-point_arithmetic) (i.e., `float`)."
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"int"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(a)"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"float"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(b)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Different types imply different behaviors for the objects. The `b` object, for example, may be \"asked\" if it is a whole number with the [is_integer() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](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** (i.e., as opposed to functions) and we look at them in detail in Chapter 10. For now, it suffices to know that we access them with the **dot operator** `.` on the object. Of course, `b` is a whole number, which the boolean object `True` tells us."
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"b.is_integer()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"For an `int` object, this [is_integer() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/stdtypes.html#float.is_integer) check does *not* make sense as we already know it is an `int`: We see the `AttributeError` below as `a` does not even know what `is_integer()` means."
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"ename": "AttributeError",
"evalue": "'int' object has no attribute 'is_integer'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-40-7db0a38aefcc>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_integer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mAttributeError\u001b[0m: 'int' object has no attribute 'is_integer'"
]
}
],
"source": [
"a.is_integer()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The `c` object is a so-called **string** type (i.e., `str`), which is Python's way of representing \"text.\" Strings also come with peculiar behaviors, for example, to make a text lower or upper case."
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"str"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(c)"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'python rocks'"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"c.lower()"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'PYTHON ROCKS'"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"c.upper()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Value / (Semantic) \"Meaning\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"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 the bag mean to *humans*. In other words, an object's value regards its *semantic* meaning.\n",
"\n",
"For built-in data types, Python prints out an object's value as a so-called **[literal <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/reference/lexical_analysis.html#literals)**: This means that we may copy and paste the value back into a code cell and create a *new* object with the *same* value."
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"42"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"42.0"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"b"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"In this book, we follow the convention of creating strings with **double quotes** `\"` instead of the **single quotes** `'` to which Python defaults in its *literal* notation for `str` objects. Both types of quotes may be used interchangeably. So, the `\"Python rocks\"` from above and `'Python rocks'` below create two objects that evaluate equal (i.e., `\"Python rocks\" == 'Python rocks'`)."
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'Python rocks'"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"c"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Formal vs. Natural Languages"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Just like the language of mathematics is good at expressing relationships among numbers and symbols, any programming language is just a formal language that is good at expressing computations.\n",
"\n",
"Formal languages come with their own \"grammatical rules\" called **syntax**."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Syntax Errors"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"If we do not follow the rules, the code cannot be **parsed** correctly, i.e., the program does not even start to run but **raises** a **syntax error** indicated as `SyntaxError` in the output. Computers are very dumb in the sense that the slightest syntax error leads to the machine not understanding our code.\n",
"\n",
"If we were to write an accounting program that adds up currencies, we would, for example, have to model dollar prices as `float` objects as the dollar symbol cannot be understood by Python."
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"ename": "SyntaxError",
"evalue": "invalid syntax (<ipython-input-47-cafa82e54b9c>, line 1)",
"output_type": "error",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"<ipython-input-47-cafa82e54b9c>\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m 3.99 $ + 10.40 $\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
]
}
],
"source": [
"3.99 $ + 10.40 $"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Python requires certain symbols at certain places (e.g., a `:` is missing here)."
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"ename": "SyntaxError",
"evalue": "invalid syntax (<ipython-input-48-499e4d0d0cbb>, line 1)",
"output_type": "error",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"<ipython-input-48-499e4d0d0cbb>\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m for number in numbers\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
]
}
],
"source": [
"for number in numbers\n",
" print(number)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Furthermore, it relies on whitespace (i.e., indentation), unlike many other programming languages. The `IndentationError` below is just a particular type of a `SyntaxError`."
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"ename": "IndentationError",
"evalue": "expected an indented block (<ipython-input-49-19398c5f89de>, line 2)",
"output_type": "error",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"<ipython-input-49-19398c5f89de>\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m print(number)\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m expected an indented block\n"
]
}
],
"source": [
"for number in numbers:\n",
"print(number)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Runtime Errors"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Syntax errors are easy to find as the code does *not* even run in the first place.\n",
"\n",
"However, there are also so-called **runtime errors** that occur whenever otherwise (i.e., syntactically) correct code does not run because of invalid input. Runtime errors are also often referred to as **exceptions**.\n",
"\n",
"This example does not work because just like in the \"real\" world, Python does not know how to divide by `0`. The syntactically correct code leads to a `ZeroDivisionError`."
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"ename": "ZeroDivisionError",
"evalue": "division by zero",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-50-bc757c3fda29>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;36m1\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mZeroDivisionError\u001b[0m: division by zero"
]
}
],
"source": [
"1 / 0"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Semantic Errors"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"So-called **semantic errors**, on the contrary, are hard to spot as they do *not* crash the program. The only way to find such errors is to run a program with test input for which we can predict the output. However, testing software is a whole discipline on its own and often very hard to do in practice.\n",
"\n",
"The cell below copies our first example from above with a \"tiny\" error. How fast could you have spotted it without the comment?"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {
"code_folding": [],
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"count = 0\n",
"total = 0\n",
"\n",
"for number in numbers:\n",
" if number % 2 == 0:\n",
" count = count + 1\n",
" total = total + count # count is wrong here, it should be number\n",
"\n",
"average = total / count"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"3.5"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"average"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Systematically finding errors is called **debugging**. For the history of the term, see this [article <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](https://en.wikipedia.org/wiki/Debugging)."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Best Practices"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Thus, adhering to just syntax rules is *never* enough. Over time, **best practices** and **style guides** were created to make it less likely for a developer to mess up a program and also to allow \"onboarding\" him as a contributor to an established code base, often called **legacy code**, faster. These rules are *not* enforced by Python itself: Badly styled code still runs. At the very least, Python programs should be styled according to [PEP 8 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://www.python.org/dev/peps/pep-0008/) and documented \"inline\" (i.e., in the code itself) according to [PEP 257 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://www.python.org/dev/peps/pep-0257/).\n",
"\n",
"An easier to read version of PEP 8 is [here](https://pep8.org/). The video below features a well known **[Pythonista](https://en.wiktionary.org/wiki/Pythonista)** talking about the importance of code style."
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAUDBAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChANCAgOCggIDRUNDhERExMTCAsWGBYSGBASExIBBQUFCAcIDwkJDxUVEBUVFhUVFRUSFRUVFRISEhUVFRUVFRUVFRUVFRIVEhUVFRUVFRUVFRUVFRUVFRUVFRUVFf/AABEIAWgB4AMBIgACEQEDEQH/xAAcAAEAAgMBAQEAAAAAAAAAAAAABgcEBQgDAgH/xABfEAABAwICBQUHDgsGAggFBQABAAIDBBEFEgYHEyExQVFTYZIUFyJxgZHTCCMyNUJSYnJzdKGxs8EVJCUzNIKDorK0wkNjZJOjw9HwJ1RVlKS10uEWJmWVpTY3RFZ1/8QAHAEBAAIDAQEBAAAAAAAAAAAAAAUGAwQHAgEI/8QAQBEAAQIDAwgGBwcEAwEAAAAAAQACAwQRBSExBhITQVFxkcEWYWKBobEUIjRTcpLRIyQyMzWC4QdSsvBCovEV/9oADAMBAAIRAxEAPwDjJEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREX6innexrOmpu3L6JO9jWdNTduX0SUKmuj0/7p3BQNFPO9jWdNTduX0Sd7Gs6am7cvokoU6PT/uncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P8AuncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P+6dwUDRTzvY1nTU3bl9EnexrOmpu3L6JKFOj0/7p3BQNFPO9jWdNTduX0Sd7Gs6am7cvokoU6PT/uncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P8AuncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P+6dwUDRTzvY1nTU3bl9EnexrOmpu3L6JKFOj0/7p3BQNFPO9jWdNTduX0Sd7Gs6am7cvokoU6PT/uncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P8AuncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P+6dwUDRTzvY1nTU3bl9EnexrOmpu3L6JKFOj0/7p3BQNFPO9jWdNTduX0Sd7Gs6am7cvokoU6PT/uncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P8AuncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P+6dwUDRTzvY1nTU3bl9EnexrOmpu3L6JKFOj0/7p3BQNFPO9jWdNTduX0Sd7Gs6am7cvokoU6PT/uncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P8AuncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P+6dwUDRTzvY1nTU3bl9EnexrOmpu3L6JKFOj0/7p3BQNFPO9jWdNTduX0Sd7Gs6am7cvokoU6PT/uncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P8AuncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P+6dwUDRTzvY1nTU3bl9EnexrOmpu3L6JKFOj0/7p3BQNFPO9jWdNTduX0Sd7Gs6am7cvokoU6PT/uncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P8AuncFA0U872NZ01N25fRJ3sazpqbty+iShTo9P+6dwUDRTzvY1nTU3bl9EnexrOmpu3L6JKFOj0/7p3BQNFPO9jWdNTduX0Sd7Gs6am7cvokoU6PT/uncFbCIi2F3RERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERTTVfoizE5JZJ3HueAtaYmOLXyvcMwDnDeyMDlG8ncCLFa81NMl4RiPwCwTMwyBDMR+AULRdEt0MwoC34PpfGYWl3lefCJ67rT41qxw2YEwiSlfyOheXM8Topcwy/FynrUDDyplnGjgR10B5qHZlDBJo4OHXd9VRyKRaX6H1eG+FIBJASA2oiByXO4NlYd8Lid2+4NwASdyjqsMCPDjMDoZBB1hTUGOyM3OYahERFlWVEUz0Q1eVOIQCoMzKWJxOyzxOkfI0btoGh7bMJuASd9r8LEyin1Qwf2tbO75KKKP+POomYtuUguLXPvFxABN/BRsW15WG4tc68agCeVFUiK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U0gTprZ/a+VWyiqbvnVnQUvYl9KnfOrOgpexL6VNIE6a2f2vlUDREWNceREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREX//2Q==\n",
"text/html": [
"\n",
" <iframe\n",
" width=\"60%\"\n",
" height=\"300\"\n",
" src=\"https://www.youtube.com/embed/Hwckt4J96dI\"\n",
" frameborder=\"0\"\n",
" allowfullscreen\n",
" ></iframe>\n",
" "
],
"text/plain": [
"<IPython.lib.display.YouTubeVideo at 0x7fdce00c69d0>"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.display import YouTubeVideo\n",
"YouTubeVideo(\"Hwckt4J96dI\", width=\"60%\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"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 built-in [sum() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#sum) and [len() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#len) functions (cf., [Chapter 2 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_nb.png\">](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 8 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_nb.png\">](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/08_mfr_00_content.ipynb#List-Comprehensions)). Pythonic code runs faster in many cases and is less error-prone."
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"numbers = [7, 11, 8, 5, 3, 12, 2, 6, 9, 10, 1, 4]"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"evens = [n for n in numbers if n % 2 == 0] # use of a list comprehension"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"[8, 12, 2, 6, 10, 4]"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"evens"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"average = sum(evens) / len(evens) # use built-in functions"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"7.0"
]
},
"execution_count": 58,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"average"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"To get a rough overview of the mindset of a typical Python programmer, look at these rules, also known as the **Zen of Python**, that are deemed so important that they are included in every Python installation."
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The Zen of Python, by Tim Peters\n",
"\n",
"Beautiful is better than ugly.\n",
"Explicit is better than implicit.\n",
"Simple is better than complex.\n",
"Complex is better than complicated.\n",
"Flat is better than nested.\n",
"Sparse is better than dense.\n",
"Readability counts.\n",
"Special cases aren't special enough to break the rules.\n",
"Although practicality beats purity.\n",
"Errors should never pass silently.\n",
"Unless explicitly silenced.\n",
"In the face of ambiguity, refuse the temptation to guess.\n",
"There should be one-- and preferably only one --obvious way to do it.\n",
"Although that way may not be obvious at first unless you're Dutch.\n",
"Now is better than never.\n",
"Although never is often better than *right* now.\n",
"If the implementation is hard to explain, it's a bad idea.\n",
"If the implementation is easy to explain, it may be a good idea.\n",
"Namespaces are one honking great idea -- let's do more of those!\n"
]
}
],
"source": [
"import this"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"### Jupyter Notebook Aspects"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"#### The Order of Code Cells is arbitrary"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"We can run the code cells in a Jupyter notebook in *any* arbitrary order.\n",
"\n",
"That means, for example, that a variable defined towards the bottom could accidentally be referenced at the top of the notebook. This happens quickly when we iteratively built a program and go back and forth between cells.\n",
"\n",
"As a good practice, it is recommended to click on \"Kernel\" > \"Restart Kernel and Run All Cells\" in the navigation bar once a notebook is finished. That restarts the Python process forgetting all **state** (i.e., all variables) and ensures that the notebook runs top to bottom without any errors the next time it is opened."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"#### Notebooks are linear"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"While this book is built with Jupyter notebooks, it is crucial to understand that \"real\" programs are almost never \"linear\" (i.e., top to bottom) sequences of instructions but instead may take many different **flows of execution**.\n",
"\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 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_nb.png\">](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 an analysis."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Variables vs. Names vs. Identifiers vs. References"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"**Variables** are created with the **[assignment statement <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/reference/simple_stmts.html#assignment-statements)** `=`, which is *not* an operator because of its *side effect* of making a **[name <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/reference/lexical_analysis.html#identifiers)** reference an object in memory.\n",
"\n",
"We read the terms **variable**, **name**, and **identifier** used interchangebly in many Python-related texts. In this book, we adopt the following convention: First, we treat *name* and *identifier* as perfect synonyms but only use the term *name* in the text for clarity. Second, whereas *name* only refers to a string of letters, numbers, and some other symbols, a *variable* means the combination of a *name* and a *reference* to an object in memory."
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"variable = 20.0"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"When used as a *literal*, a variable evaluates to the value of the object it references. Colloquially, we could say that `variable` evaluates to `20.0`, but this would not be an accurate description of what is going on in memory. We see some more colloquialisms in this section but should always relate this to what Python actually does in memory."
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"20.0"
]
},
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"variable"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"A variable may be **re-assigned** as often as we wish. Thereby, we could also assign an object of a *different* type. Because this is allowed, Python is said to be a **dynamically typed** language. On the contrary, a **statically typed** language like C also allows re-assignment but only with objects of the *same* type. This subtle distinction is one reason why Python is slower at execution than C: As it runs a program, it needs to figure out an object's type each time it is referenced."
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"variable = 20"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"20"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"variable"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"If we want to re-assign a variable while referencing its \"old\" (i.e., current) object, we may also **update** it using a so-called **[augmented assignment statement <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/reference/simple_stmts.html#augmented-assignment-statements)** (i.e., *not* operator), as introduced with [PEP 203 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://www.python.org/dev/peps/pep-0203/): The currently mapped object is implicitly inserted as the first operand on the right-hand side."
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"variable *= 4 # same as variable = variable * 4"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"80"
]
},
"execution_count": 65,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"variable"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"variable //= 2 # same as variable = variable // 2; \"//\" to retain the integer type"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"40"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"variable"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"variable += 2 # same as variable = variable + 2"
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"42"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"variable"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Variables are **[dereferenced <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/reference/simple_stmts.html#the-del-statement)** (i.e., \"deleted\") with the `del` statement. This does *not* delete the object a variable references but merely removes the variable's name from the \"global list of all names.\""
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"42"
]
},
"execution_count": 70,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"variable"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"del variable"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"If we refer to an unknown name, a *runtime* error occurs, namely a `NameError`. The `Name` in `NameError` gives a hint why we choose the term *name* over *identifier* above: Python uses it more often in its error messages."
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'variable' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-72-1748287bc46a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mvariable\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mNameError\u001b[0m: name 'variable' is not defined"
]
}
],
"source": [
"variable"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Some variables magically exist when a Python process is started or are added by Jupyter. We may safely ignore the former until Chapter 10 and the latter for good."
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'__main__'"
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"__name__"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"To see all defined names, the built-in function [dir() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#dir) is helpful."
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"text/plain": [
"['In',\n",
" 'Out',\n",
" 'YouTubeVideo',\n",
" '_',\n",
" '_10',\n",
" '_11',\n",
" '_12',\n",
" '_13',\n",
" '_14',\n",
" '_15',\n",
" '_16',\n",
" '_17',\n",
" '_18',\n",
" '_19',\n",
" '_2',\n",
" '_20',\n",
" '_21',\n",
" '_22',\n",
" '_23',\n",
" '_24',\n",
" '_25',\n",
" '_26',\n",
" '_28',\n",
" '_29',\n",
" '_31',\n",
" '_32',\n",
" '_33',\n",
" '_34',\n",
" '_35',\n",
" '_36',\n",
" '_37',\n",
" '_38',\n",
" '_39',\n",
" '_4',\n",
" '_41',\n",
" '_42',\n",
" '_43',\n",
" '_44',\n",
" '_45',\n",
" '_46',\n",
" '_5',\n",
" '_52',\n",
" '_53',\n",
" '_56',\n",
" '_58',\n",
" '_61',\n",
" '_63',\n",
" '_65',\n",
" '_67',\n",
" '_69',\n",
" '_70',\n",
" '_73',\n",
" '_9',\n",
" '__',\n",
" '___',\n",
" '__builtin__',\n",
" '__builtins__',\n",
" '__doc__',\n",
" '__loader__',\n",
" '__name__',\n",
" '__package__',\n",
" '__spec__',\n",
" '_dh',\n",
" '_i',\n",
" '_i1',\n",
" '_i10',\n",
" '_i11',\n",
" '_i12',\n",
" '_i13',\n",
" '_i14',\n",
" '_i15',\n",
" '_i16',\n",
" '_i17',\n",
" '_i18',\n",
" '_i19',\n",
" '_i2',\n",
" '_i20',\n",
" '_i21',\n",
" '_i22',\n",
" '_i23',\n",
" '_i24',\n",
" '_i25',\n",
" '_i26',\n",
" '_i27',\n",
" '_i28',\n",
" '_i29',\n",
" '_i3',\n",
" '_i30',\n",
" '_i31',\n",
" '_i32',\n",
" '_i33',\n",
" '_i34',\n",
" '_i35',\n",
" '_i36',\n",
" '_i37',\n",
" '_i38',\n",
" '_i39',\n",
" '_i4',\n",
" '_i40',\n",
" '_i41',\n",
" '_i42',\n",
" '_i43',\n",
" '_i44',\n",
" '_i45',\n",
" '_i46',\n",
" '_i47',\n",
" '_i48',\n",
" '_i49',\n",
" '_i5',\n",
" '_i50',\n",
" '_i51',\n",
" '_i52',\n",
" '_i53',\n",
" '_i54',\n",
" '_i55',\n",
" '_i56',\n",
" '_i57',\n",
" '_i58',\n",
" '_i59',\n",
" '_i6',\n",
" '_i60',\n",
" '_i61',\n",
" '_i62',\n",
" '_i63',\n",
" '_i64',\n",
" '_i65',\n",
" '_i66',\n",
" '_i67',\n",
" '_i68',\n",
" '_i69',\n",
" '_i7',\n",
" '_i70',\n",
" '_i71',\n",
" '_i72',\n",
" '_i73',\n",
" '_i74',\n",
" '_i8',\n",
" '_i9',\n",
" '_ih',\n",
" '_ii',\n",
" '_iii',\n",
" '_oh',\n",
" 'a',\n",
" 'audience',\n",
" 'average',\n",
" 'b',\n",
" 'c',\n",
" 'count',\n",
" 'evens',\n",
" 'exit',\n",
" 'get_ipython',\n",
" 'greeting',\n",
" 'number',\n",
" 'numbers',\n",
" 'quit',\n",
" 'this',\n",
" 'total']"
]
},
"execution_count": 74,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dir()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Naming Conventions"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[Phil Karlton](https://skeptics.stackexchange.com/questions/19836/has-phil-karlton-ever-said-there-are-only-two-hard-things-in-computer-science) famously noted during his time at [Netscape <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](https://en.wikipedia.org/wiki/Netscape):\n",
"\n",
"> \"There are *two* hard problems in computer science: *naming things* and *cache invalidation* ... and *off-by-one* errors.\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Variable names may contain upper and lower case letters, numbers, and underscores (i.e., `_`) and be as long as we want them to be. However, they must not begin with a number. Also, they must not be any of Python's built-in **[keywords <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/reference/lexical_analysis.html#keywords)** like `for` or `if`.\n",
"\n",
"Variable names should be chosen such that they do not need any more documentation and are self-explanatory. A widespread convention is to use so-called **[snake\\_case <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](https://en.wikipedia.org/wiki/Snake_case)**: Keep everything lowercase and use underscores to separate words.\n",
"\n",
"See this [link <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](https://en.wikipedia.org/wiki/Naming_convention_%28programming%29#Python_and_Ruby) for a comparison of different naming conventions."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"#### Good examples"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"pi = 3.14"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"answer_to_everything = 42"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"my_name = \"Alexander\""
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"work_address = \"WHU, Burgplatz 2, Vallendar\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"#### Bad examples"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"PI = 3.14 # unless used as a \"global\" constant"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"answerToEverything = 42 # this is a style used in languages like Java"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"name = \"Alexander\" # name of what?"
]
},
{
"cell_type": "code",
"execution_count": 82,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"ename": "SyntaxError",
"evalue": "can't assign to operator (<ipython-input-82-ec51dae29567>, line 1)",
"output_type": "error",
"traceback": [
"\u001b[0;36m File \u001b[0;32m\"<ipython-input-82-ec51dae29567>\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m address@work = \"WHU, Burgplatz 2, Vallendar\"\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m can't assign to operator\n"
]
}
],
"source": [
"address@work = \"WHU, Burgplatz 2, Vallendar\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"If a variable name collides with a built-in name, we add a trailing underscore."
]
},
{
"cell_type": "code",
"execution_count": 83,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"type_ = \"student\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Variables with leading and trailing double underscores, referred to as **dunder** in Python jargon, are used for built-in functionalities and to implement object-oriented features as we see in Chapter 10. We must *not* use this style for variables!"
]
},
{
"cell_type": "code",
"execution_count": 84,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"text/plain": [
"'__main__'"
]
},
"execution_count": 84,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"__name__"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Who am I? And how many?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"It is *crucial* to understand that *several* variables may reference the *same* object in memory. Not having this in mind may lead to many hard to track down bugs.\n",
"\n",
"Let's make `b` reference whatever object `a` is referencing."
]
},
{
"cell_type": "code",
"execution_count": 85,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"a = 42"
]
},
{
"cell_type": "code",
"execution_count": 86,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"b = a"
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"42"
]
},
"execution_count": 87,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"b"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"For \"simple\" types like `int` or `float` this never causes troubles.\n",
"\n",
"Let's \"change the value\" of `a`. To be precise, let's create a *new* `87` object and make `a` reference it."
]
},
{
"cell_type": "code",
"execution_count": 88,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"a = 87"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"87"
]
},
"execution_count": 89,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"`b` \"is still the same\" as before. To be precise, `b` still references the *same object* as before."
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"42"
]
},
"execution_count": 90,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"b"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"However, if a variable references an object of a more \"complex\" type (e.g., `list`), predicting the outcome of a code snippet may be unintuitive for a beginner."
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"x = [1, 2, 3]"
]
},
{
"cell_type": "code",
"execution_count": 92,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"text/plain": [
"list"
]
},
"execution_count": 92,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"type(x)"
]
},
{
"cell_type": "code",
"execution_count": 93,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"y = x"
]
},
{
"cell_type": "code",
"execution_count": 94,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"[1, 2, 3]"
]
},
"execution_count": 94,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Let's change the first element of `x`.\n",
"\n",
"[Chapter 7 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_nb.png\">](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 yet another operator, namely the **indexing operator**. So, `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 we put in the list. The indexing operator must be an operator as we merely *read* the first element and do not change anything in memory permanently.\n",
"\n",
"Python **begins counting at 0**. This is not the case for many other languages, for example, [MATLAB <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](https://en.wikipedia.org/wiki/MATLAB), [R <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](https://en.wikipedia.org/wiki/R_%28programming_language%29), or [Stata <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](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 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_wiki.png\">](https://en.wikipedia.org/wiki/Edsger_W._Dijkstra)."
]
},
{
"cell_type": "code",
"execution_count": 95,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"1"
]
},
"execution_count": 95,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x[0]"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"To change the first entry in the list, we use the assignment statement `=` again. Here, this does *not* create a *new* variable, nor overwrite an existing one, but only changes the object referenced as the first element in `x`. As we only change parts of the `x` object, we say that we **mutate** its **state**. To use the bag analogy from above, we keep the same bag but \"flip\" some of the $0$s into $1$s and some of the $1$s into $0$s."
]
},
{
"cell_type": "code",
"execution_count": 96,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"x[0] = 99"
]
},
{
"cell_type": "code",
"execution_count": 97,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"[99, 2, 3]"
]
},
"execution_count": 97,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The changes made to the object `x` is referencing can also be seen through the `y` variable!"
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"[99, 2, 3]"
]
},
"execution_count": 98,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The difference in behavior illustrated in this sub-section has to do with the fact that `int` and `float` objects are **immutable** types while `list` objects are **mutable**.\n",
"\n",
"In the first case, an object cannot be changed \"in place\" once it is created in memory. When we assigned `87` to the already existing `a`, we did *not* change the $0$s and $1$s in the object `a` referenced before the assignment but created a new `int` object and made `a` reference it while the `b` variable is *not* affected.\n",
"\n",
"In the second case, `x[0] = 99` creates a *new* `int` object `99` and merely changes the first reference in the `x` list.\n",
"\n",
"In general, the assignment statement creates a new name and makes it reference whatever object is on the right-hand side *iff* the left-hand side is a *pure* name (i.e., it contains no operators like the indexing operator in the example). Otherwise, it *mutates* an already existing object. And, we must always expect that the latter may have more than one variable referencing it.\n",
"\n",
"Visualizing what is going on in memory with a tool like [PythonTutor <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](http://pythontutor.com/visualize.html#code=x%20%3D%20%5B1,%202,%203%5D%0Ay%20%3D%20x%0Ax%5B0%5D%20%3D%2099%0Aprint%28y%5B0%5D%29&cumulative=false&curInstr=0&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false) may be helpful for a beginner."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Expressions"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"An **[expression <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/reference/expressions.html)** is any syntactically correct *combination* of *variables* and *literals* with *operators*.\n",
"\n",
"In simple words, anything that may be used on the right-hand side of an assignment statement without creating a `SyntaxError` is an expression.\n",
"\n",
"What we say about *individual* operators above, namely that they have *no* permanent side effects in memory, should be put here, to begin with: The absence of any permanent side effects is the characteristic property of expressions, and all the code cells in the \"*(Arithmetic) Operators*\" section above contain only expressions!\n",
"\n",
"The simplest possible expressions contain only one variable or literal."
]
},
{
"cell_type": "code",
"execution_count": 99,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"87"
]
},
"execution_count": 99,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a"
]
},
{
"cell_type": "code",
"execution_count": 100,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"42"
]
},
"execution_count": 100,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"42"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"For sure, we need to include operators to achieve something useful."
]
},
{
"cell_type": "code",
"execution_count": 101,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"45"
]
},
"execution_count": 101,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a - 42"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The definition of an expression is **recursive**. So, the sub-expression `a - 42` is combined with the literal `9` by the operator `//` to form the full expression `(a - 42) // 9`."
]
},
{
"cell_type": "code",
"execution_count": 102,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"5"
]
},
"execution_count": 102,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(a - 42) // 9"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Here, the variable `x` is combined with the literal `2` by the indexing operator `[]`. The resulting expression evaluates to the third element in the `x` list."
]
},
{
"cell_type": "code",
"execution_count": 103,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 103,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x[2]"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"When not used as a delimiter, parentheses also constitute an operator, namely the **call operator** `()`. We saw this syntax above when we called built-in functions and methods."
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"text/plain": [
"104"
]
},
"execution_count": 104,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sum(x)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Statements"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"A **[statement <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/reference/simple_stmts.html)** is anything that *changes* the *state of a program* or has another permanent *side effect*. Statements, unlike expressions, do not evaluate to a value; instead, they create or change values.\n",
"\n",
"Most notably, of course, are the `=` and `del` statements."
]
},
{
"cell_type": "code",
"execution_count": 105,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"a = 42"
]
},
{
"cell_type": "code",
"execution_count": 106,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"del a"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"The built-in [print() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#print) function is sometimes regarded as a \"statement\" as well. It used to be an actual statement in Python 2 and has all the necessary properties. It is a bit of a corner case but we can think of it as changing the state of the screen."
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"I change the state of the computer's display\n"
]
}
],
"source": [
"print(\"I change the state of the computer's display\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Comments"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"We use the `#` symbol to write comments in plain English right into the code.\n",
"\n",
"As a good practice, comments should *not* describe *what* happens. This should be evident by reading the code. Otherwise, it is most likely badly written code. Rather, comments should describe *why* something happens.\n",
"\n",
"Comments may be added either at the end of a line of code, by convention separated with two spaces, or on a line on their own."
]
},
{
"cell_type": "code",
"execution_count": 108,
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"outputs": [],
"source": [
"distance = 891 # in meters\n",
"elapsed_time = 93 # in seconds\n",
"\n",
"# Calculate the speed in km/h.\n",
"speed = 3.6 * distance / elapsed_time"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"But let's think wisely if we need to use a comment.\n",
"The second cell is a lot more Pythonic."
]
},
{
"cell_type": "code",
"execution_count": 109,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"seconds = 365 * 24 * 60 * 60 # = seconds in the year"
]
},
{
"cell_type": "code",
"execution_count": 110,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"seconds_per_year = 365 * 24 * 60 * 60"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"## TL;DR"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"We end each chapter with a summary of the main points (i.e., **TL;DR** = \"too long; didn't read\"). The essence in this first chapter is that just as a sentence in a real language like English may be decomposed into its parts (e.g., subject, predicate, and objects), the same may be done with programming languages.\n",
"\n",
"- program\n",
" - **sequence** of **instructions** that specify how to perform a computation (= a \"recipe\")\n",
" - a \"black box\" that processes **inputs** and transforms them into meaningful **outputs** in a *deterministic* way\n",
" - conceptually similar to a mathematical function $f$ that maps some input $x$ to an output $y = f(x)$\n",
"\n",
"\n",
"- input (examples)\n",
" - data from a CSV file\n",
" - text entered on a command line\n",
" - data obtained from a database\n",
" - etc.\n",
"\n",
"\n",
"- output (examples)\n",
" - result of a computation (e.g., statistical summary of a sample dataset)\n",
" - a \"side effect\" (e.g., a transformation of raw input data into cleaned data)\n",
" - a physical \"behavior\" (e.g., a robot moving or a document printed)\n",
" - etc.\n",
"\n",
"\n",
"- objects\n",
" - 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 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",
"- variables\n",
" - storage of intermediate **state**\n",
" - are **names** referencing **objects** in **memory**\n",
" - e.g., `x = 1` creates the variable `x` that references the object `1`\n",
"\n",
"\n",
"- operators\n",
" - special built-in symbols that perform operations with objects in memory\n",
" - usually, operate with one or two objects\n",
" - e.g., addition `+`, subtraction `-`, multiplication `*`, and division `/` all take two objects, whereas the negation `-` only takes one\n",
"\n",
"\n",
"- expressions\n",
" - **combinations** of **variables** (incl. **literals**) and **operators**\n",
" - do *not* change the involved objects/state of the program\n",
" - evaluate to a **value** (i.e., the \"result\" of the expression, usually a new object)\n",
" - e.g., `x + 2` evaluates to the (new) object `3` and `1 - 1.0` to `0.0`\n",
"\n",
"\n",
"- statements\n",
" - instructions that **\"do\" something** and **have side effects** in memory\n",
" - (re-)assign names to (different) objects, *change* an existing object *in place*, or, more conceptually, *change* the state of the program\n",
" - usually, work with expressions\n",
" - e.g., the assignment statement `=` makes a name reference an object\n",
"\n",
"\n",
"- comments\n",
" - **prose** supporting a **human's understanding** of the program\n",
" - ignored by Python\n",
"\n",
"\n",
"- functions (cf., [Chapter 2 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_nb.png\">](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 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html) like [print() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#print), [sum() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#sum), or [len() <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_py.png\">](https://docs.python.org/3/library/functions.html#len)\n",
"\n",
"\n",
"- flow control (cf., [Chapter 3 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_nb.png\">](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals_00_content.ipynb) and [Chapter 4 <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_nb.png\">](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration_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": [
"A lecture-style **video presentation** of this chapter is integrated below (cf., the [video <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_yt.png\">](https://www.youtube.com/watch?v=v0lk1Qfaw8Y&list=PL-2JV1G3J10lQ2xokyQowcRJI5jjNfW7f) or the entire [playlist <img height=\"12\" style=\"display: inline-block\" src=\"static/link_to_yt.png\">](https://www.youtube.com/playlist?list=PL-2JV1G3J10lQ2xokyQowcRJI5jjNfW7f))."
]
},
{
"cell_type": "code",
"execution_count": 111,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"image/jpeg": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAUDBAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChALCAgOCggIDRYNDhERExMTCAsWGBYSGBASExIBBQUFCAcIDwkJDxgVERUWFxcYExMYGBgVFRgWFRYWGBcVGxIaEhMXFRoYGBISFRcVFRUVFRUVFRUVGBUSFxIVFf/AABEIAWgB4AMBIgACEQEDEQH/xAAdAAEAAgIDAQEAAAAAAAAAAAAABgcFCAIDBAEJ/8QAURAAAQQBAgMBCQgRAgUEAgMAAQACAwQRBRIGEyExBxQYIjJBVZTVCBUXUVJhk9QjMzVCU1RxcnN0dYGSsbKz05G0FiQ2YrU0gqGiY3YlQ0X/xAAcAQEAAgMBAQEAAAAAAAAAAAAAAgQBAwUHBgj/xAA9EQABAwIDBQUGBAYBBQEAAAABAAIRAyEEEjEFQVFhcRMVU4GRBiIyocHwFjRysRQ1QlLR4fEjM0NigpL/2gAMAwEAAhEDEQA/ANMkREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREWzPgVcVfj/D/AK1qPs5PAq4q/H+H/WtR9nIi1mRbM+BVxV+P8P8ArWo+zk8Crir8f4f9a1H2ciLWZFsz4FXFX4/w/wCtaj7OTwKuKvx/h/1rUfZyItZkWzPgVcVfj/D/AK1qPs5PAq4q/H+H/WtR9nIi1mRbM+BVxV+P8P8ArWo+zk8Crir8f4f9a1H2ciLWZFsz4FXFX4/w/wCtaj7OTwKuKvx/h/1rUfZyItZkWzPgVcVfj/D/AK1qPs5PAq4q/H+H/WtR9nIi1mRbM+BVxV+P8P8ArWo+zk8Crir8f4f9a1H2ciLWZFsz4FXFX4/w/wCtaj7OTwKuKvx/h/1rUfZyItZkWzPgVcVfj/D/AK1qPs5PAq4q/H+H/WtR9nIi1mRbM+BVxV+P8P8ArWo+zk8Crir8f4f9a1H2ciLWZFsz4FXF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hodQ0EBkkco21dQ8qJ4e0HOodmWhZBgrB0X6DItAPDV4q9H8P+q6j7RTw1eKvR/D/quo+0VhZW/6LQDw1eKvR/D/AKrqPtFPDV4q9H8P+q6j7RRFv+i0A8NXir0fw/6rqPtFPDV4q9H8P+q6j7RRFv8AotAPDV4q9H8P+q6j7RTw1eKvR/D/AKrqPtFEW/6LQDw1eKvR/D/quo+0U8NXir0fw/6rqPtFEW/6LQDw1eKvR/D/AKrqPtFPDV4q9H8P+q6j7RRFv+i0A8NXir0fw/6rqPtFPDV4q9H8P+q6j7RRFv8AotAPDV4q9H8P+q6j7RTw1eKvR/D/AKrqPtFEW/6LQDw1eKvR/D/quo+0U8NXir0fw/6rqPtFEW/6LQDw1eKvR/D/AKrqPtFPDV4q9H8P+q6j7RRFv+i0A8NXir0fw/6rqPtFPDV4q9H8P+q6j7RRFv8AotAPDV4q9H8P+q6j7RTw1eKvR/D/AKrqPtFEW/6LQDw1eKvR/D/quo+0U8NXir0fw/6rqPtFEW/682q/aJ/0Mn9DloT4avFXo/h/1XUfaK4WPdo8UvY9hoaBh7XNOKuo5w4EHGdR7eqItaURERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERERf/2Q==\n",
"text/html": [
"\n",
" <iframe\n",
" width=\"60%\"\n",
" height=\"300\"\n",
" src=\"https://www.youtube.com/embed/v0lk1Qfaw8Y\"\n",
" frameborder=\"0\"\n",
" allowfullscreen\n",
" ></iframe>\n",
" "
],
"text/plain": [
"<IPython.lib.display.YouTubeVideo at 0x7fdce0060310>"
]
},
"execution_count": 111,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"YouTubeVideo(\"v0lk1Qfaw8Y\", width=\"60%\")"
]
},
{
"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": 112,
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [
{
"data": {
"image/jpeg": "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\n",
"text/html": [
"\n",
" <iframe\n",
" width=\"60%\"\n",
" height=\"300\"\n",
" src=\"https://www.youtube.com/embed/_AEJHKGk9ns\"\n",
" frameborder=\"0\"\n",
" allowfullscreen\n",
" ></iframe>\n",
" "
],
"text/plain": [
"<IPython.lib.display.YouTubeVideo at 0x7fdce00600d0>"
]
},
"execution_count": 112,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"YouTubeVideo(\"_AEJHKGk9ns\", width=\"60%\")"
]
}
],
"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"
},
"livereveal": {
"auto_select": "code",
"auto_select_fragment": true,
"scroll": true,
"theme": "serif"
},
"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": {
"height": "calc(100% - 180px)",
"left": "10px",
"top": "150px",
"width": "303.333px"
},
"toc_section_display": false,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 4
}