Chapter 5 Exercises: Making Decisions — IF, CASE, and Boolean Logic
These exercises progress from basic recall through creative application. Work through them in order — each part builds on the skills practiced in the previous one.
Part A: Recall and Recognition (Remember/Understand)
Exercise 5.1 — State whether each of the following is valid Pascal syntax. If invalid, explain why.
a) if x > 5 then WriteLn('big');
b) if x > 5 then WriteLn('big') else WriteLn('small');
c) if x > 5 then WriteLn('big'); else WriteLn('small');
d) if (x > 5) and (y < 10) then WriteLn('ok');
e) if x > 5 and y < 10 then WriteLn('ok');
Exercise 5.2 — Fill in the blanks:
a) In Pascal, the semicolon is a statement _, not a statement _.
b) The case statement selector must be of an _ type.
c) {$B-} enables _ evaluation of Boolean expressions.
d) De Morgan's Law states that not (A and B) equals ________ or ________.
e) The __ keyword in a case statement handles values not matched by any label.
Exercise 5.3 — Given x := 7, y := 3, and z := 12, evaluate each Boolean expression to True or False:
a) (x > 5) and (y > 5)
b) (x > 5) or (y > 5)
c) not (z < 10)
d) (x > y) and (z > x) and (z > y)
e) not ((x = 7) and (y = 3))
Exercise 5.4 — Explain the dangling else problem. Write a Pascal code fragment that demonstrates it, then show how begin..end resolves the ambiguity.
Exercise 5.5 — Why can you not use a String variable as the selector in a case statement? What could you use instead?
Part B: Tracing and Prediction (Understand/Apply)
Exercise 5.6 — Trace the following code and write the exact output for each input value of n:
program TraceMe;
var
n: Integer;
begin
ReadLn(n);
if n > 0 then
if n > 100 then
WriteLn('Large')
else
WriteLn('Small')
else
WriteLn('Non-positive');
WriteLn('Done');
end.
a) n = 150
b) n = 42
c) n = 0
d) n = -5
Exercise 5.7 — Trace this code for ch := 'G'. What is the output?
case ch of
'A'..'F': WriteLn('Hex digit (letter)');
'0'..'9': WriteLn('Hex digit (number)');
'a'..'f': WriteLn('Lowercase hex digit');
else
WriteLn('Not a hex digit');
end;
Now trace it for ch := 'b' and ch := '5'.
Exercise 5.8 — What is the output of this program?
program BoolTrace;
var
a, b, c: Boolean;
begin
a := True;
b := False;
c := True;
if a and b then
WriteLn('1')
else if a or b then
WriteLn('2')
else
WriteLn('3');
if not b and c then
WriteLn('4')
else
WriteLn('5');
if a or b and c then
WriteLn('6')
else
WriteLn('7');
end.
Explain each result by showing how operator precedence affects the evaluation.
Exercise 5.9 — The following code has a bug. Identify it, explain why it causes incorrect behavior, and fix it.
program BugHunt;
var
temperature: Integer;
begin
Write('Temperature (F): ');
ReadLn(temperature);
if temperature > 90 then
WriteLn('Hot');
WriteLn('Stay hydrated!')
else
WriteLn('Not too hot.');
end.
Exercise 5.10 — Rewrite this deeply nested if using guard clauses (assume the code is inside a procedure):
if age >= 0 then
begin
if age <= 150 then
begin
if name <> '' then
begin
WriteLn('Welcome, ', name, '! Age: ', age);
end
else
WriteLn('Error: name is empty.');
end
else
WriteLn('Error: age too large.');
end
else
WriteLn('Error: age cannot be negative.');
Part C: Short Programs (Apply)
Exercise 5.11 — Write a program that reads an integer and prints whether it is positive, negative, or zero. Use if..then..else.
Exercise 5.12 — Write a program that reads a character and classifies it as: - An uppercase letter (A-Z) - A lowercase letter (a-z) - A digit (0-9) - A space - Other punctuation/symbol
Use a case statement with ranges.
Exercise 5.13 — Write a simple calculator program. Read two real numbers and an operator character (+, -, *, /). Use a case statement on the operator to perform the correct operation. Handle division by zero with an if check. Handle invalid operators with the else clause.
Exercise 5.14 — Write a program that reads a month number (1-12) and prints the number of days in that month. Use a case statement with comma-separated labels for months with the same day count. For February, assume 28 days. (Bonus: also read the year and check for leap years.)
Exercise 5.15 — Write a program that reads a student's numerical score (0-100) and assigns a letter grade using this scale:
| Score | Grade |
|---|---|
| 93-100 | A |
| 90-92 | A- |
| 87-89 | B+ |
| 83-86 | B |
| 80-82 | B- |
| 77-79 | C+ |
| 73-76 | C |
| 70-72 | C- |
| 67-69 | D+ |
| 63-66 | D |
| 60-62 | D- |
| 0-59 | F |
Use a case statement with range labels (hint: use score div 10 or the score itself as the selector).
Exercise 5.16 — Write a program that determines if a given year is a leap year. A year is a leap year if: - It is divisible by 4, AND - It is NOT divisible by 100, UNLESS it is also divisible by 400.
Express this as a single Boolean expression. Then test with these years: 2000, 1900, 2024, 2025.
Exercise 5.17 — Write a program that reads three integers and prints them in ascending order. Use only if statements and temporary variables (no arrays or sorting algorithms).
Part D: Analysis and Debugging (Analyze)
Exercise 5.18 — The following program is supposed to classify a triangle based on its three sides. Find and fix all the bugs (there are at least three).
program Triangle;
var
a, b, c: Integer;
begin
Write('Enter three sides: ');
ReadLn(a, b, c);
if a = b = c then
WriteLn('Equilateral')
else if a = b or b = c or a = c then
WriteLn('Isosceles')
else
WriteLn('Scalene');
end.
Exercise 5.19 — Analyze this code. For what values of x does each branch execute? Are there any unreachable branches?
if x < 0 then
WriteLn('Negative')
else if x < 10 then
WriteLn('Single digit')
else if x < 5 then
WriteLn('Small')
else if x < 100 then
WriteLn('Two digits')
else
WriteLn('Large');
Exercise 5.20 — Rewrite the following if..else if chain as a case statement. If it cannot be directly converted, explain why and propose an alternative.
if month = 1 then WriteLn('January')
else if month = 2 then WriteLn('February')
else if month = 3 then WriteLn('March')
else if month = 4 then WriteLn('April')
else if month = 5 then WriteLn('May')
else if month = 6 then WriteLn('June')
else if month = 7 then WriteLn('July')
else if month = 8 then WriteLn('August')
else if month = 9 then WriteLn('September')
else if month = 10 then WriteLn('October')
else if month = 11 then WriteLn('November')
else if month = 12 then WriteLn('December')
else WriteLn('Invalid month');
Exercise 5.21 — Apply De Morgan's Laws to simplify each expression, then verify with a truth table:
a) not ((x > 0) and (x < 100))
b) not ((a = 1) or (b = 2))
c) not (not (p) or not (q))
Exercise 5.22 — Consider this code with {$B+} (complete Boolean evaluation):
{$B+}
var
x: Integer;
begin
x := 0;
if (x <> 0) and (10 div x > 2) then
WriteLn('Yes')
else
WriteLn('No');
end.
a) What happens when this code runs?
b) What happens if you change {$B+}` to `{$B-}?
c) Rewrite the code so it is safe under both evaluation modes.
Part E: Design and Creation (Apply/Analyze)
Exercise 5.23 — Design and implement a "Rock, Paper, Scissors" game where the user plays against the computer. The computer's choice should be determined by a simple formula (e.g., based on the current second from the clock — see GetTickCount64 or use a fixed sequence for now). Use case for the computer's choice and nested if or case for determining the winner.
Exercise 5.24 — Write a body mass index (BMI) calculator that: 1. Reads height (in meters) and weight (in kilograms). 2. Calculates BMI = weight / (height * height). 3. Validates that height and weight are positive. 4. Classifies the result using these ranges: - Under 18.5: Underweight - 18.5 to 24.9: Normal - 25.0 to 29.9: Overweight - 30.0 and above: Obese 5. Displays the BMI value and classification.
Use guard clauses for validation and if..else if for classification (explain why you cannot use case here).
Exercise 5.25 — Write a simple "20 Questions" style guessing program that identifies an animal through a series of yes/no questions. Use nested if..then..else to build a decision tree that can distinguish between at least 8 animals. Example questions: "Does it fly?", "Does it live in water?", "Is it larger than a dog?"
Draw the decision tree on paper first, then implement it. Comment on how deep the nesting gets and whether the code is readable.
Part M: Mastery Challenge
Exercise 5.26 — The Tax Calculator. Implement a progressive income tax calculator using the following brackets:
| Taxable Income | Rate |
|---|---|
| $0 – $11,000 | 10% |
| $11,001 – $44,725 | 12% |
| $44,726 – $95,375 | 22% |
| $95,376 – $182,100 | 24% |
| $182,101 – $231,250 | 32% |
| $231,251 – $578,125 | 35% |
| Over $578,125 | 37% |
Remember: progressive tax means each bracket applies only to the income within that bracket. Someone earning $50,000 pays 10% on the first $11,000, 12% on the next $33,725, and 22% on the remaining $5,275.
Requirements: - Validate that income is non-negative. - Display the tax owed per bracket and the total tax. - Display the effective tax rate (total tax / total income * 100). - Use named constants for the bracket boundaries.
Exercise 5.27 — Extended PennyWise. Take the PennyWise checkpoint from Section 5.9 and add these features:
a) A "Set Budget" option (menu choice 5) that lets the user set a monthly budget. Validate that the budget is positive. b) When viewing the summary, show how much of the budget remains (budget minus total expenses). If over budget, display a warning. c) When adding an expense, check if this expense would push the total over budget. Warn the user but still allow the expense. d) Add case-insensitive category matching (hint: convert the input to uppercase or lowercase before comparing). e) Add an "About" menu option that displays the program version and author name.
Test with at least five different expense entries, including edge cases (zero amount, negative amount, invalid category, exceeding budget).