{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Jupyter Notebooks\n",
    "\n",
    "<br>\n",
    "<br>\n",
    "<img src=\"https://raw.githubusercontent.com/COGS108/Tutorials/master/img/jupyter.png\" width=\"200px\">\n",
    "<br>\n",
    "<br>\n",
    "\n",
    "This is a quick introduction to Jupyter notebooks."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-success\">\n",
    "Jupyter notebooks are a way to combine executable code, code outputs, and text into one connected file.\n",
    "</div>\n",
    "\n",
    "<div class=\"alert alert-info\">\n",
    "The official documentation from project Jupyter is available \n",
    "<a href=\"https://jupyter-notebook.readthedocs.io/en/stable/\" class=\"alert-link\">here</a>\n",
    "and they also have some example notebooks \n",
    "<a href=\"https://github.com/jupyter/notebook/tree/master/docs/source/examples/Notebook\" class=\"alert-link\">here</a>.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Menu Options & Shortcuts\n",
    "\n",
    "To get a quick tour of the Jupyter user-interface, click on the 'Help' menu, then click 'User Interface Tour'.\n",
    "\n",
    "There are also a large number of useful keyboard shortcuts. Click on the 'Help' menu, and then 'Keyboard Shortcuts' to see a list. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Cells"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-success\">\n",
    "The main organizational structure of the notebook are 'cells'.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Cells, can be markdown (text), like this one or code cells (we'll get to those)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Markdown cells"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Markdown cell are useful for communicating information about our notebooks.\n",
    "\n",
    "They perform basic text formatting including italics, bold, headings, links and images.\n",
    "\n",
    "Double-click on any of the cells in this section to see what the plain-text looks like. Run the cell to then see what the formatted Markdown text looks like."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# This is a heading\n",
    "\n",
    "## This is a smaller heading\n",
    "\n",
    "### This is a really small heading"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "We can italicize my text either like *this* or like _this_."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "We can embolden my text either like **this** or like __this__."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Here is an unordered list of items:\n",
    "* This is an item\n",
    "* This is an item\n",
    "* This is an item"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Here is an ordered list of items:\n",
    "1. This is my first item\n",
    "2. This is my second item\n",
    "3. This is my third item"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "We can have a list of lists by using identation:\n",
    "* This is an item\n",
    "* This is an item\n",
    "\t* This is an item\n",
    "\t* This is an item\n",
    "* This is an item"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "We can also combine ordered and unordered lists:\n",
    "1. This is my first item\n",
    "2. This is my second item\n",
    "\t* This is an item\n",
    "\t* This is an item\n",
    "3. This is my third item"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "We can make a link to this [useful markdown cheatsheet](https://www.markdownguide.org/cheat-sheet/) as such."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "If we don't use the markdown syntax for links, it will just show the link itself as the link text: https://www.markdownguide.org/cheat-sheet/"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### LaTeX-formatted text"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "$$ P(A \\mid B) = \\frac{P(B \\mid A) \\, P(A)}{P(B)} $$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Code Cells\n",
    "\n",
    "Code cells are cells that contain code, that can be executed. \n",
    "\n",
    "Comments can also be written in code cells, indicated by '#'. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# In a code cell, comments can be typed\n",
    "a = 1\n",
    "b = 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "# Cells can also have output, that gets printed out below the cell.\n",
    "print(a + b)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Define a variable in code\n",
    "my_string = 'hello world'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "# Print out a variable\n",
    "print(my_string)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'HELLO WORLD'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Operations that return objects get printed out as output\n",
    "my_string.upper()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Define a list variable\n",
    "my_list = ['a','b','c']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['a', 'b', 'c']\n"
     ]
    }
   ],
   "source": [
    "# Print out our list variable\n",
    "print(my_list)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Accessing Documentation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-success\">\n",
    "Jupyter has useful shortcuts. Add a single '?' after a function or class get a window with the documentation, or a double '??' to pull up the source code. \n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Import numpy for examples\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Check the docs for a numpy array\n",
    "np.array?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Check the full source code for numpy append function\n",
    "np.append??"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "# Get information about a variable you've created\n",
    "my_string?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Autocomplete"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-success\">\n",
    "Jupyter also has \n",
    "<a href=\"https://en.wikipedia.org/wiki/Command-line_completion\" class=\"alert-link\">tab complete</a>\n",
    "capacities, which can autocomplete what you are typing, and/or be used to explore what code is available.  \n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "invalid syntax (<ipython-input-12-06f09a953826>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[0;36m  File \u001b[0;32m\"<ipython-input-12-06f09a953826>\"\u001b[0;36m, line \u001b[0;32m2\u001b[0m\n\u001b[0;31m    np.\u001b[0m\n\u001b[0m       ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n"
     ]
    }
   ],
   "source": [
    "# Move your cursor just after the period, press tab, and a drop menu will appear showing all possible completions\n",
    "np."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Autocomplete does not have to be at a period. Move to the end of 'ra' and hit tab to see completion options. \n",
    "ra"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# If there is only one option, tab-complete will auto-complete what you are typing\n",
    "ran"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Kernel & Namespace\n",
    "\n",
    "You do not need to run cells in order! This is useful for flexibly testing and developing code. \n",
    "\n",
    "The numbers in the square brackets to the left of a cell show which cells have been run, and in what order.\n",
    "\n",
    "However, it can also be easy to lose track of what has already been declared / imported, leading to unexpected behaviour from running cells.\n",
    "\n",
    "The kernel is what connects the notebook to your computer behind-the-scenes to execute the code. \n",
    "\n",
    "It can be useful to clear and re-launch the kernel. You can do this from the 'kernel' drop down menu, at the top, optionally also clearing all ouputs."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Magic Commands"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-success\">\n",
    "'Magic Commands' are a special (command-line like) syntax in IPython/Jupyter to run special functionality. They can run on lines and/or entire cells. \n",
    "</div>\n",
    "\n",
    "<div class=\"alert alert-info\">\n",
    "The iPython <a href=\"http://ipython.readthedocs.io/en/stable/interactive/magics.html\" class=\"alert-link\">documentation</a> has more information on magic commands.\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "Magic commands are designed to succinctly solve various common problems in standard data analysis. Magic commands come in two flavors: line magics, which are denoted by a single % prefix and operate on a single line of input, and cell magics, which are denoted by a double %% prefix and operate on multiple lines of input."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Access quick reference sheet for interactive Python (this opens a reference guide)\n",
    "%quickref"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Check a list of available magic commands\n",
    "%lsmagic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Check the current working directory\n",
    "%pwd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "# Check all currently defined variables\n",
    "%who"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "# Chcek all variables, with more information about them\n",
    "%whos"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [],
   "source": [
    "# Check code history\n",
    "%hist"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Line Magics\n",
    "\n",
    "\n",
    "Line magics use a single '%', and apply to a single line. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# For example, we can time how long it takes to create a large list\n",
    "%timeit list(range(100000))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Cell Magics\n",
    "\n",
    "Cell magics use a double '%%', and apply to the whole cell. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%timeit\n",
    "# For example, we could time a whole cell\n",
    "a = list(range(100000))\n",
    "b = [n + 1 for n in a]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Running terminal commands\n",
    "\n",
    "Another nice thing about notebooks is being able to run terminals commands"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# You can run a terminal command by adding '!' to the start of the line\n",
    "!pwd\n",
    "\n",
    "# Note that in this case, '!pwd' is equivalent to line magic '%pwd'. \n",
    "# The '!' syntax is more general though, allowing you to run anything you want through command-line "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%bash\n",
    "# Equivalently, (for bash) use the %%bash cell magic to run a cell as bash (command-line)\n",
    "pwd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "# List files in directory\n",
    "!ls"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "# Change current directory\n",
    "!cd ."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-info\">\n",
    "For more useful information, check out Jupyter Notebooks \n",
    "<a href=\"https://www.dataquest.io/blog/jupyter-notebook-tips-tricks-shortcuts/\" class=\"alert-link\">tips & tricks</a>, and more information on how \n",
    "<a href=\"http://jupyter.readthedocs.io/en/latest/architecture/how_jupyter_ipython_work.html\" class=\"alert-link\">notebooks work</a>.\n",
    "</div>"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
