{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Configuring IPython"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Finding configuration options"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "IPython has many configurable attributes. These can be viewed using the `-h` flag to the command line applications:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "=========\n",
      " IPython\n",
      "=========\n",
      "\n",
      "Tools for Interactive Computing in Python\n",
      "=========================================\n",
      "\n",
      "    A Python shell with automatic history (input and output), dynamic object\n",
      "    introspection, easier configuration, command completion, access to the\n",
      "    system shell and more.  IPython can also be embedded in running programs.\n",
      "\n",
      "Usage\n",
      "\n",
      "    ipython [subcommand] [options] [-c cmd | -m mod | file] [--] [arg] ...\n",
      "\n",
      "    If invoked with no options, it executes the file and exits, passing the\n",
      "    remaining arguments to the script, just as if you had specified the same\n",
      "    command with python. You may need to specify `--` before args to be passed\n",
      "    to the script, to prevent IPython from attempting to parse them. If you\n",
      "    specify the option `-i` before the filename, it will enter an interactive\n",
      "    IPython session after running the script, rather than exiting. Files ending\n",
      "    in .py will be treated as normal Python, but files ending in .ipy can\n",
      "    contain special IPython syntax (magic commands, shell expansions, etc.).\n",
      "\n",
      "    Almost all configuration in IPython is available via the command-line. Do\n",
      "    `ipython --help-all` to see all available options.  For persistent\n",
      "    configuration, look into your `ipython_config.py` configuration file for\n",
      "    details.\n",
      "\n",
      "    This file is typically installed in the `IPYTHONDIR` directory, and there\n",
      "    is a separate configuration directory for each profile. The default profile\n",
      "    directory will be located in $IPYTHONDIR/profile_default. IPYTHONDIR\n",
      "    defaults to to `$HOME/.ipython`.  For Windows users, $HOME resolves to\n",
      "    C:\\Documents and Settings\\YourUserName in most instances.\n",
      "\n",
      "    To initialize a profile with the default configuration file, do::\n",
      "\n",
      "      $> ipython profile create\n",
      "\n",
      "    and start editing `IPYTHONDIR/profile_default/ipython_config.py`\n",
      "\n",
      "    In IPython's documentation, we will refer to this directory as\n",
      "    `IPYTHONDIR`, you can change its default location by creating an\n",
      "    environment variable with this name and setting it to the desired path.\n",
      "\n",
      "    For more information, see the manual available in HTML and PDF in your\n",
      "    installation, or online at http://ipython.org/documentation.html.\n",
      "\n",
      "Subcommands\n",
      "-----------\n",
      "\n",
      "Subcommands are launched as `ipython cmd [args]`. For information on using\n",
      "subcommand 'cmd', do: `ipython cmd -h`.\n",
      "\n",
      "locate\n",
      "    print the path to the IPython dir\n",
      "trust\n",
      "    Sign notebooks to trust their potentially unsafe contents at load.\n",
      "install-nbextension\n",
      "    Install IPython notebook extension files\n",
      "kernel\n",
      "    Start a kernel without an attached frontend.\n",
      "kernelspec\n",
      "    Manage IPython kernel specifications.\n",
      "console\n",
      "    Launch the IPython terminal-based Console.\n",
      "nbconvert\n",
      "    Convert notebooks to/from other formats.\n",
      "profile\n",
      "    Create and manage IPython profiles.\n",
      "notebook\n",
      "    Launch the IPython HTML Notebook Server.\n",
      "history\n",
      "    Manage the IPython history database.\n",
      "qtconsole\n",
      "    Launch the IPython Qt Console.\n",
      "\n",
      "Options\n",
      "-------\n",
      "\n",
      "Arguments that take values are actually convenience aliases to full\n",
      "Configurables, whose aliases are listed on the help line. For more information\n",
      "on full configurables, see '--help-all'.\n",
      "\n",
      "--nosep\n",
      "    Eliminate all spacing between prompts.\n",
      "--quiet\n",
      "    set log level to logging.CRITICAL (minimize logging output)\n",
      "--term-title\n",
      "    Enable auto setting the terminal title.\n",
      "--pylab\n",
      "    Pre-load matplotlib and numpy for interactive use with\n",
      "    the default matplotlib backend.\n",
      "--init\n",
      "    Initialize profile with default config files.  This is equivalent\n",
      "    to running `ipython profile create <profile>` prior to startup.\n",
      "--pydb\n",
      "    Use the third party 'pydb' package as debugger, instead of pdb.\n",
      "    Requires that pydb is installed.\n",
      "--no-autoedit-syntax\n",
      "    Turn off auto editing of files with syntax errors.\n",
      "--classic\n",
      "    Gives IPython a similar feel to the classic Python prompt.\n",
      "--no-term-title\n",
      "    Disable auto setting the terminal title.\n",
      "--no-banner\n",
      "    Don't display a banner upon starting IPython.\n",
      "--no-automagic\n",
      "    Turn off the auto calling of magic commands.\n",
      "--autoindent\n",
      "    Turn on autoindenting.\n",
      "--no-deep-reload\n",
      "    Disable deep (recursive) reloading by default.\n",
      "--matplotlib\n",
      "    Configure matplotlib for interactive use with\n",
      "    the default matplotlib backend.\n",
      "--debug\n",
      "    set log level to logging.DEBUG (maximize logging output)\n",
      "--autoedit-syntax\n",
      "    Turn on auto editing of files with syntax errors.\n",
      "--no-color-info\n",
      "    Disable using colors for info related things.\n",
      "--no-pprint\n",
      "    Disable auto pretty printing of results.\n",
      "--banner\n",
      "    Display a banner upon starting IPython.\n",
      "--no-confirm-exit\n",
      "    Don't prompt the user when exiting.\n",
      "--pdb\n",
      "    Enable auto calling the pdb debugger after every exception.\n",
      "--color-info\n",
      "    IPython can display information about objects via a set of functions,\n",
      "    and optionally can use colors for this, syntax highlighting\n",
      "    source code and various other elements. This is on by default, but can cause\n",
      "    problems with some pagers. If you see such problems, you can disable the\n",
      "    colours.\n",
      "--no-pdb\n",
      "    Disable auto calling the pdb debugger after every exception.\n",
      "--quick\n",
      "    Enable quick startup with no config files.\n",
      "--deep-reload\n",
      "    Enable deep (recursive) reloading by default. IPython can use the\n",
      "    deep_reload module which reloads changes in modules recursively (it\n",
      "    replaces the reload() function, so you don't need to change anything to\n",
      "    use it). deep_reload() forces a full reload of modules whose code may\n",
      "    have changed, which the default reload() function does not.  When\n",
      "    deep_reload is off, IPython will use the normal reload(), but\n",
      "    deep_reload will still be available as dreload(). This feature is off\n",
      "    by default [which means that you have both normal reload() and\n",
      "    dreload()].\n",
      "--no-autoindent\n",
      "    Turn off autoindenting.\n",
      "--automagic\n",
      "    Turn on the auto calling of magic commands. Type %%magic at the\n",
      "    IPython  prompt  for  more information.\n",
      "-i\n",
      "    If running code from the command line, become interactive afterwards.\n",
      "--pprint\n",
      "    Enable auto pretty printing of results.\n",
      "--confirm-exit\n",
      "    Set to confirm when you try to exit IPython with an EOF (Control-D\n",
      "    in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',\n",
      "    you can force a direct exit without any confirmation.\n",
      "--config=<Unicode> (BaseIPythonApplication.extra_config_file)\n",
      "    Default: ''\n",
      "    Path to an extra config file to load.\n",
      "    If specified, load this config file in addition to any other IPython config.\n",
      "--pylab=<CaselessStrEnum> (InteractiveShellApp.pylab)\n",
      "    Default: None\n",
      "    Choices: ['auto', 'gtk', 'gtk3', 'inline', 'nbagg', 'notebook', 'osx', 'qt', 'qt4', 'qt5', 'tk', 'wx']\n",
      "    Pre-load matplotlib and numpy for interactive use, selecting a particular\n",
      "    matplotlib backend and loop integration.\n",
      "-c <Unicode> (InteractiveShellApp.code_to_run)\n",
      "    Default: ''\n",
      "    Execute the given command string.\n",
      "--log-level=<Enum> (Application.log_level)\n",
      "    Default: 30\n",
      "    Choices: (0, 10, 20, 30, 40, 50, 'DEBUG', 'INFO', 'WARN', 'ERROR', 'CRITICAL')\n",
      "    Set the log level by value or name.\n",
      "--ipython-dir=<Unicode> (BaseIPythonApplication.ipython_dir)\n",
      "    Default: ''\n",
      "    The name of the IPython directory. This directory is used for logging\n",
      "    configuration (through profiles), history storage, etc. The default is\n",
      "    usually $HOME/.ipython. This option can also be specified through the\n",
      "    environment variable IPYTHONDIR.\n",
      "--colors=<CaselessStrEnum> (InteractiveShell.colors)\n",
      "    Default: 'Linux'\n",
      "    Choices: ('NoColor', 'LightBG', 'Linux')\n",
      "    Set the color scheme (NoColor, Linux, or LightBG).\n",
      "--matplotlib=<CaselessStrEnum> (InteractiveShellApp.matplotlib)\n",
      "    Default: None\n",
      "    Choices: ['auto', 'gtk', 'gtk3', 'inline', 'nbagg', 'notebook', 'osx', 'qt', 'qt4', 'qt5', 'tk', 'wx']\n",
      "    Configure matplotlib for interactive use with the default matplotlib\n",
      "    backend.\n",
      "-m <Unicode> (InteractiveShellApp.module_to_run)\n",
      "    Default: ''\n",
      "    Run the module as a script.\n",
      "--logfile=<Unicode> (InteractiveShell.logfile)\n",
      "    Default: ''\n",
      "    The name of the logfile to use.\n",
      "--ext=<Unicode> (InteractiveShellApp.extra_extension)\n",
      "    Default: ''\n",
      "    dotted module name of an IPython extension to load.\n",
      "--profile=<Unicode> (BaseIPythonApplication.profile)\n",
      "    Default: 'default'\n",
      "    The IPython profile to use.\n",
      "--logappend=<Unicode> (InteractiveShell.logappend)\n",
      "    Default: ''\n",
      "    Start logging to the given file in append mode.\n",
      "--cache-size=<Int> (InteractiveShell.cache_size)\n",
      "    Default: 1000\n",
      "    Set the size of the output cache.  The default is 1000, you can change it\n",
      "    permanently in your config file.  Setting it to 0 completely disables the\n",
      "    caching system, and the minimum value accepted is 20 (if you provide a value\n",
      "    less than 20, it is reset to 0 and a warning is issued).  This limit is\n",
      "    defined because otherwise you'll spend more time re-flushing a too small\n",
      "    cache than working\n",
      "--autocall=<Enum> (InteractiveShell.autocall)\n",
      "    Default: 0\n",
      "    Choices: (0, 1, 2)\n",
      "    Make IPython automatically call any callable object even if you didn't type\n",
      "    explicit parentheses. For example, 'str 43' becomes 'str(43)' automatically.\n",
      "    The value can be '0' to disable the feature, '1' for 'smart' autocall, where\n",
      "    it is not applied if there are no more arguments on the line, and '2' for\n",
      "    'full' autocall, where all callable objects are automatically called (even\n",
      "    if no arguments are present).\n",
      "--gui=<CaselessStrEnum> (InteractiveShellApp.gui)\n",
      "    Default: None\n",
      "    Choices: ('glut', 'gtk', 'gtk3', 'osx', 'pyglet', 'qt', 'qt5', 'tk', 'wx')\n",
      "    Enable GUI event loop integration with any of ('glut', 'gtk', 'gtk3', 'osx',\n",
      "    'pyglet', 'qt', 'qt5', 'tk', 'wx').\n",
      "--profile-dir=<Unicode> (ProfileDir.location)\n",
      "    Default: ''\n",
      "    Set the profile location directly. This overrides the logic used by the\n",
      "    `profile` option.\n",
      "\n",
      "To see all available configurables, use `--help-all`\n",
      "\n",
      "Examples\n",
      "--------\n",
      "\n",
      "    ipython --matplotlib       # enable matplotlib integration\n",
      "    ipython --matplotlib=qt    # enable matplotlib integration with qt4 backend\n",
      "    \n",
      "    ipython --log-level=DEBUG  # set logging to DEBUG\n",
      "    ipython --profile=foo      # start with profile foo\n",
      "    \n",
      "    ipython qtconsole          # start the qtconsole GUI application\n",
      "    ipython help qtconsole     # show the help for the qtconsole subcmd\n",
      "    \n",
      "    ipython console            # start the terminal-based console application\n",
      "    ipython help console       # show the help for the console subcmd\n",
      "    \n",
      "    ipython notebook           # start the IPython notebook\n",
      "    ipython help notebook      # show the help for the notebook subcmd\n",
      "    \n",
      "    ipython profile create foo # create profile foo w/ default config files\n",
      "    ipython help profile       # show the help for the profile subcmd\n",
      "    \n",
      "    ipython locate             # print the path to the IPython directory\n",
      "    ipython locate profile foo # print the path to the directory for profile `foo`\n",
      "    \n",
      "    ipython nbconvert           # convert notebooks to/from other formats\n",
      "\n"
     ]
    }
   ],
   "source": [
    "!ipython -h"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is an important trick for finding out configuration info:\n",
    "    \n",
    "    $> ipython [subcommand] --help-all | grep [-C context] PATTERN\n",
    "\n",
    "`--help-all` exposes everything configurable in IPython,\n",
    "there is a good chance you will find what you are looking for."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A common configuration question is:\n",
    "\n",
    "> how do I disable the \"Do you really want to exit\" message when quitting with `Ctrl-d`?\n",
    "\n",
    "Well, logically this has to do with `exit`, so let's look for it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    If invoked with no options, it executes the file and \u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[Ks, passing the\r\n",
      "    IPython session after running the script, rather than \u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[King. Files ending\r\n",
      "--confirm-\u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[K\r\n",
      "    Set to confirm when you try to \u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[K IPython with an EOF (Control-D\r\n",
      "    in Unix, Control-Z/Enter in Windows). By typing '\u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[K' or 'quit',\r\n",
      "    you can force a direct \u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[K without any confirmation.\r\n",
      "--no-confirm-\u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[K\r\n",
      "    Don't prompt the user when \u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[King.\r\n",
      "--TerminalInteractiveShell.confirm_\u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[K=<CBool>\r\n",
      "    Set to confirm when you try to \u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[K IPython with an EOF (Control-D in Unix,\r\n",
      "    Control-Z/Enter in Windows). By typing '\u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[K' or 'quit', you can force a\r\n",
      "    direct \u001b[1;31;46m\u001b[Kexit\u001b[m\u001b[K without any confirmation.\r\n"
     ]
    }
   ],
   "source": [
    "!ipython --help-all | GREP_COLOR='1;31;46' grep --color exit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Which shows me that I can disable the confirmation for a single IPython session with\n",
    "\n",
    "    $> ipython --no-confirm-exit\n",
    "    \n",
    "or I can set the `TerminalInteractiveShell.confirm_exit=False` in a config file,\n",
    "to have it be the default behavior."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Configuration principles"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here are the design principles of the IPython configuration system: \n",
    "\n",
    "* Configuration is always done using class attributes\n",
    "* Classes that have configurable attributes are subclasses of `Configurable`\n",
    "* Attributes that are configurable are typed traitlets objects (`Bool`, `Unicode`, etc.) that have `config=True`\n",
    "* In config files, configurable attributes can be set using the format `Class.attr_name=the_value`\n",
    "* At the command line, configurable attributes can be set using the syntax `--Class.attr_name=the_value`\n",
    "* At the command line, some attributes have shorthands of the form `--attr-name=value`\n",
    "* Values set at the command line have higher priority than those set in config files"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The IPython Profile"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "IPython has a notion of 'profiles' - these are directories that live in your IPYTHONDIR,\n",
    "which contain configuration and runtime information.\n",
    "\n",
    "Let's create the default profile"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ProfileCreate] Generating default config file: '/home/takluyver/.ipython/profile_newprofile/ipython_config.py'\n",
      "[ProfileCreate] Generating default config file: '/home/takluyver/.ipython/profile_newprofile/ipython_kernel_config.py'\n",
      "[ProfileCreate] Generating default config file: '/home/takluyver/.ipython/profile_newprofile/ipython_console_config.py'\n",
      "[ProfileCreate] Generating default config file: '/home/takluyver/.ipython/profile_newprofile/ipython_qtconsole_config.py'\n",
      "[ProfileCreate] Generating default config file: '/home/takluyver/.ipython/profile_newprofile/ipython_notebook_config.py'\n",
      "[ProfileCreate] Generating default config file: '/home/takluyver/.ipython/profile_newprofile/ipython_nbconvert_config.py'\n"
     ]
    }
   ],
   "source": [
    "!ipython profile create newprofile"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This creates a profile in your IPYTHONDIR (`ipython locate` is a quick way to see where your IPYTHONDIR is),\n",
    "and populates it with automatically generated default config files."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/home/takluyver/.ipython/profile_default\n",
      "/home/takluyver/.ipython/profile_newprofile\n"
     ]
    }
   ],
   "source": [
    "!ipython locate profile default\n",
    "!ipython locate profile newprofile"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can skim"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/home/takluyver/.ipython/profile_default'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "profile = get_ipython().profile_dir.location\n",
    "profile"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\u001b[0m\u001b[01;34mdb\u001b[0m/                     ipython_nbconvert_config.py  \u001b[01;34mnbconfig\u001b[0m/      \u001b[01;34mstartup\u001b[0m/\r\n",
      "history.sqlite          ipython_notebook_config.py   notebook.json  \u001b[01;34mstatic\u001b[0m/\r\n",
      "history.sqlite-journal  ipython_qtconsole_config.py  \u001b[01;34mpid\u001b[0m/\r\n",
      "ipython_config.py       \u001b[01;34mlog\u001b[0m/                         \u001b[01;34msecurity\u001b[0m/\r\n"
     ]
    }
   ],
   "source": [
    "ls $profile"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's peek at our config file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "pycat $profile/ipython_config.py"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Startup Files"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Startup files are simple Python or IPython scripts\n",
    "that are run whenever you start IPython.\n",
    "These are a useful way to do super common imports,\n",
    "or for building database connections to load on startup of a non-default profile.\n",
    "\n",
    "We can use a startup file to ensure that our `%tic/toc` magics are always defined,\n",
    "every time we start IPython."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "imports.py  README\r\n"
     ]
    }
   ],
   "source": [
    "!ls $profile/startup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "This is the IPython startup directory\r\n",
      "\r\n",
      ".py and .ipy files in this directory will be run *prior* to any code or files specified\r\n",
      "via the exec_lines or exec_files configurables whenever you load this profile.\r\n",
      "\r\n",
      "Files will be run in lexicographical order, so you can control the execution order of files\r\n",
      "with a prefix, e.g.::\r\n",
      "\r\n",
      "    00-first.py\r\n",
      "    50-middle.py\r\n",
      "    99-last.ipy\r\n"
     ]
    }
   ],
   "source": [
    "!cat $profile/startup/README"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Adding common imports, so we never have to forget them again"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing /home/takluyver/.ipython/profile_default/startup/simpleimports.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile $profile/startup/simpleimports.py\n",
    "\n",
    "import sys, os, time, re"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Restart the kernel** and then run the following cells immediately to verify these scripts have been executed:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<module 'sys' (built-in)>"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sys"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Defining your own magic"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we have seen already, IPython has cell and line magics. You can define your own magics using any Python function and the `register_magic_function` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from IPython.core.magic import (register_line_magic, register_cell_magic,\n",
    "                                register_line_cell_magic)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "@register_line_magic\n",
    "def sleep(line):\n",
    "    \"\"\"A simple function for sleeping\"\"\"\n",
    "    import time\n",
    "    t = float(line)\n",
    "    time.sleep(t)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%sleep 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "%sleep?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Cell Magic"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Cell magics** take two args:\n",
    "\n",
    "1. the **line** on the same line of the magic \n",
    "2. the **cell** the multiline body of the cell after the first line"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "@register_cell_magic\n",
    "def dummy(line, cell):\n",
    "    \"\"\"dummy cell magic for displaying the line and cell it is passed\"\"\"\n",
    "    print(\"line: %r\" % line)\n",
    "    print(\"cell: %r\" % cell)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "line: 'this is the line'\n",
      "cell: 'this\\nis the\\ncell'\n"
     ]
    }
   ],
   "source": [
    "%%dummy this is the line\n",
    "this\n",
    "is the\n",
    "cell"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For more details on declaring your own magics in more complex scenarios, [see our docs](http://ipython.org/ipython-doc/stable/interactive/reference.html#defining-your-own-magics)."
   ]
  }
 ],
 "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.4.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
