True, False, and None
Truth tests, empty values, None vs 0 vs empty text, and why if result can lie when result is 0 or a blank string.
A boolean is True or False. Agent code is full of them: did the tool work, are we done, should we stop. You write them with capital letters. true and false are not Python booleans. They are NameErrors unless you defined them.
Python also does a truth test. Many values can be used in an if even when they are not real booleans. That is handy. It is also how 0, "", and [] all look like “no.” This lesson is about when that shortcut is a lie.
What counts as no
These values count as no in an if:
| Value | Meaning |
|---|---|
False | the boolean no |
None | missing |
0 and 0.0 | zero |
"" | empty text |
[] | an empty list (a row with no values) |
{} | no named keys yet |
Everything else counts as yes, including "0", "False", and [0]. A list that holds a zero is not empty. A string that holds the character 0 is not empty.
None means missing. It is not 0. It is not "". JSON uses null for the same idea. After Python reads JSON, null becomes None. If a field is absent from a dict, .get also gives None unless you pass another default.
bool(x) is the explicit truth test. print(bool(0)) prints False. Use it while you learn. In if x:, Python calls the same idea without you writing bool.
Why if result can lie
Look at this:
result = 0
if result:
print(class="tok-s">"got a result")
else:
print(class="tok-s">"looks empty")Zero can be a real answer: zero matches, zero tokens left, zero errors. if result still skips, because 0 counts as no. The program takes the empty path even though the tool succeeded and said “0.”
0, empty text, and None all look like no in an if. Check with == 0 or is None when those values are real answers.
Zero can look emptyEmpty text is the same trap. "" can mean “the tool ran, and it returned a blank message.” if result treats that as missing. A search that returns no snippet is not the same as a search that never ran.
Use an exact check:
- missing:
result is None - empty text:
result == "" - zero:
result == 0 - empty list:
result == []orlen(result) == 0
If you need “missing or empty text,” write that out: result is None or result == "". Then you know which idea you meant.
None is missing
Functions that do not return a value actually return None. A missing JSON field often becomes None. Do not use None as a stand-in for 0 or "" unless you mean “unknown.”
Check None with is None. Do not write == "None". That is text. Do not write == False. That is a boolean. None == False is False. None == 0 is False. None == "" is False. Those three “empty looking” values are three different facts.
A useful pattern for errors:
error = None
class="tok-c"># ... tool may set error to a string ...
if error is None:
print(class="tok-s">"no error")
else:
print(class="tok-s">"error was", error)Keep error as None or a string. Do not set it to False on success. Then you would have two success signals.
A function that returns True or False should return those exact objects, not 1 and 0, and not "yes". done() is True is a test you will write later. done() that returns "ok" will pass if done(): and fail a strict test. Be boring. Return booleans from predicates. Return None from “no value yet.” Return 0 from “the count is zero.” Three names, three types.
and, or, and empty values
You already saw and, or, and not. They use a truth test, not only real booleans. They also return one of the inputs, not always True or False.
name or "guest" is handy in a log. If name is "atlas", you get "atlas". If name is "", you get "guest". It is the wrong tool if 0 is a legal measurement you must keep. 0 or "missing" becomes "missing", which is a lie.
x and y returns x if x is no, otherwise y. You do not need that trick yet. Prefer if when the reader must see the rule.
The indented line under if belongs to that if. That is the indent we flagged in the first lesson. Forget the indent, and Python raises IndentationError. Indent the body four spaces. Do not indent the if line itself.
Common mistakes
if resultwhen0or""is a valid result.if error:when you meantif error is not None:— a missing error isNone, which already counts as no, but an error string of""would also look like no.- Writing
true/false/nonein lowercase. - Using
or "guest"on a counter. - Comparing to the string
"None". - Treating
[0]as empty because it “has a zero.”
Run to execute this in your browser. Nothing is sent to a server.
After you run it, set result = 5 and confirm the if result branch runs. Then set result = 0 again. Zero is the interesting case, not five.
How agents use this
A missing tool result is None, not 0 and not "". An empty list means “no items,” and if treats it as no. Zero matches is a real answer, so do not write if result when result might be 0. Check None with is None. Be exact, or the agent will stop for the wrong reason.
Stop conditions should use booleans you named: done = True, ok = False. Do not overload result as both “the number of hits” and “whether we got something.” If you need both, use two names: hits = 0 and error = None. Then if error is None: means the tool ran. if hits == 0: means it found nothing. Those are different next actions: maybe finish, maybe try another query.
JSON null, missing keys, empty strings, and false booleans all show up in tool payloads. Map them on purpose at the edge: missing key → None, empty query → reject, ok: false → retry or stop. The truth test is a shortcut for your values. It is a trap for the model’s values. Be exact at the trust edge.
Check your understanding