{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "01d26f8d",
   "metadata": {},
   "source": [
    "# UE5 Fundamentals of Algorithms\n",
    "## Exercices\n",
    "### Ecole Centrale de Lyon, Bachelor of Science in Data Science for Responsible Business\n",
    "#### [Romain Vuillemot](https://romain.vuillemot.net/)\n",
    "\n",
    "Before you turn this problem in:\n",
    "- make sure everything runs as expected. \n",
    "    - first, **restart the kernel** (in the menubar, select Kernel$\\rightarrow$Restart) \n",
    "    - then **run all cells** (in the menubar, select Cell$\\rightarrow$Run All).\n",
    "- make sure you fill in any place that says `YOUR CODE HERE` or \"YOUR ANSWER HERE\"\n",
    "- remove `raise NotImplementedError()` to get started with your answer\n",
    "- bonus points (at the end of this notebook) are optionals\n",
    "- write your name (and collaborators as a list if any) below:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a6f5bcf0",
   "metadata": {},
   "outputs": [],
   "source": [
    "ID = \"\"\n",
    "COLLABORATORS_ID = []"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51dc6634",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "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": "code",
   "execution_count": null,
   "id": "0dfe1da3-b50b-49c0-aaff-483616e13863",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "list_complexities = [\"O(1)\", \"O(log(n))\", \"O(n)\", \"O(n^2)\", \"O(nlog(n))\", \"O(n^3)\", \"O(2^n)\", \"O(n!)\", \"O(n^n)\"]"
   ]
  },
  {
   "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": null,
   "id": "431fe8c1-91d1-40f3-a7a4-f4a3770a4a01",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "8b23d599da9ca2bdba48b9bcdd6e1165",
     "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",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f6baae3c-3660-4add-ab4b-48016cba3030",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "find_maximum_iterative([1, 3, 5, 7, 9])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e68b3e9a-418f-4950-9f27-18bb0fe90794",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "9cb3441fa27dd28ce74e368375de8080",
     "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": null,
   "id": "07668fd8",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "fcd4348ffdf05fa800f15e7dba033d8e",
     "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",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f9784710-4b2b-434c-bc47-da46fa410749",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "find_maximum_recursive([1, 3, 5, 7, 9])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9b0161f8-0539-4e5e-921c-1886e61c0783",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "1aae7ba6a868f7afd015deedcdf48aa4",
     "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": null,
   "id": "de424156-0b9b-41d0-8e38-ce335f35cec0",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "3872f4f922847e273bc5a45cd425c458",
     "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",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cec0caca-cb2c-4e4d-b004-27b3cf2ff611",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "sum_of_digits(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bf276ca2-48ed-4e87-80f2-776f54b7062b",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "feb0a5b734f6734920bfec23da86992b",
     "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)\n",
    "assert sum_of_digits(0) == 0\n",
    "assert sum_of_digits(123) == 6"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2de630a-f9bd-4d45-959b-430e34cc9044",
   "metadata": {
    "tags": []
   },
   "source": [
    "### Exercise 3: Calculate the power"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "abca03a0-7bcd-4ee6-b109-ff2f2da52bb6",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "c8c385784b4dd53e96c693511e7a2e80",
     "grade": false,
     "grade_id": "power",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "def power(base, exponent):\n",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "abddd3b1-f75f-4cb6-a09e-54eed489c5b0",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "power(2, 10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8a6605fe-4f6f-45de-84a3-7601e2e2e6f6",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "1deb1e7cdc63de1900c5375bf6debf2a",
     "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\n",
    "assert power(2, 0) == 1\n",
    "assert power(5, 3) == 125"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "715100d3-fc21-49b9-a66d-b5243b4a279d",
   "metadata": {
    "tags": []
   },
   "source": [
    "### Exercise 4: Reverse a string"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ddc9826a-0863-4777-a08d-81b66652b5a5",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "762d91a747e5399677a26e44c5d8a041",
     "grade": false,
     "grade_id": "reverse_string",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "def reverse_string(s):\n",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "13acad7e-d03c-4ea6-ad86-baf02e0910eb",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "reverse_string(\"Romain\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "453c8e04-6cd9-4581-a206-dd479b6115cd",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "d42cbfb82df47fb4eb82e1530fa8f3cb",
     "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": "code",
   "execution_count": null,
   "id": "159b6d78-03ae-4cf8-8545-e822b7160b32",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "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 function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "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": null,
   "id": "0787df24-8234-4286-b910-5f9e456dd279",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "print(\"The result is {}\".format(sequence(3)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9c17cf1b-6d05-4589-af2b-c05cfcc33202",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "2137e4ccdef7bccaa7b7ed6b52f305a8",
     "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",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "43507c43-de61-414d-b389-c0a771ad9e0c",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "print(\"The result is still {}\".format(sequence_recursive_tail(3)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "dd923b7c-0cab-4678-8dc3-aad2ab9b25f9",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "c465dc72b44f305c781da5cf50e4c934",
     "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) == 15"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c28b36a",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### Example 6: check if a word is an annagram\n",
    "\n",
    "Check if a word can be read backwards."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "51bb3d08",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "1edb53556b907062a6d2f29282317e03",
     "grade": false,
     "grade_id": "annagram_rec",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "def annagram_rec(word):\n",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0c279628-9b96-4687-8e20-a954ab646e0f",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "annagram_rec(\"laval\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cf6fa61a-7c6f-4a32-96c2-b9fd50deacc6",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "22a5df98d007ceb58975b5877958e3f8",
     "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\")\n",
    "assert annagram_rec(\"LAVAL\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "798c2875-7940-488a-8458-ad08f6a71c70",
   "metadata": {},
   "source": [
    "### Example 7: Calculate GCD\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "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": null,
   "id": "bf6e1a76",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "45353cb0fdd92b57e6f6f1739ed430b3",
     "grade": false,
     "grade_id": "recursive_gcd",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "def recursive_gcd(a, b):\n",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4f1feace",
   "metadata": {},
   "outputs": [],
   "source": [
    "recursive_gcd(10, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e6ff1765-ff4b-49a5-80d3-684d2627e961",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "ed3ae90c2a4be5ff93a5d68b688f0f96",
     "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: Check if a list is sorted"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1661dfb5-88f2-411f-8fe2-63bbaa29ce72",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "9fcedc9d6262baf07013d0b6f4e8175d",
     "grade": false,
     "grade_id": "calculate_average_recursive",
     "locked": false,
     "schema_version": 3,
     "solution": true,
     "task": false
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "def is_sorted(lst):\n",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0c5c72c6-3237-4f98-ab96-50a1838b833f",
   "metadata": {},
   "outputs": [],
   "source": [
    "is_sorted([1, 2, 3, 4, 5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9f18b6b7-d980-4a72-a2a8-3aa201003d21",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "9cdabb05d7be086c1b769672a158fdc6",
     "grade": true,
     "grade_id": "correct_calculate_average_recursive",
     "locked": true,
     "points": 1,
     "schema_version": 3,
     "solution": false,
     "task": false
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "assert is_sorted([2, 3])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "79eef392-1d3d-46c0-aeee-ac805686e6f1",
   "metadata": {},
   "source": [
    "### Example 9: Check for prime number"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ac374a08-11c9-47e6-ba11-419549911266",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "58fec5e697f40d4e1934bdce3ae87647",
     "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",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "996fc91f",
   "metadata": {},
   "outputs": [],
   "source": [
    "is_prime_recursive(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5be1051c-3b60-4810-b855-6f8575ad6380",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "f571ff3e3a5bc53ffbc828b255bfb6cb",
     "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": null,
   "id": "cfeb0ad0-ed82-499e-9af3-64923291a0e7",
   "metadata": {
    "deletable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "01c4970fffe483944b93049b5d8404a0",
     "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",
    "    # YOUR CODE HERE\n",
    "    raise NotImplementedError()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "49daec07-00b3-412e-ad44-5bafadbd9f36",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "count_occurrences([1, 2, 3, 4, 2, 2, 5, 6, 2], 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "14a2eb85-1126-4506-93bb-4bf624d046b6",
   "metadata": {
    "deletable": false,
    "editable": false,
    "nbgrader": {
     "cell_type": "code",
     "checksum": "5df4afd6ed2f7dfd102b8c21f8ced2e7",
     "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: 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": null,
   "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: Find the maximum value in a list (recursive)\n",
    "\n",
    "Witout using the built-in `max` function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "153e3f05-7598-4920-bc8d-8943cb75e5a8",
   "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",
    "def my_function(lst):\n",
    "    return max(lst)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "775b7e32-a5ae-431b-9987-fcd3671fd022",
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "def find_maximum_recursive_no_max_func(L): \n",
    "    if not L:\n",
    "        raise ValueError(\"The list is empty.\")\n",
    "    \n",
    "    if len(L) == 1:\n",
    "        return L[0]\n",
    "    \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": null,
   "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": null,
   "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": null,
   "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)]"
   ]
  }
 ],
 "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.10.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}