{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Section 1: Python Essentials" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.1. A brief introduction about programming languages" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.1.1. What's an algorithm?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](imgs/slides_d1/013.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.1.2. What's a programming language?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We could say that it is a language we can use to communicate with a machine and ask about solving a specific task. \n", "We can specify an algorithm, that solves a task in a particular way, and make the machine execute and do what we need.\n", "\n", "Ok, there are some differences between programming languages. There are (in general) two categories: (1) Compiled and (2) Interpreted programming languages.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](imgs/slides_d1/019.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Interpreted and compiled programming languages**\n", "\n", "We thought about an algorithm to go to our institute or university. In that example, we learnt that I mentioned that if you are most specific, the machine will not need to \"infer\" many things. It will not have to work too hard to understand what you asking to do. Then, the most specific you are, the fastest the execution of such an algorithm.\n", "\n", "That's because of this abstraction level as we see here. Binary code is 0's and 1's, that's how machine operates over data and perform computations, but we cannot code directly in Binary Code.\n", "\n", "If we increase the level of abstraction, we will see the Machine code and Assembly languages, which are still too complicated for humans to use directly on data analysis. \n", "\n", "Then, we have the middle-level languages. Examples of that are C/C++ and FORTRAN. Here, the tasks are done very fast. And on top of them, we have high-level, scripting languages such as MATLAB, Java, and Python. \n", "\n", "Compared to High-level or scripting languages such MATLAB and Python, C/C++ is super fast. \n", "\n", "That's because in C you have access to very middle-level instructions (e.g., memory allocation). Which means you can be more specific about what the machine should do and how to do it. \n", "However, and very often, you have to code more in C/C++ than in Python. It takes longer... And your code is gonna be compiled. While others are interpreted.\n", "\n", "Now, what are the differences between them?\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](imgs/slides_d1/024.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1.1.3. What's Python?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "+ It is a **high**-level programming language that has an English-like syntax. This makes it easier to read!\n", "+ It is **interpreted** and it has **dynamic semantics**.\n", " It’s the Python Virtual Machine (the translator) that infers data types, functions, and so on." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.1.3.1. Main advantages" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some of them are:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](imgs/slides_d1/035.PNG)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1.1.3.2. Main disadvantages" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----" ] }, { "cell_type": "markdown", "metadata": { "id": "Mgzxn85UdDlq" }, "source": [ "## 1.2. Python Essentials: A quick recap" ] }, { "cell_type": "markdown", "metadata": { "id": "IfKE9JGivEgV" }, "source": [ "### 1.2.1. What's Jupyter notebook?\n" ] }, { "cell_type": "markdown", "metadata": { "id": "kBGI313-vRf5" }, "source": [ "![](https://assets.website-files.com/6141c89a3874c3702674a1c0/625012c9c0dbf1887c4bf7c7_623d8b3bd384c356fff4d0c8_memgraph-jupyter-notebook-cover-p-1080.png)\n", "\n", "(_Image source: [memgraph.com](https://memgraph.com/blog/jupyter-notebook-twitter-network-analysis)_)\n", "\n", "A notebook document can contain computer code (e.g., python scripts) and text elements (e.g., paragraph, equations, figures, links, etc). Thus, these documents contain analysis descriptions, results as well as executable cells which can be run to perform data analysis.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "OeKErhai7Y-0" }, "source": [ "Here, we can directly \"talk\" to the Python's interpreter. You can run the code of a cell by selecting it and pressing \"`shift` + `enter`\". Try it out!\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "ZTqs9G2l7Y-1", "outputId": "af3ab0b1-6d3b-4fe3-ae38-8c93fd152c69" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hallo Welt!\n" ] } ], "source": [ "# method 'print(arg)': it returns the argument 'arg' to the user's console\n", "print(\"Hallo Welt!\")" ] }, { "cell_type": "markdown", "metadata": { "id": "rBujptjD7Y-_" }, "source": [ "### 1.2.2. Variables and Python Data Types" ] }, { "cell_type": "markdown", "metadata": { "id": "8ZE_Dl2eubgq" }, "source": [ "#### 1.2.2.1. Variables" ] }, { "cell_type": "markdown", "metadata": { "id": "STEkrhARsd1H" }, "source": [ "We can think that a variable in programming is a name or a label that we will use to refer a particular object. Such object can be value we store in the memory (e.g. `n = 15`). \n", "\n", "We can store values on variables **without specifying their types**. That's because Python is a dynamically-typed languague: If we assign a value to a variable the python interpreter will assign it a type.\n", "\n", "For example, if we do this:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "7grini1l7Y_A", "outputId": "f596a461-decf-48f2-f300-c67be6f4d757" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ " 2\n", " 7.1\n", " True\n", " Hallo!\n" ] } ], "source": [ "a = 2 # int (integer)\n", "b = 7.1 # float (float/decimal)\n", "c = True # bool (boolean)\n", "d = \"Hallo!\" # str (string, list of characters)\n", "\n", "print(type(a), a)\n", "print(type(b), b)\n", "print(type(c), c)\n", "print(type(d), d)" ] }, { "cell_type": "markdown", "metadata": { "id": "MGkBsKPHs3yb" }, "source": [ "We can see with `type()` the type of each variable." ] }, { "cell_type": "markdown", "metadata": { "id": "_tk6WSof7Y_A" }, "source": [ "Note that we didn't specify explicitly the type of the data of each variable. Thus, the Python interpreter **infers** which data type is from the value you want to store.\n", "\n", "You can also change the type of the variables:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 35 }, "id": "bEGT1Zdz7Y_B", "outputId": "97059303-92bd-45ff-c66e-7035e6d04e07" }, "outputs": [ { "data": { "application/vnd.google.colaboratory.intrinsic+json": { "type": "string" }, "text/plain": [ "'2'" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "str(a) # it converts the variable's value into a string." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "3UmwvKO17Y_C", "outputId": "25e2b70e-74e9-4b2c-abd1-674cc03ccae0" }, "outputs": [ { "data": { "text/plain": [ "7" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "int(b) # from float (decimal) to integer" ] }, { "cell_type": "markdown", "metadata": { "id": "RNvMU_sL22Ld" }, "source": [ "Notice that was `b = 7.1`. However, we are forcing to convert a decimal value into an integer. Then, the interpreter truncates the original value.\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "AMALLPECtH8z" }, "source": [ "\n", "---" ] }, { "cell_type": "markdown", "metadata": { "id": "nr8AKu9JeLeA" }, "source": [ "#### 1.2.2.2. Lists" ] }, { "cell_type": "markdown", "metadata": { "id": "8EowZX7Ntzlr" }, "source": [ "##### 1.2.2.2.1. Definition" ] }, { "cell_type": "markdown", "metadata": { "id": "E938xHRSusBo" }, "source": [ "Imagine that you want to store 100 values about an specific variable (e.g., `participant_age`, `neuron_type`). It is not convenient to create 100 variables to store each value.\n", "\n", "In such cases, we use _Python lists_ (also known as vectors or arrays).\n", "\n", "For example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "5bMFw83luqM5" }, "outputs": [], "source": [ "# list of integers\n", "my_list_int = [3,1,2,5,6] \n", "# list of strings\n", "my_list_strings = [\"red\", \"green\", \"blue\", \"yellow\", \"black\"]\n", "# list with different types of elements\n", "my_list_elements = [\"3\",1.5,2,True] " ] }, { "cell_type": "markdown", "metadata": { "id": "aWiT7NAqvVdw" }, "source": [ "Note that a list can store different types of elements.\n", "\n", "![](https://www.learnbyexample.org/wp-content/uploads/python/Python-List-Indexing.png)\n", "\n", "_(Image source: LearnByExample.org)_\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "864lE4Pqtp7E" }, "source": [ "##### 1.2.2.2.2. List indexing" ] }, { "cell_type": "markdown", "metadata": { "id": "80PZLcAPth09" }, "source": [ "In order to have access to the elements of a given list, we should write the index of such element in the list, starting by the number 0.\n", "\n", "For example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "P4VUNHa6wasq", "outputId": "8856aca3-d0e4-44c1-8f24-e0cd3e12fda5" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "red\n", "blue\n" ] } ], "source": [ "print(my_list_strings[0])\n", "print(my_list_strings[2])" ] }, { "cell_type": "markdown", "metadata": { "id": "yg6-CljISHY1" }, "source": [ "Let's consider the following list of integers:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "e5VOl2G37Y_F" }, "outputs": [], "source": [ "list_of_integers = [1,5,2,9,4,8,6]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "KSzdF1TE7Y_F", "outputId": "6aec7c06-4e15-4dd8-fb5d-1bc4f2b7e8be" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 5, 2, 9, 4, 8, 6]\n" ] } ], "source": [ "print(list_of_integers)" ] }, { "cell_type": "markdown", "metadata": { "id": "F2pKkbGqR3za" }, "source": [ "We can know the length of a list (i.e., the amount of elements it has) by writing `len(my_list)`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "lOKkVKcx7Y_F", "outputId": "e4371e4c-97ff-4ab8-c051-fa3c22b125d7" }, "outputs": [ { "data": { "text/plain": [ "7" ] }, "execution_count": 154, "metadata": {}, "output_type": "execute_result" } ], "source": [ "len(list_of_integers)" ] }, { "cell_type": "markdown", "metadata": { "id": "hfwM5qUDRxvG" }, "source": [ "We can access each item by indicating its index:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "jKXX5I5r7Y_G", "outputId": "cbb9a0b1-f5e4-4291-d41c-f40f91b2a375" }, "outputs": [ { "data": { "text/plain": [ "9" ] }, "execution_count": 155, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list_of_integers[3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "ao0HqNHD7Y_G", "outputId": "e6fd9a8e-d6d8-4941-c6a9-155869bb1f0e" }, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 156, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list_of_integers[-1] # -1 represent the last element!" ] }, { "cell_type": "markdown", "metadata": { "id": "zE_UI-ZnRdW5" }, "source": [ "##### 1.2.2.2.3. Slicing\n", "\n", "\n", "We can access to specific sub-list of a list.\n", "\n", "If we write `our_list[:a]`, it will return every element of `our_list` until the index `a`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "5YrMuxpI7Y_H", "outputId": "5e83953b-1f03-4b87-fe2f-42d81860cd20" }, "outputs": [ { "data": { "text/plain": [ "[1, 5, 2]" ] }, "execution_count": 157, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list_of_integers[:3]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "ho6lDcoB7Y_H", "outputId": "8b741457-2539-4331-db02-0b37484b8052" }, "outputs": [ { "data": { "text/plain": [ "[4, 8, 6]" ] }, "execution_count": 158, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list_of_integers[-3:]" ] }, { "cell_type": "markdown", "metadata": { "id": "F-eMq46980Zw" }, "source": [ "And also access to a sublist:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Fz7cOONq8yn-", "outputId": "513d3ceb-96b4-4e86-d807-faf73f695bf4" }, "outputs": [ { "data": { "text/plain": [ "[5, 2, 9]" ] }, "execution_count": 159, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list_of_integers[1:4]" ] }, { "cell_type": "markdown", "metadata": { "id": "K-W5k3hgPUbf" }, "source": [ "We can invert a Python list as follows:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "TQ0SABeV7Y_H", "outputId": "1e4b9cf5-50bd-4fda-e33a-4c2a05527a35" }, "outputs": [ { "data": { "text/plain": [ "[6, 8, 4, 9, 2, 5, 1]" ] }, "execution_count": 160, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list_of_integers[::-1]" ] }, { "cell_type": "markdown", "metadata": { "id": "EuIrD67aupSQ" }, "source": [ "##### 1.2.2.2.4. Adding elements into a list\n", "\n", "To add an element use `append()` as follows:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Ce-Ah5PXP4Fy" }, "outputs": [], "source": [ "list_of_integers.append(10)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "v9Is1RGHQQzq", "outputId": "f4f85eff-266f-428f-ac46-71ecc75fc8f2" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 5, 2, 9, 4, 8, 6, 10]\n" ] } ], "source": [ "print(list_of_integers)" ] }, { "cell_type": "markdown", "metadata": { "id": "VXnLjBalQTZH" }, "source": [ "##### 1.2.2.2.5. Removing elements from a list\n", "\n", "You can remove an element from a list by indicating such element.\n", "\n", "For example, to remove the element `9` we do:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "sraC7S7XQTF-" }, "outputs": [], "source": [ "list_of_integers.remove(9)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "v1cDyWFSQj2A", "outputId": "b550650b-d0b9-45ff-93b5-a909f0cdac49" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 5, 2, 4, 8, 6, 10, 10, 10]\n" ] } ], "source": [ "print(list_of_integers)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "zviyfaF8QyoT" }, "outputs": [], "source": [ "list_of_integers = [5,1,6,1,2,3]\n", "list_of_integers.remove(1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "I72X_WHUQ1sq", "outputId": "c1cee13e-7e8d-4b50-f51d-fa3b0b39801b" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[5, 6, 1, 2, 3]\n" ] } ], "source": [ "print(list_of_integers)" ] }, { "cell_type": "markdown", "metadata": { "id": "P4PEvMdVRFC9" }, "source": [ "Note that `remove(item)` will remove the first item it finds (not all of them) from left to right." ] }, { "cell_type": "markdown", "metadata": { "id": "dorMtf8y7Y_E" }, "source": [ "#### 1.2.2.3. Nested lists" ] }, { "cell_type": "markdown", "metadata": { "id": "utnvb-VyPbD3" }, "source": [ "List allow us to store different types of variables such as Integers, Floats, Strings... and also lists! In this case, we call them nested lists." ] }, { "cell_type": "markdown", "metadata": { "id": "Z9hycoSPwu0Z" }, "source": [ "![](https://www.learnbyexample.org/wp-content/uploads/python/Python-Nested-List-Indexing.png)\n", "\n", "_(Image source: LearnByExample.org)_" ] }, { "cell_type": "markdown", "metadata": { "id": "PPE0ohVSuIiE" }, "source": [ "Let's check the implementation of such example below:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "OCa_X1Iiw7Oz", "outputId": "9602107c-c576-463b-d5be-edce8df4bb81" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['cc', 'dd', ['eee', 'fff']]\n", "['eee', 'fff']\n", "eee\n" ] } ], "source": [ "L = ['a', 'b', ['cc', 'dd', ['eee', 'fff']], 'g', 'h']\n", "\n", "print(L[2])\n", "# Prints ['cc', 'dd', ['eee', 'fff']]\n", "\n", "print(L[2][2])\n", "# Prints ['eee', 'fff']\n", "\n", "print(L[2][2][0])\n", "# Prints eee" ] }, { "cell_type": "markdown", "metadata": { "id": "6tpVALgExyRr" }, "source": [ "We can also use this property to represent a matrix:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "OfBcMmt08hBB", "outputId": "a33d35fb-1d65-481f-f23b-94ffb551eee3" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "A\n", " [[1, 2, 3], [1, 0, 5], [2, 0, 0]]\n", "B\n", " [[1, 2, 3], [1, 0, 5], [2, 0, 0]]\n", "C\n", " [[0, 0, 0], [0, 0, 0], [0, 0, 0]]\n" ] } ], "source": [ "A = [[1,2,3],[1,0,5],[2,0,0]]\n", "B = [[1,2,3],[1,0,5],[2,0,0]]\n", "C = [[0,0,0],[0,0,0],[0,0,0]]\n", "\n", "print(\"A\\n\", A)\n", "print(\"B\\n\", B)\n", "print(\"C\\n\", C)" ] }, { "cell_type": "markdown", "metadata": { "id": "OocWZwzyuQh3" }, "source": [ "In this case, a matrix would be represented by a list of list." ] }, { "cell_type": "markdown", "metadata": { "id": "JNRJ6_gq9thW" }, "source": [ "#### 1.2.2.4. Dictionaries" ] }, { "cell_type": "markdown", "metadata": { "id": "lsBP-uUFyDbN" }, "source": [ "Python dictionaries (`dict()`) allow us to store information on them and using keys for indexing. \n", "\n", "They are an unordered sequence of items, as pairs `(key, value)`. \n", "\n", "Just like Lists, the values of dictionaries can hold data of different types (i.e., integers, floats, strings, lists, dictionaries, etc). \n", "\n", "For example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "w4fICOA9yDLu" }, "outputs": [], "source": [ "my_dict = {\n", " \"firstname\" : \"Ash\", \n", " \"lastname\" : \"Ketchum\", \n", " \"residence\" : \"Palette Town\",\n", " \"PLZ\" : 101,\n", " \"region\" : \"Kanto\",\n", " \"Team\" : [\n", " \"Charizard\", \"Squirtle\", \"Butterfly\", \"Pidgeotto\", \"Bulbasaur\",\"Pikachu\"\n", " ]}\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Wm4HS1FO-Ydg", "outputId": "3e73dbc3-6bdf-4d43-a3db-bdbe58f15bc0" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'firstname': 'Ash', 'lastname': 'Ketchum', 'residence': 'Palette Town', 'PLZ': 101, 'region': 'Kanto', 'Team': ['Charizard', 'Squirtle', 'Butterfly', 'Pidgeotto', 'Bulbasaur', 'Pikachu']}\n" ] } ], "source": [ "print(my_dict)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "QZFfxQ87-ZAo", "outputId": "0d082c7c-b1a4-4c5c-92d4-c0347c509f24" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ash Ketchum from Palette Town\n" ] } ], "source": [ "print(my_dict['firstname'], my_dict['lastname'], \"from\", my_dict[\"residence\"])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "ONfnK5AF-rO5", "outputId": "fe19a63b-4183-4475-b369-fac94d5a99a7" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Charizard\n" ] } ], "source": [ "print(my_dict[\"Team\"][0]) # First element of \"Team\" list" ] }, { "cell_type": "markdown", "metadata": { "id": "Uchm-1xO-saw" }, "source": [ "Python dictionaries help us to store our data in complex data structures." ] }, { "cell_type": "markdown", "metadata": { "id": "eHcH1BNj7Y_J" }, "source": [ "## 1.3. Python Control Statements and loops" ] }, { "cell_type": "markdown", "metadata": { "id": "Dy0TtC3-uh-9" }, "source": [ "### 1.3.1. Control Statements (if, elif, else)" ] }, { "cell_type": "markdown", "metadata": { "id": "S1QOvkiiAvC9" }, "source": [ "In order to control the execution flow in your algorithm, in python we use `if (condition)`, `elif (condition)`, and `else`." ] }, { "cell_type": "markdown", "metadata": { "id": "Mi7MNwRsZDq1" }, "source": [ "##### 1.3.1.1. Syntax\n", "\n", "```python\n", "if (condition):\n", " # your statements if `condition` is True\n", "else:\n", " # your statements if `condition` is False\n", "```\n", "\n", "if one condition is not enough, we can do:\n", "\n", "```python\n", "if (condition1):\n", " # your statements if `condition1` is True\n", "else:\n", " # your statements if `condition1` is False\n", " if (condition2):\n", " # your statements if `condition2` is True\n", " else:\n", " # your statements if `condition2` is False\n", "```\n", "\n", "or equivalently:\n", "\n", "```python\n", "if (condition1):\n", " # your statements if `condition1` is True\n", "elif (condition2):\n", " # your statements if `condition1` is False but `condition2` is True\n", "else:\n", " # your statements if both `condition1` and `condition2` are False\n", "```\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "lMPmODa-_ZP4" }, "source": [ "##### 1.3.1.2. Example" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "eMmwak26Zqfd", "outputId": "a820340e-1d00-41c2-c665-df6ff450e0f5" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Negative\n" ] } ], "source": [ "x = -10\n", "\n", "if (x > 0):\n", " print(\"Positive\")\n", "elif (x < 0):\n", " print(\"Negative\")\n", "else:\n", " print(\"Zero\")\n" ] }, { "cell_type": "markdown", "metadata": { "id": "IzgyAKqk_0I1" }, "source": [ "### 1.3.2. Control Statements (`for` and `while`)" ] }, { "cell_type": "markdown", "metadata": { "id": "Gs6_mZ4__bGJ" }, "source": [ "We can access each element of a list through `for` and `while`.\n", "\n", "`for` allow us to repeat each element of an list or range. \n" ] }, { "cell_type": "markdown", "metadata": { "id": "PJld-l9t_Kum" }, "source": [ "**For example:**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "JoyFja2b7Y_J", "outputId": "ea378aae-4bc8-437f-93eb-de58725a4b4f" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n" ] } ], "source": [ "N = 5\n", "for i in range(N): # it goes from 0 to N-1\n", " print (i)" ] }, { "cell_type": "markdown", "metadata": { "id": "qqgD-FxkAEGh" }, "source": [ "On the other hand, `while` also loops but given a _condition_. \n", "\n", "```python\n", "while (conditional_statement):\n", " # actions\n", " # ...\n", "```\n", "\n", "While such condition is `True` all the inner statements will be executed.\n", "\n", "**Note:** Be sure that the condition will turn `False` at some point. Otherwise, the while loop will never end." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "16KDWAY6A7yf", "outputId": "0b50800b-b9a8-44f4-bd9d-a16937488bb2" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n" ] } ], "source": [ "N = 5\n", "i = 0\n", "while (i < N): # it goes from 0 to N-1\n", " print(i)\n", " i = i + 1" ] }, { "cell_type": "markdown", "metadata": { "id": "D4D5dJWiu5ks" }, "source": [ "### 1.3.3. Exercise" ] }, { "cell_type": "markdown", "metadata": { "id": "S7kQfIc9u_8E" }, "source": [ "Compute `z` as the substraction of each element of lists `x` and `y`, such that $z_i = (x_i - y_i)^2$. Assume that input lists `x` and `y` have the same length. Finally, print each value of `z` and its index in the list.\n", "\n", "Use a repetition statement to access each element of the arrays.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "J9pdYIBdvUz3" }, "source": [ "_Example input_:\n", "```python\n", "x = [1,2,3,4,5]\n", "y = [2,2,2,2,2]\n", "```\n", "\n", "_Expected output_:\n", "```bash\n", "Index 0 , value: 1\n", "Index 1 , value: 0\n", "Index 2 , value: 1\n", "Index 3 , value: 4\n", "Index 4 , value: 9\n", "```" ] }, { "cell_type": "markdown", "metadata": { "id": "xnCUurwIvGpt" }, "source": [ "**Solution**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "RySEBf4zvIpc" }, "outputs": [], "source": [ "# Here your code!\n", "\n", "# 1. Be sure you can generate an output as the expected one indicated above.\n", "\n", "# To compute the value of a number `x` to the power of two, you do: `x**2`. " ] }, { "cell_type": "markdown", "metadata": { "id": "xvpLVmv-7Y_K" }, "source": [ "**Bonus:** \n", "Compute the matrix multiplication of `A = [[2,5,2],[1,0,-2],[3,1,1]]` and `B = [[-2,1,0],[-2,2,1],[0,0,3]]` and save the result in C. Then, print each row of the matrix `C`.\n", "\n", "_Example input_:\n", "```python\n", "A = [[2,5,2],[1,0,-2],[3,1,1]]\n", "B = [[-2,1,0],[-2,2,1],[0,0,3]]\n", "```\n", "\n", "_Expected output_:\n", "```python\n", "[-14, 12, 11]\n", "[ -2, 1, -6]\n", "[ -8, 5, 4]\n", "```\n" ] }, { "cell_type": "markdown", "metadata": { "id": "h9jwhW7H0rEh" }, "source": [ "**Solution**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "9QNTGx-e0rUG" }, "outputs": [], "source": [ "A = [[2,5,2],[1,0,-2],[3,1,1]]\n", "B = [[-2,1,0],[-2,2,1],[0,0,3]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "8tev-k4i0JIh" }, "outputs": [], "source": [ "# Here your code!\n", "\n", "# Suggestions: Use `for` instead of the `while` statement\n", "# Start by defining a zero-matrix\n", "# Notice you have to access each element of each row of `A`\n", "# then, you have to access each element of each column of `B`\n", "# Finally, you have to access each element of the new matrix (`C`)" ] }, { "cell_type": "markdown", "metadata": { "id": "0_n9Opfn7w1f" }, "source": [ "## 1.4. Functions\n" ] }, { "cell_type": "markdown", "metadata": { "id": "ECa7gK-f2OTj" }, "source": [ "### 1.4.1. What's a function?\n" ] }, { "cell_type": "markdown", "metadata": { "id": "7Agc_F2V20rL" }, "source": [ "+ A function is a block of code that runs when it is called. \n", "+ You can pass data (i.e, parameters) into a function. \n", "+ Functions are used to perform specific actions, and they are also known as methods.\n" ] }, { "cell_type": "markdown", "metadata": { "id": "99rxe2f02oIH" }, "source": [ "### 1.4.2. Syntax" ] }, { "cell_type": "markdown", "metadata": { "id": "gO5VA3JD21DG" }, "source": [ "![](https://www.learnbyexample.org/wp-content/uploads/python/Python-Function-Syntax.png)\n", "\n", "(_Image source: [LearnByExample](https://www.learnbyexample.org/python-functions/)_)" ] }, { "cell_type": "markdown", "metadata": { "id": "4tEzBofg2oFQ" }, "source": [ "### 1.4.3. How to create a function?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "4XA_6PVa3ErE" }, "outputs": [], "source": [ "def hallo():\n", " print(\"Hallo Welt!\")" ] }, { "cell_type": "markdown", "metadata": { "id": "2CNtgqpl2oCj" }, "source": [ "### 1.4.4. How to call a function?" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "O3c6N9ev3Gsk", "outputId": "4ea0bbb3-6de4-49c8-d887-53e9ac081b19" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hallo Welt!\n" ] } ], "source": [ "hallo()" ] }, { "cell_type": "markdown", "metadata": { "id": "yr2p-VN53QJ8" }, "source": [ "A function can receive input parameters or _arguments_ to perform computations. In that case, you should add those arguments separated by commas.\n", "\n", "For example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "mMLPqLfh3Uk0", "outputId": "8a5f735c-d511-48a7-d615-6d116cdd45d8" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hallo, Eren Jäger !\n" ] } ], "source": [ "def hallo(name, lastname):\n", " print(\"Hallo,\", name, lastname, \"!\")\n", "\n", "hallo(name='Eren', lastname='Jäger')" ] }, { "cell_type": "markdown", "metadata": { "id": "S8ThJm_C3YoF" }, "source": [ "If you want to allow any amount of arguments, you define a function as follows:\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "uN6dqGOQ3bqs", "outputId": "97331a60-2b21-4c49-dc75-df8902123d81" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "((1, 1, 3, 5, 8),)\n" ] } ], "source": [ "def print_args(*args):\n", " print(args)\n", "\n", "print_args((1,1,3,5,8))" ] }, { "cell_type": "markdown", "metadata": { "id": "FjQdC4uY3fK7" }, "source": [ "Additionally, you can make it for _keyword arguments_:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "VTs0ZP5z3hYT", "outputId": "fab7992c-0027-45c7-e207-82812359beaa" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'name': 'Zeke', 'lastname': 'Jäger'}\n" ] } ], "source": [ "def print_keyword_args(**kwargs):\n", " print(kwargs)\n", "\n", "print_keyword_args(name=\"Zeke\", lastname=\"Jäger\")\n" ] }, { "cell_type": "markdown", "metadata": { "id": "vMTBt-bb3jx0" }, "source": [ "A function can also return values by using the `return` statement:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "ioZ4iEH-3mXL", "outputId": "edc111ac-3ad1-466f-d268-d355765b7430" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10\n" ] } ], "source": [ "# It returns the sum of two values\n", "def my_sum(a, b):\n", " return a + b\n", "\n", "x = my_sum(2, 8)\n", "print(x)" ] }, { "cell_type": "markdown", "metadata": { "id": "ffm03r5_2n8P" }, "source": [ "### 1.4.5. Advantages of using functions" ] }, { "cell_type": "markdown", "metadata": { "id": "VYSjNUAO25Ar" }, "source": [ "1. Modularity.\n", "2. Decomposing complex problems into simpler pieces.\n", "3. Reuse code, avoiding duplication.\n", "4. Clousure.\n", "5. Improving clarity." ] }, { "cell_type": "markdown", "metadata": { "id": "NWUriMEvork7" }, "source": [ "### 1.4.6. Exercise\n" ] }, { "cell_type": "markdown", "metadata": { "id": "Xl8LYeO13ggZ" }, "source": [ "\n", "1. Write a function that receives two parameters: (1) `v`, a list of numbers, and (2) `a`, an scalar. The function should return a list `y` such that `y = v*a`.\n", "\n", "> _Example input_\n", "> ```python\n", "v = [1,2,3,4,9,8,7,6,5]\n", "a = 10\n", "> ```\n", "> _Expected output_\n", "> ```python\n", "[10, 20, 30, 40, 90, 80, 70, 60, 50]\n", "```" ] }, { "cell_type": "markdown", "metadata": { "id": "GJaxpR8y4Ecs" }, "source": [ "**Solution**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "-qeDyFzUWH9L" }, "outputs": [], "source": [ "v = [1,2,3,4,9,8,7,6,5]\n", "a = 10" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "FpPXG7F33lKn" }, "outputs": [], "source": [ "# your solution here" ] }, { "cell_type": "markdown", "metadata": { "id": "TiiDJOLG3iVI" }, "source": [ "**(Bonus #1)**\n", "\n", "Write a function that returns the distance, as absolute value, between every pair of components between two lists `x` and `y`. Use `abs()`. Call such function and print the result, separating each row.\n", "\n", ">_Example Input:_\n", "> ```python\n", "x=[1,2,3,4,5]; y=[1,2,3,4,5]\n", ">```\n", "> _Expected Output:_\n", ">```python\n", "[0, 1, 2, 3, 4]\n", "[1, 0, 1, 2, 3]\n", "[2, 1, 0, 1, 2]\n", "[3, 2, 1, 0, 1]\n", "[4, 3, 2, 1, 0]\n", ">```" ] }, { "cell_type": "markdown", "metadata": { "id": "Pv6vmnNIWQ-Q" }, "source": [ "**Solution Bonus #1**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "OOfFNsjlWQ-S" }, "outputs": [], "source": [ "x=[1,2,3,4,5]\n", "y=[1,2,3,4,5]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "FqaKM1-M3lwQ" }, "outputs": [], "source": [ "# your solution here" ] }, { "cell_type": "markdown", "metadata": { "id": "18PF46Cr3j3n" }, "source": [ "**(Bonus #2)**\n", "\n", "3. Write a function that returns the multiplication of two matrices `A` and `B` (each one represented as a list of lists). Print each row of the resulting matrix separately.\n", "\n", "> _Example Input:_\n", "> ```python\n", "A = [[1,2,3],[2,0,5],[8,0,0]]\n", "B = [[1,2,3],[1,2,3],[1,2,3]]\n", "> ```\n", "> _Expected Output_\n", "> ```python\n", "[6, 12, 18]\n", "[7, 14, 21]\n", "[8, 16, 24]\n", "> ```" ] }, { "cell_type": "markdown", "metadata": { "id": "u62kePpHWhdD" }, "source": [ "**Solution Bonus #2**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "8ErRb98nWhdE" }, "outputs": [], "source": [ "A = [[1,2,3],[2,0,5],[8,0,0]]\n", "B = [[1,2,3],[1,2,3],[1,2,3]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "dQLPdLIQ3mmS" }, "outputs": [], "source": [ "# your solution here" ] }, { "cell_type": "markdown", "metadata": { "id": "ovOSisCiawfM" }, "source": [ "## 1.5. Decorators" ] }, { "cell_type": "markdown", "metadata": { "id": "KcNIf8yF4u4E" }, "source": [ "### 1.5.1. Definition\n" ] }, { "cell_type": "markdown", "metadata": { "id": "pYRyAqSuDGs7" }, "source": [ "A decorator is a function that allow us to extend the behavior of another input function (without explicitly changing it).\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "kQq9jHf443H1" }, "source": [ "### 1.5.2. Example\n", "\n", "Let's consider the next function to sum to numbers `a` and `b`:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "aCJoP4FocfGq", "outputId": "922e7ed5-3bd0-4419-f850-7e1b13d30aed" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5\n" ] } ], "source": [ "def add_together(a, b):\n", " return a + b\n", "\n", "print(add_together(2,3))" ] }, { "cell_type": "markdown", "metadata": { "id": "ZC7d9QWcDNVl" }, "source": [ "Let's try to extends its behavior and make it operate for a list of pairs (`a`,`b`)." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "P3sRGK_kcfIp" }, "outputs": [], "source": [ "def decorator_list(func):\n", " def inner(list_of_tuples):\n", " l_result = []\n", " for val in list_of_tuples:\n", " # Note that `func` exists in this context\n", " l_result.append( func(val[0],val[1]) )\n", " return l_result\n", " return inner\n", "\n", "@decorator_list\n", "def add_together(a, b):\n", " return a + b" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "tzvudvOacfLE", "outputId": "5af5b490-f6e9-4304-888d-74689acd7125" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[3, 5, 7, 9, 11, 13]\n" ] } ], "source": [ "print(add_together([(1,2),(2,3),(3,4),(4,5),(5,6),(6,7)]))" ] }, { "cell_type": "markdown", "metadata": { "id": "vPPyz8OBEbxl" }, "source": [ "As you saw, we did not need to change anything from our first function called `add_together`. Instead, we just added `@decorator_name` before its definition.\n", "\n", "This helps a lot to expand the functionalities of your functions without the need of modifying them." ] }, { "cell_type": "markdown", "metadata": { "id": "3OCigvivfGX1" }, "source": [ "So, decorators are an elegant way to extend functionalities of your functoins without the need of modifying them!\n", "\n", "**(Spoiler)** We will use decorators in more detail tomorrow. It will help us to speed-up our python code 🔥!." ] }, { "cell_type": "markdown", "metadata": { "id": "fFbwznee2c3Z" }, "source": [ "### 1.5.3. Exercise\n" ] }, { "cell_type": "markdown", "metadata": { "id": "N4RhXjiRIEYJ" }, "source": [ "Given the function `divide` as follows:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "i4x8f-Vs5k3O" }, "outputs": [], "source": [ "def divide(a, b):\n", " print(a/b)" ] }, { "cell_type": "markdown", "metadata": { "id": "xZeB5Rv35ozV" }, "source": [ "Create a decorator called `smart_divide(func)` that receives as input the function called `divide(a,b)` and executes it only if `b` is not `0`. Otherwise, print `\"I cannot divide!\"` and `return None`. " ] }, { "cell_type": "markdown", "metadata": { "id": "0Ijk9e9pIHcq" }, "source": [ "\n", "### 1.5.4. Solution\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "hnw7XZXuIGoo" }, "outputs": [], "source": [ "def smart_divide(func):\n", " # your code here\n", "\n", "@smart_divide\n", "def divide(a, b):\n", " print(a/b)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "UhrgioysJP0D", "outputId": "4cf494ae-6c56-4c40-eade-b5d1fcd0cbef" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I am going to divide 7 and 2\n", "3.5\n" ] } ], "source": [ "divide(a=7, b=2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "lQ5YnsIZJLkC", "outputId": "6f052ccc-6096-4d30-a2c8-27003d7414cd" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "I am going to divide 7 and 0\n", "Whoops! cannot divide\n" ] } ], "source": [ "divide(a=7, b=0)" ] }, { "cell_type": "markdown", "metadata": { "id": "r1VMeUYoIEwB" }, "source": [ "\n", "---\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "26NZ8rI3jaGo" }, "source": [ "## 1.6. Practical part: Python built-in functions." ] }, { "cell_type": "markdown", "metadata": { "id": "UGuBEOhZj48P" }, "source": [ "### 1.6.1. Section Exercise" ] }, { "cell_type": "markdown", "metadata": { "id": "0fbj40nmjhAS" }, "source": [ "**A distance measure between two vectors as lists**\n", "\n", "Create a function called `vector_distance` that receives three input parameters:\n", "+ `x`: a list of integers.\n", "+ `y`: a list of integers.\n", "+ `f`: a function that operates two input parameters: `a` and `b`.\n", "\n", "\n", "Then, `vector_distance` should return the mean distance after operating each pair of element (`a`,`b`) by the function `f`.\n", "\n", "Note: assume that `x` and `y` have the same lengths (i.e., number of elements)\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "zqtIUU_Xhgq0" }, "source": [ "### 1.6.2. Solution" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "_sdWOvukjgDp" }, "outputs": [], "source": [ "x = [1,2,4,8]\n", "y = [1,3,9,27]\n", "\n", "def abs_distance(a, b):\n", " return abs(a-b)\n", "\n", "def sq_distance(a, b):\n", " return (a-b)**2\n", "\n", "def inter_distance(a, b):\n", " _min = min(a,b)\n", " _max = max(a,b)\n", " return (_max / (_min + _max))\n", "\n", "def vector_distance(x, y, f):\n", " # your code here!\n", " print(\"Not implemented yet!\")" ] }, { "cell_type": "markdown", "metadata": { "id": "xbqUdFGvkumR" }, "source": [ "Try your implementation:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "mBRF8I5ikuSA", "outputId": "6861b088-efd9-42c2-a1d3-4bf17af18d75" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Not implemented yet!\n", "abs_distance : None \n", "\n", "Not implemented yet!\n", "sq_distance : None \n", "\n", "Not implemented yet!\n", "inter_distance: None \n", "\n" ] } ], "source": [ "print(\"abs_distance :\", vector_distance(x, y, abs_distance))\n", "print(\"sq_distance :\", vector_distance(x, y, sq_distance))\n", "print(\"inter_distance:\", vector_distance(x, y, inter_distance))" ] }, { "cell_type": "markdown", "metadata": { "id": "4wgCDbdYrpFl" }, "source": [ "\n", "**Bonus: A distance measure between two matrices as nested lists.**\n", "\n", "1. A distance function called `matrix_distance` which, instead of computing a distance `f(a,b)` receives as inputs two matrices `X` and `Y` as nested lists.\n", "\n", "2. Create a function called `matmut` to multiply two matrices `X` and `Y` (nested lists).\n", "\n", "3. Modify the previous function `matmul` to apply the function `vector_distance` instead of multiplying and sum the element of a row and a column." ] }, { "cell_type": "markdown", "metadata": { "id": "vvLgpg5CmIUy" }, "source": [ "-----" ] }, { "cell_type": "markdown", "metadata": { "id": "7QZiMhKa7F38" }, "source": [ "## 1.7. Python modules" ] }, { "cell_type": "markdown", "metadata": { "id": "YxT_OKnAe25g" }, "source": [ "### 1.7.1. What is a Python module?" ] }, { "cell_type": "markdown", "metadata": { "id": "QQDpo5yq6Hf1" }, "source": [ "A python module is a reusable chunk of code that you may want to include in your programs / projects.\n", "\n", "Compared to languages like C/C++, a Python libraries do not pertain to any specific context in Python. \n", "\n", "Then, a library is a collection of modules." ] }, { "cell_type": "markdown", "metadata": { "id": "DyTqEUQfk-yX" }, "source": [ "### 1.7.2. Importing Python's modules" ] }, { "cell_type": "markdown", "metadata": { "id": "TpEOmvLtKCGN" }, "source": [ "#### 1.7.2.1. Math Module" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "qAHzMaub8_X5" }, "outputs": [], "source": [ "import math" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Ue_5SXKw93kl", "outputId": "0cfe118d-c5b0-42d6-d3fb-65578c108ca5" }, "outputs": [ { "data": { "text/plain": [ "-1.0" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.cos(math.pi) # -1.0" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "xFmbmyA-B8g6", "outputId": "1ca8ae69-845c-44e6-d75e-95ae9b25e2d1" }, "outputs": [ { "data": { "text/plain": [ "1.2246467991473532e-16" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.sin(math.pi) # 0.0" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "o8loo5J8Cmov", "outputId": "ad565b1d-7510-4dc2-a115-ee041404c5e1" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n", "3\n" ] } ], "source": [ "# round a float up or down\n", "print( math.ceil(3.3))\n", "print( math.floor(3.3))" ] }, { "cell_type": "markdown", "metadata": { "id": "74YkmCU8KEel" }, "source": [ "#### 1.7.2.2. Random Module" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "XCIIpXUJCDN3" }, "outputs": [], "source": [ "import random" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "gAqV9bXh_RNa", "outputId": "0717977c-4404-4306-fd0a-3124f17791a0" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Construct a seeded random number generator:\n", "0.5824475071608946\n" ] } ], "source": [ "print(\"Construct a seeded random number generator:\")\n", "print(random.random())" ] }, { "cell_type": "markdown", "metadata": { "id": "j8Prpb3GKGsF" }, "source": [ "#### 1.7.2.3. Time Module" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "9OarX5ZkSr9c" }, "outputs": [], "source": [ "from time import time" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "fjX_u9hNKZMF", "outputId": "99b4a40a-6a30-473a-d3d3-61b2df7f7b72" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total time 0.0014522075653076172 Seconds\n" ] } ], "source": [ "t_start = time()\n", "n_numbers = 10_000\n", "for i in range(n_numbers):\n", " temp = random.random()\n", "t_end = time()\n", "total_time = time() - t_start\n", "print(\"Total time\", total_time, \"Seconds\")" ] }, { "cell_type": "markdown", "metadata": { "id": "XbVivF-a7Rq_" }, "source": [ "Computation times usually fluctuate a lot. In order to have a better estimation we compute the mean (and standard deviation) of a vector of times.\n", "\n", "Let's see this point with an example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "jNKfuoqU8NM4" }, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "aUWFBsBSC6R6" }, "outputs": [], "source": [ "l_times = []\n", "\n", "# define a method to sum\n", "def my_sum(my_list):\n", " result = 0\n", " for i in range(len(my_list)):\n", " result = result + my_list[i]\n", " return result \n", "\n", "# generating random numbers\n", "random_numbers = []\n", "for i in range(n_numbers):\n", " temp = random.random()\n", " random_numbers.append( temp )\n", "\n", "# measuring time\n", "for i in range(10):\n", " t_start = time()\n", " my_sum(random_numbers)\n", " total_time = time() - t_start\n", " l_times.append( total_time )\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "FtBK3e83TGxl", "outputId": "79cf1288-01e0-4ddb-9fcf-ea48b34be056" }, "outputs": [ { "data": { "text/plain": [ "[0.002279996871948242,\n", " 0.009655237197875977,\n", " 0.0012543201446533203,\n", " 0.0012154579162597656,\n", " 0.011293411254882812,\n", " 0.0012998580932617188,\n", " 0.003256082534790039,\n", " 0.0012285709381103516,\n", " 0.0011463165283203125,\n", " 0.0012488365173339844]" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "l_times" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "Lh_AhFsm7jTn", "outputId": "ddc2eca5-83c2-4239-fc99-fbdcd7393a1b" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "mean 0.0033878087997436523\n" ] } ], "source": [ "print(\"mean\", sum(l_times)/len(l_times))" ] }, { "cell_type": "markdown", "metadata": { "id": "ZrC-MXhfMCGA" }, "source": [ "#### 1.7.2.4. Exercises" ] }, { "cell_type": "markdown", "metadata": { "id": "4vFGlqgQMEaR" }, "source": [ "Create function that returns a list of $n \\geq 1$ random numbers between -1 and 1.\n", "Validate $n$: if $n$ is less than 1, then return an empty list.\n", "\n", "**(Bonus):**\n", "\n", "Measure the time needed to compute the sum of 1000 random numbers (in seconds)." ] }, { "cell_type": "markdown", "metadata": { "id": "HiN327yN-ddR" }, "source": [ "**Solution**" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "UZXA6ZaWQp2X" }, "outputs": [], "source": [ "# your code here !" ] }, { "cell_type": "markdown", "metadata": { "id": "MWqNG0jxZNkF" }, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": { "id": "6_wqDGsG9yv2" }, "source": [ "## 1.8. Creating Python's modules\n", "\n", "![](https://www.cognizantsoftvision.com/wp-content/uploads/2017/12/06014912/Top-10-Python-libraries-of-2016.jpg)\n", "\n", "(_Image source: Cognizant Softvision_)." ] }, { "cell_type": "markdown", "metadata": { "id": "sqUisK2X_ELy" }, "source": [ "### 1.8.1. Introduction" ] }, { "cell_type": "markdown", "metadata": { "id": "W7Poaa6Z_PCC" }, "source": [ "You can create your own modules and packages in Python. This will make easier to maintain and debug your code.\n", "\n", "Some of the benefits of modularizing your code are:\n", "+ Keeping a clear distritribution of functions you use, avoiding duplication.\n", "+ Sharing your code with colleagues or a community.\n", "+ You can show that a certain method works or an algorithm. For example: after finishing a paper, you can upload and make public the data and the code (if possible).\n", "+ Many others!" ] }, { "cell_type": "markdown", "metadata": { "id": "yCgs9tqetu88" }, "source": [ "### 1.8.2. My first python module (Google Colab)\n", "\n" ] }, { "cell_type": "markdown", "metadata": { "id": "iW9pW2N2zQXx" }, "source": [ "#### 1.8.2.1. Creating a python module\n", "Follow the next steps:\n", "\n", "1. Go to \"Files\", to the right of \"Table of contents\" panel.\n", "2. Do right-click and select \"New file\". We will create a python file (`*.py`). Name such file as `my_python_module.py`.\n", "3. Do double left-click on it. A new panel will appear in our Colab user interface. There write your own module!.\n", "4. We can start with the following code:\n", "\n", "```python\n", "import random\n", "def create_random_numbers(n):\n", " my_list = []\n", " for i in range(n):\n", " random_num = random.random()\n", " random_num = (random_num*2) - 1\n", " my_list.append( random_num )\n", " return my_list\n", "```" ] }, { "cell_type": "markdown", "metadata": { "id": "V_uMU1RZw9QG" }, "source": [ "#### 1.8.2.2. Importing my python module\n", "\n", "We can import the module as follows:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "wdsimX5-w9QI" }, "outputs": [], "source": [ "import my_python_module" ] }, { "cell_type": "markdown", "metadata": { "id": "hJRY2grew9QJ" }, "source": [ "One way to see what is the content of your python module is by doing `dir(your_module)`." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "598Tb_Phw9QK", "outputId": "64d00419-b427-4ee8-8d5a-e9b18cbecfa7" }, "outputs": [ { "data": { "text/plain": [ "['__builtins__',\n", " '__cached__',\n", " '__doc__',\n", " '__file__',\n", " '__loader__',\n", " '__name__',\n", " '__package__',\n", " '__spec__',\n", " 'create_random_numbers',\n", " 'random']" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dir(my_python_module)" ] }, { "cell_type": "markdown", "metadata": { "id": "rX31Okesw9QL" }, "source": [ "Let's use the function of `my_python_lib`" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "Dyw1hhA-xR0B" }, "outputs": [], "source": [ "n_random_numbers = 50\n", "random_numbers = my_python_module.create_random_numbers(n_random_numbers)" ] }, { "cell_type": "markdown", "metadata": { "id": "uyhE2HEJwM9R" }, "source": [ "That's it!\n", "\n", "By using modules, we can make our analysis more robust as we are leveraging existing code. When we create our modules, we can publish them and helps ourselves and other programmers/scientists to use them in future analyses 😀. " ] }, { "cell_type": "markdown", "metadata": { "id": "oVLcpJrEyUNJ" }, "source": [ "#### 1.8.2.3. Exercise\n", "\n", "Add and test the following function into your module called `my_python_module`:\n", "\n", "```python\n", "def add_together(a, b):\n", " return a + b\n", "```" ] }, { "cell_type": "markdown", "metadata": { "id": "pPvTVZoOy_Hs" }, "source": [ "#### 1.8.2.4. Solution" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "id": "mHoPQLAXy-qy" }, "outputs": [], "source": [ "# your code here !" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "\n", "Day #1 of the summer course \"_Introduction to High-Performance Computing in Python for Scientists!_\". \n", "\n", "\n", "[Goethe Research Academy for Early Career Researchers (GRADE)](https://www.goethe-university-frankfurt.de/), Goethe University Frankfurt, Germany. June 2022.\n", "\n", "---" ] } ], "metadata": { "colab": { "collapsed_sections": [], "name": "TCR-HPC-D1_github - Scientific Computing with Python.ipynb", "provenance": [], "toc_visible": true }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5" } }, "nbformat": 4, "nbformat_minor": 1 }