Programming
Languages, Git, testing, debugging, algorithms and code quality explained with real examples.
Logging in code: levels, context and what never to record
How to write useful logs in your code: severity levels, messages with context, structured JSON logs and data never to record, with Python examples.
Big O notation explained: the complexity of algorithms
Big O notation explained with examples: O(1), O(log n), O(n), O(n²), how to estimate an algorithm's complexity and why it matters in practice.
Binary search: how it works and why it is easy to get wrong
Binary search explained step by step: requirements, a Python implementation, typical boundary errors and practical uses beyond searching a list.
First programming language: how to choose it wisely
How to choose your first programming language based on your goals: Python, JavaScript, C and others compared, with a concrete study path to follow.
Python data structures: lists, dictionaries, sets and tuples
How to choose the right data structure in Python: lists, tuples, dictionaries, sets, deque and Counter compared, with operation costs and examples.
Concurrency in Python: threads, processes and asyncio compared
Threads, processes and asyncio explained: concurrency versus parallelism, I/O-bound and CPU-bound work, the GIL and how to choose the right approach.
Coupling and cohesion: designing modules that are easy to change
Coupling and cohesion explained with examples: why cohesive, loosely dependent modules make software easier to change, test and understand over time.
Effective code review: what to look for and how to give feedback
How to run a useful code review: change size, what to actually check, how to write constructive comments, and what to leave to automated tooling.
Error handling: exceptions used well, not swept under the rug
How to handle errors in code: when to catch an exception, when to let it propagate, custom exceptions, resource cleanup and mistakes worth avoiding.
Git branching strategies: trunk-based, GitHub flow, Git flow
Trunk-based development, GitHub flow and Git flow compared: how they work, when each one fits, and how to choose a branching strategy for your team.
Git explained properly: commits, branches and merges
Git's core concepts explained clearly: staging area, commits, branches, merges and remotes, with the essential commands you need for everyday work.
Validating input: defensive programming and safer code
How to validate input in code: allowlists, validation at the boundaries, parameterised queries, safe file paths and keeping secrets out of source code.
Technical debt: what it is, how to spot it and pay it back
Technical debt explained concretely: where it comes from, warning signs, how to measure it, explain it to decision makers and pay it back steadily.
Naming things in code: variables and functions that explain
How to choose good names for variables, functions and classes: intent, units of measure, booleans, conventions and mistakes, with before and after.
Python virtual environments: managing dependencies cleanly
What Python virtual environments are, how to create them with venv, pin dependencies in requirements.txt and avoid conflicts between different projects.
Reading a Python stack trace: a line-by-line guide
How to read a Python traceback: call order, exception type, chained exceptions and the most common errors, with examples explained line by line.
Recursion explained simply: base cases and recursive calls
What recursion is and how to think recursively: base case, recursive step, call stack, memoization and when to prefer a loop, with Python examples.
Regular expressions: a practical guide with Python examples
Regular expressions explained with practical Python examples: character classes, quantifiers, groups, anchors, common mistakes and when to avoid them.
Safe refactoring: improving code without breaking it
How to refactor safely: tests as a safety net, small steps, techniques such as extracting functions and renaming, and how to approach legacy code.
Semantic versioning: what version numbers really mean
Semantic versioning explained: MAJOR.MINOR.PATCH, breaking changes, 0.x versions, pre-releases and how to declare dependencies without nasty surprises.
Sorting algorithms: insertion sort, merge sort and quicksort
Sorting algorithms explained clearly: insertion sort, merge sort and quicksort, stability, complexity, and when to rely on the standard library instead.
Systematic debugging: finding bugs with the scientific method
A concrete debugging method: reproduce the problem, form hypotheses, shrink the case, and use debuggers and bisection instead of trial and error.
The testing pyramid: unit, integration and end-to-end tests
What the testing pyramid is and how to balance unit, integration and end-to-end tests to get a test suite that is fast, reliable and genuinely useful.
Unit tests: what to test, how to write them and what to avoid
A practical guide to unit testing: the Arrange-Act-Assert structure, choosing what to check, readable pytest tests and mistakes that make tests brittle.
Clear commit messages: how to write them and why they matter
How to write useful commit messages: a short imperative subject, a body explaining why, atomic commits, and concrete examples of good and bad messages.