diff --git a/lecture1/exercise_0_python.ipynb b/lecture1/exercise_0_python.ipynb
index ec543759c71a5679a1a7cd7864a5ca8d9a41622b..a453cea92a1b71ab2827f6196073935b275c5f45 100644
--- a/lecture1/exercise_0_python.ipynb
+++ b/lecture1/exercise_0_python.ipynb
@@ -135,18 +135,16 @@
    "metadata": {},
    "outputs": [
     {
-     "ename": "SyntaxError",
-     "evalue": "invalid syntax (998780084.py, line 3)",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;36m  Input \u001b[0;32mIn [6]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(\"The second element in a is:\", None,\"(should be 3)\")?\u001b[0m\n\u001b[0m                                                              ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The second element in e is: 15 (should be 3)\n"
      ]
     }
    ],
    "source": [
     "# You can use squared brackets to access elements in an array or tuple\n",
-    "# TODO: What's the second element in array e?\n",
-    "print(\"The second element in a is:\", None,\"(should be 3)\")?"
+    "print(\"The second element in e is:\", e[2],\"(should be 3)\")"
    ]
   },
   {
@@ -160,22 +158,20 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": 7,
    "id": "86b8e68c",
    "metadata": {},
    "outputs": [
     {
-     "ename": "SyntaxError",
-     "evalue": "invalid syntax (2320046825.py, line 2)",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;36m  Input \u001b[0;32mIn [12]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(\"13 x 14.5 =\", \"?\")?\u001b[0m\n\u001b[0m                             ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "13 x 14.5 = 188.5\n"
      ]
     }
    ],
    "source": [
-    "# TODO: Use the variables a and d defined above to calculate 13 x 14.5!\n",
-    "print(\"13 x 14.5 =\", \"?\")?"
+    "print(\"13 x 14.5 =\", a*d)"
    ]
   },
   {
@@ -188,7 +184,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 8,
    "id": "8c45add3",
    "metadata": {},
    "outputs": [
@@ -206,22 +202,21 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 9,
    "id": "29eac6ed",
    "metadata": {},
    "outputs": [
     {
-     "ename": "SyntaxError",
-     "evalue": "invalid syntax (2665876267.py, line 2)",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;36m  Input \u001b[0;32mIn [14]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(\"13 + True =\", \"?\")?\u001b[0m\n\u001b[0m                             ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "13 + True = 14\n"
      ]
     }
    ],
    "source": [
-    "# TODO: Booleans work as numbers as well. What happens if you add a and c?\n",
-    "print(\"13 + True =\", \"?\")?"
+    "# Booleans work as numbers as well. What happens if you add a and c?\n",
+    "print(\"13 + True =\", 13+True)"
    ]
   },
   {
@@ -235,22 +230,21 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 10,
    "id": "b0a7cbe1",
    "metadata": {},
    "outputs": [
     {
-     "ename": "SyntaxError",
-     "evalue": "invalid syntax (816995051.py, line 2)",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;36m  Input \u001b[0;32mIn [15]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print((a==14) and not (c<d))?\u001b[0m\n\u001b[0m                                ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "False\n"
      ]
     }
    ],
    "source": [
-    "# TODO: What's the output of (\"a bigger than d\" AND \"c is True\")?\n",
-    "print((a==14) and not (c<d))?"
+    "# The output of (\"a bigger than d\" AND \"c is True\")\n",
+    "print((a>=d) and (c))"
    ]
   },
   {
@@ -264,24 +258,24 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 16,
+   "execution_count": 11,
    "id": "5f42b63f",
    "metadata": {},
    "outputs": [
     {
      "ename": "IndentationError",
-     "evalue": "unexpected indent (3109148489.py, line 5)",
+     "evalue": "unexpected indent (989773714.py, line 5)",
      "output_type": "error",
      "traceback": [
-      "\u001b[0;36m  Input \u001b[0;32mIn [16]\u001b[0;36m\u001b[0m\n\u001b[0;31m    i = i + 1\u001b[0m\n\u001b[0m    ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m unexpected indent\n"
+      "\u001b[0;36m  Input \u001b[0;32mIn [11]\u001b[0;36m\u001b[0m\n\u001b[0;31m    i = i + 1\u001b[0m\n\u001b[0m    ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m unexpected indent\n"
      ]
     }
    ],
    "source": [
-    "# TODO: fix the while loop below:\n",
+    "# See, the while loop below is broken!\n",
     "i = 0\n",
     "while i<4:\n",
-    "  print(i)\n",
+    "  print(i)     # <-- The loop breaks here!\n",
     "    i = i + 1"
    ]
   },
@@ -295,25 +289,24 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
+   "execution_count": 14,
    "id": "7740d793",
    "metadata": {},
    "outputs": [
     {
-     "ename": "SyntaxError",
-     "evalue": "invalid syntax (756008327.py, line 5)",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;36m  Input \u001b[0;32mIn [17]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(sum)?\u001b[0m\n\u001b[0m              ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "10\n"
      ]
     }
    ],
    "source": [
-    "# TODO: Write a for loop adding up all the numbers from 0 to 100 and print the result.\n",
+    "# A loop adding up all the numbers from 0 to 100 and printing the result at the end:\n",
     "sum = 0\n",
     "for i in range(5):\n",
-    "    print(\"\")\n",
-    "print(sum)?"
+    "    sum = sum + i\n",
+    "print(sum)"
    ]
   },
   {
@@ -324,24 +317,32 @@
     "For **conditional branching**, the usual keywords ```if``` and ```else``` are defined. Loops can be stopped with ```break``` and skipped with ```continue```."
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "6a457a29",
+   "metadata": {},
+   "source": [
+    "### Task: <a class=\"tocSkip\"> \n",
+    "Write a small program checking whether i is an even or odd number for every integer i in [0, 10)."
+   ]
+  },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 15,
    "id": "0c47c5d6",
    "metadata": {},
    "outputs": [
     {
      "ename": "SyntaxError",
-     "evalue": "invalid syntax (2853117672.py, line 9)",
+     "evalue": "invalid syntax (1816773284.py, line 8)",
      "output_type": "error",
      "traceback": [
-      "\u001b[0;36m  Input \u001b[0;32mIn [18]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(\"else block\")?\u001b[0m\n\u001b[0m                       ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+      "\u001b[0;36m  Input \u001b[0;32mIn [15]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(\"else block\")?\u001b[0m\n\u001b[0m                       ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
      ]
     }
    ],
    "source": [
     "# TODO: With i%2, you can get the modulus of i divided by two.\n",
-    "# TODO: Write a small program checking whether i is an even or odd number for every i in [0, 10).\n",
     "# TODO: Use 'continue' to skip 0!\n",
     "n = 1\n",
     "for i in range(n):\n",
@@ -357,12 +358,12 @@
    "metadata": {},
    "source": [
     "## Functions\n",
-    "For repeating code, functions can be defined with the ```def``` keyword and their outputs can be returned using ```return```. These funtions can be also called recursively."
+    "For repeating code, functions can be defined with the ```def``` keyword and their outputs can be returned using ```return```."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 16,
    "id": "d5f33c84",
    "metadata": {},
    "outputs": [
@@ -384,27 +385,36 @@
     "print(get_greeting(\"Eric Idle\"))"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "6f42ae0f",
+   "metadata": {},
+   "source": [
+    "These functions can be also called recursively -- for this, we can take a look at the factorial function:"
+   ]
+  },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 17,
    "id": "04034c0e",
    "metadata": {},
    "outputs": [
     {
-     "ename": "SyntaxError",
-     "evalue": "invalid syntax (1882212969.py, line 5)",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[0;36m  Input \u001b[0;32mIn [20]\u001b[0;36m\u001b[0m\n\u001b[0;31m    factorial(10)?\u001b[0m\n\u001b[0m                 ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "720\n"
      ]
     }
    ],
    "source": [
-    "# TODO: Implement the factorial operation\n",
+    "# A basic implementation of the factorial operation:\n",
     "def factorial(n):\n",
-    "    print(n)\n",
-    "    return 0\n",
-    "factorial(10)?"
+    "    if n>1:\n",
+    "        return n*factorial(n-1)\n",
+    "    else:\n",
+    "        return 1\n",
+    "print(factorial(6))"
    ]
   },
   {
@@ -413,12 +423,14 @@
    "metadata": {},
    "source": [
     "## Classes\n",
-    "**Classes** are high-level objects for **storing and managing primitives**. They are initialized with ```class class_name:``` after which the constructor ```__init__(self, args)``` is automatically called. Data in classes are stored using the ```self``` keyword and are publicly accessible by default."
+    "**Classes** are high-level objects for **storing and managing primitives**. They are initialized with ```class class_name:``` after which the constructor ```__init__(self, args)``` is automatically called.\n",
+    "\n",
+    "**Data** in classes are stored using the ```self``` keyword and are **publicly accessible** by default."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 18,
    "id": "dd4ae61f",
    "metadata": {},
    "outputs": [
@@ -456,7 +468,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 19,
    "id": "caf893b1",
    "metadata": {},
    "outputs": [
@@ -490,7 +502,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 20,
    "id": "dfaeae8a",
    "metadata": {},
    "outputs": [],
@@ -509,7 +521,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 24,
+   "execution_count": 21,
    "id": "2aff9b94",
    "metadata": {},
    "outputs": [
@@ -545,7 +557,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 22,
    "id": "1141c56f",
    "metadata": {},
    "outputs": [
@@ -564,7 +576,7 @@
      "traceback": [
       "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
       "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
-      "Input \u001b[0;32mIn [25]\u001b[0m, in \u001b[0;36m<cell line: 5>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      3\u001b[0m array2 \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marray([\u001b[38;5;241m10\u001b[39m]\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m5\u001b[39m)               \u001b[38;5;66;03m# [10, 10, 10, 10, 10 ]\u001b[39;00m\n\u001b[1;32m      4\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mShape of array2\u001b[39m\u001b[38;5;124m\"\u001b[39m, array2\u001b[38;5;241m.\u001b[39mshape)  \u001b[38;5;66;03m# shape (5,)\u001b[39;00m\n\u001b[0;32m----> 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mnp_array1\u001b[49m\u001b[38;5;241m/\u001b[39mnp_array2)\n",
+      "Input \u001b[0;32mIn [22]\u001b[0m, in \u001b[0;36m<cell line: 5>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      3\u001b[0m array2 \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marray([\u001b[38;5;241m10\u001b[39m]\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m5\u001b[39m)               \u001b[38;5;66;03m# [10, 10, 10, 10, 10 ]\u001b[39;00m\n\u001b[1;32m      4\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mShape of array2\u001b[39m\u001b[38;5;124m\"\u001b[39m, array2\u001b[38;5;241m.\u001b[39mshape)  \u001b[38;5;66;03m# shape (5,)\u001b[39;00m\n\u001b[0;32m----> 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mnp_array1\u001b[49m\u001b[38;5;241m/\u001b[39mnp_array2)\n",
       "\u001b[0;31mNameError\u001b[0m: name 'np_array1' is not defined"
      ]
     }
@@ -586,98 +598,49 @@
     "Numpy supports the creation of n-dimensional arrays (arrays, matrices, tensors). Let's say you wish to generate 5 normally distributed samples of size 1000 with means 0, 10, 20, 30 and 40 and standard deviation 1. For this, you can first generate 5\\*1000 samples around 0, put them into a marix of shape (5, 1000) and shift each distribution to their respective means."
    ]
   },
-  {
-   "cell_type": "code",
-   "execution_count": 26,
-   "id": "47d6ecce",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Shape of the original dataset: (5000,)\n",
-      "Shape of the reshaped dataset: (5, 1000)\n"
-     ]
-    }
-   ],
-   "source": [
-    "ndists = 5\n",
-    "sample_size = 1000\n",
-    "dataset = np.random.normal(0, 1, ndists*sample_size)             # Dataset generation\n",
-    "print(\"Shape of the original dataset:\", dataset.shape)           # Printing the dataset shape\n",
-    "dataset_reshaped = dataset.reshape(ndists, sample_size)          # Reshaping it to (5, 1000)\n",
-    "print(\"Shape of the reshaped dataset:\", dataset_reshaped.shape)  # Printing the new shape"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "8bffbc39",
-   "metadata": {},
-   "source": [
-    "Now we can define our shift vector, extend it with a new \"dimension\" (called axis, i.e. bring it into the shape (5, 1)), such that all elements at the second index \"see\" a scalar."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 27,
-   "id": "f2ea360c",
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Shift vector shape: (5, 1)\n"
-     ]
-    }
-   ],
-   "source": [
-    "shift_vector = np.arange(5)*10                    # np.arange(n) creates an array of integers from 0 to n-1\n",
-    "shift_vector = shift_vector[:, np.newaxis]        # np.newaxis takes care of the new axis creation\n",
-    "print(\"Shift vector shape:\", shift_vector.shape)  # observe that reshape has not been called"
-   ]
-  },
   {
    "cell_type": "markdown",
-   "id": "64fdffa1",
+   "id": "274853db",
    "metadata": {},
    "source": [
-    "Now our gaussians can be shifted to their right places!"
+    "### Task: <a class=\"tocSkip\">\n",
+    "Implement the algirithm from above. Use ```array.reshape``` to reshape the dataset and create a vector of (5, 1) (eventually by using ```vector = vector[:, np.newaxis]```) which can be added to the dataset to perform the shift.\n",
+    "    \n",
+    "You can see the result of the expected distributions below."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": 23,
    "id": "f0177d95",
    "metadata": {
     "scrolled": true
    },
    "outputs": [
     {
-     "data": {
-      "image/png": "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\n",
-      "text/plain": [
-       "<Figure size 432x288 with 1 Axes>"
-      ]
-     },
-     "metadata": {
-      "needs_background": "light"
-     },
-     "output_type": "display_data"
+     "ename": "SyntaxError",
+     "evalue": "invalid syntax (3929959572.py, line 9)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Input \u001b[0;32mIn [23]\u001b[0;36m\u001b[0m\n\u001b[0;31m    plt.hist(hist)?\u001b[0m\n\u001b[0m                  ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     ]
     }
    ],
    "source": [
+    "# TODO: Create the dataset of shape (5*1000) and reshape it to (5, 1000).\n",
+    "# TODO: Create the shift vector and reshape it to (5, 1)\n",
+    "# TODO: Perform the shift and plot the result using the code below.\n",
+    "\n",
     "dataset_shifted = shift_vector + dataset_reshaped  # shape (5, 1) + shape (5, 1000) = shape (5, 1000)\n",
     "\n",
     "import matplotlib.pyplot as plt                    # import the plotting library to showcase the results\n",
     "for hist in dataset_shifted:                       # Iterate over every distribution\n",
-    "    plt.hist(hist)"
+    "    plt.hist(hist)?"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
+   "execution_count": 24,
    "id": "439f4bf4",
    "metadata": {
     "scrolled": true
@@ -685,7 +648,7 @@
    "outputs": [
     {
      "data": {
-      "image/png": "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\n",
+      "image/png": "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\n",
       "text/plain": [
        "<Figure size 432x288 with 1 Axes>"
       ]
@@ -697,12 +660,12 @@
     }
    ],
    "source": [
-    "# ... or you check the documentation and solve the problem directly by invoking:\n",
+    "# You can also check the documentation and solve the problem directly by invoking:\n",
     "dataset_shifted = np.random.normal(loc=np.arange(5)*10, scale=np.ones(5), size=(1000, 5)).T\n",
     "for hist in dataset_shifted:\n",
     "    plt.hist(hist)\n",
     "\n",
-    "# Always check the docs before inventing something \"new\"!"
+    "# By the way, always check the docs before inventing something \"new\"!"
    ]
   },
   {
@@ -716,7 +679,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 43,
+   "execution_count": 25,
    "id": "25b44ae6",
    "metadata": {},
    "outputs": [
@@ -756,7 +719,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 30,
+   "execution_count": 26,
    "id": "973bd72b",
    "metadata": {},
    "outputs": [
@@ -766,10 +729,11 @@
      "text": [
       "Basic array operations:\n",
       "Sum 5050\n",
-      "Mean [ 0.08110435  9.98545632 20.02933072 30.02389687 39.97474169]\n",
-      "Std [0.99851965 0.97608616 1.0021044  0.98741231 1.00744611]\n",
-      "Flattened array: [-0.44605952 -0.22217352 -0.25286257 ... 41.29848664 39.92391046\n",
-      " 39.72392673]\n"
+      "Mean [1.97919603e-02 1.00397004e+01 1.99855204e+01 3.00120483e+01\n",
+      " 3.99834654e+01]\n",
+      "Std [0.98188162 0.95965408 0.98533375 1.00486344 1.0097886 ]\n",
+      "Flattened array: [-0.8827242   1.5587154  -0.83441126 ... 42.48566035 41.09123383\n",
+      " 38.89384582]\n"
      ]
     }
    ],
@@ -788,12 +752,12 @@
    "metadata": {},
    "source": [
     "### Array Indexing\n",
-    "Numpy support a powerful way of accessing entries of an array. For this purpose, ranges using ```:```, numpy arrays of integers and numpy arrays of booleans can be used:"
+    "Numpy supports a powerful way of accessing entries of an array. For this purpose, ranges using ```:```, numpy arrays of integers and numpy arrays of booleans can be used:"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 50,
+   "execution_count": 27,
    "id": "e15a8939",
    "metadata": {},
    "outputs": [
@@ -826,42 +790,42 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 52,
-   "id": "184db0da",
+   "execution_count": 28,
+   "id": "739732e5",
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[54 49 48 17]\n",
-      "[17  1 12 22 14 29  3  9 13 21 23  8 20  6 16  2 10 11  4 19 30 18 28 15\n",
-      "  0 24  5  7 25 26 27]\n",
-      "[[False False False  True]\n",
-      " [ True  True False False]\n",
+      "[65 39 62 57]\n",
+      "[23  8 20 14 16 26  6 17  9 22  1  5 10  7 24  0 18  4  2 11 25 15 29 13\n",
+      " 21  3 27 30 28 12 19]\n",
+      "[[False False False False]\n",
       " [ True False False False]\n",
       " [False False False False]\n",
-      " [False  True  True  True]\n",
-      " [ True False False  True]\n",
-      " [False False False  True]\n",
-      " [ True False False False]\n",
+      " [ True False  True False]\n",
       " [False False False False]\n",
+      " [False False False  True]\n",
+      " [False False  True False]\n",
       " [False  True False False]\n",
-      " [False  True False  True]\n",
-      " [ True False False False]\n",
-      " [ True False False False]\n",
-      " [False  True  True False]\n",
-      " [ True False  True False]\n",
+      " [ True False  True  True]\n",
+      " [ True  True False False]\n",
       " [False False False False]\n",
       " [False False  True False]\n",
-      " [False False False  True]\n",
       " [False False False False]\n",
-      " [False False False  True]\n",
-      " [ True False  True False]\n",
+      " [False  True  True  True]\n",
       " [False  True False  True]\n",
-      " [False False False  True]\n",
+      " [ True  True False False]\n",
       " [False  True  True False]\n",
-      " [False False  True False]]\n"
+      " [False False  True False]\n",
+      " [False  True  True  True]\n",
+      " [False  True False False]\n",
+      " [False False  True False]\n",
+      " [ True False False False]\n",
+      " [False False False False]\n",
+      " [False  True  True  True]\n",
+      " [False False False False]]\n"
      ]
     }
    ],
diff --git a/lecture1/exercise_0_python_vispa.ipynb b/lecture1/exercise_0_python_vispa.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..ec543759c71a5679a1a7cd7864a5ca8d9a41622b
--- /dev/null
+++ b/lecture1/exercise_0_python_vispa.ipynb
@@ -0,0 +1,918 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "897fcfcd",
+   "metadata": {},
+   "source": [
+    "# Python Tutorial\n",
+    "-----------------------\n",
+    "\n",
+    "Welcome to this warm-up tutorial! Let's take a look at some highlights of Python!\n",
+    "\n",
+    "Please execute the whole notebook now by clicking on Cell->Execute All in the menubar. In the following, cells starting with TODOs and ending with a ```?``` are tasks to be solved individually.\n",
+    "\n",
+    "Let's start with the usual **hello world** program:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "c8562e26",
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Hello World!\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"Hello World!\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "48a13786",
+   "metadata": {},
+   "source": [
+    "You can print multiple items in a row:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "bea4da9f",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1 + 12 = 13\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"1 + 12 =\", 13)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5a70d15c",
+   "metadata": {},
+   "source": [
+    "## Comments\n",
+    "You can also comment your code with ```#``` for a **single line** or with ```\"\"\"comment\"\"\"``` for **multiple lines**:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "6b5d414b",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# This is a comment and will be ignored upon execution"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "d69d90e9",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "What's that thing that spells the same backwards as forwards?\n",
+      "A palindrome...?\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"What's that thing that spells the same backwards as forwards?\")\n",
+    "\"\"\"\n",
+    "I am a comment too!\n",
+    "See, this line is ignored as well!\n",
+    "\"\"\"\n",
+    "print(\"A palindrome...?\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "c4c8535a",
+   "metadata": {},
+   "source": [
+    "## Variables and Data-Types\n",
+    "Python is a **dynamically-typed** language, i.e. you don't have to define your variable types in advance:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "f7179786",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "a = 13  # This is an integer\n",
+    "b = \"This is a string\"  # This is a string\n",
+    "c = True   # A boolean \n",
+    "d = 14.5  # This is a double-precision floating-point variable (called a 'double' in C-speak)\n",
+    "e = [1, 3, 15, 34]  # This is a list, an array of objects\n",
+    "f = (\"Emmental\", \"Brie\", \"Gouda\", \"Danish Blue\")  # This is a tuple, an immutable array"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "d0586d1b",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "SyntaxError",
+     "evalue": "invalid syntax (998780084.py, line 3)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Input \u001b[0;32mIn [6]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(\"The second element in a is:\", None,\"(should be 3)\")?\u001b[0m\n\u001b[0m                                                              ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     ]
+    }
+   ],
+   "source": [
+    "# You can use squared brackets to access elements in an array or tuple\n",
+    "# TODO: What's the second element in array e?\n",
+    "print(\"The second element in a is:\", None,\"(should be 3)\")?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0019db03",
+   "metadata": {},
+   "source": [
+    "## Elementary Arithmetics\n",
+    "You can use the usual **operators** ```+```, ```-```, ```*```, ```/``` for elementary arithmetics:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "86b8e68c",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "SyntaxError",
+     "evalue": "invalid syntax (2320046825.py, line 2)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Input \u001b[0;32mIn [12]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(\"13 x 14.5 =\", \"?\")?\u001b[0m\n\u001b[0m                             ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     ]
+    }
+   ],
+   "source": [
+    "# TODO: Use the variables a and d defined above to calculate 13 x 14.5!\n",
+    "print(\"13 x 14.5 =\", \"?\")?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "32b1985e",
+   "metadata": {},
+   "source": [
+    "You can use the **double star** ```**```-operator to raise number to the **n-th power**:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "8c45add3",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1 4 9 16 1024\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(1**2, 2**2, 3**2, 4**2, 32**2)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "29eac6ed",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "SyntaxError",
+     "evalue": "invalid syntax (2665876267.py, line 2)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Input \u001b[0;32mIn [14]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(\"13 + True =\", \"?\")?\u001b[0m\n\u001b[0m                             ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     ]
+    }
+   ],
+   "source": [
+    "# TODO: Booleans work as numbers as well. What happens if you add a and c?\n",
+    "print(\"13 + True =\", \"?\")?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f6d98d65",
+   "metadata": {},
+   "source": [
+    "## Comparison Opeartors\n",
+    "You can use ```<```, ```>```, ```==```, ```<=```, ```>=``` to **compare numbers** (**and objects**), the **keywords** ```and```, ```or``` to compare statements (booleans) and the keyword ```not``` to negate them.\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "id": "b0a7cbe1",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "SyntaxError",
+     "evalue": "invalid syntax (816995051.py, line 2)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Input \u001b[0;32mIn [15]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print((a==14) and not (c<d))?\u001b[0m\n\u001b[0m                                ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     ]
+    }
+   ],
+   "source": [
+    "# TODO: What's the output of (\"a bigger than d\" AND \"c is True\")?\n",
+    "print((a==14) and not (c<d))?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cbba9080",
+   "metadata": {},
+   "source": [
+    "## Control Flow Tools\n",
+    "For pre-test loops you can use ```while```. Beware that in Python indented blocks of code belong to the same parent line (similarly to ```{...}``` in C); mixing indentations raises an ```IndentationError```."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "id": "5f42b63f",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "IndentationError",
+     "evalue": "unexpected indent (3109148489.py, line 5)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Input \u001b[0;32mIn [16]\u001b[0;36m\u001b[0m\n\u001b[0;31m    i = i + 1\u001b[0m\n\u001b[0m    ^\u001b[0m\n\u001b[0;31mIndentationError\u001b[0m\u001b[0;31m:\u001b[0m unexpected indent\n"
+     ]
+    }
+   ],
+   "source": [
+    "# TODO: fix the while loop below:\n",
+    "i = 0\n",
+    "while i<4:\n",
+    "  print(i)\n",
+    "    i = i + 1"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "118d8935",
+   "metadata": {},
+   "source": [
+    "Using ```for``` and the iterable ```range(n)``` a for-like loop can be created:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "id": "7740d793",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "SyntaxError",
+     "evalue": "invalid syntax (756008327.py, line 5)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Input \u001b[0;32mIn [17]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(sum)?\u001b[0m\n\u001b[0m              ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     ]
+    }
+   ],
+   "source": [
+    "# TODO: Write a for loop adding up all the numbers from 0 to 100 and print the result.\n",
+    "sum = 0\n",
+    "for i in range(5):\n",
+    "    print(\"\")\n",
+    "print(sum)?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "fd2059e5",
+   "metadata": {},
+   "source": [
+    "For **conditional branching**, the usual keywords ```if``` and ```else``` are defined. Loops can be stopped with ```break``` and skipped with ```continue```."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "id": "0c47c5d6",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "SyntaxError",
+     "evalue": "invalid syntax (2853117672.py, line 9)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Input \u001b[0;32mIn [18]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(\"else block\")?\u001b[0m\n\u001b[0m                       ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     ]
+    }
+   ],
+   "source": [
+    "# TODO: With i%2, you can get the modulus of i divided by two.\n",
+    "# TODO: Write a small program checking whether i is an even or odd number for every i in [0, 10).\n",
+    "# TODO: Use 'continue' to skip 0!\n",
+    "n = 1\n",
+    "for i in range(n):\n",
+    "    if True:\n",
+    "        print(i, \"is an odd/even number\")\n",
+    "    else:\n",
+    "        print(\"else block\")?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f51fc582",
+   "metadata": {},
+   "source": [
+    "## Functions\n",
+    "For repeating code, functions can be defined with the ```def``` keyword and their outputs can be returned using ```return```. These funtions can be also called recursively."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "id": "d5f33c84",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Hello John Cleese!\n",
+      "Hello Graham Chapman!\n",
+      "Hello Eric Idle!\n"
+     ]
+    }
+   ],
+   "source": [
+    "def get_greeting(name):\n",
+    "    return \"Hello \" + name +\"!\"\n",
+    "print(get_greeting(\"John Cleese\"))\n",
+    "print(get_greeting(\"Graham Chapman\"))\n",
+    "print(get_greeting(\"Eric Idle\"))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "id": "04034c0e",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "SyntaxError",
+     "evalue": "invalid syntax (1882212969.py, line 5)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Input \u001b[0;32mIn [20]\u001b[0;36m\u001b[0m\n\u001b[0;31m    factorial(10)?\u001b[0m\n\u001b[0m                 ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     ]
+    }
+   ],
+   "source": [
+    "# TODO: Implement the factorial operation\n",
+    "def factorial(n):\n",
+    "    print(n)\n",
+    "    return 0\n",
+    "factorial(10)?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "49898002",
+   "metadata": {},
+   "source": [
+    "## Classes\n",
+    "**Classes** are high-level objects for **storing and managing primitives**. They are initialized with ```class class_name:``` after which the constructor ```__init__(self, args)``` is automatically called. Data in classes are stored using the ```self``` keyword and are publicly accessible by default."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "id": "dd4ae61f",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "name: Alice ; age: 34\n",
+      "name: Alice ; age: 18\n"
+     ]
+    }
+   ],
+   "source": [
+    "class Person:\n",
+    "    def __init__(self, name, age):\n",
+    "        self.name = name\n",
+    "        self.age = age\n",
+    "        \n",
+    "    def print_info(self):\n",
+    "        print(\"name:\", self.name, \";\", \"age:\", self.age)\n",
+    "alice = Person(\"Alice\", 34)\n",
+    "alice.print_info()\n",
+    "alice.age = 18\n",
+    "alice.print_info()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0d914e99",
+   "metadata": {},
+   "source": [
+    "## Class Inheritance\n",
+    "A class can **inherit** the **properties of its parent** class. These properties can be freely overriden:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "id": "caf893b1",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Bob is a student!\n"
+     ]
+    }
+   ],
+   "source": [
+    "class Student(Person):\n",
+    "    def print_info(self):\n",
+    "        \"\"\"\n",
+    "        Beware that the attribute name has been inherited from 'Person'\n",
+    "        \"\"\"\n",
+    "        print(self.name, \"is a student!\")\n",
+    "bob = Student(\"Bob\", 20)\n",
+    "bob.print_info()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "39f231b0",
+   "metadata": {},
+   "source": [
+    "## Numpy Basics\n",
+    "Numpy is an performant, easy-to-use scientific library for numeric calculations. You will often encouter cases where numpy can perform calculations several orders of magnitudes faster due its C-backend and ability to process data in a vectorized (parallelized) form."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "id": "dfaeae8a",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np  # numpy is usually imported this way"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "935518b0",
+   "metadata": {},
+   "source": [
+    "### Numpy One Dimensional Array Operations\n",
+    "```numpy``` **operates** on arrays **element-wise** thus elementary operations are performed in an intuitive way."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "id": "2aff9b94",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[3. 3. 3. 3. 3. 3. 3. 3. 3. 3.]\n",
+      "[11 22 33 44 55 66 77] <class 'numpy.ndarray'>\n"
+     ]
+    }
+   ],
+   "source": [
+    "zero_array = np.zeros(10)   # creates an an array of 10 zeros\n",
+    "one_array  = np.ones(10)    # creates an array of... guess what!\n",
+    "two_array  = np.ones(10)*2  # this one is a bit more tricky\n",
+    "\n",
+    "three_array = one_array + two_array    # arrays are added element-wise\n",
+    "print(three_array)\n",
+    "\n",
+    "# You can also create numpy arrays from python lists:\n",
+    "np_array_from_python_list = np.array([11, 22, 33, 44, 55, 66, 77])\n",
+    "print(np_array_from_python_list, type(np_array_from_python_list))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e6057042",
+   "metadata": {},
+   "source": [
+    "For this to work however the arrays must be of the **same shape**, otherwise a ```ValueError``` will be raised. In order to avoid this error, you can always access the shape of an array using the ```array.shape``` syntax:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "id": "1141c56f",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Shape of array1 (10,)\n",
+      "Shape of array2 (5,)\n"
+     ]
+    },
+    {
+     "ename": "NameError",
+     "evalue": "name 'np_array1' is not defined",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
+      "Input \u001b[0;32mIn [25]\u001b[0m, in \u001b[0;36m<cell line: 5>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      3\u001b[0m array2 \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39marray([\u001b[38;5;241m10\u001b[39m]\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m5\u001b[39m)               \u001b[38;5;66;03m# [10, 10, 10, 10, 10 ]\u001b[39;00m\n\u001b[1;32m      4\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mShape of array2\u001b[39m\u001b[38;5;124m\"\u001b[39m, array2\u001b[38;5;241m.\u001b[39mshape)  \u001b[38;5;66;03m# shape (5,)\u001b[39;00m\n\u001b[0;32m----> 5\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[43mnp_array1\u001b[49m\u001b[38;5;241m/\u001b[39mnp_array2)\n",
+      "\u001b[0;31mNameError\u001b[0m: name 'np_array1' is not defined"
+     ]
+    }
+   ],
+   "source": [
+    "array1 = np.arange(10)                  # [0, 1, 2, ..., 9]\n",
+    "print(\"Shape of array1\", array1.shape)  # shape: (10,)\n",
+    "array2 = np.array([10]*5)               # [10, 10, 10, 10, 10 ]\n",
+    "print(\"Shape of array2\", array2.shape)  # shape (5,)\n",
+    "print(np_array1/np_array2)              # Voilà ValueError due to conflicting shapes"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d236a438",
+   "metadata": {},
+   "source": [
+    "### Numpy Arrays of Multiple Dimensions\n",
+    "Numpy supports the creation of n-dimensional arrays (arrays, matrices, tensors). Let's say you wish to generate 5 normally distributed samples of size 1000 with means 0, 10, 20, 30 and 40 and standard deviation 1. For this, you can first generate 5\\*1000 samples around 0, put them into a marix of shape (5, 1000) and shift each distribution to their respective means."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "id": "47d6ecce",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Shape of the original dataset: (5000,)\n",
+      "Shape of the reshaped dataset: (5, 1000)\n"
+     ]
+    }
+   ],
+   "source": [
+    "ndists = 5\n",
+    "sample_size = 1000\n",
+    "dataset = np.random.normal(0, 1, ndists*sample_size)             # Dataset generation\n",
+    "print(\"Shape of the original dataset:\", dataset.shape)           # Printing the dataset shape\n",
+    "dataset_reshaped = dataset.reshape(ndists, sample_size)          # Reshaping it to (5, 1000)\n",
+    "print(\"Shape of the reshaped dataset:\", dataset_reshaped.shape)  # Printing the new shape"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8bffbc39",
+   "metadata": {},
+   "source": [
+    "Now we can define our shift vector, extend it with a new \"dimension\" (called axis, i.e. bring it into the shape (5, 1)), such that all elements at the second index \"see\" a scalar."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "id": "f2ea360c",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Shift vector shape: (5, 1)\n"
+     ]
+    }
+   ],
+   "source": [
+    "shift_vector = np.arange(5)*10                    # np.arange(n) creates an array of integers from 0 to n-1\n",
+    "shift_vector = shift_vector[:, np.newaxis]        # np.newaxis takes care of the new axis creation\n",
+    "print(\"Shift vector shape:\", shift_vector.shape)  # observe that reshape has not been called"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "64fdffa1",
+   "metadata": {},
+   "source": [
+    "Now our gaussians can be shifted to their right places!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "id": "f0177d95",
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "dataset_shifted = shift_vector + dataset_reshaped  # shape (5, 1) + shape (5, 1000) = shape (5, 1000)\n",
+    "\n",
+    "import matplotlib.pyplot as plt                    # import the plotting library to showcase the results\n",
+    "for hist in dataset_shifted:                       # Iterate over every distribution\n",
+    "    plt.hist(hist)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "id": "439f4bf4",
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# ... or you check the documentation and solve the problem directly by invoking:\n",
+    "dataset_shifted = np.random.normal(loc=np.arange(5)*10, scale=np.ones(5), size=(1000, 5)).T\n",
+    "for hist in dataset_shifted:\n",
+    "    plt.hist(hist)\n",
+    "\n",
+    "# Always check the docs before inventing something \"new\"!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "43f66264",
+   "metadata": {},
+   "source": [
+    "### Numpy Matrix Operations\n",
+    "By default, numpy performs element-wise multiplication using the star-operator ```*```. For matrix-matrix, matrix-vector multiplications the ```@``` can be used:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "id": "25b44ae6",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Manual operation M*v:    [-1. -3.]\n",
+      "Matrix multiplication @: [-1. -3.]\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Define a matrix manually:\n",
+    "matrix = np.array([[1., 1.], \n",
+    "                   [0., 3.]])\n",
+    "\n",
+    "# Define a vector manually:\n",
+    "vector = np.array([0., -1.])\n",
+    "\n",
+    "# The dirty and manual way would be:\n",
+    "print(\"Manual operation M*v:   \", (matrix*vector[np.newaxis,:]).sum(axis=1))\n",
+    "\n",
+    "# Fortunately, the @-operator exists!\n",
+    "print(\"Matrix multiplication @:\", matrix@vector)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7a826bff",
+   "metadata": {},
+   "source": [
+    "## Numpy Miscellaneous:\n",
+    "### Functions\n",
+    "Below you can find a non-exhaustive list of built-in numpy functions for quick data analysis:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "id": "973bd72b",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Basic array operations:\n",
+      "Sum 5050\n",
+      "Mean [ 0.08110435  9.98545632 20.02933072 30.02389687 39.97474169]\n",
+      "Std [0.99851965 0.97608616 1.0021044  0.98741231 1.00744611]\n",
+      "Flattened array: [-0.44605952 -0.22217352 -0.25286257 ... 41.29848664 39.92391046\n",
+      " 39.72392673]\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"Basic array operations:\")\n",
+    "print(\"Sum\", np.sum(np.arange(101)))             # Sum of all numbers from 0 to 100\n",
+    "print(\"Mean\", np.mean(dataset_shifted, axis=1))  # Mean of the generated gaussians from above...\n",
+    "print(\"Std\", dataset_shifted.std(axis=1))        # ...and their respective standard deviations with a different syntax\n",
+    "\n",
+    "print(\"Flattened array:\", dataset_shifted.flatten())       # .flatten() makes an array 1D"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "fdacbe66",
+   "metadata": {},
+   "source": [
+    "### Array Indexing\n",
+    "Numpy support a powerful way of accessing entries of an array. For this purpose, ranges using ```:```, numpy arrays of integers and numpy arrays of booleans can be used:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "id": "e15a8939",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[20 21 22 23 24 25 26 27 28 29]\n",
+      "[0 1 2 3 4 5 6 7 8 9]\n",
+      "[95 96 97 98 99]\n",
+      "[10 13 21]\n"
+     ]
+    }
+   ],
+   "source": [
+    "array_to_be_masked = np.arange(100)\n",
+    "\n",
+    "# Let's select the entries between index 20 and 30:\n",
+    "print(array_to_be_masked[20:30])\n",
+    "\n",
+    "# First 10 entries:\n",
+    "print(array_to_be_masked[:10])\n",
+    "\n",
+    "# Print the last 5 elements:\n",
+    "print(array_to_be_masked[-5:])\n",
+    "\n",
+    "# Print the 10th, 13th and 21st elements:\n",
+    "print(array_to_be_masked[np.array([10, 13, 21])])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "id": "184db0da",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[54 49 48 17]\n",
+      "[17  1 12 22 14 29  3  9 13 21 23  8 20  6 16  2 10 11  4 19 30 18 28 15\n",
+      "  0 24  5  7 25 26 27]\n",
+      "[[False False False  True]\n",
+      " [ True  True False False]\n",
+      " [ True False False False]\n",
+      " [False False False False]\n",
+      " [False  True  True  True]\n",
+      " [ True False False  True]\n",
+      " [False False False  True]\n",
+      " [ True False False False]\n",
+      " [False False False False]\n",
+      " [False  True False False]\n",
+      " [False  True False  True]\n",
+      " [ True False False False]\n",
+      " [ True False False False]\n",
+      " [False  True  True False]\n",
+      " [ True False  True False]\n",
+      " [False False False False]\n",
+      " [False False  True False]\n",
+      " [False False False  True]\n",
+      " [False False False False]\n",
+      " [False False False  True]\n",
+      " [ True False  True False]\n",
+      " [False  True False  True]\n",
+      " [False False False  True]\n",
+      " [False  True  True False]\n",
+      " [False False  True False]]\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Let's shuffle the elements and reshape the array to make things more complicated!\n",
+    "np.random.shuffle(array_to_be_masked)\n",
+    "array_to_be_masked = array_to_be_masked.reshape((25, -1))  # \"-1\" means \"do whatever needed to get the right shape\"\n",
+    "\n",
+    "# Select the first entries in each row (slicing)\n",
+    "print(array_to_be_masked[0, :])\n",
+    "\n",
+    "# Select all entries <=30 in the flattened array:\n",
+    "print(array_to_be_masked[(array_to_be_masked<=30)])\n",
+    "\n",
+    "# Print the mask:\n",
+    "print((array_to_be_masked<=30))"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "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.9.12"
+  },
+  "toc": {
+   "base_numbering": 1,
+   "nav_menu": {},
+   "number_sections": true,
+   "sideBar": true,
+   "skip_h1_title": true,
+   "title_cell": "Table of Contents",
+   "title_sidebar": "Contents",
+   "toc_cell": false,
+   "toc_position": {},
+   "toc_section_display": true,
+   "toc_window_display": false
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/lecture1/exercise_0_pytorch.ipynb b/lecture1/exercise_0_pytorch.ipynb
index efa48e2b136c9a11bb7f5c534dbf9292e418977c..6e53369f2b1120184d7f56ce0bf53c48f00a91ef 100644
--- a/lecture1/exercise_0_pytorch.ipynb
+++ b/lecture1/exercise_0_pytorch.ipynb
@@ -14,7 +14,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 97,
+   "execution_count": 1,
    "id": "e812c4c3",
    "metadata": {},
    "outputs": [],
@@ -28,12 +28,12 @@
    "metadata": {},
    "source": [
     "## Tensors\n",
-    "Even if name ```pytorch``` is not as telling as ```tensorflow```, ```pytorch``` supports the creation of tensors too:"
+    "Even if the name ```pytorch``` is not as telling as ```tensorflow```, ```pytorch``` supports the creation of tensors too:"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 98,
+   "execution_count": 2,
    "id": "da356762",
    "metadata": {},
    "outputs": [
@@ -60,7 +60,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 99,
+   "execution_count": 3,
    "id": "0e83bc87",
    "metadata": {},
    "outputs": [
@@ -86,7 +86,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 100,
+   "execution_count": 4,
    "id": "2d6a9052",
    "metadata": {},
    "outputs": [
@@ -94,27 +94,27 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Input tensor xᵢ:       tensor([  1.,   5.,   9.,  15., -24., -13.], requires_grad=True)\n",
-      "Gradients of Σᵢ xᵢ²:   tensor([  2.,  10.,  18.,  30., -48., -26.])\n"
+      "Input tensor x_i:       tensor([  1.,   5.,   9.,  15., -24., -13.], requires_grad=True)\n",
+      "Gradients of Σ_i x²_i:   tensor([  2.,  10.,  18.,  30., -48., -26.])\n"
      ]
     }
    ],
    "source": [
     "# Create a tensor with gradients and print it:\n",
     "tensor_grad = torch.tensor([1., 5., 9., 15., -24., -13.], requires_grad=True)\n",
-    "print(\"Input tensor xᵢ:      \", tensor_grad)\n",
+    "print(\"Input tensor x_i:      \", tensor_grad)\n",
     "\n",
     "# Perform an operation on the tensor itself and sum the output making it a 1D function:\n",
-    "output = (tensor_grad ** 2).sum()   # This defines y = Σᵢ xᵢ² for every xᵢ\n",
+    "output = (tensor_grad ** 2).sum()   # This defines y = Σ_i x²_i for every x_i\n",
     "# Evaluating the gradients:\n",
     "output.backward()\n",
     "# ...and printing 'em:\n",
-    "print(\"Gradients of Σᵢ xᵢ²:  \", tensor_grad.grad)"
+    "print(\"Gradients of Σ_i x²_i:  \", tensor_grad.grad)"
    ]
   },
   {
    "cell_type": "markdown",
-   "id": "546969ea",
+   "id": "42d65b3f",
    "metadata": {},
    "source": [
     "**Conversion** from and to ```numpy``` is also supported in an intuitive way:"
@@ -122,8 +122,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 101,
-   "id": "b15a0f08",
+   "execution_count": 5,
+   "id": "4ff55ee1",
    "metadata": {},
    "outputs": [
     {
@@ -156,8 +156,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 102,
-   "id": "b164940f",
+   "execution_count": 6,
+   "id": "b41c3f17",
    "metadata": {},
    "outputs": [
     {
@@ -169,11 +169,11 @@
       "\n",
       "Normal Sample Properties:\n",
       "   Shape: torch.Size([1, 10000])\n",
-      "   Mean:  tensor(1.0189)\n",
-      "   Std:   tensor(0.4937)\n",
+      "   Mean:  tensor(0.9942)\n",
+      "   Std:   tensor(0.5033)\n",
       "\n",
       "The first row of the normal samples:\n",
-      "tensor([1.1931, 0.7112, 1.0409,  ..., 1.2609, 0.1830, 1.6109])\n"
+      "tensor([0.6045, 0.4586, 0.8431,  ..., 1.5992, 0.4570, 1.2081])\n"
      ]
     }
    ],
@@ -198,7 +198,7 @@
   },
   {
    "cell_type": "markdown",
-   "id": "2046ab07",
+   "id": "c7392c21",
    "metadata": {},
    "source": [
     " A key **difference in syntax** however is that ```pytorch``` knows the ```axis``` keyword as ```dim```:"
@@ -206,8 +206,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 103,
-   "id": "4d244cd6",
+   "execution_count": 7,
+   "id": "ae7c557f",
    "metadata": {},
    "outputs": [
     {
@@ -217,8 +217,8 @@
       "\n",
       "Uniform Sample Properties:\n",
       "   Shape: torch.Size([3, 100000])\n",
-      "   Mean:  tensor([0.4991, 0.5005, 0.4996])\n",
-      "   Std:   tensor([0.2888, 0.2885, 0.2884])\n"
+      "   Mean:  tensor([0.5000, 0.4996, 0.5005])\n",
+      "   Std:   tensor([0.2893, 0.2885, 0.2884])\n"
      ]
     }
    ],
@@ -230,6 +230,44 @@
     "print(\"   Mean: \", uniform.mean(dim=1))  # Equals 1/2 ≈ 0.5, the mean of a uniform distribution between [0, 1)\n",
     "print(\"   Std:  \", uniform.std(dim=1))   # Equals 1/12**0.5 ≈ 0.2887, the std of a uniform distribution of width 1"
    ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cd7f9110",
+   "metadata": {},
+   "source": [
+    "### Task <a class=\"tocSkip\">\n",
+    "Implement the mean-square difference function in pytorch:\n",
+    "    $$ L(x, y) = \\sum_i \\frac{(x_i-y_i)^2}{N}$$"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "8e87425d",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "SyntaxError",
+     "evalue": "invalid syntax (3637020795.py, line 10)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Input \u001b[0;32mIn [8]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(loss(x,y))?\u001b[0m\n\u001b[0m                    ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     ]
+    }
+   ],
+   "source": [
+    "def loss(x, y):\n",
+    "    # TODO: replace the return term\n",
+    "    return 0.\n",
+    "\n",
+    "# Use these values of x and y to get the variation using L for a uniformly distributed dataset in [0, 1)\n",
+    "x = torch.rand([1000000])\n",
+    "y = torch.ones([1000000]) * 0.5\n",
+    "\n",
+    "# Result should be around 0.083333\n",
+    "print(loss(x,y))?"
+   ]
   }
  ],
  "metadata": {
diff --git a/lecture1/exercise_0_tensorflow.ipynb b/lecture1/exercise_0_tensorflow.ipynb
index 55cc5fb465940ed8ae04f35cda45d6feff1715a5..33db1a3e7410fd1cc710a6ca3448a0cf993f1560 100644
--- a/lecture1/exercise_0_tensorflow.ipynb
+++ b/lecture1/exercise_0_tensorflow.ipynb
@@ -15,7 +15,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 29,
+   "execution_count": 1,
    "id": "fb7e3964",
    "metadata": {},
    "outputs": [],
@@ -36,7 +36,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 30,
+   "execution_count": 2,
    "id": "e776d989",
    "metadata": {},
    "outputs": [
@@ -50,11 +50,21 @@
       " [1. 1.]\n",
       " [1. 1.]], shape=(3, 2), dtype=float32)\n",
       "tf.random_uniform([1, 3]) = tf.Tensor(\n",
-      "[[0.9811375  0.9579929  0.44337857]\n",
-      " [0.4048884  0.99830174 0.6368449 ]], shape=(2, 3), dtype=float32)\n",
+      "[[0.6397505  0.4475379  0.7460896 ]\n",
+      " [0.40134668 0.6757213  0.14884555]], shape=(2, 3), dtype=float32)\n",
       "tf.linspace(1.0, 7.0, 4) = tf.Tensor([1. 3. 5. 7.], shape=(4,), dtype=float64)\n",
       "tf.convert_to_tensor( np.linspace(1, 7, 4) ) = tf.Tensor([1. 3. 5. 7.], shape=(4,), dtype=float64)\n"
      ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "2022-08-02 16:29:05.625051: I tensorflow/compiler/jit/xla_cpu_device.cc:41] Not creating XLA devices, tf_xla_enable_xla_devices not set\n",
+      "2022-08-02 16:29:05.626364: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  SSE4.1 SSE4.2 AVX\n",
+      "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
+      "2022-08-02 16:29:05.629373: I tensorflow/core/common_runtime/process_util.cc:146] Creating new thread pool with default inter op setting: 2. Tune using inter_op_parallelism_threads for best performance.\n"
+     ]
     }
    ],
    "source": [
@@ -82,7 +92,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 31,
+   "execution_count": 3,
    "id": "0b576f35",
    "metadata": {},
    "outputs": [
@@ -90,8 +100,8 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "[[0.9811375  0.9579929  0.44337857]\n",
-      " [0.4048884  0.99830174 0.6368449 ]]\n",
+      "[[0.6397505  0.4475379  0.7460896 ]\n",
+      " [0.40134668 0.6757213  0.14884555]]\n",
       "<class 'numpy.ndarray'>\n"
      ]
     }
@@ -112,7 +122,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": 4,
    "id": "a70aa763",
    "metadata": {},
    "outputs": [
@@ -151,7 +161,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 33,
+   "execution_count": 5,
    "id": "367e4ba0",
    "metadata": {},
    "outputs": [
@@ -179,8 +189,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
-   "id": "d8b9f68c",
+   "execution_count": 6,
+   "id": "57455b4b",
    "metadata": {},
    "outputs": [
     {
@@ -191,7 +201,7 @@
        "       [0., 0., 0.]], dtype=float32)>"
       ]
      },
-     "execution_count": 34,
+     "execution_count": 6,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -211,16 +221,16 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 35,
-   "id": "78ba73da",
+   "execution_count": 7,
+   "id": "6413d2a9",
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Means: tf.Tensor([-0.01646124  0.01251054  0.00447996], shape=(3,), dtype=float32)\n",
-      "Stds:  tf.Tensor([1.0073316 0.9962494 1.0039229], shape=(3,), dtype=float32)\n"
+      "Means: tf.Tensor([-0.00104369 -0.01390716 -0.01302913], shape=(3,), dtype=float32)\n",
+      "Stds:  tf.Tensor([0.9872753  0.9919341  0.98851275], shape=(3,), dtype=float32)\n"
      ]
     }
    ],
@@ -231,6 +241,44 @@
     "print(\"Means:\", tf.math.reduce_mean(y, axis=1))\n",
     "print(\"Stds: \", tf.math.reduce_std(y, axis=1))"
    ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "3d32f8a4",
+   "metadata": {},
+   "source": [
+    "### Task: <a class=\"tocSkip\">\n",
+    "Implement the mean-square difference function in tensorflow:\n",
+    "    $$ L(x, y) = \\sum_i \\frac{(x_i-y_i)^2}{N}$$"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "7aec09c9",
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "SyntaxError",
+     "evalue": "invalid syntax (3614834331.py, line 10)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Input \u001b[0;32mIn [8]\u001b[0;36m\u001b[0m\n\u001b[0;31m    print(loss(x,y))?\u001b[0m\n\u001b[0m                    ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
+     ]
+    }
+   ],
+   "source": [
+    "def loss(x, y):\n",
+    "    # TODO: replace the return term\n",
+    "    return 0.\n",
+    "\n",
+    "# Use these values of x and y to get the variation using L for a uniformly distributed dataset in [0, 1)\n",
+    "x = tf.random.uniform([100000])\n",
+    "y = tf.ones([100000]) * 0.5\n",
+    "\n",
+    "# Result should be around 0.083333\n",
+    "print(loss(x,y))? "
+   ]
   }
  ],
  "metadata": {