Try   HackMD

CS 410 Python Style Guide

Welcome to the CS410 Python Style Guide. Our mission in this course is to help you uplevel your technical skills while mastering the art of writing clean, consistent code. Trust us, your future self and teammates will thank you!

Why is this important? Clean code isn't just a nice-to-have; it's essential for effective collaboration, maintenance, and readability. This guide will walk you through industry standards and prepare you for the professional world.

Make sure to read through it carefully. We’ll be keeping an eye on your coding style, and repeated issues will lead to point deductions on your homework. But don't worryβ€”we're here to help you build great habits that will benefit you not just in this course, but throughout your entire coding career.

Background

This style guide is built on the best practices outlined in PEP 8 Style Guide for Python Code and PEP 257 Docstring Conventions, the go-to industry standards for writing readable and consistent Python code. PEP 8, created in 2001 by Guido van Rossum, Barry Warsaw, and Alyssa Coghlan, aims to standardize Python code for clarity and uniformity. PEP 257 enhances documentation through clear and consistent docstring conventions. As the PEPs keep evolving with the language, you can be sure they will stay relevant and useful. Stick to these guidelines for happier coding!

Best Practices

Naming Conventions

Variables and Functions

  • Use descriptive names: Give variables and functions names that clearly describe their purpose. For example: user_name, calculate_total.

Modules

  • Lowercase names: Module names should be all lowercase, with words concatenated together. Keep them short but descriptive. For example: mymod.

Classes

  • UpperCamelCase: Classes should be named using nouns that describe what the class models. Class names should use UpperCamelCase. For example: Ocean, TreeHouse.
  • Exceptions: Class names for exceptions should end with β€œError”. For example: BadDataError.

Constants

  • CONSTANT_CASE: Constant names should be all uppercase with words separated by underscores. For example: MY_PYTHON_CONSTANT.

Everything Else

  • snake_case: Functions, fields, parameters, and variables should use snake_case. For example: my_variable, exciting_new_method.

Formatting

Indentation

In Python, indentation is a must. Your code will not compile or run properly if you don’t have the correct indentation. It can be a little finicky, though: if you use spaces to indent in some places and tabs in another your compiler will not be happy.

  • Use 4 spaces: Indent all blocks of code with 4 spaces. Avoid using tabs.
  • Block indentation: A new block is preceded by a colon (:), and the indent level returns to the previous level when the block ends. Example:
def check_adult(age):
    if age >= 18:
        print("You are officially an adult!")
    else:
        print("Not an adult yet...")
  • Configure your editor: Set your editor to insert 4 spaces when the tab key is pressed.
Tip: Configure VSCode to insert 4 spaces when tab is pressed.

In the bottom right of your window in VSCode, there’s a portion that will say β€œSpaces: <number>” or β€œTab Size: <number>.” Click on that and choose β€œIndent using spaces” followed by β€œ4” to have the correct settings. When you’re done you should see β€œSpaces: 4” in the bottom corner of your code window.

Line Wrapping

  • 80 characters max: Lines of code should not exceed 80 characters.

  • Operator on new line: When wrapping lines, the operator should start the new line. For example:

    ​​​​# This is correct
    ​​​​long_argument_name = even_longer_argument_name \
    ​​​​                    + yet_another_even_longer_name
    
    ​​​​# This is not correct
    ​​​​long_argument_name = even_longer_argument_name +
    ​​​​                    yet_another_even_longer_name
    
    ​​​​# This is also not correct
    ​​​​long_argument_name = even_longer_argument_name
    ​​​​                    + yet_another_even_longer_name
    
  • Backslash for wrapping: Use a backslash (\) at the end of a line to indicate continuation. Here's how it may come in handy:

    ​​​​# This is correct now!
    ​​​​long_argument_name = even_longer_argument_name \
    ​​​​                    + yet_another_even_longer_name
    
    ​​​​# And so is this!
    ​​​​long_argument_name = even_longer_argument_name + \
    ​​​​                    yet_another_even_longer_name
    

    Note: When wrapping with the backslash, the wrapped line of code must be indented so that the first character of the wrapped line is in line with the beginning of the expression on the original line (in this case, the equality operator).

Commenting

The general principle of commenting is to clarify / explain your code to an outside observer (or to your future self!).

Implementation Comments

  • Use #: Begin all implementation comments with #.
    ​​# This is a multi-line comment
    ​​# in Python!
    ​​x = 5  # This is an end-of-line comment
    

Type Annotations

  • Type annotations: Include type annotations for all inputs and outputs. Omit output annotations for functions with no return value (e.g., functions that only print).

Documentation Comments (Docstrings)

Also known as a β€œdocstring,” documentation comments in Python appear directly underneath the declaration of each function.

Write docstrings for all functions including helper and nested functions. A good docstring should clearly describe the function's inputs, outputs, and purpose, allowing users to understand the function without needing to look at the body.

  • Use triple quotes: Place docstrings directly under the function declaration.
  • Follow this format:
    • One sentence summary of the function's purpose
    • Parameter descriptions (if any)
    • Return value descriptions (if any)
    • Exceptions thrown (if any)
    • Additional notes (e.g., restrictions, side effects)

Example docstring:

​​def sum(x: float, y: float) -> float:
​​    """Sums two numbers

​​    Parameters:
​​    x -- the first number
​​    y -- the second number

​​    Returns:
​​    A number (the sum of x and y)

​​    Throws:
​​    BadInputError if x or y (or both) is not a number
​​    """

Other Tips

self Keyword

  • Use self: Always use self to access methods and fields within a class. It should be the first parameter of any method in the class.
    ​​class Food:
    ​​    def __init__(self, fruit: str, color: str) -> None:
    ​​        self.fruit = fruit
    ​​        self.color = color
    
    ​​    def show(self) -> None:
    ​​        print("fruit is", self.fruit)
    ​​        print("color is", self.color)
    

Import Statements

  • Importing: You can import specific functions or entire modules.
    ​​from random import randint
    ​​num = randint(1, 10)
    
    ​​import random
    ​​num = random.randint(1, 10)
    
  1. Use constants and helper functions appropriately: Ensure they are not redundant.
  2. Return statements: Write return statements without parentheses.
    ​​​return value
    
  3. if statements: Use newlines for readability.
    ​​​if condition1:
    ​​​    print('condition1')
    ​​​elif condition2:
    ​​​    print('condition2')
    ​​​else:
    ​​​    print('condition3')