diff --git a/.gitmodules b/.gitmodules
index 12123b5bfb31a7743dda5d70a36d01156d73e269..7a9339ca9b25d882f9eb2a7516c239e025c63596 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
 [submodule "reveal.js"]
 	path = reveal.js
 	url = https://github.com/hakimel/reveal.js.git
+[submodule "programming-course-assignments"]
+	path = programming-course-assignments
+	url = git@git.lumc.nl:humgen/programming-course-assignments.git
diff --git a/08 - Object-oriented programming.ipynb b/08 - Object-oriented programming.ipynb
index cc24cc377d8151c398713c5db924cac0e0e6f0c4..2db16fab769294bda18d404688ae5dbc38e6df89 100644
--- a/08 - Object-oriented programming.ipynb	
+++ b/08 - Object-oriented programming.ipynb	
@@ -50,7 +50,7 @@
        ]
       }
      ],
-     "prompt_number": 1
+     "prompt_number": 2
     },
     {
      "cell_type": "markdown",
@@ -67,7 +67,7 @@
       "\n",
       "You can use nbconvert to convert the slides to HTML and serve them:\n",
       "\n",
-      "    ipython nbconvert --to slides --post serve classes.ipynb\n",
+      "    ipython nbconvert --to slides --post serve \"08 - Object-oriented programming.ipynb\" \n",
       "\n",
       "This will open the slides in a new browser window."
      ]
@@ -120,13 +120,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 2,
+       "prompt_number": 3,
        "text": [
         "('blue', 90, 161)"
        ]
       }
      ],
-     "prompt_number": 2
+     "prompt_number": 3
     },
     {
      "cell_type": "markdown",
@@ -147,13 +147,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 3,
+       "prompt_number": 4,
        "text": [
         "90"
        ]
       }
      ],
-     "prompt_number": 3
+     "prompt_number": 4
     },
     {
      "cell_type": "markdown",
@@ -194,13 +194,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 4,
+       "prompt_number": 5,
        "text": [
         "['blue', 90, 161]"
        ]
       }
      ],
-     "prompt_number": 4
+     "prompt_number": 5
     },
     {
      "cell_type": "markdown",
@@ -221,13 +221,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 5,
+       "prompt_number": 6,
        "text": [
         "161"
        ]
       }
      ],
-     "prompt_number": 5
+     "prompt_number": 6
     },
     {
      "cell_type": "markdown",
@@ -268,13 +268,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 6,
+       "prompt_number": 7,
        "text": [
         "{'hair_colour': 'blue', 'length': 161, 'weight': 90}"
        ]
       }
      ],
-     "prompt_number": 6
+     "prompt_number": 7
     },
     {
      "cell_type": "code",
@@ -288,13 +288,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 7,
+       "prompt_number": 8,
        "text": [
         "90"
        ]
       }
      ],
-     "prompt_number": 7
+     "prompt_number": 8
     },
     {
      "cell_type": "markdown",
@@ -339,13 +339,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 8,
+       "prompt_number": 9,
        "text": [
         "90"
        ]
       }
      ],
-     "prompt_number": 8
+     "prompt_number": 9
     },
     {
      "cell_type": "markdown",
@@ -383,13 +383,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 9,
+       "prompt_number": 10,
        "text": [
         "90"
        ]
       }
      ],
-     "prompt_number": 9
+     "prompt_number": 10
     },
     {
      "cell_type": "markdown",
@@ -435,13 +435,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 10,
+       "prompt_number": 11,
        "text": [
         "(90, 'blue')"
        ]
       }
      ],
-     "prompt_number": 10
+     "prompt_number": 11
     },
     {
      "cell_type": "code",
@@ -457,13 +457,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 11,
+       "prompt_number": 12,
        "text": [
         "(93, 'white')"
        ]
       }
      ],
-     "prompt_number": 11
+     "prompt_number": 12
     },
     {
      "cell_type": "markdown",
@@ -519,13 +519,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 12,
+       "prompt_number": 13,
        "text": [
         "(205.02965999999998, 93000)"
        ]
       }
      ],
-     "prompt_number": 12
+     "prompt_number": 13
     },
     {
      "cell_type": "markdown",
@@ -593,13 +593,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 13,
+       "prompt_number": 14,
        "text": [
         "80"
        ]
       }
      ],
-     "prompt_number": 13
+     "prompt_number": 14
     },
     {
      "cell_type": "code",
@@ -614,13 +614,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 14,
+       "prompt_number": 15,
        "text": [
         "79"
        ]
       }
      ],
