{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e843a50d",
   "metadata": {},
   "source": [
    "# In-Class Exercises, Session 5"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b7dbf09",
   "metadata": {},
   "source": [
    "<U>Notes if you are using Jupyter Notebook</U>:  to call <B>exit()</B> from a notebook, please use <B>sys.exit()</B> (requires <B>import sys</B>).\n",
    "\n",
    "If a strange error occurs, it may be because Jupyter retains variables from all executed cells.  To reset the notebook, click 'Restart Kernel' (the circular arrow) -- this will not undo any changes made."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "652160bf",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0bcb87de",
   "metadata": {},
   "source": [
    "FUNCTIONS WITH KEYWORD ARGUMENTS"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c730ea43",
   "metadata": {},
   "source": [
    "<B>5.1:  Write a function multiply() that takes one positional argument (an expected integer value) and one keyword argument (an optional multiplier called <B>mul=</B>).  Make the default for <B>mul=</B> the value <B>2</B>.  Call as shown.</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0fab3b24",
   "metadata": {},
   "outputs": [],
   "source": [
    "# your code here\n",
    "\n",
    "\n",
    "x = multiply(5, mul=3)\n",
    "print(x)                  # 15\n",
    "\n",
    "y = multiply(5)\n",
    "print(y)                  # 10"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "785da3b9",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eccc3304",
   "metadata": {},
   "source": [
    "<B>5.2:  Write a function greet() with one positional argument (a first name) and one keyword argument (an optional last name).  Make the default for <B>last=</B> the value <B>None</B>.  Call as shown.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5b0d78e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# your code here\n",
    "\n",
    "\n",
    "x = greet('Joe')\n",
    "print(x)                 # Hi, Joe!\n",
    "\n",
    "y = greet('Joe', last='Wilson')\n",
    "print(y)                 # Hi, Joe Wilson!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3d75354b",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ca5c2791",
   "metadata": {},
   "source": [
    "OBJECT REFERENCES"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6430a3cf",
   "metadata": {},
   "source": [
    "<B>5.3:  One list or two?  How can we test?  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "634a9d3f",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = ['a', 'b', 'c']\n",
    "\n",
    "y = x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "98d45954",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "72aa7b40",
   "metadata": {},
   "source": [
    "<B>5.4:  Two lists or three?  Is the list in the last item of y a duplicate list?  How can we test?  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c2e7d19c",
   "metadata": {},
   "outputs": [],
   "source": [
    "x = ['a', 'b', 'c']\n",
    "\n",
    "y = [1, 2, 3, x]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2677c843",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f18adfca",
   "metadata": {},
   "source": [
    "REFERENCES PASSED TO FUNCTIONS"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8b63e796",
   "metadata": {},
   "source": [
    "<B>5.5:  One list or two?  Is the list in <B>appendme()</B> a new list?  How can we test?  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cae2ee23",
   "metadata": {},
   "outputs": [],
   "source": [
    "def appendme(arg):\n",
    "    arg.append('d')\n",
    "\n",
    "x = ['a', 'b', 'c']\n",
    "\n",
    "appendme(x)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c8d14b69",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "10cac4bf",
   "metadata": {},
   "source": [
    "<B>5.6:  <B>greet()</B> has been assigned to <B>y</B>.  Call the function through variable <B>y</B>.</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "db539f4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "def greet():\n",
    "    print('hello, world')\n",
    "\n",
    "y = greet"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "95182801",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56c47098",
   "metadata": {},
   "source": [
    "<B>5.7:  Call <B>callit(), passing <B>greet</B> as argument, then inside <B>callit()</B>, call the function through the argument (do not call <B>greet()</B>).</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "bf7ac8d5",
   "metadata": {},
   "outputs": [],
   "source": [
    "def callit(func):\n",
    "    # your code here\n",
    "\n",
    "def greet():\n",
    "    print('hello, world!')\n",
    "\n",
    "\n",
    "# your code also here"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5478cd95",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c589761a",
   "metadata": {},
   "source": [
    "SORTING"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "189e0bd5",
   "metadata": {},
   "source": [
    "<B>5.8:  Given the below code, sort the list in reverse numeric order and print it.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "104e3309",
   "metadata": {},
   "outputs": [],
   "source": [
    "numlist = [1, 13, 23, 3, 9, 16]\n",
    "\n",
    "# your code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dbbb7570",
   "metadata": {},
   "source": [
    "<U>Expected Output</U>:  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e5531e8f",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">[23, 16, 13, 9, 3, 1]</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3fb615d5",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "269b6c12",
   "metadata": {},
   "source": [
    "<B>5.9:  Given the below code, sort the list in alphabetic order and print it.</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9c49a737",
   "metadata": {},
   "outputs": [],
   "source": [
    "charlist = ['a', 'z', 'b', 'c', 'd', 'f']\n",
    "\n",
    "# your code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc6a6d40",
   "metadata": {},
   "source": [
    "<U>Expected Output</U>:  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2fe539e2",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">['a', 'b', 'c', 'd', 'f', 'z']</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1d5f56a1",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74986d1e",
   "metadata": {},
   "source": [
    "<B>5.10:  Given the below code, sort the list using standard sort and print it (note the output below).  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1cd19ec4",
   "metadata": {},
   "outputs": [],
   "source": [
    "charlist = ['F', 'e', 'c', 'a', 'B', 'D']\n",
    "\n",
    "# your code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a72bd1a5",
   "metadata": {},
   "source": [
    "<U>Expected Output</U>:  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9372b10e",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">['B', 'D', 'F', 'a', 'c', 'e']</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "abc6f66d",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "702c39f7",
   "metadata": {},
   "source": [
    "COMPLEX SORTING"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "daff110b",
   "metadata": {},
   "source": [
    "<B>5.11:  Given your understanding that the key= argument to sorted() will in a sense process each element through whatever function we pass to it, sort the below list in alphabetical order and print it.  </B>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ad81ed06",
   "metadata": {},
   "source": [
    "(Hint:  this list will not sort alphabetically by default.  We need a key= function that can modify each element in the list, and make them all the same case.  The string upper() method or lower() method can do the job.  To refer to this method, you can say str.upper or str.lower.  However, make sure not to actually call the method (which is done with the parentheses).  Instead, you simply refer to the method, i.e., mention the method without using the parentheses.)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "75b8e6ec",
   "metadata": {},
   "outputs": [],
   "source": [
    "charlist = ['F', 'e', 'c', 'a', 'B', 'D']\n",
    "\n",
    "# your code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c62c23c9",
   "metadata": {},
   "source": [
    "<U>Expected Output</U>:  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8d3aef0d",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">['a', 'B', 'c', 'D', 'e', 'F']</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5364995e",
   "metadata": {},
   "source": [
    "If you see this message:\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ec6ba191",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">TypeError: descriptor 'upper' of 'str' object needs an argument</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "295738db",
   "metadata": {},
   "source": [
    "it means that you added parentheses and attempted to call the str.upper or str.lower method.  Keep in mind that we don't call this method -- we give it to the sorted() function to call.  We're doing this because sorted() will use whatever function we wish, to modify each element for the purposes of sorting.  If we give it str.upper it will sort 'a' as 'A' and 'B' as 'B' and 'c' as 'C' -- this should indicate to you how we are able to use it for alphabetic sorting with mixed-case strings."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "81f22c16",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ddcb1f25",
   "metadata": {},
   "source": [
    "<B>5.12:  Given your understanding that the key= argument to sorted() will in a sense process each element through whatever function we pass to it, sort these strings by their length, and print the sorted list.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4c18dd9a",
   "metadata": {},
   "outputs": [],
   "source": [
    "mystrs = ['I', 'was', 'hanging', 'on', 'a', 'rock']\n",
    "\n",
    "# your code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "db9f281a",
   "metadata": {},
   "source": [
    "<U>Expected Output</U>:  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3c458627",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">['I', 'a', 'on', 'was', 'rock', 'hanging']</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bfc45515",
   "metadata": {},
   "source": [
    "If you see this message:\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5ae89fd8",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">TypeError: len() takes exactly one argument (0 given)</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77f56680",
   "metadata": {},
   "source": [
    "it means that you added parentheses and thus attempted to call the len function.  Keep in mind that we don't call this method -- we give it to the sorted() function to call.  We're doing this because sorted() will use whatever function we wish, to modify each element for the purposes of sorting.  If we give it len it will sort 'I' as 1, 'was' as 3, 'hanging' as 7, etc -- perfect for our purposes."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b02fb06",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3de7a2e0",
   "metadata": {},
   "source": [
    "<B>5.13:  Given the following numbers, which were retrieved from a file as strings, sort the strings numerically without creating a new list.  (Hint:  based on your understanding that the key= argument to sorted() will in a sense process each element through whatever function we pass to it, use a function that converts numeric strings to integers.  </B>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7b01bcd7",
   "metadata": {},
   "source": [
    "If you see a message similar to the one mentioned in the previous exercise, it means you've done something similar to the issue mentioned there.  Remember that key= references a function, it does not call it (thus we will not use parentheses).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "df30f5e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "mynums = ['5', '101', '10', '1', '3']\n",
    "\n",
    "# your code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da54e046",
   "metadata": {},
   "source": [
    "<U>Expected Output</U>:  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "478a5412",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">['1', '3', '5', '10', '101']</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6ff3950e",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "09af01fa",
   "metadata": {},
   "source": [
    "<B>5.14:  Experiential exercise.  Please run the following code:</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "66ffde47",
   "metadata": {},
   "outputs": [],
   "source": [
    "def my_element_modifier(arg):\n",
    "    lower_arg = arg.lower()\n",
    "    print(f'sorting element \"{arg}\" by value \"{lower_arg}\"')\n",
    "    return lower_arg\n",
    "\n",
    "sorted_list = sorted(['e', 'c', 'D', 'B', 'a'],\n",
    "                     key=my_element_modifier)\n",
    "print(sorted_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2420fb2c",
   "metadata": {},
   "source": [
    "Note the output:\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3ff1ca8",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">sorting element \"e\" by value \"e\"\n",
    "sorting element \"c\" by value \"c\"\n",
    "sorting element \"D\" by value \"d\"\n",
    "sorting element \"B\" by value \"b\"\n",
    "sorting element \"a\" by value \"a\"\n",
    "\n",
    "['a', 'B', 'c', 'D', 'e']</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "381fee72",
   "metadata": {},
   "source": [
    "This exercise demonstrates that my\\_element\\_modifier() was called once for every element, in this case 5 times.  arg is assigned each element in turn.  And the value returned from my\\_element\\_modifier() is the value by which each element is sorted -- so 'a' is sorted by the value 'a', 'B' is sorted by the value 'b', 'c' by 'c', 'D' by 'd'.  This facilitates the alphabetic sorting of these values.  The values themselves don't change, but Python sorts according to the value returned from the function.\n",
    "\n",
    "If this makes sense to you, please go back to the previous examples and link this understanding to the other functions and methods we've used before -- using int, len, str.upper, etc.  They are all passing a function to be applied to each element, and Python is sorting by the value returned from the function or method."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "43480744",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ccf8463d",
   "metadata": {},
   "source": [
    "<B>5.15:  Given the below list, sort line\\_list by the number at the end of each line.  Loop through and print the sorted list.  (Hint:  call sorted() on line\\_list, and make your key= value the name of a custom function that takes the line as an argument and returns the value of the number at the end of the line.  Your custom function will simply take an arg (that will be a string, the line from the file), split the line into elements, and return the last element as an integer.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "63d84859",
   "metadata": {},
   "outputs": [],
   "source": [
    "line_list = [\n",
    "   'the value 3',\n",
    "   'this value 1',\n",
    "   'that value is 4',\n",
    "   'the value here is 2'\n",
    "]\n",
    "\n",
    "# your code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "428c907f",
   "metadata": {},
   "source": [
    "<U>Expected Output</U>:  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "217b65dd",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">line_list = [\n",
    "   'this value 1',\n",
    "   'the value here is 2',\n",
    "   'the value 3',\n",
    "   'that value is 4'\n",
    "]</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8523b529",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc12708e",
   "metadata": {},
   "source": [
    "<B>5.16:  Sort the lines of the file pyku.txt by the number of words on each line.  (Hint:  write a custom sort function that takes a single line of text, splits the line into a list, and returns the length of the list.  Pass the readlines() of the file to the sorted() function.)  Also here I am using rstrip() to strip each line before printing.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8e90b541",
   "metadata": {},
   "outputs": [],
   "source": [
    "fh = open('../pyku.txt')\n",
    "\n",
    "lines = fh.readlines()\n",
    "\n",
    "# your code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a5682aed",
   "metadata": {},
   "source": [
    "<U>Expected Output</U>:  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "28907594",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">We're out of gouda.\n",
    "Spam, spam, spam, spam, spam.\n",
    "This parrot has ceased to be.</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e8e21e67",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bf0dbd3",
   "metadata": {},
   "source": [
    "<B>5.17:  Sort the lines of revenue.csv by the numeric value in the last field by passing the list of lines returned from readlines() of the file to sorted() and using a custom sort sub similar to an earlier exercise.  (I am also rstrip()ping each line before printing it.)</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7830f4c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "fh = open('../revenue.csv')\n",
    "\n",
    "lines = fh.readlines()\n",
    "\n",
    "\n",
    "# your code here\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "843f7a8b",
   "metadata": {},
   "source": [
    "<U>Expected Output</U>:  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61595c32",
   "metadata": {},
   "source": [
    "<pre style=\"margin: 0; padding=0\"><DIV style=\"font-family: Courier; border: 1px solid #dbdbdb; padding: 7px\">Dothraki Fashions,NY,5.98\n",
    "Hipster's,NY,11.98\n",
    "Awful's,PA,23.95\n",
    "Westfield,NJ,53.90\n",
    "The Clothiers,NY,115.20\n",
    "The Store,NJ,211.50\n",
    "Haddad's,PA,239.50</DIV></pre>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "01589280",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b07ba86",
   "metadata": {},
   "source": [
    "SORTING WITH LAMBDA FUNCTIONS"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eadd6615",
   "metadata": {},
   "source": [
    "<B>5.18:  <U>Convert a function to lambda</U>.  </B>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ff6934f3",
   "metadata": {},
   "source": [
    "The following function takes one argument and returns the value doubled.  Convert to lambda and use in the <B>map()</B> function.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "da23b42a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def doubleit(arg):\n",
    "    return arg * 2\n",
    "\n",
    "seq = [1, 2, 3, 4]\n",
    "\n",
    "seq2 = map(doubleit, seq)   # replace doubleit with a lambda here\n",
    "\n",
    "print(list(seq2))           # [2, 4, 6, 8]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f88ca7d",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2fbb6d0d",
   "metadata": {},
   "source": [
    "<B>5.19:  <U>Convert another function to lambda</U>.  </B>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd583d72",
   "metadata": {},
   "source": [
    "The below function <B>by\\_last\\_float()</B> takes a string argument and returns a portion of that string (converted to float) as return value.  Replace this function with a lambda.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a451acfc",
   "metadata": {},
   "outputs": [],
   "source": [
    "revenue = '../revenue.csv'\n",
    "\n",
    "def by_last_float(line):\n",
    "    words = line.split(',')\n",
    "    return float(words[-1])\n",
    "\n",
    "fh = open(revenue)\n",
    "lines = fh.readlines()\n",
    "for line in sorted(lines, key= # your lambda function here):\n",
    "    line = line.rstrip()\n",
    "    print line"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73cf41a8",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d969da0c",
   "metadata": {},
   "source": [
    "<B>5.20:  Use a lambda to sort strings as floats.</B>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6b235ee8",
   "metadata": {},
   "source": [
    "Given the below list of strings that have float values, write a lambda to sort these values by their float equivalents.\n",
    "\n",
    "(Although this is possible without using a custom function or lambda, we would like to practice lambdas here.)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c05c9ef5",
   "metadata": {},
   "outputs": [],
   "source": [
    "fvals = ['39.5', '3.0', '300.3', '2.002', '20.95',\n",
    "         '200.1', '21.3', '20.03']\n",
    "\n",
    "\n",
    "svals = sorted(fvals, # your lambda here)\n",
    "\n",
    "print(svals)     # ['2.002', '20.03', '29.95', '21.3',\n",
    "                 #  '200.1', '3.0', '39.5', '300.3']"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c0032c53",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c134ff69",
   "metadata": {},
   "source": [
    "<B>5.21:  <U>Use a lambda to sort a dict by value</U>.  </B>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef921ce3",
   "metadata": {},
   "source": [
    "As you know, sorting a dict means sorting its keys.  Write a lambda that expects a dict key as argument, and returns the value for that key as return value.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f38b01ab",
   "metadata": {},
   "outputs": [],
   "source": [
    "d = {'a': 10, 'b': 2, 'c': 5}\n",
    "\n",
    "skeys = sorted(d, key=# your lambda function here)\n",
    "\n",
    "print(skeys)        # ['b', 'c', 'a'] (in order of value, low-to-high)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2bb9ecff",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be191d91",
   "metadata": {},
   "source": [
    "SORTING COMPLEX STRUCTURES"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6a6f524a",
   "metadata": {},
   "source": [
    "<B>5.22:  Given the following list of dicts, sort the dicts by each dict's last name.  Loop through and print each dict.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f2991be1",
   "metadata": {},
   "outputs": [],
   "source": [
    "people = [\n",
    "    { 'id':     '12345',\n",
    "      'fname':  'Joe',\n",
    "      'lname':  'Wilson',\n",
    "      'addr':   '12345 Main Street' },\n",
    "\n",
    "    { 'id':     '00355',\n",
    "      'fname':  'Marie',\n",
    "      'lname':  'Adams',\n",
    "      'addr':   '888 Elm Street' },\n",
    "\n",
    "    { 'id':     '98973',\n",
    "      'fname':  'Alex',\n",
    "      'lname':  'Wilson',\n",
    "      'addr':   '23 Marsh Avenue' }\n",
    "]\n",
    "\n",
    "# your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f388193",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4f272b48",
   "metadata": {},
   "source": [
    "<B>5.23:  Given the following dict of dicts, sort the dict keys by the last name.  Loop through and print each key.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6ee3e496",
   "metadata": {},
   "outputs": [],
   "source": [
    "people = {  '12345': { 'fname':  'Joe',\n",
    "                       'lname':  'Wilson',\n",
    "                       'addr':   '12345 Main Street' },\n",
    "\n",
    "            '00355': { 'fname':  'Marie',\n",
    "                       'lname':  'Adams',\n",
    "                       'addr':   '888 Elm Street' },\n",
    "\n",
    "            '98973': { 'fname':  'Alex',\n",
    "                       'lname':  'Wilson',\n",
    "                       'addr':   '23 Marsh Avenue' }\n",
    "}\n",
    "\n",
    "# your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c39142b",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4cee3f81",
   "metadata": {},
   "source": [
    "HIGHER ORDER FUNCTIONS"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "79a571ad",
   "metadata": {},
   "source": [
    "<B>5.24:  map() and filter() functions:  call below functions to see result.  Play with return value of functions to see altered result.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d68227c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "def doubleit(arg):\n",
    "    return arg * 2\n",
    "\n",
    "def is_positive(arg):\n",
    "    if arg > 0:\n",
    "        return True\n",
    "    else:\n",
    "        return False\n",
    "\n",
    "proclist = [-3, -2, -1, 0, 1, 2, 3]\n",
    "\n",
    "transformed_list = map(doubleit, proclist)\n",
    "\n",
    "filtered_list = filter(is_positive, proclist)\n",
    "\n",
    "print('* mapped list *')\n",
    "print(transformed_list)\n",
    "\n",
    "print()\n",
    "\n",
    "print('* filtered list *')\n",
    "print(filtered_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "72382d55",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f1df3eb",
   "metadata": {},
   "source": [
    "<B>5.25:  <B>greet</B> has been assigned to <B>callit</B>.  Call <B>greet</B> inside the function.</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f9b7cc45",
   "metadata": {},
   "outputs": [],
   "source": [
    "def callit(arg):\n",
    "    # your code here\n",
    "\n",
    "def greet():\n",
    "    print('hello, world')\n",
    "\n",
    "callit(greet)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "07d58ec6",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "432c8eab",
   "metadata": {},
   "source": [
    "<B>5.26:  <B>greet</B> has been returned from <B>returnit</B>.  Call <B>greet</B> outside the function.</B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1292b178",
   "metadata": {},
   "outputs": [],
   "source": [
    "def returnit():\n",
    "    def greet():\n",
    "        print('hello, world')\n",
    "    return greet\n",
    "\n",
    "x = returnit()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "743d79da",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "da71d3d6",
   "metadata": {},
   "source": [
    "<B>5.27:  Demo:  a \"decorator\" function -- a function that both takes a function as argument and returns a function as return value.  Use the prior concepts (regarding passing a function reference to another function and returning a function reference from a function) to understand what is happening here.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d2f65381",
   "metadata": {},
   "outputs": [],
   "source": [
    "def my_decorator(func):    # func: function, 'whoop'\n",
    "\n",
    "    def wrapper():\n",
    "        print(\"Something is happening before whoop() is called.\")\n",
    "\n",
    "        func()             # calls 'whoop'\n",
    "\n",
    "        print(\"Something is happening after whoop() is called.\")\n",
    "\n",
    "    return wrapper         # return function 'wrapper'\n",
    "\n",
    "\n",
    "def whoop():\n",
    "    print(\"Wheee!\")\n",
    "\n",
    "\n",
    "# now the same name points to a replacement function\n",
    "whoop = my_decorator(whoop)          # function 'wrapper'\n",
    "\n",
    "# calling the replacement function\n",
    "whoop()                              # (calls function wrapper)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3e75eb69",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6d42fc07",
   "metadata": {},
   "source": [
    "<B>5.28:  Same function as last time -- this time use @ (\"pie syntax\") to produce a \"true\" Python decorator.  Place the decorator just above the function def for <B>this\\_function</B>, and remove the call to <B>my\\_decorator()</B>.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9dc0b339",
   "metadata": {},
   "outputs": [],
   "source": [
    "def my_decorator(func):        # func:  function, 'whoop'\n",
    "\n",
    "    def wrapper():\n",
    "        print(\"Something is happening before whoop() is called.\")\n",
    "\n",
    "        func()                 # calls whoop()\n",
    "\n",
    "        print(\"Something is happening after whoop() is called.\")\n",
    "\n",
    "    return wrapper             # return function 'wrapper'\n",
    "\n",
    "@my_decorator\n",
    "def this_function():\n",
    "    print(\"Wheee!\")\n",
    "\n",
    "\n",
    "# calling the replacement function\n",
    "this_function()                # (calls function wrapper)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e2e5bfa1",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c93de41",
   "metadata": {},
   "source": [
    "<B>5.29:  Understanding *args and **kwargs:  the below function has 2 positional arguments and 2 keyword arguments, and prints the arguments inside the function.  Call the function as shown, and see the the arguments printed.  Now replace the arguments in the signature with <B>*args</B> and <B>**kwargs</B> and print the variables <B>args</B> and <B>kwargs</B> inside the function. </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8e303566",
   "metadata": {},
   "outputs": [],
   "source": [
    "def printargs(w, x, y=0, z=None):\n",
    "\n",
    "    print(w, x, y, z)\n",
    "\n",
    "\n",
    "printargs(5, 10, y=100, z='Hello!')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4d6fbc01",
   "metadata": {},
   "source": [
    " "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cd41eb20",
   "metadata": {},
   "source": [
    "<B>5.30:  Same decorator function as last time -- <B>this\\_function()</B> has been defined to take two positional arguments and two keyword arguments, printing these arguments inside <B>this\\_function()</B>).  Inside <B>wrapper()</B>, we accept these arguments and pass them to <B>myfunc()</B> (which is <B>this\\_function()</B>.  Run this program to see that it works.  Now replace the positional arguments with <B>*args</B> and the keyword arguments with <B>**kwargs</B> and see that it works in the same way.  </B>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8247a784",
   "metadata": {},
   "outputs": [],
   "source": [
    "def my_decorator(func):             # func:  function, 'whoop'\n",
    "\n",
    "    def wrapper(*args, **kwargs):   # args: tuple, (5, 10); kwargs: dict, {'x': 99, 'y': 'hey!'}\n",
    "        print(\"Something is happening before whoop() is called.\")\n",
    "\n",
    "        func(*args, **kwargs)       # calling whoop(5, 10, x=99, y='hey!')\n",
    "\n",
    "        print(\"Something is happening after whoop() is called.\")\n",
    "\n",
    "    return wrapper                  # return function 'wrapper'\n",
    "\n",
    "@my_decorator                       # replacing whoop with wrapper\n",
    "def whoop(a, b, x=None, y=None):\n",
    "    print(f\"Wheee!:  {a}, {b}, {x}, {y}\")\n",
    "\n",
    "\n",
    "# calling the replacement function\n",
    "whoop(5, 10, x=99, y='hey!')        # calling wrapper(5, 10, x=99, y='hey!')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ab7bb527",
   "metadata": {},
   "source": [
    " "
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 5
}
