B2.1.1 Construct, trace programs with variables (AO3)
B2.1.1_1 Data types: Boolean, char, decimal, integer, string
Example Program (Python)
# Declare variables with appropriate data types
student_name = "Alice" # String: Stores textual data
is_passing = True # Boolean: True/False for logical conditions
grade1 = 85 # Integer: Whole number for grades
grade2 = 90
weight = 75.5 # Decimal (float): For precise numerical values
initial = 'A' # Char (string of length 1): Single character
# Calculate average grade
average = (grade1 + grade2) / 2
# Output results
print(f"Student: {student_name}, Initial: {initial}")
print(f"Average Grade: {average}")
print(f"Passing: {is_passing}")
student_name = "Alice" # String: Stores textual data
is_passing = True # Boolean: True/False for logical conditions
grade1 = 85 # Integer: Whole number for grades
grade2 = 90
weight = 75.5 # Decimal (float): For precise numerical values
initial = 'A' # Char (string of length 1): Single character
# Calculate average grade
average = (grade1 + grade2) / 2
# Output results
print(f"Student: {student_name}, Initial: {initial}")
print(f"Average Grade: {average}")
print(f"Passing: {is_passing}")
Tracing the Program
- Initialize: student_name = "Alice", is_passing = True, grade1 = 85, grade2 = 90, weight = 75.5, initial = 'A'
- Calculate: average = (85 + 90) / 2 = 87.5
- Output: Prints "Student: Alice, Initial: A", "Average Grade: 87.5", "Passing: True"
Boolean
- Stores True or False for logical conditions
- Example: is_passing = grade >= 60
Char
- Single character (in Python, a string of length 1)
- Example: initial = 'A'
Decimal (Float)
- Represents numbers with decimal points
- Example: weight = 75.5 for precise measurements
Integer
- Whole numbers for counts or discrete values
- Example: grade1 = 85
String
- Text data for names, descriptions, etc.
- Example: student_name = "Alice"
Purpose
- Selecting appropriate data types ensures accurate data storage, manipulation, and program functionality
- Tracing verifies program logic by tracking variable changes and confirming expected outputs
B2.1.2 Construct programs for substring manipulation (AO3)
B2.1.2_1 Identify, extract, alter, concatenate, replace substrings
Identify
- Locate specific substrings using methods like find() or index()
- Example: text = "Hello World"; pos = text.find("World") returns 6
Extract
- Retrieve a portion using slicing or substring methods
- Example: text = "Hello World"; substring = text[6:11] extracts "World"
Alter
- Modify parts by creating a new string with changes
- Example: text = "hello"; text = text.upper() results in "HELLO"
Concatenate
- Combine strings using + operator or join() method
- Example: first = "Hello"; last = "World"; full = first + " " + last
Replace
- Substitute a substring using replace() method
- Example: text = "Hello World"; new_text = text.replace("World", "Python")
Example Program (Python)
# Program to manipulate a string
text = "Welcome to IB Computer Science"
# Identify: Find position of substring
pos = text.find("Computer")
print(f"Position of 'Computer': {pos}") # Output: 11
# Extract: Get substring
substring = text[11:19]
print(f"Extracted substring: {substring}") # Output: Computer
# Alter: Convert to uppercase
upper_text = substring.upper()
print(f"Uppercase substring: {upper_text}") # Output: COMPUTER
# Concatenate: Add prefix
new_text = "Subject: " + text
print(f"Concatenated: {new_text}") # Output: Subject: Welcome to IB Computer Science
# Replace: Change substring
replaced_text = text.replace("Computer Science", "Programming")
print(f"Replaced text: {replaced_text}") # Output: Welcome to IB Programming
text = "Welcome to IB Computer Science"
# Identify: Find position of substring
pos = text.find("Computer")
print(f"Position of 'Computer': {pos}") # Output: 11
# Extract: Get substring
substring = text[11:19]
print(f"Extracted substring: {substring}") # Output: Computer
# Alter: Convert to uppercase
upper_text = substring.upper()
print(f"Uppercase substring: {upper_text}") # Output: COMPUTER
# Concatenate: Add prefix
new_text = "Subject: " + text
print(f"Concatenated: {new_text}") # Output: Subject: Welcome to IB Computer Science
# Replace: Change substring
replaced_text = text.replace("Computer Science", "Programming")
print(f"Replaced text: {replaced_text}") # Output: Welcome to IB Programming
Construction and Tracing
- Construct: Write code to perform substring operations based on requirements
- Trace: Step through the code, tracking variable values:
- text = "Welcome to IB Computer Science"
- pos = 11 (from find("Computer"))
- substring = "Computer" (from slicing [11:19])
- upper_text = "COMPUTER" (from upper())
- new_text = "Subject: Welcome to IB Computer Science" (from concatenation)
- replaced_text = "Welcome to IB Programming" (from replace())
Use Case
- A program processing email addresses to extract usernames (e.g., user@domain.com → user)
- Concatenate with a greeting, and replace domains for standardization
- Ensuring correct manipulation through tracing
B2.1.3 Describe exception handling (AO2)
B2.1.3_1 Failure points: unexpected inputs, resource unavailability, logic errors
Unexpected Inputs
- Occurs when user data does not match expected format or type
- Example: Entering "abc" when expecting an integer
- Can cause crashes (e.g., ValueError) or incorrect behavior
Resource Unavailability
- Failure due to inaccessible resources (files, databases, network)
- Example: Attempting to open a non-existent file
- Results in FileNotFoundError, disrupting execution
Logic Errors
- Errors in program logic (division by zero, out-of-bounds access)
- Example: Dividing by a variable that equals zero
- Causes runtime errors or incorrect outputs
B2.1.3_2 Role in program development
Purpose
- Exception handling ensures programs gracefully handle errors
- Improves robustness and user experience
- Prevents crashes by catching and managing errors
- Allows programs to recover or fail gracefully
Benefits in Development
- Enhances reliability by anticipating and addressing potential failure points
- Improves debugging by providing clear error messages and controlled error handling
- Supports user-friendly applications by informing users of issues without abrupt termination
Use in Testing
- Helps developers identify and handle edge cases during testing
- Ensures comprehensive error management
- Example: Testing a calculator program for division by zero
B2.1.3_3 Constructs: try/catch (Java), try/except (Python), finally block
Try/Catch (Java)
try {
int result = 10 / 0; // Potential ZeroDivisionError
} catch (ArithmeticException e) {
System.out.println("Error: Division by zero");
}
int result = 10 / 0; // Potential ZeroDivisionError
} catch (ArithmeticException e) {
System.out.println("Error: Division by zero");
}
- Catches specific exceptions to prevent crashes
Try/Except (Python)
try:
result = 10 / 0 # Potential ZeroDivisionError
except ZeroDivisionError:
print("Error: Division by zero")
result = 10 / 0 # Potential ZeroDivisionError
except ZeroDivisionError:
print("Error: Division by zero")
- Manages runtime errors, allowing program continuation
Finally Block (Java and Python)
try:
file = open("data.txt", "r")
content = file.read()
except FileNotFoundError:
print("Error: File not found")
finally:
file.close() # Ensures file is closed
file = open("data.txt", "r")
content = file.read()
except FileNotFoundError:
print("Error: File not found")
finally:
file.close() # Ensures file is closed
- Executes code regardless of whether an exception occurs
- Often used for cleanup tasks (e.g., closing files)
- Ensures resources are properly released, preventing leaks
Use Case
- A Python program reading user input for a calculation uses try/except to handle invalid inputs
- Finally block logs the operation's completion
- Ensures robustness and proper resource management
B2.1.4 Construct, use debugging techniques (AO3)
B2.1.4_1 Techniques: trace tables, breakpoints, print statements, step-by-step execution
Trace Tables
- Table tracking variable values at each step
- Identifies logic errors or unexpected behavior
- Example: For a loop calculating sum:
total = 0
for i in range(1, 4):
total += i
print(total)
for i in range(1, 4):
total += i
print(total)
Step | i | total |
---|---|---|
1 | 1 | 1 |
2 | 2 | 3 |
3 | 3 | 6 |
Breakpoints
- Pause execution at specific lines to inspect state
- Used with debuggers (e.g., Python's pdb, IDEs)
- Example: Setting breakpoint at total += i to check values
- Pinpoints where errors occur
Print Statements
- Insert print() to output variable values
- Quick monitoring without debugger
- Example:
total = 0
for i in range(1, 4):
total += i
print(f"i={i}, total={total}")
for i in range(1, 4):
total += i
print(f"i={i}, total={total}")
- Output: i=1, total=1, i=2, total=3, i=3, total=6
Step-by-Step Execution
- Execute code line-by-line using debugger
- Observe behavior and variable changes in real-time
- Tools: pdb, VS Code, PyCharm debuggers
- Identifies exact lines where errors occur
Construction and Use
# Example: Debug a program to find the maximum number
numbers = [4, 7, 2, 9, 1]
max_num = numbers[0]
for num in numbers:
print(f"Checking num={num}, max_num={max_num}") # Print statement
if num > max_num:
max_num = num
print(f"Maximum: {max_num}")
numbers = [4, 7, 2, 9, 1]
max_num = numbers[0]
for num in numbers:
print(f"Checking num={num}, max_num={max_num}") # Print statement
if num > max_num:
max_num = num
print(f"Maximum: {max_num}")
Step | num | max_num |
---|---|---|
1 | 4 | 4 |
2 | 7 | 7 |
3 | 2 | 7 |
4 | 9 | 9 |
5 | 1 | 9 |
B2.2.1 Compare static vs dynamic data structures (AO3)
B2.2.1_1 Memory allocation, resizing mechanisms
Static Data Structures
Memory Allocation
- Memory allocated at compile time
- Fixed size that cannot change during runtime
- Example: numbers = [0] * 5 creates a Python list with 5 elements
Resizing Mechanism
- Cannot be resized dynamically
- Size is set during declaration
- To change size, a new structure must be created and data copied
Dynamic Data Structures
Memory Allocation
- Memory allocated at runtime
- Flexible size adjustments as needed
- Example: numbers = [1, 2, 3]; numbers.append(4) dynamically adds an element
Resizing Mechanism
- Automatically resizes when capacity exceeded
- Allocates new memory and copies data
- Example: Python lists double capacity when full
B2.2.1_2 Pros, cons: speed, memory, flexibility
Aspect | Static Data Structures | Dynamic Data Structures |
---|---|---|
Speed | Faster access (O(1)) due to contiguous memory and fixed size | Slower due to resizing overhead (O(n) in worst case) |
Memory | More efficient, no overhead for resizing | Higher overhead for resizing and extra capacity |
Flexibility | Inflexible, fixed size | Highly flexible, grows/shrinks as needed |
Use Case | Fixed number of student grades (exactly 10) | Tracking user inputs in a chat application |
Static Pros
- Faster access due to contiguous memory
- Memory-efficient with no overhead
Static Cons
- Inflexible size cannot change
- Wasted space if not fully utilized
Dynamic Pros
- Flexible size adjusts as needed
- Easy to use with automatic memory management
Dynamic Cons
- Slower due to resizing overhead
- Higher memory usage for extra capacity
B2.2.2 Construct programs with arrays, lists (AO3)
B2.2.2_1 1D/2D arrays, ArrayLists (Java)
1D Arrays
- Fixed-size, contiguous collection of elements
- Accessed by index
# 1D array using Python list
grades = [85, 90, 78, 92]
grades[2] = 80 # Update element
print(grades[0]) # Access: 85
grades = [85, 90, 78, 92]
grades[2] = 80 # Update element
print(grades[0]) # Access: 85
- Use: Store sequences like student grades
2D Arrays
- Matrix-like structure with rows and columns
- Accessed by two indices
# 2D array using nested lists
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
matrix[1][2] = 10 # Update element
print(matrix[0][1]) # Access: 2
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
matrix[1][2] = 10 # Update element
print(matrix[0][1]) # Access: 2
- Use: Represent grids, tables, or seating charts
ArrayLists (Java)
- Dynamic, resizable list in Java
- Part of java.util package
import java.util.ArrayList;
// Initialize ArrayList
ArrayList<Integer> scores = new ArrayList<>();
scores.add(85); // Add element
scores.add(90);
scores.set(1, 95); // Update element
System.out.println(scores.get(0)); // Access: 85
// Initialize ArrayList
ArrayList<Integer> scores = new ArrayList<>();
scores.add(85); // Add element
scores.add(90);
scores.set(1, 95); // Update element
System.out.println(scores.get(0)); // Access: 85
- Use: Store dynamic collections like user inputs
B2.2.2_2 1D/2D lists (Python)
1D Lists
- Python's built-in dynamic lists
- Resizable and can store mixed data types
# 1D list
names = ["Alice", "Bob", "Charlie"]
names.append("David") # Add element
names[1] = "Beth" # Update element
print(names[0]) # Access: Alice
names = ["Alice", "Bob", "Charlie"]
names.append("David") # Add element
names[1] = "Beth" # Update element
print(names[0]) # Access: Alice
- Use: Store dynamic sequences like customer names
2D Lists
- Nested lists representing a grid or table
- Dynamic resizing capabilities
# 2D list
grid = [[0, 1, 0], [1, 0, 1], [0, 1, 0]]
grid[1][1] = 2 # Update element
print(grid[0][2]) # Access: 0
grid.append([1, 1, 1]) # Add new row
grid = [[0, 1, 0], [1, 0, 1], [0, 1, 0]]
grid[1][1] = 2 # Update element
print(grid[0][2]) # Access: 0
grid.append([1, 1, 1]) # Add new row
- Use: Represent dynamic matrices like game boards
B2.2.2_3 Add, remove, traverse dynamic list elements
Add Elements
- Append or insert elements to expand size
students = ["Alice", "Bob"]
students.append("Charlie") # Add to end
students.insert(1, "Beth") # Add at index 1
print(students) # ['Alice', 'Beth', 'Bob', 'Charlie']
students.append("Charlie") # Add to end
students.insert(1, "Beth") # Add at index 1
print(students) # ['Alice', 'Beth', 'Bob', 'Charlie']
Remove Elements
- Remove by value, index, or clear entire list
students = ["Alice", "Beth", "Bob", "Charlie"]
students.remove("Beth") # Remove by value
students.pop(1) # Remove by index (Bob)
print(students) # ['Alice', 'Charlie']
students.remove("Beth") # Remove by value
students.pop(1) # Remove by index (Bob)
print(students) # ['Alice', 'Charlie']
Traverse Elements
- Iterate through elements to process or analyze
scores = [85, 90, 78, 92]
for score in scores:
print(f"Score: {score}")
# Access by index
for i in range(len(scores)):
scores[i] += 5 # Add 5 to each
print(scores) # [90, 95, 83, 97]
for score in scores:
print(f"Score: {score}")
# Access by index
for i in range(len(scores)):
scores[i] += 5 # Add 5 to each
print(scores) # [90, 95, 83, 97]
Use Case
- A program managing a student roster:
- Adds new students (append)
- Removes dropouts (remove)
- Traverses the list to calculate average grades or print names
- Ensures dynamic updates and efficient data processing
B2.2.3 Explain stack (LIFO) (AO2)
B2.2.3_1 Operations: push, pop, peek, isEmpty
Push
- Adds element to the top of the stack
- Example: Adding a plate to a stack of plates
stack = []
stack.append(5) # Push 5 onto stack
stack.append(5) # Push 5 onto stack
Pop
- Removes and returns the top element
- Example: Taking the top plate off
top = stack.pop() # Removes and returns 5
Peek
- Returns top element without removing it
- Example: Checking the top plate
top = stack[-1] if stack else None # Views top element
isEmpty
- Checks if stack is empty
- Returns True if no elements remain
is_empty = len(stack) == 0 # Returns True if empty
B2.2.3_2 Impact on performance, memory
Performance
- Push/Pop: O(1) time complexity
- Operations occur at the top (constant-time access)
- Peek/isEmpty: O(1) time complexity
- Only access top element or check length
- Example: Fast for function call management
Memory
- Uses contiguous or dynamic memory
- Minimal overhead for simple operations
- Dynamic resizing may cause occasional O(n) operations
- Example: Function call stack uses small, fixed space per element
Trade-offs
- Efficient for LIFO operations but limited for random access or searching (O(n))
- Memory-efficient for sequential data but may waste space if underused
B2.2.3_3 Appropriate stack use
Function Call Stack
- Manages function calls and returns
- Tracks execution context
- Example: Python's call stack in recursion
Undo/Redo Operations
- Tracks actions in reverse order
- Example: Text editor undo feature
Expression Evaluation
- Processes expressions or validates syntax
- Example: Checking balanced parentheses
Backtracking Algorithms
- Supports algorithms like depth-first search
- Example: Solving a maze by storing visited paths
Python Example
# Stack for checking balanced parentheses
def is_balanced(expression):
stack = []
for char in expression:
if char == '(':
stack.append(char) # Push
elif char == ')':
if len(stack) == 0: # Check isEmpty
return False
stack.pop() # Pop
return len(stack) == 0
print(is_balanced("(a + b)")) # Output: True
print(is_balanced("(a + b))")) # Output: False
def is_balanced(expression):
stack = []
for char in expression:
if char == '(':
stack.append(char) # Push
elif char == ')':
if len(stack) == 0: # Check isEmpty
return False
stack.pop() # Pop
return len(stack) == 0
print(is_balanced("(a + b)")) # Output: True
print(is_balanced("(a + b))")) # Output: False
Appropriateness
- Ideal for LIFO access, reversing actions, or managing nested operations
- Inappropriate for random access or frequent searching
B2.2.4 Explain queue (FIFO) (AO2)
B2.2.4_1 Operations: enqueue, dequeue, front, isEmpty
Enqueue
- Adds element to the back of the queue
- Example: Adding a customer to a ticket line
queue = []
queue.append(10) # Enqueue 10
queue.append(10) # Enqueue 10
Dequeue
- Removes and returns the front element
- Example: Serving the first customer
front = queue.pop(0) # Dequeue first element (10)
Front
- Returns the front element without removing
- Example: Checking the next customer
front = queue[0] if queue else None # View front element
isEmpty
- Checks if queue is empty
- Returns True if no elements remain
is_empty = len(queue) == 0 # Returns True if empty
B2.2.4_2 Impact on performance, memory
Performance
- Enqueue: O(1) using dynamic list (append)
- Dequeue: O(n) in basic Python list due to shifting
- Optimized implementations (collections.deque) achieve O(1)
- Front/isEmpty: O(1) time complexity
# Optimized implementation
from collections import deque
queue = deque()
queue.append(10) # O(1)
queue.popleft() # O(1)
from collections import deque
queue = deque()
queue.append(10) # O(1)
queue.popleft() # O(1)
Memory
- Uses contiguous or dynamic memory
- Overhead for resizing in dynamic implementations
- Efficient for sequential processing
- May waste memory if pre-allocated capacity is underused
- Example: Print job queue uses minimal space per job
Trade-offs
- Fast for FIFO operations but inefficient for random access (O(n))
- Optimized implementations like deque improve performance
B2.2.4_3 Appropriate queue use
Task Scheduling
- Manages tasks in arrival order
- Example: CPU process scheduling
Event Handling
- Processes events/messages in order received
- Example: Server queueing user requests
Breadth-First Search
- Explores nodes level by level
- Example: Finding shortest path in a maze
Buffering
- Handles data streams
- Example: Video player queueing frames
Python Example
from collections import deque
# Queue for processing print jobs
def process_print_jobs(jobs):
queue = deque()
for job in jobs:
queue.append(job) # Enqueue job
while len(queue) > 0: # Check isEmpty
current_job = queue.popleft() # Dequeue front job
print(f"Processing: {current_job}")
return len(queue) == 0
print_jobs = ["Doc1.pdf", "Doc2.pdf", "Doc3.pdf"]
print(process_print_jobs(print_jobs)) # Processes each job, returns True
# Queue for processing print jobs
def process_print_jobs(jobs):
queue = deque()
for job in jobs:
queue.append(job) # Enqueue job
while len(queue) > 0: # Check isEmpty
current_job = queue.popleft() # Dequeue front job
print(f"Processing: {current_job}")
return len(queue) == 0
print_jobs = ["Doc1.pdf", "Doc2.pdf", "Doc3.pdf"]
print(process_print_jobs(print_jobs)) # Processes each job, returns True
Appropriateness
- Ideal for FIFO scenarios, processing tasks in order of arrival
- Inappropriate for LIFO or random access, where stacks or arrays are better
B2.4.5 Construct, trace recursive algorithms (HL) (AO3)
B2.4.5_1 Simple, non-branching recursive algorithms
Constructing Recursive Algorithms
- Solve problems by calling themselves with smaller inputs
- Consist of:
- Base case: Terminates recursion
- Recursive case: Reduces problem size
- Non-branching: Makes a single recursive call per iteration
Factorial Example
def factorial(n):
# Base case
if n == 0 or n == 1:
return 1
# Recursive case
return n * factorial(n - 1)
# Computes n! (e.g., 5! = 5 × 4 × 3 × 2 × 1 = 120)
# Base case
if n == 0 or n == 1:
return 1
# Recursive case
return n * factorial(n - 1)
# Computes n! (e.g., 5! = 5 × 4 × 3 × 2 × 1 = 120)
Tracing Recursive Algorithms
- Follow each recursive call, tracking values until base case
- Then compute final output by unwinding the call stack
Trace for factorial(4):
- Call 1: factorial(4) → 4 × factorial(3)
- Call 2: factorial(3) → 3 × factorial(2)
- Call 3: factorial(2) → 2 × factorial(1)
- Call 4: factorial(1) → Base case, returns 1
- Unwind:
- factorial(2) → 2 × 1 = 2
- factorial(3) → 3 × 2 = 6
- factorial(4) → 4 × 6 = 24
- Result: factorial(4) returns 24
Sum of Numbers Example
def sum_to_n(n):
# Base case
if n <= 1:
return n
# Recursive case
return n + sum_to_n(n - 1)
# Computes sum from 1 to n (e.g., sum_to_n(4) = 1+2+3+4 = 10)
# Base case
if n <= 1:
return n
# Recursive case
return n + sum_to_n(n - 1)
# Computes sum from 1 to n (e.g., sum_to_n(4) = 1+2+3+4 = 10)
Trace for sum_to_n(4):
- Call 1: sum_to_n(4) → 4 + sum_to_n(3)
- Call 2: sum_to_n(3) → 3 + sum_to_n(2)
- Call 3: sum_to_n(2) → 2 + sum_to_n(1)
- Call 4: sum_to_n(1) → Base case, returns 1
- Unwind:
- sum_to_n(2) → 2 + 1 = 3
- sum_to_n(3) → 3 + 3 = 6
- sum_to_n(4) → 4 + 6 = 10
- Result: sum_to_n(4) returns 10
Key Considerations
- Ensure a clear base case to prevent infinite recursion
- Non-branching algorithms are simpler to trace and construct
- Example Use Case: Calculating power of a number (x^n)
def power(x, n):
if n == 0: # Base case
return 1
return x * power(x, n - 1) # Recursive case
# Trace for power(2, 3):
# power(2, 3) → 2 * power(2, 2)
# power(2, 2) → 2 * power(2, 1)
# power(2, 1) → 2 * power(2, 0)
# power(2, 0) → 1
# Unwind: 2 * 1 = 2, 2 * 2 = 4, 2 * 4 = 8
# Result: 8
if n == 0: # Base case
return 1
return x * power(x, n - 1) # Recursive case
# Trace for power(2, 3):
# power(2, 3) → 2 * power(2, 2)
# power(2, 2) → 2 * power(2, 1)
# power(2, 1) → 2 * power(2, 0)
# power(2, 0) → 1
# Unwind: 2 * 1 = 2, 2 * 2 = 4, 2 * 4 = 8
# Result: 8
B2.5.1 Construct file-processing code (AO3)
B2.5.1_1 Manipulate text files
Description
- Writing code to read from, write to, or modify text files
- Enables data persistence and processing
- Purpose: Store, retrieve, or update data for tasks like logging, configuration, or analysis
- Example: Reading student names from a file, updating grades, and saving results
B2.5.1_2 Open files in read, write, append modes
Read Mode ('r')
- Opens file for reading
- Raises error if file doesn't exist
- Example: Reading student grades from text file
Write Mode ('w')
- Opens file for writing
- Overwrites if exists or creates new file
- Example: Writing processed data to a file
Append Mode ('a')
- Opens file to add data at the end
- Preserves existing content
- Example: Adding new log entries without overwriting
Python Code Example
# Example: Manipulating a text file with different modes
# Write mode: Create or overwrite a file
with open('students.txt', 'w') as file:
file.write("Alice,85\nBob,90\n") # Write initial data
# Append mode: Add new data
with open('students.txt', 'a') as file:
file.write("Charlie,78\n") # Append new student
# Read mode: Read and print file contents
with open('students.txt', 'r') as file:
content = file.read()
print("File Contents:", content)
# Write mode: Create or overwrite a file
with open('students.txt', 'w') as file:
file.write("Alice,85\nBob,90\n") # Write initial data
# Append mode: Add new data
with open('students.txt', 'a') as file:
file.write("Charlie,78\n") # Append new student
# Read mode: Read and print file contents
with open('students.txt', 'r') as file:
content = file.read()
print("File Contents:", content)
B2.5.1_3 Read, write, append, close files
Read
- Retrieves data using methods like read(), readline(), or readlines()
- Example: file.read() reads entire file as string
- file.readlines() reads lines into a list
Write
- Writes data to file in 'w' mode
- Overwrites existing content
- Example: file.write("data") writes a string
Append
- Adds data to end in 'a' mode
- Preserves existing content
- Example: file.write("new data\n") appends a line
Close
- Closes file to free system resources
- Automatically handled using 'with' statement
- Example: with open('file.txt', 'r') as file: ensures closure
Python Code Example
# Read, write, append example
# Write initial data
with open('grades.txt', 'w') as file:
file.write("Alice: 85\n")
# Append additional data
with open('grades.txt', 'a') as file:
file.write("Bob: 90\n")
# Read and process file
with open('grades.txt', 'r') as file:
lines = file.readlines() # Read all lines into a list
for line in lines:
name, grade = line.strip().split(': ')
grade = int(grade) + 5 # Increase grade by 5
print(f"Updated: {name}, {grade}")
# Write initial data
with open('grades.txt', 'w') as file:
file.write("Alice: 85\n")
# Append additional data
with open('grades.txt', 'a') as file:
file.write("Bob: 90\n")
# Read and process file
with open('grades.txt', 'r') as file:
lines = file.readlines() # Read all lines into a list
for line in lines:
name, grade = line.strip().split(': ')
grade = int(grade) + 5 # Increase grade by 5
print(f"Updated: {name}, {grade}")
B2.5.1_4 Java classes: Scanner, FileWriter, BufferedReader
Scanner
- Java class (java.util.Scanner) for reading data
- Parses input into tokens
import java.util.Scanner;
import java.io.File;
File file = new File("students.txt");
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
scanner.close();
import java.io.File;
File file = new File("students.txt");
Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
System.out.println(scanner.nextLine());
}
scanner.close();
FileWriter
- Java class (java.io.FileWriter) for writing
- Writes character data to files
import java.io.FileWriter;
FileWriter writer = new FileWriter("students.txt");
writer.write("Alice,85\n");
writer.close(); // Explicitly close
FileWriter writer = new FileWriter("students.txt");
writer.write("Alice,85\n");
writer.close(); // Explicitly close
BufferedReader
- Java class for efficient reading
- Buffers input for better performance
import java.io.BufferedReader;
import java.io.FileReader;
BufferedReader reader = new BufferedReader(
new FileReader("students.txt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
import java.io.FileReader;
BufferedReader reader = new BufferedReader(
new FileReader("students.txt"));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
B2.5.1_5 Python functions: open(), read(), readline(), write(), close()
open()
- Opens file in specified mode
- Returns a file object
- Example: file = open('data.txt', 'r')
read()
- Reads entire file as string
- Example: content = file.read()
readline()
- Reads a single line
- Returns empty string at end
- Example: line = file.readline()
write()
- Writes string to file
- Example: file.write("Hello\n")
close()
- Closes file, freeing resources
- Used without 'with' statement
- Example: file.close()
Example Program
# Process a CSV file with student data
# Write student data
with open('students.csv', 'w') as file:
file.write("Name,Grade\nAlice,85\nBob,90\n")
# Read and manipulate data
with open('students.csv', 'r') as file:
lines = file.readlines()[1:] # Skip header
for line in lines:
name, grade = line.strip().split(',')
grade = int(grade) + 5 # Increase grade by 5
print(f"Updated: {name}, {grade}")
# Append new student
with open('students.csv', 'a') as file:
file.write("Charlie,78\n")
# Write student data
with open('students.csv', 'w') as file:
file.write("Name,Grade\nAlice,85\nBob,90\n")
# Read and manipulate data
with open('students.csv', 'r') as file:
lines = file.readlines()[1:] # Skip header
for line in lines:
name, grade = line.strip().split(',')
grade = int(grade) + 5 # Increase grade by 5
print(f"Updated: {name}, {grade}")
# Append new student
with open('students.csv', 'a') as file:
file.write("Charlie,78\n")
Use Case
- A program managing a log file:
- Writes new entries (write, append mode)
- Reads and analyzes past entries (readlines)
- Ensures proper closure (with or close)
- Enables reliable file processing for tasks like tracking user activity or storing configuration data