{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How Jupyter works\n",
    "\n",
    "\n",
    "## ...But first, Terminal IPython\n",
    "\n",
    "When you type `ipython`, you get the original IPython interface, running in\n",
    "the terminal. It does something like this:\n",
    "\n",
    "```\n",
    "while True:\n",
    "    code = input(\">>> \")\n",
    "    exec(code)\n",
    "```\n",
    "\n",
    "Of course, it's much more complex, because it has to deal with multi-line\n",
    "code, tab completion using `readline` or `prompt-toolkit`, magic commands, and so on. But the\n",
    "model is like that: prompt the user for some code, and when they've entered it,\n",
    "exec it in the same process. This model is often called a REPL, or\n",
    "Read-Eval-Print-Loop."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Jupyter and The IPython Kernel\n",
    "\n",
    "Jupyter expands on this REPL model and provides other interfaces to running code–the notebook, the Qt console, `jupyter console` in\n",
    "the terminal, and third party interfaces—use the IPython Kernel. This is a\n",
    "separate process which is responsible for running user code, and things like\n",
    "computing possible completions. Frontends communicate with it using JSON\n",
    "messages sent over [ZeroMQ](http://zeromq.org/) sockets; the protocol they use is described in\n",
    "[the jupyter protocol](https://jupyter-client.readthedocs.io/en/stable/messaging.html).\n",
    "\n",
    "The core execution machinery for the kernel is shared with terminal IPython:\n",
    "\n",
    "![IPython kernel and terminal relationship](images/ipy_kernel_and_terminal.png)\n",
    "\n",
    "A kernel process can be connected to more than one frontend simultaneously. In\n",
    "this case, the different frontends will have access to the same variables.\n",
    "\n",
    "<!-- TODO: Diagram illustrating this? -->\n",
    "\n",
    "This design was intended to allow easy development of different frontends based\n",
    "on the same kernel, but it also made it possible to support new languages in the\n",
    "same frontends, by developing kernels in those languages, and we are refining\n",
    "IPython to make that more practical.\n",
    "\n",
    "Today, there are two ways to develop a kernel for another language. Wrapper\n",
    "kernels reuse the communications machinery from IPython, and implement only the\n",
    "core execution part. Native kernels implement execution and communications in\n",
    "the target language:\n",
    "\n",
    "![Other Kernels](images/other_kernels.png)\n",
    "\n",
    "Wrapper kernels are easier to write quickly for languages that have good Python\n",
    "wrappers, like [octave_kernel](https://pypi.python.org/pypi/octave_kernel), or\n",
    "languages where it's impractical to implement the communications machinery, like\n",
    "[bash_kernel](https://pypi.python.org/pypi/bash_kernel). Native kernels are\n",
    "likely to be better maintained by the community using them, like\n",
    "[IJulia](https://github.com/JuliaLang/IJulia.jl) or [IHaskell](https://github.com/gibiansky/IHaskell).\n",
    "\n",
    "<!-- TODO:\n",
    ".. seealso::\n",
    "\n",
    "   :doc:`kernels`\n",
    "   \n",
    "   :doc:`wrapperkernels`\n",
    "   \n",
    "   -->"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Notebooks\n",
    "\n",
    "The Notebook frontend does something extra. In addition to running your code, it\n",
    "stores code and output, together with markdown notes, in an editable document\n",
    "called a notebook. When you save it, this is sent from your browser to the\n",
    "notebook server, which saves it on disk as a JSON file with a ``.ipynb``\n",
    "extension.\n",
    "\n",
    "![Notebook components](images/notebook_components.png)\n",
    "\n",
    "The notebook server, not the kernel, is responsible for saving and loading\n",
    "notebooks, so you can edit notebooks even if you don't have the kernel for that\n",
    "language—you just won't be able to run code. The kernel doesn't know anything\n",
    "about the notebook document: it just gets sent cells of code to execute when the\n",
    "user runs them."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Install more languages\n",
    "\n",
    "The exact procedure to install a kernel for a different language will depend on the specificity of each language. \n",
    "Though ther is a common set of step to follow.\n",
    "\n",
    "  - Install the language stack you are interested in.\n",
    "  - Install the kernel for this language (often using given language package manager).\n",
    "  - Register the kernel globally with Jupyter. \n",
    "  \n",
    "While usually a kernel is though as a specific language, a kernel may be:\n",
    "\n",
    "  - A virtual environment (or equivalent)\n",
    "  - A set of configuration/environment variables.\n",
    "  - A physical location (for remote kernels)\n",
    "  \n",
    "Installing multiple kernels does not automatically allow one notebook to use many languages at once, but this is also possible.\n",
    "\n",
    "A community maintained list of available kernel can be found on the [Jupyter Wiki](https://github.com/jupyter/jupyter/wiki/Jupyter-kernels). "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Install a second python kernel\n",
    "\n",
    "\n",
    "Using conda:\n",
    "\n",
    "\n",
    "```\n",
    "$ conda create -n pycon-env python=3.6 --yes --quiet\n",
    "$ source activate pycon-env\n",
    "(pycon-env)$ conda install ipykernel --yes\n",
    "(pycon-env)$ python -m ipykernel install --name pycon-kernel\n",
    "Installed kernelspec pycon-kernel in /usr/local/share/jupyter/kernels/pycon-kernel\n",
    "```\n",
    "\n",
    "Available options are  `--user`, `--name <machine-readable-name>`, `--display-name <\"User Friendly Name\">`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Install and R kernel\n",
    "\n",
    "\n",
    "Again using conda, let's install the R stack and create an R kernel.\n",
    "\n",
    "In a shell:\n",
    "```\n",
    "$ conda install -c r r # install r form teh R channel\n",
    "$ conda install -c r r-irkernel\n",
    "$ r\n",
    "> IRkernel::installspec()\n",
    "```\n",
    "\n",
    "If you are not using conda you may need to replace by :\n",
    "\n",
    "```\n",
    "$ R\n",
    "> install.packages(c('repr', 'IRdisplay', 'evaluate', 'crayon', 'pbdZMQ', 'devtools', 'uuid', 'digest'))\n",
    "...\n",
    "> devtools::install_github('IRkernel/IRkernel')\n",
    "```\n",
    "\n",
    "You may want to install Rin the **same** environment as the previous Python Kernel if you wish to do R **and** python inthe same notebook. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### install more kernels\n",
    "\n",
    "Feel free to experiment with other kernel, poke at the installed kernelspec folders. Use the following to list all the kernels and their locations:\n",
    "\n",
    "```\n",
    "$ jupyter kernelspec list\n",
    "Available kernels:\n",
    "  ir           /home/jovyan/.local/share/jupyter/kernels/ir\n",
    "  julia-0.5    /opt/conda/share/jupyter/kernels/julia-0.5\n",
    "  python3      /opt/conda/share/jupyter/kernels/python3\n",
    "  python2      /usr/local/share/jupyter/kernels/python2\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above process can take a long time, need to compile a few modules. You may want to try the `jupyter/datascience-notebook` Docker image which already have Python, Julia and R installed. Warning the Docker image is big (several GB) ! Please don't try to download it on Conference wifi. "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