-     "prompt_number": 14
+     "prompt_number": 15
     },
     {
      "cell_type": "code",
@@ -637,13 +637,13 @@
       {
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 15,
+       "prompt_number": 16,
        "text": [
         "90"
        ]
       }
      ],
-     "prompt_number": 15
+     "prompt_number": 16
     },
     {
      "cell_type": "markdown",
@@ -714,7 +714,7 @@
        ]
       }
      ],
-     "prompt_number": 16
+     "prompt_number": 17
     },
     {
      "cell_type": "markdown",
@@ -744,7 +744,7 @@
       }
      },
      "outputs": [],
-     "prompt_number": 17
+     "prompt_number": 18
     },
     {
      "cell_type": "markdown",
@@ -772,54 +772,32 @@
        ]
       }
      ],
-     "prompt_number": 18
+     "prompt_number": 19
     },
     {
      "cell_type": "markdown",
      "metadata": {
       "slideshow": {
-       "slide_type": "slide"
+       "slide_type": "subslide"
       }
      },
      "source": [
-      "The Sequencer assignment\n",
+      "$\\S$ A stack calculator\n",
       "==="
      ]
     },
     {
-     "cell_type": "code",
-     "collapsed": false,
-     "input": [
-      "class Read(object):\n",
-      "    def __init__(self):\n",
-      "        self.read = []\n",
-      "        self.qual = []\n",
-      "            \n",
-      "    def __str__(self):\n",
-      "        return \"\".join(self.read)\n",
-      "        \n",
-      "    def append(self, base):\n",
-      "        self.read.append(base[0])\n",
-      "        self.qual.append(base[1])\n",
-      "            \n",
-      "    def quality(self):\n",
-      "        return sum(self.qual) / len(self.read)\n",
-      "        \n",
-      "    def trim(self, score):\n",
-      "        for position in range(len(self.read) - 1, -1, -1):\n",
-      "            if self.qual[position] >= score:\n",
-      "                self.read = self.read[:position + 1]\n",
-      "                self.qual = self.qual[:position + 1]\n",
-      "                break"
-     ],
-     "language": "python",
+     "cell_type": "markdown",
      "metadata": {
       "slideshow": {
        "slide_type": "-"
       }
      },
-     "outputs": [],
-     "prompt_number": 19
+     "source": [
+      "A stack is a datastructure that only allows access to the ''top'' element.\n",
+      "\n",
+      "<img src=\"files/images/stack.png\" />"
+     ]
     },
     {
      "cell_type": "markdown",
@@ -829,7 +807,41 @@
       }
      },
      "source": [
-      "The Sequencer assignment\n",
+      "$\\S$ A stack calculator\n",
+      "==="
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Stack operations\n",
+      "---\n",
+      "\n",
+      "* Push - Add one element to the top of the stack.\n",
+      "* Pop - Retrieve the top element from the stack.\n",
+      "\n",
+      "Arithmetic with a stack\n",
+      "---\n",
+      "\n",
+      "* Pop the operands from the stack.\n",
+      "* Perform an arithmetic operation.\n",
+      "* Push the result back to the stack.\n",
+      "\n",
+      "Example (add two numbers):\n",
+      "\n",
+      "    stack.push(stack.pop() + stack.pop())"
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "subslide"
+      }
+     },
+     "source": [
+      "$\\S$ A stack calculator\n",
       "==="
      ]
     },
