Imagine you wrote a Python program for your school's library system three weeks ago. It calculates late-return fines, and it worked perfectly the day you wrote it — you tested it, got the right answers, and moved on to something else. Today your teacher asks you to add a new rule: students with a library card issued this year get a 50% discount on fines. You open the file to make the change.
You stare at it. There's a function called calc. It takes a parameter called d. Inside, there's an if, an elif, a multiplication by 2, another multiplication by 5, and a subtraction of 7 from something. You wrote every single line of this. You understood it completely three weeks ago. And right now, you cannot tell — without running it in your head line by line, slowly, like a stranger — what any of it actually does.
This is not a rare accident. It is one of the most universal experiences in programming, and it happens to professional software engineers with twenty years of experience just as often as it happens to a Grade 8 student. The code did not become wrong. It became unreadable — to the very person who wrote it. The gap between "code that works" and "code that anyone (including future-you) can understand and safely change" is exactly the problem that documentation exists to solve.
What Documentation Actually Is
Documentation is any writing, separate from the pure logic of a program, whose only job is to explain that program to a human being. It is not part of what the computer executes — a computer does not need documentation, it only needs correct instructions. Documentation exists purely for people: the programmer who wrote the code, the teammate who has to extend it, the user who has to run it, or the same programmer returning to it after time has passed.
This is worth stating precisely because students often confuse "documentation" with "code that is easy to read." They are related but not the same thing. Documentation is extra information layered on top of the code — comments, descriptions, explanations — that would not exist if you deleted every human-facing sentence and kept only the instructions the computer needs to run.
The Four Zoom Levels of Documentation
Not all documentation lives at the same distance from the code, and mixing these up is a common source of confusion. A single project usually has documentation at four different "zoom levels," each answering a different question for a different reader.
A comment explains one line to the person editing that line. A docstring explains one function to anyone who wants to call it without reading its insides. A README explains an entire project folder to anyone who downloads it. A user manual explains a finished app to someone who will never see a single line of code. Confusing these levels — for example, writing a paragraph of app-usage instructions as a comment buried inside a function — means the right reader will never find the information they need.
Comments: Explaining Why, Not What
Let's go back to the library fine problem and write it properly. In Python, a single-line comment starts with #, and everything after it on that line is ignored by the computer — it exists only for the human reader.
Here is the original, undocumented version:
def calc(d):
if d <= 0:
return 0
elif d <= 7:
return d * 2
else:
return 7 * 2 + (d - 7) * 5
Now here is a very common — and mistaken — idea of what "adding documentation" means: describing, in English, exactly what each line already says.
def calc(d):
if d <= 0: # if d is less than or equal to 0
return 0 # return 0
elif d <= 7: # else if d is less than or equal to 7
return d * 2 # return d times 2
else: # otherwise
return 7 * 2 + (d - 7) * 5 # return this formula
This is a genuine misconception worth naming directly: a comment that only restates the code in English is not useful documentation. Anyone who can read the Python already knows that d * 2 multiplies d by 2 — the comment return d times 2 adds zero new information. Worse, when the code changes later and the comment doesn't, the comment becomes an active lie sitting next to correct code, which is more dangerous than no comment at all.
Good comments explain the reasoning that isn't visible in the code itself — the business rule, the assumption, the reason a particular number was chosen:
def calc(d):
if d <= 0:
return 0 # returned on time or early — library policy: no fine
elif d <= 7:
return d * 2 # first week grace period: Rs 2 per day late
else:
# after the first week, the fine rate increases to discourage
# very long overdue periods — Rs 2/day for days 1-7,
# then Rs 5/day for every day after that
return 7 * 2 + (d - 7) * 5
Now a reader instantly understands why the formula has two different rates, which is exactly the information you'd need three weeks later when asked to add a discount rule. The code says what happens; the comment says why it happens that way. That is the single most important rule in this entire chapter.
Naming: The Documentation You Don't Have to Write
Notice something about the comments above — they had to work hard to explain what d means, what calc calculates, and what the whole function is for, because the names themselves carry no meaning. d could be "days," "discount," or "distance." calc could calculate anything.
The best kind of documentation is the kind you don't need to write, because the code explains itself. This is called self-documenting code, and the cheapest way to achieve it is through meaningful names:
def calculate_fine(days_late):
if days_late <= 0:
return 0 # returned on time or early — no fine
elif days_late <= 7:
return days_late * 2 # first week grace period: Rs 2/day
else:
# Rs 2/day for the first week, then Rs 5/day after that
return 7 * 2 + (days_late - 7) * 5
Compare this to the very first version. The function name calculate_fine and the parameter name days_late tell a reader almost the whole story before they read a single comment. This does not mean you should stop writing comments — good names explain what something represents, but they still cannot explain why a particular number like 7 or 5 was chosen. Names and comments do different jobs, and strong code uses both.
Docstrings: Documentation a Function Carries With It
A regular comment sits beside a line. A docstring is a special kind of comment in Python, written as a triple-quoted string immediately below a function's definition line, that documents the entire function as a unit — its purpose, its inputs, its output, and often a worked example. Unlike an ordinary comment, a docstring is stored by Python as part of the function itself, which is why tools and code editors can pop it up automatically when someone tries to use that function.
Here is the fully documented, final version of our library fine function:
def calculate_fine(days_late):
"""
Calculate the library fine for a late book return.
Fine structure:
- No fine for on-time or early returns (days_late <= 0)
- Rs 2 per day for the first 7 days late
- Rs 5 per day for every day beyond the first 7
Parameters:
days_late (int): number of days the book is overdue.
Zero or a negative number means it was
returned on time.
Returns:
int: the total fine, in rupees.
Example:
>>> calculate_fine(10)
29
"""
if days_late <= 0:
return 0 # returned on time or early — no fine
elif days_late <= 7:
return days_late * 2 # first week grace period: Rs 2/day
else:
# Rs 2/day for the first week, then Rs 5/day after that
return 7 * 2 + (days_late - 7) * 5
Let's trace the example the docstring promises, exactly the way an examiner or a teammate would verify it before trusting the documentation. Call calculate_fine(10). Since 10 is not <= 0, the first branch is skipped. Since 10 is not <= 7 either, the second branch is skipped. Python runs the else branch: 7 * 2 is 14 (the fine for the first 7 days at Rs 2 each), and (10 - 7) * 5 is 3 * 5 = 15 (the fine for the remaining 3 days at Rs 5 each). Adding them, 14 + 15 = 29. The function returns 29, which exactly matches the docstring's example output. A docstring that promises an output the code doesn't actually produce is worse than no docstring — it actively misleads the next reader, so this checking step is not optional.
A well-written docstring for a function you're documenting for others generally answers four questions in this order: what does it do, what does it need (parameters), what does it give back (return value), and can you show me it working (an example). You will not need every one of these for a tiny two-line function, but for anything another person will call without reading the insides, all four make the function trustworthy to use as a "black box."
The README: Documenting a Whole Project
Once a program grows past a single function — say, a full library-management project with several files — comments and docstrings are no longer enough, because nobody can find them without already having opened the right file. This is what a README is for: a plain-text file, conventionally named README.md or README.txt, placed at the very top of a project folder, that a person reads before they read any code at all.
# Library Fine Calculator
A small Python program that calculates late-return fines
for a school library based on days overdue.
## How to run
python fine_calculator.py
## Example
Input: 10 days late
Output: Fine = Rs 29
## Rules
- Rs 2 per day for the first 7 late days
- Rs 5 per day for every day after that
Notice what this README does not do — it doesn't explain the code line by line, because that's the comments' job. It answers the three questions someone asks in the first ten seconds of opening a project: what is this, how do I run it, and what should it do when it works correctly. Every serious software project — from a two-file school assignment to a large open-source library used by millions of people — starts with exactly this kind of file, because without it, a working program is often useless to anyone except the person who wrote it.
Why This Matters Beyond the Classroom
Documentation stops being a "nice to have" the moment more than one person, or more than one point in time, touches the same code. In India, the National Payments Corporation of India (NPCI) publishes detailed technical specifications describing exactly how the UPI payment system works. Every bank and every payment app — whichever apps you or your family use to send money — has to follow that published documentation precisely when connecting to UPI. Nobody at those companies is guessing how the system behaves; they are reading the documentation and building to match it exactly. A misunderstood detail in that kind of specification is not a cosmetic bug — it is the difference between a payment completing correctly and money being deducted without the transfer finishing.
At a much smaller scale, this is also why CBSE practical examinations for computer science expect your programs to include comments explaining your logic, not just correct output. An examiner reading your practical file is doing exactly what your future self does three weeks after writing a program: trying to understand a stranger's code quickly, using only what that stranger chose to write down.
Common Pitfalls to Avoid
Beyond the "comments that just restate the code" misconception already covered, two more habits quietly ruin documentation. The first is stale documentation: a comment or docstring that was accurate when written but was never updated when the code changed. A docstring claiming calculate_fine(10) returns 29 next to code that has since been edited to charge Rs 3 per day instead of Rs 2 is actively worse than having no docstring, because a reader will trust it and be wrong. Whenever you change what code does, updating its documentation is not a separate, optional step — it's part of finishing the change.
The second is over-commenting: adding a comment to every single line regardless of whether it needs one, which buries the genuinely useful comments in noise and makes the file longer without making it clearer. Reserve comments for the lines where the "why" isn't obvious from good naming alone — a clearly named variable like days_late in a simple comparison like if days_late <= 0: rarely needs a comment explaining that it checks whether the book is overdue; that line already says so.
Summary
- Documentation is writing, separate from the code's own logic, whose only purpose is to help a human understand a program — it doesn't affect what the computer executes.
- Documentation exists at four zoom levels: inline comments (one line), docstrings (one function), README files (one project), and user manuals (the finished app) — each written for a different reader.
- A useful comment explains why the code does something, not what it does — restating the code in English adds no information and can go stale into a lie.
- Meaningful names (
calculate_fine,days_late) are self-documenting and reduce how many comments you need to write in the first place. - A Python docstring is a triple-quoted string attached to a function that typically states its purpose, its parameters, its return value, and a worked example — and that example must be checked against the real output, not just assumed.
- A README documents an entire project for a reader who hasn't opened any code yet, answering "what is this" and "how do I run it."
- Stale documentation (accurate once, never updated) is more dangerous than no documentation, because it is trusted and wrong.
Try This Yourself
- Here is an undocumented function:
def f(p, r, t): return p * r * t / 100. It calculates simple interest. Rewrite it with a meaningful function name, meaningful parameter names, and a docstring with a worked example (use p = 1000, r = 5, t = 2, and calculate the correct output by hand first). - Explain, in your own words, why a comment reading
# adds 1 to countabove the linecount = count + 1is poor documentation, and rewrite it as a comment that would actually be useful. - You update
calculate_finefrom this chapter so that the grace-period rate changes from Rs 2/day to Rs 3/day. List every place in the code — including the docstring — that must now be updated so nothing goes stale. - Write a four-line README for a program you've written recently in class, following the "what is this / how do I run it / example / rules" structure used in this chapter.
Practice Exercises
Now it is time to practice! Complete these challenges to solidify your understanding:
- Exercise 1: Write a short program that demonstrates the core concept from this chapter. Test it with at least 3 different inputs.
- Exercise 2: Find a real-world example where documentation is used in an Indian company (like TCS, Infosys, Flipkart, or ISRO). Write a paragraph explaining the connection.
- Exercise 3: Create a mind-map connecting documentation to at least 3 other topics you have studied.