Theory: Worked Example, dateFashion
This worksheet takes a short specification written in words all the way to test cases: causes and effects, the logic, the cause-effect graph, the decision table, and one test per rule. The professor came back to it in the review class (Lecture 9), with one tip that makes the whole method much easier.
From the slides: the specification. int dateFashion(int you, int date). You and your date want a table at a restaurant.
you and date = how stylish your clothes are, from 0 to 10.
- Return 2 (yes) if either of you is very stylish (8 or more).
- Exception: if either of you has style 2 or less, return 0 (no).
- Otherwise return 1 (maybe).
The Professor’s Tip: Turn the Words into Simple Code First
The professor said that finding the cause-effect graph directly from the words of a specification is hard. It is much easier to first turn the words into a small, simple program (pseudocode). Once you have the code:
- the conditions in the
if statements become the causes,
- the return values become the effects.
It is like translating a long recipe paragraph into a numbered checklist before you cook: the steps were always there, but now you can see them. The professor also said to keep the code as simple as possible, because a decision table cannot handle complex statements well.
int dateFashion(int you, int date) {
if (you <= 2 || date <= 2) // causes 1, 3
return 0; // effect 70: no (the exception wins)
else if (you >= 8 || date >= 8) // causes 2, 4
return 2; // effect 72: yes
else
return 1; // effect 71: maybe
}
Why the “2 or less” check comes first
The specification says “exception”: that rule beats everything, even a very stylish partner. In the professor’s words, it “trumps everything”. So in the code it must be tested first. If you checked “8 or more” first, a stylish person with a scruffy date, say (9, 2), would wrongly get a table.
Common mistake: forgetting precedence. The first low-style condition wins. U = 9 and D = 2 must return No, not Yes, even though someone is very stylish. A table or code that checks ”≥ 8” first gets this wrong.
Step 1: Causes and Effects
| Cause | Condition | | Effect | Return value |
|---|
| 1 (c1) | you <= 2 | | 70 | 0 (no) |
| 2 (c2) | you >= 8 | | 71 | 1 (maybe) |
| 3 (c3) | date <= 2 | | 72 | 2 (yes) |
| 4 (c4) | date >= 8 | | | |
The professor numbered the causes 1 to 4 and took the effect numbers 70, 71, 72 from the slides.
Step 2: The Logic, Remembering What “else” Means
Each branch of an if / else if / else chain is reached only when every earlier condition was false. So “else” means NOT of everything before it.
- 70 (no) comes from the first
if: 70=1∨3.
- 72 (yes) comes from an
else if, so the first if must have been false: 72=(1∨3)′∧(2∨4).
- 71 (maybe) comes from the
else, so the if and the else if must both have been false: 71=(1∨3)′∧(2∨4)′.
Diagram loads as you scroll.
To reach MAYBE you must answer “no” twice, and each “no” is a NOT.
Exam radar: the professor stressed this rule and posted it again for the class:
maybe=(1∨3)′∧(2∨4)′
with both NOTs. Expanding with De Morgan, maybe = 1′∧3′∧2′∧4′: all four causes are false. Forgetting the second NOT turns “maybe” into the formula for “yes”.
Step 3: The Cause-Effect Graph
Two OR nodes group the causes (“someone is ≤ 2”, “someone is ≥ 8”). The “no” rule wins, so it is NOT-ed on its way to both YES and MAYBE; MAYBE also needs the NOT of “someone is ≥ 8”.
Diagram loads as you scroll.
Step 4: The Decision Table
The professor reminded the class: in a decision table, all the entries in one rule (one column) are joined by AND. An OR cannot fit in one column, so every OR must be split into separate rules:
- 70 = 1 ∨ 3 becomes two rules: T1 (1 is true) and T2 (3 is true).
- 72 also becomes two rules: T3 (2 is true) and T4 (4 is true), both with 1 and 3 false.
- 71 is one rule: all four false.
Conditions that do not matter in a rule get an X.
| Conditions / Effects | T1 | T2 | T3 | T4 | T5 |
|---|
| 1: you ≤ 2 | 1 | X | 0 | 0 | 0 |
| 2: you ≥ 8 | X | X | 1 | X | 0 |
| 3: date ≤ 2 | X | 1 | 0 | 0 | 0 |
| 4: date ≥ 8 | X | X | X | 1 | 0 |
| 70: no (0) | 1 | 1 | 0 | 0 | 0 |
| 71: maybe (1) | 0 | 0 | 0 | 0 | 1 |
| 72: yes (2) | 0 | 0 | 1 | 1 | 0 |
Some inputs match two rules, for example (1, 1) matches T1 and T2, but those rules give the same effect, so the table stays consistent. Every one of the 11×11=121 possible inputs matches at least one rule, and the rules it matches give the same answer as the code: the table is complete.
Step 5: One Test Case per Rule
| Rule | (you, date) | Expected |
|---|
| T1 | (2, 5) | 0 (no) |
| T2 | (5, 1) | 0 (no) |
| T3 | (8, 5) | 2 (yes) |
| T4 | (5, 9) | 2 (yes) |
| T5 | (5, 5) | 1 (maybe) |
How to write the answer: extra marks. Notice that c1 and c2 can never both be 1 (nobody is ≤ 2 and ≥ 8 at once); the same holds for c3 and c4. So add an E constraint between c1 and c2, and between c3 and c4. And a good tester adds BVA: (3, 5) → 1 and (7, 7) → 1 sit just inside the “maybe” zone, and (9, 2) → 0 checks that the exception really wins.
Worked Examples
Exercise 1
Using cause-effect graphing, derive the decision table and test cases for dateFashion. (Exam-style answer.)
Show solution ↓Hide solution ↑
Solution
Causes: c1 you <= 2, c2 you >= 8, c3 date <= 2, c4 date >= 8 (E constraint between c1, c2 and between c3, c4).
Effects: e70 = return 0 (no), e71 = return 1 (maybe), e72 = return 2 (yes).
Logic (in AND form):
e70=c1+c3e72=c1′⋅c3′⋅(c2+c4)e71=c1′⋅c2′⋅c3′⋅c4′Decision table and tests (each OR split into separate rules):
| T1 | T2 | T3 | T4 | T5 |
|---|
| c1 | 1 | X | 0 | 0 | 0 |
| c2 | X | X | 1 | X | 0 |
| c3 | X | 1 | 0 | 0 | 0 |
| c4 | X | X | X | 1 | 0 |
| output | 0 | 0 | 2 | 2 | 1 |
| test (you, date) | (2, 5) | (5, 1) | (8, 5) | (5, 9) | (5, 5) |
Why this gets marks: causes and effects listed, the logic in AND form, X for don’t care, one test case per rule with its expected output.
Exercise 2
Write the logic for “maybe” (effect 71) and explain why it needs two NOTs.
Show solution ↓Hide solution ↑
Solution
“Maybe” is the else branch. An else is reached only when every condition before it was false: the first if (1 ∨ 3) and the else if (2 ∨ 4). Each “was false” is a NOT, so
71=(1∨3)′∧(2∨4)′Apply De Morgan to each bracket (“break the line, change the sign”):
71=1′∧3′∧2′∧4′Maybe = all four causes false. With only the first NOT, (1∨3)′∧(2∨4) is exactly the formula for yes, so leaving out the second NOT makes “maybe” and “yes” the same, which is wrong.
Exercise 3
What should dateFashion(9, 2) return? Which rule of the decision table covers it, and why is it a valuable test?
Show solution ↓Hide solution ↑
Solution
date = 2, so cause 3 (date <= 2) is true. The exception “trumps everything”, so the answer is 0 (no), even though you = 9 is very stylish.
It matches T2 (c3 = 1, everything else X) and gives effect 70. ✓
It is valuable because it combines a “yes” cause (c2) with a “no” cause (c3). A program that checked “8 or more” before “2 or less” would return 2 here. This test checks that the exception really wins, which is exactly the precedence trap.
Exercise 4
Add boundary value tests to the five rule-based tests. For each, give the expected result and say what it checks.
Show solution ↓Hide solution ↑
Solution
The boundaries are between 2 and 3 (the “no” edge) and between 7 and 8 (the “yes” edge). Keep the other input in the safe middle (5) so only one edge is tested at a time:
| Test (you, date) | Expected | What it checks |
|---|
| (2, 5) | 0 | on the “no” edge for you (already T1) |
| (3, 5) | 1 | just inside “maybe” above the low edge |
| (7, 5) | 1 | just inside “maybe” below the high edge |
| (8, 5) | 2 | on the “yes” edge for you (already T3) |
| (5, 2) | 0 | on the “no” edge for date |
| (5, 3) | 1 | just inside “maybe” for date |
| (5, 7) | 1 | just inside “maybe” for date |
| (5, 8) | 2 | on the “yes” edge for date |
| (7, 7) | 1 | both inputs just below 8: still maybe |
| (9, 2) | 0 | the exception wins over “yes” |
A programmer who wrote you < 2 instead of you <= 2 is caught by (2, 5); one who wrote you > 8 is caught by (8, 5).
Exercise 5
For each input, say which rules of the T1–T5 table match and give the output: (a) (8, 8), (b) (1, 1), (c) (2, 9), (d) (7, 3).
Show solution ↓Hide solution ↑
Solution
Work out the four causes first, then find the matching columns.
| Input | c1 | c2 | c3 | c4 | Matching rules | Output |
|---|
| (a) (8, 8) | 0 | 1 | 0 | 1 | T3 and T4 | 2 |
| (b) (1, 1) | 1 | 0 | 1 | 0 | T1 and T2 | 0 |
| (c) (2, 9) | 1 | 0 | 0 | 1 | T1 | 0 |
| (d) (7, 3) | 0 | 0 | 0 | 0 | T5 | 1 |
In (a) and (b) two rules match, but both give the same effect, so the table is still consistent. In (c), c4 is true but c1 wins: T4 needs c1 = 0, so it does not match. ✓ Each output agrees with the code.
Exercise 6
A shop’s rule: orders of 10 items or more get free shipping, except that orders to remote areas never get free shipping; otherwise shipping is charged. Following the professor’s tip, write the simple code first, then the causes, effects and logic for each effect.
Show solution ↓Hide solution ↑
Solution
Simple code. The exception wins, so it is checked first:
String shipping(int items, boolean remote) {
if (remote) // cause 1
return "charged"; // effect A
else if (items >= 10) // cause 2
return "free"; // effect B
else
return "charged"; // effect C
}
Causes: 1 = the address is remote; 2 = items ≥10.
Logic, remembering that “else” means NOT of everything before:
- A (charged, remote) =1.
- B (free) =1′∧2.
- C (charged, normal) =1′∧2′.
Decision table:
| R1 | R2 | R3 |
|---|
| 1: remote | 1 | 0 | 0 |
| 2: items ≥ 10 | X | 1 | 0 |
| output | charged | free | charged |
| test (items, remote) | (12, yes) | (10, no) | (9, no) |
R2 and R3 use the boundary values 10 and 9, and R1 uses 12 items, so it also checks that the exception beats a large order. ✓