From 6f36b11cc7593deb02fcfd43f19ca9179fc8f070 Mon Sep 17 00:00:00 2001
From: Cole Nelson <ctnelson1997@gmail.com>
Date: Sun, 17 Sep 2023 21:44:32 -0500
Subject: [PATCH] cole lec06

---
 ...6_Creating_Functions_Solution_Nelson.ipynb | 776 ++++++++++++++++++
 ...6_Creating_Functions_Template_Nelson.ipynb | 518 ++++++++++++
 2 files changed, 1294 insertions(+)
 create mode 100644 f23/Cole_Lecture_Notes/06_Creating_Functions/Lec_06_Creating_Functions_Solution_Nelson.ipynb
 create mode 100644 f23/Cole_Lecture_Notes/06_Creating_Functions/Lec_06_Creating_Functions_Template_Nelson.ipynb

diff --git a/f23/Cole_Lecture_Notes/06_Creating_Functions/Lec_06_Creating_Functions_Solution_Nelson.ipynb b/f23/Cole_Lecture_Notes/06_Creating_Functions/Lec_06_Creating_Functions_Solution_Nelson.ipynb
new file mode 100644
index 0000000..3743103
--- /dev/null
+++ b/f23/Cole_Lecture_Notes/06_Creating_Functions/Lec_06_Creating_Functions_Solution_Nelson.ipynb
@@ -0,0 +1,776 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "What is your name? Cole\n",
+      "Hello, Cole\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Warmup 1\n",
+    "# Get the user's name using the input function.\n",
+    "# Then, print out 'Hello, NAME'\n",
+    "name = input(\"What is your name? \")\n",
+    "print(\"Hello,\", name)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "What number would you like to root? 81\n",
+      "The sqrt of 81.0 is 9.0\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Warmup 2\n",
+    "# Ask the user for a number, then tell them the sqrt of it.\n",
+    "# HINT: sqrt needs to be imported from math!\n",
+    "import math\n",
+    "num = float(input(\"What number would you like to root? \"))\n",
+    "rt_num = math.sqrt(num)\n",
+    "print(\"The sqrt of \" + str(num) + \" is \" + str(rt_num))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Tell me a number! 9\n",
+      "That number is even: False\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Warmup 3\n",
+    "# Fix the code below. What type of error(s) did you fix?\n",
+    "x = input(\"Tell me a number! \")\n",
+    "is_even = (float(x) % 2 == 0)\n",
+    "print(\"That number is even: \" + str(is_even))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Creating Functions\n",
+    "\n",
+    "## Readings\n",
+    "\n",
+    "- Parts of Chapter 3 of Think Python,\n",
+    "- Chapter 5.5 to 5.8 of Python for Everybody\n",
+    "- Creating Fruitful Functions"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Learning Objectives\n",
+    "\n",
+    "- Explain the syntax of a function header:\n",
+    "    - def, ( ), :, tabbing, return\n",
+    "- Write a function with:\n",
+    "    - correct header and indentation\n",
+    "    - a return value (fruitful function) or without (void function)\n",
+    "    - parameters that have default values\n",
+    "- Write a function knowing the difference in outcomes of print and return statements\n",
+    "- Explain how positional, keyword, and default arguments are copied into parameters\n",
+    "- Make function calls using positional, keyword, and default arguments and determine the result.\n",
+    "- Trace function invocations to determine control flow"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## More Warmup\n",
+    "Let's try some more problems not covered in Friday's lecture!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1695004233.8965383\n",
+      "1695004246.588747\n",
+      "12.692208766937256\n"
+     ]
+    }
+   ],
+   "source": [
+    "# On the line below, import the time module\n",
+    "import time\n",
+    "start_time = time.time()\n",
+    "x = 2**1000000000 # a very long computation\n",
+    "end_time = time.time()\n",
+    "\n",
+    "# Change the line below to compute the time difference\n",
+    "difference = end_time - start_time\n",
+    "\n",
+    "# Seperate each time with a '\\n'\n",
+    "print(start_time, end_time, difference, sep='\\n') "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Help on built-in function time in module time:\n",
+      "\n",
+      "time(...)\n",
+      "    time() -> floating point number\n",
+      "    \n",
+      "    Return the current time in seconds since the Epoch.\n",
+      "    Fractions of a second may be present if the system clock provides them.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "help(time.time)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3.0"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# From the math module, import only the log10 function\n",
+    "from math import log10\n",
+    "# Then, print the log base 10 of 1000\n",
+    "log10(1000)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "3.141592653589793\n"
+     ]
+    }
+   ],
+   "source": [
+    "# This one is done for you as an example!\n",
+    "# Note: importing with 'wildcard' * is generally considered bad practice\n",
+    "from math import *  # allows us to use all functions without writing math\n",
+    "print(pi)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "3.141592653589793\n",
+      "3.141592653589793\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Try importing and printing 'pi' the proper way!\n",
+    "\n",
+    "from math import pi\n",
+    "print(pi)\n",
+    "\n",
+    "# or\n",
+    "\n",
+    "import math\n",
+    "print(math.pi)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Functions"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Write a function that cubes any number\n",
+    "\n",
+    "def cube(side):\n",
+    "    return side ** 3\n",
+    "\n",
+    "# The first line is called the function header\n",
+    "# Notice that all the other lines are indented the same amount (4 spaces)\n",
+    "# The best practice in Jupyter Notebook is to press tab\n",
+    "# If you don't run the cell, Jupyter Notebook won't know about the function\n",
+    "\n",
+    "# We'll use PythonTutor to help us out!\n",
+    "# https://pythontutor.com/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "125\n",
+      "37\n",
+      "512\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Now we call/invoke the cube function!\n",
+    "print(cube(5))\n",
+    "print(cube(4) + cube(-3))\n",
+    "print(cube(cube(2)))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# In the bad_cube function definition, use print instead of return\n",
+    "def bad_cube(side):\n",
+    "    print(side ** 3)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "125\n",
+      "None\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Explain what goes wrong in these function calls.\n",
+    "# bad_cube does not return anything, it only prints to the screen\n",
+    "# So we return None, and store it in x.\n",
+    "x = bad_cube(5)\n",
+    "print(x)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## `return` vs `print`\n",
+    "- `return` enables us to send output from a function to the calling place\n",
+    "    - default `return` value is `None`\n",
+    "    - that means, when you don't have a `return` statement, `None` will be returned\n",
+    "- `print` function simply displays / prints something\n",
+    "    - it cannot enable you to produce output from a function"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "True\n",
+      "False\n",
+      "True\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Write a function that determines if one number is between two other numbers\n",
+    "# return a boolean ... True or False\n",
+    "def is_between(lower, num, upper):\n",
+    "    return lower <= num <= upper # also:  num >= lower and num <= upper\n",
+    "\n",
+    "# you can call a function in the same cell that you defined it\n",
+    "print(is_between(3, 7, 21))\n",
+    "print(is_between(2, 14, 5))\n",
+    "print(is_between(100, cube(5), 200))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "#####\n",
+      "#####\n",
+      "#####\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Example 3: write a function get_grid that works like this:\n",
+    "# get_grid(5, 3, \"@\") returns the string \n",
+    "# @@@@@\n",
+    "# @@@@@\n",
+    "# @@@@@\n",
+    "\n",
+    "# Let's practice Incremental Coding\n",
+    "# first, try to do this with string operators and literals\n",
+    "width = 5\n",
+    "height = 3\n",
+    "symbol = '#'\n",
+    "print(((symbol * 5) + '\\n') * 3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "#####\n",
+      "#####\n",
+      "#####\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "# then, try to do this with variables\n",
+    "width = 5\n",
+    "height = 3\n",
+    "symbol = '#'\n",
+    "print(((symbol * width) + '\\n') * height)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "*****\n",
+      "*****\n",
+      "*****\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "# now, try to write a function \n",
+    "# think about what would be good names for the parameters\n",
+    "\n",
+    "def get_grid(width, height, symb):\n",
+    "    return (((symb * width) + '\\n') * height)\n",
+    "\n",
+    "my_grid = get_grid(5, 3, \"*\");\n",
+    "# do some code\n",
+    "2**1000000000\n",
+    "# ...\n",
+    "print(my_grid)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Finally, add in a parameter for a title that appears above the grid\n",
+    "def get_grid_with_title(width, height, symb, title='My Grid'):\n",
+    "    row = (symb * width) + '\\n'\n",
+    "    grid = ((row) * height)\n",
+    "    return title + '\\n' + grid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "CS220 Grid\n",
+      "&&&&&&&\n",
+      "&&&&&&&\n",
+      "&&&&&&&\n",
+      "&&&&&&&\n",
+      "&&&&&&&\n",
+      "&&&&&&&\n",
+      "&&&&&&&\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(get_grid_with_title(7, 7, title='CS220 Grid', symb='&'))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Types of arguments\n",
+    "- positional\n",
+    "- keyword\n",
+    "- default\n",
+    "\n",
+    "Python fills arguments in this order: positional, keyword, "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "x = 100\n",
+      "y = 10\n",
+      "z = 5\n",
+      "115\n",
+      "Help on function add3 in module __main__:\n",
+      "\n",
+      "add3(x, y=100, z=100)\n",
+      "    adds three numbers\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "def add3(x, y = 100, z = 100): \n",
+    "    \"\"\"adds three numbers\"\"\"       #documentation string\n",
+    "    print (\"x = \" + str(x))\n",
+    "    print (\"y = \" + str(y))\n",
+    "    print (\"z = \" + str(z))\n",
+    "    return x + y + z\n",
+    "\n",
+    "addition_of_3 = add3(100, 10, 5)\n",
+    "print(addition_of_3)\n",
+    "# TODO: 1. sum is a bad variable, discuss: why. What would be a better variable name?\n",
+    "# TODO: 2. what type of arguments are 100, 10, and 5?\n",
+    "help(add3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "x = 1\n",
+      "y = 5\n",
+      "z = 2\n",
+      "8\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(add3(x = 1, z = 2, y = 5)) #TODO: what type of arguments are these?\n",
+    "# These are keyword arguments"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "x = 5\n",
+      "y = 6\n",
+      "z = 100\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "111"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "add3(5, 6) # TODO: what type of argument gets filled for the parameter z?\n",
+    "# 5 and 6 are positional arguments.\n",
+    "# z has a default argument of 100."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Positional arguments need to be specified before keyword arguments."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "SyntaxError",
+     "evalue": "positional argument follows keyword argument (514132732.py, line 2)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;36m  Cell \u001b[1;32mIn[22], line 2\u001b[1;36m\u001b[0m\n\u001b[1;33m    add3(z = 5, 2, 7)\u001b[0m\n\u001b[1;37m                    ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
+     ]
+    }
+   ],
+   "source": [
+    "# Incorrect function call\n",
+    "add3(z = 5, 2, 7) \n",
+    "# TODO: what category of error is this?\n",
+    "# Syntax Error"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Incorrect function definition\n",
+    "# We must specify non-default arguments first\n",
+    "def add3_bad_version(x = 10, y, z): \n",
+    "    \"\"\"adds three numbers\"\"\"              #documentation string\n",
+    "    return x + y + z"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Incorrect function call\n",
+    "add3(5, 3, 10, x = 4)\n",
+    "# TODO: what category of error is this?\n",
+    "# Runtime Error"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# TODO: will this function call work?\n",
+    "add3(y = 5, z = 10)\n",
+    "# No, we are missing an argument for x"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# TODO: will this function call work?\n",
+    "add3()\n",
+    "# No, we are missing an argument for x"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## fruitful function versus void function\n",
+    "- fruitful function: returns something\n",
+    "    - ex: add3\n",
+    "- void function: doesn't return anything\n",
+    "    - ex: bad_add3_v1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Example of void function\n",
+    "def bad_add3_v1(x, y, z):\n",
+    "    print(x + y + z)\n",
+    "\n",
+    "print(bad_add3_v1(4, 2, 1))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(bad_add3_v1(4, 2, 1) ** 2) # Cannot apply mathematical operator to None"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### `return` statement is final\n",
+    "- exactly *one* `return` statement gets executed for a function call\n",
+    "- immediately after encountering `return`, function execution terminates"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def bad_add3_v2(x, y, z):\n",
+    "    return x\n",
+    "    return x + y + z      # will never execute\n",
+    "\n",
+    "bad_add3_v2(50, 60, 70)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Tracing\n",
+    "- Try tracing this manually...\n",
+    "- ...then use [PythonTutor](https://pythontutor.com/visualize.html#code=def%20func_c%28%29%3A%0A%20%20%20%20print%28%22C%22%29%0A%0Adef%20func_b%28%29%3A%0A%20%20%20%20print%28%22B1%22%29%0A%20%20%20%20func_c%28%29%0A%20%20%20%20print%28%22B2%22%29%0A%0Adef%20func_a%28%29%3A%0A%20%20%20%20print%28%22A1%22%29%0A%20%20%20%20func_b%28%29%0A%20%20%20%20print%28%22A2%22%29%0A%0Afunc_a%28%29&cumulative=false&heapPrimitives=nevernest&mode=edit&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def func_c():\n",
+    "    print(\"C\")\n",
+    "\n",
+    "def func_b():\n",
+    "    print(\"B1\")\n",
+    "    func_c()\n",
+    "    print(\"B2\")\n",
+    "\n",
+    "def func_a():\n",
+    "    print(\"A1\")\n",
+    "    func_b()\n",
+    "    print(\"A2\")\n",
+    "\n",
+    "func_a()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Explain worksheet, start part one of each problem\n",
+    "# This worksheet has questions very similar to your exam!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.4"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/f23/Cole_Lecture_Notes/06_Creating_Functions/Lec_06_Creating_Functions_Template_Nelson.ipynb b/f23/Cole_Lecture_Notes/06_Creating_Functions/Lec_06_Creating_Functions_Template_Nelson.ipynb
new file mode 100644
index 0000000..4900ef9
--- /dev/null
+++ b/f23/Cole_Lecture_Notes/06_Creating_Functions/Lec_06_Creating_Functions_Template_Nelson.ipynb
@@ -0,0 +1,518 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Warmup 1\n",
+    "# Get the user's name using the input function.\n",
+    "# Then, print out 'Hello, NAME'\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Warmup 2\n",
+    "# Ask the user for a number, then tell them the sqrt of it.\n",
+    "# HINT: sqrt needs to be imported from math!\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Warmup 3\n",
+    "# Fix the code below. What type of error(s) did you fix?\n",
+    "x = input(\"Tell me a number! \")\n",
+    "is-even = (x % 2 == 0)\n",
+    "print(\"That number is even: \" + is-even)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Creating Functions\n",
+    "\n",
+    "## Readings\n",
+    "\n",
+    "- Parts of Chapter 3 of Think Python,\n",
+    "- Chapter 5.5 to 5.8 of Python for Everybody\n",
+    "- Creating Fruitful Functions"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Learning Objectives\n",
+    "\n",
+    "- Explain the syntax of a function header:\n",
+    "    - def, ( ), :, tabbing, return\n",
+    "- Write a function with:\n",
+    "    - correct header and indentation\n",
+    "    - a return value (fruitful function) or without (void function)\n",
+    "    - parameters that have default values\n",
+    "- Write a function knowing the difference in outcomes of print and return statements\n",
+    "- Explain how positional, keyword, and default arguments are copied into parameters\n",
+    "- Make function calls using positional, keyword, and default arguments and determine the result.\n",
+    "- Trace function invocations to determine control flow"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## More Warmup\n",
+    "Let's try some more problems not covered in Friday's lecture!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# On the line below, import the time module\n",
+    "\n",
+    "\n",
+    "\n",
+    "start_time = time.time()\n",
+    "x = 2**1000000000 # a very long computation\n",
+    "end_time = time.time()\n",
+    "\n",
+    "difference = end_time - start_time\n",
+    "\n",
+    "# Seperate each time with a '\\n'\n",
+    "print(start_time, end_time, difference) "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "help(time.time)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# From the math module, import only the log10 function\n",
+    "\n",
+    "# Then, print the log base 10 of 1000\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# This one is done for you as an example!\n",
+    "# Note: importing with 'wildcard' * is generally considered bad practice\n",
+    "from math import *  # allows us to use all functions without writing math\n",
+    "print(pi)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Try importing and printing 'pi' the proper way!\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Functions"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Write a function that cubes any number\n",
+    "\n",
+    "\n",
+    "\n",
+    "# The first line is called the function header\n",
+    "# Notice that all the other lines are indented the same amount (4 spaces)\n",
+    "# The best practice in Jupyter Notebook is to press tab\n",
+    "# If you don't run the cell, Jupyter Notebook won't know about the function\n",
+    "\n",
+    "# We'll use PythonTutor to help us out!\n",
+    "# https://pythontutor.com/"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Now we call/invoke the cube function!\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# In the bad_cube function definition, use print instead of return\n",
+    "def bad_cube(side):\n",
+    "    pass\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Explain what goes wrong in these function calls.\n",
+    "\n",
+    "\n",
+    "x = bad_cube(5)\n",
+    "print(x)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## `return` vs `print`\n",
+    "- `return` enables us to send output from a function to the calling place\n",
+    "    - default `return` value is `None`\n",
+    "    - that means, when you don't have a `return` statement, `None` will be returned\n",
+    "- `print` function simply displays / prints something\n",
+    "    - it cannot enable you to produce output from a function"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Write a function that determines if one number is between two other numbers\n",
+    "# return a boolean ... True or False\n",
+    "def is_between(lower, num, upper):\n",
+    "    pass\n",
+    "\n",
+    "# you can call a function in the same cell that you defined it\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Example 3: write a function get_grid that works like this:\n",
+    "# get_grid(5, 3, \"@\") returns the string \n",
+    "# @@@@@\n",
+    "# @@@@@\n",
+    "# @@@@@\n",
+    "\n",
+    "# Let's practice Incremental Coding\n",
+    "# first, try to do this with string operators and literals\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# then, try to do this with variables\n",
+    "width = 5\n",
+    "height = 3\n",
+    "symbol = '#'\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# now, try to write a function \n",
+    "# think about what would be good names for the parameters\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Finally, add in a parameter for a title that appears above the grid\n",
+    "def get_grid_with_title(width, height, symb, title='My Grid'):\n",
+    "    pass"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(get_grid_with_title(7, 7, title='CS220 Grid', symb='&'))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Types of arguments\n",
+    "- positional\n",
+    "- keyword\n",
+    "- default\n",
+    "\n",
+    "Python fills arguments in this order: positional, keyword, "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def add3(x, y = 100, z = 100): \n",
+    "    \"\"\"adds three numbers\"\"\"       #documentation string\n",
+    "    print (\"x = \" + str(x))\n",
+    "    print (\"y = \" + str(y))\n",
+    "    print (\"z = \" + str(z))\n",
+    "    return x + y + z\n",
+    "\n",
+    "addition_of_3 = add3(100, 10, 5)\n",
+    "print(addition_of_3)\n",
+    "# TODO: 1. sum is a bad variable, discuss: why. What would be a better variable name?\n",
+    "# TODO: 2. what type of arguments are 100, 10, and 5?\n",
+    "help(add3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(add3(x = 1, z = 2, y = 5)) #TODO: what type of arguments are these?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "add3(5, 6) # TODO: what type of argument gets filled for the parameter z?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Positional arguments need to be specified before keyword arguments."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Incorrect function call\n",
+    "add3(z = 5, 2, 7) \n",
+    "# TODO: what category of error is this?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Incorrect function definition\n",
+    "# We must specify non-default arguments first\n",
+    "def add3_bad_version(x = 10, y, z): \n",
+    "    \"\"\"adds three numbers\"\"\"              #documentation string\n",
+    "    return x + y + z"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Incorrect function call\n",
+    "add3(5, 3, 10, x = 4)\n",
+    "# TODO: what category of error is this?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# TODO: will this function call work?\n",
+    "add3(y = 5, z = 10)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# TODO: will this function call work?\n",
+    "add3()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## fruitful function versus void function\n",
+    "- fruitful function: returns something\n",
+    "    - ex: add3\n",
+    "- void function: doesn't return anything\n",
+    "    - ex: bad_add3_v1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Example of void function\n",
+    "def bad_add3_v1(x, y, z):\n",
+    "    print(x + y + z)\n",
+    "\n",
+    "print(bad_add3_v1(4, 2, 1))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(bad_add3_v1(4, 2, 1) ** 2) # Cannot apply mathematical operator to None"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### `return` statement is final\n",
+    "- exactly *one* `return` statement gets executed for a function call\n",
+    "- immediately after encountering `return`, function execution terminates"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def bad_add3_v2(x, y, z):\n",
+    "    return x\n",
+    "    return x + y + z      # will never execute\n",
+    "\n",
+    "bad_add3_v2(50, 60, 70)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Tracing\n",
+    "- Try tracing this manually...\n",
+    "- ...then use [PythonTutor](https://pythontutor.com/visualize.html#code=def%20func_c%28%29%3A%0A%20%20%20%20print%28%22C%22%29%0A%0Adef%20func_b%28%29%3A%0A%20%20%20%20print%28%22B1%22%29%0A%20%20%20%20func_c%28%29%0A%20%20%20%20print%28%22B2%22%29%0A%0Adef%20func_a%28%29%3A%0A%20%20%20%20print%28%22A1%22%29%0A%20%20%20%20func_b%28%29%0A%20%20%20%20print%28%22A2%22%29%0A%0Afunc_a%28%29&cumulative=false&heapPrimitives=nevernest&mode=edit&origin=opt-frontend.js&py=3&rawInputLstJSON=%5B%5D&textReferences=false)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def func_c():\n",
+    "    print(\"C\")\n",
+    "\n",
+    "def func_b():\n",
+    "    print(\"B1\")\n",
+    "    func_c()\n",
+    "    print(\"B2\")\n",
+    "\n",
+    "def func_a():\n",
+    "    print(\"A1\")\n",
+    "    func_b()\n",
+    "    print(\"A2\")\n",
+    "\n",
+    "func_a()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Explain worksheet, start part one of each problem\n",
+    "# This worksheet has questions very similar to your exam!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.4"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
-- 
GitLab