Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

This code style guide reproduces common conventions for Python programming. While rules can be occasionally bent with justification, most programming work in this course should follow these guidelines.

Naming

Variable names

Variable names should be descriptive, concise, and lowercase with words separated by underscores as in snake_case. Avoid single letter names for variables because a single letter usually fails to describe the values contained in a variable, with the exception of loop variables. Avoid Python keywords, such as class, print, import, or return, or names of built-in functions or types, such as len.

Function names

Function names should be descriptive, concise, and lowercase with words separated by underscores as in snake_case. As with variable names, avoid names of built-in Python functions. We usually specify the function names in the specification, so make sure to name your functions accordingly.

When writing test functions, the name of your test function should clearly indicate which function it is testing. For example, a test for the function add_two_numbers might be named test_add_two_numbers.

Whitespace

Indentation

Unlike other languages that use explicit delimiters to determine what goes inside a loop or function (such as {} in Java), Python only uses indentation. Indentation affects the behavior of programs. IndentationError: unexpected indent means there is an error in code indentation.

Blank lines

Leave two blank lines separating code for different function definitions, class definitions, and other code. The only exception is for methods defined within the same class, in which case a single blank line between methods is preferred.

Within a function definition, avoid introducing more than a single blank line at a time and only for separating complex chunks of code for readability. Careful and consistent of two blank lines can help communicate the start of a significant, new definition.

Between operators

Include spaces between operators and other elements in an expression. Mathematical operators include +, -, *, /, and **. Logical operators include ==, <=, >=, <, and >. Limit space delimiters to 1 space to avoid unnecessary whitespace. The exception to this is parentheses, which can be directly adjacent to whatever they are enclosing.

This does not apply when specifying default parameter values or keyword arguments. Avoid spaces around the assignment operator = for those cases.

Function calls

Include spaces between arguments in a function call. Avoid space(s) between the function name and its argument list. Adding space(s) incorrectly suggests that the parentheses are for grouping an expression when they actually indicate a function call.

Line length

In general, lines should not exceed 100 characters. Occaisional exceptions are permitted when a longer line would be clearer and easier to understand than two or more shorter lines. Avoid long lines with the following strategies.

Function calls
some_function(first_arg="This is a function",
              second_arg="With many arguments",
              third_arg="indent until everything lines up")
Expressions
total = (first_num + second_num + third_num
         + fourth_num + fifth_num)
Strings
print("For very very very very very very long strings, "
      "this is how we might break it up to two lines")

Documentation

Each function should contain a docstring describing what the function does right below the function definition. It should describe any parameters the function takes and values it returns (if any). If the code requires handle some special cases (like case sensitivity, or special returns values for a certain input), include that in the comment as well. The main method does not require a comment.

Long blocks of particularly complex code can be explained by including a comment # on the preceding line(s).

def add_two_numbers(a, b, return_zero=False):
    """
    This function returns the sum of the two given numbers a, b
    if return_zero is False. Otherwise returns 0.
    return_zero has False as its default value.
    """
    if return_zero:
        return 0
    else:
        return a + b

Avoid information that is unnecessary or irrelevant to clients (end-users of your work), such as “initialize variable” or “nested for loop” or “increment count”. Function comments should describe what result the program achieves rather than how it achieves that result.

Consider what a client would find useful. Documentation should contain all the necessary information needed to use a function. The exact details of how the function solves the problem is irrelevant, but the client needs to know the purpose of the parameters and the expected behavior. Avoid mentioning “the spec” or “the assessment” because clients won’t know what this means unless they’ve also taken this course.

The documentation for test functions can be relatively simple. For example, the test function test_add_two_numbers could include the docstring, “Tests the function add_two_numbers”.

Logical refactoring

If the same lines of code appear in multiple places, reduce redundancy by refactoring.

Conditional logic

Boolean zen

Avoid unnecessary comparisons to True and False. Remember to negate boolean values with the not operator.

Loop zen

Choose loop bounds or loop conditions that generalize code the best.

Computation that only need to happen once should not be recomputed inside a loop.

Avoid unnecessary looping.

Redundant cases

Avoid redundant cases. Before introducing a special case, think about whether a general case could compute the same result.

Program design

Global variables

No global variables are allowed except for simple, fixed-value constants. Constants should be named using all uppercase characters.

Unnecessary computation

Avoid computing unnecessary values.

Fit and finish

Remove all debugging print statements and fix all warnings and errors.