diff --git a/README.md b/README.md index c0da4eff2093b358705fd77d6def36ffe6150c8e..a5d44fa54f420be5153b2ecdc64309ef2f9aa523 100644 --- a/README.md +++ b/README.md @@ -55,10 +55,6 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr) - Base cases and recursive cases - Recursion vs. iteration - Tail recursion -- Lists, Search -- Introduction to lists (arrays vs. linked lists) -- Operations on lists (insertion, deletion, traversal) -- Searching algorithms (linear, binary) <details> <summary>📖 </summary> @@ -112,7 +108,7 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr) - Recursive, independent problem-solving strategy - Application to sorting (merge sort, quick sort) and search (binary search) -- Examples: Fibonacci +- Fibonacci - Knapsack Problem (greedy) <details> @@ -131,8 +127,7 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr) - Definition and characteristics of dynamic programming - Memoization data structures -- Examples (using dynamic programming): Fibonacci, Knapsack Problem - +- Optimizing Fibonacci, Knapsack Problem using dynamic programming <details> <summary>📖 </summary> @@ -185,10 +180,10 @@ Instructor: [Romain Vuillemot](romain.vuillemot@ec-lyon.fr) ### Lecture 9 - **Graphs** - - Introduction to graphs (vertices and edges) - - Types of graphs (directed, undirected, weighted, unweighted) - - Representing graphs as adjacency matrix, adjacency list - - Graph properties (connectivity, cycles) + - Introduction to graphs (vertices and edges) + - Types of graphs (directed, weighted) + - Graphs data structures (adjacency matrix, adjacency list) + - Graph properties (connectivity, cycles) <details> <summary>📖 </summary> diff --git a/exercises/02-recursion-exercises.ipynb b/exercises/02-recursion-exercises.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..d0e726ef54360cc4c77aa3b8aee8344c774ef84e --- /dev/null +++ b/exercises/02-recursion-exercises.ipynb @@ -0,0 +1,1135 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "251ea836", + "metadata": {}, + "source": [ + "NAME:" + ] + }, + { + "cell_type": "markdown", + "id": "a4e4fad3", + "metadata": { + "slideshow": { + "slide_type": "slide" + } + }, + "source": [ + "# UE5 Fundamentals of Algorithms\n", + "# Lab 2: Recursion" + ] + }, + { + "cell_type": "markdown", + "id": "a8adef9b", + "metadata": { + "slideshow": { + "slide_type": "skip" + } + }, + "source": [ + "---" + ] + }, + { + "cell_type": "markdown", + "id": "eee7125e-cd0b-4aff-ac6d-fba530b13050", + "metadata": { + "tags": [] + }, + "source": [ + "For each of the following questions:\n", + "- In the `# YOUR CODE HERE` cell, remove `raise NotImplementedError()` to write your code\n", + "- Write an example of use of your code or make sure the given examples and tests pass\n", + "- Add extra tests in the `#Tests` cell" + ] + }, + { + "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": "b2d7436d320b2a6c6d35345e11f6a6f3", + "grade": true, + "grade_id": "correct_find_maximum_iterative", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Tests\n", + "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": "343421c4b3ba581fec2bfe759dcc1f97", + "grade": true, + "grade_id": "correct_find_maximum_recursive", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Tests\n", + "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": "091a4169585fae3efcb77792729ffa7b", + "grade": true, + "grade_id": "correct_sum_of_digits", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Tests\n", + "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": "a9edcf4e2ce8a691595ab3ae8fe1a110", + "grade": true, + "grade_id": "correct_power", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Tests\n", + "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\n", + "\n", + "In a recursive way:" + ] + }, + { + "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": "e6a4bb2b9360b3872f3a09a6e5e85509", + "grade": true, + "grade_id": "correct_reverse_string", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Tests\n", + "assert reverse_string(\"\") == \"\"\n", + "assert reverse_string(\"AA\") == \"AA\"\n", + "assert reverse_string(\"ABC\") == \"CBA\"" + ] + }, + { + "cell_type": "markdown", + "id": "c1587148-f816-4af2-8f3a-6d8a8480d54d", + "metadata": { + "tags": [] + }, + "source": [ + "In an iterative way:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "159b6d78-03ae-4cf8-8545-e822b7160b32", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "d95c7211470341d4c1e960c2b506d676", + "grade": false, + "grade_id": "cell-ead02fa889911e42", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def iterative_reverse_string(s):\n", + " # YOUR CODE HERE\n", + " raise NotImplementedError()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0dcdbd99-5f57-4d1c-bc31-8f8afc617d0e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "iterative_reverse_string(\"Romain\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "43e10b0c", + "metadata": {}, + "outputs": [], + "source": [ + "# Tests\n", + "assert iterative_reverse_string(\"Romain\") == reverse_string(\"Romain\")" + ] + }, + { + "cell_type": "markdown", + "id": "5ab8f3c9-ddee-45ab-a013-fdd67d9853e0", + "metadata": {}, + "source": [ + "### Example 5: Convert an interative suite into a recursive tail function\n", + "\n", + "_A recursive tail function is a function where the last operation is the recursive call._" + ] + }, + { + "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": "c77f24ac9a0d8c58464546c9a4d8083a", + "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": [ + "# Tests\n", + "assert sequence_recursive_tail(3) == 15" + ] + }, + { + "cell_type": "markdown", + "id": "3c28b36a", + "metadata": { + "slideshow": { + "slide_type": "subslide" + } + }, + "source": [ + "### Example 6: check if a word is a palindrom\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": "a11e9594f7e72af63464586312e41230", + "grade": false, + "grade_id": "annagram_rec", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def palindrom_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": [ + "palindrom_rec(\"laval\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cf6fa61a-7c6f-4a32-96c2-b9fd50deacc6", + "metadata": { + "deletable": false, + "editable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "6af4501cee439c4fc21ff5b23ac801fe", + "grade": true, + "grade_id": "correct_annagram_rec", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Tests\n", + "assert palindrom_rec(\"\")\n", + "assert palindrom_rec(\"AA\")\n", + "assert not palindrom_rec(\"ABC\")\n", + "assert palindrom_rec(\"ABA\")\n", + "assert palindrom_rec(\"LAVAL\")" + ] + }, + { + "cell_type": "markdown", + "id": "798c2875-7940-488a-8458-ad08f6a71c70", + "metadata": {}, + "source": [ + "### Example 7: Calculate GCD\n", + "\n", + "_Here is the iterative way, write the recursive equivalent._" + ] + }, + { + "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": "deb95c0016fdfa5a2a5b39d285a894cc", + "grade": true, + "grade_id": "correct_recursive_gcd", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Tests\n", + "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 of numbers is sorted\n", + "\n", + "Write a recursive solution." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1661dfb5-88f2-411f-8fe2-63bbaa29ce72", + "metadata": { + "deletable": false, + "nbgrader": { + "cell_type": "code", + "checksum": "862e6666538916866c4f2ee16d767102", + "grade": false, + "grade_id": "calculate_average_recursive", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def is_sorted(L):\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": "0b027e0137fb8b61c2cb43033caf2610", + "grade": true, + "grade_id": "correct_calculate_average_recursive", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Tests\n", + "assert is_sorted([2, 3])\n", + "assert is_sorted([])" + ] + }, + { + "cell_type": "markdown", + "id": "79eef392-1d3d-46c0-aeee-ac805686e6f1", + "metadata": {}, + "source": [ + "### Example 9: Check for prime number in a recursive function" + ] + }, + { + "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": "213d3f1777418e990123ba6d85de759c", + "grade": true, + "grade_id": "correct_is_prime_recursive", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Tests\n", + "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": "dc82bb9d69427f625dd25265e766086e", + "grade": false, + "grade_id": "count_occurrences", + "locked": false, + "schema_version": 3, + "solution": true, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "def count_occurrences(L, 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": "cf6f12cf485200b94c45bc3c6d633253", + "grade": true, + "grade_id": "correct_count_occurrences", + "locked": true, + "points": 1, + "schema_version": 3, + "solution": false, + "task": false + }, + "tags": [] + }, + "outputs": [], + "source": [ + "# Tests\n", + "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" + ] + }, + { + "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": [ + "# Tests\n", + "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)]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "949526e9-f49e-4a5d-b56f-4f8f22b3181f", + "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.10.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}