Your First CodeBook — One of Every Cell
This tutorial builds one small notebook, a cell at a time, and uses every kind of cell on the way: a text cell with an equation, a sheet, a chart, Python code, a picture made by code, and an agent that explains the result. It takes about ten minutes, and each step ends with something you can see.
Everything here is Python. For a tour of the buttons themselves, see the CodeBook Tour.
How cells pass things on
One idea makes the rest of this page easy. Cells run top to bottom, and each cell hands a value to the cell below it:
- A code cell's value is its last line, when that line is an expression —
df,total,df.describe()— exactly as in a Jupyter notebook. An explicitreturnat the top level of the cell works too, and wins if you write one. print()is output, not the value. It shows in the cell's output and is not passed on.- The cell below receives
input. In Python the value itself isinput["value"]. - Python cells also share variables: a DataFrame made in one cell is still there in the next, as long as that cell has run.
Keep those four in mind and every step below is just a use of them.
1. A text cell, with maths
Make a new CodeBook. It opens with Add Code and Add Text — choose Text, and type:
## Tea shop takings
Each line's total is quantity times price, and the day's takings add them up:
Then add the equation. In a text cell, maths is written as a formula between dollar signs:
- As you type,
$$T = q \times p$$becomes an equation inside the sentence, and$$$\sum_{i=1}^{n} q_i p_i$$$on a line of its own becomes a display equation. - In text you paste or import — from another notebook, say —
$…$is an equation in the sentence and$$…$$a display equation. Put no space just inside the dollars ($ x $is left as text), and keep a display equation on one line.
The maths is KaTeX, which covers almost everything you would write in a formula. A few LaTeX document commands are not part of it — \begin{equation}, \label, \ref, \newcommand. For several lines under one equation use \begin{aligned}…\end{aligned}; for a piecewise definition cases; for a matrix pmatrix or bmatrix. A mistake shows in red rather than breaking the cell. The full symbol list is in Math & LaTeX.
2. A sheet cell with the data
Hover below the text cell, press and choose Sheet. Fill it in like this:
| A | B | C | D | |
|---|---|---|---|---|
| 1 | Item | Qty | Price | Total |
| 2 | Tea | 2 | 3.5 | =B2*C2 |
| 3 | Cake | 1 | 4 | =B3*C3 |
| 4 | Scone | 3 | 2.5 | =B4*C4 |
Two rules matter here:
- Column names go in the first row. That row is how the cells below know what each column is called — a chart uses it for series names, and your code uses it for column names.
- Formulas start with
=, in A1 style with the name row as row 1. Prefer a formula to a number you worked out yourself, so the table stays right when you change a quantity. The cells below receive the results —7, not=B2*C2— and numbers you typed arrive as numbers.
Run the sheet cell (Run Cell, or ⇧⏎). Its value is its rows, name row first.
3. A chart cell under the sheet
Hover below the sheet and choose Chart. A chart cell draws the cell directly above it. From a table it reads the first row as series names and the first column as labels, and each other column becomes a series.
Open the chart's settings, pick Bar, give it a title, and run it. You get a bar per item for quantity, price and total. A pie chart uses just the first two columns.
A chart passes the table on unchanged, so the next cell still receives the sheet's rows.
4. A Python cell that reads the table
Add a Code cell below the chart. New code cells are Python. Type:
import pandas as pd
rows = input["value"]
df = pd.DataFrame(rows[1:], columns=rows[0])
print("Items sold:", df["Qty"].sum())
df
Run it. Three things happen, and each is one of the rules from the top of the page:
input["value"]is the sheet's rows.rows[0]is the name row, sopd.DataFrame(rows[1:], columns=rows[0])gives a table with real column names, and the Total column holds the sheet's computed totals.- The
printline appears in the output. It is there for you to read. - The last line,
df, is the cell's value — the table, which is what the next cell receives.
Change the last line to df["Total"].sum() and run again: the value is now the day's takings. Nothing else needs to change. If you prefer, write return df["Total"].sum() — that works too.
One thing to avoid: if your value is a dictionary, don't give it a key called "value". The next cell would take that key for the value itself and unwrap it.
5. A picture made by code
Charts from a chart cell are quick and restylable. For anything they cannot draw, use matplotlib in a code cell. Add another code cell:
import io, base64
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
df.plot(kind="bar", x="Item", y="Total", legend=False, title="Takings by item")
buf = io.BytesIO()
plt.savefig(buf, format="png", bbox_inches="tight")
plt.close()
"data:image/png;base64," + base64.b64encode(buf.getvalue()).decode()
df is still here from the cell above, because Python cells share variables. The last line turns the finished figure into a picture and makes it the cell's value.
Now add an Image cell directly below and run the code cell: the picture appears in the image cell.
plt.show() is what you will see in most books and examples. There is no window here for it to open, so it does not put the picture anywhere — end the cell with the picture instead, as above. The same works for an image made with Pillow: save it to PNG and end with the same data:image/png;base64,… line. Matplotlib — Pictures from Numbers keeps this frame for you and has many more examples.
6. An agent cell that explains the result
Hover between the Python cell from step 4 and the picture cell, and add an Agent cell there, directly under the cell whose value is the table (or the day's takings). Give it a prompt:
Here are today's takings at a small tea shop:
{{input.value}}
In two sentences, say which item earned the most and whether anything looks unusual.
Pick a model for the cell — each agent cell has its own, so a quick model can do one step and a stronger one another. Run it, and the answer becomes the cell's value, ready for the next cell.
Before the prompt is sent, the {{…}} placeholders are filled in:
| Write | You get |
|---|---|
{{input.value}} | the value of the cell directly above |
{{input.value.total}} | one field of it, when the value has fields |
{{nodes['Cell name'].value}} | the value of any cell, by its name, that has already run in the same run — use `icon:Play |
{{vars.threshold}} | a workflow variable |
With no placeholder at all, the value of the cell above is added to the prompt for you. As soon as you use one, only what you place is sent — so you decide exactly what the model sees.
If the next cell needs to use the answer as data, say so in the prompt: describe the exact shape you want and end with "Respond ONLY with valid JSON".
More on placeholders: Template Variables.
7. Run it all
Press Run All Cells in the bottom toolbar. The notebook runs top to bottom: the sheet computes its totals, the chart draws them, the code cells count and plot, and the agent writes its two sentences from the real numbers.
Now change Cake's quantity to 3 and run all again. Every cell below follows.
Quick reference
| You want to | Do this |
|---|---|
| Pass a result to the next cell | End the code cell with it — df, total — or return it |
| Show something without passing it on | print(...) |
| Read the cell above in Python | input["value"] |
| Turn sheet rows into a DataFrame | pd.DataFrame(rows[1:], columns=rows[0]) |
| Show a matplotlib or Pillow picture | End with the data:image/png;base64,… string, with an Image cell below |
| Put the cell above into a prompt | {{input.value}} |
| Write an equation | Between dollar signs, KaTeX, one line for a display equation |
Where next
- CodeBook Tour — every control, the REPL, reading mode.
- Math with Python — SymPy, NumPy, Matplotlib and SciPy, lesson by lesson.
- Values in Every Language — the same steps in JavaScript, TypeScript, Lua, Ruby, Go, Rust, C, C++, Zig and Shell.
- Languages, and Where They Run — code cells in other languages, and what each needs.
- Coming from Jupyter — how your notebooks map across.