The Path and The Way
Every command you type is a name, and the shell must find who answers. The Path ($PATH) is the ranked list of directories it searches, top to bottom, until the first match wins, which is why loading a module can change which python responds. But a bare terminal can draw a plot without ever showing it, so the Path leads to JupyterHub: your window into the cluster, where code runs on the Yens’ hardware but appears in your browser. There you’ll run Python three ways, line-by-line in the interpreter, cell-by-cell in a notebook, and start-to-finish as a script, the form you submit to the cluster.

🗡️ Main Quest: The Path
Quest: Follow the sacred Path, Learn about JupyterHub, command AI to do your bidding
Review
Before opening any notebooks, confirm you’re on the Yens.
ssh SUNetID@yen.stanford.edu
Once connected:
hostname # which Yen did you land on?
ls # do you see files from Day 1?
module avail # Remember these?
You should see your home directory and the gsb-research-computing-ai-skills folder you cloned yesterday.
Step 1: Who and Where Are You?
Get your bearings before walking the Path:
whoami # who am I logged in as?
pwd # where am I?
echo $PATH | tr ':' '\n' # what is the Path? (one entry per line)
pwd should show your home directory, /home/users/SUNetID. If you’re somewhere else, run cd on its own to return home before continuing.
Step Into the Repo First
pwd isn’t trivia. It decides two things you’ll care about all day: where the files you create land, and whether the commands you type can be found. So before you run anything, move into the clone you made on Day 1 and stay there:
cd ~/gsb-research-computing-ai-skills
pwd # confirm: /home/users/SUNetID/gsb-research-computing-ai-skills
🔮 This is also where you cast from. Your spell-caster,
cast, is a single file sitting at the root of your repo. Running./castmeans “run the thing calledcastin the folder I am in right now” — so from anywhere else, the shell looks in the wrong folder and reportsNo such file or directory. Your progress isn’t lost; you’re just standing in the wrong room.cd ~/gsb-research-computing-ai-skills # go to the repo root ls cast # you should see it listed here ./cast <spell> # now the spell landsWhen a command “doesn’t exist,”
pwdis the first thing to check.
$PATH is the shell’s search checklist. It is a list of directories, roughly:
/home/users/SUNetID/.local/bin # your SUNetID goes here
/usr/local/sbin
/usr/local/bin
/usr/bin
...
/zfs/tools/darc/bin
When you type a command, the shell walks these directories top to bottom and runs the first matching executable it finds.
Exercise: Using yesterday’s skills, find
python3.
💡 Hint — click to reveal
Runwhich python3 and look at the front of the Path.
So typing python3 checks .local/bin/python3, then /usr/local/sbin/python3, and so on, stopping at the first hit.
Loading a Module Changes the Path
module load python
echo $PATH | tr ':' '\n'
A new directory jumps to the front of the list:
/software/free/python/3.10.5/bin
Now which python3 points there instead. The module put its own Python first.
Undo the Change: Deactivating a Module
Loading a module is reversible. Unload it and your $PATH snaps back to where it started:
module unload python # or: module purge (unloads everything at once)
echo $PATH | tr ':' '\n' # the python module's bin/ is gone from the front
which python3 # back to the system python3 again
💡 This load / unload of
$PATHis the exact same mechanism you’ll meet in The Venv Forge: activating an environment prepends a directory to the front of your PATH, and deactivating removes it.
Step 2: Running Standalone Python Code
You do not need a file to run Python. The interactive interpreter lets you type code straight into the terminal and run it immediately, one line at a time.
Still in your repo folder from Step 1 (check with pwd if you’re unsure), start Python:
python3
The prompt changes to >>>. You are now inside Python. Type (or paste) this code:
import matplotlib.pyplot as plt # plotting library
import numpy as np # scientific computing library
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [1, 4, 2, 3])
ax.set_title("My First Plot")
ax.set_xlabel("x")
ax.set_ylabel("y")
plt.show()
fig.savefig("my_plot.png", dpi=300, bbox_inches="tight")
plt.close(fig)
When you are done, leave the interpreter and return to the shell:
exit()
💡
plt.show()would normally pop open a window, but a terminal has no screen to draw on, so nothing appears. That is why we also callfig.savefig(...): it writes the plot tomy_plot.pngin your current directory.
💡 Hint: got a ModuleNotFoundError? — click to reveal
Leave Python withexit(), run pip install matplotlib numpy in the same environment, then start python3 again.
Look at What You Made
Back at the normal shell prompt:
pwd # where am I? this is where the file was written
ls # you should now see my_plot.png
cat my_plot.png # try to "read" the image
There’s the payoff for stepping into the repo first: savefig wrote my_plot.png into whatever folder you were standing in, and because that was your repo, the file is somewhere git can see it. Had you stayed in your home directory, it would have landed there instead — not wrong, just harder to find later.
cat spills something like:
�PNG
IHDR....IDATx...��KѐP....
What is this incantation? A terminal can run the code that draws an image, but it cannot show you the image itself. If this is all the Yens has to offer, why did you take this perilous journey? For that, you need a window into the cluster: JupyterHub.
🟢 Green sticky = the plotting code ran in the interpreter and
lsshowsmy_plot.pngin my repo folder 🔴 Red sticky = I got aModuleNotFoundError, or nomy_plot.pngappearedPut a sticky note on your laptop lid so instructors can see where you are.
Step 3: Summon JupyterHub
JupyterHub is the development environment we offer on the Yens. It runs in your browser, but your code executes on the cluster’s hardware, not your laptop. Instead of the bare command line from Step 2, you get an interactive workspace: write and run code in notebooks, edit files, open a terminal, and see plots and tables right on the screen.
Choose any node to log in:
Log in with your SUNetID credentials. The file browser on the left starts in your home directory on the Yens, showing the same files you’d see from ls in a terminal. Double-click into gsb-research-computing-ai-skills and you’ll find the my_plot.png you just made — the same folder, seen two ways.
🟢 Green sticky = I’m logged in to JupyterHub and I can see
my_plot.pngin my repo folder 🔴 Red sticky = I need helpPut a sticky note on your laptop lid so instructors can see where you are.
Step 4: Start a Notebook and a Terminal
- Click the blue “+” to open the Launcher
- Start a Python 3 notebook
- Open a Terminal tab as well
A notebook runs code in cells you execute one at a time, with the results (text, tables, even images) appearing right below each cell. The Terminal is a shell similar to the one you used in Step 2, though not identical. You will dig into that difference in The Venv Forge. You’ll switch between the two throughout Day 2.
Step 5: Run a Cell
Type this into the first cell and run it with Shift+Enter:
numbers = [1, 2, 3, 4, 5]
print(sum(numbers))
Expected output: 15
Now for the payoff. Remember the “incantation” from Step 2, the plot your terminal could make but not show? Paste the same code into a new cell and run it:
import matplotlib.pyplot as plt # plotting library
import numpy as np # scientific computing library
fig, ax = plt.subplots()
ax.plot([1, 2, 3, 4], [1, 4, 2, 3])
ax.set_title("My First Plot")
ax.set_xlabel("x")
ax.set_ylabel("y")
plt.show()
This time the graph appears right below the cell. That is what JupyterHub buys you: in a notebook, plt.show() draws the plot inline instead of needing a screen of its own.
💡 In a notebook you don’t even need
fig.savefig(...)just to see a plot. You still save it when you want a file to keep, share, or hand to the cluster.
Step 6: Run the Same Code as a Script
You have now run Python two ways: the interactive interpreter (Step 2) and a notebook (Step 5). The third way is a script, a .py file that runs start to finish on its own. This is what you submit to the cluster.
- In the Launcher, open a Text File (or run
nano plotting_code.pyin the Terminal) and name itplotting_code.py. - Paste in the plotting code from Step 2, keeping the
fig.savefig("my_plot.png", ...)andplt.close(fig)lines so it writes the image to a file. - Run it from the Terminal:
python3 plotting_code.py
Same output, different workflow. Notebooks are good for exploration; scripts are what you submit to the cluster. For the rest of Day 2, you will write scripts.
Side quests
Finished early? Try any of these.
Side quest — Behold the Incantation
The terminal could only show you my_plot.png as gibberish. JupyterHub can do better. In the file browser on the left, find my_plot.png and double-click it. It opens in an image viewer, and the plot you drew finally reveals itself, the same file, now readable because you have the right tool to look at it.
Side quest — Enchant the Plot
A plot is never finished. Back in your notebook, edit the plotting cell to make it your own, then re-run it with Shift+Enter and watch it change:
- Plot a second line, e.g.
ax.plot([1, 2, 3, 4], [2, 3, 1, 4], label="second run") - Give each line a
label=...and addax.legend()to name them - Change a line’s colour with
color="crimson"(or"teal","goldenrod")
Now command the AI to do your bidding. First save your notebook into your repo folder with a name you’ll recognise (File → Save Notebook As…, e.g. gsb-research-computing-ai-skills/plotting.ipynb). Then open a Terminal in JupyterHub and summon Claude Code, exactly as you did in Working with Claude Code:
cd ~/gsb-research-computing-ai-skills # the folder holding your notebook
ml claude-code
claude
That cd matters for the same reason it did in Step 1: Claude Code works from the folder you start it in. Launch it from your home directory and it can’t see a notebook that lives in your repo.
Then describe the plot you want — no matplotlib to memorise, just say it.
💡 Hint — what to ask Claude
You don’t need a fancy prompt. Say what you want and let it work:
Make the plot in plotting.ipynb as exciting as you can — bold colours, several lines, a dramatic title, annotations, gridlines, whatever looks great. Then leave the notebook so I can re-run it.
🎛️ Two dials worth setting deliberately — both from Day 1, both relevant right here.
Permission mode (
Shift+Tabcycles it; the current one shows at the bottom of the screen). The question is always how bad is a wrong move here? This task edits one throwaway plot in your own repo, so accept edits is a reasonable place to sit: you skip approving every change and nothing important is at risk. Reach for plan mode instead when you want to read the intent before anything changes, and stay in manual when the target is real work you can’t easily redo. The mode is a statement about the stakes, not about how much you trust Claude.Model (
/model). Restyling a matplotlib cell is small, well-trodden work, so a lighter model like Sonnet or Haiku answers quickly and spends far less of your allowance. Save Opus for the genuinely hard problems later this week. Remember the constraint from Day 1: Stanford gives you Claude on a managed plan with a usage limit, so when it runs out you wait for the reset rather than paying for more. Spending Opus on a plot is how you end up rationing later.
Claude edits the .ipynb file on disk. Switch back to the notebook tab — JupyterHub will notice the file changed and offer to reload it (click Reload) — then Kernel → Restart Kernel and Run All Cells to see your enchanted plot.
🧠 Skills Learned
- You can open JupyterHub on the Yens and run Python from any browser
- You know the difference between a notebook cell and a script, and you know when each is useful
- You can run a
.pyscript from the terminal, which is how cluster jobs work