diff --git a/02-recursion-exercices.ipynb b/02-recursion-exercices.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..167b8ab969bb0475dc0c03a5583318d726e319bc
--- /dev/null
+++ b/02-recursion-exercices.ipynb
@@ -0,0 +1,1233 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "a4e4fad3",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Recursion"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a8adef9b",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "skip"
+    }
+   },
+   "source": [
+    "---"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "568202fd",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Exercise 0: Find the maximum value in a list (iterative)\n",
+    "\n",
+    "Write a function `find_maximum_iterative` that takes a list of numbers as input and returns the maximum value in the list. For this question, you are  not allowed to use built-in functions like `max()``."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 62,
+   "id": "431fe8c1-91d1-40f3-a7a4-f4a3770a4a01",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "find_maximum_iterative",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def find_maximum_iterative(L):\n",
+    "    ### BEGIN SOLUTION    \n",
+    "    if len(L) == 0:\n",
+    "        raise ValueError(\"The list is empty.\")\n",
+    "\n",
+    "    max_val = L[0]\n",
+    "    for num in L:\n",
+    "        if num > max_val:\n",
+    "            max_val = num\n",
+    "    return max_val\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 63,
+   "id": "f6baae3c-3660-4add-ab4b-48016cba3030",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "9"
+      ]
+     },
+     "execution_count": 63,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "find_maximum_iterative([1, 3, 5, 7, 9])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 64,
+   "id": "e68b3e9a-418f-4950-9f27-18bb0fe90794",
+   "metadata": {
+    "nbgrader": {
+     "grade": true,
+     "grade_id": "correct_find_maximum_iterative",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert find_maximum_iterative([1, 3, 5, 7, 9]) == 9\n",
+    "assert find_maximum_iterative([-1, -5, -3]) == -1\n",
+    "assert find_maximum_iterative([42]) == 42\n",
+    "assert find_maximum_iterative([4, 8, 8, 2, 7]) == 8\n",
+    "assert find_maximum_iterative([-10, -5, -8, -2, -7]) == -2"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "612dc873-419b-42c5-be36-0accd03ffa79",
+   "metadata": {},
+   "source": [
+    "### Exercise 1: Find the maximum value in a list (recursive)\n",
+    "\n",
+    "Write a recursive version of the previous function; you may use the `max()` function for the recursive call."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 134,
+   "id": "07668fd8",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "find_maximum_recursive",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def find_maximum_recursive(L):\n",
+    "    ### BEGIN SOLUTION\n",
+    "    if len(L) == 1:\n",
+    "        return L[0]\n",
+    "    else:\n",
+    "        return max(L[0], find_maximum_recursive(L[1:]))\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 135,
+   "id": "f9784710-4b2b-434c-bc47-da46fa410749",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "9"
+      ]
+     },
+     "execution_count": 135,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "find_maximum_recursive([1, 3, 5, 7, 9])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 90,
+   "id": "9b0161f8-0539-4e5e-921c-1886e61c0783",
+   "metadata": {
+    "nbgrader": {
+     "grade": true,
+     "grade_id": "correct_find_maximum_recursive",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert find_maximum_iterative([-10, -5, -8, -2, -7]) == find_maximum_recursive([-10, -5, -8, -2, -7])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "005efd41-baa1-4505-b80e-3644d61ea094",
+   "metadata": {},
+   "source": [
+    "### Exercise 2: Sum of digits"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 65,
+   "id": "de424156-0b9b-41d0-8e38-ce335f35cec0",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "sum_of_digits",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def sum_of_digits(n):\n",
+    "    ### BEGIN SOLUTION\n",
+    "    if n < 10:\n",
+    "        return n\n",
+    "    else:\n",
+    "        return n % 10 + sum_of_digits(n // 10)\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 66,
+   "id": "cec0caca-cb2c-4e4d-b004-27b3cf2ff611",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 66,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "sum_of_digits(10)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 67,
+   "id": "bf276ca2-48ed-4e87-80f2-776f54b7062b",
+   "metadata": {
+    "nbgrader": {
+     "grade": true,
+     "grade_id": "correct_sum_of_digits",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert sum_of_digits(10) == sum_of_digits(100000)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e2de630a-f9bd-4d45-959b-430e34cc9044",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "### Exercise 3: Calculate the power"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "id": "abca03a0-7bcd-4ee6-b109-ff2f2da52bb6",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "power",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def power(base, exponent):\n",
+    "    ### BEGIN SOLUTION\n",
+    "    if exponent == 0:\n",
+    "        return 1\n",
+    "    else:\n",
+    "        return base * power(base, exponent - 1)\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "id": "abddd3b1-f75f-4cb6-a09e-54eed489c5b0",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1024"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "power(2, 10)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 70,
+   "id": "8a6605fe-4f6f-45de-84a3-7601e2e2e6f6",
+   "metadata": {
+    "nbgrader": {
+     "grade": true,
+     "grade_id": "correct_power",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert power(2, 10) == 1024"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "715100d3-fc21-49b9-a66d-b5243b4a279d",
+   "metadata": {
+    "tags": []
+   },
+   "source": [
+    "### Exercise 4: Reverse a string"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "id": "ddc9826a-0863-4777-a08d-81b66652b5a5",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "reverse_string",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def reverse_string(s):\n",
+    "    ### BEGIN SOLUTION\n",
+    "    if len(s) == 0:\n",
+    "        return s\n",
+    "    else:\n",
+    "        return reverse_string(s[1:]) + s[0]\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "id": "13acad7e-d03c-4ea6-ad86-baf02e0910eb",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'niamoR'"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "reverse_string(\"Romain\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "id": "453c8e04-6cd9-4581-a206-dd479b6115cd",
+   "metadata": {
+    "nbgrader": {
+     "grade": true,
+     "grade_id": "correct_reverse_string",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert reverse_string(\"\") == \"\"\n",
+    "assert reverse_string(\"AA\") == \"AA\"\n",
+    "assert reverse_string(\"ABC\") == \"CBA\""
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a0c5c115-1f3c-43f3-8098-930c707cd863",
+   "metadata": {},
+   "source": [
+    "def iterative_reverse_string(s):\n",
+    "    reversed_str = \"\"\n",
+    "    for char in s:\n",
+    "        reversed_str = char + reversed_str\n",
+    "    return reversed_str"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "43e10b0c",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5ab8f3c9-ddee-45ab-a013-fdd67d9853e0",
+   "metadata": {},
+   "source": [
+    "### Example 5: convert an interative suite into a recursive tail and non-tail function"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "id": "219add7f",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def sequence(n):\n",
+    "    u = 1\n",
+    "    while n > 0:\n",
+    "        u = 2 * u + 1\n",
+    "        n -= 1\n",
+    "    return u"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "id": "0787df24-8234-4286-b910-5f9e456dd279",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The result is 15\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"The result is {}\".format(sequence(3)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "id": "9c17cf1b-6d05-4589-af2b-c05cfcc33202",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "sequence_recursive_tail",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def sequence_recursive_tail(n):\n",
+    "    ### BEGIN SOLUTION\n",
+    "    if n == 0:\n",
+    "        return 1\n",
+    "    return 2 * sequence_recursive_tail(n - 1) + 1\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "id": "43507c43-de61-414d-b389-c0a771ad9e0c",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The result is still 15\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"The result is still {}\".format(sequence_recursive_tail(3)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "id": "921939d8",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "sequence_recursive_non_tail",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def sequence_recursive_non_tail(n, acc=1):\n",
+    "    ### BEGIN SOLUTION\n",
+    "    if n == 0:\n",
+    "        return acc\n",
+    "    return sequence_recursive_non_tail(n - 1, 2 * acc + 1)\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "id": "b754bf67-3d8d-42d9-a7ca-c43e2995837d",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The result is still  15\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"The result is still  {}\".format(sequence_recursive_non_tail(3)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "id": "dd923b7c-0cab-4678-8dc3-aad2ab9b25f9",
+   "metadata": {
+    "nbgrader": {
+     "grade": true,
+     "grade_id": "correct_sequence_recursive_non_tail",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    },
+    "slideshow": {
+     "slide_type": "slide"
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert sequence_recursive_tail(3) == sequence_recursive_non_tail(3)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "3c28b36a",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Example 6: check if annagram\n",
+    "\n",
+    "Écrire une fonction \\texttt{palindrome} qui indique si un mot peut être lu de manière identique dans les deux sens. Donnez la forme itérative et récursive.\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "id": "51bb3d08",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "annagram_rec",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def annagram_rec(mot):\n",
+    "    ### BEGIN SOLUTION\n",
+    "    if len(mot) < 2: \n",
+    "        return True\n",
+    "    return mot[0] == mot [len(mot) - 1] and palindrome_rec(mot[1:len(mot)-1])\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "id": "0c279628-9b96-4687-8e20-a954ab646e0f",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "annagram_rec(\"laval\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "id": "cf6fa61a-7c6f-4a32-96c2-b9fd50deacc6",
+   "metadata": {
+    "nbgrader": {
+     "grade": true,
+     "grade_id": "correct_annagram_rec",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert annagram_rec(\"\")\n",
+    "assert annagram_rec(\"AA\")\n",
+    "assert not annagram_rec(\"ABC\")\n",
+    "assert annagram_rec(\"ABA\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "798c2875-7940-488a-8458-ad08f6a71c70",
+   "metadata": {},
+   "source": [
+    "### Example 7: Calculate GCD\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "id": "48c65c83-be0c-41c4-8c04-1d29ac4415cb",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def iterative_gcd(a, b):\n",
+    "    while b:\n",
+    "        a, b = b, a % b\n",
+    "    return a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "id": "bf6e1a76",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "recursive_gcd",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def recursive_gcd(a, b):\n",
+    "    ### BEGIN SOLUTION\n",
+    "    if b == 0:\n",
+    "        return a\n",
+    "    else:\n",
+    "        return recursive_gcd(b, a % b)\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "id": "4f1feace",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "recursive_gcd(10, 2)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "id": "e6ff1765-ff4b-49a5-80d3-684d2627e961",
+   "metadata": {
+    "nbgrader": {
+     "grade": true,
+     "grade_id": "correct_recursive_gcd",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert iterative_gcd(10, 2) == recursive_gcd(10, 2)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d8b05edf-9536-4fc1-bfcc-ddbbeee426fc",
+   "metadata": {},
+   "source": [
+    "### Example 8: Calculate average of a list"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "id": "1661dfb5-88f2-411f-8fe2-63bbaa29ce72",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "calculate_average_recursive",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def calculate_average_recursive(lst, index=0):\n",
+    "    ### BEGIN SOLUTION\n",
+    "    if not lst:\n",
+    "        return None\n",
+    "\n",
+    "    if index == len(lst):\n",
+    "        return 0\n",
+    "\n",
+    "    sum_rest = calculate_average_recursive(lst, index + 1)\n",
+    "\n",
+    "    return (lst[index] + sum_rest) / (index + 1)\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "id": "0c5c72c6-3237-4f98-ab96-50a1838b833f",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2.5"
+      ]
+     },
+     "execution_count": 55,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "calculate_average_recursive([1, 2, 3])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "id": "9f18b6b7-d980-4a72-a2a8-3aa201003d21",
+   "metadata": {
+    "nbgrader": {
+     "grade": true,
+     "grade_id": "correct_calculate_average_recursive",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert calculate_average_recursive([1, 2, 3]) == 2.5"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "79eef392-1d3d-46c0-aeee-ac805686e6f1",
+   "metadata": {},
+   "source": [
+    "### Example 9: Check for prime number"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "id": "ac374a08-11c9-47e6-ba11-419549911266",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "is_prime_recursive",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def is_prime_recursive(n, divisor=2):\n",
+    "    ### BEGIN SOLUTION\n",
+    "    if n < 2:\n",
+    "        return False\n",
+    "    \n",
+    "    # Base case: If n is 2, it's a prime number\n",
+    "    if n == 2:\n",
+    "        return True\n",
+    "    \n",
+    "    # Base case: If n is divisible by the current divisor, it's not prime\n",
+    "    if n % divisor == 0:\n",
+    "        return False\n",
+    "    \n",
+    "    # Base case: If the divisor squared is greater than n, it's prime\n",
+    "    if divisor * divisor > n:\n",
+    "        return True\n",
+    "    \n",
+    "    # Recursive case: Check with the next divisor\n",
+    "    return is_prime_recursive(n, divisor + 1)\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "id": "996fc91f",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "True"
+      ]
+     },
+     "execution_count": 42,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "is_prime_recursive(3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "id": "5be1051c-3b60-4810-b855-6f8575ad6380",
+   "metadata": {
+    "nbgrader": {
+     "grade": true,
+     "grade_id": "correct_is_prime_recursive",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert is_prime_recursive(3) "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5423682d-c31f-4a8d-9a0f-6812de7b1ae3",
+   "metadata": {},
+   "source": [
+    "### Example 10: Count occurrences of a given element in a list"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "id": "cfeb0ad0-ed82-499e-9af3-64923291a0e7",
+   "metadata": {
+    "nbgrader": {
+     "grade": false,
+     "grade_id": "count_occurrences",
+     "locked": false,
+     "schema_version": 3,
+     "solution": true,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def count_occurrences(arr, target, index=0):\n",
+    "    ### BEGIN SOLUTION\n",
+    "    if index == len(arr):\n",
+    "        return 0\n",
+    "    \n",
+    "    # Check if the current element is equal to the target element.\n",
+    "    # If it is, increment the count by 1.\n",
+    "    count = (1 if arr[index] == target else 0)\n",
+    "    \n",
+    "    # Recursively call the function on the rest of the list (from the next index).\n",
+    "    return count + count_occurrences(arr, target, index + 1)\n",
+    "    ### END SOLUTION"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 59,
+   "id": "49daec07-00b3-412e-ad44-5bafadbd9f36",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4"
+      ]
+     },
+     "execution_count": 59,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "count_occurrences([1, 2, 3, 4, 2, 2, 5, 6, 2], 2)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 60,
+   "id": "14a2eb85-1126-4506-93bb-4bf624d046b6",
+   "metadata": {
+    "nbgrader": {
+     "grade": true,
+     "grade_id": "correct_count_occurrences",
+     "locked": true,
+     "points": 1,
+     "schema_version": 3,
+     "solution": false,
+     "task": false
+    },
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert count_occurrences([1, 2, 3, 4, 2, 2, 5, 6, 2], 2) == 4"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "bb1784f5-2426-4661-aa13-dba96743ceb5",
+   "metadata": {},
+   "source": [
+    "# Bonus points"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7fdcd705-dc0b-4614-8e27-9ba62f8fe442",
+   "metadata": {},
+   "source": [
+    "### Exercise 1: Find the maximum value in a list (iterative)\n",
+    "\n",
+    "Check that an empty lists raises a `ValueError` exception with a `\"The list is empty.\"` message."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 68,
+   "id": "f9334f32-f760-46c0-a649-c82f267aba5b",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "try:\n",
+    "    result = find_maximum_iterative([])\n",
+    "    assert False, \"Exception not raised\"\n",
+    "except ValueError as e:\n",
+    "    assert str(e) == \"The list is empty.\", f\"Expected error message: 'The list is empty.' but got '{str(e)}'\""
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "c121315a-4aaa-4e04-912f-73f56555be56",
+   "metadata": {},
+   "source": [
+    "### Exercise 1: Find the maximum value in a list (recursive)\n",
+    "\n",
+    "Witout using the built-in `max` function"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 69,
+   "id": "775b7e32-a5ae-431b-9987-fcd3671fd022",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "def find_maximum_recursive_no_max_func(L): \n",
+    "    # Base case: If the list is empty, raise a ValueError\n",
+    "    if not L:\n",
+    "        raise ValueError(\"The list is empty.\")\n",
+    "    \n",
+    "    # Base case: If there's only one element in the list, return it as the maximum\n",
+    "    if len(L) == 1:\n",
+    "        return L[0]\n",
+    "    \n",
+    "    # Recursive case: Compare the first element with the maximum of the rest of the list\n",
+    "    rest_max = find_maximum_recursive(L[1:])\n",
+    "    return L[0] if L[0] > rest_max else rest_max"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 70,
+   "id": "f76ed657-3288-4b36-9175-21168d2eb761",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert not calls_builtin_max(find_maximum_recursive_no_max_func)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "bbe7023a-aabd-489d-bae6-3b71566e22ef",
+   "metadata": {},
+   "source": [
+    "# Additional tests (do not change)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 65,
+   "id": "b8bc657e-d491-4851-aa8c-ac2f2eac0841",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# checks if a function uses another function, eg \"max\"\n",
+    "import inspect\n",
+    "\n",
+    "def calls_builtin_max(func):\n",
+    "    source_code = inspect.getsource(func)\n",
+    "    return 'max(' in source_code\n",
+    "\n",
+    "# Example of such function using max\n",
+    "def my_function(lst):\n",
+    "    return max(lst)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 66,
+   "id": "1c73ad0e-ddc9-483d-85a1-f2a65d04f30b",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "assert calls_builtin_max(my_function)\n",
+    "assert not calls_builtin_max(find_maximum_iterative)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 72,
+   "id": "8ce960f5-08da-449e-9e6f-dae215bc1b6a",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "# generates more examples for a given function\n",
+    "def gen_examples(fnct, n=10):\n",
+    "    return [fnct(i) for i in range(0, n)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "d601b2f3-c33b-4ed2-81be-639ce1ffab76",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "1f252530-7817-444c-ae10-d7b3bca87f2d",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "0976f7c2-4375-4d76-a6c1-9e729a6c8aeb",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "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.10.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/02-recursion-slides.pdf b/02-recursion-slides.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..e4466c87c20caca9014df9d2f448c79df709e34b
Binary files /dev/null and b/02-recursion-slides.pdf differ
diff --git a/02-recursion.ipynb b/02-recursion.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..96f87fa998c46344f9d799e6c3c7f8d493ddb0d1
--- /dev/null
+++ b/02-recursion.ipynb
@@ -0,0 +1,648 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "id": "a4e4fad3",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# UE5 Fundamentals of Algorithms\n",
+    "## Lecture 2: Recursion\n",
+    "### Ecole Centrale de Lyon, Bachelor of Science in Data Science for Responsible Business\n",
+    "#### [Romain Vuillemot](https://romain.vuillemot.net/)\n",
+    "<center><img  src=\"figures/Logo_ECL.png\" style=\"width:300px\"></center>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a8adef9b",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "skip"
+    }
+   },
+   "source": [
+    "---"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e1e1d200",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "## Outline\n",
+    "- What is recursion?\n",
+    "- Recursive/iterative approach\n",
+    "- Recursive data structures\n",
+    "- Tail vs non-tail recursion"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d9f749f7",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "## What is recursion?\n",
+    "\n",
+    "\n",
+    "> A function is considered **recursive** when it invokes itself. This self-invocation typically involves handling a straightforward case, known as the **base case**, and implementing instructions that lead towards reaching this base case. \n",
+    "\n",
+    "### Why recursion?\n",
+    "\n",
+    "* Main reason: some problems are more easily implementable recursively.\n",
+    "* Other reeasons: Iterative code is difficult to parallelize\n",
+    "* Code can be more elegant and concise than the iterative version, simpler to implement.\n",
+    "* Similarity to proof by induction."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "0f552254",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Example 1: factorial (iterative)\n",
+    "\n",
+    "Reminder: Reminder: here is the factorial function in the iterative version"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "id": "76ef6d91",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def factorial_iter(n):\n",
+    "    r = 1\n",
+    "    for i in range(1, n + 1):\n",
+    "        r *= i\n",
+    "    return r"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "c0e5f5fa",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "assert factorial_iter(0) == 1\n",
+    "assert factorial_iter(1) == 1\n",
+    "assert factorial_iter(5) == 120\n",
+    "assert factorial_iter(10) == 3628800"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7bb5014d",
+   "metadata": {},
+   "source": [
+    "- The function `fact_iter`is called once\n",
+    "- Uses iterative operator (loop, while, etc.)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "ec5d15c8",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Example 1: factorial (recursive)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "id": "63d8fa50",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def factorial_rec(n):\n",
+    "    if n == 0:\n",
+    "        return 1\n",
+    "    else:\n",
+    "        return n * factorial_rec(n - 1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "id": "8271ac13",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "assert factorial_iter(0) == factorial_rec(0)\n",
+    "assert factorial_iter(1) == factorial_rec(1)\n",
+    "assert factorial_iter(5) == factorial_rec(5)\n",
+    "assert factorial_iter(10) == factorial_rec(10)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "642fdb3b",
+   "metadata": {},
+   "source": [
+    "- The function `factorial_rec`is called multiple times\n",
+    "- Identical results to an _iterative_ version of the function"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d6694db0",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Example: Sum of digits"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "08473203",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def recursive_sum(arr):\n",
+    "    if not arr:\n",
+    "        return 0\n",
+    "    else:\n",
+    "        return arr[0] + recursive_sum(arr[1:])\n",
+    "\n",
+    "    \n",
+    "def iterative_sum(arr):\n",
+    "    total = 0\n",
+    "    for num in arr:\n",
+    "        total += num\n",
+    "    return total"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "3b6720b2",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Example 2: Fibonnacci (iterative)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "id": "fd5b77cc",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "def fibo_iter(n):\n",
+    "    arr = [0, 1]\n",
+    "    for i in range(2, n+1):\n",
+    "        arr.append(arr[i-1] + arr[i-2])\n",
+    "    return arr[n]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "id": "fd7f5ef0",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "fibo_iter(4)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "8ba75114",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "Recursive version?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "id": "69c01047",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "def fibo_rec(n):\n",
+    "    if n <= 1:\n",
+    "        return n\n",
+    "    else:\n",
+    "        return fibo_rec(n-1) + fibo_rec(n-2)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "id": "43b02670",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "assert fibo_rec(10) == fibo_iter(10)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "1948228a",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Recursion in real life (plants)\n",
+    "\n",
+    "https://en.wikipedia.org/wiki/Barnsley_fern<br>\n",
+    "https://en.wikipedia.org/wiki/List_of_fractals_by_Hausdorff_dimension\n",
+    "\n",
+    "<img src=\"figures/Barnsley_fern_plotted_with_VisSim.png\">"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "fc4cf71f",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Recursion in real life (paper folding)\n",
+    "\n",
+    "https://en.wikipedia.org/wiki/Paper_size\n",
+    "\n",
+    "(uses the ISO 216 standard's scaling factor of approximately 1.1892071 (2^(1/4)) to calculate the dimensions of various ISO paper sizes based on their relation to A0)\n",
+    "\n",
+    "<img src=\"figures/a-series-paper-sizes-1.jpg\" style=\"width:200px\">"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "cc338630",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Recursion in real life (paper folding) in Pseudo Code\n",
+    "\n",
+    "1. Constant Ratio:\n",
+    "   - ratio = √2\n",
+    "\n",
+    "2. Creating A_i from A_i-1:\n",
+    "   - function createPaper(A_i-1):\n",
+    "     - fold A_i-1 along its length to create A_i\n",
+    "\n",
+    "3. Recurrence Relation:\n",
+    "   - function calculateDimensions(A_i-1):\n",
+    "     - length_A_i = width_A_i-1\n",
+    "     - width_A_i = length_A_i-1 / 2\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "bc7ab125",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Recursion in real life (paper folding) in Python\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "id": "3e633e5f",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "A0: Width = 841 mm, Height = 1189 mm\n",
+      "A1: Width = 594.5 mm, Height = 841 mm\n",
+      "A2: Width = 420.5 mm, Height = 594.5 mm\n",
+      "A3: Width = 297.25 mm, Height = 420.5 mm\n",
+      "A4: Width = 210.25 mm, Height = 297.25 mm\n",
+      "A5: Width = 148.625 mm, Height = 210.25 mm\n"
+     ]
+    }
+   ],
+   "source": [
+    "def generate_iso_paper_sizes(n):\n",
+    "    iso_sizes = {\"A0\": (841, 1189)}\n",
+    "    current_size = \"A0\"\n",
+    "\n",
+    "    for i in range(1, n + 1):\n",
+    "        width, height = iso_sizes[current_size]\n",
+    "        next_size = f\"A{i}\"\n",
+    "        iso_sizes[next_size] = (height / 2, width)\n",
+    "        current_size = next_size\n",
+    "\n",
+    "    return iso_sizes\n",
+    "\n",
+    "# Generate and print the first 5 ISO paper sizes\n",
+    "iso_paper_sizes = generate_iso_paper_sizes(5)\n",
+    "for size, dimensions in iso_paper_sizes.items():\n",
+    "    print(f\"{size}: Width = {dimensions[0]} mm, Height = {dimensions[1]} mm\")\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "381280e8",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "## Recursive data structures\n",
+    "    \n",
+    "Some **data types** are inherently recursive, meaning that a subset of this data type has the same data type:\n",
+    "\n",
+    "- Lists\n",
+    "- Strings (arrays)\n",
+    "- Binary trees\n",
+    "- Linked lists\n",
+    "- Custom (e.g., using objects)\n",
+    "     "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "c134a8ac",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "## Tail vs non-tail recursion\n",
+    "\n",
+    "Recursion can be categorized into two types: **tail recursion** and **non-tail recursion**.\n",
+    "\n",
+    "- **tail recursion**, the recursive call is the last operation before returning a result. This makes it efficient in terms of memory usage and stack overflow risk, as there are no pending calculations.\n",
+    "\n",
+    "- **non-tail recursion** involves additional operations after the recursive call, potentially leading to a stack of calls and increased memory consumption.\n",
+    "\n",
+    "The choice between these types depends on the problem and programming language. Tail recursion often leads to more efficient and readable code, but sometimes non-tail recursion is necessary, impacting variable lifespan and the result.\n",
+    "\n",
+    "⚠️ Impacts results and variables span of life"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "5dfcce6b",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "## Tail vs non-tail recursion (cont.)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "id": "021f2066",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def print_desc(n):\n",
+    "    if n > 0:\n",
+    "        print(\" \" * n, \"  n= \" , n ,\" brefore recursive call\")\n",
+    "        ecrire_desc (n - 1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "id": "ed36ce86",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "      n=  3  brefore recursive call\n",
+      "     n=  2  avant l'appel récursif\n",
+      "    n=  1  avant l'appel récursif\n"
+     ]
+    }
+   ],
+   "source": [
+    "print_desc(3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "id": "5223a19b",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "def print_asc(n) :\n",
+    "    if n > 0:\n",
+    "        ecrire_asc(n - 1)    \n",
+    "        print(\" \" * n, \"  n= \" , n ,\" after recrusive call\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "id": "a4262dee",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "    n=  1  après l'appel récursif\n",
+      "     n=  2  après l'appel récursif\n",
+      "      n=  3  after recrusive call\n"
+     ]
+    }
+   ],
+   "source": [
+    "print_asc(3)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "d6ff87a9",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "\n",
+    "## Disadvantages of Recursion\n",
+    "\n",
+    "<a href=\"https://www.xkcd.com/1739/\">\n",
+    "<img src=\"figures/xkcd_fixing_problems.png\" width=\"200px\">\n",
+    "</a>\n",
+    "\n",
+    "- While recursion can lead to concise and elegant solutions, it's crucial to handle base cases properly to avoid infinite loops or excessive function calls.\n",
+    "- Recursive functions require careful consideration of termination conditions to prevent stack overflow errors or excessive memory usage.\n",
+    "- Can become memory-intensive if written poorly.\n",
+    "- One must wait for the base case to start getting results (no intermediate result), results cannot be obtained progressively (if non-tail recursion)."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "a06f5f12",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "## Recursion calls\n",
+    "\n",
+    "<img src=\"figures/execution-recursive.png\" width=\"400px\">\n",
+    "\n",
+    "Visualize recursive calls [pythontutor](http://www.pythontutor.com/visualize.html#mode=edit)\n",
+    "\n",
+    "In case of too many function calls, a **maximum recursion depth exceeded error** is triggered. You can anticipate this error by not exceeding the limit `sys.getrecursionlimit()` or by changing it using `sys.setrecursionlimit`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "id": "1ced11f3",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3000"
+      ]
+     },
+     "execution_count": 30,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import sys\n",
+    "sys.getrecursionlimit()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "7f22c3de",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "## Transformation Schemes\n",
+    "\n",
+    "There are some recursive to iterative transformation schemes:\n",
+    "\n",
+    "1. Write a recursive algorithm.\n",
+    "2. Test, validate, and prove it (in critical applications).\n",
+    "3. Apply transformation techniques to obtain an iterative version.\n",
+    "\n",
+    "Note that these techniques are not 100% automated.\n",
+    "\n",
+    "```python\n",
+    "f_rec(X) =\n",
+    "  if p(X) then a(X)\n",
+    "  else\n",
+    "    b(X)\n",
+    "    f_rec(new(X))\n",
+    "  end if;\n",
+    "\n",
+    "f_iter(X) =\n",
+    "  if p(X) = false then\n",
+    "    do\n",
+    "      b(X);\n",
+    "      X := new(X);\n",
+    "    until p(X) = true;\n",
+    "  end if;\n",
+    "  a(X);\n",
+    "```\n"
+   ]
+  }
+ ],
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "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.10.9"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/README.md b/README.md
index a4e6401b86eaeb13a9897a933925db8fb416846b..4987100084f5d5c3ff20601af2e7a4bbe190cafc 100644
--- a/README.md
+++ b/README.md
@@ -17,7 +17,7 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr)
 
 📖 [Python for Everybody](pdf/pythonlearn.pdf) chapter 9 (dictionnaries), chapter 10 (tuples)
 
-### Lecture 2 - **Recursion** | [notebook](02-recursion.ipynb) | [slides](02-recursion-slides.ipynb) | [exercices](02-recursion-exercices.ipynb)
+### Lecture 2 - **Recursion** | [notebook](02-recursion.ipynb) | [slides](02-recursion-slides.pdf) | [exercices](02-recursion-exercices.ipynb)
 
 📖 [Think Python](pdf/thinkpython2.pdf) chapter 5 (Conditionals and recursion)