Comments, indentation and style
Write readable Python with correct indentation, helpful comments and the naming conventions of PEP 8.
What you will learn
- Indent blocks correctly and read an IndentationError
- Write comments that explain why, not what
- Apply PEP 8 naming and spacing, and let ruff format do the rest
On this page
Python is unusual in that the shape of your code is part of its meaning. Get the layout right and the program reads like an outline. Get it wrong and Python refuses to run it.
Indentation is syntax
Most languages use braces to group statements. Python uses indentation. A line ending in a colon opens a block, and every line in the block is indented by the same amount.
The only block statement you could write with what you know so far is if, which runs its block only when a condition is true. Lesson 14 teaches it properly. Treat the next example as a preview, there to show layout:
# Check whether the guests fit around the table.guests = 3 # people who said yes
if guests <= 4: print("Everyone fits.") print("Spare seats:", 4 - guests)Everyone fits.Spare seats: 1The two highlighted lines belong to the if because they sit four spaces in. Move them back to the left edge and they would no longer be part of it.
The standard is four spaces per level. Configure your editor so that the Tab key inserts four spaces, and never mix tabs and spaces in one file.
If the layout breaks the rules, Python tells you. A block that is missing its indent gives this message:
File "bad.py", line 2 print("hi") ^^^^^IndentationError: expected an indented block after 'if' statement on line 1An extra indent where none belongs gives IndentationError: unexpected indent. Both messages point at the line to look at, and the first one even names the statement that wanted a block.
Comments
A # starts a comment, which runs to the end of the line. Python ignores it. There is no block-comment syntax; use one # per line.
Good comments say why, because the code already says what. This comment only repeats the code:
guests = 3 # set guests to 3This one explains a decision that the code cannot show:
guests = 3 # people who said yes, not counting the hostDo not leave dead code commented out. Version control remembers old versions for you.
Naming conventions
Python’s style guide, PEP 8, asks for:
snake_casefor variables and functions:total_cost,birth_year.UPPER_SNAKE_CASEfor constants:MAX_SEATS.PascalCasefor classes, which arrive in the intermediate course.- Names that say what they hold.
guestsbeatsg.
Spacing matters too. Put one space on each side of = and arithmetic operators, no space before a comma, and no space just inside parentheses. PEP 8 suggests lines of at most 79 characters; ruff and black default to 88.
Let a tool do it
You do not have to remember all of this. ruff is a popular tool that checks and reformats Python code, and black is another. Once installed, it fixes layout for you.
ruff format messy_script.pyruff check messy_script.pyInstalling tools comes in a later module. For now, it helps to know that the tidy version of a file is something a program can produce for you.
A messy script and its cleaned-up version
Here is a working script that breaks nearly every convention.
Rent=900food = 250Transport= 80total_Cost=Rent+food+Transportprint( "Total cost:",total_Cost )Total cost: 1230The same program, tidied:
rent = 900food = 250transport = 80total_cost = rent + food + transportprint("Total cost:", total_cost)Total cost: 1230The two programs behave identically. The tidy one uses lowercase names consistently, puts one space on each side of = and +, and has no stray spaces inside the parentheses.
Common pitfalls
- Mixing tabs and spaces. Python rejects it with a
TabError. Use spaces only. - Inconsistent indentation within a block. Three spaces on one line and four on the next is an
IndentationError. - Comments that go stale. If you change the code, change the comment.
- A colon forgotten at the end of a block line. The error is a
SyntaxErrorpointing at the line.
Rewrite this script following PEP 8: lowercase names, spaces around operators and =, and no stray spaces inside the parentheses. The behaviour must not change.
Input: none. Expected output: Total: 12.
Price=4Count =3TOTAL_price=Price*Countprint( "Total:",TOTAL_price )Total: 12Show solution
price = 4count = 3total_price = price * countprint("Total:", total_price)Total: 12Changing names and whitespace never changes what the program does, only how easy it is to read.
This comment only repeats the code. Rewrite the script so that the variable name explains the number and no comment is needed.
Input: none. Expected output: 86400.
x = 60 * 60 * 24 # multiply 60 by 60 by 24print(x)86400Show solution
seconds_per_day = 60 * 60 * 24print(seconds_per_day)86400The name seconds_per_day says what the number means, which the comment never did. When a good name can carry the meaning, you do not need a comment.
Summary
- Indentation is syntax: four spaces per block, never mixed with tabs.
#comments should explain why.snake_casefor names andUPPER_SNAKE_CASEfor constants.- A formatter such as ruff applies PEP 8 for you.
Next: the built-in types behind every value.