Blocks and indentation
How Python groups lines: the colon and the indent.
Do this lesson in the simulatorUntil now every program has been a flat list: one line after another. Real programs have structure: some lines belong together as a group, and the group runs only sometimes, or runs many times. Python shows those groups with indentation, the spaces at the start of a line. This lesson is about that, before the rest of the module uses it for real.
A block is a group of lines
Look at this program. Do not worry about the if yet (it is next lesson); look at the shape.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
print("before")
if True:
print("inside the block")
led("green")
print("after")
The two lines pushed in by four spaces are a block: a group of lines that belong to the if line above them. The if line ends with a colon :, which is Python's way of saying "a block starts on the next line".
print("after") is back at the left edge, so it is not in the block. It belongs to the program as a whole.
The colon and the indent go together
Every line that ends with : must be followed by an indented block. Every indented block must follow a line that ends with :. Break either rule and Python stops:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
if True
print("no colon")
SyntaxError: expected ':'. Fix it and run. Now try the other way round:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
print("start")
print("indented for no reason")
IndentationError: unexpected indent. Python does not allow indentation that has no block to belong to. Both are syntax errors: nothing runs.
How much to indent
Four spaces is the convention, and the editor does it for you when you press Enter after a colon. What Python actually cares about is that every line in the same block is indented the same amount:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
if True:
print("four spaces")
print("three spaces")
IndentationError. Lines in one block must line up exactly. If the editor's automatic indentation ever gets muddled, delete the spaces at the start of the line and press Tab.
Where a block ends
A block ends at the first line that is indented less. Predict the output, then run:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
if True:
print("one")
print("two")
print("three")
if True:
print("four")
print("five")
Blocks inside blocks
A block can contain another : line with its own deeper block:
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
if True:
print("outer block")
if True:
print("inner block, eight spaces in")
print("outer block again")
print("no block")
Read it as boxes inside boxes. Each level in is one more block.
Why Python does it this way
Other languages mark blocks with { } or with words like endif, and people indent anyway so they can read the code. Python makes the indentation be the structure, so what you see is always what runs. The price is that you have to get the spaces right. The editor helps; the error messages tell you when it has gone wrong.
Task: fix the indentation
This program's lines are in the right order but the indentation is wrong. It should print inside the block, then leave the LED green, then print after the block once. Fix only the spaces.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()
if True:
print("inside the block")
# the LED: green
led("green")
print("after the block")
Challenges
- Write a block inside a block inside a block, printing a line at each level.
- Indent the first line of a program by one space. What does Python say?
- Change the last cell so that "no block" is inside the outer block instead. What changes in the output?