FreeCampus Python

Comments and Docstrings That Help

Write comments and introductory docstrings that explain purpose, units, constraints, and decisions without merely translating the code.
python-foundations python-syntax comments docstrings
Open in Colab
  • Level: Beginner
  • Estimated time: 2–3 hours
  • You will learn: Distinguish comments from docstrings and executable strings, then document decisions in a way that remains useful when code changes.
  • Practice in: Google Colab, JupyterLab, or a local editor

Python code has two audiences. Python needs exact syntax. People need purpose, context, units, assumptions, and reasons. Clear names and structure should carry most of the explanation; comments and docstrings fill the gaps that code alone cannot express.

NoteQuestions you will answer
  1. What information belongs in a comment rather than in a name?
  2. How is a docstring different from a # comment?
  3. When does Python make a docstring discoverable through help()?
  4. Why can an outdated comment be more dangerous than no comment?

1. Comments speak to people reading the source

A # begins a comment outside a string. Python ignores the comment from that point to the end of the physical line.

# Session lengths are measured in minutes.
session_minutes = 45
print(session_minutes)

The output is 45. The comment does not create a value, perform assignment, or become part of the output.

A comment can follow code:

break_minutes = 10  # Includes time to leave and return to the room.

Python performs the assignment and ignores the comment.

The # character inside a string is ordinary text:

message = "Complete lesson #1"
print(message)

Expected output:

Complete lesson #1

Quotation marks determine that #1 belongs to the string rather than starting a comment.

Remove a comment and compare behavior

Run:

# Keep the named stages so each cost can be checked.
room_cost = 120
materials_cost = 80
event_total = room_cost + materials_cost
print(event_total)

Then remove only the comment and rerun. The output stays 200. A normal comment does not change program behavior.

This makes comments useful for explanation, but unsuitable for disabling important logic without careful review.

2. Prefer comments that explain why

This comment merely translates visible syntax:

# Add room_cost and materials_cost.
event_total = room_cost + materials_cost

Anyone who recognizes + can read that. It adds maintenance work without adding knowledge.

This comment supplies context that the expression cannot:

# The venue invoice includes equipment, so do not add it a second time.
event_total = room_cost + materials_cost

Useful comments often explain:

  • why a non-obvious rule exists;
  • which unit a number uses;
  • where a requirement or constraint came from;
  • why an apparently simpler approach is unsafe;
  • what a temporary workaround is waiting for;
  • what a surprising boundary means.

Put meaning in names first

Weak:

m = 45  # minutes
b = 10  # break
r = m - b  # remaining focused time

Stronger:

session_minutes = 45
break_minutes = 10
focused_minutes = session_minutes - break_minutes

The stronger version does not require three comments because the names carry the meaning.

A comment can still add a domain rule:

# Break time is excluded because the report measures active instruction.
focused_minutes = session_minutes - break_minutes
TipUse this order

First improve the names and structure. Then add a comment only for important information that still is not visible.

3. Place comments where readers need them

A full-line comment introduces a decision

ticket_income = 336

# The grant is paid directly to the venue, so it reduces costs rather than income.
venue_cost = 150 - 50
balance = ticket_income - venue_cost

print(balance)

The comment sits immediately above the decision it explains.

An inline comment labels a compact fact

grace_period_seconds = 30  # Required by the device protocol.

Inline comments work best when both the code and explanation remain short. Avoid pushing a long paragraph to the right of a long expression.

A short comment can divide a small script

# Inputs
room_cost = 120
materials_cost = 80

# Calculations
event_total = room_cost + materials_cost

# Output
print("Total:", event_total)

Section comments can help in a small educational script. In larger programs, functions and modules become better structural tools.

Too many comments interrupt reading

Avoid narrating every line:

# Set the price to 12.
ticket_price = 12

# Set the count to 3.
ticket_count = 3

# Multiply price by count.
ticket_total = ticket_price * ticket_count

# Print the total.
print(ticket_total)

The code already tells that story. A single relevant comment may be enough:

ticket_price = 12
ticket_count = 3

# Service fees are already included in the advertised ticket price.
ticket_total = ticket_price * ticket_count
print(ticket_total)

Check your understanding

4. Comments must change when the code changes

An outdated comment lies:

# Give a 10 percent discount.
discount_rate = 0.20

