Programming Fundamentals
Variables, Constants, and Data Types
Variables
A variable is a named storage location in memory whose value can change during program execution. A Variable has a name (identifier), a data type (which determines the kind of data it can hold and how Much memory it occupies), and a value (the data currently stored).
Declaration allocates memory for the variable and associates a name with that location. Initialization assigns an initial value at the point of declaration. Assignment changes the Value stored in the variable after it has been declared.
Constants
A constant is a named storage location whose value cannot change after initialization. Constants Make programs more readable and maintainable by replacing magic numbers with meaningful names. In IB Pseudocode, constants are declared with the CONSTANTS keyword.
CONSTANTS MAX_STUDENTS ← 30 TAX_RATE ← 0.15 SCHOOL_NAME ← "Springfield High"Attempting to reassign a constant is a logic error (or a compilation error in statically typed Languages with constant enforcement).
Primitive Data Types
| Data Type | Description | Typical Size | Example Values |
|---|---|---|---|
| INTEGER | Whole numbers (positive, negative, or zero) | 4 bytes | -42, 0, 1024 |
| FLOAT | Real numbers with fractional parts | 8 bytes | 3.14, -0.001, 1.0e10 |
| CHAR | A single character | 1 byte | ”A’, ‘z’, ‘9’, ’?’ |
| STRING | A sequence of characters | Variable | ”Hello”, “IB CS 2025” |
| BOOLEAN | Logical values | 1 byte | TRUE, FALSE |
INTEGER vs FLOAT: Integers are exact; floating-point numbers have limited precision due to their Binary representation. This matters for comparison. The expression 0.1 + 0.2 = 0.3 may evaluate to FALSE in many languages because 0.1 + 0.2 is stored as 0.30000000000000004.
CHAR vs STRING: A CHAR is a single character. A STRING is a sequence of zero or more characters. In many languages, a STRING is an array of CHARs with a null terminator or a length field.
BOOLEAN: Named after George Boole. Only two values: TRUE and FALSE. Used as the condition in Selection and iteration constructs, and as the return type of functions that perform checks or Comparisons.
Worked Example: Choosing Data Types
A school management system needs to store the following data. Choose the most appropriate data type For each.
| Data Item | Appropriate Data Type | Justification |
|---|---|---|
| Number of students in a class | INTEGER | Whole number, no fractional part needed |
| Student’s average grade (e.g. 85.5) | FLOAT | May have a fractional part |
| Student’s letter grade (A, B, C) | CHAR | Single character |
| Student’s full name | STRING | Multiple characters |
| Whether a student has graduated | BOOLEAN | Only two possible values: TRUE or FALSE |
| Maximum allowed absences (fixed) | CONSTANT INTEGER | Known at design time, never changes |
| School name | CONSTANT STRING | Known at design time, never changes |
| Pi (3.14159…) | CONSTANT FLOAT | Mathematical constant used throughout the program |
Solution
The key principle is to choose the most restrictive type that can represent all possible values. Using INTEGER instead of FLOAT when only whole numbers are needed avoids floating-point precision Issues. Using CHAR instead of STRING for single characters saves memory. Using CONSTANTS for values That should never change prevents accidental modification and makes the code self-documenting.
A common mistake is using FLOAT for values that are always whole numbers (like student counts). Another mistake is using STRING when CHAR suffices (like grade letters).
Operators
Arithmetic Operators
| Operator | Description | Example | Result |
|---|---|---|---|
+ | Addition | 7 + 3 | 10 |
- | Subtraction | 7 - 3 | 4 |
* | Multiplication | 7 * 3 | 21 |
/ | Division | 7 / 3 | 2.33 |
| DIV | Integer division | 7 DIV 3 | 2 |
| MOD | Modulo (remainder) | 7 MOD 3 | 1 |
^ | Exponentiation | 2 ^ 10 | 1024 |
DIV vs /: DIV discards the fractional part (truncates toward zero in most IB pseudocode Contexts). / produces a floating-point result. For 7 / 3DIV gives 2 and / gives 2.333…
MOD: Returns the remainder after integer division. 7 MOD 3 = 1 because 7 = 3 * 2 + 1. MOD is Commonly used to test divisibility (e.g., n MOD 2 = 0 tests if n is even), to wrap indices in Circular data structures, and to extract digits.
Worked Example: DIV and MOD to Extract Digits
Extract the hundreds, tens, and units digits of the number n = 472.
Solution
n ← 472hundreds ← n DIV 100 // 472 DIV 100 = 4remainder ← n MOD 100 // 472 MOD 100 = 72tens ← remainder DIV 10 // 72 DIV 10 = 7units ← n MOD 10 // 472 MOD 10 = 2OUTPUT hundreds, tens, units // Outputs: 4, 7, 2Verification: . Correct.
This pattern generalizes: to extract digit at position (0-indexed from the right), compute n DIV (10^p) MOD 10.
Relational (Comparison) Operators
| Operator | Description | Example | Result |
|---|---|---|---|
= | Equal to | 5 = 5 | TRUE |
<> | Not equal to | 5 <> 3 | TRUE |
< | Less than | 3 < 5 | TRUE |
> | Greater than | 5 > 3 | TRUE |
$\le$ | Less than or equal to | 5 $\le$ 5 | TRUE |
$\ge$ | Greater than or equal to | 5 $\ge$ 3 | TRUE |
Relational operators always produce a BOOLEAN result. They can be applied to numeric types (comparing magnitude) and string types (comparing lexicographically based on character codes).
Logical Operators
| Operator | Description | Truth Table Rule |
|---|---|---|
| NOT | Negation | Reverses the truth value |
| AND | Conjunction | TRUE only when both operands are TRUE |
| OR | Disjunction | TRUE when at least one operand is TRUE |
| XOR | Exclusive | TRUE when operands differ |
Operator precedence (highest to lowest): NOT, AND, OR. This matters in expressions like:
NOT a AND b OR cThis is evaluated as ((NOT a) AND b) OR cNot NOT (a AND (b OR c)). Use parentheses to make Intent explicit.
Assignment Operator
In IB pseudocode, the assignment operator is the left arrow ←. It evaluates the expression on the Right and stores the result in the variable on the left. Assignment is not equality: count ← count + 1 means “take the current value of countAdd 1, and store the result back in count.”
Bitwise Operators
| Operator | Description | Example (binary) | Result |
|---|---|---|---|
| AND | Bitwise AND | 1100 AND 1010 | 1000 |
| OR | Bitwise OR | 1100 OR 1010 | 1110 |
| XOR | Bitwise exclusive OR | 1100 XOR 1010 | 0110 |
| NOT | Bitwise complement (one’s complement) | NOT 1100 | 0011 |
<< | Left shift | 1100 << 1 | 1000 |
>> | Right shift | 1100 >> 1 | 0110 |
Bitwise operators operate on the binary representation of integers. Each bit position is treated Independently. Bitwise AND is used for masking (extracting specific bits), bitwise OR is used for Setting bits, and bitwise XOR is used for toggling bits.
Common Pitfalls: Operators
- Operator precedence confusion: Without parentheses,
2 + 3 * 4evaluates to 14, not 20. Always use parentheses when in doubt:(2 + 3) * 4 = 20. - Integer division surprise:
7 DIV 2gives 3, not 3.5. If a fractional result is needed, use/instead ofDIV. - MOD with negative numbers: The behavior of MOD with negative operands varies between languages. In IB pseudocode, focus on non-negative operands to avoid ambiguity.
- Confusing
=(comparison) with←(assignment): In IB pseudocode these are distinct, but in many programming languages=is assignment and==is comparison. Mixing them up causes logic errors that are hard to spot. - Bitwise vs logical operators:
ANDandORin IB pseudocode are logical operators that work on BOOLEAN values. Bitwise AND/OR work on the binary representation of integers. Do not confuse them.
Control Structures
Sequence
Sequence is the default control structure: statements execute one after another in the order they Appear. Every program is ultimately a sequence of operations, possibly interspersed with selections And iterations.
Selection
Selection allows the program to choose between different paths of execution based on a condition.
IF…THEN…ELSE:
IF grade >= 50 THEN OUTPUT "Pass" passed ← passed + 1 ELSE OUTPUT "Fail" failed ← failed + 1END IFNested IF:
IF score >= 90 THEN OUTPUT "Grade: A" ELSE IF score >= 80 THEN OUTPUT "Grade: B" ELSE IF score >= 70 THEN OUTPUT "Grade: C" ELSE IF score >= 60 THEN OUTPUT "Grade: D" ELSE OUTPUT "Grade: F" END IF END IF END IFEND IFCASE (switch): The CASE structure is cleaner when there are multiple discrete values to compare Against:
CASE OF month 1 : OUTPUT "January" 2 : OUTPUT "February" 3 : OUTPUT "March" ... 12: OUTPUT "December" OTHERWISE OUTPUT "Invalid month"ENDCASECASE is appropriate when the selection is based on a single variable being tested against specific Values. Nested IF is appropriate when conditions involve different variables or ranges.
Worked Example: Tracing a Selection Structure
Trace the following pseudocode with score = 75:
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" END IF END IF END IFEND IFOUTPUT gradeSolution
| Step | Condition Tested | Result | Action |
|---|---|---|---|
| 1 | 75 $\ge$ 90` | FALSE | Skip to ELSE |
| 2 | 75 $\ge$ 80` | FALSE | Skip to ELSE |
| 3 | 75 $\ge$ 70` | TRUE | Grade ← "C" |
| 4 | (inner ELSE skipped) | — | — |
| 5 | Output grade | — | Outputs “C” |
Output: C
Key insight: Nested IF-ELSE IF evaluates conditions top-down. Once a TRUE condition is found, the Corresponding branch executes and all remaining branches are skipped. The order of conditions matters: If they were reversed (checking $\ge$ 60 first), every score of 60 or above would get “D”.
Iteration
FOR loop (counted loop): Executes a fixed number of times.
FOR i ← 1 TO 10 OUTPUT iEND FORThe loop variable i is automatically initialized to 1, incremented by 1 after each iteration, and The loop terminates when i exceeds 10. IB pseudocode also supports stepping:
FOR i ← 10 DOWNTO 1 OUTPUT iEND FORWHILE loop (pre-test conditional loop): Tests the condition before each iteration. The loop body May execute zero times.
WHILE count < target count ← count + 1END WHILEUse WHILE when the number of iterations is not known in advance and the loop may not execute at all.
REPEAT…UNTIL loop (post-test conditional loop): Tests the condition after each iteration. The Loop body always executes at least once.
REPEAT INPUT passwordUNTIL password = correctPasswordUse REPEAT…UNTIL when the loop body must execute at least once (e.g., prompting for input that Must be validated).
Comparison of Loop Constructs
| Feature | FOR | WHILE | REPEAT…UNTIL |
|---|---|---|---|
| Test position | Pre-test | Pre-test | Post-test |
| Minimum runs | 0 | 0 | 1 |
| Known iterations | Yes | No | No |
| Use case | Counting | Unknown count | Input validation |
| Risk | Off-by-one error | Infinite loop | Always runs once |
Nested Loops
A loop inside another loop. The inner loop completes all its iterations for each single iteration of The outer loop.
Worked example: Print a multiplication table for 1 to 5.
FOR i ← 1 TO 5 FOR j ← 1 TO 5 OUTPUT i * j, " " END FOR OUTPUT newLineEND FORThe inner loop executes 5 times for each of the 5 iterations of the outer loop, giving a total of 25 Iterations. For nested loops with outer loop size and inner loop size The total iterations Are .
Common Loop Patterns
Accumulator pattern: Maintain a running total.
total ← 0FOR i ← 1 TO n total ← total + arr[i]END FORCounter pattern: Count occurrences of a condition.
count ← 0FOR i ← 0 TO LENGTH(arr) - 1 IF arr[i] > threshold THEN count ← count + 1 END IFEND FORSentinel pattern: Loop until a special value is encountered.
REPEAT INPUT value IF value <> -1 THEN total ← total + value END IFUNTIL value = -1**Flag pattern:** Use a boolean to signal loop termination.Found ← FALSE I ← 0 WHILE i < LENGTH(arr) AND found = FALSE IF arr[i] = target THEN found ← TRUE END IF i ← i + 1 END WHILE
Common Pitfalls: Loops
- Off-by-one errors: The most common loop bug. For an array of size Valid indices are to . A FOR loop from TO would access index Which is out of bounds. Always trace with boundary values.
- Infinite WHILE loops: If the loop variable is never updated inside the loop body, the condition never changes and the loop runs forever. Always ensure the loop variable moves toward the termination condition.
- Modifying the FOR loop variable: Changing the loop variable inside a FOR loop body (e.g.,
i ← i + 2insideFOR i ← 1 TO 10) produces unpredictable results depending on the language. Use a WHILE loop if you need non-standard stepping. - REPEAT…UNTIL runs at least once: Do not use REPEAT…UNTIL when the loop body might not need to execute at all. If a file could be empty, a REPEAT…UNTIL that reads from it would still execute once with no data.
Procedures and Functions
Procedures
A procedure is a named block of code that performs a specific task. It does not return a value. It Is called for its side effects (e.g., printing output, modifying global state, updating data Structures).
PROCEDURE printStars(n) FOR i ← 1 TO n OUTPUT "*" END FOREND PROCEDUREFunctions
A function is a named block of code that performs a computation and returns a value. Functions Should not have side effects — they should be pure: the same inputs always produce the same output.
FUNCTION factorial(n) RETURNS INTEGER IF n <= 1 THEN RETURN 1 END IF RETURN n * factorial(n - 1)END FUNCTIONParameters and Return Values
Parameters are variables listed in the procedure or function definition that receive values from The caller. Arguments are the actual values passed when the procedure or function is called.
FUNCTION rectangleArea(length, width) RETURNS REAL RETURN length * widthEND FUNCTION
area ← rectangleArea(5.0, 3.0) // 5.0 and 3.0 are argumentsReturn values: A function uses the RETURN statement to send a result back to the caller. Execution of the function terminates immediately when RETURN is encountered. A procedure does not Have a return value.
Side Effects
A side effect occurs when a function or procedure modifies state outside its local scope. Side Effects include modifying global variables, performing I/O, and mutating arguments passed by Reference. Pure functions have no side effects: they depend only on their inputs and produce only a Return value.
Side effects make code harder to reason about, test, and debug because the behavior of a function Depends on the state of the entire program, not just its inputs.
Worked Example: Designing a Function
Write an IB pseudocode function celsiusToFahrenheit(c) that converts a temperature from Celsius to Fahrenheit. Use it to convert 100 degrees and display the result.
Solution
FUNCTION celsiusToFahrenheit(c) RETURNS REAL RETURN c * 9 / 5 + 32END FUNCTION
result ← celsiusToFahrenheit(100)OUTPUT result // Outputs: 212.0The formula converts Celsius to Fahrenheit. This function is pure: it Has no side effects, and the same input always produces the same output.
To convert in the opposite direction, use .
Common Pitfalls: Procedures and Functions
- Calling a procedure like a function: A procedure does not return a value. Writing
result ← printStars(5)is an error becauseprintStarsis a procedure, not a function. - Missing RETURN statement: If a function has a code path that does not execute a RETURN statement, the behavior is undefined. Always ensure every path through a function ends with a RETURN.
- Side effects in functions: A function that modifies a global variable or prints output is not pure. This makes the function harder to test and reason about. Keep functions pure; use procedures for side effects.
- Parameter count mismatch: Calling a function with too many or too few arguments causes an error. Always check the function definition to verify the expected number and types of parameters.
Parameter Passing
By Value (Pass by Value)
A copy of the argument’s value is passed to the parameter. Modifications to the parameter inside the Function do not affect the original argument.
PROCEDURE increment(x) x ← x + 1 OUTPUT xEND PROCEDURE
num ← 10increment(num)OUTPUT num // Outputs 10 (unchanged)The parameter x is a local copy. Changing it has no effect on num.
By Reference (Pass by Reference)
The memory address of the argument is passed to the parameter. Modifications to the parameter inside The function directly affect the original argument.
PROCEDURE increment(REF x) x ← x + 1 OUTPUT xEND PROCEDURE
num ← 10increment(num)OUTPUT num // Outputs 11 (changed)The REF keyword in IB pseudocode indicates pass by reference. The parameter x is an alias for numSo changing x changes num.
Comparison
| Aspect | By Value | By Reference |
|---|---|---|
| What is passed | Copy of the value | Address of the original variable |
| Original affected | No | Yes |
| Memory overhead | Yes (copy created) | No (just an address) |
| Safety | High (original cannot be modified) | Lower (original can be modified) |
| Use case | Input-only parameters | Output parameters, large objects |
| Default in IB | Default | Must specify REF keyword |
Worked Example: Tracing By-Value vs By-Reference
Trace the following pseudocode and predict all outputs:
PROCEDURE swapByValue(a, b) temp ← a a ← b b ← temp OUTPUT a, bEND PROCEDURE
PROCEDURE swapByRef(REF a, REF b) temp ← a a ← b b ← temp OUTPUT a, bEND PROCEDURE
x ← 10y ← 20swapByValue(x, y)OUTPUT x, y
swapByRef(x, y)OUTPUT x, ySolution
swapByValue(x, y) call:
| Variable | Before Call | Inside Procedure | After Call |
|---|---|---|---|
x | 10 | 10 (unchanged) | 10 |
y | 20 | 20 (unchanged) | 20 |
a | — | 20 | — |
b | — | 10 | — |
temp | — | 10 | — |
Inside swapByValue: outputs 20, 10. After call: x = 10``y = 20 (unchanged).
swapByRef(x, y) call:
| Variable | Before Call | Inside Procedure | After Call |
|---|---|---|---|
x | 10 | 20 | 20 |
y | 20 | 10 | 10 |
a | — | 20 (alias for x) | — |
b | — | 10 (alias for y) | — |
Inside swapByRef: outputs 20, 10. After call: x = 20``y = 10 (swapped!).
Complete output sequence: 20, 10, 10, 20, 20, 10, 20, 10
The by-value version appears to work inside the procedure but has no effect on the original Variables. Only by-reference can modify the caller’s variables.
Recursion
Recursion is a problem-solving technique where a function calls itself to solve smaller instances of The same problem. Every recursive solution has two essential components:
Base case: The condition under which the function returns directly without making a recursive Call. Without a base case, the recursion never terminates (infinite recursion), eventually causing a Stack overflow.
Recursive case: The condition under which the function calls itself with a modified argument That moves closer to the base case.
Worked Example: Factorial
FUNCTION factorial(n) RETURNS INTEGER IF n <= 1 THEN RETURN 1 // Base case END IF RETURN n * factorial(n - 1) // Recursive caseEND FUNCTIONCall stack trace for factorial(4):
| Call Stack Frame | Action | Return Value |
|---|---|---|
factorial(4) | Calls factorial(3) | |
factorial(3) | Calls factorial(2) | |
factorial(2) | Calls factorial(1) | |
factorial(1) | Returns 1 (base case) | 1 |
Worked Example: Fibonacci
FUNCTION fibonacci(n) RETURNS INTEGER IF n <= 1 THEN RETURN n END IF RETURN fibonacci(n - 1) + fibonacci(n - 2)END FUNCTIONThis naive recursive Fibonacci has exponential time complexity because each call spawns two Sub-calls. The call tree for fibonacci(5) has 15 calls total. For fibonacci(40)There are over 300 million calls. This demonstrates why recursion must be used carefully — memoization or an Iterative approach is required for practical Fibonacci computation.
Worked Example: Sum of Array
FUNCTION arraySum(arr, index) RETURNS INTEGER IF index >= LENGTH(arr) THEN RETURN 0 END IF RETURN arr[index] + arraySum(arr, index + 1)END FUNCTIONThis is tail-recursive (the recursive call is the last operation). Some compilers optimize tail Recursion into iteration to avoid stack growth.
When to Use Recursion vs Iteration
| Criterion | Recursion | Iteration |
|---|---|---|
| Readability | Clearer for tree/graph traversal, divide and conquer | Clearer for simple loops |
| Memory | Uses call stack ( stack frames) | auxiliary space |
| Performance | Function call overhead | Generally faster |
| Risk | Stack overflow for deep recursion | No stack overflow risk |
| Natural fit | Tree traversal, fractals, backtracking | Linear processing, counting |
Worked Example: Tracing a Recursive Function
Trace mystery(4) where:
FUNCTION mystery(n) RETURNS INTEGER IF n = 1 THEN RETURN 1 END IF RETURN n + mystery(n - 1)END FUNCTIONSolution
| Call Stack Frame | Action | Return Value |
|---|---|---|
mystery(4) | Calls mystery(3) | |
mystery(3) | Calls mystery(2) | |
mystery(2) | Calls mystery(1) | |
mystery(1) | Returns 1 (base case) | 1 |
Result: 10
This function computes the sum . It is equivalent to the formula .
The recursive case reduces the problem: mystery(4) needs mystery(3)Which needs mystery(2) Which needs mystery(1). The base case stops the recursion. Each return value propagates back up The call stack.
Common Pitfalls: Recursion
- No base case or unreachable base case: Without a valid base case, recursion is infinite. For
factorial(n)withn = -1The base casen \lt{}= 1is never reached because the recursive call usesn - 1Making the argument more negative each time. - Stack overflow: Each recursive call adds a frame to the call stack. For deep recursion (e.g., naive
fibonacci(1000)), the stack exceeds available memory. Prefer iteration for problems requiring many levels. - Redundant computation: Naive recursive Fibonacci makes calls because it recomputes the same values repeatedly. Use memoization (caching results) or convert to iteration for efficiency.
Programming Paradigms
Procedural Programming
Programs are structured as a sequence of instructions that operate on data. Data and functions are Separate. The focus is on “what to do” step by step. Variables are shared globally or passed between Procedures.
Characteristics: Top-down design, stepwise refinement, procedures and functions, global and Local scope, sequential execution.
Languages: C, Pascal, Fortran, BASIC.
Strengths: Simple to understand for small programs, efficient execution, close to hardware.
Weaknesses: Difficult to maintain for large programs, data is not protected (global variables Can be modified anywhere), limited code reuse.
Object-Oriented Programming (OOP)
Programs are organized around objects that combine data (attributes) and behavior (methods). Objects Are instances of classes, which define the structure and behavior.
Characteristics: Encapsulation, inheritance, polymorphism, abstraction, classes and objects, Message passing.
Languages: Java, Python, C++, C#.
Strengths: Data hiding and protection, code reuse through inheritance, natural modeling of Real-world entities, easier maintenance of large systems.
Weaknesses: Steeper learning curve, runtime overhead from objects and method dispatch, can be Overkill for simple programs.
Functional Programming
Programs are structured as a composition of pure functions. Data is immutable — once created, it Cannot be changed. Functions are first-class citizens (they can be passed as arguments, returned as Values, and stored in data structures).
Characteristics: Pure functions, immutability, higher-order functions, recursion instead of Loops, function composition.
Languages: Haskell, Lisp, Erlang, F#.
Strengths: No side effects (easier to reason about, test, and debug), natural support for Parallelism (no shared mutable state), mathematical elegance.
Weaknesses: Can be less intuitive for stateful problems, immutability can lead to performance Overhead (creating new copies of data structures), steep learning curve for imperative programmers.
Paradigm Comparison
| Aspect | Procedural | OOP | Functional |
|---|---|---|---|
| Primary unit | Procedure/function | Object/class | Function |
| Data | Separate from logic | Encapsulated in objects | Immutable |
| State | Global/local vars | Object state | No mutable state |
| Reuse | Libraries | Inheritance, composition | Higher-order functions |
| Side effects | Common | Controlled by encapsulation | Avoided |
| Parallelism | Manual | Manual | Natural |
Worked Example: Identifying Programming Paradigms
Identify the programming paradigm demonstrated by each code snippet.
Solution
Snippet 1:
total ← 0FOR i ← 0 TO LENGTH(scores) - 1 total ← total + scores[i]END FORaverage ← total / LENGTH(scores)OUTPUT averageParadigm: Procedural. The program is a sequence of instructions operating on data. Variables are Separate from the operations. There are no objects, no encapsulation, and no pure function Composition.
Snippet 2:
CLASS Student PRIVATE name : STRING PRIVATE grade : INTEGER
PUBLIC PROCEDURE setName(n) name ← n END PROCEDURE
PUBLIC FUNCTION getGrade() RETURNS INTEGER RETURN grade END FUNCTIONEND CLASS
s ← NEW Student()s.setName("Alice")OUTPUT s.getGrade()Paradigm: Object-Oriented. Data (name, grade) and behavior (setName, getGrade) are encapsulated In a class. Access is controlled with PRIVATE/PUBLIC modifiers. An object is created with NEW.
Snippet 3:
FUNCTION applyDiscount(price, discount) RETURNS REAL RETURN price - price * discountEND FUNCTION
FUNCTION addTax(amount, rate) RETURNS REAL RETURN amount + amount * rateEND FUNCTION
finalPrice ← addTax(applyDiscount(100.0, 0.1), 0.05)Paradigm: Functional. Functions are pure (no side effects, no shared state). The result is built By composing function calls. Data is never mutated — new values are computed and returned.
Pseudocode and Flowchart Conventions
IB Pseudocode Standard
The IB defines a specific pseudocode standard. Key elements:
Variable assignment: variable ← expression
Input/output: INPUT variable``OUTPUT expression
Selection: IF ... THEN ... ELSE IF ... ELSE ... END IF
Case selection: CASE OF ... ENDCASE
Counted loop: FOR variable ← start TO end ... END FOR
Pre-test loop: WHILE condition ... END WHILE
Post-test loop: REPEAT ... UNTIL condition
Procedures: PROCEDURE name(params) ... END PROCEDURE
Functions: FUNCTION name(params) RETURNS type ... END FUNCTION
Arrays: Zero-indexed, arr[i]``matrix[i, j]
Comments: Use // for single-line comments.
Nassi-Shneiderman Diagrams
Nassi-Shneiderman diagrams (also called structorgrams) are a structured alternative to traditional Flowcharts. They eliminate the need for flow lines (arrows) by using nested rectangular blocks. This Enforces structured programming — there is no way to represent a GOTO or unstructured branching.
The diagram uses three fundamental structures:
- Process block: A simple rectangle containing a sequence of statements.
- Selection block: A rectangle divided into sections. For IF/ELSE, the block is split vertically into two parts (true and false branches). For CASE, the block is divided into multiple columns.
- Iteration block: A rectangle with a condition at the top and the loop body below. For WHILE loops, the condition is tested first. For REPEAT…UNTIL loops, the body appears first and the condition appears at the bottom.
Nassi-Shneiderman diagrams are particularly useful for illustrating structured algorithms because They make the nesting of control structures visually explicit. They cannot represent unstructured Jumps, which is both a strength (enforcing good practice) and a limitation (cannot represent certain Low-level algorithms).
Worked Example: Converting a Problem Description to IB Pseudocode
Problem: Read 10 exam scores from the user, calculate the average, and output “Above average” if The average is greater than 60, otherwise output “At or below average.”
Solution
CONSTANTS NUM_SCORES ← 10 PASS_THRESHOLD ← 60
total ← 0FOR i ← 1 TO NUM_SCORES INPUT score total ← total + scoreEND FOR
average ← total / NUM_SCORESIF average > PASS_THRESHOLD THEN OUTPUT "Above average: ", average ELSE OUTPUT "At or below average: ", averageEND IFKey decisions:
- Used a CONSTANT for
NUM_SCORESandPASS_THRESHOLDto make the code self-documenting and easy to modify. - Used a FOR loop because the number of iterations is known (10).
- Used the accumulator pattern to maintain a running total.
- Used IF/THEN/ELSE for the final selection based on the computed average.
Debugging and Testing
Error Types
Syntax errors: Violations of the language’s grammar rules. Detected at compile time (or parse Time for interpreted languages). The program will not run until all syntax errors are fixed.
Examples: missing semicolons, mismatched parentheses, misspelled keywords, undeclared variables.
Logic errors: The program runs without crashing but produces incorrect results. The code does Something different from what the programmer intended. Logic errors are the most difficult to find Because the program appears to work.
Examples: off-by-one errors in loop bounds, incorrect comparison operators, wrong formula, using Assignment (=) instead of comparison (==) in a condition.
Runtime errors: Errors that occur during program execution. The program compiles successfully But crashes or produces unexpected behavior when run.
Examples: division by zero, array index out of bounds, stack overflow from infinite recursion, null Pointer dereference, insufficient memory.
Debugging Strategies
Trace tables: Systematically record the value of each variable at each step of execution. This Is the primary debugging technique in IB examinations.
FUNCTION mystery(n) RETURNS INTEGER result ← 0 i ← 1 WHILE i <= n result ← result + i * i i ← i + 1 END WHILE RETURN resultEND FUNCTIONTrace with n = 3:
| Step | i | n | result | i $\le$ n | result + i * i |
|---|---|---|---|---|---|
| 1 | 1 | 3 | 0 | True | 0 + 1 = 1 |
| 2 | 2 | 3 | 1 | True | 1 + 4 = 5 |
| 3 | 3 | 3 | 5 | True | 5 + 9 = 14 |
| 4 | 4 | 3 | 14 | False | — |
The function returns 14, which is . It computes the sum of squares.
Worked Example: Selecting Test Data
A function getLetterGrade(score) accepts an integer score from 0 to 100 and returns a letter grade (A: 90-100, B: 80-89, C: 70-79, D: 60-69, F: 0-59). Identify appropriate test data for each Category.
Solution
| Category | Test Input | Expected Output | Rationale |
|---|---|---|---|
| Normal | 85 | B | Typical value within a grade range |
| Normal | 42 | F | Typical value in another range |
| Boundary | 90 | A | Lowest score for grade A |
| Boundary | 89 | B | Highest score for grade B (boundary between A and B) |
| Boundary | 60 | D | Lowest score for grade D |
| Boundary | 0 | F | Lowest possible score |
| Boundary | 100 | A | Highest possible score |
| Erroneous | -5 | Error message | Below valid range |
| Erroneous | 105 | Error message | Above valid range |
| Erroneous | ”abc” | Error message | Wrong data type (string instead of integer) |
Boundary values are the most likely to reveal off-by-one errors. Always test the exact boundary and One value on each side.
Print statements (dry running): Insert output statements at key points to observe variable Values during execution.
Breakpoints: Pause execution at a specific line and inspect the program state. Available in IDEs.
Rubber duck debugging: Explain the code line by line to an inanimate object (or a colleague). The act of verbalizing often reveals the error.
Testing Strategies
Unit testing: Testing individual functions or procedures in isolation. Each unit test provides a Specific input and checks whether the output matches the expected result. A comprehensive test suite Covers normal cases, boundary cases, and error cases.
Integration testing: Testing the interactions between multiple units (functions, modules, Components) to ensure they work together correctly.
System testing: Testing the entire system as a whole to verify that it meets all requirements.
Black-box testing: Testing without knowledge of the internal code. Tests are based on the Specification: given these inputs, the expected output is X.
White-box testing: Testing with knowledge of the internal code. Tests are designed to exercise Specific paths, branches, and conditions in the code.
Test Data Categories
| Category | Description | Example (function: isEven(n)) |
|---|---|---|
| Normal | Typical inputs within the expected range | isEven(4) returns TRUE |
| Boundary | Values at the edge of valid ranges | isEven(0) returns TRUE |
| Erroneous | Invalid inputs that should be rejected | isEven(-1) returns FALSE |
| Extreme | Very large or very small values | isEven(2147483646) returns TRUE |
Worked Example: Constructing an Advanced Trace Table
Trace the following function with arr = [5, 3, 8, 1, 8, 3] and target = 8:
FUNCTION countAndFind(arr, target) RETURNS INTEGER count ← 0 firstIndex ← -1 i ← 0 WHILE i < LENGTH(arr) IF arr[i] = target THEN count ← count + 1 IF firstIndex = -1 THEN firstIndex ← i END IF END IF i ← i + 1 END WHILE OUTPUT "First at: ", firstIndex, " Count: ", count RETURN countEND FUNCTIONSolution
| Step | i | arr[i] | arr[i] = target | count | firstIndex | firstIndex = -1 |
|---|---|---|---|---|---|---|
| Init | 0 | — | — | 0 | -1 | — |
| 1 | 0 | 5 | FALSE | 0 | -1 | — |
| 2 | 1 | 3 | FALSE | 0 | -1 | — |
| 3 | 2 | 8 | TRUE | 1 | 2 | TRUE (was -1) |
| 4 | 3 | 1 | FALSE | 1 | 2 | — |
| 5 | 4 | 8 | TRUE | 2 | 2 | FALSE (not -1) |
| 6 | 5 | 3 | FALSE | 2 | 2 | — |
| 7 | 6 | — | — | 2 | 2 | — (loop ends) |
Output: First at: 2, Count: 2
The function returns 2. It finds the first occurrence of 8 at index 2 and counts 2 total occurrences.
Common Pitfalls: Debugging and Testing
- Incomplete trace tables: Every variable that changes must have a column. Forgetting to include a variable (like the loop counter
i) means the trace is incomplete and may miss errors. - Testing only normal cases: A test suite that only tests valid inputs within the expected range will miss boundary and error cases. Always include boundary values (0, 1, maximum) and invalid inputs.
- Confusing syntax errors with logic errors: A program that compiles successfully can still produce wrong results. Fixing compilation errors does not guarantee correctness. Always verify output against expected results.
- Not testing edge cases: For a function that processes an array, test with an empty array, a single-element array, and an array where all elements are the same. These edge cases often reveal bugs.
Exception Handling
Exception handling is a mechanism for managing runtime errors gracefully without crashing the Program. When an exceptional condition occurs (e.g., division by zero, file not found, invalid Input), an exception object is created and “thrown.” The program can “catch” the exception and take Corrective action.
Try-Catch-Finally Pattern
TRY result ← numerator / denominator OUTPUT resultCATCH error OUTPUT "Error: Division by zero"FINALLY OUTPUT "Calculation attempted"END TRYThe TRY block contains the code that might throw an exception. The CATCH block handles the Exception if one occurs. The FINALLY block executes regardless of whether an exception occurred — It is used for cleanup operations like closing files or releasing resources.
Worked Example: Exception Handling in Practice
Write IB pseudocode that prompts the user for two integers and outputs their quotient. Handle the case Where the second number is zero.
Solution
LOOP TRY INPUT numerator INPUT denominator IF denominator = 0 THEN RAISE "DivisionError" END IF result ← numerator / denominator OUTPUT numerator, " / ", denominator, " = ", result EXIT // Success: leave the loop CATCH error IF error = "DivisionError" THEN OUTPUT "Error: Cannot divide by zero. Try again." ELSE OUTPUT "Unexpected error: ", error END IF END TRYEND LOOPKey points:
- The
RAISEstatement explicitly triggers an exception when an invalid condition is detected (denominator is zero). - The
TRYblock contains the risky operation. TheCATCHblock handles the specific error type. - The outer LOOP ensures the user is re-prompted until they provide valid input. The
EXITstatement is only reached on success. - Multiple error types can be distinguished within the CATCH block using conditional logic.
Common Pitfalls by Construct
Selection:
- Using
=(assignment) instead of==(comparison) in conditions. In IB pseudocode this is less of an issue since=is the comparison operator, but in languages like C/Java this is a frequent bug. - Forgetting the
ELSEbranch when all cases should be handled, leading to silent failures. - Overlapping conditions in nested IF statements, where a later condition can never be reached because an earlier one already covers it.
Iteration:
- Off-by-one errors: using
$\le$instead of<(or vice versa) in loop conditions. Always verify with boundary values. - Infinite loops: forgetting to update the loop variable in a WHILE loop, or setting a condition that can never become false.
- Modifying the loop variable inside the loop body (in a FOR loop), which can produce unexpected behavior depending on the language.
- Fence-post errors: looping one time too many or one time too few. For an array of size Valid indices are to .
Recursion:
- Missing base case, causing infinite recursion and stack overflow.
- Base case that is never reached, e.g.,
factorial(-1)callsfactorial(-2)Which callsfactorial(-3)And so on indefinitely. - Excessive recursion depth for problems that could be solved iteratively, leading to performance degradation.
- Redundant recursive calls that recompute the same values, leading to exponential time complexity (as in the naive Fibonacci implementation).
Parameters:
- Passing by value when by reference is needed (the original variable will not be modified).
- Passing by reference when by value is intended (the original variable will be unexpectedly modified).
- Modifying a by-value parameter and expecting the change to persist after the function returns.
Data types:
- Integer overflow: exceeding the maximum representable value. For a 32-bit signed integer, the range is to . Adding 1 to the maximum produces (wrap around).
- Floating-point precision: comparing floating-point numbers for exact equality is unreliable due to rounding errors. Use a tolerance:
ABS(a - b) < epsilonwhere epsilon is a small value like . - Type coercion: implicitly converting between types (e.g., integer to float) can cause unexpected results. In some languages,
7 / 2gives 3 (integer division), while7.0 / 2gives 3.5.
Problem Set: 15 IB-Style Questions
Q1. State the most appropriate primitive data type for each of the following: (a) The number of students in a school (b) A student’s phone number (e.g., “555-1234”) (c) Whether a user is an administrator (d) A single menu option character (A, B, C, or Q) (e) The current temperature to one decimal place
Solution
(a) INTEGER — student count is a whole number. (b) STRING — phone numbers contain hyphens and may start with 0; they are not used for arithmetic, so STRING is more appropriate than INTEGER. (c) BOOLEAN — only two states: administrator or not. (d) CHAR — exactly one character from a known set. (e) FLOAT — has a fractional part (one decimal place).
Revision: Variables and Data Types
Q2. Evaluate the following IB pseudocode expression step by step, showing the result after each Operator:
result ← (17 DIV 4) + (17 MOD 4) * 2 ^ 3 - 1Solution
Following operator precedence (parentheses first, then exponentiation, then multiplication, then Addition/subtraction):
| Step | Expression | Result |
|---|---|---|
| 1 | 17 DIV 4 | 4 |
| 2 | 17 MOD 4 | 1 |
| 3 | 2 ^ 3 | 8 |
| 4 | 1 * 8 (MOD result times power) | 8 |
| 5 | 4 + 8 (DIV result plus product) | 12 |
| 6 | 12 - 1 | 11 |
result = 11
Revision: Operators, Operator Precedence
Q3. Given a ← TRUE``b ← FALSE``c ← TRUEEvaluate each expression: (a) NOT a AND b (b) a OR b AND c (c) NOT (a OR b) XOR c (d) (a AND b) OR (NOT b AND c)
Solution
(a) NOT a AND b = NOT TRUE AND FALSE = FALSE AND FALSE = FALSE
(b) a OR b AND c = TRUE OR FALSE AND TRUE = TRUE OR FALSE = TRUE (AND has higher precedence than OR)
(c) NOT (a OR b) XOR c = NOT (TRUE OR FALSE) XOR TRUE = NOT TRUE XOR TRUE = FALSE XOR TRUE = TRUE
(d) (a AND b) OR (NOT b AND c) = (TRUE AND FALSE) OR (TRUE AND TRUE) = FALSE OR TRUE = TRUE
Revision: Logical Operators, Operator Precedence
Q4. Explain the difference between "apple" < "banana" and "Zebra" < "apple" in terms of string Comparison. What will each expression evaluate to?
Solution
String comparison is lexicographic, based on character codes (e.g., ASCII/Unicode values).
"apple" < "banana"evaluates to TRUE because ‘a’ (code 97) \lt{} ‘b’ (code 98). The first character differs, so the comparison is decided immediately."Zebra" < "apple"evaluates to TRUE because ‘Z’ (code 90) \lt{} ‘a’ (code 97). Uppercase letters have lower character codes than lowercase letters.
This is a common source of bugs: case-sensitive comparison means “Zebra” sorts before “apple” Alphabetically. To perform case-insensitive comparison, convert both strings to the same case first.
Revision: Relational Operators, Data Types
Q5. Trace the following pseudocode with score ← 55 and state the output:
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" END IF END IF END IFEND IFOUTPUT gradeSolution
| Step | Condition | Result | Action |
|---|---|---|---|
| 1 | 55 $\ge$ 90` | FALSE | Check next |
| 2 | 55 $\ge$ 80` | FALSE | Check next |
| 3 | 55 $\ge$ 70` | FALSE | Check next |
| 4 | 55 $\ge$ 60` | FALSE | Check next |
| 5 | (else branch) | — | grade ← "F" |
| 6 | — | — | OUTPUT “F” |
Output: F
Revision: Selection, Nested IF
Q6. Rewrite the following nested IF statement as a CASE statement:
IF day = 1 THEN OUTPUT "Monday" ELSE IF day = 2 THEN OUTPUT "Tuesday" ELSE IF day = 3 THEN OUTPUT "Wednesday" ELSE IF day = 4 THEN OUTPUT "Thursday" ELSE IF day = 5 THEN OUTPUT "Friday" ELSE IF day = 6 OR day = 7 THEN OUTPUT "Weekend" ELSE OUTPUT "Invalid" END IF END IF END IF END IF END IFEND IFSolution
CASE OF day 1 : OUTPUT "Monday" 2 : OUTPUT "Tuesday" 3 : OUTPUT "Wednesday" 4 : OUTPUT "Thursday" 5 : OUTPUT "Friday" 6 : OUTPUT "Weekend" 7 : OUTPUT "Weekend" OTHERWISE OUTPUT "Invalid"ENDCASECASE tests against specific values, so days 6 and 7 each need their own line pointing to “Weekend”. The OTHERWISE clause handles any value outside 1—7. CASE is more readable here because we are comparing A single variable against discrete values, but CASE cannot directly express day = 6 OR day = 7 as a Single condition.
Revision: Selection, CASE Statement
Q7. What is the output of the following pseudocode?
FOR i ← 1 TO 4 output ← "" FOR j ← 1 TO i output ← output + "*" END FOR OUTPUT outputEND FORSolution
Outer i | Inner j range | output built | OUTPUT |
|---|---|---|---|
| 1 | 1 to 1 | * | * |
| 2 | 1 to 2 | ** | ** |
| 3 | 1 to 3 | *** | *** |
| 4 | 1 to 4 | **** | **** |
Output:
**********The inner loop runs i times for each value of the outer loop, producing a triangle pattern. Total Inner loop iterations: .
Revision: Iteration, Nested Loops
Q8. Write IB pseudocode that reads positive integers from the user until the user enters 0. The Program should then output the sum, count, and average of all numbers entered (excluding the 0).
Solution
sum ← 0count ← 0REPEAT INPUT value IF value > 0 THEN sum ← sum + value count ← count + 1 END IFUNTIL value = 0
IF count > 0 THEN average ← sum / count OUTPUT "Sum: ", sum OUTPUT "Count: ", count OUTPUT "Average: ", average ELSE OUTPUT "No positive numbers were entered."END IFKey points:
- REPEAT…UNTIL ensures the prompt appears at least once.
- The
value > 0check excludes both 0 (sentinel) and negative numbers. - The final IF/ELSE handles the edge case where the user enters 0 immediately (avoiding division by zero).
Revision: Iteration, REPEAT…UNTIL, Selection
Q9. Explain the key difference between a WHILE loop and a REPEAT…UNTIL loop. For each scenario, State which loop is more appropriate and explain why: (a) Validating user input (must prompt at least once) (b) Processing items in a queue that may be empty (c) Searching for a value in a sorted array using binary search
Solution
Key difference: WHILE is a pre-test loop (condition checked before the body; may execute zero Times). REPEAT…UNTIL is a post-test loop (condition checked after the body; always executes at Least once).
(a) REPEAT…UNTIL — The user must see the prompt at least once before they can provide input. Post-test is correct because the body must run at least once.
(b) WHILE — If the queue is empty, there is nothing to process. The loop should not execute at All. Pre-test is correct.
(c) WHILE — Binary search may terminate immediately if the search range is empty (e.g., searching An empty array). Pre-test is correct.
Revision: Iteration, WHILE, REPEAT…UNTIL
Q10. How many times does the statement OUTPUT i, j execute in total?
FOR i ← 0 TO 4 FOR j ← i TO 4 OUTPUT i, j END FOREND FORSolution
Outer i | Inner j values | Inner iterations |
|---|---|---|
| 0 | 0, 1, 2, 3, 4 | 5 |
| 1 | 1, 2, 3, 4 | 4 |
| 2 | 2, 3, 4 | 3 |
| 3 | 3, 4 | 2 |
| 4 | 4 | 1 |
Total: times.
The inner loop’s starting value depends on the outer loop variable, so the number of inner iterations Decreases as i increases. This is the triangular number .
Revision: Nested Loops, FOR Loop
Q11. Write an IB pseudocode function isPrime(n) that returns TRUE if n is a prime number and FALSE otherwise.
Solution
FUNCTION isPrime(n) RETURNS BOOLEAN IF n < 2 THEN RETURN FALSE END IF IF n = 2 THEN RETURN TRUE END IF IF n MOD 2 = 0 THEN RETURN FALSE END IF i ← 3 WHILE i * i <= n IF n MOD i = 0 THEN RETURN FALSE END IF i ← i + 2 END WHILE RETURN TRUEEND FUNCTIONOptimizations:
- Check divisibility by 2 separately, then only test odd divisors (step by 2).
- Only test up to (since if and Then ). In pseudocode,
i * i $\le$n avoids needing a square root function. - Time complexity: Which is efficient for the values tested in IB exams.
Revision: Functions, Iteration, WHILE Loop, Operators (MOD)
Q12. Trace the following pseudocode and state the final values of a``bAnd c:
PROCEDURE modify(REF x, y, REF z) x ← x + y y ← y * 2 z ← x + zEND PROCEDURE
a ← 5b ← 3c ← 10modify(a, b, c)OUTPUT a, b, cSolution
| Step | Action | a | b | c | x | y | z |
|---|---|---|---|---|---|---|---|
| 1 | Initialize | 5 | 3 | 10 | — | — | — |
| 2 | Call modify(a, b, c) | 5 | 3 | 10 | 5 | 3 | 10 |
| 3 | x ← x + y (REF to a) | 8 | 3 | 10 | 8 | 3 | 10 |
| 4 | y ← y * 2 (copy of b) | 8 | 3 | 10 | 8 | 6 | 10 |
| 5 | z ← x + z (REF to c) | 8 | 3 | 18 | 8 | 6 | 18 |
| 6 | Procedure returns | 8 | 3 | 18 | — | — | — |
Final values: a = 8, b = 3, c = 18
x (REF to a) and z (REF to c) are aliases, so changes persist. y is a copy of bSo Changes to y do not affect b.
Revision: Parameter Passing, By Value, By Reference
Q13. Construct a trace table showing the evaluation of factorial(5). How many stack frames are Created, and what is the final return value?
Solution
FUNCTION factorial(n) RETURNS INTEGER IF n <= 1 THEN RETURN 1 END IF RETURN n * factorial(n - 1)END FUNCTION| Call | n | Base case? | Action | Return value |
|---|---|---|---|---|
factorial(5) | 5 | No | Calls factorial(4) | |
factorial(4) | 4 | No | Calls factorial(3) | |
factorial(3) | 3 | No | Calls factorial(2) | |
factorial(2) | 2 | No | Calls factorial(1) | |
factorial(1) | 1 | Yes | Returns 1 (base case) | 1 |
Stack frames created: 5 (one for each call from factorial(5) down to factorial(1))
Final return value: 120
Returns are resolved bottom-up: factorial(1) returns 1, then factorial(2) returns Then factorial(3) returns And so on up to factorial(5) Returning .
Revision: Recursion, Call Stack, Functions
Q14. The following function is intended to return the sum of all elements in an array. It contains A logic error. Identify the error, explain why it is wrong, and provide the corrected version.
FUNCTION arrayTotal(arr) RETURNS INTEGER total ← 0 FOR i ← 1 TO LENGTH(arr) total ← total + arr[i] END FOR RETURN totalEND FUNCTIONSolution
Error: The FOR loop starts at i ← 1 and goes to LENGTH(arr). Since IB pseudocode arrays are Zero-indexed, the loop accesses arr[1] through arr[LENGTH(arr)]. This means:
arr[0]is never included in the sum (off-by-one, first element missed).arr[LENGTH(arr)]is out of bounds and causes a runtime error.
Corrected version:
FUNCTION arrayTotal(arr) RETURNS INTEGER total ← 0 FOR i ← 0 TO LENGTH(arr) - 1 total ← total + arr[i] END FOR RETURN totalEND FUNCTIONThe corrected loop runs from index 0 to LENGTH(arr) - 1Covering every valid index exactly once.
Error type: Logic error (also causes a runtime error due to out-of-bounds access).
Revision: Iteration, FOR Loop, Arrays, Debugging
Q15. Write IB pseudocode for a program that repeatedly asks the user to enter a student’s score (0—100). The program should:
- Reject scores outside the range 0—100 and ask again.
- Stop when the user enters -1.
- After stopping, output the number of valid scores entered and the average score.
Solution
CONSTANTS MIN_SCORE ← 0 MAX_SCORE ← 100 SENTINEL ← -1
total ← 0count ← 0LOOP INPUT score IF score = SENTINEL THEN EXIT END IF IF score >= MIN_SCORE AND score <= MAX_SCORE THEN total ← total + score count ← count + 1 ELSE OUTPUT "Invalid score. Enter a value between 0 and 100." END IFEND LOOP
IF count > 0 THEN average ← total / count OUTPUT "Valid scores entered: ", count OUTPUT "Average score: ", average ELSE OUTPUT "No valid scores were entered."END IFKey points:
- A sentinel value (-1) signals the end of input. It is checked first, before validation.
- Constants make the code readable and easy to modify.
- Input validation rejects invalid scores and prompts again without counting them.
- The final IF/ELSE prevents division by zero if no valid scores were entered.
Revision: Iteration, Selection, Constants, Operators, Exception Handling
Common Pitfalls
Forgetting edge cases in algorithm design (e.g., empty input, single element, already sorted data).
Forgetting that average-case for quicksort becomes worst-case on already sorted input.
Misunderstanding the difference between a stack (LIFO) and a queue (FIFO) in data structure applications.
Mixing up Big O, Big , and Big notation — Big O is an upper bound, not necessarily tight.
Cross-References
| Topic | Site | Link |
|---|---|---|
| [Programming Constructs] | A-Level | View |
| [Programming Constructs] | IB | View |
| [Programming Constructs] | DSE | View |
Summary
The key principles covered in this topic are linked in the sub-pages above. Focus on understanding the definitions, applying the formulas or frameworks, and evaluating strengths and limitations of each approach.
Worked Examples
Worked examples demonstrating the application of key concepts are covered in the detailed sub-pages linked above.