{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "municipal-birth",
   "metadata": {},
   "source": [
    "<!--\n",
    "title: Python Programming: Advanced Function Arguments\n",
    "type: lesson\n",
    "duration: \"01:00\"\n",
    "creator: Brandi Butler\n",
    "-->\n",
    "\n",
    "\n",
    "<h1>Python Programming: Advanced Function Arguments</h1>\n",
    "\n",
    "\n",
    "<!--\n",
    "\n",
    "## Overview\n",
    "This lesson starts with a review of the previous function lesson, leading into a few recap exercises. After that, it discusses `*args`, `kwargs`, and default argument values.\n",
    "\n",
    "## Important Notes or Prerequisites\n",
    "- Important Note: They don't know dictionaries yet! We introduce `**kwargs`, but are careful not to phrase it in terms of dictionaries.\n",
    "\n",
    "## Learning Objectives\n",
    "In this lesson, students will:\n",
    "- Use arbitrary numbers of arguments in functions.\n",
    "- Use keyword arguments in functions.\n",
    "- Use default values in functions.\n",
    "\n",
    "## Duration\n",
    "40 minutes\n",
    "\n",
    "\n",
    "## Suggested Agenda\n",
    "\n",
    "| Time | Activity |\n",
    "| --- | --- |\n",
    "| 0:00 - 0:03 | Welcome |\n",
    "| 0:03 - 0:10 | Function Review |\n",
    "| 0:10 - 0:30 | Args / Kwargs |\n",
    "| 0:30 - 0:42 | Other Args |\n",
    "| 0:42 - 0:45 | Summary |\n",
    "\n",
    "## In Class: Materials\n",
    "- Projector\n",
    "- Internet connection\n",
    "- Python3\n",
    "-->\n",
    "\n",
    "\n",
    "---\n",
    "\n",
    "## Lesson Objectives\n",
    "*After this lesson, you will be able to...*\n",
    "\n",
    "* Review all topics to this point.\n",
    "* Use keyword arguments in functions.\n",
    "\n",
    "This lesson will help to answer the following:\n",
    "- What if I want to have a variable number of arguments?\n",
    "- What if I want to have my arguments out of order?\n",
    "- What if I want to specify some arguments but not others?\n",
    "\n",
    "---\n",
    "\n",
    "## Review: Functions\n",
    "\n",
    "Main points:\n",
    "\n",
    "* Define functions using the `def` keyword.\n",
    "* A function must be **called** before the code in it will run!\n",
    "* You will recognize function calls by the `()` at the end.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "alive-cabin",
   "metadata": {},
   "outputs": [],
   "source": [
    "# This part is the function definition!\n",
    "def say_hello():\n",
    "    print(\"hello world!\")\n",
    "\n",
    "# This part is actually calling/running the function!\n",
    "say_hello()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "arctic-learning",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Review: Function Arguments\n",
    "\n",
    "* Provide an argument to a function when you need something small to vary."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eligible-concrete",
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_order(product):\n",
    "    print(\"Thank you for ordering the \" + product + \".\")\n",
    "    print(\"There will be a $5.00 shipping charge for this order.\")\n",
    "\n",
    "print_order(\"Trampoline\")\n",
    "print_order(\"Spider-Man Comic\")\n",
    "print_order(\"Hot Cheetos\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "conditional-minutes",
   "metadata": {},
   "source": [
    "</aside>\n",
    "\n",
    "\n",
    "---\n",
    "\n",
    "## Multiple Parameters\n",
    "\n",
    "Functions can have...\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "interracial-factory",
   "metadata": {},
   "outputs": [],
   "source": [
    "# No parameters\n",
    "def add_2_and_3():\n",
    "    x = 2 + 3\n",
    "    print(x)\n",
    "\n",
    "# One parameter\n",
    "def add_2(x):\n",
    "    print(x + 2)\n",
    "\n",
    "# Multiple parameters\n",
    "def add(x, y, z):\n",
    "    print(x + y + z)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "applicable-zealand",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Discussion: Print vs Return\n",
    "\n",
    "Why doesn't this do anything?\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "former-expansion",
   "metadata": {},
   "outputs": [],
   "source": [
    "def add(x, y, z):\n",
    "    return x + y + z\n",
    "\n",
    "add(1, 2, 3) # does nothing (unless you're in jupyter)!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "enormous-distance",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## We Do: Review Exercises\n",
    "\n",
    "- We'll define a function named `are_both_even`.\n",
    "\n",
    "- It will accept two parameters: `num1` and `num2`.\n",
    "\n",
    "- Inside the function, we'll return `True` if `num1` and `num2` are both even but `False` if they are not.\n",
    "\n",
    "- We'll test this with `print(are_both_even(1, 4))`, `print(are_both_even(2, 4))`, and `print(are_both_even(2, 3))`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "neutral-cannon",
   "metadata": {},
   "outputs": [],
   "source": [
    "# function definition\n",
    "\n",
    "\n",
    "\n",
    "print(are_both_even(1, 4)) # False\n",
    "print(are_both_even(2, 4)) # True\n",
    "print(are_both_even(2, 3)) # False"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "elect-blank",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## We Do: Another Review Exercise!\n",
    "\n",
    "We'll define another function named `light_or_dark` that takes the parameter `hour`.\n",
    "\n",
    "- If `hour` is greater than 24, the function will print \"That's not an hour in the day!\" and **return nothing.**\n",
    "\n",
    "- If `hour` is less than 7 or greater than 17, the function will return \"It's dark outside!\"\n",
    "\n",
    "- Otherwise, the function will return \"It's light outside!\"\n",
    "\n",
    "- We'll test this with `print(light_or_dark(4))`,  `print(light_or_dark(26))`, and `print(light_or_dark(`10`))`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "relevant-excellence",
   "metadata": {},
   "outputs": [],
   "source": [
    "# funtion definition\n",
    "\n",
    "\n",
    "\n",
    "print(light_or_dark(4)) # \"It's dark outside!\"\n",
    "print(light_or_dark(26)) # \"That's not an hour in the day!\"\n",
    "print(light_or_dark(10)) # \"It's light outside!\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "industrial-instrument",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Discussion: Arguments\n",
    "\n",
    "Now, let's make functions a little more sophisticated.\n",
    "\n",
    "What do you think the following code does?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "impressive-private",
   "metadata": {},
   "outputs": [],
   "source": [
    "def multiply(x, y):\n",
    "    print(x * y)\n",
    "\n",
    "multiply(1, 2, 3) # Too many arguments! What happens?\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "hired-conjunction",
   "metadata": {},
   "source": [
    "\n",
    "What if we want all of these to work?\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "miniature-builder",
   "metadata": {},
   "outputs": [],
   "source": [
    "def multiply(x, y):\n",
    "    print(x * y)\n",
    "\n",
    "multiply(4, 5, 6)\n",
    "multiply(4, 5)\n",
    "multiply(4, 5, 2, 7, 3, 9)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "proved-breach",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Introducing `*args`\n",
    "\n",
    "`*args` is a parameter that says \"Put as many parameters as you'd like!\"\n",
    "\n",
    "- Pronounced like a pirate - \"arrrrghhhs!\"\n",
    "- Known as **positional arguments**\n",
    "- The `*` at the beginning is what specifies the variable number of arguments\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "yellow-riding",
   "metadata": {},
   "outputs": [],
   "source": [
    "def multiply(*args):\n",
    "    product = 1\n",
    "\n",
    "    # We don't know the number of args, so we need a loop\n",
    "    for num in args:\n",
    "        product *= num\n",
    "    print(product)\n",
    "\n",
    "multiply(4, 5, 6) # Prints 120!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "negative-multiple",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## We Do: `*args`\n",
    "\n",
    "- We'll write a function, `sum_everything` that takes any numbers of arguments and adds them together.\n",
    "- At the end, we'll print out the sum.\n",
    "- Let's try it with `sum_everything(4, 5, 6)` and `sum_everything(6, 4, 5)`. The order doesn't matter!\n",
    "- `*args` says \"any number\" - you can pass in none at all!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "italian-stability",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "\n",
    "sum_everything(4, 5, 6)\n",
    "sum_everything(6, 4, 5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "vertical-tourism",
   "metadata": {},
   "source": [
    "\n",
    "</aside>\n",
    "\n",
    "---\n",
    "\n",
    "## Discussion: Often, Order Does Matter.\n",
    "\n",
    "Let's switch gears. Back to a set number of arguments!\n",
    "\n",
    "Check this out:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "secondary-creek",
   "metadata": {},
   "outputs": [],
   "source": [
    "def triple_divide(x, y, z):\n",
    "    print(x / y / z)\n",
    "\n",
    "triple_divide(1, 2, 10) # Prints 0.05"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "valued-testament",
   "metadata": {},
   "source": [
    "Without otherwise specifying, `x` is `1`, `y` is `2`, and `z` is `10`.\n",
    "\n",
    "- What if we want `x`, the first parameter to get the value `10`?\n",
    "- Is there a way to specify which argument goes to which parameter?\n",
    "\n",
    "---\n",
    "\n",
    "## Forcing the Order\n",
    "\n",
    "Here we've forced the order to be reversed from the default. In fact, we can specify any ordering we want by using the names of the parameters (keywords) when providing the argument values.\n",
    "\n",
    "<iframe height=\"400px\" width=\"100%\" src=\"https://repl.it/@GAcoding/02-Python-Kwargs-09?lite=true\" scrolling=\"no\" frameborder=\"no\" allowtransparency=\"true\" allowfullscreen=\"true\" sandbox=\"allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-modals\"></iframe>\n",
    "\n",
    "Take a moment to play around with the values until you really believe it!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "miniature-gathering",
   "metadata": {},
   "outputs": [],
   "source": [
    "def triple_divide(x, y, z):\n",
    "    print(x / y / z)\n",
    "\n",
    "triple_divide(z=1, y=2, x=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "upper-telescope",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Keyword Arguments (kwargs)\n",
    "\n",
    "Using kwargs, odrer deons't mtater:\n",
    "\n",
    "- Arguments are named according to their corresponding parameters.\n",
    "- Order doesn't matter - Python will check the names and match them!\n",
    "- Values are assigned because the *keyword argument* and the *parameter name* match."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "awful-stylus",
   "metadata": {},
   "outputs": [],
   "source": [
    "def triple_divide(x, y, z):\n",
    "    print(x / y / z)\n",
    "\n",
    "triple_divide(x=10, y=2, z=1)\n",
    "# This runs 10 / 2 / 1, and prints 5\n",
    "triple_divide(y=2, z=1, x=10)\n",
    "# This ALSO runs 10 /  2 / 1, and prints 5."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "editorial-arabic",
   "metadata": {},
   "source": [
    "\n",
    "> **Protip**: Keep your parameter names simple and concise to prevent typos and misspellings!\n",
    "\n",
    "- In normal cases for function args a default order is assumed. Much in the same way, if you go to a restaurant, by default you will get drinks, then appetizers, then entrees, then desserts. However, you are free to ask your waiter to bring your dessert first or bring your appetizer with the meal. You don't need to specify anything if the default order will do, but if you are going to reinvent dinner order, you will need to say something!\n",
    "\n",
    "---\n",
    "\n",
    "## Mix It Up....  but Not With Every Argument?\n",
    "\n",
    "Fun fact: You can provide some args in order - **positional** - and some with keywords.\n",
    "\n",
    "- Undefined are assigned in sequential order.\n",
    "- Keywords have to come last! - then, in any order.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "copyrighted-tennessee",
   "metadata": {},
   "outputs": [],
   "source": [
    "def dinner(drink, app, main_course, dessert):\n",
    "    print(\"You're drinking\", drink)\n",
    "    print(\"You're snacking on\", app)\n",
    "    print(\"You're drinking\", main_course)\n",
    "    print(\"You're wrapping up with\", dessert)\n",
    "\n",
    "# all keyword arguments\n",
    "dinner(app=\"chicken wings\", main_course=\"steak\", drink=\"water\", dessert=\"milkshake\")\n",
    "print()\n",
    "\n",
    "# mix of positional and keyword arguments\n",
    "dinner(\"water\", \"nachos\", dessert=\"cake\", main_course=\"steak\")\n",
    "print()\n",
    "\n",
    "# mix of positional and keyword arguments; note the order of the output\n",
    "dinner(\"chicken wings\", \"water\", dessert=\"milkshake\", main_course=\"medium steak\")\n",
    "print()\n",
    "\n",
    "# what happens when you put a keyword argument before a positional argument?\n",
    "# dinner(main_course= \"steak\", \"nachos\", \"water\", dessert=\"cake\")\n",
    "\n",
    "# what happens when you repeat a keyword argument?\n",
    "# dinner(app=\"nachos\", app=\"steak\", app=\"water\", dessert=\"cake\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "extraordinary-extra",
   "metadata": {},
   "source": [
    "</aside>\n",
    "\n",
    "___\n",
    "\n",
    "## Quick Review\n",
    "\n",
    "`*args`: Any number of arguments - even 0! - can be passed in.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "finite-sunrise",
   "metadata": {},
   "outputs": [],
   "source": [
    "def sum_everything(*args):\n",
    "    total = 0\n",
    "\n",
    "    for num in args:\n",
    "        total += num\n",
    "    print(total)\n",
    "\n",
    "sum_everything(4, 5, 6) # Prints 15"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "numerical-timothy",
   "metadata": {},
   "source": [
    "\n",
    "Keyword arguments (kwargs): Arguments can be passed in out of order.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "opposed-nowhere",
   "metadata": {},
   "outputs": [],
   "source": [
    "def divide(first, second, third):\n",
    "    print(first / second / third)\n",
    "\n",
    "divide(first=10, second=2, third=1)\n",
    "divide(second=2, third=1, first=10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "collective-statement",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Discussion: Variable Numbers of Kwargs?\n",
    "\n",
    "What if I go to Froyo? I need:\n",
    "\n",
    "- One argument `spoon`, to pick a spoon size.\n",
    "- A variable number of arguments for all the flavors of frozen yogurt I might eat!\n",
    "\n",
    "`def yogurt_land(*args)`?\n",
    "\n",
    "- No! `*args` won't work - we need to know which arg is the spoon.\n",
    "\n",
    "`def yogurt_land(spoon, froyo)`?\n",
    "\n",
    "- No! We don't know the number of froyo arguments.\n",
    "\n",
    "___\n",
    "\n",
    "## Introducing: `**kwargs`\n",
    "\n",
    "The `*` in `*args` means: Any  number of arguments.\n",
    "\n",
    "Let's add `**` to our kwargs: `**kwargs` can take a variable number of arguments. Note the double `**`!\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "actual-brooklyn",
   "metadata": {},
   "outputs": [],
   "source": [
    "def yogurt_land(spoon, **kwargs):\n",
    "    print(spoon)\n",
    "    # We need a loop, because we don't know how many kwargs there are.\n",
    "    for keyword, flavor in kwargs.items():\n",
    "    # kwargs.items has the keyword and the value, which we're calling \"flavor\" in the loop.\n",
    "        print(\"My\", keyword, \"is a\", flavor)\n",
    "\n",
    "# Like before, the unnamed arg has to come first!\n",
    "yogurt_land(\"large!\", first_froyo=\"vanilla\", second_froyo=\"chocolate\", third_froyo=\"banana\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bulgarian-yorkshire",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## We Do: 4 Froyos\n",
    "\n",
    "* Can we subtract one of the froyos?\n",
    "* Where is my 4th froyo?\n",
    "* What if I drop all my froyos on the ground? (No kwargs)\n",
    "* Can I skip the drink or spoon positional arguments?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "accredited-pendant",
   "metadata": {},
   "outputs": [],
   "source": [
    "def yogurt_land(drink, spoon, **kwargs):\n",
    "    if spoon:\n",
    "        print(\"Here is your spoon!\")\n",
    "\n",
    "    else:\n",
    "        print(\"No spoon, no worries\")\n",
    "\n",
    "    print(\"Here is your\", drink)\n",
    "\n",
    "    for keyword, flavor in kwargs.items():\n",
    "        print(\"My\", keyword, \"is a\", flavor)\n",
    "\n",
    "\n",
    "yogurt_land(\"water\", \"large\", first_froyo=\"vanilla\", second_froyo=\"chocolate\", third_froyo=\"banana\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "allied-glasgow",
   "metadata": {},
   "source": [
    "</aside>\n",
    "\n",
    "---\n",
    "\n",
    "## Quick Review of Useful Argument Types:\n",
    "\n",
    "At this point, we have `*args`, `kwargs` and `**kwargs`:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "center-thesis",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Args: Any number of arguments:\n",
    "def multiply(*args):\n",
    "    product = 1\n",
    "    for num in args:\n",
    "        product *= num\n",
    "\n",
    "multiply(4, 5, 6)\n",
    "\n",
    "# Kwargs: Named (keyword) arguments\n",
    "def triple_divide(x, y, z):\n",
    "    print(x / y / z)\n",
    "\n",
    "triple_divide(x=10, y=2, z=1)\n",
    "\n",
    "# **Kwargs: Any number of Kwargs\n",
    "def my_froyo(spoon, **kwargs):\n",
    "    for froyo, flavor in kwargs.items():\n",
    "        print(froyo, \"is a\", flavor)\n",
    "\n",
    "my_froyo(\"large!\", froyo1=\"vanilla\", froyo2=\"chocolate\", froyo3=\"banana\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "downtown-whole",
   "metadata": {},
   "source": [
    "\n",
    "---\n",
    "\n",
    "## Discussion: Printing\n",
    "\n",
    "`print` is a function! That's why it has parentheses!\n",
    "- It's built into Python, so you don't have to define it. You can just use it.\n",
    "\n",
    "When printing, commas automatically add spaces:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "reported-charger",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"Hi!\", \"Vanilla,\", \"please.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "efficient-fitting",
   "metadata": {},
   "source": [
    "But since `print` is a function, too - do you think there's anything we can do to change those spaces to something else?\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "agricultural-elimination",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Hi!-and-Vanilla,-and-please.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "secondary-tactics",
   "metadata": {},
   "source": [
    "\n",
    "</aside>\n",
    "\n",
    "---\n",
    "\n",
    "## Quick Review\n",
    "\n",
    "So  far, we've learned:\n",
    "\n",
    "- `*args`:\n",
    "    - ​A variable number of function arguments.\n",
    "- kwargs:\n",
    "    - ​A set number of function arguments.\n",
    "    - Can be defined out of order\n",
    "- `**kwargs`:\n",
    "    - Any number of positional arguments.\n",
    "- `sep` in print.\n",
    "\n",
    "There's one more: Optional parameters.\n",
    "\n",
    "---\n",
    "\n",
    "## Optional Parameters with Default Values\n",
    "\n",
    "This idea exists in programming - you've already seen it!\n",
    "\n",
    "The default value for `sep` in `print` is `\" \"`. You don't **need** to include it.\n",
    "\n",
    "This makes it optional! **Optional parameters** have default values, so you don't need to include them.\n",
    "\n",
    "- Only include them if you want to change them!\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "continued-rating",
   "metadata": {},
   "outputs": [],
   "source": [
    "name = 'Carl'\n",
    "dessert = 'cake'\n",
    "\n",
    "# Here, `sep` is optional to include. It defaults to a space \" \".\n",
    "print(\"Hello\", \"my\", \"name\", \"is\", name, \"and\", \"I\", \"enjoy\", dessert, \":)\")\n",
    "\n",
    "# But we can include it, if we want, and `sep` will use our value instead of the space.\n",
    "print(\"Hello\", \"my\", \"name\", \"is\", name, \"and\", \"I\", \"enjoy\", dessert, \":)\", sep=\" HELLO \")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "sorted-atlantic",
   "metadata": {},
   "source": [
    "\n",
    "Default parameters are in the *function declaration*.\n",
    "\n",
    "They're there if you don't include a value.\n",
    "\n",
    "---\n",
    "\n",
    "\n",
    "## Any Functions: Optional Parameters with Default Values\n",
    "\n",
    "These can be added to any functions.\n",
    "\n",
    "Here, `c` has a default of `20`. We don't need to include it!\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "positive-virtue",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Optional parameters: Default values are only used if needed.\n",
    "def my_func(a, b, c=20):\n",
    "    print(a + b + c)\n",
    "my_func(1, 2)\n",
    "# Uses the default! Prints 23.\n",
    "my_func(1, 2, 4)\n",
    "# Overrides the default! Prints 7."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "published-atmosphere",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Partner Exercise: Poke At It!\n",
    "\n",
    "Pair up! Choose a driver and a navigator.\n",
    "\n",
    "- Write a function, `print_food` that has four optional parameters (all with defaults of your choice): `favorite_food`, `lunch_today`, `lunch_yesterday`, and `breakfast`.\n",
    "\n",
    "`print_food` should print out each of these.\n",
    "\n",
    "Call this with a couple different arguments:\n",
    "\n",
    "- No arguments.\n",
    "- All arguments - a regular function call.\n",
    "- 2 keyword arguments. Give all four arguments, but use a keyword for `lunch_yesterday` and `breakfast`.\n",
    "- All keyword arguments - out of order."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "beautiful-queen",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "incorporate-westminster",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Optional Practice: Keep Poking!\n",
    "\n",
    "Underneath `print_food`, rewrite it, twice.\n",
    "\n",
    "First, write `print_food_args`, using `*args` as the parameter. Start the function by printing `args`, so you can see what's going on. Then, print the values you pass in.\n",
    "\n",
    "Then, write `print_food_kwargs`, using `**kwargs` as the parameter. Start the function by printing `kwargs`, so you can see what's going on. Then, as above, print the values you pass in."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "agreed-fiber",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "horizontal-possession",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "## Summary + Q&A\n",
    "\n",
    "- `*args`:\n",
    "    - ​A variable number of function arguments.\n",
    "    - Taken in any order.\n",
    "    - `def multiply(*args):`\n",
    "- kwargs:\n",
    "    - ​A set number of function arguments.\n",
    "    - Can be defined out of order\n",
    "    - `my_func(a=1, b=2, c=3)`\n",
    "- `**kwargs`:\n",
    "    ​- Any number of positional arguments.\n",
    "    - `def froyo(*kwargs)`\n",
    "- sep in print.\n",
    "- Optional parameters:\n",
    "    - Default values in the function declaration\n",
    "    - `def my_func(a=10, b=15, c=20)`\n",
    "\n",
    "---\n",
    "\n",
    "## Additional Resources\n",
    "\n",
    "* [Optional Parameter Repl.it](https://repl.it/@GAcoding/python-programming-optional-parameters)\n",
    "* [Keyword Args](http://treyhunner.com/2018/04/keyword-arguments-in-python/)\n",
    "* [Args and Kwargs](https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3)\n",
    "* [Defining Functions](https://docs.python.org/3/tutorial/controlflow.html#more-on-defining-functions)"
   ]
  }
 ],
 "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.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
