diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..097c3b399318131da767ffa9474b4e686c6f9a1e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,56 @@
+# Created by https://www.toptal.com/developers/gitignore/api/macos,visualstudiocode
+# Edit at https://www.toptal.com/developers/gitignore?templates=macos,visualstudiocode
+
+### macOS ###
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+### macOS Patch ###
+# iCloud generated files
+*.icloud
+
+### VisualStudioCode ###
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+!.vscode/*.code-snippets
+
+# Local History for Visual Studio Code
+.history/
+
+# Built Visual Studio Code Extensions
+*.vsix
+
+### VisualStudioCode Patch ###
+# Ignore all local history of files
+.history
+.ionide
+
+# End of https://www.toptal.com/developers/gitignore/api/macos,visualstudiocode
diff --git a/Exercise/EKF_UKF/task1.ipynb b/Exercise/EKF_UKF/task1.ipynb
index 7ef82a7e1640471147f702d7756aa84821871747..a8ba1c66f568f838ec02f6bd4ceaf04f5d30e266 100644
--- a/Exercise/EKF_UKF/task1.ipynb
+++ b/Exercise/EKF_UKF/task1.ipynb
@@ -2,32 +2,33 @@
  "cells": [
   {
    "cell_type": "code",
-   "execution_count": 16,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
     "import numpy as np\n",
     "import matplotlib.pyplot as plt\n",
     "import seaborn as sns\n",
-    "import pandas as pd"
+    "from seaborn import despine\n",
+    "import pandas as pd\n",
+    "\n",
+    "sns.set(style='white', rc={'lines.linewidth': 0.75})"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "In case you want your plots in external windows"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": null,
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Using matplotlib backend: Qt5Agg\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
-    "%matplotlib\n",
-    "sns.set(style='white', rc={'lines.linewidth': 0.75})"
+    "# %matplotlib"
    ]
   },
   {
@@ -46,7 +47,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -68,7 +69,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -78,15 +79,15 @@
     "x[:, 0] = x0\n",
     "\n",
     "u = np.zeros((1, N))\n",
-    "u[0][np.logical_and(t >= 5, t < 10)] = -1\n",
-    "u[0][np.logical_and(t >= 10, t < 12)] = 0\n",
-    "u[0][np.logical_and(t >= 12, t < 15)] = 1\n",
-    "u[0][np.logical_and(t >= 15, t < 17)] = -1\n",
+    "u[0][(t >= 5) &  (t < 10)] = -1\n",
+    "u[0][(t >= 10) & (t < 12)] = 0\n",
+    "u[0][(t >= 12) & (t < 15)] = 1\n",
+    "u[0][(t >= 15) & (t < 17)] = -1\n",
     "\n",
     "for ti in np.arange(0, N-1):\n",
-    "  x[:, ti+1] = model['f'](x[:, ti], u[0, ti], 0)\n",
+    "    x[:, ti + 1] = model['f'](x[:, ti], u[0, ti], 0)\n",
     "y0 = model['h'](x, u)\n",
-    "y = y0 + (np.diag([0.6, 0.03])@np.random.normal(0, 1, size=(2, N)))\n",
+    "y = y0 + (np.diag([0.6, 0.03]) @ np.random.normal(0, 1, size=(2, N)))\n",
     "data = {'t': t, 'x': x, 'u': u, 'y0': y0, 'y': y}"
    ]
   },
@@ -99,18 +100,18 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
-    "plt.figure(10, clear=True)\n",
-    "plt.plot(data['x'][0, :], data['x'][1, :])\n",
-    "plt.plot(data['x'][0, 0], data['x'][1, 0], 'bo')\n",
-    "plt.plot(data['x'][0, -1], data['x'][1, -1], 'rx')\n",
-    "plt.axis('square')\n",
-    "plt.xlabel('x')\n",
-    "plt.ylabel('y')\n",
-    "sns.despine()"
+    "_, ax = plt.subplots(num=10, clear=True)\n",
+    "ax.plot(data['x'][0, :], data['x'][1, :])\n",
+    "ax.plot(data['x'][0, 0], data['x'][1, 0], 'bo')\n",
+    "ax.plot(data['x'][0, -1], data['x'][1, -1], 'rx')\n",
+    "ax.axis('square')\n",
+    "ax.set_xlabel('x')\n",
+    "ax.set_ylabel('y')\n",
+    "despine(ax=ax)"
    ]
   },
   {
@@ -122,27 +123,24 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
-    "plt.figure(20, clear=True)\n",
-    "plt.subplot(2, 1, 1)\n",
-    "plt.plot(data['t'], data['y0'][0], 'b', lw=2)\n",
-    "plt.plot(data['t'], data['y'][0], 'r')\n",
-    "plt.xlabel('t [s]')\n",
-    "plt.ylabel('[m]')\n",
-    "plt.title('Range measurement')\n",
-    "sns.despine()\n",
+    "_, ax = plt.subplots(2, 1, num=20, clear=True, layout=\"tight\")\n",
+    "ax[0].plot(data['t'], data['y0'][0], 'b', lw=2)\n",
+    "ax[0].plot(data['t'], data['y'][0], 'r')\n",
+    "ax[0].set_xlabel('t [s]')\n",
+    "ax[0].set_ylabel('[m]')\n",
+    "ax[0].set_title('Range measurement')\n",
+    "despine(ax=ax[0])\n",
     "\n",
-    "plt.subplot(2, 1, 2)\n",
-    "plt.plot(data['t'], data['y0'][1]*180/np.pi, 'b', lw=2)\n",
-    "plt.plot(data['t'], data['y'][1]*180/np.pi, 'r')\n",
-    "plt.xlabel('t [s]')\n",
-    "plt.ylabel('[deg]')\n",
-    "plt.title('Angle measurement')\n",
-    "sns.despine()\n",
-    "plt.tight_layout()"
+    "ax[1].plot(data['t'], data['y0'][1]*180/np.pi, 'b', lw=2)\n",
+    "ax[1].plot(data['t'], data['y'][1]*180/np.pi, 'r')\n",
+    "ax[1].set_xlabel('t [s]')\n",
+    "ax[1].set_ylabel('[deg]')\n",
+    "ax[1].set_title('Angle measurement')\n",
+    "despine(ax=ax[1])"
    ]
   },
   {
@@ -161,7 +159,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 28,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -179,20 +177,20 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 31,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
-    "plt.figure(30, clear=True)\n",
-    "plt.plot(data['x'][0], data['x'][1])\n",
-    "plt.plot(data['x'][0, 0], data['x'][1, 0], 'bo')\n",
-    "plt.plot(data['x'][0, -1], data['x'][1, -1], 'rx')\n",
-    "plt.plot(pos_hat_0[0], pos_hat_0[1], 'k')\n",
-    "plt.axis('square')\n",
-    "plt.xlabel('x')\n",
-    "plt.ylabel('y')\n",
-    "plt.title('Direct computation from measurements')\n",
-    "sns.despine()"
+    "_, ax = plt.subplots(num=30, clear=True)\n",
+    "ax.plot(data['x'][0], data['x'][1])\n",
+    "ax.plot(data['x'][0, 0], data['x'][1, 0], 'bo')\n",
+    "ax.plot(data['x'][0, -1], data['x'][1, -1], 'rx')\n",
+    "ax.plot(pos_hat_0[0], pos_hat_0[1], 'k')\n",
+    "ax.axis('square')\n",
+    "ax.set_xlabel('x')\n",
+    "ax.set_ylabel('y')\n",
+    "ax.set_title('Direct computation from measurements')\n",
+    "despine(ax=ax)"
    ]
   },
   {
@@ -204,26 +202,22 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
-    "plt.figure(31, clear=True)\n",
-    "plt.subplot(2, 1, 1)\n",
-    "plt.plot(data['t'], data['x'][0] - pos_hat_0[0])\n",
-    "plt.xlabel('t [s]');\n",
-    "plt.ylabel('[m]')\n",
-    "plt.title('x position error in direct computation');\n",
-    "sns.despine()\n",
-    "\n",
-    "plt.subplot(2, 1, 2)\n",
-    "plt.plot(data['t'], data['x'][1] - pos_hat_0[1])\n",
-    "plt.xlabel('t [s]');\n",
-    "plt.ylabel('[m]')\n",
-    "plt.title('y position error in direct computation')\n",
-    "sns.despine()\n",
+    "_, ax = plt.subplots(2, 1, num=31, clear=True, layout=\"tight\")\n",
+    "ax[0].plot(data['t'], data['x'][0] - pos_hat_0[0])\n",
+    "ax[0].set_xlabel('t [s]');\n",
+    "ax[0].set_ylabel('[m]')\n",
+    "ax[0].set_title('x position error in direct computation');\n",
+    "despine(ax=ax[0])\n",
     "\n",
-    "plt.tight_layout()"
+    "ax[1].plot(data['t'], data['x'][1] - pos_hat_0[1])\n",
+    "ax[1].set_xlabel('t [s]');\n",
+    "ax[1].set_ylabel('[m]')\n",
+    "ax[1].set_title('y position error in direct computation')\n",
+    "despine(ax=ax[1])"
    ]
   },
   {
@@ -242,7 +236,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -280,7 +274,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 35,
+   "execution_count": null,
    "metadata": {},
    "outputs": [],
    "source": [
@@ -352,7 +346,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.0"
+   "version": "3.11.0"
   }
  },
  "nbformat": 4,
diff --git a/Lectures/slides_3.pdf b/Lectures/slides_3.pdf
index 853c0d2ac7033e4ff2219444f0e35ff8d4f8290a..e7263263b9b39ac7e316f7a809a5a6820fae3042 100644
Binary files a/Lectures/slides_3.pdf and b/Lectures/slides_3.pdf differ