{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "5c291475-8c7c-461c-9b12-545a887b2432",
   "metadata": {},
   "source": [
    "# Notebooks in Cursor\n",
    "\n",
    "This course makes heavy use of a brilliant thing called Notebooks (also known as Jupyter Notebooks or Labs.) Those from a traditional software engineering background may feel discomfort with the \"hacky\" nature of Notebooks, but I must assure you: part of working with AI is being comfortable being a Scientist. As a Scientist, there's a lot of exploration and experimentation. And Notebooks are ideal for this kind of activity.\n",
    "\n",
    "A notebook is a file with the extension \".ipynb\" which stands for IPython Notebook, an early name for these.\n",
    "\n",
    "## Briefing on Notebooks in Cursor\n",
    "\n",
    "First, here's a briefing on how this fits together, and how to create and run a notebook in Cursor:\n",
    "\n",
    "https://chatgpt.com/share/6806291a-25f0-8012-a08b-057acb5045ae\n",
    "\n",
    "\n",
    "## A broader guide to Notebooks with examples\n",
    "\n",
    "The Notebook is a Data Science playground where you can easily write code and investigate the results. It's an ideal environment for:  \n",
    "- Research & Development\n",
    "- Prototyping\n",
    "- Learning (that's us!)\n",
    "\n",
    "The notebook consists of a series of square boxes called \"cells\". Some of them contain text, like this cell, and some of them contain code, like the cell below.\n",
    "\n",
    "First, you may need to click the `Select Kernel` button on the top right, and then pick `venv (Python 3.12.x)` or similar.\n",
    "\n",
    "Click in a cell with code and press `Shift + Return` (or `Shift + Enter`) to run the code and print the output.\n",
    "\n",
    "Do that now for the cell below this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "33d37cd8-55c9-4e03-868c-34aa9cab2c80",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Click anywhere in this cell and press Shift + Return\n",
    "\n",
    "2 + 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e95df7b-55c6-4204-b8f9-cae83360fc23",
   "metadata": {},
   "source": [
    "## Congrats!\n",
    "\n",
    "Now run the next cell which sets a value, followed by the cells after it to print the value"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "585eb9c1-85ee-4c27-8dc2-b4d8d022eda0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set a value for a variable\n",
    "\n",
    "favorite_fruit = \"bananas\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "07792faa-761d-46cb-b9b7-2bbf70bb1628",
   "metadata": {},
   "outputs": [],
   "source": [
    "# The result of the last statement is shown after you run it\n",
    "\n",
    "favorite_fruit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a067d2b1-53d5-4aeb-8a3c-574d39ff654a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Use the variable\n",
    "\n",
    "print(f\"My favorite fruit is {favorite_fruit}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "4c5a4e60-b7f4-4953-9e80-6d84ba4664ad",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Now change the variable\n",
    "\n",
    "favorite_fruit = f\"anything but {favorite_fruit}\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9442d5c9-f57d-4839-b0af-dce58646c04f",
   "metadata": {},
   "source": [
    "## Now go back and rerun the cell with the print statement, two cells back\n",
    "\n",
    "See how it prints something different, even though favorite_fruit was changed further down in the notebook? \n",
    "\n",
    "The order that code appears in the notebook doesn't matter. What matters is the order that the code is **executed**. There's a python process sitting behind this notebook in which the variables are being changed.\n",
    "\n",
    "This catches some people out when they first use notebooks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8e5ec81d-7c5b-4025-bd2e-468d67b581b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Then run this cell twice, and see if you understand what's going on\n",
    "\n",
    "print(f\"My favorite fruit is {favorite_fruit}\")\n",
    "\n",
    "favorite_fruit = \"apples\""
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a29dab2d-bab9-4a54-8504-05e62594cc6f",
   "metadata": {},
   "source": [
    "# Explaining the 'kernel'\n",
    "\n",
    "Sitting behind this notebook is a Python process which executes each cell when you run it. That Python process is known as the Kernel. Each notebook has its own separate Kernel.\n",
    "\n",
    "You can click the button above \"Restart Kernel\".\n",
    "\n",
    "If you then try to run the next cell, you'll get an error, because favorite_fruit is no longer defined. You'll need to run the cells from the top of the notebook again. Then the next cell should run fine."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "84b1e410-5eda-4e2c-97ce-4eebcff816c5",
   "metadata": {},
   "outputs": [],
   "source": [
    "print(f\"My favorite fruit is {favorite_fruit}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4d4188fc-d9cc-42be-8b4e-ae8630456764",
   "metadata": {},
   "source": [
    "# Adding and removing cells\n",
    "\n",
    "Click in this cell, then click the \\[+ Code\\] button in the toolbar above to create a new cell immediately below this one. Copy and paste in the code in the prior cell, then run it! There are also icons in the top right of the selected cell to delete it (bin).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ce258424-40c3-49a7-9462-e6fa25014b03",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "30e71f50-8f01-470a-9d7a-b82a6cef4236",
   "metadata": {},
   "source": [
    "# Cell output\n",
    "\n",
    "When you execute a cell, the standard output and the result of the last statement is written to the area immediately under the code, known as the 'cell output'. When you save a Notebook from the file menu (or ctrl+S or command+S), the output is also saved, making it a useful record of what happened.\n",
    "\n",
    "You can clean this up by clicking \"Clear All Outputs\" in the toolbar. It's a good idea to clear outputs before you push code to a repo like GitHub, otherwise the files can be large and harder to read."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a4d021e2-c284-411f-8ab1-030530cfbe72",
   "metadata": {},
   "outputs": [],
   "source": [
    "spams = [\"spam\"] * 1000\n",
    "print(spams)\n",
    "\n",
    "# Might be worth clearing output after running this!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eac060f2-7a71-46e7-8235-b6ad0a76f5f8",
   "metadata": {},
   "source": [
    "# Using markdown\n",
    "\n",
    "So what's going on with these areas with writing in them, like this one? Well, there's actually a different kind of cell called a 'Markdown' cell for adding explanations like this. Click the [+ Markdown] button to add a new markdown cell.\n",
    "\n",
    "Add some comments using Markdown format, perhaps copying and pasting from here:\n",
    "\n",
    "```\n",
    "# This is a heading\n",
    "## This is a sub-head\n",
    "### And a sub-sub-head\n",
    "\n",
    "I like Jupyter Lab because it's\n",
    "- Easy\n",
    "- Flexible\n",
    "- Satisfying\n",
    "```\n",
    "\n",
    "And to turn this into formatted text simply with Shift+Return in the cell.\n",
    "Click in the cell and press the Bin icon if you want to remove it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e1586320-c90f-4f22-8b39-df6865484950",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "id": "1330c83c-67ac-4ca0-ac92-a71699e0c31b",
   "metadata": {},
   "source": [
    "# The exclamation point\n",
    "\n",
    "There's a super useful feature of jupyter labs; you can type a command with a ! in front of it in a code cell, like:\n",
    "\n",
    "!ls  \n",
    "!pwd\n",
    "\n",
    "And it will run it at the command line (as if in Windows Powershell or Mac Terminal) and print the result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "82042fc5-a907-4381-a4b8-eb9386df19cd",
   "metadata": {},
   "outputs": [],
   "source": [
    "# list the current directory\n",
    "\n",
    "!ls"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4fc3e3da-8a55-40cc-9706-48bf12a0e20e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ping cnn.com - press the stop / interrupt button in the toolbar when you're bored\n",
    "\n",
    "!ping cnn.com"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4688baaf-a72c-41b5-90b6-474cb24790a7",
   "metadata": {},
   "source": [
    "# Minor things we encounter on the course\n",
    "\n",
    "This isn't necessarily a feature of notebooks, but it's a nice package to know about that is useful in notebooks.\n",
    "\n",
    "The package `tqdm` will print a nice progress bar if you wrap any iterable."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "2646a4e5-3c23-4aee-a34d-d623815187d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Here's some code with no progress bar\n",
    "# It will take 10 seconds while you wonder what's happpening..\n",
    "\n",
    "import time\n",
    "\n",
    "spams = [\"spam\"] * 1000\n",
    "\n",
    "for spam in spams:\n",
    "    time.sleep(0.01)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6e96be3d-fa82-42a3-a8aa-b81dd20563a5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# And now, with a nice little progress bar:\n",
    "\n",
    "import time\n",
    "from tqdm import tqdm\n",
    "\n",
    "spams = [\"spam\"] * 1000\n",
    "\n",
    "for spam in tqdm(spams):\n",
    "    time.sleep(0.01)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "63c788dd-4618-4bb4-a5ce-204411a38ade",
   "metadata": {},
   "outputs": [],
   "source": [
    "# On a different topic, here's a useful way to print output in markdown\n",
    "\n",
    "from IPython.display import Markdown, display\n",
    "\n",
    "display(Markdown(\"# This is a big heading!\\n\\n- And this is a bullet-point\\n- So is this\\n- Me, too!\"))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d14c1fb-3321-4387-b6ca-9af27676f980",
   "metadata": {},
   "source": [
    "# That's it! You're up to speed on Notebooks / Labs in Cursor.\n",
    "\n",
    "## Want to be even more advanced?\n",
    "\n",
    "If you want to become a pro at Jupyter Lab (the technology behind this), you can read their tutorial [here](https://jupyterlab.readthedocs.io/en/latest/). But this isn't required for our course; just a good technique for hitting Shift + Return and enjoying the result!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "db6e47b6",
   "metadata": {},
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "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.12.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
