Skip to main content

Strategy Pattern in Python: Write Flexible, Clean Code

Strategy Pattern in Python: Write Flexible, Clean Code How to pick different algorithms at runtime—without a tangled web of if/else Hey there! Today I want to write about a design pattern:  the Strategy Pattern . Perfect for when you have multiple ways to solve the same problem and you want clean, maintainable code. Why the Strategy Pattern? Let’s start with a scenario: imagine you're building a pizza delivery app, and different restaurants have wildly different APIs. Without planning, you might end up stuffing your code full of branching logic. Instead, the Strategy Pattern lets you isolate each integration into its own “strategy,” making your code neat and flexible. In software design terms, a strategy defines a family of algorithms, each encapsulated in its own class (or callable), and they’re all interchangeable at runtime. This helps avoid massive if/else blocks and makes adding new behavior super easy without touching existing code—hell...

Format Your Python Code with black (Using uv like a Pro)

Keep things clean, fast, and simple—no extra installs needed.

 

Hey there! I want to show you a smooth way to clean up your Python code using black, but with a twist: we’ll use uv to handle it. Why uv you might ask? My short answer: No cluttered virtual environments, no extra installs, just clean code.


Why I Use uv (and you might too)

If you’ve ever felt bogged down setting up virtual environments just to install tools like black, flake8, or pytest, I hear you. uv is a package and project manager that’s fast, one-and-done, and smart (and written in Rust, by the way). It lets you run or install tools in clean, cache-friendly environments, with commands like:

uv tool install black     # keeps black handy on your PATH
uvx black my_code.py      # quick run in a temp environment

Check out the uv docs, especially the "Tools" section, for all the details (Astral Docs).

Step‑by‑Step: Get black Set Up

1. Install uv

(from the Astral Docs)

On macOS or Linux:

curl -LsSf https://astral.sh/uv/install.sh | sh

On Windows:

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Once you’ve got it, test it with:

uv --version

2. Install black for good

To keep black always ready:

uv tool install black

Now you’ll have a black command available anywhere in your terminal.

3. Run black on your code

Run it quickly with:

uvx black path/to/your_project

Or, now that it’s installed, just:

black .

What black Actually Does (and Doesn’t)

Does:

  • Formats code consistently: indentation, spacing, line lengths.

  • Great to pair with --check for CI/CD pipelines.

Doesn’t:

  • black formats import layout but doesn’t sort them alphabetically—that’s isort’s job (black.readthedocs.io).

  • Catch unused variables or linting issues. For that, use tools like flake8, ruff, mypy or pylint.

Configuring black via pyproject.toml

Here’s a starter pyproject.toml snippet you can copy into your repo (from the black docs):

[tool.black]
line-length = 88
target-version = ['py37']
include = '\.pyi?$'
# 'extend-exclude' excludes files or directories in addition to the defaults
extend-exclude = '''
# A regex preceded with ^/ will apply only to files and directories
# in the root of the project.
(
  ^/foo.py    # exclude a file named foo.py in the root of the project
  | .*_pb2.py  # exclude autogenerated Protocol Buffer files anywhere in the project
)
'''

Then format with:

black .

Simple, right?

Bonus: Pairing black with isort

If you do want import sorting, here’s the friendly way to add it. Install isort:

uv tool install isort

Then add this to your pyproject.toml:

[tool.isort]
profile = "black"
line_length = 88

This makes isort format imports in a way that plays nicely with black.

Run them together:

isort .
black .

Or set both as pre-commit hooks in CI, so your code is always clean.


TL;DR

  • uv lets you install/run black (or any tool) without messing with environments.

  • uv tool install black or uvx black . = formatted code, fast.

  • black formats code but doesn't sort imports or check for lint errors.

  • Add isort for imports, and you’re golden.

  • Stick with pyproject.toml for clean configuration, easy sharing.

Why I Think You’ll Like It

I used to create a separate virtualenv just to install black, then swap around to run it. Moving to uv felt like decluttering a messy desk. Now I just run uvx black . and move on.

Want to dig deeper?

So that’s it! A clean, friendly way to format your Python code using black and uv without extra hassle. Give it a try, and let me know how it goes!

Wanna go further? We could cover adding pre-commit hooks, CI setup, or automating formatting on save in your editor. Just say the word!

Comments

Popular posts from this blog

Avoiding Pandas Pitfalls: View vs Copy and Keeping Your Base Dataframe Safe

Avoiding Pandas Pitfalls: View vs Copy and Keeping Your Base DataFrame Safe Ever accidentally changed your original pandas DataFrame without meaning to? I certainly have. It can feel like a debugging nightmare. In this post, I want to walk you through some of the lessons I’ve learned, like how pandas handles views and copies, and how to organize your code so you don't trip over unexpected behavior. Understanding View vs Copy in pandas In pandas, a “view” is just another way of looking at the same data in memory. That means if you change it, the original changes too. A “copy”, on the other hand, is a separate object entirely. What you do with it stays isolated. The problem is that pandas doesn’t always make it obvious whether you're dealing with a view or a copy. Sometimes a slice of a DataFrame gives you a view. Other times it gives you a copy. That inconsistency is the reason behind the infamous SettingWithCopyWarning [1] . For example, if...

Understanding the Python GIL (for Beginners)

What it is, why it matters, and what’s coming in future Python releases. Hey! Let’s talk about something that trips up a lot of developers when they dive into Python threading: the Global Interpreter Lock , or GIL . We will cover the essentials here. This will be a good starting point to decide if you want or need to dig deeper in the topic. What is the GIL? The GIL is a lock inside CPython (the standard Python interpreter). It ensures only one thread executes Python bytecode at a time, even on multi-core machines. See more on Wikipedia and the Python Wiki . It was put in place to manage Python’s internal systems (like memory and reference counting) without race conditions. Without the GIL, Python could crash or corrupt data. That’s why it exists, even if it feels limiting [ 1 ]. How does the GIL affect your code? Single-threaded scripts: No change. The GIL is invisible. I/O-bound tasks (like networking or file access): The G...