diff --git a/f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references.ipynb b/f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references.ipynb index 43b5e6bd9558d6e5e3f301d362462df0f1d96e1d..8139c7021c55d885332eac97cffb5270d63f0613 100644 --- a/f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references.ipynb +++ b/f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references.ipynb @@ -1,5 +1,21 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Announcements - Monday, October 30\n", + "\n", + "* Download ALL files for today's lecture\n", + "* <b>If you have any problem with P1-P4 grades, please send me (Gurmail.Singh@wisc.edu) an email by November 03.</b>\n", + "* If you have questions, it is almost always faster to \n", + " * Post on Piazza\n", + " * Go to [office hours](https://sites.google.com/wisc.edu/cs220-oh-f23/home?pli=1) \n", + "### Conflict Form\n", + " * [Exam 2 - November 8, 5:45 pm](https://cs220.cs.wisc.edu/f23/surveys.html)\n", + " * [Final - December 19, 7:45 am](https://cs220.cs.wisc.edu/f23/surveys.html)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -19,6 +35,39 @@ "execution_count": 1, "metadata": {}, "outputs": [], + "source": [ + "def fact(n):\n", + " if n == 1:\n", + " return 1\n", + " p = fact(n-1) \n", + " return n * p" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "6" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fact(3)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], "source": [ "# Nested data structures are defined recursively.\n", "\n", @@ -29,7 +78,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -38,7 +87,7 @@ "9" ] }, - "execution_count": 2, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -100,7 +149,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -138,7 +187,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -157,7 +206,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -190,7 +239,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -215,7 +264,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -241,7 +290,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -261,7 +310,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -277,7 +326,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -311,7 +360,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -320,7 +369,7 @@ "[1, 23, 456]" ] }, - "execution_count": 11, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -339,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -368,7 +417,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -397,7 +446,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 16, "metadata": {}, "outputs": [ { @@ -434,7 +483,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -447,7 +496,7 @@ " ('Troy', 'Fumagalli', 88)]" ] }, - "execution_count": 15, + "execution_count": 17, "metadata": {}, "output_type": "execute_result" } @@ -479,7 +528,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -495,7 +544,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -504,7 +553,7 @@ "'JJ'" ] }, - "execution_count": 17, + "execution_count": 19, "metadata": {}, "output_type": "execute_result" } @@ -523,7 +572,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -536,7 +585,7 @@ " ('Russel', 'Wilson', 32)]" ] }, - "execution_count": 18, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } @@ -554,7 +603,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -567,7 +616,7 @@ " ('Troy', 'Fumagalli', 88)]" ] }, - "execution_count": 19, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } @@ -585,7 +634,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -598,7 +647,7 @@ " ('Jonathan', 'Taylor', 22)]" ] }, - "execution_count": 20, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } @@ -616,7 +665,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 23, "metadata": {}, "outputs": [ { @@ -629,7 +678,7 @@ " ('Jonathan', 'Taylor', 22)]" ] }, - "execution_count": 21, + "execution_count": 23, "metadata": {}, "output_type": "execute_result" } @@ -650,7 +699,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -670,7 +719,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -679,7 +728,7 @@ "{'name': 'A', 'year': 2000, 'speed': 150}" ] }, - "execution_count": 23, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } @@ -697,7 +746,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -706,7 +755,7 @@ "{'name': 'B', 'year': 1980, 'speed': 100}" ] }, - "execution_count": 24, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -724,7 +773,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -740,7 +789,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -757,7 +806,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -777,7 +826,7 @@ " {'name': 'A', 'year': 2000, 'speed': 150}]" ] }, - "execution_count": 27, + "execution_count": 29, "metadata": {}, "output_type": "execute_result" } @@ -802,7 +851,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -822,7 +871,7 @@ " {'name': 'B', 'year': 1980, 'speed': 100}]" ] }, - "execution_count": 28, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -842,7 +891,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": 31, "metadata": {}, "outputs": [ { @@ -853,7 +902,7 @@ " {'name': 'A', 'year': 2000, 'speed': 150}]" ] }, - "execution_count": 29, + "execution_count": 31, "metadata": {}, "output_type": "execute_result" } @@ -880,7 +929,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 32, "metadata": {}, "outputs": [ { @@ -889,7 +938,7 @@ "['A', 'C', 'b', 'd']" ] }, - "execution_count": 30, + "execution_count": 32, "metadata": {}, "output_type": "execute_result" } @@ -900,7 +949,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 33, "metadata": {}, "outputs": [ { @@ -909,7 +958,7 @@ "['A', 'b', 'C', 'd']" ] }, - "execution_count": 31, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -934,7 +983,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 34, "metadata": {}, "outputs": [ { @@ -943,7 +992,7 @@ "{'bob': 20, 'alice': 8, 'alex': 9, 'cindy': 15}" ] }, - "execution_count": 32, + "execution_count": 34, "metadata": {}, "output_type": "execute_result" } @@ -966,7 +1015,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 35, "metadata": {}, "outputs": [ { @@ -975,7 +1024,7 @@ "['alex', 'alice', 'bob', 'cindy']" ] }, - "execution_count": 33, + "execution_count": 35, "metadata": {}, "output_type": "execute_result" } @@ -995,7 +1044,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 36, "metadata": {}, "outputs": [ { @@ -1004,7 +1053,7 @@ "dict_items([('bob', 20), ('alice', 8), ('alex', 9), ('cindy', 15)])" ] }, - "execution_count": 34, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -1022,7 +1071,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 37, "metadata": {}, "outputs": [], "source": [ @@ -1039,7 +1088,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 38, "metadata": {}, "outputs": [ { @@ -1048,7 +1097,7 @@ "[('alice', 8), ('alex', 9), ('cindy', 15), ('bob', 20)]" ] }, - "execution_count": 36, + "execution_count": 38, "metadata": {}, "output_type": "execute_result" } @@ -1066,7 +1115,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 39, "metadata": {}, "outputs": [ { @@ -1075,7 +1124,7 @@ "{'alice': 8, 'alex': 9, 'cindy': 15, 'bob': 20}" ] }, - "execution_count": 37, + "execution_count": 39, "metadata": {}, "output_type": "execute_result" } @@ -1112,7 +1161,7 @@ }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 40, "metadata": {}, "outputs": [ { @@ -1121,7 +1170,7 @@ "{'alex': 9, 'alice': 8, 'bob': 20, 'cindy': 15}" ] }, - "execution_count": 38, + "execution_count": 40, "metadata": {}, "output_type": "execute_result" } @@ -1139,7 +1188,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 41, "metadata": {}, "outputs": [ { @@ -1148,7 +1197,7 @@ "{'alice': 8, 'alex': 9, 'cindy': 15, 'bob': 20}" ] }, - "execution_count": 39, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -1166,7 +1215,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 42, "metadata": {}, "outputs": [ { @@ -1175,7 +1224,7 @@ "{'bob': 20, 'alex': 9, 'alice': 8, 'cindy': 15}" ] }, - "execution_count": 40, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -1193,7 +1242,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 43, "metadata": {}, "outputs": [ { @@ -1217,7 +1266,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 44, "metadata": {}, "outputs": [ { @@ -1230,7 +1279,7 @@ " ('Troy', 'Fumagalli', 88)]" ] }, - "execution_count": 42, + "execution_count": 44, "metadata": {}, "output_type": "execute_result" } @@ -1248,7 +1297,7 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 45, "metadata": {}, "outputs": [ { @@ -1261,7 +1310,7 @@ " ('Russel', 'Wilson', 32)]" ] }, - "execution_count": 43, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -1279,7 +1328,7 @@ }, { "cell_type": "code", - "execution_count": 44, + "execution_count": 46, "metadata": {}, "outputs": [ { @@ -1292,7 +1341,7 @@ " ('Troy', 'Fumagalli', 88)]" ] }, - "execution_count": 44, + "execution_count": 46, "metadata": {}, "output_type": "execute_result" } @@ -1310,7 +1359,7 @@ }, { "cell_type": "code", - "execution_count": 45, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -1323,7 +1372,7 @@ " ('Jonathan', 'Taylor', 22)]" ] }, - "execution_count": 45, + "execution_count": 47, "metadata": {}, "output_type": "execute_result" } @@ -1349,7 +1398,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.7" + "version": "3.11.4" } }, "nbformat": 4, diff --git a/f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references_template.ipynb b/f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references_template_Gurmail_lec1.ipynb similarity index 94% rename from f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references_template.ipynb rename to f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references_template_Gurmail_lec1.ipynb index d39ef000174f67147b7ae86de32664411419575e..431a6ee0d7701903e1d0908cc7192a92154a518e 100644 --- a/f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references_template.ipynb +++ b/f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references_template_Gurmail_lec1.ipynb @@ -1,5 +1,21 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Announcements - Monday, October 30\n", + "\n", + "* Download ALL files for today's lecture\n", + "* <b>If you have any problem with P1-P4 grades, please send me (Gurmail.Singh@wisc.edu) an email by November 03.</b>\n", + "* If you have questions, it is almost always faster to \n", + " * Post on Piazza\n", + " * Go to [office hours](https://sites.google.com/wisc.edu/cs220-oh-f23/home?pli=1) \n", + "### Conflict Form\n", + " * [Exam 2 - November 8, 5:45 pm](https://cs220.cs.wisc.edu/f23/surveys.html)\n", + " * [Final - December 19, 7:45 am](https://cs220.cs.wisc.edu/f23/surveys.html)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -14,6 +30,28 @@ "### Recursion review" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def fact(n):\n", + " if n == 1:\n", + " return 1\n", + " p = fact(n-1) \n", + " return n * p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fact(3)" + ] + }, { "cell_type": "code", "execution_count": null, @@ -899,7 +937,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.7" + "version": "3.11.4" } }, "nbformat": 4, diff --git a/f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references_template_Gurmail_lec2.ipynb b/f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references_template_Gurmail_lec2.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..431a6ee0d7701903e1d0908cc7192a92154a518e --- /dev/null +++ b/f23/Gurmail_Lecture_Notes/23_Function_References/lec_23_function_references_template_Gurmail_lec2.ipynb @@ -0,0 +1,945 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Announcements - Monday, October 30\n", + "\n", + "* Download ALL files for today's lecture\n", + "* <b>If you have any problem with P1-P4 grades, please send me (Gurmail.Singh@wisc.edu) an email by November 03.</b>\n", + "* If you have questions, it is almost always faster to \n", + " * Post on Piazza\n", + " * Go to [office hours](https://sites.google.com/wisc.edu/cs220-oh-f23/home?pli=1) \n", + "### Conflict Form\n", + " * [Exam 2 - November 8, 5:45 pm](https://cs220.cs.wisc.edu/f23/surveys.html)\n", + " * [Final - December 19, 7:45 am](https://cs220.cs.wisc.edu/f23/surveys.html)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Function references" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Recursion review" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def fact(n):\n", + " if n == 1:\n", + " return 1\n", + " p = fact(n-1) \n", + " return n * p" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fact(3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Nested data structures are defined recursively.\n", + "\n", + "# A Python list can contain lists\n", + "# A Python dictionary can contain dictionaries\n", + "# A JSON dictionary can contain a JSON dictionary" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Trace Recursion by hand\n", + "# Run this on your own in Python Tutor\n", + "\n", + "def mystery(a, b): \n", + " # precondition: assume a > 0 and b > 0\n", + " if b == 1: \n", + " return a\n", + " return a * mystery(a, b - 1)\n", + "\n", + "# make a function call here\n", + "mystery(3, 2)\n", + "\n", + "# TODO: what does the mystery function compute?\n", + "\n", + "# Question: What would be the result of the below function call?\n", + "# mystery(-3, -1) \n", + "# Answer: " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Learning Objectives:\n", + "\n", + "- Define a function reference and trace code that uses function references.\n", + "- Explain the default use of `sorted()` on lists of tuples, and dictionaries.\n", + "- Sort a list of tuples, a list of dictionaries, or a dictionary using a function as a key.\n", + "- Use a lambda expression when sorting." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Functions are objects\n", + "\n", + "- Every data in Python is an object instance, including a function definition\n", + "- Implications:\n", + " - variables can reference functions\n", + " - lists/dicts can reference functions\n", + " - we can pass function references to other functions\n", + " - we can pass lists of function references to other functions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example 1: slide deck example introducing function object references\n", + "#### Use PyTutor to step through this example" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "l1 = [1, 2, 3] # Explanation: l1 should reference a new list object\n", + "l2 = l1 # Explanation: l2 should reference whatever l1 references\n", + "\n", + "def f(l): # Explanation: f should reference a new function object\n", + " return l[-1]\n", + "\n", + "g = f # Explanation: g should reference whatever f references\n", + "\n", + "num = f(l2) # Explanation: l should reference whatever l2 references\n", + " # Explanation: num should reference whatever f returns\n", + "\n", + "print(num)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Function references\n", + "\n", + "- Since function definitions are objects in Python, function reference is a variable that refers to a function object.\n", + "- In essence, it gives a function another name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Both these calls would have run the same code, returning the same result\n", + "num = f(l1)\n", + "num = g(l2) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example 2: function references can be passed as arguments to another function, wow!\n", + "#### Use PyTutor to step through this example" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def say_hi():\n", + " print(\"Hello there!\")\n", + "\n", + "def say_bye():\n", + " print(\"Wash your hands and stay well, bye!\")\n", + " \n", + "f = say_hi\n", + "f()\n", + "f()\n", + "f = say_bye\n", + "f()\n", + "f()\n", + "f()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "for i in range(2):\n", + " say_hi()\n", + "\n", + "for i in range(3):\n", + " say_bye()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def call_n_times(f, n):\n", + " for i in range(n):\n", + " f()\n", + "\n", + "call_n_times(say_hi, 2)\n", + "call_n_times(say_bye, 3)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# call_n_times(say_bye(), 3) # uncomment to see TypeError\n", + "\n", + "# Question: Why does this give TypeError?\n", + "# Answer: when you specify say_bye(), you are invoking the function, which returns None\n", + "# (default return value when return statement is not defined)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example 3: Apply various transformations to all items on a list" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "L = [\"1\", \"23\", \"456\"]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Write apply_to_each function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# a. Input: list object reference, function object\n", + "# b. Output: new list reference to transformed object\n", + "# c. Pseudocode:\n", + "# 1. Initiliaze new empty list for output - we don't want to modify \n", + "# the input list! \n", + "# 2. Process each item in input list\n", + "# 3. Apply the function passed as arugment to 2nd parameter\n", + "# 4. And the transformed item into output list\n", + "# 5. return output list\n", + "\n", + "def apply_to_each(original_L, f):\n", + " \"\"\"\n", + " returns a new list with transformed items, by applying f function\n", + " to each item in the original list\n", + " \"\"\"\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Apply `int` function to list L using apply_to_each function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Write strip_dollar function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# a. Input: string value\n", + "# b. Output: transformed string value\n", + "# c. Pseudocode: \n", + "# 1. Check whether input string begins with $ - \n", + "# what string method do you need here?\n", + "# 2. If so remove it\n", + "\n", + "def strip_dollar(s):\n", + " \"\"\"\n", + " Removes the beginning $ sign from string s\n", + " \"\"\"\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Apply strip_dollar function and then apply int function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "L = [\"$1\", \"23\", \"$456\"]\n", + "vals = apply_to_each(L, strip_dollar)\n", + "print(vals)\n", + "vals = apply_to_each(vals, int)\n", + "print(vals)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Apply upper method call to the below list L by using apply_to_each function" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "L = [\"aaa\", \"bbb\", \"ccc\"]\n", + "vals = apply_to_each(L, ???)\n", + "print(vals)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Custom sorting nested data structures\n", + "\n", + "Examples:\n", + "- list of tuples\n", + "- list of dictionaries" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example 4: Custom sort a list of tuples" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "badgers_in_nfl = [ # tuple storing (first name, last name, age)\n", + " (\"Jonathan\", \"Taylor\", 22 ), \n", + " (\"Russel\", \"Wilson\", 32), \n", + " (\"Troy\", \"Fumagalli\", 88),\n", + " (\"Melvin\", \"Gordon\", 27), \n", + " (\"JJ\", \"Watt\", 31),\n", + " ]\n", + "\n", + "sorted(badgers_in_nfl) # or sort() method by default uses first element to sort" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### What what if we want to sort by the last name or by the length of the name?\n", + "\n", + "- `sorted` function and `sort` method takes a function reference as keyword argument for the parameter `key`\n", + "- We can define functions that take one of the inner data structure as argument and return the field based on which we want to perform the sorting.\n", + " - We then pass a reference to such a function as argument to the parameter `key`.\n", + " \n", + "#### Define functions that will enable extraction of item at each tuple index position. These functions only deal with a single tuple processing" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def extract_fname(???): # function must have exactly one parameter\n", + " return ???\n", + "\n", + "def extract_lname(player_tuple):\n", + " return ???\n", + "\n", + "def extract_age(player_tuple):\n", + " return ???" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Test extract_fname function on the tuple ('JJ', 'Watt', 31)\n", + "extract_fname(('JJ', 'Watt', 31))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sort players by their last name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sorted(badgers_in_nfl, ???) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sort players by their age" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sorted(badgers_in_nfl, ???) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sort players by descending order of age" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sorted(badgers_in_nfl, ???, ???) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sort players by length of first name + length of last name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def compute_name_length(player_tuple):\n", + " return ???\n", + "\n", + "sorted(badgers_in_nfl, ???) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example 5: Custom sort a list of dictionaries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hurricanes = [\n", + " {\"name\": \"A\", \"year\": 2000, \"speed\": 150},\n", + " {\"name\": \"B\", \"year\": 1980, \"speed\": 100},\n", + " {\"name\": \"C\", \"year\": 1990, \"speed\": 250},\n", + "]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Extract hurricane at index 0" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hurricanes[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Extract hurricane at index 1" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hurricanes[1]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Can you compare hurricane at index 0 and hurricane at index 1 using \"<\" operator?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# hurricanes[0] < hurricanes[1] #uncomment to see TypeError" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### What about calling sorted method by passing hurricanes as argument?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# sorted(hurricanes) # Doesn't work because there isn't a defined \"first\" key in a dict.\n", + "# Unlike tuple, where the first item can be considered \"first\" by ordering." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Sort hurricanes based on the year" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# a. Input: single hurricane's dict\n", + "# b. Output: return \"year\" value from the dict\n", + "\n", + "def get_year(???):\n", + " ???\n", + "\n", + "sorted(hurricanes, ???)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Sort hurricanes in descending order of their year" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sorted(hurricanes, key = get_year, reverse = True) \n", + "# alternatively get_year function could return negative of year \n", + "# --- that produces the same result as passing True as argument to reverse parameter" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Sort hurricanes in ascending order of their speed" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hurricanes = [\n", + " {\"name\": \"A\", \"year\": 2000, \"speed\": 150},\n", + " {\"name\": \"B\", \"year\": 1980, \"speed\": 100},\n", + " {\"name\": \"C\", \"year\": 1990}, # notice the missing speed key\n", + "]\n", + "\n", + "def get_speed(hurricane):\n", + " return ???\n", + "\n", + "sorted(hurricanes, key = get_speed)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example 6: How can you pass string method to sorted function?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sorted([\"A\", \"b\", \"C\", \"d\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sorted([\"A\", \"b\", \"C\", \"d\"], key = ???)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Sorting dictionary by keys / values" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Example 7: sorting dictionaries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "players = {\n", + " \"bob\": 20, \n", + " \"alice\": 8, \n", + " \"alex\": 9, \n", + " \"cindy\": 15} # Key: player_name; Value: score\n", + "players" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### This only returns a list of sorted keys. What if we want to create a new sorted dictionary object directly using sorted function?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "sorted(players) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Let's learn about items method on a dictionary\n", + "- returns a list of tuples\n", + "- each tuple item contains two items: key and value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Write an extract function to extract dict value (that is player score), using items method return value" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "def extract_score(player_tuple):\n", + " return player_tuple[1]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Sort players dict by key" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "How can you convert sorted list of tuples back into a `dict`?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using `lambda`\n", + "- `lambda` functions are a way to abstract a function reference\n", + "- lambdas are simple functions with:\n", + " - multiple possible parameters\n", + " - single expression line as the function body\n", + "- lambdas are useful abstractions for:\n", + " - mathematical functions\n", + " - lookup operations\n", + "- lambdas are often associated with a collection of values within a list\n", + "- Syntax: \n", + "```python \n", + "lambda parameters: expression\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Now let's write the same solution using lambda." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dict(sorted(players.items(), key = ???))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### What about sorting dictionary by values using lambda?" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dict(sorted(players.items(), key = ???))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Now let's sort players dict using length of player name." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "dict(sorted(players.items(), key = ???))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Self-practice: Use lambdas to solve the NFL sorting questions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "print(badgers_in_nfl)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sort players using their first name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sort players using their last name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sort players using their age" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Sort players using the length of first name and last name" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.4" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}