1) Forming Correct Conditions
Decision logic starts with a condition: an expression that evaluates to TRUE or FALSE. Precise conditions make branching predictable and easy to read. Your goal is to express the rule directly, with minimal mental translation.
Keep comparisons simple and direct
- Prefer positive statements:
IF isMemberinstead ofIF NOT (isNotMember). - Prefer one comparison per idea:
IF age >= 18instead of mixing multiple concepts into one long line. - Use clear boundaries for ranges, and decide whether endpoints are included.
Example: a score range rule is clearer when written as explicit bounds.
IF score >= 90 AND score <= 100 THEN ...Avoid double negatives
Double negatives increase mistakes because readers must invert logic mentally. Rewrite the variable or the condition so it reads naturally.
| Harder to read | Clearer |
|---|---|
IF NOT (NOT isActive) | IF isActive |
IF NOT (status != "PAID") | IF status = "PAID" |
IF NOT (age < 18) | IF age >= 18 |
Be careful with AND/OR grouping
When conditions mix AND and OR, add parentheses to show intent. This prevents subtle bugs caused by operator precedence assumptions.
IF (isStudent AND hasID) OR isStaff THEN allowEntryIf the rule is actually “students must have ID, staff always allowed,” the parentheses above match that meaning. If the rule is “anyone with ID who is student or staff,” you would write:
Continue in our app.
You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.
Or continue reading below...Download the app
IF (isStudent OR isStaff) AND hasID THEN allowEntryPrefer named helper conditions for complex rules
If a condition becomes long, extract parts into well-named boolean variables (or helper checks). This keeps the branching readable without changing the logic.
isValidScore = (score >= 0 AND score <= 100) IF isValidScore THEN ...2) Writing Binary Decisions (IF/ELSE) with Symmetrical Branches
A binary decision chooses between exactly two paths. The most readable IF/ELSE blocks are symmetrical: both branches do comparable kinds of work (e.g., both assign a value, or both output a message), and they leave the program in a consistent state.
Pattern: assign once, then use
Instead of duplicating later steps in both branches, assign a result inside the branches and use it afterward.
IF orderTotal >= 50 THEN shippingFee = 0 ELSE shippingFee = 6.99 ENDIF totalDue = orderTotal + shippingFeePattern: handle error vs success clearly
When one branch is an error path, keep it short and explicit, and ensure the success branch still reads cleanly.
IF quantity <= 0 THEN OUTPUT "Quantity must be positive" ELSE lineTotal = quantity * unitPrice OUTPUT lineTotal ENDIFStep-by-step checklist for a clean IF/ELSE
- Write the condition as a positive, direct statement.
- Ensure both branches set the same key outputs (variables, messages, next step).
- Avoid doing half of a task in one branch and the other half outside; either both branches complete the task, or both only set a result.
- After the
ENDIF, the reader should know which variables are guaranteed to be set.
3) Multi-Branch Logic (ELSE IF Chains and CASE/SWITCH-Style Pseudocode)
Multi-branch logic selects one path from many. Two common forms are (a) an ELSE IF chain for ordered rules, and (b) a CASE/SWITCH style for matching one value against multiple options.
ELSE IF chains: best for ordered ranges and priority rules
Use an ELSE IF chain when the first matching condition should win, especially with numeric ranges (scores, weights, ages) or priority-based policies (VIP overrides standard).
Worked example: grading rules (ordered conditions + default)
Rules:
- Score must be between 0 and 100, otherwise grade is
"INVALID". - 90–100:
"A" - 80–89:
"B" - 70–79:
"C" - 60–69:
"D" - 0–59:
"F"
Step-by-step ordering logic:
- First, validate the input range (so later branches can assume it’s valid).
- Then, check from highest threshold down to lowest to avoid overlaps.
- End with a default branch that catches the remaining valid range.
IF score < 0 OR score > 100 THEN grade = "INVALID" ELSE IF score >= 90 THEN grade = "A" ELSE IF score >= 80 THEN grade = "B" ELSE IF score >= 70 THEN grade = "C" ELSE IF score >= 60 THEN grade = "D" ELSE grade = "F" ENDIFNotice how each threshold is simple (score >= 90, score >= 80, etc.). Because the checks are ordered from high to low, you do not need to write score < 90 in the B branch; it is already implied by earlier branches failing.
CASE/SWITCH: best for matching discrete values
Use CASE when one variable is compared to several specific values (status codes, menu choices, shipping methods). This can be clearer than a long ELSE IF chain.
CASE paymentStatus OF "PAID": action = "SHIP" "PENDING": action = "HOLD" "FAILED": action = "CANCEL" OTHERWISE: action = "REVIEW" ENDCASEGuidelines for CASE-style pseudocode:
- Use it when each branch depends on the same variable.
- Include an
OTHERWISE(default) branch to handle unexpected values. - Keep each branch similar in shape (e.g., each sets
action).
4) Common Pitfalls (and How to Avoid Them)
Pitfall: overlapping conditions
Overlaps happen when more than one branch could be true. In an ELSE IF chain, only the first true branch runs, so overlaps can silently produce wrong results.
Example of overlap:
IF score >= 60 THEN grade = "PASS" ELSE IF score >= 50 THEN grade = "BORDERLINE" ELSE grade = "FAIL" ENDIFHere, a score of 65 matches the first branch (fine), but the second branch is not truly “50–59”; it’s “50+” and is partially overlapped by the first. Fix by ordering and using thresholds that partition the space:
IF score >= 60 THEN grade = "PASS" ELSE IF score >= 50 THEN grade = "BORDERLINE" ELSE grade = "FAIL" ENDIFThis specific example is actually correct because of ordering, but it is still easy to misread. A clearer rewrite makes the intended range explicit:
IF score >= 60 THEN grade = "PASS" ELSE IF score >= 50 AND score <= 59 THEN grade = "BORDERLINE" ELSE grade = "FAIL" ENDIFUse explicit bounds when readability matters more than brevity, especially for beginners or critical rules.
Pitfall: unreachable branches
An unreachable branch can never run because earlier conditions already cover all possibilities.
IF age >= 18 THEN group = "ADULT" ELSE IF age >= 21 THEN group = "21+" ELSE group = "MINOR" ENDIFThe age >= 21 branch is unreachable because any age 21+ already satisfies age >= 18. Fix by ordering from most specific to most general:
IF age >= 21 THEN group = "21+" ELSE IF age >= 18 THEN group = "ADULT" ELSE group = "MINOR" ENDIFPitfall: missing default case
If you do not include an ELSE (or OTHERWISE in CASE), you may leave variables unset or ignore unexpected inputs.
Example (missing default):
CASE size OF "S": fee = 5 "M": fee = 7 "L": fee = 10 ENDCASEIf size is "XL", fee is never set. Add a default branch:
CASE size OF "S": fee = 5 "M": fee = 7 "L": fee = 10 OTHERWISE: fee = 0 ENDCASEDepending on the situation, the default might set a safe value (0), raise an error, or route to manual review.
Pitfall: gaps in ranges
Gaps occur when some values match no branch. This is common when writing numeric ranges with mixed < and <=.
Example gap (score 90 is missed):
IF score > 90 THEN grade = "A" ELSE IF score >= 80 AND score < 90 THEN grade = "B" ELSE grade = "C" ENDIFFix by deciding the boundary rule and applying it consistently:
IF score >= 90 THEN grade = "A" ELSE IF score >= 80 THEN grade = "B" ELSE grade = "C" ENDIFPitfall: conditions that are correct but hard to read
Even correct logic can be difficult to maintain if it’s written in a tangled way. Prefer small, named checks and straightforward comparisons over cleverness.
isFreeShipping = (isMember AND orderTotal >= 25) OR (orderTotal >= 50) IF isFreeShipping THEN shippingFee = 0 ELSE shippingFee = 6.99 ENDIF