diff --git a/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/function_references-checkpoint.ipynb b/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/function_references-checkpoint.ipynb deleted file mode 100644 index 8c17aee11f61320f317c012da8691ef1496af5c1..0000000000000000000000000000000000000000 --- a/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/function_references-checkpoint.ipynb +++ /dev/null @@ -1,1323 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Function references" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Recursion review" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "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": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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) # uncomment to see RecursionError\n", - "# Answer: infinite recursion, because we never get to the base case" - ] - }, - { - "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." - ] - }, - { - "attachments": {}, - "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": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "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": 4, - "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": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello there!\n", - "Hello there!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n" - ] - } - ], - "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": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello there!\n", - "Hello there!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n" - ] - } - ], - "source": [ - "for i in range(2):\n", - " say_hi()\n", - "\n", - "for i in range(3):\n", - " say_bye()" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello there!\n", - "Hello there!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n" - ] - } - ], - "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": "markdown", - "metadata": {}, - "source": [ - "### Example 3: Apply various transformations to all items on a list" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "L = [\"1\", \"23\", \"456\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Write apply_to_each function" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "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", - " new_vals = []\n", - " for val in original_L:\n", - " new_vals.append(f(val))\n", - " return new_vals" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Apply int function to list L using apply_to_each function" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 23, 456]" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "vals = apply_to_each(L, int)\n", - "vals" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Write strip_dollar function" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "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", - " #Remove the beginning $ sign from string s\n", - " if s.startswith(\"$\"):\n", - " s = s[1:]\n", - " return s" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Apply strip_dollar function and then apply int function" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['1', '23', '456']\n", - "[1, 23, 456]\n" - ] - } - ], - "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": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['AAA', 'BBB', 'CCC']\n" - ] - } - ], - "source": [ - "L = [\"aaa\", \"bbb\", \"ccc\"]\n", - "vals = apply_to_each(L, str.upper)\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": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('JJ', 'Watt', 31),\n", - " ('Jonathan', 'Taylor', 22),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Troy', 'Fumagalli', 88)]" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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`." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Define functions that will enable extraction of item at each tuple index position\n", - "#### These functions only deal with a single tuple processing" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "def extract_fname(player_tuple): # function must have exactly one parameter\n", - " return player_tuple[0]\n", - "\n", - "def extract_lname(player_tuple):\n", - " return player_tuple[1]\n", - "\n", - "def extract_age(player_tuple):\n", - " return player_tuple[2]" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'JJ'" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# Test these functions on the tuple (\"Andy\", \"Meena\", \"Peyman\")\n", - "extract_fname(('JJ', 'Watt', 31))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players by their last name" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('Troy', 'Fumagalli', 88),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Jonathan', 'Taylor', 22),\n", - " ('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32)]" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = extract_lname) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players by their age" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('Jonathan', 'Taylor', 22),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Troy', 'Fumagalli', 88)]" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = extract_age) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players by descending order of age" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('Troy', 'Fumagalli', 88),\n", - " ('Russel', 'Wilson', 32),\n", - " ('JJ', 'Watt', 31),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Jonathan', 'Taylor', 22)]" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = extract_age, reverse = True) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players by length of first name + length of last name" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Troy', 'Fumagalli', 88),\n", - " ('Jonathan', 'Taylor', 22)]" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "def compute_name_length(player_tuple):\n", - " return len(player_tuple[0] + player_tuple[1])\n", - "\n", - "sorted(badgers_in_nfl, key = compute_name_length) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Example 5: Custom sort a list of dictionaries" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "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": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'name': 'A', 'year': 2000, 'speed': 150}" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hurricanes[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Extract hurricane at index 1" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'name': 'B', 'year': 1980, 'speed': 100}" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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": 24, - "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": 25, - "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": 26, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "DEBUG: Calling get_year function for: {'name': 'A', 'year': 2000, 'speed': 150}\n", - "DEBUG: Calling get_year function for: {'name': 'B', 'year': 1980, 'speed': 100}\n", - "DEBUG: Calling get_year function for: {'name': 'C', 'year': 1990, 'speed': 250}\n" - ] - }, - { - "data": { - "text/plain": [ - "[{'name': 'B', 'year': 1980, 'speed': 100},\n", - " {'name': 'C', 'year': 1990, 'speed': 250},\n", - " {'name': 'A', 'year': 2000, 'speed': 150}]" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# a. Input: single hurricane's dict\n", - "# b. Output: return \"year\" value from the dict\n", - "\n", - "def get_year(hurricane):\n", - " print(\"DEBUG: Calling get_year function for:\", hurricane)\n", - " return hurricane[\"year\"]\n", - "\n", - "sorted(hurricanes, key = get_year)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Sort hurricanes in descending order of their year" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "DEBUG: Calling get_year function for: {'name': 'A', 'year': 2000, 'speed': 150}\n", - "DEBUG: Calling get_year function for: {'name': 'B', 'year': 1980, 'speed': 100}\n", - "DEBUG: Calling get_year function for: {'name': 'C', 'year': 1990, 'speed': 250}\n" - ] - }, - { - "data": { - "text/plain": [ - "[{'name': 'A', 'year': 2000, 'speed': 150},\n", - " {'name': 'C', 'year': 1990, 'speed': 250},\n", - " {'name': 'B', 'year': 1980, 'speed': 100}]" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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": 28, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'name': 'C', 'year': 1990},\n", - " {'name': 'B', 'year': 1980, 'speed': 100},\n", - " {'name': 'A', 'year': 2000, 'speed': 150}]" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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 hurricane.get(\"speed\", 0)\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": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['A', 'C', 'b', 'd']" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted([\"A\", \"b\", \"C\", \"d\"])" - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['A', 'b', 'C', 'd']" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted([\"A\", \"b\", \"C\", \"d\"], key = str.upper)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Sorting dictionary by keys 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: *lambda* parameters: expression" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Example 7: sorting dictionaries" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'bob': 20, 'alice': 8, 'alex': 9}" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "players = {\"bob\": 20, \"alice\": 8, \"alex\": 9}\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": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['alex', 'alice', 'bob']" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "dict_items([('bob', 20), ('alice', 8), ('alex', 9)])" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "players.items()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Write an extract function to extract dict value using items method return value" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": {}, - "outputs": [], - "source": [ - "def extract(player_tuple):\n", - " return player_tuple[1]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Sort players dict by key" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('alice', 8), ('alex', 9), ('bob', 20)]" - ] - }, - "execution_count": 35, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(players.items(), key = extract)" - ] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'alice': 8, 'alex': 9, 'bob': 20}" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dict(sorted(players.items(), key = extract))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Now let's write the same solution using lambda." - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'alex': 9, 'alice': 8, 'bob': 20}" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dict(sorted(players.items(), key = lambda item: item[0]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What about sorting dictionary by values using lambda?" - ] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'alice': 8, 'alex': 9, 'bob': 20}" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dict(sorted(players.items(), key = lambda item: item[1]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Now let's sort players dict using length of player name." - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'bob': 20, 'alex': 9, 'alice': 8}" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dict(sorted(players.items(), key = lambda item: len(item[0])))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Self-practice: Use lambdas to solve the NFL sorting questions" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[('Jonathan', 'Taylor', 22), ('Russel', 'Wilson', 32), ('Troy', 'Fumagalli', 88), ('Melvin', 'Gordon', 27), ('JJ', 'Watt', 31)]\n" - ] - } - ], - "source": [ - "print(badgers_in_nfl)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players using their first name" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('JJ', 'Watt', 31),\n", - " ('Jonathan', 'Taylor', 22),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Troy', 'Fumagalli', 88)]" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = lambda t: t[0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players using their last name" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('Troy', 'Fumagalli', 88),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Jonathan', 'Taylor', 22),\n", - " ('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32)]" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = lambda t: t[1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players using their age" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('Jonathan', 'Taylor', 22),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Troy', 'Fumagalli', 88)]" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = lambda t : t[-1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players using the length of first name and last name" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Troy', 'Fumagalli', 88),\n", - " ('Jonathan', 'Taylor', 22)]" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = lambda t : len(t[0]) + len(t[1]) )" - ] - } - ], - "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.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/lec_23_function_references-checkpoint.ipynb b/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/lec_23_function_references-checkpoint.ipynb deleted file mode 100644 index 43b5e6bd9558d6e5e3f301d362462df0f1d96e1d..0000000000000000000000000000000000000000 --- a/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/lec_23_function_references-checkpoint.ipynb +++ /dev/null @@ -1,1357 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Function references" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Recursion review" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "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": 2, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "9" - ] - }, - "execution_count": 2, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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", - "# a power b\n", - "\n", - "# Question: What would be the result of the below function call?\n", - "# mystery(-3, -1) # uncomment to see RecursionError\n", - "# Answer: infinite recursion, because we never get to the base case" - ] - }, - { - "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": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3\n" - ] - } - ], - "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": 4, - "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": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello there!\n", - "Hello there!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n" - ] - } - ], - "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": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello there!\n", - "Hello there!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n" - ] - } - ], - "source": [ - "for i in range(2):\n", - " say_hi()\n", - "\n", - "for i in range(3):\n", - " say_bye()" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hello there!\n", - "Hello there!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n", - "Wash your hands and stay well, bye!\n" - ] - } - ], - "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": 8, - "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": 9, - "metadata": {}, - "outputs": [], - "source": [ - "L = [\"1\", \"23\", \"456\"]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Write apply_to_each function" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "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", - " new_vals = []\n", - " for val in original_L:\n", - " new_vals.append(f(val))\n", - " return new_vals" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Apply `int` function to list L using apply_to_each function" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[1, 23, 456]" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "vals = apply_to_each(L, int)\n", - "vals" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Write strip_dollar function" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "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", - " if s.startswith(\"$\"):\n", - " s = s[1:]\n", - " return s" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Apply strip_dollar function and then apply int function" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['1', '23', '456']\n", - "[1, 23, 456]\n" - ] - } - ], - "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": 14, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "['AAA', 'BBB', 'CCC']\n" - ] - } - ], - "source": [ - "L = [\"aaa\", \"bbb\", \"ccc\"]\n", - "vals = apply_to_each(L, str.upper)\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": 15, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('JJ', 'Watt', 31),\n", - " ('Jonathan', 'Taylor', 22),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Troy', 'Fumagalli', 88)]" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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": 16, - "metadata": {}, - "outputs": [], - "source": [ - "def extract_fname(player_tuple): # function must have exactly one parameter\n", - " return player_tuple[0]\n", - "\n", - "def extract_lname(player_tuple):\n", - " return player_tuple[1]\n", - "\n", - "def extract_age(player_tuple):\n", - " return player_tuple[2]" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'JJ'" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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": 18, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('Troy', 'Fumagalli', 88),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Jonathan', 'Taylor', 22),\n", - " ('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32)]" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = extract_lname) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players by their age" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('Jonathan', 'Taylor', 22),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Troy', 'Fumagalli', 88)]" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = extract_age) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players by descending order of age" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('Troy', 'Fumagalli', 88),\n", - " ('Russel', 'Wilson', 32),\n", - " ('JJ', 'Watt', 31),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Jonathan', 'Taylor', 22)]" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = extract_age, reverse = True) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players by length of first name + length of last name" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Troy', 'Fumagalli', 88),\n", - " ('Jonathan', 'Taylor', 22)]" - ] - }, - "execution_count": 21, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "def compute_name_length(player_tuple):\n", - " return len(player_tuple[0] + player_tuple[1])\n", - "\n", - "sorted(badgers_in_nfl, key = compute_name_length) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Example 5: Custom sort a list of dictionaries" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "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": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'name': 'A', 'year': 2000, 'speed': 150}" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "hurricanes[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Extract hurricane at index 1" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'name': 'B', 'year': 1980, 'speed': 100}" - ] - }, - "execution_count": 24, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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": 25, - "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": 26, - "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": 27, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "DEBUG: Calling get_year function for: {'name': 'A', 'year': 2000, 'speed': 150}\n", - "DEBUG: Calling get_year function for: {'name': 'B', 'year': 1980, 'speed': 100}\n", - "DEBUG: Calling get_year function for: {'name': 'C', 'year': 1990, 'speed': 250}\n" - ] - }, - { - "data": { - "text/plain": [ - "[{'name': 'B', 'year': 1980, 'speed': 100},\n", - " {'name': 'C', 'year': 1990, 'speed': 250},\n", - " {'name': 'A', 'year': 2000, 'speed': 150}]" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# a. Input: single hurricane's dict\n", - "# b. Output: return \"year\" value from the dict\n", - "\n", - "def get_year(hurricane):\n", - " print(\"DEBUG: Calling get_year function for:\", hurricane)\n", - " return hurricane[\"year\"]\n", - "\n", - "sorted(hurricanes, key = get_year)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Sort hurricanes in descending order of their year" - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "DEBUG: Calling get_year function for: {'name': 'A', 'year': 2000, 'speed': 150}\n", - "DEBUG: Calling get_year function for: {'name': 'B', 'year': 1980, 'speed': 100}\n", - "DEBUG: Calling get_year function for: {'name': 'C', 'year': 1990, 'speed': 250}\n" - ] - }, - { - "data": { - "text/plain": [ - "[{'name': 'A', 'year': 2000, 'speed': 150},\n", - " {'name': 'C', 'year': 1990, 'speed': 250},\n", - " {'name': 'B', 'year': 1980, 'speed': 100}]" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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": 29, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'name': 'C', 'year': 1990},\n", - " {'name': 'B', 'year': 1980, 'speed': 100},\n", - " {'name': 'A', 'year': 2000, 'speed': 150}]" - ] - }, - "execution_count": 29, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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 hurricane.get(\"speed\", 0)\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": 30, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['A', 'C', 'b', 'd']" - ] - }, - "execution_count": 30, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted([\"A\", \"b\", \"C\", \"d\"])" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['A', 'b', 'C', 'd']" - ] - }, - "execution_count": 31, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted([\"A\", \"b\", \"C\", \"d\"], key = str.upper)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Sorting dictionary by keys / values" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Example 7: sorting dictionaries" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'bob': 20, 'alice': 8, 'alex': 9, 'cindy': 15}" - ] - }, - "execution_count": 32, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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": 33, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['alex', 'alice', 'bob', 'cindy']" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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": 34, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "dict_items([('bob', 20), ('alice', 8), ('alex', 9), ('cindy', 15)])" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "players.items()" - ] - }, - { - "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": 35, - "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": 36, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('alice', 8), ('alex', 9), ('cindy', 15), ('bob', 20)]" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(players.items(), key = extract_score)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "How can you convert sorted list of tuples back into a `dict`?" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'alice': 8, 'alex': 9, 'cindy': 15, 'bob': 20}" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dict(sorted(players.items(), key = extract_score))" - ] - }, - { - "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": 38, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'alex': 9, 'alice': 8, 'bob': 20, 'cindy': 15}" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dict(sorted(players.items(), key = lambda item: item[0]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What about sorting dictionary by values using lambda?" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'alice': 8, 'alex': 9, 'cindy': 15, 'bob': 20}" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dict(sorted(players.items(), key = lambda item: item[1]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Now let's sort players dict using length of player name." - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'bob': 20, 'alex': 9, 'alice': 8, 'cindy': 15}" - ] - }, - "execution_count": 40, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "dict(sorted(players.items(), key = lambda item: len(item[0])))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Self-practice: Use lambdas to solve the NFL sorting questions" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[('Jonathan', 'Taylor', 22), ('Russel', 'Wilson', 32), ('Troy', 'Fumagalli', 88), ('Melvin', 'Gordon', 27), ('JJ', 'Watt', 31)]\n" - ] - } - ], - "source": [ - "print(badgers_in_nfl)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players using their first name" - ] - }, - { - "cell_type": "code", - "execution_count": 42, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('JJ', 'Watt', 31),\n", - " ('Jonathan', 'Taylor', 22),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Troy', 'Fumagalli', 88)]" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = lambda t: t[0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players using their last name" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('Troy', 'Fumagalli', 88),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Jonathan', 'Taylor', 22),\n", - " ('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32)]" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = lambda t: t[1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players using their age" - ] - }, - { - "cell_type": "code", - "execution_count": 44, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('Jonathan', 'Taylor', 22),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Troy', 'Fumagalli', 88)]" - ] - }, - "execution_count": 44, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = lambda t: t[-1])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### Sort players using the length of first name and last name" - ] - }, - { - "cell_type": "code", - "execution_count": 45, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[('JJ', 'Watt', 31),\n", - " ('Russel', 'Wilson', 32),\n", - " ('Melvin', 'Gordon', 27),\n", - " ('Troy', 'Fumagalli', 88),\n", - " ('Jonathan', 'Taylor', 22)]" - ] - }, - "execution_count": 45, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "sorted(badgers_in_nfl, key = lambda t: len(t[0]) + len(t[1]) )" - ] - } - ], - "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.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/lec_23_function_references_template-checkpoint.ipynb b/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/lec_23_function_references_template-checkpoint.ipynb deleted file mode 100644 index b2bd9c4ca98df8b66dd1b79d4c5d64a7f2f7734e..0000000000000000000000000000000000000000 --- a/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/lec_23_function_references_template-checkpoint.ipynb +++ /dev/null @@ -1,903 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Function references" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Recursion review" - ] - }, - { - "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 = {\"bob\": 20, \"alice\": 8, \"alex\": 9} # 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.9.7" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/recursion-checkpoint.ipynb b/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/recursion-checkpoint.ipynb deleted file mode 100644 index 7b563575e377695bc15dca8213430e86f319440e..0000000000000000000000000000000000000000 --- a/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/recursion-checkpoint.ipynb +++ /dev/null @@ -1,254 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Recursion" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Copying review\n", - "- Copy-paste the below code in PyTutor. \n", - "- Uncomment each copy type and look at the visualization of the objects." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import copy\n", - "\n", - "x = [ [ [\"hello\", \"world\"] ] ]\n", - "\n", - "#y = x # ref copy (0 new objects)\n", - "#y = copy.copy(x) # shallow copy (1 new object)\n", - "#y = copy.deepcopy(x) # deep copy (all new objects)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Example: Pretty Print" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What is the simplest example for this problem? This determines the base case" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "# Single-dimensional list passed as argument to pretty_print function." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How can you define self-reference here?" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "# Passing nested list as argument to pretty_print function." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Let's write the code for the recursive function." - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* A\n", - "* 1\n", - "* 2\n", - "* 3\n", - "* B\n", - "* 4\n", - "* i\n", - "* ii\n" - ] - } - ], - "source": [ - "def pretty_print_v1(items):\n", - " for v in items:\n", - " if type(v) == list:\n", - " # Recursive case\n", - " pretty_print_v1(v)\n", - " else:\n", - " # Base case\n", - " print(\"* \" + v)\n", - " \n", - "#data = [\"A\", \"B\", \"C\"]\n", - "data = [\"A\", [\"1\", \"2\", \"3\",], \"B\", [\"4\", [\"i\", \"ii\"]]]\n", - "pretty_print_v1(data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How can we handle indent for nesting here?" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "#Defining a new parameter called \"indent\" to take care of nesting level." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* A\n", - " * 1\n", - " * 2\n", - " * 3\n", - "* B\n", - " * 4\n", - " * i\n", - " * ii\n" - ] - } - ], - "source": [ - "def pretty_print_v2(items, indent = 0):\n", - " for v in items:\n", - " if type(v) == list:\n", - " #Recursive case\n", - " pretty_print_v2(v, indent + 1)\n", - " else:\n", - " #Base case\n", - " spaces = \" \" * indent\n", - " print(spaces + \"* \" + str(v))\n", - "\n", - "#data = [\"A\", \"B\", \"C\"]\n", - "data = [\"A\", [\"1\", \"2\", \"3\",], \"B\", [\"4\", [\"i\", \"ii\"]]]\n", - "pretty_print_v2(data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Practice: Recursive List Search" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* 1\n", - "* 2\n", - " * 4\n", - " * 3\n", - " * 8\n", - " * 9\n", - " * 5\n", - " * 6\n", - "0 False\n", - "1 True\n", - "2 True\n", - "3 True\n", - "4 True\n", - "5 True\n", - "6 True\n", - "7 False\n", - "8 True\n", - "9 True\n", - "10 False\n", - "11 False\n", - "12 False\n" - ] - } - ], - "source": [ - "def contains(n, numbers):\n", - " for i in numbers:\n", - " if type(i) == list:\n", - " if contains(n, i):\n", - " return True\n", - " else:\n", - " if n == i:\n", - " return True\n", - " return False\n", - "\n", - "data = [1, 2, [4, [[3], [8, 9]], 5, 6]]\n", - "pretty_print_v2(data)\n", - "\n", - "for i in range(13):\n", - " print(i, contains(i, data))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.8.8" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/recursion_template-checkpoint.ipynb b/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/recursion_template-checkpoint.ipynb deleted file mode 100644 index 23879e3714ba229f95e3441fdb614c8ac6865835..0000000000000000000000000000000000000000 --- a/f22/meena_lec_notes/lec-23/.ipynb_checkpoints/recursion_template-checkpoint.ipynb +++ /dev/null @@ -1,149 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Recursion" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Copying review\n", - "- Copy-paste the below code in PyTutor. \n", - "- Uncomment each copy type and look at the visualization of the objects." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "import copy\n", - "\n", - "x = [ [ [\"hello\", \"world\"] ] ]\n", - "\n", - "#y = x # ref copy (0 new objects)\n", - "#y = copy.copy(x) # shallow copy (1 new object)\n", - "#y = copy.deepcopy(x) # deep copy (all new objects)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Example: Pretty Print" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### What is the simplest example for this problem? This determines the base case" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How can you define self-reference here?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Let's write the code for the recursive function." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "def pretty_print(items):\n", - " pass\n", - "\n", - "#data = [\"A\", \"B\", \"C\"]\n", - "data = [\"A\", [\"1\", \"2\", \"3\",], \"B\", [\"4\", [\"i\", \"ii\"]]]\n", - "pretty_print(data)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### How can we handle indent for nesting here?" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "#Defining a new parameter called \"indent\" to take care of nesting level." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Practice: Recursive List Search" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.8.8" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -}