Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions documenting-python-code/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Documenting Python Code: A Complete Guide

This folder provides the code examples for the Real Python tutorial [Documenting Python Code: A Complete Guide](https://realpython.com/documenting-python-code/).

## Installation

Only the spreadsheet examples need third-party packages. Install them into a virtual environment with:

```sh
$ python -m pip install -r requirements.txt
```

The standalone examples run on Python 3.6 or later. The spreadsheet examples use the pinned pandas version, which requires Python 3.11 or later.

## Files

- **`comments.py`**: Functions showing short and multi-line comments.
- **`type_hints.py`**: A function that uses type hints in place of comments.
- **`say_hello_v1.py`**: Sets a function's docstring by assigning to `__doc__`.
- **`say_hello_v2.py`**: Sets the same docstring with a string literal below the `def` line.
- **`simple_class.py`**: Shows where class and method docstrings go.
- **`animal.py`**: The `Animal` class with NumPy/SciPy-style class and method docstrings.
- **`spreadsheet_columns.py`**: A command-line script with a script docstring that prints a spreadsheet's column headers.
- **`docstring_formats.py`**: The spreadsheet function documented in the Google, reStructuredText, NumPy/SciPy, and Epytext formats.

## Usage

Inspect docstrings with `help()`:

```pycon
>>> from say_hello_v2 import say_hello
>>> help(say_hello)
Help on function say_hello in module say_hello_v2:

say_hello(name)
A simple function that says hello... Richie style

>>> from animal import Animal
>>> Animal("dog", "woof").says()
A dog says woof
```

Print the column headers of an Excel spreadsheet:

```sh
$ python spreadsheet_columns.py people.xlsx
name
age
city
```

Run `python spreadsheet_columns.py -h` to see the script's docstring used as the help message, or run `python docstring_formats.py` to print the same docstring in all four formats.
69 changes: 69 additions & 0 deletions documenting-python-code/animal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
class Animal:
"""
A class used to represent an Animal

...

Attributes
----------
says_str : str
a formatted string to print out what the animal says
name : str
the name of the animal
sound : str
the sound that the animal makes
num_legs : int
the number of legs the animal has (default 4)

Methods
-------
says(sound=None)
Prints the animals name and what sound it makes
"""

says_str = "A {name} says {sound}"

def __init__(self, name, sound, num_legs=4):
"""
Parameters
----------
name : str
The name of the animal
sound : str
The sound the animal makes
num_legs : int, optional
The number of legs the animal (default is 4)
"""

self.name = name
self.sound = sound
self.num_legs = num_legs

def says(self, sound=None):
"""Prints what the animals name is and what sound it makes.

If the argument `sound` isn't passed in, the default Animal
sound is used.

Parameters
----------
sound : str, optional
The sound the animal makes (default is None)

Raises
------
NotImplementedError
If no sound is set for the animal or passed in as a
parameter.
"""

if self.sound is None and sound is None:
raise NotImplementedError("Silent Animals are not supported!")

out_sound = self.sound if sound is None else sound
print(self.says_str.format(name=self.name, sound=out_sound))


if __name__ == "__main__":
Animal("dog", "woof").says()
help(Animal)
14 changes: 14 additions & 0 deletions documenting-python-code/comments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
def hello_world():
# A simple comment preceding a simple print statement
print("Hello World")


def hello_long_world():
# A very long statement that just goes on and on and on and on and
# never ends until after it's reached the 80 char limit
print("Hellooooooooooooooooooooooooooooooooooooooooooooooooooooooo World")


if __name__ == "__main__":
hello_world()
hello_long_world()
106 changes: 106 additions & 0 deletions documenting-python-code/docstring_formats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
"""The same function documented in four common docstring formats.

Compare the output of help() on each function to see how the Google,
reStructuredText, NumPy/SciPy, and Epytext formats look.
"""

import pandas as pd


def get_spreadsheet_cols_google(file_loc, print_cols=False):
"""Gets and prints the spreadsheet's header columns

Args:
file_loc (str): The file location of the spreadsheet
print_cols (bool): A flag used to print the columns to the console
(default is False)

Returns:
list: a list of strings representing the header columns
"""

file_data = pd.read_excel(file_loc)
col_headers = list(file_data.columns.values)

if print_cols:
print("\n".join(col_headers))

return col_headers


def get_spreadsheet_cols_rest(file_loc, print_cols=False):
"""Gets and prints the spreadsheet's header columns

:param file_loc: The file location of the spreadsheet
:type file_loc: str
:param print_cols: A flag used to print the columns to the console
(default is False)
:type print_cols: bool
:returns: a list of strings representing the header columns
:rtype: list
"""

file_data = pd.read_excel(file_loc)
col_headers = list(file_data.columns.values)

if print_cols:
print("\n".join(col_headers))

return col_headers


def get_spreadsheet_cols_numpy(file_loc, print_cols=False):
"""Gets and prints the spreadsheet's header columns

Parameters
----------
file_loc : str
The file location of the spreadsheet
print_cols : bool, optional
A flag used to print the columns to the console (default is False)

Returns
-------
list
a list of strings representing the header columns
"""

file_data = pd.read_excel(file_loc)
col_headers = list(file_data.columns.values)

if print_cols:
print("\n".join(col_headers))

return col_headers


def get_spreadsheet_cols_epytext(file_loc, print_cols=False):
"""Gets and prints the spreadsheet's header columns

@type file_loc: str
@param file_loc: The file location of the spreadsheet
@type print_cols: bool
@param print_cols: A flag used to print the columns to the console
(default is False)
@rtype: list
@returns: a list of strings representing the header columns
"""

file_data = pd.read_excel(file_loc)
col_headers = list(file_data.columns.values)

if print_cols:
print("\n".join(col_headers))

return col_headers


if __name__ == "__main__":
for func in (
get_spreadsheet_cols_google,
get_spreadsheet_cols_rest,
get_spreadsheet_cols_numpy,
get_spreadsheet_cols_epytext,
):
print(f"--- {func.__name__} ---")
print(func.__doc__)
3 changes: 3 additions & 0 deletions documenting-python-code/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pandas==3.0.6
openpyxl==3.1.5
xlrd==2.0.2
8 changes: 8 additions & 0 deletions documenting-python-code/say_hello_v1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
def say_hello(name):
print(f"Hello {name}, is it me you're looking for?")


say_hello.__doc__ = "A simple function that says hello... Richie style"

if __name__ == "__main__":
help(say_hello)
7 changes: 7 additions & 0 deletions documenting-python-code/say_hello_v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
def say_hello(name):
"""A simple function that says hello... Richie style"""
print(f"Hello {name}, is it me you're looking for?")


if __name__ == "__main__":
help(say_hello)
11 changes: 11 additions & 0 deletions documenting-python-code/simple_class.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class SimpleClass:
"""Class docstrings go here."""

def say_hello(self, name: str):
"""Class method docstrings go here."""

print(f"Hello {name}")


if __name__ == "__main__":
help(SimpleClass)
63 changes: 63 additions & 0 deletions documenting-python-code/spreadsheet_columns.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""Spreadsheet Column Printer

This script allows the user to print to the console all columns in the
spreadsheet. It is assumed that the first row of the spreadsheet is the
location of the columns.

This tool accepts comma separated value files (.csv) as well as excel
(.xls, .xlsx) files.

This script requires that `pandas` be installed within the Python
environment you are running this script in.

This file can also be imported as a module and contains the following
functions:

* get_spreadsheet_cols - returns the column headers of the file
* main - the main function of the script
"""

import argparse

import pandas as pd


def get_spreadsheet_cols(file_loc, print_cols=False):
"""Gets and prints the spreadsheet's header columns

Parameters
----------
file_loc : str
The file location of the spreadsheet
print_cols : bool, optional
A flag used to print the columns to the console (default is
False)

Returns
-------
list
a list of strings used that are the header columns
"""

file_data = pd.read_excel(file_loc)
col_headers = list(file_data.columns.values)

if print_cols:
print("\n".join(col_headers))

return col_headers


def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"input_file",
type=str,
help="The spreadsheet file to print the columns of",
)
args = parser.parse_args()
get_spreadsheet_cols(args.input_file, print_cols=True)


if __name__ == "__main__":
main()
6 changes: 6 additions & 0 deletions documenting-python-code/type_hints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
def hello_name(name: str) -> str:
return f"Hello {name}"


if __name__ == "__main__":
print(hello_name("Real Python"))
Loading
Loading