diff --git a/README.md b/README.md
index d813869c8a340295603a772dcc166ecac3bebe8d..7345fecf93ace469895810a4f2627e2e1e90e635 100644
--- a/README.md
+++ b/README.md
@@ -65,7 +65,7 @@ The top-level directory contains materials for the following lessons:
 8. Object-oriented programming ([slides][lesson_08])
 9. A sip of Biopython ([notebook 1][lesson_09_01], [notebook 2][lesson_09_02])
 
-[lesson_01]: http://nbviewer.ipython.org/urls/git.lumc.nl/courses/programming-course/raw/master/01%20-%20Welcome.ipynb
+[lesson_01]: http://nbviewer.ipython.org/urls/git.lumc.nl/courses/programming-course/raw/master/introduction/01_welcome.ipynb
 [lesson_02_01]: http://nbviewer.ipython.org/urls/git.lumc.nl/courses/programming-course/raw/master/02%20-%20Introduction%20to%20Python%20(1).ipynb
 [lesson_02_02]: http://nbviewer.ipython.org/urls/git.lumc.nl/courses/programming-course/raw/master/02%20-%20Introduction%20to%20Python%20(2).ipynb
 [lesson_02_03]: http://nbviewer.ipython.org/urls/git.lumc.nl/courses/programming-course/raw/master/02%20-%20Introduction%20to%20Python%20(3).ipynb
