2
A variable is a named storage location whose value can change during program execution.
A constant is a named value that does not change once assigned.
## Constants (convention: UPPER_CASE)
Why use constants? If a value like the VAT rate (20%) appears in many places in your code, using A constant VAT_RATE = 0.20 means you only need to change it in one place if the rate changes. This Reduces errors and makes the code easier to maintain.
Data types:
Type Description Example Integer Whole numbers 42, -7, 0 Real/Float Numbers with decimal places 3.14, -0.5 String Text enclosed in quotes ”Hello”, “World’ Character A single character ’A’, ‘7’ Boolean True or False True, False
Type casting converts a value from one type to another:
age_int = int (age_str) # String to integer
price_int = int (price) # Float to integer (truncates to 9)
number_str = str (number) # Integer to string
name = input ( " Enter your name: " )
age = int ( input ( " Enter your age: " ))
print ( " Hello, " + name + " . You are " + str (age) + " years old. " )
Formatted output (f-strings):
print ( f "Hello, { name } . You are { age } years old." )
IF statement:
age = int ( input ( " Enter your age: " ))
print ( " You can work but not vote. " )
print ( " You are too young. " )
Nested IF:
Nested IF pitfall. In the example above, the inner if score >= 70 only executes when score >= 50. If score = 80The output is “Grade A”. If score = 60The output is “Grade C”. If score = 40The output is “Fail”. Think carefully about the nesting order to avoid unreachable Branches.
CASE / SELECT statements (pseudocode):
"C": PRINT "Satisfactory"
OTHERWISE: PRINT "Below expectations"
In Python, this can be simulated with if/elif/else or a dictionary:
print (messages.get(grade, " Below expectations " ))
Count-controlled (FOR loop):
range(start, stop) generates integers from start up to but not including stop. So range(1, 11) gives 1, 2, 3, …, 10.
range(n) is shorthand for range(0, n)Giving 0, 1, …, n-1.
range(start, stop, step) allows a custom step:
for i in range ( 0 , 20 , 5 ):
Condition-controlled (WHILE loop):
number = int ( input ( " Enter a number: " ))
DO…UNTIL loop (pseudocode):
A post-test loop that always executes at least once:
UNTIL number >= 1 AND number <= 10
Python has no built-in DO...UNTIL. The equivalent pattern is:
number = int ( input ( " Enter a number between 1 and 10: " ))
Nested loops:
print (i, " x " , j, " = " , i * j)
The inner loop runs completely for each iteration of the outer loop. For nested loops with n n n and m m m iterations, the total number of iterations is n × m n \times m n × m .
An array is a data structure that stores a fixed number of elements of the same data type, Accessed by an index.
scores = [ 85 , 92 , 78 , 95 , 88 ]
# Accessing elements (0-indexed)
# Iterating over an array
for i in range ( len (scores)):
print ( f "Index { i } : { scores[i] } " )
Common array operations:
scores.append( 76 ) # Add to end
scores.insert( 2 , 90 ) # Insert at index 2
scores.remove( 78 ) # Remove first occurrence of 78
popped = scores.pop() # Remove and return last element
popped = scores.pop( 0 ) # Remove and return first element
index = scores.index( 92 ) # Find index of first occurrence
count = scores.count( 85 ) # Count occurrences
A 2D array is an array of arrays, representing a table or grid.
# Iterating over a 2D array
for row in range ( len (grid)):
for col in range ( len (grid[row])):
print (grid[row][col], end = " " )
Access pattern: grid[row][col] — the first index selects the row, the second selects the Column. Think of a spreadsheet: you pick the row first, then the column.
Practical example: Representing a tic-tac-toe board:
A record is a data structure that groups related data items of different types under a single Name.
Records are useful because they group related data. Instead of having separate variables student_name``student_age``student_formA record keeps them together logically.
A procedure performs a task but does not return a value. A function performs a task and Returns a value.
print ( " Hello, " + name + " ! " )
def calculate_area ( length , width ):
room_area = calculate_area( 5.5 , 3.2 )
print ( " Area: " , room_area)
Why use subprograms?
Reusability: Write once, call many timesAbstraction: The caller does not need to know how the function works internallyModularity: Break a large program into smaller, manageable piecesTesting: Each function can be tested independentlyParameters are variables listed in the function definition. Arguments are the actual values Passed when the function is called.
result = add_numbers( 5 , 3 ) # a=5, b=3
Parameters by value vs. By reference:
By value: A copy of the argument is passed; changes inside the function do not affect the originalBy reference: A reference to the original is passed; changes inside the function affect the originalIn Python, immutable types (int, float, string, tuple) are passed by value. Mutable types (list, Dict) are passed by reference.
items.append( 4 ) # Modifies the original list
n = n + 1 # Does NOT modify the original
print (my_list) # [1, 2, 3, 4]
total = 0 # Global variable
total = total + value # Modifying the global variable
Scope rules: A variable created inside a function is local to that function and cannot be Accessed from outside. A variable created outside any function is global and can be read by any Function, but can only be modified with the global keyword.
Best practice: Use local variables wherever possible to avoid unintended side effects. Global Variables make code harder to debug because any function can modify them.
Recursion is when a function calls itself. Every recursive function must have a base case (stopping condition) to prevent infinite recursion.
return n * factorial(n - 1 ) # Recursive case
print (factorial( 5 )) # 120
Trace: factorial(5) = 5 factorial(4) = 5 4 factorial(3) = 5 4 3 factorial(2) = 5
4 3 2 factorial(1) = 5 4 3 2 1 factorial(0) = 5 4 3 2 1 * 1 = 120. The call stack. Each recursive call adds a new frame to the call stack. For factorial(5)The Stack grows to 6 frames before the base case is reached. Then the frames are unwound as each call Returns. If there is no base case, the stack grows until memory is exhausted, causing a StackOverflowError .
When to use recursion vs iteration: Any recursive function can be rewritten as an iterative Version (using a loop). Iteration is generally more memory-efficient because it does not add frames To the call stack. Recursion is more natural for problems with a self-similar structure, such as Tree traversal or divide-and-conquer algorithms.
print ( len (name)) # 11 (length)
print (name[ 0 ]) # H (first character)
print (name[ - 1 ]) # d (last character)
print (name[ 0 : 5 ]) # Hello (substring from index 0 to 4)
print (name[ 6 : ]) # World (substring from index 6 to end)
print (name.upper()) # HELLO WORLD
print (name.lower()) # hello world
print (name.strip()) # removes leading and trailing whitespace
print (name.replace( " World " , " Python " )) # Hello Python
print (name.split( " " )) # ['Hello', 'World']
print (name.find( " World " )) # 6 (index of first occurrence)
full_name = first_name + " " + last_name
message = " You are " + str (age) + " years old. "
f-strings (formatted string literals) are preferred for readability:
message = f "You are { age } years old."
# Check if input is numeric
password = input ( " Enter a number: " )
print ( " Password is long enough " )
for i in range ( len (word)):
A palindrome reads the same forwards and backwards.
return word == word[ :: - 1 ]
print (is_palindrome( " Racecar " )) # True
print (is_palindrome( " Hello " )) # False
The slice word[::-1] reverses the string. The [::-1] syntax means: start at the end, move Backwards with a step of -1.
file = open ( " data.txt " , " r " )
file = open ( " data.txt " , " r " )
file = open ( " output.txt " , " w " )
file .write( " Hello, World! \n " )
file .write( " Second line \n " )
file = open ( " output.txt " , " a " )
file .write( " Third line \n " )
The with statement automatically closes the file, even if an exception occurs. This is the Recommended approach.
with open ( " data.txt " , " r " ) as file :
with open ( " students.csv " , " r " ) as file :
reader = csv.reader( file )
with open ( " output.csv " , " w " , newline = "" ) as file :
writer = csv.writer( file )
writer.writerow([ " Name " , " Score " ])
writer.writerow([ " Alice " , 92 ])
writer.writerow([ " Bob " , 78 ])
Validation checks that data is sensible and reasonable (but not necessarily correct).
Type Check Example Range check Value is within an acceptable range Age between 0 and 120 Type check Correct data type Input is an integer Length check Correct number of characters Password is 8-20 characters Presence check Data has been entered Name field is not empty Format check Correct pattern (e.g. Email format) Contains @ symbol
print ( " Age must be between 0 and 120. " )
print ( " Please enter a whole number. " )
Comprehensive validation example:
def validate_password ( password ):
return False , " Password must be at least 8 characters. "
if not any (c.isupper() for c in password):
return False , " Password must contain an uppercase letter. "
if not any (c.isdigit() for c in password):
return False , " Password must contain a digit. "
return True , " Password is valid. "
result, message = validate_password( " Password123 " )
Verification checks that data has been entered correctly (matches the source).
Double entry: Data is entered twice and the two entries are comparedVisual check: Data is checked by a person against the original source document numerator = int ( input ( " Enter numerator: " ))
denominator = int ( input ( " Enter denominator: " ))
result = numerator / denominator
print ( " Please enter valid integers. " )
except ZeroDivisionError :
print ( " Cannot divide by zero. " )
How try/except works: Python attempts the code in the try block. If an error occurs, it Immediately jumps to the matching except block. If no error occurs, the except block is skipped.
Writing code that anticipates and handles potential errors:
def get_positive_integer ( prompt ):
value = int ( input (prompt))
print ( " Please enter a positive number. " )
print ( " Please enter a whole number. " )
age = get_positive_integer( " Enter your age: " )
# Random integer between 1 and 10 (inclusive)
dice = random.randint( 1 , 6 )
print ( f "You rolled: { dice } " )
# Random float between 0 and 1
# Random choice from a list
colours = [ " red " , " green " , " blue " ]
choice = random.choice(colours)
Off-by-one errors with arrays. Most languages use 0-based indexing; the last element is at index n − 1 n-1 n − 1 . Accessing array[n] causes an IndexError.Confusing = and ==. A single = is assignment; == is comparison. Writing if x = 5 in Python is a syntax error, but in some pseudocode contexts it can cause subtle bugs.Forgetting to close files. Always close files after use, or use a with statement. Leaving files open can cause data corruption or resource leaks.Infinite loops. Ensure the condition in a WHILE loop will eventually become false. If the loop variable never changes inside the loop body, the loop runs forever.Not handling invalid input. Always validate and handle potential errors in user input. A user might type “abc” when asked for their age.Confusing local and global scope. Use the global keyword only when necessary. Overusing global variables makes code hard to debug and test.Integer division in Python 2 vs Python 3. In Python 3, 5 / 2 gives 2.5. In Python 2, it gives 2. Use // for integer division in Python 3: 5 // 2 gives 2.String immutability. Strings cannot be modified in place. Operations like upper() and replace() return new strings; they do not modify the original.Write a function that takes an array of integers and returns the average.
Write a program that reads 20 numbers from a file, sorts them using bubble sort, and writes the sorted list to another file.
Write a recursive function to calculate the n n n -th Fibonacci number.
Write a program that validates a password: at least 8 characters, contains at least one digit and one uppercase letter.
Write a function that takes a 2D array (3x3) and returns the sum of all elements in the main diagonal.
Write a program that uses a trace table to count the frequency of each character in a string.
Explain the difference between validation and verification, giving an example of each.
Write a program that reads student records from a CSV file and displays the names of students who scored above 80.
Write a function that takes a string and returns True if it is a palindrome (reads the same forwards and backwards).
Write a program that repeatedly asks the user for a number until they enter a valid positive integer, then displays the square root.
(Higher Tier) Write a function that takes two arrays and returns a new array containing elements that appear in both arrays (intersection).
(Higher Tier) Write a program that simulates a simple quiz. It should read questions and answers from a file, display each question, accept the user’s answer, and keep score.
Example 1:
A typical exam question on Programming requires you to apply your knowledge to an unfamiliar context. Read the question carefully, identify the key concept being tested, and structure your answer using the appropriate terminology.
Example 2:
Multi-step problems in Programming often combine two or more concepts. Break the problem down: identify what you need to find, recall the relevant formula or principle, substitute values, and state your answer with correct units or formatting.
A[5_Programming] --> B[Key Concepts]
A --> D[Practical Applications]
B --> E[Fundamental definitions]
D --> G[Real-world usage]
This topic covers the core concepts of programming, including underlying theory, practical implementation, and key applications.
Key concepts include:
arrays and linked lists stacks and queues trees (binary, AVL, BST) hash tables graphs and their representations Understanding these concepts thoroughly is essential for both examinations and practical programming, and requires both theoretical knowledge and hands-on practice.