From 48903cbb02f6cb04cb47510d0572a0ead3be6777 Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Thu, 1 Feb 2018 16:51:34 +0000
Subject: [PATCH] New prac on function args. In progress

---
 .../function_inputs_and_outputs.ipynb         | 193 ++++++++++++++++++
 .../function_inputs_and_outputs.md            | 112 ++++++++++
 2 files changed, 305 insertions(+)
 create mode 100644 advanced_topics/function_inputs_and_outputs.ipynb
 create mode 100644 advanced_topics/function_inputs_and_outputs.md

diff --git a/advanced_topics/function_inputs_and_outputs.ipynb b/advanced_topics/function_inputs_and_outputs.ipynb
new file mode 100644
index 0000000..335cb06
--- /dev/null
+++ b/advanced_topics/function_inputs_and_outputs.ipynb
@@ -0,0 +1,193 @@
+{
+ "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
+}
diff --git a/advanced_topics/function_inputs_and_outputs.md b/advanced_topics/function_inputs_and_outputs.md
new file mode 100644
index 0000000..0a5ee93
--- /dev/null
+++ b/advanced_topics/function_inputs_and_outputs.md
@@ -0,0 +1,112 @@
+# Function inputs and outputs
+
+
+In Python, arguments to a function can be specified in two different ways - by
+using _positional_ arguments, or by using _keyword_ arguments.
+
+
+## Positional arguments
+
+
+Let's say we have a function that looks like this
+
+
+```
+def myfunc(a, b, c):
+   print('First argument: ', a)
+   print('Second argument:', b)
+   print('Third argument: ', c)
+```
+
+
+If we call this function like so:
+
+
+```
+myfunc(1, 2, 3)
+```
+
+
+The values `1`, `2` and `3` get assigned to arguments `a`, `b`, and `c`
+respectively, based on the position in which they are passed.
+
+
+Python allows us to pass positional arguments into a function from a sequence,
+using the star (`*`) operator. So we could store our arguments in a list or
+tuple, and then pass the list straight in:
+
+```
+args = [3, 4, 5]
+myfunc(*args)
+```
+
+You can think of the star operator as 'unpacking' the contents of the
+sequence.
+
+
+## Keyword arguments
+
+
+Using keyword arguments allows us to pass arguments to a function in any order
+we like.  We could just as easily call our `myfunc` function like so, and get
+the same result that we did earlier when using positional arguments:
+
+
+```
+myfunc(c=3, b=2, a=1)
+```
+
+
+Python has another operator - the double-star (`**`), which will unpack
+keyword arguments from `dict`. For example:
+
+```
+kwargs = {'a' : 4, 'b' : 5, 'c' : 6}
+myfunc(**kwargs)
+```
+
+
+## Combining positional and keyword arguments
+
+
+In fact, we can use both of these techniques at once, like so:
+
+```
+args   = (100, 200)
+kwargs = {'c' : 300}
+
+myfunc(*args, **kwargs)
+```
+
+
+## Default argument values
+
+
+Function arguments can be given default values, like so:
+
+
+```
+myfunc(a=1, b=2, c=3):
+    print('First argument: ', a)
+    print('Second argument:', b)
+    print('Third argument: ', c)
+```
+
+
+Now we can call `myfunc`, only passing the arguments that we need to. The
+arguments which are unspecified in the function call will be assigned their
+default value:
+
+
+```
+myfunc()
+myfunc(10)
+myfunc(10, b=30)
+myfunc(c=300)
+```
+
+
+> Pitfall: mutable argument values
+
+
+You can see here that
-- 
GitLab