diff --git a/1_Basics.ipynb b/1_Basics.ipynb
index 7f816cecfd0d785cda2d2f8c4fe5c084667c02a8..4b76a6d04d50fc0f5c3940dfb1dcf5d2eaf21d35 100644
--- a/1_Basics.ipynb
+++ b/1_Basics.ipynb
@@ -133,7 +133,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "76trombones = \"big parade\""
+    "1test = \"hello\""
    ]
   },
   {
@@ -153,7 +153,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "struct = \"Advanced Theoretical Zymurgy\""
+    "struct = \"another illegale variable name\""
    ]
   },
   {
@@ -161,7 +161,7 @@
    "id": "cc36688b-c983-43f8-8bdf-9b82aae59909",
    "metadata": {},
    "source": [
-    "It turns out that struct is one of Julia’s keywords. The REPL uses keywords to recognize the structure of the program, and they cannot be used as variable names."
+    "It turns out that struct is one of Julia’s keywords, and they cannot be used as variable names."
    ]
   },
   {
@@ -225,7 +225,7 @@
    "id": "61ff8194-669c-4ece-ba31-44e88ed808ac",
    "metadata": {},
    "source": [
-    "## Exercises"
+    "### Exercises"
    ]
   },
   {
@@ -253,22 +253,6 @@
     "  - Suppose the cover price of a book is € 24.95, but bookstores get a 40 % discount. Shipping costs € 3 for the first copy and 75 cents for each additional copy. What is the total wholesale cost for 60 copies?"
    ]
   },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "id": "5d99fb94-0d78-4812-abbb-b528bc8cbf73",
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "markdown",
-   "id": "4f6858ae-316a-4102-b9d8-9a5e087af1ca",
-   "metadata": {},
-   "source": [
-    "  - If I leave my house at 6:52 am and run 1 km at an easy pace (6:00 per km), then 3 km at tempo (5:00 per km) and 1 km at easy pace again, what time o I get home for breakfast?"
-   ]
-  },
   {
    "cell_type": "code",
    "execution_count": null,
@@ -446,6 +430,15 @@
     "x < 5 ? \"smaller than 5\" : \"larger or equal 5\""
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "b597c363-8066-470e-b1c8-edd00b114317",
+   "metadata": {},
+   "source": [
+    "For more details\n",
+    "    https://docs.julialang.org/en/v1/manual/control-flow/"
+   ]
+  },
   {
    "cell_type": "markdown",
    "id": "e4510840-0890-4217-8a8c-c24aa5d3405b",
@@ -575,26 +568,20 @@
    "id": "bdb2eef9-bdee-4cf3-8bab-d6c1d46ecc2f",
    "metadata": {},
    "source": [
-    "The mathematician Srinivasa Ramanujan found an infinite series that can be used to generate a numerical approximation of 1/π"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "id": "feeb613b-544b-4a01-8817-9db86b8775e3",
-   "metadata": {},
-   "source": [
-    "    1    2 √2   ∞   (4k)! (1103 + 26390 k)\n",
-    "    - = ------  ∑  ------------------------\n",
-    "    π    9801  k=0      (k!)^4 396^(4 k)"
+    "The mathematician Srinivasa Ramanujan found an infinite series that can be used to generate a numerical approximation of 1/π\n",
+    "\n",
+    "$$ \\frac{1}{\\pi} = \\frac{2\\sqrt{2}}{9801} \\sum_{k=0}^\\infty \\frac{(4k)! (1103 + 26390 k)}{(k!)^4 396^{4 k}}$$\n",
+    "\n",
+    "Use this formula to compute an estimate of π. It should use a while loop ot compute terms of the summation untile the last term is smaller than 1e-15. Afterwards, you can check the result by comparing it to π (to get π in Julia, write \\pi and then press TAB)."
    ]
   },
   {
-   "cell_type": "markdown",
-   "id": "8a8ae5ef-f9ec-480e-9927-8d21ecdf1915",
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "9243c8ee-b3b9-4e23-a829-d20fc8bf0b16",
    "metadata": {},
-   "source": [
-    "Use this formula to compute an estimate of π. It should use a while loop ot compute terms of the summation untile the last term is smaller than 1e-15. Afterwards, you can check the result by comparing it to π (to get π in Julia, write \\pi and then press TAB)."
-   ]
+   "outputs": [],
+   "source": []
   },
   {
    "cell_type": "markdown",
@@ -665,29 +652,13 @@
    "metadata": {},
    "source": [
     "Julia provides several mathematical functions.\n",
-    "  - abs(x): Absolute value of x.\n",
-    "  - sqrt(x): Square root of x.\n",
-    "  - cbrt(x): Cube root of x.\n",
-    "  - exp(x): Exponential function e^x.\n",
-    "  - log(x): Natural logarithm of x.\n",
-    "  - log10(x): Base 10 logarithm of x.\n",
-    "  - log2(x): Base 2 logarithm of x.\n",
-    "  - sin(x): Sine of x (in radians).\n",
-    "  - cos(x): Cosine of x (in radians).\n",
-    "  - tan(x): Tangent of x (in radians).\n",
-    "  - asin(x): Arcsine of x (result in radians).\n",
-    "  - acos(x): Arccosine of x (result in radians).\n",
-    "  - atan(x): Arctangent of x (result in radians).\n",
-    "  - sinh(x): Hyperbolic sine of x.\n",
-    "  - cosh(x): Hyperbolic cosine of x.\n",
-    "  - tanh(x): Hyperbolic tangent of x.\n",
-    "  - asinh(x): Inverse hyperbolic sine of x.\n",
-    "  - acosh(x): Inverse hyperbolic cosine of x.\n",
-    "  - atanh(x): Inverse hyperbolic tangent of x.\n",
-    "  - floor(x): Largest integer not greater than x.\n",
-    "  - ceil(x): Smallest integer not less than x.\n",
-    "  - round(x): Nearest integer to x.\n",
-    "  - trunc(x): Integer part of x."
+    "  - abs, sqrt, cbrt, exp, log, log10, log2\n",
+    "  - sin, cos, tan, asin, acos, atan\n",
+    "  - sinh, cosh, tanh, asinh, acosh, atanh\n",
+    "  - floor: Largest integer not greater than x.\n",
+    "  - ceil: Smallest integer not less than x.\n",
+    "  - round: Nearest integer to x.\n",
+    "  - trunc: Integer part of x."
    ]
   },
   {
@@ -695,7 +666,8 @@
    "id": "d048851b-8eac-4dc3-81b7-ea1d625a1db2",
    "metadata": {},
    "source": [
-    "So far, we have only been using the functions that come with Julia, but it is also possible to add new functions. A function definition specifies the name of a new function and the sequence of statements that run when the function is called. Here is an example:"
+    "So far, we have only been using the functions that come with Julia, but it is also possible to add new functions. \n",
+    "Defining functions follows a rather intuitive syntax. The value obtained by evaluating the last expression of a `function` block will be automatically returned:"
    ]
   },
   {
@@ -704,6 +676,501 @@
    "id": "fd2f4828-47f5-4df4-b5bd-a42625487b5a",
    "metadata": {},
    "outputs": [],
+   "source": [
+    "function mymult(x, y)\n",
+    "    x * y\n",
+    "end"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "08bab11e-df61-4906-a925-b93184e5c600",
+   "metadata": {},
+   "source": [
+    "For one-line functions one may also use a convenient short-hand:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5ed8292a-96e2-49ad-8f00-3c07b9483637",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "mysquare(x) = mymult(x, x)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "13b7892e-df8a-462f-a84c-107276d8e499",
+   "metadata": {},
+   "source": [
+    "Both such functions are fully generic in the argument types"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "49ceeeff-5291-460d-800d-5ed11a03b13e",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "@show mysquare(2)           # Use integer arithmetic\n",
+    "@show mymult(-1, 3. + 2im)  # Use complex arithmetic\n",
+    "@show mysquare(\" abc \");    # Use string concatenation"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "15ece147-0384-4c1b-a8c3-d11a795bd1b7",
+   "metadata": {},
+   "source": [
+    "Notice, that for each type combination a separate piece of code will be compiled even though we only *defined* the functionality a single time. This compilation takes place on first use of a particular tuple of types."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7e5dcfeb-960a-47f3-b2f8-f6f0906d2f24",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "mymult"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "934dc8e8-564b-4566-9eb0-a96df39f0870",
+   "metadata": {},
+   "source": [
+    "and may be passed around to other functions, for example:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "171b1a83-c076-4ac4-a309-9d607ea0b5a4",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\"\"\"The fold function, applying f from the left and accumulating the results\"\"\"\n",
+    "function myfold(f, x, y, z)\n",
+    "    f(f(x, y), z)\n",
+    "end\n",
+    "myfold(mymult, \"Hello\", \" Julia \", \"World\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "f31327e4-5d69-4dfb-a4bf-ed1e419b1be3",
+   "metadata": {},
+   "source": [
+    "Julia makes a distinction between **functions** and **methods**. Roughly speaking **function**s specify *what* is done and **methods** specify *how* this is done.\n",
+    "\n",
+    "Methods are concrete implementations in form of a list of Julia expressions to be executed, when the function name is used in the code. Multiple methods may be defined for the same function name. They differ in the number of arguments or in the supported argument types (more on this in a second). When a particular function name is used in the code, Julia looks at the types of the arguments and uses this information to **dispatch** to the best-fitting method. \n",
+    "\n",
+    "For our `myfold` example, one could easily imagine a few more method implementations, for example "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "c249f818-6544-42fe-b387-34058e5f5890",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "myfold(f, x) = x\n",
+    "myfold(f, x, y) = f(x, y)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "88f62159-2a1b-4a5a-8434-0e91810f2c69",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "methods(myfold)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "879d9441-ece1-4f07-a496-6aef71fd2e91",
+   "metadata": {},
+   "source": [
+    "So now `myfold` works transparently with 1, 2 or 3 arguments:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d67f9c21-2c5c-43fd-a7e4-a4ce74281bf0",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "@show myfold(mymult, 2., 3.)\n",
+    "@show myfold(+, 1)\n",
+    "@show myfold(==, false, false, true)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "59fa4c2a-a1fa-4a1b-9529-68f821589206",
+   "metadata": {},
+   "source": [
+    "We can also check which method is actually employed using the `@which` macro:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "0fa105fb-b3ad-405a-85f1-598a12cbc655",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "@which myfold(*, 1, 2)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "73fa3be7-67a8-4817-9d94-e04765513dd3",
+   "metadata": {},
+   "source": [
+    "Standard functions (like `+` or `*`) are by no means special and behave exactly the same way as custom functions ... including the ability to define new methods for them:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d771af33-5174-4a95-b8e3-ac1c29eb71e9",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import Base: + # we have to import functions to override/extend them\n",
+    "+(x::String, y::String) = x * \" \" * y"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "32429003-4879-4a37-ad3c-153857a360dd",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\"Hello\" + \"World!\""
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8fdf6362-7ca3-4d32-a542-26df56b83108",
+   "metadata": {},
+   "source": [
+    "(**Important note:** Since we neither own the `+` function nor the `String` type, this is known as **type piracy** and should in general be avoided!)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "89ffcdef-cf06-438f-8448-4bf6dfd1af7e",
+   "metadata": {},
+   "source": [
+    "Now standard functions relying on `+` just magically work:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "75b4afeb-a3f4-40d7-8b23-b961b01c41bc",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sum([\"a\", \"b\", \"c\", \"d\", \"e\"])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d8edaaf0-3de7-4a63-b0bd-bff53ba060f4",
+   "metadata": {},
+   "source": [
+    "Variables and Parameters Are Local:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d02e6bca-6723-4a05-82ee-1f30ba127bd5",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "function multiply_and_print(a, b)\n",
+    "    product = a * b\n",
+    "    println(product)\n",
+    "end\n",
+    "\n",
+    "multiply_and_print(2, 3)\n",
+    "println(product)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "29968f96-5766-4cb7-8538-3bef9aeb8cc9",
+   "metadata": {},
+   "source": [
+    "It may not be clear why it is worth the trouble to divide a program into functions. There are several reasons:\n",
+    "  - Creating a new function gives you an opportunity to name a group of statements, which makes your program easier to read and debug.\n",
+    "  - Functions can make a program smaller by eliminating repetitive code. Later, if you make a change, you only have to make it in one place.\n",
+    "  - Dividing a long program into functions allows you to debug the parts one at a time and then assemble them into a working whole.\n",
+    "  - Well-designed functions are often useful for many programs. Once you write and debug one, you can reuse it.\n",
+    "  - In Julia, functions can improve performance a lot.\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7780ae66-db68-48c1-ba62-a883406f1f1c",
+   "metadata": {},
+   "source": [
+    "More details\n",
+    "    https://docs.julialang.org/en/v1/manual/methods/"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d914b36b-8b05-4c68-bf57-1fc74aeb26df",
+   "metadata": {},
+   "source": [
+    "### Exercises"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "247215e4-47e1-4eb6-978b-a09f14478bb8",
+   "metadata": {},
+   "source": [
+    "  - Write a function printgrid that draws a grid like the following:"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "1704f451-9500-41c5-b74b-4a2b4a7b910f",
+   "metadata": {},
+   "source": [
+    "    + - - - - + - - - - +\n",
+    "    |         |         |\n",
+    "    |         |         |\n",
+    "    |         |         |\n",
+    "    |         |         |\n",
+    "    + - - - - + - - - - +\n",
+    "    |         |         |\n",
+    "    |         |         |\n",
+    "    |         |         |\n",
+    "    |         |         |\n",
+    "    + - - - - + - - - - +"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "58ef3248-f85e-4825-bf10-02cee3e068cb",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e6a58742-9d24-47a5-aa68-73d44ca05127",
+   "metadata": {},
+   "source": [
+    "  - Write a function that draws a similar grid with four rows and four columns."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "b953857f-e8d7-47aa-bc8d-8e2bd1cd20fd",
+   "metadata": {},
+   "source": [
+    "Tips:\n",
+    "  - To print more than one value on a line, you can print a comma-separated sequence of values: println(\"+\", \"-\").\n",
+    "  - The function print does not advance to the next line."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "2ebc911c-7fe0-4d7f-ab5d-d8084f25a93d",
+   "metadata": {},
+   "source": [
+    "### Recursive functions\n",
+    "\n",
+    "It is legal for one function to call another; it is also legal for a function to call itself. It may not be obvious why that is a good thing, but it turns out to be one of the most magical things a program can do. For example, look at the following function:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "e578011e-d0de-4f86-8c2c-a8408454d3ac",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "function countdown(n)\n",
+    "    if n ≤ 0\n",
+    "        println(\"Blastoff!\")\n",
+    "    else\n",
+    "        print(n, \" \")\n",
+    "        countdown(n-1)\n",
+    "    end\n",
+    "end"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "3af51513-c92e-4488-b2fe-243e2fef6b95",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "countdown(10)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "c59c0f54-d967-4416-b57c-e855dfc2c350",
+   "metadata": {},
+   "source": [
+    "If a recursion never reaches a base case, it goes on making recursive calls forever, and the program never terminates. This is known as infinite recursion, and it is generally not a good idea. Here is a minimal program with an infinite recursion: "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "13a4a762-6584-47ab-9fb5-428557770d15",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "function recurse()\n",
+    "    recurse()\n",
+    "end"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "0dde579f-6b12-4072-aa62-aeee3a970503",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "recurse()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "22c8c79d-6d41-4758-9550-aaab4f1dc1b1",
+   "metadata": {},
+   "source": [
+    "### Exercise\n",
+    "  - Write a recursive function to compute the factorial of a number.\n",
+    "  - Then write a function that computes bynomial coefficients\n",
+    "$$ \\left(\\begin{array}{c} n \\\\ k \\end{array}\\right) = \\frac{n!}{k! (n-k)!} $$\n",
+    " by calling the function of the previous points.\n",
+    "  - Use the two functions to compute\n",
+    "$$ 15! \\qquad \\left(\\begin{array}{c} 5 \\\\ 2 \\end{array}\\right) \\qquad \\left(\\begin{array}{c} 5 \\\\ 3 \\end{array}\\right) $$"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "240cc4bd-3e45-45b8-ad98-170dbb68f78d",
+   "metadata": {},
+   "source": [
+    "### Keywords argument\n",
+    "\n",
+    "Function arguments can be either position based (like what we saw so far) or keyword based, like in the following example."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "30ddeb3b-be35-40eb-8491-1269a4e19f62",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "function greet(name; greeting=\"Hello\")\n",
+    "    println(\"$(greeting), $(name)!\")\n",
+    "end"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "b39f22b1-4a1b-4afd-b6db-041bd7150b66",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "greet(\"Michele\")\n",
+    "greet(\"Lambert\"; greeting=\"Hallo\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "52b90aa8-4b19-4371-8fae-2121a78fbb96",
+   "metadata": {},
+   "source": [
+    "This is quite convenient in the following cases:\n",
+    "  - to set a default behavior of the function, while retaining the possibility to finely control it.\n",
+    "  - to add at a later point in time new functionality, without breaking retrocompatibility."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "c939f951-2aaf-4e39-a60f-df7600af1d8f",
+   "metadata": {},
+   "source": [
+    "## Further Exercises"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "59e2e997-42f7-426c-bfd0-233724704117",
+   "metadata": {},
+   "source": [
+    "  - Create a function called fibonacci_sum that takes a positive integer n as input. This function should return the sum of the first n terms of the Fibonacci sequence."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "3e704e3b-2c3e-48fa-98c1-3b6ba20f1d65",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "id": "49fd546f-009d-46ff-af61-6954000bce5f",
+   "metadata": {},
+   "source": [
+    "  - Write a function that converts a Celsius temperature in Fahrenheit and returns the result. Additionally, if the temperature is below freezing (0°C), the program should print a message indicating that it's below freezing."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "a30a1812-6116-4441-8786-7450c60ef354",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e2c81cc5-7d0d-4a5a-ba69-81686648df90",
+   "metadata": {},
+   "source": [
+    "  - Write a function which analyzes a sentence. The function should then count and display the number of vowels (both upper and lower case) in the sentence."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "5ce5ed55-b379-44a6-99dc-bcc8130d8d08",
+   "metadata": {},
+   "outputs": [],
    "source": []
   }
  ],