diff --git a/Notebook2_Wilson_Barrera.ipynb b/Notebook2_Wilson_Barrera.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..4f1304ee16bbe733083ee014b9b202f7c3d531c3
--- /dev/null
+++ b/Notebook2_Wilson_Barrera.ipynb
@@ -0,0 +1,1216 @@
+{
+  "cells": [
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "h6xUw6cmzrmb"
+      },
+      "source": [
+        "<img src=\"https://gitlab.com/bivl2ab/academico/cursos-uis/ai/ai-uis-student/raw/master/imgs/banner_IA.png\"  width=\"1000px\" height=\"250px\">\n",
+        "\n",
+        "\n",
+        "# <center> **02. Numpy Review! </center>**\n",
+        "\n",
+        "\n",
+        "##  **Outline**\n",
+        "1. [**Numpy introduction**](#eje1)\n",
+        "2. [**Vector, matrices and axis**](#eje2)\n",
+        "3. [**Math operations**](#eje3)\n",
+        "\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 1,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/",
+          "height": 36
+        },
+        "id": "zdP4n3FMQepe",
+        "outputId": "28dad7ae-5a96-47ef-fdc4-2211c248a505",
+        "cellView": "form"
+      },
+      "outputs": [
+        {
+          "output_type": "execute_result",
+          "data": {
+            "text/plain": [
+              "\"\\nPut your student ID here\\n\\nExample: student_id =  '2152145'\\n\""
+            ],
+            "application/vnd.google.colaboratory.intrinsic+json": {
+              "type": "string"
+            }
+          },
+          "metadata": {},
+          "execution_count": 1
+        }
+      ],
+      "source": [
+        "#@title Execute this cell\n",
+        "#@markdown Please include your student id\n",
+        "import sys\n",
+        "import inspect\n",
+        "\n",
+        "group_id = \"DA-20241-Laconga\" #@param {type:\"string\"}\n",
+        "assignment_id = group_id +'.numpy'\n",
+        "student_id = \"2904109\" #@param {type:\"string\"}\n",
+        "\"\"\"\n",
+        "Put your student ID here\n",
+        "\n",
+        "Example: student_id =  '2152145'\n",
+        "\"\"\""
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 2,
+      "metadata": {
+        "id": "Irfg11RlQeec",
+        "cellView": "form"
+      },
+      "outputs": [],
+      "source": [
+        "#@title **Execute this cell**\n",
+        "#@markdown **UTILS**\n",
+        "#@markdown Please dont modify any line in this cell\n",
+        "\n",
+        "import os\n",
+        "import json\n",
+        "import requests\n",
+        "from collections import namedtuple\n",
+        "\n",
+        "\n",
+        "Config = namedtuple('Config', ['server_name'])\n",
+        "config = Config(server_name='https://bivlabgrader.azurewebsites.net/api')\n",
+        "\n",
+        "\n",
+        "def check_solution_and_evaluate(assignment_id: str, student_func_str: str):\n",
+        "\n",
+        "    # Set the endpoint and payload.\n",
+        "    payload = {\n",
+        "        'func_str': student_func_str,\n",
+        "        'assignment_id': assignment_id,\n",
+        "        'student_id': student_id\n",
+        "    }\n",
+        "    endpoint_url = config.server_name + '/CheckAndEvaluateSolution'\n",
+        "    # print(endpoint_url)\n",
+        "\n",
+        "    # Make request to server with the data coming from the notebook.\n",
+        "    r = requests.post(endpoint_url, params=payload)\n",
+        "    pprint_json_response(r.json())\n",
+        "    return r\n",
+        "\n",
+        "\n",
+        "def pprint_json_response(response, indent=0):\n",
+        "    \"\"\"Pretty print the response.\"\"\"\n",
+        "    for key, value in response.items():\n",
+        "        print('\\t' * indent + str(key.capitalize()))\n",
+        "\n",
+        "        # If dictionary, do a recurrent call.\n",
+        "        if isinstance(value, dict):\n",
+        "            pprint_json_response(value, indent + 1)\n",
+        "        else:\n",
+        "            # Enumerate elements if list.\n",
+        "            if isinstance(value, list):\n",
+        "                if len(value) == 1:\n",
+        "                    print('\\t' * (indent + 1) + str(value[0]))\n",
+        "                else:\n",
+        "                    for i, e in enumerate(value, start=1):\n",
+        "                        print('\\t' * (indent + 1) + f'{i}. {e}')\n",
+        "            else:\n",
+        "                print('\\t' * (indent + 1) + str(value))"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "qP70yL5NzroQ"
+      },
+      "source": [
+        "# **1. Numpy introduction**  <a name=\"eje1\"></a>\n",
+        "\n",
+        "The `Numpy`  library allows the efficient manage of **tensors**, it to say, multidimensional arrays. \"NumPy was an important part of the software stack used in the discovery of gravitational waves and in the first imaging of a black hole2 [7]\"\n",
+        "\n",
+        "<img src=\"https://gitlab.com/bivl2ab/academico/cursos-uis/ai/ai-uis-student/raw/master/imgs/numpy.png\" width=\"700\">\n"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "XLjJn5SStbp4"
+      },
+      "source": [
+        "# **2. Vector, matrices and axis** <a name=\"eje2\"></a>\n",
+        "\n",
+        "### **2.1 Vector and matrices from `ndarray`**\n",
+        "The `ndarray` are homogenous (same type)  **data containers**  and **functions** to operate over the data. Operations are highly efficient.\n",
+        "    - It is indexed as non-negative integers\n",
+        "    - The number of dimensions is the `rank`\n",
+        "    - `shape` is a tuple with size along each dimension\n",
+        "Some initial notation and how the dimensions works are expressed as follows."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 3,
+      "metadata": {
+        "id": "wNkC0MzRzroT",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "8eac3cb3-fda4-4332-faa3-77316c5e0ece"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "a shape (7, 5)\n",
+            "a rows 7\n",
+            "a cols 5\n",
+            "v shape (8,)\n",
+            "v elems 8\n",
+            "<class 'numpy.ndarray'>\n",
+            "float64\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **code** working with **Numpy**\n",
+        "import numpy as np # the convention to import numpy\n",
+        "\n",
+        "a = np.array([[1,2,3,4,5],\n",
+        "              [5,4,3,2,1],\n",
+        "              [9,8,7,6,5],\n",
+        "              [7,6,5,6,7],\n",
+        "              [2,2,2,3,3],\n",
+        "              [4,3,4,3,4],\n",
+        "              [5,1,1,4,1]])\n",
+        "print( \"a shape\", a.shape) # (filas, columnas)\n",
+        "print( \"a rows\", a.shape[0])\n",
+        "print( \"a cols\", a.shape[1])\n",
+        "\n",
+        "v = np.array([2,3,4,5,6,7,3,12])\n",
+        "print( \"v shape\", v.shape)\n",
+        "print( \"v elems\", v.shape[0])\n",
+        "print(type(v))\n",
+        "\n",
+        "x = np.array([1, 2], dtype=np.float64)   # Force a particular datatype\n",
+        "print(x.dtype)"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 4,
+      "metadata": {
+        "id": "UFFp2M2kzror",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "b1c2779e-29eb-467a-84db-02bb7d59c823"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "[[1 2 3 4 5]\n",
+            " [5 4 3 2 1]\n",
+            " [9 8 7 6 5]\n",
+            " [7 6 5 6 7]\n",
+            " [2 2 2 3 3]\n",
+            " [4 3 4 3 4]\n",
+            " [5 1 1 4 1]]\n",
+            "una fila         [9 8 7 6 5]\n",
+            "una fila         [9 8 7 6 5]\n",
+            "una columna      [3 3 7 5 2 4 1]\n",
+            "un elemento      7\n",
+            "varias filas    \n",
+            " [[9 8 7 6 5]\n",
+            " [7 6 5 6 7]\n",
+            " [2 2 2 3 3]]\n",
+            "varias columnas \n",
+            " [[2 3]\n",
+            " [4 3]\n",
+            " [8 7]\n",
+            " [6 5]\n",
+            " [2 2]\n",
+            " [3 4]\n",
+            " [1 1]]\n",
+            "una porcion     \n",
+            " [[8 7]\n",
+            " [6 5]\n",
+            " [2 2]]\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **code** slicing on `ndarray` structures.\n",
+        "print(a)\n",
+        "print(\"una fila        \" ,a[2])\n",
+        "print( \"una fila        \",a[2,:])\n",
+        "print( \"una columna     \",a[:,2])\n",
+        "print( \"un elemento     \",a[2,2])\n",
+        "print( \"varias filas    \\n\",a[2:5])\n",
+        "print( \"varias columnas \\n\",a[:,1:3])\n",
+        "print( \"una porcion     \\n\",a[2:5,1:3])\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 5,
+      "metadata": {
+        "id": "5tSU31DnAtaR",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "3fa48e2e-83c0-42b6-92cd-e6047d555034"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "[[0. 0.]\n",
+            " [0. 0.]]\n",
+            "[[1. 1.]]\n",
+            "[[7 7]\n",
+            " [7 7]]\n",
+            "[[1. 0.]\n",
+            " [0. 1.]]\n",
+            "matrix identidad\n",
+            " [[1. 0. 0.]\n",
+            " [0. 1. 0.]\n",
+            " [0. 0. 1.]]\n",
+            "matrix identidad\n",
+            " [[1. 0. 0.]\n",
+            " [0. 1. 0.]\n",
+            " [0. 0. 1.]]\n",
+            "vector de ceros [0. 0. 0. 0.]\n",
+            "matriz de ceros\n",
+            " [[0. 0.]\n",
+            " [0. 0.]\n",
+            " [0. 0.]]\n",
+            "matriz de unos\n",
+            " [[1. 1. 1.]\n",
+            " [1. 1. 1.]]\n",
+            "vector rango [0 1 2 3 4 5 6 7 8 9]\n",
+            "vector rango [5 6 7 8 9]\n",
+            "matriz aleatoria según distribución uniforme [0,1]\n",
+            " [[0.33243408 0.34095528 0.34477179 0.02798027 0.65546526]\n",
+            " [0.48602333 0.89836108 0.45181737 0.5398295  0.73810968]\n",
+            " [0.06933923 0.35053601 0.64616254 0.50731578 0.42066507]]\n",
+            "vector aleatorio de enteros entre 0 y 5 [2 1 1 0 1 4 2 0 4 4]\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **code:** Easy construction of matrices and vectors\n",
+        "b = np.zeros((2,2))   # Create an array of all zeros\n",
+        "print(b)              # Prints \"[[ 0.  0.]\n",
+        "                      #          [ 0.  0.]]\"\n",
+        "\n",
+        "c = np.ones((1,2))    # Create an array of all ones\n",
+        "print(c)              # Prints \"[[ 1.  1.]]\"\n",
+        "\n",
+        "d = np.full((2,2), 7)  # Create a constant array\n",
+        "print(d)               # Prints \"[[ 7.  7.]\n",
+        "                       #          [ 7.  7.]]\"\n",
+        "\n",
+        "f = np.eye(2)         # Create a 2x2 identity matrix\n",
+        "print(f)              # Prints \"[[ 1.  0.]\n",
+        "                      #          [ 0.  1.]]\"\n",
+        "\n",
+        "print( \"matrix identidad\\n\", np.eye(3))\n",
+        "print( \"matrix identidad\\n\", np.identity(3))\n",
+        "print( \"vector de ceros\", np.zeros(4))\n",
+        "print( \"matriz de ceros\\n\", np.zeros((3,2)))\n",
+        "print( \"matriz de unos\\n\", np.ones((2,3)))\n",
+        "print( \"vector rango\", np.arange(10))\n",
+        "print( \"vector rango\", np.arange(5,10))\n",
+        "print( \"matriz aleatoria según distribución uniforme [0,1]\\n\", np.random.random(size=(3,5)))\n",
+        "print( \"vector aleatorio de enteros entre 0 y 5\", np.random.randint(5, size=10))"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "xLySLwIhzro0"
+      },
+      "source": [
+        "<img src=\"https://gitlab.com/bivl2ab/academico/cursos-uis/ai/ai-2-uis-student/-/raw/master/imgs/icon1.png\" width=\"200\">\n",
+        "\n",
+        "- How works `np.linspace(A,B,C))`?. Replace A, B, and C by any number and evaluate the funtion.\n",
+        "\n",
+        "- Create a random matrix of integers `Aa` with Row>4 rows and Col>10 colums.\n",
+        "\n",
+        "- Which means the next notation `Aa[:2, 1:3]` ?.\n",
+        "\n",
+        "- Which is the output?"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 51,
+      "metadata": {
+        "id": "I684UtRlDrC-"
+      },
+      "outputs": [],
+      "source": [
+        "#@title **code student**\n",
+        "A =  -3#@param {type:\"integer\"}\n",
+        "B =  8#@param {type:\"integer\"}\n",
+        "C =   6#@param {type:\"integer\"}\n",
+        "Row =   5#@param {type:\"integer\"}\n",
+        "Col =   11#@param {type:\"integer\"}\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "row=5\n",
+        "col=11\n",
+        "Aa=np.random.random(size=(row,col))\n",
+        "\n",
+        "print(Aa,\" \\n\")\n",
+        "print(Aa[:2, 1:3],\" \\n\")"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "lu2epyHwQVME",
+        "outputId": "e187bd1c-cf84-4919-f0eb-ec0b2fd9dcea"
+      },
+      "execution_count": 53,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "[[0.22345943 0.64528651 0.73729393 0.86980738 0.05600251 0.87557119\n",
+            "  0.81985373 0.92046863 0.56040921 0.61181743 0.54454255]\n",
+            " [0.36501934 0.32719557 0.42539835 0.31651316 0.80967469 0.65809695\n",
+            "  0.3998071  0.61212675 0.20953604 0.82539621 0.5886512 ]\n",
+            " [0.28137152 0.16954939 0.15375192 0.49889757 0.8593513  0.49654506\n",
+            "  0.13856989 0.22863108 0.38536776 0.47051217 0.87835082]\n",
+            " [0.42281821 0.01896247 0.36150034 0.30271687 0.88347506 0.75355268\n",
+            "  0.31743792 0.22725246 0.86967348 0.77252954 0.66156584]\n",
+            " [0.54198344 0.44503912 0.57235895 0.2930554  0.9858733  0.36093274\n",
+            "  0.32367438 0.48125258 0.63216613 0.57071737 0.15088475]]  \n",
+            "\n",
+            "[[0.64528651 0.73729393]\n",
+            " [0.32719557 0.42539835]]  \n",
+            "\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "91gi2BFbzrpA"
+      },
+      "source": [
+        "### **2.2 `axis`**\n",
+        "\n",
+        "<img src=\"https://gitlab.com/bivl2ab/academico/cursos-uis/ai/ai-uis-student/raw/master/imgs/axis_numpy.png\" width=\"700\">\n",
+        "\n",
+        "Many functions in `numpy` can be executed from independent columns and rows  by using the argument value of `axis`.\n",
+        "\n",
+        "Axes are defined for arrays with more than one dimension. A 2-dimensional array has two corresponding axes:\n",
+        "- the first running vertically downwards across rows (axis 0)\n",
+        "- the second running horizontally across columns (axis 1)"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 7,
+      "metadata": {
+        "id": "xe4qGDWHzrpB",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "838e9530-1b8b-46fa-ffb7-ae3233e90089"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "[[77 49 41 26]\n",
+            " [10 30 99 29]\n",
+            " [ 5 18 34 71]]\n",
+            "[193 168 128]\n",
+            "a: \n",
+            "[[1 2 3 4 5]\n",
+            " [5 4 3 2 1]\n",
+            " [9 8 7 6 5]\n",
+            " [7 6 5 6 7]\n",
+            " [2 2 2 3 3]\n",
+            " [4 3 4 3 4]\n",
+            " [5 1 1 4 1]]\n",
+            "suma total 138\n",
+            "suma eje 0 [33 26 25 28 26]\n",
+            "suma eje 1 [15 15 35 31 12 18 12]\n",
+            "promedio total 3.942857142857143\n",
+            "promedio eje 0 [4.71428571 3.71428571 3.57142857 4.         3.71428571]\n",
+            "promedio eje 1 [3.  3.  7.  6.2 2.4 3.6 2.4]\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **code** working wit **`axis`**\n",
+        "z = np.random.randint(100, size=(3,4)) # Create an array filled with random values\n",
+        "print(z)\n",
+        "print(np.sum(z, axis=1))\n",
+        "\n",
+        "\n",
+        "a = np.array([[1,2,3,4,5],\n",
+        "              [5,4,3,2,1],\n",
+        "              [9,8,7,6,5],\n",
+        "              [7,6,5,6,7],\n",
+        "              [2,2,2,3,3],\n",
+        "              [4,3,4,3,4],\n",
+        "              [5,1,1,4,1]])\n",
+        "\n",
+        "print(\"a: \")\n",
+        "print(a)\n",
+        "\n",
+        "print(\"suma total\", np.sum(a))\n",
+        "print(\"suma eje 0\", np.sum(a, axis=0))\n",
+        "print(\"suma eje 1\", np.sum(a, axis=1))\n",
+        "print(\"promedio total\", np.mean(a))\n",
+        "print(\"promedio eje 0\", np.mean(a, axis=0))\n",
+        "print(\"promedio eje 1\", np.mean(a, axis=1))"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "VjSdFKypXzVp"
+      },
+      "source": [
+        "### **Logical slicing and indexing**\n",
+        "The numpy functions also works with _boolean_ expressions. For instance to select some specific objects."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 8,
+      "metadata": {
+        "id": "BXfPrrhFVVX6",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "02fc630a-c9db-465e-e46e-bbe42d18987a"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "[[False False]\n",
+            " [ True  True]\n",
+            " [ True  True]]\n",
+            "[3 4 5 6]\n",
+            "[3 4 5 6]\n",
+            "[ 1  8  4 10 -4  5]\n",
+            "[False  True False  True False  True]\n",
+            "[ 8 10  5]\n",
+            "posiciones en a >4: [False  True False  True False  True]\n",
+            "elementos de a >4: [ 8 10  5]\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **code** Boolean array indexing\n",
+        "a = np.array([[1,2], [3, 4], [5, 6]])\n",
+        "\n",
+        "bool_idx = (a > 2)   # Find the elements of a that are bigger than 2;\n",
+        "                     # this returns a numpy array of Booleans of the same\n",
+        "                     # shape as a, where each slot of bool_idx tells\n",
+        "                     # whether that element of a is > 2.\n",
+        "\n",
+        "print(bool_idx)      # Prints \"[[False False]\n",
+        "                     #          [ True  True]\n",
+        "                     #          [ True  True]]\"\n",
+        "\n",
+        "# We use boolean array indexing to construct a rank 1 array\n",
+        "# consisting of the elements of a corresponding to the True values\n",
+        "# of bool_idx\n",
+        "print(a[bool_idx])  # Prints \"[3 4 5 6]\"\n",
+        "\n",
+        "# We can do all of the above in a single concise statement:\n",
+        "print(a[a > 2])     # Prints \"[3 4 5 6]\"\n",
+        "\n",
+        "a = np.array([1,8,4,10,-4,5])\n",
+        "print(a)\n",
+        "print(a>4)\n",
+        "print(a[a>4])\n",
+        "\n",
+        "a = np.array([1,8,4,10,-4,5])\n",
+        "print(\"posiciones en a >4:\", a>4)\n",
+        "print(\"elementos de a >4:\",a[a>4])"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "Nv6KnaCozrpw"
+      },
+      "source": [
+        "# **3. Math operations** <a name=\"eje3\"></a>\n",
+        "\n",
+        "\n",
+        "### **3.1 Math and vectorized operations with   `numpy`**\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 9,
+      "metadata": {
+        "id": "LsMZlaaxzrpx",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "367ea367-9244-44d7-bb66-ff316ad639b2"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "[10 12 13 15 20]\n",
+            "[11 13 14 16 21]\n",
+            "[20 24 26 30 40]\n",
+            "[[ 6.  8.]\n",
+            " [10. 12.]]\n",
+            "[[ 6.  8.]\n",
+            " [10. 12.]]\n",
+            "[[-4. -4.]\n",
+            " [-4. -4.]]\n",
+            "[[-4. -4.]\n",
+            " [-4. -4.]]\n",
+            "[[ 5. 12.]\n",
+            " [21. 32.]]\n",
+            "[[ 5. 12.]\n",
+            " [21. 32.]]\n",
+            "[[0.2        0.33333333]\n",
+            " [0.42857143 0.5       ]]\n",
+            "[[0.2        0.33333333]\n",
+            " [0.42857143 0.5       ]]\n",
+            "[[1.         1.41421356]\n",
+            " [1.73205081 2.        ]]\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **code** elementwise array operations\n",
+        "v = np.array([10,12,13,15,20])\n",
+        "print(v)\n",
+        "print(v+1)\n",
+        "print(v*2)\n",
+        "\n",
+        "x = np.array([[1,2],[3,4]], dtype=np.float64)\n",
+        "y = np.array([[5,6],[7,8]], dtype=np.float64)\n",
+        "\n",
+        "#overload and as functions\n",
+        "print(x + y)\n",
+        "print(np.add(x, y))\n",
+        "\n",
+        "# Elementwise difference; both produce the array\n",
+        "# [[-4.0 -4.0]\n",
+        "#  [-4.0 -4.0]]\n",
+        "print(x - y)\n",
+        "print(np.subtract(x, y))\n",
+        "\n",
+        "# Elementwise product; both produce the array\n",
+        "# [[ 5.0 12.0]\n",
+        "#  [21.0 32.0]]\n",
+        "print(x * y)\n",
+        "print(np.multiply(x, y))\n",
+        "\n",
+        "# Elementwise division; both produce the array\n",
+        "# [[ 0.2         0.33333333]\n",
+        "#  [ 0.42857143  0.5       ]]\n",
+        "print(x / y)\n",
+        "print(np.divide(x, y))\n",
+        "\n",
+        "# Elementwise square root; produces the array\n",
+        "# [[ 1.          1.41421356]\n",
+        "#  [ 1.73205081  2.        ]]\n",
+        "print(np.sqrt(x))"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "yifiiX5YzrqB"
+      },
+      "source": [
+        "- `*` is elementwise multiplication\n",
+        "- `dot` function to compute inner products of vectors   "
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 10,
+      "metadata": {
+        "id": "qye3DdcazrqM",
+        "scrolled": true,
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "4eb04253-38a3-4c0a-8197-141e5e82c00d"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "[[1 2 3]\n",
+            " [4 5 6]]\n",
+            "[[6 5 4]\n",
+            " [3 2 1]]\n",
+            "--\n",
+            " que esta haciendo: ??\n",
+            "[[17 22 27]\n",
+            " [22 29 36]\n",
+            " [27 36 45]]\n",
+            "matrix multiplication\n",
+            "[[17 22 27]\n",
+            " [22 29 36]\n",
+            " [27 36 45]]\n",
+            "[[17 22 27]\n",
+            " [22 29 36]\n",
+            " [27 36 45]]\n",
+            "pointwise\n",
+            "[[ 6 10 12]\n",
+            " [12 10  6]]\n",
+            "--\n",
+            "a+b\n",
+            " [[7 7 7]\n",
+            " [7 7 7]]\n",
+            "a**2\n",
+            " [[ 1  4  9]\n",
+            " [16 25 36]]\n",
+            "a*b\n",
+            " [[ 6 10 12]\n",
+            " [12 10  6]]\n",
+            "a x b'\n",
+            " [[28 10]\n",
+            " [73 28]]\n",
+            "a' x b\n",
+            " [[18 13  8]\n",
+            " [27 20 13]\n",
+            " [36 27 18]]\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **code** vector and elementwise operations\n",
+        "a = np.array([[1,2,3],[4,5,6]])\n",
+        "\n",
+        "b = np.array([[6,5,4],[3,2,1]])\n",
+        "c = np.array([[1,2],[4,5]])\n",
+        "print(a)\n",
+        "print(b)\n",
+        "print(\"--\")\n",
+        "print(\" que esta haciendo: ??\")\n",
+        "print(a.T.dot(a))\n",
+        "\n",
+        "print(\"matrix multiplication\")\n",
+        "print(a.T.dot(a))\n",
+        "print(np.dot(a.T, a))\n",
+        "print(\"pointwise\")\n",
+        "print(a*b)\n",
+        "\n",
+        "print(\"--\")\n",
+        "\n",
+        "print(\"a+b\\n\",a+b)\n",
+        "print(\"a**2\\n\", a**2)\n",
+        "print(\"a*b\\n\",a*b)\n",
+        "print(\"a x b'\\n\",a.dot(b.T))\n",
+        "print(\"a' x b\\n\",a.T.dot(b))\n"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "N5XcgrWmWoJW"
+      },
+      "source": [
+        "<img src=\"https://gitlab.com/bivl2ab/academico/cursos-uis/ai/ai-2-uis-student/-/raw/master/imgs/icon1.png\" width=\"200\">\n",
+        "\n",
+        "- Use the function `arange` to obtain a matrix  `SampleInd` of consecutive numbers from `0 to 19`.  \n",
+        "\n",
+        "- `Reshape` matrix to fix a matrix with dimension `SampleInd` with Row=5 rows and Col=4 colums.\n",
+        "\n",
+        "- Print matrix values and shape\n",
+        "- Return a vector with the values in `(row=2,col=3)`, `(row=4,col=3) `and  `(row=0,col=0)`"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 11,
+      "metadata": {
+        "id": "fh3O7RSXW2Gx",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "389bb8ac-68e1-49b7-9b17-accea83b48a2"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "[[ 0  1  2  3]\n",
+            " [ 4  5  6  7]\n",
+            " [ 8  9 10 11]\n",
+            " [12 13 14 15]\n",
+            " [16 17 18 19]] (5, 4)\n",
+            "[11 19  0]\n"
+          ]
+        }
+      ],
+      "source": [
+        "def sample_ind():\n",
+        "  import numpy as np\n",
+        "  SampleInd=np.arange(20)\n",
+        "  SampleInd=SampleInd.reshape((5,4))\n",
+        "  print(SampleInd,SampleInd.shape)\n",
+        "  values_vector = np.array([SampleInd[2, 3], SampleInd[4, 3], SampleInd[0, 0]])\n",
+        "\n",
+        "  return values_vector\n",
+        "print(sample_ind())"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 12,
+      "metadata": {
+        "id": "0pE6Nz0qW19A",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "f4738caf-f243-4dbb-801e-5de0c748d28f"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Score\n",
+            "\t5\n",
+            "Message\n",
+            "\tWell done. You got the highest score.\n",
+            "Status\n",
+            "\tYou have achieved your best score: 5\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **send your answer**\n",
+        "student_func_str = inspect.getsource(sample_ind)\n",
+        "r = check_solution_and_evaluate(assignment_id, student_func_str)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "B-BN4fTbzrqd"
+      },
+      "source": [
+        "## **2.4 Vectorization**\n",
+        "\n",
+        "Vectorization is used to speed up the Python code without using **loop** structures. For instance, the dot product (inner product) between two vector:\n",
+        "$$a_{1 \\times n} \\cdot b_{n\\times 1} = c$$\n"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 13,
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "TTj-idSszrqf",
+        "outputId": "b52cec40-e8be-44e2-c55f-5ec373771b2a"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "dot_product = 201281.0\n",
+            "Computation time = 10.404258999999971ms\n",
+            "\n",
+            "n_dot_product = 201281\n",
+            "Computation time = 0.19852399999997772ms\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **code** vectorization performance\n",
+        "import time\n",
+        "a = np.random.randint(10, size=10000)\n",
+        "b = np.random.randint(10, size=10000)\n",
+        "\n",
+        "#@markdown  Classical way\n",
+        "tic = time.process_time()\n",
+        "dot = 0.0;\n",
+        "\n",
+        "for i in range(len(a)):\n",
+        "      dot += a[i] * b[i]\n",
+        "\n",
+        "toc = time.process_time()\n",
+        "print(\"dot_product = \"+ str(dot));\n",
+        "print(\"Computation time = \" + str(1000*(toc - tic )) + \"ms\")\n",
+        "\n",
+        "#@markdown  vectorized way\n",
+        "\n",
+        "n_tic = time.process_time()\n",
+        "n_dot_product = np.dot(a, b)\n",
+        "n_toc = time.process_time()\n",
+        "\n",
+        "print(\"\\nn_dot_product = \"+str(n_dot_product))\n",
+        "print(\"Computation time = \"+str(1000*(n_toc - n_tic ))+\"ms\")"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "NSomNs1Rzrqy"
+      },
+      "source": [
+        "Another way, but with outer product (tensor product):\n",
+        "$$a_{n\\times1}b^{T}_{1\\times n} = c_{n\\times n}$$"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 14,
+      "metadata": {
+        "id": "Z96WDyMjzrq0",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "5da28e84-cc6f-414d-db11-07e8694574c4"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "outer_product = [[42. 28. 42. ... 49. 42. 35.]\n",
+            " [18. 12. 18. ... 21. 18. 15.]\n",
+            " [42. 28. 42. ... 49. 42. 35.]\n",
+            " ...\n",
+            " [48. 32. 48. ... 56. 48. 40.]\n",
+            " [18. 12. 18. ... 21. 18. 15.]\n",
+            " [ 0.  0.  0. ...  0.  0.  0.]]\n",
+            "Computation time = 106671.14216199999ms\n",
+            "outer_product = [[42 28 42 ... 49 42 35]\n",
+            " [18 12 18 ... 21 18 15]\n",
+            " [42 28 42 ... 49 42 35]\n",
+            " ...\n",
+            " [48 32 48 ... 56 48 40]\n",
+            " [18 12 18 ... 21 18 15]\n",
+            " [ 0  0  0 ...  0  0  0]]\n",
+            "\n",
+            "Computation time = 465.43927099999394ms\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **code**\n",
+        "#@markdown classical way\n",
+        "tic = time.process_time()\n",
+        "outer_product = np.zeros((len(a), len(b)))\n",
+        "\n",
+        "for i in range(len(a)):\n",
+        "    for j in range(len(b)):\n",
+        "        outer_product[i][j]= a[i]*b[j]\n",
+        "\n",
+        "toc = time.process_time()\n",
+        "print(\"outer_product = \"+ str(outer_product));\n",
+        "print(\"Computation time = \"+str(1000*(toc - tic ))+\"ms\")\n",
+        "#@markdown vectorized way\n",
+        "n_tic = time.process_time()\n",
+        "outer_product = np.outer(a, b)\n",
+        "n_toc = time.process_time()\n",
+        "\n",
+        "print(\"outer_product = \"+str(outer_product));\n",
+        "print(\"\\nComputation time = \"+str(1000*(n_toc - n_tic ))+\"ms\")"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "BNPr5-4Ozrrg"
+      },
+      "source": [
+        "Also, this mathematical expression:\n",
+        "$y^i = \\sum_{j=0}^{n}\\theta_{j}^{i}x_{j}^{i}=\\Theta X^\\top; i=\\{1,2\\}$, where lowercase letters correspond to elements and uppercase letters to matrices or vectors."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 15,
+      "metadata": {
+        "id": "5HtBJ6vvzrri",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "4325af2e-0114-47bd-aff4-fd70e3d78da8"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "[8.3  5.72]\n",
+            "[8.3  5.72]\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **code**\n",
+        "#@markdown elementwise operations\n",
+        "theta = np.array([0.4,0.04,0.3,0.2,0.5])\n",
+        "X = np.array([[1,5,8,9,7],\n",
+        "              [1,3,4,5,6]])\n",
+        "y = np.array([0.0,0.0])\n",
+        "\n",
+        "for m in list(range(2)):\n",
+        "    result = 0\n",
+        "    for n in list(range(5)):\n",
+        "        result = result + (theta[n]*X[m,n])\n",
+        "    y[m] = result\n",
+        "\n",
+        "print(y)\n",
+        "#@markdown Dot product\n",
+        "y = np.dot(theta,X.T)\n",
+        "print(y)\n",
+        "#@markdown What about time operations?"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "print(np.sum(np.array([0.4,0.04,0.3,0.2,0.5])*np.array([1,3,4,5,6])))"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "qX1Pl4Ro5D7A",
+        "outputId": "492f82a1-5502-452e-e773-e401e87dd57a"
+      },
+      "execution_count": null,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "5.72\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "TPYxJI0UT_jT"
+      },
+      "source": [
+        "<img src=\"https://gitlab.com/bivl2ab/academico/cursos-uis/ai/ai-2-uis-student/-/raw/master/imgs/icon1.png\" width=\"200\">\n",
+        "\n",
+        "\n",
+        "- Create a random matrix of size `30x40`.\n",
+        "- Compute the [Frobenius Norm](https://mathworld.wolfram.com/FrobeniusNorm.html) in two ways. The first one using Numpy and the second one iteraring over rows and columns using a loop.\n",
+        "- Return the computed norms."
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 46,
+      "metadata": {
+        "id": "HSEb8sWeUdvS"
+      },
+      "outputs": [],
+      "source": [
+        " #@title **code student**\n",
+        "def frobenius_norm(a):\n",
+        "  import numpy as np\n",
+        "\n",
+        "  y = np.zeros((2),dtype='float')\n",
+        "\n",
+        "  suma=0\n",
+        "\n",
+        "  y[0]=np.sqrt(np.trace(np.dot(a,a.T)))\n",
+        "\n",
+        "  for i in range(len(a[:,0])):\n",
+        "    for j in range(len(a[0,:])):\n",
+        "      suma=(a[i][j])**2+suma\n",
+        "\n",
+        "\n",
+        "\n",
+        "\n",
+        "  y[1]=suma**0.5\n",
+        "\n",
+        "\n",
+        "\n",
+        "\n",
+        "  return y"
+      ]
+    },
+    {
+      "cell_type": "code",
+      "source": [
+        "X = np.array([[1,5,8,9,7],\n",
+        "              [1,3,4,5,6]])\n",
+        "print(frobenius_norm(X))"
+      ],
+      "metadata": {
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "id": "0lKL2DWmLQD9",
+        "outputId": "c329cb07-0fc3-4603-f10f-11c92f213715"
+      },
+      "execution_count": 47,
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "[17.52141547 17.52141547]\n"
+          ]
+        }
+      ]
+    },
+    {
+      "cell_type": "code",
+      "execution_count": 48,
+      "metadata": {
+        "id": "ppuegPJsUg3L",
+        "colab": {
+          "base_uri": "https://localhost:8080/"
+        },
+        "outputId": "da9941bf-792b-4308-c4ea-5b38d9dace2f"
+      },
+      "outputs": [
+        {
+          "output_type": "stream",
+          "name": "stdout",
+          "text": [
+            "Score\n",
+            "\t5\n",
+            "Message\n",
+            "\tWell done. You got the highest score.\n",
+            "Status\n",
+            "\tYou have achieved your best score: 5\n"
+          ]
+        }
+      ],
+      "source": [
+        "#@title **send your answer**\n",
+        "student_func_str = inspect.getsource(frobenius_norm)\n",
+        "r = check_solution_and_evaluate(assignment_id, student_func_str)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "WNpbHNYpWSr8"
+      },
+      "source": [
+        "### **In summary**\n",
+        "\n",
+        "<img src=\"https://gitlab.com/bivl2ab/academico/cursos-uis/ai/ai-uis-student/raw/master/imgs/numpysummary.png\" width=\"700\">\n",
+        "\n",
+        "Taken from [7]."
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "WKWsJZiazrul"
+      },
+      "source": [
+        "## **About markdown please see the notebook complement 01**\n",
+        "\n"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "YCSA87eLzrvO"
+      },
+      "source": [
+        "## **Referencias**\n",
+        "\n",
+        "[1] [official numpy tutorial](https://docs.scipy.org/doc/numpy/user/quickstart.html)\n",
+        "\n",
+        "[2] [Datacamp tutorial of numpy](https://www.datacamp.com/community/tutorials/python-numpy-tutorial)\n",
+        "\n",
+        "[3] [Other tutorial](https://www.twilio.com/blog/2017/10/basic-statistics-python-numpy-jupyter-notebook.html)\n",
+        "\n",
+        "[4] [About dictionaries](https://docs.python.org/3.5/library/stdtypes.html#dict)\n",
+        "\n",
+        "[5] [Mathematical functions in numpy](https://docs.scipy.org/doc/numpy/reference/routines.math.html)\n",
+        "\n",
+        "[6] [More deeply in numpy](https://docs.scipy.org/doc/numpy/reference/)\n",
+        "\n",
+        "[7] [Array programming with NumPy. Nature](https://www.nature.com/articles/s41586-020-2649-2)"
+      ]
+    },
+    {
+      "cell_type": "markdown",
+      "metadata": {
+        "id": "jRcLU8qvzrvT"
+      },
+      "source": [
+        "---\n",
+        "<img src=\"https://gitlab.com/bivl2ab/academico/cursos-uis/ai/ai-uis-student/raw/master/imgs/bannerThanks.jpg\" alt=\"Drawing\" style=\"width:700px;\">\n"
+      ]
+    }
+  ],
+  "metadata": {
+    "colab": {
+      "collapsed_sections": [
+        "WKWsJZiazrul"
+      ],
+      "provenance": []
+    },
+    "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.8"
+    },
+    "toc": {
+      "toc_cell": false,
+      "toc_number_sections": true,
+      "toc_threshold": 6,
+      "toc_window_display": false
+    }
+  },
+  "nbformat": 4,
+  "nbformat_minor": 0
+}
\ No newline at end of file