# Python Guidance

# 📘 Purpose

This guidance outlines the tools and coding standards we follow to ensure a consistent, readable, and high-quality codebase. By adhering to these practices, we aim to improve collaboration, reduce bugs, and create a smoother development experience for everyone involved.


# 🛠 Tooling

These are the tools we use to help us keep the project in line and improve our dev experience:

  • Black – Auto code formatter
    We use Black to automatically format our code.

    • Ensure the Black extension is installed in VSCode.
    • The .vscode directory contains settings to format code on save.
  • Ruff – Check for common coding mistakes
    Ruff analyzes our code and provides early feedback to catch errors before they become an issue.

  • Pytest – Runs our unit tests
    Used to ensure stability across the codebase.

  • Mypy – Static type checking
    Mypy checks for type-related errors by analyzing code annotations, helping catch bugs and improve code clarity early in development.

  • Bandit – Security check
    Run Bandit to detect security vulnerabilities in the code.

  • .vscode folder
    This folder holds configurations for this project, including:

    • Launch/debug settings.
    • Linting and formatting configurations (on save).

# 🧭 Coding Guidance

  1. Formatting

    • Most formatting is handled by Black.
    • VSCode will auto-format on save using the settings in .vscode.
  2. Linting

    • Your code must be lint-free.
    • Any code with pylint issues will be rejected.
  3. Vertical spacing

    • Vertical spacing is very important.
    • Think of it like writing: just as you break up paragraphs for readability, you should break up blocks of code that represent different ideas or logic.
    • Avoid writing a single "wall of code".

    Bad example:

    def process_data(data):
     result = []
     for item in data:
         if item > 0:
             result.append(item * 2)
         else:
             result.append(0)
     return result

    Good example:

    def process_data(data):
        result = []
    
        for item in data:
            if item > 0:
                result.append(item * 2)
            else:
                result.append(0)
    
        return result
  4. Variable naming

    • Use descriptive variable names.

    Bad example:

    tn = "Infrastructure Automation"

    Good example:

    team_name = "Infrastructure Automation"
  5. Commenting

    • Don’t overuse comment blocks.

    Bad example:

    ####
    # Bad - this takes away from the comment itself
    ####
    tn = "Infrastructure Automation"

    Good example:

    # Good - one comma per line is fine. No need for multiple or to make it a block. It distracts from the code.
    team_name = "Infrastructure Automation"
  6. Function types

    • Always include type annotations in your function signatures.

    Bad example:

       # Bad - Not as helpful to someone using your code.
       def say_hello (name):
          return f"Hi {name}!"
    

    Good example:

       #Good - Helpful because it provides context on what to expect. def say_hello (name: str) -> str:
       return f"Hi {name}!"
  7. Error handling

    • Use try/except properly:
      • Avoid bare excepts
      • Avoid except Exception as e
      • Be specific about what you are catching
    • Make error messages meaningful:
      • "Error"
      • "Failed to parse JSON payload from request"
  8. PEP8 Compliance

    • Class names: CamelCase (e.g., MyClass)
    • Variable names: snake_case, lowercase (e.g., first_name)
    • Function names: snake_case, lowercase (e.g., quick_sort())
    • Constants: SNAKE_CASE, uppercase (e.g., PI = 3.14159)
    • Module names: short, snake_case, lowercase (e.g., numpy)
    • Every function must include a docstring