Source code represents primary knowledge
Secondary knowledge takes the form of
more human-readable documentation
Every package/ module/ class/ function should have a
one-liner stating what its purpose is
Given the source code - is there a need for secondary documentation?
Values with unexplained meaning which
should be replaced with a named
constant
Bad for code maintenance and readability
# ...
profit = round(profit, 2)
effort = round(effort, 2)
postal_code = data.get("postal_code", 8010)
PRECISION = 2 # use given precision throughout the program
DEFAULT_POSTAL_CODE = 8010
POSTAL_CODE_KEY = "postal_code"
# ...
profit = round(profit, PRECISION)
effort = round(effort, PRECISION)
postal_code = data.get(POSTAL_CODE_KEY, DEFAULT_POSTAL_CODE)
"""
or '''
__doc__
gives access to an object's docstring"""
.. moduleauthor:: Gerald Senarclens de Grancy <oss@senarclens.eu>
This module provides basic mathematical functions.
"""
def add(first, second):
"""
Return the sum of the parameters.
"""
return first + second
print(__doc__) # access the module documentation
print(add.__doc__) # access the documentation for `add`
help(add) # access interactive help in the interpreter; `add?` in ipython
Download doc.py
Use docstrings if available in your language
Python has excellent support for docstrings!
You may use docstings to give hints on data types
def add(first, second):
"""
Return the sum of the parameters as integer or floating point number.
Arguments:
first -- an integer or floating point number
second -- an integer or floating point number
"""
return first + second
Download docstring_type_hints.py
However, it is much better to use type annotations for this purpose
def add(first: float, second: float) -> float:
"""
Return the sum of the parameters.
"""
return first + second
Download function_annotation.py
Arguments annotated as float
also accept int
(
The numeric tower)
from typing import TypeAlias
Iterable: TypeAlias = list | tuple # variable annotation as `TypeAlias`
def demo(first: list, second: Iterable) -> int:
"""
Demonstrate type hints.
"""
first.extend(second)
count: int = len(first) # variable annotation as `int`
return count
Download type_annotation.py
There are multiple third party tools that allow type checking
sudo apt install python3-mypy (or using a venv)
python type_issue.py
Look at the code and try to figure out what's wrong
Or ... ask mypy
to work for you
mypy type_issue.py
Key purpose is tutorial documentation
>>>
followed by new commands...
when continuing commands on multiple lines>>>
mark
the end of the outputdef add(first: float, second: float) -> float:
"""
Return the sum of the parameters.
>>> add(1,3)
4
>>> add(7.3, -3.0)
4.3
>>> add(42, "foo")
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for +: 'int' and 'str'
"""
return first + second
Download doctest_sample.py
Doctests can also be written in textual documentation files
The ``doctest_sample`` module
=============================
Using ``add``
-------------
This is an example text file in reStructuredText format. First import
``add`` from the ``doctest_sample`` module:
>>> from doctest_sample import add
Now use it:
>>> add(6, 5)
120
Documentation like this can be used by the Sphinx documentation generator.
Download doctest_sample.rst
No output is shown when tests pass (unless -v
is used)
$ python3 -m doctest doctest_sample.py # no output for passing tests
$ python3 -m doctest -v doctest_sample.py # detailed output
$ python3 -m doctest -v doctest_sample.rst # run against textual documentation
Running executable scripts with -m doctest
doesn't work
(-m doctest
would be an argument to the script and not to
the Python interpreter)
Doctests can also be exectured from within Python scripts, e.g.
if __name__=="__main__": # not executed when imported as a module
import doctest
doctest.testmod() # or doctest.testmod(verbose=True)
If the code and the comments disagree,
then both are probably wrong.