@@ -837,40 +849,78 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "from sequencer import Sequencer\n",
+      "%load programming-course-assignments/calculator/calculator.py"
+     ],
+     "language": "python",
+     "metadata": {
+      "slideshow": {
+       "slide_type": "skip"
+      }
+     },
+     "outputs": [],
+     "prompt_number": 40
+    },
+    {
+     "cell_type": "code",
+     "collapsed": false,
+     "input": [
+      "#!/usr/bin/env python\n",
       "\n",
-      "spots = 2\n",
-      "run = Sequencer(spots, readlength=60)\n",
+      "class Stack(list):\n",
+      "    def push(self, element):\n",
+      "        self.append(element)\n",
+      "\n",
+      "    def __str__(self):\n",
+      "        return str(self[-1])\n",
       "\n",
-      "reads = [Read() for _ in range(spots)]\n",
-      "for tile in run:\n",
-      "    for read_id, base in enumerate(tile):\n",
-      "        reads[read_id].append(base)\n",
       "\n",
-      "for i in reads:\n",
-      "    print i, i.quality()\n",
-      "    i.trim(39)\n",
-      "    print i, i.quality()"
+      "class Calculator(Stack):\n",
+      "    def add(self):\n",
+      "        self.push(self.pop() + self.pop())\n",
+      "\n",
+      "    def sub(self):\n",
+      "        temp = self.pop()\n",
+      "        self.push(self.pop() - temp)\n",
+      "\n",
+      "    def mul(self):\n",
+      "        self.push(self.pop() * self.pop())\n",
+      "\n",
+      "    def div(self):\n",
+      "        temp = self.pop()\n",
+      "        self.push(self.pop() / temp)\n"
      ],
      "language": "python",
+     "metadata": {},
+     "outputs": []
+    },
+    {
+     "cell_type": "markdown",
      "metadata": {
       "slideshow": {
-       "slide_type": "-"
+       "slide_type": "subslide"
       }
      },
-     "outputs": [
-      {
-       "output_type": "stream",
-       "stream": "stdout",
-       "text": [
-        "AACAGTGAGCAATGCGCACTTCCAGTGCCATGCCTATACGCCGGGCCGTTAAGAATTTAT 31\n",
-        "AACAGTGAGCAATGCGCACTTCCAGTGCCATGCCTATACGCCG 34\n",
-        "CACCTTGAGGTATACGGGCACTACACGAACGTATAATTACCGTATTATGGGTCTCCCAGA 30\n",
-        "CACCTTGAGGTATACGGGCACTACACGAACGTATAATTACCGTATTATG 33\n"
-       ]
-      }
-     ],
-     "prompt_number": 20
+     "source": [
+      "$\\S$ A stack calculator\n",
+      "==="
+     ]
+    },
+    {
+     "cell_type": "markdown",
+     "metadata": {},
+     "source": [
+      "Assignment\n",
+      "---\n",
+      "\n",
+      "* Make a scientific calculator.\n",
+      "* Add exponentiation and square root functions.\n",
+      "\n",
+      "Hints:\n",
+      "\n",
+      "* Do not edit the `calculator.py` file, use `import` instead.\n",
+      "* Use inheritance.\n",
+      "* To use mathematical functions, use the `math` library."
+     ]
     },
     {
      "cell_type": "code",
@@ -884,7 +934,7 @@
      "language": "python",
      "metadata": {
       "slideshow": {
-       "slide_type": "slide"
+       "slide_type": "skip"
       }
      },
      "outputs": [
@@ -892,7 +942,7 @@
        "html": [
         "<style>/* Remove the vertical scrollbar added by nbconvert. */\n",
         ".reveal {\n",
-        "  overflow-y: hidden;\n",
+        "  overflow: hidden;\n",
         "}\n",
         "\n",
         "/* Workaround some highlight.js bugs in language autodetection. */\n",
@@ -917,13 +967,13 @@
        ],
        "metadata": {},
        "output_type": "pyout",
-       "prompt_number": 21,
+       "prompt_number": 22,
        "text": [
-        "<IPython.core.display.HTML at 0x3cc71d0>"
+        "<IPython.core.display.HTML at 0xb182306c>"
        ]
       }
      ],
-     "prompt_number": 21
+     "prompt_number": 22
     }
    ],
    "metadata": {}
diff --git a/images/stack.png b/images/stack.png
new file mode 100644
index 0000000000000000000000000000000000000000..8009df8a2ba76aacb4c380bf48e629027d6b64be
Binary files /dev/null and b/images/stack.png differ
diff --git a/programming-course-assignments b/programming-course-assignments
new file mode 160000
index 0000000000000000000000000000000000000000..44222ed4f2d9b932d6bde32b1587d2668b9dd7da
--- /dev/null
+++ b/programming-course-assignments
@@ -0,0 +1 @@
+Subproject commit 44222ed4f2d9b932d6bde32b1587d2668b9dd7da
diff --git a/solutions/python_08_scientific_calculator.py b/solutions/python_08_scientific_calculator.py
new file mode 100644
index 0000000000000000000000000000000000000000..421f136b2529fb44ecd295293ac5c41f9f93293b
--- /dev/null
+++ b/solutions/python_08_scientific_calculator.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+
+import math
+
+from calculator import Calculator
+
+class ScientificCalculator(Calculator):
+    def pow(self):
+        temp = self.pop()
+        self.push(self.pop() ** temp)
+
+    def sqrt(self):
+        self.push(math.sqrt(self.pop()))
+
+
+s = ScientificCalculator()
+s.push(2)
+s.push(3)
+s.pow()
+print s
+s.sqrt()
+print s