Command Palette

Search for a command to run...

Hectal
PHASE 1Beginner ~25 min· topic 4 of 11

Topic 1.4

True, False and None

In one line

A bool is either True or False, the answer to a yes-or-no question. None is Python's way of saying "no value here". Every value also has a truthiness: empty and zero values count as false, nearly everything else as true.

Think of it like this

A light switch and an empty hook. A switch is either on or off, nothing in between: that is a bool. A hook on the wall may have a coat hanging on it, or nothing. "Nothing there" is not the same as a coat with the colour "none": it is the absence of a coat. Python calls the absence None.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

bool
The type with only two values, True and False.
None
The special value meaning "no value". Its type is NoneType.
Truthy
A value that counts as true in a condition.
Falsy
A value that counts as false in a condition: 0, "", None, False, empty containers (a container is a value that holds other values, such as a list; Phase 4).
Condition
A yes-or-no question that decides what the program does next.
Subclass
A type built on another. bool is built on int.
Singleton
A value of which only one copy exists. There is exactly one None.
Return value
What a function gives back. With no return, that value is None.

Step by step

01bool is a kind of int

True is the number 1 wearing a name, and False is 0. That is why you can add them. Programmers use this to count: (a > 0) + (b > 0) + (c > 0) is how many of three numbers are positive.

main.pywhole filepython
print(True + True, True * 10)       # 2 10
print(isinstance(True, int))        # True
print(type(True), type(None))       # <class 'bool'> <class 'NoneType'>

02Truthiness: what counts as false

Python turns any value into true or false using a short list of rules. Zero is false. Empty is false. None is false. Everything else is true. The bool() function applies those rules and shows you the result.

You will use truthiness constantly in Phase 2: if name: means "if there is a name". It is short and readable, but only when you really mean "not empty".

main.pywhole filepython
print(bool(0), bool(1), bool(-5), bool(0.0))       # False True True False
print(bool(""), bool("False"), bool(" "))          # False True True
print(bool([]), bool([0]))                         # False True
print(bool(None))                                  # False
Truthiness: what counts as falsediagram
Rendering diagram…

03None means nothing here

Start a variable at None when you do not know its value yet. Later you give it a real value. There is only one None in the whole program, so the right check is identity: result is None. We will study is properly in Topic 1.8.

print() is a function that shows text and returns None. If you store its result, you get None, which is why shown = print("hello") prints hello first and print(shown) prints None.

main.pywhole filepython
result = None
print(result is None)       # True

shown = print("hello")      # prints hello
print(shown)                # None

040 is not None

A student with 0 marks and a student who has not been marked yet are different. 0 is falsy but is a real number, None is falsy and means no value. score is None separates them; not score does not.

main.pywhole filepython
score = 0
print(score is None, score == 0, bool(score))      # False True False

05Using None by mistake

The most common beginner error with None is calculating with it. If a name is None because something returned nothing, None + 10 raises a TypeError that mentions NoneType. When you see 'NoneType' in an error, ask: which earlier line was supposed to give me a value and did not?

terminal
$ python main.py
── expected output ──
Traceback (most recent call last):
File "main.py", line 2, in <module>
total = bonus + 10
~~~~~~^~~~
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

06True and False cannot be renamed

True, False and None are keywords. You cannot assign to them. True = 5 is a SyntaxError with the message cannot assign to True. (In the old Python 2 you could, with confusing results.)

Try it yourself

  1. 1

    Count with True

    Write a = 5, b = -2, c = 9. Print (a > 0) + (b > 0) + (c > 0). Predict the answer, then run. It counts how many are positive.

  2. 2

    Test the truthiness of your own values

    Call bool() on 0.1, "0", "", [], [None] and None. Write your prediction before running each one.

Code & diagrams

bool is an int, and truthiness New tab

Predict each line of the bool() group first. Which surprised you?

Sign in to run this example in your browser.

Expected output

2 10
True
<class 'bool'> <class 'NoneType'>
False True True False
False True True
False True
False
None, and the function that returns nothing New tab

The word hello is printed by print itself. The None on the next line is what print returned.

Sign in to run this example in your browser.

Expected output

None
True
True
<class 'NoneType'>
hello
None
False True False
A form payload: 0, None and the word "False" New tab

Realistic bugs: treating 0 as missing, trusting bool("False"), and assigning the result of list.sort(). The dictionary and list in it are taught in Phase 4; for now read them as a record and a list of values.

Sign in to run this example in your browser.

Expected output

age given: True | age is falsy: True
nickname missing: True
bool of the word: True | parsed: False
3 4 0.75
{1: 'c'}
None [1, 2, 3]

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Add to None

Add 10 to a variable that holds None.

main.pywhole filepython
bonus = None
total = bonus + 10
terminal
$ python main.py
── what you'll see ──
Traceback (most recent call last):
File "main.py", line 2, in <module>
total = bonus + 10
~~~~~~^~~~
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'

