Comments, indentation and style

Beginner20 min

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:

style_demo.py
# 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)
Output
Everyone fits.
Spare seats: 1

The 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 1

An 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 3

This one explains a decision that the code cannot show:

guests = 3 # people who said yes, not counting the host

Do not leave dead code commented out. Version control remembers old versions for you.

Naming conventions

Python’s style guide, PEP 8, asks for:

  • snake_case for variables and functions: total_cost, birth_year.
  • UPPER_SNAKE_CASE for constants: MAX_SEATS.
  • PascalCase for classes, which arrive in the intermediate course.
  • Names that say what they hold. guests beats g.

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.

Terminal window
ruff format messy_script.py
ruff check messy_script.py

Installing 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.

messy_script.py
Rent=900
food = 250
Transport= 80
total_Cost=Rent+food+Transport
print( "Total cost:",total_Cost )
Output
Total cost: 1230

The same program, tidied:

tidy_script.py
rent = 900
food = 250
transport = 80
total_cost = rent + food + transport
print("Total cost:", total_cost)
Output
Total cost: 1230

The 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 SyntaxError pointing at the line.
ExerciseTidy a messy script

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.

messy_price.py
Price=4
Count =3
TOTAL_price=Price*Count
print( "Total:",TOTAL_price )
Output
Total: 12
Show solution
tidy_price.py
price = 4
count = 3
total_price = price * count
print("Total:", total_price)
Output
Total: 12

Changing names and whitespace never changes what the program does, only how easy it is to read.

ExerciseReplace a comment with a name

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.

seconds_comment.py
x = 60 * 60 * 24 # multiply 60 by 60 by 24
print(x)
Output
86400
Show solution
seconds_named.py
seconds_per_day = 60 * 60 * 24
print(seconds_per_day)
Output
86400

The 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_case for names and UPPER_SNAKE_CASE for constants.
  • A formatter such as ruff applies PEP 8 for you.

Next: the built-in types behind every value.