Jupyter Notebooks
Notebooks are the lab bench of AI engineering. You prototype here, then move what works into production.
Prerequisites: Phase 0, Lesson 01
Video coming soon
An AI-narrated walkthrough for this module is on the way. Everything you need is in the lesson below.
#Learning Objectives
- Install and launch JupyterLab, Jupyter Notebook, or VS Code with the Jupyter extension
- Use magic commands (
%timeit,%%time,%matplotlib inline) to benchmark and visualize inline - Distinguish when to use notebooks vs scripts and apply the "explore in notebooks, ship in scripts" workflow
- Identify and avoid common notebook traps: out-of-order execution, hidden state, and memory leaks
#The Problem
Every AI paper, tutorial, and Kaggle competition uses Jupyter notebooks. They let you run code in pieces, see outputs inline, mix code with explanations, and iterate fast. If you try to learn AI without notebooks, you're doing math homework without scratch paper.
But notebooks have real traps. People use them for everything, including things they're terrible at. Knowing when to use a notebook and when to use a script will save you from debugging nightmares later.
#The Concept
A notebook is a list of cells. Each cell is either code or text.
graph TD
A["**Markdown Cell**\n# My Experiment\nTesting learning rate 0.01"] --> B["**Code Cell** ► Run\nmodel.fit(X, y, lr=0.01)\n---\nOutput: loss = 0.342"]
B --> C["**Code Cell** ► Run\nplt.plot(losses)\n---\nOutput: inline plot"]
The kernel is a Python process running in the background. When you run a cell, it sends the code to the kernel, which executes it and sends back the result. All cells share the same kernel, so variables persist between cells.
graph LR
A[Notebook UI] <--> B[Kernel\nPython process]
B --> C[Keeps variables in memory]
B --> D[Runs cells in whatever order you click]
B --> E[Dies when you restart it]
That "whatever order you click" part is both the superpower and the foot-gun.
#Build It
#Step 1: Pick your interface
Three options, one format:
| Interface | Install | Best for |
|---|---|---|
| JupyterLab | pip install jupyterlab then jupyter lab | Full IDE experience, multiple tabs, file browser, terminal |
| Jupyter Notebook | pip install notebook then jupyter notebook | Simple, lightweight, one notebook at a time |
| VS Code | Install "Jupyter" extension | Already in your editor, git integration, debugging |
All three read and write the same .ipynb file. Pick whatever you like. JupyterLab is the most common in AI work.
pip install jupyterlab
jupyter lab#Step 2: Keyboard shortcuts that matter
You operate in two modes. Press Escape for command mode (blue bar on the left), Enter for edit mode (green bar).
Command mode (most used):
| Key | Action |
|---|---|
Shift+Enter | Run cell, move to next |
A | Insert cell above |
B | Insert cell below |
DD | Delete cell |
M | Convert to markdown |
Y | Convert to code |
Z | Undo cell operation |
Ctrl+Shift+H | Show all shortcuts |
Edit mode:
| Key | Action |
|---|---|
Tab | Autocomplete |
Shift+Tab | Show function signature |
Ctrl+/ | Toggle comment |
Shift+Enter is the one you'll use a thousand times a day. Learn it first.
#Step 3: Cell types
Code cells run Python and show the output:
import numpy as np
data = np.random.randn(1000)
data.mean(), data.std()Output: (0.0032, 0.9987)
Markdown cells render formatted text. Use them to document what you're doing and why. Supports headers, bold, italic, LaTeX math ($E = mc^2$), tables, and images.
#Step 4: Magic commands
These aren't Python. They're Jupyter-specific commands that start with % (line magic) or %% (cell magic).
Time your code:
%timeit np.random.randn(10000)Output: 45.2 us +/- 1.3 us per loop
%%time
model.fit(X_train, y_train, epochs=10)Output: Wall time: 2.34 s
%timeit runs the code many times and averages. %%time runs it once. Use %timeit for microbenchmarks, %%time for training runs.
Enable inline plots:
%matplotlib inlineEvery plt.plot() or plt.show() now renders directly in the notebook.
Install packages without leaving the notebook:
!pip install scikit-learnThe ! prefix runs any shell command.
Check environment variables:
%env CUDA_VISIBLE_DEVICES#Step 5: Display rich output inline
Notebooks auto-display the last expression in a cell. But you can control it:
import pandas as pd
df = pd.DataFrame({
"model": ["Linear", "Random Forest", "Neural Net"],
"accuracy": [0.72, 0.89, 0.94],
"training_time": [0.1, 2.3, 45.6]
})
dfThis renders a formatted HTML table, not a text dump. Same with plots:
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 4))
plt.plot([1, 2, 3, 4], [1, 4, 2, 3])
plt.title("Inline Plot")
plt.show()The plot appears right below the cell. This is why notebooks dominate AI work. You see the data, the plot, and the code together.
For images:
from IPython.display import Image, display
display(Image(filename="architecture.png"))#Step 6: Google Colab
Colab is a free Jupyter notebook in the cloud. It gives you a GPU, pre-installed libraries, and Google Drive integration. No setup required.
- Go to colab.research.google.com
- Upload any
.ipynbfile from this course - Runtime > Change runtime type > T4 GPU (free)
Colab differences from local Jupyter:
- Files don't persist between sessions (save to Drive or download)
- Pre-installed: numpy, pandas, matplotlib, torch, tensorflow, sklearn
from google.colab import filesto upload/download filesfrom google.colab import drive; drive.mount('/content/drive')for persistent storage- Sessions time out after 90 minutes of inactivity (free tier)
#Use It
#Notebooks vs Scripts: When to use which
| Use notebooks for | Use scripts for |
|---|---|
| Exploring a dataset | Training pipelines |
| Prototyping a model | Reusable utilities |
| Visualizing results | Anything with if __name__ |
| Explaining your work | Code that runs on a schedule |
| Quick experiments | Production code |
| Course exercises | Packages and libraries |
The rule: explore in notebooks, ship in scripts.
A common workflow in AI:
- Explore data in a notebook
- Prototype your model in the notebook
- Once it works, move the code to
.pyfiles - Import those
.pyfiles back into the notebook for further experiments
#Common traps
Out-of-order execution. You run cell 5, then cell 2, then cell 7. The notebook works on your machine but breaks when someone runs it top to bottom. Fix: Kernel > Restart & Run All before sharing.
Hidden state. You delete a cell but the variable it created is still in memory. The notebook looks clean but depends on a ghost cell. Fix: Restart the kernel regularly.
Memory leaks. Loading a 4GB dataset, training a model, loading another dataset. Nothing gets freed. Fix: del variable_name and gc.collect(), or restart the kernel.
#Ship It
This lesson produces:
outputs/prompt-notebook-helper.mdfor debugging notebook issues
#Exercises
- Open JupyterLab, create a notebook, and use
%timeitto compare list comprehension vs numpy for creating an array of 100,000 random numbers - Create a notebook with both markdown and code cells that loads a CSV, displays a dataframe, and plots a chart. Then run Kernel > Restart & Run All to verify it works top to bottom
- Take the code from
code/notebook_tips.py, paste it into a Colab notebook, and run it with a free GPU
#Key Terms
| Term | What people say | What it actually means |
|---|---|---|
| Kernel | "The thing running my code" | A separate Python process that executes cells and keeps variables in memory |
| Cell | "A code block" | An independently runnable unit in a notebook, either code or markdown |
| Magic command | "Jupyter tricks" | Special commands prefixed with % or %% that control the notebook environment |
.ipynb | "Notebook file" | A JSON file containing cells, outputs, and metadata. Stands for IPython Notebook |
#Further Reading
- JupyterLab Docs for the full feature set
- Google Colab FAQ for Colab-specific limits and features
- 28 Jupyter Notebook Tips for power-user shortcuts
Run this lesson in the Code Lab
A real JupyterLab, with this lesson's code files (and a ready-to-run notebook). The Quick Lab opens instantly in your browser. The Cloud Lab adds a terminal, saved files and the full toolchain.
import time
import sys
import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import pandas as pd
def timing_comparison():
print("=== Timing: List vs NumPy ===\n")
size = 1_000_000
start = time.perf_counter()
python_list = [x ** 2 for x in range(size)]
list_time = time.perf_counter() - start
print(f"List comprehension: {list_time:.4f}s")
start = time.perf_counter()
numpy_array = np.arange(size) ** 2
numpy_time = time.perf_counter() - start
print(f"NumPy: {numpy_time:.4f}s")
print(f"Speedup: {list_time / numpy_time:.1f}x")
def inline_plotting():
print("\n=== Inline Plotting ===\n")
np.random.seed(42)
x = np.linspace(0, 10, 200)
y_sin = np.sin(x)
y_noisy = y_sin + np.random.normal(0, 0.2, 200)
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
axes[0].plot(x, y_sin, label="sin(x)")
axes[0].plot(x, y_noisy, alpha=0.5, label="noisy")
axes[0].set_title("Signal vs Noise")
axes[0].legend()
axes[1].hist(y_noisy - y_sin, bins=30, edgecolor="black")
axes[1].set_title("Noise Distribution")
plt.tight_layout()
plt.savefig("notebook_plot.png", dpi=100)
print("Saved plot to notebook_plot.png")
print("In a notebook, plt.show() displays this inline.")
def dataframe_display():
print("\n=== DataFrame Display ===\n")
df = pd.DataFrame({
"model": ["Linear Regression", "Random Forest", "Neural Network", "XGBoost"],
"accuracy": [0.72, 0.89, 0.94, 0.91],
"train_time_sec": [0.1, 2.3, 45.6, 8.2],
"parameters": [102, 50_000, 1_200_000, 25_000],
})
print("In a notebook, just typing 'df' renders a rich HTML table:\n")
print(df.to_string(index=False))
print(f"\nBest model: {df.loc[df['accuracy'].idxmax(), 'model']}")
print(f"Fastest model: {df.loc[df['train_time_sec'].idxmin(), 'model']}")
def memory_check():
print("\n=== Memory Usage ===\n")
small = np.random.randn(1000)
medium = np.random.randn(100_000)
large = np.random.randn(10_000_000)
for name, arr in [("1K", small), ("100K", medium), ("10M", large)]:
size_mb = arr.nbytes / 1e6
print(f"Array {name:>4s} elements: {size_mb:>8.2f} MB")
print(f"\nPython process memory: ~{sys.getsizeof(large) / 1e6:.1f} MB for the large array")
print("In notebooks, memory accumulates across cells. Restart the kernel to free it.")
def magic_command_equivalents():
print("\n=== Magic Command Equivalents ===\n")
print("In a notebook, you would use magic commands:")
print(" %timeit np.random.randn(10000) -> micro-benchmark")
print(" %%time long_operation() -> wall clock time")
print(" %matplotlib inline -> show plots in cells")
print(" !pip install package -> install from notebook")
print(" %env VAR -> check env variable")
print()
iterations = 1000
start = time.perf_counter()
for _ in range(iterations):
np.random.randn(10000)
elapsed = time.perf_counter() - start
per_call = elapsed / iterations * 1e6
print(f"Manual timing (like %%timeit): np.random.randn(10000)")
print(f" {per_call:.1f} us per call ({iterations} iterations)")
if __name__ == "__main__":
print("Notebook Tips - Key Patterns\n")
print("Run these in a Jupyter notebook to see rich output.\n")
timing_comparison()
inline_plotting()
dataframe_display()
memory_check()
magic_command_equivalents()
5 questions on this lesson
Answer each one and see straight away whether you were right and why. Your first answer to a question counts. You are not signed in, so this is practice and nothing is saved.
Reusable outputs from this lesson. Copy them into your own work.
---
name: prompt-notebook-helper
description: Debug Jupyter notebook issues including kernel crashes, memory problems, and display failures
phase: 0
lesson: 5
---
You diagnose Jupyter notebook problems. When someone describes an issue, identify the cause and give the fix.
Common issues and fixes:
**Kernel crashes:**
- Out of memory: The dataset or model is too large. Fix: reduce batch size, load data in chunks with `pd.read_csv(path, chunksize=10000)`, use `del variable` then `gc.collect()`, or switch to a machine with more RAM.
- Segfault from native library: Usually a version mismatch between numpy/torch/tensorflow and the system libraries. Fix: create a fresh virtual environment and reinstall.
- Kernel dies silently: Check the terminal where Jupyter is running for the actual error message. The notebook UI often hides it.
**Display problems:**
- Plots not showing: Add `%matplotlib inline` at the top of the notebook. If using JupyterLab, try `%matplotlib widget` for interactive plots (requires `ipympl`).
- DataFrame shows as text instead of HTML table: Make sure the dataframe is the last expression in the cell, not inside a `print()` call. `print(df)` gives text, just `df` gives the rich table.
- Images not rendering: Use `from IPython.display import Image, display` then `display(Image(filename="path.png"))`.
- LaTeX not rendering in markdown: Check for missing dollar signs. Inline: `$x^2$`. Block: `$$\sum_{i=0}^n x_i$$`.
**Memory issues:**
- Notebook uses too much RAM: Variables persist across all cells. Run `%who` to see all variables. Delete large ones with `del var_name` and run `import gc; gc.collect()`.
- Memory keeps growing: You are probably reassigning large variables without freeing the old ones. Restart the kernel (Kernel > Restart) to clear everything.
- Loading multiple large datasets: Use generators or chunked reading. `pd.read_csv(path, chunksize=N)` returns an iterator instead of loading everything at once.
**Execution issues:**
- Notebook works for me but not others: Cells were run out of order. Fix: Kernel > Restart & Run All. If it fails, you have a hidden dependency on a deleted or reordered cell.
- Cell runs forever (hanging): The code might be waiting for input (`input()`), stuck in an infinite loop, or blocked on a network request. Interrupt with Kernel > Interrupt (or press `I` twice in command mode).
- Import errors after pip install: The package installed in a different Python than the kernel is using. Fix: run `!pip install package` inside the notebook, or check `!which python` matches your environment.
**Colab-specific:**
- Session disconnected: Free Colab times out after 90 minutes of inactivity. Save work to Google Drive or download files.
- GPU not available: Runtime > Change runtime type > select GPU. If all GPUs are busy, try again later or use Colab Pro.
- Files disappeared: Colab wipes the filesystem between sessions. Mount Google Drive for persistent storage: `from google.colab import drive; drive.mount('/content/drive')`.
Diagnostic steps:
1. What is the exact error message? (Check both the notebook and the terminal)
2. Does the issue happen after restarting the kernel and running all cells top to bottom?
3. How much data are you loading? (`df.info()` for dataframes, `tensor.shape` and `tensor.dtype` for tensors)
4. What environment are you using? (Local JupyterLab, VS Code, Colab)
5. Were packages installed in the same environment as the kernel? (`!which python` and `import sys; sys.executable`)
The text and code of this lesson are based on AI Engineering from Scratch by Rohit Ghumare, MIT licensed.