7 Coding Fixes That Made Me Write Better Code

Coding Code - My Code Diary

7 Coding Fixes That Made Me Write Better Code

I still remember the day I stared at 400 lines of Python that did exactly one thing badly. It wasn’t broken. It ran. It just made future-me want to go back in time and have a serious conversation with past-me. That was the moment I stopped writing code that “works” and started writing code that lasts.

These aren’t tips you’ll find in a beginner tutorial. They’re the kind of fixes that only make sense after you’ve made the mistake enough times to feel it personally.


1. Stop writing functions that do two things

Here’s the uncomfortable truth: if you have to use “and” to describe what your function does, it’s two functions pretending to be one.

I spent years writing functions like fetch_and_process_data(). Convenient? Sure. Debuggable? Absolutely not. The moment something broke, I had no idea which half was the culprit.

The fix is almost embarrassingly simple split it. One function fetches. One function processes. Suddenly, testing becomes possible and reading becomes pleasant.

def fetch_data(url: str) -> dict:
    response = requests.get(url)
    return response.json()

def process_data(data: dict) -> list:
    return [item for item in data["results"] if item["active"]]

Pro tip: If your function is longer than 20 lines, it’s almost certainly doing too much. Treat that as a trigger to refactor, not a badge of honor.


2. Use type hints like you mean it

Python is dynamically typed, which means it will let you pass a string where you expected a list and not say a word until runtime usually in production, usually at the worst moment.

Type hints don’t make Python statically typed. But they do make your code readable, your IDE smarter, and your teammates less likely to misuse what you wrote.

from typing import Optional

def get_user(user_id: int) -> Optional[dict]:
    return db.query(f"SELECT * FROM users WHERE id = ")

This took me embarrassingly long to adopt. Once I did, I started catching bugs during development that previously only surfaced in testing.


3. Replace nested loops with list comprehensions (carefully)

Nested loops are not inherently evil. But they are often a sign that you haven’t thought hard enough about what you’re trying to express.

The first time I saw someone collapse three nested loops into a single comprehension, I thought they were showing off. Three years later, I do it without thinking.

# Before
result = []
for user in users:
    for order in user["orders"]:
        if order["status"] == "completed":
            result.append(order)

# After
result = [order for user in users for order in user["orders"] if order["status"] == "completed"]

The rule I follow: if the comprehension needs a comment to explain itself, write the loop instead. Cleverness is not clarity.


4. Stop hardcoding configuration values

I once shipped code with a database URL hardcoded as a string literal. It worked perfectly right up until the URL changed and I had to search through fourteen files to fix it.

Environment variables exist for exactly this reason. Use them.

import os
from dotenv import load_dotenv

load_dotenv()

DB_URL = os.getenv("DATABASE_URL")
API_KEY = os.getenv("API_KEY")

This is one of those fixes where the amount of code you write is almost identical, but the professional quality of what you’ve built jumps by an order of magnitude. Recruiters and senior engineers notice.


5. Write the error handling before you need it

Most beginner code treats error handling as an afterthought something you add when things break. The problem with that strategy is that things break in production, not in your local environment.

Get into the habit of writing the try/except block at the same time you write the happy path. Think about what happens when the API doesn’t respond. What happens when the file doesn’t exist?

def load_config(filepath: str) -> dict:
    try:
        with open(filepath, "r") as f:
            return json.load(f)
    except FileNotFoundError:
        raise ValueError(f"Config file not found: {filepath}")
    except json.JSONDecodeError as e:
        raise ValueError(f"Invalid JSON in config file: {e}")

The mindset shift here is subtle but important: you’re not handling errors because things will go wrong. You’re handling errors because you respect the people who will use your code including yourself, six months from now.


6. Use dataclasses instead of raw dictionaries for structured data

Passing dictionaries around feels flexible. It is, until you can’t remember whether the key is "user_id" or "userId" or "id". That bug cost me two hours on a Friday afternoon.

Python’s dataclasses module gives you structure, type hints, and readable __repr__ output with almost no overhead.

from dataclasses import dataclass

@dataclass
class User:
    id: int
    name: str
    email: str
    is_active: bool = True

Now your editor will autocomplete fields. Now your teammate knows exactly what a User looks like. Now you can’t accidentally typo a key that silently returns None.


7. Automate the boring parts seriously, automate them

This is the one that changed how I work more than any other. Not because it makes me a better programmer in theory, but because it saves real time every single day.

Pre-commit hooks are an underused gem. They run checks automatically before every commit formatting, linting, basic tests. You stop thinking about formatting forever.

pip install pre-commit

Then add a .pre-commit-config.yaml:

repos:
  - repo: https://github.com/psf/black
    rev: 23.1.0
    hooks:
      - id: black
  - repo: https://github.com/PyCQA/flake8
    rev: 6.0.0
    hooks:
      - id: flake8

Now every commit is automatically formatted. Every teammate gets consistent code. You never have a code review comment about indentation again. That is a genuinely good use of fifteen minutes.


My Thoughts

None of these are revolutionary. That’s exactly the point. The gap between a programmer who writes code that works and one who writes code that’s a pleasure to maintain isn’t talent, it’s habits. Small decisions, made consistently, over hundreds of commits.

Pick one. Just one. Apply it to whatever you’re building this weekend. Come back to this list in a month and pick another.

The best time to build good habits was when you wrote your first function. The second best time is right now.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top