Conditionals: how to spot decision patterns in code (and everywhere else)
Don't outsource your critical thinking. This essay teaches you how to spot decision patterns and avoid AI slop.
Last time, we covered loops, the part of code that repeats an action. If you haven’t read that one, start here, since conditionals are the piece that usually lives right inside a loop, deciding what happens on each pass.
Why conditionals are worth understanding
Last time, I wrote a short guide on loops for people who don’t write code but increasingly need to understand what it's doing. My anti-slop cheat sheet. Because I believe that even if you don’t code, or if you now code less, the inherent logic behind code is still important to understand. It’s how computers communicate with humans after all. Sure, AI talks to us in natural language (and a lot of us would argue, it uses too many words). But it reasons and acts in code, and then in binary (but we don’t need to go that deep).
And I think if we get too far from the nature of how technology communicates and reasons, we’ll outsource all our critical thinking to the machines that run our lives.
So this is my challenge to you. In your next prototype or project, in that next dashboard you decided to vibe code for your manager, look for loops, and look for conditionals. And ask yourself what they’re doing. Then ask your AI agent, and see if the logic lines up with the output you’re actually looking for.
This is the new kind of literacy. It might seem toilsome in the moment because you’re learning something new (or you’re practicing something old from a new angle), but like a chess grandmaster that put in hours of practice to recognize and anticipate shapes and patterns on the board, once you can spot those shapes inside blocks of code, you’ll start noticing them everywhere rules get made and logic is needed. A policy document, a set of hiring criteria, a pricing tier, an argument someone’s making in a meeting.
So the goal here isn’t code literacy for its own sake. It’s recognizing the shape of a decision clearly enough to sanity-check it and think critically about it.
Are you ready? Let’s dive in.
What’s in a conditional
If loops are about repetition, then conditionals are about decisions. They’re the part of the code that says “it depends” and then spells out exactly what it depends on. They’re an instruction that says: check if something is true, and do a different thing depending on the answer.
The reason conditionals exist in code is the same reason they exist in real life: you constantly make decisions based on circumstances, not on a fixed script.
A real-life conditional you already run
If it’s raining, bring an umbrella. Otherwise, wear sunglasses.
That’s exactly what a conditional does in code. It has:
A condition to check (is it raining?)
An action for when it’s true (bring the umbrella)
An action for when it’s false (wear sunglasses)
How to read a conditional when you see one
You don’t need to understand every symbol, but make sure you ask four questions:
What’s the condition being checked? (A value? A comparison? Multiple things at once?)
What happens if it’s true?
What happens if it’s false, or if there are other cases in between?
What order are the conditions checked in?
If you can answer those four questions, you understand the conditional, and you can start seeing what decision it’s actually making inside the larger system.
The three core patterns
Almost every conditional you’ll encounter in the real world is a version of these three (high-level) patterns.
Pattern 1: the simple if (”do this, only if”)
The most basic version. One condition, one action. If the condition isn’t met, nothing happens.
The idea
If an order is over $100, apply free shipping.
In Python
if order_total > 100:
apply_free_shipping()In JavaScript
if (orderTotal > 100) {
applyFreeShipping();
}In Ruby
if order_total > 100
apply_free_shipping
endIn SQL
UPDATE orders SET free_shipping = TRUE WHERE order_total > 100;What to notice
There’s a condition, and there’s an action that only fires when it’s met.
If the condition is false, the code simply moves on.
SQL hides the “if” inside a WHERE clause rather than spelling it out as a separate step.
Pattern 2: if / else (”do this, otherwise do that”)
This pattern guarantees one of two outcomes always happens. Nothing falls through the cracks.
The idea
If a customer is a returning customer, show them their saved cart. Otherwise, show them a new one.
In Python
if is_returning_customer:
show_saved_cart()
else:
show_new_cart()In JavaScript
if (isReturningCustomer) {
showSavedCart();
} else {
showNewCart();
}In Ruby
if is_returning_customer
show_saved_cart
else
show_new_cart
endIn SQL
SELECT CASE
WHEN is_returning_customer THEN 'saved_cart'
ELSE 'new_cart'
END AS cart_type
FROM customers;What to notice
Every customer lands somewhere. There’s no third option, no gap.
This is the pattern to look for whenever you need certainty that something happens no matter what the input looks like.
SQL’s CASE statement is doing the same job as if/else, just written as an expression (when) instead of a block.
Pattern 3: the chain (”check these, in order, until one fits”)
Sometimes there are more than two possible outcomes. This pattern checks conditions one at a time, top to bottom, and stops at the first one that’s true.
The idea
If a support ticket is urgent, route it to the on-call agent. Otherwise if it’s a billing issue, route it to billing. Otherwise, route it to the general queue.
In Python
if ticket.is_urgent:
route_to_oncall()
elif ticket.category == "billing":
route_to_billing()
else:
route_to_general_queue()In JavaScript
if (ticket.isUrgent) {
routeToOncall();
} else if (ticket.category === "billing") {
routeToBilling();
} else {
routeToGeneralQueue();
}In Ruby
if ticket.urgent?
route_to_oncall
elsif ticket.category == "billing"
route_to_billing
else
route_to_general_queue
endIn SQL
SELECT CASE
WHEN is_urgent THEN 'oncall'
WHEN category = 'billing' THEN 'billing'
ELSE 'general_queue'
END AS routed_to
FROM tickets;What to notice
Order matters here in a way it didn’t in the first two patterns. If a ticket is both urgent and a billing issue, it goes to on-call, because that condition is checked first. Swap the order, and the same ticket goes to billing instead.
This is the pattern behind most routing logic, tiered pricing, and eligibility rules (anywhere there are more than two buckets something can fall into).
One thing to watch for: a chain with no final ‘else’ can leave a case with nowhere to go. If none of the conditions match and there’s no catch-all, the code may do nothing at all.
A quick mental model to take away
Back to real life for a moment:
The simple if is you grabbing an umbrella only if it’s raining, and doing nothing different otherwise.
The if/else is you always leaving the house dressed for something. You’re prepared with rain gear or sunglasses, one or the other, but never neither.
The chain is you checking, in order: is it raining? If yes, grab the umbrella. Is it cold? If yes, grab a coat. On a day that’s both rainy and cold, checking rain first means you walk out with just the umbrella, no coat. Swap the order, and that same day gets you a coat with no umbrella. Either way, you only ever end up with one item, because a chain stops at the first match.
If you actually wanted both the umbrella and the coat on a day that’s rainy and cold, you’d need two separate, independent checks instead of a chain:“if it’s raining, grab the umbrella” and, separately, “if it’s cold, grab the coat.” Each one fires on its own, so nothing has to lose to the other, and the order you check them in stops mattering.
Loops repeat. Conditionals decide. Put them together, and you’ve got most of what code is actually doing, day to day. Not so bad, is it? Now go learn those patterns. Happy thinking!

