Module 1 · Foundations of Programming ⏱ 18 min

Comments & Code Readability

By the end of this lesson you will be able to:
  • Write an inline comment and a multi-line block comment using #
  • Explain that comments are ignored by Python and exist for human readers
  • Distinguish a useful comment (the why) from a noisy one (restating the code)
  • Write a docstring that documents what a function is for

A comment is a note that Python completely ignores. Put a # anywhere on a line, and everything from there to the end of the line is for humans, not the computer:

print("Hi")   # this part is a comment

Comments do not change what a program does — not one bit. Their job is to leave clues for the next person who reads the code, and that person is very often you, six months later, trying to remember why you wrote something the way you did. Good comments are the difference between code you can return to and code you have to re-learn from scratch.

flowchart LR
  L["print(result)"] --> R["runs"]
  C["a comment"] --> S["skipped by Python"]
  style L fill:#3776ab,color:#fff
  style C fill:#9aa4af,color:#fff
Real code runs; comments are skipped by Python entirely.

Two places to put a comment

An inline comment sits at the end of a line of code, explaining that one statement. A block comment is several # lines stacked together to introduce a whole section:

# Convert a temperature from Celsius to Fahrenheit.
# Uses the standard formula: F = C * 9/5 + 32
celsius = 25
fahrenheit = celsius * 9 / 5 + 32
print(celsius, "C is", fahrenheit, "F")

Block comments suit a chunk of logic that needs context; inline comments suit a single line that would otherwise raise a question. Use both sparingly — a comment earns its place only when it says something the code cannot.

A program with a block comment and an inline comment — it still runs normally.
# Convert Celsius to Fahrenheit
celsius = 25
fahrenheit = celsius * 9 / 5 + 32   # the standard formula
print(celsius, "C is", fahrenheit, "F")

Explain the why, not the what

The single most important rule: a comment should explain why, not restate what. The code already shows what it does — that is its job. A comment that merely repeats it adds noise:

count = count + 1   # add one to count     <- says nothing new
count = count + 1   # retry counter for flaky API   <- now we're talking

The second comment is worth keeping because it captures an intent — this counter exists because the API is unreliable — that no reader could recover from count = count + 1 alone. That is the bar: would a future reader understand the code better with this line? If not, delete it.

flowchart LR
  G["good comment: explains the why"] --> OK["keep it"]
  Bp["bad comment: restates the code"] --> CUT["delete it"]
  Cl["clear, well-named code"] --> NONE["no comment needed"]
  style G fill:#3776ab,color:#fff
  style Bp fill:#b45309,color:#fff
  style Cl fill:#3776ab,color:#fff
Three outcomes for a line of code: a helpful comment, a redundant one, or none at all.

Comments rescue your future self

The comment that feels obvious today — why this loop starts at 1 instead of 0, why we round down here — is exactly the one you will wish existed when you come back cold, months later, with the original reasoning gone. Code shows what happens; a well-placed comment shows what was in the author's head.

A line of code answers how; a good comment answers why. The best notes capture things the source cannot carry: a hidden assumption, a constraint a user once hit, a pointer to the ticket that introduced the line. If reading the code alone leaves you guessing about the intent, that gap is precisely where a comment belongs.

flowchart TD
  Q{"is the code clear?"} -- "no" --> R["rename or rewrite first"]
  Q -- "yes" --> Q2{"does it hide a why?"}
  Q2 -- "yes" --> C["write a comment"]
  Q2 -- "no" --> N["leave it alone"]
  style C fill:#3776ab,color:#fff
  style N fill:#9aa4af,color:#fff
Decide per line: if the code is unclear, fix the code; if it hides a reason, comment it; otherwise leave it be.

Good names do the job of comments

Before reaching for a comment, ask whether a better name would make it unnecessary. A function called process(data) hides its purpose and demands a comment; the same code renamed remove_duplicates(rows) states its intent at every call site, for free. Names travel with the code everywhere it is used; a comment stays on one line and is easy to drift out of sync.

That is why experienced developers rename first and comment second. A clear name is a comment you never have to maintain, because it cannot fall out of step with the code it describes.

Docstrings: comments Python can read

Python has a special kind of comment called a docstring — a triple-quoted string placed immediately after a def or class line. Unlike a # comment, a docstring is stored on the object and tools can read it:

def area(width, height):
    """Return the area of a rectangle (width * height)."""
    return width * height

Now area.__doc__ holds that string, and editors, help systems, and documentation generators can display it. Use # for short in-file notes to yourself, and use a docstring when you are explaining what a function or class is for — that is the contract other code, and other people, will rely on.

The docstring is stored on the function as .__doc__ — tools and other code can read it.
def area(width, height):
    """Return the area of a rectangle (width * height)."""
    return width * height

print(area.__doc__)
print(area(3, 4))

Docstring conventions worth knowing

A docstring follows a few habits that make it useful to tools. It sits as the very first statement under the def or class line, wrapped in triple double-quotes. The first line is a short summary that fits on one row, and if you need more, a blank line separates that summary from a longer explanation.

Because the object keeps the docstring, calling help(area) prints it, and editors surface it as a hint wherever the function is used. That turns a quiet note into living documentation that travels with the code — quite different from a # comment, which nothing ever reads back.

A block comment introducing a section, plus a docstring documenting one function.
# Pricing helpers for the checkout flow.
# Keep all rounding in one place so rates stay consistent.

def final_price(base, tax_rate):
    """Return base price after applying a percentage tax_rate."""
    return base + base * tax_rate

print(final_price(100, 0.08))
Exercise

What does this print? Comments — even a whole commented-out line — are ignored by Python. Predict the exact output.

# This program greets a user
name = "Lin"   # set the name
# print("Hello, TEST")
print("Hello,", name)
Exercise

Which comment best explains the line tax = subtotal * 0.08?

Exercise

Write volume(width, height, depth) that returns the product of its three arguments and carries a docstring as its very first line describing what it returns.

def volume(width, height, depth):
    # add a docstring on the line below, then return the product
    pass
Exercise

You see the line x = x * 1.8 + 32 buried in a program. Which change makes it clearest for future readers?

Exercise

Write circle_area(radius) that returns the area of a circle (pi times radius squared, using 3.14159 for pi). Its very first line must be a docstring describing what it returns, and the docstring must contain the word area.

def circle_area(radius):
    # docstring first, then return the area
    pass

Recap

  • A # starts a comment; Python ignores everything after it on that line.
  • Use inline comments for one line, block comments (several # lines) for a section.
  • Aim to explain why a line exists, not what it does — the code already shows the what.
  • A docstring (triple-quoted, first line of a def or class) documents what something is for, and tools can read it.
  • When the code is clear, the best comment is none at all — rename a variable instead.

Next you will start organizing many lines of code into functions, where good names and docstrings do most of the explaining for you.

Checkpoint quiz

What character starts a Python comment?

Which is the BEST use of a comment?

How is a docstring different from a # comment?

Go deeper — technical resources