Python uses 0.20; it ignores the conflicting comment. A reader may trust the wrong explanation and make a bad decision later.

Possible repairs depend on the real requirement:

# Give a 20 percent discount during the community event.
discount_rate = 0.20

or:

# Give the standard 10 percent discount.
discount_rate = 0.10

The absence of a syntax error does not decide which requirement is correct.

Review comments as part of every behavior change

Suppose the first version excludes breaks:

# Report active time, excluding breaks.
reported_minutes = session_minutes - break_minutes

A later requirement includes the entire scheduled time:

reported_minutes = session_minutes

The old comment must be removed or rewritten. Comments are part of the product even though Python does not execute them.

Temporary comments need an owner or condition

Vague:

# TODO: fix this later
display_minutes = session_minutes

Useful:

# TODO: include break_minutes after the schedule form collects it.
display_minutes = session_minutes

The second comment states what is missing and what condition allows the work to continue. A real project may also include an issue reference or owner.

Do not use TODO to avoid finishing a requirement that the current lesson or challenge expects.

5. A docstring documents a surrounding object

A docstring is a string literal placed as the first statement in a module, function, class, or method body. Python records it as that object’s documentation.

At the top of a Python file or first code cell:

"""Calculate and display a community workshop budget."""

room_cost = 120
materials_cost = 80
event_total = room_cost + materials_cost

print(event_total)

The opening string is the module docstring because it is the first statement.

A comment and module docstring have different jobs:

"""Summarize one workshop budget."""

# The venue invoice already includes equipment rental.
room_cost = 120
materials_cost = 80
event_total = room_cost + materials_cost
  • The docstring identifies the module’s overall purpose.
  • The comment explains one local domain decision.
  • The assignments perform the calculation.

A random triple-quoted string is not automatically a docstring

course = "Python Foundations"
"""This string appears after executable code."""

The triple-quoted text creates a string value, but it is not the module’s docstring because another statement came first.

Triple quotes allow multiline strings. Position, not triple-quote spelling alone, gives a string its docstring role.

Inspect the current module docstring

In a notebook cell, run:

"""Explore module documentation."""

print(__doc__)

Many notebook environments expose the cell or interactive module documentation differently, so the exact surrounding value can vary. The reliable language rule is that a module’s first string statement becomes its __doc__ value when the module is loaded.

A .py file makes this easiest to observe:

"""Calculate a study-session summary."""

course = "Python Foundations"
minutes = 45

print(__doc__)

6. Function and class docstrings are previews

Functions are introduced fully in Unit 5. For now, read the placement:

def focused_time(session_minutes, break_minutes):
    """Return active study minutes after subtracting a break."""
    return session_minutes - break_minutes

The levels are:

  1. def ...: opens the function body.
  2. The indented string is the first body statement, so it becomes the function docstring.
  3. The indented return provides the function’s behavior.

Move an assignment above the string:

def focused_time(session_minutes, break_minutes):
    active_minutes = session_minutes - break_minutes
    """Return active study minutes after subtracting a break."""
    return active_minutes

The string is now an unused expression inside the function, not its docstring. The code is syntactically valid, but documentation discovery changes.

A class follows the same position rule:

class StudySession:
    """Represent one planned study session."""

    pass

You do not need to design classes yet. Recognize the class header, indented body, first string, and placeholder pass.

NoteDocstrings describe a public promise

A useful introductory docstring says what the module, function, or class provides. Detailed parameter formats, exceptions, examples, documentation toolchains, and publishing belong to Unit 15.

7. help() makes docstrings discoverable

Run:

def focused_time(session_minutes, break_minutes):
    """Return active study minutes after subtracting a break."""
    return session_minutes - break_minutes


help(focused_time)

The output includes the function’s name, signature, and docstring.

You can also inspect the recorded text directly:

print(focused_time.__doc__)

The dot selects the __doc__ attribute. Attribute and method syntax receive more attention in later units; here it shows that docstrings are data Python preserves, not comments Python discards.

Compare with a comment-only function

def focused_time(session_minutes, break_minutes):
    # Return active minutes after subtracting the break.
    return session_minutes - break_minutes


print(focused_time.__doc__)

The output is None because a # comment is not recorded as a docstring.

Check your understanding

8. Write a small docstring with a clear promise