diff --git a/introduction/01_welcome.ipynb b/introduction/01_welcome.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..dd1d9299576d53ebcf61b793e928a0822ca8b724
--- /dev/null
+++ b/introduction/01_welcome.ipynb
@@ -0,0 +1,240 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "<span style=\"font-size: 200%\">Programming in Python</span>\n",
+    "===\n",
+    "\n",
+    "<br>\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "About the course\n",
+    "===\n",
+    "\n",
+    "* Aimed at PhD students, Postdocs, researchers, analysts, ...\n",
+    "* Programming as a tool to do your research.\n",
+    "* Slightly focussed on bioinformatics.\n",
+    "\n",
+    "**Note:** This is its third session."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Teachers\n",
+    "===\n",
+    "\n",
+    "* Jeroen Laros<br>\n",
+    "  [j.f.j.laros@lumc.nl](mailto:j.f.j.laros@lumc.nl)\n",
+    "\n",
+    "\n",
+    "* Mihai Lefter<br>\n",
+    "  [m.lefter@lumc.nl](mailto:m.lefter@lumc.nl)\n",
+    "\n",
+    "\n",
+    "* Jonathan Vis<br>\n",
+    "  [j.k.vis@lumc.nl](mailto:j.k.vis@lumc.nl)\n",
+    "\n",
+    "\n",
+    "* Mark Santcroos<br>\n",
+    "  [m.a.santcroos@lumc.nl](mailto:m.a.santcroos@lumc.nl)\n",
+    "\n",
+    "\n",
+    "* Guy Allard<br>\n",
+    "  [w.g.Allard@lumc.nl](mailto:w.g.allard@lumc.nl)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Program\n",
+    "===\n",
+    "\n",
+    "| Day             | Time  | Lesson                              | Teacher  | \n",
+    "|-----------------|-------|------------------------------------ |----------|\n",
+    "| Monday, 18/9    | 9-10  | Welcome, Introduction to Python (1) | Mihai    | \n",
+    "|                 | 10-11 | Introduction to Python (2)          | Jeroen   |  \n",
+    "|                 | 11-12 | Introduction to Python (3)          | Mihai    | \n",
+    "|                 | 12-13 | Practical help                      |          | \n",
+    "| Tuesday, 19/9   | 9-10  | Assignments review                  |          |\n",
+    "|                 | 10-11 | More Python Goodness (1)            | Mihai    | \n",
+    "|                 | 11-12 | More Python Goodness (2)            | Mihai    | \n",
+    "|                 | 12-13 | IPython Notebook                    | Mark     | \n",
+    "| Wednesday, 20/9 | 9-10  | Assignments review                  |          | \n",
+    "|                 | 10-11 | Data manipulation (NumPy, Pandas)   | Mark     | \n",
+    "|                 | 11-12 | Data visualisation (1)              | Guy      | \n",
+    "|                 | 12-13 | Data visualisation (2)              | Guy      | \n",
+    "| Thursday, 21/9  | 9-10  | Assignments review                  |          | \n",
+    "|                 | 10-11 | Object-oriented programming         | Jonathan | \n",
+    "|                 | 11-12 | Biopython                           | Guy      | \n",
+    "|                 | 12-13 | Putting everything together         | Jeroen   |\n",
+    "\n",
+    "All slides are linked as one-page documents from the course website: [https://git.lumc.nl/courses/programming-course](https://git.lumc.nl/courses/programming-course)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Software requirements\n",
+    "===\n",
+    "\n",
+    "* Anaconda\n",
+    "    * Python 2.7\n",
+    "    * NumPy, matplotlib, Biopython\n",
+    "* Git\n",
+    "\n",
+    "Anaconda installation instructions [here](https://docs.anaconda.com/anaconda/install/)."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Exercises\n",
+    "===\n",
+    "\n",
+    "You only learn programming by doing it.\n",
+    "\n",
+    "* Have your laptop open during the lessons.\n",
+    "* Repeat the code from the slides, play around with it.\n",
+    "* Do the exercises.\n",
+    "* There will be a few assignments to submit."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Getting help\n",
+    "===\n",
+    "\n",
+    "* Ask a teacher.\n",
+    "* If it's private, mail one of the teachers.\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "skip"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<style>/* Remove the vertical scrollbar added by nbconvert. */\n",
+       ".reveal {\n",
+       "  overflow: hidden;\n",
+       "}\n",
+       "\n",
+       "/* Workaround some highlight.js bugs in language autodetection. */\n",
+       "code.objectivec *,\n",
+       "code.perl *,\n",
+       "code.cs *,\n",
+       "code.javascript *,\n",
+       "code.http * {\n",
+       "  color: black ! important;\n",
+       "  font-weight: normal ! important;\n",
+       "}\n",
+       "span.title {\n",
+       "  color: black ! important;\n",
+       "}\n",
+       "span.tag {\n",
+       "  color: black ! important;\n",
+       "}\n",
+       "span.attribute {\n",
+       "  color: black ! important;\n",
+       "}\n",
+       "</style>"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML object>"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from IPython.display import HTML\n",
+    "def css_styling():\n",
+    "    styles = open('../styles/custom.css', 'r').read()\n",
+    "    return HTML('<style>' + styles + '</style>')\n",
+    "css_styling()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "License: [Creative Commons Attribution 3.0 License (CC-by)](http://creativecommons.org/licenses/by/3.0)\n"
+   ]
+  }
+ ],
+ "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.5.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/introduction/02_introduction_to_python_1.ipynb b/introduction/02_introduction_to_python_1.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..4a01e69444ff586a2851aa1f8ae5eb9dc2ef0851
--- /dev/null
+++ b/introduction/02_introduction_to_python_1.ipynb
@@ -0,0 +1,940 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "<span style=\"font-size: 200%\">Introduction to Python (1)</span>\n",
+    "===\n",
+    "\n",
+    "<br>\n",
+    "\n",
+    "[Martijn Vermaat](mailto:m.vermaat.hg@lumc.nl), [Department of Human Genetics, Leiden University Medical Center](http://humgen.nl)\n",
+    "\n",
+    "[Jeroen Laros](mailto:j.f.j.laros@lumc.nl), [Department of Human Genetics, Leiden University Medical Center](http://humgen.nl)\n",
+    "\n",
+    "Based on: [Python Scientific Lecture Notes](http://scipy-lectures.github.io/)\n",
+    "\n",
+    "License: [Creative Commons Attribution 3.0 License (CC-by)](http://creativecommons.org/licenses/by/3.0)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "About Python\n",
+    "===\n",
+    "\n",
+    "History\n",
+    "---\n",
+    "\n",
+    "* Created early 90's by Guido van Rossem at CWI.\n",
+    "* General purpose, high-level programming language.\n",
+    "* Design is driven by code readability."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "About Python\n",
+    "===\n",
+    "\n",
+    "Features\n",
+    "---\n",
+    "\n",
+    "* Interpreted, no separate compilation step needed.\n",
+    "* Imperative and object-oriented programming (and some functional programming).\n",
+    "* Dynamic type system.\n",
+    "* Automatic memory management.\n",
+    "\n",
+    "We'll come back to most of this."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "About Python\n",
+    "===\n",
+    "\n",
+    "Why Python?\n",
+    "---\n",
+    "\n",
+    "* Readable and low barrier to entry.\n",
+    "* Rich scientific libraries.\n",
+    "* Many other libraries available.\n",
+    "* Widely used with a large community."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "About Python\n",
+    "===\n",
+    "\n",
+    "Python 2 versus Python 3\n",
+    "---\n",
+    "\n",
+    "* Python 3 is backwards incompatible.\n",
+    "* Some libraries don't support it yet.\n",
+    "* Python 2.7 is the last Python 2.\n",
+    "* Some Python 3 features are backported in Python 2.7.\n",
+    "* Default Python on most distributions is Python 2.7.\n",
+    "\n",
+    "We use Python 2.7 for the time being."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Running Python code\n",
+    "===\n",
+    "\n",
+    "Two main ways of writing and executing Python code.\n",
+    "\n",
+    "Interactively\n",
+    "---\n",
+    "\n",
+    "* Statement by statement directly in the interpreter.\n",
+    "\n",
+    "Non-interactively\n",
+    "---\n",
+    "\n",
+    "* By editing in a file and running the code afterwards."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "We'll start with the first option."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Running Python code\n",
+    "===\n",
+    "\n",
+    "The standard Python interpreter\n",
+    "---\n",
+    "\n",
+    "Start it by typing `python` on the command line:\n",
+    "\n",
+    "    $ python\n",
+    "    Python 2.7.3 (default, Jan  2 2013, 13:56:14) \n",
+    "    [GCC 4.7.2] on linux2\n",
+    "    Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n",
+    "    >>>\n",
+    "\n",
+    "* It shows an interpreter prompt.\n",
+    "* You can give it Python code to interpret."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Running Python code\n",
+    "===\n",
+    "\n",
+    "The IPython interpreter\n",
+    "---\n",
+    "\n",
+    "* Similar to the standard Python interpreter, but with\n",
+    "* syntax highlighting,\n",
+    "* tab completion,\n",
+    "* cross-session history, etcetera...\n",
+    "\n",
+    "Start it by typing `ipython` on the command line:\n",
+    "\n",
+    "    $ ipython\n",
+    "    Python 2.7.3 (default, Jan  2 2013, 13:56:14) \n",
+    "    Type \"copyright\", \"credits\" or \"license\" for more information.\n",
+    "\n",
+    "    IPython 0.13.1 -- An enhanced Interactive Python.\n",
+    "    ?         -> Introduction and overview of IPython's features.\n",
+    "    %quickref -> Quick reference.\n",
+    "    help      -> Python's own help system.\n",
+    "    object?   -> Details about 'object', use 'object??' for extra details.\n",
+    "\n",
+    "    In [1]:"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "From now on, play along in your own IPython interpreter."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Python as a calculator\n",
+    "===\n",
+    "\n",
+    "Integers\n",
+    "---"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "17"
+      ]
+     },
+     "execution_count": 1,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "17"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "42"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "(17 + 4) * 2"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Python as a calculator\n",
+    "===\n",
+    "\n",
+    "Floating point numbers\n",
+    "---"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "55.5"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "3.2 * 18 - 2.1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7.2"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "36. / 5"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Scientific notation:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1.3e+20"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "1.3e20 + 2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1.3e+20"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "1.3 * 10**20"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Python as a calculator\n",
+    "===\n",
+    "\n",
+    "The division operator\n",
+    "---"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "35 / 5"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "36 / 5"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Division is a bit weird: if you give it integer arguments, the result will also be an integer."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Python as a calculator\n",
+    "===\n",
+    "\n",
+    "The division operator\n",
+    "---"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "35 / 5"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "36 / 5"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Solution 1\n",
+    "---\n",
+    "\n",
+    "Give floating point arguments instead of integer arguments."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7.2"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "36. / 5."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Python as a calculator\n",
+    "===\n",
+    "\n",
+    "The division operator\n",
+    "---"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "35 / 5"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "36 / 5"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Solution 2\n",
+    "---\n",
+    "\n",
+    "From Python 3 onwards, division behaves differently. You can actually get that behaviour in Python 2.7:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7.2"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from __future__ import division\n",
+    "36 / 5"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Python as a calculator\n",
+    "===\n",
+    "\n",
+    "Variables\n",
+    "---\n",
+    "\n",
+    "* We can use names to reference values (variables).\n",
+    "* No need to declare them first or define the type."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "a = 1.3e20"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1.3e+20"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "a"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2.84e+20"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "b = a + 1.2e19\n",
+    "b * 2"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Python's type system (1/2)\n",
+    "===\n",
+    "\n",
+    "Every value has a type, view it using `type`:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "int"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "type(27)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "float"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "type(3.0 * 2.7)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "float"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "type(a)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Another example of a builtin datatype is `str`, we'll see more later:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "str"
+      ]
+     },
+     "execution_count": 21,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "type('I am a homo sapiens')"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Python's type system (2/2)\n",
+    "===\n",
+    "\n",
+    "Some operations are defined on more than one type, possibly with different meanings."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "'beerbeerbeerbeerbeerwhiskey'"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "'beer' * 5 + 'whiskey'"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Dynamic typing means that variables can be assigned values of different types during runtime."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "str"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "a = 'spezi'\n",
+    "type(a)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Python is strongly typed, meaning that operations on values with incompatible types are forbidden."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "TypeError",
+     "evalue": "cannot concatenate 'str' and 'int' objects",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
+      "\u001b[1;32m<ipython-input-24-ec918fbfdf41>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;34m'beer'\u001b[0m \u001b[1;33m+\u001b[0m \u001b[1;36m34\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
+      "\u001b[1;31mTypeError\u001b[0m: cannot concatenate 'str' and 'int' objects"
+     ]
+    }
+   ],
+   "source": [
+    "'beer' + 34"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "skip"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/html": [
+       "<style>/* Remove the vertical scrollbar added by nbconvert. */\n",
+       ".reveal {\n",
+       "  overflow: hidden;\n",
+       "}\n",
+       "\n",
+       "/* Workaround some highlight.js bugs in language autodetection. */\n",
+       "code.objectivec *,\n",
+       "code.perl *,\n",
+       "code.cs *,\n",
+       "code.javascript *,\n",
+       "code.http * {\n",
+       "  color: black ! important;\n",
+       "  font-weight: normal ! important;\n",
+       "}\n",
+       "span.title {\n",
+       "  color: black ! important;\n",
+       "}\n",
+       "span.tag {\n",
+       "  color: black ! important;\n",
+       "}\n",
+       "span.attribute {\n",
+       "  color: black ! important;\n",
+       "}\n",
+       "</style>"
+      ],
+      "text/plain": [
+       "<IPython.core.display.HTML at 0x3463a50>"
+      ]
+     },
+     "execution_count": 1,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from IPython.display import HTML\n",
+    "def css_styling():\n",
+    "    styles = open('styles/custom.css', 'r').read()\n",
+    "    return HTML('<style>' + styles + '</style>')\n",
+    "css_styling()"
+   ]
+  }
+ ],
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "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.5.2"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 1
+}
diff --git a/02 - Introduction to Python (2).ipynb b/introduction/02_introduction_to_python_2.ipynb
similarity index 100%
rename from 02 - Introduction to Python (2).ipynb
rename to introduction/02_introduction_to_python_2.ipynb
diff --git a/02 - Introduction to Python (3).ipynb b/introduction/02_introduction_to_python_3.ipynb
similarity index 100%
rename from 02 - Introduction to Python (3).ipynb
rename to introduction/02_introduction_to_python_3.ipynb
diff --git a/01 - Welcome.ipynb b/past_sessions/2014_july/01 - Welcome.ipynb
similarity index 100%
rename from 01 - Welcome.ipynb
rename to past_sessions/2014_july/01 - Welcome.ipynb
diff --git a/02 - Introduction to Python (1).ipynb b/past_sessions/2014_july/02 - Introduction to Python (1).ipynb
similarity index 100%
rename from 02 - Introduction to Python (1).ipynb
rename to past_sessions/2014_july/02 - Introduction to Python (1).ipynb
diff --git a/past_sessions/2014_july/02 - Introduction to Python (2).ipynb b/past_sessions/2014_july/02 - Introduction to Python (2).ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..d7010ad5a4bc1c27708e86ce779188c6d3977840
--- /dev/null
+++ b/past_sessions/2014_july/02 - Introduction to Python (2).ipynb	
@@ -0,0 +1,1883 @@
+{
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "name": "",
+  "signature": "sha256:7b4c4307ccc127e749bcc6fae78706177f4e98973022d13424e5a50a8325f24e"
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "<span style=\"font-size: 200%\">Introduction to Python (2)</span>\n",
+      "===\n",
+      "\n",
+      "<br>\n",
+      "\n",
+      "[Martijn Vermaat](mailto:m.vermaat.hg@lumc.nl), [Department of Human Genetics, Leiden University Medical Center](http://humgen.nl)\n",
+      "\n",
+      "[Jeroen Laros](mailto:j.f.j.laros@lumc.nl), [Department of Human Genetics, Leiden University Medical Center](http://humgen.nl)\n",
+      "\n",
+      "Based on: [Python Scientific Lecture Notes](http://scipy-lectures.github.io/)\n",
+      "\n",
+      "License: [Creative Commons Attribution 3.0 License (CC-by)](http://creativecommons.org/licenses/by/3.0)"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Sequence types\n",
+      "===\n",
+      "\n",
+      "Lists\n",
+      "---\n",
+      "\n",
+      "Mutable sequences of values."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "l = [2, 5, 2, 3, 7]\n",
+      "type(l)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 1,
+       "text": [
+        "list"
+       ]
+      }
+     ],
+     "prompt_number": 1
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Lists can be heterogeneous, but we typically don't use that."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "a = 'spezi'\n",
+      "[3, 'abc', 1.3e20, [a, a, 2]]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 2,
+       "text": [
+        "[3, 'abc', 1.3e+20, ['spezi', 'spezi', 2]]"
+       ]
+      }
+     ],
+     "prompt_number": 2
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Sequence types\n",
+      "===\n",
+      "\n",
+      "Tuples\n",
+      "---\n",
+      "\n",
+      "Immutable sequences of values."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "t = 'white', 77, 1.5\n",
+      "type(t)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 3,
+       "text": [
+        "tuple"
+       ]
+      }
+     ],
+     "prompt_number": 3
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "color, width, scale = t\n",
+      "width"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 4,
+       "text": [
+        "77"
+       ]
+      }
+     ],
+     "prompt_number": 4
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Sequence types\n",
+      "===\n",
+      "\n",
+      "Strings (1/2)\n",
+      "---\n",
+      "\n",
+      "Immutable sequences of characters."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "'a string can be written in single quotes'"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 5,
+       "text": [
+        "'a string can be written in single quotes'"
+       ]
+      }
+     ],
+     "prompt_number": 5
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Strings can also be written with double quotes, or over multiple lines with triple-quotes."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "\"this makes it easier to use the ' character\""
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 6,
+       "text": [
+        "\"this makes it easier to use the ' character\""
+       ]
+      }
+     ],
+     "prompt_number": 6
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "\"\"\"This is a multiline string.\n",
+      "\n",
+      "You see? I continued after a blank line.\"\"\""
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 7,
+       "text": [
+        "'This is a multiline string.\\n\\nYou see? I continued after a blank line.'"
+       ]
+      }
+     ],
+     "prompt_number": 7
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Sequence types\n",
+      "===\n",
+      "\n",
+      "Strings (2/2)\n",
+      "---\n",
+      "\n",
+      "A common operation is formatting strings using argument substitutions."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "'{} times {} equals {:.2f}'.format('pi', 2, 6.283185307179586)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 8,
+       "text": [
+        "'pi times 2 equals 6.28'"
+       ]
+      }
+     ],
+     "prompt_number": 8
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Accessing arguments by position or name is more readable."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "'{1} times {0} equals {2:.2f}'.format('pi', 2, 6.283185307179586)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 9,
+       "text": [
+        "'2 times pi equals 6.28'"
+       ]
+      }
+     ],
+     "prompt_number": 9
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "'{number} times {amount} equals {result:.2f}'.format(number='pi', amount=2,\n",
+      "                                                     result=6.283185307179586)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 10,
+       "text": [
+        "'pi times 2 equals 6.28'"
+       ]
+      }
+     ],
+     "prompt_number": 10
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Sequence types\n",
+      "===\n",
+      "\n",
+      "Common operations (1/2)\n",
+      "---\n",
+      "\n",
+      "All sequence types support concatenation, membership/substring tests, indexing, and slicing."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "[1, 2, 3] + [4, 5, 6]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 11,
+       "text": [
+        "[1, 2, 3, 4, 5, 6]"
+       ]
+      }
+     ],
+     "prompt_number": 11
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "'bier' in 'we drinken bier vanaf half 5'"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 12,
+       "text": [
+        "True"
+       ]
+      }
+     ],
+     "prompt_number": 12
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "'abcdefghijkl'[5]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 13,
+       "text": [
+        "'f'"
+       ]
+      }
+     ],
+     "prompt_number": 13
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Sequence types\n",
+      "===\n",
+      "\n",
+      "Slicing\n",
+      "---\n",
+      "\n",
+      "Slice `s` from `i` to `j` with `s[i:j]`."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "'abcdefghijkl'[4:8]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 14,
+       "text": [
+        "'efgh'"
+       ]
+      }
+     ],
+     "prompt_number": 14
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "'abcdefghijkl'[:3]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 15,
+       "text": [
+        "'abc'"
+       ]
+      }
+     ],
+     "prompt_number": 15
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "We can also define the step `k` with `s[i:j:k]`."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "'abcdefghijkl'[7:3:-1]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 16,
+       "text": [
+        "'hgfe'"
+       ]
+      }
+     ],
+     "prompt_number": 16
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Sequence types\n",
+      "===\n",
+      "\n",
+      "Common operations (2/2)\n",
+      "---\n",
+      "\n",
+      "Contrary to strings and tuples, lists are mutable. We can also get their length, smallest/largest item, and number/position of certain items."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "len('attacgataggcatccgt')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 17,
+       "text": [
+        "18"
+       ]
+      }
+     ],
+     "prompt_number": 17
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "max([17, 86, 34, 51])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 18,
+       "text": [
+        "86"
+       ]
+      }
+     ],
+     "prompt_number": 18
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "('atg', 22, True, 'atg').count('atg')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 19,
+       "text": [
+        "2"
+       ]
+      }
+     ],
+     "prompt_number": 19
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Sequence types\n",
+      "===\n",
+      "\n",
+      "Additional operations with lists\n",
+      "---\n",
+      "\n",
+      "We can replace, add, remove, reverse and sort items in-place."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "l = [1, 2, 3, 4]\n",
+      "l[3] = 7\n",
+      "l.append(1)\n",
+      "l[1:3] = [3, 2]\n",
+      "l.sort()\n",
+      "l.reverse()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 20
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "l"
+     ],
+     "language": "python",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "fragment"
+      }
+     },
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 21,
+       "text": [
+        "[7, 3, 2, 1, 1]"
+       ]
+      }
+     ],
+     "prompt_number": 21
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Dictionaries\n",
+      "===\n",
+      "\n",
+      "Dictionaries map *hashable* values to arbitrary objects\n",
+      "---\n",
+      "\n",
+      "* All built-in immutable objects are hashable.\n",
+      "* No built-in mutable objects are hashable."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "d = {'a': 27, 'b': 18, 'c': 12}\n",
+      "type(d)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 22,
+       "text": [
+        "dict"
+       ]
+      }
+     ],
+     "prompt_number": 22
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "d['e'] = 17\n",
+      "'e' in d"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 23,
+       "text": [
+        "True"
+       ]
+      }
+     ],
+     "prompt_number": 23
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "d.update({'a': 18, 'f': 2})\n",
+      "d"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 24,
+       "text": [
+        "{'a': 18, 'b': 18, 'c': 12, 'e': 17, 'f': 2}"
+       ]
+      }
+     ],
+     "prompt_number": 24
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Dictionaries\n",
+      "===\n",
+      "\n",
+      "Accessing dictionary content\n",
+      "---"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "d['b']"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 25,
+       "text": [
+        "18"
+       ]
+      }
+     ],
+     "prompt_number": 25
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "d.keys()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 26,
+       "text": [
+        "['a', 'c', 'b', 'e', 'f']"
+       ]
+      }
+     ],
+     "prompt_number": 26
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "d.values()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 27,
+       "text": [
+        "[18, 12, 18, 17, 2]"
+       ]
+      }
+     ],
+     "prompt_number": 27
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "d.items()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 28,
+       "text": [
+        "[('a', 18), ('c', 12), ('b', 18), ('e', 17), ('f', 2)]"
+       ]
+      }
+     ],
+     "prompt_number": 28
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Sets\n",
+      "===\n",
+      "\n",
+      "Mutable unordered collections of hashable values without duplication\n",
+      "---"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "x = {12, 28, 21, 17}\n",
+      "type(x)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 29,
+       "text": [
+        "set"
+       ]
+      }
+     ],
+     "prompt_number": 29
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "x.add(12)\n",
+      "x"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 30,
+       "text": [
+        "{12, 17, 21, 28}"
+       ]
+      }
+     ],
+     "prompt_number": 30
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "x.discard(21)\n",
+      "x"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 31,
+       "text": [
+        "{12, 17, 28}"
+       ]
+      }
+     ],
+     "prompt_number": 31
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Sets\n",
+      "===\n",
+      "\n",
+      "Operations with sets\n",
+      "---\n",
+      "\n",
+      "We can test for membership and apply many common set operations such as union and intersect."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "17 in {12, 28, 21, 17}"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 32,
+       "text": [
+        "True"
+       ]
+      }
+     ],
+     "prompt_number": 32
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "{12, 28, 21, 17} | {12, 18, 11}"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 33,
+       "text": [
+        "{11, 12, 17, 18, 21, 28}"
+       ]
+      }
+     ],
+     "prompt_number": 33
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "{12, 28, 21, 17} & {12, 18, 11}"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 34,
+       "text": [
+        "{12}"
+       ]
+      }
+     ],
+     "prompt_number": 34
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Booleans\n",
+      "===\n",
+      "\n",
+      "Boolean values and operations\n",
+      "---\n",
+      "\n",
+      "The two boolean values are written `False` and `True`."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "True or False"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 35,
+       "text": [
+        "True"
+       ]
+      }
+     ],
+     "prompt_number": 35
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "True and False"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 36,
+       "text": [
+        "False"
+       ]
+      }
+     ],
+     "prompt_number": 36
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "not False"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 37,
+       "text": [
+        "True"
+       ]
+      }
+     ],
+     "prompt_number": 37
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Booleans\n",
+      "===\n",
+      "\n",
+      "Comparisons\n",
+      "---\n",
+      "\n",
+      "Comparisons can be done on all objects and return a boolean value."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "22 * 3 > 66"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 38,
+       "text": [
+        "False"
+       ]
+      }
+     ],
+     "prompt_number": 38
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "We have two equivalence relations: value equality (`==`) and object identity (`is`)."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "a, b = [1, 2, 3], [1, 2, 3]\n",
+      "a == b"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 39,
+       "text": [
+        "True"
+       ]
+      }
+     ],
+     "prompt_number": 39
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "a is b"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 40,
+       "text": [
+        "False"
+       ]
+      }
+     ],
+     "prompt_number": 40
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Booleans\n",
+      "===\n",
+      "\n",
+      "`if` statements\n",
+      "---\n",
+      "\n",
+      "(The `print` statement writes a string representation of the given value.)"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "if 26 <= 17:\n",
+      "    print 'Fact: 26 is less than or equal to 17'\n",
+      "elif (26 + 8 > 14) == True:\n",
+      "    print 'Did we need the ` == True` part here?'\n",
+      "else:\n",
+      "    print 'Nothing seems true'"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Did we need the ` == True` part here?\n"
+       ]
+      }
+     ],
+     "prompt_number": 41
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Booleans\n",
+      "===\n",
+      "\n",
+      "`while` statements\n",
+      "---\n",
+      "\n",
+      "Our first looping control structure just repeats until the given expression evaluates to `False`."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "i = 0\n",
+      "while i < 5:\n",
+      "    print i\n",
+      "    i += 1"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "0\n",
+        "1\n",
+        "2\n",
+        "3\n",
+        "4\n"
+       ]
+      }
+     ],
+     "prompt_number": 42
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Notes about syntax\n",
+      "===\n",
+      "\n",
+      "Indentation\n",
+      "---\n",
+      "\n",
+      "Python uses indentation to delimit blocks\n",
+      "\n",
+      "* Instead of `begin ... end` or `{ ... }` in other languages.\n",
+      "* Always increase indentation by *4 spaces*, never use tabs.\n",
+      "* In any case, be consistent."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "if False:\n",
+      "    if False:\n",
+      "        print 'Why am I here?'\n",
+      "    else:\n",
+      "        while True:\n",
+      "            print 'When will it stop?'\n",
+      "    print \"And we're back to the first indentation level\""
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 43
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Some editors can be configured to behave just like that."
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Notes about syntax\n",
+      "===\n",
+      "\n",
+      "Comments\n",
+      "---\n",
+      "\n",
+      "Comments are prepended by `#` and completely ignored."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "# Add 42 to this list.\n",
+      "l.append(42)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 44
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "`pass` statements\n",
+      "---\n",
+      "\n",
+      "If you ever need a statement syntactically but don't want to do anything, use `pass`."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "while False:\n",
+      "    # This is never executed anyway.\n",
+      "    pass"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 45
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Useful built-ins\n",
+      "===\n",
+      "\n",
+      "Getting help\n",
+      "---\n",
+      "\n",
+      "You can get help on almost any object with `help`."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "help(range)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Help on built-in function range in module __builtin__:\n",
+        "\n",
+        "range(...)\n",
+        "    range([start,] stop[, step]) -> list of integers\n",
+        "    \n",
+        "    Return a list containing an arithmetic progression of integers.\n",
+        "    range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.\n",
+        "    When step is given, it specifies the increment (or decrement).\n",
+        "    For example, range(4) returns [0, 1, 2, 3].  The end point is omitted!\n",
+        "    These are exactly the valid indices for a list of 4 elements.\n",
+        "\n"
+       ]
+      }
+     ],
+     "prompt_number": 46
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "In IPython you can do it faster by typing:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "range?"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 47
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Useful built-ins\n",
+      "===\n",
+      "\n",
+      "We'll shortly use the following built-in functions."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "range(5, 16)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 48,
+       "text": [
+        "[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]"
+       ]
+      }
+     ],
+     "prompt_number": 48
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "zip(['red', 'white', 'blue'], range(3))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 49,
+       "text": [
+        "[('red', 0), ('white', 1), ('blue', 2)]"
+       ]
+      }
+     ],
+     "prompt_number": 49
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "list('abcdefghijk')"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 50,
+       "text": [
+        "['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k']"
+       ]
+      }
+     ],
+     "prompt_number": 50
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Iteration\n",
+      "===\n",
+      "\n",
+      "Iterating over a sequence\n",
+      "---"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "colors = ['red', 'white', 'blue', 'orange']\n",
+      "cities = ['leiden', 'utrecht', 'warmond', 'san francisco']"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 51
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "The `for` statement can iterate over sequence items."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "for color in colors:\n",
+      "    print color"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "red\n",
+        "white\n",
+        "blue\n",
+        "orange\n"
+       ]
+      }
+     ],
+     "prompt_number": 52
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "for character in 'blue':\n",
+      "    print character"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "b\n",
+        "l\n",
+        "u\n",
+        "e\n"
+       ]
+      }
+     ],
+     "prompt_number": 53
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Iteration\n",
+      "===\n",
+      "\n",
+      "Python anti-patterns\n",
+      "---\n",
+      "\n",
+      "These are common for programmers coming from other languages."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "i = 0\n",
+      "while i < len(colors):\n",
+      "    print colors[i]\n",
+      "    i += 1"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "red\n",
+        "white\n",
+        "blue\n",
+        "orange\n"
+       ]
+      }
+     ],
+     "prompt_number": 54
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "for i in range(len(colors)):\n",
+      "    print colors[i]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "red\n",
+        "white\n",
+        "blue\n",
+        "orange\n"
+       ]
+      }
+     ],
+     "prompt_number": 55
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "We call them *unpythonic*."
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Iteration\n",
+      "===\n",
+      "\n",
+      "Using values *and* indices\n",
+      "---"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "for i, color in enumerate(colors):\n",
+      "    print i, '->', color"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "0 -> red\n",
+        "1 -> white\n",
+        "2 -> blue\n",
+        "3 -> orange\n"
+       ]
+      }
+     ],
+     "prompt_number": 56
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Taking two sequences together\n",
+      "---"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "for city, color in zip(cities, colors):\n",
+      "    print city, '->', color"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "leiden -> red\n",
+        "utrecht -> white\n",
+        "warmond -> blue\n",
+        "san francisco -> orange\n"
+       ]
+      }
+     ],
+     "prompt_number": 57
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Iteration\n",
+      "===\n",
+      "\n",
+      "Other iterables\n",
+      "---\n",
+      "\n",
+      "Iterating over a dictionary yields keys."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "for key in {'a': 33, 'b': 17, 'c': 18}:\n",
+      "    print key"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "a\n",
+        "c\n",
+        "b\n"
+       ]
+      }
+     ],
+     "prompt_number": 58
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Iterating over a file yields lines."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "for line in open('data/short_file.txt'):\n",
+      "    print line"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "this short file has two lines\n",
+        "\n",
+        "it is used in the example code\n",
+        "\n"
+       ]
+      }
+     ],
+     "prompt_number": 59
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "There are many more useful iterables in Python."
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "$\\S$ Exercise: Iterate over a list\n",
+      "===\n",
+      "\n",
+      "First we are going to make a list and fill it with a simple sequence. Then we are going to use this list to print something.\n",
+      "\n",
+      "* Make a list containing the numbers 0, 1, ... 9.\n",
+      "* Print the last 10 lines of the song ''99 bottles of beer'' using this list."
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "$\\S$ Exercise: Analyse a repeat structure\n",
+      "===\n",
+      "\n",
+      "We are going to make a repeating DNA sequence and extract some subsequences from it.\n",
+      "\n",
+      "* Make a short tandem repeat that consists of three \"ACGT\" units and five \"TTATT\" units.\n",
+      "* Print all suffixes of the repeat structure.\n",
+      "\n",
+      "**Note:** A suffix is an ending. For example, the word \"spam\" has five suffixes: \"spam\", \"pam\", \"am\", \"m\" and \"\".\n",
+      "\n",
+      "* Print all substrings of length 3.\n",
+      "* Print all unique substrings of length 3.\n",
+      "\n",
+      "**Hint:** All elements in a set are unique."
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "$\\S$ Exercise: Boolean comparison\n",
+      "===\n",
+      "\n",
+      "Try to guess the outcome of the following statements:\n",
+      "\n",
+      "    2 * 3 > 4\n",
+      "    2 * (3 > 4)\n",
+      "    2 * (4 > 3)"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "$\\S$ Exercise: Combining lists\n",
+      "===\n",
+      "\n",
+      "Calculate all coordinates of the line x=y with x < 100.\n",
+      "\n",
+      "**Note:** This is the sequence (0, 0), (1, 1), ... (99, 99)"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "$\\S$ Exercise: Dictionaries\n",
+      "===\n",
+      "We are going to store the output of a function ($f(x) = x^2$) together with its input in a dictionary.\n",
+      "\n",
+      "* Make a dictionary containing all squares smaller than 100.\n",
+      "* Print the content of this dictionary in english, e.g., \"4 is the square of 2\"."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "from IPython.display import HTML\n",
+      "def css_styling():\n",
+      "    styles = open('styles/custom.css', 'r').read()\n",
+      "    return HTML('<style>' + styles + '</style>')\n",
+      "css_styling()"
+     ],
+     "language": "python",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "skip"
+      }
+     },
+     "outputs": [
+      {
+       "html": [
+        "<style>/* Remove the vertical scrollbar added by nbconvert. */\n",
+        ".reveal {\n",
+        "  overflow: hidden;\n",
+        "}\n",
+        "\n",
+        "/* Workaround some highlight.js bugs in language autodetection. */\n",
+        "code.objectivec *,\n",
+        "code.perl *,\n",
+        "code.cs *,\n",
+        "code.javascript *,\n",
+        "code.http * {\n",
+        "  color: black ! important;\n",
+        "  font-weight: normal ! important;\n",
+        "}\n",
+        "span.title {\n",
+        "  color: black ! important;\n",
+        "}\n",
+        "span.tag {\n",
+        "  color: black ! important;\n",
+        "}\n",
+        "span.attribute {\n",
+        "  color: black ! important;\n",
+        "}\n",
+        "</style>"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 1,
+       "text": [
+        "<IPython.core.display.HTML at 0x1873a50>"
+       ]
+      }
+     ],
+     "prompt_number": 1
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file
diff --git a/past_sessions/2014_july/02 - Introduction to Python (3).ipynb b/past_sessions/2014_july/02 - Introduction to Python (3).ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..792c0926b7c98083cfb53aa045d31ddf4fff937a
--- /dev/null
+++ b/past_sessions/2014_july/02 - Introduction to Python (3).ipynb	
@@ -0,0 +1,892 @@
+{
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "name": "",
+  "signature": "sha256:255f999074050e52200e04b7179ca89a373daf14311e382c4ab05b4444cf392e"
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+  {
+   "cells": [
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "<span style=\"font-size: 200%\">Introduction to Python (3)</span>\n",
+      "===\n",
+      "\n",
+      "<br>\n",
+      "\n",
+      "[Martijn Vermaat](mailto:m.vermaat.hg@lumc.nl), [Department of Human Genetics, Leiden University Medical Center](http://humgen.nl)\n",
+      "\n",
+      "[Jeroen Laros](mailto:j.f.j.laros@lumc.nl), [Department of Human Genetics, Leiden University Medical Center](http://humgen.nl)\n",
+      "\n",
+      "Based on: [Python Scientific Lecture Notes](http://scipy-lectures.github.io/)\n",
+      "\n",
+      "License: [Creative Commons Attribution 3.0 License (CC-by)](http://creativecommons.org/licenses/by/3.0)"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Functions\n",
+      "===\n",
+      "\n",
+      "Defining a function\n",
+      "---\n",
+      "\n",
+      "A function definition includes its name, arguments and body."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "def add_two(number):\n",
+      "    return number + 2"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 1
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "for i in range(5):\n",
+      "    print add_two(i)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "2\n",
+        "3\n",
+        "4\n",
+        "5\n",
+        "6\n"
+       ]
+      }
+     ],
+     "prompt_number": 2
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Functions\n",
+      "===\n",
+      "\n",
+      "Keyword arguments\n",
+      "---\n",
+      "\n",
+      "Besides regular arguments, functions can have keyword arguments."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "def add_some_other_number(number, other_number=12):\n",
+      "    return number + other_number"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 3
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "add_some_other_number(2, 6)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 4,
+       "text": [
+        "8"
+       ]
+      }
+     ],
+     "prompt_number": 4
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "add_some_other_number(3, other_number=4)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 5,
+       "text": [
+        "7"
+       ]
+      }
+     ],
+     "prompt_number": 5
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "add_some_other_number(5)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 6,
+       "text": [
+        "17"
+       ]
+      }
+     ],
+     "prompt_number": 6
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Functions\n",
+      "===\n",
+      "\n",
+      "Docstrings\n",
+      "---\n",
+      "\n",
+      "Like many other definitions, functions can have docstrings.\n",
+      "\n",
+      "* Docstrings are regular string values which you start the definition body with.\n",
+      "* You can access an object's docstring using `help`."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "def factorial(n):\n",
+      "    \"\"\"Compute factorial of n in the obious way.\"\"\"\n",
+      "    if n == 0:\n",
+      "        return 1\n",
+      "    else:\n",
+      "        return factorial(n - 1) * n"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 7
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "help(factorial)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Help on function factorial in module __main__:\n",
+        "\n",
+        "factorial(n)\n",
+        "    Compute factorial of n in the obious way.\n",
+        "\n"
+       ]
+      }
+     ],
+     "prompt_number": 8
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Functions\n",
+      "===\n",
+      "\n",
+      "Functions are values\n",
+      "---\n",
+      "\n",
+      "We can pass functions around just like other values, and call them."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "functions = [add_two, add_some_other_number]\n",
+      "for function in functions:\n",
+      "    print function(7)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "9\n",
+        "19\n"
+       ]
+      }
+     ],
+     "prompt_number": 9
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Simple anonymous functions can be created with `lambda`."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "functions.append(lambda x: x * 7)\n",
+      "for function in functions:\n",
+      "    print function(4)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "6\n",
+        "16\n",
+        "28\n"
+       ]
+      }
+     ],
+     "prompt_number": 10
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Functions\n",
+      "===\n",
+      "\n",
+      "Higher-order functions\n",
+      "---\n",
+      "\n",
+      "A function that takes a function as argument is a higher-order function."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "help(map)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Help on built-in function map in module __builtin__:\n",
+        "\n",
+        "map(...)\n",
+        "    map(function, sequence[, sequence, ...]) -> list\n",
+        "    \n",
+        "    Return a list of the results of applying the function to the items of\n",
+        "    the argument sequence(s).  If more than one sequence is given, the\n",
+        "    function is called with an argument list consisting of the corresponding\n",
+        "    item of each sequence, substituting None for missing values when not all\n",
+        "    sequences have the same length.  If the function is None, return a list of\n",
+        "    the items of the sequence (or a list of tuples if more than one sequence).\n",
+        "\n"
+       ]
+      }
+     ],
+     "prompt_number": 11
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "map(add_two, [1, 2, 3, 4])"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 12,
+       "text": [
+        "[3, 4, 5, 6]"
+       ]
+      }
+     ],
+     "prompt_number": 12
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "$\\S$ Exercise: k-mer counting (1/2)\n",
+      "===\n",
+      "\n",
+      "Remember the previous exercise of finding (unique) substrings of length 3.\n",
+      "\n",
+      "* Make a function from your implementation.\n",
+      "* Have `k` as an argument to the function.\n",
+      "* Test the function on several input strings.\n",
+      "\n",
+      "**Note:** Editing multi-line statements in the console can be frustrating. You can try the QT console (`ipython qtconsole`) or edit your function in an editor with `%edit`:\n",
+      "\n",
+      "    def my_function(arg):\n",
+      "        print arg * 4\n",
+      "    %edit my_function"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "$\\S$ Exercise: k-mer counting (2/2)\n",
+      "===\n",
+      "\n",
+      "Modify your function to use a dictionary with substring counts.\n",
+      "\n",
+      "* Use the substrings as dictionary keys.\n",
+      "* Use the counts as dictionary values.\n",
+      "* Have the function return the dictionary.\n",
+      "* Add a docstring to the function.\n",
+      "* Use the function to print k-mer counts for some strings."
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Comprehensions\n",
+      "===\n",
+      "\n",
+      "List comprehensions\n",
+      "---\n",
+      "\n",
+      "Similar to mathematical set notation (e.g., $\\{ x ~|~ x \\in \\mathbf R \\land x > 0\\}$), we can create lists."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "[(x, x * x) for x in range(10) if x % 2]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 13,
+       "text": [
+        "[(1, 1), (3, 9), (5, 25), (7, 49), (9, 81)]"
+       ]
+      }
+     ],
+     "prompt_number": 13
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "We can do the same thing using `map` and `filter`, but list comprehensions are often more readable."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "map(lambda x: (x, x * x), filter(lambda x: x %2, range(10)))"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 14,
+       "text": [
+        "[(1, 1), (3, 9), (5, 25), (7, 49), (9, 81)]"
+       ]
+      }
+     ],
+     "prompt_number": 14
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Comprehensions\n",
+      "===\n",
+      "\n",
+      "Set and dictionary comprehensions\n",
+      "---\n",
+      "\n",
+      "Similar notation can be used for (non-empty) sets."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "{c for c in 'LUMC-standard' if 'a' <= c <= 'z'}"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 15,
+       "text": [
+        "{'a', 'd', 'n', 'r', 's', 't'}"
+       ]
+      }
+     ],
+     "prompt_number": 15
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "And dictionaries."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "colors = ['red', 'white', 'blue', 'orange']\n",
+      "{c: len(c) for c in colors}"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 16,
+       "text": [
+        "{'blue': 4, 'orange': 6, 'red': 3, 'white': 5}"
+       ]
+      }
+     ],
+     "prompt_number": 16
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Everything is an object\n",
+      "===\n",
+      "\n",
+      "* Objects have properties and methods. \n",
+      "* Explore them using `dir(o)`, or by typing `o.<tab>` in the IPython interpreter."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "dir('abc')[-5:]"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 17,
+       "text": [
+        "['swapcase', 'title', 'translate', 'upper', 'zfill']"
+       ]
+      }
+     ],
+     "prompt_number": 17
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "help('abc'.upper)"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "Help on built-in function upper:\n",
+        "\n",
+        "upper(...)\n",
+        "    S.upper() -> string\n",
+        "    \n",
+        "    Return a copy of the string S converted to uppercase.\n",
+        "\n"
+       ]
+      }
+     ],
+     "prompt_number": 18
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "'abc'.upper()"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 19,
+       "text": [
+        "'ABC'"
+       ]
+      }
+     ],
+     "prompt_number": 19
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Code in files\n",
+      "===\n",
+      "\n",
+      "Running code from a file\n",
+      "---"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "cat examples/fsquare.py"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "d = {}\r\n",
+        "for i in range(10):\r\n",
+        "    d[i] = i ** 2\r\n",
+        "\r\n",
+        "for i in d:\r\n",
+        "    print \"{0} is the square of {1}.\".format(d[i], i)\r\n"
+       ]
+      }
+     ],
+     "prompt_number": 20
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "%%sh\n",
+      "python examples/fsquare.py"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "0 is the square of 0.\n",
+        "1 is the square of 1.\n",
+        "4 is the square of 2.\n",
+        "9 is the square of 3.\n",
+        "16 is the square of 4.\n",
+        "25 is the square of 5.\n",
+        "36 is the square of 6.\n",
+        "49 is the square of 7.\n",
+        "64 is the square of 8.\n",
+        "81 is the square of 9.\n"
+       ]
+      }
+     ],
+     "prompt_number": 21
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Code in files\n",
+      "===\n",
+      "\n",
+      "Working with files in IPython\n",
+      "---\n",
+      "\n",
+      "The `%run` magic runs the code from a file directly in IPython:"
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "%run examples/fsquare.py"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [
+      {
+       "output_type": "stream",
+       "stream": "stdout",
+       "text": [
+        "0 is the square of 0.\n",
+        "1 is the square of 1.\n",
+        "4 is the square of 2.\n",
+        "9 is the square of 3.\n",
+        "16 is the square of 4.\n",
+        "25 is the square of 5.\n",
+        "36 is the square of 6.\n",
+        "49 is the square of 7.\n",
+        "64 is the square of 8.\n",
+        "81 is the square of 9.\n"
+       ]
+      }
+     ],
+     "prompt_number": 22
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "-"
+      }
+     },
+     "source": [
+      "You can edit and run a file with `%edit`."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "%edit examples/fsquare.py"
+     ],
+     "language": "python",
+     "metadata": {},
+     "outputs": [],
+     "prompt_number": 23
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "Code in files\n",
+      "===\n",
+      "\n",
+      "Saving your IPython session history to a file\n",
+      "---\n",
+      "\n",
+      "Give the `%save` magic a name and a range of input lines and it will save them to a `.py` file with that name:\n",
+      "\n",
+      "    In [4]: %save my_session 1-3\n",
+      "    The following commands were written to file `my_session.py`:\n",
+      "    a = 4\n",
+      "    a += 3\n",
+      "    b = a"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "$\\S$ Exercise: Running code from a file\n",
+      "===\n",
+      "\n",
+      "* Save your k-mer counting code to a file `kmer_counting.py`.\n",
+      "* Include some code using it on an example string and printing the results.\n",
+      "* Run the code from the command line."
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "slide"
+      }
+     },
+     "source": [
+      "Further reading\n",
+      "===\n",
+      "\n",
+      "* [The Python Tutorial](http://docs.python.org/2/tutorial/index.html)\n",
+      "  <br>\n",
+      "  From the official Python documentation.\n",
+      "\n",
+      "\n",
+      "* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/)\n",
+      "  <br>\n",
+      "  Book on learning Python by exercises, online available for free.\n",
+      "\n",
+      "\n",
+      "* [The Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)\n",
+      "  <br>\n",
+      "  This opinionated guide exists to provide both novice and expert Python developers a best-practice handbook to the installation, configuration, and usage of Python on a daily basis.\n",
+      "\n",
+      "\n",
+      "* [A Primer on Scientific Programming with Python](http://codingcat.com/knjige/python/A%20Primer%20on%20Scientific%20Programming%20with%20Python.pdf)\n",
+      "  <br>\n",
+      "  Complete PDF version of the book. The aim of this book is to teach computer programming using examples from mathematics and the natural sciences.\n",
+      "\n",
+      "\n",
+      "* [Python Module of the Week](http://pymotw.com/)\n",
+      "  <br>\n",
+      "  Series of articles providing a tour of the Python standard library through short examples."
+     ]
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "from IPython.display import HTML\n",
+      "def css_styling():\n",
+      "    styles = open('styles/custom.css', 'r').read()\n",
+      "    return HTML('<style>' + styles + '</style>')\n",
+      "css_styling()"
+     ],
+     "language": "python",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "skip"
+      }
+     },
+     "outputs": [
+      {
+       "html": [
+        "<style>/* Remove the vertical scrollbar added by nbconvert. */\n",
+        ".reveal {\n",
+        "  overflow: hidden;\n",
+        "}\n",
+        "\n",
+        "/* Workaround some highlight.js bugs in language autodetection. */\n",
+        "code.objectivec *,\n",
+        "code.perl *,\n",
+        "code.cs *,\n",
+        "code.javascript *,\n",
+        "code.http * {\n",
+        "  color: black ! important;\n",
+        "  font-weight: normal ! important;\n",
+        "}\n",
+        "span.title {\n",
+        "  color: black ! important;\n",
+        "}\n",
+        "span.tag {\n",
+        "  color: black ! important;\n",
+        "}\n",
+        "span.attribute {\n",
+        "  color: black ! important;\n",
+        "}\n",
+        "</style>"
+       ],
+       "metadata": {},
+       "output_type": "pyout",
+       "prompt_number": 1,
+       "text": [
+        "<IPython.core.display.HTML at 0x2e0ea50>"
+       ]
+      }
+     ],
+     "prompt_number": 1
+    }
+   ],
+   "metadata": {}
+  }
+ ]
+}
\ No newline at end of file
diff --git a/03 - More Python goodness (1).ipynb b/past_sessions/2014_july/03 - More Python goodness (1).ipynb
similarity index 100%
rename from 03 - More Python goodness (1).ipynb
rename to past_sessions/2014_july/03 - More Python goodness (1).ipynb
diff --git a/03 - More Python goodness (2).ipynb b/past_sessions/2014_july/03 - More Python goodness (2).ipynb
similarity index 100%
rename from 03 - More Python goodness (2).ipynb
rename to past_sessions/2014_july/03 - More Python goodness (2).ipynb
diff --git a/04 - Working with NumPy arrays.ipynb b/past_sessions/2014_july/04 - Working with NumPy arrays.ipynb
similarity index 100%
rename from 04 - Working with NumPy arrays.ipynb
rename to past_sessions/2014_july/04 - Working with NumPy arrays.ipynb
diff --git a/05 - IPython Notebook.ipynb b/past_sessions/2014_july/05 - IPython Notebook.ipynb
similarity index 100%
rename from 05 - IPython Notebook.ipynb
rename to past_sessions/2014_july/05 - IPython Notebook.ipynb
diff --git a/06 - Plotting with matplotlib.ipynb b/past_sessions/2014_july/06 - Plotting with matplotlib.ipynb
similarity index 100%
rename from 06 - Plotting with matplotlib.ipynb
rename to past_sessions/2014_july/06 - Plotting with matplotlib.ipynb
diff --git a/07 - Painting Pandas.ipynb b/past_sessions/2014_july/07 - Painting Pandas.ipynb
similarity index 100%
rename from 07 - Painting Pandas.ipynb
rename to past_sessions/2014_july/07 - Painting Pandas.ipynb
diff --git a/08 - Object-oriented programming.ipynb b/past_sessions/2014_july/08 - Object-oriented programming.ipynb
similarity index 100%
rename from 08 - Object-oriented programming.ipynb
rename to past_sessions/2014_july/08 - Object-oriented programming.ipynb
diff --git a/09 - A sip of Biopython (1).ipynb b/past_sessions/2014_july/09 - A sip of Biopython (1).ipynb
similarity index 100%
rename from 09 - A sip of Biopython (1).ipynb
rename to past_sessions/2014_july/09 - A sip of Biopython (1).ipynb
diff --git a/09 - A sip of Biopython (2).ipynb b/past_sessions/2014_july/09 - A sip of Biopython (2).ipynb
similarity index 100%
rename from 09 - A sip of Biopython (2).ipynb
rename to past_sessions/2014_july/09 - A sip of Biopython (2).ipynb
diff --git a/INSTALL.md b/past_sessions/2014_july/INSTALL.md
similarity index 100%
rename from INSTALL.md
rename to past_sessions/2014_july/INSTALL.md
diff --git a/past_sessions/2014_july/README.md b/past_sessions/2014_july/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..75c9c3e9b536c0de6b721e4f898381d7d62bfc19
--- /dev/null
+++ b/past_sessions/2014_july/README.md
@@ -0,0 +1,132 @@
+Programming course
+==================
+
+This repository contains material for the second installment (July 2014) of a
+programming course for scientists organised by the department of Human
+Genetics of the Leiden University Medical Center.
+
+The course is targeted at PhD students, Postdocs, or anyone willing to learn
+how to program in Python. Students are assumed to have some experience with
+programming, but not necessarily in Python, and the UNIX shell.
+
+The program consists of four mornings with lessons and some assignments to
+be done in your own time (i.e., during the afternoons).
+
+See the
+[Trac Wiki](https://humgenprojects.lumc.nl/trac/humgenprojects/wiki/ProgrammingCourse)
+for more information.
+
+Software installation
+---------------------
+
+See the instructions in `INSTALL.md`.
+
+
+Materials
+---------
+
+The top-level directory contains materials for the following lessons:
+
+1. Welcome ([slides][lesson_01])
+2. Introduction to Python ([slides 1][lesson_02_01], [slides 2][lesson_02_02],
+   [slides 3][lesson_02_03])
+3. More Python Goodness ([notebook 1][lesson_03_01], [notebook 2][lesson_03_02])
+4. Working with NumPy arrays ([slides][lesson_04])
+5. IPython Notebook ([notebook][lesson_05])
+6. Plotting with matplotlib ([notebook][lesson_06])
+7. Painting Pandas ([slides][lesson_07])
+8. Object-oriented programming ([slides][lesson_08])
+9. A sip of Biopython ([notebook 1][lesson_09_01], [notebook 2][lesson_09_02])
+
+[lesson_01]: http://nbviewer.ipython.org/urls/git.lumc.nl/courses/programming-course/raw/master/past_sessions/2014_july/01%20-%20Welcome.ipynb
+[lesson_02_01]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/02%20-%20Introduction%20to%20Python%20(1).ipynb
+[lesson_02_02]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/02%20-%20Introduction%20to%20Python%20(2).ipynb
+[lesson_02_03]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/02%20-%20Introduction%20to%20Python%20(3).ipynb
+[lesson_03_01]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/03%20-%20More%20Python%20goodness%20(1).ipynb
+[lesson_03_02]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/03%20-%20More%20Python%20goodness%20(2).ipynb
+[lesson_04]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/04%20-%20Working%20with%20NumPy%20arrays.ipynb
+[lesson_05]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/05%20-%20IPython%20Notebook.ipynb
+[lesson_06]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/06%20-%20Plotting%20with%20matplotlib.ipynb
+[lesson_07]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/07%20-%20Painting%20Pandas.ipynb
+[lesson_08]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/08%20-%20Object-oriented%20programming.ipynb
+[lesson_09_01]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/09%20-%20A%20sip%20of%20Biopython%20(1).ipynb
+[lesson_09_02]: http://nbviewer.ipython.org/urls/git.lumc.nl/humgen/programming-course/raw/master/09%20-%20A%20sip%20of%20Biopython%20(2).ipynb
+
+As indicated, some of the lessons are slideshows, whereas others are just
+notebooks we scroll through during class. The links above are all one-page
+static renderings on [IPython Notebook Viewer](http://nbviewer.ipython.org/).
+
+We also have a
+[repository with material for the assignments](https://git.lumc.nl/humgen/programming-course-assignments).
+
+
+Notebooks
+---------
+
+We apply some custom styling to the notebooks (e.g., body width, font), which
+is loaded in the last cell. This loads `styles/notebook.css` and
+`styles/notebook.js`.
+
+A variant `styles/notebook.css.small` is provided that is more suitable for
+use on low-resolution displays. To use it, manually change the reference to
+this file in the bottom cell, and rerun it.
+
+
+Slideshows
+----------
+
+The sources for the slideshows are also IPython notebooks and you can edit
+them by starting a notebook server:
+
+    ipython notebook
+
+Choose *Slideshow* in the *Cell Toolbar* menu.
+
+Some aditional information on editing slides in the Notebook can be found
+here in
+[this presentation](http://www.slideviper.oquanta.info/tutorial/slideshow_tutorial_slides.html).
+
+We also apply some custom styling to the slideshows, which is loaded in the
+last cell.
+
+
+Live rendering of the slides
+----------------------------
+
+You can use nbconvert to convert the slides to HTML and serve them. For
+example:
+
+    ipython nbconvert --to slides --post serve numpy.ipynb
+
+This will open the slides in a new browser window. If you don't want that, add
+this argument:
+
+    --ServePostProcessor.open_in_browser=False
+
+To serve on another IP address than the default 127.0.0.1, use the `ip`
+configuration of the serve postprocessing. For example, to listen on all IP
+addresses:
+
+    --ServePostProcessor.ip=0.0.0.0
+
+Changing the port can be done similarly with `port`.
+
+By default, the reveal.js library is loaded over the internet from a CDN. I
+think it's usually not a good idea to rely on internet connectivity for your
+slides, so you can also place a copy of reveal.js on your local computer and
+specify the location like this:
+
+    --reveal-prefix reveal.js
+
+This would look for the reveal.js library in the `reveal.js` directory. A Git
+submodule is already setup for this, so you can just do:
+
+    git submodule init
+    git submodule update
+
+(Unfortunately, there are other online dependencies such Font Awesome, so
+without an internet connection, not everything will look ok, but it will
+work.)
+
+Also, if you just want to compile the slides to HTML without serving them to
+your browser, leave out the `--post serve` argument.
diff --git a/person.py b/past_sessions/2014_july/person.py
similarity index 100%
rename from person.py
rename to past_sessions/2014_july/person.py
diff --git a/solutions/More_goodness_progression.ipynb b/past_sessions/2014_july/solutions/More_goodness_progression.ipynb
similarity index 100%
rename from solutions/More_goodness_progression.ipynb
rename to past_sessions/2014_july/solutions/More_goodness_progression.ipynb
diff --git a/solutions/matplotlib.ipynb b/past_sessions/2014_july/solutions/matplotlib.ipynb
similarity index 100%
rename from solutions/matplotlib.ipynb
rename to past_sessions/2014_july/solutions/matplotlib.ipynb
diff --git a/solutions/more_python_seq_toolbox.py b/past_sessions/2014_july/solutions/more_python_seq_toolbox.py
similarity index 100%
rename from solutions/more_python_seq_toolbox.py
rename to past_sessions/2014_july/solutions/more_python_seq_toolbox.py
diff --git a/solutions/notebook.ipynb b/past_sessions/2014_july/solutions/notebook.ipynb
similarity index 100%
rename from solutions/notebook.ipynb
rename to past_sessions/2014_july/solutions/notebook.ipynb
diff --git a/solutions/numpy.ipynb b/past_sessions/2014_july/solutions/numpy.ipynb
similarity index 100%
rename from solutions/numpy.ipynb
rename to past_sessions/2014_july/solutions/numpy.ipynb
diff --git a/solutions/python_01_bottles_of_beer.py b/past_sessions/2014_july/solutions/python_01_bottles_of_beer.py
similarity index 100%
rename from solutions/python_01_bottles_of_beer.py
rename to past_sessions/2014_july/solutions/python_01_bottles_of_beer.py
diff --git a/solutions/python_02_repeat_structure.py b/past_sessions/2014_july/solutions/python_02_repeat_structure.py
similarity index 100%
rename from solutions/python_02_repeat_structure.py
rename to past_sessions/2014_july/solutions/python_02_repeat_structure.py
diff --git a/solutions/python_03_combining_lists.py b/past_sessions/2014_july/solutions/python_03_combining_lists.py
similarity index 100%
rename from solutions/python_03_combining_lists.py
rename to past_sessions/2014_july/solutions/python_03_combining_lists.py
diff --git a/solutions/python_04_dictionaries.py b/past_sessions/2014_july/solutions/python_04_dictionaries.py
similarity index 100%
rename from solutions/python_04_dictionaries.py
rename to past_sessions/2014_july/solutions/python_04_dictionaries.py
diff --git a/solutions/python_05_kmer_counting.py b/past_sessions/2014_july/solutions/python_05_kmer_counting.py
similarity index 100%
rename from solutions/python_05_kmer_counting.py
rename to past_sessions/2014_july/solutions/python_05_kmer_counting.py
diff --git a/solutions/python_08_scientific_calculator.py b/past_sessions/2014_july/solutions/python_08_scientific_calculator.py
similarity index 100%
rename from solutions/python_08_scientific_calculator.py
rename to past_sessions/2014_july/solutions/python_08_scientific_calculator.py
diff --git a/reveal.js b/reveal.js
index 131c00689a4c7a18e5c991fc8102347e4594b5d4..43eada79901830702bd40dce857831aef8e76759 160000
--- a/reveal.js
+++ b/reveal.js
@@ -1 +1 @@
-Subproject commit 131c00689a4c7a18e5c991fc8102347e4594b5d4
+Subproject commit 43eada79901830702bd40dce857831aef8e76759