{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d146a41d-586c-4186-8408-8516873bf766",
   "metadata": {},
   "source": [
    "# Jupyter Notebook"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "contents",
   "metadata": {},
   "source": [
    "```{contents}\n",
    ":local:\n",
    ":depth: 2\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "21fbda68-9ec5-4bb1-971a-0927cd348b26",
   "metadata": {},
   "source": [
    "The Jupyter Notebook system is a powerful tool for interactive coding and note-taking. Instead of using proprietary tools such as Tableau or Power BI, it is now common for data scientists to use Python and Jupyter Notebook to integrate many other tools for data science tasks. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "48650371",
   "metadata": {},
   "source": [
    "## Installing Jupyter Notebook\n",
    "\n",
    "Once you have a virtual environment, you can begin installing Python packages within it. For package installation, Python has a package manager `pip` (Pip Installs Packages). `pip` installs Python packages from the Python Package Index (**PyPI**) software repository, where Python developers publish and distribute packages. \n",
    "\n",
    "In order to install a software package as part of the project environment, before you install the package, you need to first:\n",
    "\n",
    "1. Change directory into your project folder, and \n",
    "2. Activate the project virtual environment.\n",
    "\n",
    "To install Python packages using `pip` in the project folder with a virtual environment activated, the syntax is:\n",
    "\n",
    "```powershell\n",
    "pip install [PACKAGE_NAME]\n",
    "``` \n",
    "\n",
    "To install Jupyter Notebook, you issue the command below with the virtual environment **activated** (with the **(.venv)** at the beginning of the command prompt), for example, issue the command as: \n",
    "\n",
    "::::{tab-set}\n",
    ":::{tab-item} Windows\n",
    "\n",
    "```powershell\n",
    "(.venv) PS C:\\Users\\[user]\\workspace\\py> pip install notebook  \n",
    "Collecting notebook\n",
    "  Downloading notebook-7.5.2-py3-none-any.whl.metadata (10 kB)\n",
    "Collecting jupyter-server<3,>=2.4.0 (from notebook)\n",
    "  Using cached jupyter_server-2.17.0-py3-none-any.whl.metadata (8.5 kB)\n",
    "Collecting jupyterlab-server<3,>=2.28.0 (from notebook)\n",
    "  Downloading jupyterlab_server-2.28.0-py3-none-any.whl.metadata (5.9 kB)\n",
    "Collecting jupyterlab<4.6,>=4.5.2 (from notebook)\n",
    "  Downloading jupyterlab-4.5.2-py3-none-any.whl.metadata (16 kB)\n",
    "Collecting notebook-shim<0.3,>=0.2 (from notebook) \n",
    "...\n",
    "...\n",
    "```\n",
    ":::\n",
    "\n",
    ":::{tab-item} macOS\n",
    "\n",
    "```bash\n",
    "(.venv) [user]@[host]ː~/workspaces/py$ pip install notebook  \n",
    "Collecting notebook  \n",
    "  Downloading notebook-7.2.2-py3-none-any.whl (10.5 MB)  \n",
    "Collecting jupyterlab-server!=2.10.0,>=2.3.0  \n",
    "  Downloading jupyterlab_server-2.25.1-py3-none-any.whl (58 kB)  \n",
    "...\n",
    "...\n",
    "```\n",
    ":::\n",
    "::::"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8449d6ac-8b82-4e0d-bb10-b8422f6dcdd1",
   "metadata": {},
   "source": [
    "## Launch Jupyter\n",
    "\n",
    "To open a Jupyter Notebook, go to your project folder in PowerShell (Windows) or Terminal (macOS) CLI, and type the following command and press Enter (**with the venv activated**):\n",
    "\n",
    "::::{tab-set}\n",
    ":::{tab-item} Windows\n",
    "\n",
    "```powershell\n",
    "(.venv) PS C:\\Users\\[user]\\workspace\\py> jupyter notebook\n",
    "```\n",
    ":::\n",
    "\n",
    ":::{tab-item} macOS\n",
    "\n",
    "```bash\n",
    "(.venv) [user]@[host]ː~/workspaces/py$ jupyter notebook\n",
    "```\n",
    ":::\n",
    "::::\n",
    "\n",
    "This command will launch Jupyter Notebook in your default browser and a CLI showing the **Notebook server** processes. When you launch Jupyter Notebook, it opens the **Home** page in your browser. Navigate the Jupyter Notebook Homepage and you will see the URL \"**http://localhost:8888/tree**\" in the address bar. \n",
    "\n",
    "```{figure} ../../../figures/jupyter_new_empty.png\n",
    "---\n",
    "width: 475px\n",
    "name: jupyter_new_empty\n",
    "---\n",
    "A new Jupyter Home page\n",
    "```\n",
    "\n",
    "```{figure} ../../../figures/jupyter_notebook_server.png\n",
    "---\n",
    "width: 425px\n",
    "name: jupyter_notebook_server\n",
    "---\n",
    "The Jupyter Notebook server\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a1a41b5c",
   "metadata": {},
   "source": [
    "## Create New Notebooks\n",
    "\n",
    "To create a new notebook, click the 'New' button on the upper right corner of the Jupyter Home page and select the desired Python environment (*Python3 (ipykernel)*). This will give you a new untitled notebook in a new browser tab. The new notebook will have a title called \"Untitled\" by the Jupyter sign at the top of the browser tab. To rename a notebook, click on the title (i.e., 'Untitled') and enter a new name, e.g., test. Do not remove the extension name.\n",
    "\n",
    "```{figure} ../../../figures/jupyter_rename_notebook.png\n",
    "---\n",
    "width: 250px\n",
    "name: jupyter_rename_notebook\n",
    "---\n",
    "Renaming a Jupyter Notebook\n",
    "```\n",
    "After renaming the notebook, you can go back to the Jupyter Home tab and refresh the tab to see that `Untitled.ipynb` becomes `test.ipynb`.  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85507c9d-c1f2-4bad-87c7-88dbe8e65e51",
   "metadata": {},
   "source": [
    "## Code Cells\n",
    "\n",
    "Jupyter Notebook uses **code cells** to execute Python code and **markdown** cells for notes. By default, a new cell is a code cell. For example, to print a message in our test.ipynb, you issue:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "1409faf6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "print(\"hello world\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae9eb42c",
   "metadata": {},
   "source": [
    "You can highlight and execute a cell by clicking on the 'Run' icon or simply by using the keyboard shortcut `Shift+Enter` or `Ctl+Enter`. The output appears below the cell. \n",
    "\n",
    "```{figure} ../../../figures/jupyter_hello-world.png\n",
    "---\n",
    "width: 350px\n",
    "name: jupyter_hello-world\n",
    "---\n",
    "Executing a code cell in Jupyter Notebook\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb2416b3-3f1e-423c-b315-29ce4a7f2ff1",
   "metadata": {},
   "source": [
    "## Markdown Cells\n",
    "\n",
    "Jupyter Notebook is called a \"notebook\" because it functions like a digital notebook: A document that combines \"live code, equations, visualizations, and text in a single, shareable file format. For non-code text presentation, we use **markdown** cells. Markdown is a popular lightweight **markup** language that is a superset of HTML syntax, allowing for rich text formatting.\n",
    "\n",
    "Let's add a new cell by using the toolbar or the keyboard shortcut `B`. We can then use the Cell menu, the toolbar, or the key shortcut `M` to turn the highlighted code cell into a Markdown cell for notes. Note that Markdown cells are not executable, and we can format the text using Markdown syntax. \n",
    "\n",
    "Markdown cells are useful for taking notes and support formatting such as headings, bold, italics, lists (itemized and enumerated), and even LaTeX for equations. You can use `#` to specify the heading levels (1-6): \n",
    "\n",
    "\\# Heading Level 1 (H1) <br>\n",
    "\\## Heading Level 2 (H2) <br>\n",
    "\\### Heading Level 3 (H3)\n",
    "\n",
    "For lists, use `-` and `[number].`; nested lists are also supported. For **bold** and *italic*, use double and single `*`.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "85e7f821",
   "metadata": {},
   "source": [
    "## Keyboard Shortcuts and Help\n",
    "\n",
    "Some keyboard shortcuts are handy when operating a notebook by streamlining your workflow.:\n",
    "- `Shift`+`Enter`: Runs the current cell and moves to the next cell\n",
    "- `Ctl`+`Enter`: Runs the current cell and stays in the current cell\n",
    "- `A`: add a new cell above the current cell\n",
    "- `B`: add a new cell below the current cell\n",
    "- `C`: copy a cell/selected cells\n",
    "- `X`: cut a cell/selected cells\n",
    "- `V`: paste a copied cell/selected ceells\n",
    "- `DD`: delete the highlighted cell(s)\n",
    "- `Z`: undo cell operation\n",
    "- `M`: turn a code cell to Markdown cell\n",
    "- `Y`: turn a Markdown cell to a code cell\n",
    "- `Ctl`+`Shift`+`ArrowUp/Down`: Duplicate lines\n",
    "- `Ctl`+`/`: toggle comments\n",
    "\n",
    "To show a list of shortcuts, go to the Help menu and choose \"**Show Keyboard Shortcuts**\" from the dropdown. \n",
    "The 'Help' menu also gives you access to documentation for libraries and the notebook itself. "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "abc77d3b",
   "metadata": {},
   "source": [
    "## Other Notebook Operations\n",
    "\n",
    "### Saving and Exporting Notebooks\n",
    "\n",
    "You can save your notebook by clicking the save icon or pressing Ctrl+S. Jupyter Notebooks have an autosave feature that saves every two minutes.\n",
    "\n",
    "To export your notebook, go to File > Download As and select your preferred format, such as .py (\"Executable Script\") for Python scripts, PDF for documentation, or .html for web viewing.\n",
    "\n",
    "### Restarting and Interrupting the Kernel\n",
    "\n",
    "If you encounter an infinite loop or need to restart your Python environment, go to the 'Kernel' menu and select 'Restart Kernel' (`0,0`). This will reset the notebook's kernel and stop any running code. You can also use 'Interrupt' (`I,I`) to stop a specific cell.\n",
    "\n",
    "### Shutdown Notebook \n",
    "\n",
    "To shut down Jupyter Notebook safely, you need to \n",
    "1. One by one, save your work (the notebooks/tabs), shut down the notebook kernels (Kernel → Shutdown, and close the notebooks.\n",
    "2. Check the Running tab of the Dashboard/Home, shut down the notebook kernels if any\n",
    "3. Shut down (File -> Shut Down) and close the Home tab.\n",
    "\n",
    "Alternatively, if you closed your notebook tabs already, go to the notebook server terminal, press `Ctrl+C` (confirm when prompted) to shut it down.\n",
    "\n",
    "\n",
    "### Deactivate and Exit\n",
    "1. Deactivate (`deactivate`) the Python virtual environment (venv) in the CLI.\n",
    "2. Quit (`exit`) the terminal/shell."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b4bc497f",
   "metadata": {},
   "source": [
    "## Key Takeaways\n",
    "\n",
    "- Jupyter Notebooks allow for interactive Python coding and note-taking in one environment.\n",
    "- Use PowerShell or Terminal to launch Jupyter Notebooks and navigate directories as needed.\n",
    "- Code cells execute Python code, while markdown cells are for formatted notes and documentation.\n",
    "- Keyboard shortcuts like Shift+Enter and A, B, DD to streamline workflow in notebooks.\n",
    "- Notebooks can be saved, exported, and kernels restarted or interrupted for troubleshooting."
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all"
  },
  "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.13.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