For a module, begin with one direct sentence:

"""Calculate attendance and cost summaries for one workshop."""

For a simple function preview:

def material_cost(learner_count, cost_per_learner):
    """Return the total material cost for all learners."""
    return learner_count * cost_per_learner

Prefer a verb that describes the result or action:

  • Return ...
  • Calculate ...
  • Load ...
  • Display ...
  • Represent ...

Avoid empty wording:

def material_cost(learner_count, cost_per_learner):
    """This is the material_cost function."""
    return learner_count * cost_per_learner

The weak docstring repeats the name and says nothing about the result.

Document units and boundaries when they matter

def focused_minutes(session_minutes, break_minutes):
    """Return active minutes; both inputs are measured in whole minutes."""
    return session_minutes - break_minutes

This is more useful because a caller can distinguish minutes from seconds and knows what “focused” excludes.

Do not promise validation or error handling the function does not provide. A docstring must match actual behavior.

9. Review good and harmful explanations

Example A

# Multiply by 60.
duration_seconds = duration_minutes * 60

The comment repeats the operator but not the reason. Improve it:

# The device API accepts seconds, while the form collects minutes.
duration_seconds = duration_minutes * 60

Example B

# Never change this.
grace_period = 30

“Never” has no context. Improve it:

# The access controller requires a 30-second grace period.
grace_period_seconds = 30

Example C

"""Do stuff."""

room_cost = 120
materials_cost = 80
print(room_cost + materials_cost)

Improve the module docstring:

"""Calculate the base cost of one community workshop."""

room_cost = 120
materials_cost = 80
print(room_cost + materials_cost)

Example D

# Total is price times quantity.
total = price * quantity

Remove the comment. The names and expression already explain the line.

10. Prepare a program for a classmate

Start with:

c = "Python Foundations"
m = 45
b = 10
f = m - b
print(c, f)

The behavior is small, but the program lacks context. Revise it so that:

  1. a module docstring states the program’s purpose;
  2. names express course, scheduled time, break time, and focused time;
  3. one comment explains why break time is excluded;
  4. no comment merely translates an assignment;
  5. output labels identify both displayed values;
  6. the result remains 35 focused minutes;
  7. changing scheduled time to 60 requires changing only one input assignment.

Then give only the revised source to another person. Ask them:

  • What unit is time measured in?
  • Why is the break subtracted?
  • Which value should they edit for a longer session?
  • What output should appear for a 60-minute session?

If the code and documentation do not answer those questions, revise them.

Hint: let names carry the basic story

Use names such as course_name, session_minutes, break_minutes, and focused_minutes. Reserve the comment for the reporting rule that excludes the break.

Show one documented version
"""Display the active study time for one planned course session."""

course_name = "Python Foundations"
session_minutes = 45
break_minutes = 10

# The study report measures active work, so scheduled breaks are excluded.
focused_minutes = session_minutes - break_minutes

print("Course:", course_name)
print("Focused minutes:", focused_minutes)

assert focused_minutes == 35

11. Find documentation drift

Run this first version:

"""Calculate the cost after a standard 10 percent discount."""

subtotal = 200
discount_rate = 0.10
discount = subtotal * discount_rate
final_total = subtotal - discount

print(final_total)

Now imagine the event discount changes to 20 percent. Change only the numeric value and observe that the code runs while the docstring becomes false.

Your repair must update both behavior and documentation:

"""Calculate the cost after the current event discount."""

subtotal = 200
discount_rate = 0.20
discount = subtotal * discount_rate
final_total = subtotal - discount

print(final_total)

The revised docstring avoids duplicating a value that already has a clear name. Another valid choice is to retain “20 percent” and commit to updating it whenever the rule changes. Decide which promise will be safer for the next reader.

12. Check the next-reader experience

Key points

TipKey points
  • A # comment is ignored by Python outside a string.
  • Clear names and structure should explain ordinary mechanics.
  • Useful comments record purpose, units, constraints, and non-obvious decisions.
  • Comments must be updated when the behavior or requirement changes.
  • A docstring is a string in the first statement position of a module, function, class, or method.
  • Triple quotes alone do not make a string a docstring.
  • help() and .__doc__ expose recorded docstrings.
  • Documentation should promise only behavior the code actually provides.

References

Back to top