Tuesday, 9/22
What one row means
Open in a new tab
· press f for fullscreen, o for an overview
The notebook is loading. The first load takes about 25 seconds.
Or run it on your own machine, which is how this course works from the second session on.
- Download
02-lists-and-records.pyinto your project'snotebooks/folder. -
Run
uv run marimo editfrom the project, with no file name. You get a page listing every notebook in it.
uv run 02-lists-and-records.py runs the cells and exits without showing you
anything, which looks like nothing happened. No project yet?
uvx marimo edit opens whichever folder you are in.
·
Jupyter version, which
reads without being run but has no working controls.
TL;DR#
Tonight put names on things you had already run. A value is not a variable, a variable has a type, and the type decides what an operator does: "16.5" * 2 repeats the text, 16.5 * 2 multiplies. Then four things you do to a list: take one out, keep the ones that meet a condition, do the same thing to each, and turn many into one number. Those four come back in October on a table and in November on a database. The habit worth keeping: say what you expect a cell to print before you run it. Every useful thing that happened tonight came from somebody being wrong out loud and then finding out why.
What we covered#
A value on its own does nothing. 16.75 typed into a cell is just a number. cost = 16.75 is a statement: it makes a name and points it at a value. Read the = aloud as "assign 16.75 to cost", which keeps it separate from ==, the one that asks whether two things are equal.
The variables panel shows you what exists. It is the second icon down the left side of a marimo notebook. It lists every name the notebook has defined, with its type and its value, and it updates as you run cells. When a number on screen disagrees with what you expected, look here first.
Type is something you can read, and it is easy to change by accident. type(cost) tells you. 16 is an int, 16.5 is a float, "16.5" is a str, and the quotation marks are the whole difference. Python will not add a string to a number; it stops and says so. Some other languages convert for you silently, which is worse, because you get a number back and no way to know what it did.
Anything that comes from outside your program arrives as text. A form, a file, input(): the value looks like a number and is a string. Convert it before you calculate:
cost = float(input("Enter the cost: "))float before int. int("16.5") fails, because that is not a whole number. int(float("16.5")) gives you 16. When you do not know whether a value has a decimal part, convert with float first.
f-strings put values inside a sentence, and they take formatting instructions:
print(f"The total cost is ${total_cost:.2f}"):.2f is the two decimal places accountants expect. You do not need to memorize that notation. You need to know it exists, so that you can ask for it.
Four things you do to a list. This is the table the course keeps coming back to:
| Take one out | charges[0] |
| Keep some | for with an if |
| Do the same to each | for charge in charges: |
| Turn many into one number | sum(charges), or a running total |
Indexing rules, in one place. Counting starts at zero, so charges[0] is the first item. charges[-1] is the last one and charges[-2] the one before it, which saves you counting from the front. Ask for a position that does not exist and you get an IndexError. Ask for position 1.0 and you get a TypeError, because a position has to be a whole number. charges[1:4] is a slice: it starts at 1 and stops before 4, so you get three items.
The loop variable is temporary and you choose its name. In for charge in charges:, charge does not exist before the loop and does not survive it. Python makes it fresh on each pass. That is why you never have to define it first, and why for whatever in charges: works exactly as well.
elif is one decision; two ifs are two decisions. This is what question A in section 3 is about. In a chain of if / elif / else, Python checks from the top and stops at the first true branch, so a score of 95 prints Pass when the >= 60 test comes first, and the >= 90 branch below it never runs at all. Split the same code into two separate if statements and you get both lines printed, because they have become two independent questions.
Where the rule comes from is not a programming question. Whether "under 25" includes 25 is business logic. If you wrote the rule, decide; if somebody else wrote it, ask them. < and <= give different totals, and the code cannot tell you which one is right.
Habits worth picking up#
- Keep a playground notebook. Make a second notebook in your
notebooks/folder, call itplayground.py, and use it for trying things out: a new library, a line you are unsure of, a question for your agent. Your session notebook stays the record of the week's work and the playground absorbs the experiments. - Names that already exist in a notebook are taken. marimo refuses to let one name be defined in two cells, and it says so on screen, so the wrong value never reaches your output. When you want to experiment with a name the notebook already uses, do it in the playground.
- A deleted cell can be brought back.
Ctrl+Zwill not do it, but the undo button at the bottom right will, and so willCtrl+Kfollowed byundo, even after you have carried on with other cells. marimo Basics has the rest, including how to stopShift+Backspacedeleting cells at all. - Keep the agent panel open beside your work. The question does not have to be well formed. "Why is there a syntax error" with the cell on screen is enough, because the agent can read the cell.
pyproject.tomlis the record of what you installed.uv add pandaswrites a line into it. That file is what makes your project work on another machine, and it is the reason this course installs withuv. Apip installcopied out of a tutorial leaves nothing behind in it.
A change of pace#
We covered sections 1 to 3 tonight and stopped there. Sections 4 to 6, on records and tables, move to next session. They are not this week's work. Nothing is dropped and nothing is skipped: the list is what everything else is built on, so it was worth the extra time, and a record makes more sense once the list behind it is solid.
Public links#
- marimo Basics, including getting a deleted cell back
- Python Projects,
uv init,uv add, and where each kind of file goes - What to Commit, and what should never reach github.com
- Lightning Talks, now optional and worth a bonus point
- The Zen of Python, which you can also read by running
import this
Before next session#
- Finish section 3 of the notebook,
3. ✏️ Your Turn. A to E are the required ones, and F, G and H are there for anyone who wants more. Each question has its code in a cell already, and a check value to test your answer against. Add a new cell underneath for your answer. - Commit and push. The commit you make at the end of class is part of your participation, and so is the work you push afterwards. Saving is not pushing.
- Check two files exist in your repository, because everything from here runs inside it:
pyproject.toml, whichuv initmakes, and.gitignorewith__marimo__/in it, which is on the Downloads page of this site. A repository missing either one stops at the first command next session. - Sign up for a lightning talk if you want one. They are optional now, one adds a point to your final grade, and nobody loses anything by declining. The next open slot is 9/29.
Checkpoint 2 covers this session and the next one. The checklist is on Canvas, and it grows as each session it covers is taught.
In the handbook
Reference for this session. None of it is assigned.