Professional Documentation Practices
๐ท๏ธ Functions / Docstrings
When you're starting out with Python, writing code that works is only half the battle. The other half is making sure other engineers (and your future self) can understand what your code does and how to use it. Professional documentation practices transform messy, confusing code into clean, maintainable, and shareable tools. This section covers the essential habits that separate hobby scripts from production-ready code.
๐ฏ Why Documentation Matters
- Saves time โ Well-documented code reduces the need for verbal explanations or digging through logic.
- Prevents errors โ Clear documentation helps other engineers use your functions correctly.
- Enables collaboration โ Teams can work on the same codebase without constant hand-holding.
- Supports maintenance โ When you revisit code months later, good docs remind you what you were thinking.
- Builds professionalism โ Documentation is a hallmark of reliable, production-grade engineering.
๐ The Three Levels of Documentation
Professional Python documentation operates at three distinct levels, each serving a different audience:
| Level | Purpose | Audience | Example |
|---|---|---|---|
| Inline Comments | Explain why a specific line or block exists | Yourself and code reviewers | A note explaining a workaround for a known bug |
| Docstrings | Describe what a function, class, or module does | Other engineers using your code | Parameters, return values, and usage notes |
| External Docs | Provide how to guides and context | End users or new team members | README files, wikis, or user manuals |
For most day-to-day work, mastering docstrings is the highest-impact skill.
โ๏ธ Docstring Basics
A docstring is a string literal that appears as the first statement in a function, class, or module. It's not a comment โ Python actually stores it as an attribute of the object, making it accessible programmatically.
- Single-line docstrings โ Use for very simple functions where one line says it all.
- Multi-line docstrings โ Use for anything more complex. Start with a summary line, then a blank line, then details.
A good docstring answers three questions: 1. What does this function do? 2. What inputs does it expect? 3. What does it return (or what side effect does it have)?
๐ ๏ธ Choosing a Docstring Style
There are several accepted formats. Pick one and stick with it across your entire project. Here are the three most common:
| Style | Best For | Key Feature |
|---|---|---|
| Google Style | Readability and simplicity | Uses section headers like Args, Returns, Raises |
| NumPy/SciPy Style | Scientific or data-heavy projects | Uses a more structured, visual format |
| reStructuredText (Sphinx) | Large projects needing auto-generated docs | Uses directives like :param: and :type: |
For most engineers starting out, Google Style is the easiest to read and write.
๐ต๏ธ Anatomy of a Google-Style Docstring
Here is the standard structure for a Google-style docstring:
- Summary line โ A single sentence describing what the function does. Ends with a period.
- Extended description โ Optional paragraph with more detail, separated by a blank line.
- Args section โ Lists each parameter, its type, and a brief description.
- Returns section โ Describes the return value and its type.
- Raises section โ Documents any exceptions the function might raise.
Each section uses a consistent format: - Section header followed by a colon - Indented bullet points or lines for each item - Type information in parentheses after the parameter name
๐ Common Docstring Patterns
Here are the patterns you will use most frequently:
For a simple function with parameters and a return value: - Summary line describing the action - Args section listing each parameter with its type and purpose - Returns section describing the output and its type
For a function that modifies data in place (no return): - Summary line describing the modification - Args section as usual - Returns section stating None, or omit it entirely
For a function that can raise errors: - Standard Args and Returns sections - Raises section listing each exception type and when it occurs
For a class: - Summary line describing the class purpose - Extended description if needed - Attributes section listing key instance variables
๐งช Practical Tips for Better Docstrings
- Write the docstring first โ It helps you clarify your thinking before writing the code.
- Be specific about types โ Use standard Python types (str, int, list, dict) or custom class names.
- Describe behavior, not implementation โ Focus on what the function does, not how it does it.
- Use active voice โ "Returns the sum of two numbers" is clearer than "The sum of two numbers is returned."
- Keep descriptions concise โ One or two sentences per parameter is usually enough.
- Document edge cases โ Mention what happens with empty inputs, None values, or boundary conditions.
๐ซ Common Docstring Mistakes to Avoid
- Writing obvious comments โ Don't restate what the code clearly shows. Focus on the why.
- Forgetting to update docstrings โ When you change code, update the docstring immediately.
- Using inconsistent style โ Mixing Google and NumPy styles in the same project creates confusion.
- Omitting the Raises section โ If your function can raise exceptions, document them.
- Writing overly long descriptions โ If a docstring is longer than the function itself, consider refactoring.
โ Final Checklist for Professional Documentation
Before considering your code complete, run through this checklist:
- [ ] Every public function has a docstring
- [ ] Every class has a docstring
- [ ] The module has a module-level docstring (at the top of the file)
- [ ] All parameters are documented with types and descriptions
- [ ] Return values are documented with types
- [ ] Exceptions are documented if applicable
- [ ] Docstrings follow a consistent style across the project
- [ ] Comments explain non-obvious logic (not what the code does)
- [ ] External documentation (README, wiki) is up to date
Professional documentation is not an afterthought โ it is an integral part of writing code that other engineers can trust, use, and improve. Start with good docstrings, and the rest will follow naturally.
Professional documentation practices help engineers write clear, self-explanatory code that others can understand and maintain without guessing.
๐ Example 1: Single-line docstring for a simple function
A single-line docstring explains what a function does in one brief sentence.
def add_numbers(a, b):
"""Return the sum of two numbers."""
return a + b
result = add_numbers(3, 5)
print(result)
๐ค Output: 8
๐ Example 2: Multi-line docstring with parameters and return value
A multi-line docstring describes the function, its parameters, and what it returns.
def calculate_area(length, width):
"""
Calculate the area of a rectangle.
Parameters:
length (float): The length of the rectangle.
width (float): The width of the rectangle.
Returns:
float: The area of the rectangle.
"""
area = length * width
return area
result = calculate_area(4.5, 3.2)
print(result)
๐ค Output: 14.4
๐ Example 3: Docstring with example usage
Including an example in the docstring helps engineers see how the function works in practice.
def convert_celsius_to_fahrenheit(celsius):
"""
Convert a temperature from Celsius to Fahrenheit.
Example:
>>> convert_celsius_to_fahrenheit(0)
32.0
>>> convert_celsius_to_fahrenheit(100)
212.0
Parameters:
celsius (float): Temperature in degrees Celsius.
Returns:
float: Temperature in degrees Fahrenheit.
"""
fahrenheit = (celsius * 9 / 5) + 32
return fahrenheit
result = convert_celsius_to_fahrenheit(25)
print(result)
๐ค Output: 77.0
๐ Example 4: Docstring for a function with multiple return conditions
A clear docstring helps engineers understand different return paths in a function.
def check_temperature(temp):
"""
Check if a temperature is hot, cold, or comfortable.
Parameters:
temp (float): Temperature in degrees Celsius.
Returns:
str: "Hot" if temp > 30, "Cold" if temp < 10, "Comfortable" otherwise.
"""
if temp > 30:
result = "Hot"
elif temp < 10:
result = "Cold"
else:
result = "Comfortable"
return result
status = check_temperature(22)
print(status)
๐ค Output: Comfortable
๐ Example 5: Docstring for a function that validates input
A docstring can describe what happens when invalid input is provided.
def divide_numbers(numerator, denominator):
"""
Divide two numbers safely.
Parameters:
numerator (float): The number to be divided.
denominator (float): The number to divide by.
Returns:
float: The result of division.
Raises:
ValueError: If denominator is zero.
"""
if denominator == 0:
error_message = "Cannot divide by zero"
raise ValueError(error_message)
result = numerator / denominator
return result
try:
output = divide_numbers(10, 2)
print(output)
except ValueError as error:
print(error)
๐ค Output: 5.0
๐ Comparison Table
| Docstring Type | Best Used For | Example |
|---|---|---|
| Single-line | Simple, obvious functions | """Return the sum of two numbers.""" |
| Multi-line | Functions with parameters and returns | Describes inputs, outputs, and logic |
| With examples | Functions needing usage clarification | Shows >>> example calls |
| With error info | Functions that raise exceptions | Documents what errors can occur |
When you're starting out with Python, writing code that works is only half the battle. The other half is making sure other engineers (and your future self) can understand what your code does and how to use it. Professional documentation practices transform messy, confusing code into clean, maintainable, and shareable tools. This section covers the essential habits that separate hobby scripts from production-ready code.
๐ฏ Why Documentation Matters
- Saves time โ Well-documented code reduces the need for verbal explanations or digging through logic.
- Prevents errors โ Clear documentation helps other engineers use your functions correctly.
- Enables collaboration โ Teams can work on the same codebase without constant hand-holding.
- Supports maintenance โ When you revisit code months later, good docs remind you what you were thinking.
- Builds professionalism โ Documentation is a hallmark of reliable, production-grade engineering.
๐ The Three Levels of Documentation
Professional Python documentation operates at three distinct levels, each serving a different audience:
| Level | Purpose | Audience | Example |
|---|---|---|---|
| Inline Comments | Explain why a specific line or block exists | Yourself and code reviewers | A note explaining a workaround for a known bug |
| Docstrings | Describe what a function, class, or module does | Other engineers using your code | Parameters, return values, and usage notes |
| External Docs | Provide how to guides and context | End users or new team members | README files, wikis, or user manuals |
For most day-to-day work, mastering docstrings is the highest-impact skill.
โ๏ธ Docstring Basics
A docstring is a string literal that appears as the first statement in a function, class, or module. It's not a comment โ Python actually stores it as an attribute of the object, making it accessible programmatically.
- Single-line docstrings โ Use for very simple functions where one line says it all.
- Multi-line docstrings โ Use for anything more complex. Start with a summary line, then a blank line, then details.
A good docstring answers three questions: 1. What does this function do? 2. What inputs does it expect? 3. What does it return (or what side effect does it have)?
๐ ๏ธ Choosing a Docstring Style
There are several accepted formats. Pick one and stick with it across your entire project. Here are the three most common:
| Style | Best For | Key Feature |
|---|---|---|
| Google Style | Readability and simplicity | Uses section headers like Args, Returns, Raises |
| NumPy/SciPy Style | Scientific or data-heavy projects | Uses a more structured, visual format |
| reStructuredText (Sphinx) | Large projects needing auto-generated docs | Uses directives like :param: and :type: |
For most engineers starting out, Google Style is the easiest to read and write.
๐ต๏ธ Anatomy of a Google-Style Docstring
Here is the standard structure for a Google-style docstring:
- Summary line โ A single sentence describing what the function does. Ends with a period.
- Extended description โ Optional paragraph with more detail, separated by a blank line.
- Args section โ Lists each parameter, its type, and a brief description.
- Returns section โ Describes the return value and its type.
- Raises section โ Documents any exceptions the function might raise.
Each section uses a consistent format: - Section header followed by a colon - Indented bullet points or lines for each item - Type information in parentheses after the parameter name
๐ Common Docstring Patterns
Here are the patterns you will use most frequently:
For a simple function with parameters and a return value: - Summary line describing the action - Args section listing each parameter with its type and purpose - Returns section describing the output and its type
For a function that modifies data in place (no return): - Summary line describing the modification - Args section as usual - Returns section stating None, or omit it entirely
For a function that can raise errors: - Standard Args and Returns sections - Raises section listing each exception type and when it occurs
For a class: - Summary line describing the class purpose - Extended description if needed - Attributes section listing key instance variables
๐งช Practical Tips for Better Docstrings
- Write the docstring first โ It helps you clarify your thinking before writing the code.
- Be specific about types โ Use standard Python types (str, int, list, dict) or custom class names.
- Describe behavior, not implementation โ Focus on what the function does, not how it does it.
- Use active voice โ "Returns the sum of two numbers" is clearer than "The sum of two numbers is returned."
- Keep descriptions concise โ One or two sentences per parameter is usually enough.
- Document edge cases โ Mention what happens with empty inputs, None values, or boundary conditions.
๐ซ Common Docstring Mistakes to Avoid
- Writing obvious comments โ Don't restate what the code clearly shows. Focus on the why.
- Forgetting to update docstrings โ When you change code, update the docstring immediately.
- Using inconsistent style โ Mixing Google and NumPy styles in the same project creates confusion.
- Omitting the Raises section โ If your function can raise exceptions, document them.
- Writing overly long descriptions โ If a docstring is longer than the function itself, consider refactoring.
โ Final Checklist for Professional Documentation
Before considering your code complete, run through this checklist:
- [ ] Every public function has a docstring
- [ ] Every class has a docstring
- [ ] The module has a module-level docstring (at the top of the file)
- [ ] All parameters are documented with types and descriptions
- [ ] Return values are documented with types
- [ ] Exceptions are documented if applicable
- [ ] Docstrings follow a consistent style across the project
- [ ] Comments explain non-obvious logic (not what the code does)
- [ ] External documentation (README, wiki) is up to date
Professional documentation is not an afterthought โ it is an integral part of writing code that other engineers can trust, use, and improve. Start with good docstrings, and the rest will follow naturally.
Interactive Views
You are currently in ๐ All-in-One mode. Use the tabs at the top to switch to ๐ Theory Only or ๐ป Code Only views.
Professional documentation practices help engineers write clear, self-explanatory code that others can understand and maintain without guessing.
๐ Example 1: Single-line docstring for a simple function
A single-line docstring explains what a function does in one brief sentence.
def add_numbers(a, b):
"""Return the sum of two numbers."""
return a + b
result = add_numbers(3, 5)
print(result)
๐ค Output: 8
๐ Example 2: Multi-line docstring with parameters and return value
A multi-line docstring describes the function, its parameters, and what it returns.
def calculate_area(length, width):
"""
Calculate the area of a rectangle.
Parameters:
length (float): The length of the rectangle.
width (float): The width of the rectangle.
Returns:
float: The area of the rectangle.
"""
area = length * width
return area
result = calculate_area(4.5, 3.2)
print(result)
๐ค Output: 14.4
๐ Example 3: Docstring with example usage
Including an example in the docstring helps engineers see how the function works in practice.
def convert_celsius_to_fahrenheit(celsius):
"""
Convert a temperature from Celsius to Fahrenheit.
Example:
>>> convert_celsius_to_fahrenheit(0)
32.0
>>> convert_celsius_to_fahrenheit(100)
212.0
Parameters:
celsius (float): Temperature in degrees Celsius.
Returns:
float: Temperature in degrees Fahrenheit.
"""
fahrenheit = (celsius * 9 / 5) + 32
return fahrenheit
result = convert_celsius_to_fahrenheit(25)
print(result)
๐ค Output: 77.0
๐ Example 4: Docstring for a function with multiple return conditions
A clear docstring helps engineers understand different return paths in a function.
def check_temperature(temp):
"""
Check if a temperature is hot, cold, or comfortable.
Parameters:
temp (float): Temperature in degrees Celsius.
Returns:
str: "Hot" if temp > 30, "Cold" if temp < 10, "Comfortable" otherwise.
"""
if temp > 30:
result = "Hot"
elif temp < 10:
result = "Cold"
else:
result = "Comfortable"
return result
status = check_temperature(22)
print(status)
๐ค Output: Comfortable
๐ Example 5: Docstring for a function that validates input
A docstring can describe what happens when invalid input is provided.
def divide_numbers(numerator, denominator):
"""
Divide two numbers safely.
Parameters:
numerator (float): The number to be divided.
denominator (float): The number to divide by.
Returns:
float: The result of division.
Raises:
ValueError: If denominator is zero.
"""
if denominator == 0:
error_message = "Cannot divide by zero"
raise ValueError(error_message)
result = numerator / denominator
return result
try:
output = divide_numbers(10, 2)
print(output)
except ValueError as error:
print(error)
๐ค Output: 5.0
๐ Comparison Table
| Docstring Type | Best Used For | Example |
|---|---|---|
| Single-line | Simple, obvious functions | """Return the sum of two numbers.""" |
| Multi-line | Functions with parameters and returns | Describes inputs, outputs, and logic |
| With examples | Functions needing usage clarification | Shows >>> example calls |
| With error info | Functions that raise exceptions | Documents what errors can occur |