Break #2

Assign to True

Try to store 5 in True.

main.pywhole filepython
True = 5
terminal
$ python main.py
── what you'll see ──
File "main.py", line 1
True = 5
^^^^
SyntaxError: cannot assign to True

Myth vs fact

Myth

bool("False") is False.

Fact

Any non-empty text is truthy, including the word "False". If you read the word "False" from a file or a user, you must compare the text yourself.

Myth

None, 0 and "" are all the same.

Fact

They are all falsy, but they are different values: a number, empty text and "no value". Code that must tell them apart uses is None or == 0.

Myth

== None and is None are equivalent, so it does not matter.

Fact

is None is the right test. A class (a blueprint for making your own kinds of value; Phase 8) can define == to say yes to anything, but nothing can change what is None means. Linters (tools that read code and warn about suspicious lines; Topic 11.6) flag == None.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    True and False are built-in singletons, like None. True is True always holds, which is why if x is True works, but it is almost never what you want: write if x: for truthiness or if x == True only in tests.

  • ▸

    bool cannot be subclassed (class B(bool) raises TypeError), which keeps the two values truly unique.

  • ▸

    Because True == 1 and hash(True) == hash(1), they collide as dictionary keys and set members: {1: "a", True: "b"} is {1: "b"}, and {0, False, 0.0} has one element. The same applies to 1.0. Arithmetic works too: ~True is -2 (bitwise not on the int 1), a surprise when someone writes ~flag instead of not flag. Bitwise &, | and ^ on two bools return a bool, but and/or return an operand (Topic 1.8).

  • ▸

    None is the only instance of NoneType, and NoneType cannot be created again, so is None is both correct and the fastest test. A function with no return returns None implicitly, and so does a method like list.sort() that mutates in place. lst = lst.sort() therefore sets lst to None, one of the most common bugs in real code.

  • ▸

    Truthiness for your own classes is controlled by __bool__ or __len__ (Phase 8). That is why a container is falsy when it is empty. NumPy arrays refuse truthiness for arrays with more than one element and raise ValueError, to stop you writing if array:.

  • ▸

    In AI code, None marks "not set" in a lot of configuration: max_tokens=None often means "use the default". Using is None rather than falsiness there avoids bugs where 0 was a real choice.

Remember this

  1. 1

    True and False are the only two values of type bool. They start with a capital letter. Comparisons produce them: 5 > 3 is True, 2 == 3 is False. You will use them in Phase 2 to decide which lines of the program run.

  2. 2

    bool is a **subclass of int**. True behaves like 1 and False like 0, so True + True is 2 and True * 10 is 10. This is a historical decision. It is handy for counting how many conditions are true, but it also means isinstance(True, int) is True. (isinstance(value, type) asks "is this value of that type?"; Topic 1.6 covers it.)

  3. 3

    None is a single special value, the only value of type NoneType. It means "no value" or "nothing here yet". A function that does not return anything gives back None (even print does: it shows text, then returns None). Always test for it with **is None**, not == None.

  4. 4

    Every Python value can be treated as true or false when it appears in a condition. This is called its truthiness. The falsy values are: False, None, zero of every kind (0, 0.0), and anything empty ("", [], and the empty dictionary and set you will meet in Phase 4). Everything else is truthy.

  5. 5

    bool(x) shows the truthiness of x. Be careful with text: bool("False") is True, because the text is not empty. And bool(" ") (one space) is True too. Truthiness only asks "is there something here?", never "does it say yes?".

  6. 6

    Do not mix up the three "empties": 0 is a number, "" is empty text, None is no value at all. All three are falsy, but they are different. A score of 0 is a real result; a score of None means "not marked yet". Treating them the same is a classic bug.

Explain it without notes

01

Which values are falsy in Python? Give at least five.

02

Why should you test x is None and not x == None?

03

What is the relationship between bool and int?

04

Why does bool("False") return True?

Practice

01

Set x = 0 and y = None. Print bool(x) and bool(y), and then x is None and y is None.

02

Set a = 3, b = 0, c = 7 and print how many of them are non-zero by adding up bool() values.

03

Store the result of print("hi") in a variable and print the variable. Say what it shows.

Trade-offs

  • ↔

    Short truthiness checks vs. explicit checks. if name: is short, but it treats 0 and "" the same. Use an explicit test (is None, == 0, len(x) == 0) when the difference matters.

  • ↔

    **None for "missing" vs. a special value.** None is clear and cannot be mistaken for real data, but any code that uses the value must check for it. A hidden None is the cause of many TypeErrors.

Done when you can

  • Done when you can list the falsy values of Python.

  • Done when you can explain why True + True is 2.

  • Done when you can say why is None is the correct check.

  • Done when you can tell 0, "" and None apart and say when each is used.

  • Done when you can read a TypeError that mentions NoneType.