From 0eb29929c79d6279b46e1557e6851b9b2585d2a0 Mon Sep 17 00:00:00 2001
From: Julius <julius.zocher@rwth-aachen.de>
Date: Tue, 28 Nov 2023 17:35:49 +0100
Subject: [PATCH 01/23] initial structure

---
 .gitignore                                    |  3 +
 Dockerfile                                    |  6 +-
 .../Quickstart.ipynb                          | 57 ++++++++++-----
 Excercise_1/main.ipynb                        | 48 +++++++++++++
 Excercise_2/main.ipynb                        | 69 +++++++++++++++++++
 Excercise_3/main.ipynb                        | 69 +++++++++++++++++++
 environment.yml                               |  4 +-
 requirements.txt                              |  1 -
 8 files changed, 231 insertions(+), 26 deletions(-)
 rename Quickstart.ipynb => Excercise_1/Quickstart.ipynb (93%)
 create mode 100644 Excercise_1/main.ipynb
 create mode 100644 Excercise_2/main.ipynb
 create mode 100644 Excercise_3/main.ipynb
 delete mode 100644 requirements.txt

diff --git a/.gitignore b/.gitignore
index 5751acb..06caacc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,6 @@ __pycache__/
 
 # Jupyter
 .ipynb_checkpoints
+
+# pycharm
+.idea
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index bf7b0ec..9fdc660 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,11 +2,7 @@
 ARG BASE_IMAGE=registry.git.rwth-aachen.de/jupyter/profiles/rwth-courses:latest
 FROM ${BASE_IMAGE}
 
-# Install packages via requirements.txt
-ADD requirements.txt .
-RUN pip install -r requirements.txt
-
-# .. Or update conda base environment to match specifications in environment.yml
+# Update conda base environment to match specifications in environment.yml
 ADD environment.yml /tmp/environment.yml
 
 # All packages specified in environment.yml are installed in the base environment
diff --git a/Quickstart.ipynb b/Excercise_1/Quickstart.ipynb
similarity index 93%
rename from Quickstart.ipynb
rename to Excercise_1/Quickstart.ipynb
index c38cd0b..bd022ba 100644
--- a/Quickstart.ipynb
+++ b/Excercise_1/Quickstart.ipynb
@@ -19,11 +19,13 @@
   },
   {
    "cell_type": "markdown",
-   "metadata": {},
+   "metadata": {
+    "jp-MarkdownHeadingCollapsed": true
+   },
    "source": [
     "## Markdown\n",
     "\n",
-    "You can specify the cell type which is either _Code_ or _Markdown_. \n",
+    "ou can specify the cell type which is either _Code_ or _Markdown_. \n",
     "\n",
     "### Lists\n",
     "\n",
@@ -58,15 +60,6 @@
     "## Python"
    ]
   },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "print(\"Hello world!\")"
-   ]
-  },
   {
    "cell_type": "markdown",
    "metadata": {},
@@ -78,14 +71,19 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
+   "execution_count": 1,
    "metadata": {},
-   "outputs": [],
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Hello world!\n"
+     ]
+    }
+   ],
    "source": [
-    "import numpy as np\n",
-    "\n",
-    "a = np.array([0, 1, -5])\n",
-    "a"
+    "print(\"Hello world!\")"
    ]
   },
   {
@@ -97,6 +95,29 @@
     "Nice matplotlib [tutorial](https://matplotlib.org/tutorials/introductory/usage.html#sphx-glr-tutorials-introductory-usage-py)"
    ]
   },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "array([ 0,  1, -5])"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import numpy as np\n",
+    "\n",
+    "a = np.array([0, 1, -5])\n",
+    "a"
+   ]
+  },
   {
    "cell_type": "code",
    "execution_count": null,
@@ -264,7 +285,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.7"
+   "version": "3.9.18"
   }
  },
  "nbformat": 4,
diff --git a/Excercise_1/main.ipynb b/Excercise_1/main.ipynb
new file mode 100644
index 0000000..daab14b
--- /dev/null
+++ b/Excercise_1/main.ipynb
@@ -0,0 +1,48 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# main"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "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.18"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/Excercise_2/main.ipynb b/Excercise_2/main.ipynb
new file mode 100644
index 0000000..d8e9a62
--- /dev/null
+++ b/Excercise_2/main.ipynb
@@ -0,0 +1,69 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# main"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "ModuleNotFoundError",
+     "evalue": "No module named 'pandas'",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[1;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
+      "Cell \u001b[1;32mIn[2], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpandas\u001b[39;00m\n",
+      "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'pandas'"
+     ]
+    }
+   ],
+   "source": [
+    "import pandas"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "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.18"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/Excercise_3/main.ipynb b/Excercise_3/main.ipynb
new file mode 100644
index 0000000..d8e9a62
--- /dev/null
+++ b/Excercise_3/main.ipynb
@@ -0,0 +1,69 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# main"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "ModuleNotFoundError",
+     "evalue": "No module named 'pandas'",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[1;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
+      "Cell \u001b[1;32mIn[2], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpandas\u001b[39;00m\n",
+      "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'pandas'"
+     ]
+    }
+   ],
+   "source": [
+    "import pandas"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "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.18"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}
diff --git a/environment.yml b/environment.yml
index c22af46..44bf026 100644
--- a/environment.yml
+++ b/environment.yml
@@ -1,5 +1,5 @@
-name: base
+name: DEV
 channels:
   - conda-forge
 dependencies:
-  - bokeh==2.4.0
+  - pandas==2.0.0
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index fb6c7ed..0000000
--- a/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-pandas
-- 
GitLab


From 75244d0f6a272fafbdff5e84a3f3556c9c1cabcb Mon Sep 17 00:00:00 2001
From: Julius <julius.zocher@rwth-aachen.de>
Date: Wed, 28 Feb 2024 09:46:23 +0100
Subject: [PATCH 02/23] test1

---
 .gitignore                                    |   2 +-
 ...Ex2_Battery_Optimization_noSolutions.ipynb | 462 +++++++++++++++
 Excercise_1/Quickstart.ipynb                  | 293 ----------
 Excercise_1/main.ipynb                        |  48 --
 .../2023_12_01_DEV_UE2_A2_v1.0_students.ipynb | 539 ++++++++++++++++++
 Excercise_2/main.ipynb                        |  69 ---
 Excercise_2/measurement_data.xlsx             | Bin 0 -> 8737 bytes
 Excercise_3/340px-English-slf(1).png          | Bin 0 -> 10402 bytes
 Excercise_3/Cryptography.ipynb                | 483 ++++++++++++++++
 Excercise_3/main.ipynb                        |  69 ---
 Excercise_3/shakethatpear.txt                 |  33 ++
 11 files changed, 1518 insertions(+), 480 deletions(-)
 create mode 100644 Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
 delete mode 100644 Excercise_1/Quickstart.ipynb
 delete mode 100644 Excercise_1/main.ipynb
 create mode 100644 Excercise_2/2023_12_01_DEV_UE2_A2_v1.0_students.ipynb
 delete mode 100644 Excercise_2/main.ipynb
 create mode 100644 Excercise_2/measurement_data.xlsx
 create mode 100644 Excercise_3/340px-English-slf(1).png
 create mode 100644 Excercise_3/Cryptography.ipynb
 delete mode 100644 Excercise_3/main.ipynb
 create mode 100644 Excercise_3/shakethatpear.txt

diff --git a/.gitignore b/.gitignore
index 06caacc..c2d867e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,4 @@ __pycache__/
 .ipynb_checkpoints
 
 # pycharm
-.idea
\ No newline at end of file
+.idea
diff --git a/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb b/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
new file mode 100644
index 0000000..915d5e0
--- /dev/null
+++ b/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
@@ -0,0 +1,462 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "52b6c1bb",
+   "metadata": {},
+   "source": [
+    "# DEV Excercise 3\n",
+    "Task 2 - Battery storage optimization\n",
+    "\n",
+    "In this task, an energy system consisting of a building with an electrical load (e.g. household appliances), PV system, battery storage and electricity grid connection is considered.\n",
+    "24 time steps are considered, corresponding to the 24 hours of a day.\n",
+    "Complete the code snippets where needed at places market with \"!!!\"."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "6e26b8e3",
+   "metadata": {},
+   "source": [
+    "Definition of the individual components:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "id": "f93f1b55",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Time series of electrical load [kW]\n",
+    "el_demand_kW = [0.3, 0.4, 0.3, 0.3, 0.3, 0.3, 0.6, 0.7, 0.5, 0.4, 0.4, 0.7, 1.1, 0.8, 0.3, 0.3, 0.3, 0.3, 0.5, 0.7, 1.2, 1, 0.8, 0.4]\n",
+    "\n",
+    "# Time series for costs of electricity from the grid [€/kWh]\n",
+    "c_euro_kWh = [0.24, 0.32, 0.26, 0.25, 0.23, 0.32, 0.33, 0.35, 0.32, 0.32, 0.31, 0.28, 0.24, 0.33, 0.22, 0.27, 0.32, 0.32, 0.35, 0.32, 0.3, 0.33, 0.32, 0.31]\n",
+    "\n",
+    "# PV system\n",
+    "pv_pu = [0, 0, 0, 0, 0, 0, 0.1, 0.3, 0.6, 0.7, 0.8, 0.9, 1, 1, 0.9, 0.8, 0.7, 0.6, 0.3, 0.1, 0, 0, 0, 0] # Generation time series per unit [p.u.]\n",
+    "pv_kWp = 8 # peak power [kW]\n",
+    "\n",
+    "# Battery storage system\n",
+    "E_bat_kWh = 3 # capacity [kWh]\n",
+    "P_bat_max_charge_kW = 1 # max charging power [kW] (charging efficiency of 100 % is assumed)\n",
+    "P_bat_max_discharge_kW = 1 # max discharging power [kW] (discharging efficiency of 100 % is assumed)\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d8d3f3bb",
+   "metadata": {},
+   "source": [
+    "# Task 2 a)\n",
+    "Plot the electrical demand, the electricity price as well as the PV generation for a 8 kWp plant. Use the python library matplotlib."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "id": "8f2b2111",
+   "metadata": {},
+   "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": [
+    "import matplotlib.pyplot as plt\n",
+    "import numpy as np\n",
+    "\n",
+    "# define the function\n",
+    "def plot_time_series(el_demand_kW, c_euro_kWh, pv_pu, pv_kWp):\n",
+    "    # !!! insert function\n",
+    "    plt.plot(el_demand_kW)\n",
+    "    plt.plot(c_euro_kWh)\n",
+    "    plt.plot(pv_pu)\n",
+    "    plt.plot(pv_kWp)\n",
+    "    plt.show()\n",
+    "    pass\n",
+    "\n",
+    "# Call the function\n",
+    "plot_time_series(el_demand_kW, c_euro_kWh, pv_pu, pv_kWp)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "40fc921d",
+   "metadata": {},
+   "source": [
+    "# Task 2 b)\n",
+    "Calculate the costs of electricity supply assuming the PV plant and battery storage system are not operating. (Using numpy might be helpfull)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "id": "69488a00",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The total electricity costs are 3.9 €\n"
+     ]
+    }
+   ],
+   "source": [
+    "# define function\n",
+    "def get_total_costs(energy, costs):\n",
+    "    c_total = np.dot(np.array(energy),np.array(costs)) # !!! <-- insert calculation\n",
+    "    return c_total\n",
+    "\n",
+    "# call function\n",
+    "c_total = get_total_costs(el_demand_kW, c_euro_kWh)\n",
+    "print(f\"The total electricity costs are {round(c_total,2)} €\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9d4e20d6",
+   "metadata": {},
+   "source": [
+    "# Task 2 c)\n",
+    "Calculate the costs of electricity considering a 8 kWp PV plant, but no battery storage system. Assume that no income is generated by feeding the PV generated electricity into the grid."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "id": "e410b81f",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The total electricity costs are -16.82 €\n"
+     ]
+    }
+   ],
+   "source": [
+    "# calculate residuum\n",
+    "residuum_kW = np.array(el_demand_kW) - pv_kWp*np.array(pv_pu) #  !!! <-- insert calculation \n",
+    "\n",
+    "# call cost calculating function\n",
+    "c_total_residuum = get_total_costs(residuum_kW, c_euro_kWh)\n",
+    "print(f\"The total electricity costs are {round(c_total_residuum,2)} €\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e432595f",
+   "metadata": {},
+   "source": [
+    "# Task 2d)\n",
+    "In the following, an optimization problem is set up to optimize the operation of the battery in such a way that the electricity supply for the house is as cost-effective as possible."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "id": "eedebac7",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Import of necessary packages\n",
+    "from pulp import LpProblem, LpVariable, lpSum, LpMinimize\n",
+    "\n",
+    "# Create a new model\n",
+    "def optimze_battery_operation(el_demand_kW, pv_kWp, pv_pu, E_bat_kWh, P_bat_max_charge_kW, P_bat_max_discharge_kW, c_euro_kWh):\n",
+    "    model = LpProblem(\"charging_optimization\", LpMinimize)\n",
+    "\n",
+    "    # Decision Variables\n",
+    "    buy = LpVariable.dicts(\"buy\", range(24), lowBound=0)  # The amount of electricity (in kW) bought from the grid at time t\n",
+    "    soc = LpVariable.dicts(\"soc\", range(25), lowBound=0, upBound=E_bat_kWh)  # The State of Charge (in kWh) of the battery at time t\n",
+    "    discharge = LpVariable.dicts(\"discharge\", range(24), lowBound=0, upBound=P_bat_max_discharge_kW)  # Discharge rate (in kW) at time t\n",
+    "    charge = LpVariable.dicts(\"charge\", range(24), lowBound=0, upBound=P_bat_max_charge_kW)  # Charge rate (in kW) at time t\n",
+    "    feedin = LpVariable.dicts(\"feedin\", range(24), lowBound=0)  # The amount of electricity (in kW) sold to the grid at time t\n",
+    "    consumed_pv = LpVariable.dicts(\"consumed_pv\", range(24), lowBound=0)  # The amount of electricity (in kW) consumed directly from PV at time t\n",
+    "\n",
+    "    # Objective Function\n",
+    "    model += lpSum(c_euro_kWh[t] * buy[t] for t in range(24))\n",
+    "\n",
+    "    # Constraints\n",
+    "    model += soc[0] == E_bat_kWh/2\n",
+    "    model += soc[23] == E_bat_kWh/2\n",
+    "\n",
+    "    # Energy balance for consumed electricity\n",
+    "    for t in range(24):\n",
+    "        model += el_demand_kW[t] == consumed_pv[t] + buy[t] + discharge[t]\n",
+    "\n",
+    "    # Energy balance for generated electricity\n",
+    "    for t in range(24):\n",
+    "        model += pv_kWp * pv_pu[t] ==  charge[t] + feedin[t] + consumed_pv[t]\n",
+    "\n",
+    "    # State of Charge\n",
+    "    for t in range(23):\n",
+    "        model += soc[t+1] == soc[t] + charge[t] - discharge[t]\n",
+    "\n",
+    "    # Solve the optimization problem\n",
+    "    model.solve()\n",
+    "\n",
+    "    return model, buy, soc, feedin"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "fe89f489",
+   "metadata": {},
+   "source": [
+    "Calculate the costs of electricity considering a 8 kWp PV plant and 3 kWh battery storage system. Assume that no income is generated by feeding the PV generated electricity into the grid. Plot the resulting state of charge (SOC) and buy time series and compare them to the other time series.\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "id": "4e6625bc",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The total electricity costs are 0.55 €\n",
+      "The total electricity costs are 0.55 €\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    },
+    {
+     "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": [
+    "## call the optimization function\n",
+    "model, buy, soc, feedin_cost_minimizing = optimze_battery_operation(el_demand_kW, pv_kWp, pv_pu, E_bat_kWh, P_bat_max_charge_kW, P_bat_max_discharge_kW, c_euro_kWh)\n",
+    "\n",
+    "# read results\n",
+    "buy_results = []\n",
+    "soc_results = []\n",
+    "feedin_cost_minimizing_results = []\n",
+    "\n",
+    "for i in range(0,24):\n",
+    "    buy_results.append(buy[i].value())\n",
+    "    soc_results.append(soc[i].value())\n",
+    "    feedin_cost_minimizing_results.append(feedin_cost_minimizing[i].value())\n",
+    "\n",
+    "# print results calculated with time series\n",
+    "c_total_optimal = get_total_costs(buy_results, c_euro_kWh)\n",
+    "print(f\"The total electricity costs are {round(c_total_optimal,2)} €\")\n",
+    "\n",
+    "# print results from objective value (validation)\n",
+    "c_total_optimal = model.objective.value()\n",
+    "print(f\"The total electricity costs are {round(c_total_optimal,2)} €\")\n",
+    "\n",
+    "# plots\n",
+    "plot_time_series(el_demand_kW, c_euro_kWh, pv_pu, pv_kWp)\n",
+    "\n",
+    "# !!! insert plot for Battery SOC\n",
+    "plt.plot(soc_results)\n",
+    "\n",
+    "# !!! insert plot for electricity bought\n",
+    "plt.plot(buy_results)\n",
+    "\n",
+    "\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "312a055f",
+   "metadata": {},
+   "source": [
+    "The SOC of the battery starts and ends at 50% of the maximum capacity, as this is specified by the constraints. Initially, the battery discharges as no PV power is generated. It is sufficient to charge the battery in the last hours of the day, as the size of the battery is comparatively small. It can be seen that the grid power is drawn in the time steps when the grid power is most favorable."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8c3cc635",
+   "metadata": {},
+   "source": [
+    "# Task 2 e)\n",
+    "Change the battery optimization function (1 Variable, 1 Objective, 1 Constraint) below so that the maximium (single peak value, not sum of all values!) feed in from the pv plant to the grid gets minimized. How much was the maximum feed in without battery operation, with cost minimizing battery operation and with feed-in minimizing battery operation? Plot the resulting feed-in time series."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "id": "4e8c2c60",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The maximum feed-in without battery operation is 9.1 kW.\n",
+      "The maximum feed-in with cost minimizing battery operation is 7.2 kW.\n",
+      "The maximum feed-in with feed-in minimizing battery operation is 6.2 kW.\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAEGCAYAAABvtY4XAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAABU8klEQVR4nO3dd1iUx9rA4d/s0rsIgg1RsdNERYoae9QYS2JMMc2cJCfRmF40vZzkM8f0dlLV9GKMJbYYExWNvSBYwYIiIgIK0lnY+f54AUHKLspS574uLuGtj8vyMMw784yQUqIoiqI0P7qGDkBRFEWxDJXgFUVRmimV4BVFUZopleAVRVGaKZXgFUVRmimrhg6gPA8PD+nr69vQYSiKojQZu3fvTpNSela1r1EleF9fX3bt2tXQYSiKojQZQoiT1e1TXTSKoijNlErwiqIozZRK8IqiKM1Uo+qDV5SqGAwGTp8+TX5+fkOHoigNxs7Ojg4dOmBtbW32OSrBK43e6dOncXZ2xtfXFyFEQ4ejKPVOSkl6ejqnT5+mc+fOZp+numiURi8/P5/WrVur5K60WEIIWrduXeu/YlWCV5oEldyVlu5KfgZUgleUKySlJD27gHxDcUOHoihVUgleUUx47LHHeO+998q+vvbaa7n33nu5kGsgKSOP+2c+wguvzeXX35Yyd+5cAJYuXcrBgwfLzhk6dGidTeJ74403qt3n6+tLQEAAwcHBBAQEsGzZslpdLyMjg08++aRO4lQankrwimJCZGQkW7ZsAcBoNJKWlsaBAwc4dzEfe2s9B6N30jOoP91Dh3LrfbPIKyyulODrUk0JHmD9+vVER0fz66+/8vDDD9fqeleS4KWUGI3GWp2j1A+V4BXFhIiICLZu3QrAgQMH8Pf3x87BkbT087jZCY7GHWHyqEGsX76IOU88xqJV61i6bDlPPvkUwcHBHDt2DIBFixYRGhpK9+7d2bRpE6A9QJ4+fToBAQH07duX9evXA7Bw4UIeeuihshjGjx/Phg0bmD17Nnl5eQQHBzNt2rQa47548SKtWrUq+3rSpEn069ePPn368PnnnwNUut7s2bM5duwYwcHBPPXUUwDMmzePAQMGEBgYyEsvvQRAQkICPXr04M4778Tf35/XXnuNRx99tOxeX3zxBY899tjVvOxKHVDDJJUm5ZXfD3DwzMU6vWbvdi68dH2fave3a9cOKysrTp06xZYtWxgYFoZD3AkOx+yGDC8CAgJwsLfD1cEaN0drrh1+DUNHjWHwiGu58cYptHGxBaCoqIgdO3awatUqXnnlFdatW8fHH3+MEILY2FgOHz7M6NGjiYuLqzaWuXPn8tFHHxEdHV3tMcOGDUNKyfHjx/nll1/Kts+fPx93d3fy8vIYMGAAN954Y6XrJSQksH///rKv165dS3x8PDt27EBKyYQJE4iKisLHx4f4+Hi+/vprwsLCyM7OJigoiHnz5mFtbc2CBQv47LPPzP8mKBahEryimCEiIoItW7awZcsW7nngIaRja47E7OJCkjuRkZFlx+mEwMvFDld7a9zsrckpLOLoOQP5hmLGjp8AQL9+/UhISABg8+bNzJo1C4CePXvSqVOnGhO8OdavX4+HhwfHjh1jxIgRDB06FCcnJz744AOWLFkCQGJiIvHx8bRu3brGa61du5a1a9fSt29fALKzs4mPj8fHx4dOnToRFhYGgJOTE8OHD2fFihX06tULg8FAQEDAVf0/lKunErzSpNTU0rak0n742NhYWnf0I8zdi9++/gwXFxemT59e6XghBK4ONvT0diE9pwCjhNRcI8dTs9EXSYqKimq8n5WVVYV+7SuZxdu1a1e8vLw4ePAgubm5rFu3jq1bt+Lg4MDQoUPNuqaUkjlz5vDvf/+7wvaEhAQcHR0rbLv33nt544036NmzZ5WviVL/VB+8opghIiKCFStW4OzqhhFBj05tycjIYOvWrURERFQ63tnZmaysLPQ6QRtnO+xt9Hg42ZJvMJKQnoNRSgAGDx7M999/D0BcXBynTp2iR48e+Pr6Eh0djdFoJDExkR07dpRd29raGoPBYDLmc+fOceLECTp16kRmZiatWrXCwcGBw4cPs23btiqvVxp3qWuvvZb58+eTnZ0NQFJSEufOnavyfgMHDiQxMZEffviBW2+91WR8iuWpFryimCEgIIC0tDRGTbgRR1srnOysCQgIIDs7Gw8Pj0rH33LLLdx333188MEH/PrrrwiglaMNPb2dyc+6QLFRUmw0MmPGDB588EECAgKwsrJi4cKF2NraEhkZSefOnenduze9evUiJCSk7Nr3338/gYGBhISElP1yKG/YsGHo9XoMBgNz587Fy8uLMWPG8Omnn9KrVy969OhR1rVS1fUiIyPx9/dn7NixzJs3j0OHDhEeHg5oXTHfffcder2+ytdp6tSpREdHV3i4qzQcIUtaEo1B//79pVrwQ7ncoUOH6NWrV0OHQWpWAcmZeXTxdMLJ9srbRnmFRcSfy8bb1Y42znZ1GGHDGz9+PI899hgjRoxo6FCapap+FoQQu6WU/as6XnXRKIoZio2S1KwCnGytriq5A9jbaNdIyyrEaGw8DayrkZGRQffu3bG3t1fJvRFRXTSKYob0nAKKjEa8XBzq5HptnG05npbDhdxCWjvZ1sk1G5Kbm9tVj/5R6p5qwSuKCcVGSVpWAc521jheZeu9lKOtFQ42VqRmF9CYukmV5kUleEUxIT27gCKjxMul7lraQgg8nW0pLDKSmWd6RIyiXAmV4BWlBsVGI6nZBbjYWeNgU7c9mi52Vtha6UnNUq14xTJUgleUGqRlF1Jcx633UqWt+DxDMdkFNU98UpQroRK8olSjqNhIWnYB7//neT775KOy7aXlgks98cQTvPPOOyxfvrzW5YLdHKyx1us4l1UAaJOdxo0bR7du3QgJCWHq1KmkpKTUKm5TFSGFENx+++2X/p9FRXh6ejJ+/HiACv+P6pw5c4YpU6bUKq4XX3yRdevWXfH+2lBlk0tIKRvNR79+/aSiXO7gwYMNct/kjDy5L/GC/P7Hn+VNN90kpZSyuLhYhoSEyLCwsLLjwsLC5NatWyuce9ddd8lFixaVfX3NNdfInTt3Vnmfcxfz5b7ECzItI0v6+fnJ5cuXl+1bv369jI2NrVXcJ06ckH369Kl2v6OjowwKCpK5ublSSilXrVolg4KC5HXXXVer+zRmnTp1kqmpqVJKKQ8fPix9fHxMnuPo6Fj2uanXsCpGo1EWFxfXLtBaqupnAdglq8mpqgWvKFUoKjaSnl2Aq701Q4cMqlQu2NnZmQsXLlBQUMChQ4cICQkpK/G7ZcsWli9fzlNPmS4XDODuaINeJ/hq4beEh4dz/fXXl+0bOnQo/v7+1ZYVPnDgAKGhoQQHBxMYGEh8fHyVJX8vN27cOFauXAnAjz/+WKG0QPlSxXfffTcPP/wwERERdOnShV9//RXQatH4+/uXHT9p0iRGjRqFr68vH330Ee+88w59+/YlLCyM8+fPl13r119/ZdeuXQQHB5e1rkuXoivdD1oL/KWXXiIkJISAgAAOHz4MQGpqKqNGjaJPnz7ce++9dOrUibS0tBq/ly25bLIaB680Latnw9nYur2mdwCMrdglkZZdQLGUeLnYYWftWKFccHh4OElJSWzduhVXV1cCAgKwsbEpOzciIoIJEyYwfvz4Ct0YVZULBtDrBK2dbIndv5+g4L5VhlhdWeFPP/2URx55hGnTplFYWEhxcTFz586tUPK3Krfccguvvvoq48ePJyYmhnvuuafCL53ykpOT2bx5M4cPH2bChAlVds3s37+fvXv3kp+fj5+fH2+++SZ79+7lscce45tvvqmQ9Pr3718W21NPPcWYMWOqvK+Hhwd79uzhk08+4a233uLLL7/klVdeYfjw4cyZM4c1a9bw1VdfVft/VGWTVYJXlEq0vvdC3OxtsLPWaq6ULxf8+OOPk5SUxJYtW3B1da1QLrgmN9xwA1CxXHApD0cbhKDah63VlRUODw/n9ddf5/Tp09xwww1069bNrFgCAwNJSEjgxx9/ZNy4cTUeO2nSJHQ6Hb179672ecCwYcNwdnbG2dkZV1fXsr9CAgICiImJqfKcn3/+mT179rB27doq95d/vX777TdAex1KSx6PGTOmxpo3qmyySvBKUzO25od/daF08lGbciNnypcL9vf3p2PHjrz99tvVlguuiq2tdj29Xl+pXLCVXkdQgD8bNm6ksMiIjZV5vae33XYbAwcOZOXKlYwbN47PPvuMLl26mHXuhAkTePLJJ9mwYQPp6ekm4waqHc5Z/hidTlf2tU6nq7I08v79+3n55ZeJioqqtnBZTa9XbbTksskW7YMXQjwmhDgghNgvhPhRCNG8KispzY6h2Eh6diFuDpda73CpXLC7uzt6vR53d3ezygXXxr1338G+XTv4afHSsm1RUVHs37+/2rLCx48fp0uXLjz88MNMnDiRmJgYs+99zz338NJLL9V7CzMjI4Nbb72Vb775Bk9Pz1qdGxkZWdbdsnbtWi5cuGDynJZcNtliCV4I0R54GOgvpfQH9MAtlrqfotQFbdKRViumvNJyweXL7AYEBODq6lptueB58+bRt2/fsoesprg6O/H1T4v5/H+f0K1bN3r37s0nn3yCp6cnM2bMwGg0EhAQwM0331xWVviXX37B39+f4OBg9u/fz5133knr1q3LSv5W95AVoEOHDmYtyl3Xli1bxsmTJ7nvvvvKHraa66WXXmLt2rX4+/uzaNEivL29cXZ2rvLYYcOGERwczLBhwyqUTS4qKqJXr17Mnj27yrLJ06ZNq/Qajh49mttuu43w8HACAgKYMmVKjb9Ep06dSmRkZIOXTbZYueCSBL8NCAIuAkuBD6SUVXe4ocoFK1Wrr3LBhmIjR85m4WpvTUf3uikqVlv5hmLiUrLwcrHDy0X9wXu5goIC9Ho9VlZWbN26lQcffLDGh8kNxVJlk2tbLthiffBSyiQhxFvAKSAPWFtVchdC3A/cD+Dj42OpcBTFpLLWuwVmrZrLzlqPi501adkFeDjZoteJBoulMTp16hRTp07FaDRiY2PDF1980dAhVZCRkUFoaChBQUGNomyyxRK8EKIVMBHoDGQAi4QQt0spvyt/nJTyc+Bz0FrwlopHUWpSWGQkPaeQVo7W2FpV/dCvvng623Ix1cCFnEI8nJt+KeG61K1bN/bu3dvQYVSrsZVNtuRD1pHACSllqpTSAPwGVH4apSiNwLmL2kiKy/veG4KjrRWOtlopYaOFulCVlsGSCf4UECaEcBDaVLURwCEL3k9RrkieoVhbeMPRBpsGbr2X8nS2xVBsJCNXlRJWrpzFEryUcjvwK7AHiC251+eWup+iXKmzmfnodKJRtN5LOdtaYWetSgkrV8ei4+CllC9JKXtKKf2llHdIKQsseT9Fqa2sfANZ+QbaONthpW88pZmE0H7hFBQVczFflRJWrkzjeUcrSj2TUpKcmY+NlY7WTjbVHvfYY4/x3nvvlX1dl+WCy0tISMDe3r5sbPjQiFAwFl1VK758UbDL1bY874YNGxBC8OWXX5Zti46ORgjBW2+9ZfY1zSlHfLlx48aRkZFxxfvNVf57EBQUREREBEeOHDF5zg8//FD2dXR0NKtWrbrqWOqCSvBKi3Uh10C+oRhvFzt0ovrhiKVlCgCMRiNpaWkcOHCgbP+WLVvKCozNnj0bqJzgzdW1a1eio6PLPtq7O5NbWEROYXGtr2XKq6++ysiRI2t1jr+/f4XCXT/++CNBQUG1umb518lcq1atws3N7Yr310bp92Dfvn3cddddFerEV6UuEvzVlGKoiUrwSotkNEpSLubjYGOFq711jcdGRERYtFxwTVo52LB903qGDIokJCSEm266qWy6/O7du7nmmmvo168f1157LcnJyWXbg4KCCAoK4uOPP6722uaU571cp06dyM/PJyUlBSkla9asYezYsbW65uXliB988EHCwsLo0qULGzZs4J577qFXr17cfffdZdf19fUlLS2NTz/9tOwvnM6dOzNs2LAK+xMSEujVqxf33Xcfffr0YfTo0eTl5QGwc+dOAgMDy0oAV/eXTXnlSw0nJCQwePBgQkJCCAkJKfulP3v2bDZt2kRwcDBvvvkmL774Ij///DPBwcH8/PPP5OTkcM899xAaGkrfvn3LFh9ZuHAhEyZMYPjw4YwYMYI777yTpUuXlt172rRpZi1UUhNVbExpUt7c8SaHz1edfGqjsNiIociInbWePh69eCb0mWqPbdeunUXLBZdXWoMctL8cXnnlFeZ/9DaffP8bQb7efPDuW7zzzjvMmTOHWbNmsWzZMjw9Pfn555957rnnmD9/PtOnT+ejjz5iyJAhNZYquFxV5XmrMmXKFBYtWkTfvn0JCQmpUGjsSq554cIFtm7dyvLly5kwYQL//PMPX375JQMGDCA6OrpCKYMHHniABx54AIPBwPDhw3n88ccrXS8+Pp4ff/yRL774gqlTp7J48WJuv/12pk+fzhdffEF4eHiNf0GUfg+ysrLIzc1l+/btALRp04Y///wTOzs74uPjufXWW9m1axdz587lrbfeYsWKFQB4eXmxa9cuPvpIWwXs2WefZfjw4cyfP79sIlTpXzl79uwhJiYGd3d3Nm7cyLvvvsukSZPIzMxky5YtfP3119XGaQ6V4JUWR0owFBnR64TZM0UtXS64VGn3QKkVK1YQf+Qwd08eg04noLiI8PBwjhw5wv79+xk1ahQAxcXFtG3bloyMDDIyMhgyZAgAd9xxB6tXr651fKXleasydepUbr75Zg4fPsytt95a1pK90mtef/31CCEICAjAy8urrPhZnz59SEhIqLJWzSOPPMLw4cMrLI5SqnPnzmXnlL7WGRkZZGVlER4eDmhVOEsT8uXKfw9+/vln7r//ftasWYPBYOChhx4iOjoavV5v9oSmtWvXsnz58rLnFPn5+Zw6dQqAUaNG4e7uDsA111zDjBkzSE1NZfHixdx4441YWV1dilYJXmlSamppmyvpQi7ncwx093LC1tq8ce+WLhdcHSklo0aN4r3PFpByMZ8OrRxwd7QhNjaWPn36lHUdlarpQeP06dPZu3cv7dq1q7KP2Nz4vL29sba25s8//+T999+vMcGbc83ypYUvLztc1TkLFy7k5MmTZS3k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\n",
+      "text/plain": [
+       "<Figure size 432x288 with 1 Axes>"
+      ]
+     },
+     "metadata": {
+      "needs_background": "light"
+     },
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Import of necessary packages\n",
+    "from pulp import LpProblem, LpVariable, lpSum, LpMinimize\n",
+    "\n",
+    "# Create a new model\n",
+    "def optimze_battery_operation_PV(el_demand_kW, pv_kWp, pv_pu, E_bat_kWh, P_bat_max_charge_kW, P_bat_max_discharge_kW, c_euro_kWh):\n",
+    "    model = LpProblem(\"charging_optimization\", LpMinimize)\n",
+    "\n",
+    "    # Decision Variables\n",
+    "    buy = LpVariable.dicts(\"buy\", range(24), lowBound=0)  # The amount of electricity (in kW) bought from the grid at time t\n",
+    "    soc = LpVariable.dicts(\"soc\", range(25), lowBound=0, upBound=E_bat_kWh)  # The State of Charge (in kWh) of the battery at time t\n",
+    "    discharge = LpVariable.dicts(\"discharge\", range(24), lowBound=0, upBound=P_bat_max_discharge_kW)  # Discharge rate (in kW) at time t\n",
+    "    charge = LpVariable.dicts(\"charge\", range(24), lowBound=0, upBound=P_bat_max_charge_kW)  # Charge rate (in kW) at time t\n",
+    "    feedin = LpVariable.dicts(\"feedin\", range(24), lowBound=0)  # The amount of electricity (in kW) sold to the grid at time t\n",
+    "    consumed_pv = LpVariable.dicts(\"consumed_pv\", range(24), lowBound=0)  # The amount of electricity (in kW) consumed directly from PV at time t\n",
+    "\n",
+    "    #  !!! insert new decision variable\n",
+    "    max_pv_feed_in = LpVariable(\"max_pv_feed_in\", lowBound=0)\n",
+    "\n",
+    "    # !!! insert new objective function\n",
+    "    model += max_pv_feed_in, \"Minimize_Max_Feedin\" #lpSum(0)\n",
+    "\n",
+    "    # Constraints\n",
+    "    model += soc[0] == E_bat_kWh/2\n",
+    "    model += soc[23] == E_bat_kWh/2\n",
+    "\n",
+    "    # Energy balance for consumed electricity\n",
+    "    for t in range(24):\n",
+    "        model += el_demand_kW[t] == consumed_pv[t] + buy[t] + discharge[t]\n",
+    "\n",
+    "    # Energy balance for generated electricity\n",
+    "    for t in range(24):\n",
+    "        model += pv_kWp * pv_pu[t] ==  charge[t] + feedin[t] + consumed_pv[t]\n",
+    "\n",
+    "    # State of Charge\n",
+    "    for t in range(23):\n",
+    "        model += soc[t+1] == soc[t] + charge[t] - discharge[t]\n",
+    "\n",
+    "    # !!! insert new constraint\n",
+    "    for t in range(23):\n",
+    "        model += max_pv_feed_in >= feedin[t]\n",
+    "\n",
+    "    # Solve the optimization problem\n",
+    "    model.solve()\n",
+    "\n",
+    "    return model, buy, soc, feedin\n",
+    "\n",
+    "# call optimization function\n",
+    "model, buy, soc, feedin = optimze_battery_operation_PV(el_demand_kW, pv_kWp, pv_pu, E_bat_kWh, P_bat_max_charge_kW, P_bat_max_discharge_kW, c_euro_kWh)\n",
+    "\n",
+    "# read results\n",
+    "feedin_results = []\n",
+    "\n",
+    "for i in range(0,24):\n",
+    "    feedin_results.append(feedin[i].value())\n",
+    "\n",
+    "# max feed-in without battery:\n",
+    "max_feedin_1 = max(pv_kWp * np.array(pv_pu) + np.array(el_demand_kW))\n",
+    "\n",
+    "print(f\"The maximum feed-in without battery operation is {max_feedin_1} kW.\")\n",
+    "\n",
+    "# max feed-in with cost minimizing battery operation:\n",
+    "max_feedin_2 = 0 # !!! <-- insert calculation\n",
+    "max_feedin_2 = max(feedin_cost_minimizing_results)\n",
+    "print(f\"The maximum feed-in with cost minimizing battery operation is {max_feedin_2} kW.\")\n",
+    "\n",
+    "# max feed-in with feed-in minimizing battery operation:\n",
+    "max_feedin_3 = max(feedin_results)#0 # !!! <-- insert calculation\n",
+    "print(f\"The maximum feed-in with feed-in minimizing battery operation is {max_feedin_3} kW.\")\n",
+    "\n",
+    "# !!! insert plots\n",
+    "plt.plot(range(24), pv_kWp * np.array(pv_pu) + np.array(el_demand_kW), label='Without Battery')\n",
+    "plt.plot(range(24), feedin_cost_minimizing_results, label='With Cost Minimizing Battery')\n",
+    "plt.plot(range(24), feedin_results, label='With Feed-in Minimizing Battery')\n",
+    "\n",
+    "plt.xlabel('Time (hours)')\n",
+    "plt.ylabel('Feed-in (kW)')\n",
+    "plt.legend()\n",
+    "\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "01ca0a8e",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "97f4c29d",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/Excercise_1/Quickstart.ipynb b/Excercise_1/Quickstart.ipynb
deleted file mode 100644
index bd022ba..0000000
--- a/Excercise_1/Quickstart.ipynb
+++ /dev/null
@@ -1,293 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "![RWTH Logo](https://www.rwth-aachen.de/global/show_picture.asp?id=aaaaaaaaaaagazb)\n",
-    "\n",
-    "# Jupyter Example Profile Quickstart\n",
-    "\n",
-    "Welcome to JupyterLab!\n",
-    "\n",
-    "* Execute a single cell: <span class=\"fa-play fa\"></span>\n",
-    "* Execute all cells: Menu: Run <span class=\"fa-chevron-right fa\"></span> Run All Cells\n",
-    "* To reboot kernel: <span class=\"fa-refresh fa\"></span>\n",
-    "\n",
-    "Find more in the reference (menu: Help <span class=\"fa-chevron-right fa\"></span> Jupyter Reference)."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "jp-MarkdownHeadingCollapsed": true
-   },
-   "source": [
-    "## Markdown\n",
-    "\n",
-    "ou can specify the cell type which is either _Code_ or _Markdown_. \n",
-    "\n",
-    "### Lists\n",
-    "\n",
-    "* Like\n",
-    "* this\n",
-    "  1. We can even nest them like\n",
-    "  2. this!\n",
-    "* Isn't that wonderfull?\n",
-    "  \n",
-    "### Images \n",
-    "\n",
-    "![Newtons cradle](https://upload.wikimedia.org/wikipedia/commons/thumb/d/d3/Newtons_cradle_animation_book_2.gif/200px-Newtons_cradle_animation_book_2.gif)\n",
-    "\n",
-    "### LaTeX equations\n",
-    "\n",
-    "$$\\mathrm{e}^{\\mathrm{j} x} = \\cos(x)+\\mathrm{j}\\sin(x)$$\n",
-    "\n",
-    "### Code\n",
-    "\n",
-    "``` python\n",
-    "print(\"Hello world!\")\n",
-    "```\n",
-    "\n",
-    "### Further reading\n",
-    "Read more in the reference (menu: Help <span class=\"fa-chevron-right fa\"></span> Markdown Reference)."
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Python"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## numpy\n",
-    "\n",
-    "Execute the cell below to see the contents of variable `a`"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Hello world!\n"
-     ]
-    }
-   ],
-   "source": [
-    "print(\"Hello world!\")"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Plots with matplotlib\n",
-    "\n",
-    "Nice matplotlib [tutorial](https://matplotlib.org/tutorials/introductory/usage.html#sphx-glr-tutorials-introductory-usage-py)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "array([ 0,  1, -5])"
-      ]
-     },
-     "execution_count": 3,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "import numpy as np\n",
-    "\n",
-    "a = np.array([0, 1, -5])\n",
-    "a"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "%matplotlib widget\n",
-    "import matplotlib.pyplot as plt\n",
-    "import rwth_nb.plots.mpl_decorations as rwth_plots\n",
-    "\n",
-    "fs = 44100;\n",
-    "(t, deltat) = np.linspace(-10, 10, 20*fs, retstep=True) # t axis in seconds\n",
-    "\n",
-    "fig,ax = plt.subplots(); ax.grid();\n",
-    "ax.plot(t, np.sin(2*np.pi*t), 'rwth:blue')\n",
-    "ax.set_xlabel(r'$t$'); ax.set_ylabel(r'$s(t) = \\sin(2 \\pi t)$'); "
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Interactive Widgets\n",
-    "\n",
-    "Jupyter Widgets. You can find a detailled widget list [here](https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20List.html).\n",
-    "This requires to install [Jupyter Matplotlib](https://github.com/matplotlib/jupyter-matplotlib) which is called with the `%matplotlib widget` magic.\n",
-    "\n",
-    "Uses Python [decorators](https://docs.python.org/3/glossary.html#term-decorator)."
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import ipywidgets as widgets\n",
-    "\n",
-    "# Create figure\n",
-    "fig0, ax0 = plt.subplots(); \n",
-    "\n",
-    "# Create update function and decorate them with widgets\n",
-    "@widgets.interact(F = widgets.FloatSlider(min=0.1, max=10, step=0.1, value=0, description='$F$:'))\n",
-    "def update_plot(F): \n",
-    "    # Generate signal with given F\n",
-    "    s = np.sin(2*np.pi*F*t)\n",
-    "          \n",
-    "    # Plot\n",
-    "    if not ax0.lines: # decorate axes with labels etc. (which is only needed once)\n",
-    "        ax0.plot(t, s, 'rwth:blue'); \n",
-    "        ax0.set_xlabel(r'$t$'); ax.set_ylabel(r'$s(t)=\\sin(2 \\pi F t)$')\n",
-    "    else: # update only lines and leave everything else as is (gives huge speed-up)\n",
-    "        ax0.lines[0].set_ydata(s)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Audio"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from IPython.display import Audio, Latex\n",
-    "\n",
-    "def audio_play(s, fs, txt=\"\", autoplay=False):\n",
-    "    if txt: display(Latex(txt))\n",
-    "    display(Audio(s, rate=fs, autoplay=autoplay))\n",
-    "\n",
-    "# Create sin\n",
-    "s = np.sin(2*np.pi*440*t)\n",
-    "\n",
-    "# Play back\n",
-    "audio_play(s, fs, r'$s(t)$')"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## RWTH Colors"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# adapted from https://matplotlib.org/2.0.0/examples/color/named_colors.html\n",
-    "\n",
-    "colors = rwth_plots.colors.rwth_colors;\n",
-    "ncols = 5; nrows = len(colors.keys()) // ncols + 1;\n",
-    "    \n",
-    "fig, ax = plt.subplots()\n",
-    "X, Y = fig.get_dpi() * fig.get_size_inches() # Get height and width\n",
-    "w = X / ncols; h = Y / (nrows + 1)\n",
-    "\n",
-    "for i, name in enumerate(colors.keys()):\n",
-    "    col = i % ncols\n",
-    "    row = i // ncols\n",
-    "    y = Y - (row * h) - h\n",
-    "    \n",
-    "    xi_line = w * (col + 0.05); xf_line = w * (col + 0.25); xi_text = w * (col + 0.3)\n",
-    "    ax.text(xi_text, y, name, fontsize=10, horizontalalignment='left', verticalalignment='center')\n",
-    "    ax.hlines(y + h * 0.1, xi_line, xf_line, color=colors[name], linewidth=(h * 0.6))\n",
-    "    \n",
-    "ax.set_xlim(0, X); ax.set_ylim(0, Y); ax.set_axis_off();\n",
-    "fig.subplots_adjust(left=0, right=1, top=1, bottom=0, hspace=0, wspace=0)"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "## Magic\n"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "%%svg\n",
-    "\n",
-    "<svg width='300px' height='300px'>\n",
-    "\n",
-    "<title>Small SVG example</title>\n",
-    "\n",
-    "<circle cx='120' cy='150' r='60' style='fill: gold;'>\n",
-    " <animate attributeName='r' from='2' to='80' begin='0' \n",
-    " dur='3' repeatCount='indefinite' /></circle>\n",
-    "\n",
-    "<polyline points='120 30, 25 150, 290 150' \n",
-    " stroke-width='4' stroke='brown' style='fill: none;' />\n",
-    "\n",
-    "<polygon points='210 100, 210 200, 270 150' \n",
-    " style='fill: lawngreen;' /> \n",
-    "   \n",
-    "<text x='60' y='250' fill='blue'>Hello, World!</text>\n",
-    "\n",
-    "</svg>"
-   ]
-  }
- ],
- "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.18"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/Excercise_1/main.ipynb b/Excercise_1/main.ipynb
deleted file mode 100644
index daab14b..0000000
--- a/Excercise_1/main.ipynb
+++ /dev/null
@@ -1,48 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# main"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import numpy"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "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.18"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/Excercise_2/2023_12_01_DEV_UE2_A2_v1.0_students.ipynb b/Excercise_2/2023_12_01_DEV_UE2_A2_v1.0_students.ipynb
new file mode 100644
index 0000000..790a5d6
--- /dev/null
+++ b/Excercise_2/2023_12_01_DEV_UE2_A2_v1.0_students.ipynb
@@ -0,0 +1,539 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "source": [
+    "# DEV Exercise 2"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%% md\n"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "This Jupyter notebook contains tasks that are calculated for you on the blackboard during the exercise session. To practice using python and to see the advantage of programming when dealing with data, you will reprogram parts of it in this Jupyter notebook. If you have not yet installed the packages required for this exercise, run the following cell to install them."
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [
+    "!pip install pandas\n",
+    "!pip install numpy\n",
+    "!pip install scipy\n",
+    "!pip install openpyxl"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Now run the following cell to import the most important libraries. You can run a cell either by clicking `Run` on the toolbar or by pressing `CTRL+RETURN`."
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "collapsed": true,
+    "pycharm": {
+     "name": "#%%\n"
+    },
+    "ExecuteTime": {
+     "end_time": "2024-01-03T15:01:38.782849Z",
+     "start_time": "2024-01-03T15:01:34.983511400Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "from scipy.optimize import curve_fit"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Predefine functions\n",
+    "It is good programming practice to define functions at the beginning that you want to use again and again in the course of the code. You can find instructions with examples for defining functions under the following [link](https://www.w3schools.com/python/python_functions.asp). In the course of this exercise, you will need to complete functions at this point. "
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%% md\n"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "outputs": [],
+   "source": [
+    "def round_up(x, decimals: int):\n",
+    "    \"\"\"\n",
+    "    Returns the numerical value given in \"value\", rounded up to the given number of decimal places given in \"decimals\". This function is particularly relevant when dealing with measurement uncertainties, as these must always be rounded up.\n",
+    "\n",
+    "    :param x: value to be rounded\n",
+    "    :param decimals: number of decimals\n",
+    "    :return: rounded up value\n",
+    "    \"\"\"\n",
+    "    value = np.ceil(pow(10, decimals)*x) / pow(10, decimals)\n",
+    "\n",
+    "    return value\n",
+    "\n",
+    "def uri(U,I):\n",
+    "    \"\"\"\n",
+    "    Returns the value for the resistance following Ohm's law U=R*I\n",
+    "    :param U: voltage value\n",
+    "    :param I: current value\n",
+    "    :return: resistance value\n",
+    "    \"\"\"\n",
+    "    # Complete the code\n",
+    "    return\n",
+    "\n",
+    "def calc_sig_R(U, I, sig_I):\n",
+    "    \"\"\"\n",
+    "    Returns the value of the uncertainty of the resistance according to Ohm's law and Gaussian error propagation\n",
+    "    :param U: voltage value\n",
+    "    :param I: current value\n",
+    "    :param sig_I: uncertainty of the resistance\n",
+    "    :return: \n",
+    "    \"\"\"\n",
+    "    # Complete the code\n",
+    "    return \n",
+    "\n",
+    "def weighted_mean(x, sig_x):\n",
+    "    \"\"\"\n",
+    "    Returns the weighted mean of variables x and their uncertainties sig_x\n",
+    "    :param x: array with x values\n",
+    "    :param sig_x: array with uncertainty of respective x value\n",
+    "    :return: weighted mean\n",
+    "    \"\"\"\n",
+    "    # Complete the code\n",
+    "\n",
+    "    return \n",
+    "\n",
+    "def sig_weighted_mean(sig_x):\n",
+    "    \"\"\"\n",
+    "    Returns the uncertainty of the weighted mean of variables x and their uncertainties sig_x\n",
+    "    :param sig_x: array with uncertainty of respective x value\n",
+    "    :return: uncertainty of weighted mean\n",
+    "    \"\"\"\n",
+    "    # Complete the code\n",
+    "\n",
+    "    return \n",
+    "\n",
+    "\n",
+    "def ml_estimator(x, y, sig_y):\n",
+    "    \"\"\"\n",
+    "    Returns the parameter m that is determined by using the maximum likelihood method.\n",
+    "    :param x:\n",
+    "    :param y:\n",
+    "    :param sigma:\n",
+    "    :return: m\n",
+    "    \"\"\"\n",
+    "    # Complete the code\n",
+    "\n",
+    "    return \n",
+    "\n",
+    "def chi2_formula(x, y, sig_y, R):\n",
+    "    \"\"\"\n",
+    "    Formula to calculate the Chi^2 value in the case of the relationship y = x/R\n",
+    "    :param x: x values\n",
+    "    :param y: y values\n",
+    "    :param sig_y: uncertainty of y values\n",
+    "    :param m: slope\n",
+    "    :return: \n",
+    "    \"\"\"\n",
+    "    # Complete the code\n",
+    "\n",
+    "    return \n"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%%\n"
+    },
+    "ExecuteTime": {
+     "end_time": "2024-01-03T15:01:44.000874400Z",
+     "start_time": "2024-01-03T15:01:43.987393800Z"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2a\n",
+    "First, the measurement data must be read in from the Excel spreadsheet. The table contains the measured voltages and currents, each with their uncertainties. Use the [pd.read_excel](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_excel.html) function to do this.\n"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "outputs": [
+    {
+     "ename": "ImportError",
+     "evalue": "Missing optional dependency 'openpyxl'.  Use pip or conda to install openpyxl.",
+     "output_type": "error",
+     "traceback": [
+      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
+      "\u001B[1;31mModuleNotFoundError\u001B[0m                       Traceback (most recent call last)",
+      "File \u001B[1;32m~\\Documents\\Tools\\DEV\\.venv\\lib\\site-packages\\pandas\\compat\\_optional.py:142\u001B[0m, in \u001B[0;36mimport_optional_dependency\u001B[1;34m(name, extra, errors, min_version)\u001B[0m\n\u001B[0;32m    141\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m--> 142\u001B[0m     module \u001B[38;5;241m=\u001B[39m \u001B[43mimportlib\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mimport_module\u001B[49m\u001B[43m(\u001B[49m\u001B[43mname\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    143\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mImportError\u001B[39;00m:\n",
+      "File \u001B[1;32m~\\AppData\\Local\\Programs\\Python\\Python38\\lib\\importlib\\__init__.py:127\u001B[0m, in \u001B[0;36mimport_module\u001B[1;34m(name, package)\u001B[0m\n\u001B[0;32m    126\u001B[0m         level \u001B[38;5;241m+\u001B[39m\u001B[38;5;241m=\u001B[39m \u001B[38;5;241m1\u001B[39m\n\u001B[1;32m--> 127\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43m_bootstrap\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_gcd_import\u001B[49m\u001B[43m(\u001B[49m\u001B[43mname\u001B[49m\u001B[43m[\u001B[49m\u001B[43mlevel\u001B[49m\u001B[43m:\u001B[49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mpackage\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mlevel\u001B[49m\u001B[43m)\u001B[49m\n",
+      "File \u001B[1;32m<frozen importlib._bootstrap>:1014\u001B[0m, in \u001B[0;36m_gcd_import\u001B[1;34m(name, package, level)\u001B[0m\n",
+      "File \u001B[1;32m<frozen importlib._bootstrap>:991\u001B[0m, in \u001B[0;36m_find_and_load\u001B[1;34m(name, import_)\u001B[0m\n",
+      "File \u001B[1;32m<frozen importlib._bootstrap>:973\u001B[0m, in \u001B[0;36m_find_and_load_unlocked\u001B[1;34m(name, import_)\u001B[0m\n",
+      "\u001B[1;31mModuleNotFoundError\u001B[0m: No module named 'openpyxl'",
+      "\nDuring handling of the above exception, another exception occurred:\n",
+      "\u001B[1;31mImportError\u001B[0m                               Traceback (most recent call last)",
+      "Cell \u001B[1;32mIn[6], line 3\u001B[0m\n\u001B[0;32m      1\u001B[0m \u001B[38;5;66;03m### First, the data needs to be loaded from the given xlsx-file. Note that all datatypes shall be set to float.\u001B[39;00m\n\u001B[1;32m----> 3\u001B[0m data \u001B[38;5;241m=\u001B[39m \u001B[43mpd\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mread_excel\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mmeasurement_data.xlsx\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mindex_col\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;241;43m0\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mdtype\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43mfloat\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[0;32m      5\u001B[0m \u001B[38;5;66;03m### Define arrays with the corresponding voltage and current values for later use.\u001B[39;00m\n\u001B[0;32m      6\u001B[0m U       \u001B[38;5;241m=\u001B[39m data\u001B[38;5;241m.\u001B[39mloc[:, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvoltage\u001B[39m\u001B[38;5;124m\"\u001B[39m]\n",
+      "File \u001B[1;32m~\\Documents\\Tools\\DEV\\.venv\\lib\\site-packages\\pandas\\io\\excel\\_base.py:478\u001B[0m, in \u001B[0;36mread_excel\u001B[1;34m(io, sheet_name, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skiprows, nrows, na_values, keep_default_na, na_filter, verbose, parse_dates, date_parser, date_format, thousands, decimal, comment, skipfooter, storage_options, dtype_backend)\u001B[0m\n\u001B[0;32m    476\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(io, ExcelFile):\n\u001B[0;32m    477\u001B[0m     should_close \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[1;32m--> 478\u001B[0m     io \u001B[38;5;241m=\u001B[39m \u001B[43mExcelFile\u001B[49m\u001B[43m(\u001B[49m\u001B[43mio\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstorage_options\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mstorage_options\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mengine\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mengine\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    479\u001B[0m \u001B[38;5;28;01melif\u001B[39;00m engine \u001B[38;5;129;01mand\u001B[39;00m engine \u001B[38;5;241m!=\u001B[39m io\u001B[38;5;241m.\u001B[39mengine:\n\u001B[0;32m    480\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\n\u001B[0;32m    481\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mEngine should not be specified when passing \u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m    482\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124man ExcelFile - ExcelFile already has the engine set\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m    483\u001B[0m     )\n",
+      "File \u001B[1;32m~\\Documents\\Tools\\DEV\\.venv\\lib\\site-packages\\pandas\\io\\excel\\_base.py:1513\u001B[0m, in \u001B[0;36mExcelFile.__init__\u001B[1;34m(self, path_or_buffer, engine, storage_options)\u001B[0m\n\u001B[0;32m   1510\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mengine \u001B[38;5;241m=\u001B[39m engine\n\u001B[0;32m   1511\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mstorage_options \u001B[38;5;241m=\u001B[39m storage_options\n\u001B[1;32m-> 1513\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_reader \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_engines\u001B[49m\u001B[43m[\u001B[49m\u001B[43mengine\u001B[49m\u001B[43m]\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_io\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstorage_options\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mstorage_options\u001B[49m\u001B[43m)\u001B[49m\n",
+      "File \u001B[1;32m~\\Documents\\Tools\\DEV\\.venv\\lib\\site-packages\\pandas\\io\\excel\\_openpyxl.py:548\u001B[0m, in \u001B[0;36mOpenpyxlReader.__init__\u001B[1;34m(self, filepath_or_buffer, storage_options)\u001B[0m\n\u001B[0;32m    533\u001B[0m \u001B[38;5;129m@doc\u001B[39m(storage_options\u001B[38;5;241m=\u001B[39m_shared_docs[\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mstorage_options\u001B[39m\u001B[38;5;124m\"\u001B[39m])\n\u001B[0;32m    534\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m__init__\u001B[39m(\n\u001B[0;32m    535\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[0;32m    536\u001B[0m     filepath_or_buffer: FilePath \u001B[38;5;241m|\u001B[39m ReadBuffer[\u001B[38;5;28mbytes\u001B[39m],\n\u001B[0;32m    537\u001B[0m     storage_options: StorageOptions \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[0;32m    538\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m    539\u001B[0m \u001B[38;5;250m    \u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[0;32m    540\u001B[0m \u001B[38;5;124;03m    Reader using openpyxl engine.\u001B[39;00m\n\u001B[0;32m    541\u001B[0m \n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m    546\u001B[0m \u001B[38;5;124;03m    {storage_options}\u001B[39;00m\n\u001B[0;32m    547\u001B[0m \u001B[38;5;124;03m    \"\"\"\u001B[39;00m\n\u001B[1;32m--> 548\u001B[0m     \u001B[43mimport_optional_dependency\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mopenpyxl\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[0;32m    549\u001B[0m     \u001B[38;5;28msuper\u001B[39m()\u001B[38;5;241m.\u001B[39m\u001B[38;5;21m__init__\u001B[39m(filepath_or_buffer, storage_options\u001B[38;5;241m=\u001B[39mstorage_options)\n",
+      "File \u001B[1;32m~\\Documents\\Tools\\DEV\\.venv\\lib\\site-packages\\pandas\\compat\\_optional.py:145\u001B[0m, in \u001B[0;36mimport_optional_dependency\u001B[1;34m(name, extra, errors, min_version)\u001B[0m\n\u001B[0;32m    143\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mImportError\u001B[39;00m:\n\u001B[0;32m    144\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m errors \u001B[38;5;241m==\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mraise\u001B[39m\u001B[38;5;124m\"\u001B[39m:\n\u001B[1;32m--> 145\u001B[0m         \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mImportError\u001B[39;00m(msg)\n\u001B[0;32m    146\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[0;32m    148\u001B[0m \u001B[38;5;66;03m# Handle submodules: if we have submodule, grab parent module from sys.modules\u001B[39;00m\n",
+      "\u001B[1;31mImportError\u001B[0m: Missing optional dependency 'openpyxl'.  Use pip or conda to install openpyxl."
+     ]
+    }
+   ],
+   "source": [
+    "### First, the data needs to be loaded from the given xlsx-file as a pandas dataframe called 'data'. Note that all datatypes shall be set to float.\n",
+    "\n",
+    "data = ...\n",
+    "\n",
+    "### Define arrays with the corresponding voltage and current values for later use.\n",
+    "U       = \n",
+    "sig_U   = \n",
+    "I       = \n",
+    "sig_I   = "
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-01-03T15:02:26.578566600Z",
+     "start_time": "2024-01-03T15:02:26.440889500Z"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2b\n",
+    "After the data has been read in, the resistance and its uncertainty are to be determined for the value pairs. \n",
+    "Add the corresponding code to the functions in the cell above to calculate the resistance with the function <code> def uri(U,I) </code> and the uncertainty with the function def <code> def calc_sig_R(U, I, sig_I) </code>. Why does the function <code> def calc_sig_R(U, I, sig_I) </code> not have the uncertainty of the voltage as an input variable? Note that the propagated uncertainty must always be rounded up."
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "First add the code here to calculate the resistance with the function<code> def uri(U,I) </code> and add them to your pandas dataframe. Round the values to a suitable number of decimal places using the function [round](https://docs.python.org/3/library/functions.html#round)"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "   voltage  voltage_sig  current  current_sig  resistance  resistance_sig\n",
+      "0     10.0          0.0     1.55         0.08        6.45            0.34\n",
+      "1     15.0          0.0     2.19         0.11        6.85            0.35\n",
+      "2     20.0          0.0     3.00         0.15        6.67            0.34\n",
+      "3     25.0          0.0     3.97         0.20        6.30            0.32\n",
+      "4     30.0          0.0     6.18         1.55        4.85            1.22\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Calculate and round the resistance\n",
+    "data.loc[:, \"resistance\"]       = "
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%%\n"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Now calculate the uncertainty, round it and add it to the dataframe. Then print the dataframe to check your results."
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [
+    "# Calculate resistance uncertainty\n",
+    "# Remember that uncertainties shall always be rounded up!\n",
+    "\n",
+    "### Print resulting table in one line\n",
+    "pd.set_option(\"expand_frame_repr\", False)\n",
+    "print(data)"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2e\n",
+    "Now we have several pairs of measured values with different measurement uncertainties. In order to combine the information including the measurement uncertainties, we need to determine a suitable estimated value for the resistance. Calculate an estimation value for the resistance first using the arithmetic mean by using the function [np.mean](https://numpy.org/doc/stable/reference/generated/numpy.mean.html) and secondly using the expression for the weighted mean. The weighted mean is defined by the following formula, which you must add under the function <code> def weighted_mean(x, sig_x) </code>:\n",
+    "\n",
+    "\n",
+    "\n",
+    "$\\left<x\\right>=\\frac{\\sum_{i=1}^N x_i / \\sigma_{i,abs}^2}{\\sum_{i=1}^N 1 / \\sigma_{i,abs}^2}$\n",
+    "\n",
+    "\n",
+    "Also calculate the uncertainty of the calculated mean values, in each case using the function [np.std](https://numpy.org/doc/stable/reference/generated/numpy.std.html) for the arithmetic mean and the function <code> def sig_weighted_mean(sig_x) </code> for the weighted mean. In advance, add the following formula to the function <code> def sig_weighted_mean(sig_x) </code> using [np.sqrt](https://numpy.org/doc/stable/reference/generated/numpy.sqrt.html):\n",
+    "\n",
+    "$\\sigma_{\\left<x\\right>}=\\frac{1}{\\sqrt{\\sum_{i=1}^N 1 / \\sigma_{i,abs}^2}}$\n",
+    "\n",
+    "Remember to round the values to a meaningful number of decimal places using [round](https://docs.python.org/3/library/functions.html#round) and <code> def round_up(x, decimals) </code>. \n",
+    "Compare your results and explain where the differences come from! \n"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%% md\n"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "             weighted  arithmetic\n",
+      "mean             6.52        6.22\n",
+      "uncertainty      0.17        0.72\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Extract the needed data from our dataframe\n",
+    "\n",
+    "n                   = data.shape[0] # number of measurements\n",
+    "R                   = \n",
+    "sig_R               = \n",
+    "\n",
+    "# Calculate the arithmetic mean and its uncertainty and round your results\n",
+    "ar_mean        = \n",
+    "sig_ar_mean    = \n",
+    "\n",
+    "# Calculate the weighted mean and its uncertainty and round your results\n",
+    "w_mean     = \n",
+    "sig_w_mean =\n",
+    "\n",
+    "# Create and print a Dataframe with results\n",
+    "results_2e           = pd.DataFrame(np.array([[ w_mean, ar_mean], [ sig_w_mean, sig_ar_mean ]]), columns=[\"Weighted\", \"Arithmetic\"], index=[\"Mean\", \"Uncertainty\"])\n",
+    "print(results_2e)"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%%\n"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2f\n",
+    "\n",
+    "In the lecture and the first part of this exercise session, we learned about the maximum likelihood method on the one hand and solved the analytical solution of the problem here using the ML method on the other.\n",
+    "According to Ohm's law, $I = U/R = m*U$ with $m=1/R$. This results in a linear relationship between the current and the voltage. Using the ML method, we have calculated that the following equation applies for m:\n",
+    "\n",
+    "$m = \\frac{\\sum_{i=1}^N \\frac{x_i \\cdot y_i}{\\sigma_i^2}}{\\sum_{i=1}^N \\frac{ x_i^2}{\\sigma_i^2}}$\n",
+    "\n",
+    "In this case, $x = U$, $y = I$ and $\\sigma_y = \\sigma_I$. Add the function <code> def ml_estimator(x, y, sig_y) </code> to the function cell and determine both the value for the ML estimator $m$ and then the value for the resistance. Round the value for the resistance to a meaningful number of decimal places and compare the value for the resistance with the previous ones. \n"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%% md\n"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "m = 0.152\n",
+      "\n",
+      "   weighted  arithmetic  ML-method\n",
+      "0      6.52        6.22       6.58\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Extract needed data from dataframe\n",
+    "x           = \n",
+    "y           = \n",
+    "sig_y       = \n",
+    "\n",
+    "# Calculate best estimate for the parameter m\n",
+    "m           = \n",
+    "R_ml        = \n",
+    "print(\"m = \" + str(m) + \", R = \"+str(R_ml))\n",
+    "\n",
+    "# Create and print a Dataframe with results\n",
+    "results_2f  = pd.DataFrame(np.array([[w_mean, ar_mean, R_ml]]), columns=[\"weighted\", \"arithmetic\", \"ML-method\"])\n",
+    "print(results_2f)"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%%\n"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2g\n",
+    "\n",
+    "In practice, the majority of functional relationships can no longer be determined analytically using the ML method. For these cases, the Python package [Scipy](https://scipy.org/) can be used. The [scipy.optimize.curve_fit](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html) function can be used to estimate the parameters of previously defined functional relationships for a specific data set. In the scipy documentation you will find all relevant information and steps for the implementation. \n",
+    "Use the function to fit a linear relationship to the measurement data according to task 2f). Compare the result for the resistance with the previous ones. \n",
+    "\n"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%% md\n"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [
+    "# First, the linear relationship needs to be defined as a function\n",
+    "\n",
+    "    \n",
+    "\n",
+    "# Use curve_fit to solve the problem and print the parameter m with its uncertainty\n",
+    "\n",
+    "\n",
+    "# Calculate the resistance and its uncertainty (Hint: Think about Gaussian Error Propagation!)\n",
+    "\n",
+    "\n",
+    "\n",
+    "# Create and print a Dataframe with results\n",
+    "results_2g  = pd.DataFrame(np.array([[w_mean, ar_mean, R_ml, R_sc]]), columns=[\"weighted\", \"arithmetic\", \"ML-method\", \"Scipy Curve-Fit\"])\n",
+    "print(results_2g)\n"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2h\n",
+    "\n",
+    "The $\\Chi^2$ test, which is defined as follows, is suitable for determining the quality of the fit:\n",
+    "\n",
+    "$\\chi^2 = \\sum_{i=1}^N \\frac{(y_i - f(x_i, m))^2}{\\sigma_i^2}$\n",
+    "\n",
+    "Where $x=U$, $y=I$,  $\\sigma_i = \\sigma_y_i$ and $f(x_i,m) = U_i/R$. Complete the function <code> def chi2_formula(x, y, sig_y, R) </code> and calculate the $\\Chi^2/n_{d.o.f.}$ for the results from tasks 2f and 2g. Explain what the numerical values for $\\Chi^2/n_{d.o.f.}$ mean.\n",
+    "\n"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "outputs": [],
+   "source": [
+    "# Determine n_dof\n",
+    "\n",
+    "n = # Hint: The number of degrees of freedom is the number of measurements minus the number of parameters which were fitted \n",
+    "\n",
+    "# Calculate the Chi^2 and Chi^2/ndof for task 2f\n",
+    "\n",
+    "\n",
+    "# Calculate the Chi^2 and Chi^2/ndof for task 2g\n",
+    "\n",
+    "\n",
+    "# Print the resulting Chi^2/ndof\n",
+    "print(\"Chi^2/ndof (ML-Method) = \" + str(round(chi2_ml_n), 4))\n",
+    "print(\"Chi^2/ndof (Scipy) = \" + str(round(chi2_sc_n), 4))"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%%\n"
+    }
+   }
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 2
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython2",
+   "version": "2.7.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
diff --git a/Excercise_2/main.ipynb b/Excercise_2/main.ipynb
deleted file mode 100644
index d8e9a62..0000000
--- a/Excercise_2/main.ipynb
+++ /dev/null
@@ -1,69 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# main"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import numpy"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [
-    {
-     "ename": "ModuleNotFoundError",
-     "evalue": "No module named 'pandas'",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
-      "\u001b[1;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
-      "Cell \u001b[1;32mIn[2], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpandas\u001b[39;00m\n",
-      "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'pandas'"
-     ]
-    }
-   ],
-   "source": [
-    "import pandas"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "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.18"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/Excercise_2/measurement_data.xlsx b/Excercise_2/measurement_data.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..e94f54b2f1a9ca80fe7a64efee4abe9889a89d2f
GIT binary patch
literal 8737
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
Hc@Pf($E^_<

literal 0
HcmV?d00001

diff --git a/Excercise_3/340px-English-slf(1).png b/Excercise_3/340px-English-slf(1).png
new file mode 100644
index 0000000000000000000000000000000000000000..6431723cc3736d149d90d33dd835198b795b3c41
GIT binary patch
literal 10402
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
UFVtBuFfcH9y85}Sb4q9e019!;jsO4v

literal 0
HcmV?d00001

diff --git a/Excercise_3/Cryptography.ipynb b/Excercise_3/Cryptography.ipynb
new file mode 100644
index 0000000..c575144
--- /dev/null
+++ b/Excercise_3/Cryptography.ipynb
@@ -0,0 +1,483 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "7bdcd773",
+   "metadata": {},
+   "source": [
+    "# Introduction to Cryptography and Letter Frequencies\n",
+    "\n",
+    "**Cryptography** is a field of study focused on secure communication techniques that allow only the sender and intended recipient of a message to view its contents. **Substitution ciphers** are a basic method of encryption where elements of the plaintext (the original message) are replaced systematically to form the ciphertext (the encoded message).\n",
+    "\n",
+    "In this exercise, we'll explore a simple **shift cipher** (also known as a Caesar cipher), where each letter in the plaintext is 'shifted' a certain number of places down the alphabet. We'll also delve into **frequency analysis**, a method to break ciphers by analyzing the frequency of symbols in the encoded message.\n",
+    "\n",
+    "The first objective of this exercise is to implement a simple shift cypher using python. Afterwards, we will try to break the shift cypher, by analyzing the letter frequencies."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "595a8870",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Setting Up the Environment\n",
+    "\n",
+    "import string # might be helpful to look at\n",
+    "from collections import Counter\n",
+    "import random\n",
+    "import matplotlib.pyplot as plt"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ed7799e9",
+   "metadata": {},
+   "source": [
+    "## Implementation of the Cypher\n",
+    "\n",
+    "Let's begin by encoding the message. As described above we aim at a simple shift cypher, which shifts every letter in the message a certain number of letters down the alphabet, looping back to the beginning after the end. For instance, when we apply a shift of 2, the letter 'a' becomes 'c', 'b' becomes 'd', etc. As a result, the word \"at\" transforms into \"cv\". This applies to lower-case letters as well as upper-case. We will ignore special characters like punctuation or white spaces for now."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "caa9910f",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Encoding a Message\n",
+    "\n",
+    "def encode_message(message, key=2):\n",
+    "    \"\"\"\n",
+    "    Encodes a message using a shift cipher.\n",
+    "    \n",
+    "    Parameters:\n",
+    "        message (str): The message to encode.\n",
+    "        key (int): The encryption key (how times the letters are shifted)\n",
+    "    Returns:\n",
+    "        str: The encoded message.\n",
+    "    \"\"\"\n",
+    "    # Put your own code here\n",
+    "    \n",
+    "    return\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7efd44c6-484b-47ee-9472-6b3a36ae9fc4",
+   "metadata": {},
+   "source": [
+    "### Testing the cypher\n",
+    "Now let us quickly test you encryption. Try out some strings and some keys. You can use a single letter at a time. Think about special keys: What should happen if you use 0? or 26? Does it work as expected?\n",
+    "\n",
+    "The `assert` statement can help you here design some easy tests, like this:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "45f1c38b-3650-4209-a288-dd5dbc004b94",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "If no error occured: everything worked as expected!\n"
+     ]
+    }
+   ],
+   "source": [
+    "assert encode_message(\"a\", 0) == \"a\"\n",
+    "\n",
+    "# Add some more tests to check if your encryption works\n",
+    "\n",
+    "print(\"If no error occured: everything worked as expected!\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "df31d050",
+   "metadata": {},
+   "source": [
+    "## Decyphering\n",
+    "Since the purpose of encryption is to deliver the information to another place or a later time, we need a way to get our original message back as long as we know the encryption key. Next, implement the decryption function. In our case, it should be somewhat similar to the encryption from before. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "id": "91d2ec6b",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Decoding a Message\n",
+    "\n",
+    "def decode_message(encoded_message, key):\n",
+    "    \"\"\"\n",
+    "    Decodes a message encoded with a shift cipher.\n",
+    "    \n",
+    "    Parameters:\n",
+    "        encoded_message (str): The encoded message.\n",
+    "        shift (int): The number of places each character was shifted.\n",
+    "        \n",
+    "    Returns:\n",
+    "        str: The decoded (original) message.\n",
+    "    \"\"\"\n",
+    "    # Put your own code here \n",
+    "    \n",
+    "    return "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1974d1d-703c-4e7e-8636-4047efdc9a91",
+   "metadata": {},
+   "source": [
+    "### Testing the decypher\n",
+    "As before we can test our decoding algorithm by many statements. However, since we have two functions know, this might help us. Can you figure out how?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "b63b9859-0b69-447a-a39e-b5ca555d0348",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "If no error occured: everything worked as expected!\n"
+     ]
+    }
+   ],
+   "source": [
+    "assert decode_message(\"a\", 0) == \"a\"\n",
+    "\n",
+    "# Add some more tests to check if your encryption works\n",
+    "\n",
+    "print(\"If no error occured: everything worked as expected!\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "261c284d",
+   "metadata": {},
+   "source": [
+    "## Breaking a cypher\n",
+    "### Brute Force\n",
+    "As you might have noticed already this is not a particularly strong cypher algorithm. Since we only have 25 usable keys, a simple \"brute force\" approch can yield a result. This could even be done by hand, and certainly with computers. That's why it is important for modern encryption algorithms to have a huge number of possible key. AES for examples uses between 128 and 256 bit keys, making the respective numbers of keys 2^128 - 2^256.\n",
+    "\n",
+    "The following code produces a cypher text with a random key. See if you can figure out the key using brute force."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "id": "cabfa50c-5366-4728-af0a-18791b558fac",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Key: 1: Zkxtm! Rhn yhngw max vhkkxvm dxr.\n",
+      "Key: 2: Yjwsl! Qgm xgmfv lzw ugjjwul cwq.\n",
+      "Key: 3: Xivrk! Pfl wfleu kyv tfiivtk bvp.\n",
+      "Key: 4: Whuqj! Oek vekdt jxu sehhusj auo.\n",
+      "Key: 5: Vgtpi! Ndj udjcs iwt rdggtri ztn.\n",
+      "Key: 6: Ufsoh! Mci tcibr hvs qcffsqh ysm.\n",
+      "Key: 7: Terng! Lbh sbhaq gur pbeerpg xrl.\n",
+      "Key: 8: Sdqmf! Kag ragzp ftq oaddqof wqk.\n",
+      "Key: 9: Rcple! Jzf qzfyo esp nzccpne vpj.\n",
+      "Key: 10: Qbokd! Iye pyexn dro mybbomd uoi.\n",
+      "Key: 11: Panjc! Hxd oxdwm cqn lxaanlc tnh.\n",
+      "Key: 12: Ozmib! Gwc nwcvl bpm kwzzmkb smg.\n",
+      "Key: 13: Nylha! Fvb mvbuk aol jvyylja rlf.\n",
+      "Key: 14: Mxkgz! Eua luatj znk iuxxkiz qke.\n",
+      "Key: 15: Lwjfy! Dtz ktzsi ymj htwwjhy pjd.\n",
+      "Key: 16: Kviex! Csy jsyrh xli gsvvigx oic.\n",
+      "Key: 17: Juhdw! Brx irxqg wkh fruuhfw nhb.\n",
+      "Key: 18: Itgcv! Aqw hqwpf vjg eqttgev mga.\n",
+      "Key: 19: Hsfbu! Zpv gpvoe uif dpssfdu lfz.\n",
+      "Key: 20: Great! You found the correct key.\n",
+      "Key: 21: Fqdzs! Xnt entmc sgd bnqqdbs jdx.\n",
+      "Key: 22: Epcyr! Wms dmslb rfc amppcar icw.\n",
+      "Key: 23: Dobxq! Vlr clrka qeb zloobzq hbv.\n",
+      "Key: 24: Cnawp! Ukq bkqjz pda yknnayp gau.\n",
+      "Key: 25: Bmzvo! Tjp ajpiy ocz xjmmzxo fzt.\n"
+     ]
+    }
+   ],
+   "source": [
+    "message = \"Great! You found the correct key.\"\n",
+    "key = random.randint(1, 25)\n",
+    "cypher_message = encode_message(message, key)\n",
+    "\n",
+    "# Your code goes here\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "3ad2956c-aba5-4d92-93bd-1080d5064f10",
+   "metadata": {},
+   "source": [
+    "### Frequency analysis\n",
+    "A more intelligent aproach to breaking a cyper is called frequency analysis and uses statistics to find the correct key. The concept is based on the fact, that in structued data such as text, certain statical effect emerge. For example: in the English language certain letters, like 'e', 't' or 'a' are used much more often than others, like 'x' or 'j'.\n",
+    "\n",
+    "The letter frequencies for the English language can be found here: https://www3.nd.edu/~busiforc/handouts/cryptography/letterfrequencies.html\n",
+    "\n",
+    "In order to visualize these frequencies for a given text we need to count their occurences. Write a function, that counts all letters in a text. It should return a dict containing all letters (lower-case) in alphabetical order as keys and their respective amounts as values. Ignore special characters and white space for now. The second function should then be able to visualize the frequencies in a histogram."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "8d4767f6",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def count_letters(text):\n",
+    "    \"\"\"\n",
+    "    Counts the occurence of each letter in a string.\n",
+    "    \n",
+    "    Parameters:\n",
+    "        text (str): Text, of which the letters should be counted.\n",
+    "    Returns:\n",
+    "        dict[str, int]: A dictionary with letters in alphabetical order as keys and their amounts as values.\n",
+    "    \"\"\"\n",
+    "    # Your code goes here\n",
+    "    \n",
+    "    return\n",
+    "\n",
+    "def plot_frequencies(letter_frequencies):\n",
+    "    \"\"\"\n",
+    "    Plots a histogram of letter frequencies\n",
+    "    \n",
+    "    Parameters:\n",
+    "        letter_frequencies (dict[str, int]): A dictionary with letters as keys and their amounts as values.\n",
+    "    Returns:\n",
+    "        None\n",
+    "    \"\"\"\n",
+    "    # Create a bar plot\n",
+    "    plt.figure(figsize=(8, 6))\n",
+    "    plt.bar(letter_frequencies.keys(), letter_frequencies.values())\n",
+    "\n",
+    "    # Customize the plot\n",
+    "    plt.xlabel(\"Letters\")\n",
+    "    plt.ylabel(\"Frequency\")\n",
+    "    plt.title(\"Letter Distribution in Text (Ascending Order)\")\n",
+    "    plt.xticks(rotation=45)  # Rotate x-axis labels for better readability\n",
+    "\n",
+    "    # Show the plot\n",
+    "    plt.show()\n",
+    "    return\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a1fcf1a0",
+   "metadata": {},
+   "source": [
+    "### Using the frequency analysis\n",
+    "\n",
+    "You just built all the tools you need to systematically break a Caesar cypher. The text document `shakethatpear.txt` holds some example text. Load this as a string and compare the distribution to the normal English distribution shown below."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "id": "f8168f9a",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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rpxFRETc8nq6d+9uib2c7N+/3yRZUFCQnTp1KtF1199XHTt2NEnWs2dP97K4uDiLiIiwDBky2OnTp83MbNWqVSbJVq1a9bc1b9ab2bX7c9iwYe7zzZs3twwZMtjevXvdy44dO2ZZs2a1Bx980L0sfp8JDw+3uLg49/K+ffta+vTp7dy5c4leX7xhw4Yl6EmSZciQwfbs2eNetnXrVpNkb7/99i3rXe+zzz7zuG/++usvCwkJsa5du3psd+LECQsODvZYHh0dbUWLFrXSpUvbpUuXLCIiwoKCguzgwYMelw0MDPTYR25l+fLlJsm+/vrrRNf36NHDChQo4L4fly5dapJsy5YtHtsFBwdb9+7db3o9V69etcKFC1uhQoXszz//9Fh3/WPUoEEDK1u2rF26dMljfY0aNaxYsWLuZbf7GJ86dcoyZMhgERERHtu9+OKLJsnjfkpsv61Tp45JstmzZ7uXxcTEWGhoqLVo0cK97I033jBJtmDBAveyixcvWokSJRJ9Llzv3LlzJsmaNWt2023MzB599FGTZFFRUWb2v/20TZs2Htsl5TaPGjXKAgMD7ffff/eoMWjQIEufPr0dOnTIzG79WhFv7ty5JsnWr19/y9sBMC0B+Btmpi+++EKPPPKIzEx//PGH+9S4cWNFRkYm+NdoUnz22WcqWbKkSpQo4VG7fv36kpRgZKZOnToqVapUsm5TvPjR47/++uum24SEhGjHjh3avXu319fTokWLBP8KvZUePXq4/44fLb98+bKWL1/udQ9/JzY2VkuXLlXz5s095hzmyZNHbdu21Zo1axQVFeVxmW7dunn8q7127dqKjY31+nBX4eHhHqOg999/v4KCgrRv3z6v6knXRjPPnTunNm3aeOxf6dOnV7Vq1Tz2r8yZM2vmzJnatWuXHnzwQS1cuFBvvfWWChYs6PX1nzlzRpKULVu2BOuuXr2qTz75RE8++aT7fqxfv75y5cqlOXPmeGwbEhKi9evX69ixY4lez5YtW7R//3716dNHISEhHuvia589e1YrV65Uq1at9Ndff7nvizNnzqhx48bavXu3jh496nHZv3uMly9frsuXL6tnz54e2/Xp0+c27p1rsmTJ4jEvPkOGDKpatarH47548WLly5dPjz76qHtZxowZ1bVr17+tH//8zpo16y23i19/434eP2ofLym3+bPPPlPt2rWVLVs2j/0vPDxcsbGx+u677zy2v9VrRfw+9Mcff9zydgBMSwD+xunTp3Xu3Dm9++67evfddxPd5tSpU17X3717t3bt2nXTF/QbaxcuXNjr67pR/FEJbvWmN3LkSDVr1kzFixdXmTJl9NBDD6l9+/ZJ+uZ9UnpOly5dgi+0FC9eXJLu6JEmTp8+rQsXLui+++5LsK5kyZKKi4vT4cOHVbp0affyG0Nf/Jvvn3/+6VUPiYXIbNmyeV1PkvtDSfyHpRvd+O/dmjVr6l//+pcmT56sxo0b6+mnn/b6uq9niRytYunSpTp9+rSqVq2qPXv2uJfXq1dPH330kcaNG+c+qsCrr76qjh07qkCBAqpUqZKaNGmiDh06uPeVvXv3SpLKlClz0x727NkjM9OQIUM0ZMiQRLc5deqU8uXL5z7/d49xfMgtVqyYx3Y5c+ZMNNAnJn/+/AnmI2fLlk3btm1znz948KCKFCmSYLuiRYv+bf345/etPsRev/7G14Mbn79Juc27d+/Wtm3bfPL6Fr8P/dOOEY2kI9wCfyN+buhTTz2ljh07JrpNcg6xFBcXp7Jly+rNN99MdH2BAgU8zmfKlMnr67pR/EHRb/UG+eCDD2rv3r368ssvtXTpUv3nP//RW2+9palTp+qZZ565revxZc/Szd/cYmNjfXo9fyf+EGY3SizIpUQ96X/77wcffKDQ0NAE6288akNMTIz7y0l79+7VhQsXlDlzZq+vP36ucGIBPX50tlWrVoledvXq1apXr557m9q1a2v+/PlaunSpXnvtNY0bN07z5s1zz0v9O/H3Rf/+/dW4ceNEt7nxuXAnHpMb3enrCA4OVp48eTzCcmK2bdumfPnyJfjAk5znb1xcnBo2bKgXXngh0fXxH1xv57ri96F77rnH637wz0C4Bf5Gzpw5lTVrVsXGxio8PPyW295qROFm64oUKaKtW7eqQYMGd3VEIjY2VnPnzlXmzJnd34C+mezZs6tz587q3Lmzzp8/rwcffFDDhw93h1tf9h0XF6d9+/Z5vOn9/vvvkuT+8lz86NC5c+c8LpvYdIDb7S1nzpzKnDmzfvvttwTrfv31V6VLly7BB420IH6aQ65cuf52/5WkYcOGadeuXXr99dc1cOBADRo0SBMnTvTYJimPd4kSJSRJ+/fv91geHR2tL7/8Uk8++aRatmyZ4HK9evXSnDlz3OFWujZF5Pnnn9fzzz+vU6dOqWLFinrllVf08MMPu2/n9u3bb3o740d5/f39b+u+uB3xP0qxe/duj/84nD59Olkj7oldz86dO2VmHvf/9SPet9K0aVO99957WrNmTaLP9++//14HDhzQs88+e1u9SLd3m4sUKaLz58/75P7ev3+/0qVLlyAQAzdizi3wN9KnT68WLVroiy++SPTnH68/LFD88R9vDF3x664/5Fa8Vq1a6ejRo3rvvfcSrLt48aKio6OT0X3iYmNj1atXL+3atUu9evW65TeP4+dMxsuSJYuKFi3qcZiyW91ub0yaNMn9t5lp0qRJ8vf3V4MGDSRde3NNnz59gvl677zzToJat9tb+vTp1ahRI3355Zce0x9OnjypuXPnqlatWmnyG9qNGzdWUFCQRo8erStXriRYf/3+u379er3++uvq06eP/v3vf2vAgAGaNGmSVq9e7XGZwMDA236s8+XLpwIFCiT4BcD58+crOjpa3bt3V8uWLROcmjZtqi+++EIxMTGKjY1N8NzJlSuX8ubN694PK1asqMKFC2v8+PEJeosfAc2VK5fq1q2radOm6fjx47e8L25XeHi4/P399fbbb3uMtPr61wgbN26so0ePehyy7NKlS4m+biRmwIABypQpk5599tkEz+mzZ8/queeeU+bMmTVgwIC/rZWU29yqVSutXbtWS5YsSbDu3Llzunr16m31L0mbNm1S6dKlFRwcfNuXwT8TI7fA/zd9+vREjynau3dvjR07VqtWrVK1atXUtWtXlSpVSmfPntXmzZu1fPlynT17VtK1UYqQkBBNnTpVWbNmVWBgoKpVq6bChQurUqVK+uSTT9SvXz9VqVJFWbJk0SOPPKL27dvr008/1XPPPadVq1apZs2aio2N1a+//qpPP/1US5YsSdYvp0VGRurDDz+UdO2wPPG/ULZ37161bt1ao0aNuuXlS5Uqpbp166pSpUrKnj27Nm7c6D4kU7xKlSpJujba1rhxY6VPn16tW7f2qt+MGTNq8eLF6tixo6pVq6ZFixZp4cKFevHFF93z9oKDg/XEE0/o7bfflsvlUpEiRfTNN98kOvc5Kb29/PLLWrZsmWrVqqXnn39efn5+mjZtmmJiYhI97mhaEBQUpClTpqh9+/aqWLGiWrdurZw5c+rQoUNauHChatasqUmTJunSpUvq2LGjihUrpldeeUWSNGLECH399dfq3LmzfvnlF/cHhUqVKmn58uV68803lTdvXhUuXDjBYdKu16xZM82fP99j1HHOnDnKkSOHatSokehlHn30Ub333ntauHCh6tevr/z586tly5YqV66csmTJouXLl2vDhg164403JF2bqz1lyhQ98sgjKl++vDp37qw8efLo119/1Y4dO9zhavLkyapVq5bKli2rrl276t5779XJkye1du1aHTlyRFu3bk3S/ZszZ071799fY8aMUdOmTdWkSRNt2bJFixYt8um/z5999llNmjRJbdq0Ue/evZUnTx7NmTPH/aMQfzeaXqxYMc2aNUvt2rVT2bJlE/xC2R9//KGPPvrotn79Kym3ecCAAfrqq6/UtGlTderUSZUqVVJ0dLR++eUXff755zpw4MBt3U9XrlzR6tWr9fzzz//ttgCHAsM/Xvwhf252Onz4sJmZnTx50rp3724FChQwf39/Cw0NtQYNGti7777rUe/LL7+0UqVKmZ+fn8dhqc6fP29t27a1kJAQk+RxWLDLly/buHHjrHTp0hYQEGDZsmWzSpUq2YgRIywyMtK9naRbHg7pRvGHGYo/ZcmSxYoVK2ZPPfWULV26NNHL3HgosJdfftmqVq1qISEhlilTJitRooS98sordvnyZfc2V69etZ49e1rOnDnN5XK5D3MVf3if1157LcH13OxQYIGBgbZ3715r1KiRZc6c2XLnzm3Dhg2z2NhYj8ufPn3aWrRoYZkzZ7Zs2bLZs88+a9u3b09Q82a9xd+f1x8KzMxs8+bN1rhxY8uSJYtlzpzZ6tWrZz/++KPHNjc7fNzNDlF2o5sdCiyxx/bGx+Pv3HgosOt7a9y4sQUHB1vGjBmtSJEi1qlTJ9u4caOZ/e8QVzceZmnjxo3m5+dn//rXv9zLfv31V3vwwQctU6ZMCQ79lJjNmzebJPfh7k6ePGl+fn7Wvn37m17mwoULljlzZnvssccsJibGBgwYYOXKlbOsWbNaYGCglStXzt55550El1uzZo01bNjQvd3999+f4FBqe/futQ4dOlhoaKj5+/tbvnz5rGnTpvb555+7t0nKYxwbG2sjRoywPHnyWKZMmaxu3bq2ffv2BI/dzQ4Fltjh+jp27Jjg0IH79u2ziIgIy5Qpk+XMmdP+/e9/2xdffGGSbN26dTe9L6+3bds2a9OmjeXJk8f9OtamTRv75ZdfEmwbv5/GH4Lverd7m82uHY5u8ODBVrRoUcuQIYPdc889VqNGDXv99dfdryO3eq0wM1u0aJFJst27d9/W7cQ/m8vMh7PiAQBIRIMGDZQ3b97b+jEN3L7x48erb9++OnLkiMdRHpymefPmcrlcmj9/fkq3gjSAcAsAuOPWr1+v2rVra/fu3e4vJCFpLl686HE0gUuXLqlChQqKjY11f+nSiXbt2qWyZcvq559/vuWh3oB4hFsAANKAhx9+WAULFlT58uXdc+l37NihOXPmqG3btindHpBq8IUyAADSgMaNG+s///mP5syZo9jYWJUqVUoff/yxnnzyyZRuDUhVGLkFAACAY3CcWwAAADgG4RYAAACOwZxbXfu5z2PHjilr1qx39edPAQAAcHvMTH/99Zfy5s2rdOluPj5LuJV07NixNPmb8QAAAP80hw8fVv78+W+6nnArKWvWrJKu3Vlp8bfjAQAAnC4qKkoFChRw57abIdzqf7/JHRQURLgFAABIxf5uCilfKAMAAIBjEG4BAADgGCkabr/77js98sgjyps3r1wulxYsWHDTbZ977jm5XC6NHz/eY/nZs2fVrl07BQUFKSQkRF26dNH58+fvbOMAAABIlVI03EZHR6tcuXKaPHnyLbebP3++1q1bp7x58yZY165dO+3YsUPLli3TN998o++++07dunW7Uy0DAAAgFUvRL5Q9/PDDevjhh2+5zdGjR9WzZ08tWbJEERERHut27dqlxYsXa8OGDapcubIk6e2331aTJk30+uuvJxqGAQAA4Fypes5tXFyc2rdvrwEDBqh06dIJ1q9du1YhISHuYCtJ4eHhSpcundavX3/TujExMYqKivI4AQAAIO1L1eF23Lhx8vPzU69evRJdf+LECeXKlctjmZ+fn7Jnz64TJ07ctO6YMWMUHBzsPvEDDgAAAM6QasPtpk2bNGHCBM2cOdPnP4k7ePBgRUZGuk+HDx/2aX0AAACkjFQbbr///nudOnVKBQsWlJ+fn/z8/HTw4EH9+9//VlhYmCQpNDRUp06d8rjc1atXdfbsWYWGht60dkBAgPsHG/jhBgAAAOdItb9Q1r59e4WHh3ssa9y4sdq3b6/OnTtLkqpXr65z585p06ZNqlSpkiRp5cqViouLU7Vq1e56zwAAAEhZKRpuz58/rz17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4BiEWwAAADgG4RYAAACOQbgFAACAYxBuAQAA4BiEWwAAADiGV+F23759vu4DAAAASDavwm3RokVVr149ffjhh7p06ZKve3KLjY3VkCFDVLhwYWXKlElFihTRqFGjZGbubcxMQ4cOVZ48eZQpUyaFh4dr9+7dd6wnAAAApF5e/YjD5s2bNWPGDPXr1089evTQk08+qS5duqhq1ao+bW7cuHGaMmWKZs2apdKlS2vjxo3q3LmzgoOD1atXL0nSq6++qokTJ2rWrFkqXLiwhgwZosaNG2vnzp3KmDGjT/sBAOBu8MUP/Uj82A/+mbwauS1fvrwmTJigY8eOafr06Tp+/Lhq1aqlMmXK6M0339Tp06d90tyPP/6oZs2aKSIiQmFhYWrZsqUaNWqkn376SdK1Udvx48fr//7v/9SsWTPdf//9mj17to4dO6YFCxb4pAcAAACkHcn6Qpmfn58ef/xxffbZZxo3bpz27Nmj/v37q0CBAurQoYOOHz+erOZq1KihFStW6Pfff5ckbd26VWvWrNHDDz8sSdq/f79OnDih8PBw92WCg4NVrVo1rV279qZ1Y2JiFBUV5XECAABA2pescLtx40Y9//zzypMnj9588031799fe/fu1bJly3Ts2DE1a9YsWc0NGjRIrVu3VokSJeTv768KFSqoT58+ateunSTpxIkTkqTcuXN7XC537tzudYkZM2aMgoOD3acCBQokq08AAACkDl7NuX3zzTc1Y8YM/fbbb2rSpIlmz56tJk2aKF26a1m5cOHCmjlzpsLCwpLV3Keffqo5c+Zo7ty5Kl26tH7++Wf16dNHefPmVceOHb2uO3jwYPXr1899PioqioALAADgAF6F2ylTpujpp59Wp06dlCdPnkS3yZUrl95///1kNTdgwAD36K0klS1bVgcPHtSYMWPUsWNHhYaGSpJOnjzp0cfJkydVvnz5m9YNCAhQQEBAsnoDAABA6uNVuL2dQ21lyJAhWaOrknThwgX3aHC89OnTKy4uTtK1EeLQ0FCtWLHCHWajoqK0fv16/etf/0rWdQMAACDt8SrczpgxQ1myZNETTzzhsfyzzz7ThQsXkh1q4z3yyCN65ZVXVLBgQZUuXVpbtmzRm2++qaefflqS5HK51KdPH7388ssqVqyY+1BgefPmVfPmzX3SAwAAANIOr75QNmbMGN1zzz0JlufKlUujR49OdlPx3n77bbVs2VLPP/+8SpYsqf79++vZZ5/VqFGj3Nu88MIL6tmzp7p166YqVaro/PnzWrx4Mce4BQAA+AfyauT20KFDKly4cILlhQoV0qFDh5LdVLysWbNq/PjxGj9+/E23cblcGjlypEaOHOmz6wUAAEDa5NXIba5cubRt27YEy7du3aocOXIkuykAAADAG16F2zZt2qhXr15atWqVYmNjFRsbq5UrV6p3797uIxsAAAAAd5tX0xJGjRqlAwcOqEGDBvLzu1YiLi5OHTp08OmcWwAAACApvAq3GTJk0CeffKJRo0Zp69atypQpk8qWLatChQr5uj8AAADgtnkVbuMVL15cxYsX91UvAAAAQLJ4FW5jY2M1c+ZMrVixQqdOnXL/qEK8lStX+qQ5AAAAICm8Cre9e/fWzJkzFRERoTJlysjlcvm6LwDJFDZoYbJrHBgb4YNOAAC4e7wKtx9//LE+/fRTNWnSxNf9AAAAAF7z6lBgGTJkUNGiRX3dCwAAAJAsXoXbf//735owYYLMzNf9AAAAAF7zalrCmjVrtGrVKi1atEilS5eWv7+/x/p58+b5pDkAAAAgKbwKtyEhIXrsscd83QsAAACQLF6F2xkzZvi6DwAAACDZvJpzK0lXr17V8uXLNW3aNP3111+SpGPHjun8+fM+aw4AAABICq9Gbg8ePKiHHnpIhw4dUkxMjBo2bKisWbNq3LhxiomJ0dSpU33dJwAAAPC3vBq57d27typXrqw///xTmTJlci9/7LHHtGLFCp81BwAAACSFVyO333//vX788UdlyJDBY3lYWJiOHj3qk8YAAACApPJq5DYuLk6xsbEJlh85ckRZs2ZNdlMAAACAN7wKt40aNdL48ePd510ul86fP69hw4bxk7wAAABIMV5NS3jjjTfUuHFjlSpVSpcuXVLbtm21e/du3XPPPfroo4983SMAAABwW7wKt/nz59fWrVv18ccfa9u2bTp//ry6dOmidu3aeXzBDAAAALibvAq3kuTn56ennnrKl70AAAAAyeJVuJ09e/Yt13fo0MGrZgAAAIDk8Crc9u7d2+P8lStXdOHCBWXIkEGZM2cm3AIAACBFeHW0hD///NPjdP78ef3222+qVasWXygDAABAivEq3CamWLFiGjt2bIJRXQAAAOBu8Vm4la59yezYsWO+LAkAAADcNq/m3H711Vce581Mx48f16RJk1SzZk2fNAYAAAAklVfhtnnz5h7nXS6XcubMqfr16+uNN97wRV8AAABAknkVbuPi4nzdBwAAAJBsPp1zCwAAAKQkr0Zu+/Xrd9vbvvnmm95cBQAAAJBkXoXbLVu2aMuWLbpy5Yruu+8+SdLvv/+u9OnTq2LFiu7tXC6Xb7oEACAVChu00Cd1DoyN8EkdAF6G20ceeURZs2bVrFmzlC1bNknXftihc+fOql27tv7973/7tEkAAADgdng15/aNN97QmDFj3MFWkrJly6aXX36ZoyUAAAAgxXgVbqOionT69OkEy0+fPq2//vor2U0BAAAA3vAq3D722GPq3Lmz5s2bpyNHjujIkSP64osv1KVLFz3++OO+7hEAAAC4LV7NuZ06dar69++vtm3b6sqVK9cK+fmpS5cueu2113zaIAAAAHC7vAq3mTNn1jvvvKPXXntNe/fulSQVKVJEgYGBPm0OAAAASIpk/YjD8ePHdfz4cRUrVkyBgYEyM1/1BQAAACSZV+H2zJkzatCggYoXL64mTZro+PHjkqQuXbpwGDAAAACkGK/Cbd++feXv769Dhw4pc+bM7uVPPvmkFi9e7LPmAAAAgKTwas7t0qVLtWTJEuXPn99jebFixXTw4EGfNAYA8A1f/IoWv6AFIK3wauQ2OjraY8Q23tmzZxUQEJDspgAAAABveBVua9eurdmzZ7vPu1wuxcXF6dVXX1W9evV81hwAAACQFF5NS3j11VfVoEEDbdy4UZcvX9YLL7ygHTt26OzZs/rhhx983SMAAABwW7wauS1Tpox+//131apVS82aNVN0dLQef/xxbdmyRUWKFPF1jwAAAMBtSfLI7ZUrV/TQQw9p6tSpeumll+5ETwAAAIBXkjxy6+/vr23btt2JXgAAAIBk8WpawlNPPaX333/f170AAAAAyeLVF8quXr2q6dOna/ny5apUqZICAwM91r/55ps+aQ4AAABIiiSF23379iksLEzbt29XxYoVJUm///67xzYul8t33QEAAABJkKRwW6xYMR0/flyrVq2SdO3ndidOnKjcuXPfkeYAAACApEjSnFsz8zi/aNEiRUdH+7QhAAAAwFtefaEs3o1h9044evSonnrqKeXIkUOZMmVS2bJltXHjRo8ehg4dqjx58ihTpkwKDw/X7t2773hfAAAA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Je/DX2RkpOrWratVq1b5qj1JUkxMjD7//HOtXr3ap3U//vhjPfTQQ9q5c6cOHTrk09p3jSHVmD9/voWFhVnJkiUtU6ZM9vTTT9uxY8eSXGfhwoX2888/u89/8cUXVq1aNStSpIg1b97c3n///WT3+ttvv1nhwoXtnXfeSXateHFxcWZm9sknn1irVq2sevXqljlzZitatKgtXLgw2fU///xzCw4OttatW1uNGjWscuXK1q1bN69qXbhwwerXr2/PPPOMlSpVytq1a+ded/Xq1WT32r9/f2vRooXVqFHDsmfPbvfdd59X98GN+8K8efOsZs2aVrx4cRs+fLht3rw52b1GRkZauXLlrF27drZjx45k17vRzJkz7cEHH7SOHTvaxYsXvaqxcOFC27p1q5n9bz974okn7I033vBZn5s3b7aKFSvaM888Y9u3b/dZ3Xjz58+3LFmyWNGiRS0gIMCmTZtmUVFRya7p6/3hs88+sxw5clj58uUtXbp0Vr16dfvss8+SXXfgwIFWokQJu+eee6xOnTo+e+3p37+/PfbYY1alShULCQnx+rl2vd27d9vQoUNt8ODBZva/fS65vvnmG8uUKZO99957Xr033OjPP/+0atWqmcvlsn/961/u5bGxscmuHW/69OmWL18+69Wrl+3cudNndc3Mdu3aZYGBgTZz5kyf1bxw4YL77wcffNDq1KmT7JqXLl2yypUr24wZM5JdK178PrVx40YLCgqyL7/80id1P/vsM3O5XDZ//nxr27atDRs2zMx88752NxFuU4klS5ZYSEiITZs2zWJiYmzRokXmcrmsdevWdvjw4duuc+LECStcuLB17tzZ9u7dazt27LCsWbPayy+/bGPHjrXnn3/eMmTIYKNHj05Wv8uWLbPixYvbgQMH3Mt88QK+bt06y5w5s73//vv266+/2u7du61u3bpWvXp1++9//+t13Z07d1rBggVt6tSp7vOZMmVyv/l4Izo62szM3n//fbvvvvt8FnBnzJhhISEhtmnTJjt79qwdP37cGjVqZNWrV7dFixbddp3r94U9e/bYrl27LCQkxEaNGmW9e/e2ihUrWosWLez777/3utd4GzZssKpVq/o02F2/P82YMcPrgHv9/XB9+K5du7a9+eabPuk13p0IuHFxcXbmzBmrWbOmTZs2zXbv3m2jR482l8tlo0ePtnPnznlVd9OmTRYcHGwjR4702f6wefNmu+eee+w///mPnT171k6cOGEdO3a0Bx980ObNm+d13Y8++shCQ0NtwYIFNnPmTBswYID5+/vbmDFjvK5pZjZr1izLli2bbdq0yf744w87evSoNWzY0B544IEkPdeuFxkZaZUrV7acOXNa37593cuT+/p48eJFe+KJJ+zFF180s2uvP3v37rVXXnnF5s+f79UHncuXL1v9+vWtfPny1rBhQ/vwww/d63wZcGfNmmX33Xefde/e3WcBN76/Pn36WIsWLezMmTPJrrl48WJ76qmnbMmSJWZmdvDgQStatKiNHDnSq3rXv1Z16tTJ/R4RFxfns/s3MjLSWrVqZb179zaz5D1u8+bNM5fLZdOnTzczs6ZNm7o/9PjqA9rdQrhNBSIjI61bt242YsQIMzPbt2+fFSlSxFq2bGkhISHWrFkzO3jw4G3X27Rpk1WuXNm6d+9uL730kvXv39/juiZNmmQZM2a02bNne93z/PnzrUCBAu5we/0T6ttvv7VNmzZ5VXfatGlWqlQpj0/PR44csVq1alnRokXdLzpJtWTJEqtQoYKZXbt/CxUq5DFq622/ZmZ//fWXTZ8+3UqUKOGTgPvSSy9ZrVq1LDY21n2/HjlyxKpVq2ZFixZN0ptu/L7Qo0cPGzVqlI0aNcq97ptvvrF69epZ8+bNfRJw71Swi5ecgLtp0yarUqWKPfPMM/bLL7+YmVmjRo3cb+aXL182M/O4z73l6/vh4sWLduHCBXvxxRft7Nmz7uUTJkxwB9zIyMgk1dyzZ4+NGjXKXn75ZfcyX+wPc+bMsVKlSllkZKT7sTtx4oS1a9fOateubTExMUmuuWrVKnvmmWc8PohERUXZ22+/bYGBgckaFR46dKjVrFnTYmNj3f0eOXLEqlatmuTn2vU2b95sxYoVs/Lly7v/Y5BcFy5csMqVK1vPnj3tzJkz1qNHD6tTp47lz5/fcufO7fHcTopLly7Z8ePHLSIiwurVq+cRcM28ex3bu3evHT161GPZjBkzrESJEvavf/3Lfv/9d696/fbbb+2DDz7weI5+8cUXliNHDvc+6+3zNy4uzrp27Woul8uyZ89uw4YNs3379tkrr7xirVq1SvJ7xKJFi6xOnToWERFhY8eOtbp161rbtm3t4sWL7tcbb7z55pv2+uuvewx6vfvuuxYYGGh79uxx3xZv/Pe//7U5c+a4z/fs2dPat2/vsc3u3bu9qn23EW5TgZiYGPv0009tz549dubMGatQoYJ16dLFzK6NWLhcLmvSpIkdOXLktmtu2rTJqlataoUKFbLu3bt7rDt37px17tzZ2rZta5cvX/bqibBv3z7LlCmTexThen369LGhQ4d69QSePXu23XfffXbq1Ckz+1/o2LZtm2XJksXuv/9+r95wli5dak2aNLH9+/db/vz5rVu3bu4X7R9++MEGDhxohw4dSnLdeOfPn7fp06dbmTJl7NFHH/WqRvzjMHLkSKtcubI7wMXfBytXrrTMmTNbgwYNbMWKFbdd9/p9YeDAgR7rvv76a6tbt661bNnSVq5c6VXf17s+2PlqisL1++f06dPtwQcftE6dOtmlS5e86u3pp5+2X375xZ588slE78fz588nu2df3Q8LFiywxo0bW6lSpaxEiRIJgtKECRPM39/fhgwZctsBN35kMVeuXDZo0CCPdcndHz766CMrUqSIHT9+3MzMrly5YmZm+/fvN5fLZcuWLUtSvePHj1uRIkXc/3263tmzZ6158+bWq1cvM0vaG3r8tmPGjLHKlSu7P0zHP9eWL19umTJlsnr16tlXX32VpJ7jbd261e6//36fftibNWuWZcqUyYKCguyxxx6zWbNmmdm119x69eol64PZ3r17LSIiwho0aGAffPCBmV37oN21a9ck3bdnz561PHny2Isvvphg6sR//vMf8/f3t549e9q2bduS1F9MTIz16dPHXC6XPf744/baa6+513Xt2tVq1Khhf/31V5Jq3mj9+vXWpk0be+WVV6xy5cr23HPP2TPPPGMlS5a0t956y8xufz9bvXq1jRs3zlq3bm0tW7a0/Pnzm8vlskaNGlmZMmWse/fuNnDgwCR9kLxw4YINHDjQgoODrX79+vb000/bmTNn7OLFi9auXTt7/vnnkxWc48XfxldeecWqVavmfq8cNmyYVapUKckfplMC4TaViA8yH3zwgVWvXt39qeyjjz6yunXrWqFChZI0emt27cU1LCzMSpQoYVu2bPFY9+KLL1r58uWT9UR4//33zd/f3wYMGGC//PKL7dy501544QULCQmxXbt2eVVz9+7dljFjRhsyZIjH8o0bN1qdOnWsTZs2Sb4fzK69uWbOnNlcLpf7zTBer169rFGjRh6jYt44f/68vfPOO1a1atUEoxZJsW3bNkufPr0NHz7cY/nixYutRYsWVr9+fQsPD0/SY7d161YrXLiw1axZM8Eb7cKFC61ChQrWrl07jxFzb23evNmqVq1qrVu39no/uNH1byjxc3CHDh2a5DfzzZs3W+XKla1jx46WJUsWu/feey08PNwaNmxo9evXtzp16linTp1Sxf2wYcMGCwoKsueee846depk/v7+1rt3b4+pQGZmY8eOtWzZstkff/yRpN6KFy/u8/1hz549FhAQYP/3f//nsfzAgQNWtmxZW7duXZLqmV3bd4sUKWIVK1ZMMCe4S5cu9vDDDye5Zrzt27ebn59fgufawoULrXnz5vb4449b7dq1vZ6Deyc+7O3YscOWLl1qZv8bpezevbt16NAhyR/4brRv3z577LHHrEyZMlalShULCgry6jFbtWqVhYWF2YgRIxK8FlaqVMmCg4PthRde8Gokf+fOnfavf/3LSpQoYSVKlLDp06fbhAkT7NFHH/XqPw4rVqyw9957z8yu3Z89evSwp59+2qKiouydd96xZ555xlwul7lcLq/ui3jLly+3kJAQe/3112348OHWqVMnK126tHu0NSkOHz5s7777rlWsWNFKlChhHTp0sIiICIuIiHAH/ORMI4i/7KRJk+y+++4zM7Phw4ebv7+/bdy40eu6dxPhNpUZOXKklSlTxh20Bg0aZG+//bbXIXTbtm1WtmxZ69Spk8cXi7p162bh4eHJGqWKjY21Tz/91LJly2b58+e3okWL2n333ZfsL6V88MEH5u/vby+++KLt37/f/vzzTxsyZIh17NgxWZ8YFyxYYIGBgTZw4ED7/fff7ZdffrH+/ftbSEiI+1/VyRUdHe31HMjrzZgxw/3BYePGje5RlVdeecV27tzp1SjY1q1brXz58tatW7cEgWbJkiUJQlNy/PTTT1anTh2ffOkl3vUv1v3797datWp59ea4adMmK1u2rJUrV87atm1rs2bNsgkTJtiwYcNszJgxPv0ymLf3w549e2zo0KEec0rfeecdy58/vw0aNCjBY+XNB7M7tT98+OGHliFDBhs0aJDt3r3bTp48aS+99JIVKFDA6w99W7dutXLlylmHDh3cH9SjoqKsRo0a1rVrV69qxot/rvXv399++ukn27Nnj0VERNiQIUPs2LFj1qpVKytbtqzXU6Lu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",
+      "text/plain": [
+       "<Figure size 800x600 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Put your code here\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "03674516-86f8-42a3-83e3-5ecb1c376a30",
+   "metadata": {},
+   "source": [
+    "<img src=\"340px-English-slf.png\" alt=\"Letter Frequencies English\" width=\"500\" height=\"auto\">\n",
+    "This should look roughly similar, as we are using an English text.\n",
+    "\n",
+    "Now we use our cypher using a random key. Can you figure out the correct key from the frequency analysis of the cypher text and the standard English letter distribution? Try out your guess by decoding the cypher text!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "id": "8ae904cd",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAArcAAAIpCAYAAAC48RBEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8WgzjOAAAACXBIWXMAAA9hAAAPYQGoP6dpAABZ+ElEQVR4nO3deXhMd///8deQBSEJitijllprp7baghYtLVVLbVXau3Y3RXvbW0tXlKK9a2vpji5uO9VqUVuppa1930olFQTJ+/eHX+ZrJFQmQ5LT5+O65roy55x5z3tmzsy85pPPnHGZmQkAAABwgHQp3QAAAADgK4RbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAB7Cw8PVqVOnO349Bw4ckMvl0syZM93LOnXqpMyZM9/x647ncrk0fPjwu3Z98YYPHy6Xy3XXrzcl/fTTTwoICNDBgwdTupW75sbn0rfffiuXy6Vvv/02xXq60+7E68fOnTvl5+en7du3+7QunItwi3+8mTNnyuVyaePGjcmudezYMQ0fPlw///xzgnVz587V+PHjk30dSVGnTh25XC65XC6lS5dOwcHBuu+++9S+fXstW7bMZ9fzv//9L0VC4u1Izb35wvWP8a1OvrwPRo8erQULFiTpMi+99JLatGmjggULJrq+SpUqcrlcmjJlig86xM3s2LFDTz31lPLmzavAwEDlyZNH7dq1044dO1K6tZsqWbKkmjRpoqFDh6Z0K0gjXGZmKd0EkJJmzpypzp07a8OGDapUqVKyam3cuFGVK1fWjBkzEoxeNG3aVNu3b9eBAweSdR1JUadOHe3du1djxoyRJEVHR2vPnj2aN2+e9u3bp1atWunDDz+Uv7+/+zIxMTFKly6dx7K/06NHD02ePFlJeTkxM8XExMjf31/p06eXdG3k9vPPP9f58+dvu05yert06ZL8/Pzk5+fns+u7HVevXtXVq1eVIUOGZNdatmyZTp486T6/YcMGTZw4US+++KJKlCjhXn7//ffr/vvvT/b1SVLmzJnVsmVLj1H3W/n5559Vvnx5/fjjj6pWrVqC9bt371axYsUUHh6uvHnzas2aNT7pM6WFh4erTp067vspLi5Oly9fVkBAgNKlu/tjS/PmzVObNm2ULVs2denSRYUKFdKBAwf0/vvv68yZM/r444/12GOPJes6brzNvrJo0SI1btxYe/bsUeHChX1aG85zd1/RAfhU/JvlrUJSSEiInnrqKY9lY8eOVa9evfTOO+8oPDxc48aNc68LDAy8Y/1K14JdXFycAgICfBLukiOlrt+XgbpBgwYe5zNkyKCJEyeqQYMGqlOnjk+uI7lmzJihAgUK6IEHHkh0/YcffqicOXPqjTfeUMuWLXXgwAGFh4ff3SbvgnTp0qXYPrd37161b99e9957r7777jvlyJHDva53796qVauW2rdvr23btunee++9aZ3o6GgFBQXdjZY9XisiIiKUNWtWzZo1SyNHjrwr14+0i2kJwG06evSonn76aeXKlUuBgYEqVaqUpk+f7l7/7bffqnLlypKkzp07u/8dPHPmTNWpU0cLFy7UwYMH3cuvf/OOiYnRsGHDVKRIEQUGBip//vx64YUXFBMT49GDy+VSjx49NGfOHJUqVUqBgYFavHhxkm9L+vTpNXHiRJUsWVKTJk1SZGSke92Nc+auXLmiESNGqGjRosqQIYOyZ8+umjVruqc1dOrUSZMnT3b3F3+S/m9e7euvv67x48ercOHCCgwM1M6dOxOdcxtv3759atSokYKCgpQnTx6NHDnSY+T1ZnMXb6x5q97il9347/otW7bo4YcfVnBwsDJnzqz69etr3bp1HtvET2X54Ycf1K9fP+XIkUNBQUF67LHHdPr06b+9/xObcxv/2C5YsEClS5d272PePL6JWbRokWrVqqWgoCBlyZJFTZo08fhX9MqVK5UuXboE//qdO3eux3QBl8ul6OhozZo1y31//t0cywULFqhevXo3nWc8d+5ctWzZUk2bNlVISIjmzp2bYJu//vpLffr0UXh4uAIDA5UzZ041aNBAmzdv9thu/fr1aty4sbJmzaqgoCDdf//9mjBhgsc2v/76q1q2bKls2bIpQ4YMqlSpkr766iuPbZLyGJuZXn75ZeXLl0+ZMmVS3bp1E/03f2L7bZ06dVS6dGnt3LlTdevWVaZMmZQ3b169+uqrCS5/8OBBPfroowoKClLOnDnVt29fLVmy5Lbm8b722mu6cOGC3n33XY9gK0n33HOPpk2bpujoaI/rjd9Pd+7cqbZt2ypr1qyqWbNmkm6zJJ07d059+vRR/vz5FRgYqCJFimjcuHGKi4tzb3Or1wpJ8vf3V506dfTll1/e8nYCEiO3wG05efKkHnjgAXcAyZEjhxYtWqQuXbooKipKffr0UYkSJTRy5EgNHTpU3bp1U61atSRJ1atXV968eRUZGakjR47orbfekiT3F6fi4uL06KOPas2aNerWrZtKlCihX375RW+99ZZ+//33BHMbV65cqU8//VQ9evTQPffc4/UIV/r06dWmTRsNGTJEa9asUZMmTRLdbvjw4RozZoyeeeYZValSRVFRUdq4caM2b96sBg0a6Nlnn9WxY8e0bNkyffDBB4nWmDFjhi5duqRu3bopMDBQ2bJl83hju15sbKweeughPfDAA3r11Ve1ePFiDRs2TFevXk3yiM3t9Ha9HTt2qFatWgoODtYLL7wgf39/TZs2TXXq1NHq1atVtWpVj+179uyprFmzatiwYTpw4IDGjx+vHj166JNPPklSn/HWrFmjefPm6fnnn1eWLFk0ceJEtWjRQocOHVL27Nm9qilJH3zwgTp27KhGjRpp3LhxunDhgqZMmaKaNWtqy5YtCg8PV7169fT8889rzJgxat68uSpUqKDjx4+rZ8+eioiI0HPPPeeuFb8vdOvWTZJu+W/io0eP6tChQ6pQoUKi69evX689e/ZoxowZCggI0OOPP645c+boxRdf9Njuueee0+eff64ePXqoZMmSOnPmjNasWaNdu3a5ay9btkxNmzZV7ty51bt3b4WFhWnXrl365ptv1Lt3b0nXHuMaNWoob968GjRokIKCgvTpp5+qefPm+uKLLxL8W/52HuOhQ4fq5ZdfVuPGjdW4cWNt3rxZDRs21OXLl2/r8fnzzz/10EMP6fHHH1erVq30+eefa+DAgSpTpowefvhhSddGTOvVq6fjx4+7b9vcuXO1atWq27qOr7/+WuHh4e7XpRs9+OCDCg8P18KFCxOse+KJJ1S0aFGNHj3a/SHzdm/zhQsXVLt2bR09elTPPvusChQooB9//FGDBw/W8ePHE3wPIbHXingVK1bUl19+qaioKAUHB9/W7cY/lAH/cDNmzDBJtmHDhptu06VLF8udO7f98ccfHstbt25tISEhduHCBTMz27Bhg0myGTNmJKjRpEkTK1iwYILlH3zwgaVLl86+//57j+VTp041SfbDDz+4l0mydOnS2Y4dO27rttWuXdtKlSp10/Xz5883STZhwgT3soIFC1rHjh3d58uW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1qZNG8udO7f7daxNmzb2yy+/JNg2fj+NPwTf9W73NptdOxzd4MGDrUiRIhYQEGD33HOPVa9e3V5//XX368itXivMzBYtWmSSbPfu3bd1O/HP5jLz4ax4AAASUb9+feXJk+e2fkwDt2/8+PHq27evjhw54nGUB6dp3ry5XC6X5s+fn9KtIA0g3AIA7rj169erVq1a2r17t/sLSUiaixcvehxN4NKlSypfvrxiY2PdX7p0ol27dqlMmTL6+eefb3moNyAe4RYAgDTg4YcfVoECBVSuXDn3XPodO3Zozpw5atu2bUq3B6QafKEMAIA0oFGjRvrvf/+rOXPmKDY2ViVLltTHH3+sJ598MqVbA1IVRm4BAADgGBznFgAAAI5BuAUAAIBjMOdW137u89ixY8qSJctd/flTAAAA3B4z019//aU8efIoXbqbj88SbiUdO3YsTf5mPAAAwD/N4cOHlS9fvpuuJ9xKypIli6Rrd1Za/O14AAAAp4uKilL+/Pndue1mCLf6v9/kDg4OJtwCAACkYn83hZQvlAEAAMAxCLcAAABwjBQNt999950eeeQR5cmTRy6XSwsWLLjpts8995xcLpfGjx/vsfzs2bNq166dgoODFRoaqi5duuj8+fN3tnEAAACkSikabqOjo1W2bFlNnjz5ltvNnz9f69atU548eRKsa9eunXbs2KFly5bpm2++0Xfffadu3brdqZYBAACQiqXoF8oefvhhPfzww7fc5ujRo+rZs6eWLFmiJk2aeKzbtWuXFi9erA0bNqhSpUqSpLfffluNGzfW66+/nmgYBgAAgHOl6jm3cXFxat++vQYMGKBSpUolWL927VqFhoa6g60kRUREKF26dFq/fv1N68bExCgqKsrjBAAAgLQvVYfbcePGyc/PT7169Up0/YkTJ5QzZ06PZX5+fsqWLZtOnDhx07pjxoxRSEiI+8QPOAAAADhDqg23mzZt0oQJEzRz5kyf/yTu4MGDFRkZ6T4dPnzYp/UBAACQMlJtuP3+++916tQpFShQQH5+fvLz89PBgwf173//W+Hh4ZKksLAwnTp1yuNyV69e1dmzZxUWFnbT2oGBge4fbOCHGwAAAJwj1f5CWfv27RUREeGxrFGjRmrfvr06d+4sSapWrZrOnTunTZs2qWLFipKklStXKi4uTlWrVr3rPQMAACBlpWi4PX/+vPbs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99q7d6+k5H34i4yMVJ06dbRq1SpftSdJiomJ0eeff67Vq1f7tO7HH3+shx56SDt37tShQ4d8WvuuMaQa8+fPt/DwcCtRooRlzJjRnn76aTt27FiS6yxcuNB+/vln9/kvvvjCqlataoULF7bmzZvb+++/n+xef/vtNytUqJC98847ya4VLy4uzszMPvnkE2vVqpVVq1bNMmXKZEWKFLGFCxcmu/7nn39uISEh1rp1a6tevbpVqlTJunXr5lWtCxcuWL169eyZZ56xkiVLWrt27dzrrl69muxe+/fvby1atLDq1atbtmzZ7L777vPqPrhxX5g3b57VqFHDihUrZsOHD7fNmzcnu9fIyEgrW7astWvXznbs2JHsejeaOXOmPfjgg9axY0e7ePGiVzUWLlxoW7duNbP/28+eeOIJe+ONN3zW5+bNm61ChQr2zDPP2Pbt231WN978+fMtc+bMVqRIEQsMDLRp06ZZVFRUsmv6en/47LPPLHv27FauXDlLly6dVatWzT777LNk1x04cKAVL17c7rnnHqtdu7bPXnv69+9vjz32mFWuXNlCQ0O9fq5db/fu3TZ06FAbPHiwmf3fPpdc33zzjWXMmNHee+89r94bbvTnn39a1apVzeVy2b/+9S/38tjY2GTXjjd9+nTLmzev9erVy3bu3OmzumZmu3btsqCgIJs5c6bPal64cMH994MPPmi1a9dOds1Lly5ZpUqVbMaMGcmuFS9+n9q4caMFBwfbl19+6ZO6n332mblcLps/f761bdvWhg0bZma+eV+7mwi3qcSSJUssNDTUpk2bZjExMbZo0SJzuVzWunVrO3z48G3XOXHihBUqVMg6d+5se/futR07dliWLFns5ZdftrFjx9rzzz9vAQEBNnr06GT1u2zZMitWrJgdOHDAvcwXL+Dr1q2zTJky2fvvv2+//vqr7d692+rUqWPVqlWz//3vf17X3blzpxUoUMCmTp3qPp8xY0b3m483oqOjzczs/ffft/vuu89nAXfGjBkWGhpqmzZtsrNnz9rx48etYcOGVq1aNVu0aNFt17l+X9izZ4/t2rXLQkNDbdSoUda7d2+rUKGCtWjRwr7//nuve423YcMGq1Klik+D3fX704wZM7wOuNffD9eH71q1atmbb77pk17j3YmAGxcXZ2fOnLEaNWrYtGnTbPfu3TZ69GhzuVw2evRoO3funFd1N23aZCEhITZy5Eif7Q+bN2+2e+65x/773//a2bNn7cSJE9axY0d78MEHbd68eV7X/eijjywsLMwWLFhgM2fOtAEDBpi/v7+NGTPG65pmZrNmzbKsWbPapk2b7I8//rCjR49agwYN7IEHHkjSc+16kZGRVqlSJcuRI4f17dvXvTy5r48XL160J554wl588UUzu/b6s3fvXnvllVds/vz5Xn3QuXz5stWrV8/KlStnDRo0sA8//NC9zpcBd9asWXbfffdZ9+7dfRZw4/vr06ePtWjRws6cOZPsmosXL7annnrKlixZYmZmBw8etCJFitjIkSO9qnf9a1WnTp3c7xFxcXE+u38jIyOtVatW1rt3bzNL3uM2b948c7lcNn36dDMza9q0qftDj68+oN0thNtUIDIy0rp162YjRowwM7N9+/ZZ4cKFrWXLlhYaGmrNmjWzgwcP3na9TZs2WaVKlax79+720ksvWf/+/T2ua9KkSZYhQwabPXu21z3Pnz/f8ufP7w631z+hvv32W9u0aZNXdadNm2YlS5b0+PR85MgRq1mzphUpUsT9opNUS5YssfLly5vZtfu3YMGCHqO23vZrZvbXX3/Z9OnTrXjx4j4JuC+99JLVrFnTYmNj3ffrkSNHrGrVqlakSJEkvenG7ws9evSwUaNG2ahRo9zrvvnmG6tbt641b97cJwH3TgW7eMkJuJs2bbLKlSvbM888Y7/88ouZmTVs2ND9Zn758mUzM4/73Fu+vh8uXrxoFy5csBdffNHOnj3rXj5hwgR3wI2MjExSzT179tioUaPs5Zdfdi/zxf4wZ84cK1mypEVGRrofuxMnTli7du2sVq1aFhMTk+Saq1atsmeeecbjg0hUVJS9/fbbFhQUlKxR4aFDh1qNGjUsNjbW3e+RI0esSpUqSX6uXW/z5s1WtGhRK1eunPs/Bsl14cIFq1SpkvXs2dPOnDljPXr0sNq1a1u+fPksV65cHs/tpLh06ZIdP37cmjRpYnXr1vUIuGbevY7t3bvXjh496rFsxowZVrx4cfvXv/5lv//+u1e9fvvtt/bBBx94PEe/+OILy549u3uf9fb5GxcXZ127djWXy2XZsmWzYcOG2b59++yVV16xVq1aJfk9YtGiRVa7dm1r0qSJjR071urUqWNt27a1ixcvul9vvPHmm2/a66+/7jHo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",
+      "text/plain": [
+       "<Figure size 800x600 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Mh ux, hk ghm mh ux, matm bl max jnxlmbhg:\n",
+      "Paxmaxk 'mbl ghuexk bg max fbgw mh lnyyxk\n",
+      "Max lebgzl tgw tkkhpl hy hnmktzxhnl yhkmngx,\n",
+      "Hk mh mtdx tkfl tztbglm t lxt hy mkhnuexl\n",
+      "Tgw ur hiihlbgz xgw maxf. Mh wbx--mh lexxi,\n",
+      "Gh fhkx; tgw ur t lexxi mh ltr px xgw\n",
+      "Max axtkm-tvax tgw max mahnltgw gtmnkte lahvdl\n",
+      "Matm yexla bl axbk mh: 'mbl t vhglnfftmbhg\n",
+      "Wxohnmer mh ux pbla'w. Mh wbx, mh lexxi;\n",
+      "Mh lexxi, ixkvatgvx mh wkxtf--tr, maxkx'l max knu:\n",
+      "Yhk bg matm lexxi hy wxtma patm wkxtfl ftr vhfx,\n",
+      "Paxg px atox lanyyexw hyy mabl fhkmte vhbe,\n",
+      "Fnlm zbox nl itnlx--maxkx'l max kxlixvm\n",
+      "Matm ftdxl vtetfbmr hy lh ehgz ebyx.\n",
+      "Yhk pah phnew uxtk max pabil tgw lvhkgl hy mbfx,\n",
+      "Ma'hiikxllhk'l pkhgz, max ikhnw ftg'l vhgmnfxer,\n",
+      "Max itgzl hy wblikbs'w ehox, max etp'l wxetr,\n",
+      "Max bglhexgvx hy hyybvx, tgw max linkgl\n",
+      "Matm itmbxgm fxkbm hy ma'ngphkmar mtdxl,\n",
+      "Paxg ax abflxey fbzam abl jnbxmnl ftdx\n",
+      "Pbma t utkx uhwdbg? Pah phnew ytkwxel uxtk,\n",
+      "Mh zkngm tgw lpxtm ngwxk t pxtkr ebyx,\n",
+      "Unm matm max wkxtw hy lhfxmabgz tymxk wxtma,\n",
+      "Max ngwblvhoxkx'w vhngmkr, ykhf pahlx uhnkg\n",
+      "Gh mktoxeexk kxmnkgl, inssexl max pbee,\n",
+      "Tgw ftdxl nl ktmaxk uxtk mahlx beel px atox\n",
+      "Matg yer mh hmaxkl matm px dghp ghm hy?\n",
+      "Manl vhglvbxgvx whma ftdx vhptkwl hy nl tee,\n",
+      "Tgw manl max gtmbox anx hy kxlhenmbhg\n",
+      "Bl lbvdebxw h'xk pbma max itex vtlm hy mahnzam,\n",
+      "Tgw xgmxkikblxl hy zkxtm ibma tgw fhfxgm\n",
+      "Pbma mabl kxztkw maxbk vnkkxgml mnkg tpkr\n",
+      "Tgw ehlx max gtfx hy tvmbhg.\n"
+     ]
+    }
+   ],
+   "source": [
+    "cypher_text = encode_message(original_text, random.randint(1,25)) # If you re=run this cell, the key will change!\n",
+    "plot_frequencies(count_letters(cypher_text))\n",
+    "print(cypher_text)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "3ed45915-a7cf-4d93-9d95-cdb591a45771",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Decoded Message:\n",
+      " To be, or not to be, that is the question:\n",
+      "Whether 'tis nobler in the mind to suffer\n",
+      "The slings and arrows of outrageous fortune,\n",
+      "Or to take arms against a sea of troubles\n",
+      "And by opposing end them. To die--to sleep,\n",
+      "No more; and by a sleep to say we end\n",
+      "The heart-ache and the thousand natural shocks\n",
+      "That flesh is heir to: 'tis a consummation\n",
+      "Devoutly to be wish'd. To die, to sleep;\n",
+      "To sleep, perchance to dream--ay, there's the rub:\n",
+      "For in that sleep of death what dreams may come,\n",
+      "When we have shuffled off this mortal coil,\n",
+      "Must give us pause--there's the respect\n",
+      "That makes calamity of so long life.\n",
+      "For who would bear the whips and scorns of time,\n",
+      "Th'oppressor's wrong, the proud man's contumely,\n",
+      "The pangs of dispriz'd love, the law's delay,\n",
+      "The insolence of office, and the spurns\n",
+      "That patient merit of th'unworthy takes,\n",
+      "When he himself might his quietus make\n",
+      "With a bare bodkin? Who would fardels bear,\n",
+      "To grunt and sweat under a weary life,\n",
+      "But that the dread of something after death,\n",
+      "The undiscovere'd country, from whose bourn\n",
+      "No traveller returns, puzzles the will,\n",
+      "And makes us rather bear those ills we have\n",
+      "Than fly to others that we know not of?\n",
+      "Thus conscience doth make cowards of us all,\n",
+      "And thus the native hue of resolution\n",
+      "Is sicklied o'er with the pale cast of thought,\n",
+      "And enterprises of great pith and moment\n",
+      "With this regard their currents turn awry\n",
+      "And lose the name of action.\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Decoding\n",
+    "guessed_key = 19 # Put your guess here\n",
+    "decoded_text = decode_message(cypher_text, guessed_key)\n",
+    "print(\"Decoded Message:\\n\", decoded_text)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2bd70c5e",
+   "metadata": {},
+   "source": [
+    "## Conclusion and final thoughts\n",
+    "Did the last cell yield an understandable English text? If yes: Congratulations! You cracked the code.\n",
+    "\n",
+    "Let's have a few closing questions:\n",
+    "- The presented method of frequency analysis above has some advantages but also some disadvantages. Can you name some?\n",
+    "- As stated above, this cypher is not used in reality, because it is very easily broken by brute force alone. However, increasing the key space does not solve this problem on its own, as frequency analysis is easily capable to find the correct key without trying out all possible ones. What is necessary to mitigate this problem as well? "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ab55c9fd-cfa5-4aca-afa6-b6c7c976cb3c",
+   "metadata": {},
+   "source": [
+    "Answers:\n",
+    "- Advantage: Finds key without having to try all possible ones; Disadvantage: Needs a somewhat large amount of data for statistical properties to emerge, as well as knowledge about the underlying statistics.\n",
+    "- In order to make statistical properties disapear, we need to introduce randomness into the cypher. The symbol frequencies of the cypher text should not depend on the original message."
+   ]
+  }
+ ],
+ "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.8.8"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/Excercise_3/main.ipynb b/Excercise_3/main.ipynb
deleted file mode 100644
index d8e9a62..0000000
--- a/Excercise_3/main.ipynb
+++ /dev/null
@@ -1,69 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "# main"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import numpy"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [
-    {
-     "ename": "ModuleNotFoundError",
-     "evalue": "No module named 'pandas'",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
-      "\u001b[1;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
-      "Cell \u001b[1;32mIn[2], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mpandas\u001b[39;00m\n",
-      "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'pandas'"
-     ]
-    }
-   ],
-   "source": [
-    "import pandas"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  }
- ],
- "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.18"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 4
-}
diff --git a/Excercise_3/shakethatpear.txt b/Excercise_3/shakethatpear.txt
new file mode 100644
index 0000000..01e5e64
--- /dev/null
+++ b/Excercise_3/shakethatpear.txt
@@ -0,0 +1,33 @@
+To be, or not to be, that is the question:
+Whether 'tis nobler in the mind to suffer
+The slings and arrows of outrageous fortune,
+Or to take arms against a sea of troubles
+And by opposing end them. To die--to sleep,
+No more; and by a sleep to say we end
+The heart-ache and the thousand natural shocks
+That flesh is heir to: 'tis a consummation
+Devoutly to be wish'd. To die, to sleep;
+To sleep, perchance to dream--ay, there's the rub:
+For in that sleep of death what dreams may come,
+When we have shuffled off this mortal coil,
+Must give us pause--there's the respect
+That makes calamity of so long life.
+For who would bear the whips and scorns of time,
+Th'oppressor's wrong, the proud man's contumely,
+The pangs of dispriz'd love, the law's delay,
+The insolence of office, and the spurns
+That patient merit of th'unworthy takes,
+When he himself might his quietus make
+With a bare bodkin? Who would fardels bear,
+To grunt and sweat under a weary life,
+But that the dread of something after death,
+The undiscovere'd country, from whose bourn
+No traveller returns, puzzles the will,
+And makes us rather bear those ills we have
+Than fly to others that we know not of?
+Thus conscience doth make cowards of us all,
+And thus the native hue of resolution
+Is sicklied o'er with the pale cast of thought,
+And enterprises of great pith and moment
+With this regard their currents turn awry
+And lose the name of action.
\ No newline at end of file
-- 
GitLab


From 128cdecb0d933df00c4bf7ddaf549111aa09ffc5 Mon Sep 17 00:00:00 2001
From: Julius <julius.zocher@rwth-aachen.de>
Date: Wed, 28 Feb 2024 09:52:25 +0100
Subject: [PATCH 03/23] update dependencies

---
 environment.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/environment.yml b/environment.yml
index 44bf026..b1936a1 100644
--- a/environment.yml
+++ b/environment.yml
@@ -3,3 +3,6 @@ channels:
   - conda-forge
 dependencies:
   - pandas==2.0.0
+  - numpy==1.26.2
+  - matplotlib==3.8.2
+  - pulp==2.7.0
-- 
GitLab


From c2bc668661afb1fbe039971f1b82f9794c31fa89 Mon Sep 17 00:00:00 2001
From: Julius <julius.zocher@rwth-aachen.de>
Date: Wed, 28 Feb 2024 14:21:26 +0100
Subject: [PATCH 04/23] ipdate ex2

---
 ...Ex2_Battery_Optimization_noSolutions.ipynb | 320 +++++++++---------
 1 file changed, 164 insertions(+), 156 deletions(-)

diff --git a/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb b/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
index 915d5e0..5a059e6 100644
--- a/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
+++ b/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
@@ -2,8 +2,6 @@
  "cells": [
   {
    "cell_type": "markdown",
-   "id": "52b6c1bb",
-   "metadata": {},
    "source": [
     "# DEV Excercise 3\n",
     "Task 2 - Battery storage optimization\n",
@@ -11,21 +9,25 @@
     "In this task, an energy system consisting of a building with an electrical load (e.g. household appliances), PV system, battery storage and electricity grid connection is considered.\n",
     "24 time steps are considered, corresponding to the 24 hours of a day.\n",
     "Complete the code snippets where needed at places market with \"!!!\"."
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "7d6b628352d925e2"
   },
   {
    "cell_type": "markdown",
-   "id": "6e26b8e3",
-   "metadata": {},
    "source": [
     "Definition of the individual components:"
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "7c9c80da0ef98b06"
   },
   {
    "cell_type": "code",
-   "execution_count": 16,
-   "id": "f93f1b55",
-   "metadata": {},
+   "execution_count": 1,
    "outputs": [],
    "source": [
     "# Time series of electrical load [kW]\n",
@@ -42,134 +44,175 @@
     "E_bat_kWh = 3 # capacity [kWh]\n",
     "P_bat_max_charge_kW = 1 # max charging power [kW] (charging efficiency of 100 % is assumed)\n",
     "P_bat_max_discharge_kW = 1 # max discharging power [kW] (discharging efficiency of 100 % is assumed)\n"
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "b0157151aac2977a"
   },
   {
    "cell_type": "markdown",
-   "id": "d8d3f3bb",
-   "metadata": {},
    "source": [
     "# Task 2 a)\n",
     "Plot the electrical demand, the electricity price as well as the PV generation for a 8 kWp plant. Use the python library matplotlib."
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "259a9633f492299a"
   },
   {
    "cell_type": "code",
-   "execution_count": 17,
-   "id": "8f2b2111",
-   "metadata": {},
-   "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"
-    }
-   ],
+   "execution_count": 2,
+   "outputs": [],
    "source": [
     "import matplotlib.pyplot as plt\n",
     "import numpy as np\n",
     "\n",
     "# define the function\n",
     "def plot_time_series(el_demand_kW, c_euro_kWh, pv_pu, pv_kWp):\n",
-    "    # !!! insert function\n",
-    "    plt.plot(el_demand_kW)\n",
-    "    plt.plot(c_euro_kWh)\n",
-    "    plt.plot(pv_pu)\n",
-    "    plt.plot(pv_kWp)\n",
-    "    plt.show()\n",
+    "    \"\"\"\n",
+    "    Plots the curves for electrical demand, the electricity price and the PV generation for a 8kWp plant.\n",
+    "    :param el_demand_kW: time series of electrical load \n",
+    "    :param c_euro_kWh: time series for costs of electricity from the grid\n",
+    "    :param pv_pu: generation time series per unit [p.u.]\n",
+    "    :param pv_kWp: peak power\n",
+    "    \"\"\"\n",
+    "    # !!! complete the code\n",
+    " \n",
     "    pass\n",
     "\n",
     "# Call the function\n",
     "plot_time_series(el_demand_kW, c_euro_kWh, pv_pu, pv_kWp)"
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "a291137bccc17837"
   },
   {
    "cell_type": "markdown",
-   "id": "40fc921d",
-   "metadata": {},
    "source": [
     "# Task 2 b)\n",
     "Calculate the costs of electricity supply assuming the PV plant and battery storage system are not operating. (Using numpy might be helpfull)"
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "b3f112adafd4323a"
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
-   "id": "69488a00",
-   "metadata": {},
+   "execution_count": 3,
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "The total electricity costs are 3.9 €\n"
+      "The total electricity costs are 0 €\n"
      ]
     }
    ],
    "source": [
     "# define function\n",
     "def get_total_costs(energy, costs):\n",
-    "    c_total = np.dot(np.array(energy),np.array(costs)) # !!! <-- insert calculation\n",
+    "    \"\"\"\n",
+    "    Returns the costs of electricity supply assuming the PV plant and battery storage system are not operating\n",
+    "    :param energy: time series of electrical load \n",
+    "    :param costs: time series for costs of electricity from the grid\n",
+    "    :return: total cost value\n",
+    "    \"\"\"    \n",
+    "    \n",
+    "    c_total = 0 # !!! <-- insert calculation\n",
     "    return c_total\n",
     "\n",
     "# call function\n",
     "c_total = get_total_costs(el_demand_kW, c_euro_kWh)\n",
     "print(f\"The total electricity costs are {round(c_total,2)} €\")"
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "72143018a6eed25"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Result: The total electricity costs are 3.9 €"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "13535b9a1577d9fb"
   },
   {
    "cell_type": "markdown",
-   "id": "9d4e20d6",
-   "metadata": {},
    "source": [
     "# Task 2 c)\n",
     "Calculate the costs of electricity considering a 8 kWp PV plant, but no battery storage system. Assume that no income is generated by feeding the PV generated electricity into the grid."
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "af8783fe2a5abeba"
   },
   {
    "cell_type": "code",
-   "execution_count": 33,
-   "id": "e410b81f",
-   "metadata": {},
+   "execution_count": 1,
    "outputs": [
     {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The total electricity costs are -16.82 €\n"
+     "ename": "NameError",
+     "evalue": "name 'get_total_costs' is not defined",
+     "output_type": "error",
+     "traceback": [
+      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
+      "\u001B[1;31mNameError\u001B[0m                                 Traceback (most recent call last)",
+      "Cell \u001B[1;32mIn[1], line 5\u001B[0m\n\u001B[0;32m      2\u001B[0m residuum_kW \u001B[38;5;241m=\u001B[39m \u001B[38;5;241m0\u001B[39m \u001B[38;5;66;03m#  !!! <-- insert calculation\u001B[39;00m\n\u001B[0;32m      4\u001B[0m \u001B[38;5;66;03m# call cost calculating function\u001B[39;00m\n\u001B[1;32m----> 5\u001B[0m c_total_residuum \u001B[38;5;241m=\u001B[39m \u001B[43mget_total_costs\u001B[49m(residuum_kW, c_euro_kWh)\n\u001B[0;32m      6\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mThe total electricity costs are \u001B[39m\u001B[38;5;132;01m{\u001B[39;00m\u001B[38;5;28mround\u001B[39m(c_total_residuum,\u001B[38;5;241m2\u001B[39m)\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m €\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n",
+      "\u001B[1;31mNameError\u001B[0m: name 'get_total_costs' is not defined"
      ]
     }
    ],
    "source": [
     "# calculate residuum\n",
-    "residuum_kW = np.array(el_demand_kW) - pv_kWp*np.array(pv_pu) #  !!! <-- insert calculation \n",
+    "residuum_kW = 0 #  !!! <-- insert calculation\n",
     "\n",
     "# call cost calculating function\n",
     "c_total_residuum = get_total_costs(residuum_kW, c_euro_kWh)\n",
     "print(f\"The total electricity costs are {round(c_total_residuum,2)} €\")"
-   ]
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-01-29T12:05:29.914599200Z",
+     "start_time": "2024-01-29T12:05:29.220590900Z"
+    }
+   },
+   "id": "eab981a9d9c604fe"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Result: The total electricity costs are 1.59 €"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "15d46ddd46dbad9b"
   },
   {
    "cell_type": "markdown",
-   "id": "e432595f",
-   "metadata": {},
    "source": [
     "# Task 2d)\n",
     "In the following, an optimization problem is set up to optimize the operation of the battery in such a way that the electricity supply for the house is as cost-effective as possible."
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "a34b5d21c3844d90"
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
-   "id": "eedebac7",
-   "metadata": {},
+   "execution_count": 5,
    "outputs": [],
    "source": [
     "# Import of necessary packages\n",
@@ -210,53 +253,33 @@
     "    model.solve()\n",
     "\n",
     "    return model, buy, soc, feedin"
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "9bc932d40fa4a87f"
   },
   {
    "cell_type": "markdown",
-   "id": "fe89f489",
-   "metadata": {},
    "source": [
     "Calculate the costs of electricity considering a 8 kWp PV plant and 3 kWh battery storage system. Assume that no income is generated by feeding the PV generated electricity into the grid. Plot the resulting state of charge (SOC) and buy time series and compare them to the other time series.\n"
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "4716844fbe8d1a33"
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
-   "id": "4e6625bc",
-   "metadata": {},
+   "execution_count": 6,
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "The total electricity costs are 0.55 €\n",
+      "The total electricity costs are 0 €\n",
       "The total electricity costs are 0.55 €\n"
      ]
-    },
-    {
-     "data": {
-      "image/png": "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\n",
-      "text/plain": [
-       "<Figure size 432x288 with 1 Axes>"
-      ]
-     },
-     "metadata": {
-      "needs_background": "light"
-     },
-     "output_type": "display_data"
-    },
-    {
-     "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": [
@@ -285,58 +308,53 @@
     "plot_time_series(el_demand_kW, c_euro_kWh, pv_pu, pv_kWp)\n",
     "\n",
     "# !!! insert plot for Battery SOC\n",
-    "plt.plot(soc_results)\n",
     "\n",
     "# !!! insert plot for electricity bought\n",
-    "plt.plot(buy_results)\n",
     "\n",
     "\n",
     "plt.show()"
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "36908ba960de9d4b"
   },
   {
    "cell_type": "markdown",
-   "id": "312a055f",
-   "metadata": {},
    "source": [
     "The SOC of the battery starts and ends at 50% of the maximum capacity, as this is specified by the constraints. Initially, the battery discharges as no PV power is generated. It is sufficient to charge the battery in the last hours of the day, as the size of the battery is comparatively small. It can be seen that the grid power is drawn in the time steps when the grid power is most favorable."
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "f7e51d061cdba850"
   },
   {
    "cell_type": "markdown",
-   "id": "8c3cc635",
-   "metadata": {},
    "source": [
     "# Task 2 e)\n",
     "Change the battery optimization function (1 Variable, 1 Objective, 1 Constraint) below so that the maximium (single peak value, not sum of all values!) feed in from the pv plant to the grid gets minimized. How much was the maximum feed in without battery operation, with cost minimizing battery operation and with feed-in minimizing battery operation? Plot the resulting feed-in time series."
-   ]
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "e323c8dc005ac6c6"
   },
   {
    "cell_type": "code",
-   "execution_count": 45,
-   "id": "4e8c2c60",
-   "metadata": {},
+   "execution_count": 7,
    "outputs": [
     {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The maximum feed-in without battery operation is 9.1 kW.\n",
-      "The maximum feed-in with cost minimizing battery operation is 7.2 kW.\n",
-      "The maximum feed-in with feed-in minimizing battery operation is 6.2 kW.\n"
+     "ename": "TypeError",
+     "evalue": "'int' object is not subscriptable",
+     "output_type": "error",
+     "traceback": [
+      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
+      "\u001B[1;31mTypeError\u001B[0m                                 Traceback (most recent call last)",
+      "Cell \u001B[1;32mIn[7], line 48\u001B[0m\n\u001B[0;32m     45\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m model, buy, soc, feedin\n\u001B[0;32m     47\u001B[0m \u001B[38;5;66;03m# call optimization function\u001B[39;00m\n\u001B[1;32m---> 48\u001B[0m model, buy, soc, feedin \u001B[38;5;241m=\u001B[39m \u001B[43moptimze_battery_operation_PV\u001B[49m\u001B[43m(\u001B[49m\u001B[43mel_demand_kW\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mpv_kWp\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mpv_pu\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mE_bat_kWh\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mP_bat_max_charge_kW\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mP_bat_max_discharge_kW\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mc_euro_kWh\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m     50\u001B[0m \u001B[38;5;66;03m# read results\u001B[39;00m\n\u001B[0;32m     51\u001B[0m feedin_results \u001B[38;5;241m=\u001B[39m []\n",
+      "Cell \u001B[1;32mIn[7], line 40\u001B[0m, in \u001B[0;36moptimze_battery_operation_PV\u001B[1;34m(el_demand_kW, pv_kWp, pv_pu, E_bat_kWh, P_bat_max_charge_kW, P_bat_max_discharge_kW, c_euro_kWh)\u001B[0m\n\u001B[0;32m     38\u001B[0m \u001B[38;5;66;03m# !!! insert new constraint\u001B[39;00m\n\u001B[0;32m     39\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m t \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mrange\u001B[39m(\u001B[38;5;241m23\u001B[39m):\n\u001B[1;32m---> 40\u001B[0m     model \u001B[38;5;241m+\u001B[39m\u001B[38;5;241m=\u001B[39m \u001B[43mmax_pv_feed_in\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;241;43m0\u001B[39;49m\u001B[43m]\u001B[49m \u001B[38;5;241m>\u001B[39m\u001B[38;5;241m=\u001B[39m feedin[t]\n\u001B[0;32m     42\u001B[0m \u001B[38;5;66;03m# Solve the optimization problem\u001B[39;00m\n\u001B[0;32m     43\u001B[0m model\u001B[38;5;241m.\u001B[39msolve()\n",
+      "\u001B[1;31mTypeError\u001B[0m: 'int' object is not subscriptable"
      ]
-    },
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAEGCAYAAABvtY4XAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAABU8klEQVR4nO3dd1iUx9rA4d/s0rsIgg1RsdNERYoae9QYS2JMMc2cJCfRmF40vZzkM8f0dlLV9GKMJbYYExWNvSBYwYIiIgIK0lnY+f54AUHKLspS574uLuGtj8vyMMw784yQUqIoiqI0P7qGDkBRFEWxDJXgFUVRmimV4BVFUZopleAVRVGaKZXgFUVRmimrhg6gPA8PD+nr69vQYSiKojQZu3fvTpNSela1r1EleF9fX3bt2tXQYSiKojQZQoiT1e1TXTSKoijNlErwiqIozZRK8IqiKM1Uo+qDV5SqGAwGTp8+TX5+fkOHoigNxs7Ojg4dOmBtbW32OSrBK43e6dOncXZ2xtfXFyFEQ4ejKPVOSkl6ejqnT5+mc+fOZp+numiURi8/P5/WrVur5K60WEIIWrduXeu/YlWCV5oEldyVlu5KfgZUgleUKySlJD27gHxDcUOHoihVUgleUUx47LHHeO+998q+vvbaa7n33nu5kGsgKSOP+2c+wguvzeXX35Yyd+5cAJYuXcrBgwfLzhk6dGidTeJ74403qt3n6+tLQEAAwcHBBAQEsGzZslpdLyMjg08++aRO4lQankrwimJCZGQkW7ZsAcBoNJKWlsaBAwc4dzEfe2s9B6N30jOoP91Dh3LrfbPIKyyulODrUk0JHmD9+vVER0fz66+/8vDDD9fqeleS4KWUGI3GWp2j1A+V4BXFhIiICLZu3QrAgQMH8Pf3x87BkbT087jZCY7GHWHyqEGsX76IOU88xqJV61i6bDlPPvkUwcHBHDt2DIBFixYRGhpK9+7d2bRpE6A9QJ4+fToBAQH07duX9evXA7Bw4UIeeuihshjGjx/Phg0bmD17Nnl5eQQHBzNt2rQa47548SKtWrUq+3rSpEn069ePPn368PnnnwNUut7s2bM5duwYwcHBPPXUUwDMmzePAQMGEBgYyEsvvQRAQkICPXr04M4778Tf35/XXnuNRx99tOxeX3zxBY899tjVvOxKHVDDJJUm5ZXfD3DwzMU6vWbvdi68dH2fave3a9cOKysrTp06xZYtWxgYFoZD3AkOx+yGDC8CAgJwsLfD1cEaN0drrh1+DUNHjWHwiGu58cYptHGxBaCoqIgdO3awatUqXnnlFdatW8fHH3+MEILY2FgOHz7M6NGjiYuLqzaWuXPn8tFHHxEdHV3tMcOGDUNKyfHjx/nll1/Kts+fPx93d3fy8vIYMGAAN954Y6XrJSQksH///rKv165dS3x8PDt27EBKyYQJE4iKisLHx4f4+Hi+/vprwsLCyM7OJigoiHnz5mFtbc2CBQv47LPPzP8mKBahEryimCEiIoItW7awZcsW7nngIaRja47E7OJCkjuRkZFlx+mEwMvFDld7a9zsrckpLOLoOQP5hmLGjp8AQL9+/UhISABg8+bNzJo1C4CePXvSqVOnGhO8OdavX4+HhwfHjh1jxIgRDB06FCcnJz744AOWLFkCQGJiIvHx8bRu3brGa61du5a1a9fSt29fALKzs4mPj8fHx4dOnToRFhYGgJOTE8OHD2fFihX06tULg8FAQEDAVf0/lKunErzSpNTU0rak0n742NhYWnf0I8zdi9++/gwXFxemT59e6XghBK4ONvT0diE9pwCjhNRcI8dTs9EXSYqKimq8n5WVVYV+7SuZxdu1a1e8vLw4ePAgubm5rFu3jq1bt+Lg4MDQoUPNuqaUkjlz5vDvf/+7wvaEhAQcHR0rbLv33nt544036NmzZ5WviVL/VB+8opghIiKCFStW4OzqhhFBj05tycjIYOvWrURERFQ63tnZmaysLPQ6QRtnO+xt9Hg42ZJvMJKQnoNRSgAGDx7M999/D0BcXBynTp2iR48e+Pr6Eh0djdFoJDExkR07dpRd29raGoPBYDLmc+fOceLECTp16kRmZiatWrXCwcGBw4cPs23btiqvVxp3qWuvvZb58+eTnZ0NQFJSEufOnavyfgMHDiQxMZEffviBW2+91WR8iuWpFryimCEgIIC0tDRGTbgRR1srnOysCQgIIDs7Gw8Pj0rH33LLLdx333188MEH/PrrrwiglaMNPb2dyc+6QLFRUmw0MmPGDB588EECAgKwsrJi4cKF2NraEhkZSefOnenduze9evUiJCSk7Nr3338/gYGBhISElP1yKG/YsGHo9XoMBgNz587Fy8uLMWPG8Omnn9KrVy969OhR1rVS1fUiIyPx9/dn7NixzJs3j0OHDhEeHg5oXTHfffcder2+ytdp6tSpREdHV3i4qzQcIUtaEo1B//79pVrwQ7ncoUOH6NWrV0OHQWpWAcmZeXTxdMLJ9srbRnmFRcSfy8bb1Y42znZ1GGHDGz9+PI899hgjRoxo6FCapap+FoQQu6WU/as6XnXRKIoZio2S1KwCnGytriq5A9jbaNdIyyrEaGw8DayrkZGRQffu3bG3t1fJvRFRXTSKYob0nAKKjEa8XBzq5HptnG05npbDhdxCWjvZ1sk1G5Kbm9tVj/5R6p5qwSuKCcVGSVpWAc521jheZeu9lKOtFQ42VqRmF9CYukmV5kUleEUxIT27gCKjxMul7lraQgg8nW0pLDKSmWd6RIyiXAmV4BWlBsVGI6nZBbjYWeNgU7c9mi52Vtha6UnNUq14xTJUgleUGqRlF1Jcx633UqWt+DxDMdkFNU98UpQroRK8olSjqNhIWnYB7//neT775KOy7aXlgks98cQTvPPOOyxfvrzW5YLdHKyx1us4l1UAaJOdxo0bR7du3QgJCWHq1KmkpKTUKm5TFSGFENx+++2X/p9FRXh6ejJ+/HiACv+P6pw5c4YpU6bUKq4XX3yRdevWXfH+2lBlk0tIKRvNR79+/aSiXO7gwYMNct/kjDy5L/GC/P7Hn+VNN90kpZSyuLhYhoSEyLCwsLLjwsLC5NatWyuce9ddd8lFixaVfX3NNdfInTt3Vnmfcxfz5b7ECzItI0v6+fnJ5cuXl+1bv369jI2NrVXcJ06ckH369Kl2v6OjowwKCpK5ublSSilXrVolg4KC5HXXXVer+zRmnTp1kqmpqVJKKQ8fPix9fHxMnuPo6Fj2uanXsCpGo1EWFxfXLtBaqupnAdglq8mpqgWvKFUoKjaSnl2Aq701Q4cMqlQu2NnZmQsXLlBQUMChQ4cICQkpK/G7ZcsWli9fzlNPmS4XDODuaINeJ/hq4beEh4dz/fXXl+0bOnQo/v7+1ZYVPnDgAKGhoQQHBxMYGEh8fHyVJX8vN27cOFauXAnAjz/+WKG0QPlSxXfffTcPP/wwERERdOnShV9//RXQatH4+/uXHT9p0iRGjRqFr68vH330Ee+88w59+/YlLCyM8+fPl13r119/ZdeuXQQHB5e1rkuXoivdD1oL/KWXXiIkJISAgAAOHz4MQGpqKqNGjaJPnz7ce++9dOrUibS0tBq/ly25bLIaB680Latnw9nYur2mdwCMrdglkZZdQLGUeLnYYWftWKFccHh4OElJSWzduhVXV1cCAgKwsbEpOzciIoIJEyYwfvz4Ct0YVZULBtDrBK2dbIndv5+g4L5VhlhdWeFPP/2URx55hGnTplFYWEhxcTFz586tUPK3Krfccguvvvoq48ePJyYmhnvuuafCL53ykpOT2bx5M4cPH2bChAlVds3s37+fvXv3kp+fj5+fH2+++SZ79+7lscce45tvvqmQ9Pr3718W21NPPcWYMWOqvK+Hhwd79uzhk08+4a233uLLL7/klVdeYfjw4cyZM4c1a9bw1VdfVft/VGWTVYJXlEq0vvdC3OxtsLPWaq6ULxf8+OOPk5SUxJYtW3B1da1QLrgmN9xwA1CxXHApD0cbhKDah63VlRUODw/n9ddf5/Tp09xwww1069bNrFgCAwNJSEjgxx9/ZNy4cTUeO2nSJHQ6Hb179672ecCwYcNwdnbG2dkZV1fXsr9CAgICiImJqfKcn3/+mT179rB27doq95d/vX777TdAex1KSx6PGTOmxpo3qmyySvBKUzO25od/daF08lGbciNnypcL9vf3p2PHjrz99tvVlguuiq2tdj29Xl+pXLCVXkdQgD8bNm6ksMiIjZV5vae33XYbAwcOZOXKlYwbN47PPvuMLl26mHXuhAkTePLJJ9mwYQPp6ekm4waqHc5Z/hidTlf2tU6nq7I08v79+3n55ZeJioqqtnBZTa9XbbTksskW7YMXQjwmhDgghNgvhPhRCNG8KispzY6h2Eh6diFuDpda73CpXLC7uzt6vR53d3ezygXXxr1338G+XTv4afHSsm1RUVHs37+/2rLCx48fp0uXLjz88MNMnDiRmJgYs+99zz338NJLL9V7CzMjI4Nbb72Vb775Bk9Pz1qdGxkZWdbdsnbtWi5cuGDynJZcNtliCV4I0R54GOgvpfQH9MAtlrqfotQFbdKRViumvNJyweXL7AYEBODq6lptueB58+bRt2/fsoesprg6O/H1T4v5/H+f0K1bN3r37s0nn3yCp6cnM2bMwGg0EhAQwM0331xWVviXX37B39+f4OBg9u/fz5133knr1q3LSv5W95AVoEOHDmYtyl3Xli1bxsmTJ7nvvvvKHraa66WXXmLt2rX4+/uzaNEivL29cXZ2rvLYYcOGERwczLBhwyqUTS4qKqJXr17Mnj27yrLJ06ZNq/Qajh49mttuu43w8HACAgKYMmVKjb9Ep06dSmRkZIOXTbZYueCSBL8NCAIuAkuBD6SUVXe4ocoFK1Wrr3LBhmIjR85m4WpvTUf3uikqVlv5hmLiUrLwcrHDy0X9wXu5goIC9Ho9VlZWbN26lQcffLDGh8kNxVJlk2tbLthiffBSyiQhxFvAKSAPWFtVchdC3A/cD+Dj42OpcBTFpLLWuwVmrZrLzlqPi501adkFeDjZoteJBoulMTp16hRTp07FaDRiY2PDF1980dAhVZCRkUFoaChBQUGNomyyxRK8EKIVMBHoDGQAi4QQt0spvyt/nJTyc+Bz0FrwlopHUWpSWGQkPaeQVo7W2FpV/dCvvng623Ix1cCFnEI8nJt+KeG61K1bN/bu3dvQYVSrsZVNtuRD1pHACSllqpTSAPwGVH4apSiNwLmL2kiKy/veG4KjrRWOtlopYaOFulCVlsGSCf4UECaEcBDaVLURwCEL3k9RrkieoVhbeMPRBpsGbr2X8nS2xVBsJCNXlRJWrpzFEryUcjvwK7AHiC251+eWup+iXKmzmfnodKJRtN5LOdtaYWetSgkrV8ei4+CllC9JKXtKKf2llHdIKQsseT9Fqa2sfANZ+QbaONthpW88pZmE0H7hFBQVczFflRJWrkzjeUcrSj2TUpKcmY+NlY7WTjbVHvfYY4/x3nvvlX1dl+WCy0tISMDe3r5sbPjQiFAwFl1VK758UbDL1bY874YNGxBC8OWXX5Zti46ORgjBW2+9ZfY1zSlHfLlx48aRkZFxxfvNVf57EBQUREREBEeOHDF5zg8//FD2dXR0NKtWrbrqWOqCSvBKi3Uh10C+oRhvFzt0ovrhiKVlCgCMRiNpaWkcOHCgbP+WLVvKCozNnj0bqJzgzdW1a1eio6PLPtq7O5NbWEROYXGtr2XKq6++ysiRI2t1jr+/f4XCXT/++CNBQUG1umb518lcq1atws3N7Yr310bp92Dfvn3cddddFerEV6UuEvzVlGKoiUrwSotkNEpSLubjYGOFq711jcdGRERYtFxwTVo52LB903qGDIokJCSEm266qWy6/O7du7nmmmvo168f1157LcnJyWXbg4KCCAoK4uOPP6722uaU571cp06dyM/PJyUlBSkla9asYezYsbW65uXliB988EHCwsLo0qULGzZs4J577qFXr17cfffdZdf19fUlLS2NTz/9tOwvnM6dOzNs2LAK+xMSEujVqxf33Xcfffr0YfTo0eTl5QGwc+dOAgMDy0oAV/eXTXnlSw0nJCQwePBgQkJCCAkJKfulP3v2bDZt2kRwcDBvvvkmL774Ij///DPBwcH8/PPP5OTkcM899xAaGkrfvn3LFh9ZuHAhEyZMYPjw4YwYMYI777yTpUuXlt172rRpZi1UUhNVbExpUt7c8SaHz1edfGqjsNiIociInbWePh69eCb0mWqPbdeunUXLBZdXWoMctL8cXnnlFeZ/9DaffP8bQb7efPDuW7zzzjvMmTOHWbNmsWzZMjw9Pfn555957rnnmD9/PtOnT+ejjz5iyJAhNZYquFxV5XmrMmXKFBYtWkTfvn0JCQmpUGjsSq554cIFtm7dyvLly5kwYQL//PMPX375JQMGDCA6OrpCKYMHHniABx54AIPBwPDhw3n88ccrXS8+Pp4ff/yRL774gqlTp7J48WJuv/12pk+fzhdffEF4eHiNf0GUfg+ysrLIzc1l+/btALRp04Y///wTOzs74uPjufXWW9m1axdz587lrbfeYsWKFQB4eXmxa9cuPvpIWwXs2WefZfjw4cyfP79sIlTpXzl79uwhJiYGd3d3Nm7cyLvvvsukSZPIzMxky5YtfP3119XGaQ6V4JUWR0owFBnR64TZM0UtXS64VGn3QKkVK1YQf+Qwd08eg04noLiI8PBwjhw5wv79+xk1ahQAxcXFtG3bloyMDDIyMhgyZAgAd9xxB6tXr651fKXleasydepUbr75Zg4fPsytt95a1pK90mtef/31CCEICAjAy8urrPhZnz59SEhIqLJWzSOPPMLw4cMrLI5SqnPnzmXnlL7WGRkZZGVlER4eDmhVOEsT8uXKfw9+/vln7r//ftasWYPBYOChhx4iOjoavV5v9oSmtWvXsnz58rLnFPn5+Zw6dQqAUaNG4e7uDsA111zDjBkzSE1NZfHixdx4441YWV1dilYJXmlSamppmyvpQi7ncwx093LC1tq8ce+WLhdcHSklo0aN4r3PFpByMZ8OrRxwd7QhNjaWPn36lHUdlarpQeP06dPZu3cv7dq1q7KP2Nz4vL29sba25s8//+T999+vMcGbc83ypYUvLztc1TkLFy7k5MmTZS3k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\n",
-      "text/plain": [
-       "<Figure size 432x288 with 1 Axes>"
-      ]
-     },
-     "metadata": {
-      "needs_background": "light"
-     },
-     "output_type": "display_data"
     }
    ],
    "source": [
@@ -355,11 +373,11 @@
     "    feedin = LpVariable.dicts(\"feedin\", range(24), lowBound=0)  # The amount of electricity (in kW) sold to the grid at time t\n",
     "    consumed_pv = LpVariable.dicts(\"consumed_pv\", range(24), lowBound=0)  # The amount of electricity (in kW) consumed directly from PV at time t\n",
     "\n",
-    "    #  !!! insert new decision variable\n",
-    "    max_pv_feed_in = LpVariable(\"max_pv_feed_in\", lowBound=0)\n",
+    "    #  !!! insert new variable\n",
+    "    max_pv_feed_in = 0\n",
     "\n",
-    "    # !!! insert new objective function\n",
-    "    model += max_pv_feed_in, \"Minimize_Max_Feedin\" #lpSum(0)\n",
+    "    # !!! insert new Objective Function\n",
+    "    model += lpSum(0)\n",
     "\n",
     "    # Constraints\n",
     "    model += soc[0] == E_bat_kWh/2\n",
@@ -379,7 +397,7 @@
     "\n",
     "    # !!! insert new constraint\n",
     "    for t in range(23):\n",
-    "        model += max_pv_feed_in >= feedin[t]\n",
+    "        model += max_pv_feed_in[0] >= feedin[t]\n",
     "\n",
     "    # Solve the optimization problem\n",
     "    model.solve()\n",
@@ -396,46 +414,36 @@
     "    feedin_results.append(feedin[i].value())\n",
     "\n",
     "# max feed-in without battery:\n",
-    "max_feedin_1 = max(pv_kWp * np.array(pv_pu) + np.array(el_demand_kW))\n",
-    "\n",
+    "max_feedin_1 = 0 # !!! <-- insert calculation\n",
     "print(f\"The maximum feed-in without battery operation is {max_feedin_1} kW.\")\n",
     "\n",
     "# max feed-in with cost minimizing battery operation:\n",
     "max_feedin_2 = 0 # !!! <-- insert calculation\n",
-    "max_feedin_2 = max(feedin_cost_minimizing_results)\n",
     "print(f\"The maximum feed-in with cost minimizing battery operation is {max_feedin_2} kW.\")\n",
     "\n",
     "# max feed-in with feed-in minimizing battery operation:\n",
-    "max_feedin_3 = max(feedin_results)#0 # !!! <-- insert calculation\n",
+    "max_feedin_3 = 0 # !!! <-- insert calculation\n",
     "print(f\"The maximum feed-in with feed-in minimizing battery operation is {max_feedin_3} kW.\")\n",
     "\n",
     "# !!! insert plots\n",
-    "plt.plot(range(24), pv_kWp * np.array(pv_pu) + np.array(el_demand_kW), label='Without Battery')\n",
-    "plt.plot(range(24), feedin_cost_minimizing_results, label='With Cost Minimizing Battery')\n",
-    "plt.plot(range(24), feedin_results, label='With Feed-in Minimizing Battery')\n",
     "\n",
-    "plt.xlabel('Time (hours)')\n",
-    "plt.ylabel('Feed-in (kW)')\n",
-    "plt.legend()\n",
     "\n",
     "plt.show()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "01ca0a8e",
-   "metadata": {},
-   "outputs": [],
-   "source": []
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "649d87d692c5365"
   },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "97f4c29d",
-   "metadata": {},
    "outputs": [],
-   "source": []
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "21ab0d83302acf04"
   }
  ],
  "metadata": {
@@ -447,14 +455,14 @@
   "language_info": {
    "codemirror_mode": {
     "name": "ipython",
-    "version": 3
+    "version": 2
    },
    "file_extension": ".py",
    "mimetype": "text/x-python",
    "name": "python",
    "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.8.5"
+   "pygments_lexer": "ipython2",
+   "version": "2.7.6"
   }
  },
  "nbformat": 4,
-- 
GitLab


From 87189d614fa1549f3d390c67f148d3c55ffb8469 Mon Sep 17 00:00:00 2001
From: "f.tischbein" <f.tischbein@iaew.rwth-aachen.de>
Date: Wed, 28 Feb 2024 15:29:13 +0100
Subject: [PATCH 05/23] Update Exercise 2

---
 ...> 2024_02_23_DEV_UE2_A2_v2_students.ipynb} | 318 +++++++++---------
 1 file changed, 150 insertions(+), 168 deletions(-)
 rename Excercise_2/{2023_12_01_DEV_UE2_A2_v1.0_students.ipynb => 2024_02_23_DEV_UE2_A2_v2_students.ipynb} (51%)

diff --git a/Excercise_2/2023_12_01_DEV_UE2_A2_v1.0_students.ipynb b/Excercise_2/2024_02_23_DEV_UE2_A2_v2_students.ipynb
similarity index 51%
rename from Excercise_2/2023_12_01_DEV_UE2_A2_v1.0_students.ipynb
rename to Excercise_2/2024_02_23_DEV_UE2_A2_v2_students.ipynb
index 790a5d6..c489a49 100644
--- a/Excercise_2/2023_12_01_DEV_UE2_A2_v1.0_students.ipynb
+++ b/Excercise_2/2024_02_23_DEV_UE2_A2_v2_students.ipynb
@@ -46,15 +46,15 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": 2,
    "metadata": {
     "collapsed": true,
     "pycharm": {
      "name": "#%%\n"
     },
     "ExecuteTime": {
-     "end_time": "2024-01-03T15:01:38.782849Z",
-     "start_time": "2024-01-03T15:01:34.983511400Z"
+     "end_time": "2024-02-23T12:58:40.909857800Z",
+     "start_time": "2024-02-23T12:58:28.941463400Z"
     }
    },
    "outputs": [],
@@ -65,18 +65,11 @@
     "from scipy.optimize import curve_fit"
    ]
   },
-  {
-   "cell_type": "markdown",
-   "source": [],
-   "metadata": {
-    "collapsed": false
-   }
-  },
   {
    "cell_type": "markdown",
    "source": [
     "### Predefine functions\n",
-    "It is good programming practice to define functions at the beginning that you want to use again and again in the course of the code. You can find instructions with examples for defining functions under the following [link](https://www.w3schools.com/python/python_functions.asp). In the course of this exercise, you will need to complete functions at this point. "
+    "It is good programming practice to define functions at the beginning that you want to use again and again in the course of the code. You can find instructions with examples for defining functions under the following [link](https://www.w3schools.com/python/python_functions.asp). For reasons of overview, however, we will always define these in the respective task section first. As an example, we give you the function <code> round_up(x, decimals) </code>. This function always rounds up values and will be used more frequently throughout the code."
    ],
    "metadata": {
     "collapsed": false,
@@ -87,7 +80,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": null,
    "outputs": [],
    "source": [
     "def round_up(x, decimals: int):\n",
@@ -100,85 +93,10 @@
     "    \"\"\"\n",
     "    value = np.ceil(pow(10, decimals)*x) / pow(10, decimals)\n",
     "\n",
-    "    return value\n",
-    "\n",
-    "def uri(U,I):\n",
-    "    \"\"\"\n",
-    "    Returns the value for the resistance following Ohm's law U=R*I\n",
-    "    :param U: voltage value\n",
-    "    :param I: current value\n",
-    "    :return: resistance value\n",
-    "    \"\"\"\n",
-    "    # Complete the code\n",
-    "    return\n",
-    "\n",
-    "def calc_sig_R(U, I, sig_I):\n",
-    "    \"\"\"\n",
-    "    Returns the value of the uncertainty of the resistance according to Ohm's law and Gaussian error propagation\n",
-    "    :param U: voltage value\n",
-    "    :param I: current value\n",
-    "    :param sig_I: uncertainty of the resistance\n",
-    "    :return: \n",
-    "    \"\"\"\n",
-    "    # Complete the code\n",
-    "    return \n",
-    "\n",
-    "def weighted_mean(x, sig_x):\n",
-    "    \"\"\"\n",
-    "    Returns the weighted mean of variables x and their uncertainties sig_x\n",
-    "    :param x: array with x values\n",
-    "    :param sig_x: array with uncertainty of respective x value\n",
-    "    :return: weighted mean\n",
-    "    \"\"\"\n",
-    "    # Complete the code\n",
-    "\n",
-    "    return \n",
-    "\n",
-    "def sig_weighted_mean(sig_x):\n",
-    "    \"\"\"\n",
-    "    Returns the uncertainty of the weighted mean of variables x and their uncertainties sig_x\n",
-    "    :param sig_x: array with uncertainty of respective x value\n",
-    "    :return: uncertainty of weighted mean\n",
-    "    \"\"\"\n",
-    "    # Complete the code\n",
-    "\n",
-    "    return \n",
-    "\n",
-    "\n",
-    "def ml_estimator(x, y, sig_y):\n",
-    "    \"\"\"\n",
-    "    Returns the parameter m that is determined by using the maximum likelihood method.\n",
-    "    :param x:\n",
-    "    :param y:\n",
-    "    :param sigma:\n",
-    "    :return: m\n",
-    "    \"\"\"\n",
-    "    # Complete the code\n",
-    "\n",
-    "    return \n",
-    "\n",
-    "def chi2_formula(x, y, sig_y, R):\n",
-    "    \"\"\"\n",
-    "    Formula to calculate the Chi^2 value in the case of the relationship y = x/R\n",
-    "    :param x: x values\n",
-    "    :param y: y values\n",
-    "    :param sig_y: uncertainty of y values\n",
-    "    :param m: slope\n",
-    "    :return: \n",
-    "    \"\"\"\n",
-    "    # Complete the code\n",
-    "\n",
-    "    return \n"
+    "    return value"
    ],
    "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    },
-    "ExecuteTime": {
-     "end_time": "2024-01-03T15:01:44.000874400Z",
-     "start_time": "2024-01-03T15:01:43.987393800Z"
-    }
+    "collapsed": false
    }
   },
   {
@@ -193,36 +111,12 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
-   "outputs": [
-    {
-     "ename": "ImportError",
-     "evalue": "Missing optional dependency 'openpyxl'.  Use pip or conda to install openpyxl.",
-     "output_type": "error",
-     "traceback": [
-      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
-      "\u001B[1;31mModuleNotFoundError\u001B[0m                       Traceback (most recent call last)",
-      "File \u001B[1;32m~\\Documents\\Tools\\DEV\\.venv\\lib\\site-packages\\pandas\\compat\\_optional.py:142\u001B[0m, in \u001B[0;36mimport_optional_dependency\u001B[1;34m(name, extra, errors, min_version)\u001B[0m\n\u001B[0;32m    141\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m--> 142\u001B[0m     module \u001B[38;5;241m=\u001B[39m \u001B[43mimportlib\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mimport_module\u001B[49m\u001B[43m(\u001B[49m\u001B[43mname\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    143\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mImportError\u001B[39;00m:\n",
-      "File \u001B[1;32m~\\AppData\\Local\\Programs\\Python\\Python38\\lib\\importlib\\__init__.py:127\u001B[0m, in \u001B[0;36mimport_module\u001B[1;34m(name, package)\u001B[0m\n\u001B[0;32m    126\u001B[0m         level \u001B[38;5;241m+\u001B[39m\u001B[38;5;241m=\u001B[39m \u001B[38;5;241m1\u001B[39m\n\u001B[1;32m--> 127\u001B[0m \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[43m_bootstrap\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_gcd_import\u001B[49m\u001B[43m(\u001B[49m\u001B[43mname\u001B[49m\u001B[43m[\u001B[49m\u001B[43mlevel\u001B[49m\u001B[43m:\u001B[49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mpackage\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mlevel\u001B[49m\u001B[43m)\u001B[49m\n",
-      "File \u001B[1;32m<frozen importlib._bootstrap>:1014\u001B[0m, in \u001B[0;36m_gcd_import\u001B[1;34m(name, package, level)\u001B[0m\n",
-      "File \u001B[1;32m<frozen importlib._bootstrap>:991\u001B[0m, in \u001B[0;36m_find_and_load\u001B[1;34m(name, import_)\u001B[0m\n",
-      "File \u001B[1;32m<frozen importlib._bootstrap>:973\u001B[0m, in \u001B[0;36m_find_and_load_unlocked\u001B[1;34m(name, import_)\u001B[0m\n",
-      "\u001B[1;31mModuleNotFoundError\u001B[0m: No module named 'openpyxl'",
-      "\nDuring handling of the above exception, another exception occurred:\n",
-      "\u001B[1;31mImportError\u001B[0m                               Traceback (most recent call last)",
-      "Cell \u001B[1;32mIn[6], line 3\u001B[0m\n\u001B[0;32m      1\u001B[0m \u001B[38;5;66;03m### First, the data needs to be loaded from the given xlsx-file. Note that all datatypes shall be set to float.\u001B[39;00m\n\u001B[1;32m----> 3\u001B[0m data \u001B[38;5;241m=\u001B[39m \u001B[43mpd\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mread_excel\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mmeasurement_data.xlsx\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mindex_col\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;241;43m0\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mdtype\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;28;43mfloat\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[0;32m      5\u001B[0m \u001B[38;5;66;03m### Define arrays with the corresponding voltage and current values for later use.\u001B[39;00m\n\u001B[0;32m      6\u001B[0m U       \u001B[38;5;241m=\u001B[39m data\u001B[38;5;241m.\u001B[39mloc[:, \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mvoltage\u001B[39m\u001B[38;5;124m\"\u001B[39m]\n",
-      "File \u001B[1;32m~\\Documents\\Tools\\DEV\\.venv\\lib\\site-packages\\pandas\\io\\excel\\_base.py:478\u001B[0m, in \u001B[0;36mread_excel\u001B[1;34m(io, sheet_name, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skiprows, nrows, na_values, keep_default_na, na_filter, verbose, parse_dates, date_parser, date_format, thousands, decimal, comment, skipfooter, storage_options, dtype_backend)\u001B[0m\n\u001B[0;32m    476\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(io, ExcelFile):\n\u001B[0;32m    477\u001B[0m     should_close \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mTrue\u001B[39;00m\n\u001B[1;32m--> 478\u001B[0m     io \u001B[38;5;241m=\u001B[39m \u001B[43mExcelFile\u001B[49m\u001B[43m(\u001B[49m\u001B[43mio\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstorage_options\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mstorage_options\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mengine\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mengine\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m    479\u001B[0m \u001B[38;5;28;01melif\u001B[39;00m engine \u001B[38;5;129;01mand\u001B[39;00m engine \u001B[38;5;241m!=\u001B[39m io\u001B[38;5;241m.\u001B[39mengine:\n\u001B[0;32m    480\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mValueError\u001B[39;00m(\n\u001B[0;32m    481\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mEngine should not be specified when passing \u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m    482\u001B[0m         \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124man ExcelFile - ExcelFile already has the engine set\u001B[39m\u001B[38;5;124m\"\u001B[39m\n\u001B[0;32m    483\u001B[0m     )\n",
-      "File \u001B[1;32m~\\Documents\\Tools\\DEV\\.venv\\lib\\site-packages\\pandas\\io\\excel\\_base.py:1513\u001B[0m, in \u001B[0;36mExcelFile.__init__\u001B[1;34m(self, path_or_buffer, engine, storage_options)\u001B[0m\n\u001B[0;32m   1510\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mengine \u001B[38;5;241m=\u001B[39m engine\n\u001B[0;32m   1511\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mstorage_options \u001B[38;5;241m=\u001B[39m storage_options\n\u001B[1;32m-> 1513\u001B[0m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_reader \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_engines\u001B[49m\u001B[43m[\u001B[49m\u001B[43mengine\u001B[49m\u001B[43m]\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_io\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mstorage_options\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mstorage_options\u001B[49m\u001B[43m)\u001B[49m\n",
-      "File \u001B[1;32m~\\Documents\\Tools\\DEV\\.venv\\lib\\site-packages\\pandas\\io\\excel\\_openpyxl.py:548\u001B[0m, in \u001B[0;36mOpenpyxlReader.__init__\u001B[1;34m(self, filepath_or_buffer, storage_options)\u001B[0m\n\u001B[0;32m    533\u001B[0m \u001B[38;5;129m@doc\u001B[39m(storage_options\u001B[38;5;241m=\u001B[39m_shared_docs[\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mstorage_options\u001B[39m\u001B[38;5;124m\"\u001B[39m])\n\u001B[0;32m    534\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m__init__\u001B[39m(\n\u001B[0;32m    535\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[0;32m    536\u001B[0m     filepath_or_buffer: FilePath \u001B[38;5;241m|\u001B[39m ReadBuffer[\u001B[38;5;28mbytes\u001B[39m],\n\u001B[0;32m    537\u001B[0m     storage_options: StorageOptions \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[0;32m    538\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m:\n\u001B[0;32m    539\u001B[0m \u001B[38;5;250m    \u001B[39m\u001B[38;5;124;03m\"\"\"\u001B[39;00m\n\u001B[0;32m    540\u001B[0m \u001B[38;5;124;03m    Reader using openpyxl engine.\u001B[39;00m\n\u001B[0;32m    541\u001B[0m \n\u001B[1;32m   (...)\u001B[0m\n\u001B[0;32m    546\u001B[0m \u001B[38;5;124;03m    {storage_options}\u001B[39;00m\n\u001B[0;32m    547\u001B[0m \u001B[38;5;124;03m    \"\"\"\u001B[39;00m\n\u001B[1;32m--> 548\u001B[0m     \u001B[43mimport_optional_dependency\u001B[49m\u001B[43m(\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mopenpyxl\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[0;32m    549\u001B[0m     \u001B[38;5;28msuper\u001B[39m()\u001B[38;5;241m.\u001B[39m\u001B[38;5;21m__init__\u001B[39m(filepath_or_buffer, storage_options\u001B[38;5;241m=\u001B[39mstorage_options)\n",
-      "File \u001B[1;32m~\\Documents\\Tools\\DEV\\.venv\\lib\\site-packages\\pandas\\compat\\_optional.py:145\u001B[0m, in \u001B[0;36mimport_optional_dependency\u001B[1;34m(name, extra, errors, min_version)\u001B[0m\n\u001B[0;32m    143\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mImportError\u001B[39;00m:\n\u001B[0;32m    144\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m errors \u001B[38;5;241m==\u001B[39m \u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mraise\u001B[39m\u001B[38;5;124m\"\u001B[39m:\n\u001B[1;32m--> 145\u001B[0m         \u001B[38;5;28;01mraise\u001B[39;00m \u001B[38;5;167;01mImportError\u001B[39;00m(msg)\n\u001B[0;32m    146\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[0;32m    148\u001B[0m \u001B[38;5;66;03m# Handle submodules: if we have submodule, grab parent module from sys.modules\u001B[39;00m\n",
-      "\u001B[1;31mImportError\u001B[0m: Missing optional dependency 'openpyxl'.  Use pip or conda to install openpyxl."
-     ]
-    }
-   ],
+   "execution_count": 3,
+   "outputs": [],
    "source": [
-    "### First, the data needs to be loaded from the given xlsx-file as a pandas dataframe called 'data'. Note that all datatypes shall be set to float.\n",
+    "### First, the data needs to be loaded from the given xlsx-file. Note that all datatypes shall be set to float.\n",
     "\n",
-    "data = ...\n",
+    "data = \n",
     "\n",
     "### Define arrays with the corresponding voltage and current values for later use.\n",
     "U       = \n",
@@ -233,8 +127,8 @@
    "metadata": {
     "collapsed": false,
     "ExecuteTime": {
-     "end_time": "2024-01-03T15:02:26.578566600Z",
-     "start_time": "2024-01-03T15:02:26.440889500Z"
+     "end_time": "2024-02-23T13:00:28.694732900Z",
+     "start_time": "2024-02-23T13:00:28.119399700Z"
     }
    }
   },
@@ -243,16 +137,51 @@
    "source": [
     "### Task 2b\n",
     "After the data has been read in, the resistance and its uncertainty are to be determined for the value pairs. \n",
-    "Add the corresponding code to the functions in the cell above to calculate the resistance with the function <code> def uri(U,I) </code> and the uncertainty with the function def <code> def calc_sig_R(U, I, sig_I) </code>. Why does the function <code> def calc_sig_R(U, I, sig_I) </code> not have the uncertainty of the voltage as an input variable? Note that the propagated uncertainty must always be rounded up."
+    "First add the corresponding code to the functions in the cell below to calculate the resistance with the function <code> def uri(U,I) </code> and the uncertainty with the function def <code> def calc_sig_R(U, I, sig_I) </code>. Why does the function <code> def calc_sig_R(U, I, sig_I) </code> not have the uncertainty of the voltage as an input variable? "
    ],
    "metadata": {
     "collapsed": false
    }
   },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "outputs": [],
+   "source": [
+    "def uri(U,I):\n",
+    "    \"\"\"\n",
+    "    Returns the value for the resistance following Ohm's law U=R*I\n",
+    "    :param U: voltage value\n",
+    "    :param I: current value\n",
+    "    :return: resistance value\n",
+    "    \"\"\"\n",
+    "    # Complete the code\n",
+    "\n",
+    "    return \n",
+    "\n",
+    "def calc_sig_R(U, I, sig_I):\n",
+    "    \"\"\"\n",
+    "    Returns the value of the uncertainty of the resistance according to Ohm's law and Gaussian error propagation\n",
+    "    :param U: voltage value\n",
+    "    :param I: current value\n",
+    "    :param sig_I: uncertainty of the resistance\n",
+    "    :return: \n",
+    "    \"\"\"\n",
+    "    # Complete the code\n",
+    "    return "
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:00:33.278431500Z",
+     "start_time": "2024-02-23T13:00:33.248408400Z"
+    }
+   }
+  },
   {
    "cell_type": "markdown",
    "source": [
-    "First add the code here to calculate the resistance with the function<code> def uri(U,I) </code> and add them to your pandas dataframe. Round the values to a suitable number of decimal places using the function [round](https://docs.python.org/3/library/functions.html#round)"
+    "Afterwards, add the code here to calculate the resistance with the function<code> def uri(U,I) </code> and add them to your pandas dataframe. Round the values to a suitable number of decimal places using the function [round](https://docs.python.org/3/library/functions.html#round)."
    ],
    "metadata": {
     "collapsed": false
@@ -260,21 +189,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 32,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "   voltage  voltage_sig  current  current_sig  resistance  resistance_sig\n",
-      "0     10.0          0.0     1.55         0.08        6.45            0.34\n",
-      "1     15.0          0.0     2.19         0.11        6.85            0.35\n",
-      "2     20.0          0.0     3.00         0.15        6.67            0.34\n",
-      "3     25.0          0.0     3.97         0.20        6.30            0.32\n",
-      "4     30.0          0.0     6.18         1.55        4.85            1.22\n"
-     ]
-    }
-   ],
+   "execution_count": 5,
+   "outputs": [],
    "source": [
     "# Calculate and round the resistance\n",
     "data.loc[:, \"resistance\"]       = "
@@ -283,13 +199,17 @@
     "collapsed": false,
     "pycharm": {
      "name": "#%%\n"
+    },
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:00:43.809786300Z",
+     "start_time": "2024-02-23T13:00:43.786756300Z"
     }
    }
   },
   {
    "cell_type": "markdown",
    "source": [
-    "Now calculate the uncertainty, round it and add it to the dataframe. Then print the dataframe to check your results."
+    "Now calculate the uncertainty, round it up and add it to the dataframe. Then print the dataframe to check your results."
    ],
    "metadata": {
     "collapsed": false
@@ -302,6 +222,7 @@
    "source": [
     "# Calculate resistance uncertainty\n",
     "# Remember that uncertainties shall always be rounded up!\n",
+    "data.loc[:, \"resistance_sig\"]   = \n",
     "\n",
     "### Print resulting table in one line\n",
     "pd.set_option(\"expand_frame_repr\", False)\n",
@@ -315,7 +236,7 @@
    "cell_type": "markdown",
    "source": [
     "### Task 2e\n",
-    "Now we have several pairs of measured values with different measurement uncertainties. In order to combine the information including the measurement uncertainties, we need to determine a suitable estimated value for the resistance. Calculate an estimation value for the resistance first using the arithmetic mean by using the function [np.mean](https://numpy.org/doc/stable/reference/generated/numpy.mean.html) and secondly using the expression for the weighted mean. The weighted mean is defined by the following formula, which you must add under the function <code> def weighted_mean(x, sig_x) </code>:\n",
+    "Now we have several pairs of measured values with different measurement uncertainties. In order to combine the information including the measurement uncertainties, we need to determine a suitable estimated value for the resistance. Calculate an estimation value for the resistance first using the arithmetic mean by using the function [np.mean](https://numpy.org/doc/stable/reference/generated/numpy.mean.html) and secondly using the expression for the weighted mean. The weighted mean is defined by the following formula, which you must add under the function <code> def weighted_mean(x, sig_x) </code> in the cell below:\n",
     "\n",
     "\n",
     "\n",
@@ -338,18 +259,40 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 33,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "             weighted  arithmetic\n",
-      "mean             6.52        6.22\n",
-      "uncertainty      0.17        0.72\n"
-     ]
-    }
+   "execution_count": 7,
+   "outputs": [],
+   "source": [
+    "def weighted_mean(x, sig_x):\n",
+    "    \"\"\"\n",
+    "    Returns the weighted mean of variables x and their uncertainties sig_x\n",
+    "    :param x: array with x values\n",
+    "    :param sig_x: array with uncertainty of respective x value\n",
+    "    :return: weighted mean\n",
+    "    \"\"\"\n",
+    "\n",
+    "    return \n",
+    "\n",
+    "def sig_weighted_mean(sig_x):\n",
+    "    \"\"\"\n",
+    "    Returns the uncertainty of the weighted mean of variables x and their uncertainties sig_x\n",
+    "    :param sig_x: array with uncertainty of respective x value\n",
+    "    :return: uncertainty of weighted mean\n",
+    "    \"\"\"\n",
+    "\n",
+    "    return "
    ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:01:31.910988Z",
+     "start_time": "2024-02-23T13:01:31.900940200Z"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
    "source": [
     "# Extract the needed data from our dataframe\n",
     "\n",
@@ -386,7 +329,7 @@
     "\n",
     "$m = \\frac{\\sum_{i=1}^N \\frac{x_i \\cdot y_i}{\\sigma_i^2}}{\\sum_{i=1}^N \\frac{ x_i^2}{\\sigma_i^2}}$\n",
     "\n",
-    "In this case, $x = U$, $y = I$ and $\\sigma_y = \\sigma_I$. Add the function <code> def ml_estimator(x, y, sig_y) </code> to the function cell and determine both the value for the ML estimator $m$ and then the value for the resistance. Round the value for the resistance to a meaningful number of decimal places and compare the value for the resistance with the previous ones. \n"
+    "In this case, $x = U$, $y = I$ and $\\sigma_y = \\sigma_I$. Add the function <code> def ml_estimator(x, y, sig_y) </code> to the cell below and determine both the value for the ML estimator $m$ and then the value for the resistance. Round the value for the resistance to a meaningful number of decimal places and compare the value for the resistance with the previous ones. \n"
    ],
    "metadata": {
     "collapsed": false,
@@ -397,19 +340,32 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 34,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "m = 0.152\n",
-      "\n",
-      "   weighted  arithmetic  ML-method\n",
-      "0      6.52        6.22       6.58\n"
-     ]
-    }
+   "execution_count": 9,
+   "outputs": [],
+   "source": [
+    "def ml_estimator(x, y, sig_y):\n",
+    "    \"\"\"\n",
+    "    Returns the parameter m that is determined by using the maximum likelihood method.\n",
+    "    :param x:\n",
+    "    :param y:\n",
+    "    :param sigma:\n",
+    "    :return: m\n",
+    "    \"\"\"\n",
+    "\n",
+    "    return "
    ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:01:40.086529600Z",
+     "start_time": "2024-02-23T13:01:40.070463800Z"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
    "source": [
     "# Extract needed data from dataframe\n",
     "x           = \n",
@@ -438,8 +394,7 @@
     "### Task 2g\n",
     "\n",
     "In practice, the majority of functional relationships can no longer be determined analytically using the ML method. For these cases, the Python package [Scipy](https://scipy.org/) can be used. The [scipy.optimize.curve_fit](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html) function can be used to estimate the parameters of previously defined functional relationships for a specific data set. In the scipy documentation you will find all relevant information and steps for the implementation. \n",
-    "Use the function to fit a linear relationship to the measurement data according to task 2f). Compare the result for the resistance with the previous ones. \n",
-    "\n"
+    "Use the function to fit a linear relationship to the measurement data according to task 2f). Compare the result for the resistance with the previous ones. "
    ],
    "metadata": {
     "collapsed": false,
@@ -481,7 +436,7 @@
     "\n",
     "$\\chi^2 = \\sum_{i=1}^N \\frac{(y_i - f(x_i, m))^2}{\\sigma_i^2}$\n",
     "\n",
-    "Where $x=U$, $y=I$,  $\\sigma_i = \\sigma_y_i$ and $f(x_i,m) = U_i/R$. Complete the function <code> def chi2_formula(x, y, sig_y, R) </code> and calculate the $\\Chi^2/n_{d.o.f.}$ for the results from tasks 2f and 2g. Explain what the numerical values for $\\Chi^2/n_{d.o.f.}$ mean.\n",
+    "Where $x=U$, $y=I$,  $\\sigma_i = \\sigma_y_i$ and $f(x_i,m) = U_i/R$. Complete the function <code> def chi2_formula(x, y, sig_y, R) </code> in the cell below and calculate the $\\Chi^2/n_{d.o.f.}$ for the results from 2e) (arithmetic and weighted mean) and 2g) (Scipy Curve-Fit). Explain what the numerical values for $\\Chi^2/n_{d.o.f.}$ mean.\n",
     "\n"
    ],
    "metadata": {
@@ -490,7 +445,32 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 35,
+   "execution_count": 14,
+   "outputs": [],
+   "source": [
+    "def chi2_formula(x, y, sig_y, R):\n",
+    "    \"\"\"\n",
+    "    Formula to calculate the Chi^2 value in the case of the relationship y = x/R\n",
+    "    :param x: x values\n",
+    "    :param y: y values\n",
+    "    :param sig_y: uncertainty of y values\n",
+    "    :param m: slope\n",
+    "    :return: \n",
+    "    \"\"\"\n",
+    "\n",
+    "    return "
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:07:01.068534900Z",
+     "start_time": "2024-02-23T13:07:01.050115Z"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
    "outputs": [],
    "source": [
     "# Determine n_dof\n",
@@ -504,8 +484,10 @@
     "\n",
     "\n",
     "# Print the resulting Chi^2/ndof\n",
-    "print(\"Chi^2/ndof (ML-Method) = \" + str(round(chi2_ml_n), 4))\n",
-    "print(\"Chi^2/ndof (Scipy) = \" + str(round(chi2_sc_n), 4))"
+    "# Print the resulting Chi^2/ndof\n",
+    "print(\"Chi^2/ndof (Airthmetic Mean) = \" + str(round(chi2_ar_n, 4)))\n",
+    "print(\"Chi^2/ndof (Weighted Mean) = \" + str(round(chi2_weigh_n, 4)))\n",
+    "print(\"Chi^2/ndof (Scipy) = \" + str(round(chi2_sc_n, 4)))\n"
    ],
    "metadata": {
     "collapsed": false,
-- 
GitLab


From f5b37a9dcfb536233a4de417a3f1a4b006001563 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=96mer=20Sen?= <oemer.sen@rwth-aachen.de>
Date: Wed, 8 May 2024 17:37:53 +0200
Subject: [PATCH 06/23] deleted errror output

---
 ...Ex2_Battery_Optimization_noSolutions.ipynb | 48 +++----------------
 1 file changed, 7 insertions(+), 41 deletions(-)

diff --git a/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb b/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
index 5a059e6..1fa5952 100644
--- a/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
+++ b/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
@@ -54,7 +54,7 @@
    "cell_type": "markdown",
    "source": [
     "# Task 2 a)\n",
-    "Plot the electrical demand, the electricity price as well as the PV generation for a 8 kWp plant. Use the python library matplotlib."
+    "Plot the electrical demand, the electricity price as well as the PV generation for a 8 kWp plant. Use the python library matplotlib. You can find a user guide under the following [link](https://matplotlib.org/stable/users/index)."
    ],
    "metadata": {
     "collapsed": false
@@ -94,7 +94,7 @@
    "cell_type": "markdown",
    "source": [
     "# Task 2 b)\n",
-    "Calculate the costs of electricity supply assuming the PV plant and battery storage system are not operating. (Using numpy might be helpfull)"
+    "Calculate the costs of electricity supply assuming the PV plant and battery storage system are not operating. (Using numpy might be helpfull. You can find a user guide under the following [link](https://numpy.org/doc/stable/).)"
    ],
    "metadata": {
     "collapsed": false
@@ -159,19 +159,7 @@
   {
    "cell_type": "code",
    "execution_count": 1,
-   "outputs": [
-    {
-     "ename": "NameError",
-     "evalue": "name 'get_total_costs' is not defined",
-     "output_type": "error",
-     "traceback": [
-      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
-      "\u001B[1;31mNameError\u001B[0m                                 Traceback (most recent call last)",
-      "Cell \u001B[1;32mIn[1], line 5\u001B[0m\n\u001B[0;32m      2\u001B[0m residuum_kW \u001B[38;5;241m=\u001B[39m \u001B[38;5;241m0\u001B[39m \u001B[38;5;66;03m#  !!! <-- insert calculation\u001B[39;00m\n\u001B[0;32m      4\u001B[0m \u001B[38;5;66;03m# call cost calculating function\u001B[39;00m\n\u001B[1;32m----> 5\u001B[0m c_total_residuum \u001B[38;5;241m=\u001B[39m \u001B[43mget_total_costs\u001B[49m(residuum_kW, c_euro_kWh)\n\u001B[0;32m      6\u001B[0m \u001B[38;5;28mprint\u001B[39m(\u001B[38;5;124mf\u001B[39m\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mThe total electricity costs are \u001B[39m\u001B[38;5;132;01m{\u001B[39;00m\u001B[38;5;28mround\u001B[39m(c_total_residuum,\u001B[38;5;241m2\u001B[39m)\u001B[38;5;132;01m}\u001B[39;00m\u001B[38;5;124m €\u001B[39m\u001B[38;5;124m\"\u001B[39m)\n",
-      "\u001B[1;31mNameError\u001B[0m: name 'get_total_costs' is not defined"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "# calculate residuum\n",
     "residuum_kW = 0 #  !!! <-- insert calculation\n",
@@ -203,7 +191,7 @@
    "cell_type": "markdown",
    "source": [
     "# Task 2d)\n",
-    "In the following, an optimization problem is set up to optimize the operation of the battery in such a way that the electricity supply for the house is as cost-effective as possible."
+    "In the following, an optimization problem is set up to optimize the operation of the battery in such a way that the electricity supply for the house is as cost-effective as possible. "
    ],
    "metadata": {
     "collapsed": false
@@ -272,16 +260,7 @@
   {
    "cell_type": "code",
    "execution_count": 6,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The total electricity costs are 0 €\n",
-      "The total electricity costs are 0.55 €\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "## call the optimization function\n",
     "model, buy, soc, feedin_cost_minimizing = optimze_battery_operation(el_demand_kW, pv_kWp, pv_pu, E_bat_kWh, P_bat_max_charge_kW, P_bat_max_discharge_kW, c_euro_kWh)\n",
@@ -333,7 +312,7 @@
    "cell_type": "markdown",
    "source": [
     "# Task 2 e)\n",
-    "Change the battery optimization function (1 Variable, 1 Objective, 1 Constraint) below so that the maximium (single peak value, not sum of all values!) feed in from the pv plant to the grid gets minimized. How much was the maximum feed in without battery operation, with cost minimizing battery operation and with feed-in minimizing battery operation? Plot the resulting feed-in time series."
+    "Change the battery optimization function (1 Variable, 1 Objective, 1 Constraint) below so that the maximium (single peak value, not sum of all values!) feed in from the pv plant to the grid gets minimized. How much was the maximum feed in without battery operation, with cost minimizing battery operation and with feed-in minimizing battery operation? Plot the resulting feed-in time series. You can take a look at the user guide of the library Pulp under the following [link](https://coin-or.github.io/pulp/main/includeme.html)."
    ],
    "metadata": {
     "collapsed": false
@@ -343,20 +322,7 @@
   {
    "cell_type": "code",
    "execution_count": 7,
-   "outputs": [
-    {
-     "ename": "TypeError",
-     "evalue": "'int' object is not subscriptable",
-     "output_type": "error",
-     "traceback": [
-      "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m",
-      "\u001B[1;31mTypeError\u001B[0m                                 Traceback (most recent call last)",
-      "Cell \u001B[1;32mIn[7], line 48\u001B[0m\n\u001B[0;32m     45\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m model, buy, soc, feedin\n\u001B[0;32m     47\u001B[0m \u001B[38;5;66;03m# call optimization function\u001B[39;00m\n\u001B[1;32m---> 48\u001B[0m model, buy, soc, feedin \u001B[38;5;241m=\u001B[39m \u001B[43moptimze_battery_operation_PV\u001B[49m\u001B[43m(\u001B[49m\u001B[43mel_demand_kW\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mpv_kWp\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mpv_pu\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mE_bat_kWh\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mP_bat_max_charge_kW\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mP_bat_max_discharge_kW\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mc_euro_kWh\u001B[49m\u001B[43m)\u001B[49m\n\u001B[0;32m     50\u001B[0m \u001B[38;5;66;03m# read results\u001B[39;00m\n\u001B[0;32m     51\u001B[0m feedin_results \u001B[38;5;241m=\u001B[39m []\n",
-      "Cell \u001B[1;32mIn[7], line 40\u001B[0m, in \u001B[0;36moptimze_battery_operation_PV\u001B[1;34m(el_demand_kW, pv_kWp, pv_pu, E_bat_kWh, P_bat_max_charge_kW, P_bat_max_discharge_kW, c_euro_kWh)\u001B[0m\n\u001B[0;32m     38\u001B[0m \u001B[38;5;66;03m# !!! insert new constraint\u001B[39;00m\n\u001B[0;32m     39\u001B[0m \u001B[38;5;28;01mfor\u001B[39;00m t \u001B[38;5;129;01min\u001B[39;00m \u001B[38;5;28mrange\u001B[39m(\u001B[38;5;241m23\u001B[39m):\n\u001B[1;32m---> 40\u001B[0m     model \u001B[38;5;241m+\u001B[39m\u001B[38;5;241m=\u001B[39m \u001B[43mmax_pv_feed_in\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;241;43m0\u001B[39;49m\u001B[43m]\u001B[49m \u001B[38;5;241m>\u001B[39m\u001B[38;5;241m=\u001B[39m feedin[t]\n\u001B[0;32m     42\u001B[0m \u001B[38;5;66;03m# Solve the optimization problem\u001B[39;00m\n\u001B[0;32m     43\u001B[0m model\u001B[38;5;241m.\u001B[39msolve()\n",
-      "\u001B[1;31mTypeError\u001B[0m: 'int' object is not subscriptable"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "# Import of necessary packages\n",
     "from pulp import LpProblem, LpVariable, lpSum, LpMinimize\n",
-- 
GitLab


From f4ce3662fe3c73f67a2a7e539482397de360edd2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=96mer=20Sen?= <oemer.sen@rwth-aachen.de>
Date: Wed, 8 May 2024 17:47:46 +0200
Subject: [PATCH 07/23] fixed pulp import error

---
 Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb b/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
index 1fa5952..d4b9b19 100644
--- a/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
+++ b/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
@@ -203,6 +203,9 @@
    "execution_count": 5,
    "outputs": [],
    "source": [
+    "import sys",
+    "!{sys.executable} -m pip install pulp",
+    "\n",
     "# Import of necessary packages\n",
     "from pulp import LpProblem, LpVariable, lpSum, LpMinimize\n",
     "\n",
-- 
GitLab


From e2488233cda03614d43b3b628d8b7721735977ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=96mer=20Sen?= <oemer.sen@rwth-aachen.de>
Date: Wed, 8 May 2024 17:48:40 +0200
Subject: [PATCH 08/23] added new space

---
 Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb b/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
index d4b9b19..ef56481 100644
--- a/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
+++ b/Excercise_1/Ex2_Battery_Optimization_noSolutions.ipynb
@@ -203,8 +203,8 @@
    "execution_count": 5,
    "outputs": [],
    "source": [
-    "import sys",
-    "!{sys.executable} -m pip install pulp",
+    "import sys\n",
+    "!{sys.executable} -m pip install pulp\n",
     "\n",
     "# Import of necessary packages\n",
     "from pulp import LpProblem, LpVariable, lpSum, LpMinimize\n",
-- 
GitLab


From afb5d2ac46ae07b40558a7a6dd6ee798254bae8d Mon Sep 17 00:00:00 2001
From: Julius Zocher <julius.zocher@rwth-aachen.de>
Date: Mon, 13 May 2024 18:18:01 +0200
Subject: [PATCH 09/23] Update environment.yml

---
 environment.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/environment.yml b/environment.yml
index b1936a1..596dacf 100644
--- a/environment.yml
+++ b/environment.yml
@@ -1,4 +1,4 @@
-name: DEV
+name: base
 channels:
   - conda-forge
 dependencies:
-- 
GitLab


From 0c837200f93ae5905585ec57b2dec5854687632c Mon Sep 17 00:00:00 2001
From: Franziska Maria Tischbein <franziska.tischbein@rwth-aachen.de>
Date: Thu, 16 May 2024 11:47:34 +0200
Subject: [PATCH 10/23] Upload Solution Exercise 2 - Measurement and Sensor
 Technology

---
 Excercise_2/2024_02_23_DEV_UE2_A2_v2.ipynb | 729 +++++++++++++++++++++
 1 file changed, 729 insertions(+)
 create mode 100644 Excercise_2/2024_02_23_DEV_UE2_A2_v2.ipynb

diff --git a/Excercise_2/2024_02_23_DEV_UE2_A2_v2.ipynb b/Excercise_2/2024_02_23_DEV_UE2_A2_v2.ipynb
new file mode 100644
index 0000000..deb8b6f
--- /dev/null
+++ b/Excercise_2/2024_02_23_DEV_UE2_A2_v2.ipynb
@@ -0,0 +1,729 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "source": [
+    "# DEV Exercise 2"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%% md\n"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "This Jupyter notebook contains tasks that are calculated for you on the blackboard during the exercise session. To practice using python and to see the advantage of programming when dealing with data, you will reprogram parts of it in this Jupyter notebook. If you have not yet installed the packages required for this exercise, run the following cell to install them."
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Requirement already satisfied: pandas in c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (2.0.3)\n",
+      "Requirement already satisfied: numpy>=1.20.3 in c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas) (1.24.4)\n",
+      "Requirement already satisfied: python-dateutil>=2.8.2 in c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas) (2.8.2)\n",
+      "Requirement already satisfied: pytz>=2020.1 in c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas) (2023.4)\n",
+      "Requirement already satisfied: tzdata>=2022.1 in c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from pandas) (2023.4)\n",
+      "Requirement already satisfied: six>=1.5 in c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from python-dateutil>=2.8.2->pandas) (1.16.0)\n"
+     ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "WARNING: You are using pip version 21.1.1; however, version 24.0 is available.\n",
+      "You should consider upgrading via the 'c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\python.exe -m pip install --upgrade pip' command.\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Requirement already satisfied: numpy in c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (1.24.4)\n"
+     ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "WARNING: You are using pip version 21.1.1; however, version 24.0 is available.\n",
+      "You should consider upgrading via the 'c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\python.exe -m pip install --upgrade pip' command.\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Requirement already satisfied: scipy in c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (1.10.1)\n",
+      "Requirement already satisfied: numpy<1.27.0,>=1.19.5 in c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\lib\\site-packages (from scipy) (1.24.4)\n"
+     ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "WARNING: You are using pip version 21.1.1; however, version 24.0 is available.\n",
+      "You should consider upgrading via the 'c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\python.exe -m pip install --upgrade pip' command.\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Collecting openpyxl\n",
+      "  Using cached openpyxl-3.1.2-py2.py3-none-any.whl (249 kB)\n",
+      "Collecting et-xmlfile\n",
+      "  Using cached et_xmlfile-1.1.0-py3-none-any.whl (4.7 kB)\n",
+      "Installing collected packages: et-xmlfile, openpyxl\n",
+      "Successfully installed et-xmlfile-1.1.0 openpyxl-3.1.2\n"
+     ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "WARNING: You are using pip version 21.1.1; however, version 24.0 is available.\n",
+      "You should consider upgrading via the 'c:\\users\\f.tischbein\\appdata\\local\\programs\\python\\python38\\python.exe -m pip install --upgrade pip' command.\n"
+     ]
+    }
+   ],
+   "source": [
+    "!pip install pandas\n",
+    "!pip install numpy\n",
+    "!pip install scipy\n",
+    "!pip install openpyxl"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T12:58:13.139796300Z",
+     "start_time": "2024-02-23T12:57:57.909215100Z"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Now run the following cell to import the most important libraries. You can run a cell either by clicking `Run` on the toolbar or by pressing `CTRL+RETURN`."
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "collapsed": true,
+    "pycharm": {
+     "name": "#%%\n"
+    },
+    "ExecuteTime": {
+     "end_time": "2024-02-23T12:58:40.909857800Z",
+     "start_time": "2024-02-23T12:58:28.941463400Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "import matplotlib.pyplot as plt\n",
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "from scipy.optimize import curve_fit"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Predefine functions\n",
+    "It is good programming practice to define functions at the beginning that you want to use again and again in the course of the code. You can find instructions with examples for defining functions under the following [link](https://www.w3schools.com/python/python_functions.asp). For reasons of overview, however, we will always define these in the respective task section first. As an example, we give you the function <code> round_up(x, decimals) </code>. This function always rounds up values and will be used more frequently throughout the code."
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%% md\n"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [
+    "def round_up(x, decimals: int):\n",
+    "    \"\"\"\n",
+    "    Returns the numerical value given in \"value\", rounded up to the given number of decimal places given in \"decimals\". This function is particularly relevant when dealing with measurement uncertainties, as these must always be rounded up.\n",
+    "\n",
+    "    :param x: value to be rounded\n",
+    "    :param decimals: number of decimals\n",
+    "    :return: rounded up value\n",
+    "    \"\"\"\n",
+    "    value = np.ceil(pow(10, decimals)*x) / pow(10, decimals)\n",
+    "\n",
+    "    return value"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2a\n",
+    "First, the measurement data must be read in from the Excel spreadsheet. The table contains the measured voltages and currents, each with their uncertainties. Use the [pd.read_excel](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_excel.html) function to do this.\n"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "outputs": [],
+   "source": [
+    "### First, the data needs to be loaded from the given xlsx-file. Note that all datatypes shall be set to float.\n",
+    "\n",
+    "data = pd.read_excel(\"measurement_data.xlsx\", index_col=0, dtype=float)\n",
+    "\n",
+    "### Define arrays with the corresponding voltage and current values for later use.\n",
+    "U       = data.loc[:, \"voltage\"]\n",
+    "sig_U   = data.loc[:, \"voltage_sig\"]\n",
+    "I       = data.loc[:, \"current\"]\n",
+    "sig_I   = data.loc[:, \"current_sig\"]"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:00:28.694732900Z",
+     "start_time": "2024-02-23T13:00:28.119399700Z"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2b\n",
+    "After the data has been read in, the resistance and its uncertainty are to be determined for the value pairs. \n",
+    "First add the corresponding code to the functions in the cell below to calculate the resistance with the function <code> def uri(U,I) </code> and the uncertainty with the function def <code> def calc_sig_R(U, I, sig_I) </code>. Why does the function <code> def calc_sig_R(U, I, sig_I) </code> not have the uncertainty of the voltage as an input variable? "
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "outputs": [],
+   "source": [
+    "def uri(U,I):\n",
+    "    \"\"\"\n",
+    "    Returns the value for the resistance following Ohm's law U=R*I\n",
+    "    :param U: voltage value\n",
+    "    :param I: current value\n",
+    "    :return: resistance value\n",
+    "    \"\"\"\n",
+    "    # Complete the code\n",
+    "    R = U/I\n",
+    "    return R\n",
+    "\n",
+    "def calc_sig_R(U, I, sig_I):\n",
+    "    \"\"\"\n",
+    "    Returns the value of the uncertainty of the resistance according to Ohm's law and Gaussian error propagation\n",
+    "    :param U: voltage value\n",
+    "    :param I: current value\n",
+    "    :param sig_I: uncertainty of the resistance\n",
+    "    :return: \n",
+    "    \"\"\"\n",
+    "    # Complete the code\n",
+    "    sig_R = U/I**2 * sig_I\n",
+    "    return sig_R"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:00:33.278431500Z",
+     "start_time": "2024-02-23T13:00:33.248408400Z"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Afterwards, add the code here to calculate the resistance with the function<code> def uri(U,I) </code> and add them to your pandas dataframe. Round the values to a suitable number of decimal places using the function [round](https://docs.python.org/3/library/functions.html#round)."
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "outputs": [],
+   "source": [
+    "# Calculate and round the resistance\n",
+    "data.loc[:, \"resistance\"]       = round( uri(U,I) , 2)"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%%\n"
+    },
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:00:43.809786300Z",
+     "start_time": "2024-02-23T13:00:43.786756300Z"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Now calculate the uncertainty, round it up and add it to the dataframe. Then print the dataframe to check your results."
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "   voltage  voltage_sig  current  current_sig  resistance  resistance_sig\n",
+      "0     10.0          0.0     1.55         0.08        6.45            0.34\n",
+      "1     15.0          0.0     2.19         0.11        6.85            0.35\n",
+      "2     20.0          0.0     3.00         0.15        6.67            0.34\n",
+      "3     25.0          0.0     3.97         0.20        6.30            0.32\n",
+      "4     30.0          0.0     6.18         1.55        4.85            1.22\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Calculate resistance uncertainty\n",
+    "# Remember that uncertainties shall always be rounded up!\n",
+    "data.loc[:, \"resistance_sig\"]   = round_up( calc_sig_R(U, I, sig_I), 2)\n",
+    "\n",
+    "### Print resulting table in one line\n",
+    "pd.set_option(\"expand_frame_repr\", False)\n",
+    "print(data)"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:00:55.126280100Z",
+     "start_time": "2024-02-23T13:00:55.105678900Z"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2e\n",
+    "Now we have several pairs of measured values with different measurement uncertainties. In order to combine the information including the measurement uncertainties, we need to determine a suitable estimated value for the resistance. Calculate an estimation value for the resistance first using the arithmetic mean by using the function [np.mean](https://numpy.org/doc/stable/reference/generated/numpy.mean.html) and secondly using the expression for the weighted mean. The weighted mean is defined by the following formula, which you must add under the function <code> def weighted_mean(x, sig_x) </code> in the cell below:\n",
+    "\n",
+    "\n",
+    "\n",
+    "$\\left<x\\right>=\\frac{\\sum_{i=1}^N x_i / \\sigma_{i,abs}^2}{\\sum_{i=1}^N 1 / \\sigma_{i,abs}^2}$\n",
+    "\n",
+    "\n",
+    "Also calculate the uncertainty of the calculated mean values, in each case using the function [np.std](https://numpy.org/doc/stable/reference/generated/numpy.std.html) for the arithmetic mean and the function <code> def sig_weighted_mean(sig_x) </code> for the weighted mean. In advance, add the following formula to the function <code> def sig_weighted_mean(sig_x) </code> using [np.sqrt](https://numpy.org/doc/stable/reference/generated/numpy.sqrt.html):\n",
+    "\n",
+    "$\\sigma_{\\left<x\\right>}=\\frac{1}{\\sqrt{\\sum_{i=1}^N 1 / \\sigma_{i,abs}^2}}$\n",
+    "\n",
+    "Remember to round the values to a meaningful number of decimal places using [round](https://docs.python.org/3/library/functions.html#round) and <code> def round_up(x, decimals) </code>. \n",
+    "Compare your results and explain where the differences come from! \n"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%% md\n"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "outputs": [],
+   "source": [
+    "def weighted_mean(x, sig_x):\n",
+    "    \"\"\"\n",
+    "    Returns the weighted mean of variables x and their uncertainties sig_x\n",
+    "    :param x: array with x values\n",
+    "    :param sig_x: array with uncertainty of respective x value\n",
+    "    :return: weighted mean\n",
+    "    \"\"\"\n",
+    "    nen = 0\n",
+    "    zae = 0\n",
+    "    for i in range(len(x)):\n",
+    "        nen += x[i]/sig_x[i]**2\n",
+    "        zae += 1/sig_x[i]**2\n",
+    "    \n",
+    "    wm = nen/zae\n",
+    "    return wm\n",
+    "\n",
+    "def sig_weighted_mean(sig_x):\n",
+    "    \"\"\"\n",
+    "    Returns the uncertainty of the weighted mean of variables x and their uncertainties sig_x\n",
+    "    :param sig_x: array with uncertainty of respective x value\n",
+    "    :return: uncertainty of weighted mean\n",
+    "    \"\"\"\n",
+    "    sum_weights = 0\n",
+    "    for i in range(len(sig_x)):\n",
+    "        sum_weights += 1/sig_x[i]**2\n",
+    "        \n",
+    "    sig_wm = 1/np.sqrt(sum_weights)\n",
+    "    return sig_wm"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:01:31.910988Z",
+     "start_time": "2024-02-23T13:01:31.900940200Z"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "             Weighted  Arithmetic\n",
+      "Mean             6.52        6.22\n",
+      "Uncertainty      0.17        0.72\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Extract the needed data from our dataframe\n",
+    "\n",
+    "n                   = data.shape[0] # number of measurements\n",
+    "R                   = data.loc[:, \"resistance\"]\n",
+    "sig_R               = data.loc[:, \"resistance_sig\"]\n",
+    "\n",
+    "# Calculate the arithmetic mean and its uncertainty and round your results\n",
+    "ar_mean        = round(np.mean(R), 2)\n",
+    "sig_ar_mean    = round_up(np.std(R), 2)\n",
+    "\n",
+    "# Calculate the weighted mean and its uncertainty and round your results\n",
+    "w_mean     = round( weighted_mean(R, sig_R), 2)\n",
+    "sig_w_mean = round_up(sig_weighted_mean(sig_R), 2)\n",
+    "\n",
+    "# Create and print a Dataframe with results\n",
+    "results_2e           = pd.DataFrame(np.array([[ w_mean, ar_mean], [ sig_w_mean, sig_ar_mean ]]), columns=[\"Weighted\", \"Arithmetic\"], index=[\"Mean\", \"Uncertainty\"])\n",
+    "print(results_2e)"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%%\n"
+    },
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:01:34.538085900Z",
+     "start_time": "2024-02-23T13:01:34.513089800Z"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2f\n",
+    "\n",
+    "In the lecture and the first part of this exercise session, we learned about the maximum likelihood method on the one hand and solved the analytical solution of the problem here using the ML method on the other.\n",
+    "According to Ohm's law, $I = U/R = m*U$ with $m=1/R$. This results in a linear relationship between the current and the voltage. Using the ML method, we have calculated that the following equation applies for m:\n",
+    "\n",
+    "$m = \\frac{\\sum_{i=1}^N \\frac{x_i \\cdot y_i}{\\sigma_i^2}}{\\sum_{i=1}^N \\frac{ x_i^2}{\\sigma_i^2}}$\n",
+    "\n",
+    "In this case, $x = U$, $y = I$ and $\\sigma_y = \\sigma_I$. Add the function <code> def ml_estimator(x, y, sig_y) </code> to the cell below and determine both the value for the ML estimator $m$ and then the value for the resistance. Round the value for the resistance to a meaningful number of decimal places and compare the value for the resistance with the previous ones. \n"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%% md\n"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "outputs": [],
+   "source": [
+    "def ml_estimator(x, y, sig_y):\n",
+    "    \"\"\"\n",
+    "    Returns the parameter m that is determined by using the maximum likelihood method.\n",
+    "    :param x:\n",
+    "    :param y:\n",
+    "    :param sigma:\n",
+    "    :return: m\n",
+    "    \"\"\"\n",
+    "    nen = 0\n",
+    "    zae = 0\n",
+    "    for i in range(len(x)):\n",
+    "        nen += (x[i]*y[i]/sig_y[i]**2)\n",
+    "        zae += (x[i]/sig_y[i])**2\n",
+    "    m = nen/zae\n",
+    "    return m"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:01:40.086529600Z",
+     "start_time": "2024-02-23T13:01:40.070463800Z"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "m = 0.15238572230070688\n",
+      "\n",
+      "   weighted  arithmetic  ML-method\n",
+      "0      6.52        6.22       6.56\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Extract needed data from dataframe\n",
+    "x           = data.loc[:, \"voltage\"]\n",
+    "y           = data.loc[:, \"current\"]\n",
+    "sig_y       = data.loc[:, \"current_sig\"]\n",
+    "\n",
+    "# Calculate best estimate for the parameter m\n",
+    "m           = ml_estimator(x, y, sig_y)\n",
+    "R_ml        = 1/m\n",
+    "R_ml  = round(R_ml, 2)\n",
+    "print(\"m = \" + str(m) + \"\\n\")\n",
+    "\n",
+    "# Create and print a Dataframe with results\n",
+    "results_2f  = pd.DataFrame(np.array([[w_mean, ar_mean, R_ml]]), columns=[\"weighted\", \"arithmetic\", \"ML-method\"])\n",
+    "print(results_2f)"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%%\n"
+    },
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:01:42.678661600Z",
+     "start_time": "2024-02-23T13:01:42.649206600Z"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2g\n",
+    "\n",
+    "In practice, the majority of functional relationships can no longer be determined analytically using the ML method. For these cases, the Python package [Scipy](https://scipy.org/) can be used. The [scipy.optimize.curve_fit](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html) function can be used to estimate the parameters of previously defined functional relationships for a specific data set. In the scipy documentation you will find all relevant information and steps for the implementation. \n",
+    "Use the function to fit a linear relationship to the measurement data according to task 2f). Compare the result for the resistance with the previous ones. \n",
+    "\n"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%% md\n"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Optimal Parameter m   = 0.15\n",
+      "Uncertainty = 0.0031424538988126835\n",
+      "   weighted  arithmetic  ML-method  Scipy Curve-Fit\n",
+      "0      6.52        6.22       6.56             6.56\n"
+     ]
+    }
+   ],
+   "source": [
+    "# First, the linear relationship needs to be defined as a function\n",
+    "def linear(x, a):\n",
+    "    \"\"\"\n",
+    "    Linear relationship between y=m*x and x\n",
+    "    :param x: x Variables\n",
+    "    :param a: Slope\n",
+    "    :return: y\n",
+    "    \"\"\"\n",
+    "    return x*a\n",
+    "\n",
+    "def sig_R_m(m, sig_m):\n",
+    "    \"\"\"\n",
+    "    Gaussian Error Distribution to calculate the uncertainty of R=1/m\n",
+    "    :param m: slope\n",
+    "    :param sig_m: uncertainty of the slope\n",
+    "    :return: uncertainty of the resistance\n",
+    "    \"\"\"\n",
+    "    sig_R = sig_m/m**2\n",
+    "    return sig_R\n",
+    "    \n",
+    "\n",
+    "# Use curve_fit to solve the problem and print the parameter m with its uncertainty\n",
+    "popt, pcov  = curve_fit(linear, U, I, sigma=sig_I)\n",
+    "m = popt[0]\n",
+    "sig_m = np.sqrt(pcov[0,0])\n",
+    "print(\"Optimal Parameter m   = \" + str(round(m, 2)))\n",
+    "print(\"Uncertainty = \" + str(sig_m))\n",
+    "\n",
+    "# Calculate the resistance and its uncertainty (Hint: Think about Gaussian Error Propagation!)\n",
+    "R_sc = round(1/m, 2)\n",
+    "sig_sc = round_up(sig_R_m(m, sig_m),2)\n",
+    "\n",
+    "\n",
+    "# Create and print a Dataframe with results\n",
+    "results_2g  = pd.DataFrame(np.array([[w_mean, ar_mean, R_ml, R_sc]]), columns=[\"weighted\", \"arithmetic\", \"ML-method\", \"Scipy Curve-Fit\"])\n",
+    "print(results_2g)\n"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:01:47.668723700Z",
+     "start_time": "2024-02-23T13:01:47.652728400Z"
+    }
+   }
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2h\n",
+    "\n",
+    "The $\\Chi^2$ test, which is defined as follows, is suitable for determining the quality of the fit:\n",
+    "\n",
+    "$\\chi^2 = \\sum_{i=1}^N \\frac{(y_i - f(x_i, m))^2}{\\sigma_i^2}$\n",
+    "\n",
+    "Where $x=U$, $y=I$,  $\\sigma_i = \\sigma_y_i$ and $f(x_i,m) = U_i/R$. Complete the function <code> def chi2_formula(x, y, sig_y, R) </code> in the cell below and calculate the $\\Chi^2/n_{d.o.f.}$ for the results from 2e) (arithmetic and weighted mean) and 2g) (Scipy Curve-Fit). Explain what the numerical values for $\\Chi^2/n_{d.o.f.}$ mean.\n",
+    "\n"
+   ],
+   "metadata": {
+    "collapsed": false
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "outputs": [],
+   "source": [
+    "def chi2_formula(x, y, sig_y, R):\n",
+    "    \"\"\"\n",
+    "    Formula to calculate the Chi^2 value in the case of the relationship y = x/R\n",
+    "    :param x: x values\n",
+    "    :param y: y values\n",
+    "    :param sig_y: uncertainty of y values\n",
+    "    :param m: slope\n",
+    "    :return: \n",
+    "    \"\"\"\n",
+    "    chi2 = 0\n",
+    "    for i in range(len(x)):\n",
+    "        chi2 += (y[i] - x[i]/R)**2/sig_y[i]**2\n",
+    "    return chi2"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:07:01.068534900Z",
+     "start_time": "2024-02-23T13:07:01.050115Z"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Chi^2/ndof (Airthmetic Mean) = 1.867\n",
+      "Chi^2/ndof (Weighted Mean) = 0.6881\n",
+      "Chi^2/ndof (Scipy) = 0.6715\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Determine n_dof\n",
+    "\n",
+    "n = 5-1 \n",
+    "\n",
+    "# Calculate the Chi^2 for task 2e arithmetic mean\n",
+    "chi2_ar = chi2_formula(U, I, sig_I, ar_mean)\n",
+    "chi2_ar_n = chi2_ar/n\n",
+    "\n",
+    "# Calculate the Chi^2 for task 2e wighted mean\n",
+    "chi2_weigh = chi2_formula(U, I, sig_I, w_mean)\n",
+    "chi2_weigh_n = chi2_weigh/n\n",
+    "\n",
+    "# Calculate the Chi^2 for task 2g\n",
+    "chi2_sc = chi2_formula(U, I, sig_I, R_sc)\n",
+    "chi2_sc_n = chi2_sc/n\n",
+    "\n",
+    "# Print the resulting Chi^2/ndof\n",
+    "print(\"Chi^2/ndof (Airthmetic Mean) = \" + str(round(chi2_ar_n, 4)))\n",
+    "print(\"Chi^2/ndof (Weighted Mean) = \" + str(round(chi2_weigh_n, 4)))\n",
+    "print(\"Chi^2/ndof (Scipy) = \" + str(round(chi2_sc_n, 4)))\n",
+    "print(\"Chi^2/ndof < 1 means, that the uncertainties are overestimated while Chi^2/ndof > 1, means that the uncertainties are underestimated. A fit good to the data would be Chi^2/ndof = 1\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "pycharm": {
+     "name": "#%%\n"
+    },
+    "ExecuteTime": {
+     "end_time": "2024-02-23T13:07:55.840103800Z",
+     "start_time": "2024-02-23T13:07:55.707676300Z"
+    }
+   }
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   }
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 2
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython2",
+   "version": "2.7.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
-- 
GitLab


From 643e97c3a3fbfca1f92b54db271bed02e15e07d8 Mon Sep 17 00:00:00 2001
From: "f.tischbein" <f.tischbein@iaew.rwth-aachen.de>
Date: Mon, 3 Jun 2024 16:31:05 +0200
Subject: [PATCH 11/23] Add Exercise for Asset Management

---
 Exercise_4/2024_06_03_A6_v1_students.ipynb | 401 +++++++++++++++++++++
 Exercise_4/std_type_costs.xlsx             | Bin 0 -> 7861 bytes
 2 files changed, 401 insertions(+)
 create mode 100644 Exercise_4/2024_06_03_A6_v1_students.ipynb
 create mode 100644 Exercise_4/std_type_costs.xlsx

diff --git a/Exercise_4/2024_06_03_A6_v1_students.ipynb b/Exercise_4/2024_06_03_A6_v1_students.ipynb
new file mode 100644
index 0000000..95c1b97
--- /dev/null
+++ b/Exercise_4/2024_06_03_A6_v1_students.ipynb
@@ -0,0 +1,401 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "source": [
+    "# DEV Exercise 6\n",
+    "In this Jupyter notebook we will deal with the calculation of investment and operational costs. If you have not yet installed the packages required for this exercise, run the following cell to install them."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "72ab3cf5505dbbc2"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [
+    "!pip install pandas\n",
+    "!pip install pandapower\n",
+    "!pip install simbench"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "e99cc0f65671eb71"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Now run the following cell to import the most important libraries. You can run a cell either by clicking Run on the toolbar or by pressing CTRL+RETURN."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "ddeb3acb51e3e4cd"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "initial_id",
+   "metadata": {
+    "collapsed": true,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:20:24.081312800Z",
+     "start_time": "2024-06-03T14:20:24.064701400Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "import warnings\n",
+    "warnings.simplefilter(action='ignore', category=FutureWarning)\n",
+    "\n",
+    "import pandas as pd\n",
+    "pd.options.display.max_rows = 10\n",
+    "\n",
+    "import pandapower as pp\n",
+    "import simbench as sb"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Example grid\n",
+    "\n",
+    "We will carry out the calculation using a [SimBench](https://simbench.readthedocs.io/en/stable/) example grid. SimBench is a database with synthetic grid data that maps different grid structures in low voltage. Import the grid “1-LV-rural1--0-sw” and print its properties (number and type of assets). The standard types in particular are required later for the calculation of annuities. \n"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "4963cb76c621b1bc"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "ce2565ab7f9d932b"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Afterwards, you can plot the SimBench grid by using [the pandapower simple plotting tool](https://pandapower.readthedocs.io/en/v2.0.1/plotting/matplotlib/simple_plot.html)."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "f25c7b3b43552621"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "2eb6d9517e99be23"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2a \n",
+    "\n",
+    "To calculate the annuities, we must first determine the investment costs of the lines and transformer types. For this purpose, read these from the Excel table using [the pandas function \"read_excel\"](https://pandas.pydata.org/docs/reference/api/pandas.read_excel.html)."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "e43234c36ca7e4ba"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:21:58.923764700Z",
+     "start_time": "2024-06-03T14:21:58.809907500Z"
+    }
+   },
+   "id": "c6f5410eee07a074"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2b\n",
+    "Calculate the total investment cost in t=0 for the transformer and the lines.\n",
+    "For the equipment with unit prices the total costs can be calculated via\n",
+    "$C_{inv} = \\sum_{pc=1}^{n} {C_{pc}} = n \\cdot C_{pc}$"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "90aeb0e3ed2ee0d4"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "527eba7f1fdd1827"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "For the equipment with length related costs:\n",
+    "$C_{inv} = \\sum_{pc=1}^{n} {l_{pc} \\cdot C_l} = (\\sum_{pc=1}^{n} {l_{pc}}) \\cdot C_l$.\n",
+    "First sum up over the total line length using [pandas groupby](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html)."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "de5e30b6e28016b7"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "4731e97d3b9e66f1"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "3e4b323df9b033ec"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Afterwards, calculate the total investment cost of the grid by:\n",
+    "$C_{grid,inv} = \\sum_{equip.} {C_{inv,equip.}}$"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "1262245f8ee4319d"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "f56701e0558fd50e"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2c\n",
+    "Calculate the annuity factors for the different lifetimes and components.\n",
+    "The annuity factors for the different lifetimes can be calculated via:\n",
+    "$a=\\frac{q^{T,max} \\cdot (q-1)}{q^{T,max}-1}$\n",
+    "\n",
+    "The lifetimes $T_{max}$ of the assets can be found in the Excel tables or data frames. First, define a function to calculate the annuity. This should have the lifetime and the discount rate $q = 1+r$ as input data. Usually, distribution grid operators assume an interest rate of $r=5\\%$."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "4a8f16d1e3d93bcc"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "outputs": [],
+   "source": [
+    "interestrate=0.05\n",
+    "\n",
+    "def annuity(n, r=interestrate):\n",
+    "    \"\"\"Calculate the annuity factor for an asset with lifetime n years and\n",
+    "    discount rate of r\"\"\"\n"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:21.141660Z",
+     "start_time": "2024-06-03T14:22:21.122542800Z"
+    }
+   },
+   "id": "ba8c3aebb2b2edf1"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "The following annuity costs then result for the components:"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "8bc1eeef24887502"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "e63a003d70957a59"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "966f8b18dc754e17"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2d\n",
+    "Afterwards, calculate the operating costs for the transformer and the lines. The operating costs can be found in the corresponding Excel files or data frames. The operating costs correspond to the multiplication of the investment costs with the specific operating costs from the Excel table or data frame."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "6e9b5e1600f9bf78"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "644d4a2306910ee6"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "1faf1a9504e028da"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2e\n",
+    "Calculate the annual cost of the grid equipment (sum of operating and investment costs)."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "79769693879cb833"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "de48aec2ff9058bf"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2f\n",
+    "In the course of digitizing the distribution grids, it is advisable to equip most of the LV system equipment with measurement technology. For our system, the following assumptions can be made:\n",
+    "- The specific investment costs for the measurement technology system in the transformer station is 500.000€, the interest rate equals 5%/a and its lifetime equals 20 years\n",
+    "- Every grid customer within our grid will also be equipped with a smart meter. As the smart meters belong to the metering point operator and not the distribution grid operator, there are no investment costs here.\n",
+    "- Because metering technology allows the grid to operate more efficiently, the lifetimes of all other technologies increase by 5 years\n",
+    "\n",
+    "Calculate the new annuity of investment costs for the total system with the measurement technology"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "ee9bcd85e1c42abc"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "e9bf09de56cfedb1"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2g\n",
+    "What are the maximum annual operating costs for the measurement equipment in order to still be cheaper than without measurement equipment?"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "51cf92fb26790ff"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "b749b6d14d16ff43"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "dfd9b25d20fc7b6c"
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 2
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython2",
+   "version": "2.7.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/Exercise_4/std_type_costs.xlsx b/Exercise_4/std_type_costs.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..a5491ca162bb4c77ff6db38b4bc55047e3340a2f
GIT binary patch
literal 7861
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
AN&o-=

literal 0
HcmV?d00001

-- 
GitLab


From f678882e392036c6b13347e71d771852ec0ca15b Mon Sep 17 00:00:00 2001
From: Markus <m.stroot@iaew.rwth-aachen.de>
Date: Mon, 24 Jun 2024 16:24:53 +0200
Subject: [PATCH 12/23] Deleted outputs

---
 Excercise_3/Cryptography.ipynb | 189 ++++-----------------------------
 1 file changed, 19 insertions(+), 170 deletions(-)

diff --git a/Excercise_3/Cryptography.ipynb b/Excercise_3/Cryptography.ipynb
index c575144..11f6668 100644
--- a/Excercise_3/Cryptography.ipynb
+++ b/Excercise_3/Cryptography.ipynb
@@ -16,7 +16,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 1,
+   "execution_count": null,
    "id": "595a8870",
    "metadata": {},
    "outputs": [],
@@ -41,7 +41,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": null,
    "id": "caa9910f",
    "metadata": {},
    "outputs": [],
@@ -76,18 +76,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 3,
+   "execution_count": null,
    "id": "45f1c38b-3650-4209-a288-dd5dbc004b94",
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "If no error occured: everything worked as expected!\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "assert encode_message(\"a\", 0) == \"a\"\n",
     "\n",
@@ -107,7 +99,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": null,
    "id": "91d2ec6b",
    "metadata": {},
    "outputs": [],
@@ -141,18 +133,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": null,
    "id": "b63b9859-0b69-447a-a39e-b5ca555d0348",
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "If no error occured: everything worked as expected!\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "assert decode_message(\"a\", 0) == \"a\"\n",
     "\n",
@@ -175,42 +159,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": null,
    "id": "cabfa50c-5366-4728-af0a-18791b558fac",
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Key: 1: Zkxtm! Rhn yhngw max vhkkxvm dxr.\n",
-      "Key: 2: Yjwsl! Qgm xgmfv lzw ugjjwul cwq.\n",
-      "Key: 3: Xivrk! Pfl wfleu kyv tfiivtk bvp.\n",
-      "Key: 4: Whuqj! Oek vekdt jxu sehhusj auo.\n",
-      "Key: 5: Vgtpi! Ndj udjcs iwt rdggtri ztn.\n",
-      "Key: 6: Ufsoh! Mci tcibr hvs qcffsqh ysm.\n",
-      "Key: 7: Terng! Lbh sbhaq gur pbeerpg xrl.\n",
-      "Key: 8: Sdqmf! Kag ragzp ftq oaddqof wqk.\n",
-      "Key: 9: Rcple! Jzf qzfyo esp nzccpne vpj.\n",
-      "Key: 10: Qbokd! Iye pyexn dro mybbomd uoi.\n",
-      "Key: 11: Panjc! Hxd oxdwm cqn lxaanlc tnh.\n",
-      "Key: 12: Ozmib! Gwc nwcvl bpm kwzzmkb smg.\n",
-      "Key: 13: Nylha! Fvb mvbuk aol jvyylja rlf.\n",
-      "Key: 14: Mxkgz! Eua luatj znk iuxxkiz qke.\n",
-      "Key: 15: Lwjfy! Dtz ktzsi ymj htwwjhy pjd.\n",
-      "Key: 16: Kviex! Csy jsyrh xli gsvvigx oic.\n",
-      "Key: 17: Juhdw! Brx irxqg wkh fruuhfw nhb.\n",
-      "Key: 18: Itgcv! Aqw hqwpf vjg eqttgev mga.\n",
-      "Key: 19: Hsfbu! Zpv gpvoe uif dpssfdu lfz.\n",
-      "Key: 20: Great! You found the correct key.\n",
-      "Key: 21: Fqdzs! Xnt entmc sgd bnqqdbs jdx.\n",
-      "Key: 22: Epcyr! Wms dmslb rfc amppcar icw.\n",
-      "Key: 23: Dobxq! Vlr clrka qeb zloobzq hbv.\n",
-      "Key: 24: Cnawp! Ukq bkqjz pda yknnayp gau.\n",
-      "Key: 25: Bmzvo! Tjp ajpiy ocz xjmmzxo fzt.\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "message = \"Great! You found the correct key.\"\n",
     "key = random.randint(1, 25)\n",
@@ -234,7 +186,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": null,
    "id": "8d4767f6",
    "metadata": {},
    "outputs": [],
@@ -289,21 +241,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": null,
    "id": "f8168f9a",
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "image/png": "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rpxFRETc8nq6d+9uib2c7N+/3yRZUFCQnTp1KtF1199XHTt2NEnWs2dP97K4uDiLiIiwDBky2OnTp83MbNWqVSbJVq1a9bc1b9ab2bX7c9iwYe7zzZs3twwZMtjevXvdy44dO2ZZs2a1Bx980L0sfp8JDw+3uLg49/K+ffta+vTp7dy5c4leX7xhw4Yl6EmSZciQwfbs2eNetnXrVpNkb7/99i3rXe+zzz7zuG/++usvCwkJsa5du3psd+LECQsODvZYHh0dbUWLFrXSpUvbpUuXLCIiwoKCguzgwYMelw0MDPTYR25l+fLlJsm+/vrrRNf36NHDChQo4L4fly5dapJsy5YtHtsFBwdb9+7db3o9V69etcKFC1uhQoXszz//9Fh3/WPUoEEDK1u2rF26dMljfY0aNaxYsWLuZbf7GJ86dcoyZMhgERERHtu9+OKLJsnjfkpsv61Tp45JstmzZ7uXxcTEWGhoqLVo0cK97I033jBJtmDBAveyixcvWokSJRJ9Llzv3LlzJsmaNWt2023MzB599FGTZFFRUWb2v/20TZs2Htsl5TaPGjXKAgMD7ffff/eoMWjQIEufPr0dOnTIzG79WhFv7ty5JsnWr19/y9sBMC0B+Btmpi+++EKPPPKIzEx//PGH+9S4cWNFRkYm+NdoUnz22WcqWbKkSpQo4VG7fv36kpRgZKZOnToqVapUsm5TvPjR47/++uum24SEhGjHjh3avXu319fTokWLBP8KvZUePXq4/44fLb98+bKWL1/udQ9/JzY2VkuXLlXz5s095hzmyZNHbdu21Zo1axQVFeVxmW7dunn8q7127dqKjY31+nBX4eHhHqOg999/v4KCgrRv3z6v6knXRjPPnTunNm3aeOxf6dOnV7Vq1Tz2r8yZM2vmzJnatWuXHnzwQS1cuFBvvfWWChYs6PX1nzlzRpKULVu2BOuuXr2qTz75RE8++aT7fqxfv75y5cqlOXPmeGwbEhKi9evX69ixY4lez5YtW7R//3716dNHISEhHuvia589e1YrV65Uq1at9Ndff7nvizNnzqhx48bavXu3jh496nHZv3uMly9frsuXL6tnz54e2/Xp0+c27p1rsmTJ4jEvPkOGDKpatarH47548WLly5dPjz76qHtZxowZ1bVr17+tH//8zpo16y23i19/434eP2ofLym3+bPPPlPt2rWVLVs2j/0vPDxcsbGx+u677zy2v9VrRfw+9Mcff9zydgBMSwD+xunTp3Xu3Dm9++67evfddxPd5tSpU17X3717t3bt2nXTF/QbaxcuXNjr67pR/FEJbvWmN3LkSDVr1kzFixdXmTJl9NBDD6l9+/ZJ+uZ9UnpOly5dgi+0FC9eXJLu6JEmTp8+rQsXLui+++5LsK5kyZKKi4vT4cOHVbp0affyG0Nf/Jvvn3/+6VUPiYXIbNmyeV1PkvtDSfyHpRvd+O/dmjVr6l//+pcmT56sxo0b6+mnn/b6uq9niRytYunSpTp9+rSqVq2qPXv2uJfXq1dPH330kcaNG+c+qsCrr76qjh07qkCBAqpUqZKaNGmiDh06uPeVvXv3SpLKlClz0x727NkjM9OQIUM0ZMiQRLc5deqU8uXL5z7/d49xfMgtVqyYx3Y5c+ZMNNAnJn/+/AnmI2fLlk3btm1znz948KCKFCmSYLuiRYv+bf345/etPsRev/7G14Mbn79Juc27d+/Wtm3bfPL6Fr8P/dOOEY2kI9wCfyN+buhTTz2ljh07JrpNcg6xFBcXp7Jly+rNN99MdH2BAgU8zmfKlMnr67pR/EHRb/UG+eCDD2rv3r368ssvtXTpUv3nP//RW2+9palTp+qZZ565revxZc/Szd/cYmNjfXo9fyf+EGY3SizIpUQ96X/77wcffKDQ0NAE6288akNMTIz7y0l79+7VhQsXlDlzZq+vP36ucGIBPX50tlWrVoledvXq1apXr557m9q1a2v+/PlaunSpXnvtNY0bN07z5s1zz0v9O/H3Rf/+/dW4ceNEt7nxuXAnHpMb3enrCA4OVp48eTzCcmK2bdumfPnyJfjAk5znb1xcnBo2bKgXXngh0fXxH1xv57ri96F77rnH637wz0C4Bf5Gzpw5lTVrVsXGxio8PPyW295qROFm64oUKaKtW7eqQYMGd3VEIjY2VnPnzlXmzJnd34C+mezZs6tz587q3Lmzzp8/rwcffFDDhw93h1tf9h0XF6d9+/Z5vOn9/vvvkuT+8lz86NC5c+c8LpvYdIDb7S1nzpzKnDmzfvvttwTrfv31V6VLly7BB420IH6aQ65cuf52/5WkYcOGadeuXXr99dc1cOBADRo0SBMnTvTYJimPd4kSJSRJ+/fv91geHR2tL7/8Uk8++aRatmyZ4HK9evXSnDlz3OFWujZF5Pnnn9fzzz+vU6dOqWLFinrllVf08MMPu2/n9u3bb3o740d5/f39b+u+uB3xP0qxe/duj/84nD59Olkj7oldz86dO2VmHvf/9SPet9K0aVO99957WrNmTaLP9++//14HDhzQs88+e1u9SLd3m4sUKaLz58/75P7ev3+/0qVLlyAQAzdizi3wN9KnT68WLVroiy++SPTnH68/LFD88R9vDF3x664/5Fa8Vq1a6ejRo3rvvfcSrLt48aKio6OT0X3iYmNj1atXL+3atUu9evW65TeP4+dMxsuSJYuKFi3qcZiyW91ub0yaNMn9t5lp0qRJ8vf3V4MGDSRde3NNnz59gvl677zzToJat9tb+vTp1ahRI3355Zce0x9OnjypuXPnqlatWmnyG9qNGzdWUFCQRo8erStXriRYf/3+u379er3++uvq06eP/v3vf2vAgAGaNGmSVq9e7XGZwMDA236s8+XLpwIFCiT4BcD58+crOjpa3bt3V8uWLROcmjZtqi+++EIxMTGKjY1N8NzJlSuX8ubN694PK1asqMKFC2v8+PEJeosfAc2VK5fq1q2radOm6fjx47e8L25XeHi4/P399fbbb3uMtPr61wgbN26so0ePehyy7NKlS4m+biRmwIABypQpk5599tkEz+mzZ8/queeeU+bMmTVgwIC/rZWU29yqVSutXbtWS5YsSbDu3Llzunr16m31L0mbNm1S6dKlFRwcfNuXwT8TI7fA/zd9+vREjynau3dvjR07VqtWrVK1atXUtWtXlSpVSmfPntXmzZu1fPlynT17VtK1UYqQkBBNnTpVWbNmVWBgoKpVq6bChQurUqVK+uSTT9SvXz9VqVJFWbJk0SOPPKL27dvr008/1XPPPadVq1apZs2aio2N1a+//qpPP/1US5YsSdYvp0VGRurDDz+UdO2wPPG/ULZ37161bt1ao0aNuuXlS5Uqpbp166pSpUrKnj27Nm7c6D4kU7xKlSpJujba1rhxY6VPn16tW7f2qt+MGTNq8eLF6tixo6pVq6ZFixZp4cKFevHFF93z9oKDg/XEE0/o7bfflsvlUpEiRfTNN98kOvc5Kb29/PLLWrZsmWrVqqXnn39efn5+mjZtmmJiYhI97mhaEBQUpClTpqh9+/aqWLGiWrdurZw5c+rQoUNauHChatasqUmTJunSpUvq2LGjihUrpldeeUWSNGLECH399dfq3LmzfvnlF/cHhUqVKmn58uV68803lTdvXhUuXDjBYdKu16xZM82fP99j1HHOnDnKkSOHatSokehlHn30Ub333ntauHCh6tevr/z586tly5YqV66csmTJouXLl2vDhg164403JF2bqz1lyhQ98sgjKl++vDp37qw8efLo119/1Y4dO9zhavLkyapVq5bKli2rrl276t5779XJkye1du1aHTlyRFu3bk3S/ZszZ071799fY8aMUdOmTdWkSRNt2bJFixYt8um/z5999llNmjRJbdq0Ue/evZUnTx7NmTPH/aMQfzeaXqxYMc2aNUvt2rVT2bJlE/xC2R9//KGPPvrotn79Kym3ecCAAfrqq6/UtGlTderUSZUqVVJ0dLR++eUXff755zpw4MBt3U9XrlzR6tWr9fzzz//ttgCHAsM/Xvwhf252Onz4sJmZnTx50rp3724FChQwf39/Cw0NtQYNGti7777rUe/LL7+0UqVKmZ+fn8dhqc6fP29t27a1kJAQk+RxWLDLly/buHHjrHTp0hYQEGDZsmWzSpUq2YgRIywyMtK9naRbHg7pRvGHGYo/ZcmSxYoVK2ZPPfWULV26NNHL3HgosJdfftmqVq1qISEhlilTJitRooS98sordvnyZfc2V69etZ49e1rOnDnN5XK5D3MVf3if1157LcH13OxQYIGBgbZ3715r1KiRZc6c2XLnzm3Dhg2z2NhYj8ufPn3aWrRoYZkzZ7Zs2bLZs88+a9u3b09Q82a9xd+f1x8KzMxs8+bN1rhxY8uSJYtlzpzZ6tWrZz/++KPHNjc7fNzNDlF2o5sdCiyxx/bGx+Pv3HgosOt7a9y4sQUHB1vGjBmtSJEi1qlTJ9u4caOZ/e8QVzceZmnjxo3m5+dn//rXv9zLfv31V3vwwQctU6ZMCQ79lJjNmzebJPfh7k6ePGl+fn7Wvn37m17mwoULljlzZnvssccsJibGBgwYYOXKlbOsWbNaYGCglStXzt55550El1uzZo01bNjQvd3999+f4FBqe/futQ4dOlhoaKj5+/tbvnz5rGnTpvb555+7t0nKYxwbG2sjRoywPHnyWKZMmaxu3bq2ffv2BI/dzQ4Fltjh+jp27Jjg0IH79u2ziIgIy5Qpk+XMmdP+/e9/2xdffGGSbN26dTe9L6+3bds2a9OmjeXJk8f9OtamTRv75ZdfEmwbv5/GH4Lverd7m82uHY5u8ODBVrRoUcuQIYPdc889VqNGDXv99dfdryO3eq0wM1u0aJFJst27d9/W7cQ/m8vMh7PiAQBIRIMGDZQ3b97b+jEN3L7x48erb9++OnLkiMdRHpymefPmcrlcmj9/fkq3gjSAcAsAuOPWr1+v2rVra/fu3e4vJCFpLl686HE0gUuXLqlChQqKjY11f+nSiXbt2qWyZcvq559/vuWh3oB4hFsAANKAhx9+WAULFlT58uXdc+l37NihOXPmqG3btindHpBq8IUyAADSgMaNG+s///mP5syZo9jYWJUqVUoff/yxnnzyyZRuDUhVGLkFAACAY3CcWwAAADgG4RYAAACOwZxbXfu5z2PHjilr1qx39edPAQAAcHvMTH/99Zfy5s2rdOluPj5LuJV07NixNPmb8QAAAP80hw8fVv78+W+6nnArKWvWrJKu3Vlp8bfjAQAAnC4qKkoFChRw57abIdzqf7/JHRQURLgFAABIxf5uCilfKAMAAIBjEG4BAADgGCkabr/77js98sgjyps3r1wulxYsWHDTbZ977jm5XC6NHz/eY/nZs2fVrl07BQUFKSQkRF26dNH58+fvbOMAAABIlVI03EZHR6tcuXKaPHnyLbebP3++1q1bp7x58yZY165dO+3YsUPLli3TN998o++++07dunW7Uy0DAAAgFUvRL5Q9/PDDevjhh2+5zdGjR9WzZ08tWbJEERERHut27dqlxYsXa8OGDapcubIk6e2331aTJk30+uuvJxqGAQAA4Fypes5tXFyc2rdvrwEDBqh06dIJ1q9du1YhISHuYCtJ4eHhSpcundavX3/TujExMYqKivI4AQAAIO1L1eF23Lhx8vPzU69evRJdf+LECeXKlctjmZ+fn7Jnz64TJ07ctO6YMWMUHBzsPvEDDgAAAM6QasPtpk2bNGHCBM2cOdPnP4k7ePBgRUZGuk+HDx/2aX0AAACkjFQbbr///nudOnVKBQsWlJ+fn/z8/HTw4EH9+9//VlhYmCQpNDRUp06d8rjc1atXdfbsWYWGht60dkBAgPsHG/jhBgAAAOdItb9Q1r59e4WHh3ssa9y4sdq3b6/OnTtLkqpXr65z585p06ZNqlSpkiRp5cqViouLU7Vq1e56zwAAAEhZKRpuz58/rz179rjP79+/Xz///LOyZ8+uggULKkeOHB7b+/v7KzQ0VPfdd58kqWTJknrooYfUtWtXTZ06VVeuXFGPHj3UunVrjpQAAADwD5Si0xI2btyoChUqqEKFCpKkfv36qUKFCho6dOht15gzZ45KlCihBg0aqEmTJqpVq5befffdO9UyAAAAUjGXmVlKN5HSoqKiFBwcrMjISObfAgAApEK3m9dS7RfKAAAAgKQi3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxUu0vlAHeChu00Cd1DoyN8EkdAABw9zByCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwjBQNt999950eeeQR5c2bVy6XSwsWLHCvu3LligYOHKiyZcsqMDBQefPmVYcOHXTs2DGPGmfPnlW7du0UFBSkkJAQdenSRefPn7/LtwQAAACpQYqG2+joaJUrV06TJ09OsO7ChQvavHmzhgwZos2bN2vevHn67bff9Oijj3ps165dO+3YsUPLli3TN998o++++07dunW7WzcBAAAAqYjLzCylm5Akl8ul+fPnq3nz5jfdZsOGDapataoOHjyoggULateuXSpVqpQ2bNigypUrS5IWL16sJk2a6MiRI8qbN+9tXXdUVJSCg4MVGRmpoKAgX9wcpKCwQQt9UufA2Aif1AEAAMl3u3ktTc25jYyMlMvlUkhIiCRp7dq1CgkJcQdbSQoPD1e6dOm0fv36m9aJiYlRVFSUxwkAAABpX5oJt5cuXdLAgQPVpk0bd1o/ceKEcuXK5bGdn5+fsmfPrhMnTty01pgxYxQcHOw+FShQ4I72DgAAgLsjTYTbK1euqFWrVjIzTZkyJdn1Bg8erMjISPfp8OHDPugSAAAAKc0vpRv4O/HB9uDBg1q5cqXHHIvQ0FCdOnXKY/urV6/q7NmzCg0NvWnNgIAABQQE3LGeAQAAkDJS9chtfLDdvXu3li9frhw5cnisr169us6dO6dNmza5l61cuVJxcXGqVq3a3W4XAAAAKSxFR27Pnz+vPXv2uM/v379fP//8s7Jnz648efKoZcuW2rx5s7755hvFxsa659Fmz55dGTJkUMmSJfXQQw+pa9eumjp1qq5cuaIePXqodevWt32kBAAAADhHiobbjRs3ql69eu7z/fr1kyR17NhRw4cP11dffSVJKl++vMflVq1apbp160qS5syZox49eqhBgwZKly6dWrRooYkTJ96V/gEAAJC6pGi4rVu3rm51mN3bOQRv9uzZNXfuXF+2BQAAgDQq1X+hDAAA+IYvfuSGH7hBapeqv1AGAAAAJAXhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGCkabr/77js98sgjyps3r1wulxYsWOCx3sw0dOhQ5cmTR5kyZVJ4eLh2797tsc3Zs2fVrl07BQUFKSQkRF26dNH58+fv4q0AAABAapGi4TY6OlrlypXT5MmTE13/6quvauLEiZo6darWr1+vwMBANW7cWJcuXXJv065dO+3YsUPLli3TN998o++++07dunW7WzcBAAAAqYhfSl75ww8/rIcffjjRdWam8ePH6//+7//UrFkzSdLs2bOVO3duLViwQK1bt9auXbu0ePFibdiwQZUrV5Ykvf3222rSpIlef/115c2b967dFgAAAKS8VDvndv/+/Tpx4oTCw8Pdy4KDg1WtWjWtXbtWkrR27VqFhIS4g60khYeHK126dFq/fv1d7xkAAAApK0VHbm/lxIkTkqTcuXN7LM+dO7d73YkTJ5QrVy6P9X5+fsqePbt7m8TExMQoJibGfT4qKspXbQMAACAFpdqR2ztpzJgxCg4Odp8KFCiQ0i0BAADAB1JtuA0NDZUknTx50mP5yZMn3etCQ0N16tQpj/VXr17V2bNn3dskZvDgwYqMjHSfDh8+7OPuAQAAkBJSbbgtXLiwQkNDtWLFCveyqKgorV+/XtWrV5ckVa9eXefOndOmTZvc26xcuVJxcXGqVq3aTWsHBAQoKCjI4wQAAIC0L0Xn3J4/f1579uxxn9+/f79+/vlnZc+eXQULFlSfPn308ssvq1ixYipcuLCGDBmivHnzqnnz5pKkkiVL6qGHHlLXrl01depUXblyRT169FDr1q05UgIAAMA/UIqG240bN6pevXru8/369ZMkdezYUTNnztQLL7yg6OhodevWTefOnVOtWrW0ePFiZcyY0X2ZOXPmqEePHmrQoIHSpUunFi1aaOLEiXf9tgAAACDluczMUrqJlBYVFaXg4GBFRkYyRcEBwgYt9EmdA2MjfFIHAFILX7w+8tqIlHK7eS3VzrkFAAAAkopwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDMItAAAAHINwCwAAAMcg3AIAAMAxCLcAAABwDL+UbgAAkDaFDVqY7BoHxkb4oBMA+B9GbgEAAOAYhFsAAAA4BuEWAAAAjkG4BQAAgGMQbgEAAOAYhFsAAAA4BuEWAAAAjkG4BQAAgGMQbgEAAOAYhFsAAAA4BuEWAAAAjkG4BQAAgGMQbgEAAOAYhFsAAAA4BuEWAAAAjkG4BQAAgGMQbgEAAOAYhFsAAAA4BuEWAAAAjkG4BQAAgGMQbgEAAOAYhFsAAAA4BuEWAAAAjkG4BQAAgGMQbgEAAOAYhFsAAAA4BuEWAAAAjkG4BQAAgGMQbgEAAOAYfindwD9V2KCFya5xYGyEDzoBAABwDkZuAQAA4BiEWwAAADgG4RYAAACOQbgFAACAYxBuAQAA4BiEWwAAADiGV+F23759vu4DAAAASDavwm3RokVVr149ffjhh7p06ZKve3KLjY3VkCFDVLhwYWXKlElFihTRqFGjZGbubcxMQ4cOVZ48eZQpUyaFh4dr9+7dd6wnAAAApF5e/YjD5s2bNWPGDPXr1089evTQk08+qS5duqhq1ao+bW7cuHGaMmWKZs2apdKlS2vjxo3q3LmzgoOD1atXL0nSq6++qokTJ2rWrFkqXLiwhgwZosaNG2vnzp3KmDGjT/sBAOBu8MUP/Uj82A/+mbwauS1fvrwmTJigY8eOafr06Tp+/Lhq1aqlMmXK6M0339Tp06d90tyPP/6oZs2aKSIiQmFhYWrZsqUaNWqkn376SdK1Udvx48fr//7v/9SsWTPdf//9mj17to4dO6YFCxb4pAcAAACkHcn6Qpmfn58ef/xxffbZZxo3bpz27Nmj/v37q0CBAurQoYOOHz+erOZq1KihFStW6Pfff5ckbd26VWvWrNHDDz8sSdq/f79OnDih8PBw92WCg4NVrVo1rV279qZ1Y2JiFBUV5XECAABA2pescLtx40Y9//zzypMnj9588031799fe/fu1bJly3Ts2DE1a9YsWc0NGjRIrVu3VokSJeTv768KFSqoT58+ateunSTpxIkTkqTcuXN7XC537tzudYkZM2aMgoOD3acCBQokq08AAACkDl7NuX3zzTc1Y8YM/fbbb2rSpIlmz56tJk2aKF26a1m5cOHCmjlzpsLCwpLV3Keffqo5c+Zo7ty5Kl26tH7++Wf16dNHefPmVceOHb2uO3jwYPXr1899PioqioALAADgAF6F2ylTpujpp59Wp06dlCdPnkS3yZUrl95///1kNTdgwAD36K0klS1bVgcPHtSYMWPUsWNHhYaGSpJOnjzp0cfJkydVvnz5m9YNCAhQQEBAsnoDAABA6uNVuL2dQ21lyJAhWaOrknThwgX3aHC89OnTKy4uTtK1EeLQ0FCtWLHCHWajoqK0fv16/etf/0rWdQMAACDt8SrczpgxQ1myZNETTzzhsfyzzz7ThQsXkh1q4z3yyCN65ZVXVLBgQZUuXVpbtmzRm2++qaefflqS5HK51KdPH7388ssqVqyY+1BgefPmVfPmzX3SAwAAANIOr75QNmbMGN1zzz0JlufKlUujR49OdlPx3n77bbVs2VLPP/+8SpYsqf79++vZZ5/VqFGj3Nu88MIL6tmzp7p166YqVaro/PnzWrx4Mce4BQAA+AfyauT20KFDKly4cILlhQoV0qFDh5LdVLysWbNq/PjxGj9+/E23cblcGjlypEaOHOmz6wUAAEDa5NXIba5cubRt27YEy7du3aocOXIkuykAAADAG16F2zZt2qhXr15atWqVYmNjFRsbq5UrV6p3797uIxsAAAAAd5tX0xJGjRqlAwcOqEGDBvLzu1YiLi5OHTp08OmcWwAAACApvAq3GTJk0CeffKJRo0Zp69atypQpk8qWLatChQr5uj8AAADgtnkVbuMVL15cxYsX91UvAAAAQLJ4FW5jY2M1c+ZMrVixQqdOnXL/qEK8lStX+qQ5AAAAICm8Cre9e/fWzJkzFRERoTJlysjlcvm6LwDJFDZoYbJrHBgb4YNOAAC4e7wKtx9//LE+/fRTNWnSxNf9AAAAAF7z6lBgGTJkUNGiRX3dCwAAAJAsXoXbf//735owYYLMzNf9AAAAAF7zalrCmjVrtGrVKi1atEilS5eWv7+/x/p58+b5pDkAAAAgKbwKtyEhIXrsscd83QsAAACQLF6F2xkzZvi6DwAAACDZvJpzK0lXr17V8uXLNW3aNP3111+SpGPHjun8+fM+aw4AAABICq9Gbg8ePKiHHnpIhw4dUkxMjBo2bKisWbNq3LhxiomJ0dSpU33dJwAAAPC3vBq57d27typXrqw///xTmTJlci9/7LHHtGLFCp81BwAAACSFVyO333//vX788UdlyJDBY3lYWJiOHj3qk8YAAACApPJq5DYuLk6xsbEJlh85ckRZs2ZNdlMAAACAN7wKt40aNdL48ePd510ul86fP69hw4bxk7wAAABIMV5NS3jjjTfUuHFjlSpVSpcuXVLbtm21e/du3XPPPfroo4983SMAAABwW7wKt/nz59fWrVv18ccfa9u2bTp//ry6dOmidu3aeXzBDAAAALibvAq3kuTn56ennnrKl70AAAAAyeJVuJ09e/Yt13fo0MGrZgAAAIDk8Crc9u7d2+P8lStXdOHCBWXIkEGZM2cm3AIAACBFeHW0hD///NPjdP78ef3222+qVasWXygDAABAivEq3CamWLFiGjt2bIJRXQAAAOBu8Vm4la59yezYsWO+LAkAAADcNq/m3H711Vce581Mx48f16RJk1SzZk2fNAYAAAAklVfhtnnz5h7nXS6XcubMqfr16+uNN97wRV8AAABAknkVbuPi4nzdBwAAAJBsPp1zCwAAAKQkr0Zu+/Xrd9vbvvnmm95cBQAAAJBkXoXbLVu2aMuWLbpy5Yruu+8+SdLvv/+u9OnTq2LFiu7tXC6Xb7oEACAVChu00Cd1DoyN8EkdAF6G20ceeURZs2bVrFmzlC1bNknXftihc+fOql27tv7973/7tEkAAADgdng15/aNN97QmDFj3MFWkrJly6aXX36ZoyUAAAAgxXgVbqOionT69OkEy0+fPq2//vor2U0BAAAA3vAq3D722GPq3Lmz5s2bpyNHjujIkSP64osv1KVLFz3++OO+7hEAAAC4LV7NuZ06dar69++vtm3b6sqVK9cK+fmpS5cueu2113zaIAAAAHC7vAq3mTNn1jvvvKPXXntNe/fulSQVKVJEgYGBPm0OAAAASIpk/YjD8ePHdfz4cRUrVkyBgYEyM1/1BQAAACSZV+H2zJkzatCggYoXL64mTZro+PHjkqQuXbpwGDAAAACkGK/Cbd++feXv769Dhw4pc+bM7uVPPvmkFi9e7LPmAAAAgKTwas7t0qVLtWTJEuXPn99jebFixXTw4EGfNAYA8A1f/IoWv6AFIK3wauQ2OjraY8Q23tmzZxUQEJDspgAAAABveBVua9eurdmzZ7vPu1wuxcXF6dVXX1W9evV81hwAAACQFF5NS3j11VfVoEEDbdy4UZcvX9YLL7ygHTt26OzZs/rhhx983SMAAABwW7wauS1Tpox+//131apVS82aNVN0dLQef/xxbdmyRUWKFPF1jwAAAMBtSfLI7ZUrV/TQQw9p6tSpeumll+5ETwAAAIBXkjxy6+/vr23btt2JXgAAAIBk8WpawlNPPaX333/f170AAAAAyeLVF8quXr2q6dOna/ny5apUqZICAwM91r/55ps+aQ4AAABIiiSF23379iksLEzbt29XxYoVJUm///67xzYul8t33QEAAABJkKRwW6xYMR0/flyrVq2SdO3ndidOnKjcuXPfkeYAAACApEjSnFsz8zi/aNEiRUdH+7QhAAAAwFtefaEs3o1h9044evSonnrqKeXIkUOZMmVS2bJltXHjRo8ehg4dqjx58ihTpkwKDw/X7t2773hfAAAA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Je/DX2RkpOrWratVq1b5qj1JUkxMjD7//HOtXr3ap3U//vhjPfTQQ9q5c6cOHTrk09p3jSHVmD9/voWFhVnJkiUtU6ZM9vTTT9uxY8eSXGfhwoX2888/u89/8cUXVq1aNStSpIg1b97c3n///WT3+ttvv1nhwoXtnXfeSXateHFxcWZm9sknn1irVq2sevXqljlzZitatKgtXLgw2fU///xzCw4OttatW1uNGjWscuXK1q1bN69qXbhwwerXr2/PPPOMlSpVytq1a+ded/Xq1WT32r9/f2vRooXVqFHDsmfPbvfdd59X98GN+8K8efOsZs2aVrx4cRs+fLht3rw52b1GRkZauXLlrF27drZjx45k17vRzJkz7cEHH7SOHTvaxYsXvaqxcOFC27p1q5n9bz974okn7I033vBZn5s3b7aKFSvaM888Y9u3b/dZ3Xjz58+3LFmyWNGiRS0gIMCmTZtmUVFRya7p6/3hs88+sxw5clj58uUtXbp0Vr16dfvss8+SXXfgwIFWokQJu+eee6xOnTo+e+3p37+/PfbYY1alShULCQnx+rl2vd27d9vQoUNt8ODBZva/fS65vvnmG8uUKZO99957Xr033OjPP/+0atWqmcvlsn/961/u5bGxscmuHW/69OmWL18+69Wrl+3cudNndc3Mdu3aZYGBgTZz5kyf1bxw4YL77wcffNDq1KmT7JqXLl2yypUr24wZM5JdK178PrVx40YLCgqyL7/80id1P/vsM3O5XDZ//nxr27atDRs2zMx88752NxFuU4klS5ZYSEiITZs2zWJiYmzRokXmcrmsdevWdvjw4duuc+LECStcuLB17tzZ9u7dazt27LCsWbPayy+/bGPHjrXnn3/eMmTIYKNHj05Wv8uWLbPixYvbgQMH3Mt88QK+bt06y5w5s73//vv266+/2u7du61u3bpWvXp1++9//+t13Z07d1rBggVt6tSp7vOZMmVyv/l4Izo62szM3n//fbvvvvt8FnBnzJhhISEhtmnTJjt79qwdP37cGjVqZNWrV7dFixbddp3r94U9e/bYrl27LCQkxEaNGmW9e/e2ihUrWosWLez777/3utd4GzZssKpVq/o02F2/P82YMcPrgHv9/XB9+K5du7a9+eabPuk13p0IuHFxcXbmzBmrWbOmTZs2zXbv3m2jR482l8tlo0ePtnPnznlVd9OmTRYcHGwjR4702f6wefNmu+eee+w///mPnT171k6cOGEdO3a0Bx980ObNm+d13Y8++shCQ0NtwYIFNnPmTBswYID5+/vbmDFjvK5pZjZr1izLli2bbdq0yf744w87evSoNWzY0B544IEkPdeuFxkZaZUrV7acOXNa37593cuT+/p48eJFe+KJJ+zFF180s2uvP3v37rVXXnnF5s+f79UHncuXL1v9+vWtfPny1rBhQ/vwww/d63wZcGfNmmX33Xefde/e3WcBN76/Pn36WIsWLezMmTPJrrl48WJ76qmnbMmSJWZmdvDgQStatKiNHDnSq3rXv1Z16tTJ/R4RFxfns/s3MjLSWrVqZb179zaz5D1u8+bNM5fLZdOnTzczs6ZNm7o/9PjqA9rdQrhNBSIjI61bt242YsQIMzPbt2+fFSlSxFq2bGkhISHWrFkzO3jw4G3X27Rpk1WuXNm6d+9uL730kvXv39/juiZNmmQZM2a02bNne93z/PnzrUCBAu5we/0T6ttvv7VNmzZ5VXfatGlWqlQpj0/PR44csVq1alnRokXdLzpJtWTJEqtQoYKZXbt/CxUq5DFq622/ZmZ//fWXTZ8+3UqUKOGTgPvSSy9ZrVq1LDY21n2/HjlyxKpVq2ZFixZN0ptu/L7Qo0cPGzVqlI0aNcq97ptvvrF69epZ8+bNfRJw71Swi5ecgLtp0yarUqWKPfPMM/bLL7+YmVmjRo3cb+aXL182M/O4z73l6/vh4sWLduHCBXvxxRft7Nmz7uUTJkxwB9zIyMgk1dyzZ4+NGjXKXn75ZfcyX+wPc+bMsVKlSllkZKT7sTtx4oS1a9fOateubTExMUmuuWrVKnvmmWc8PohERUXZ22+/bYGBgckaFR46dKjVrFnTYmNj3f0eOXLEqlatmuTn2vU2b95sxYoVs/Lly7v/Y5BcFy5csMqVK1vPnj3tzJkz1qNHD6tTp47lz5/fcufO7fHcTopLly7Z8ePHLSIiwurVq+cRcM28ex3bu3evHT161GPZjBkzrESJEvavf/3Lfv/9d696/fbbb+2DDz7weI5+8cUXliNHDvc+6+3zNy4uzrp27Woul8uyZ89uw4YNs3379tkrr7xirVq1SvJ7xKJFi6xOnToWERFhY8eOtbp161rbtm3t4sWL7tcbb7z55pv2+uuvewx6vfvuuxYYGGh79uxx3xZv/Pe//7U5c+a4z/fs2dPat2/vsc3u3bu9qn23EW5TgZiYGPv0009tz549dubMGatQoYJ16dLFzK6NWLhcLmvSpIkdOXLktmtu2rTJqlataoUKFbLu3bt7rDt37px17tzZ2rZta5cvX/bqibBv3z7LlCmTexThen369LGhQ4d69QSePXu23XfffXbq1Ckz+1/o2LZtm2XJksXuv/9+r95wli5dak2aNLH9+/db/vz5rVu3bu4X7R9++MEGDhxohw4dSnLdeOfPn7fp06dbmTJl7NFHH/WqRvzjMHLkSKtcubI7wMXfBytXrrTMmTNbgwYNbMWKFbdd9/p9YeDAgR7rvv76a6tbt661bNnSVq5c6VXf17s+2PlqisL1++f06dPtwQcftE6dOtmlS5e86u3pp5+2X375xZ588slE78fz588nu2df3Q8LFiywxo0bW6lSpaxEiRIJgtKECRPM39/fhgwZctsBN35kMVeuXDZo0CCPdcndHz766CMrUqSIHT9+3MzMrly5YmZm+/fvN5fLZcuWLUtSvePHj1uRIkXc/3263tmzZ6158+bWq1cvM0vaG3r8tmPGjLHKlSu7P0zHP9eWL19umTJlsnr16tlXX32VpJ7jbd261e6//36fftibNWuWZcqUyYKCguyxxx6zWbNmmdm119x69eol64PZ3r17LSIiwho0aGAffPCBmV37oN21a9ck3bdnz561PHny2Isvvphg6sR//vMf8/f3t549e9q2bduS1F9MTIz16dPHXC6XPf744/baa6+513Xt2tVq1Khhf/31V5Jq3mj9+vXWpk0be+WVV6xy5cr23HPP2TPPPGMlS5a0t956y8xufz9bvXq1jRs3zlq3bm0tW7a0/Pnzm8vlskaNGlmZMmWse/fuNnDgwCR9kLxw4YINHDjQgoODrX79+vb000/bmTNn7OLFi9auXTt7/vnnkxWc48XfxldeecWqVavmfq8cNmyYVapUKckfplMC4TaViA8yH3zwgVWvXt39qeyjjz6yunXrWqFChZI0emt27cU1LCzMSpQoYVu2bPFY9+KLL1r58uWT9UR4//33zd/f3wYMGGC//PKL7dy501544QULCQmxXbt2eVVz9+7dljFjRhsyZIjH8o0bN1qdOnWsTZs2Sb4fzK69uWbOnNlcLpf7zTBer169rFGjRh6jYt44f/68vfPOO1a1atUEoxZJsW3bNkufPr0NHz7cY/nixYutRYsWVr9+fQsPD0/SY7d161YrXLiw1axZM8Eb7cKFC61ChQrWrl07jxFzb23evNmqVq1qrVu39no/uNH1byjxc3CHDh2a5DfzzZs3W+XKla1jx46WJUsWu/feey08PNwaNmxo9evXtzp16linTp1Sxf2wYcMGCwoKsueee846depk/v7+1rt3b4+pQGZmY8eOtWzZstkff/yRpN6KFy/u8/1hz549FhAQYP/3f//nsfzAgQNWtmxZW7duXZLqmV3bd4sUKWIVK1ZMMCe4S5cu9vDDDye5Zrzt27ebn59fgufawoULrXnz5vb4449b7dq1vZ6Deyc+7O3YscOWLl1qZv8bpezevbt16NAhyR/4brRv3z577LHHrEyZMlalShULCgry6jFbtWqVhYWF2YgRIxK8FlaqVMmCg4PthRde8Gokf+fOnfavf/3LSpQoYSVKlLDp06fbhAkT7NFHH/XqPw4rVqyw9957z8yu3Z89evSwp59+2qKiouydd96xZ555xlwul7lcLq/ui3jLly+3kJAQe/3112348OHWqVMnK126tHu0NSkOHz5s7777rlWsWNFKlChhHTp0sIiICIuIiHAH/ORMI4i/7KRJk+y+++4zM7Phw4ebv7+/bdy40eu6dxPhNpUZOXKklSlTxh20Bg0aZG+//bbXIXTbtm1WtmxZ69Spk8cXi7p162bh4eHJGqWKjY21Tz/91LJly2b58+e3okWL2n333ZfsL6V88MEH5u/vby+++KLt37/f/vzzTxsyZIh17NgxWZ8YFyxYYIGBgTZw4ED7/fff7ZdffrH+/ftbSEiI+1/VyRUdHe31HMjrzZgxw/3BYePGje5RlVdeecV27tzp1SjY1q1brXz58tatW7cEgWbJkiUJQlNy/PTTT1anTh2ffOkl3vUv1v3797datWp59ea4adMmK1u2rJUrV87atm1rs2bNsgkTJtiwYcNszJgxPv0ymLf3w549e2zo0KEec0rfeecdy58/vw0aNCjBY+XNB7M7tT98+OGHliFDBhs0aJDt3r3bTp48aS+99JIVKFDA6w99W7dutXLlylmHDh3cH9SjoqKsRo0a1rVrV69qxot/rvXv399++ukn27Nnj0VERNiQIUPs2LFj1qpVKytbtqzXU6Lu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",
-      "text/plain": [
-       "<Figure size 800x600 with 1 Axes>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
+   "outputs": [],
    "source": [
     "# Put your code here\n"
    ]
@@ -316,121 +257,29 @@
     "<img src=\"340px-English-slf.png\" alt=\"Letter Frequencies English\" width=\"500\" height=\"auto\">\n",
     "This should look roughly similar, as we are using an English text.\n",
     "\n",
-    "Now we use our cypher using a random key. Can you figure out the correct key from the frequency analysis of the cypher text and the standard English letter distribution? Try out your guess by decoding the cypher text!"
+    "Now we use our encryption with a random key. Can you figure out the correct key from the frequency analysis of the cypher text and the standard English letter distribution? Try out your guess by decoding the cypher text!"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": null,
    "id": "8ae904cd",
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAArcAAAIpCAYAAAC48RBEAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8WgzjOAAAACXBIWXMAAA9hAAAPYQGoP6dpAABZ+ElEQVR4nO3deXhMd///8deQBSEJitijllprp7baghYtLVVLbVXau3Y3RXvbW0tXlKK9a2vpji5uO9VqUVuppa1930olFQTJ+/eHX+ZrJFQmQ5LT5+O65roy55x5z3tmzsy85pPPnHGZmQkAAABwgHQp3QAAAADgK4RbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAAAAOAbhFgAAAI5BuAUAAIBjEG4BAADgGIRbAB7Cw8PVqVOnO349Bw4ckMvl0syZM93LOnXqpMyZM9/x647ncrk0fPjwu3Z98YYPHy6Xy3XXrzcl/fTTTwoICNDBgwdTupW75sbn0rfffiuXy6Vvv/02xXq60+7E68fOnTvl5+en7du3+7QunItwi3+8mTNnyuVyaePGjcmudezYMQ0fPlw///xzgnVz587V+PHjk30dSVGnTh25XC65XC6lS5dOwcHBuu+++9S+fXstW7bMZ9fzv//9L0VC4u1Izb35wvWP8a1OvrwPRo8erQULFiTpMi+99JLatGmjggULJrq+SpUqcrlcmjJlig86xM3s2LFDTz31lPLmzavAwEDlyZNH7dq1044dO1K6tZsqWbKkmjRpoqFDh6Z0K0gjXGZmKd0EkJJmzpypzp07a8OGDapUqVKyam3cuFGVK1fWjBkzEoxeNG3aVNu3b9eBAweSdR1JUadOHe3du1djxoyRJEVHR2vPnj2aN2+e9u3bp1atWunDDz+Uv7+/+zIxMTFKly6dx7K/06NHD02ePFlJeTkxM8XExMjf31/p06eXdG3k9vPPP9f58+dvu05yert06ZL8/Pzk5+fns+u7HVevXtXVq1eVIUOGZNdatmyZTp486T6/YcMGTZw4US+++KJKlCjhXn7//ffr/vvvT/b1SVLmzJnVsmVLj1H3W/n5559Vvnx5/fjjj6pWrVqC9bt371axYsUUHh6uvHnzas2aNT7pM6WFh4erTp067vspLi5Oly9fVkBAgNKlu/tjS/PmzVObNm2ULVs2denSRYUKFdKBAwf0/vvv68yZM/r444/12GOPJes6brzNvrJo0SI1btxYe/bsUeHChX1aG85zd1/RAfhU/JvlrUJSSEiInnrqKY9lY8eOVa9evfTOO+8oPDxc48aNc68LDAy8Y/1K14JdXFycAgICfBLukiOlrt+XgbpBgwYe5zNkyKCJEyeqQYMGqlOnjk+uI7lmzJihAgUK6IEHHkh0/YcffqicOXPqjTfeUMuWLXXgwAGFh4ff3SbvgnTp0qXYPrd37161b99e9957r7777jvlyJHDva53796qVauW2rdvr23btunee++9aZ3o6GgFBQXdjZY9XisiIiKUNWtWzZo1SyNHjrwr14+0i2kJwG06evSonn76aeXKlUuBgYEqVaqUpk+f7l7/7bffqnLlypKkzp07u/8dPHPmTNWpU0cLFy7UwYMH3cuvf/OOiYnRsGHDVKRIEQUGBip//vx64YUXFBMT49GDy+VSjx49NGfOHJUqVUqBgYFavHhxkm9L+vTpNXHiRJUsWVKTJk1SZGSke92Nc+auXLmiESNGqGjRosqQIYOyZ8+umjVruqc1dOrUSZMnT3b3F3+S/m9e7euvv67x48ercOHCCgwM1M6dOxOdcxtv3759atSokYKCgpQnTx6NHDnSY+T1ZnMXb6x5q97il9347/otW7bo4YcfVnBwsDJnzqz69etr3bp1HtvET2X54Ycf1K9fP+XIkUNBQUF67LHHdPr06b+9/xObcxv/2C5YsEClS5d272PePL6JWbRokWrVqqWgoCBlyZJFTZo08fhX9MqVK5UuXboE//qdO3eux3QBl8ul6OhozZo1y31//t0cywULFqhevXo3nWc8d+5ctWzZUk2bNlVISIjmzp2bYJu//vpLffr0UXh4uAIDA5UzZ041aNBAmzdv9thu/fr1aty4sbJmzaqgoCDdf//9mjBhgsc2v/76q1q2bKls2bIpQ4YMqlSpkr766iuPbZLyGJuZXn75ZeXLl0+ZMmVS3bp1E/03f2L7bZ06dVS6dGnt3LlTdevWVaZMmZQ3b169+uqrCS5/8OBBPfroowoKClLOnDnVt29fLVmy5Lbm8b722mu6cOGC3n33XY9gK0n33HOPpk2bpujoaI/rjd9Pd+7cqbZt2ypr1qyqWbNmkm6zJJ07d059+vRR/vz5FRgYqCJFimjcuHGKi4tzb3Or1wpJ8vf3V506dfTll1/e8nYCEiO3wG05efKkHnjgAXcAyZEjhxYtWqQuXbooKipKffr0UYkSJTRy5EgNHTpU3bp1U61atSRJ1atXV968eRUZGakjR47orbfekiT3F6fi4uL06KOPas2aNerWrZtKlCihX375RW+99ZZ+//33BHMbV65cqU8//VQ9evTQPffc4/UIV/r06dWmTRsNGTJEa9asUZMmTRLdbvjw4RozZoyeeeYZValSRVFRUdq4caM2b96sBg0a6Nlnn9WxY8e0bNkyffDBB4nWmDFjhi5duqRu3bopMDBQ2bJl83hju15sbKweeughPfDAA3r11Ve1ePFiDRs2TFevXk3yiM3t9Ha9HTt2qFatWgoODtYLL7wgf39/TZs2TXXq1NHq1atVtWpVj+179uyprFmzatiwYTpw4IDGjx+vHj166JNPPklSn/HWrFmjefPm6fnnn1eWLFk0ceJEtWjRQocOHVL27Nm9qilJH3zwgTp27KhGjRpp3LhxunDhgqZMmaKaNWtqy5YtCg8PV7169fT8889rzJgxat68uSpUqKDjx4+rZ8+eioiI0HPPPeeuFb8vdOvWTZJu+W/io0eP6tChQ6pQoUKi69evX689e/ZoxowZCggI0OOPP645c+boxRdf9Njuueee0+eff64ePXqoZMmSOnPmjNasWaNdu3a5ay9btkxNmzZV7ty51bt3b4WFhWnXrl365ptv1Lt3b0nXHuMaNWoob968GjRokIKCgvTpp5+qefPm+uKLLxL8W/52HuOhQ4fq5ZdfVuPGjdW4cWNt3rxZDRs21OXLl2/r8fnzzz/10EMP6fHHH1erVq30+eefa+DAgSpTpowefvhhSddGTOvVq6fjx4+7b9vcuXO1atWq27qOr7/+WuHh4e7XpRs9+OCDCg8P18KFCxOse+KJJ1S0aFGNHj3a/SHzdm/zhQsXVLt2bR09elTPPvusChQooB9//FGDBw/W8ePHE3wPIbHXingVK1bUl19+qaioKAUHB9/W7cY/lAH/cDNmzDBJtmHDhptu06VLF8udO7f98ccfHstbt25tISEhduHCBTMz27Bhg0myGTNmJKjRpEkTK1iwYILlH3zwgaVLl86+//57j+VTp041SfbDDz+4l0mydOnS2Y4dO27rttWuXdtKlSp10/Xz5883STZhwgT3soIFC1rHjh3d58uW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1qZNG8udO7f7daxNmzb2yy+/JNg2fj+NPwTf9W73NptdOxzd4MGDrUiRIhYQEGD33HOPVa9e3V5//XX368itXivMzBYtWmSSbPfu3bd1O/HP5jLz4ax4AAASUb9+feXJk+e2fkwDt2/8+PHq27evjhw54nGUB6dp3ry5XC6X5s+fn9KtIA0g3AIA7rj169erVq1a2r17t/sLSUiaixcvehxN4NKlSypfvrxiY2PdX7p0ol27dqlMmTL6+eefb3moNyAe4RYAgDTg4YcfVoECBVSuXDn3XPodO3Zozpw5atu2bUq3B6QafKEMAIA0oFGjRvrvf/+rOXPmKDY2ViVLltTHH3+sJ598MqVbA1IVRm4BAADgGBznFgAAAI5BuAUAAIBjMOdW137u89ixY8qSJctd/flTAAAA3B4z019//aU8efIoXbqbj88SbiUdO3YsTf5mPAAAwD/N4cOHlS9fvpuuJ9xKypIli6Rrd1Za/O14AAAAp4uKilL+/Pndue1mCLf6v9/kDg4OJtwCAACkYn83hZQvlAEAAMAxCLcAAABwjBQNt999950eeeQR5cmTRy6XSwsWLLjpts8995xcLpfGjx/vsfzs2bNq166dgoODFRoaqi5duuj8+fN3tnEAAACkSikabqOjo1W2bFlNnjz5ltvNnz9f69atU548eRKsa9eunXbs2KFly5bpm2++0Xfffadu3brdqZYBAACQiqXoF8oefvhhPfzww7fc5ujRo+rZs6eWLFmiJk2aeKzbtWuXFi9erA0bNqhSpUqSpLfffluNGzfW66+/nmgYBgAAgHOl6jm3cXFxat++vQYMGKBSpUolWL927VqFhoa6g60kRUREKF26dFq/fv1N68bExCgqKsrjBAAAgLQvVYfbcePGyc/PT7169Up0/YkTJ5QzZ06PZX5+fsqWLZtOnDhx07pjxoxRSEiI+8QPOAAAADhDqg23mzZt0oQJEzRz5kyf/yTu4MGDFRkZ6T4dPnzYp/UBAACQMlJtuP3+++916tQpFShQQH5+fvLz89PBgwf173//W+Hh4ZKksLAwnTp1yuNyV69e1dmzZxUWFnbT2oGBge4fbOCHGwAAAJwj1f5CWfv27RUREeGxrFGjRmrfvr06d+4sSapWrZrOnTunTZs2qWLFipKklStXKi4uTlWrVr3rPQMAACBlpWi4PX/+vPbs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99q7d6+k5H34i4yMVJ06dbRq1SpftSdJiomJ0eeff67Vq1f7tO7HH3+shx56SDt37tShQ4d8WvuuMaQa8+fPt/DwcCtRooRlzJjRnn76aTt27FiS6yxcuNB+/vln9/kvvvjCqlataoULF7bmzZvb+++/n+xef/vtNytUqJC98847ya4VLy4uzszMPvnkE2vVqpVVq1bNMmXKZEWKFLGFCxcmu/7nn39uISEh1rp1a6tevbpVqlTJunXr5lWtCxcuWL169eyZZ56xkiVLWrt27dzrrl69muxe+/fvby1atLDq1atbtmzZ7L777vPqPrhxX5g3b57VqFHDihUrZsOHD7fNmzcnu9fIyEgrW7astWvXznbs2JHsejeaOXOmPfjgg9axY0e7ePGiVzUWLlxoW7duNbP/28+eeOIJe+ONN3zW5+bNm61ChQr2zDPP2Pbt231WN978+fMtc+bMVqRIEQsMDLRp06ZZVFRUsmv6en/47LPPLHv27FauXDlLly6dVatWzT777LNk1x04cKAVL17c7rnnHqtdu7bPXnv69+9vjz32mFWuXNlCQ0O9fq5db/fu3TZ06FAbPHiwmf3fPpdc33zzjWXMmNHee+89r94bbvTnn39a1apVzeVy2b/+9S/38tjY2GTXjjd9+nTLmzev9erVy3bu3OmzumZmu3btsqCgIJs5c6bPal64cMH994MPPmi1a9dOds1Lly5ZpUqVbMaMGcmuFS9+n9q4caMFBwfbl19+6ZO6n332mblcLps/f761bdvWhg0bZma+eV+7mwi3qcSSJUssNDTUpk2bZjExMbZo0SJzuVzWunVrO3z48G3XOXHihBUqVMg6d+5se/futR07dliWLFns5ZdftrFjx9rzzz9vAQEBNnr06GT1u2zZMitWrJgdOHDAvcwXL+Dr1q2zTJky2fvvv2+//vqr7d692+rUqWPVqlWz//3vf17X3blzpxUoUMCmTp3qPp8xY0b3m483oqOjzczs/ffft/vuu89nAXfGjBkWGhpqmzZtsrNnz9rx48etYcOGVq1aNVu0aNFt17l+X9izZ4/t2rXLQkNDbdSoUda7d2+rUKGCtWjRwr7//nuve423YcMGq1Klik+D3fX704wZM7wOuNffD9eH71q1atmbb77pk17j3YmAGxcXZ2fOnLEaNWrYtGnTbPfu3TZ69GhzuVw2evRoO3funFd1N23aZCEhITZy5Eif7Q+bN2+2e+65x/773//a2bNn7cSJE9axY0d78MEHbd68eV7X/eijjywsLMwWLFhgM2fOtAEDBpi/v7+NGTPG65pmZrNmzbKsWbPapk2b7I8//rCjR49agwYN7IEHHkjSc+16kZGRVqlSJcuRI4f17dvXvTy5r48XL160J554wl588UUzu/b6s3fvXnvllVds/vz5Xn3QuXz5stWrV8/KlStnDRo0sA8//NC9zpcBd9asWXbfffdZ9+7dfRZw4/vr06ePtWjRws6cOZPsmosXL7annnrKlixZYmZmBw8etCJFitjIkSO9qnf9a1WnTp3c7xFxcXE+u38jIyOtVatW1rt3bzNL3uM2b948c7lcNn36dDMza9q0qftDj68+oN0thNtUIDIy0rp162YjRowwM7N9+/ZZ4cKFrWXLlhYaGmrNmjWzgwcP3na9TZs2WaVKlax79+720ksvWf/+/T2ua9KkSZYhQwabPXu21z3Pnz/f8ufP7w631z+hvv32W9u0aZNXdadNm2YlS5b0+PR85MgRq1mzphUpUsT9opNUS5YssfLly5vZtfu3YMGCHqO23vZrZvbXX3/Z9OnTrXjx4j4JuC+99JLVrFnTYmNj3ffrkSNHrGrVqlakSJEkvenG7ws9evSwUaNG2ahRo9zrvvnmG6tbt641b97cJwH3TgW7eMkJuJs2bbLKlSvbM888Y7/88ouZmTVs2ND9Zn758mUzM4/73Fu+vh8uXrxoFy5csBdffNHOnj3rXj5hwgR3wI2MjExSzT179tioUaPs5Zdfdi/zxf4wZ84cK1mypEVGRrofuxMnTli7du2sVq1aFhMTk+Saq1atsmeeecbjg0hUVJS9/fbbFhQUlKxR4aFDh1qNGjUsNjbW3e+RI0esSpUqSX6uXW/z5s1WtGhRK1eunPs/Bsl14cIFq1SpkvXs2dPOnDljPXr0sNq1a1u+fPksV65cHs/tpLh06ZIdP37cmjRpYnXr1vUIuGbevY7t3bvXjh496rFsxowZVrx4cfvXv/5lv//+u1e9fvvtt/bBBx94PEe/+OILy549u3uf9fb5GxcXZ127djWXy2XZsmWzYcOG2b59++yVV16xVq1aJfk9YtGiRVa7dm1r0qSJjR071urUqWNt27a1ixcvul9vvPHmm2/a66+/7jHo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",
-      "text/plain": [
-       "<Figure size 800x600 with 1 Axes>"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Mh ux, hk ghm mh ux, matm bl max jnxlmbhg:\n",
-      "Paxmaxk 'mbl ghuexk bg max fbgw mh lnyyxk\n",
-      "Max lebgzl tgw tkkhpl hy hnmktzxhnl yhkmngx,\n",
-      "Hk mh mtdx tkfl tztbglm t lxt hy mkhnuexl\n",
-      "Tgw ur hiihlbgz xgw maxf. Mh wbx--mh lexxi,\n",
-      "Gh fhkx; tgw ur t lexxi mh ltr px xgw\n",
-      "Max axtkm-tvax tgw max mahnltgw gtmnkte lahvdl\n",
-      "Matm yexla bl axbk mh: 'mbl t vhglnfftmbhg\n",
-      "Wxohnmer mh ux pbla'w. Mh wbx, mh lexxi;\n",
-      "Mh lexxi, ixkvatgvx mh wkxtf--tr, maxkx'l max knu:\n",
-      "Yhk bg matm lexxi hy wxtma patm wkxtfl ftr vhfx,\n",
-      "Paxg px atox lanyyexw hyy mabl fhkmte vhbe,\n",
-      "Fnlm zbox nl itnlx--maxkx'l max kxlixvm\n",
-      "Matm ftdxl vtetfbmr hy lh ehgz ebyx.\n",
-      "Yhk pah phnew uxtk max pabil tgw lvhkgl hy mbfx,\n",
-      "Ma'hiikxllhk'l pkhgz, max ikhnw ftg'l vhgmnfxer,\n",
-      "Max itgzl hy wblikbs'w ehox, max etp'l wxetr,\n",
-      "Max bglhexgvx hy hyybvx, tgw max linkgl\n",
-      "Matm itmbxgm fxkbm hy ma'ngphkmar mtdxl,\n",
-      "Paxg ax abflxey fbzam abl jnbxmnl ftdx\n",
-      "Pbma t utkx uhwdbg? Pah phnew ytkwxel uxtk,\n",
-      "Mh zkngm tgw lpxtm ngwxk t pxtkr ebyx,\n",
-      "Unm matm max wkxtw hy lhfxmabgz tymxk wxtma,\n",
-      "Max ngwblvhoxkx'w vhngmkr, ykhf pahlx uhnkg\n",
-      "Gh mktoxeexk kxmnkgl, inssexl max pbee,\n",
-      "Tgw ftdxl nl ktmaxk uxtk mahlx beel px atox\n",
-      "Matg yer mh hmaxkl matm px dghp ghm hy?\n",
-      "Manl vhglvbxgvx whma ftdx vhptkwl hy nl tee,\n",
-      "Tgw manl max gtmbox anx hy kxlhenmbhg\n",
-      "Bl lbvdebxw h'xk pbma max itex vtlm hy mahnzam,\n",
-      "Tgw xgmxkikblxl hy zkxtm ibma tgw fhfxgm\n",
-      "Pbma mabl kxztkw maxbk vnkkxgml mnkg tpkr\n",
-      "Tgw ehlx max gtfx hy tvmbhg.\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "cypher_text = encode_message(original_text, random.randint(1,25)) # If you re=run this cell, the key will change!\n",
-    "plot_frequencies(count_letters(cypher_text))\n",
-    "print(cypher_text)"
+    "# Your code goes here"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": null,
    "id": "3ed45915-a7cf-4d93-9d95-cdb591a45771",
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Decoded Message:\n",
-      " To be, or not to be, that is the question:\n",
-      "Whether 'tis nobler in the mind to suffer\n",
-      "The slings and arrows of outrageous fortune,\n",
-      "Or to take arms against a sea of troubles\n",
-      "And by opposing end them. To die--to sleep,\n",
-      "No more; and by a sleep to say we end\n",
-      "The heart-ache and the thousand natural shocks\n",
-      "That flesh is heir to: 'tis a consummation\n",
-      "Devoutly to be wish'd. To die, to sleep;\n",
-      "To sleep, perchance to dream--ay, there's the rub:\n",
-      "For in that sleep of death what dreams may come,\n",
-      "When we have shuffled off this mortal coil,\n",
-      "Must give us pause--there's the respect\n",
-      "That makes calamity of so long life.\n",
-      "For who would bear the whips and scorns of time,\n",
-      "Th'oppressor's wrong, the proud man's contumely,\n",
-      "The pangs of dispriz'd love, the law's delay,\n",
-      "The insolence of office, and the spurns\n",
-      "That patient merit of th'unworthy takes,\n",
-      "When he himself might his quietus make\n",
-      "With a bare bodkin? Who would fardels bear,\n",
-      "To grunt and sweat under a weary life,\n",
-      "But that the dread of something after death,\n",
-      "The undiscovere'd country, from whose bourn\n",
-      "No traveller returns, puzzles the will,\n",
-      "And makes us rather bear those ills we have\n",
-      "Than fly to others that we know not of?\n",
-      "Thus conscience doth make cowards of us all,\n",
-      "And thus the native hue of resolution\n",
-      "Is sicklied o'er with the pale cast of thought,\n",
-      "And enterprises of great pith and moment\n",
-      "With this regard their currents turn awry\n",
-      "And lose the name of action.\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "# Decoding\n",
-    "guessed_key = 19 # Put your guess here\n",
+    "guessed_key = 0 # Put your guess here\n",
     "decoded_text = decode_message(cypher_text, guessed_key)\n",
     "print(\"Decoded Message:\\n\", decoded_text)"
    ]
-- 
GitLab


From 284389a7aca7e5186af581b4198b42f74d98fd29 Mon Sep 17 00:00:00 2001
From: Markus <m.stroot@iaew.rwth-aachen.de>
Date: Thu, 27 Jun 2024 01:07:34 +0200
Subject: [PATCH 13/23] Small changes to Crypto and adding elaborate ICT
 exercise

---
 Excercise_3/Cryptography.ipynb |   3 +-
 Exercise_2_5/ASKnPSK.png       | Bin 0 -> 14077 bytes
 Exercise_2_5/Exercise_4.ipynb  | 362 +++++++++++++++++++++++++++++++++
 Exercise_2_5/ImagRep.png       | Bin 0 -> 5871 bytes
 Exercise_2_5/QAM_Amplitude.png | Bin 0 -> 16144 bytes
 Exercise_2_5/QAM_Phases.png    | Bin 0 -> 20935 bytes
 6 files changed, 364 insertions(+), 1 deletion(-)
 create mode 100644 Exercise_2_5/ASKnPSK.png
 create mode 100644 Exercise_2_5/Exercise_4.ipynb
 create mode 100644 Exercise_2_5/ImagRep.png
 create mode 100644 Exercise_2_5/QAM_Amplitude.png
 create mode 100644 Exercise_2_5/QAM_Phases.png

diff --git a/Excercise_3/Cryptography.ipynb b/Excercise_3/Cryptography.ipynb
index 11f6668..96b9a4a 100644
--- a/Excercise_3/Cryptography.ipynb
+++ b/Excercise_3/Cryptography.ipynb
@@ -254,7 +254,8 @@
    "id": "03674516-86f8-42a3-83e3-5ecb1c376a30",
    "metadata": {},
    "source": [
-    "<img src=\"340px-English-slf.png\" alt=\"Letter Frequencies English\" width=\"500\" height=\"auto\">\n",
+    "<img src=\"340px-English-slf(1).png\" alt=\"Letter Frequencies English\" width=\"500\" height=\"auto\">\n",
+    "\n",
     "This should look roughly similar, as we are using an English text.\n",
     "\n",
     "Now we use our encryption with a random key. Can you figure out the correct key from the frequency analysis of the cypher text and the standard English letter distribution? Try out your guess by decoding the cypher text!"
diff --git a/Exercise_2_5/ASKnPSK.png b/Exercise_2_5/ASKnPSK.png
new file mode 100644
index 0000000000000000000000000000000000000000..82276b78c65e794f7f1ecf37b12834bca063e287
GIT binary patch
literal 14077
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
E04;c6)Bpeg

literal 0
HcmV?d00001

diff --git a/Exercise_2_5/Exercise_4.ipynb b/Exercise_2_5/Exercise_4.ipynb
new file mode 100644
index 0000000..4ff8cb4
--- /dev/null
+++ b/Exercise_2_5/Exercise_4.ipynb
@@ -0,0 +1,362 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercise 4\n",
+    "This exercise cover topics of ICT and Grid Control Sysytems\n",
+    "For all calculation tasks this Notebook was prepared."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Task 2: Modulation\n",
+    "Modulation is the process of imprinting an information signal onto a carrier signal. In many cases the carrier signal is a sinusoidal, electromagnetic wave. When  the frequency is fixed, amplitude and phase of the signal can be represented by a vector in the complex plane. Modulation schemes such as ASK or PSK use discrete values for these parameters to represent symbols. They can be visualized as points in this plane.\n",
+    "\n",
+    "<img src=\"ImagRep.png\" alt=\"Imaginary Representation of a signal\" width=\"300\" height=\"auto\">\n",
+    "<img src=\"ASKnPSK.png\" alt=\"ASK and PSK examples\" width=\"400\" height=\"auto\">\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Naturally, the closer these point are to each other, the easier it is to confuse them or for transmission errors to make one symbol look like the other. QAM tries to efficiently use the whole complex plane, while minimizing the possibility of confusion and the error rate.\n",
+    "For 16-QAM, it looks like this:\n",
+    "\n",
+    "\n",
+    "<img src=\"QAM_Amplitude.png\" alt=\"\" width=\"300\" height=\"auto\">\n",
+    "<img src=\"QAM_Phases.png\" alt=\"\" width=\"300\" height=\"auto\">\n",
+    "\n",
+    " Here, we need 3 Amplitudes and 12 phase angles to represent all symbols. The amplitudes ca be determined from the first given amplitude value `A1 = 1`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import math"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "A1 = 1.\n",
+    "# Calculate missing values A2 and A3\n",
+    "\n",
+    "A2 = \n",
+    "A3 = \n",
+    "\n",
+    "print(f\"A1: {round(A1, 2)}\")\n",
+    "print(f\"A2: {round(A2, 2)}\")\n",
+    "print(f\"A3: {round(A3, 2)}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The Phases can be calculated using the amplitudes and some trigonometry. You may even use symmetry to you advantage"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "phase = [[],[],[]] # Use phase[i][j] as the indices as indicated in the slides\n",
+    "\n",
+    "# You code goes here\n",
+    "\n",
+    "\n",
+    "for j in range(4):\n",
+    "    for i in range(3):\n",
+    "        print(f\"phi_{i+1},{j+1}: {round(math.degrees(phase[i][j]),2)}\")\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Task 3: Multi-Dimensional Parity check\n",
+    "Multi-dimensional parity checks are a form of Forward-Error-Correction. A message in enlaced with parity bits such that in a matrix arangement and the parities can be checked per line and column. If a single bit is fliped, the corresponding line and column parity won't fit anymore and the error can be corrected."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "line_parity = False\n",
+    "column_parity = False\n",
+    "line_index = -1\n",
+    "column_index = -1\n",
+    "\n",
+    "block_line_size = 4\n",
+    "number = 0xDFC966\n",
+    "total_message_size = 24\n",
+    "#number = 0b1111111111001001011001101\n",
+    "#total_message_size = 25\n",
+    "\n",
+    "# Your code goes here\n",
+    "\n",
+    "# This should correct the error is the parity check works correctly:\n",
+    "if column_index != -1 and line_index != -1:\n",
+    "    fault_shift = total_message_size-1 - column_index - line_index*(block_line_size+1)\n",
+    "    corrected_number = number ^ 1<<fault_shift\n",
+    "    print(f\"Corrected number: {hex(corrected_number)}\")\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Task 4: Addressing and Routing\n",
+    "Dynamic routing protocols can build tables of valid routes to all connected networks by themselves. One such example is the Bellman-Ford-Algorithm. In this task we try to implement it in a distributed manner, as it would be in actual routers.\n",
+    "\n",
+    "It is you task to fill in the update table function of the Router-class below, such that the shourtest routes are determined dynamically for any scenario."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import pandas as pd\n",
+    "import numpy as np\n",
+    "from typing import Self\n",
+    "\n",
+    "class Router:\n",
+    "    def __init__(self, initial_table: pd.DataFrame) -> None:\n",
+    "        self.neighbors = initial_table.copy()\n",
+    "        self.neighbors = self.neighbors[self.neighbors[\"time\"] != 0]\n",
+    "        self.routing_table = initial_table\n",
+    "        self.name = self.routing_table[self.routing_table[\"time\"] == 0].index[0]\n",
+    "\n",
+    "    def get_routing_table(self) -> pd.DataFrame:\n",
+    "        return self.routing_table\n",
+    "    \n",
+    "    def update_routing_table(self, routers: dict[str, Self]):\n",
+    "        for neighbor, dist in self.neighbors.iterrows():\n",
+    "            # Your code goes here\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now let's try this from a fresh topology, where each router only knows their neighbor. Does it work? What can you observe in the outputs? Will this always look the same?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "r1 = Router(pd.DataFrame(data={\"time\": [0, 1, 4], \"via\": [\"A\", \"C\", \"D\"]}, index=[\"A\", \"C\", \"D\"]))\n",
+    "r2 = Router(pd.DataFrame(data={\"time\": [0, 2, 1], \"via\": [\"B\", \"C\", \"F\"]}, index=[\"B\", \"C\", \"F\"]))\n",
+    "r3 = Router(pd.DataFrame(data={\"time\": [1, 2, 0, 2], \"via\": [\"A\", \"B\", \"C\", \"D\"]}, index=[\"A\", \"B\", \"C\", \"D\"]))\n",
+    "r4 = Router(pd.DataFrame(data={\"time\": [4, 2, 0, 2, 1], \"via\": [\"A\", \"C\", \"D\", \"E\", \"F\"]}, index=[\"A\", \"C\", \"D\", \"E\", \"F\"]))\n",
+    "r5 = Router(pd.DataFrame(data={\"time\": [2, 0, 5], \"via\": [\"D\", \"E\", \"F\"]}, index=[\"D\", \"E\", \"F\"]))\n",
+    "r6 = Router(pd.DataFrame(data={\"time\": [1, 1, 5, 0], \"via\": [\"B\", \"D\", \"E\", \"F\"]}, index=[\"B\", \"D\", \"E\", \"F\"]))\n",
+    "\n",
+    "routers = {\"A\": r1, \"B\": r2, \"C\": r3, \"D\": r4, \"E\": r5, \"F\": r6}\n",
+    "\n",
+    "for _ in range(3):\n",
+    "    table = pd.concat([r1.get_routing_table(),r2.get_routing_table(),r3.get_routing_table(),r4.get_routing_table(),r5.get_routing_table(),r6.get_routing_table()], axis=1).sort_index()\n",
+    "    table.columns = pd.MultiIndex.from_tuples([(\"A\", \"time\"), (\"A\", \"via\"), (\"B\", \"time\"), (\"B\", \"via\"), (\"C\", \"time\"), (\"C\", \"via\"), (\"D\", \"time\"), (\"D\", \"via\"), (\"E\", \"time\"), (\"E\", \"via\"), (\"F\", \"time\"), (\"F\", \"via\")], names=[\"Router\", \"Parameters\"])\n",
+    "    print(table)\n",
+    "    for r in reversed(routers.values()):\n",
+    "        r.update_routing_table(routers)\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Now let's check what happens if a communication link is droped ..."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "r4.routing_table = r4.routing_table[r4.routing_table[\"via\"] != \"F\"] # We delete all routes D uses via F\n",
+    "r4.neighbors = r4.neighbors[r4.neighbors.index != \"F\"] # We delete F from Ds neighbor-table\n",
+    "r6.routing_table = r6.routing_table[r6.routing_table[\"via\"] != \"D\"] # We delete all routes F uses via D\n",
+    "r6.neighbors = r6.neighbors[r6.neighbors.index != \"D\"] # We delete D from F's neighbor-table\n",
+    "for _ in range(5):\n",
+    "    table = pd.concat([r1.get_routing_table(),r2.get_routing_table(),r3.get_routing_table(),r4.get_routing_table(),r5.get_routing_table(),r6.get_routing_table()], axis=1).sort_index()\n",
+    "    table.columns = pd.MultiIndex.from_tuples([(\"A\", \"time\"), (\"A\", \"via\"), (\"B\", \"time\"), (\"B\", \"via\"), (\"C\", \"time\"), (\"C\", \"via\"), (\"D\", \"time\"), (\"D\", \"via\"), (\"E\", \"time\"), (\"E\", \"via\"), (\"F\", \"time\"), (\"F\", \"via\")], names=[\"Router\", \"Parameters\"])\n",
+    "    print(table)\n",
+    "    for r in reversed(routers.values()):\n",
+    "        r.update_routing_table(routers)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Task 5: Network Performance Metrics\n",
+    "In a communication link there is several performance metrics which can be calculated, measured and evaluated. These metrics are for example latency, bandwidth, troughput, framerate, or the delay-bandwidth-product. These parameters can vary due to physical reasons, but also depending on the protocol layer, meassaging patter, etc."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "dist_NY = 6000e3\n",
+    "dist_SF = 4000e3\n",
+    "c = 300e6\n",
+    "t_queue = 2e-3\n",
+    "t_proc = 5e-3\n",
+    "bw_NY = 10e6\n",
+    "bw_SF = 7e6\n",
+    "frame_size = 12e3\n",
+    "frame_per_min_NY = 10e3\n",
+    "frame_per_min_SF = 20e3"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 5.a Latency"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "latency = \n",
+    "print(f\"Latency: {round(latency*1e3,2)} ms\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 5.b Actual Troughput"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "throughput_l1 = \n",
+    "print(f\"Layer 1 Throughut: {round(throughput_l1/1e6, 2)} MBit/s\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 5.c Layer 4 Troughput"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "headder_size = (42 + 20 + 20) * 8\n",
+    "throughput_l4 = \n",
+    "print(f\"Layer 4 Throughut: {round(throughput_l4/1e6, 2)} MBit/s\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 5.d Smaller Frames, but more of them"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "new_framerate = 100e3\n",
+    "throughput_l4_alt = \n",
+    "print(f\"Layer 4 Throughut: {round(throughput_l4_alt/1e3, 2)} kBit/s\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 5.e Round-Trip"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "throughput_l4_ack = \n",
+    "print(f\"Layer 4 Throughut: {round(throughput_l4_ack/1e3, 2)} kBit/s\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### 5.f Delay-Bandwidth-Product"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "frames_to_buffer = \n",
+    "print(f\"The tranmitter needs to buffer {frames_to_buffer} frames for continuous transmission.\")"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": ".venv",
+   "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.11.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/Exercise_2_5/ImagRep.png b/Exercise_2_5/ImagRep.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f5f2dba2f6ceb4e9060c1d9a3ba2c3feeda47f7
GIT binary patch
literal 5871
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
a-|F9HzMjIBpzaLnuzI@sxvX<aXaWG-Oy}SL

literal 0
HcmV?d00001

diff --git a/Exercise_2_5/QAM_Amplitude.png b/Exercise_2_5/QAM_Amplitude.png
new file mode 100644
index 0000000000000000000000000000000000000000..0ae31a7fbade25b6479715a36c03a4dd142b4449
GIT binary patch
literal 16144
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
a`2XwjBHP@}u^T{}vprq?T-G@yGywo?A+F2-

literal 0
HcmV?d00001

diff --git a/Exercise_2_5/QAM_Phases.png b/Exercise_2_5/QAM_Phases.png
new file mode 100644
index 0000000000000000000000000000000000000000..9bbeb9389b76cfa42b38f77657d133dbbc69c639
GIT binary patch
literal 20935
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
T!@brMG|lbl>gTe~DWM4f`2b{x

literal 0
HcmV?d00001

-- 
GitLab


From 7f14f00a4b6553c0e8c8eda2478c0c08935432c7 Mon Sep 17 00:00:00 2001
From: Markus <m.stroot@iaew.rwth-aachen.de>
Date: Tue, 2 Jul 2024 12:36:27 +0200
Subject: [PATCH 14/23] Updates to Cryptography notebook

---
 .gitignore                     |   3 +
 Excercise_3/Cryptography.ipynb | 145 ++++++++++++++++++++++++++++++++-
 Exercise_2_5/Exercise_4.ipynb  |  18 ++--
 3 files changed, 158 insertions(+), 8 deletions(-)

diff --git a/.gitignore b/.gitignore
index c2d867e..369caa5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,6 @@ __pycache__/
 
 # pycharm
 .idea
+Excercise_3/Cryptography-Solutions.ipynb
+Exercise_2_5/Exercise_4 _solution.ipynb
+*.zip
diff --git a/Excercise_3/Cryptography.ipynb b/Excercise_3/Cryptography.ipynb
index 96b9a4a..4a40c6b 100644
--- a/Excercise_3/Cryptography.ipynb
+++ b/Excercise_3/Cryptography.ipynb
@@ -34,7 +34,7 @@
    "id": "ed7799e9",
    "metadata": {},
    "source": [
-    "## Implementation of the Cypher\n",
+    "## Implementation of the Caesar Cypher\n",
     "\n",
     "Let's begin by encoding the message. As described above we aim at a simple shift cypher, which shifts every letter in the message a certain number of letters down the alphabet, looping back to the beginning after the end. For instance, when we apply a shift of 2, the letter 'a' becomes 'c', 'b' becomes 'd', etc. As a result, the word \"at\" transforms into \"cv\". This applies to lower-case letters as well as upper-case. We will ignore special characters like punctuation or white spaces for now."
    ]
@@ -307,6 +307,147 @@
     "- Advantage: Finds key without having to try all possible ones; Disadvantage: Needs a somewhat large amount of data for statistical properties to emerge, as well as knowledge about the underlying statistics.\n",
     "- In order to make statistical properties disapear, we need to introduce randomness into the cypher. The symbol frequencies of the cypher text should not depend on the original message."
    ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a34f3806",
+   "metadata": {},
+   "source": [
+    "## Diffie-Hellman key exchange\n",
+    "If we want to use symmetric encryption, both communication partners need to use the same key. If we simply transmit the key, everyone listening can use them. We need a secure way to exchange symmetric keys over an insecure network. The Diffie-Hellman algorithm provides a way of generating symetric keys by exchanging public info, without outsiders being able to reconstruct the key.\n",
+    "\n",
+    "It works as follows:\n",
+    "1. A public pair of numbers is used/shared, anyone can know them (g, p; g < p) \n",
+    "2. Each participant chooses a private key (Alice uses key “a” and Bob key “b”)\n",
+    "3. Both calculate $s_a = g^a \\, mod\\, p$ and $s_b = g^b \\, mod\\, p$\n",
+    "4. They exchange the results\n",
+    "5. Each one then calculates the key as: $k=s_b^a\\, mod\\, p = s_a^b\\, mod\\, p$\n",
+    "\n",
+    "Please implement an example below to check if it works"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "4deae21e",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import random\n",
+    "\n",
+    "g = random.randint(10,50)\n",
+    "p =\n",
+    "\n",
+    "a =\n",
+    "b =\n",
+    "\n",
+    "s_a =\n",
+    "s_b =\n",
+    "\n",
+    "k_a =\n",
+    "k_b =\n",
+    "\n",
+    "print(f\"Public info: g = {g}; p = {p}\")\n",
+    "print(f\"Secret Key of Alice: {a}. Public key of Alice: {s_a}. Shared secret as calculated by Alice: {k_a}\")\n",
+    "print(f\"Secret Key of Bob: {b}. Public key of Bob: {s_b}. Shared secret as calculated by Bob: {k_b}\")\n",
+    "print(f\"Did the procedure work: {k_a == k_b}\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "9889ea2c",
+   "metadata": {},
+   "source": [
+    "## RSA\n",
+    "The RSA cryptosystem is an asymetric system. Therefore it supports creating two different keys, where one key is the inverse of the other. This supports public-key encryption, so everyone can encrypt messages using the public key that only the intended receriver can read using the private one. Reversely, an entity can generate a message using its private key, which everyone can confirm is generated by that entity using its public key.\n",
+    "\n",
+    "To generate the keys several steps are necessary:\n",
+    "1. Generate two random prime numbers p and q\n",
+    "2. Calculate $n=pq$; This is the systems modulo\n",
+    "3. Calculate $\\phi(n)=(p-1)(q-1)$\n",
+    "4. Choose encryption key e such that it is coprime with $\\phi(n)$ (gcd = 1)\n",
+    "5. Generate decryption key d such that $de = 1 \\quad mod\\, \\phi(n)$\n",
+    "\n",
+    "Our public key is now the combination of e and n\n",
+    "\n",
+    "Encryption of a message m is now done like this:\n",
+    "- $m_e = m^e \\quad mod \\, n$\n",
+    "\n",
+    "And using decryption d should give back m:\n",
+    "- $m = m_e^d \\quad mod \\, n$\n",
+    "\n",
+    "While using e again should generally not work:\n",
+    "- $m \\neq m_e^e \\quad mod \\, n$\n",
+    "\n",
+    "Please implement and try out for yourself below:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "2cb73e37",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import random\n",
+    "import math\n",
+    "\n",
+    "def check_prime(number):\n",
+    "    # Put code for checking if a number is prinme here\n",
+    "    \n",
+    "    \n",
+    "def check_coprime(a, b):\n",
+    "    # Put code to check if two numbers are coprime here"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "ad60e2dd",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "primes = []\n",
+    "\n",
+    "# Put code generating two random primes here\n",
+    "\n",
+    "p = primes[0]\n",
+    "q = primes[1]\n",
+    "\n",
+    "# Calculate the necessary numbers and keys\n",
+    "n = \n",
+    "phi_n = \n",
+    "\n",
+    "e=\n",
+    "d=\n",
+    "\n",
+    "print(f\"Primes chosen: ({p}, {q})\")\n",
+    "print(f\"n: {n}\")\n",
+    "print(f\"Phi_n: {phi_n}\")\n",
+    "print(f\"encryption: {e}\")\n",
+    "print(f\"decryption: {d}\")\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "b310b0ee",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# you can coose any message here\n",
+    "message = 721\n",
+    "\n",
+    "# Calculate the encryptet message, the wrong decryption using the same key and the correct decryption using the private key\n",
+    "message_encrypt = \n",
+    "message_decrypt_wrong = \n",
+    "message_decrypt = \n",
+    "\n",
+    "print(f\"Message: {message}\")\n",
+    "print(f\"Encrypted message: {message_encrypt}\")\n",
+    "print(f\"Wrongly decrypted message: {message_decrypt_wrong}\")\n",
+    "print(f\"Right decrypted message: {message_decrypt}\")"
+   ]
   }
  ],
  "metadata": {
@@ -325,7 +466,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.8.8"
+   "version": "3.11.9"
   }
  },
  "nbformat": 4,
diff --git a/Exercise_2_5/Exercise_4.ipynb b/Exercise_2_5/Exercise_4.ipynb
index 4ff8cb4..41b2a63 100644
--- a/Exercise_2_5/Exercise_4.ipynb
+++ b/Exercise_2_5/Exercise_4.ipynb
@@ -237,7 +237,8 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### 5.a Latency"
+    "### a) Latency\n",
+    "What is the one-way latency of this communication link?"
    ]
   },
   {
@@ -254,7 +255,8 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### 5.b Actual Troughput"
+    "### b) Layer 1 troughput\n",
+    "What is the max. throughput of raw bits, the Layer 1 throughput?"
    ]
   },
   {
@@ -271,7 +273,8 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### 5.c Layer 4 Troughput"
+    "### c) Layer 4 troughput\n",
+    "How much layer 4 data throughput can we expect?"
    ]
   },
   {
@@ -289,7 +292,8 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### 5.d Smaller Frames, but more of them"
+    "### d) Smaller Frames, but more of them\n",
+    "How much layer 4 data throughput do we get under the same conditions but with a frame size of 1200 bit? Assume the link is able to handle 10x the amount of frames to keep a similar layer 1 throughput!\n"
    ]
   },
   {
@@ -307,7 +311,8 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### 5.e Round-Trip"
+    "### e) Round-Trip\n",
+    "Assume conditions of subtask c). Now the top layer protocol requires acknowledgements from the receiving station after each packet before continuing to send data. What is the layer 4 throughput now? For acknowledgement, only transmission time can be neglected."
    ]
   },
   {
@@ -324,7 +329,8 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "### 5.f Delay-Bandwidth-Product"
+    "### f) Delay-Bandwidth-Product\n",
+    "In Full-Duplex communication, a more efficient scheme would be to acknowledge only every few packets. How many max. size packets would the transmitter need to buffer to be able to continuously send data? (round up)"
    ]
   },
   {
-- 
GitLab


From b940d41783090169e4bc4940af21076b4d872e37 Mon Sep 17 00:00:00 2001
From: "f.tischbein" <f.tischbein@iaew.rwth-aachen.de>
Date: Thu, 18 Jul 2024 12:46:53 +0200
Subject: [PATCH 15/23] Add Solution for Asset Management

---
 Exercise_4/2024_07_18_A6_v1.ipynb | 627 ++++++++++++++++++++++++++++++
 1 file changed, 627 insertions(+)
 create mode 100644 Exercise_4/2024_07_18_A6_v1.ipynb

diff --git a/Exercise_4/2024_07_18_A6_v1.ipynb b/Exercise_4/2024_07_18_A6_v1.ipynb
new file mode 100644
index 0000000..3e18187
--- /dev/null
+++ b/Exercise_4/2024_07_18_A6_v1.ipynb
@@ -0,0 +1,627 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "source": [
+    "# DEV Exercise 6\n",
+    "In this Jupyter notebook we will deal with the calculation of investment and operational costs. If you have not yet installed the packages required for this exercise, run the following cell to install them."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "72ab3cf5505dbbc2"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [
+    "!pip install pandas\n",
+    "!pip install pandapower\n",
+    "!pip install simbench"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "e99cc0f65671eb71"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Now run the following cell to import the most important libraries. You can run a cell either by clicking Run on the toolbar or by pressing CTRL+RETURN."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "ddeb3acb51e3e4cd"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "id": "initial_id",
+   "metadata": {
+    "collapsed": true,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:20:24.081312800Z",
+     "start_time": "2024-06-03T14:20:24.064701400Z"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "import warnings\n",
+    "warnings.simplefilter(action='ignore', category=FutureWarning)\n",
+    "\n",
+    "import pandas as pd\n",
+    "pd.options.display.max_rows = 10\n",
+    "\n",
+    "import pandapower as pp\n",
+    "import simbench as sb"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Example grid\n",
+    "\n",
+    "We will carry out the calculation using a [SimBench](https://simbench.readthedocs.io/en/stable/) example grid. SimBench is a database with synthetic grid data that maps different grid structures in low voltage. Import the grid “1-LV-rural1--0-sw” and print its properties (number and type of assets). The standard types in particular are required later for the calculation of annuities. \n"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "4963cb76c621b1bc"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "outputs": [
+    {
+     "data": {
+      "text/plain": "               name              std_type  from_bus  to_bus  length_km  \\\n0    LV1.101 Line 1  NAYY 4x150SE 0.6/1kV         9       2   0.055767   \n1    LV1.101 Line 2  NAYY 4x150SE 0.6/1kV        13      11   0.053576   \n2    LV1.101 Line 3  NAYY 4x150SE 0.6/1kV         6       3   0.049814   \n3    LV1.101 Line 4  NAYY 4x150SE 0.6/1kV         8       1   0.017886   \n4    LV1.101 Line 5  NAYY 4x150SE 0.6/1kV         7      10   0.016089   \n..              ...                   ...       ...     ...        ...   \n8    LV1.101 Line 9  NAYY 4x150SE 0.6/1kV         5      13   0.137215   \n9   LV1.101 Line 10  NAYY 4x150SE 0.6/1kV         3       0   0.132499   \n10  LV1.101 Line 12  NAYY 4x150SE 0.6/1kV         1       3   0.016207   \n11  LV1.101 Line 13  NAYY 4x150SE 0.6/1kV        12       8   0.046015   \n12  LV1.101 Line 11  NAYY 4x150SE 0.6/1kV         4       5   0.002583   \n\n    r_ohm_per_km  x_ohm_per_km  c_nf_per_km  g_us_per_km  max_i_ka   df  \\\n0         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n1         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n2         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n3         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n4         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n..           ...           ...          ...          ...       ...  ...   \n8         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n9         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n10        0.2067      0.080425   829.999394          0.0      0.27  1.0   \n11        0.2067      0.080425   829.999394          0.0      0.27  1.0   \n12        0.2067      0.080425   829.999394          0.0      0.27  1.0   \n\n    parallel type  in_service voltLvl  max_loading_percent   subnet  \n0          1   cs        True       7                100.0  LV1.101  \n1          1   cs        True       7                100.0  LV1.101  \n2          1   cs        True       7                100.0  LV1.101  \n3          1   cs        True       7                100.0  LV1.101  \n4          1   cs        True       7                100.0  LV1.101  \n..       ...  ...         ...     ...                  ...      ...  \n8          1   cs        True       7                100.0  LV1.101  \n9          1   cs        True       7                100.0  LV1.101  \n10         1   cs        True       7                100.0  LV1.101  \n11         1   cs        True       7                100.0  LV1.101  \n12         1   cs        True       7                100.0  LV1.101  \n\n[13 rows x 17 columns]",
+      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>name</th>\n      <th>std_type</th>\n      <th>from_bus</th>\n      <th>to_bus</th>\n      <th>length_km</th>\n      <th>r_ohm_per_km</th>\n      <th>x_ohm_per_km</th>\n      <th>c_nf_per_km</th>\n      <th>g_us_per_km</th>\n      <th>max_i_ka</th>\n      <th>df</th>\n      <th>parallel</th>\n      <th>type</th>\n      <th>in_service</th>\n      <th>voltLvl</th>\n      <th>max_loading_percent</th>\n      <th>subnet</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>LV1.101 Line 1</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>9</td>\n      <td>2</td>\n      <td>0.055767</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>LV1.101 Line 2</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>13</td>\n      <td>11</td>\n      <td>0.053576</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>LV1.101 Line 3</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>6</td>\n      <td>3</td>\n      <td>0.049814</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>LV1.101 Line 4</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>8</td>\n      <td>1</td>\n      <td>0.017886</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>LV1.101 Line 5</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>7</td>\n      <td>10</td>\n      <td>0.016089</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>...</th>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n    </tr>\n    <tr>\n      <th>8</th>\n      <td>LV1.101 Line 9</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>5</td>\n      <td>13</td>\n      <td>0.137215</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>9</th>\n      <td>LV1.101 Line 10</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>3</td>\n      <td>0</td>\n      <td>0.132499</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>10</th>\n      <td>LV1.101 Line 12</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>1</td>\n      <td>3</td>\n      <td>0.016207</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>11</th>\n      <td>LV1.101 Line 13</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>12</td>\n      <td>8</td>\n      <td>0.046015</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>12</th>\n      <td>LV1.101 Line 11</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>4</td>\n      <td>5</td>\n      <td>0.002583</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n  </tbody>\n</table>\n<p>13 rows × 17 columns</p>\n</div>"
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sb_code1 = \"1-LV-rural1--0-sw\"\n",
+    "net = sb.get_simbench_net(sb_code1)\n",
+    "net\n",
+    "net.line"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:21:02.405316800Z",
+     "start_time": "2024-06-03T14:20:58.805268800Z"
+    }
+   },
+   "id": "ce2565ab7f9d932b"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Afterwards, you can plot the SimBench grid by using [the pandapower simple plotting tool](https://pandapower.readthedocs.io/en/v2.0.1/plotting/matplotlib/simple_plot.html)."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "f25c7b3b43552621"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "outputs": [
+    {
+     "data": {
+      "text/plain": "<Figure size 1000x800 with 1 Axes>",
+      "image/png": "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AMA0eAYdACrii1/8Yt70pjclSQ477LC89a1vzVVXXZVHHnkkc+fOzWGHHZZTTz019957b4499tisWLEiIyMjufvuu7Pzzjv39/AAwJQEOgBUxHOe85xcf/31SZJtt902S5cufdJjRkZG8trXvjYLFizIpz71qSTJ3/7t3+b9739/T88KAEyfQAeACli5cuW0Bt/22WefNcvuJ5xwQr73ve9162gAwAzxGnQAqIBly5Y96cde85rX5LLLLstvfvOb3HLLLXnf+96XbbfdNknWxHmSSZ9pBwDK4xl0AKiA+++/PwsXLlzz9le/+tW88pWvfNLjfvnLX+Z5z3te7rnnnjU/9oIXvCCXXXZZT84JAGw+z6ADQAX8y7/8y3pv77fffpM+7mlPe9qa155POOqoo7p1LABgBgl0AKiAb37zm+u9/Z73vCerVq2a9LEHHHBAGo3Gmrff+MY3dvVsAMDMEOgAUAEPPvjgem9ffvnleeELX5irrroqE69We/zxx3PBBRfkuOOOy7qvYJt4XToAULbhfh8AAJjanDlz1vv+448/nquvvjrPe97zsvvuu2ennXbKnXfeOemY3LrvCwCUyzPoAFABBx100Jrvv+Md78iuu+665u277747//Ef/zFpnO++++6ZP39+T84IAGwZgQ4AFXDGGWes+f43vvGN3HTTTfnyl7+c4447LvPmzUuz2cwOO+yQ173udTnppJPWe791X48OAJRLoANABRx66KF57nOfm6T9pdROOumkHHDAAfnBD36QRx99NGNjY1m8eHHmzZuXb3/720mS2bNn5/TTT+/nsQGAafB10AGgIu68884cddRRefjhh9f82M4775xDDz00IyMj+e53v5vVq1ev+bkLLrjAgjsAVIhAB4AKWbRoUU466aTcfffdG33MyMhIzj777Jx66qk9PBkAsKVccQeACjnooIOyePHifPazn83w8PpfjGX77bfPX/zFX+SOO+4Q5wBQQZ5BB4AKWrp0aRYsWJAkedaznpWvfe1r2X333TMyMtLfgwEAm83XQQeACrrtttvWfP/www/P0572tD6eBgCYCa64A0AFLV68eM33DzzwwD6eBACYKQIdACpo3UA/4IAD+ngSAGCmCHQAqKBbb711zfc9gw4A9SDQAaCCJp5B32677bLLLrv0+TQAwEwQ6ABQMUuXLs0999yTpH29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"
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/plain": "<Axes: >"
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pp.plotting.simple_plot(net, show_plot=True)"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:20:39.998814Z",
+     "start_time": "2024-06-03T14:20:39.471146800Z"
+    }
+   },
+   "id": "2eb6d9517e99be23"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2a \n",
+    "\n",
+    "To calculate the annuities, we must first determine the investment costs of the lines and transformer types. For this purpose, read these from the Excel table using [the pandas function \"read_excel\"](https://pandas.pydata.org/docs/reference/api/pandas.read_excel.html)."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "e43234c36ca7e4ba"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "outputs": [],
+   "source": [
+    "line_std_types = pd.read_excel(io=\"./std_type_costs.xlsx\", index_col=[0], sheet_name=\"line_std_types\")\n",
+    "trafo_std_types = pd.read_excel(io=\"./std_type_costs.xlsx\", index_col=[0], sheet_name=\"trafo_std_types\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:21:58.923764700Z",
+     "start_time": "2024-06-03T14:21:58.809907500Z"
+    }
+   },
+   "id": "c6f5410eee07a074"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2b\n",
+    "Calculate the total investment cost in t=0 for the transformer and the lines.\n",
+    "For the equipment with unit prices the total costs can be calculated via\n",
+    "$C_{inv} = \\sum_{pc=1}^{n} {C_{pc}} = n \\cdot C_{pc}$"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "90aeb0e3ed2ee0d4"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The investment costs for trafos are : 13.0 mio. €\n"
+     ]
+    }
+   ],
+   "source": [
+    "trafo_name = net.trafo.std_type[0]\n",
+    "c_inv_trafo = len(net.trafo) * trafo_std_types.at[trafo_name, \"cost_per_piece\"]\n",
+    "print(f\"The investment costs for trafos are : {round(c_inv_trafo/1e6, 2)} mio. €\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:02.934409600Z",
+     "start_time": "2024-06-03T14:22:02.914839400Z"
+    }
+   },
+   "id": "527eba7f1fdd1827"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "For the equipment with length related costs:\n",
+    "$C_{inv} = \\sum_{pc=1}^{n} {l_{pc} \\cdot C_l} = (\\sum_{pc=1}^{n} {l_{pc}}) \\cdot C_l$.\n",
+    "First sum up over the total line length using [pandas groupby](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html)."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "de5e30b6e28016b7"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The line length is : 0.56 km\n"
+     ]
+    }
+   ],
+   "source": [
+    "line_name = net.line.std_type[0]\n",
+    "sum_lines = net.line[[\"std_type\", \"length_km\"]].groupby(\"std_type\").sum().at[line_name, \"length_km\"]\n",
+    "print(f\"The line length is : {round(sum_lines, 3)} km\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:07.921782200Z",
+     "start_time": "2024-06-03T14:22:07.887759400Z"
+    }
+   },
+   "id": "4731e97d3b9e66f1"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The investment costs for lines are : 0.01 mio. €\n"
+     ]
+    }
+   ],
+   "source": [
+    "c_inv_lines = sum_lines * line_std_types.at[line_name, \"cost_per_km\"]\n",
+    "print(f\"The investment costs for lines are : {round(c_inv_lines/1e6, 2)} mio. €\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:09.292713800Z",
+     "start_time": "2024-06-03T14:22:09.267721Z"
+    }
+   },
+   "id": "3e4b323df9b033ec"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "Afterwards, calculate the total investment cost of the grid by:\n",
+    "$C_{grid,inv} = \\sum_{equip.} {C_{inv,equip.}}$"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "1262245f8ee4319d"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The total grid costs are : 13.01 mio. €\n"
+     ]
+    }
+   ],
+   "source": [
+    "c_total = c_inv_trafo + c_inv_lines\n",
+    "print(f\"The total grid costs are : {round(c_total/1e6, 2)} mio. €\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:17.122947500Z",
+     "start_time": "2024-06-03T14:22:17.097954900Z"
+    }
+   },
+   "id": "f56701e0558fd50e"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2c\n",
+    "Calculate the annuity factors for the different lifetimes and components.\n",
+    "The annuity factors for the different lifetimes can be calculated via:\n",
+    "$a=\\frac{q^{T,max} \\cdot (q-1)}{q^{T,max}-1}$\n",
+    "\n",
+    "The lifetimes $T_{max}$ of the assets can be found in the Excel tables or data frames. First, define a function to calculate the annuity. This should have the lifetime and the discount rate $q = 1+r$ as input data. Usually, distribution grid operators assume an interest rate of $r=5\\%$."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "4a8f16d1e3d93bcc"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "outputs": [],
+   "source": [
+    "interestrate=0.05\n",
+    "\n",
+    "def annuity(n, r=interestrate):\n",
+    "    \"\"\"Calculate the annuity factor for an asset with lifetime n years and\n",
+    "    discount rate of r\"\"\"\n",
+    "\n",
+    "    q=1+r\n",
+    "\n",
+    "    if r > 0:\n",
+    "        return (q**n*(q-1))/(q**n-1)\n",
+    "    else:\n",
+    "        return 1/n"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:21.141660Z",
+     "start_time": "2024-06-03T14:22:21.122542800Z"
+    }
+   },
+   "id": "ba8c3aebb2b2edf1"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "The following annuity costs then result for the components:"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "8bc1eeef24887502"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The annuity factor for the lines is : 0.0611\n"
+     ]
+    }
+   ],
+   "source": [
+    "ann_lines = annuity(line_std_types.at[line_name, \"lifetime\"])\n",
+    "print(f\"The annuity factor for the lines is : {round(ann_lines, 4)}\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:23.374625200Z",
+     "start_time": "2024-06-03T14:22:23.328846900Z"
+    }
+   },
+   "id": "e63a003d70957a59"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The annuity factor for the trafos is : 0.0651\n"
+     ]
+    }
+   ],
+   "source": [
+    "ann_trafo = annuity(trafo_std_types.at[trafo_name, \"lifetime\"])\n",
+    "print(f\"The annuity factor for the trafos is : {round(ann_trafo, 4)}\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:24.896539Z",
+     "start_time": "2024-06-03T14:22:24.868448200Z"
+    }
+   },
+   "id": "966f8b18dc754e17"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2d\n",
+    "Afterwards, calculate the operating costs for the transformer and the lines. The operating costs can be found in the corresponding Excel files or data frames. The operating costs correspond to the multiplication of the investment costs with the specific operating costs from the Excel table or data frame."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "6e9b5e1600f9bf78"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The operating costs for lines are : 156.49 €\n"
+     ]
+    }
+   ],
+   "source": [
+    "c_o_lines = c_inv_lines * line_std_types.at[line_name, \"operating_cost\"]\n",
+    "print(f\"The operating costs for lines are : {round(c_o_lines, 2)} €\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:36.659044600Z",
+     "start_time": "2024-06-03T14:22:36.638976800Z"
+    }
+   },
+   "id": "644d4a2306910ee6"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The operating costs for transformer are : 0.39 mio. €\n"
+     ]
+    }
+   ],
+   "source": [
+    "c_o_trafo = c_inv_trafo * trafo_std_types.at[trafo_name, \"operating_cost\"]\n",
+    "print(f\"The operating costs for transformer are : {round(c_o_trafo/1e6, 2)} mio. €\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:39.725035900Z",
+     "start_time": "2024-06-03T14:22:39.704038Z"
+    }
+   },
+   "id": "1faf1a9504e028da"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2e\n",
+    "Calculate the annual cost of the grid equipment (sum of operating and investment costs)."
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "79769693879cb833"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The annual grid costs are : 1.24 mio. €\n"
+     ]
+    }
+   ],
+   "source": [
+    "c_ann_total = ann_lines * c_inv_lines + ann_trafo * c_inv_trafo + c_o_lines + c_o_trafo  \n",
+    "print(f\"The annual grid costs are : {round(c_ann_total/1e6, 2)} mio. €\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:45.654863600Z",
+     "start_time": "2024-06-03T14:22:45.633570100Z"
+    }
+   },
+   "id": "de48aec2ff9058bf"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2f\n",
+    "In the course of digitizing the distribution grids, it is advisable to equip most of the LV system equipment with measurement technology. For our system, the following assumptions can be made:\n",
+    "- The specific investment costs for the measurement technology system in the transformer station is 500.000€, the interest rate equals 5%/a and its lifetime equals 20 years\n",
+    "- Every grid customer within our grid will also be equipped with a smart meter. As the smart meters belong to the metering point operator and not the distribution grid operator, there are no investment costs here.\n",
+    "- Because metering technology allows the grid to operate more efficiently, the lifetimes of all other technologies increase by 5 years\n",
+    "\n",
+    "Calculate the new annuity of investment costs for the total system with the measurement technology"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "ee9bcd85e1c42abc"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The new annual grid costs are : 1.22 mio. €\n"
+     ]
+    }
+   ],
+   "source": [
+    "c_ann_trafo = 1 * trafo_std_types.at[trafo_name, \"cost_per_piece\"] * annuity(trafo_std_types.at[trafo_name, \"lifetime\"] + 5)\n",
+    "c_ann_lines = sum_lines * line_std_types.at[line_name, \"cost_per_km\"] * annuity(line_std_types.at[line_name, \"lifetime\"] + 5)\n",
+    "\n",
+    "c_inv_measure = 500000\n",
+    "lifetime_measure = 20\n",
+    "c_ann_measure = annuity(lifetime_measure) * c_inv_measure\n",
+    "\n",
+    "c_ann_total_new = c_ann_trafo + c_ann_lines + c_o_trafo + c_o_lines + c_ann_measure\n",
+    "print(f\"The new annual grid costs are : {round(c_ann_total_new/1e6, 2)} mio. €\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:48.991815900Z",
+     "start_time": "2024-06-03T14:22:48.974735500Z"
+    }
+   },
+   "id": "e9bf09de56cfedb1"
+  },
+  {
+   "cell_type": "markdown",
+   "source": [
+    "### Task 2g\n",
+    "What are the maximum annual operating costs for the measurement equipment in order to still be cheaper than without measurement equipment?"
+   ],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "51cf92fb26790ff"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The maximum annual operating costs can be : 11651.6 €\n"
+     ]
+    }
+   ],
+   "source": [
+    "c_o_measure = c_ann_total - c_ann_total_new\n",
+    "print(f\"The maximum annual operating costs can be : {round(c_o_measure, 2)} €\")"
+   ],
+   "metadata": {
+    "collapsed": false,
+    "ExecuteTime": {
+     "end_time": "2024-06-03T14:22:54.454657700Z",
+     "start_time": "2024-06-03T14:22:54.436729800Z"
+    }
+   },
+   "id": "b749b6d14d16ff43"
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "outputs": [],
+   "source": [],
+   "metadata": {
+    "collapsed": false
+   },
+   "id": "dfd9b25d20fc7b6c"
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 2
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython2",
+   "version": "2.7.6"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
-- 
GitLab


From f828c0bad6bd4598686e9343b91c04de95f34131 Mon Sep 17 00:00:00 2001
From: Amirali Mahjoob <amirali.mahjoob@rwth-aachen.de>
Date: Tue, 29 Apr 2025 16:41:09 +0200
Subject: [PATCH 16/23] change file name

---
 ...{2024_02_23_DEV_UE2_A2_v2.ipynb => Exercise_2_DEV_A2_v2.ipynb} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Excercise_2/{2024_02_23_DEV_UE2_A2_v2.ipynb => Exercise_2_DEV_A2_v2.ipynb} (100%)

diff --git a/Excercise_2/2024_02_23_DEV_UE2_A2_v2.ipynb b/Excercise_2/Exercise_2_DEV_A2_v2.ipynb
similarity index 100%
rename from Excercise_2/2024_02_23_DEV_UE2_A2_v2.ipynb
rename to Excercise_2/Exercise_2_DEV_A2_v2.ipynb
-- 
GitLab


From 709f327257a1995b05b81294053cca5e534c6d71 Mon Sep 17 00:00:00 2001
From: Amirali Mahjoob <amirali.mahjoob@rwth-aachen.de>
Date: Tue, 29 Apr 2025 16:42:14 +0200
Subject: [PATCH 17/23] Edit name

---
 ..._v2_students.ipynb => Exercise_2_DEV_UE2_A2_v2_students.ipynb} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Excercise_2/{2024_02_23_DEV_UE2_A2_v2_students.ipynb => Exercise_2_DEV_UE2_A2_v2_students.ipynb} (100%)

diff --git a/Excercise_2/2024_02_23_DEV_UE2_A2_v2_students.ipynb b/Excercise_2/Exercise_2_DEV_UE2_A2_v2_students.ipynb
similarity index 100%
rename from Excercise_2/2024_02_23_DEV_UE2_A2_v2_students.ipynb
rename to Excercise_2/Exercise_2_DEV_UE2_A2_v2_students.ipynb
-- 
GitLab


From 6216086b1cf4f867acce069ab4c0e55e3dea8079 Mon Sep 17 00:00:00 2001
From: Amirali Mahjoob <amirali.mahjoob@rwth-aachen.de>
Date: Tue, 29 Apr 2025 16:43:16 +0200
Subject: [PATCH 18/23] Edit .gitignore

---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index 369caa5..7e83bf6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,4 +12,5 @@ __pycache__/
 .idea
 Excercise_3/Cryptography-Solutions.ipynb
 Exercise_2_5/Exercise_4 _solution.ipynb
+Excercise_2/Exercise_2_DEV_UE2_A2_v2_students.ipynb
 *.zip
-- 
GitLab


From 9f81b80a78f16b3e4593d536ff1a690861f137c7 Mon Sep 17 00:00:00 2001
From: Amirali Mahjoob <amirali.mahjoob@rwth-aachen.de>
Date: Tue, 29 Apr 2025 16:44:09 +0200
Subject: [PATCH 19/23] Edit name 2024_06_03_A6_v1_students.ipynb

---
 ...06_03_A6_v1_students.ipynb => exercise_4_A6_v1_students.ipynb} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Exercise_4/{2024_06_03_A6_v1_students.ipynb => exercise_4_A6_v1_students.ipynb} (100%)

diff --git a/Exercise_4/2024_06_03_A6_v1_students.ipynb b/Exercise_4/exercise_4_A6_v1_students.ipynb
similarity index 100%
rename from Exercise_4/2024_06_03_A6_v1_students.ipynb
rename to Exercise_4/exercise_4_A6_v1_students.ipynb
-- 
GitLab


From 91f220632ab79b9528fd7b25b69a8d7e4665c076 Mon Sep 17 00:00:00 2001
From: Amirali Mahjoob <amirali.mahjoob@rwth-aachen.de>
Date: Tue, 29 Apr 2025 16:44:56 +0200
Subject: [PATCH 20/23] Edit 2024_07_18_A6_v1.ipynb

---
 Exercise_4/{2024_07_18_A6_v1.ipynb => exercise_4_A6_v1.ipynb} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Exercise_4/{2024_07_18_A6_v1.ipynb => exercise_4_A6_v1.ipynb} (100%)

diff --git a/Exercise_4/2024_07_18_A6_v1.ipynb b/Exercise_4/exercise_4_A6_v1.ipynb
similarity index 100%
rename from Exercise_4/2024_07_18_A6_v1.ipynb
rename to Exercise_4/exercise_4_A6_v1.ipynb
-- 
GitLab


From e645906b8cfccb142e91bb9589053249857a82ad Mon Sep 17 00:00:00 2001
From: Amirali Mahjoob <amirali.mahjoob@rwth-aachen.de>
Date: Tue, 29 Apr 2025 16:45:33 +0200
Subject: [PATCH 21/23] Edit .gitignore

---
 .gitignore | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitignore b/.gitignore
index 7e83bf6..f5cbd29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,4 +13,5 @@ __pycache__/
 Excercise_3/Cryptography-Solutions.ipynb
 Exercise_2_5/Exercise_4 _solution.ipynb
 Excercise_2/Exercise_2_DEV_UE2_A2_v2_students.ipynb
+Exercise_4/exercise_4_A6_v1_students.ipynb
 *.zip
-- 
GitLab


From 504fc3ee161d54f736900382483f5a3101fede46 Mon Sep 17 00:00:00 2001
From: Amirali Mahjoob <amirali.mahjoob@rwth-aachen.de>
Date: Tue, 29 Apr 2025 16:50:00 +0200
Subject: [PATCH 22/23] Delete Exercise_2_DEV_UE2_A2_v2_students.ipynb

---
 .../Exercise_2_DEV_UE2_A2_v2_students.ipynb   | 521 ------------------
 1 file changed, 521 deletions(-)
 delete mode 100644 Excercise_2/Exercise_2_DEV_UE2_A2_v2_students.ipynb

diff --git a/Excercise_2/Exercise_2_DEV_UE2_A2_v2_students.ipynb b/Excercise_2/Exercise_2_DEV_UE2_A2_v2_students.ipynb
deleted file mode 100644
index c489a49..0000000
--- a/Excercise_2/Exercise_2_DEV_UE2_A2_v2_students.ipynb
+++ /dev/null
@@ -1,521 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "source": [
-    "# DEV Exercise 2"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "This Jupyter notebook contains tasks that are calculated for you on the blackboard during the exercise session. To practice using python and to see the advantage of programming when dealing with data, you will reprogram parts of it in this Jupyter notebook. If you have not yet installed the packages required for this exercise, run the following cell to install them."
-   ],
-   "metadata": {
-    "collapsed": false
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "outputs": [],
-   "source": [
-    "!pip install pandas\n",
-    "!pip install numpy\n",
-    "!pip install scipy\n",
-    "!pip install openpyxl"
-   ],
-   "metadata": {
-    "collapsed": false
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Now run the following cell to import the most important libraries. You can run a cell either by clicking `Run` on the toolbar or by pressing `CTRL+RETURN`."
-   ],
-   "metadata": {
-    "collapsed": false
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {
-    "collapsed": true,
-    "pycharm": {
-     "name": "#%%\n"
-    },
-    "ExecuteTime": {
-     "end_time": "2024-02-23T12:58:40.909857800Z",
-     "start_time": "2024-02-23T12:58:28.941463400Z"
-    }
-   },
-   "outputs": [],
-   "source": [
-    "import matplotlib.pyplot as plt\n",
-    "import pandas as pd\n",
-    "import numpy as np\n",
-    "from scipy.optimize import curve_fit"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Predefine functions\n",
-    "It is good programming practice to define functions at the beginning that you want to use again and again in the course of the code. You can find instructions with examples for defining functions under the following [link](https://www.w3schools.com/python/python_functions.asp). For reasons of overview, however, we will always define these in the respective task section first. As an example, we give you the function <code> round_up(x, decimals) </code>. This function always rounds up values and will be used more frequently throughout the code."
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "outputs": [],
-   "source": [
-    "def round_up(x, decimals: int):\n",
-    "    \"\"\"\n",
-    "    Returns the numerical value given in \"value\", rounded up to the given number of decimal places given in \"decimals\". This function is particularly relevant when dealing with measurement uncertainties, as these must always be rounded up.\n",
-    "\n",
-    "    :param x: value to be rounded\n",
-    "    :param decimals: number of decimals\n",
-    "    :return: rounded up value\n",
-    "    \"\"\"\n",
-    "    value = np.ceil(pow(10, decimals)*x) / pow(10, decimals)\n",
-    "\n",
-    "    return value"
-   ],
-   "metadata": {
-    "collapsed": false
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2a\n",
-    "First, the measurement data must be read in from the Excel spreadsheet. The table contains the measured voltages and currents, each with their uncertainties. Use the [pd.read_excel](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_excel.html) function to do this.\n"
-   ],
-   "metadata": {
-    "collapsed": false
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "outputs": [],
-   "source": [
-    "### First, the data needs to be loaded from the given xlsx-file. Note that all datatypes shall be set to float.\n",
-    "\n",
-    "data = \n",
-    "\n",
-    "### Define arrays with the corresponding voltage and current values for later use.\n",
-    "U       = \n",
-    "sig_U   = \n",
-    "I       = \n",
-    "sig_I   = "
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-02-23T13:00:28.694732900Z",
-     "start_time": "2024-02-23T13:00:28.119399700Z"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2b\n",
-    "After the data has been read in, the resistance and its uncertainty are to be determined for the value pairs. \n",
-    "First add the corresponding code to the functions in the cell below to calculate the resistance with the function <code> def uri(U,I) </code> and the uncertainty with the function def <code> def calc_sig_R(U, I, sig_I) </code>. Why does the function <code> def calc_sig_R(U, I, sig_I) </code> not have the uncertainty of the voltage as an input variable? "
-   ],
-   "metadata": {
-    "collapsed": false
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "outputs": [],
-   "source": [
-    "def uri(U,I):\n",
-    "    \"\"\"\n",
-    "    Returns the value for the resistance following Ohm's law U=R*I\n",
-    "    :param U: voltage value\n",
-    "    :param I: current value\n",
-    "    :return: resistance value\n",
-    "    \"\"\"\n",
-    "    # Complete the code\n",
-    "\n",
-    "    return \n",
-    "\n",
-    "def calc_sig_R(U, I, sig_I):\n",
-    "    \"\"\"\n",
-    "    Returns the value of the uncertainty of the resistance according to Ohm's law and Gaussian error propagation\n",
-    "    :param U: voltage value\n",
-    "    :param I: current value\n",
-    "    :param sig_I: uncertainty of the resistance\n",
-    "    :return: \n",
-    "    \"\"\"\n",
-    "    # Complete the code\n",
-    "    return "
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-02-23T13:00:33.278431500Z",
-     "start_time": "2024-02-23T13:00:33.248408400Z"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Afterwards, add the code here to calculate the resistance with the function<code> def uri(U,I) </code> and add them to your pandas dataframe. Round the values to a suitable number of decimal places using the function [round](https://docs.python.org/3/library/functions.html#round)."
-   ],
-   "metadata": {
-    "collapsed": false
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "outputs": [],
-   "source": [
-    "# Calculate and round the resistance\n",
-    "data.loc[:, \"resistance\"]       = "
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    },
-    "ExecuteTime": {
-     "end_time": "2024-02-23T13:00:43.809786300Z",
-     "start_time": "2024-02-23T13:00:43.786756300Z"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Now calculate the uncertainty, round it up and add it to the dataframe. Then print the dataframe to check your results."
-   ],
-   "metadata": {
-    "collapsed": false
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "outputs": [],
-   "source": [
-    "# Calculate resistance uncertainty\n",
-    "# Remember that uncertainties shall always be rounded up!\n",
-    "data.loc[:, \"resistance_sig\"]   = \n",
-    "\n",
-    "### Print resulting table in one line\n",
-    "pd.set_option(\"expand_frame_repr\", False)\n",
-    "print(data)"
-   ],
-   "metadata": {
-    "collapsed": false
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2e\n",
-    "Now we have several pairs of measured values with different measurement uncertainties. In order to combine the information including the measurement uncertainties, we need to determine a suitable estimated value for the resistance. Calculate an estimation value for the resistance first using the arithmetic mean by using the function [np.mean](https://numpy.org/doc/stable/reference/generated/numpy.mean.html) and secondly using the expression for the weighted mean. The weighted mean is defined by the following formula, which you must add under the function <code> def weighted_mean(x, sig_x) </code> in the cell below:\n",
-    "\n",
-    "\n",
-    "\n",
-    "$\\left<x\\right>=\\frac{\\sum_{i=1}^N x_i / \\sigma_{i,abs}^2}{\\sum_{i=1}^N 1 / \\sigma_{i,abs}^2}$\n",
-    "\n",
-    "\n",
-    "Also calculate the uncertainty of the calculated mean values, in each case using the function [np.std](https://numpy.org/doc/stable/reference/generated/numpy.std.html) for the arithmetic mean and the function <code> def sig_weighted_mean(sig_x) </code> for the weighted mean. In advance, add the following formula to the function <code> def sig_weighted_mean(sig_x) </code> using [np.sqrt](https://numpy.org/doc/stable/reference/generated/numpy.sqrt.html):\n",
-    "\n",
-    "$\\sigma_{\\left<x\\right>}=\\frac{1}{\\sqrt{\\sum_{i=1}^N 1 / \\sigma_{i,abs}^2}}$\n",
-    "\n",
-    "Remember to round the values to a meaningful number of decimal places using [round](https://docs.python.org/3/library/functions.html#round) and <code> def round_up(x, decimals) </code>. \n",
-    "Compare your results and explain where the differences come from! \n"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "outputs": [],
-   "source": [
-    "def weighted_mean(x, sig_x):\n",
-    "    \"\"\"\n",
-    "    Returns the weighted mean of variables x and their uncertainties sig_x\n",
-    "    :param x: array with x values\n",
-    "    :param sig_x: array with uncertainty of respective x value\n",
-    "    :return: weighted mean\n",
-    "    \"\"\"\n",
-    "\n",
-    "    return \n",
-    "\n",
-    "def sig_weighted_mean(sig_x):\n",
-    "    \"\"\"\n",
-    "    Returns the uncertainty of the weighted mean of variables x and their uncertainties sig_x\n",
-    "    :param sig_x: array with uncertainty of respective x value\n",
-    "    :return: uncertainty of weighted mean\n",
-    "    \"\"\"\n",
-    "\n",
-    "    return "
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-02-23T13:01:31.910988Z",
-     "start_time": "2024-02-23T13:01:31.900940200Z"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "outputs": [],
-   "source": [
-    "# Extract the needed data from our dataframe\n",
-    "\n",
-    "n                   = data.shape[0] # number of measurements\n",
-    "R                   = \n",
-    "sig_R               = \n",
-    "\n",
-    "# Calculate the arithmetic mean and its uncertainty and round your results\n",
-    "ar_mean        = \n",
-    "sig_ar_mean    = \n",
-    "\n",
-    "# Calculate the weighted mean and its uncertainty and round your results\n",
-    "w_mean     = \n",
-    "sig_w_mean =\n",
-    "\n",
-    "# Create and print a Dataframe with results\n",
-    "results_2e           = pd.DataFrame(np.array([[ w_mean, ar_mean], [ sig_w_mean, sig_ar_mean ]]), columns=[\"Weighted\", \"Arithmetic\"], index=[\"Mean\", \"Uncertainty\"])\n",
-    "print(results_2e)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2f\n",
-    "\n",
-    "In the lecture and the first part of this exercise session, we learned about the maximum likelihood method on the one hand and solved the analytical solution of the problem here using the ML method on the other.\n",
-    "According to Ohm's law, $I = U/R = m*U$ with $m=1/R$. This results in a linear relationship between the current and the voltage. Using the ML method, we have calculated that the following equation applies for m:\n",
-    "\n",
-    "$m = \\frac{\\sum_{i=1}^N \\frac{x_i \\cdot y_i}{\\sigma_i^2}}{\\sum_{i=1}^N \\frac{ x_i^2}{\\sigma_i^2}}$\n",
-    "\n",
-    "In this case, $x = U$, $y = I$ and $\\sigma_y = \\sigma_I$. Add the function <code> def ml_estimator(x, y, sig_y) </code> to the cell below and determine both the value for the ML estimator $m$ and then the value for the resistance. Round the value for the resistance to a meaningful number of decimal places and compare the value for the resistance with the previous ones. \n"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "outputs": [],
-   "source": [
-    "def ml_estimator(x, y, sig_y):\n",
-    "    \"\"\"\n",
-    "    Returns the parameter m that is determined by using the maximum likelihood method.\n",
-    "    :param x:\n",
-    "    :param y:\n",
-    "    :param sigma:\n",
-    "    :return: m\n",
-    "    \"\"\"\n",
-    "\n",
-    "    return "
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-02-23T13:01:40.086529600Z",
-     "start_time": "2024-02-23T13:01:40.070463800Z"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "outputs": [],
-   "source": [
-    "# Extract needed data from dataframe\n",
-    "x           = \n",
-    "y           = \n",
-    "sig_y       = \n",
-    "\n",
-    "# Calculate best estimate for the parameter m\n",
-    "m           = \n",
-    "R_ml        = \n",
-    "print(\"m = \" + str(m) + \", R = \"+str(R_ml))\n",
-    "\n",
-    "# Create and print a Dataframe with results\n",
-    "results_2f  = pd.DataFrame(np.array([[w_mean, ar_mean, R_ml]]), columns=[\"weighted\", \"arithmetic\", \"ML-method\"])\n",
-    "print(results_2f)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2g\n",
-    "\n",
-    "In practice, the majority of functional relationships can no longer be determined analytically using the ML method. For these cases, the Python package [Scipy](https://scipy.org/) can be used. The [scipy.optimize.curve_fit](https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html) function can be used to estimate the parameters of previously defined functional relationships for a specific data set. In the scipy documentation you will find all relevant information and steps for the implementation. \n",
-    "Use the function to fit a linear relationship to the measurement data according to task 2f). Compare the result for the resistance with the previous ones. "
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%% md\n"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "outputs": [],
-   "source": [
-    "# First, the linear relationship needs to be defined as a function\n",
-    "\n",
-    "    \n",
-    "\n",
-    "# Use curve_fit to solve the problem and print the parameter m with its uncertainty\n",
-    "\n",
-    "\n",
-    "# Calculate the resistance and its uncertainty (Hint: Think about Gaussian Error Propagation!)\n",
-    "\n",
-    "\n",
-    "\n",
-    "# Create and print a Dataframe with results\n",
-    "results_2g  = pd.DataFrame(np.array([[w_mean, ar_mean, R_ml, R_sc]]), columns=[\"weighted\", \"arithmetic\", \"ML-method\", \"Scipy Curve-Fit\"])\n",
-    "print(results_2g)\n"
-   ],
-   "metadata": {
-    "collapsed": false
-   }
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2h\n",
-    "\n",
-    "The $\\Chi^2$ test, which is defined as follows, is suitable for determining the quality of the fit:\n",
-    "\n",
-    "$\\chi^2 = \\sum_{i=1}^N \\frac{(y_i - f(x_i, m))^2}{\\sigma_i^2}$\n",
-    "\n",
-    "Where $x=U$, $y=I$,  $\\sigma_i = \\sigma_y_i$ and $f(x_i,m) = U_i/R$. Complete the function <code> def chi2_formula(x, y, sig_y, R) </code> in the cell below and calculate the $\\Chi^2/n_{d.o.f.}$ for the results from 2e) (arithmetic and weighted mean) and 2g) (Scipy Curve-Fit). Explain what the numerical values for $\\Chi^2/n_{d.o.f.}$ mean.\n",
-    "\n"
-   ],
-   "metadata": {
-    "collapsed": false
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "outputs": [],
-   "source": [
-    "def chi2_formula(x, y, sig_y, R):\n",
-    "    \"\"\"\n",
-    "    Formula to calculate the Chi^2 value in the case of the relationship y = x/R\n",
-    "    :param x: x values\n",
-    "    :param y: y values\n",
-    "    :param sig_y: uncertainty of y values\n",
-    "    :param m: slope\n",
-    "    :return: \n",
-    "    \"\"\"\n",
-    "\n",
-    "    return "
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-02-23T13:07:01.068534900Z",
-     "start_time": "2024-02-23T13:07:01.050115Z"
-    }
-   }
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "outputs": [],
-   "source": [
-    "# Determine n_dof\n",
-    "\n",
-    "n = # Hint: The number of degrees of freedom is the number of measurements minus the number of parameters which were fitted \n",
-    "\n",
-    "# Calculate the Chi^2 and Chi^2/ndof for task 2f\n",
-    "\n",
-    "\n",
-    "# Calculate the Chi^2 and Chi^2/ndof for task 2g\n",
-    "\n",
-    "\n",
-    "# Print the resulting Chi^2/ndof\n",
-    "# Print the resulting Chi^2/ndof\n",
-    "print(\"Chi^2/ndof (Airthmetic Mean) = \" + str(round(chi2_ar_n, 4)))\n",
-    "print(\"Chi^2/ndof (Weighted Mean) = \" + str(round(chi2_weigh_n, 4)))\n",
-    "print(\"Chi^2/ndof (Scipy) = \" + str(round(chi2_sc_n, 4)))\n"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "pycharm": {
-     "name": "#%%\n"
-    }
-   }
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 2
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython2",
-   "version": "2.7.6"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
-- 
GitLab


From 9ee57d00ff9d9887c1593c9b0cd451e7cd35f8ac Mon Sep 17 00:00:00 2001
From: Amirali Mahjoob <amirali.mahjoob@rwth-aachen.de>
Date: Tue, 29 Apr 2025 16:51:22 +0200
Subject: [PATCH 23/23] Delete exercise_4_A6_v1.ipynb

---
 Exercise_4/exercise_4_A6_v1.ipynb | 627 ------------------------------
 1 file changed, 627 deletions(-)
 delete mode 100644 Exercise_4/exercise_4_A6_v1.ipynb

diff --git a/Exercise_4/exercise_4_A6_v1.ipynb b/Exercise_4/exercise_4_A6_v1.ipynb
deleted file mode 100644
index 3e18187..0000000
--- a/Exercise_4/exercise_4_A6_v1.ipynb
+++ /dev/null
@@ -1,627 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "markdown",
-   "source": [
-    "# DEV Exercise 6\n",
-    "In this Jupyter notebook we will deal with the calculation of investment and operational costs. If you have not yet installed the packages required for this exercise, run the following cell to install them."
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "72ab3cf5505dbbc2"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "outputs": [],
-   "source": [
-    "!pip install pandas\n",
-    "!pip install pandapower\n",
-    "!pip install simbench"
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "e99cc0f65671eb71"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Now run the following cell to import the most important libraries. You can run a cell either by clicking Run on the toolbar or by pressing CTRL+RETURN."
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "ddeb3acb51e3e4cd"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "id": "initial_id",
-   "metadata": {
-    "collapsed": true,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:20:24.081312800Z",
-     "start_time": "2024-06-03T14:20:24.064701400Z"
-    }
-   },
-   "outputs": [],
-   "source": [
-    "import warnings\n",
-    "warnings.simplefilter(action='ignore', category=FutureWarning)\n",
-    "\n",
-    "import pandas as pd\n",
-    "pd.options.display.max_rows = 10\n",
-    "\n",
-    "import pandapower as pp\n",
-    "import simbench as sb"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Example grid\n",
-    "\n",
-    "We will carry out the calculation using a [SimBench](https://simbench.readthedocs.io/en/stable/) example grid. SimBench is a database with synthetic grid data that maps different grid structures in low voltage. Import the grid “1-LV-rural1--0-sw” and print its properties (number and type of assets). The standard types in particular are required later for the calculation of annuities. \n"
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "4963cb76c621b1bc"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "outputs": [
-    {
-     "data": {
-      "text/plain": "               name              std_type  from_bus  to_bus  length_km  \\\n0    LV1.101 Line 1  NAYY 4x150SE 0.6/1kV         9       2   0.055767   \n1    LV1.101 Line 2  NAYY 4x150SE 0.6/1kV        13      11   0.053576   \n2    LV1.101 Line 3  NAYY 4x150SE 0.6/1kV         6       3   0.049814   \n3    LV1.101 Line 4  NAYY 4x150SE 0.6/1kV         8       1   0.017886   \n4    LV1.101 Line 5  NAYY 4x150SE 0.6/1kV         7      10   0.016089   \n..              ...                   ...       ...     ...        ...   \n8    LV1.101 Line 9  NAYY 4x150SE 0.6/1kV         5      13   0.137215   \n9   LV1.101 Line 10  NAYY 4x150SE 0.6/1kV         3       0   0.132499   \n10  LV1.101 Line 12  NAYY 4x150SE 0.6/1kV         1       3   0.016207   \n11  LV1.101 Line 13  NAYY 4x150SE 0.6/1kV        12       8   0.046015   \n12  LV1.101 Line 11  NAYY 4x150SE 0.6/1kV         4       5   0.002583   \n\n    r_ohm_per_km  x_ohm_per_km  c_nf_per_km  g_us_per_km  max_i_ka   df  \\\n0         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n1         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n2         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n3         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n4         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n..           ...           ...          ...          ...       ...  ...   \n8         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n9         0.2067      0.080425   829.999394          0.0      0.27  1.0   \n10        0.2067      0.080425   829.999394          0.0      0.27  1.0   \n11        0.2067      0.080425   829.999394          0.0      0.27  1.0   \n12        0.2067      0.080425   829.999394          0.0      0.27  1.0   \n\n    parallel type  in_service voltLvl  max_loading_percent   subnet  \n0          1   cs        True       7                100.0  LV1.101  \n1          1   cs        True       7                100.0  LV1.101  \n2          1   cs        True       7                100.0  LV1.101  \n3          1   cs        True       7                100.0  LV1.101  \n4          1   cs        True       7                100.0  LV1.101  \n..       ...  ...         ...     ...                  ...      ...  \n8          1   cs        True       7                100.0  LV1.101  \n9          1   cs        True       7                100.0  LV1.101  \n10         1   cs        True       7                100.0  LV1.101  \n11         1   cs        True       7                100.0  LV1.101  \n12         1   cs        True       7                100.0  LV1.101  \n\n[13 rows x 17 columns]",
-      "text/html": "<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>name</th>\n      <th>std_type</th>\n      <th>from_bus</th>\n      <th>to_bus</th>\n      <th>length_km</th>\n      <th>r_ohm_per_km</th>\n      <th>x_ohm_per_km</th>\n      <th>c_nf_per_km</th>\n      <th>g_us_per_km</th>\n      <th>max_i_ka</th>\n      <th>df</th>\n      <th>parallel</th>\n      <th>type</th>\n      <th>in_service</th>\n      <th>voltLvl</th>\n      <th>max_loading_percent</th>\n      <th>subnet</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>LV1.101 Line 1</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>9</td>\n      <td>2</td>\n      <td>0.055767</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>LV1.101 Line 2</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>13</td>\n      <td>11</td>\n      <td>0.053576</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>LV1.101 Line 3</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>6</td>\n      <td>3</td>\n      <td>0.049814</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>LV1.101 Line 4</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>8</td>\n      <td>1</td>\n      <td>0.017886</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>LV1.101 Line 5</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>7</td>\n      <td>10</td>\n      <td>0.016089</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>...</th>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n      <td>...</td>\n    </tr>\n    <tr>\n      <th>8</th>\n      <td>LV1.101 Line 9</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>5</td>\n      <td>13</td>\n      <td>0.137215</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>9</th>\n      <td>LV1.101 Line 10</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>3</td>\n      <td>0</td>\n      <td>0.132499</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>10</th>\n      <td>LV1.101 Line 12</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>1</td>\n      <td>3</td>\n      <td>0.016207</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>11</th>\n      <td>LV1.101 Line 13</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>12</td>\n      <td>8</td>\n      <td>0.046015</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n    <tr>\n      <th>12</th>\n      <td>LV1.101 Line 11</td>\n      <td>NAYY 4x150SE 0.6/1kV</td>\n      <td>4</td>\n      <td>5</td>\n      <td>0.002583</td>\n      <td>0.2067</td>\n      <td>0.080425</td>\n      <td>829.999394</td>\n      <td>0.0</td>\n      <td>0.27</td>\n      <td>1.0</td>\n      <td>1</td>\n      <td>cs</td>\n      <td>True</td>\n      <td>7</td>\n      <td>100.0</td>\n      <td>LV1.101</td>\n    </tr>\n  </tbody>\n</table>\n<p>13 rows × 17 columns</p>\n</div>"
-     },
-     "execution_count": 6,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "sb_code1 = \"1-LV-rural1--0-sw\"\n",
-    "net = sb.get_simbench_net(sb_code1)\n",
-    "net\n",
-    "net.line"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:21:02.405316800Z",
-     "start_time": "2024-06-03T14:20:58.805268800Z"
-    }
-   },
-   "id": "ce2565ab7f9d932b"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Afterwards, you can plot the SimBench grid by using [the pandapower simple plotting tool](https://pandapower.readthedocs.io/en/v2.0.1/plotting/matplotlib/simple_plot.html)."
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "f25c7b3b43552621"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "outputs": [
-    {
-     "data": {
-      "text/plain": "<Figure size 1000x800 with 1 Axes>",
-      "image/png": "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AMA0eAYdACrii1/8Yt70pjclSQ477LC89a1vzVVXXZVHHnkkc+fOzWGHHZZTTz019957b4499tisWLEiIyMjufvuu7Pzzjv39/AAwJQEOgBUxHOe85xcf/31SZJtt902S5cufdJjRkZG8trXvjYLFizIpz71qSTJ3/7t3+b9739/T88KAEyfQAeACli5cuW0Bt/22WefNcvuJ5xwQr73ve9162gAwAzxGnQAqIBly5Y96cde85rX5LLLLstvfvOb3HLLLXnf+96XbbfdNknWxHmSSZ9pBwDK4xl0AKiA+++/PwsXLlzz9le/+tW88pWvfNLjfvnLX+Z5z3te7rnnnjU/9oIXvCCXXXZZT84JAGw+z6ADQAX8y7/8y3pv77fffpM+7mlPe9qa155POOqoo7p1LABgBgl0AKiAb37zm+u9/Z73vCerVq2a9LEHHHBAGo3Gmrff+MY3dvVsAMDMEOgAUAEPPvjgem9ffvnleeELX5irrroqE69We/zxx3PBBRfkuOOOy7qvYJt4XToAULbhfh8AAJjanDlz1vv+448/nquvvjrPe97zsvvuu2ennXbKnXfeOemY3LrvCwCUyzPoAFABBx100Jrvv+Md78iuu+665u277747//Ef/zFpnO++++6ZP39+T84IAGwZgQ4AFXDGGWes+f43vvGN3HTTTfnyl7+c4447LvPmzUuz2cwOO+yQ173udTnppJPWe791X48OAJRLoANABRx66KF57nOfm6T9pdROOumkHHDAAfnBD36QRx99NGNjY1m8eHHmzZuXb3/720mS2bNn5/TTT+/nsQGAafB10AGgIu68884cddRRefjhh9f82M4775xDDz00IyMj+e53v5vVq1ev+bkLLrjAgjsAVIhAB4AKWbRoUU466aTcfffdG33MyMhIzj777Jx66qk9PBkAsKVccQeACjnooIOyePHifPazn83w8PpfjGX77bfPX/zFX+SOO+4Q5wBQQZ5BB4AKWrp0aRYsWJAkedaznpWvfe1r2X333TMyMtLfgwEAm83XQQeACrrtttvWfP/www/P0572tD6eBgCYCa64A0AFLV68eM33DzzwwD6eBACYKQIdACpo3UA/4IAD+ngSAGCmCHQAqKBbb711zfc9gw4A9SDQAaCCJp5B32677bLLLrv0+TQAwEwQ6ABQMUuXLs0999yTpH29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"
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    },
-    {
-     "data": {
-      "text/plain": "<Axes: >"
-     },
-     "execution_count": 5,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "pp.plotting.simple_plot(net, show_plot=True)"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:20:39.998814Z",
-     "start_time": "2024-06-03T14:20:39.471146800Z"
-    }
-   },
-   "id": "2eb6d9517e99be23"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2a \n",
-    "\n",
-    "To calculate the annuities, we must first determine the investment costs of the lines and transformer types. For this purpose, read these from the Excel table using [the pandas function \"read_excel\"](https://pandas.pydata.org/docs/reference/api/pandas.read_excel.html)."
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "e43234c36ca7e4ba"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "outputs": [],
-   "source": [
-    "line_std_types = pd.read_excel(io=\"./std_type_costs.xlsx\", index_col=[0], sheet_name=\"line_std_types\")\n",
-    "trafo_std_types = pd.read_excel(io=\"./std_type_costs.xlsx\", index_col=[0], sheet_name=\"trafo_std_types\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:21:58.923764700Z",
-     "start_time": "2024-06-03T14:21:58.809907500Z"
-    }
-   },
-   "id": "c6f5410eee07a074"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2b\n",
-    "Calculate the total investment cost in t=0 for the transformer and the lines.\n",
-    "For the equipment with unit prices the total costs can be calculated via\n",
-    "$C_{inv} = \\sum_{pc=1}^{n} {C_{pc}} = n \\cdot C_{pc}$"
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "90aeb0e3ed2ee0d4"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The investment costs for trafos are : 13.0 mio. €\n"
-     ]
-    }
-   ],
-   "source": [
-    "trafo_name = net.trafo.std_type[0]\n",
-    "c_inv_trafo = len(net.trafo) * trafo_std_types.at[trafo_name, \"cost_per_piece\"]\n",
-    "print(f\"The investment costs for trafos are : {round(c_inv_trafo/1e6, 2)} mio. €\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:02.934409600Z",
-     "start_time": "2024-06-03T14:22:02.914839400Z"
-    }
-   },
-   "id": "527eba7f1fdd1827"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "For the equipment with length related costs:\n",
-    "$C_{inv} = \\sum_{pc=1}^{n} {l_{pc} \\cdot C_l} = (\\sum_{pc=1}^{n} {l_{pc}}) \\cdot C_l$.\n",
-    "First sum up over the total line length using [pandas groupby](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.groupby.html)."
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "de5e30b6e28016b7"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The line length is : 0.56 km\n"
-     ]
-    }
-   ],
-   "source": [
-    "line_name = net.line.std_type[0]\n",
-    "sum_lines = net.line[[\"std_type\", \"length_km\"]].groupby(\"std_type\").sum().at[line_name, \"length_km\"]\n",
-    "print(f\"The line length is : {round(sum_lines, 3)} km\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:07.921782200Z",
-     "start_time": "2024-06-03T14:22:07.887759400Z"
-    }
-   },
-   "id": "4731e97d3b9e66f1"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The investment costs for lines are : 0.01 mio. €\n"
-     ]
-    }
-   ],
-   "source": [
-    "c_inv_lines = sum_lines * line_std_types.at[line_name, \"cost_per_km\"]\n",
-    "print(f\"The investment costs for lines are : {round(c_inv_lines/1e6, 2)} mio. €\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:09.292713800Z",
-     "start_time": "2024-06-03T14:22:09.267721Z"
-    }
-   },
-   "id": "3e4b323df9b033ec"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "Afterwards, calculate the total investment cost of the grid by:\n",
-    "$C_{grid,inv} = \\sum_{equip.} {C_{inv,equip.}}$"
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "1262245f8ee4319d"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The total grid costs are : 13.01 mio. €\n"
-     ]
-    }
-   ],
-   "source": [
-    "c_total = c_inv_trafo + c_inv_lines\n",
-    "print(f\"The total grid costs are : {round(c_total/1e6, 2)} mio. €\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:17.122947500Z",
-     "start_time": "2024-06-03T14:22:17.097954900Z"
-    }
-   },
-   "id": "f56701e0558fd50e"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2c\n",
-    "Calculate the annuity factors for the different lifetimes and components.\n",
-    "The annuity factors for the different lifetimes can be calculated via:\n",
-    "$a=\\frac{q^{T,max} \\cdot (q-1)}{q^{T,max}-1}$\n",
-    "\n",
-    "The lifetimes $T_{max}$ of the assets can be found in the Excel tables or data frames. First, define a function to calculate the annuity. This should have the lifetime and the discount rate $q = 1+r$ as input data. Usually, distribution grid operators assume an interest rate of $r=5\\%$."
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "4a8f16d1e3d93bcc"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "outputs": [],
-   "source": [
-    "interestrate=0.05\n",
-    "\n",
-    "def annuity(n, r=interestrate):\n",
-    "    \"\"\"Calculate the annuity factor for an asset with lifetime n years and\n",
-    "    discount rate of r\"\"\"\n",
-    "\n",
-    "    q=1+r\n",
-    "\n",
-    "    if r > 0:\n",
-    "        return (q**n*(q-1))/(q**n-1)\n",
-    "    else:\n",
-    "        return 1/n"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:21.141660Z",
-     "start_time": "2024-06-03T14:22:21.122542800Z"
-    }
-   },
-   "id": "ba8c3aebb2b2edf1"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "The following annuity costs then result for the components:"
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "8bc1eeef24887502"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The annuity factor for the lines is : 0.0611\n"
-     ]
-    }
-   ],
-   "source": [
-    "ann_lines = annuity(line_std_types.at[line_name, \"lifetime\"])\n",
-    "print(f\"The annuity factor for the lines is : {round(ann_lines, 4)}\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:23.374625200Z",
-     "start_time": "2024-06-03T14:22:23.328846900Z"
-    }
-   },
-   "id": "e63a003d70957a59"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The annuity factor for the trafos is : 0.0651\n"
-     ]
-    }
-   ],
-   "source": [
-    "ann_trafo = annuity(trafo_std_types.at[trafo_name, \"lifetime\"])\n",
-    "print(f\"The annuity factor for the trafos is : {round(ann_trafo, 4)}\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:24.896539Z",
-     "start_time": "2024-06-03T14:22:24.868448200Z"
-    }
-   },
-   "id": "966f8b18dc754e17"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2d\n",
-    "Afterwards, calculate the operating costs for the transformer and the lines. The operating costs can be found in the corresponding Excel files or data frames. The operating costs correspond to the multiplication of the investment costs with the specific operating costs from the Excel table or data frame."
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "6e9b5e1600f9bf78"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The operating costs for lines are : 156.49 €\n"
-     ]
-    }
-   ],
-   "source": [
-    "c_o_lines = c_inv_lines * line_std_types.at[line_name, \"operating_cost\"]\n",
-    "print(f\"The operating costs for lines are : {round(c_o_lines, 2)} €\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:36.659044600Z",
-     "start_time": "2024-06-03T14:22:36.638976800Z"
-    }
-   },
-   "id": "644d4a2306910ee6"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 17,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The operating costs for transformer are : 0.39 mio. €\n"
-     ]
-    }
-   ],
-   "source": [
-    "c_o_trafo = c_inv_trafo * trafo_std_types.at[trafo_name, \"operating_cost\"]\n",
-    "print(f\"The operating costs for transformer are : {round(c_o_trafo/1e6, 2)} mio. €\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:39.725035900Z",
-     "start_time": "2024-06-03T14:22:39.704038Z"
-    }
-   },
-   "id": "1faf1a9504e028da"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2e\n",
-    "Calculate the annual cost of the grid equipment (sum of operating and investment costs)."
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "79769693879cb833"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 18,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The annual grid costs are : 1.24 mio. €\n"
-     ]
-    }
-   ],
-   "source": [
-    "c_ann_total = ann_lines * c_inv_lines + ann_trafo * c_inv_trafo + c_o_lines + c_o_trafo  \n",
-    "print(f\"The annual grid costs are : {round(c_ann_total/1e6, 2)} mio. €\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:45.654863600Z",
-     "start_time": "2024-06-03T14:22:45.633570100Z"
-    }
-   },
-   "id": "de48aec2ff9058bf"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2f\n",
-    "In the course of digitizing the distribution grids, it is advisable to equip most of the LV system equipment with measurement technology. For our system, the following assumptions can be made:\n",
-    "- The specific investment costs for the measurement technology system in the transformer station is 500.000€, the interest rate equals 5%/a and its lifetime equals 20 years\n",
-    "- Every grid customer within our grid will also be equipped with a smart meter. As the smart meters belong to the metering point operator and not the distribution grid operator, there are no investment costs here.\n",
-    "- Because metering technology allows the grid to operate more efficiently, the lifetimes of all other technologies increase by 5 years\n",
-    "\n",
-    "Calculate the new annuity of investment costs for the total system with the measurement technology"
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "ee9bcd85e1c42abc"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 19,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The new annual grid costs are : 1.22 mio. €\n"
-     ]
-    }
-   ],
-   "source": [
-    "c_ann_trafo = 1 * trafo_std_types.at[trafo_name, \"cost_per_piece\"] * annuity(trafo_std_types.at[trafo_name, \"lifetime\"] + 5)\n",
-    "c_ann_lines = sum_lines * line_std_types.at[line_name, \"cost_per_km\"] * annuity(line_std_types.at[line_name, \"lifetime\"] + 5)\n",
-    "\n",
-    "c_inv_measure = 500000\n",
-    "lifetime_measure = 20\n",
-    "c_ann_measure = annuity(lifetime_measure) * c_inv_measure\n",
-    "\n",
-    "c_ann_total_new = c_ann_trafo + c_ann_lines + c_o_trafo + c_o_lines + c_ann_measure\n",
-    "print(f\"The new annual grid costs are : {round(c_ann_total_new/1e6, 2)} mio. €\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:48.991815900Z",
-     "start_time": "2024-06-03T14:22:48.974735500Z"
-    }
-   },
-   "id": "e9bf09de56cfedb1"
-  },
-  {
-   "cell_type": "markdown",
-   "source": [
-    "### Task 2g\n",
-    "What are the maximum annual operating costs for the measurement equipment in order to still be cheaper than without measurement equipment?"
-   ],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "51cf92fb26790ff"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 20,
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "The maximum annual operating costs can be : 11651.6 €\n"
-     ]
-    }
-   ],
-   "source": [
-    "c_o_measure = c_ann_total - c_ann_total_new\n",
-    "print(f\"The maximum annual operating costs can be : {round(c_o_measure, 2)} €\")"
-   ],
-   "metadata": {
-    "collapsed": false,
-    "ExecuteTime": {
-     "end_time": "2024-06-03T14:22:54.454657700Z",
-     "start_time": "2024-06-03T14:22:54.436729800Z"
-    }
-   },
-   "id": "b749b6d14d16ff43"
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "outputs": [],
-   "source": [],
-   "metadata": {
-    "collapsed": false
-   },
-   "id": "dfd9b25d20fc7b6c"
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 2
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython2",
-   "version": "2.7.6"
-  }
- },
- "nbformat": 4,
- "nbformat_minor": 5
-}
-- 
GitLab