Kihagyás

Code-Level Documentation: inline comments, docstrings, and code blocks

Discuss the following examples of code comments and clean code practices. For each example, consider the questions provided and reflect on the lessons learned.

0) Opening contrast

code

1
a[b[c[d]]] != 0xabc42137 // quick sort

questions

  • What does the code actually do, and what does the comment claim?
  • Which facts are missing that no reader (or compiler) can infer?
lessons
  • Code shows how; comments must record why and assumptions.
  • A wrong comment is worse than none.

1) Hidden context: origin, units, IDs (medical dispenser)

code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class Dispenser:
    def set_patient_frame(self, landmarks_mm: dict) -> None:
        """Calibrate patient-relative frame from optical markers (mm)."""

    def move_toolhead_mm(self, target_mm: tuple[float, float, float]) -> None:
        """Move in PATIENT frame (mm)."""

    def normalize_drug_label(label: str) -> str:
        """Lowercase, strip diacritics/whitespace, map brand↔generic via formulary."""

    def verify_global_ids(insurance_id: str, rx_id: str, country: str) -> None:
        """Cross-country registry checks; rx_id must be globally unique."""

questions

  • What breaks if a move is issued in machine frame but assumed patient frame?
  • Are units in names (*_mm) clearer than only in comments?
  • How does normalization prevent a incorrect drug due to casing/locale?
  • Why isn’t clinic-local uniqueness enough for rx_id?
lessons
  • Comments should clarify real-world context that code can’t fully imply (frames, units, identity scope).
  • Prefer self-explanatory names/types/APIs (e.g., *_mm, set_patient_frame) to make context visible in code; add brief comments only where names can’t carry it.
  • When naming would be awkward or incomplete (multi-unit/multi-frame, cross-border IDs), keep a short “why” at the boundary to lock intent.

2) Names and types are documentation

code

1
2
def find_index(xs: tuple[int], needle: int) -> int | None:
    ...

questions

  • What did we learn from the new name and int | None?
  • What is the promise expressed by requiring tuple[int] instead of list[int]?
  • None vs -1: which forces safer caller behavior?
lessons
  • Good names and types reduce guesswork and bad comments.
  • Types encode expectations the machine can check.

3) Comment the why, not the what

code

1
2
3
4
# BAD
i = i + 1  # increment i
if i >= 5: # too many retries
    abort() # abort
1
2
3
4
5
# BETTER
MAX_RETRIES = 5
retry_count += 1  # cap to avoid hammering a flaky provider
if retry_count >= MAX_RETRIES:
    abort()

questions

  • What new information appears in the “better” version?
lessons
  • Narration is noise; rationale is value.
  • Pair named constructs with a short “why” to explain intent.

4) Docstrings as use-contracts

code

1
2
3
4
5
6
7
def smooth(samples: list[float], window_s: float) -> list[float]:
    """
    Purpose: UI-only jitter reduction (not for analytics).
    Units: window_s in seconds.
    Edge cases: preserve spikes <0.05s to keep clicks responsive.
    """
    ...

questions

  • Which misuse does this docstring prevent?
  • What must always be in a contract: purpose, units, edge cases?
  • Is this format the best way to express it?
lessons
  • Docstrings define how to use, not internals.
  • State purpose, units, and boundaries to lock intent in place.

Here’s the refactored “comment rot” block in your strict rhythm (code → questions → lessons), short and to the point.

5) Commented-out code rot (use VCS instead)

code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# BEFORE — left “just in case”
# def legacy_dose(weight_kg, drug):
#     # old calc kept for reference
#     return (weight_kg * 0.8) if drug == "x" else (weight_kg * 0.6)
# TODO: remove after rollout
def dose(weight_kg: float, drug: str) -> float:
    return new_protocol_dose(weight_kg, drug)

# Tests guard against reintroduction
def test_no_legacy_symbol():
    import mymod
    assert not hasattr(mymod, "legacy_dose")

questions

  • Who will notice if the commented code becomes wrong after future changes?
  • Will the compiler/interpreter/IDE ever validate commented code or its variables?
  • How can comments drift from the original location?
  • Where should the “why we removed it” live if not in the file?
lessons
  • Nobody maintains commented-out code; it silently rots.
  • Tooling (compiler/interpreter/IDE) doesn’t check comments.
  • Comments drift while code evolves; names and dependencies change underneath.
  • Use version control to preserve history and rationale; keep the source clean and up-to-date.