Add initial version of chapter 11, part 4
This commit is contained in:
parent
8dc67c5bdd
commit
85b7fd274c
9 changed files with 2927 additions and 222 deletions
|
@ -1571,7 +1571,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"source": [
|
"source": [
|
||||||
"Packages are a generalization of modules, and we look at one in detail in [Chapter 11 <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_nb.png\">](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/develop/11_classes/00_content.ipynb). You may, however, already look at a [sample package <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_gh.png\">](https://github.com/webartifex/intro-to-python/tree/develop/11_classes/sample_package) in the repository, which is nothing but a folder with *.py* files in it.\n",
|
"Packages are a generalization of modules, and we look at one in detail in [Chapter 11 <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_nb.png\">](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/develop/11_classes/04_content.ipynb#Packages-vs.-Modules).\n",
|
||||||
"\n",
|
"\n",
|
||||||
"As a further reading on modules and packages, we refer to the [official tutorial <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/tutorial/modules.html)."
|
"As a further reading on modules and packages, we refer to the [official tutorial <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/tutorial/modules.html)."
|
||||||
]
|
]
|
||||||
|
|
|
@ -808,7 +808,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"source": [
|
"source": [
|
||||||
"Every instance comes with a special `.__class__` attribute that also references the corresponding class object."
|
"`v`'s semantic \"value\" is not so clear yet. We fix this in the next section."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -819,41 +819,6 @@
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"__main__.Vector"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 21,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"v.__class__"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {
|
|
||||||
"slideshow": {
|
|
||||||
"slide_type": "skip"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"source": [
|
|
||||||
"`v`'s semantic \"value\" is not so clear yet. We fix this in the next section."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 22,
|
|
||||||
"metadata": {
|
|
||||||
"slideshow": {
|
|
||||||
"slide_type": "fragment"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
|
@ -861,7 +826,7 @@
|
||||||
"<__main__.Vector at 0x7f9b9416d760>"
|
"<__main__.Vector at 0x7f9b9416d760>"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 22,
|
"execution_count": 21,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -885,7 +850,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 23,
|
"execution_count": 22,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -910,7 +875,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 24,
|
"execution_count": 23,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
|
@ -946,7 +911,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 25,
|
"execution_count": 24,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -983,7 +948,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 26,
|
"execution_count": 25,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -996,7 +961,7 @@
|
||||||
"[1.0, 2.0, 3.0]"
|
"[1.0, 2.0, 3.0]"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 26,
|
"execution_count": 25,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -1031,7 +996,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 27,
|
"execution_count": 26,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -1042,6 +1007,30 @@
|
||||||
"x = 1, 2, 3"
|
"x = 1, 2, 3"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 27,
|
||||||
|
"metadata": {
|
||||||
|
"slideshow": {
|
||||||
|
"slide_type": "fragment"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"(1, 2, 3)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 27,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"x"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 28,
|
"execution_count": 28,
|
||||||
|
@ -1062,30 +1051,6 @@
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
|
||||||
"x"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 29,
|
|
||||||
"metadata": {
|
|
||||||
"slideshow": {
|
|
||||||
"slide_type": "fragment"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"(1, 2, 3)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 29,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
"source": [
|
||||||
"(1, 2, 3)"
|
"(1, 2, 3)"
|
||||||
]
|
]
|
||||||
|
@ -1103,7 +1068,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 30,
|
"execution_count": 29,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -1144,7 +1109,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 31,
|
"execution_count": 30,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -1157,7 +1122,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 32,
|
"execution_count": 31,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
|
@ -1170,7 +1135,7 @@
|
||||||
"Vector((1.000, 2.000, 3.000))"
|
"Vector((1.000, 2.000, 3.000))"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 32,
|
"execution_count": 31,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -1192,7 +1157,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 33,
|
"execution_count": 32,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "skip"
|
"slide_type": "skip"
|
||||||
|
@ -1205,7 +1170,7 @@
|
||||||
"Vector((1.000, 2.000, 3.000))"
|
"Vector((1.000, 2.000, 3.000))"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 33,
|
"execution_count": 32,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -1227,7 +1192,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 34,
|
"execution_count": 33,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -1240,7 +1205,7 @@
|
||||||
"'Vector((1.000, 2.000, 3.000))'"
|
"'Vector((1.000, 2.000, 3.000))'"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 34,
|
"execution_count": 33,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -1266,7 +1231,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 35,
|
"execution_count": 34,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
|
@ -1279,7 +1244,7 @@
|
||||||
"'Vector(1.0, ..., 3.0)[3]'"
|
"'Vector(1.0, ..., 3.0)[3]'"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 35,
|
"execution_count": 34,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -1301,7 +1266,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 36,
|
"execution_count": 35,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
|
@ -1342,14 +1307,14 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"source": [
|
"source": [
|
||||||
"Below is a first implementation of the `Matrix` class that stores the entries internally as a `list` of `list`s.\n",
|
"Below is a first implementation of the `Matrix` class that stores the `._entries` internally as a `list` of `list`s.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"The `.__init__()` method ensures that all the rows come with the same number of columns. Again, we do not allow `Matrix` instances without any entries."
|
"The `.__init__()` method ensures that all the rows come with the same number of columns. Again, we do not allow `Matrix` instances without any entries."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 37,
|
"execution_count": 36,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"code_folding": [],
|
"code_folding": [],
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
|
@ -1391,7 +1356,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 38,
|
"execution_count": 37,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "skip"
|
"slide_type": "skip"
|
||||||
|
@ -1404,7 +1369,7 @@
|
||||||
"94113690738160"
|
"94113690738160"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 38,
|
"execution_count": 37,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -1413,6 +1378,30 @@
|
||||||
"id(Matrix)"
|
"id(Matrix)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 38,
|
||||||
|
"metadata": {
|
||||||
|
"slideshow": {
|
||||||
|
"slide_type": "skip"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 38,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"type(Matrix)"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 39,
|
"execution_count": 39,
|
||||||
|
@ -1421,30 +1410,6 @@
|
||||||
"slide_type": "skip"
|
"slide_type": "skip"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"type"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 39,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"type(Matrix)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 40,
|
|
||||||
"metadata": {
|
|
||||||
"slideshow": {
|
|
||||||
"slide_type": "skip"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
|
@ -1452,7 +1417,7 @@
|
||||||
"__main__.Matrix"
|
"__main__.Matrix"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 40,
|
"execution_count": 39,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -1474,7 +1439,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 41,
|
"execution_count": 40,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -1487,7 +1452,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 42,
|
"execution_count": 41,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "skip"
|
"slide_type": "skip"
|
||||||
|
@ -1500,7 +1465,7 @@
|
||||||
"140306180401856"
|
"140306180401856"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 42,
|
"execution_count": 41,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -1511,7 +1476,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 43,
|
"execution_count": 42,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
|
@ -1524,7 +1489,7 @@
|
||||||
"__main__.Matrix"
|
"__main__.Matrix"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 43,
|
"execution_count": 42,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -1546,7 +1511,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 44,
|
"execution_count": 43,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
|
@ -1559,7 +1524,7 @@
|
||||||
"Matrix(((1.000, 2.000, 3.000,), (4.000, 5.000, 6.000,), (7.000, 8.000, 9.000,)))"
|
"Matrix(((1.000, 2.000, 3.000,), (4.000, 5.000, 6.000,), (7.000, 8.000, 9.000,)))"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 44,
|
"execution_count": 43,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -1570,7 +1535,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 45,
|
"execution_count": 44,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
|
@ -1602,7 +1567,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 46,
|
"execution_count": 45,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "skip"
|
"slide_type": "skip"
|
||||||
|
@ -1628,7 +1593,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 47,
|
"execution_count": 46,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -1673,12 +1638,14 @@
|
||||||
"source": [
|
"source": [
|
||||||
"The methods we have seen so far are all **instance methods**. The characteristic idea behind an instance method is that the behavior it provides either depends on the state of a concrete instance or mutates it. In other words, an instance method *always* works with attributes on the `self` argument. If a method does *not* need access to `self` to do its job, it is conceptually *not* an instance method and we should probably convert it into another kind of method as shown below.\n",
|
"The methods we have seen so far are all **instance methods**. The characteristic idea behind an instance method is that the behavior it provides either depends on the state of a concrete instance or mutates it. In other words, an instance method *always* works with attributes on the `self` argument. If a method does *not* need access to `self` to do its job, it is conceptually *not* an instance method and we should probably convert it into another kind of method as shown below.\n",
|
||||||
"\n",
|
"\n",
|
||||||
"An example of an instance method from linear algebra is the `.transpose()` method below that switches the rows and columns of an *existing* `Matrix` instance and returns a *new* `Matrix` instance based off that. It is implemented by passing the *iterator* created with the [zip() <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/functions.html#zip) built-in as the `data` argument to the `Matrix` constructor: The expression `zip(*self._entries)` may be a bit hard to understand because of the involved unpacking but simply flips a `Vector`'s rows and columns. The built-in [list() <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/functions.html#func-list) constructor within the `.__init__()` method then materializes the iterator into the `._entries`. Without a concrete `Matrix`'s rows and columns, `.transpose()` does not make sense, conceptually speaking."
|
"An example of an instance method from linear algebra is the `.transpose()` method below that switches the rows and columns of an *existing* `Matrix` instance and returns a *new* `Matrix` instance based off that. It is implemented by passing the *iterator* created with the [zip() <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/functions.html#zip) built-in as the `data` argument to the `Matrix` constructor: The expression `zip(*self._entries)` may be a bit hard to understand because of the involved unpacking but simply flips a `Matrix`'s rows and columns. The built-in [list() <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/functions.html#func-list) constructor within the `.__init__()` method then materializes the iterator into the `._entries` attribute. Without a concrete `Matrix`'s rows and columns, `.transpose()` does not make sense, conceptually speaking.\n",
|
||||||
|
"\n",
|
||||||
|
"Also, we see that it is ok to reference a class from within one of its methods. While this seems trivial to some readers, others may find this confusing. The final versions of the `Vector` and `Matrix` classes in the [fourth part <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_nb.png\">](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/develop/11_classes/04_content.ipynb#The-final-Vector-and-Matrix-Classes) of this chapter show how this \"hard coded\" redundancy can be avoided."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 48,
|
"execution_count": 47,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -1713,7 +1680,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 49,
|
"execution_count": 48,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -1724,6 +1691,30 @@
|
||||||
"m = Matrix([(1, 2, 3), (4, 5, 6), (7, 8, 9)])"
|
"m = Matrix([(1, 2, 3), (4, 5, 6), (7, 8, 9)])"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 49,
|
||||||
|
"metadata": {
|
||||||
|
"slideshow": {
|
||||||
|
"slide_type": "fragment"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"Matrix(((1.000, 2.000, 3.000,), (4.000, 5.000, 6.000,), (7.000, 8.000, 9.000,)))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 49,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"m"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 50,
|
"execution_count": 50,
|
||||||
|
@ -1732,30 +1723,6 @@
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"Matrix(((1.000, 2.000, 3.000,), (4.000, 5.000, 6.000,), (7.000, 8.000, 9.000,)))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 50,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"m"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 51,
|
|
||||||
"metadata": {
|
|
||||||
"slideshow": {
|
|
||||||
"slide_type": "fragment"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
|
@ -1763,7 +1730,7 @@
|
||||||
"Matrix(((1.000, 4.000, 7.000,), (2.000, 5.000, 8.000,), (3.000, 6.000, 9.000,)))"
|
"Matrix(((1.000, 4.000, 7.000,), (2.000, 5.000, 8.000,), (3.000, 6.000, 9.000,)))"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 51,
|
"execution_count": 50,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -1785,7 +1752,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 52,
|
"execution_count": 51,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -1796,6 +1763,30 @@
|
||||||
"n = m.transpose().transpose()"
|
"n = m.transpose().transpose()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 52,
|
||||||
|
"metadata": {
|
||||||
|
"slideshow": {
|
||||||
|
"slide_type": "fragment"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"Matrix(((1.000, 2.000, 3.000,), (4.000, 5.000, 6.000,), (7.000, 8.000, 9.000,)))"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 52,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"n"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 53,
|
"execution_count": 53,
|
||||||
|
@ -1808,7 +1799,7 @@
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
"text/plain": [
|
"text/plain": [
|
||||||
"Matrix(((1.000, 2.000, 3.000,), (4.000, 5.000, 6.000,), (7.000, 8.000, 9.000,)))"
|
"False"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 53,
|
"execution_count": 53,
|
||||||
|
@ -1817,7 +1808,18 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"n"
|
"m is n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {
|
||||||
|
"slideshow": {
|
||||||
|
"slide_type": "skip"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"source": [
|
||||||
|
"Unintuitively, the comparison operator `==` returns a wrong result as `m` and `n` have `_entries` attributes that compare equal. We fix this in the \"*Operator Overloading*\" section later in this chapter."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1840,41 +1842,6 @@
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
|
||||||
"m is n"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {
|
|
||||||
"slideshow": {
|
|
||||||
"slide_type": "skip"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"source": [
|
|
||||||
"Unintuitively, the comparison operator `==` returns a wrong result as `m` and `n` have `_entries` attributes that compare equal. We fix this in the \"*Operator Overloading*\" section later in this chapter."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 55,
|
|
||||||
"metadata": {
|
|
||||||
"slideshow": {
|
|
||||||
"slide_type": "fragment"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"False"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 55,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
"source": [
|
||||||
"m == n"
|
"m == n"
|
||||||
]
|
]
|
||||||
|
@ -1894,7 +1861,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 56,
|
"execution_count": 55,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -1933,7 +1900,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 57,
|
"execution_count": 56,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -1946,7 +1913,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 58,
|
"execution_count": 57,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
|
@ -1959,7 +1926,7 @@
|
||||||
"Matrix(((1.000, 2.000, 3.000,), (4.000, 5.000, 6.000,), (7.000, 8.000, 9.000,)))"
|
"Matrix(((1.000, 2.000, 3.000,), (4.000, 5.000, 6.000,), (7.000, 8.000, 9.000,)))"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 58,
|
"execution_count": 57,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -2007,7 +1974,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 59,
|
"execution_count": 58,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -2051,7 +2018,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 60,
|
"execution_count": 59,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "slide"
|
"slide_type": "slide"
|
||||||
|
@ -2064,7 +2031,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 61,
|
"execution_count": 60,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
|
@ -2077,7 +2044,7 @@
|
||||||
"(2, 3)"
|
"(2, 3)"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 61,
|
"execution_count": 60,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
@ -2099,7 +2066,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 62,
|
"execution_count": 61,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"slideshow": {
|
"slideshow": {
|
||||||
"slide_type": "fragment"
|
"slide_type": "fragment"
|
||||||
|
|
|
@ -1577,7 +1577,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"source": [
|
"source": [
|
||||||
"After this discussion of mutable `Vector` and `Matrix` classes, we continue with immutable classes in the rest of this chapter."
|
"After this discussion of mutable `Vector` and `Matrix` classes, we continue with immutable implementations in the rest of this chapter. To lower the chance that we accidently design parts of our classes to be mutable, we replace the built-in [list() <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/functions.html#func-list) constructor with [tuple() <img height=\"12\" style=\"display: inline-block\" src=\"../static/link/to_py.png\">](https://docs.python.org/3/library/functions.html#func-tuple) in the `.__init__()` methods. As we learn in [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/develop/07_sequences/03_content.ipynb#Tuples-are-like-%22Immutable-Lists%22), `tuple`s are like immutable `list`s."
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -82,7 +82,7 @@
|
||||||
"class Vector:\n",
|
"class Vector:\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __init__(self, data):\n",
|
" def __init__(self, data):\n",
|
||||||
" self._entries = list(float(x) for x in data)\n",
|
" self._entries = tuple(float(x) for x in data)\n",
|
||||||
" # ...\n",
|
" # ...\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __repr__(self):\n",
|
" def __repr__(self):\n",
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
"class Matrix:\n",
|
"class Matrix:\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __init__(self, data):\n",
|
" def __init__(self, data):\n",
|
||||||
" self._entries = list(list(float(x) for x in r) for r in data)\n",
|
" self._entries = tuple(tuple(float(x) for x in r) for r in data)\n",
|
||||||
" # ...\n",
|
" # ...\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __repr__(self):\n",
|
" def __repr__(self):\n",
|
||||||
|
@ -678,7 +678,7 @@
|
||||||
"class Vector:\n",
|
"class Vector:\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __init__(self, data):\n",
|
" def __init__(self, data):\n",
|
||||||
" self._entries = list(float(x) for x in data)\n",
|
" self._entries = tuple(float(x) for x in data)\n",
|
||||||
" # ...\n",
|
" # ...\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __repr__(self):\n",
|
" def __repr__(self):\n",
|
||||||
|
@ -692,7 +692,7 @@
|
||||||
" return iter(self._entries)\n",
|
" return iter(self._entries)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __add__(self, other):\n",
|
" def __add__(self, other):\n",
|
||||||
" if isinstance(other, self.__class__): # vector addition\n",
|
" if isinstance(other, Vector): # vector addition\n",
|
||||||
" if len(self) != len(other):\n",
|
" if len(self) != len(other):\n",
|
||||||
" raise ValueError(\"vectors must be of the same length\")\n",
|
" raise ValueError(\"vectors must be of the same length\")\n",
|
||||||
" return Vector(x + y for (x, y) in zip(self, other))\n",
|
" return Vector(x + y for (x, y) in zip(self, other))\n",
|
||||||
|
@ -704,7 +704,7 @@
|
||||||
" return self + other\n",
|
" return self + other\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __sub__(self, other):\n",
|
" def __sub__(self, other):\n",
|
||||||
" if isinstance(other, self.__class__): # vector subtraction\n",
|
" if isinstance(other, Vector): # vector subtraction\n",
|
||||||
" if len(self) != len(other):\n",
|
" if len(self) != len(other):\n",
|
||||||
" raise ValueError(\"vectors must be of the same length\")\n",
|
" raise ValueError(\"vectors must be of the same length\")\n",
|
||||||
" return Vector(x - y for (x, y) in zip(self, other))\n",
|
" return Vector(x - y for (x, y) in zip(self, other))\n",
|
||||||
|
@ -719,7 +719,7 @@
|
||||||
" return NotImplemented\n",
|
" return NotImplemented\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __mul__(self, other):\n",
|
" def __mul__(self, other):\n",
|
||||||
" if isinstance(other, self.__class__): # dot product\n",
|
" if isinstance(other, Vector): # dot product\n",
|
||||||
" if len(self) != len(other):\n",
|
" if len(self) != len(other):\n",
|
||||||
" raise ValueError(\"vectors must be of the same length\")\n",
|
" raise ValueError(\"vectors must be of the same length\")\n",
|
||||||
" return sum(x * y for (x, y) in zip(self, other))\n",
|
" return sum(x * y for (x, y) in zip(self, other))\n",
|
||||||
|
@ -1142,7 +1142,7 @@
|
||||||
"class Matrix:\n",
|
"class Matrix:\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __init__(self, data):\n",
|
" def __init__(self, data):\n",
|
||||||
" self._entries = list(list(float(x) for x in r) for r in data)\n",
|
" self._entries = tuple(tuple(float(x) for x in r) for r in data)\n",
|
||||||
" # ...\n",
|
" # ...\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __repr__(self):\n",
|
" def __repr__(self):\n",
|
||||||
|
@ -1169,7 +1169,7 @@
|
||||||
" return (self._entries[r][c] for r in range(self.n_rows) for c in range(self.n_cols))\n",
|
" return (self._entries[r][c] for r in range(self.n_rows) for c in range(self.n_cols))\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __add__(self, other):\n",
|
" def __add__(self, other):\n",
|
||||||
" if isinstance(other, self.__class__): # matrix addition\n",
|
" if isinstance(other, Matrix): # matrix addition\n",
|
||||||
" if (self.n_rows != other.n_rows) or (self.n_cols != other.n_cols):\n",
|
" if (self.n_rows != other.n_rows) or (self.n_cols != other.n_cols):\n",
|
||||||
" raise ValueError(\"matrices must have the same dimensions\")\n",
|
" raise ValueError(\"matrices must have the same dimensions\")\n",
|
||||||
" return Matrix((s_col + o_col for (s_col, o_col) in zip(s_row, o_row))\n",
|
" return Matrix((s_col + o_col for (s_col, o_col) in zip(s_row, o_row))\n",
|
||||||
|
@ -1184,7 +1184,7 @@
|
||||||
" return self + other\n",
|
" return self + other\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __sub__(self, other):\n",
|
" def __sub__(self, other):\n",
|
||||||
" if isinstance(other, self.__class__): # matrix subtraction\n",
|
" if isinstance(other, Matrix): # matrix subtraction\n",
|
||||||
" if (self.n_rows != other.n_rows) or (self.n_cols != other.n_cols):\n",
|
" if (self.n_rows != other.n_rows) or (self.n_cols != other.n_cols):\n",
|
||||||
" raise ValueError(\"matrices must have the same dimensions\")\n",
|
" raise ValueError(\"matrices must have the same dimensions\")\n",
|
||||||
" return Matrix((s_col - o_col for (s_col, o_col) in zip(s_row, o_row))\n",
|
" return Matrix((s_col - o_col for (s_col, o_col) in zip(s_row, o_row))\n",
|
||||||
|
@ -1211,7 +1211,7 @@
|
||||||
" return Matrix((x * other for x in r) for r in self._entries)\n",
|
" return Matrix((x * other for x in r) for r in self._entries)\n",
|
||||||
" elif isinstance(other, Vector):\n",
|
" elif isinstance(other, Vector):\n",
|
||||||
" return self._matrix_multiply(other.as_matrix()).as_vector()\n",
|
" return self._matrix_multiply(other.as_matrix()).as_vector()\n",
|
||||||
" elif isinstance(other, self.__class__):\n",
|
" elif isinstance(other, Matrix):\n",
|
||||||
" return self._matrix_multiply(other)\n",
|
" return self._matrix_multiply(other)\n",
|
||||||
" return NotImplemented\n",
|
" return NotImplemented\n",
|
||||||
"\n",
|
"\n",
|
||||||
|
@ -1720,7 +1720,7 @@
|
||||||
" zero_threshold = 1e-12\n",
|
" zero_threshold = 1e-12\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __init__(self, data):\n",
|
" def __init__(self, data):\n",
|
||||||
" self._entries = list(float(x) for x in data)\n",
|
" self._entries = tuple(float(x) for x in data)\n",
|
||||||
" # ...\n",
|
" # ...\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __repr__(self):\n",
|
" def __repr__(self):\n",
|
||||||
|
@ -1734,7 +1734,7 @@
|
||||||
" return iter(self._entries)\n",
|
" return iter(self._entries)\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __eq__(self, other):\n",
|
" def __eq__(self, other):\n",
|
||||||
" if isinstance(other, self.__class__):\n",
|
" if isinstance(other, Vector):\n",
|
||||||
" if len(self) != len(other):\n",
|
" if len(self) != len(other):\n",
|
||||||
" raise ValueError(\"vectors must be of the same length\")\n",
|
" raise ValueError(\"vectors must be of the same length\")\n",
|
||||||
" for x, y in zip(self, other):\n",
|
" for x, y in zip(self, other):\n",
|
||||||
|
@ -1990,7 +1990,7 @@
|
||||||
"class Vector:\n",
|
"class Vector:\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __init__(self, data):\n",
|
" def __init__(self, data):\n",
|
||||||
" self._entries = list(float(x) for x in data)\n",
|
" self._entries = tuple(float(x) for x in data)\n",
|
||||||
" # ...\n",
|
" # ...\n",
|
||||||
"\n",
|
"\n",
|
||||||
" def __repr__(self):\n",
|
" def __repr__(self):\n",
|
||||||
|
|
2719
11_classes/04_content.ipynb
Normal file
2719
11_classes/04_content.ipynb
Normal file
File diff suppressed because one or more lines are too long
|
@ -28,3 +28,7 @@ from sample_package.vector import Vector
|
||||||
__name__ = "linear_algebra_tools"
|
__name__ = "linear_algebra_tools"
|
||||||
__version__ = "0.1.0" # see https://semver.org/ for how the format works
|
__version__ = "0.1.0" # see https://semver.org/ for how the format works
|
||||||
__author__ = "Alexander Hess"
|
__author__ = "Alexander Hess"
|
||||||
|
|
||||||
|
# Define what is imported with the "star import"
|
||||||
|
# (i.e., with `from sample_package import *`).
|
||||||
|
__all__ = ["Matrix", "Vector"]
|
||||||
|
|
|
@ -17,12 +17,14 @@ class Matrix:
|
||||||
defaults to tuple
|
defaults to tuple
|
||||||
typing (callable): type casting applied to all entries upon creation;
|
typing (callable): type casting applied to all entries upon creation;
|
||||||
defaults to float
|
defaults to float
|
||||||
|
vector_cls (vector.Vector): a reference to the Vector class to work with
|
||||||
zero_threshold (float): max. tolerance when comparing an entry to zero;
|
zero_threshold (float): max. tolerance when comparing an entry to zero;
|
||||||
defaults to 1e-12
|
defaults to 1e-12
|
||||||
"""
|
"""
|
||||||
|
|
||||||
storage = utils.DEFAULT_ENTRIES_STORAGE
|
storage = utils.DEFAULT_ENTRIES_STORAGE
|
||||||
typing = utils.DEFAULT_ENTRY_TYPE
|
typing = utils.DEFAULT_ENTRY_TYPE
|
||||||
|
# the `vector_cls` attribute is set at the bottom of this file
|
||||||
zero_threshold = utils.ZERO_THRESHOLD
|
zero_threshold = utils.ZERO_THRESHOLD
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
|
@ -156,7 +158,7 @@ class Matrix:
|
||||||
Returns:
|
Returns:
|
||||||
rows (generator): produces a Matrix's rows as Vectors
|
rows (generator): produces a Matrix's rows as Vectors
|
||||||
"""
|
"""
|
||||||
return (Vector(r) for r in self._entries)
|
return (self.vector_cls(r) for r in self._entries)
|
||||||
|
|
||||||
def cols(self):
|
def cols(self):
|
||||||
"""Loop over a Matrix's columns.
|
"""Loop over a Matrix's columns.
|
||||||
|
@ -165,7 +167,7 @@ class Matrix:
|
||||||
columns (generator): produces a Matrix's columns as Vectors
|
columns (generator): produces a Matrix's columns as Vectors
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
Vector(self._entries[r][c] for r in range(self.n_rows))
|
self.vector_cls(self._entries[r][c] for r in range(self.n_rows))
|
||||||
for c in range(self.n_cols)
|
for c in range(self.n_cols)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -232,7 +234,7 @@ class Matrix:
|
||||||
|
|
||||||
def __radd__(self, other):
|
def __radd__(self, other):
|
||||||
"""See docstring for .__add__()."""
|
"""See docstring for .__add__()."""
|
||||||
if isinstance(other, Vector):
|
if isinstance(other, self.vector_cls):
|
||||||
raise TypeError("vectors and matrices cannot be added")
|
raise TypeError("vectors and matrices cannot be added")
|
||||||
# As both matrix and broadcasting addition are commutative,
|
# As both matrix and broadcasting addition are commutative,
|
||||||
# we dispatch to .__add__().
|
# we dispatch to .__add__().
|
||||||
|
@ -260,7 +262,7 @@ class Matrix:
|
||||||
|
|
||||||
def __rsub__(self, other):
|
def __rsub__(self, other):
|
||||||
"""See docstring for .__sub__()."""
|
"""See docstring for .__sub__()."""
|
||||||
if isinstance(other, Vector):
|
if isinstance(other, self.vector_cls):
|
||||||
raise TypeError("vectors and matrices cannot be subtracted")
|
raise TypeError("vectors and matrices cannot be subtracted")
|
||||||
# Same comments as in .__sub__() apply
|
# Same comments as in .__sub__() apply
|
||||||
# with the roles of self and other swapped.
|
# with the roles of self and other swapped.
|
||||||
|
@ -294,6 +296,8 @@ class Matrix:
|
||||||
|
|
||||||
Matrix-vector and vector-matrix multiplication are not commutative.
|
Matrix-vector and vector-matrix multiplication are not commutative.
|
||||||
|
|
||||||
|
>>> from sample_package import Vector
|
||||||
|
|
||||||
>>> Matrix([(1, 2), (3, 4)]) * Vector([5, 6])
|
>>> Matrix([(1, 2), (3, 4)]) * Vector([5, 6])
|
||||||
Vector((17.000, 39.000))
|
Vector((17.000, 39.000))
|
||||||
|
|
||||||
|
@ -304,7 +308,7 @@ class Matrix:
|
||||||
if isinstance(other, numbers.Number):
|
if isinstance(other, numbers.Number):
|
||||||
return self.__class__((x * other for x in r) for r in self._entries)
|
return self.__class__((x * other for x in r) for r in self._entries)
|
||||||
# Matrix-vector multiplication: Vector is a column Vector
|
# Matrix-vector multiplication: Vector is a column Vector
|
||||||
elif isinstance(other, Vector):
|
elif isinstance(other, self.vector_cls):
|
||||||
# First, cast the other Vector as a Matrix, then do matrix-matrix
|
# First, cast the other Vector as a Matrix, then do matrix-matrix
|
||||||
# multiplication, and lastly return the result as a Vector again.
|
# multiplication, and lastly return the result as a Vector again.
|
||||||
return self._matrix_multiply(other.as_matrix()).as_vector()
|
return self._matrix_multiply(other.as_matrix()).as_vector()
|
||||||
|
@ -319,7 +323,7 @@ class Matrix:
|
||||||
if isinstance(other, numbers.Number):
|
if isinstance(other, numbers.Number):
|
||||||
return self * other
|
return self * other
|
||||||
# Vector-matrix multiplication: Vector is a row Vector
|
# Vector-matrix multiplication: Vector is a row Vector
|
||||||
elif isinstance(other, Vector):
|
elif isinstance(other, self.vector_cls):
|
||||||
return other.as_matrix(column=False)._matrix_multiply(self).as_vector()
|
return other.as_matrix(column=False)._matrix_multiply(self).as_vector()
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
|
@ -375,7 +379,7 @@ class Matrix:
|
||||||
|
|
||||||
def __abs__(self):
|
def __abs__(self):
|
||||||
"""The Frobenius norm of a Matrix."""
|
"""The Frobenius norm of a Matrix."""
|
||||||
return utils.norm(self) # use the norm() function shared with the Vector class
|
return utils.norm(self) # uses the norm() function shared vector.Vector
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
"""A Matrix is truthy if its Frobenius norm is strictly positive."""
|
"""A Matrix is truthy if its Frobenius norm is strictly positive."""
|
||||||
|
@ -398,7 +402,7 @@ class Matrix:
|
||||||
"""Get a Vector representation of a Matrix.
|
"""Get a Vector representation of a Matrix.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
vector (Vector)
|
vector (vector.Vector)
|
||||||
|
|
||||||
Raises:
|
Raises:
|
||||||
RuntimeError: if one of the two dimensions, .n_rows or .n_cols, is not 1
|
RuntimeError: if one of the two dimensions, .n_rows or .n_cols, is not 1
|
||||||
|
@ -409,7 +413,7 @@ class Matrix:
|
||||||
"""
|
"""
|
||||||
if not (self.n_rows == 1 or self.n_cols == 1):
|
if not (self.n_rows == 1 or self.n_cols == 1):
|
||||||
raise RuntimeError("one dimension (m or n) must be 1")
|
raise RuntimeError("one dimension (m or n) must be 1")
|
||||||
return Vector(x for x in self)
|
return self.vector_cls(x for x in self)
|
||||||
|
|
||||||
def transpose(self):
|
def transpose(self):
|
||||||
"""Switch the rows and columns of a Matrix.
|
"""Switch the rows and columns of a Matrix.
|
||||||
|
@ -432,4 +436,8 @@ class Matrix:
|
||||||
# We call that a circular import. Whereas Python handles "circular" references
|
# We call that a circular import. Whereas Python handles "circular" references
|
||||||
# (e.g., both the Matrix and Vector classes have methods that reference the
|
# (e.g., both the Matrix and Vector classes have methods that reference the
|
||||||
# respective other class), that is forbidden for imports.
|
# respective other class), that is forbidden for imports.
|
||||||
from sample_package.vector import Vector
|
from sample_package import vector
|
||||||
|
|
||||||
|
# This attribute cannot be set in the class definition
|
||||||
|
# as the vector module is only imported down here.
|
||||||
|
Matrix.vector_cls = vector.Vector
|
||||||
|
|
|
@ -7,8 +7,8 @@ import numbers
|
||||||
# If third-party libraries are needed, they are
|
# If third-party libraries are needed, they are
|
||||||
# put into a group on their own in between.
|
# put into a group on their own in between.
|
||||||
# Within a group, imports are sorted lexicographically.
|
# Within a group, imports are sorted lexicographically.
|
||||||
|
from sample_package import matrix
|
||||||
from sample_package import utils
|
from sample_package import utils
|
||||||
from sample_package.matrix import Matrix
|
|
||||||
|
|
||||||
|
|
||||||
class Vector:
|
class Vector:
|
||||||
|
@ -17,6 +17,7 @@ class Vector:
|
||||||
All entries are converted to floats, or whatever is set in the typing attribute.
|
All entries are converted to floats, or whatever is set in the typing attribute.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
|
matrix_cls (matrix.Matrix): a reference to the Matrix class to work with
|
||||||
storage (callable): data type used to store the entries internally;
|
storage (callable): data type used to store the entries internally;
|
||||||
defaults to tuple
|
defaults to tuple
|
||||||
typing (callable): type casting applied to all entries upon creation;
|
typing (callable): type casting applied to all entries upon creation;
|
||||||
|
@ -25,6 +26,7 @@ class Vector:
|
||||||
defaults to 1e-12
|
defaults to 1e-12
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
matrix_cls = matrix.Matrix
|
||||||
storage = utils.DEFAULT_ENTRIES_STORAGE
|
storage = utils.DEFAULT_ENTRIES_STORAGE
|
||||||
typing = utils.DEFAULT_ENTRY_TYPE
|
typing = utils.DEFAULT_ENTRY_TYPE
|
||||||
zero_threshold = utils.ZERO_THRESHOLD
|
zero_threshold = utils.ZERO_THRESHOLD
|
||||||
|
@ -219,7 +221,7 @@ class Vector:
|
||||||
|
|
||||||
def __abs__(self):
|
def __abs__(self):
|
||||||
"""The Euclidean norm of a vector."""
|
"""The Euclidean norm of a vector."""
|
||||||
return utils.norm(self) # use the norm() function shared with the Matrix class
|
return utils.norm(self) # uses the norm() function shared matrix.Matrix
|
||||||
|
|
||||||
def __bool__(self):
|
def __bool__(self):
|
||||||
"""A Vector is truthy if its Euclidean norm is strictly positive."""
|
"""A Vector is truthy if its Euclidean norm is strictly positive."""
|
||||||
|
@ -246,7 +248,7 @@ class Vector:
|
||||||
column vector or a row vector; defaults to True
|
column vector or a row vector; defaults to True
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
matrix (Matrix)
|
matrix (matrix.Matrix)
|
||||||
|
|
||||||
Example Usage:
|
Example Usage:
|
||||||
>>> v = Vector([1, 2, 3])
|
>>> v = Vector([1, 2, 3])
|
||||||
|
@ -256,5 +258,5 @@ class Vector:
|
||||||
Matrix(((1.000, 2.000, 3.000,)))
|
Matrix(((1.000, 2.000, 3.000,)))
|
||||||
"""
|
"""
|
||||||
if column:
|
if column:
|
||||||
return Matrix([x] for x in self)
|
return self.matrix_cls([x] for x in self)
|
||||||
return Matrix([(x for x in self)])
|
return self.matrix_cls([(x for x in self)])
|
||||||
|
|
|
@ -284,3 +284,8 @@ If this is not possible,
|
||||||
[<img height="12" style="display: inline-block" src="static/link/to_mb.png">](https://mybinder.org/v2/gh/webartifex/intro-to-python/develop?urlpath=lab/tree/11_classes/03_content.ipynb)
|
[<img height="12" style="display: inline-block" src="static/link/to_mb.png">](https://mybinder.org/v2/gh/webartifex/intro-to-python/develop?urlpath=lab/tree/11_classes/03_content.ipynb)
|
||||||
(Operator Overloading: Arithmetic & Relational Operators;
|
(Operator Overloading: Arithmetic & Relational Operators;
|
||||||
Number Emulation)
|
Number Emulation)
|
||||||
|
- [content <img height="12" style="display: inline-block" src="static/link/to_nb.png">](https://nbviewer.jupyter.org/github/webartifex/intro-to-python/blob/develop/11_classes/04_content.ipynb)
|
||||||
|
[<img height="12" style="display: inline-block" src="static/link/to_mb.png">](https://mybinder.org/v2/gh/webartifex/intro-to-python/develop?urlpath=lab/tree/11_classes/04_content.ipynb)
|
||||||
|
(Writing one's own Packages;
|
||||||
|
The final `Vector` & `Matrix` Classes;
|
||||||
|
Comparison with `numpy`)
|
||||||
|
|
Loading…
Reference in a new issue