Streamline previous content

This commit is contained in:
Alexander Hess 2019-10-01 17:47:45 +02:00
commit 250aa09209
7 changed files with 181 additions and 104 deletions

View file

@ -19,7 +19,7 @@
}
},
"source": [
"We analyzed every aspect of the `average_evens()` function in Chapter 2 except for the `if` part. While it seems to intuitively do what we expect it to, there is a whole lot more to be learned from taking it apart. In particular, the `if` can occur within both a **statement** as in our introductory example in Chapter 1 but also an **expression** as in `average_evens()`. This is 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 versions of the `if` 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.ipynb) except for the `if` part. While it seems to intuitively do what we expect it to, there is a whole lot more to be learned from taking it apart. In particular, the `if` can occur within both a **statement** as in our introductory example in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb) but also an **expression** as in `average_evens()`. This is 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 versions of the `if` 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 and raising **exceptions**."
]
@ -139,7 +139,7 @@
}
},
"source": [
"There are, however, cases where even well-behaved Python does not make us happy. Chapter 5 will provide more insights on that."
"There are, however, cases where even well-behaved Python does not make us happy. Chapter 5 will provide more insights on this \"bug\"."
]
},
{
@ -189,7 +189,7 @@
{
"data": {
"text/plain": [
"94709180875744"
"94163040564192"
]
},
"execution_count": 5,
@ -213,7 +213,7 @@
{
"data": {
"text/plain": [
"94709180875712"
"94163040564160"
]
},
"execution_count": 6,
@ -281,9 +281,9 @@
}
},
"source": [
"Let's not confuse the boolean `False` with `None`, another special built-in object! We saw the latter before in Chapter 2 as the *implicit* return value of a function without a `return` statement.\n",
"Let's not confuse the boolean `False` with `None`, another special 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) 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. But for Python, there are no \"maybe\" or \"unknown\" objects as we will see further below!\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 will see further below!\n",
"\n",
"Whereas `False` is of type `bool`, `None` is of type `NoneType`. So, they are totally unrelated. On the contrary, as both `True` and `False` are of the same type, we could call them \"siblings\"."
]
@ -313,7 +313,7 @@
{
"data": {
"text/plain": [
"94709180862704"
"94163040551152"
]
},
"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 will never mutate its value in place (i.e., to re-use the bag analogy from Chapter 1, 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 already 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 will *not* mutate its value (i.e., to re-use the bag analogy from [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb), 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 already built in for *some* types.\n",
"\n",
"We can verify this with either the `is` operator or by comparing memory addresses."
]
@ -512,7 +512,7 @@
}
],
"source": [
"42 != 123 # = \"not equal to\"; other programming languages sometimes use \"<>\" instead"
"42 != 123 # = \"not equal to\"; other languages may use \"<>\""
]
},
{
@ -672,7 +672,7 @@
}
},
"source": [
"Relational operators have a *higher precedence* over logical operators (cf., the [reference](https://docs.python.org/3/reference/expressions.html#operator-precedence)). So the following expression means what we intuitively think it does."
"Relational operators have a **[higher precedence](https://docs.python.org/3/reference/expressions.html#operator-precedence)** over logical operators. So the following expression means what we intuitively think it does."
]
},
{
@ -825,7 +825,7 @@
}
},
"source": [
"For even better readability, [some practitioner](https://llewellynfalco.blogspot.com/2016/02/dont-use-greater-than-sign-in.html) suggest to never use the `>` and `>=` operators (note that the included example is written in [Java](https://en.wikipedia.org/wiki/Java_%28programming_language%29) and `&&` means `and` and `||` means `or`).\n",
"For even better readability, [some practitioners](https://llewellynfalco.blogspot.com/2016/02/dont-use-greater-than-sign-in.html) suggest to *never* use the `>` and `>=` operators (note that the included example is written in [Java](https://en.wikipedia.org/wiki/Java_%28programming_language%29) and `&&` means `and` and `||` means `or`).\n",
"\n",
"Python allows **chaining** relational operators that are combined with the `and` operator. For example, the following two cells implement the same logic where the second is a lot easier to read."
]
@ -899,7 +899,7 @@
"source": [
"The operands of the logical operators do not actually have to be *boolean* expressions as defined above but may be *any* kind of expression. If a sub-expression does *not* evaluate to an object of type `bool`, Python automatically casts the resulting object as such.\n",
"\n",
"For example, any non-zero numeric object effectively becomes `True`. While this behavior allows writing more concise and thus \"beautiful\" code, it is also a common source of confusion."
"For example, any non-zero numeric object becomes `True`. While this behavior allows writing conciser and thus more \"beautiful\" code, it is also a common source of confusion."
]
},
{
@ -1028,7 +1028,7 @@
}
},
"source": [
"In a boolean context `None` is casted as `False`. So, `None` is really *not* a \"maybe\" answer but a \"no\"."
"In a boolean context, `None` is casted as `False`! So, `None` is really *not* a \"maybe\" answer but a \"no\"."
]
},
{
@ -1144,9 +1144,9 @@
}
},
"source": [
"In order to write useful programs, we need to control the flow of execution, for example, to react to user input.\n",
"In order to write useful programs, we need to control the flow of execution, for example, to react to user input. The logic by which a program does that is referred to as **business logic**.\n",
"\n",
"One major language construct to do so is the **conditional statement** or `if` **statement** (cf., the [reference](https://docs.python.org/3/reference/compound_stmts.html#the-if-statement)). It consists of:\n",
"One major language construct to do so is the **[conditional statement](https://docs.python.org/3/reference/compound_stmts.html#the-if-statement)** or `if` statement. It consists of:\n",
"\n",
"- *one* mandatory `if`-clause,\n",
"- an *arbitrary* number of `elif`-clauses (i.e. \"else if\"), and\n",
@ -1350,7 +1350,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"z is positive\n"
"z is odd\n"
]
}
],
@ -1602,7 +1602,7 @@
"source": [
"In the previous two chapters we already encountered a couple of *runtime* errors. A natural urge we might have after reading about conditional statements is to write code that somehow reacts to the occurence of such exceptions. All we need for that is a way to formulate a condition for that.\n",
"\n",
"For sure, this is such a common thing to do that Python provides its own language construct for it, namely the `try` statement (cf., the [reference](https://docs.python.org/3/reference/compound_stmts.html#the-try-statement)).\n",
"For sure, this is such a common thing to do that Python provides its own language construct for it, namely the `try` [statement](https://docs.python.org/3/reference/compound_stmts.html#the-try-statement).\n",
"\n",
"In its simplest form, it comes with just two branches: `try` and `except`. The following basically tells Python to execute the code in the `try`-branch and if *anything* goes wrong, continue in the `except`-branch instead of **raising** an error to us. Of course, if nothing goes wrong, the `except`-branch is *not* executed."
]
@ -1711,7 +1711,7 @@
"name": "stdout",
"output_type": "stream",
"text": [
"Yes, division worked smoothly.\n",
"Oops. Division by 0. How does that work?\n",
"I am always printed\n"
]
}
@ -1748,7 +1748,7 @@
}
},
"source": [
"- **boolean expressions** evaluate either to `True` or `False`\n",
"- **boolean expressions** evaluate to either `True` or `False`\n",
"- **relational operators** compare operands according to \"human\" interpretations\n",
"- **logical operators** combine boolean sub-expressions to more \"complex\" expressions\n",
"- the **conditional statement** is a *major* concept to **control** the **flow of execution** depending on some **conditions**\n",