6 exercises — identify and write Google-style, NumPy-style, and Sphinx-style Python docstrings in real engineering contexts.
0 / 19 completed
1 / 19
What style is this Python docstring?
```python
def parse_date(date_str):
"""Parse a date string into a datetime object.
Args:
date_str (str): Date string in ISO 8601 format (YYYY-MM-DD).
Returns:
datetime: Parsed datetime object.
Raises:
ValueError: If the string does not match ISO 8601 format.
"""
```
Google style docstring — recognisable by its indented sections with a colon-terminated header.
Google style sections: • Args: — list of parameters (name (type): description) • Returns: — return type and description • Raises: — exceptions with conditions • Note:, Example:, Yields: — optional sections
When to use Google style: • Most popular in general Python projects • Used by Google, many open-source projects • Works well with Sphinx via the sphinx.ext.napoleon extension • Preferred by Black, isort, and most Python style guides
Linted/generated by: Google's own styleguide, pylint, pydocstyle, mkdocs.
2 / 19
A colleague shows you this docstring. What style is it?
```python
def compute_rmse(y_true, y_pred):
"""
Compute root mean squared error.
Parameters
----------
y_true : array-like of shape (n_samples,)
Ground truth target values.
y_pred : array-like of shape (n_samples,)
Estimated target values.
Returns
-------
float
RMSE value.
"""
```
NumPy style — recognisable by its underlined section headers and the "name : type" annotation pattern.
NumPy style characteristics: • Section headers underlined with dashes: Parameters\n---------- • Parameter format: name : type (space-colon-space) • Type annotations on their own "name : type" line, description indented below • Common sections: Parameters, Returns, Raises, See Also, Notes, References, Examples
When to use NumPy style: • Data science and scientific computing projects • numpy, scipy, pandas, scikit-learn all use this style • Projects where detailed mathematical documentation is needed • When your audience is data scientists (familiar with numpy docs)
Tool support: Sphinx with sphinx.ext.napoleon, numpydoc Sphinx extension.
3 / 19
What style is this docstring?
```python
def connect(host, port=5432):
"""
Connect to a PostgreSQL database.
:param host: Hostname or IP of the database server.
:type host: str
:param port: Port number. Defaults to 5432.
:type port: int
:returns: Active database connection.
:rtype: psycopg2.extensions.connection
:raises ConnectionError: If the server is unreachable.
"""
```
Sphinx / reStructuredText (reST) style — recognisable by inline directives starting with a colon: :param:, :type:, :returns:, :rtype:, :raises:.
Sphinx reST style characteristics: • All annotations inline, not grouped into sections • Separates the parameter description (:param:) from its type (:type:) • :returns: for description, :rtype: for the return type • Oldest of the three styles; native to Sphinx documentation system
When to use Sphinx style: • Projects using Sphinx for documentation (https://www.sphinx-doc.org) • Django, older Python packages, projects targeting Sphinx HTML docs • Mixed into many legacy codebases
Comparison: | Style | Separator | Type notation | |---|---|---| | Google | colon-header sections | (type) in parentheses | | NumPy | underlined sections | name : type | | Sphinx | :param:/:type: inline | :type name: |
4 / 19
In a Google-style docstring, how should you document a function that yields values (a generator)?
Yields: section — used in Google-style (and NumPy-style) docstrings for generator functions.
Example:
def read_lines(filepath):
"""Read lines from a file lazily.
Args:
filepath (str): Path to the text file.
Yields:
str: Each line from the file, stripped of trailing newline.
Raises:
FileNotFoundError: If the file does not exist.
"""
When a function is a generator (uses yield), document with Yields: not Returns: • Returns: — for functions that return a value with return • Yields: — for generator functions that use yield • The type in Yields: should be the type of each yielded value (e.g. str, not Generator[str, None, None])
This distinction matters because generators are iterable objects, not single return values — callers iterate them with a for loop or next().
5 / 19
Which Python docstring first line follows the PEP 257 style convention?
Option B follows PEP 257 conventions:
PEP 257 rules for one-liners and multi-line docstrings: • First line: brief summary — imperative mood ("Validates", "Computes", "Returns", "Converts") • First line should fit on ONE line — detailed description goes after a blank line • First line ends with a period • Multi-line: blank line after summary, then extended description, then sections • Closing quotes on their own line for multi-line docstrings
PEP 257 examples: Good one-liner: """Return the absolute value of x.""" Good multi-line:
"""Validate an email address.
Checks format against RFC 5321, then verifies the domain
via DNS MX record lookup.
"""
Options A and C: "This function..." and "Function that..." — do NOT start with "This function"; PEP 257 says to use imperative mood without preamble. Option D: no capitalisation, no period — violates PEP 257.
6 / 19
You are joining a data science team that uses scikit-learn and pandas. Which docstring style should you use to match the existing codebase?
NumPy style — the dominant convention in the scientific Python ecosystem.
Why NumPy style fits data science: • scikit-learn, numpy, scipy, pandas all use NumPy style • Data scientists recognise it immediately from reading library documentation • Well-suited to complex parameter types (array-like, ndarray, DataFrame) • The underlined section headers are easy to scan when there are many parameters
Practical rule for choosing docstring style: • Check the existing codebase — consistency beats personal preference • Data science (numpy/pandas ecosystem) → NumPy style • General Python (Django, Flask, FastAPI) → Google style • Sphinx documentation sites → Sphinx/reST style • Greenfield project → pick one and add a linter rule (pydocstyle/flake8-docstrings)
Most AI code assistants (GitHub Copilot, Cursor) can generate any style if you write one correctly-styled example and tell the assistant which convention to follow.
7 / 19
During a code review of a new payment processing module for our online store, David highlights the following docstring:
```python
def process_payment(amount, card_number):
"""Processes a payment.
Args:
amount (float): The amount to charge.
card_number (str): The card number.
Returns:
bool: True if the payment was successful, False otherwise.
"""
# Some code here that doesn't actually process the payment...
return True
The core issue here isn't just stating *what* the function does (it processes payment), but anticipating potential problems. A robust docstring should acknowledge possible errors and how they are handled, even if the implementation doesn't explicitly handle them. Options A and C misrepresent the purpose of a good docstring; option D is tangential. Option B correctly identifies that documenting error handling is vital for maintainability and clarity.
8 / 19
During a code review of a new API endpoint for our mobile app, Liam comments: 'I'm not entirely sure what this response means. The documentation doesn't explain the fields clearly.' You see the following docstring:
```python
def get_user_profile(user_id):
"" summary: Retrieves a user profile based on their ID.
parameters:
user_id (int): The unique identifier for the user.
returns:
dict: A dictionary containing user profile information, including name, email, and registration date.
""
# Code to fetch user data from the database
return {'name': 'John Doe', 'email': 'john.doe@example.com', 'registration_date': '2023-10-26'}
```
What is the most appropriate response to Liam's comment, focusing on improving the docstring's clarity for a developer unfamiliar with this API?
Liam's comment highlights a crucial problem: the summary within the docstring isn't sufficient to convey the response structure. The incorrect options either dismiss the feedback or provide overly simplistic advice. The correct answer focuses on adding more detail *specifically* about the dictionary keys and their expected types – this is what a developer unfamiliar with the API needs to understand. Providing example data clarifies the format of the returned dictionary, directly addressing Liam's concern.
9 / 19
During a code review of a new payment processing module for our online store, David highlights the following docstring:
```python
def process_payment(amount, card_number):
"""Processes a payment.
Args:
amount (float): The amount to charge.
card_number (str): The card number.
Returns:
bool: True if the payment was successful, False otherwise.
"""
# Some code here that doesn't actually process the payment...
return True
The core issue here isn't just stating *what* the function does (it processes payment), but anticipating potential problems. A robust docstring should acknowledge possible errors and how they are handled, even if the implementation doesn't explicitly handle them. Options A and C misrepresent the purpose of a good docstring; option D is tangential. Option B correctly identifies that documenting error handling is vital for maintainability and clarity.
10 / 19
During a code review of a new API endpoint for our mobile app, Liam comments: 'I'm not entirely sure what this response means. The documentation doesn't explain the fields clearly.' You see the following docstring:
```python
def get_user_profile(user_id):
"" summary: Retrieves a user profile based on their ID.
parameters:
user_id (int): The unique identifier for the user.
returns:
dict: A dictionary containing user profile information, including name, email, and registration date.
""
# Code to fetch user data from the database
return {'name': 'John Doe', 'email': 'john.doe@example.com', 'registration_date': '2023-10-26'}
```
What is the most appropriate response to Liam's comment, focusing on improving the docstring's clarity for a developer unfamiliar with this API?
Liam's comment highlights a crucial problem: the summary within the docstring isn't sufficient to convey the response structure. The incorrect options either dismiss the feedback or provide overly simplistic advice. The correct answer focuses on adding more detail *specifically* about the dictionary keys and their expected types – this is what a developer unfamiliar with the API needs to understand. Providing example data clarifies the format of the returned dictionary, directly addressing Liam's concern.
11 / 19
During a code review of a new payment processing module for our online store, David highlights the following docstring:
```python
def process_payment(amount, card_number):
"""Processes a payment.
Args:
amount (float): The amount to charge.
card_number (str): The card number.
Returns:
bool: True if the payment was successful, False otherwise.
"""
# Some code here that doesn't actually process the payment...
return True
The core issue here isn't just stating *what* the function does (it processes payment), but anticipating potential problems. A robust docstring should acknowledge possible errors and how they are handled, even if the implementation doesn't explicitly handle them. Options A and C misrepresent the purpose of a good docstring; option D is tangential. Option B correctly identifies that documenting error handling is vital for maintainability and clarity.
12 / 19
During a code review of a new API endpoint for our mobile app, Liam comments: 'I'm not entirely sure what this response means. The documentation doesn't explain the fields clearly.' You see the following docstring:
```python
def get_user_profile(user_id):
"" summary: Retrieves a user profile based on their ID.
parameters:
user_id (int): The unique identifier for the user.
returns:
dict: A dictionary containing user profile information, including name, email, and registration date.
""
# Code to fetch user data from the database
return {'name': 'John Doe', 'email': 'john.doe@example.com', 'registration_date': '2023-10-26'}
```
What is the most appropriate response to Liam's comment, focusing on improving the docstring's clarity for a developer unfamiliar with this API?
Liam's comment highlights a crucial problem: the summary within the docstring isn't sufficient to convey the response structure. The incorrect options either dismiss the feedback or provide overly simplistic advice. The correct answer focuses on adding more detail *specifically* about the dictionary keys and their expected types – this is what a developer unfamiliar with the API needs to understand. Providing example data clarifies the format of the returned dictionary, directly addressing Liam's concern.
13 / 19
During a code review of a new payment processing module for our online store, David highlights the following docstring:
```python
def process_payment(amount, card_number):
"""Processes a payment.
Args:
amount (float): The amount to charge.
card_number (str): The card number.
Returns:
bool: True if the payment was successful, False otherwise.
"""
# Some code here that doesn't actually process the payment...
return True
The core issue here isn't just stating *what* the function does (it processes payment), but anticipating potential problems. A robust docstring should acknowledge possible errors and how they are handled, even if the implementation doesn't explicitly handle them. Options A and C misrepresent the purpose of a good docstring; option D is tangential. Option B correctly identifies that documenting error handling is vital for maintainability and clarity.
14 / 19
During a code review of a new API endpoint for our mobile app, Liam comments: 'I'm not entirely sure what this response means. The documentation doesn't explain the fields clearly.' You see the following docstring:
```python
def get_user_profile(user_id):
"" summary: Retrieves a user profile based on their ID.
parameters:
user_id (int): The unique identifier for the user.
returns:
dict: A dictionary containing user profile information, including name, email, and registration date.
""
# Code to fetch user data from the database
return {'name': 'John Doe', 'email': 'john.doe@example.com', 'registration_date': '2023-10-26'}
```
What is the most appropriate response to Liam's comment, focusing on improving the docstring's clarity for a developer unfamiliar with this API?
Liam's comment highlights a crucial problem: the summary within the docstring isn't sufficient to convey the response structure. The incorrect options either dismiss the feedback or provide overly simplistic advice. The correct answer focuses on adding more detail *specifically* about the dictionary keys and their expected types – this is what a developer unfamiliar with the API needs to understand. Providing example data clarifies the format of the returned dictionary, directly addressing Liam's concern.
15 / 19
During a standup meeting, Sarah explains that she's writing a function to fetch user data from the API. She shows you this docstring:
```python
def get_user(user_id):
"""Retrieves user information.
Args:
user_id (int): The ID of the user to retrieve.
Returns:
dict: User data, or None if not found.
"""
# Function implementation here
pass
This docstring follows the Google style convention which is widely used in Python development. It explicitly defines each argument (`user_id`) with its type (`int`) and describes what the function returns (a `dict` or `None`). The key here is that it's comprehensive – a good practice for documentation.
16 / 19
You are reviewing a pull request and see this comment from a colleague:
`'Could you explain what the `status_code` parameter in this function means? The docstring doesn't specify its range or potential values.' You see the following code:
```python
def send_notification(message, status_code):
"""Sends a notification.
Args:
message (str): The notification message.
status_code (int): The HTTP status code of the request.
"""
# Function implementation here
pass
A well-written docstring should *always* define the meaning and expected values for each parameter. In this case, the description needs to clarify that `status_code` represents the HTTP status code returned by the notification service (e.g., 200 for success, 400 for bad request).
17 / 19
A senior developer asks you to improve this docstring:
```python
def calculate_average(numbers):
"""Calculates the average of a list of numbers.
:param numbers (list): A list of numerical values.
:type numbers: list
"""
# Function implementation here
pass
While the provided docstring uses the standard `:param` and `:type` format, adding a specific data type (e.g., `list[float]`) improves clarity and helps prevent errors. Explicitly stating the expected types is crucial for code maintainability and reducing potential bugs.
18 / 19
You're writing a new function that generates a sequence of numbers using Python's `yield` keyword. Which docstring style is most appropriate to document this generator function?
```python
def generate_numbers(start, stop):
"""Generates a sequence of numbers from start (inclusive) to stop (exclusive).
Args:
start: The starting number.
stop: The ending number (exclusive).
"""
for i in range(start, stop):
yield i
Generator functions using `yield` produce values on demand. Therefore, the docstring *must* explain that the function returns a generator object and how to iterate over it. This is critical for developers to understand how to consume the generated sequence.
19 / 19
A team member submits code with this docstring:
```python
def process_data(input_data):
"""Process the input data.
"""
# Function implementation here
pass
PEP 257 specifies that the first line of a docstring should summarize the object's purpose. This example follows this convention perfectly – it's concise and clearly states the function's primary role. Adhering to PEP guidelines is crucial for code readability and maintainability within a team.
What will I practice in "Python Docstrings — Code Comments Exercises"?
This is a Code Comments exercise set. It walks through 19 scenario-based multiple-choice questions built around real usage of Code Comments terminology that IT professionals encounter on the job.
Is this exercise free to use?
Yes. Every exercise on CoderSlingo, including this one, is free to complete with no account, sign-up, or paywall.
How many questions are in this exercise?
This set contains 19 questions. Each one shows immediate feedback and a detailed explanation after you answer, so you learn the correct usage right away rather than waiting for a final score.
Do I need prior experience to complete this exercise?
No prior experience is required. Each question includes a full explanation covering the reasoning behind the correct answer, so the exercise itself teaches the Code Comments vocabulary as you go.
Can I retry the exercise if I get questions wrong?
Yes — use the "Try again" button on the results screen to reset your answers and go through all the questions again. There is no limit on attempts.
Is my progress saved?
Your answers and score for the current session are tracked in the browser as you go. No account or login is needed, and there is nothing to install.
What if I don't understand a term used in a question?
Read the explanation shown after you answer each question — it breaks down the correct term in plain English with a real-world example. You can also check the site Glossary for quick definitions.
How is this different from reading a blog article on the topic?
Exercises like this one are interactive drills that test and reinforce specific vocabulary through multiple-choice questions, while blog articles explain concepts in prose. Practising here after reading builds active recall, not just passive recognition.
Where can I find more Code Comments exercises?
See the Code Comments exercises hub for the full set of related pages, or browse all exercise categories from the main Exercises index.
Can I use this exercise to prepare for a technical interview?
Yes — Code Comments vocabulary comes up often in technical discussions and interviews. Pair this exercise with our dedicated Interview Preparation section for role-specific practice.