diff --git a/cppcourse/.gitignore b/cppcourse/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..58461f25420fa09ee4a525651a0c54efa1b11af7
--- /dev/null
+++ b/cppcourse/.gitignore
@@ -0,0 +1 @@
+.ipynb_checkpoints
\ No newline at end of file
diff --git a/cppcourse/ClassTemplateFunctionDefinition.ipynb b/cppcourse/ClassTemplateFunctionDefinition.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..cbd90b3fa0c43fd63d8718c9df057db98fb76439
--- /dev/null
+++ b/cppcourse/ClassTemplateFunctionDefinition.ipynb
@@ -0,0 +1,119 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template <typename T>\n",
+    "class Counter\n",
+    "{\n",
+    "public:\n",
+    "    Counter();\n",
+    "    void increment();\n",
+    "    T getValue() const;\n",
+    "private:\n",
+    "    T v_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename T >\n",
+    "Counter<T>::Counter() : v_(0) {}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename T >\n",
+    "void Counter<T>::increment()\n",
+    "{\n",
+    "    ++v_;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename T >\n",
+    "T Counter<T>::getValue() const\n",
+    "{\n",
+    "    return v_;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Counter<short> ctr;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ctr.increment();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ctr.getValue()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/Homework_A.ipynb b/cppcourse/Homework_A.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..7d3cbf37197d80507ff48ea6fb6b5d03bd6947a0
--- /dev/null
+++ b/cppcourse/Homework_A.ipynb
@@ -0,0 +1,153 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Homework A"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Write a function that parses the values from a matrix given as a string to a `std::vector`. A sample 3x4 matrix may be given like this:\n",
+    "\n",
+    "```\n",
+    "2.0 3.2 5.6 7.8\n",
+    "1.0 4.3 6.9 4.4\n",
+    "6.8 2.0 10.8 9.1\n",
+    "```\n",
+    "\n",
+    "Use `double` as a dataype for your vector. Store the values to the vector using [row-major order](https://en.wikipedia.org/wiki/Row-_and_column-major_order). Your function should also report the number of rows `m` and the number of columns `n` to the caller. Implement the following signature:\n",
+    "\n",
+    "```c++\n",
+    "void readMatrix( const std::string & matrix, std::vector<double> & values, unsigned int & m, unsigned int & n )\n",
+    "```\n",
+    "\n",
+    "Also write the opposite function that converts the matrix back to a string:\n",
+    "\n",
+    "```c++\n",
+    "std::string matrixToString( const std::vector<double> & values, const unsigned int m, const unsigned int n )\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// readMatrix"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// matrixToString"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string matrix(\"2.0 3.2 5.6 7.8\\n1.0 4.3 6.9 4.4\\n6.8 2.0 10.8 9.1\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "unsigned int n, m;\n",
+    "std::vector<double> values;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "readMatrix( matrix, values, m, n );\n",
+    "values"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "m // should be 3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "n // should be 4"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "matrixToString( values, m , n )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Also test some corner cases:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string m1(\"2.0\"); // 1x1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string m2(\"\"); // empty matrix (0x0)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/Homework_A_sol.ipynb b/cppcourse/Homework_A_sol.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..4e7e19d09b32064744e3ed3c5096aa4c5e228bed
--- /dev/null
+++ b/cppcourse/Homework_A_sol.ipynb
@@ -0,0 +1,275 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Homework A"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Write a function that parses the values from a matrix given as a string to a `std::vector`. A sample 3x4 matrix may be given like this:\n",
+    "\n",
+    "```\n",
+    "2.0 3.2 5.6 7.8\n",
+    "1.0 4.3 6.9 4.4\n",
+    "6.8 2.0 10.8 9.1\n",
+    "```\n",
+    "\n",
+    "Use `double` as a dataype for your vector. Store the values to the vector using [row-major order](https://en.wikipedia.org/wiki/Row-_and_column-major_order). Your function should also report the number of rows `m` and the number of columns `n` to the caller. Implement the following signature:\n",
+    "\n",
+    "```c++\n",
+    "void readMatrix( const std::string & matrix, std::vector<double> & values, \n",
+    "                 unsigned int & m, unsigned int & n )\n",
+    "```\n",
+    "\n",
+    "Also write the opposite function that converts the matrix back to a string:\n",
+    "\n",
+    "```c++\n",
+    "std::string matrixToString( const std::vector<double> & values,\n",
+    "                            unsigned int m, const unsigned int n )\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <string>\n",
+    "#include <vector>\n",
+    "#include <sstream>\n",
+    "\n",
+    "void readMatrix( const std::string & matrix, \n",
+    "                 std::vector<double> & values, \n",
+    "                 unsigned int & m, unsigned int & n )\n",
+    "{\n",
+    "    values.clear();\n",
+    "    \n",
+    "    std::istringstream iss(matrix);\n",
+    "    \n",
+    "    std::string line;\n",
+    "    m = 0;\n",
+    "    n = 0;\n",
+    "    while( std::getline( iss, line ) )\n",
+    "    {\n",
+    "        ++m;\n",
+    "        std::istringstream issLine( line );\n",
+    "        double v;\n",
+    "        n = 0;\n",
+    "        while( issLine >> v )\n",
+    "        {\n",
+    "            ++n;\n",
+    "            values.push_back( v );\n",
+    "        }\n",
+    "    }\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> vector;\n",
+    "for( int = 0; i < 100; ++i )\n",
+    "{\n",
+    "    vector.assign( 100, i );\n",
+    "    \n",
+    "    // ...\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string matrixToString( const std::vector<double> & values,\n",
+    "                            const unsigned int m, const unsigned int n )\n",
+    "{\n",
+    "    // we should check whether m * n == values.size() but no error handling yet...\n",
+    "    \n",
+    "    std::ostringstream oss;\n",
+    "    \n",
+    "    size_t idx = 0;\n",
+    "    for( unsigned int i = 0; i < m; ++i )\n",
+    "    {\n",
+    "        if( i > 0 )\n",
+    "            oss << \"\\n\";\n",
+    "        \n",
+    "        for( unsigned int j = 0; j < m; ++j )\n",
+    "        {\n",
+    "            if( j > 0 )\n",
+    "                oss << \" \";\n",
+    "            \n",
+    "            oss << values[idx];\n",
+    "            \n",
+    "            ++idx;            \n",
+    "        }\n",
+    "    }\n",
+    "    \n",
+    "    return oss.str();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string matrix(\"2.0 3.2 5.6 7.8\\n1.0 4.3 6.9 4.4\\n6.8 2.0 10.8 9.1\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "unsigned int n, m;\n",
+    "std::vector<double> values;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 2, 3.2, 5.6, 7.8, 1, 4.3, 6.9, 4.4, 6.8, 2, 10.8, 9.1 }"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "readMatrix( matrix, values, m, n );\n",
+    "values"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "m // should be 3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "n // should be 4"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"2 3.2 5.6\n",
+       "7.8 1 4.3\n",
+       "6.9 4.4 6.8\""
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "matrixToString( values, m , n )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Also test some corner cases:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string m1(\"2.0\"); // 1x1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string m2(\"\"); // empty matrix (0x0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/const_demo.ipynb b/cppcourse/const_demo.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..b8bd689ba68633a62bc385ca3372c173126357e1
--- /dev/null
+++ b/cppcourse/const_demo.ipynb
@@ -0,0 +1,551 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int i = 23;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "i = 42;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const int ci = 42;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_10:2:5: error: cannot assign to variable 'ci' with const-qualified type 'const int'\n",
+      " ci = 32;\n",
+      " ~~ ^\n",
+      "input_line_9:2:12: note: variable 'ci' declared const here\n",
+      " const int ci = 42;\n",
+      " ~~~~~~~~~~^~~~~~~\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "ci = 32;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const double dbl = 2.5;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int i2 = 34;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int &ir = i2;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const int &irc = i2;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "62"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << i2;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "62"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << irc;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "i2 = 62;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_23:2:6: error: cannot assign to variable 'irc' with const-qualified type 'const int &'\n",
+      " irc = 32;\n",
+      " ~~~ ^\n",
+      "input_line_15:2:13: note: variable 'irc' declared const here\n",
+      " const int &irc = i2;\n",
+      " ~~~~~~~~~~~^~~~~~~~\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "irc = 32;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const int ic2 = 42;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const int &irc2 = i2;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_26:2:7: error: binding value of type 'const int' to reference to type 'int' drops 'const' qualifier\n",
+      " int &irc2 = ic2;\n",
+      "      ^      ~~~\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "int &irc2 = ic2;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int i = 23;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int *pi = &i;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int *const pci = &i;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "23"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "std::cout << i;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "23"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*pi"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "23"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*pci"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "*pi = 42;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "42"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*pi"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "42"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*pci"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "*pci = 63;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "63"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*pi"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_29:2:6: error: cannot assign to variable 'pci' with const-qualified type 'int *const'\n",
+      " pci = nullptr;\n",
+      " ~~~ ^\n",
+      "input_line_11:2:13: note: variable 'pci' declared const here\n",
+      " int *const pci = &i;\n",
+      " ~~~~~~~~~~~^~~~~~~~\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "pci = nullptr;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const int *pci2 = &i;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_31:2:8: error: read-only variable is not assignable\n",
+      " *pci2 = 52;\n",
+      " ~~~~~ ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "*pci2 = 52;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "pci2 = nullptr;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const int * const pci3 = &i;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_34:2:7: error: cannot assign to variable 'pci3' with const-qualified type 'const int *const'\n",
+      " pci3 = nullptr;\n",
+      " ~~~~ ^\n",
+      "input_line_33:2:20: note: variable 'pci3' declared const here\n",
+      " const int * const pci3 = &i;\n",
+      " ~~~~~~~~~~~~~~~~~~^~~~~~~~~\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "pci3 = nullptr;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_36:2:8: error: read-only variable is not assignable\n",
+      " *pci3 = 67;\n",
+      " ~~~~~ ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "*pci3 = 67;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/const_exercise.ipynb b/cppcourse/const_exercise.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..6de0277ea791d3220db6880f85b14f503e69dec1
--- /dev/null
+++ b/cppcourse/const_exercise.ipynb
@@ -0,0 +1,85 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercise `const`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Which of the following initializations are legal? Explain why."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "- `int i2 = -1, &r = 0;`\n",
+    "- `int *const p2 = &i2;`\n",
+    "- `const int i = -1, &r = 0;`\n",
+    "- `const int *const p3 = &i2;`\n",
+    "- `const int *p1 = &i2;`\n",
+    "- `const int &const r2;`\n",
+    "- `const int i2 = i, &r = i;`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Explain the following definitions. Identify any that are illegal."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "- `int i, *const cp;`\n",
+    "- `int *p1, *const p2;`\n",
+    "- `const int ic, &r = ic;`\n",
+    "- `const int *const p3;`\n",
+    "- `const int *p;`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Using the variables in the previous exercise, which of the following assignments are legal? Explain why.\n",
+    "- `i = ic;`\n",
+    "- `p1 = p3;`\n",
+    "- `p1 = &ic;`\n",
+    "- `p3 = &ic;`\n",
+    "- `p2 = p1;`\n",
+    "- `ic = *p3;`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture00.ipynb b/cppcourse/lecture00.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..ea458bd765c7909258348c7247cdecc551ac7064
--- /dev/null
+++ b/cppcourse/lecture00.ipynb
@@ -0,0 +1,128 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# C++ Course\n",
+    "\n",
+    "## Christian Godenschwager\n",
+    "\n",
+    "### Friedrich-Alexander-Universität (FAU) Erlangen, Germany\n",
+    "\n",
+    "#### April 2018, Curitiba, Brazil"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Systems Simulations Group led by Prof. Ulrich Rüde\n",
+    "\n",
+    "- Large scale simulations on millions of CPU cores\n",
+    "- High Performance Computing (HPC) software development\n",
+    "- 2 large, massively parrallel C++ codes:\n",
+    "    - waLBerla: Lattice Boltzmann fluid dynamics\n",
+    "    - TERRANEO: Simulation of earth mantle convection"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "##  Questions?\n",
+    "\n",
+    "During the course: just ask!\n",
+    "\n",
+    "Outside of the course: christian.godenschwager@fau.de"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Which programming languages have you used before?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Why C++?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "- Huge codebase\n",
+    "\n",
+    "- High performance (if you know what you're doing)\n",
+    "\n",
+    "- International Standard (currently C++17, new standard every three years)\n",
+    "\n",
+    "- Large user base in industry -> very good backwards compatibility"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Sources\n",
+    "\n",
+    "Main source for this course is the __C++ Primer__ (fifth edition)\n",
+    "\n",
+    "Good book _but_:\n",
+    "    - very focused on sytax not so much on concepts of the language\n",
+    "    - Only C++11\n",
+    "    \n",
+    "Book situation on C++ is difficult due to the large amount of additions C++11/14 braught to C++"
+   ]
+  }
+ ],
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture01.ipynb b/cppcourse/lecture01.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..edc91230bda12c292a6ce208dfb9fa0a30c14e9c
--- /dev/null
+++ b/cppcourse/lecture01.ipynb
@@ -0,0 +1,1151 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Lecture 1:\n",
+    "# IO, Comments, Basic Types and Control Flow"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Hello World!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Hello World!\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "std::cout << \"Hello World!\" << std::endl; "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Output"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "First you need to include the C++ input/output library "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "#include <iostream>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Normal output of your application should be written to the standard output stream\n",
+    "\n",
+    "The C++ input/output library offers the global object `std::cout` to print on the standard output stream\n",
+    "\n",
+    "You can print something using the __insertion operator__ (`<<`)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Everything is working well!"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << \"Everything is working well!\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Errors should be printed to the standard error stream `std::cerr`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "Oh no, an error!"
+     ]
+    }
+   ],
+   "source": [
+    "std::cerr << \"Oh no, an error!\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Multi-line outputs can be generated with the line break character `\\n`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Line 1\n",
+      "Line 2\n",
+      "Line 3"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << \"Line 1\\nLine 2\\nLine 3\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "More elegant:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Line 1\n",
+      "Line 2\n",
+      "Line 3"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << \"Line 1\\n\"\n",
+    "          << \"Line 2\\n\"\n",
+    "          << \"Line 3\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Comments"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "You can have line comments that span to end of the line"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Comments are important!"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "@0x349bf40"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::cout << \"Comments are important!\"; // This is a single line comment"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "There are also block comments where you mark the beginning and the end"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Comments are important!"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << \"Comments are \"; /* This is a block comment */ std::cout << \"important!\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Comments are important!"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << \"Comments are \";\n",
+    "/* A block comment\n",
+    "   can span multiple lines */\n",
+    "std::cout << \"important!\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "/* Watch out! Nested Block comments are not valid */ "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Primitive Built-In Types"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "C++ is a strongly typed language\n",
+    "\n",
+    "Each variable is of a specific type\n",
+    "\n",
+    "The predefined primitive types are `void` and a set of __arithemtic types__\n",
+    "\n",
+    "`void` marks the absence of a value and can be used only at a few places\n",
+    "\n",
+    "The __arithmetic types__ are composed of __integral types__ and __floating-point types__\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "### Integral Types\n",
+    "\n",
+    "| Type | Meaning | Minimum Size |\n",
+    "| --- | --- | --- | --- |\n",
+    "| bool | boolean | NA |\n",
+    "| char | character | 8 bits | \n",
+    "| short | short integer | 16 bits |\n",
+    "| int | integer | 16 bits | \n",
+    "| long | long integer | 32 bits | \n",
+    "| long long | long integer | 64 bits |"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Actual sizes of the integral data types in this imeplementation"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "bool:      8 bits\n",
+      "char:      8 bits\n",
+      "short:     16 bits\n",
+      "int:       32 bits\n",
+      "long:      64 bits\n",
+      "long long: 64 bits\n"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << \"bool:      \" << 8 * sizeof(bool)      << \" bits\\n\";\n",
+    "std::cout << \"char:      \" << 8 * sizeof(char)      << \" bits\\n\";\n",
+    "std::cout << \"short:     \" << 8 * sizeof(short)     << \" bits\\n\";\n",
+    "std::cout << \"int:       \" << 8 * sizeof(int)       << \" bits\\n\";\n",
+    "std::cout << \"long:      \" << 8 * sizeof(long)      << \" bits\\n\";\n",
+    "std::cout << \"long long: \" << 8 * sizeof(long long) << \" bits\\n\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "#### Signedness of integral types\n",
+    "\n",
+    "Except for `bool` all types above come in a `signed` and and `unsigned` variant.\n",
+    "\n",
+    "E.g. `signed int` or `unsigned long`\n",
+    "\n",
+    "If you do not specify the signedness the default is `signed`\n",
+    "\n",
+    "Only for `char` this is implementation defined and you cannot rely on `char` to be a `signed char`!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "char:      1\n",
+      "short:     1\n",
+      "int:       1\n",
+      "long:      1\n",
+      "long long: 1\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <limits>\n",
+    "\n",
+    "std::cout << \"char:      \" << std::numeric_limits<char>::is_signed      << \"\\n\";\n",
+    "std::cout << \"short:     \" << std::numeric_limits<short>::is_signed     << \"\\n\";\n",
+    "std::cout << \"int:       \" << std::numeric_limits<int>::is_signed       << \"\\n\";\n",
+    "std::cout << \"long:      \" << std::numeric_limits<long>::is_signed      << \"\\n\";\n",
+    "std::cout << \"long long: \" << std::numeric_limits<long long>::is_signed << \"\\n\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Warning: unsigned and signed do not mix well!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "-3\n",
+      "4294967293\n"
+     ]
+    }
+   ],
+   "source": [
+    "int i = 5;\n",
+    "unsigned int u = 5;\n",
+    "\n",
+    "int i2 = -8;\n",
+    "\n",
+    "std::cout << i + i2 << \"\\n\";\n",
+    "std::cout << u + i2 << \"\\n\";\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "#### Literals for integral types\n",
+    "\n",
+    "If you write a literal decimal number like `2018` in your C++ is is assigned the smallest type of `int`, `long` or `long long` that fits the number.\n",
+    "\n",
+    "You can use suffixes to control the chosen type and the signedness:\n",
+    "\n",
+    "| Suffix | Minimum Type |\n",
+    "| --- | --- |\n",
+    "| `u` or `U` | unsigned |\n",
+    "| `l` or `L` | long |\n",
+    "| `ll` or `LL` | long long |"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Examples:\n",
+    "\n",
+    "`5` is of type `int`\n",
+    "\n",
+    "`5u` is of type `unsigned int`\n",
+    "\n",
+    "`5l`  is of type `long`\n",
+    "\n",
+    "`5ull`  is of type `unsigned long long`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "#### Character and string literals\n",
+    "\n",
+    "`'a'` is a character literal and is of type `char`\n",
+    "\n",
+    "\"Hello World\" is a string literal, a zero (`'\\0'`) terminated array of `char`s"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Floating-Point Types\n",
+    "\n",
+    "| Type | Meaning | Minimum Size |\n",
+    "| --- | --- | --- | --- |\n",
+    "| float | single-precision floating point | 6 significant disgits |\n",
+    "| double | double-precision floating point | 10 significant disgits | \n",
+    "| long double | extended-precision floating point | 10 significant disgits |"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {
+    "scrolled": true,
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "float:       32 bits\n",
+      "double:      64 bits\n",
+      "long double: 128 bits\n"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << \"float:       \" << 8 * sizeof(float)       << \" bits\\n\";\n",
+    "std::cout << \"double:      \" << 8 * sizeof(double)      << \" bits\\n\";\n",
+    "std::cout << \"long double: \" << 8 * sizeof(long double) << \" bits\\n\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "#### Signedness of floating-point types\n",
+    "\n",
+    "floating-point types are always signed"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "#### Literals for floating-point types\n",
+    "\n",
+    "Floating point types are identified either by a decimal point or an exponent\n",
+    "\n",
+    "By default they are of type `double`\n",
+    "\n",
+    "A different type can be chosen via Suffix\n",
+    "\n",
+    "You can use suffixes to control the chosen type and the signedness:\n",
+    "\n",
+    "| Suffix | Type |\n",
+    "| --- | --- |\n",
+    "| `f` or `F` | `float` |\n",
+    "| `l` or `L` | `long double` |"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "Examples:\n",
+    "\n",
+    "`5.0`, `5e-1` (0.5) and `-5.2e2` (-520.0) are of type `double`\n",
+    "\n",
+    "`5.0f`, `5e-1f` and `-5.2e2f` are of type `float`\n",
+    "\n",
+    "`5.0l`, `5e-1l` and `-5.2e2l` are of type `long double`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Variables\n",
+    "## Variable Definition \n",
+    "A variable definition constists of a type specifier (e.g. int or double), followed by a list of one or more variable names. Optionally, an initial value can be provided."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "int value; // defines the variable value of type int\n",
+    "double fp = 0.0; // defines variable fp of type double and initializes it with 0"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "__Watch Out: Variables of arithmetic types are not default initialized to 0!__\n",
+    "\n",
+    "In most cases it is considered bad practice to declare uninitialized variables\n",
+    "\n",
+    "Accessing uninitialized variables leads to __undefined behavior__"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Identifiers\n",
+    "Identifiers in C++ (e.g. variable names) con be composed of letters, digits and underscores (_).\n",
+    "\n",
+    "They must begin with eitehr a letter or an underscore.\n",
+    "\n",
+    "Identifiers are case-sensitive (e.g. `value` and `Value` are distinct identifiers)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### Disallowed identifiers\n",
+    "The C++ Standard reserves some identifiers for internal use:\n",
+    "- Everything containing two consecutive underscores\n",
+    "- Everything beginning with an underscore followed by an uppercase letter\n",
+    "- Everything outside of functions beginning with an underscore\n",
+    "- Any of the C++ keywords"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "### C++ Keywords\n",
+    "\n",
+    "alignas \n",
+    "alignof\n",
+    "and\n",
+    "and_eq\n",
+    "asm\n",
+    "atomic_cancel \n",
+    "atomic_commit \n",
+    "atomic_noexcept\n",
+    "auto\n",
+    "bitand\n",
+    "bitor\n",
+    "bool\n",
+    "break \n",
+    "case\n",
+    "catch \n",
+    "char \n",
+    "char16_t \n",
+    "char32_t \n",
+    "class\n",
+    "compl\n",
+    "concept \n",
+    "const\n",
+    "constexpr \n",
+    "const_cast\n",
+    "continue\n",
+    "co_await \n",
+    "co_return \n",
+    "co_yield \n",
+    "decltype \n",
+    "default\n",
+    "delete\n",
+    "do\n",
+    "double\n",
+    "dynamic_cast\n",
+    "else\n",
+    "enum\n",
+    "explicit\n",
+    "export\n",
+    "extern\n",
+    "false\n",
+    "float\n",
+    "for\n",
+    "friend\n",
+    "goto\n",
+    "if\n",
+    "import \n",
+    "inline\n",
+    "int\n",
+    "long\n",
+    "module \n",
+    "mutable\n",
+    "namespace\n",
+    "new\n",
+    "noexcept \n",
+    "not\n",
+    "not_eq\n",
+    "nullptr \n",
+    "operator\n",
+    "or\n",
+    "or_eq\n",
+    "private\n",
+    "protected\n",
+    "public\n",
+    "register\n",
+    "reinterpret_cast\n",
+    "requires \n",
+    "return\n",
+    "short\n",
+    "signed\n",
+    "sizeof\n",
+    "static\n",
+    "static_assert \n",
+    "static_cast\n",
+    "struct\n",
+    "switch\n",
+    "synchronized \n",
+    "template\n",
+    "this\n",
+    "thread_local \n",
+    "throw\n",
+    "true\n",
+    "try\n",
+    "typedef\n",
+    "typeid\n",
+    "typename\n",
+    "union\n",
+    "unsigned\n",
+    "using\n",
+    "virtual\n",
+    "void\n",
+    "volatile\n",
+    "wchar_t\n",
+    "while\n",
+    "xor\n",
+    "xor_eq "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Scopes\n",
+    "A name usually refers to a single entity (e.g. a variable).\n",
+    "\n",
+    "However, a name can be reused in a different _scope_\n",
+    "\n",
+    "Names that visiable throughout the whole program have __global scope__\n",
+    "\n",
+    "Name sthat are visible only in __block__ have __block scope__ "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_14:8:14: error: use of undeclared identifier 'i42'\n",
+      "std::cout << i42; // Ooops, i is out of scope\n",
+      "             ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "int sum = 0; // sum has global scope\n",
+    "for( int i42 = 0; i < 10; ++i ) // i has block scope\n",
+    "{ // curly braces start a new block\n",
+    "    sum += i42;\n",
+    "} // block ends here\n",
+    "\n",
+    "std::cout << sum; // OK, sum is in scope\n",
+    "std::cout << i42; // Ooops, i is out of scope"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_15:2:6: error: redefinition of 'sum2'\n",
+      " int sum2 = 0; // sum2 has global scope, sum would clash with the sum defined above\n",
+      "     ^\n",
+      "input_line_9:2:6: note: previous definition is here\n",
+      " int sum2 = 0; // sum2 has global scope, sum would clash with the sum defined above\n",
+      "     ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "int sum2 = 0; // sum2 has global scope, sum would clash with the sum defined above\n",
+    "int i = 0; // i has global scope\n",
+    "while( i < 10 )\n",
+    "{ \n",
+    "    sum2 += i;\n",
+    "    ++i;\n",
+    "}\n",
+    "\n",
+    "std::cout << sum2 << \"\\n\";\n",
+    "std::cout << i; //OK, i has global scope now"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "i at block scope: 5\n",
+      "i at global scope: 10\n"
+     ]
+    }
+   ],
+   "source": [
+    "{ // you can also start a new block without using a loop or if\n",
+    "    int i = 5;\n",
+    "    std::cout << \"i at block scope: \" << i << \"\\n\" ;\n",
+    "}\n",
+    "std::cout << \"i at global scope: \" << i << \"\\n\" ;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "__Watch Out: variables with the same name at different scope can be very confusing!__\n",
+    "\n",
+    "Rule: Try to avoid shadowing of variables, e.g. defining variables with the same name in different scopes!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Control Flow\n",
+    "\n",
+    "To go beyond sequential execution of your statements you need two things: branches and loops"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "## `while` loop\n",
+    "\n",
+    "The `while` loop repeats a statement as long as a conditions evaluates to `true`\n",
+    "\n",
+    "__while__ (_condition_)  \n",
+    "&nbsp;&nbsp;&nbsp;&nbsp;_statement_"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0 1 2 3 4 5 6 7 8 9 "
+     ]
+    }
+   ],
+   "source": [
+    "int var = 0;\n",
+    "while( var < 10 )\n",
+    "{\n",
+    "    std::cout << var << \" \";\n",
+    "    ++var; // same as var = var + 1;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## `for` loop\n",
+    "\n",
+    "The `for` loop extends the while loop with an init statement and an expression that is esecuted at the end of the loop body\n",
+    "\n",
+    "__for__ (_init-statement_, _condition_, _expression_)  \n",
+    "&nbsp;&nbsp;&nbsp;&nbsp;_statement_"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0 1 2 3 4 5 6 7 8 9 "
+     ]
+    }
+   ],
+   "source": [
+    "for( int var = 0; var < 10; ++var )\n",
+    "{\n",
+    "    std::cout << var << \" \";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## `if` statement\n",
+    "\n",
+    "The `if` statement introduces branching into your code\n",
+    "\n",
+    "__if__ (_condition_)  \n",
+    "&nbsp;&nbsp;&nbsp;&nbsp;_statement_  \n",
+    "[__else__  \n",
+    "&nbsp;&nbsp;&nbsp;&nbsp;_statement_]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0 is even\n",
+      "1 is odd\n",
+      "2 is even\n",
+      "3 is odd\n",
+      "4 is even\n",
+      "5 is odd\n",
+      "6 is even\n",
+      "7 is odd\n",
+      "8 is even\n",
+      "9 is odd\n"
+     ]
+    }
+   ],
+   "source": [
+    "for( int var = 0; var < 10; ++var )\n",
+    "{\n",
+    "    if( var % 2 == 0 )\n",
+    "    {\n",
+    "        std::cout << var << \" is even\\n\";\n",
+    "    }\n",
+    "    else\n",
+    "    {\n",
+    "        std::cout << var << \" is odd\\n\";\n",
+    "    }\n",
+    "}"
+   ]
+  }
+ ],
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  },
+  "rise": {
+   "theme": "sky"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture01_ex.ipynb b/cppcourse/lecture01_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..2982323854943b20a791024d4b7042721cb00c34
--- /dev/null
+++ b/cppcourse/lecture01_ex.ipynb
@@ -0,0 +1,465 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Excersises to Lecture 1"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# https://cppdemo.walberla.net/"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Literal Constants\n",
+    "What is the type of each of these literal constants:\n",
+    "\n",
+    "- `-10`\n",
+    "- `-10U`\n",
+    "- `false`\n",
+    "- `-10.`\n",
+    "- `-10E-2`\n",
+    "- `'X'`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Type checker snippet\n",
+    "To validate your answers above (obviously, after you have thought of an answer by yourself 😉) use the following function:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <typeinfo>\n",
+    "#include <string>\n",
+    "#include <boost/core/demangle.hpp>\n",
+    "\n",
+    "template< typename T >\n",
+    "std::string typeNameAsString( const T & /*value*/ )\n",
+    "{\n",
+    "    return boost::core::demangle( typeid(T).name() );\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The snippet defines a function `typeNameAsString` which can be used like this:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "std::cout << typeNameAsString(32) << \"\\n\";\n",
+    "\n",
+    "std::cout << typeNameAsString(3.2f) << \"\\n\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Names \n",
+    "Which, if any, of the following identifiers are valid?\n",
+    "\n",
+    "- `int double = 3.14159;`\n",
+    "- `bool catch-22;`\n",
+    "- `float Float = 3.14F;`\n",
+    "- `char _;`\n",
+    "- `char 1_or_2 = '1';`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Check your answers below:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int double = 3.14159;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "bool catch-22;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "float Float = 3.14F;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "char _;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "char 1_or_2 = '1';"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Code Fragments\n",
+    "\n",
+    "### sum I\n",
+    "\n",
+    "Given the following code fragment:\n",
+    "```c++\n",
+    "int i = 100, sum = 0;\n",
+    "for( int i = 0; i != 10; ++i )\n",
+    "    sum += i;\n",
+    "std::cout << \"  i: \" << i << std::endl;\n",
+    "std::cout << \"sum: \" << sum << std::endl;\n",
+    "```\n",
+    "which values are printed?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Check your answer here:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "// openening a block here avoids refinition errors (e.g. for i)\n",
+    "// if you run the cell multiple times because variables are not declared at global scope\n",
+    "{\n",
+    "    int i = 100, sum = 0;\n",
+    "    for( int i = 0; i != 10; ++i )\n",
+    "        sum += i;\n",
+    "    std::cout << \"  i: \" << i << std::endl;\n",
+    "    std::cout << \"sum: \" << sum << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### sum II\n",
+    "\n",
+    "What is the ouput of the following code fragement?\n",
+    "\n",
+    "```c++\n",
+    "unsigned int length1 = 10U, length2 = 12U;\n",
+    "unsigned int sum = 0U;\n",
+    "for( unsigned int i = 0U; i < length1-length2; ++i )\n",
+    "    sum += i;\n",
+    "std::cout << \"sum: \" << sum << std::endl;\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Check your answer:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    unsigned int length1 = 10U, length2 = 12U;\n",
+    "    unsigned int sum = 0U;\n",
+    "    for( unsigned int i = 0U; i < length1 - length2; ++i )\n",
+    "        sum += i;\n",
+    "    std::cout << \"sum: \" << sum << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### sum III\n",
+    "What is printed in this code fragment?\n",
+    "```c++\n",
+    "    unsigned int sum = 0U;\n",
+    "    for( unsigned int i = 100U; i >= 0U; --i )\n",
+    "        sum += i;\n",
+    "    std::cout << \"sum: \" << sum << std::endl;\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Check your answer, if you dare:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    unsigned int sum = 0U;\n",
+    "    for( unsigned int i = 100U; i >= 0U; --i )\n",
+    "        sum += i;\n",
+    "    std::cout << \"sum: \" << sum << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Just in case 😉: You can stop a kernel trapped in an infinite loop using the menu Kernel -> Interrupt or the ■ button in the toolbar."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## xwdigets\n",
+    "For the input values of the code snippets we will use [xwidgets](https://github.com/QuantStack/xwidgets). If you are interested, a tour through all the widgets available can be found in [this notebook](xwidgets.ipynb)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// The parts of xwidgets we need for this exercise\n",
+    "#include <xwidgets/xnumeral.hpp>\n",
+    "#include <xcpp/xdisplay.hpp>\n",
+    "\n",
+    "using xcpp::display;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Assigining values to and reading values from an xwidget"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "xw::numeral<int> demoWidget; // declaring a \"numeral\" widget of type int\n",
+    "demoWidget.value = 1; // assigning a value to the widget\n",
+    "display(demoWidget); // displaying the widget in the notebook"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "// reading a value from the widget using .value()\n",
+    "std::cout << demoWidget.value();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Range sum\n",
+    "Write a snippet that sums the numbers in the range `begin` to `end` (including `begin`, excluding `end`) and print the result to `std::cout`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// Create two widgets for the range boundaries\n",
+    "xw::numeral<int> begin;\n",
+    "begin.value = 1;\n",
+    "begin.description = \"Range begin\";\n",
+    "xw::numeral<int> end;\n",
+    "end.value = 5;\n",
+    "end.description = \"Range end\";\n",
+    "\n",
+    "display(begin);\n",
+    "display(end);\n",
+    "\n",
+    "// you can access the value of the range boundaries using begin.value() and end.value()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "/* Add your Code here */"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Factorial\n",
+    "\n",
+    "Write a snippet that calculates the factorial of the given number `n` and writes it to the standard output. \n",
+    "\n",
+    "Verify your program at least against the following test cases:\n",
+    "\n",
+    "$$\t\\begin{eqnarray*}\n",
+    "\t\t& 0!=1 \\quad  ; \\quad 1!=1 \\quad ; \\quad 6!=720 \\quad ; \\quad 12!=479001600 &  \\\\\n",
+    "\t\t& 13!=6227020800 \\quad ; \\quad 21!\\approx 5.1091e19 & \\\\\n",
+    "\t\t& 35!\\approx 1.0333e40 \\quad ; \\quad -1!=? &\n",
+    "\t\\end{eqnarray*}\n",
+    "$$\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "// Create a widget for n\n",
+    "xw::numeral<int> n;\n",
+    "n.description = \"n\";\n",
+    "n.value = 3;\n",
+    "display(n);\n",
+    "\n",
+    "// you can access the value of the widget using n.value()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "/* Add your Code here */"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Prime Numbers\n",
+    "\n",
+    "Write a snippet that prints all prime numbers up to `maxPrime` using a trial divide algrithm. You may or may not use the provided hints."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// Create a widget for mapRime\n",
+    "xw::numeral<int> maxPrime;\n",
+    "maxPrime.description = \"max. Prime\";\n",
+    "maxPrime.value = 100;\n",
+    "maxPrime.max = 1000000; // overwrite the default maximum number of 100\n",
+    "display(maxPrime);\n",
+    "\n",
+    "// you can access the value of the widget using maxPrime.value()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// fill out the blanks (or write your own code if you like)\n",
+    "for( int i = ; ; )\n",
+    "{\n",
+    "    bool isPrime = ;\n",
+    "    for( int j = ; ;  )\n",
+    "    {\n",
+    "        if( )\n",
+    "        {\n",
+    "            isPrime = false;\n",
+    "        }\n",
+    "    }\n",
+    "    if( isPrime )\n",
+    "    {\n",
+    "        std::cout ;\n",
+    "    }\n",
+    "}"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture01_ex_sol.ipynb b/cppcourse/lecture01_ex_sol.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..e358f4f81915f4ebc75256038eb375cfce5c3d38
--- /dev/null
+++ b/cppcourse/lecture01_ex_sol.ipynb
@@ -0,0 +1,593 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Excersises to Lecture 1"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Literal Constants\n",
+    "What is the type of each of these literal constants:\n",
+    "\n",
+    "- `-10`\n",
+    "- `-10U`\n",
+    "- `false`\n",
+    "- `-10.`\n",
+    "- `-10E-2`\n",
+    "- `'X'`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Type checker snippet\n",
+    "To validate your answers above (obviously, after you have thought of an answer by yourself 😉) use the following function:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <typeinfo>\n",
+    "#include <string>\n",
+    "#include <boost/core/demangle.hpp>\n",
+    "\n",
+    "template< typename T >\n",
+    "std::string typeNameAsString( const T & /*value*/ )\n",
+    "{\n",
+    "    return boost::core::demangle( typeid(T).name() );\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The snippet defines a function `typeNameAsString` which can be used like this:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "std::cout << typeNameAsString(32) << \"\\n\";\n",
+    "\n",
+    "std::cout << typeNameAsString(3.2f) << \"\\n\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Names \n",
+    "Which, if any, of the following identifiers are valid?\n",
+    "\n",
+    "- `int double = 3.14159;`\n",
+    "- `bool catch-22;`\n",
+    "- `float Float = 3.14F;`\n",
+    "- `char _;`\n",
+    "- `char 1_or_2 = '1';`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Check your answers below:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int double = 3.14159;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "bool catch-22;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "float Float = 3.14F;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "char _;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "char 1_or_2 = '1';"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Code Fragments\n",
+    "\n",
+    "### sum I\n",
+    "\n",
+    "Given the following code fragment:\n",
+    "```c++\n",
+    "int i = 100, sum = 0;\n",
+    "for( int i = 0; i != 10; ++i )\n",
+    "    sum += i;\n",
+    "std::cout << \"  i: \" << i << std::endl;\n",
+    "std::cout << \"sum: \" << sum << std::endl;\n",
+    "```\n",
+    "which values are printed?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Check your answer here:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "// openening a block here avoids refinition errors (e.g. for i)\n",
+    "// if you run the cell multiple times because variables are not declared at global scope\n",
+    "{\n",
+    "    int i = 100, sum = 0;\n",
+    "    for( int i = 0; i != 10; ++i )\n",
+    "        sum += i;\n",
+    "    std::cout << \"  i: \" << i << std::endl;\n",
+    "    std::cout << \"sum: \" << sum << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### sum II\n",
+    "\n",
+    "What is the ouput of the following code fragement?\n",
+    "\n",
+    "```c++\n",
+    "unsigned int length1 = 10U, length2 = 12U;\n",
+    "unsigned int sum = 0U;\n",
+    "for( unsigned int i = 0U; i < length1-length2; ++i )\n",
+    "    sum += i;\n",
+    "std::cout << \"sum: \" << sum << std::endl;\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Check your answer:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    unsigned int length1 = 10U, length2 = 12U;\n",
+    "    unsigned int sum = 0U;\n",
+    "    for( unsigned int i = 0U; i < length1 - length2; ++i )\n",
+    "        sum += i;\n",
+    "    std::cout << \"sum: \" << sum << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### sum III\n",
+    "What is printed in this code fragment?\n",
+    "```c++\n",
+    "    unsigned int sum = 0U;\n",
+    "    for( unsigned int i = 100U; i >= 0U; --i )\n",
+    "        sum += i;\n",
+    "    std::cout << \"sum: \" << sum << std::endl;\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Check your answer if you dare:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    unsigned int sum = 0U;\n",
+    "    for( unsigned int i = 100U; i >= 0U; --i )\n",
+    "        sum += i;\n",
+    "    std::cout << \"sum: \" << sum << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Just in case 😉: You can stop a kernel trapped in an infinite loop using the menu Kernel -> Interrupt or the ■ button in the toolbar."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## xwdigets\n",
+    "For the input values of the code snippets we will use [xwidgets](https://github.com/QuantStack/xwidgets). If you are interested, a tour through all the widgets available can be found in [this notebook](xwidgets.ipynb)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// The parts of xwidgets we need for this exercise\n",
+    "#include <xwidgets/xnumeral.hpp>\n",
+    "#include <xcpp/xdisplay.hpp>\n",
+    "\n",
+    "using xcpp::display;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Assigining values to and reading values from an xwidget"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "1bd54644dcad4c66b180b7f140928f65",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "xw::numeral<int> demoWidget; // declaring a \"numeral\" widget of type int\n",
+    "demoWidget.value = 1; // assigning a value to the widget\n",
+    "display(demoWidget); // displaying the widget in the notebook"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "// reading a value from the widget using .value()\n",
+    "std::cout << demoWidget.value();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Range sum\n",
+    "Write a snippet that sums the numbers in the range `begin` to `end` (including `begin`, excluding `end`) and print the result to `std::cout`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "d180837fb9194d87a7962c0644b8692d",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "c7300f7ceb254c928f6e9eba8febf5f5",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "// Create two widgets for the range boundaries\n",
+    "xw::numeral<int> begin;\n",
+    "begin.value = 1;\n",
+    "begin.description = \"Range begin\";\n",
+    "xw::numeral<int> end;\n",
+    "end.value = 5;\n",
+    "end.description = \"Range end\";\n",
+    "\n",
+    "display(begin);\n",
+    "display(end);\n",
+    "\n",
+    "// you can access the value of the range boundaries using begin.value() and end.value()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "45"
+     ]
+    }
+   ],
+   "source": [
+    "/* Add your Code here */\n",
+    "#include <iostream>\n",
+    "\n",
+    "{\n",
+    "    int sum = 0;\n",
+    "    for( int i = begin.value(); i < end.value(); ++i )\n",
+    "    {\n",
+    "        sum += i;\n",
+    "    }\n",
+    "    std::cout << sum;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Factorial\n",
+    "\n",
+    "Write a snippet that calculates the factorial of the given number `n` and writes it to the standard output. \n",
+    "\n",
+    "Verify your program at least against the following test cases:\n",
+    "\n",
+    "$$\t\\begin{eqnarray*}\n",
+    "\t\t& 0!=1 \\quad  ; \\quad 1!=1 \\quad ; \\quad 6!=720 \\quad ; \\quad 12!=479001600 &  \\\\\n",
+    "\t\t& 13!=6227020800 \\quad ; \\quad 21!\\approx 5.1091e19 & \\\\\n",
+    "\t\t& 35!\\approx 1.0333e40 \\quad ; \\quad -1!=? &\n",
+    "\t\\end{eqnarray*}\n",
+    "$$\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "878954cbce8e4a4481fd4bea2940f90e",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "// Create a widget for n\n",
+    "xw::numeral<int> n;\n",
+    "n.description = \"n\";\n",
+    "n.value = 3;\n",
+    "display(n);\n",
+    "\n",
+    "// you can access the value of the widget using n.value()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "6"
+     ]
+    }
+   ],
+   "source": [
+    "if( n.value() < 0 )\n",
+    "{\n",
+    "    std::cout << \"?\";\n",
+    "}\n",
+    "else\n",
+    "{\n",
+    "    double fac = 1.0;\n",
+    "    for( int i = 2; i <= n.value(); ++i )\n",
+    "    {\n",
+    "        double factor = i;\n",
+    "        fac *= factor;\n",
+    "    }\n",
+    "    std::cout << fac;\n",
+    "}\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Prime Numbers\n",
+    "\n",
+    "Write a snippet that prints all numbers up to `maxPrime` using a trial divide algrithm. You may or may not use the provided hints."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "6b077212b6fd40b5a792b9e95bb3f2df",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "// Create a widget for maxPrime\n",
+    "xw::numeral<int> maxPrime;\n",
+    "maxPrime.description = \"max. Prime\";\n",
+    "maxPrime.value = 100;\n",
+    "maxPrime.max = 1000000; // overwrite the default maximum number of 100\n",
+    "display(maxPrime);\n",
+    "\n",
+    "// you can access the value of the widget using maxPrime.value()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 "
+     ]
+    }
+   ],
+   "source": [
+    "for( int i = 2; i <= maxPrime.value(); ++i )\n",
+    "{\n",
+    "    bool isPrime = i % 2 != 0;\n",
+    "    \n",
+    "    if( i == 2 )\n",
+    "        isPrime = true;\n",
+    "    \n",
+    "    for( int j = 3; j < i; j += 2 )\n",
+    "    {\n",
+    "        if( i % j == 0 )\n",
+    "            isPrime = false;\n",
+    "    }\n",
+    "    if( isPrime )\n",
+    "        std::cout << i << \" \";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture02.ipynb b/cppcourse/lecture02.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..24b8094d34463b78b4bda7242a208c87bcd897fe
--- /dev/null
+++ b/cppcourse/lecture02.ipynb
@@ -0,0 +1,402 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Lecture 2:\n",
+    "\n",
+    "# Compound Types, References"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "A compound type is a type which is defined in terms of a base type"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "The most common compound types are _pointers_ and _references_"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "Compound types are declared using a __base type__ followed a list of __declarators__"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## (lvalue) References\n",
+    "\n",
+    "A refence defines an alternative name for object\n",
+    "\n",
+    "Declarators for references start with an `&` followed by the name of the refence"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "int ival = 42;\n",
+    "int &refVal = ival;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "int &refVal2;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "### Reference Initialization\n",
+    "\n",
+    "Initilization of _variables_ means __copying__ the value of the initializer, while _references_ are __bound__ to the initializer\n",
+    "\n",
+    "There are no \"unbound\" references\n",
+    "\n",
+    "References can not be rebound"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "__References always have to be initialized when declared!__"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "### A Reference is an Alias\n",
+    "\n",
+    "A Reference is not an object, it is just another name for an object.\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "All operations that are performed on a reference, are actually perfromed on the object to which the reference is bound"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "int i = 23;\n",
+    "int &ir = i;\n",
+    "std::cout << \"i = \" << i << \" ir = \" << ir;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "i = 42;\n",
+    "std::cout << \"i = \" << i << \" ir = \" << ir;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "ir = 5;\n",
+    "std::cout << \"i = \" << i << \" ir = \" << ir;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "int &ir2 = ir;\n",
+    "std::cout << \"i = \" << i << \" ir = \" << ir << \" ir2 = \" << ir2;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "int i2 = ir2;\n",
+    "std::cout << \"i = \" << i << \" ir = \" << ir << \" ir2 = \" << ir2 << \" i2 = \" << i2;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "i2 = 25;\n",
+    "std::cout << \"i = \" << i << \" ir = \" << ir << \" ir2 = \" << ir2 << \" i2 = \" << i2;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "### Reference Definitions\n",
+    "\n",
+    "We can define multiple variables and references in a single definition:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int iv = 1024, iv2 = 2048; // i and i2 are both ints"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "int &rv = iv, rv2 = iv2; // r is ref bound to iv, r2 is an int"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "int iv3 = 1024, &ri = iv3; // iv3 is an int, ri is a ref bound to iv3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true,
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "int &r3 = iv3, &r4 = iv2; // two references"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "You will see a lot of badly formated C++ code:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int intValue = 10;\n",
+    "int& intReference = intValue; // syntacticly correct, not ambiguous in *this* case"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "int& intReference1 = intValue, intReference2 = intValue;  //Ooops, intReference2 is not a reference!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "__The `&` belongs to the name of reference not to its base type__"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "References must be bound to an object, not to a literal or an expression"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "int &refVal = 10; // 10 is not an object, its a literal"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The type of a reference and the type of the object it is bound to must match (with few exception)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "double dVal = 3.14;\n",
+    "int &refVal5 = dVal;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture02_ex.ipynb b/cppcourse/lecture02_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..beb774c95d22905d4b54d25cb7ffc559b1886902
--- /dev/null
+++ b/cppcourse/lecture02_ex.ipynb
@@ -0,0 +1,253 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Excersises to Lecture 2"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Reference Definitions\n",
+    "Which of the following definitions are invalid? Why?\n",
+    "- `int ival = 1.01`\n",
+    "- `int &rval1 = 1.01`\n",
+    "- `int &rval2 = ival`\n",
+    "- `int &rval3`\n",
+    "\n",
+    "See if you are right:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int ival = 1.01;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int &rval1 = 1.01;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int &rval2 = ival;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_7:2:7: error: declaration of reference variable 'rval3' requires an initializer\n",
+      " int &rval3;\n",
+      "      ^~~~~\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "int &rval3;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Assignments & References\n",
+    "\n",
+    "Given the definitions\n",
+    "```c++\n",
+    "int i = 0, &r1 = i;\n",
+    "double d = 0.0, &r2 = d;\n",
+    "```\n",
+    "Which assignments are invalid? If they are valid, what do they do?\n",
+    "- `r2 = 3.14159`\n",
+    "- `r2 = r1`\n",
+    "- `i = r2`\n",
+    "- `r1 = d`\n",
+    "\n",
+    "Check your theories here:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int i = 0, &r1 = i;\n",
+    "double d = 0.0, &r2 = d;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "3.14159"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "r2 = 3.14159"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "r2 = r1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "i = r2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "r1 = d"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## References at work\n",
+    "\n",
+    "What does the following code print?\n",
+    "\n",
+    "```c++\n",
+    "int i, &ri = i;\n",
+    "i = 5;\n",
+    "ri = 10;\n",
+    "std::cout << i << \" \" << ri << std::endl;\n",
+    "```\n",
+    "\n",
+    "Let's see:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "10 10\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    int i, &ri = i;\n",
+    "    i = 5;\n",
+    "    ri = 10;\n",
+    "    std::cout << i << \" \" << ri << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture03.ipynb b/cppcourse/lecture03.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..7f73f9d2c7d4fcf0bd280a2adad657d44e9ff537
--- /dev/null
+++ b/cppcourse/lecture03.ipynb
@@ -0,0 +1,505 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Pointers"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "Pointers are compund types that \"point to\" another object"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "A pointer is an object of its own, unlike a reference"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "Pointers can be assigned and copied"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "Pointers may be unitialized and have undefined value if they are not initialized"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "A pointer is defined by writing a _declarator_ in the form of `*d` where d is the name being defined\n",
+    "\n",
+    "Same as with references, the `*` has to be repeated with each declaration"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int *ip1, *ip2; // ip1 and ip2 are both pointers to int\n",
+    "double dp, *dp2; // dp is a double, dp2 is a pointer to doble"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "source": [
+    "## Taking the adress of an object\n",
+    "\n",
+    "A pointer holds the address of an object"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "We can retrieve the address of an object using the __address-of operator__ (`&`)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int ival = 42;\n",
+    "int *p =  &ival; // p holds the address of ival; p is pointer to ival"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "The type of the pointer and the the type of the object it points to must match (with some exceptions)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "double dval;\n",
+    "double *pd = &dval; // OK, double pointer initilized with address of a double\n",
+    "double *pd2 = pd; // OK, initialized with a copy of other pointer to a double"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_9:2:7: error: cannot initialize a variable of type 'int *' with an lvalue of type 'double *'\n",
+      " int *pi = pd;\n",
+      "      ^    ~~\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "int *pi = pd; // Oops, pointer to int can't be initialized with pointer to double"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_12:2:7: error: cannot initialize a variable of type 'int *' with an rvalue of type 'double *'\n",
+      " int *pi = &dval; // Ooops, pointer to int can't be initialized with an address of a double value\n",
+      "      ^    ~~~~~\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "int *pi = &dval; // Ooops, pointer to int can't be initialized with an address of a double value"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Pointer value\n",
+    "The value (i.e. the address) stored in a pointer can be in one of four states\n",
+    "- It can point to an object\n",
+    "- It can point to a location just behind the end of an object\n",
+    "- It can be a null pointer, indicating it does not point to any object\n",
+    "- It can be invalid"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "Only in the first case we can access an object through the pointer\n",
+    "\n",
+    "In all other cases accessing the supposed object pointed to results in __undefined behavior__"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Using a Pointer to Access an Object\n",
+    "\n",
+    "_If a pointer points to an object_, we can use the __dereference operator__ (`*`) "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_23:3:6: error: redefinition of 'p'\n",
+      "int *p = &ival2; // p holds the address of ival2, p is a pointer to ival2\n",
+      "     ^\n",
+      "input_line_7:3:6: note: previous definition is here\n",
+      "int *p =  &ival; // p holds the address of ival; p is pointer to ival\n",
+      "     ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "int ival2 = 42;\n",
+    "int *p = &ival2; // p holds the address of ival2, p is a pointer to ival2\n",
+    "std::cout << *p; // * derefences p and yields the object which p points to"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Assigning to `*p` means assigning to the object p points to"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0"
+     ]
+    }
+   ],
+   "source": [
+    "*p = 0;\n",
+    "std::cout << *p;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Symbol Confusion\n",
+    "\n",
+    "`*` and `&` each have two meanings depening on if they are used in an expression or a declaration"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "```c++\n",
+    "int i = 42;\n",
+    "int &r = i; // & follows a type and is part of a declaration; r is a reference\n",
+    "int *p; // * follows a type and is part of a declaration; p is a pointer\n",
+    "p = &i; // & is used in an expression as the address-of operator\n",
+    "*p = i; // * is used in an expression as the dereference operator\n",
+    "int &r2 = *p; // & is part of the declaration; * is the dereference operator\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "Ignore appearances, think of both uses of the symbols as completly different things!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Null Pointer\n",
+    "\n",
+    "A null pointer does not point to any object"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int * p1 = nullptr;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_29:3:6: error: redefinition of 'p2'\n",
+      "int *p2 = 0;\n",
+      "     ^\n",
+      "input_line_27:3:6: note: previous definition is here\n",
+      "int *p2 = 0;\n",
+      "     ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "// Before C++11 alternatives were used\n",
+    "int *p2 = 0;\n",
+    "int *p3 = NULL;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Assignment and Pointers\n",
+    "\n",
+    "A major difference between pointers and references is that pointers can be assigned a new value after initiliazation\n",
+    "\n",
+    "Assignment makes the pointer point to a different object"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "```c++\n",
+    "int i = 42;\n",
+    "int *pi = nullptr; // pi is initialized but addresses no object\n",
+    "int *pi2 = &i; // pi2 initialized to hold the address of i\n",
+    "int *pi3; // if pi3 is defined inside a block, pi3 is uninitialized\n",
+    "pi3 = pi2; // pi3 and pi2 address the same object, e.g., i\n",
+    "pi2 = nullptr; // pi2 now addresses no object\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "##  Other pointer operations\n",
+    "\n",
+    "You can test wether a pointer is a nullptr\n",
+    "\n",
+    "```c++\n",
+    "int ival = 1024;\n",
+    "int *pi = nullptr; // pi is a valid, null pointer\n",
+    "int *pi2 = &ival; // pi2 is a valid pointer that holds the address of ival\n",
+    "if(pi) // pi has value 0, so condition evaluates as false\n",
+    "    // ...\n",
+    "if(pi2) // pi2 points to ival, so it is not 0; the condition evaluates as true\n",
+    "    // ...\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "You can also compare pointers using the equality (`==`) and inequality (`!=`) operators\n",
+    "\n",
+    "Two pointers are equal if they hold the same address and inequal otherwise"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture03_ex.ipynb b/cppcourse/lecture03_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..24d844ac3e9ea7e75e3fae883488b313961ef8b3
--- /dev/null
+++ b/cppcourse/lecture03_ex.ipynb
@@ -0,0 +1,101 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 3"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## References and Pointers\n",
+    "\n",
+    "What are the key differences between references and pointers?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Program with Pointers\n",
+    "\n",
+    "What does the following program do?\n",
+    "\n",
+    "```c++\n",
+    "int i = 42;\n",
+    "int *p1 = &i;\n",
+    "*p1 = *p1 * *p1;\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int i =5;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Pointer Definitions\n",
+    "\n",
+    "What do the following definitions do? Are they legal?\n",
+    "\n",
+    "`int i = 0;`\n",
+    "- `double* dp = &i`\n",
+    "- `int* ip = &i`\n",
+    "- `int *p = &i`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Conditions & Pointers\n",
+    "\n",
+    "Assuming `p` is a pointer to `int`, explain what the following code does:\n",
+    "- `if(p) //...`\n",
+    "- `if(*p) //...`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Pointer Validity\n",
+    "\n",
+    "Given a pointer `p`, can you determine whether p points to a valid object? If so, how? If not, why?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture04.ipynb b/cppcourse/lecture04.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..c14dae551683087d10f3aca6baec7274bce01d43
--- /dev/null
+++ b/cppcourse/lecture04.ipynb
@@ -0,0 +1,535 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Lecture 4: Functions"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "A function constsists of a _return type_, a _name_, a list of zero or more _parameters_, and a _body_"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int add( const int i0, const int i1 )\n",
+    "{\n",
+    "    return i0 + i1;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "11"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "add( 5, 6 ) // 5 and 6 arge arguments, while i0 and i1 are parameters"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Argument passing\n",
+    "\n",
+    "Parameter initialization works the same way as variable initialization"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "If the arguments values are copied (i.e. if the parameter type is not a reference), arguments are __passed by value__ or the function is __called by value__"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "If the parameter types are references, arguments are __passed by reference__ or the function is __called by reference__"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "### Passing Arguments by Value "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "When you pass arguments _by value_ the values are copied into the function and there is no way to modify the initializer"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void increment( int i )\n",
+    "{\n",
+    "    ++i;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int i = 0;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "increment(i);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "i"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void incrementByPtr( int * iPtr )\n",
+    "{\n",
+    "    *iPtr = *iPtr + 1;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "incrementByPtr( &i );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "i"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "### Passing Arguments by Reference"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Passing arguments by reference is the C++-way to pass arguments which are _modified_ by the function"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void reset( int &i )\n",
+    "{\n",
+    "    i = 0;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int i2 = 0;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "i2 = 5;\n",
+    "reset( i2 );\n",
+    "i2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "If we pass large objects we can use a _const reference_ to avoid the copy operation"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <string>\n",
+    "\n",
+    "bool isShorter( const std::string &s1, const std::string & s2 )\n",
+    "{\n",
+    "    return s1.size() < s2.size();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "false"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "isShorter( \"aaaa\", \"aaa\" )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "### Const Parameters"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "You can use `const` parameters using both _call by value_ and _call by reference_ semantics"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Return types"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "A `return` statement terminates the functions and returns controll to the caller"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The function may not return a value which is indicated by the return type `void`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void swap( int & v1, int & v2 )\n",
+    "{\n",
+    "    if( v1 == v2 )\n",
+    "        return;\n",
+    "        \n",
+    "    int tmp;\n",
+    "    tmp = v1;\n",
+    "    v1 = v2;\n",
+    "    v2 = tmp;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int j = 7;\n",
+    "int k = 8;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "swap( j, k );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "8"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "j"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "j = 7;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "swap(j, k);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7"
+      ]
+     },
+     "execution_count": 22,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "j"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "7"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "k"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "cp /home/godenschwager/cpp/lecture04* ~/cpp"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture04_ex.ipynb b/cppcourse/lecture04_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..c715b554ac545d95ae36b84abaaa4800aea2530a
--- /dev/null
+++ b/cppcourse/lecture04_ex.ipynb
@@ -0,0 +1,168 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Exercises to Lecture 04"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `abs` that returns the absolute value of its `int` argument__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// define abs here"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "abs(-1) // should return 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "abs( 5 ) // should return 5"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "abs(0) // should return 0"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Somebody wrote the `dumbSwap` function below to swap the values of two `int`s.\n",
+    "Unfortunately it does not work. Why?__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "void dumbSwap( int i0, int i1 )\n",
+    "{ \n",
+    "    int tmp = i0;\n",
+    "    i0 = i1;\n",
+    "    i1 = tmp;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    int i = 2;\n",
+    "    int j = 10;\n",
+    "    dumbSwap(i, j);\n",
+    "    std::cout << i << \" \" << j; // should print \"10 2\" :-(\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Using pointers, write a working function `swapByPtr` that swaps two `ints`__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// define function swapByPtr here"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    int i = 2;\n",
+    "    int j = 10;\n",
+    "    swapByPtr(&i, &j);\n",
+    "    std::cout << i << \" \" << j; // should print \"10 2\"\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `swap` that swaps two `int`s using references__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// define function swap ref"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    int i = 2;\n",
+    "    int j = 10;\n",
+    "    swap(i, j);\n",
+    "    std::cout << i << \" \" << j; // should print \"10 2\"\n",
+    "}"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture04_ex_sol.ipynb b/cppcourse/lecture04_ex_sol.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..9f6cf7a8a69bbb467c488d27900c2d966540dbe7
--- /dev/null
+++ b/cppcourse/lecture04_ex_sol.ipynb
@@ -0,0 +1,241 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Exercises to Lecture 04"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `abs` that returns the absolute value of its `int` argument__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// define abs here\n",
+    "int abs( const int number )\n",
+    "{ \n",
+    "    return number < 0 ? -number : number;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "abs(-1) // should return 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "abs( 5 ) // should return 5"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "abs(0) // should return 0"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Somebody wrote the `dumbSwap` function below to swap the values of two `int`s.\n",
+    "Unfortunately it does not work. Why?__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "void dumbSwap( int i0, int i1 )\n",
+    "{ \n",
+    "    int tmp = i0;\n",
+    "    i0 = i1;\n",
+    "    i1 = tmp;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2 10"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    int i = 2;\n",
+    "    int j = 10;\n",
+    "    dumbSwap(i, j);\n",
+    "    std::cout << i << \" \" << j; // should print \"10 2\" :-(\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Using pointers, write a working function `swapByPtr` that swaps two `ints`__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// define function swapByPtr here\n",
+    "void swapByPtr( int * const i0, int * const i1 )\n",
+    "{ \n",
+    "    const int tmp = *i0;\n",
+    "    *i0 = *i1;\n",
+    "    *i1 = tmp;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "10 2"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    int i = 2;\n",
+    "    int j = 10;\n",
+    "    swapByPtr(&i, &j);\n",
+    "    std::cout << i << \" \" << j; // should print \"10 2\"\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `swap` that swaps two `int`s using references__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// define function swap ref\n",
+    "void swap( int &i0, int &i1 )\n",
+    "{ \n",
+    "    const int tmp = i0;\n",
+    "    i0 = i1;\n",
+    "    i1 = tmp;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "10 2"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    int i = 2;\n",
+    "    int j = 10;\n",
+    "    swap(i, j);\n",
+    "    std::cout << i << \" \" << j; // should print \"10 2\"\n",
+    "}"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture05.ipynb b/cppcourse/lecture05.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..89505b9b9e45e27d70b8bdda6cb889b3ca09b08f
--- /dev/null
+++ b/cppcourse/lecture05.ipynb
@@ -0,0 +1,756 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Lecture 5 `std::string`"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "A `std::string` is a __variable-length__ sequence of characters"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Initialization"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <string>\n",
+    "\n",
+    "std::string s;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"\""
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "s"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string s2( 10, ' ' );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"          \""
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "s2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"XXXXXXXXXXXXXXXXXXXX\""
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::string( 20, 'X' )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"Hello World!\""
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::string( \"Hello World!\" )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string s5( 20, 'X' );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string s6 = std::string( 20, 'X' );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int i = 5;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int i2(5);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Operations on `string`s"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Composing a `string`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Hello! 10"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "std::cout << \"Hello!\" << \" \" << 10;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <sstream>\n",
+    "std::ostringstream oss;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "oss << \"Hello!\" << \" \" << 10;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "oss << \"\\n\" << 2.76;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string s7 = oss.str();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"Hello! 10\n",
+       "2.76\""
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "s7"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for( int i = 0; i < 10; ++i )\n",
+    "    oss << i << \" \";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"Hello! 10\n",
+       "2.760 1 2 3 4 5 6 7 8 9 \""
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "oss.str()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Parsing a `string`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string inputString(\"3 7 6 9 10 98\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::istringstream iss2(inputString);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int i10;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_40:2:2: error: use of undeclared identifier 'iss'; did you mean 'iss2'?\n",
+      " iss >> i10;\n",
+      " ^~~\n",
+      " iss2\n",
+      "input_line_38:2:21: note: 'iss2' declared here\n",
+      " std::istringstream iss2(inputString);\n",
+      "                    ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "iss >> i10;\n",
+    "i10"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "while( iss2 >> i10 )\n",
+    "    std::cout << i10 << \" \";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string s50 = \"Hello World!\\nHow are you today?\";\n",
+    "std::istringstream iss3(s50);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\n",
+    "int lineCounter = 0;\n",
+    "std::string line;\n",
+    "while( std::getline( iss3, line ) )\n",
+    "{\n",
+    "    std::cout << lineCounter << \": \" << line << \"\\n\";\n",
+    "    ++lineCounter;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### `empty()` and `size()`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "inputString.empty()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string sEmpty;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sEmpty.empty()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "inputString.size()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sEmpty.size()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### `string::size_type`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string::size_type stringSize = inputString.size();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "size_t stringSize2 = inputString.size();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Comparisons"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string s11(\"Hello!\");\n",
+    "std::string s12(\"Hello!\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "bool b = s11 == s12;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << (s11 != s12);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Assignment"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string s20( \"AAA\" );\n",
+    "std::string s21( \"BBB\" );\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "s20"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "s21"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "s20 = s21;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "s20"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "s21"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "s20[0] = 'X';"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "s20"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "s21"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string s22 = s21;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Concatenation"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "s20 + s21"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Character handling"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Processing every Character: Range-Based for"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string s30(\"ABCDEFGH\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for( char c : s30 )\n",
+    "{\n",
+    "    std::cout << c << \" \";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <cctype>\n",
+    "\n",
+    "std::string s31(\"Hello World!\");\n",
+    "\n",
+    "for( const char c : s31 )\n",
+    "{\n",
+    "    if( std::isupper(c) )\n",
+    "        std::cout << c << \" \";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "#### Changing characters in range based for"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for( char & c : s31 )\n",
+    "{\n",
+    "    c = std::toupper(c);\n",
+    "}\n",
+    "s31"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Processing some characters"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for( size_t i = s31.size(); i != 0; --i )\n",
+    "{\n",
+    "    std::cout << s31[i - 1];\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "cp /home/godenschwager/cpp/lecture05* ~/cpp"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture05_ex.ipynb b/cppcourse/lecture05_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..9274795db45870a13e262ae2ab03e426790180c2
--- /dev/null
+++ b/cppcourse/lecture05_ex.ipynb
@@ -0,0 +1,159 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 5"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `addLineNumbers` that takes an input string as an argument and returns a string the same string but with each Line prefixed with its line number.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <string>\n",
+    "#include <sstream>\n",
+    "\n",
+    "std::string addLineNumbers( const std::string & s )\n",
+    "{\n",
+    "    // add your function here\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The following xwidgets will call your function. The text in the upper text area will be taken as an input. A click on the button calls your function and the result will be put in the lower text area."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xtextarea.hpp\"\n",
+    "#include \"xwidgets/xbutton.hpp\"\n",
+    "#include <xcpp/xdisplay.hpp>\n",
+    "\n",
+    "using xcpp::display;\n",
+    "\n",
+    "xw::textarea txtIn, txtOut;\n",
+    "xw::button button;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "txtIn.value = \"Hello World!\\nHow are you today?\";\n",
+    "button.on_click( [&]{ txtOut.value = addLineNumbers(txtIn.value()); } );\n",
+    "button.description = \"Add Line Numbers\";\n",
+    "display(txtIn);\n",
+    "display(button);\n",
+    "display(txtOut);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Do the same thing as above, but now with one word of the input string per line. Each line should start with the word count.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string getWordList( const std::string & s )\n",
+    "{\n",
+    "    // add your function here\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// this changes the setup of the widgets to work with your getWordList function and displays them again\n",
+    "button.on_click( [&]{ txtOut.value = getWordList(txtIn.value()); } );\n",
+    "button.description = \"Get Word List\";\n",
+    "display(txtIn);\n",
+    "display(button);\n",
+    "display(txtOut);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a string as an argument and removes all punction characters! To check whether a character is a punctuation character, take look at the functions defined in the [`<cctype>` headerfile](http://en.cppreference.com/w/cpp/header/cctype)__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <cctype>\n",
+    "std::string removePunctuation( const std::string & s )\n",
+    "{\n",
+    "    // add your function here\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "button.on_click( [&]{ txtOut.value = removePunctuation(txtIn.value()); } );\n",
+    "button.description = \"Remove Punctuation\";\n",
+    "display(txtIn);\n",
+    "display(button);\n",
+    "display(txtOut);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture05_ex_sol.ipynb b/cppcourse/lecture05_ex_sol.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..3a90a5eeb5476492a8eaf614079fc6ef95be05a7
--- /dev/null
+++ b/cppcourse/lecture05_ex_sol.ipynb
@@ -0,0 +1,320 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 5"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `addLineNumbers` that takes an input string as an argument and returns a string the same string but with each Line prefixed with its line number.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <string>\n",
+    "#include <sstream>\n",
+    "\n",
+    "std::string addLineNumbers( const std::string & s )\n",
+    "{\n",
+    "    // add your function here\n",
+    "    std::istringstream iss(s);\n",
+    "    std::ostringstream oss;\n",
+    "    \n",
+    "    unsigned int lineCounter = 1;\n",
+    "    std::string line;\n",
+    "    while( std::getline(iss, line) )\n",
+    "    {\n",
+    "        oss << lineCounter << \": \" << line << \"\\n\";\n",
+    "        ++lineCounter;\n",
+    "    }\n",
+    "    \n",
+    "    return oss.str();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The following xwidgets will call your function. The text in the upper text area will be taken as an input. A click on the button calls your function and the result will be put in the lower text area."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xtextarea.hpp\"\n",
+    "#include \"xwidgets/xbutton.hpp\"\n",
+    "#include <xcpp/xdisplay.hpp>\n",
+    "\n",
+    "using xcpp::display;\n",
+    "\n",
+    "xw::textarea txtIn, txtOut;\n",
+    "xw::button button;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "42e2016d5c914484b6c6db2d23ea30da",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "ca43ce0245fa423cb6833f9f9479eec5",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "dcfc91b9a28d48a0b7db7c807acb8531",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "txtIn.value = \"Hello World!\\nHow are you today?\";\n",
+    "button.on_click( [&]{ txtOut.value = addLineNumbers(txtIn.value()); } );\n",
+    "button.description = \"Add Line Numbers\";\n",
+    "display(txtIn);\n",
+    "display(button);\n",
+    "display(txtOut);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Do the same thing as above, but now with one word of the input string per line. Each line should start with the word count.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string getWordList( const std::string & s )\n",
+    "{\n",
+    "    // add your function here\n",
+    "    std::istringstream iss(s);\n",
+    "    std::ostringstream oss;\n",
+    "    \n",
+    "    unsigned int lineCounter = 1;\n",
+    "    std::string word;\n",
+    "    while( iss >> word )\n",
+    "    {\n",
+    "        oss << lineCounter << \": \" << word << \"\\n\";\n",
+    "        ++lineCounter;\n",
+    "    }\n",
+    "    \n",
+    "    return oss.str();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "42e2016d5c914484b6c6db2d23ea30da",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "ca43ce0245fa423cb6833f9f9479eec5",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "dcfc91b9a28d48a0b7db7c807acb8531",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "button.on_click( [&]{ txtOut.value = getWordList(txtIn.value()); } );\n",
+    "button.description = \"Get Word List\";\n",
+    "display(txtIn);\n",
+    "display(button);\n",
+    "display(txtOut);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a string as an argument and removes all punction characters! To check whether a character is a punctuation character, take look at the functions defined in the [`<cctype>` headerfile](http://en.cppreference.com/w/cpp/header/cctype)__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <cctype>\n",
+    "std::string removePunctuation( const std::string & s )\n",
+    "{\n",
+    "    // add your function here\n",
+    "    std::ostringstream oss;\n",
+    "    \n",
+    "    for( const char &c : s )\n",
+    "    {\n",
+    "        if( !std::ispunct(c) )\n",
+    "            oss << c;\n",
+    "    }\n",
+    "    \n",
+    "    return oss.str();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "42e2016d5c914484b6c6db2d23ea30da",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "ca43ce0245fa423cb6833f9f9479eec5",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "dcfc91b9a28d48a0b7db7c807acb8531",
+       "version_major": 2,
+       "version_minor": 0
+      },
+      "text/plain": [
+       "A Jupyter widget"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "button.on_click( [&]{ txtOut.value = removePunctuation(txtIn.value()); } );\n",
+    "button.description = \"Remove Punctuation\";\n",
+    "display(txtIn);\n",
+    "display(button);\n",
+    "display(txtOut);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture06.ipynb b/cppcourse/lecture06.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..d0b32ed77a05075f9c2a73f6b1f7748f87bc4927
--- /dev/null
+++ b/cppcourse/lecture06.ipynb
@@ -0,0 +1,844 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Lecture 06: `std::vector`\n",
+    "\n",
+    "`std::vector` is a dynamicaly sized collection of objects of the same type"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Initializing `vector`s"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <vector>\n",
+    "#include <string>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> v;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::vector<int>( 10 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" }"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::vector<std::string>( 10 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 }"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::vector<int>( 10, 7 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ \"Hello!\", \"Hello!\", \"Hello!\", \"Hello!\", \"Hello!\", \"Hello!\", \"Hello!\", \"Hello!\", \"Hello!\", \"Hello!\" }"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::vector<std::string>( 10, \"Hello!\" )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 1, 6, 7, 3, 5 }"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::vector<int> v1{ 1, 6, 7, 3, 5 };\n",
+    "v1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 5 }"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::vector<int> v3{ 5 };\n",
+    "v3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 0, 0, 0, 0, 0 }"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::vector<int>( 5 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Adding elements to `vector`s"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::vector<int> v10;\n",
+    "v10"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 15 }"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v10.push_back( 15 );\n",
+    "v10"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "v10.push_back( 23 );\n",
+    "v10.push_back( 42 );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 15, 23, 42, 23, 42 }"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v10"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Growth policy\n",
+    "The C++ standard requires the `push_back` operation to have an amortized complexity of O(1). How is this achieved?"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> v20;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20.size()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20.capacity()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "v20.push_back(1);\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 31,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20.size()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20.capacity()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "size: 2 capacity: 2\n",
+      "size: 3 capacity: 4\n",
+      "size: 4 capacity: 4\n",
+      "size: 5 capacity: 8\n",
+      "size: 6 capacity: 8\n",
+      "size: 7 capacity: 8\n",
+      "size: 8 capacity: 8\n",
+      "size: 9 capacity: 16\n",
+      "size: 10 capacity: 16\n",
+      "size: 11 capacity: 16\n",
+      "size: 12 capacity: 16\n",
+      "size: 13 capacity: 16\n",
+      "size: 14 capacity: 16\n",
+      "size: 15 capacity: 16\n",
+      "size: 16 capacity: 16\n",
+      "size: 17 capacity: 32\n",
+      "size: 18 capacity: 32\n",
+      "size: 19 capacity: 32\n",
+      "size: 20 capacity: 32\n",
+      "size: 21 capacity: 32\n",
+      "size: 22 capacity: 32\n",
+      "size: 23 capacity: 32\n",
+      "size: 24 capacity: 32\n",
+      "size: 25 capacity: 32\n",
+      "size: 26 capacity: 32\n",
+      "size: 27 capacity: 32\n",
+      "size: 28 capacity: 32\n",
+      "size: 29 capacity: 32\n",
+      "size: 30 capacity: 32\n",
+      "size: 31 capacity: 32\n",
+      "size: 32 capacity: 32\n",
+      "size: 33 capacity: 64\n",
+      "size: 34 capacity: 64\n",
+      "size: 35 capacity: 64\n",
+      "size: 36 capacity: 64\n",
+      "size: 37 capacity: 64\n",
+      "size: 38 capacity: 64\n",
+      "size: 39 capacity: 64\n",
+      "size: 40 capacity: 64\n",
+      "size: 41 capacity: 64\n",
+      "size: 42 capacity: 64\n",
+      "size: 43 capacity: 64\n",
+      "size: 44 capacity: 64\n",
+      "size: 45 capacity: 64\n",
+      "size: 46 capacity: 64\n",
+      "size: 47 capacity: 64\n",
+      "size: 48 capacity: 64\n",
+      "size: 49 capacity: 64\n",
+      "size: 50 capacity: 64\n",
+      "size: 51 capacity: 64\n",
+      "size: 52 capacity: 64\n",
+      "size: 53 capacity: 64\n",
+      "size: 54 capacity: 64\n",
+      "size: 55 capacity: 64\n",
+      "size: 56 capacity: 64\n",
+      "size: 57 capacity: 64\n",
+      "size: 58 capacity: 64\n",
+      "size: 59 capacity: 64\n",
+      "size: 60 capacity: 64\n",
+      "size: 61 capacity: 64\n",
+      "size: 62 capacity: 64\n",
+      "size: 63 capacity: 64\n",
+      "size: 64 capacity: 64\n",
+      "size: 65 capacity: 128\n",
+      "size: 66 capacity: 128\n",
+      "size: 67 capacity: 128\n",
+      "size: 68 capacity: 128\n",
+      "size: 69 capacity: 128\n",
+      "size: 70 capacity: 128\n",
+      "size: 71 capacity: 128\n",
+      "size: 72 capacity: 128\n",
+      "size: 73 capacity: 128\n",
+      "size: 74 capacity: 128\n",
+      "size: 75 capacity: 128\n",
+      "size: 76 capacity: 128\n",
+      "size: 77 capacity: 128\n",
+      "size: 78 capacity: 128\n",
+      "size: 79 capacity: 128\n",
+      "size: 80 capacity: 128\n",
+      "size: 81 capacity: 128\n",
+      "size: 82 capacity: 128\n",
+      "size: 83 capacity: 128\n",
+      "size: 84 capacity: 128\n",
+      "size: 85 capacity: 128\n",
+      "size: 86 capacity: 128\n",
+      "size: 87 capacity: 128\n",
+      "size: 88 capacity: 128\n",
+      "size: 89 capacity: 128\n",
+      "size: 90 capacity: 128\n",
+      "size: 91 capacity: 128\n",
+      "size: 92 capacity: 128\n",
+      "size: 93 capacity: 128\n",
+      "size: 94 capacity: 128\n",
+      "size: 95 capacity: 128\n",
+      "size: 96 capacity: 128\n",
+      "size: 97 capacity: 128\n",
+      "size: 98 capacity: 128\n",
+      "size: 99 capacity: 128\n",
+      "size: 100 capacity: 128\n",
+      "size: 101 capacity: 128\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "for( int i = 0; i < 100; ++i )\n",
+    "{\n",
+    "    v20.push_back(1);\n",
+    "    std::cout << \"size: \" << v20.size() << \" capacity: \" << v20.capacity() << \"\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "v20.reserve(1000);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "101"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20.size()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1000"
+      ]
+     },
+     "execution_count": 38,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20.capacity()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Other operations on `vector`s"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 "
+     ]
+    }
+   ],
+   "source": [
+    "for( int i : v20 )\n",
+    "{\n",
+    "    std::cout << i << \" \";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 41,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    " v20[16]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for( int & i : v20 )\n",
+    "{\n",
+    "    i = 2;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }"
+      ]
+     },
+     "execution_count": 43,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "false"
+      ]
+     },
+     "execution_count": 44,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20.empty()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "true"
+      ]
+     },
+     "execution_count": 47,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    " bool b = v20 == v10;\n",
+    "b"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "v20 = v10;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5"
+      ]
+     },
+     "execution_count": 49,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20.size()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "for( int i = 0; i < 100; ++i )\n",
+    "{\n",
+    "    v20.push_back(1);\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "105"
+      ]
+     },
+     "execution_count": 51,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20.size()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1000"
+      ]
+     },
+     "execution_count": 52,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20.capacity()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "v20.shrink_to_fit()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "105"
+      ]
+     },
+     "execution_count": 54,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v20.capacity()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "bool b2 = v20 != v10;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "true"
+      ]
+     },
+     "execution_count": 57,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "b2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> v40;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "v40[10] = 5;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture06_ex.ipynb b/cppcourse/lecture06_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..018cafa3028c15d599c6153fbd21f2570994f8d4
--- /dev/null
+++ b/cppcourse/lecture06_ex.ipynb
@@ -0,0 +1,253 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 6"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `parseInts` that parses a number of `int`s from a string and returns a `vector<int>`__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <string>\n",
+    "#include <vector>\n",
+    "#include <sstream>\n",
+    "\n",
+    "std::vector<int> parseInts( const std::string & s )\n",
+    "{\n",
+    "\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "parseInts(\"1 2 3 4 5 299\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "parseInts(\"\") // does this return an empty vector?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Do the same thing but this time parse single words and return a `std::vector<string>`__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <string>\n",
+    "#include <vector>\n",
+    "#include <sstream>\n",
+    "\n",
+    "std::vector<std::string> parseStrings( const std::string & s )\n",
+    "{\n",
+    "\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "parseStrings(\"C++ is great\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "parseStrings(\"1 2 3 4 5 299\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a `vector` of `string`s and change each word to uppercase. Do the conversion in-place, i.e. directly modify the argument to your function and do not return a copy of the `vector`. (Hint: use `toupper` from `<cctype>`)__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void toUppercase( std::vector<std::string> & vs )\n",
+    "{\n",
+    "\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<std::string> sampleStrings = parseStrings(\"C++ is easy!\");\n",
+    "toUppercase( sampleStrings );\n",
+    "sampleStrings"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a `std::vector<int>` and computes the sum of each pair of adjacent elements. Return a `std::vector<int>` with the result.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> adjacentSum( const std::vector<int> & v )\n",
+    "{\n",
+    "\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "adjacentSum( { 1 } ) // should be { }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "adjacentSum( { } ) // should be { }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "adjacentSum( { 1, 2, 3, 4 } ) // should be { 3, 5, 7 }"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write similar program as above that sums the first and the last, the second and the second-to-last element and so on. On `vector`s with an uneven number of elements ignore the center element.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> outerSum( const std::vector<int> & v )\n",
+    "{\n",
+    "\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 0, 1, 2, 3, 4, 5 } ) // should be { 5, 5, 5 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 4 , 8 , 18, 20 } ) // should be { 24, 26 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 4 , 8 , 18, 20, 25 } ) // should be { 29, 28 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( {} ) // should be {} (and most importantly not crash)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 1 } ) // should be {}"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture06_ex_sol.ipynb b/cppcourse/lecture06_ex_sol.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..f92d658d516eff3afcd53061a537b1f3273556ea
--- /dev/null
+++ b/cppcourse/lecture06_ex_sol.ipynb
@@ -0,0 +1,437 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 6"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `parseInts` that parses a number of `int`s from a string and returns a `vector<int>`__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <string>\n",
+    "#include <vector>\n",
+    "#include <sstream>\n",
+    "\n",
+    "std::vector<int> parseInts( const std::string & s )\n",
+    "{\n",
+    "    std::vector<int> vi;\n",
+    "    std::istringstream iss(s);\n",
+    "    \n",
+    "    int i = 0;\n",
+    "    while( iss >> i )\n",
+    "        vi.push_back(i);\n",
+    "    \n",
+    "    return vi;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 1, 2, 3, 4, 5, 299 }"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "parseInts(\"1 2 3 4 5 299\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "parseInts(\"\") // does this return an empty vector?"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Do the same thing but this time parse single words and return a `std::vector<string>`__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <string>\n",
+    "#include <vector>\n",
+    "#include <sstream>\n",
+    "\n",
+    "std::vector<std::string> parseStrings( const std::string & s )\n",
+    "{\n",
+    "    std::vector<std::string> vs;\n",
+    "    std::istringstream iss(s);\n",
+    "    \n",
+    "    std::string str;\n",
+    "    while( iss >> str )\n",
+    "        vs.push_back(str);\n",
+    "    \n",
+    "    return vs;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ \"C++\", \"is\", \"great\" }"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "parseStrings(\"C++ is great\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ \"1\", \"2\", \"3\", \"4\", \"5\", \"299\" }"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "parseStrings(\"1 2 3 4 5 299\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a `vector` of `string`s and change each word to uppercase. Do the conversion in-place, i.e. directly modify the argument to your function and do not return a copy of the `vector`. (Hint: use `toupper` from `<cctype>`)__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void toUppercase( std::vector<std::string> & vs )\n",
+    "{\n",
+    "   for( std::string & s : vs )\n",
+    "       for( char & c : s )\n",
+    "           c = std::toupper(c);\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ \"C++\", \"IS\", \"EASY!\" }"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::vector<std::string> sampleStrings = parseStrings(\"C++ is easy!\");\n",
+    "toUppercase( sampleStrings );\n",
+    "sampleStrings"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a `std::vector<int>` and computes the sum of each pair of adjacent elements. Return a `std::vector<int>` with the result.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> adjacentSum( const std::vector<int> & v )\n",
+    "{\n",
+    "    std::vector<int> result;\n",
+    "    \n",
+    "    if( v.empty() )\n",
+    "        return result;\n",
+    "    \n",
+    "    result.reserve( v.size() - 1 );\n",
+    "    for( size_t i = 1; i < v.size(); ++i )\n",
+    "        result.push_back( v[i-1] + v[i] );\n",
+    "    return result;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 3, 5, 7 }"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "adjacentSum( { 1, 2, 3, 4 } ) // should be { 3, 5, 7 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "adjacentSum( { 1 } ) // should be { }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "adjacentSum( { } ) // should be { }"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write similar program as above that sums the first and the last, the second and the second-to-last element and so on. On `vector`s with an uneven number of elements ignore the center element.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> outerSum( const std::vector<int> & v )\n",
+    "{\n",
+    "    std::vector<int> result;\n",
+    "    \n",
+    "    if( v.size() <= 1 )\n",
+    "        return result;\n",
+    "    \n",
+    "    result.reserve( v.size() / 2 );\n",
+    "    \n",
+    "    for( size_t first = 0, last = v.size() - 1; first < last; ++first, --last )\n",
+    "        result.push_back( v[first] + v[last] );\n",
+    "    \n",
+    "    return result;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 5, 5, 5 }"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "outerSum( { 0, 1, 2, 3, 4, 5 } ) // should be { 5, 5, 5 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 24, 26 }"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "outerSum( { 4 , 8 , 18, 20 } ) // should be { 24, 26 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 29, 28 }"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "outerSum( { 4 , 8 , 18, 20, 25 } ) // should be { 29, 28 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "outerSum( {} ) // should be {} (and most importantly not crash)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "outerSum( { 1 } ) // should be {}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture07.ipynb b/cppcourse/lecture07.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..5e2c733ae1166ca854ff5ac40ef4077b0f71bcae
--- /dev/null
+++ b/cppcourse/lecture07.ipynb
@@ -0,0 +1,984 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Lecture 7: Iterators "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Throughout the C++ Standard Library `iterators` are used to traverse collections and reference elements in collections. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Using iterators"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Iterator Operations"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <vector>\n",
+    "\n",
+    "std::vector<int> v (100);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int ctr = 0;\n",
+    "for( int & i : v )\n",
+    "{\n",
+    "    i = ctr;\n",
+    "    ++ctr;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int>::iterator it = v.begin();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "auto it2 = v.begin();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*it"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Moving Iterators to Another Element"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "++it;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "@0x7fbe0d0ce040"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "--it;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*it"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Iterator Types"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int>::iterator it3 = v.begin();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const std::vector<int> v2(100);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int>::const_iterator it4 = v2.begin();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*it3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*it4"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "*it3 = 13;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "13"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*it3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_45:2:7: error: cannot assign to return value because function 'operator*' returns a const value\n",
+      " *it4 = 15;\n",
+      " ~~~~ ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/stl_iterator.h:791:7: note: function 'operator*' which returns const-qualified type '__gnu_cxx::__normal_iterator<const int *, std::vector<int, std::allocator<int> > >::reference' (aka 'const int &') declared here\n",
+      "      reference\n",
+      "      ^~~~~~~~~\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "*it4 = 15;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int>::const_iterator it5 = v.begin();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_47:2:7: error: cannot assign to return value because function 'operator*' returns a const value\n",
+      " *it5 = 17\n",
+      " ~~~~ ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/stl_iterator.h:791:7: note: function 'operator*' which returns const-qualified type '__gnu_cxx::__normal_iterator<const int *, std::vector<int, std::allocator<int> > >::reference' (aka 'const int &') declared here\n",
+      "      reference\n",
+      "      ^~~~~~~~~\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "*it5 = 17"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "auto it6 = v.cbegin();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_49:2:7: error: cannot assign to return value because function 'operator*' returns a const value\n",
+      " *it6 = 17;\n",
+      " ~~~~ ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/stl_iterator.h:791:7: note: function 'operator*' which returns const-qualified type '__gnu_cxx::__normal_iterator<const int *, std::vector<int, std::allocator<int> > >::reference' (aka 'const int &') declared here\n",
+      "      reference\n",
+      "      ^~~~~~~~~\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "*it6 = 17;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### begin and end"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "auto itBegin = v.begin();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "auto itEnd = v.end();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*itBegin"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "91588240"
+      ]
+     },
+     "execution_count": 37,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*itEnd"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 "
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "for( auto it10 = v.begin(); it10 != v.end(); ++it10 )\n",
+    "{\n",
+    "    std::cout << *it10 << \" \";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 "
+     ]
+    }
+   ],
+   "source": [
+    "for( auto & i : v )\n",
+    "{\n",
+    "    std::cout << i << \" \";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 "
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "for( auto it10 = v.begin(); it10 != v.end(); ++it10 )\n",
+    "{\n",
+    "    auto & i = *it10;\n",
+    "    std::cout << i << \" \";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### The arrow operator (`->`)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<std::string> sv( 10, \"Hello\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "5 5 5 5 5 5 5 5 5 5 "
+     ]
+    }
+   ],
+   "source": [
+    "for( auto sIt = sv.begin(); sIt != sv.end(); ++sIt )\n",
+    "{\n",
+    "    std::cout << sIt->size() << \" \";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Iterator invalidation"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> v20( 10, 5 );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for( auto it = v20.begin(); it != v20.end(); ++it )\n",
+    "{\n",
+    "    v20.push_back( *it );\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_13:2:19: error: redefinition of 'v21'\n",
+      " std::vector<int> v21(v20);\n",
+      "                  ^\n",
+      "input_line_8:2:19: note: previous definition is here\n",
+      " std::vector<int> v21(v20);\n",
+      "                  ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "std::vector<int> v21(v20);\n",
+    "for( auto it = v20.begin(); it != v20.end(); ++it )\n",
+    "{\n",
+    "    v21.push_back( *it );\n",
+    "}\n",
+    "v20 = v21;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v21"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Iterator Arithmetic"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "auto it = v.begin();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "++it;\n",
+    "*it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "--it;\n",
+    "*it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "10"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "it += 10; // it = it + 10;\n",
+    "*it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "it -= 5;\n",
+    "*it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "true"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "bool(v.begin() < it)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "false"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "bool(v.begin() > it)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "-5"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v.begin() - it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iterator>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5"
+      ]
+     },
+     "execution_count": 23,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::distance( v.begin(), it )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "auto itNext = std::next( it );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5"
+      ]
+     },
+     "execution_count": 25,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "6"
+      ]
+     },
+     "execution_count": 26,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*itNext"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "auto itPrev = std::prev( it );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "4"
+      ]
+     },
+     "execution_count": 28,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "*itPrev"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "10"
+      ]
+     },
+     "execution_count": 29,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::advance( it, 5 );\n",
+    "*it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture07_ex.ipynb b/cppcourse/lecture07_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..82f668568528baf76f2a18d1c27ff259363c8b49
--- /dev/null
+++ b/cppcourse/lecture07_ex.ipynb
@@ -0,0 +1,215 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 7"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a `vector<int>` and multiply each value by `10`. Use Iterators and a regular `for` loop to do the task.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <vector>\n",
+    "\n",
+    "void multiplyBy10( std::vector<int> & v )\n",
+    "{\n",
+    "\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> someNumbers{ 4, 8, 15, 16, 23, 42 };\n",
+    "multiplyBy10( someNumbers );\n",
+    "someNumbers"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write the last three functions from the previous exercise using iterators:__"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a `vector` of `string`s and change each word to uppercase. Do the conversion in-place, i.e. directly modify the argument to your function and do not return a copy of the `vector`. (Hint: use `toupper` from `<cctype>`)__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void toUppercase( std::vector<std::string> & vs )\n",
+    "{\n",
+    "\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<std::string> sampleStrings = {\"C++\", \"is\", \"hard!\"};\n",
+    "toUppercase( sampleStrings );\n",
+    "sampleStrings"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a `std::vector<int>` and computes the sum of each pair of adjacent elements. Return a `std::vector<int>` with the result.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> adjacentSum( const std::vector<int> & v )\n",
+    "{\n",
+    "\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "adjacentSum( { 1, 2, 3, 4 } ) // should be { 3, 5, 7 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "adjacentSum( { 1 } ) // should be { }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "adjacentSum( { } ) // should be { }"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write similar program as above that sums the first and the last, the second and the second-to-last element and so on. On `vector`s with an uneven number of elements ignore the center element.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> outerSum( const std::vector<int> & v )\n",
+    "{\n",
+    "\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 0, 1, 2, 3, 4, 5 } ) // should be { 5, 5, 5 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 4 , 8 , 18, 20 } ) // should be { 24, 26 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 4 , 8 , 18, 20, 25 } ) // should be { 29, 28 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( {} ) // should be {} (and most importantly not crash)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 1 } ) // should be {}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture07_ex_sol.ipynb b/cppcourse/lecture07_ex_sol.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..42b8079b8d4a608eb3d2e1da0178083b2889ac61
--- /dev/null
+++ b/cppcourse/lecture07_ex_sol.ipynb
@@ -0,0 +1,238 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 7"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a `vector<int>` and multiply each value by `10`. Use Iterators and a regular `for` loop to do the task.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <vector>\n",
+    "\n",
+    "void multiplyBy10( std::vector<int> & v )\n",
+    "{\n",
+    "    for( std::vector<int>::iterator it = v.begin(); it != v.end(); ++it )\n",
+    "    {\n",
+    "        *it *= 10;\n",
+    "    }\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> someNumbers{ 4, 8, 15, 16, 23, 42 };\n",
+    "multiplyBy10( someNumbers );\n",
+    "someNumbers"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write the last three functions from the previous excise using iterators:__"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a `vector` of `string`s and change each word to uppercase. Do the conversion in-place, i.e. directly modify the argument to your function and do not return a copy of the `vector`. (Hint: use `toupper` from `<cctype>`)__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void toUppercase( std::vector<std::string> & vs )\n",
+    "{\n",
+    "   for( auto vIt = vs.begin(); vIt != vs.end(); ++vIt )\n",
+    "       for( auto sIt = vIt->begin(); sIt != vIt->end(); ++sIt )\n",
+    "           *sIt = std::toupper(*sIt);\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<std::string> sampleStrings = {\"C++\", \"is\", \"hard!\"};\n",
+    "toUppercase( sampleStrings );\n",
+    "sampleStrings"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a `std::vector<int>` and computes the sum of each pair of adjacent elements. Return a `std::vector<int>` with the result.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> adjacentSum( const std::vector<int> & v )\n",
+    "{\n",
+    "    std::vector<int> result;\n",
+    "    \n",
+    "    if( v.empty() )\n",
+    "        return result;\n",
+    "    \n",
+    "    result.reserve( v.size() - 1 );\n",
+    "    for( auto it = std::next(v.begin()); it != v.end(); ++it )\n",
+    "        result.push_back( *std::prev(it) + *it );\n",
+    "    return result;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "adjacentSum( { 1, 2, 3, 4 } ) // should be { 3, 5, 7 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "adjacentSum( { 1 } ) // should be { }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "adjacentSum( { } ) // should be { }"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write similar program as above that sums the first and the last, the second and the second-to-last element and so on. On `vector`s with an uneven number of elements ignore the center element.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> outerSum( const std::vector<int> & v )\n",
+    "{\n",
+    "    std::vector<int> result;\n",
+    "    \n",
+    "    if( v.size() <= 1 )\n",
+    "        return result;\n",
+    "    \n",
+    "    result.reserve( v.size() / 2 );\n",
+    "    \n",
+    "    for( auto first =  v.begin(), last = std::prev( v.end() ); first < last; ++first, --last )\n",
+    "        result.push_back( *first + *last );\n",
+    "    \n",
+    "    return result;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 0, 1, 2, 3, 4, 5 } ) // should be { 5, 5, 5 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 4 , 8 , 18, 20 } ) // should be { 24, 26 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 4 , 8 , 18, 20, 25 } ) // should be { 29, 28 }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( {} ) // should be {} (and most importantly not crash)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "outerSum( { 1 } ) // should be {}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture08.ipynb b/cppcourse/lecture08.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..26e2ea8fb0ffa2371a250ed588d59840f910d1ca
--- /dev/null
+++ b/cppcourse/lecture08.ipynb
@@ -0,0 +1,935 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Lecture 8: Classes"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "_Classes_ offer the possibility to define own data types in C++"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "Classes offer _data abstraction_ and _data encapsulation_"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "__Data abstraction__ means the separation of an _interface_ from the actual _implementation_"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Users of the class must only know about the interface, the operations that users of the class can execute"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The actual implementation includes data members, member function implementations, and member functions that are needed only internally "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "_Encapsulation_ enforces the data asbtraction by disallowing access to the implementation"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Users may only see and do what the class author let's them"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "#include <cmath>\n",
+    "\n",
+    "class Vector2\n",
+    "{\n",
+    "public: // access to all following functions is public\n",
+    "    \n",
+    "    Vector2() : x_( 0.0 ), y_(0.0) { }\n",
+    "    explicit Vector2( const double d ) : x_( d ), y_(d) { }\n",
+    "    Vector2( const double x, const double y ) // Constructor\n",
+    "        : x_( x ), y_( y ) { }\n",
+    "    \n",
+    "    double x() const { return x_; } // member functions\n",
+    "    double y() const { return y_; }\n",
+    "    \n",
+    "    double & x() { return x_; } // member functions\n",
+    "    double & y() { return y_; }\n",
+    "    \n",
+    "    void setX( const double x ) { x_ = x; }\n",
+    "    void setY( const double y ) { y_ = y; }\n",
+    "    \n",
+    "    double squaredLength() const { return x_ * x_ + y_ * y_; }\n",
+    "    double length() const { return std::sqrt( squaredLength() ); }\n",
+    "    \n",
+    "    Vector2 operator+( const Vector2 & other ) const {\n",
+    "        return Vector2( this->x_ + other.x_, this->y_ + other.y_ );\n",
+    "    }\n",
+    "    \n",
+    "    Vector2 operator*( const double d ) {\n",
+    "        return Vector2( x_ * d, y_ * d );\n",
+    "    }\n",
+    "    \n",
+    "private: // acces to the following data members is restricted to the class members\n",
+    "    double x_;\n",
+    "    double y_;\n",
+    "}; // don't forget the semicolon!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "Vector2 v( 1.0, 1.0 );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "v = (1, 1) has length 1.41421"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "std::cout << \"v = (\" << v.x() << \", \" << v.y() << \") has length \" << v.length();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "__ Overloading the insertion operator for output streams__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_13:3:1: error: function definition is not allowed here\n",
+      "{\n",
+      "^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "//#include <ostream>\n",
+    "//#include <iostream>\n",
+    "//\n",
+    "//std::ostream & operator<<( std::ostream & os, const Vector2 & v )\n",
+    "//{\n",
+    "//    os << \"(\" << v.x() << \", \" << v.y() << \")\";\n",
+    "//    return os;\n",
+    "//}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "#include <ostream>\n",
+    "#include <iostream>\n",
+    "\n",
+    "#define INSERTION_OPERATOR operator<< // Workaround for a bug of cling\n",
+    "\n",
+    "//std::ostream & operator<<( std::ostream & os, const Vector2 & v )\n",
+    "std::ostream & INSERTION_OPERATOR( std::ostream & os, const Vector2 & v )\n",
+    "{\n",
+    "    os << \"(\" << v.x() << \", \" << v.y() << \")\";\n",
+    "    return os;\n",
+    "}\n",
+    "\n",
+    "#undef INSERTION_OPERATOR"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "std::cout << v << \" has length \" << v.length();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "__Encapsulation prohibits direct access to private members__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << v.x_;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "__Automatic assignment operator__ "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_14:3:11: error: invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'Vector2')\n",
+      "std::cout << v << \"\\n\";\n",
+      "~~~~~~~~~ ^  ~\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:245:7: note: candidate function not viable: no known conversion from 'Vector2' to 'const void *' for 1st argument; take the address of the argument with &\n",
+      "      operator<<(const void* __p)\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/system_error:217:5: note: candidate function not viable: no known conversion from 'Vector2' to 'const std::error_code' for 2nd argument\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:108:7: note: candidate function not viable: no known conversion from 'Vector2' to 'std::basic_ostream<char, std::char_traits<char> >::__ostream_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ostream_type &)' (aka 'basic_ostream<char, std::char_traits<char> > &(*)(basic_ostream<char, std::char_traits<char> > &)') for 1st argument\n",
+      "      operator<<(__ostream_type& (*__pf)(__ostream_type&))\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:117:7: note: candidate function not viable: no known conversion from 'Vector2' to 'std::basic_ostream<char, std::char_traits<char> >::__ios_type &(*)(std::basic_ostream<char, std::char_traits<char> >::__ios_type &)' (aka 'basic_ios<char, std::char_traits<char> > &(*)(basic_ios<char, std::char_traits<char> > &)') for 1st argument\n",
+      "      operator<<(__ios_type& (*__pf)(__ios_type&))\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:127:7: note: candidate function not viable: no known conversion from 'Vector2' to 'std::ios_base &(*)(std::ios_base &)' for 1st argument\n",
+      "      operator<<(ios_base& (*__pf) (ios_base&))\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:166:7: note: candidate function not viable: no known conversion from 'Vector2' to 'long' for 1st argument\n",
+      "      operator<<(long __n)\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:170:7: note: candidate function not viable: no known conversion from 'Vector2' to 'unsigned long' for 1st argument\n",
+      "      operator<<(unsigned long __n)\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:174:7: note: candidate function not viable: no known conversion from 'Vector2' to 'bool' for 1st argument\n",
+      "      operator<<(bool __n)\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:178:7: note: candidate function not viable: no known conversion from 'Vector2' to 'short' for 1st argument\n",
+      "      operator<<(short __n);\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:181:7: note: candidate function not viable: no known conversion from 'Vector2' to 'unsigned short' for 1st argument\n",
+      "      operator<<(unsigned short __n)\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:189:7: note: candidate function not viable: no known conversion from 'Vector2' to 'int' for 1st argument\n",
+      "      operator<<(int __n);\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:192:7: note: candidate function not viable: no known conversion from 'Vector2' to 'unsigned int' for 1st argument\n",
+      "      operator<<(unsigned int __n)\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:201:7: note: candidate function not viable: no known conversion from 'Vector2' to 'long long' for 1st argument\n",
+      "      operator<<(long long __n)\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:205:7: note: candidate function not viable: no known conversion from 'Vector2' to 'unsigned long long' for 1st argument\n",
+      "      operator<<(unsigned long long __n)\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:220:7: note: candidate function not viable: no known conversion from 'Vector2' to 'double' for 1st argument\n",
+      "      operator<<(double __f)\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:224:7: note: candidate function not viable: no known conversion from 'Vector2' to 'float' for 1st argument\n",
+      "      operator<<(float __f)\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:232:7: note: candidate function not viable: no known conversion from 'Vector2' to 'long double' for 1st argument\n",
+      "      operator<<(long double __f)\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:270:7: note: candidate function not viable: no known conversion from 'Vector2' to 'std::basic_ostream<char, std::char_traits<char> >::__streambuf_type *' (aka 'basic_streambuf<char, std::char_traits<char> > *') for 1st argument\n",
+      "      operator<<(__streambuf_type* __sb);\n",
+      "      ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:502:5: note: candidate function not viable: no known conversion from 'Vector2' to 'char' for 2nd argument\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __out, char __c)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:508:5: note: candidate function not viable: no known conversion from 'Vector2' to 'char' for 2nd argument\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, char __c)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:514:5: note: candidate function not viable: no known conversion from 'Vector2' to 'signed char' for 2nd argument\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, signed char __c)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:519:5: note: candidate function not viable: no known conversion from 'Vector2' to 'unsigned char' for 2nd argument\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, unsigned char __c)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:556:5: note: candidate function not viable: no known conversion from 'Vector2' to 'const char *' for 2nd argument\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, const char* __s)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:569:5: note: candidate function not viable: no known conversion from 'Vector2' to 'const signed char *' for 2nd argument\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, const signed char* __s)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:574:5: note: candidate function not viable: no known conversion from 'Vector2' to 'const unsigned char *' for 2nd argument\n",
+      "    operator<<(basic_ostream<char, _Traits>& __out, const unsigned char* __s)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/ostream.tcc:321:5: note: candidate function not viable: no known conversion from 'Vector2' to 'const char *' for 2nd argument\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __out, const char* __s)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/iomanip:79:5: note: candidate function not viable: no known conversion from 'Vector2' to 'std::_Resetiosflags' for 2nd argument\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __os, _Resetiosflags __f)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/iomanip:109:5: note: candidate function not viable: no known conversion from 'Vector2' to 'std::_Setiosflags' for 2nd argument\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __os, _Setiosflags __f)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/iomanip:143:5: note: candidate function not viable: no known conversion from 'Vector2' to 'std::_Setbase' for 2nd argument\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __os, _Setbase __f)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/iomanip:208:5: note: candidate function not viable: no known conversion from 'Vector2' to 'std::_Setprecision' for 2nd argument\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __os, _Setprecision __f)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/iomanip:238:5: note: candidate function not viable: no known conversion from 'Vector2' to 'std::_Setw' for 2nd argument\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __os, _Setw __f)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:497:5: note: candidate template ignored: deduced conflicting types for parameter '_CharT' ('char' vs. 'Vector2')\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __out, _CharT __c)\n",
+      "    ^\n"
+     ]
+    },
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/basic_string.h:6082:5: note: candidate template ignored: could not match 'basic_string<type-parameter-0-0, type-parameter-0-1, type-parameter-0-2>' against 'Vector2'\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __os,\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:539:5: note: candidate template ignored: could not match 'const _CharT *' against 'Vector2'\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __out, const _CharT* __s)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/shared_ptr.h:66:5: note: candidate template ignored: could not match '__shared_ptr<type-parameter-0-2, _Lp>' against 'Vector2'\n",
+      "    operator<<(std::basic_ostream<_Ch, _Tr>& __os,\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:410:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n",
+      "    _DEFINE_EXPR_BINARY_OPERATOR(<<, __shift_left)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:341:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n",
+      "    operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v,   \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:410:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:354:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n",
+      "    operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v,     \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:410:5: note: candidate template ignored: could not match '_Expr<type-parameter-0-0, typename type-parameter-0-0::value_type>' against 'Vector2'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:367:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n",
+      "    operator _Op(const typename _Dom::value_type& __t,                  \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:410:5: note: candidate template ignored: could not match '_Expr' against 'basic_ostream'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:380:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n",
+      "    operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e,      \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:410:5: note: candidate template ignored: could not match '_Expr<type-parameter-0-0, typename type-parameter-0-0::value_type>' against 'Vector2'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:393:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n",
+      "    operator _Op(const valarray<typename _Dom::value_type>& __v,        \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1180:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n",
+      "_DEFINE_BINARY_OPERATOR(<<, __shift_left)\n",
+      "^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1144:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n",
+      "    operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w)    \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1180:1: note: candidate template ignored: could not match 'valarray' against 'basic_ostream'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n",
+      "    operator _Op(const valarray<_Tp>& __v, const _Tp& __t)              \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1180:1: note: candidate template ignored: could not match 'valarray<type-parameter-0-0>' against 'Vector2'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1165:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n",
+      "    operator _Op(const _Tp& __t, const valarray<_Tp>& __v)              \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/iomanip:178:5: note: candidate template ignored: could not match '_Setfill<type-parameter-0-0>' against 'Vector2'\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __os, _Setfill<_CharT> __f)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/ostream:682:5: note: candidate template ignored: requirement '__and_<__not_<is_lvalue_reference<basic_ostream<char> &> >, __is_convertible_to_basic_ostream<basic_ostream<char> &>, __is_insertable<__rvalue_ostream_type<basic_ostream<char> &>, const Vector2 &> >::value' was not satisfied [with _Ostream = std::basic_ostream<char> &, _Tp = Vector2]\n",
+      "    operator<<(_Ostream&& __os, const _Tp& __x)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/iomanip:311:5: note: candidate template ignored: could not match '_Put_money<type-parameter-0-2>' against 'Vector2'\n",
+      "    operator<<(basic_ostream<_CharT, _Traits>& __os, _Put_money<_MoneyT> __f)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/iomanip:363:5: note: candidate template ignored: could not match '_Put_time<type-parameter-0-0>' against 'Vector2'"
+     ]
+    }
+   ],
+   "source": [
+    "Vector2 v2( 3.0, 2.0 );\n",
+    "std::cout << v << \"\\n\";\n",
+    "v = v2;\n",
+    "std::cout << v;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "__Default constructability__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(0, 0)"
+     ]
+    }
+   ],
+   "source": [
+    "Vector2 v3;\n",
+    "std::cout << v3;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "__Single value constructor__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(1, 1)"
+     ]
+    }
+   ],
+   "source": [
+    "Vector2 v4a( 1.0 );\n",
+    "std::cout << v4a;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "source": [
+    "__Constructors with a single parameter enable implicit conversions by default__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(6, 6)"
+     ]
+    }
+   ],
+   "source": [
+    "double d = 6.0;\n",
+    "Vector2 v6(1.0, 2.0);\n",
+    "v6 = Vector2( d );\n",
+    "std::cout << v6;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Disallow unwanted implicit conversions by making the constructor `expclicit`!"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Arithmetic operators__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Vector2 v10(1, 2), v11(2,3);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(3, 5)"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << v10 + v11;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(2, 4)"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << v10 * 2.0;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Non-const member functions__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Vector2 v20;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(20, 0)"
+     ]
+    }
+   ],
+   "source": [
+    "v20.setX( 20 );\n",
+    "std::cout << v20;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const Vector2 v21;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_14:2:2: error: member function 'setX' not viable: 'this' argument has type 'const Vector2', but function is not marked const\n",
+      " v21.setX( 20 );\n",
+      " ^~~\n",
+      "input_line_8:13:10: note: 'setX' declared here\n",
+      "    void setX( const double x ) { x_ = x; }\n",
+      "         ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "v21.setX( 20 );"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "__Giving access to member variables__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Vector2 v30;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0\n",
+      "5"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << v30.x() << \"\\n\";\n",
+    "v30.x() = 5.0;\n",
+    "std::cout << v30.x();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "const Vector2 v31;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_14:2:10: error: expression is not assignable\n",
+      " v31.x() = 5.0;\n",
+      " ~~~~~~~ ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "v31.x() = 5.0;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << v31.x();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Separate member function definition from its declaration__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class Counter\n",
+    "{\n",
+    "public:\n",
+    "    Counter(); // initializes count to 0\n",
+    "    void increment();\n",
+    "    int getCount() const;\n",
+    "private:\n",
+    "    int count_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Counter::Counter()\n",
+    "    : count_(0)\n",
+    "{}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void Counter::increment()\n",
+    "{\n",
+    "    ++count_;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Counter c;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "c.increment()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "c.getCount()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int Counter::getCount() const\n",
+    "{\n",
+    "    return count_;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "1"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "Counter counter;\n",
+    "counter.increment();\n",
+    "counter.getCount()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture08_ex.ipynb b/cppcourse/lecture08_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..75b4ba1f0e7a008d7ece2f1d2b3684ddef0a1300
--- /dev/null
+++ b/cppcourse/lecture08_ex.ipynb
@@ -0,0 +1,253 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 8"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Implement a class `Matrix` that stores and manages an `m`x`n` matrix\n",
+    "\n",
+    "- Use data type `double` for the matrix entries\n",
+    "- Use `std::vector` to store the matrix elements in row-wise order\n",
+    "- You will also have to store `m` and `n`. Use `size_t` as their type\n",
+    "- Make sure your `vector`, `m` and `n` are marked private\n",
+    "- Implement the following constructors\n",
+    "    - A Default constructor which initializes an empty matrix\n",
+    "    - A constructor that takes the number of rows, number of columns and a double to initialize the whole Matrix with\n",
+    "    - A constructor that takes the number of rows and columns and initializes the matrix with zeroes\n",
+    "    - A constructor that parses a matrix from a string (see your homework)\n",
+    "- Implement a function `double get( const size_t row, const size_t col )` which returns the respective element of the matrix\n",
+    "- Implement the Insertion operator for `std::ostream`. As you do not have access to your `vector` use the `get` function to access to the elements\n",
+    "- Implement the functions `numRows` and `numCols` which return the number of columns and rows\n",
+    "- See that the `get` function can also be used to set elements\n",
+    "- Implement the operations `+`, `-`, `*` for two matrices. Assume that the functions are called only with matrices of the approrpriate sizes! (You can check your multiplication algorithm against http://www.bluebit.gr/matrix-calculator/matrix_multiplication.aspx)\n",
+    "- Implement the (in)equality operators `==` and `!=`\n",
+    "- Implement a function `transpose`. Maybe the [`vector::swap`](http://en.cppreference.com/w/cpp/container/vector/swap) function is of use to you here to avoid unenecessary copy operations"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// use the defined alternatives for the operator function names when you\n",
+    "// encounter the \"function definition not allowed here\" bug in cling\n",
+    "\n",
+    "#define OPERATOR_PLUS operator+\n",
+    "#define OPERATOR_MINUS operator-\n",
+    "#define OPERATOR_MULT operator*\n",
+    "#define OPERATOR_EX operator>>\n",
+    "#define OPERATOR_INS operator<<\n",
+    "#define OPERATOR_EQ operator==\n",
+    "#define OPERATOR_IEQ operator!="
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// Put your class here"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// Define longer functions outside of the class for cleaner view of the class declaration"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Some things to test your class with:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const Matrix m0( \"1 2 3 \\n 4 5 6 \\n 7 8 9\" );\n",
+    "const Matrix m1( \"9 8 7 \\n 6 5 4 \\n 3 2 1\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "std::cout << m0 << \"\\n\\n\" << m1;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "std::cout << m0.get(0, 0) << \" \" << m0.get(0, 1) << \" \" << m0.get(0, 2) << \"\\n\"\n",
+    "          << m0.get(1, 0) << \" \" << m0.get(1, 1) << \" \" << m0.get(1, 2) << \"\\n\"\n",
+    "          << m0.get(2, 0) << \" \" << m0.get(2, 1) << \" \" << m0.get(2, 2) << \"\\n\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << m0.rows() << \"x\" << m0.cols();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << m0 * m1;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << m0 + m1;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << m0 - m1;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << (m0 == m1);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << (m0 != m1);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const Matrix m2 = m0;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << (m2 == m0);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << (m2 != m0);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const Matrix m3( 100, 100, 2.0 );\n",
+    "Matrix m4( 100, 100, 0.0 );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for( size_t i = 0; i < m4.rows(); ++i )\n",
+    "    m4.get(i, i) = 1; // generate the unit matrix"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << (m3 == m3 * m4); "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << Matrix( \"1 2 3 4\\n 5 6 7 8\" ) * Matrix( \"1 2 \\n 3 4 \\n  \\ \" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture08_ex_sol.ipynb b/cppcourse/lecture08_ex_sol.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..c1daee00390d18b6a5c1d01ea16323a4d56d0ac1
--- /dev/null
+++ b/cppcourse/lecture08_ex_sol.ipynb
@@ -0,0 +1,586 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 8"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Implement a class `Matrix` that stores and manages an `m`x`n` matrix\n",
+    "\n",
+    "- Use data type `double` for the matrix entries\n",
+    "- Use `std::vector` to store the matrix elements in row-wise order\n",
+    "- You will also have to store `m` and `n`. Use `size_t` as their type\n",
+    "- Make sure your `vector`, `m` and `n` are marked private\n",
+    "- Implement the following constructors\n",
+    "    - A Default constructor which initializes an empty matrix\n",
+    "    - A constructor that takes the number of rows, number of columns and a double to initialize the whole Matrix with\n",
+    "    - A constructor that takes the number of rows and columns and initializes the matrix with zeroes\n",
+    "    - A constructor that parses a matrix from a string (see your homework)\n",
+    "- Implement a function `double get( const size_t row, const size_t col )` which returns the respective element of the matrix\n",
+    "- Implement the Insertion operator for `std::ostream`. As you do not have access to your `vector` use the `get` function to access to the elements\n",
+    "- Implement the functions `numRows` and `numCols` which return the number of columns and rows\n",
+    "- See that the `get` function can also be used to set elements\n",
+    "- Implement the operations `+`, `-`, `*` for two matrices. Assume that the functions are called only with matrices of the approrpriate sizes! (You can check your multiplication algorithm against http://www.bluebit.gr/matrix-calculator/matrix_multiplication.aspx)\n",
+    "- Implement the (in)equality operators `==` and `!=`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "// use the defined alternatives for the operator function names when you\n",
+    "// encounter the \"function definition not allowed here\" bug in cling\n",
+    "\n",
+    "#define OPERATOR_PLUS operator+\n",
+    "#define OPERATOR_MINUS operator-\n",
+    "#define OPERATOR_MULT operator*\n",
+    "#define OPERATOR_EX operator>>\n",
+    "#define OPERATOR_INS operator<<\n",
+    "#define OPERATOR_EQ operator==\n",
+    "#define OPERATOR_IEQ operator!="
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <vector>\n",
+    "#include <string>\n",
+    "#include <type_traits>\n",
+    "\n",
+    "template< typename T >\n",
+    "class Matrix\n",
+    "{\n",
+    "    static_assert( std::is_arithmetic<T>::value, \"Matrix must be used with arithmetic types only!\" );\n",
+    "public:\n",
+    "    Matrix() = default;\n",
+    "    Matrix( const size_t m, const size_t n, const T v ) \n",
+    "        : m_(m), n_(n), values_( m * n, v ) { }\n",
+    "    Matrix( const size_t m, const size_t n ) : Matrix( m, n, 0.0 ) { }\n",
+    "    Matrix( const std::string & s );\n",
+    "    \n",
+    "    T   get( const size_t row, const size_t col ) const { return values_[ row * n_ + col ]; }\n",
+    "    T & get( const size_t row, const size_t col ) { return values_[ row * n_ + col ]; }\n",
+    "    \n",
+    "    size_t rows() const { return m_; }\n",
+    "    size_t cols() const { return n_; }\n",
+    "    \n",
+    "    Matrix operator+( const Matrix & other ) const;\n",
+    "    Matrix operator-( const Matrix & other ) const;\n",
+    "    Matrix operator*( const Matrix & other ) const;\n",
+    "    \n",
+    "    bool operator==( const Matrix & other ) const;\n",
+    "    bool operator!=( const Matrix & other ) const;\n",
+    "    \n",
+    "    void transpose();    \n",
+    "    \n",
+    "private:\n",
+    "    size_t m_ = 0;\n",
+    "    size_t n_ = 0;\n",
+    "    std::vector<T> values_;\n",
+    "};\n",
+    "    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <sstream>\n",
+    "\n",
+    "template< typename T >\n",
+    "Matrix<T>::Matrix( const std::string & s )\n",
+    "    : Matrix()\n",
+    "{    \n",
+    "    std::istringstream iss(s);\n",
+    "    \n",
+    "    std::string line;\n",
+    "    while( std::getline( iss, line ) )\n",
+    "    {\n",
+    "        ++m_;\n",
+    "        std::istringstream issLine( line );\n",
+    "        T v;\n",
+    "        n_ = 0;\n",
+    "        while( issLine >> v )\n",
+    "        {\n",
+    "            ++n_;\n",
+    "            values_.push_back( v );\n",
+    "        }\n",
+    "    }\n",
+    "        \n",
+    "    if( n_ * m_ != values_.size() )\n",
+    "        throw std::invalid_argument(\"Invalid matrix string!\");\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename T >\n",
+    "Matrix<T> Matrix<T>::OPERATOR_PLUS( const Matrix & other ) const\n",
+    "{\n",
+    "    Matrix<T> result( *this ); // copy *this into the result    \n",
+    "    std::transform( result.values_.begin(), result.values_.end(), \n",
+    "                    other.values_.begin(), result.values_.begin(), \n",
+    "                    std::plus<T>() );\n",
+    "    return result;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename T >\n",
+    "Matrix<T> Matrix<T>::OPERATOR_MINUS( const Matrix & other ) const\n",
+    "{\n",
+    "    Matrix<T> result( *this ); // copy *this into the result    \n",
+    "    std::transform( result.values_.begin(), result.values_.end(),\n",
+    "                    other.values_.begin(), result.values_.begin(),\n",
+    "                    std::minus<T>() );\n",
+    "    return result;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename T >\n",
+    "Matrix<T> Matrix<T>::OPERATOR_MULT( const Matrix & other ) const\n",
+    "{\n",
+    "    if( n_ != other.m_ )\n",
+    "        throw std::invalid_argument(\"Matrix multiplication failed due to invalid layout!\");\n",
+    "        \n",
+    "    Matrix<T> result( m_, other.n_ );\n",
+    "    \n",
+    "    for( size_t i = 0; i < m_; ++i )\n",
+    "        for( size_t j = 0; j < other.n_; ++j )\n",
+    "            for( int k = 0; k < n_; ++k )\n",
+    "                result.get( i, j ) += get( i, k ) * other.get( k, j );\n",
+    "    \n",
+    "    return result;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename T >\n",
+    "bool Matrix<T>::OPERATOR_EQ( const Matrix & other ) const\n",
+    "{\n",
+    "    return m_ == other.m_ && n_ == other.n_ && values_ == other.values_;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename T >\n",
+    "bool Matrix<T>::OPERATOR_IEQ( const Matrix & other ) const\n",
+    "{\n",
+    "    return !(*this == other);\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename T >\n",
+    "std::ostream & OPERATOR_INS( std::ostream & os, const Matrix<T> & m )\n",
+    "{\n",
+    "    for( size_t i = 0; i < m.rows(); ++i )\n",
+    "    {\n",
+    "        if( i != 0 )\n",
+    "            os << \"\\n\";\n",
+    "        \n",
+    "        for( size_t j = 0; j < m.cols(); ++j )\n",
+    "        {\n",
+    "            if( j != 0 )\n",
+    "                os << \" \";\n",
+    "            \n",
+    "            os << m.get( i, j );\n",
+    "        }\n",
+    "    }\n",
+    "    \n",
+    "    return os;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename T >\n",
+    "void Matrix<T>::transpose()\n",
+    "{\n",
+    "    for( size_t i = 0; i < m_; ++i )\n",
+    "        for( size_t j = i + 1; j < n_; ++j )\n",
+    "            std::swap( get(i,j), get(j,i) );\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Some things to test your class with:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const Matrix<double> m0( \"1 2 3 \\n 4 5 6 \\n 7 8 9\" );\n",
+    "const Matrix<double> m1( \"9 8 7 \\n 6 5 4 \\n 3 2 1\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1 2 3\n",
+      "4 5 6\n",
+      "7 8 9\n",
+      "\n",
+      "9 8 7\n",
+      "6 5 4\n",
+      "3 2 1"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "std::cout << m0 << \"\\n\\n\" << m1;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1 2 3\n",
+      "4 5 6\n",
+      "7 8 9\n"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << m0.get(0, 0) << \" \" << m0.get(0, 1) << \" \" << m0.get(0, 2) << \"\\n\"\n",
+    "          << m0.get(1, 0) << \" \" << m0.get(1, 1) << \" \" << m0.get(1, 2) << \"\\n\"\n",
+    "          << m0.get(2, 0) << \" \" << m0.get(2, 1) << \" \" << m0.get(2, 2) << \"\\n\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "3x3"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << m0.rows() << \"x\" << m0.cols();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "30 24 18\n",
+      "84 69 54\n",
+      "138 114 90"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << m0 * m1;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "10 10 10\n",
+      "10 10 10\n",
+      "10 10 10"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << m0 + m1;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "-8 -6 -4\n",
+      "-2 0 2\n",
+      "4 6 8"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << m0 - m1;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << (m0 == m1);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << (m0 != m1);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const Matrix<double> m2 = m0;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << (m2 == m0);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << (m2 != m0);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const Matrix<double> m3( 100, 100, 2.0 );\n",
+    "Matrix<double> m4( 100, 100, 0.0 );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "for( size_t i = 0; i < m4.rows(); ++i )\n",
+    "    m4.get(i, i) = 1; // generate the unit matrix"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << (m3 == m3 * m4); "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "50 60\n",
+      "114 140"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << Matrix<double>( \"1 2 3 4\\n 5 6 7 8\" ) * Matrix<double>( \"1 2 \\n 3 4 \\n 5 6 \\n 7 8\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "Standard Exception",
+     "evalue": "Matrix multiplication failed due to invalid layout!",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: Matrix multiplication failed due to invalid layout!"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << Matrix<double>( \"1 2 3 4\\n 5 6 7 8\" ) * Matrix<double>( \"1 2 \\n 3 4 \\n 5 6\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 28,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "1 4 7\n",
+      "2 5 8\n",
+      "3 6 9"
+     ]
+    }
+   ],
+   "source": [
+    "Matrix<double> m5( \"1 2 3 \\n 4 5 6 \\n 7 8 9\" );\n",
+    "m5.transpose();\n",
+    "std::cout << m5;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture09.ipynb b/cppcourse/lecture09.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..53696e4ada003f84a49f858d65693c8c6dfee86e
--- /dev/null
+++ b/cppcourse/lecture09.ipynb
@@ -0,0 +1,532 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Lecture 9\n",
+    "# Templates"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "int abs( int x )\n",
+    "{\n",
+    "    if( x < 0 )\n",
+    "        return -x;\n",
+    "    else\n",
+    "        return x;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "double abs( double x )\n",
+    "{\n",
+    "    if( x < 0.0 )\n",
+    "        return -x;\n",
+    "    else\n",
+    "        return x;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "abs( -5 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "abs( -5.5 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "abs( -5.5f )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "T abs( T x )\n",
+    "{\n",
+    "    if( x < T(0) )\n",
+    "        return -x;\n",
+    "    else\n",
+    "        return x;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "template< typename T >\n",
+    "T abs( T x )\n",
+    "{\n",
+    "    if( x < T(0) )\n",
+    "        return -x;\n",
+    "    else\n",
+    "        return x;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "abs( 5l ) // instantiation"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "abs( 5.5f ) // template type T is automatically deduced"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "class Vector2\n",
+    "{\n",
+    "public:\n",
+    "    Vector2( const double x, const double y )\n",
+    "        : x_(x), y_(y) {}\n",
+    "    \n",
+    "    double x() const { return x_; }\n",
+    "    double y() const { return y_; }\n",
+    "private:\n",
+    "    double x_, y_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "template <typename T>\n",
+    "class Vector2\n",
+    "{\n",
+    "public:\n",
+    "    Vector2( const T x, const T y )\n",
+    "        : x_(x), y_(y) {}\n",
+    "    \n",
+    "    T x() const { return x_; }\n",
+    "    T y() const { return y_; }\n",
+    "private:\n",
+    "    T x_, y_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Vector2<double> v( 10.5, 11.9 ); //C++17: automatic deduction here also "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Vector2<int> vi(2, 5);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "#include <ostream>\n",
+    "#include <iostream>\n",
+    "\n",
+    "#define INSERTION_OPERATOR operator<< // Workaround for a bug of cling\n",
+    "\n",
+    "template< typename T >\n",
+    "std::ostream & INSERTION_OPERATOR( std::ostream & os, const Vector2<T> & v )\n",
+    "{\n",
+    "    os << \"(\" << v.x() << \", \" << v.y() << \")\";\n",
+    "    return os;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << v;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << vi;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "template <typename T>\n",
+    "class Vector2\n",
+    "{\n",
+    "public:\n",
+    "    Vector2( const T x, const T y )\n",
+    "        : x_(x), y_(y) {}\n",
+    "    \n",
+    "    T x() const { return x_; }\n",
+    "    T y() const { return y_; }\n",
+    "    \n",
+    "    Vector2 operator+( const Vector2 & o ) const {\n",
+    "        return Vector2( x_ + o.x_, y_ + o.y_ );\n",
+    "    }    \n",
+    "        \n",
+    "    Vector2 operator-( const Vector2 & o ) const {\n",
+    "        return Vector2( x_ - o.x_, y_ - o.y_ );\n",
+    "    }\n",
+    "private:\n",
+    "    T x_, y_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "#include <string>\n",
+    "#include <iostream>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "Vector2<std::string> v( \"Hello\", \"World\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "std::cout << v;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "Vector2<std::string> v2( \"Template\", \"Stuff\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "(HelloTemplate, WorldStuff)"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << v + v2;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_7:16:28: error: invalid operands to binary expression ('const std::__cxx11::basic_string<char>' and 'const std::__cxx11::basic_string<char>')\n",
+      "        return Vector2( x_ - o.x_, y_ - o.y_ );\n",
+      "                        ~~ ^ ~~~~\n",
+      "input_line_16:2:17: note: in instantiation of member function 'Vector2<std::__cxx11::basic_string<char> >::operator-' requested here\n",
+      " std::cout << v - v2;\n",
+      "                ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/stl_bvector.h:208:3: note: candidate function not viable: no known conversion from 'const std::__cxx11::basic_string<char>' to 'const std::_Bit_iterator_base' for 1st argument\n",
+      "  operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)\n",
+      "  ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/stl_iterator.h:389:5: note: candidate template ignored: could not match 'reverse_iterator' against 'basic_string'\n",
+      "    operator-(const reverse_iterator<_IteratorL>& __x,\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/stl_iterator.h:950:5: note: candidate template ignored: could not match '__normal_iterator' against 'basic_string'\n",
+      "    operator-(const __normal_iterator<_IteratorL, _Container>& __lhs,\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/stl_iterator.h:962:5: note: candidate template ignored: could not match '__normal_iterator' against 'basic_string'\n",
+      "    operator-(const __normal_iterator<_Iterator, _Container>& __lhs,\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/stl_iterator.h:1191:5: note: candidate template ignored: could not match 'move_iterator' against 'basic_string'\n",
+      "    operator-(const move_iterator<_IteratorL>& __x,\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:403:5: note: candidate template ignored: could not match '_Expr' against 'basic_string'\n",
+      "    _DEFINE_EXPR_BINARY_OPERATOR(-, __minus)\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:341:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n",
+      "    operator _Op(const _Expr<_Dom1, typename _Dom1::value_type>& __v,   \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:403:5: note: candidate template ignored: could not match '_Expr' against 'basic_string'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:354:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n",
+      "    operator _Op(const _Expr<_Dom, typename _Dom::value_type>& __v,     \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:403:5: note: candidate template ignored: could not match '_Expr' against 'basic_string'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:367:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n",
+      "    operator _Op(const typename _Dom::value_type& __t,                  \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:403:5: note: candidate template ignored: could not match '_Expr' against 'basic_string'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:380:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n",
+      "    operator _Op(const _Expr<_Dom,typename _Dom::value_type>& __e,      \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:403:5: note: candidate template ignored: could not match '_Expr' against 'basic_string'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/valarray_after.h:393:5: note: expanded from macro '_DEFINE_EXPR_BINARY_OPERATOR'\n",
+      "    operator _Op(const valarray<typename _Dom::value_type>& __v,        \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1173:1: note: candidate template ignored: could not match 'valarray' against 'basic_string'\n",
+      "_DEFINE_BINARY_OPERATOR(-, __minus)\n",
+      "^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1144:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n",
+      "    operator _Op(const valarray<_Tp>& __v, const valarray<_Tp>& __w)    \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1173:1: note: candidate template ignored: could not match 'valarray' against 'basic_string'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1155:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n",
+      "    operator _Op(const valarray<_Tp>& __v, const _Tp& __t)              \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1173:1: note: candidate template ignored: could not match 'valarray' against 'basic_string'\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/valarray:1165:5: note: expanded from macro '_DEFINE_BINARY_OPERATOR'\n",
+      "    operator _Op(const _Tp& __t, const valarray<_Tp>& __v)              \\\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/stl_deque.h:351:5: note: candidate template ignored: could not match '_Deque_iterator' against 'basic_string'\n",
+      "    operator-(const _Deque_iterator<_Tp, _Ref, _Ptr>& __x,\n",
+      "    ^\n",
+      "/usr/local/bin/../lib/gcc/../../gcc/include/c++/bits/stl_deque.h:363:5: note: candidate template ignored: could not match '_Deque_iterator' against 'basic_string'\n",
+      "    operator-(const _Deque_iterator<_Tp, _RefL, _PtrL>& __x,\n",
+      "    ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << v - v2;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "#include <type_traits>\n",
+    "\n",
+    "template <typename T>\n",
+    "class Vector2\n",
+    "{\n",
+    "public:\n",
+    "    static_assert( std::is_arithmetic<T>::value,\n",
+    "                   \"Vector2 must be used with arithmetic types only!\" );\n",
+    "    \n",
+    "    Vector2( const T x, const T y )\n",
+    "        : x_(x), y_(y) {}\n",
+    "    \n",
+    "    T x() const { return x_; }\n",
+    "    T y() const { return y_; }\n",
+    "private:\n",
+    "    T x_, y_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_8:5:5: error: static_assert failed \"Vector2 must be used with arithmetic types only!\"\n",
+      "    static_assert( std::is_arithmetic<T>::value,\n",
+      "    ^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n",
+      "input_line_9:2:2: note: in instantiation of template class 'Vector2<std::__cxx11::basic_string<char> >' requested here\n",
+      " Vector2<std::string>(\"Hello\", \"World\");\n",
+      " ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "Vector2<std::string>(\"Hello\", \"World\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture09_ex.ipynb b/cppcourse/lecture09_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..c036de375750d1db111d88d95b93aa8179cc9cb0
--- /dev/null
+++ b/cppcourse/lecture09_ex.ipynb
@@ -0,0 +1,114 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Excersies to Lecture 9"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function template `print` that receives one argument `value` and prints it to `cout`! What is a good way to pass `value`? By value, by reference or by `const` reference?__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(5);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(\"Hello World!\");"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__An `std::vector` can not be printed to an `std::ostream` by default. Overload the insertion operator (`operator<<`) to pretty-print a vector of _arbitrary type_!__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <vector>\n",
+    "#include <ostream>\n",
+    "\n",
+    "#define INSERTION_OPERATOR operator<< // Workaround for a bug of cling\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << std::vector<int>{1, 2, 3, 4};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::cout << std::vector<std::string>{\"Templates\", \"are\", \"great\" };"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Modify your `Matrix` class to become a class template for arbitrary arithmetic types!__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture09_ex_sol.ipynb b/cppcourse/lecture09_ex_sol.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..54d3a23dbbfa0abc3870e1f62c445c19929349e0
--- /dev/null
+++ b/cppcourse/lecture09_ex_sol.ipynb
@@ -0,0 +1,168 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Excersies to Lecture 9"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function template `print` that receives one argument `value` and prints it to `cout`! What is a good way to pass `value`? By value, by reference or by `const` reference?__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "\n",
+    "template< typename T >\n",
+    "void print( const T & value )\n",
+    "{\n",
+    "    std::cout << value;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "5"
+     ]
+    }
+   ],
+   "source": [
+    "print(5);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Hello World!"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"Hello World!\");"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__An `std::vector` can not be printed to an `std::ostream` by default. Overload the insertion operator (`operator<<`) to pretty print a vector of _arbitrary type_!__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <vector>\n",
+    "#include <ostream>\n",
+    "\n",
+    "#define INSERTION_OPERATOR operator<< // Workaround for a bug of cling\n",
+    "\n",
+    "template<typename T>\n",
+    "std::ostream & INSERTION_OPERATOR( std::ostream & os,\n",
+    "                                   const std::vector<T> & v )\n",
+    "{\n",
+    "    os << \"{\";\n",
+    "    \n",
+    "    if( !v.empty() )\n",
+    "    {\n",
+    "        os << v.front();\n",
+    "        for( auto it = std::next(v.begin()); it != v.end(); ++it )\n",
+    "            os << \", \" << *it;\n",
+    "    }\n",
+    "    \n",
+    "    os << \"}\";\n",
+    "    \n",
+    "    return os;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{1, 2, 3, 4}"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << std::vector<int>{1, 2, 3, 4};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{Templates, are, great}"
+     ]
+    }
+   ],
+   "source": [
+    "std::cout << std::vector<std::string>{\"Templates\", \"are\", \"great\" };"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Modify your `Matrix` class to become a class template for arbitrary arithmetic types!__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture10.ipynb b/cppcourse/lecture10.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..837cb9e83601c943c145614609c5118715d67561
--- /dev/null
+++ b/cppcourse/lecture10.ipynb
@@ -0,0 +1,1184 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Lecture 10: STL"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <vector>\n",
+    "#include <deque>\n",
+    "#include <array>\n",
+    "#include <iostream>\n",
+    "#include <list>\n",
+    "#include <iterator>\n",
+    "#include <set>\n",
+    "#include <map>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> v (10);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::deque<int> d(10);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v[3]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "d[5]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::array<int, 10> a;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "0"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "a[5]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\" }"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::deque<std::string>( 10 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ \"Hello\", \"Hello\", \"Hello\", \"Hello\", \"Hello\", \"Hello\", \"Hello\", \"Hello\", \"Hello\", \"Hello\" }"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::deque<std::string>( 10, \"Hello\" )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ \"C++\", \"is\", \"great!\" }"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::deque<std::string> ddd{ \"C++\", \"is\", \"great!\" };\n",
+    "ddd"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::deque<std::string>()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> v10(100);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> v12( v10 );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v12"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> v13( v12.begin(), v12.end() );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }"
+      ]
+     },
+     "execution_count": 16,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v13"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }"
+      ]
+     },
+     "execution_count": 17,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::list<int>( v12.begin(), v12.end() )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }"
+      ]
+     },
+     "execution_count": 18,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::list<int>( v12.begin(), v12.begin() + 10u )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "100"
+      ]
+     },
+     "execution_count": 19,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v13.size()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "124681952"
+      ]
+     },
+     "execution_count": 20,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v13[120]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "Standard Exception",
+     "evalue": "vector::_M_range_check: __n (which is 120) >= this->size() (which is 100)",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: vector::_M_range_check: __n (which is 120) >= this->size() (which is 100)"
+     ]
+    }
+   ],
+   "source": [
+    "v13.at(120)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> v20;\n",
+    "for( int i = 0; i < 100; ++i )\n",
+    "    v20.push_back( i );\n",
+    "v20"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "v20.erase( v20.begin(), v20.begin() + 9 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "v20"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "v20.insert( std::next(v20.begin()), 10 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "v20"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<std::string> vs;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.push_back( \"Hello\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string( 10, 'X' )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.push_back( std::string( 10, 'X' ) )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.emplace_back( 10, 'X' )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.emplace( vs.begin(), 10, 'Y' )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.assign(100, \"\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "auto it = vs.begin();"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.push_back(\"Hello\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "*it"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const std::string &sr = vs[10];"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sr"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.push_back(\"Hello\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sr"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.capacity()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.size()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.insert( vs.begin(), 100, \"\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.size()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "vs.capacity()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sr"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::set<int> intSet;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "intSet.insert(100);\n",
+    "intSet.insert(20);\n",
+    "intSet.insert(50);\n",
+    "intSet.insert(-15);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "intSet"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "intSet.insert(20);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "intSet"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::pair<std::set<int>::iterator, bool> result = intSet.insert(20)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "*(result.first)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "result.second"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::pair<std::set<int>::iterator, bool> result2 = intSet.insert(21)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "result2.second"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "*result2.first"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::map< int, std::string > ourMap;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ourMap[ 5 ] = \"five\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 5 => \"five\" }"
+      ]
+     },
+     "execution_count": 24,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ourMap"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ourMap[ 3 ] = \"three\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ourMap[ 2 ] = \"two\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ourMap"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ourMap.at( 2 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ourMap[2]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ourMap[1]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ourMap.at( 0 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string find( const std::map<int, std::string> & theMap, \n",
+    "                  const int i )\n",
+    "{\n",
+    "    return theMap.at(i);\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "find( ourMap, 5 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "find( ourMap, 33 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 27,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 2 => \"two\", 3 => \"three\", 5 => \"five\" }"
+      ]
+     },
+     "execution_count": 27,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "ourMap"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2 two\n",
+      "3 three\n",
+      "5 five\n"
+     ]
+    }
+   ],
+   "source": [
+    "for( auto it = ourMap.begin(); it != ourMap.end(); ++it )\n",
+    "{\n",
+    "    std::cout << it->first << \" \" << it->second << \"\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <unordered_set>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::unordered_set<int> uoset;\n",
+    "uoset.insert(100);\n",
+    "uoset.insert(-10);\n",
+    "uoset.insert(5);\n",
+    "uoset.insert(13);\n",
+    "uoset.insert(100);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 5, 100, 13, -10 }"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "uoset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::vector<int> v50;\n",
+    "for( int i = 0; i < 100; ++i )\n",
+    "    v50.push_back( i );\n",
+    "v50"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "auto it = std::find( v50.begin(), v50.end(), 87 );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "it = std::find( v50.begin(), v50.end(), 130 );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Element not found!"
+     ]
+    }
+   ],
+   "source": [
+    "if( it == v50.end() )\n",
+    "    std::cout << \"Element not found!\";\n",
+    "else\n",
+    "    std::cout << \"Found element \" << *it <<\n",
+    "                 \" at position \" << int(std::distance(v50.begin(), it));"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::set<int> setInts{4, 2, 7, 10};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "auto setIt = setInts.find( 2 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "@0x7fdb57fbe208"
+      ]
+     },
+     "execution_count": 48,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "setIt = setInts.find( 11 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Element not found!"
+     ]
+    }
+   ],
+   "source": [
+    "if( setIt == setInts.end() )\n",
+    "    std::cout << \"Element not found!\";\n",
+    "else\n",
+    "    std::cout << \"Found element \" << *setIt <<\n",
+    "                 \" at position \" << int(std::distance(setInts.begin(), setIt));"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "@0x9b2e1f0"
+      ]
+     },
+     "execution_count": 54,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v50.erase( std::remove( v50.begin(), v50.end(), 10 ), v50.end() )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 0, 1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99 }"
+      ]
+     },
+     "execution_count": 55,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "v50"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<std::string> vstr{ \"C++\", \"is\", \"so\", \"easy!\"};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 62,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "bool selectString( const std::string & s )\n",
+    "{\n",
+    "    return s.size() == 5;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 63,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "auto strIt = std::find_if( vstr.begin(), vstr.end(), selectString );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 64,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "easy!"
+     ]
+    }
+   ],
+   "source": [
+    "if( strIt == vstr.end() )\n",
+    "    std::cout << \"not found!\";\n",
+    "else\n",
+    "    std::cout << *strIt;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture10_ex.ipynb b/cppcourse/lecture10_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..6af77bd641a0793e3cefb17c614ede8b6ada3795
--- /dev/null
+++ b/cppcourse/lecture10_ex.ipynb
@@ -0,0 +1,392 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 10"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <vector>\n",
+    "#include <list>\n",
+    "#include <deque>\n",
+    "#include <iterator>\n",
+    "#include <algorithm>\n",
+    "#include <iostream>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a vector, partitions it according to whether the elements are even or odd and then prints the even and odd elements. Take a look at `std::partition` and note that the order of elements may change.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void printEvenOdd( std::vector<int> & v )\n",
+    "{\n",
+    "    \n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> values{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n",
+    "printEvenOdd( values );"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that splits a `vector<int>` into even and odd values. `std::partition_copy` and `std::back_inserter` might help.__ "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void splitEvenOdd( const std::vector<int> & v, std::vector<int> & evenValues, std::vector<int> & oddValues )\n",
+    "{\n",
+    "    \n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const std::vector<int> input{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n",
+    "std::vector<int> evenValues, oddValues;\n",
+    "splitEvenOdd( input, evenValues, oddValues );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "evenValues"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "oddValues"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Can you implement the same functionality using Iterators? Why do we use two distinct types for the output iterators and not one for both?__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename InputIt, typename OutputIt1, typename OutputIt2 >\n",
+    "void splitEvenOddIt( InputIt inputFirst, InputIt inputLast, OutputIt1 evenValues, OutputIt2 oddValues )\n",
+    "{\n",
+    "    \n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const std::list<int> input2{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n",
+    "std::list<int> evenValues2;\n",
+    "std::deque<int> oddValues2;\n",
+    "// add the call to splitEvenOddIt here"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "evenValues2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{}"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "oddValues2"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `median` that takes two Iterators from a sequential container and returns the median value! Make sure your functions works on any sequantial container of any arithmetic type. In case of an even number of elements you return whichever of the two central elements you want. Have a look at `std::nth_element`, note that it modifies the iterator range!__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const std::vector<int> vmi{ 2, 8, 5, 3, -19, 21, -100, 32, 45, -6, 7, 8, 91, -4, -9, -16 };\n",
+    "const std::vector<float> vmf{ 2.0f, -4.0f, -50.0f, 13.4f, 16.8f, 19.5f };"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_25:2:2: error: use of undeclared identifier 'median'\n",
+      " median( vmi.begin(), vmi.end() )\n",
+      " ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "median( vmi.begin(), vmi.end() )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "median( vmf.begin(), vmf.end() )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Use the follwing Timer class for timing"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <chrono>\n",
+    "\n",
+    "class Timer\n",
+    "{\n",
+    "public:\n",
+    "    Timer() : begin_(), end_( begin_ ) { }\n",
+    "    \n",
+    "    void start()\n",
+    "    {\n",
+    "        begin_ = std::chrono::high_resolution_clock::now();\n",
+    "        end_ = begin_;\n",
+    "    }\n",
+    "    \n",
+    "    void stop()\n",
+    "    {\n",
+    "        end_ = std::chrono::high_resolution_clock::now();\n",
+    "    }\n",
+    "    \n",
+    "    double elapsed() const\n",
+    "    {\n",
+    "        std::chrono::duration<double, std::milli> elapsed = end_ - begin_;\n",
+    "        return elapsed.count();\n",
+    "    }\n",
+    "    \n",
+    "private:\n",
+    "    std::chrono::high_resolution_clock::time_point begin_;\n",
+    "    std::chrono::high_resolution_clock::time_point end_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Use it like this:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Building a vector element by element took 136.633ms\n",
+      "Building a vector with prereseved space took 98.1253ms"
+     ]
+    }
+   ],
+   "source": [
+    "Timer timer;\n",
+    "std::vector<int> v0, v1;\n",
+    "timer.start();\n",
+    "for( int i = 0; i < 10000000; ++i )\n",
+    "    v0.push_back( 0 );\n",
+    "timer.stop();\n",
+    "std::cout << \"Building a vector element by element took \" << timer.elapsed() << \"ms\\n\";\n",
+    "timer.start();\n",
+    "v1.reserve(10000000);\n",
+    "for( int i = 0; i < 10000000; ++i )\n",
+    "    v1.push_back( 0 );\n",
+    "timer.stop();\n",
+    "std::cout << \"Building a vector with prereserved space took \" << timer.elapsed() << \"ms\";\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Compare the `median` function you wrote using `nth_element` with a `medianFull` function that uses `std::sort` and sorts the whole vector! Use a large vector (1 million elements or more)__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Compare the runtimes of a `std::fill` operation on an `std::vector` with that on an `std::list`. Use reasonably large containers for you tests__"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Implement `operator+` and `operator-` using `std::transform`. Do you need to use `std::back_inserter`? If no, is it better to use one?__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture10_ex_sol.ipynb b/cppcourse/lecture10_ex_sol.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..12727ba04eeee1fb8888cb0e62a3d296976b0224
--- /dev/null
+++ b/cppcourse/lecture10_ex_sol.ipynb
@@ -0,0 +1,521 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 10"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <vector>\n",
+    "#include <list>\n",
+    "#include <deque>\n",
+    "#include <iterator>\n",
+    "#include <algorithm>\n",
+    "#include <iostream>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that takes a vector, partitions it according to whether the elements are even or odd and then prints the even and odd elements. Take a look at `std::partition` and note that the order of elements may change.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void printEvenOdd( std::vector<int> & v )\n",
+    "{\n",
+    "    auto it = std::stable_partition( v.begin(), v.end(),\n",
+    "                             []( const auto & v ) {\n",
+    "                                 return v % 2 == 0;\n",
+    "                             } );\n",
+    "    std::copy( v.begin(), it, std::ostream_iterator<int>( std::cout, \" \" ) );\n",
+    "    std::cout << \"\\n\";\n",
+    "    std::copy( it, v.end(), std::ostream_iterator<int>( std::cout, \" \" ) );\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "2 4 6 8 10 \n",
+      "1 3 5 7 9 "
+     ]
+    }
+   ],
+   "source": [
+    "std::vector<int> values{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n",
+    "printEvenOdd( values );"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function that splits a `vector<int>` into even and odd values. `std::partition_copy` and `std::back_inserter` might help.__ "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void splitEvenOdd( const std::vector<int> & v,\n",
+    "                   std::vector<int> & evenValues,\n",
+    "                   std::vector<int> & oddValues )\n",
+    "{\n",
+    "    std::partition_copy( v.begin(), v.end(), \n",
+    "                         std::back_inserter(evenValues),\n",
+    "                         std::back_inserter(oddValues),\n",
+    "                         [](const auto & v){\n",
+    "                             return v % 2 == 0;\n",
+    "                         });\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const std::vector<int> input{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n",
+    "std::vector<int> evenValues, oddValues;\n",
+    "splitEvenOdd( input, evenValues, oddValues );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 2, 4, 6, 8, 10 }"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "evenValues"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 1, 3, 5, 7, 9 }"
+      ]
+     },
+     "execution_count": 7,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "oddValues"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Can you implement the same functionality using Iterators? Why do we use two distinct types for the output iterators and not one for both?__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename InputIt, typename OutputIt1, typename OutputIt2 >\n",
+    "void splitEvenOddIt( InputIt inputFirst, InputIt inputLast, \n",
+    "                     OutputIt1 evenValues, OutputIt2 oddValues )\n",
+    "{\n",
+    "    std::partition_copy( inputFirst, inputLast, evenValues, oddValues,\n",
+    "                         [](const auto & v){\n",
+    "                            return v % 2 == 0;\n",
+    "                        });\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const std::list<int> input2{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\n",
+    "std::vector<int> evenValues2;\n",
+    "std::deque<int> oddValues2;\n",
+    "splitEvenOddIt( input2.begin(), input2.end(), std::back_inserter(evenValues2), std::back_inserter(oddValues2) );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 2, 4, 6, 8, 10 }"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "evenValues2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{ 1, 3, 5, 7, 9 }"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "oddValues2"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `median` that takes two Iterators from a sequential container and returns the median value! Make sure your functions works on any sequantial container of any arithmetic type. In case of an even number of elements you return whichever of the two central elements you want. Have a look at `std::nth_element`, note that it modifies the iterator range!__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename InputIterator >\n",
+    "typename InputIterator::value_type median( InputIterator first,\n",
+    "                                           InputIterator last )\n",
+    "{\n",
+    "    std::vector<typename InputIterator::value_type> tmp( first, last );\n",
+    "    auto medianIt = std::next(tmp.begin(), tmp.size() / 2);\n",
+    "    std::nth_element( tmp.begin(), medianIt, tmp.end() );\n",
+    "    return *medianIt;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "const std::vector<int> vmi{ 2, 8, 5, 3, -19, 21, -100, 32, 45, -6, 7, 8, 91, -4, -9, -16 };\n",
+    "const std::vector<float> vmf{ 2.0f, -4.0f, -50.0f, 13.4f, 16.8f, 19.5f };"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "5"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "median( vmi.begin(), vmi.end() )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "13.4f"
+      ]
+     },
+     "execution_count": 15,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "median( vmf.begin(), vmf.end() )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Use the follwing Timer class for timing"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <chrono>\n",
+    "\n",
+    "class Timer\n",
+    "{\n",
+    "public:\n",
+    "    Timer() : begin_(), end_( begin_ ) { }\n",
+    "    \n",
+    "    void start()\n",
+    "    {\n",
+    "        begin_ = std::chrono::high_resolution_clock::now();\n",
+    "        end_ = begin_;\n",
+    "    }\n",
+    "    \n",
+    "    void stop()\n",
+    "    {\n",
+    "        end_ = std::chrono::high_resolution_clock::now();\n",
+    "    }\n",
+    "    \n",
+    "    double elapsed() const\n",
+    "    {\n",
+    "        std::chrono::duration<double, std::milli> elapsed = end_ - begin_;\n",
+    "        return elapsed.count();\n",
+    "    }\n",
+    "    \n",
+    "private:\n",
+    "    std::chrono::high_resolution_clock::time_point begin_;\n",
+    "    std::chrono::high_resolution_clock::time_point end_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Use it like this:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Building a vector element by element took 135.603ms\n",
+      "Building a vector with prereserved space took 97.5711ms"
+     ]
+    }
+   ],
+   "source": [
+    "Timer timer;\n",
+    "std::vector<int> v0, v1;\n",
+    "timer.start();\n",
+    "for( int i = 0; i < 10000000; ++i )\n",
+    "    v0.push_back( 0 );\n",
+    "timer.stop();\n",
+    "std::cout << \"Building a vector element by element took \" << timer.elapsed() << \"ms\\n\";\n",
+    "timer.start();\n",
+    "v1.reserve(10000000);\n",
+    "for( int i = 0; i < 10000000; ++i )\n",
+    "    v1.push_back( 0 );\n",
+    "timer.stop();\n",
+    "std::cout << \"Building a vector with prereserved space took \" << timer.elapsed() << \"ms\";\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Compare the `median` function you wrote using `nth_element` with a `medianFull` function that uses `std::sort` and sorts the whole vector! Use a large vector (1 million elements or more)__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template< typename InputIterator >\n",
+    "typename InputIterator::value_type medianFull( InputIterator first,\n",
+    "                                               InputIterator last )\n",
+    "{\n",
+    "    std::vector<typename InputIterator::value_type> tmp( first, last );\n",
+    "    std::sort( tmp.begin(), tmp.end() );\n",
+    "    return tmp[tmp.size() / 2];\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "median = 50001 took 171.5ms\n",
+      "medianFull = 50001 took 1188.76ms\n"
+     ]
+    }
+   ],
+   "source": [
+    "std::vector<double> vec( 100000 );\n",
+    "size_t ctr = vec.size();\n",
+    "for( auto & v : vec )\n",
+    "    v = double(ctr--);\n",
+    "\n",
+    "timer.start();\n",
+    "double med1 = median( vec.begin(), vec.end() );\n",
+    "timer.stop();\n",
+    "std::cout << \"median = \" << med1 << \" took \" << timer.elapsed() << \"ms\\n\";\n",
+    "timer.start();\n",
+    "double med2 = medianFull( vec.begin(), vec.end() );\n",
+    "timer.stop();\n",
+    "std::cout << \"medianFull = \" << med2 << \" took \" << timer.elapsed() << \"ms\\n\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Compare the runtimes of an `std::fill` operation on an `std::vector` with that on an `std::list`. Use reasonably large containers for your tests__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "fill on vector took 71.1855ms\n",
+      "fill on list took 146.078ms\n",
+      "fill on forward list took 146.568ms\n",
+      "fill on deque took 72.1189ms\n",
+      "fill on array took 71.5135ms\n"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    constexpr size_t n = 100000;\n",
+    "    std::vector<double> vec( n );\n",
+    "    std::deque<double> deque( n );\n",
+    "    std::list<double> list( n );\n",
+    "    std::forward_list<double> fwlist( n );\n",
+    "    std::array<double, n> array;\n",
+    "    \n",
+    "    timer.start();\n",
+    "    std::fill( vec.begin(), vec.end(), 5.0 );\n",
+    "    timer.stop();\n",
+    "    std::cout << \"fill on vector took \" << timer.elapsed() << \"ms\\n\";\n",
+    "    \n",
+    "    timer.start();\n",
+    "    std::fill( list.begin(), list.end(), 5.0 );\n",
+    "    timer.stop();\n",
+    "    std::cout << \"fill on list took \" << timer.elapsed() << \"ms\\n\";\n",
+    "    \n",
+    "    timer.start();\n",
+    "    std::fill( fwlist.begin(), fwlist.end(), 5.0 );\n",
+    "    timer.stop();\n",
+    "    std::cout << \"fill on forward list took \" << timer.elapsed() << \"ms\\n\";\n",
+    "    \n",
+    "    timer.start();\n",
+    "    std::fill( deque.begin(), deque.end(), 5.0 );\n",
+    "    timer.stop();\n",
+    "    std::cout << \"fill on deque took \" << timer.elapsed() << \"ms\\n\";\n",
+    "    \n",
+    "    timer.start();\n",
+    "    std::fill( array.begin(), array.end(), 5.0 );\n",
+    "    timer.stop();\n",
+    "    std::cout << \"fill on array took \" << timer.elapsed() << \"ms\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Implement `operator+` and `operator-` using `std::transform`. Do you need to use `std::back_inserter`? If no, is it better to use one?__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture11.ipynb b/cppcourse/lecture11.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..ac4bfa2ce353404fec67c262e58f642a46ed513c
--- /dev/null
+++ b/cppcourse/lecture11.ipynb
@@ -0,0 +1,383 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Lecture 11\n",
+    "# Exceptions"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "Exceptions are runtime anomalies, e.g. loosing a database connection, encountering unexpected input"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Throwing an exception"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <exception>\n",
+    "#include <vector>\n",
+    "#include <iostream>\n",
+    "\n",
+    "void printMatrix( const unsigned int n, const unsigned int m,\n",
+    "                  const std::vector<double> & values )\n",
+    "{\n",
+    "    if( n * m != values.size() )\n",
+    "        throw std::invalid_argument( \"n*m != values.size()\" );\n",
+    "    \n",
+    "    std::cout << \"The Matrix\\n\"; // print Matrix....\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "The Matrix\n"
+     ]
+    }
+   ],
+   "source": [
+    "printMatrix( 10, 10, std::vector<double>(100) )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "ename": "Standard Exception",
+     "evalue": "n*m != values.size()",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: n*m != values.size()"
+     ]
+    }
+   ],
+   "source": [
+    "printMatrix( 10, 10, std::vector<double>(50) )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Catching an exception"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Something went wrong: n*m != values.size()"
+     ]
+    }
+   ],
+   "source": [
+    "try {\n",
+    "   printMatrix( 10, 10, std::vector<double>(50) ); \n",
+    "}\n",
+    "catch( const std::invalid_argument & e ) { // exception handler\n",
+    "    std::cout << \"Something went wrong: \" << e.what();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Exception pass through the callstack"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "void f( const size_t s )\n",
+    "{\n",
+    "    std::cout << \"before\\n\";\n",
+    "    printMatrix( 10, 10, std::vector<double>(s) ); \n",
+    "    std::cout << \"after\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "before\n",
+      "The Matrix\n",
+      "after\n"
+     ]
+    }
+   ],
+   "source": [
+    "f(100);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "before\n"
+     ]
+    },
+    {
+     "ename": "Standard Exception",
+     "evalue": "n*m != values.size()",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: n*m != values.size()"
+     ]
+    }
+   ],
+   "source": [
+    "f(50);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "before\n",
+      "Something went wrong: n*m != values.size()"
+     ]
+    }
+   ],
+   "source": [
+    "try {\n",
+    "   f( 50 ); \n",
+    "}\n",
+    "catch( const std::invalid_argument & e ) { // exception handler\n",
+    "    std::cout << \"Something went wrong: \" << e.what();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Unhandled Exceptions\n",
+    "\n",
+    "Unhandled exceptions lead to a call to the function `terminate` which termintes the program\n",
+    "\n",
+    "In the Jupyter notebook exceptions are caught automatically by the kernel and the error message is printed"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Exception Hierarchy\n",
+    "\n",
+    "Exception classes form a hierarchy starting witch `std::exception` (see http://en.cppreference.com/w/cpp/error/exception)\n",
+    "\n",
+    "You can catch excptions lower in the hirarachy in terms of exception higher in the hirarchy (_polymorphism_)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "void f() { throw std::invalid_argument( \"oops!\" ); }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Invalid Agument! oops!"
+     ]
+    }
+   ],
+   "source": [
+    "try { f(); }\n",
+    "catch( const std::invalid_argument & e ) {\n",
+    "    std::cout << \"Invalid Agument! \" << e.what(); }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Logic Error! oops!"
+     ]
+    }
+   ],
+   "source": [
+    "try { f(); }\n",
+    "catch( const std::logic_error & e ) {\n",
+    "    std::cout << \"Logic Error! \" << e.what(); }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "subslide"
+    }
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Some exception happened! oops!"
+     ]
+    }
+   ],
+   "source": [
+    "try { f(); }\n",
+    "catch( const std::exception & e ) { \n",
+    "    std::cout << \"Some exception happened! \" << e.what(); }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "outputs": [
+    {
+     "ename": "Standard Exception",
+     "evalue": "oops!",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: oops!"
+     ]
+    }
+   ],
+   "source": [
+    "try { f(); }\n",
+    "catch( const std::runtime_error & e ) { \n",
+    "    std::cout << \"Runtime Error! \" << e.what(); }"
+   ]
+  }
+ ],
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture11_ex.ipynb b/cppcourse/lecture11_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..cc1307b31826b22b2924875772e451e6d02c78a3
--- /dev/null
+++ b/cppcourse/lecture11_ex.ipynb
@@ -0,0 +1,82 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 11"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `safeDivide` taking two `double`s as arguments, divides them and returns the result. Throw an exception if the divisor is zero.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "safeDivide( 5.0, 2.0 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "safeDivide( 5.0, 0.0 )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a try block around the call to `safeDivide` and catch the exception. __"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "safeDivide( 3.0, 0.0 );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture11_ex_sol.ipynb b/cppcourse/lecture11_ex_sol.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..b1b28b9fba55adf47411dd772de1c940d230c495
--- /dev/null
+++ b/cppcourse/lecture11_ex_sol.ipynb
@@ -0,0 +1,126 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 11"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a function `safeDivide` taking two `double`s as arguments, divides them and returns the result. Throw an exception if the divisor is zero.__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "double safeDivide( double a, double b )\n",
+    "{\n",
+    "    if( b == 0.0  )\n",
+    "        throw std::invalid_argument(\"Division by Zero!\");\n",
+    "    \n",
+    "    return a / b;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "2.5"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "safeDivide( 5.0, 2.0 )"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "Standard Exception",
+     "evalue": "Division by Zero!",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: Division by Zero!"
+     ]
+    }
+   ],
+   "source": [
+    "safeDivide( 5.0, 0.0 )"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Write a try block around the call to `safeDivide` and catch the exception. __"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Error: Division by Zero!"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "try\n",
+    "{\n",
+    "    safeDivide( 3.0, 0.0 );\n",
+    "}\n",
+    "catch( const std::exception & e )\n",
+    "{\n",
+    "    std::cout << \"Error: \" << e.what();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture12.ipynb b/cppcourse/lecture12.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..a0ce65221e81f217896049a96ebb66cbe48afe5c
--- /dev/null
+++ b/cppcourse/lecture12.ipynb
@@ -0,0 +1,820 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "# Lecture 12\n",
+    "# RAII"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## Memory Management in C++\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "### Dynamic Allocation and Initialization "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "93826640"
+      ]
+     },
+     "execution_count": 1,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "int * pi = new int;\n",
+    "*pi"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "42"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "int * pi2 = new int(42);\n",
+    "*pi2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "42"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "const int * pi3 = new const int(42);\n",
+    "*pi3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"\""
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::string * ps = new std::string;\n",
+    "*ps"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"XXXXXXXXXX\""
+      ]
+     },
+     "execution_count": 5,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "std::string * ps1 = new std::string( 10, 'X');\n",
+    "*ps1"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "### Freeing memory resources"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {
+    "slideshow": {
+     "slide_type": "-"
+    }
+   },
+   "outputs": [],
+   "source": [
+    "delete pi;\n",
+    "delete pi2;\n",
+    "delete pi3;\n",
+    "delete ps;\n",
+    "delete ps1;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int * ip = new int(42);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ip = new int(23);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "### Allocating and freeing arrays of elements"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::string * psa = new std::string[20];"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\"Hello\""
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "psa[10]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "psa[10] = \"Hello\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "delete[] psa;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "slide"
+    }
+   },
+   "source": [
+    "## RAII\n",
+    "### Resource Acquisition Is Initialization"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "The lifecycle of an acquired resource is bound to the lifecycle of an object in C++"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "slideshow": {
+     "slide_type": "fragment"
+    }
+   },
+   "source": [
+    "This concept applies to all kinds of resources: memory, database connections, file handles..."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### A memory managment class "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "template< typename T >\n",
+    "class MemoryManager\n",
+    "{\n",
+    "public:\n",
+    "    explicit MemoryManager( T * const ptr ) : ptr_( ptr ) {\n",
+    "        std::cout << __PRETTY_FUNCTION__ << \"\\n\";\n",
+    "    }\n",
+    "    \n",
+    "    ~MemoryManager() {\n",
+    "        std::cout << __PRETTY_FUNCTION__ << \"\\n\";\n",
+    "        delete ptr_; \n",
+    "    } // Destructor\n",
+    "    \n",
+    "    //MemoryManager( const MemoryManager & other ) = delete;\n",
+    "    MemoryManager( const MemoryManager & other )\n",
+    "     : ptr_( other.ptr_ ? new T( *other.ptr_ ) : nullptr )\n",
+    "     {\n",
+    "         std::cout << __PRETTY_FUNCTION__ << \"\\n\";\n",
+    "     }\n",
+    "    \n",
+    "    // MemoryManager & operator=( const MemoryManager & other ) = delete\n",
+    "    MemoryManager & operator=( const MemoryManager & other )\n",
+    "    {\n",
+    "        std::cout << __PRETTY_FUNCTION__ << \"\\n\";\n",
+    "        delete ptr_;\n",
+    "        ptr_ = new T( *other.ptr_ );\n",
+    "        \n",
+    "        return *this;\n",
+    "    }\n",
+    "    \n",
+    "     MemoryManager( MemoryManager && other )\n",
+    "         : ptr_( other.ptr_ )\n",
+    "     {\n",
+    "         other.ptr_ = nullptr;\n",
+    "         std::cout << __PRETTY_FUNCTION__ << \"\\n\";\n",
+    "     }\n",
+    "    \n",
+    "    MemoryManager & operator=( MemoryManager && other )\n",
+    "    {\n",
+    "        std::cout << __PRETTY_FUNCTION__ << \"\\n\";\n",
+    "        delete ptr_;\n",
+    "        ptr_ = other.ptr_;\n",
+    "        other.ptr_ = nullptr;        \n",
+    "        return *this;\n",
+    "    }\n",
+    "    \n",
+    "    T * get() const { return ptr_; }\n",
+    "private:\n",
+    "    T * ptr_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MemoryManager<int>::MemoryManager(T *const) [T = int]\n",
+      "23\n",
+      "MemoryManager<int>::~MemoryManager() [T = int]\n"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    MemoryManager<int> mm( new int(23) );\n",
+    "    std::cout << *mm.get() << \"\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 18,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "Standard Exception",
+     "evalue": "oops!",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: oops!"
+     ]
+    }
+   ],
+   "source": [
+    "#include <exception>\n",
+    "{\n",
+    "    int * ip = new int(42);\n",
+    "    \n",
+    "    if( true )\n",
+    "    {\n",
+    "        throw std::runtime_error(\"oops!\");\n",
+    "    }\n",
+    "    \n",
+    "    delete ip;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MemoryManager<int>::MemoryManager(T *const) [T = int]\n",
+      "MemoryManager<int>::~MemoryManager() [T = int]\n"
+     ]
+    },
+    {
+     "ename": "Standard Exception",
+     "evalue": "oops!",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: oops!"
+     ]
+    }
+   ],
+   "source": [
+    "void f()\n",
+    "{\n",
+    "    MemoryManager<int> ip( new int(42) );\n",
+    "    \n",
+    "    if( true )\n",
+    "    {\n",
+    "        return;\n",
+    "    }\n",
+    "    \n",
+    "    \n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void f()\n",
+    "{\n",
+    "    throw std::runtime_error(\"oops\");\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MemoryManager<int>::MemoryManager(T *const) [T = int]\n",
+      "MemoryManager<int>::~MemoryManager() [T = int]\n",
+      "oops"
+     ]
+    }
+   ],
+   "source": [
+    "try {\n",
+    "    MemoryManager<int> pi( new int(23) );\n",
+    "    f();   \n",
+    "}\n",
+    "catch( const std::exception & e )\n",
+    "{\n",
+    "    std::cout << e.what();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MemoryManager<int>::MemoryManager(T *const) [T = int]\n",
+      "MemoryManager<int>::MemoryManager(const MemoryManager<T> &) [T = int]\n",
+      "23\n",
+      "23\n",
+      "MemoryManager<int>::~MemoryManager() [T = int]\n",
+      "MemoryManager<int>::~MemoryManager() [T = int]\n"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    MemoryManager<int> mm( new int(23) );\n",
+    "    MemoryManager<int> mm2( mm );\n",
+    "    \n",
+    "    std::cout << *mm.get() << \"\\n\";\n",
+    "    std::cout << *mm2.get() << \"\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MemoryManager<int>::MemoryManager(T *const) [T = int]\n",
+      "MemoryManager<int>::MemoryManager(T *const) [T = int]\n",
+      "MemoryManager<T> &MemoryManager<int>::operator=(const MemoryManager<T> &) [T = int]\n",
+      "42\n",
+      "42\n",
+      "MemoryManager<int>::~MemoryManager() [T = int]\n",
+      "MemoryManager<int>::~MemoryManager() [T = int]\n"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    MemoryManager<int> mm( new int(23) );\n",
+    "    MemoryManager<int> mm2( new int(42) );\n",
+    "    \n",
+    "    mm = mm2;\n",
+    "    \n",
+    "    std::cout << *mm.get() << \"\\n\";\n",
+    "    std::cout << *mm2.get() << \"\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MemoryManager<int>::MemoryManager(T *const) [T = int]\n",
+      "MemoryManager<int>::MemoryManager(MemoryManager<T> &&) [T = int]\n",
+      "23\n",
+      "MemoryManager<int>::~MemoryManager() [T = int]\n",
+      "MemoryManager<int>::~MemoryManager() [T = int]\n"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    MemoryManager<int> mm( new int(23) );\n",
+    "    MemoryManager<int> mm2( std::move( mm ) );\n",
+    "    \n",
+    "    //std::cout << *mm.get() << \"\\n\";\n",
+    "    std::cout << *mm2.get() << \"\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "MemoryManager<int>::MemoryManager(T *const) [T = int]\n",
+      "MemoryManager<int>::MemoryManager(T *const) [T = int]\n",
+      "MemoryManager<T> &MemoryManager<int>::operator=(MemoryManager<T> &&) [T = int]\n",
+      "23\n",
+      "MemoryManager<int>::~MemoryManager() [T = int]\n",
+      "MemoryManager<int>::~MemoryManager() [T = int]\n"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    MemoryManager<int> mm( new int(23) );\n",
+    "    MemoryManager<int> mm2( new int(42) );\n",
+    "    \n",
+    "    mm2 = std::move( mm );\n",
+    "    \n",
+    "    //std::cout << *mm.get() << \"\\n\";\n",
+    "    std::cout << *mm2.get() << \"\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <memory>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "42"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    std::unique_ptr<int> pi( new int(42) );\n",
+    "    std::cout << *pi;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "int f()\n",
+    "{\n",
+    "    if( true )\n",
+    "        throw std::runtime_error(\"Nooooo!\");\n",
+    "    \n",
+    "    return 42;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "Standard Exception",
+     "evalue": "Nooooo!",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: Nooooo!"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    std::unique_ptr<int> pi( new int( f() ) );\n",
+    "    std::cout << *pi;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "Standard Exception",
+     "evalue": "Nooooo!",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: Nooooo!"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    auto pi = std::make_unique<int>( f() );\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "XXXXXXXXXX"
+     ]
+    }
+   ],
+   "source": [
+    "{  \n",
+    "    auto sp = std::make_unique<std::string>( 10, 'X' );\n",
+    "    std::cout << *sp;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "XXXXXXXXXX"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    std::shared_ptr<std::string> sp = \n",
+    "        std::make_shared<std::string>( 10, 'X' );\n",
+    "    std::cout << *sp;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "XXXXXYXXXX\n",
+      "XXXXXYXXXX"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    std::shared_ptr<std::string> sp = \n",
+    "        std::make_shared<std::string>( 10, 'X' );\n",
+    "    \n",
+    "    std::shared_ptr<std::string> sp2( sp );\n",
+    "    \n",
+    "    (*sp)[5] = 'Y';\n",
+    "    \n",
+    "    std::cout << *sp << \"\\n\";\n",
+    "    std::cout << *sp2;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "abc"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    std::unique_ptr< std::string[] > psa=\n",
+    "        std::make_unique<std::string[]>( 100 );\n",
+    "    \n",
+    "    psa[10] = \"abc\";\n",
+    "    std::cout << psa[10];\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0 0 1000"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    std::vector<int> vi( 1000, 5 );\n",
+    "    std::vector<int> v2( std::move( vi ) );\n",
+    "    \n",
+    "    std::vector<int> v3;\n",
+    "    v3 = std::move( v2 );\n",
+    "    \n",
+    "    std::cout << vi.size() << \" \" << v2.size() << \" \" << v3.size();\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector<int> vi( std::vector<int>(1000) );"
+   ]
+  }
+ ],
+ "metadata": {
+  "celltoolbar": "Slideshow",
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture12_ex.ipynb b/cppcourse/lecture12_ex.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..0cca06089cb4999624effcffe4d755270adaa2a2
--- /dev/null
+++ b/cppcourse/lecture12_ex.ipynb
@@ -0,0 +1,443 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 12"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "This is a short version of our well known Matrix class"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class Matrix\n",
+    "{\n",
+    "public:\n",
+    "    Matrix() = default;\n",
+    "    Matrix( const size_t m, const size_t n, const double v ) : m_(m), n_(n), values_( m * n, v ) { }\n",
+    "    \n",
+    "    double   get( const size_t row, const size_t col ) const { return values_[ row * n_ + col ]; }\n",
+    "    double & get( const size_t row, const size_t col ) { return values_[ row * n_ + col ]; }\n",
+    "\n",
+    "    size_t rows() const { return m_; }\n",
+    "    size_t cols() const { return n_; }  \n",
+    "    \n",
+    "private:\n",
+    "    size_t m_ = 0;\n",
+    "    size_t n_ = 0;\n",
+    "    std::vector<double> values_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "And the overload for its insertion operator to `std::ostream`"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#define OPERATOR_INS operator<<\n",
+    "\n",
+    "std::ostream & OPERATOR_INS( std::ostream & os, const Matrix & m )\n",
+    "{\n",
+    "    for( size_t i = 0; i < m.rows(); ++i )\n",
+    "    {\n",
+    "        if( i != 0 )\n",
+    "            os << \"\\n\";\n",
+    "        \n",
+    "        for( size_t j = 0; j < m.cols(); ++j )\n",
+    "        {\n",
+    "            if( j != 0 )\n",
+    "                os << \" \";\n",
+    "            \n",
+    "            os << m.get( i, j );\n",
+    "        }\n",
+    "    }\n",
+    "    \n",
+    "    return os;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Here you can test wether the gang of five works with our implementation:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( m0 );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( 10, 12, 6.9 );\n",
+    "    m1 = m0;\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m2;\n",
+    "    m2 = m0;\n",
+    "    std::cout << m2 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( std::move(m0) );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( 10, 12, 6.9 );\n",
+    "    m1 = std::move( m0 );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m2;\n",
+    "    m2 = std::move(m1);\n",
+    "    std::cout << m2 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As you can see, thanks to the `vector` class all operations work flawlessly"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Below you find a version of Matrix using a dynamically allocated array. The destructor is already defined, define the rest of the gang of five!__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class Matrix\n",
+    "{\n",
+    "public:\n",
+    "    Matrix() : values_(  new double[0] ) {};\n",
+    "    Matrix( const size_t m, const size_t n, const double v ) \n",
+    "        : m_(m), n_(n), values_( new double[m*n] )\n",
+    "    {\n",
+    "        std::fill( values_, values_ + m_ * n_, v );\n",
+    "    }\n",
+    "    ~Matrix() { delete[] values_; }\n",
+    "    \n",
+    "    double   get( const size_t row, const size_t col ) const { return values_[ row * n_ + col ]; }\n",
+    "    double & get( const size_t row, const size_t col ) { return values_[ row * n_ + col ]; }\n",
+    "    \n",
+    "    size_t rows() const { return m_; }\n",
+    "    size_t cols() const { return n_; }\n",
+    "    \n",
+    "    void transpose();    \n",
+    "    \n",
+    "private:\n",
+    "    size_t m_ = 0;\n",
+    "    size_t n_ = 0;\n",
+    "    double * values_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#define OPERATOR_INS operator<<\n",
+    "\n",
+    "std::ostream & OPERATOR_INS( std::ostream & os, const Matrix & m )\n",
+    "{\n",
+    "    for( size_t i = 0; i < m.rows(); ++i )\n",
+    "    {\n",
+    "        if( i != 0 )\n",
+    "            os << \"\\n\";\n",
+    "        \n",
+    "        for( size_t j = 0; j < m.cols(); ++j )\n",
+    "        {\n",
+    "            if( j != 0 )\n",
+    "                os << \" \";\n",
+    "            \n",
+    "            os << m.get( i, j );\n",
+    "        }\n",
+    "    }\n",
+    "    \n",
+    "    return os;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( m0 );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( 10, 12, 6.9 );\n",
+    "    m1 = m0;\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m2;\n",
+    "    m2 = m0;\n",
+    "    std::cout << m2 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( std::move(m0) );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( 10, 12, 6.9 );\n",
+    "    m1 = std::move( m0 );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m2;\n",
+    "    m2 = std::move(m1);\n",
+    "    std::cout << m2 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Implement the gang of five for a `std::unique_ptr` version of Matrix!__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <memory>\n",
+    "\n",
+    "class Matrix\n",
+    "{\n",
+    "public:\n",
+    "    Matrix() : values_(  std::make_unique<double[]>(0) ) {};\n",
+    "    Matrix( const size_t m, const size_t n, const double v ) \n",
+    "        : m_(m), n_(n), values_( std::make_unique<double[]>(m*n) )\n",
+    "    {\n",
+    "        std::fill( values_.get(), values_.get() + m_ * n_, v );\n",
+    "    }\n",
+    "    \n",
+    "    double   get( const size_t row, const size_t col ) const { return values_[ row * n_ + col ]; }\n",
+    "    double & get( const size_t row, const size_t col ) { return values_[ row * n_ + col ]; }\n",
+    "    \n",
+    "    size_t rows() const { return m_; }\n",
+    "    size_t cols() const { return n_; }\n",
+    "    \n",
+    "    void transpose();    \n",
+    "    \n",
+    "private:\n",
+    "    size_t m_ = 0;\n",
+    "    size_t n_ = 0;\n",
+    "    std::unique_ptr<double[]> values_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( m0 );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( 10, 12, 6.9 );\n",
+    "    m1 = m0;\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m2;\n",
+    "    m2 = m0;\n",
+    "    std::cout << m2 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( std::move(m0) );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( 10, 12, 6.9 );\n",
+    "    m1 = std::move( m0 );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m2;\n",
+    "    m2 = std::move(m1);\n",
+    "    std::cout << m2 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/lecture12_ex_sol.ipynb b/cppcourse/lecture12_ex_sol.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..143a159ef5f87ae47404ad18f000ae2828bf04f6
--- /dev/null
+++ b/cppcourse/lecture12_ex_sol.ipynb
@@ -0,0 +1,595 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Exercises to Lecture 12"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class Matrix\n",
+    "{\n",
+    "public:\n",
+    "    Matrix() = default;\n",
+    "    Matrix( const size_t m, const size_t n, const double v ) \n",
+    "        : m_(m), n_(n), values_( m * n, v ) { }\n",
+    "    \n",
+    "    double   get( const size_t row, const size_t col ) const { \n",
+    "        return values_[ row * n_ + col ]; }\n",
+    "    double & get( const size_t row, const size_t col ) { \n",
+    "        return values_[ row * n_ + col ]; }\n",
+    "\n",
+    "    size_t rows() const { return m_; }\n",
+    "    size_t cols() const { return n_; }\n",
+    "    \n",
+    "    void transpose();    \n",
+    "    \n",
+    "private:\n",
+    "    size_t m_ = 0;\n",
+    "    size_t n_ = 0;\n",
+    "    std::vector<double> values_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Below you find a version of Matrix using a dynamically allocated array. The destructor is already defined, define the rest of the gang of five!__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class Matrix\n",
+    "{\n",
+    "public:\n",
+    "    Matrix() : values_(  new double[0] ) {};\n",
+    "    \n",
+    "    \n",
+    "    Matrix( const size_t m, const size_t n, const double v ) \n",
+    "        : m_(m), n_(n), values_( new double[m*n] )\n",
+    "    {\n",
+    "        std::fill( values_, values_ + m_ * n_, v );\n",
+    "    }\n",
+    "    \n",
+    "    \n",
+    "    ~Matrix() { delete[] values_; }\n",
+    "    \n",
+    "        \n",
+    "    Matrix( const Matrix & other ) \n",
+    "     : m_(other.m_), n_(other.n_), values_( new double[m_ * n_] )\n",
+    "        {\n",
+    "            std::copy( other.values_, other.values_ + m_ * n_,\n",
+    "                       values_ );\n",
+    "        }\n",
+    "    \n",
+    "    \n",
+    "    Matrix & operator=( const Matrix & other )\n",
+    "    {\n",
+    "        delete[] values_;\n",
+    "        m_ = other.m_;\n",
+    "        n_ = other.n_;\n",
+    "        values_ = new double[m_ * n_];\n",
+    "        std::copy( other.values_, other.values_ + m_ * n_, values_ );\n",
+    "        return *this;\n",
+    "    }\n",
+    "    \n",
+    "    \n",
+    "    Matrix( Matrix && other ) \n",
+    "     : m_(other.m_), n_(other.n_), values_( other.values_ )\n",
+    "        {\n",
+    "            other.values_ = new double[0];\n",
+    "            other.m_ = 0;\n",
+    "            other.n_ = 0;\n",
+    "        }\n",
+    "    \n",
+    "    \n",
+    "    Matrix & operator=( Matrix && other )\n",
+    "    {\n",
+    "        delete[] values_;\n",
+    "        m_ = other.m_;\n",
+    "        n_ = other.n_;\n",
+    "        values_ = other.values_;\n",
+    "        \n",
+    "        other.values_ = new double[0];\n",
+    "        other.m_ = 0;\n",
+    "        other.n_ = 0;\n",
+    "        \n",
+    "        return *this;\n",
+    "    }\n",
+    "    \n",
+    "    \n",
+    "    double   get( const size_t row, const size_t col ) const { return values_[ row * n_ + col ]; }\n",
+    "    double & get( const size_t row, const size_t col ) { return values_[ row * n_ + col ]; }\n",
+    "    \n",
+    "    size_t rows() const { return m_; }\n",
+    "    size_t cols() const { return n_; }\n",
+    "    \n",
+    "    void transpose();    \n",
+    "    \n",
+    "private:\n",
+    "    size_t m_ = 0;\n",
+    "    size_t n_ = 0;\n",
+    "    double * values_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#define OPERATOR_INS operator<<\n",
+    "\n",
+    "std::ostream & OPERATOR_INS( std::ostream & os, const Matrix & m )\n",
+    "{\n",
+    "    for( size_t i = 0; i < m.rows(); ++i )\n",
+    "    {\n",
+    "        if( i != 0 )\n",
+    "            os << \"\\n\";\n",
+    "        \n",
+    "        for( size_t j = 0; j < m.cols(); ++j )\n",
+    "        {\n",
+    "            if( j != 0 )\n",
+    "                os << \" \";\n",
+    "            \n",
+    "            os << m.get( i, j );\n",
+    "        }\n",
+    "    }\n",
+    "    \n",
+    "    return os;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( m0 );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( 10, 12, 6.9 );\n",
+    "    m1 = m0;\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m2;\n",
+    "    m2 = m0;\n",
+    "    std::cout << m2 << \"\\n\\n\";h\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( std::move(m0) );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( 10, 12, 6.9 );\n",
+    "    m1 = std::move( m0 );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m2;\n",
+    "    m2 = std::move(m1);\n",
+    "    std::cout << m2 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "__Implement the gang of five for a `std::unique_ptr` version of Matrix!__"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <memory>\n",
+    "\n",
+    "class Matrix\n",
+    "{\n",
+    "public:\n",
+    "    Matrix() : values_(  std::make_unique<double[]>(0) ) {};\n",
+    "    Matrix( const size_t m, const size_t n, const double v ) \n",
+    "        : m_(m), n_(n), values_( std::make_unique<double[]>(m*n) )\n",
+    "    {\n",
+    "        std::fill( values_.get(), values_.get() + m_ * n_, v );\n",
+    "    }\n",
+    "    \n",
+    "    ~Matrix() = default;    \n",
+    "    \n",
+    "    Matrix( const Matrix & other ) \n",
+    "     : m_(other.m_), n_(other.n_), \n",
+    "       values_( std::make_unique<double[]>(m_ * n_) )\n",
+    "    {\n",
+    "        std::copy( other.values_.get(), \n",
+    "                   other.values_.get() + m_ * n_, values_.get() );\n",
+    "    }\n",
+    "    \n",
+    "    \n",
+    "    Matrix & operator=( const Matrix & other )\n",
+    "    {\n",
+    "        m_ = other.m_;\n",
+    "        n_ = other.n_;\n",
+    "        values_ = std::make_unique<double[]>(m_ * n_); \n",
+    "                  // assignment auto deletes old pointer\n",
+    "        std::copy( other.values_.get(),\n",
+    "                   other.values_.get() + m_ * n_, values_.get() );\n",
+    "        return *this;\n",
+    "    }\n",
+    "    \n",
+    "    \n",
+    "    Matrix( Matrix && other ) \n",
+    "     : m_(other.m_), n_(other.n_), \n",
+    "       values_( std::move( other.values_ ) )\n",
+    "        {\n",
+    "            other.values_ = std::make_unique<double[]>(0);\n",
+    "            other.m_ = 0;\n",
+    "            other.n_ = 0;\n",
+    "        }\n",
+    "    \n",
+    "    \n",
+    "    Matrix & operator=( Matrix && other )\n",
+    "    {\n",
+    "        m_ = other.m_;\n",
+    "        n_ = other.n_;\n",
+    "        values_ = std::move( other.values_ );\n",
+    "        \n",
+    "        other.values_ = std::make_unique<double[]>(0);\n",
+    "        other.m_ = 0;\n",
+    "        other.n_ = 0;\n",
+    "        \n",
+    "        return *this;\n",
+    "    }\n",
+    "    \n",
+    "    \n",
+    "    double   get( const size_t row, const size_t col ) const { return values_[ row * n_ + col ]; }\n",
+    "    double & get( const size_t row, const size_t col ) { return values_[ row * n_ + col ]; }\n",
+    "    \n",
+    "    size_t rows() const { return m_; }\n",
+    "    size_t cols() const { return n_; }\n",
+    "    \n",
+    "    void transpose();    \n",
+    "    \n",
+    "private:\n",
+    "    size_t m_ = 0;\n",
+    "    size_t n_ = 0;\n",
+    "    std::unique_ptr<double[]> values_;\n",
+    "};"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( m0 );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( 10, 12, 6.9 );\n",
+    "    m1 = m0;\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m2;\n",
+    "    m2 = m0;\n",
+    "    std::cout << m2 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( std::move(m0) );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "7.7 7.7 7.7 7.7 7.7 7.7\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "#include <iostream>\n",
+    "{\n",
+    "    Matrix m0( 5, 6, 7.7 );\n",
+    "    std::cout << m0 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m1( 10, 12, 6.9 );\n",
+    "    m1 = std::move( m0 );\n",
+    "    std::cout << m1 << \"\\n\\n\";\n",
+    "    \n",
+    "    Matrix m2;\n",
+    "    m2 = std::move(m1);\n",
+    "    std::cout << m2 << \"\\n\\n\";\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/rise.css b/cppcourse/rise.css
new file mode 100644
index 0000000000000000000000000000000000000000..11842fd7934ebc32ce9dd807db74b6974cf75467
--- /dev/null
+++ b/cppcourse/rise.css
@@ -0,0 +1,11 @@
+table {
+    float:left;
+}
+
+div.slides table thead tr th {
+    font-size: 26px; 
+}
+
+div.slides table tbody tr td {
+    font-size: 22px; 
+}
\ No newline at end of file
diff --git a/cppcourse/sqlite_demo.ipynb b/cppcourse/sqlite_demo.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..bed7762b047b80437f30a9fce311a737a8fd114e
--- /dev/null
+++ b/cppcourse/sqlite_demo.ipynb
@@ -0,0 +1,259 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "#include <exception>\n",
+    "#include <string>\n",
+    "#include <memory>\n",
+    "#include <vector>\n",
+    "#include <algorithm>\n",
+    "\n",
+    "#define OPERATOR_ASSIGNMENT operator=\n",
+    "\n",
+    "#include <sqlite3.h>\n",
+    ".L libsqlite3"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "{\n",
+    "    sqlite3 *db;\n",
+    "    char *zErrMsg = 0;\n",
+    "    int rc;\n",
+    "\n",
+    "    rc = sqlite3_open(\"/tmp/database.sqlite\", &db);\n",
+    "    if( rc ){\n",
+    "      std::cerr << \"Can't open database: \" << sqlite3_errmsg(db) << \"\\n\";\n",
+    "      sqlite3_close(db);\n",
+    "    }\n",
+    "    rc = sqlite3_exec(db, \"SELECT * FROM sqlite_master where type='table'\",\n",
+    "                      nullptr, 0, &zErrMsg);\n",
+    "    if( rc!=SQLITE_OK ){\n",
+    "      std::cerr << \"SQL error: \" << zErrMsg << \"\\n\";\n",
+    "      sqlite3_free(zErrMsg);\n",
+    "    }\n",
+    "    sqlite3_close(db);\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class SqLiteDB\n",
+    "{\n",
+    "public:\n",
+    "    explicit SqLiteDB( const std::string & dbPath );\n",
+    "    \n",
+    "    ~SqLiteDB() { if( db_ ) sqlite3_close(db_); }\n",
+    "    SqLiteDB( const SqLiteDB & other ) = delete;\n",
+    "    SqLiteDB( SqLiteDB && other ) : db_( other.db_ ) { other.db_ = nullptr; }\n",
+    "    \n",
+    "    SqLiteDB & operator=( const SqLiteDB & other ) = delete;\n",
+    "    SqLiteDB & operator=( SqLiteDB && other );\n",
+    "    \n",
+    "    void exec( const std::string & cmd );\n",
+    "private:\n",
+    "    sqlite3 * db_ = nullptr;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "SqLiteDB::SqLiteDB( const std::string & dbPath )\n",
+    "{\n",
+    "    int rc = sqlite3_open( dbPath.c_str(), &db_);\n",
+    "    if( rc!=SQLITE_OK )\n",
+    "        throw std::runtime_error( std::string(\"Can't open database: \") + sqlite3_errmsg(db_) );\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "SqLiteDB & SqLiteDB::OPERATOR_ASSIGNMENT( SqLiteDB && other ) \n",
+    "{\n",
+    "    if( db_ )\n",
+    "        sqlite3_close(db_);\n",
+    "    db_ = other.db_;\n",
+    "    other.db_ = nullptr; \n",
+    "    \n",
+    "    return *this;\n",
+    " }"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "void SqLiteDB::exec( const std::string & cmd )\n",
+    "{\n",
+    "    if( !db_ )\n",
+    "        throw std::runtime_error( \"Using SqLiteDB which doesn't have an open DB!\" );\n",
+    "    \n",
+    "    char *tmpErrMsg = nullptr;\n",
+    "    int rc = sqlite3_exec(db_, cmd.c_str(), nullptr, nullptr, &tmpErrMsg);\n",
+    "    std::string errMsg( tmpErrMsg ? tmpErrMsg : \"\" );\n",
+    "    sqlite3_free( tmpErrMsg );\n",
+    "    if( rc != SQLITE_OK )\n",
+    "    {\n",
+    "        throw std::runtime_error( std::string(\"SQL error: \") + errMsg );\n",
+    "    }\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "SqLiteDB sqDb( \"/tmp/database.sqlite\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sqDb.exec( \"SELECT * FROM sqlite_master where type='table'\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_17:2:11: error: call to deleted constructor of 'SqLiteDB'\n",
+      " SqLiteDB sqDb2 = sqDb;\n",
+      "          ^       ~~~~\n",
+      "input_line_10:7:5: note: 'SqLiteDB' has been explicitly marked deleted here\n",
+      "    SqLiteDB( const SqLiteDB & other ) = delete;\n",
+      "    ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "SqLiteDB sqDb2 = sqDb;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "SqLiteDB sqDb2 = std::move( sqDb );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "sqDb2.exec( \"SELECT * FROM sqlite_master where type='table'\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "Standard Exception",
+     "evalue": "Using SqLiteDB which doesn't have an open DB!",
+     "output_type": "error",
+     "traceback": [
+      "Standard Exception: Using SqLiteDB which doesn't have an open DB!"
+     ]
+    }
+   ],
+   "source": [
+    "sqDb.exec( \"SELECT * FROM sqlite_master where type='table'\" );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "std::vector< SqLiteDB > dbs;\n",
+    "dbs.emplace_back( \"/tmp/a.sqlite\" );\n",
+    "dbs.emplace_back( \"/tmp/b.sqlite\" );\n",
+    "dbs.emplace_back( \"/tmp/c.sqlite\" );\n",
+    "\n",
+    "for( auto & db : dbs )\n",
+    "   db.exec( \"SELECT * FROM sqlite_master where type='table'\" ); "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "dbs.erase( std::remove_if( dbs.begin(), dbs.end(), []( const auto & db) {\n",
+    "        return false; // close databases which fit certain conditions etc...\n",
+    "    } ), dbs.end() );"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/cppcourse/xwidgets.ipynb b/cppcourse/xwidgets.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..120dd345b35d5d8cd2c75b6f6c1f49edf85845c8
--- /dev/null
+++ b/cppcourse/xwidgets.ipynb
@@ -0,0 +1,1756 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Numerical widgets"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Defining a Slider Widget"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 128,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xslider.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 129,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "input_line_177:2:21: error: redefinition of 'slider'\n",
+      " xw::slider<double> slider;\n",
+      "                    ^\n",
+      "input_line_8:2:21: note: previous definition is here\n",
+      " xw::slider<double> slider;\n",
+      "                    ^\n"
+     ]
+    },
+    {
+     "ename": "Interpreter Error",
+     "evalue": "",
+     "output_type": "error",
+     "traceback": [
+      "Interpreter Error: "
+     ]
+    }
+   ],
+   "source": [
+    "xw::slider<double> slider;\n",
+    "\n",
+    "slider                 // If the semicolon is ommitted in the last line, the return value is displayed."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "slider.value = 20;      // Modifying properties of widgets triggers the update of the frontend."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "slider.value()          // Reading the value requires using the call operator"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "// changine some more properties\n",
+    "slider.max = 40;\n",
+    "slider.style().handle_color = \"blue\";\n",
+    "slider.orientation = \"vertical\";\n",
+    "slider.description = \"A slider\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xcpp/xdisplay.hpp\"\n",
+    "\n",
+    "using xcpp::display;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "display(slider);       // xcpp::display can be called to explicitely trigger a the display of an object."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Using operator chaining to mimic keyword arguments"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "auto other_slider = xw::slider_generator<double>()\n",
+    "    .min(-1.0)\n",
+    "    .max(1.0)\n",
+    "    .description(\"Another slider\")\n",
+    "    .finalize();\n",
+    "\n",
+    "display(other_slider);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Progress"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xprogress.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::progress<double> progress;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "progress"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "progress.value = 60;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "progress.style().bar_color = \"red\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "progress.description = \"Completion\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "progress.style().description_width = \"30px\""
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Numerical input"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xnumeral.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::numeral<double> numeral;\n",
+    "numeral"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "numeral.value = 4"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "numeral.value()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Timer"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xplay.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::play play;\n",
+    "play"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Boolean widgets"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Checkbox"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xcheckbox.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::checkbox checkbox;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "checkbox"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "checkbox.value = true;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "checkbox.indent = false;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Toggle button"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xtogglebutton.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::togglebutton toggle;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "toggle"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "toggle.value = true;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "toggle.description = \"toggle\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Valid check"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xvalid.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::valid valid;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "valid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "valid.value = true;"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# String widgets"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Label widget"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xlabel.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::label label;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "label"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "label.value = \"Some caption\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## HTML widget"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xhtml.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::html html;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "html.value = R\"xhtml(\n",
+    "    <div style=\"\n",
+    "        width: 50%;\n",
+    "        height: 100px;\n",
+    "        background: #323;\n",
+    "        color: white;\n",
+    "        text-align: center;\"\n",
+    "        >Some HTML\n",
+    "    </div>\n",
+    ")xhtml\";\n",
+    "html"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Text widget"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "#include \"xwidgets/xtext.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::text text;\n",
+    "text.value = \"Some text\";\n",
+    "text"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "void submit_callback()\n",
+    "{\n",
+    "    std::cout << \"submitted\" << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "text.on_submit(submit_callback);"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Textarea widget"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xtextarea.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::textarea textarea;\n",
+    "textarea.value = R\"textarea(Lorem ipsum dolor sit amet, consectetur \n",
+    "adipiscing elit,  sed do eiusmod tempor incididunt ut labore et dolore\n",
+    "magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco\n",
+    "laboris  nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor\n",
+    "in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \n",
+    "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa \n",
+    "qui officia deserunt mollit anim id est laborum.\n",
+    ")textarea\";\n",
+    "textarea"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Password widget"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xpassword.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::password password;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "password"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Button widget"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include <iostream>\n",
+    "#include \"xwidgets/xbutton.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::button bt;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "void foo()\n",
+    "{\n",
+    "    std::cout << \"Clicked!\" << std::endl;\n",
+    "}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "bt.on_click(foo);\n",
+    "    \n",
+    "bt"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "bt.description = \"button\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "bt.button_style = \"success\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "//bt.button_style = \"some invalid value\";  // values are validated upon assignment"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "std::cout << bt.button_style();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "collapsed": true
+   },
+   "source": [
+    "# Widgets layout"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "bt.layout().width = \"50%\";\n",
+    "bt.layout().height = \"200px\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "bt.style().button_color = \"#888\";"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Value semantics"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::button bt_copy = bt;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "bt_copy"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "bt.style().button_color = \"red\";\n",
+    "bt_copy.style().button_color = \"green\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xslider.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::slider<double> slide1;\n",
+    "slide1.value = 4.0;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::slider<double> slide2 = slide1;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "slide2"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "collapsed": true
+   },
+   "source": [
+    "# Link widget"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xslider.hpp\"\n",
+    "#include \"xwidgets/xlink.hpp\"\n",
+    "#include \"xwidgets/xbox.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::slider<double> s1, s2;\n",
+    "\n",
+    "s1.description = \"Slider 1\";\n",
+    "s2.description = \"Slider 2\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "auto l = xw::link(s1, \"value\", s2, \"value\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "s1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "s2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::slider<double> source, target;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "auto dl = xw::directional_link(source, \"value\", target, \"value\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "source"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "target"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Box widgets"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xbutton.hpp\"\n",
+    "#include \"xwidgets/xslider.hpp\"\n",
+    "#include \"xwidgets/xbox.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::vbox b;\n",
+    "xw::slider<double> slid;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "b.add(xw::button())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "b.add(slid)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "b"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Controller"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xcontroller.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::controller c"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "c"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Selection widgets"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Toggle buttons"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": false
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xtogglebuttons.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::togglebuttons tb(std::vector<std::string>({\"foo\", \"bar\"}), \"foo\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "tb"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "tb.value = \"bar\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "tb._options_labels = std::vector<std::string>({\"baz\", \"taz\"});"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Dropdown"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xdropdown.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::dropdown dd(std::vector<std::string>({\"foo\", \"bar\"}), \"foo\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "dd"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## RadioButtons"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xradiobuttons.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::radiobuttons rb(std::vector<std::string>({\"foo\", \"bar\"}), \"foo\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "rb"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "collapsed": true
+   },
+   "source": [
+    "## Select"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xselect.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::select sel(std::vector<std::string>({\"foo\", \"bar\"}), \"foo\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "sel"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "sel.rows = 3"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Selection slider"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xselectionslider.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::selectionslider sslid(std::vector<std::string>({\"foo\", \"bar\", \"baz\", \"taz\"}), \"foo\");"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "sslid"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "collapsed": true
+   },
+   "source": [
+    "## Multiple Select"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xselect.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::select_multiple mul_sel(std::vector<std::string>({\"foo\", \"bar\"}));"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "mul_sel"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "mul_sel.value()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "mul_sel.value = std::vector<std::string>();"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Selection range slider"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xselectionslider.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::selection_rangeslider range_sslid(std::vector<std::string>({\"foo\", \"bar\", \"baz\", \"taz\"}));"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "range_sslid"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "range_sslid.value()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "collapsed": true
+   },
+   "source": [
+    "# Selection Containers"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Tabs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xtab.hpp\"\n",
+    "#include \"xwidgets/xbutton.hpp\"\n",
+    "#include \"xwidgets/xslider.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::tab tabs;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::slider<double> tab_slid;\n",
+    "tabs.add(xw::button());\n",
+    "tabs.add(tab_slid);"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "tabs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "tabs.set_title(0, \"zero\");\n",
+    "tabs.set_title(1, \"one\");"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Accordion"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xaccordion.hpp\"\n",
+    "#include \"xwidgets/xbutton.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::accordion accord;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "accord.add(xw::button());\n",
+    "accord.add(xw::button());\n",
+    "accord.add(xw::button());"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "accord"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "accord.set_title(0, \"zero\");\n",
+    "accord.set_title(1, \"one\");\n",
+    "accord.set_title(2, \"two\");"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {
+    "collapsed": true
+   },
+   "source": [
+    "# Color picker"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "#include \"xwidgets/xcolor_picker.hpp\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "xw::color_picker cpicker;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "cpicker"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "cpicker.value = \"blue\";"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "scrolled": true
+   },
+   "outputs": [],
+   "source": [
+    "cpicker.concise = true;"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "C++14",
+   "language": "C++14",
+   "name": "xeus-cling-cpp14"
+  },
+  "language_info": {
+   "codemirror_mode": "text/x-c++src",
+   "file_extension": ".cpp",
+   "mimetype": "text/x-c++src",
+   "name": "c++",
+   "version": "14"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}