diff --git a/theme1/PE100/PE100-02TypesVarsAndOperators.ipynb b/theme1/PE100/PE100-02TypesVarsAndOperators.ipynb index 44a5f03..0e3f634 100644 --- a/theme1/PE100/PE100-02TypesVarsAndOperators.ipynb +++ b/theme1/PE100/PE100-02TypesVarsAndOperators.ipynb @@ -518,7 +518,7 @@ { "cell_type": "code", "execution_count": null, - "id": "9be5ce2d-e475-442c-bcdd-1ebe1668cf6b", + "id": "bdf177e9-7e0c-4772-a8ef-f93869a1f5bf", "metadata": {}, "outputs": [], "source": [ @@ -533,7 +533,35 @@ "id": "f8ff396b-d067-485c-8c0a-f9069991d2dd", "metadata": {}, "source": [ - "# TODO - type coercion" + "How do we handle situations like that, where `second_thing` held a string representing a seven, but because it was a string variable it couldn't be used as an integer? Python provides a few functions to convert values from one type to another. The `str()` function takes a variable and converts it to a string. The `float()` and `int()` functions convert their arguments to floating-point and to integer numbers, respectively." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "8b0fa20d-3cf4-4e9d-9c66-28619c8598b6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "13\n", + "13.0\n" + ] + } + ], + "source": [ + "print(first_thing + int(second_thing))\n", + "print(first_thing + float(second_thing))" + ] + }, + { + "cell_type": "markdown", + "id": "8fc293e2-f0f6-4b3c-a9ed-f34c07a5f905", + "metadata": {}, + "source": [ + "Sometimes the expressions we need to evaluate can be very long. It would be nice if we could split up a long expression and spread it out over a few lines. As a small example, we'll take a look at 4+2+3. Manyb programming languages will let us just split an expression anywhere we want, such as:" ] }, { @@ -552,15 +580,26 @@ "id": "9552bdf3-e316-4151-859e-2428672a4e9d", "metadata": {}, "source": [ - "That isn't right. The last line, ```+3```, was evaluated and printed as the result of running that cell. It turns out, if we need to continue an expression on the next line, we just end the line with a backslash ```\\``` and press enter. It has to be a backslash, by the way, and **cannot** be the forward slash like we use for division." + "...but that result isn't right. The last line, `+3`, was evaluated and printed as the result of running that cell. In Python,it turns out, if we need to continue an expression on the next line we just end the current line with a backslash `\\` and press enter. It has to be a backslash, by the way, and **cannot** be the forward slash like we use for division." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "a3f81522-1f91-4fc5-92d8-02d8d88d208f", "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "9" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "4+2\\\n", "+3" @@ -627,7 +666,7 @@ "id": "413f8e00-ffb5-4304-820f-80fd214ac8dc", "metadata": {}, "source": [ - "Some, probably most, languages contain strings inside \"double quotes\", ```\"```, which is shift+apostrophe on US English keyboards. Other languages (SQL and Pascal are the only two I can think of) use single quotes: ```'```. Python let's you use either one. You *do* have to be consistent in each string, but it can vary from one string to the next:" + "Some, probably most, languages contain strings inside \"double quotes\", ```\"```, which is shift+apostrophe on US English keyboards. Other languages (SQL and Pascal are the only two I can think of) use single quotes: ```'```. Python lets you use either one. You *do* have to be consistent in each string, but it can vary from one string to the next:" ] }, { @@ -706,9 +745,11 @@ "That sentence contains three things, inside the string itself:\n", "1. Double Quotes to surround a direct quotation\n", "2. A single quote, also called an apostrophe depending on how it's used, to make a contraction, and\n", - "3. A totally not incredibly awesome/terrifying molecule you have to google to believe.\n", + "3. A totally awesome/terrifying molecule you have to google to believe.\n", + "\n", + "OK, I'll save you the trouble. [Prepare to lose most of a day's productivity](https://www.science.org/content/blog-post/things-i-won-t-work-hexanitrohexaazaisowurtzitane). You're welcome.\n", "\n", - "OK, I'll save you the trouble. [Prepare to lose most of a day's productivity](https://www.science.org/content/blog-post/things-i-won-t-work-hexanitrohexaazaisowurtzitane). You're welcome." + "(Derek has written gobs of articles on fun substances. [Here are some more.](https://www.science.org/topic/blog-category/things-i-wont-work-with) )" ] }, { diff --git a/theme1/PE101/python-packages-conda.ipynb b/theme1/PE101/python-packages-conda.ipynb index 77fe211..0c2c31a 100644 --- a/theme1/PE101/python-packages-conda.ipynb +++ b/theme1/PE101/python-packages-conda.ipynb @@ -4,7 +4,44 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Using Python packages & libraries, Conda" + "# PE101-01: Using Python Packages and Libraries\n", + "\n", + "By itself, Python provides everything you need to write programs. These programs won't have a fancy user interface and they may not run very fast, but they'll work. If that's all Python offered, it might have become a popular language but it wouldn't have taken over most of the world the way it has. No, what Python has going for it is a simple way to take commonly-used chunks of code, wrap them up neatly into sharable budles, and distribute those bundles far and wide. The mechanism for doing this in Python is called **packages**.\n", + "\n", + "In this training unit, PE101-01, we're going to look at some of the packages that come with Python. These are packages that you can count on being available anywhere you can run Python. In the next unit, PE101-02, we'll look at how to find and use packages hosted in _repositories_ available to anyone but not necessarily already installed where you're running your programs.\n", + "\n", + "Python is, by itself, a rather simple language. The PE100 series of units has introduced you to almost all of the language. The language is kept small by moving the \"nice to have, but not really necessary\" parts into their own independent packages. Let's start with an example:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "pi equals 3.141592653589793\n", + "There are 2652 possible outcomes when drawing two cards from a deck\n", + "The natural logarithm of 7.994 is 2.0786912602891316\n" + ] + } + ], + "source": [ + "import math\n", + "\n", + "print(\"pi equals\", math.pi)\n", + "print(\"There are\", math.perm(52,2), \"possible outcomes when drawing two cards from a deck\")\n", + "print(\"The natural logarithm of 7.994 is\", math.log(7.994))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are literally oodles of mathematical functions already implemented for you in the `math` package. To see a list of them as they stand currently, see [math - mathematical functions](https://docs.python.org/3/library/math.html) in the current Python documentation.\n", + "\n" ] } ], diff --git a/theme1/PE102/PE102-02NumPy.ipynb b/theme1/PE102/PE102-02NumPy.ipynb index e635cbe..f8c8077 100644 --- a/theme1/PE102/PE102-02NumPy.ipynb +++ b/theme1/PE102/PE102-02NumPy.ipynb @@ -9,11 +9,11 @@ "\n", "In the previous section, modules for Python was introduced. In this section, we'll take a much more detailed look at one of the most useful to scientists: NumPy. This module contains numerous routinues and support frameworks for numerical computing. The routinues in it are very carefully tested for correctness and are crafted for speed. Any time you _can_ use something from this package, it's a good idea to.\n", "\n", - "Python is built for versatility and ease of programming. Unfortunately, it is not built for speed. Over the years Python has gotten faster and faster, but there is still a speed penalty as compared to classic compiled languages like C, C++, or Fortran.\n", + "Python is built for versatility and ease of programming. Unfortunately, it is not built for speed. Over the years Python has gotten faster and faster but there is still a speed penalty compared to classic compiled languages like C, C++, or Fortran.\n", "\n", - "Enter NumPy: a package of mathematical routines written in C and Fortran and made to work with Python via a \"glue\" or \"shim\" layer. This interface is invisible to the programmer. NumPy looks and behaves just like any other Python package. But under the surface lies a very fast, efficient library of algorithms.\n", + "Enter NumPy: a package of mathematical routines written in C and Fortran and made to work with Python via a \"glue\" or \"shim\" layer. This interface is invisible to the programmer. NumPy looks and behaves just like any other Python package. Under the surface, though, lies a very fast and efficient library of algorithms.\n", "\n", - "### A first glimpse\n", + "## A first glimpse\n", "\n", "Let's take a quick look at NumPy and see a few of the things it can do. NumPy is a package, not part of Python proper, so we have to tell Python to load it. It's traditional to import numpy and give it the alias \"np\" - it's less typing that way, and if you're cutting and pasting code from other sources then it's handy to follow the convention." ] @@ -43,7 +43,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 6, "id": "2b954fa8-72d4-4c2a-aa3a-250949c3ff11", "metadata": {}, "outputs": [ @@ -55,7 +55,7 @@ " [ 9, 10, 11, 12]])" ] }, - "execution_count": 2, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -203,14 +203,12 @@ "source": [ "The output isn't terribly easy to read, but then again representing a four dimensional array on a flat page is challenging at best.\n", "\n", - "If we ever need to see the dimensions of an array, we can use the `shape()` method. \n", - "\n", - "# FIX THIS FIX THIS FIX THIS" + "If we ever need to see the dimensions of an array, we can use the `shape()` method. \n" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "72fbfda8-ed6e-40dc-94e4-ce4ccefe0c66", "metadata": {}, "outputs": [ @@ -240,40 +238,19 @@ "print(np.shape(big_m))" ] }, - { - "cell_type": "code", - "execution_count": 8, - "id": "66e56019-f630-46ab-98a7-b3d3350737e0", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(3,)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "np.shape(z)\n" - ] - }, { "cell_type": "markdown", "id": "72e6eaaf-b3cb-4d27-9bc1-ecfeaf1ff213", "metadata": {}, "source": [ - "### Let's do some actual math, shall we?\n", + "## Let's do some actual math, shall we?\n", "\n", "The trivial example: add a scalar (\"a single number\") to every element of the matrix:" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "id": "2646ba7d-7d8c-4103-bf8d-da4a4bec05d4", "metadata": {}, "outputs": [ @@ -297,14 +274,12 @@ "id": "075d1805-07b2-4ef8-81c0-995fc0ac3d38", "metadata": {}, "source": [ - "You can use any of the Python operators, of course: `+, -, *, /, %, **`...\n", - "\n", - "CHECK THIS CHECK THIS CHECK THIS CHECK THIS the ** ooperator?" + "You can use any of the Python operators, of course: `+, -, *, /, %, **`...\n" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "id": "25781f79-c2e5-4a78-bfd8-05b92f4fedd6", "metadata": {}, "outputs": [ @@ -332,7 +307,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "id": "45637e00-2f0e-45b1-976f-d4c5ed4a4d72", "metadata": {}, "outputs": [ @@ -361,36 +336,32 @@ "id": "16d7c234-3497-4e9c-9297-64a806542ff3", "metadata": {}, "source": [ - "### Linear algebra, anyone?\n", + "## Linear algebra, anyone?\n", "\n", "Let's use NumPy to do some basic linear algebra. First, we'll need another module in the NumPy package:" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 7, "id": "7edc25f0-e902-4234-9a95-41597190e0c7", "metadata": {}, - "outputs": [ - { - "ename": "ImportError", - "evalue": "cannot import name 'nl' from 'numpy.linalg' (/opt/homebrew/lib/python3.12/site-packages/numpy/linalg/__init__.py)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mImportError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[12], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01mnumpy\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mlinalg\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m nl\n", - "\u001b[0;31mImportError\u001b[0m: cannot import name 'nl' from 'numpy.linalg' (/opt/homebrew/lib/python3.12/site-packages/numpy/linalg/__init__.py)" - ] - } - ], + "outputs": [], "source": [ - "from numpy.linalg import nl" + "import numpy.linalg as nl" + ] + }, + { + "cell_type": "markdown", + "id": "e61aee98-093a-4658-9871-5089de494a5e", + "metadata": {}, + "source": [ + "That `import` statement went out to where Python packages are stored and found the \"linalg\" module of the numpy package. This module was imported into the Python interpreter under the name \"nl\" (as in \"NumPy linear algebra\"). Using the \"nl\" alias saves a lot of typing and even makes the code easier to read." ] }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 8, "id": "e4c96df7-c701-4a2a-87f8-ea545f01c980", "metadata": {}, "outputs": [ @@ -404,23 +375,23 @@ ] }, { - "ename": "AttributeError", - "evalue": "module 'numpy' has no attribute 'inv'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[27], line 4\u001b[0m\n\u001b[1;32m 1\u001b[0m k \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marray([[\u001b[38;5;241m1\u001b[39m,\u001b[38;5;241m1\u001b[39m,\u001b[38;5;241m1\u001b[39m], [\u001b[38;5;241m1\u001b[39m,\u001b[38;5;241m1\u001b[39m,\u001b[38;5;241m0\u001b[39m], [\u001b[38;5;241m1\u001b[39m,\u001b[38;5;241m0\u001b[39m,\u001b[38;5;241m0\u001b[39m]])\n\u001b[1;32m 2\u001b[0m \u001b[38;5;28mprint\u001b[39m(k)\n\u001b[0;32m----> 4\u001b[0m kinv \u001b[38;5;241m=\u001b[39m \u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43minv\u001b[49m(k)\n\u001b[1;32m 5\u001b[0m kinv\n", - "File \u001b[0;32m/opt/homebrew/lib/python3.12/site-packages/numpy/__init__.py:333\u001b[0m, in \u001b[0;36m__getattr__\u001b[0;34m(attr)\u001b[0m\n\u001b[1;32m 330\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRemoved in NumPy 1.25.0\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 331\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mRuntimeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mTester was removed in NumPy 1.25.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 333\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mAttributeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmodule \u001b[39m\u001b[38;5;132;01m{!r}\u001b[39;00m\u001b[38;5;124m has no attribute \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 334\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{!r}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(\u001b[38;5;18m__name__\u001b[39m, attr))\n", - "\u001b[0;31mAttributeError\u001b[0m: module 'numpy' has no attribute 'inv'" - ] + "data": { + "text/plain": [ + "array([[ 0., 0., 1.],\n", + " [-0., 1., -1.],\n", + " [ 1., -1., -0.]])" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ "k = np.array([[1,1,1], [1,1,0], [1,0,0]])\n", "print(k)\n", "\n", - "kinv = np.inv(k)\n", + "kinv = nl.inv(k)\n", "kinv" ] }, @@ -434,53 +405,103 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 9, "id": "2a60a483-96e2-4929-a8a5-3c5d93332b8a", "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name 'kinv' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[28], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m k \u001b[38;5;241m@\u001b[39m \u001b[43mkinv\u001b[49m\n", - "\u001b[0;31mNameError\u001b[0m: name 'kinv' is not defined" - ] + "data": { + "text/plain": [ + "array([[1., 0., 0.],\n", + " [0., 1., 0.],\n", + " [0., 0., 1.]])" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ "k @ kinv" ] }, + { + "cell_type": "markdown", + "id": "51da9010-c787-4b87-adae-d9b37f41004c", + "metadata": {}, + "source": [ + "## Very Simple Visualization" + ] + }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 14, "id": "33a135b2-6a0a-4b06-a59c-8956f0f77db4", "metadata": {}, "outputs": [ { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'matplotlib'", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[29], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mmatplotlib\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mpyplot\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mplt\u001b[39;00m\n\u001b[1;32m 2\u001b[0m plt\u001b[38;5;241m.\u001b[39mmatshow(a)\n", - "\u001b[0;31mModuleNotFoundError\u001b[0m: No module named 'matplotlib'" + "name": "stdout", + "output_type": "stream", + "text": [ + "Matrix a:\n", + "[[ 1 2 3 4]\n", + " [ 5 6 7 8]\n", + " [ 9 10 11 12]]\n", + "\n", + "Matrix product:\n", + "[[1. 0. 0.]\n", + " [0. 1. 0.]\n", + " [0. 0. 1.]]\n" ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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dPSJBwDwYqooLO7duxePHz+O1tbWJ463trbG0NDQr76mv78/mpubJx8dHR3PPy0AMKVV/btCdu/eHSMjI5OPwcHBai8JABSkoZKT58+fH7NmzYrh4eEnjg8PD8eCBQt+9TWlUilKpdLzTwgATBsVXbGYPXt2rFy5MgYGBiaPlcvlGBgYiK6urvThAIDppaIrFhERfX190d3dHatWrYo1a9bEvn37YmxsLLZv316N+QCAaaTisHj77bfj7t278cEHH8TQ0FCsWLEiTp069Tc3dAIAM0/FYRER0dvbG729vdmzAADTnN8VAgCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkaShq4Tv/1hmzSnOKWp4a+u+WiaJHoIYe/uP/FD0CNfRKy2jRI1Ajj/80HvEfv32eKxYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQBphAQCkERYAQJqKw+LcuXOxdevWaGtri7q6ujh+/HgVxgIApqOKw2JsbCyWL18eBw4cqMY8AMA01lDpC7Zs2RJbtmypxiwAwDRXcVhUanx8PMbHxyefj46OVntJAKAgVb95s7+/P5qbmycfHR0d1V4SAChI1cNi9+7dMTIyMvkYHBys9pIAQEGq/lZIqVSKUqlU7WUAgCnAz7EAANJUfMXiwYMHcePGjcnnN2/ejKtXr8a8efNi4cKFqcMBANNLxWFx6dKl2LBhw+Tzvr6+iIjo7u6OQ4cOpQ0GAEw/FYfF+vXrY2JiohqzAADTnHssAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0wgIASCMsAIA0DUUt/M//eiNe+t3sopanhlb/wx+LHoEa+sPvrhc9AjW0do7/n84Uo/fL8fv/x3k+IwCANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANMICAEgjLACANBWFRX9/f6xevToaGxujpaUltm3bFtevX6/WbADANFNRWJw9ezZ6enriwoULcfr06Xj06FFs2rQpxsbGqjUfADCNNFRy8qlTp554fujQoWhpaYnLly/HunXrUgcDAKafisLir42MjERExLx58556zvj4eIyPj08+Hx0d/XuWBACmsOe+ebNcLseuXbti7dq1sXTp0qee19/fH83NzZOPjo6O510SAJjinjssenp64tq1a3HkyJFnnrd79+4YGRmZfAwODj7vkgDAFPdcb4X09vbGyZMn49y5c9He3v7Mc0ulUpRKpecaDgCYXioKi4mJidi5c2ccO3Yszpw5E4sXL67WXADANFRRWPT09MThw4fjxIkT0djYGENDQxER0dzcHHPnzq3KgADA9FHRPRYHDx6MkZGRWL9+fbz66quTj6NHj1ZrPgBgGqn4rRAAgKfxu0IAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBIIywAgDTCAgBI01DrBScmJiIi4tHYw1ovTUF+aXhU9AjU0Fi5XPQI1NCof94zxuiDP//b/svX8aepm/itM5LdunUrOjo6arkkAJBkcHAw2tvbn/rxmodFuVyO27dvR2NjY9TV1dVy6UKNjo5GR0dHDA4ORlNTU9HjUGX2e2ax3zPLTN3viYmJuH//frS1tUV9/dPvpKj5WyH19fXPLJ0XXVNT04z6RJzp7PfMYr9nlpm4383Nzb95jps3AYA0wgIASCMsaqRUKsWePXuiVCoVPQo1YL9nFvs9s9jvZ6v5zZsAwIvLFQsAII2wAADSCAsAII2wAADSCAsAII2wAADSCAsAII2wAADS/C+1F/PqSgYMswAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZoAAAGkCAYAAAAIduO+AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy80BEi2AAAACXBIWXMAAA9hAAAPYQGoP6dpAAANoklEQVR4nO3dTWhV977H4V+ix2g5STgiaoMRvYMOigcF3xBBFERxIHhGHVoHHUVBMqqT2lkGhSJFaUetI6kjFeTgQSwqBUWqOHDiRZBLisQXuCQxg9SafQb3NhfvqZbt8bt3Xp4HFrKXa+f/gyX7w1p7Z9vRaDQaBQAhne0eAIC5TWgAiBIaAKKEBoAooQEgSmgAiBIaAKKEBoAooQEgSmgAiBKaFjh16lStWbOmFi9eXFu3bq1bt261eyRCrl+/Xvv376++vr7q6Oio8+fPt3skQoaGhmrz5s3V3d1dy5cvrwMHDtT9+/fbPdaMJDRhZ8+ercHBwTp+/HjduXOn1q9fX3v37q0nT560ezQCJiYmav369XXq1Kl2j0LYtWvXamBgoG7evFmXL1+uFy9e1J49e2piYqLdo804Hb5UM2vr1q21efPmOnnyZFVVTU1NVX9/fx05cqQ+/fTTNk9HUkdHR507d64OHDjQ7lFogadPn9by5cvr2rVrtWPHjnaPM6O4ogn65Zdf6vbt27V79+7pfZ2dnbV79+66ceNGGycD3rXR0dGqqlq6dGmbJ5l5hCbo2bNn9fLly1qxYsUr+1esWFEjIyNtmgp416ampuro0aO1ffv2WrduXbvHmXEWtnsAgNluYGCg7t27Vz/++GO7R5mRhCZo2bJltWDBgnr8+PEr+x8/flwrV65s01TAu3T48OG6ePFiXb9+vVatWtXucWYkt86CFi1aVBs3bqwrV65M75uamqorV67Utm3b2jgZ8O9qNBp1+PDhOnfuXP3www+1du3ado80Y7miCRscHKyDBw/Wpk2basuWLXXixImamJioQ4cOtXs0Ap4/f14PHjyYfvzw4cO6e/duLV26tFavXt3GyXjXBgYG6syZM3XhwoXq7u6eft+1t7e3lixZ0ubpZhYfb26BkydP1hdffFEjIyO1YcOG+uqrr2rr1q3tHouAq1ev1q5du/5l/8GDB+v06dOtH4iYjo6O393/3Xff1ccff9zaYWY4oQEgyns0AEQJDQBRQgNAlNAAECU0AEQJDQBRQtMik5OT9fnnn9fk5GS7R6EFnO/5xfl+M79H0yJjY2PV29tbo6Oj1dPT0+5xCHO+5xfn+81c0QAQJTQARLX8SzWnpqbq0aNH1d3d/drvCpqLxsbGXvmTuc35nl/m6/luNBo1Pj5efX191dn5+uuWlr9H8/PPP1d/f38rlwQgaHh4+I3/F0/Lr2i6u7urquq/7qypnj+7czcf/O2Dv7Z7BCDg13pRP9bfp1/XX6flofntdlnPnzurp1to5oOFHX9q9whAwv/eD/ujt0G80gMQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFCA0CU0AAQJTQARAkNAFFvFZpTp07VmjVravHixbV169a6devWu54LgDmi6dCcPXu2BgcH6/jx43Xnzp1av3597d27t548eZKYD4BZrunQfPnll/XJJ5/UoUOH6sMPP6xvvvmm3nvvvfr2228T8wEwyzUVml9++aVu375du3fv/r8f0NlZu3fvrhs3bvzucyYnJ2tsbOyVDYD5o6nQPHv2rF6+fFkrVqx4Zf+KFStqZGTkd58zNDRUvb2901t/f//bTwvArBP/1NmxY8dqdHR0ehseHk4vCcAMsrCZg5ctW1YLFiyox48fv7L/8ePHtXLlyt99TldXV3V1db39hADMak1d0SxatKg2btxYV65cmd43NTVVV65cqW3btr3z4QCY/Zq6oqmqGhwcrIMHD9amTZtqy5YtdeLEiZqYmKhDhw4l5gNglms6NB999FE9ffq0PvvssxoZGakNGzbUpUuX/uUDAgBQVdXRaDQarVxwbGysent767//8z+qp9s34MwHe/s2tHsEIODXxou6WhdqdHS0enp6XnucV3oAooQGgCihASBKaACIEhoAooQGgCihASBKaACIEhoAooQGgCihASBKaACIEhoAooQGgCihASBKaACIEhoAooQGgCihASBKaACIEhoA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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", - "plt.matshow(a)" + "print(\"Matrix a:\")\n", + "print(a)\n", + "plt.matshow(a)\n", + "print()\n", + "product=k@kinv\n", + "print(\"Matrix product:\")\n", + "print(product)\n", + "plt.matshow(product)" ] }, { "cell_type": "code", "execution_count": null, - "id": "1d6a4998-94f6-45b4-b3fb-c3480ab717a3", + "id": "52888c70-976c-40e2-907d-4e3db09cdd49", "metadata": {}, "outputs": [], "source": []