Streamline previous content

This commit is contained in:
Alexander Hess 2019-11-06 11:10:29 +01:00
commit 8fd14a614d
6 changed files with 393 additions and 384 deletions

View file

@ -21,7 +21,7 @@
"source": [
"After learning about the basic building blocks of expressing and structuring the business logic in programs, we focus our attention on the **data types** Python offers us, both built-in and available via the [standard library](https://docs.python.org/3/library/index.html) or third-party packages.\n",
"\n",
"We start with the \"simple\" ones: Numerical types in this chapter and textual data in [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb). An important fact that holds for all objects of these types is that they are **immutable**. To re-use the bag analogy from [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Objects-vs.-Types-vs.-Values), this means that the $0$s and $1$s making up an object's *value* cannot be changed once the bag is created in memory, implying that any operation with or method on the object creates a *new* object in a *different* memory location.\n",
"We start with the \"simple\" ones: Numeric types in this chapter and textual data in [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb). An important fact that holds for all objects of these types is that they are **immutable**. To re-use the bag analogy from [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#Objects-vs.-Types-vs.-Values), this means that the $0$s and $1$s making up an object's *value* cannot be changed once the bag is created in memory, implying that any operation with or method on the object creates a *new* object in a *different* memory location.\n",
"\n",
"[Chapter 7](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/07_sequences.ipynb) and Chapter 8 then cover the more \"complex\" data types, including, for example, the `list` type. Finally, Chapter 9 completes the picture by introducing language constructs to create custom types.\n",
"\n",
@ -31,7 +31,7 @@
"- [Chapter 3](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/03_conditionals.ipynb#Boolean-Expressions) raises questions regarding the **limited precision** of `float` numbers (e.g., `42 == 42.000000000000001` evaluates to `True`), and\n",
"- [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Infinite-Recursion) shows that sometimes a `float` \"walks\" and \"quacks\" like an `int`, whereas the reverse is true in other cases.\n",
"\n",
"This chapter introduces all the [built-in numerical types](https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex): `int`, `float`, and `complex`. To mitigate the limited precision of floating-point numbers, we also look at two replacements for the `float` type in the [standard library](https://docs.python.org/3/library/index.html), namely the `Decimal` type in the [decimals](https://docs.python.org/3/library/decimal.html#decimal.Decimal) and the `Fraction` type in the [fractions](https://docs.python.org/3/library/fractions.html#fractions.Fraction) module."
"This chapter introduces all the [built-in numeric types](https://docs.python.org/3/library/stdtypes.html#numeric-types-int-float-complex): `int`, `float`, and `complex`. To mitigate the limited precision of floating-point numbers, we also look at two replacements for the `float` type in the [standard library](https://docs.python.org/3/library/index.html), namely the `Decimal` type in the [decimals](https://docs.python.org/3/library/decimal.html#decimal.Decimal) and the `Fraction` type in the [fractions](https://docs.python.org/3/library/fractions.html#fractions.Fraction) module."
]
},
{
@ -53,7 +53,7 @@
}
},
"source": [
"The simplest numerical type is the `int` type: It behaves like an [integer in ordinary math](https://en.wikipedia.org/wiki/Integer) (i.e., the set $\\mathbb{Z}$) and supports operators in the way we saw in the section on arithmetic operators in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#%28Arithmetic%29-Operators)."
"The simplest numeric type is the `int` type: It behaves like an [integer in ordinary math](https://en.wikipedia.org/wiki/Integer) (i.e., the set $\\mathbb{Z}$) and supports operators in the way we saw in the section on arithmetic operators in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#%28Arithmetic%29-Operators)."
]
},
{
@ -92,7 +92,7 @@
{
"data": {
"text/plain": [
"139630197982416"
"140087541220560"
]
},
"execution_count": 2,
@ -160,7 +160,7 @@
}
},
"source": [
"A nice feature is using underscores `_` as (thousands) separator in numerical literals. For example, `1_000_000` evaluates to `1000000` in memory."
"A nice feature is using underscores `_` as (thousands) separator in numeric literals. For example, `1_000_000` evaluates to `1000000` in memory."
]
},
{
@ -1165,7 +1165,7 @@
}
},
"source": [
"Whereas the boolean literals `True` and `False` are commonly *not* regarded as numerical types, they behave like `1` and `0` in an arithmetic context."
"Whereas the boolean literals `True` and `False` are commonly *not* regarded as numeric types, they behave like `1` and `0` in an arithmetic context."
]
},
{
@ -2115,7 +2115,7 @@
{
"data": {
"text/plain": [
"139630198164096"
"140087541402072"
]
},
"execution_count": 63,
@ -2218,7 +2218,7 @@
}
},
"source": [
"In cases where the dot `.` is unnecessary from a mathematical point of view, we either need to end the number with it nevertheless or use the [float()](https://docs.python.org/3/library/functions.html#float) built-in to cast the number explicitly. [float()](https://docs.python.org/3/library/functions.html#float) can process any numerical object or a properly formatted `str` object."
"In cases where the dot `.` is unnecessary from a mathematical point of view, we either need to end the number with it nevertheless or use the [float()](https://docs.python.org/3/library/functions.html#float) built-in to cast the number explicitly. [float()](https://docs.python.org/3/library/functions.html#float) can process any numeric object or a properly formatted `str` object."
]
},
{
@ -3517,7 +3517,7 @@
"source": [
"The [format()](https://docs.python.org/3/library/functions.html#format) function does *not* round a `float` object in the mathematical sense! It just allows us to show an arbitrary number of the digits as stored in memory, and it also does *not* change these.\n",
"\n",
"On the contrary, the built-in [round()](https://docs.python.org/3/library/functions.html#round) function creates a *new* numerical object that is a rounded version of the one passed in as the argument. It adheres to the common rules of math.\n",
"On the contrary, the built-in [round()](https://docs.python.org/3/library/functions.html#round) function creates a *new* numeric object that is a rounded version of the one passed in as the argument. It adheres to the common rules of math.\n",
"\n",
"For example, let's round `1 / 3` to five decimals. The obtained value for `roughly_a_third` is also *imprecise* but different from the \"exact\" representation of `1 / 3` above."
]
@ -4617,7 +4617,7 @@
}
},
"source": [
"The [quantize()](https://docs.python.org/3/library/decimal.html#decimal.Decimal.quantize) method allows us to [quantize](https://www.dictionary.com/browse/quantize) (i.e., \"round\") a `Decimal` number at any precision that is *smaller* than the set precision. It looks at the number of decimals (i.e., to the right of the period) of the numerical argument we pass in.\n",
"The [quantize()](https://docs.python.org/3/library/decimal.html#decimal.Decimal.quantize) method allows us to [quantize](https://www.dictionary.com/browse/quantize) (i.e., \"round\") a `Decimal` number at any precision that is *smaller* than the set precision. It looks at the number of decimals (i.e., to the right of the period) of the numeric argument we pass in.\n",
"\n",
"For example, as the overall imprecise value of `two` still has an internal precision of `28` digits, we can correctly round it to *four* decimals (i.e., `Decimal(\"0.0001\")` has four decimals)."
]
@ -5498,7 +5498,7 @@
{
"data": {
"text/plain": [
"139630197402224"
"140087540555856"
]
},
"execution_count": 176,
@ -5636,7 +5636,7 @@
}
},
"source": [
"Alternatively, we may use the [complex()](https://docs.python.org/3/library/functions.html#complex) built-in: This takes two parameters where the second is optional and defaults to `0`. We may either call it with one or two arguments of any numerical type or a `str` object in the format of the previous code cell without any spaces."
"Alternatively, we may use the [complex()](https://docs.python.org/3/library/functions.html#complex) built-in: This takes two parameters where the second is optional and defaults to `0`. We may either call it with one or two arguments of any numeric type or a `str` object in the format of the previous code cell without any spaces."
]
},
{
@ -5708,7 +5708,7 @@
}
],
"source": [
"complex(Decimal(\"2.0\"), Fraction(1, 2)) # the arguments may be any numerical type"
"complex(Decimal(\"2.0\"), Fraction(1, 2)) # the arguments may be any numeric type"
]
},
{
@ -5743,7 +5743,7 @@
}
},
"source": [
"Arithmetic expressions work with `complex` numbers. They may be mixed with the other numerical types, and the result is always a `complex` number."
"Arithmetic expressions work with `complex` numbers. They may be mixed with the other numeric types, and the result is always a `complex` number."
]
},
{
@ -6111,7 +6111,7 @@
}
},
"source": [
"Analogous to the discussion of containers and iterables in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Containers-vs.-Iterables), we contrast the *concrete* numerical data types in this chapter with the *abstract* ideas behind [numbers in mathematics](https://en.wikipedia.org/wiki/Number).\n",
"Analogous to the discussion of containers and iterables in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Containers-vs.-Iterables), we contrast the *concrete* numeric data types in this chapter with the *abstract* ideas behind [numbers in mathematics](https://en.wikipedia.org/wiki/Number).\n",
"\n",
"The figure below summarizes five *major* sets of [numbers in mathematics](https://en.wikipedia.org/wiki/Number) as we know them from high school:\n",
"\n",
@ -6723,7 +6723,7 @@
}
},
"source": [
"Replacing *concrete* data types with *abstract* ones is particularly valuable in the context of input validation: The revised version of the `factorial()` function below allows its user to take advantage of *duck typing*: If a real but non-integer argument `n` is passed in, `factorial()` tries to cast `n` as an `int` object with the [trunc()](https://docs.python.org/3/library/math.html#math.trunc) function from the [math](https://docs.python.org/3/library/math.html) module in the [standard library](https://docs.python.org/3/library/index.html). [trunc()](https://docs.python.org/3/library/math.html#math.trunc) cuts off all decimals and any *concrete* numerical type implementing the *abstract* `numbers.Real` type supports it (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Real)).\n",
"Replacing *concrete* data types with *abstract* ones is particularly valuable in the context of input validation: The revised version of the `factorial()` function below allows its user to take advantage of *duck typing*: If a real but non-integer argument `n` is passed in, `factorial()` tries to cast `n` as an `int` object with the [trunc()](https://docs.python.org/3/library/math.html#math.trunc) function from the [math](https://docs.python.org/3/library/math.html) module in the [standard library](https://docs.python.org/3/library/index.html). [trunc()](https://docs.python.org/3/library/math.html#math.trunc) cuts off all decimals and any *concrete* numeric type implementing the *abstract* `numbers.Real` type supports it (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Real)).\n",
"\n",
"Two popular and distinguished Pythonistas, [Luciano Ramalho](https://github.com/ramalho) and [Alex Martelli](https://en.wikipedia.org/wiki/Alex_Martelli), coin the term **goose typing** to specifically mean using the built-in [isinstance()](https://docs.python.org/3/library/functions.html#isinstance) function with an *abstract base class* (cf., Chapter 11 in this [book](https://www.amazon.com/Fluent-Python-Concise-Effective-Programming/dp/1491946008) or this [summary](https://dgkim5360.github.io/blog/python/2017/07/duck-typing-vs-goose-typing-pythonic-interfaces/) thereof)."
]
@ -7015,7 +7015,7 @@
}
},
"source": [
"There exist three numerical types in core Python:\n",
"There exist three numeric types in core Python:\n",
"- `int`: a near-perfect model for whole numbers (i.e., the set $\\mathbb{Z}$); inherently precise\n",
"- `float`: the \"gold\" standard to approximate real numbers (i.e., the set $\\mathbb{R}$); inherently imprecise\n",
"- `complex`: layer on top of the `float` type; therefore inherently imprecise\n",