Programming Style

Overview

Teaching: 5 min
Exercises: 10 min
Questions
  • How can I make programs more robust?

  • How can I make programs easier to understand?

Objectives
  • Add assert statements to programs to check pre-conditions, post-conditions, and invariants.

Follow standard Python style in your code.

Use assertions to check for internal errors.

def bounds(values):
    assert len(values) > 0, 'Cannot get bounds of empty list.'
    low = min(values)
    high = max(values)
    assert low <= high, 'Low bound should not be greater than high bound'
    return low, high

Use docstrings to provide online help.

def average(values):
    "Return average of values, or None if no values are supplied."

    if len(values) == 0:
        return None
    return sum(values) / average(values)

help(average)
Help on function average in module __main__:

average(values)
    Return average of values, or None if no values are supplied.

Multiline Strings

Often use multiline strings for documentation. These start and end with three quote characters (either single or double) and end with three matching characters.

"""This string spans multiple lines.

Blank lines are allowed. For documentation, typically a first line
summarizes the functionality, and a blank line separates that summary
from the remainder. The ending three quote characters, in the case of a
long documentation string, are typically on their own line.
"""

Document This

Turn the comment on the following function into a docstring and check that help displays it properly.

def middle(a, b, c):
    # Return the middle value of three.
    # Assumes the values can actually be compared.
    values = [a, b, c]
    values.sort()
    return values[1]

Clean Up This Code

  1. Read this short program and try to predict what it does.
  2. Run it: how accurate was your prediction?
  3. Refactor the program to make it more readable. Add assertions as you go to make sure you’re not breaking things, and run it after each change to test it.
  4. Compare your rewrite with your neighbor’s. What did you do the same? What did you do differently, and why?
n = 10
s = 'et cetera'
print(s)
i = 0
while i < n:
    # print('at', j)
    new = ''
    for j in range(len(s)):
        left = j-1
        right = (j+1)%len(s)
        if s[left]==s[right]: new += '-'
        else: new += '*'
    s=''.join(new)
    print(s)
    i += 1

Key Points

  • Fail early, often, and meaningfully.

  • Use assert to check that programs are working correctly.

  • Give assert statements meaningful error messages to help users.