Coding Standards for Python Programs

Version 3 [1]

This document gives some rules of thumb for writing programs in good style. No set of rules can cover all possible situations; use common sense always. The purpose of good style is to make programs easily readable and intelligible. This has at least two important benefits: it helps us avoid errors when writing the program initially, and we or others who subsequently need to revise the program won't be confused.

How to Develop Programs

Coding Standards

Standards are listed under the chapter where they first become applicable.

Chapter 3: Codes and Other Secrets

  1. Each source file should begin with a header comment which shows the course number, lab number, author's name(s), and date, in this form:

    # INFO I210, Lab 3
    # (Your name)
    # (Today's date)
    
  2. Use comments to identify and briefly describe each problem, e.g.,

    # Page 205, Exercise 6.10
    # Display an animated, dancing skeleton
    
  3. Put all import statements at the top of the file, just below the header comment, before any function definitions or other code.

  4. Use meaningful variable names.

  5. Use white space to make code clearer:

    • Space around operators like + and =
    • Vertical space between problems, functions, and even sections of code in longer functions.
  6. Identifiers (variable, function, module, and class names) should be meaningful and (even more importantly) not misleading. This applies to function parameters as well as other variables.

    Good:

    student_name = "Jack"
    

    Bad, meaningless:

    n = "Jack"
    

    Worse, misleading:

    score = "Jack"
    

    However, in some contexts it is okay to use short, standard variable names, like i and j for indexes or counters in a loop, and n for a generic integer (in a purely mathematical function) or s for a generic string.

    For long identifiers, use underscores or capitalization to separate the parts, e.g., best_of_three or bestOfThree.

  7. Where Python requires code to be indented (bodies of functions; if, for, and while statements, etc.), use two to four spaces for each level of indentation. Be consistent: don't use two spaces for one block of code and four for another.

  8. Correct spelling in comments and code makes the program easier to read and understand.

  9. Lines should be no more than 79 characters wide. Longer lines will "wrap around" when printed, making them ugly and hard to read. Split complex statements across lines at sensible breaking points, using \\ if needed, and indent the continuation lines.

  10. (When turning in hardcopies of your work): Always staple together your source code, followed by test I/O, with pages in the proper order. Loose or out-of-order pages cause frustration for the grader; loose pages also may become lost.

    Do not turn in work in a folder. The grader should not have to take your work out of a folder and put it back in.

  11. Code should be clear, simple, and straightforward to the extent possible. Avoid obscure and bizarre usages and unnecessary complexity.

  12. Code that is not self-explanatory should be documented with comments.

  13. Use spaces to separate the parts of expressions and lists. For example (I am using _ to represent a space more visibly), 5 * (x + 1) is better than 5*(x+1).

    But, do not use spaces to separate parentheses from what they contain. Write (x_+_1), not (_x_+_1_). Likewise, do not space between a list, string, dictionary, or tuple and its subscript. For example, write scholar[i], not scholar [i]. Spacing is not required around the : in a slice operation: myString[2:8] is fine.

  14. Use parentheses if they will help to clarify complex expressions.

  15. Use blank lines to separate distinct sections of code.

  16. If a function is getting too complex, divide it into subproblems, and define a helping function for each of the subproblems. Generally, several short functions are better than a single long function.

  17. Use functions to avoid code repetition. It is hard to give strict rules about this, but here are some rules of thumb:

    1. One complex line repeated two or more times.
    2. Two or more simple lines repeated two or more times.
  18. Use functions to improve code clarity. Sometimes the meaning of a few lines, or even one line, of code can be made clearer by wrapping it in a function definition and giving it a name. This may be true even if the lines are unrepeated.

  19. Write a comment above each function (a "header comment") that explains what its parameters are, what it does, what value it returns, unless this information is perfectly obvious from reading the function's name, return type, and parameter list. The header comment should also explain what conditions must be true before the function is called (preconditions), and what conditions the function guarantees to be true when it returns (postconditions).

  20. Avoid redundant tests in if statements. For example,

    if score > 85:
      return "Good"
    elif score > 50:
      return "So-so"
    else:
      return "Poor"
    

    is preferable to

    if score > 85:
      return "Good"
    elif score > 50 and score <= 85:
      return "So-so"
    elif score <= 50:
      return "Poor"
    
  21. If an if statement has one or more elif clauses, it should end with an else clause to make it sure and clear that all cases have been covered. The else clause might print an error message for an unexpected value.

  22. Use boolean variables and expressions outside the context of an if statement to simplify code. For example,

    return x == y
    

    is preferable to

    if x == y
      return True
    else
      return False
    
  23. Usually, True and False should be used in boolean context rather than 1 and 0 or other values.

Chapter 10: Astronomy: Writing Classes

  1. Variables that are used only by one method should be declared as local variables, within the method, rather than instance variables.
  2. Avoid using the same name for a local variable and an instance variable (shadowing).
  3. Use meaningful and appropriate method names, just as you would use meaningful and appropriate variable names.
  4. Use blank lines to separate methods.
  5. In general, rules for style concerning functions apply also to methods.
  6. Use character-case to distinguish between the names of classes, functions, variables, and constants:
    • Use "camel case" for class names: begin with a capital letter, and capitalize "word parts" within the name.
      • Examples: Point, GeometricObject, SolarSystem
    • Begin variable and function names (this applies also to instance variables and and methods) with a lower-case letter. Either separate "word parts" with underscores, or capitalize following "word parts"; but do it the same way consistently within a program.
      • Examples: bear, bear_facts, live_a_little
      • Alternate examples: bear, bearFacts, liveALittle
    • Use all-upper-case identifiers for constants. Separate word parts with underscores.
      • Examples: PI, FISH_SHAPE
    • Module names should be all lower-case, with word parts separated by underscores.
      • Examples: point, geometric_object, solar_system

Chapter 12: Your Father Was a Rectangle: Inheritance

  1. Design of class hierarchies:
    1. Keep common features as high in the hierarchy as possible. This maximizes software re-use and minimizes the needs of software maintenance.
    2. Override or specialize methods to make exceptions to general rules.
    3. Only use subclasses when there is an "is-a" relationship.
    4. There is no one best class hierarchy for all purposes; think carefully about what design works best for the application.
  2. Use abstract classes to specify behaviors that are required but not (yet) defined.
  3. Avoid shadowing inherited instance variables. Shadowing occurs when a subclass and superclass have instance variables with the same name.
  4. Let each class manage its own data, using constructors, accessors, and mutators.
  5. Use other object-oriented design techniques (in addition to inheritance) to avoid redundancy:
    1. The "has a" relationship: an object can have instance variables that refer to other objects.
    2. Delegation: an object performs a task by asking another object to perform the task.
    3. Polymorphism: different classes can define methods with the same name that behave differently. For example, different shapes draw themselves in different ways.

Reference

Footnote

[1]

Version log:

  • Version 3, 2011 Sep 18. Moved rules for chapter 5 to chapter 3.
  • Version 2, 2009 Nov 18. Added rules for object-oriented programs.
  • Version 1, 2009 Oct 3.