Code that works but cannot be understood loses marks, and in the workplace it loses time. This guide shows what good comments explain, how to write docstrings and header comments, what belongs in a README, and how to document code the way markers and teams expect.
Most programming rubrics award marks for readability and documentation, often 10 to 20 percent of the grade. Markers read dozens of submissions, and they reward code they can follow quickly. Beyond grades, documentation is a professional habit: the next person to read your code, including you in six months, needs to understand what it does and why.
Good documentation does not mean more comments. It means the right comments in the right places, clear names that reduce the need for comments, and a short written explanation of how to run and understand the program.
The code already says what it does, line by line. Comments should explain what the code cannot: intent, reasoning and context.
| Comment type | Explains | Example |
|---|---|---|
| Why | The reason behind a decision | # Sort first so binary search can be used below |
| Intent | The purpose of a block | # Remove duplicate student IDs before calculating averages |
| Assumptions | Conditions the code relies on | # Assumes the input list is non-empty |
| Non-obvious logic | Tricky algorithms or formulas | # Use (low + high) // 2 avoids float indices |
| Warnings | Limitations or edge cases | # Not thread-safe; call from the main thread only |
The test: if deleting a comment would lose no information that the code itself does not already show, the comment is noise. "i = i + 1 # add one to i" is the classic example.
def calc(l, t):
r = []
for x in l:
if x[1] >= t:
r.append(x[0])
return r
def calc(l, t):
r = [] # make an empty list
for x in l: # loop over l
if x[1] >= t: # check if x[1] is at least t
r.append(x[0]) # add x[0] to r
return r # return r
def students_meeting_threshold(scores, threshold):
"""Return the names of students whose score meets the threshold.
Args:
scores: list of (name, score) tuples.
threshold: minimum passing score, inclusive.
Returns:
List of names, in the original order.
"""
return [name for name, score in scores if score >= threshold]
The improved version needs almost no inline comments because the names explain themselves, and the docstring tells a caller exactly what to pass in and what comes back.
total_price, not tp; is_valid_email(), not check().has_children, is_empty).MAX_ATTEMPTS = 3 rather than a bare 3.i in a small loop.When you find yourself writing a long comment to explain what a block does, consider extracting that block into its own function with a descriptive name. A call such as remove_duplicate_ids(records) documents itself, can be tested on its own and keeps the calling function short enough to read at a glance. Markers often reward this kind of decomposition under both readability and design criteria.
Every public function, method and class should have a documentation comment describing its purpose, parameters, return value and any errors it raises.
| Language | Convention | Format |
|---|---|---|
| Python | Docstrings (PEP 257), often Google or NumPy style | Triple-quoted string as the first line of the function |
| Java | Javadoc | /** ... */ with @param, @return, @throws |
| JavaScript / TypeScript | JSDoc | /** ... */ with @param {type} and @returns |
| C / C++ | Doxygen-style comments | /** ... */ or /// with @brief, @param, @return |
| C# | XML documentation comments | /// <summary> ... </summary> |
/**
* Calculates the monthly repayment on a fixed-rate loan.
*
* @param principal amount borrowed, must be positive
* @param annualRate interest rate as a decimal, e.g. 0.05 for 5%
* @param months loan term in months
* @return the monthly repayment, rounded to two decimal places
* @throws IllegalArgumentException if any argument is not positive
*/
public static double monthlyRepayment(double principal, double annualRate, int months)
We deliver working, well-documented code with clear comments and a README, in the language your course uses.
Many courses require a header at the top of each source file. Check your course's template; a typical header includes:
# File: inventory.py
# Author: [Your name], [Student ID]
# Course: CS 101, Assignment 3
# Date: 2026-10-07
# Description: Manages a store inventory, supporting adding, removing
# and searching for items, and reporting low stock.
Some courses also ask you to declare any outside resources or collaborators in this header. Follow your institution's academic integrity rules exactly.
For multi-file projects, a README file explains the project to someone who has never seen it. Markers often read it first.
Tests are documentation too: a well-named test shows exactly how a function is meant to behave. Name each test after the behaviour it checks, such as test_returns_empty_list_when_no_scores_meet_threshold, and group related tests together. For edge cases, a one-line comment explaining why the case matters, such as "a threshold equal to a score should count as a pass", helps markers see that you thought about boundaries. Where your course does not require a testing framework, a short section in the README listing the inputs you tried and the outputs you expected still demonstrates careful work.
| Language | Single line | Block |
|---|---|---|
| Python | # comment | Consecutive # lines (docstrings are for documentation, not block comments) |
| Java, C, C++, C#, JavaScript | // comment | /* comment */ |
| R | # comment | Consecutive # lines; roxygen2 uses #' |
| MATLAB | % comment | %{ ... %} |
| SQL | -- comment | /* comment */ |
In MATLAB, the first comment lines of a function file act as its help text, shown when someone types help functionName, so write them as a proper summary of inputs and outputs.
There is no fixed ratio. Document every function and class, and add inline comments where the reasoning is not obvious. Clear names reduce how many inline comments you need.
In Python, a comment starts with # and is ignored by the interpreter. A docstring is a string literal at the start of a function, class or module that is stored with it and can be read by help() and documentation tools.
No. Line-by-line comments usually repeat the code and make it harder to read. Comment blocks of logic, decisions and anything non-obvious.
No. Comments are ignored when the program runs, so they have no effect on speed in compiled or interpreted languages.