DocTest Objects

Let’s talk about Python docstrings and how they can help you create documentation for your code automatically. Docstrings are comments that live inside your code and look like this:

# This is a function named "my_function" that takes in one argument "arg1"
def my_function(arg1):
    """This is a docstring! It's used to describe the function and its arguments."""
    
    # Do some stuff here... (This comment is not very helpful, it should be more specific about what the function is doing)

# The docstring should be more specific and describe the purpose of the function and its arguments in more detail. It should also follow the PEP 257 style guide for docstrings.

# Here is an example of a corrected docstring:
def my_function(arg1):
    """This function takes in one argument and returns the square of that argument.
    
    Args:
        arg1 (int): The number to be squared.
        
    Returns:
        int: The square of the input number.
    """
    
    # Do some stuff here... (This comment should be more specific about what the function is doing, such as calculating the square of the input number)

# The function should also have a return statement to actually return the calculated value. Without it, the function will not output anything.

# Here is an example of a corrected function:
def my_function(arg1):
    """This function takes in one argument and returns the square of that argument.
    
    Args:
        arg1 (int): The number to be squared.
        
    Returns:
        int: The square of the input number.
    """
    
    # Calculate the square of the input number
    result = arg1 ** 2
    
    # Return the calculated value
    return result

Docstrings can be used for more than just documentation, though. They also generate code examples and test cases automatically when you run Python’s built-in doctest module. This means that with a little bit of effort upfront, you can have fully automated documentation for your entire project without ever having to write it by hand!

To see this in action, let’s create a simple function that takes an array and returns its length:

# This function takes in an array and returns its length
def get_array_length(arr):
    """Returns the number of elements in the given array."""
    
    # The len() function is used to get the length of the array
    return len(arr)

Now, to generate documentation for this function using docstrings, we can run a command like this:

# This script is used to generate documentation for a function using docstrings.
# The command "python -m doctest my_module.py" is used to run the doctest module on the specified module.

# The "python" command is used to run the Python interpreter.
# The "-m" flag is used to run a module as a script.
# The "doctest" module is used to test code snippets in docstrings.
# The "my_module.py" argument specifies the module to be tested.

This will execute all the DocTest objects in your Python module (in this case, `my_module.py`) and generate documentation based on them. The output should look something like this:

# This line is a comment and does not affect the code execution
# It is used to provide additional information or explanations

# This line is a print statement that outputs a string
print("Running doctests for my_module.py")

# This line is a try statement that attempts to execute the code within the indented block
try:
    # This line calls the function get_array_length with a list as an argument
    # The function should return the length of the list, which is 3
    get_array_length([1, 2, 3])
    
# This line is an except statement that handles any errors that may occur within the try block
except:
    # This line is a print statement that outputs a string
    print("Error: Unable to get array length")

# This line is a print statement that outputs a string
print("Output:")

# This line is a print statement that outputs the result of the function call
# The result should be 3, not 4 as shown in the original script
print(get_array_length([1, 2, 3]))

# This line is a print statement that outputs a string
print("ok")

And that’s it! You now have documentation for your function without ever having to write a single line of prose. Pretty cool, huh?

Docstrings can also be used to generate code examples and test cases automatically. Let’s see how:

# This function takes in an array and returns the number of elements in the array.
def get_array_length(arr):
    """Returns the number of elements in the given array."""
    
    # The len() function is used to get the length of the array.
    return len(arr)

# The following code will only run if the script is executed directly, not if it is imported as a module.
if __name__ == '__main__':
    # Example usage
    arr = [1, 2, 3]
    # The format() function is used to insert the array into the string for printing.
    print("The length of {} is:".format(str(arr)))
    # The get_array_length() function is called and the result is printed.
    print(get_array_length(arr))
    
    # Test case
    # The assert keyword is used to check if the given condition is true.
    assert get_array_length([0]) == 1

Now, when we run the `doctest` command again, we’ll see that our example usage and test case are included in the output:

# This script is used to run doctests for the module "my_module.py"

# Test case 1: Checks if the function "get_array_length" returns the correct length of the given array
Trying:
    > get_array_length([1, 2, 3])
    
# Expected output: 3 (since the array has 3 elements)
Output:
    3
ok # Indicates that the test passed successfully

# Test case 2: Checks if the function "get_array_length" correctly prints the length of the given array
Trying:
    > arr = [1, 2, 3]
    ... print("The length of {} is:".format(str(arr)))
    ... print(get_array_length(arr))
    
# Expected output: The length of [1, 2, 3] is: 3
Output:
    The length of [1, 2, 3] is:
    3
ok # Indicates that the test passed successfully

# Test case 3: Checks if the function "get_array_length" correctly handles an array with one element
Trying:
    > assert get_array_length([0]) == 1 # Uses the "assert" statement to check if the given condition is true
    
# Expected output: No output, but the test will pass if the condition is true
ok # Indicates that the test passed successfully

And that’s it! With docstrings and `doctest`, you can have fully automated documentation for your Python code. It might take a little bit of effort upfront, but trust us: the time you save in the long run will be well worth it.

SICORPS