Question bank — Jupyter notebooks workflow
Before you start, hold three plain-English facts in your head:
Recall
What is the kernel in one sentence? Kernel ::: The single background Python process that actually runs your code and holds every variable in one shared memory space (a namespace dictionary) until you restart it.
What does the number in In [n] mean?
Execution counter ::: It is the order in which cells were run, not the order they appear on screen — it only goes up, one per run.
What does the .ipynb file actually save?
Saved contents ::: The cell source and the last output of each cell — it does not save the live variables or the run order needed to reproduce them.
Picture the two halves that drift apart
The whole page hinges on one image: on the left, the cells as text on your screen (top-to-bottom); on the right, the kernel's namespace — the single dictionary of live variables. The counters In [n] are the thread connecting them, and they follow the order you pressed Run, not the order the cells sit on screen.
Look at the arrows: cell C at the top carries In [3] while cell B below it carries In [1]. The number going down the page decreases — that is the visible fingerprint of an out-of-order run. Whenever a smaller counter sits above a larger one, the kernel's memory was built in a sequence your eyes cannot infer from position alone.
Ghost variables — a picture first
In the figure, the blue box x = 5 is deleted from the notebook (crossed out on the left), but the namespace on the right still holds x -> 5. A later cell reads x happily now, and crashes with NameError after "Restart & Run All". That gap between screen and memory is the ghost.
Idempotent vs mutating cells — see the difference
The left track (chalk-blue) reassigns from a raw source every time — the bar stays the same height no matter how often you run it. The right track (chalk-pink) overwrites in place — each run stacks another log1p on top, and the value silently collapses toward zero. Same-looking code, opposite safety.
True or false — justify
A notebook that shows outputs under every cell is guaranteed to run cleanly top-to-bottom. ::: False. Saved outputs are just pictures of the last run, which may have been out of order; a fresh top-to-bottom run can still crash. Only "Restart & Run All" proves reproducibility. Restarting the kernel deletes the code you typed in your cells. ::: False. Restart only wipes the live memory (variables, imports); the cell source is text saved in the file and stays untouched. You lose results, not code. If
In [5]sits aboveIn [12], the notebook was run out of order. ::: True. Counter numbers only ever increase per run, so a smaller number physically above a larger one means the upper cell was executed earlier despite being higher on the page. Deleting a cell that definedxalso removesxfrom memory. ::: False. Deleting the cell removes the text, but the kernel already storedxin its namespace;xsurvives as a ghost variable until you restart or reassign it. Two cells running in either order always give the same final state. ::: False. Order matters whenever one cell depends on another's variable, or when a cell mutates shared data (e.g.data.dropna()reassigned in place). Reordering can change or break the result. Re-running the mutating celldata['rev'] = np.log1p(data['rev'])twice leaves the data unchanged the second time. ::: False. The cell is not idempotent: the second run logs the already-logged column, givinglog1p(log1p(rev))— a silent corruption. Only cells that read from an untouched source survive repeated runs.Shift+EnterandCtrl+Enterdo the same thing. ::: False. Both execute the cell, butShift+Entermoves focus to the next cell (fast linear flow) whileCtrl+Enterstays put (repeatedly re-test the same cell) — the difference is where your cursor lands, which shapes your workflow. A notebook with no errors and all outputs present is safe to hand a collaborator. ::: False. "No errors now" only reflects your out-of-order history. The collaborator runs fresh, so hidden dependencies surface asNameError. Always Restart & Run All before sharing.
Spot the error
Cell A:
data = pd.read_csv('sales.csv'). Cell B (run first, appears below A):data.describe(). Reader sees output, ships it. ::: The output only exists because A was run at some earlier point. On a clean run B executes before A, raisingNameError: data is not defined. The visible output is a stale artifact. A cell containsdata['rev'] = np.log1p(data['rev'])and the user re-runs it three times to "make sure". ::: Each run logs the already-logged column, so the values are nowlog1p(log1p(log1p(x)))— meaningless. Log-transforms must read from a raw source column, not overwrite in place, or the cell must be run exactly once. A collaborator'sModuleNotFoundError: pandason your working notebook. ::: The notebook code is fine; the environment differs — pandas isn't installed in their kernel. This is an environment problem, fixed with a shared virtual environment, not a code edit.describe()is written mid-cell above a plot, and the user complains the table never shows. ::: Only the last expression of a cell auto-displays.describe()above other lines is computed and thrown away; wrap it indisplay(...)to force it to render. A cell does: load CSV (2 min), clean (3 min), train (10 min) — training fails, user re-runs the whole cell. ::: One giant cell forces re-running 5 minutes of already-working load+clean just to retry the model. Splitting into separate cells keeps clean data in memory so only the 10-minute train step reruns. User callsx = old_valuein a cell, edits the cell tox = new_value, but a later cell still "sees"old_value. ::: They edited the source but never re-ran the edited cell, so the kernel's namespace still holdsold_value. Editing text changes nothing until execution; press Run. A cell runs%run setup.pyto "import" helpers, then a later cell uses a function from it — works today,NameErrorafter restart-run-all only if the file moved. :::%runexecutes an external file into the current namespace, injecting names that never appear in any cell — a source of ghost-like variables. If the reader doesn't havesetup.pyor it changed, the top-to-bottom run breaks in a way the cells alone can't explain.
Why questions
Why does the execution counter matter more than a cell's position on the page? ::: Because Jupyter runs the kernel, which only knows the order you pressed Run — the counter is the true timeline, while vertical position is just how you arranged the text. Why does "Restart & Run All" catch bugs that a normal save does not? ::: It throws away all hidden live state and forces every cell to run strictly top-to-bottom from an empty namespace, reproducing exactly what a fresh reader experiences. Why is keeping cells short (5–15 lines) a debugging strategy, not just tidiness? ::: When a short cell fails you instantly know which single operation broke; a long multi-purpose cell hides which line failed and re-runs working steps unnecessarily — see debugging strategies. Why can you fix a model bug by editing Cell 3 and re-running Cell 2, without touching Cell 1? ::: Because
modelis a live object in the shared namespace; Cell 3 mutates that same object, so Cell 2's reference already points at the fixed version — no reload needed. Why does splitting an analysis into cells make it faster than a script, given the code is identical? ::: The kernel keeps every intermediate result in memory, so you re-run only the piece you changed instead of restarting the whole pipeline from scratch each time. Why does only the last bare expression of a cell auto-display, regardless of whether it's a string, a DataFrame, or a number? ::: Jupyter renders the value of the final expression statement of a cell and nothing else; a baredata.head()on the last line is that value, butf"R2 = {score}"buried mid-cell, or any non-final line, is computed and discarded — so those need an explicitprint()ordisplay().
Edge cases
What is in memory the instant a fresh kernel starts, before any cell runs? ::: An essentially empty namespace — no
importhas executed, so evenpdornpare undefined until you run the imports cell. See NumPy basics for what those imports bring in. A cell defines nothing and outputs nothing (e.g.# just a comment). What happens to the counter? ::: It still increments — the counter tracks runs, not output. An empty run bumpsIn [n]even with no visible effect, which can puzzle you when tracing order. You run a cell whose last line is an assignmenty = x * 2. Why is there no output? ::: An assignment is a statement, not an expression, so it has no display value; nothing renders even thoughyis now stored. Add a bareyline orprint(y)to see it. A cell errors halfway through (line 3 of 5 raises). What is the state of the first two lines' effects? ::: They already ran and their side-effects (variables set, files opened) persist in memory, while lines 4–5 never executed — leaving a half-applied, inconsistent state that often confuses the next run. You definedatain Cell 4, then delete Cell 4 but keep Cell 2 that usesdata. Does Cell 2 still work? ::: Yes right now, becausedatalingers as a ghost variable in the namespace — but the notebook is now unreproducible: a restart makesdataundefined and Cell 2 breaks. A silent time-bomb. A cell uses a magic like%%bashor%timeit. Does it run in the same namespace as ordinary cells? ::: Not necessarily —%%bashruns in a separate shell (its variables never reach Python), and%timeitruns its code in an isolated loop, so any variable "defined" there does not persist in the kernel namespace. Assuming they do is a subtle state-drift trap. During a EDA session you mutate a shared DataFramedatain place across several cells, then jump back and re-run an early cell. Why might the plot look wrong? ::: The early cell sees the already-mutateddata, not the original — in-place mutation destroys the ability to safely re-run earlier cells, unlike pure reassignment to new variables. What happens to a running cell's variables if the kernel dies mid-execution (out of memory)? ::: Everything in the namespace is lost — the kernel process itself is gone, so all imports and variables vanish and you must re-run from the top; partial results are not recoverable.