{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Function inputs and outputs\n",
    "\n",
    "\n",
    "In Python, arguments to a function can be specified in two different ways - by\n",
    "using _positional_ arguments, or by using _keyword_ arguments.\n",
    "\n",
    "\n",
    "## Positional arguments\n",
    "\n",
    "\n",
    "Let's say we have a function that looks like this"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def myfunc(a, b, c):\n",
    "   print('First argument: ', a)\n",
    "   print('Second argument:', b)\n",
    "   print('Third argument: ', c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If we call this function like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "myfunc(1, 2, 3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The values `1`, `2` and `3` get assigned to arguments `a`, `b`, and `c`\n",
    "respectively, based on the position in which they are passed.\n",
    "\n",
    "\n",
    "Python allows us to pass positional arguments into a function from a sequence,\n",
    "using the star (`*`) operator. So we could store our arguments in a list or\n",
    "tuple, and then pass the list straight in:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "args = [3, 4, 5]\n",
    "myfunc(*args)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can think of the star operator as 'unpacking' the contents of the\n",
    "sequence.\n",
    "\n",
    "\n",
    "## Keyword arguments\n",
    "\n",
    "\n",
    "Using keyword arguments allows us to pass arguments to a function in any order\n",
    "we like.  We could just as easily call our `myfunc` function like so, and get\n",
    "the same result that we did earlier when using positional arguments:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "myfunc(c=3, b=2, a=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python has another operator - the double-star (`**`), which will unpack\n",
    "keyword arguments from `dict`. For example:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "kwargs = {'a' : 4, 'b' : 5, 'c' : 6}\n",
    "myfunc(**kwargs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Combining positional and keyword arguments\n",
    "\n",
    "\n",
    "In fact, we can use both of these techniques at once, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "args   = (100, 200)\n",
    "kwargs = {'c' : 300}\n",
    "\n",
    "myfunc(*args, **kwargs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Default argument values\n",
    "\n",
    "\n",
    "Function arguments can be given default values, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "myfunc(a=1, b=2, c=3):\n",
    "    print('First argument: ', a)\n",
    "    print('Second argument:', b)\n",
    "    print('Third argument: ', c)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can call `myfunc`, only passing the arguments that we need to. The\n",
    "arguments which are unspecified in the function call will be assigned their\n",
    "default value:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "myfunc()\n",
    "myfunc(10)\n",
    "myfunc(10, b=30)\n",
    "myfunc(c=300)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> Pitfall: mutable argument values\n",
    "\n",
    "\n",
    "You can see here that"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}