Streamline previous content
This commit is contained in:
parent
5e71194787
commit
04d53956a3
11 changed files with 1089 additions and 402 deletions
|
|
@ -8,7 +8,7 @@
|
|||
}
|
||||
},
|
||||
"source": [
|
||||
"# Chapter 5: Numbers"
|
||||
"# Chapter 5: Bits & Numbers"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -21,9 +21,9 @@
|
|||
"source": [
|
||||
"After learning about the basic building blocks of expressing and structuring the business logic in programs, we focus our attention on the **data types** Python offers us, both built-in and available via the [standard library](https://docs.python.org/3/library/index.html) or third-party packages.\n",
|
||||
"\n",
|
||||
"We start with the \"simple\" ones: Numeric types in this chapter and textual data in [Chapter 6](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/06_text.ipynb). An important fact that holds for all objects of these types is that they are **immutable**. To 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: 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",
|
||||
"\n",
|
||||
"Chapters 7, 8, and 9 then cover the more \"complex\" data types, including, for example, the `list` type. Finally, Chapter 10 completes the picture by introducing language constructs to create custom types.\n",
|
||||
"[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",
|
||||
"We have already seen many hints indicating that numbers are not as trivial to work with as it seems at first sight:\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 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."
|
||||
"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."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -53,7 +53,7 @@
|
|||
}
|
||||
},
|
||||
"source": [
|
||||
"The simplest numeric type is the `int` type: It behaves like an [integer in ordinary math](https://en.wikipedia.org/wiki/Integer) (i.e., the set $\\mathbb{Z}$) and supports operators in the way we saw in the section on arithmetic operators in [Chapter 1](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/01_elements.ipynb#%28Arithmetic%29-Operators)."
|
||||
"The simplest 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)."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -92,7 +92,7 @@
|
|||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"139928698315984"
|
||||
"139630197982416"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
|
|
@ -160,7 +160,7 @@
|
|||
}
|
||||
},
|
||||
"source": [
|
||||
"A nice feature is using underscores `_` as (thousands) separator in numeric literals. For example, `1_000_000` evaluates to `1000000` in memory."
|
||||
"A nice feature is using underscores `_` as (thousands) separator in numerical 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 numeric types, they behave like `1` and `0` in an arithmetic context."
|
||||
"Whereas the boolean literals `True` and `False` are commonly *not* regarded as numerical types, they behave like `1` and `0` in an arithmetic context."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -2115,7 +2115,7 @@
|
|||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"139928698489496"
|
||||
"139630198164096"
|
||||
]
|
||||
},
|
||||
"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 numeric 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 numerical object or a properly formatted `str` object."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -2242,7 +2242,7 @@
|
|||
}
|
||||
],
|
||||
"source": [
|
||||
"1. # on the contrary, 1 creates an int object"
|
||||
"1. # 1 without a dot creates an int 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* numeric 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* numerical 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 numeric 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 numerical 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": [
|
||||
"139928697740272"
|
||||
"139630197402224"
|
||||
]
|
||||
},
|
||||
"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 numeric 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 numerical 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 numeric type"
|
||||
"complex(Decimal(\"2.0\"), Fraction(1, 2)) # the arguments may be any numerical type"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -5743,7 +5743,7 @@
|
|||
}
|
||||
},
|
||||
"source": [
|
||||
"Arithmetic expressions work with `complex` numbers. They may be mixed with the other numeric types, and the result is always a `complex` number."
|
||||
"Arithmetic expressions work with `complex` numbers. They may be mixed with the other numerical types, and the result is always a `complex` number."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -6100,7 +6100,7 @@
|
|||
}
|
||||
},
|
||||
"source": [
|
||||
"## The Numeric Tower"
|
||||
"## The Numerical Tower"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -6111,7 +6111,7 @@
|
|||
}
|
||||
},
|
||||
"source": [
|
||||
"Analogous to the discussion of containers and iterables in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.ipynb#Containers-vs.-Iterables), we contrast the *concrete* numeric data types in this chapter with the *abstract* ideas behind [numbers in mathematics](https://en.wikipedia.org/wiki/Number).\n",
|
||||
"Analogous to the discussion of containers and iterables in [Chapter 4](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/master/04_iteration.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",
|
||||
"\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",
|
||||
|
|
@ -6149,7 +6149,7 @@
|
|||
"\n",
|
||||
"For the other types, in particular, the `float` type, the implications of their imprecision are discussed in detail above.\n",
|
||||
"\n",
|
||||
"The abstract concepts behind the four outer-most mathematical sets are part of Python since [PEP 3141](https://www.python.org/dev/peps/pep-3141/) in 2007. The [numbers](https://docs.python.org/3/library/numbers.html) module in the [standard library](https://docs.python.org/3/library/index.html) defines what Pythonistas call the **numeric tower**, a collection of five **[abstract data types](https://en.wikipedia.org/wiki/Abstract_data_type)**, or **abstract base classes** as they are called in Python jargon:\n",
|
||||
"The abstract concepts behind the four outer-most mathematical sets are part of Python since [PEP 3141](https://www.python.org/dev/peps/pep-3141/) in 2007. The [numbers](https://docs.python.org/3/library/numbers.html) module in the [standard library](https://docs.python.org/3/library/index.html) defines what programmers call the **[numerical tower](https://en.wikipedia.org/wiki/Numerical_tower)**, a collection of five **[abstract data types](https://en.wikipedia.org/wiki/Abstract_data_type)**, or **abstract base classes** as they are called in Python jargon:\n",
|
||||
"\n",
|
||||
"- `numbers.Number`: \"any number\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Number))\n",
|
||||
"- `numbers.Complex`: \"all complex numbers\" (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Complex))\n",
|
||||
|
|
@ -6712,7 +6712,7 @@
|
|||
}
|
||||
},
|
||||
"source": [
|
||||
"#### Example: [Factorial](https://en.wikipedia.org/wiki/Factorial) (revisited)"
|
||||
"### Goose Typing"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -6723,7 +6723,9 @@
|
|||
}
|
||||
},
|
||||
"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* numeric type implementing the *abstract* `numbers.Real` type supports it (cf., [documentation](https://docs.python.org/3/library/numbers.html#numbers.Real))."
|
||||
"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",
|
||||
"\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)."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -6763,6 +6765,17 @@
|
|||
"math.trunc(1 / 10)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {
|
||||
"slideshow": {
|
||||
"slide_type": "skip"
|
||||
}
|
||||
},
|
||||
"source": [
|
||||
"#### Example: [Factorial](https://en.wikipedia.org/wiki/Factorial) (revisited)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 211,
|
||||
|
|
@ -6893,7 +6906,7 @@
|
|||
}
|
||||
},
|
||||
"source": [
|
||||
"With the keyword-only argument `strict`, we can control whether or not a passed in `float` object may be rounded. By default, this is not allowed."
|
||||
"With the keyword-only argument `strict`, we can control whether or not a passed in `float` object may be rounded. By default, this is not allowed and results in a `TypeError`."
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
@ -7002,21 +7015,21 @@
|
|||
}
|
||||
},
|
||||
"source": [
|
||||
"There exist three numeric types in core Python:\n",
|
||||
"- `int`: a perfect model for whole numbers (i.e., the set $\\mathbb{Z}$); inherently precise\n",
|
||||
"There exist three numerical 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",
|
||||
"\n",
|
||||
"Furthermore, the [standard library](https://docs.python.org/3/library/index.html) adds two more types that can be used as substitutes for `float` objects:\n",
|
||||
"- `Decimal`: similar to `float` but allows customizing the precision; still inherently imprecise\n",
|
||||
"- `Fraction`: a perfect model for rational numbers (i.e., the set $\\mathbb{Q}$); built on top of the `int` type and therefore inherently precise\n",
|
||||
"- `Fraction`: a near-perfect model for rational numbers (i.e., the set $\\mathbb{Q}$); built on top of the `int` type and therefore inherently precise\n",
|
||||
"\n",
|
||||
"The *important* takeaways for the data science practitioner are:\n",
|
||||
"\n",
|
||||
"1. **Do not mix** precise and imprecise data types, and\n",
|
||||
"2. actively expect `nan` results when working with `float` numbers as there are no **loud failures**.\n",
|
||||
"\n",
|
||||
"The **numeric tower** is Python's way of implementing the various **abstract** ideas of what a number is in mathematics."
|
||||
"The **numerical tower** is Python's way of implementing the various **abstract** ideas of what numbers are in mathematics."
|
||||
]
|
||||
}
|
||||
],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue