Teacher Guide: Methods & Modularization
Student page: Methods & Modularization IB Syllabus: B2.3.4 Estimated periods: 2 (70-90 min each) Prerequisites: Selection, Iteration, 1D Arrays
Contents
Lesson Plans
Period 1: Method Basics + Refactoring Activity
| Phase | Time | Activity | Student Page Section |
|---|---|---|---|
| Hook | 5 min | Show monolithic MiniProj/GradeArray code. “Would you debug this?” | – |
| Objectives | 2 min | Learning objectives slide | – |
| Teach | 10 min | What is a method, anatomy, parameter vs argument, void vs return, boolean return | Key Concepts, Worked Examples 1-2, 4 |
| Quick Check | 5 min | Students open EduCS.me, answer Q1-Q5 | Quick Check |
| Teach | 5 min | Methods calling methods (printReport example) | Worked Example 3 |
| Hands-on | 15 min | Refactor RefactorGrades.java in Codespaces – extract 6 methods | Practice Exercise 8 / GH Classroom |
| Teach | 7 min | Scope: local vs global, pass-by-value | Scope section |
| Quick Check | 5 min | Trace exercise + output predictions on EduCS.me | Trace Exercise, Output Prediction |
| Discussion | 6 min | Benefits of modularization – students share what they experienced | Why Modularize |
| Practice | 10 min | Core exercises 1-4 on EduCS.me (or start in GH Classroom) | Practice Exercises |
Teaching notes:
- The hook is critical. Show familiar code they wrote (MiniProj). Let them feel the pain of a 120-line
mainbefore showing the solution. - Introduce parameter vs argument terminology explicitly – this appears on IB exams.
- During the refactoring activity, students will naturally encounter scope errors when they move code into methods and variables are no longer visible. Use this as the teachable moment for scope instead of teaching it abstractly first.
- The
printReportexample shows methods calling methods – emphasize thatmain(or any orchestrating method) should read like a high-level summary. - Pass-by-value: the output prediction exercise (
change: 15, main: 5) is the key demonstration. Ask students to predict BEFORE revealing.
Period 2: Practice + GH Classroom Homework
| Phase | Time | Activity | Student Page Section |
|---|---|---|---|
| Warm-up | 10 min | Review: “Name 3 benefits of modularization” + quick scope question | – |
| Practice | 30 min | Extension exercises 5-7 (temperature converter, array statistics, password checker) | Practice Exercises |
| Challenge | 15 min | Exercise 9: Mini calculator (methods + loop + String comparison) | Practice Exercises |
| Wrap-up | 15 min | Review GH Classroom submission process. Show test results. Assign deadline. | GitHub Classroom |
Teaching notes:
- Extension exercise 6 (array statistics) is the most important – it combines void methods, return methods, and array parameters in one program.
- Exercise 7 (password checker) requires iterating through characters with
charAt()– connect back to Strings topic. - Exercise 9 (mini calculator) requires
.equals()for string comparison in the quit condition – reinforce this. - Students who finish early can start
StringHelper.javaorMathUtils.javafrom the GH Classroom template.
Differentiation
Supporting weaker students:
| Strategy | When to use | Example |
|---|---|---|
| Start with void only | Can’t grasp return values yet | Write printSeparator() and greet(name) first – no return |
| Method header template | Can’t write signatures | Give: public static ___ methodName(___) { } with blanks to fill |
| Pair refactoring | Stuck on RefactorGrades | Pair with a stronger student; one drives, one navigates |
| Reduce to Core 1-3 | Overwhelmed | printSeparator, sum, isEven – simplest patterns |
Extending stronger students:
| Strategy | When to use | Example |
|---|---|---|
| MathUtils.java | Finishes Extension early | isPrime, gcd, countPrimes (methods calling methods) |
| StringHelper.java | Wants String practice | isPalindrome, toTitleCase, summarize (calls other methods) |
| Refactor their own code | After exercise 8 | “Go back to any previous assignment and extract methods” |
| Discuss method design | After Challenge | “When should you use void vs return? When should a method do one thing vs two?” |
Integration Notes
Connects backward to:
- Selection (B2.3.2): conditions inside methods (isValidGrade, isEven)
- Iteration (B2.3.3): loops inside methods (calculateAverage, findMax)
- 1D Arrays (B2.2.2): arrays as method parameters (all RefactorGrades methods)
Connects forward to:
- OOP (B3.1): methods become instance methods instead of static;
thiskeyword replaces parameter passing - Searching/Sorting (B2.4): linear search, binary search, bubble sort, selection sort are all methods
- File Processing (B2.5): file reading/writing logic extracted into methods
- IA: modularization is assessed in Criterion C (development) – “limited discussion of approach” is a common weakness
IB exam relevance:
- Exam questions often provide a method header and ask students to complete the body
- “Explain the benefits of modularization” is a common 4-6 mark question – students need at least 3 named benefits with explanations
- Trace tables with method calls: students must track which method is executing, what parameters receive, and what is returned
- Scope questions: “What is the value of x after this code runs?” where a method modifies a local copy
Answer Keys
Core 1: Print separator
public class SeparatorDemo {
public static void main(String[] args) {
printSeparator();
System.out.println("Your Name Here");
printSeparator();
}
public static void printSeparator() {
for (int i = 0; i < 30; i++) {
System.out.print("-");
}
System.out.println();
}
}
Expected output:
------------------------------
Your Name Here
------------------------------
Common mistakes: Hardcoding the string "------------------------------" instead of using a loop. Both are acceptable but the loop approach is more flexible.
Marking notes: Accept any approach that prints 30 dashes. The key skill is defining and calling a void method.
Core 2: Sum of two
public class SumDemo {
public static void main(String[] args) {
System.out.println("3 + 5 = " + sum(3, 5));
System.out.println("10 + 20 = " + sum(10, 20));
System.out.println("-4 + 4 = " + sum(-4, 4));
}
public static int sum(int a, int b) {
return a + b;
}
}
Expected output:
3 + 5 = 8
10 + 20 = 30
-4 + 4 = 0
Common mistakes: Printing inside the method instead of returning. Students may write System.out.println(a + b) and make the method void.
Marking notes: The method MUST return int, not print. Deduct if void + print instead of return.
Core 3: Is even
public class EvenCheck {
public static void main(String[] args) {
System.out.println("4 is even: " + isEven(4));
System.out.println("7 is even: " + isEven(7));
System.out.println("0 is even: " + isEven(0));
}
public static boolean isEven(int n) {
return n % 2 == 0;
}
}
Expected output:
4 is even: true
7 is even: false
0 is even: true
Common mistakes: Using if (n % 2 == 0) return true; else return false; – works but verbose. Encourage the direct return of the boolean expression.
Marking notes: Accept the if/else version but point out the simpler return n % 2 == 0 pattern.
Core 4: Greeting
public class GreetingDemo {
public static void main(String[] args) {
greet("Alice");
greet("Bob");
greet("Charlie");
}
public static void greet(String name) {
System.out.println("Hello, " + name + "! Welcome to CS.");
}
}
Expected output:
Hello, Alice! Welcome to CS.
Hello, Bob! Welcome to CS.
Hello, Charlie! Welcome to CS.
Common mistakes: Hardcoding the name instead of using the parameter.
Marking notes: Accept any greeting format as long as the name comes from the parameter.
Extension 5: Temperature converter
public class TempConverter {
public static void main(String[] args) {
System.out.println("0C = " + celsiusToFahrenheit(0) + "F");
System.out.println("100C = " + celsiusToFahrenheit(100) + "F");
System.out.println("32F = " + fahrenheitToCelsius(32) + "C");
System.out.println("212F = " + fahrenheitToCelsius(212) + "C");
}
public static double celsiusToFahrenheit(double celsius) {
return celsius * 9.0 / 5.0 + 32;
}
public static double fahrenheitToCelsius(double fahrenheit) {
return (fahrenheit - 32) * 5.0 / 9.0;
}
}
Expected output:
0C = 32.0F
100C = 212.0F
32F = 0.0C
212F = 100.0C
Common mistakes: Integer division – using 9/5 gives 1, not 1.8. Must use 9.0/5.0 or cast to double.
Marking notes: Formulas must be correct. Accept (double) 9 / 5 or 9.0 / 5 as alternatives.
Extension 6: Array statistics
public class ArrayStats {
public static void main(String[] args) {
int[] grades = {85, 92, 78, 95, 88, 73, 91};
System.out.println("Max: " + findMax(grades));
System.out.println("Min: " + findMin(grades));
System.out.println("Average: " + calculateAverage(grades));
}
public static int findMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
public static int findMin(int[] arr) {
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
public static double calculateAverage(int[] arr) {
int total = 0;
for (int i = 0; i < arr.length; i++) {
total = total + arr[i];
}
return (double) total / arr.length;
}
}
Common mistakes:
- Starting loop at 0 instead of 1 for findMax/findMin (works but unnecessary comparison with self)
- Integer division in calculateAverage – forgetting the
(double)cast
Marking notes: This is the most important Extension exercise. All three methods must return values (not print). Accept loop starting at 0.
Extension 7: Password checker
public class PasswordChecker {
public static void main(String[] args) {
System.out.println("Abc12345: " + isStrongPassword("Abc12345"));
System.out.println("abc: " + isStrongPassword("abc"));
System.out.println("abcdefgh: " + isStrongPassword("abcdefgh"));
System.out.println("ABCD1234: " + isStrongPassword("ABCD1234"));
System.out.println("abcd1234: " + isStrongPassword("abcd1234"));
}
public static boolean isStrongPassword(String password) {
if (password.length() < 8) {
return false;
}
boolean hasDigit = false;
boolean hasUpper = false;
for (int i = 0; i < password.length(); i++) {
char c = password.charAt(i);
if (c >= '0' && c <= '9') {
hasDigit = true;
}
if (c >= 'A' && c <= 'Z') {
hasUpper = true;
}
}
return hasDigit && hasUpper;
}
}
Expected output:
Abc12345: true
abc: false
abcdefgh: false
ABCD1234: false
abcd1234: false
Common mistakes:
- Using
Character.isDigit()/Character.isUpperCase()– these work and are acceptable, but not required knowledge - Checking only the first character instead of iterating through all
Marking notes: Accept Character.isDigit()/Character.isUpperCase() as alternatives to manual range checks. The key skill is iterating through characters and tracking boolean flags.
Challenge 8: Refactor the GradeArray
This is the in-class RefactorGrades.java activity. The answer key is the completed version with all 6 methods filled in.
import java.util.Scanner;
public class RefactorGrades {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String[] studentNames = {"Alice", "Bob", "Charlie", "Diana", "Eve"};
int[] grades = {85, 92, 78, 95, 88};
printSeparator();
System.out.println("Student Grades:");
printGrades(studentNames, grades);
printSeparator();
System.out.println("Average: " + calculateAverage(grades));
System.out.println("Highest: " + findMax(grades));
System.out.println("Lowest: " + findMin(grades));
printSeparator();
System.out.print("Enter student name to search: ");
String searchName = input.nextLine();
int foundIndex = searchStudent(studentNames, searchName);
if (foundIndex != -1) {
System.out.println(searchName + "'s grade: " + grades[foundIndex]);
} else {
System.out.println("Student '" + searchName + "' not found.");
}
}
public static void printSeparator() {
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
public static double calculateAverage(int[] grades) {
int total = 0;
for (int i = 0; i < grades.length; i++) {
total = total + grades[i];
}
return (double) total / grades.length;
}
public static int findMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
public static int findMin(int[] arr) {
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
public static void printGrades(String[] names, int[] grades) {
for (int i = 0; i < names.length; i++) {
System.out.println(names[i] + ": " + grades[i]);
}
}
public static int searchStudent(String[] names, String target) {
for (int i = 0; i < names.length; i++) {
if (names[i].equalsIgnoreCase(target)) {
return i;
}
}
return -1;
}
}
Common mistakes:
- Forgetting to pass arrays as parameters (trying to access
gradesfrom inside a method without a parameter) - Using
==instead of.equalsIgnoreCase()for string search - Integer division in calculateAverage
Marking notes: The refactored main should be significantly shorter and readable. Methods should each do one job. Accept minor style variations.
Challenge 9: Mini calculator
import java.util.Scanner;
public class MiniCalculator {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean running = true;
while (running) {
System.out.print("Enter first number (or type quit): ");
String first = input.nextLine();
if (first.equals("quit")) {
running = false;
} else {
double a = Double.parseDouble(first);
System.out.print("Enter operation (+, -, *, /): ");
String op = input.nextLine();
if (isValidOperation(op)) {
System.out.print("Enter second number: ");
double b = Double.parseDouble(input.nextLine());
double result = 0;
if (op.equals("+")) {
result = add(a, b);
} else if (op.equals("-")) {
result = subtract(a, b);
} else if (op.equals("*")) {
result = multiply(a, b);
} else if (op.equals("/")) {
result = divide(a, b);
}
System.out.println("Result: " + result);
} else {
System.out.println("Invalid operation.");
}
}
}
System.out.println("Goodbye!");
}
public static double add(double a, double b) {
return a + b;
}
public static double subtract(double a, double b) {
return a - b;
}
public static double multiply(double a, double b) {
return a * b;
}
public static double divide(double a, double b) {
return a / b;
}
public static boolean isValidOperation(String op) {
return op.equals("+") || op.equals("-") || op.equals("*") || op.equals("/");
}
}
Common mistakes:
- Using
==to compare strings instead of.equals() - Division by zero not handled (acceptable for this exercise – not required)
- Using
breakto exit the loop – should use loop condition (runningflag)
Marking notes: The key skills are: method design (each operation as a method), boolean return (isValidOperation), and string comparison with .equals(). Accept variations in input handling. Do not require division-by-zero handling unless students add it voluntarily.
GitHub Classroom Answer Key
The GitHub Classroom template has 4 files. Complete solutions for auto-graded methods:
TemperatureConverter.java (5 methods)
public class TemperatureConverter {
public static double celsiusToFahrenheit(double celsius) {
return celsius * 9.0 / 5.0 + 32;
}
public static double fahrenheitToCelsius(double fahrenheit) {
return (fahrenheit - 32) * 5.0 / 9.0;
}
public static boolean isBelowFreezing(double celsius) {
return celsius < 0;
}
public static String getCategory(double celsius) {
if (celsius < 0) {
return "Freezing";
} else if (celsius < 15) {
return "Cold";
} else if (celsius < 25) {
return "Comfortable";
}
return "Hot";
}
public static void printConversionTable(int startC, int endC) {
for (int c = startC; c <= endC; c += 10) {
System.out.println(c + "C = " + celsiusToFahrenheit(c) + "F");
}
}
}
StringHelper.java (5 methods)
public class StringHelper {
public static int countVowels(String text) {
int count = 0;
String lower = text.toLowerCase();
for (int i = 0; i < lower.length(); i++) {
char c = lower.charAt(i);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
count++;
}
}
return count;
}
public static boolean isPalindrome(String text) {
String lower = text.toLowerCase();
int left = 0;
int right = lower.length() - 1;
while (left < right) {
if (lower.charAt(left) != lower.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
public static String toTitleCase(String text) {
String lower = text.toLowerCase();
String result = "";
boolean capitalizeNext = true;
for (int i = 0; i < lower.length(); i++) {
char c = lower.charAt(i);
if (c == ' ') {
result += c;
capitalizeNext = true;
} else if (capitalizeNext) {
result += (char) (c - 32);
capitalizeNext = false;
} else {
result += c;
}
}
return result;
}
public static String maskString(String text) {
if (text.length() <= 4) {
return text;
}
String masked = "";
for (int i = 0; i < text.length() - 4; i++) {
masked += "*";
}
masked += text.substring(text.length() - 4);
return masked;
}
public static String summarize(String text) {
return text + " has " + text.length() + " chars, " + countVowels(text) + " vowels, palindrome: " + isPalindrome(text);
}
}
MathUtils.java (6 methods)
public class MathUtils {
public static boolean isPrime(int n) {
if (n <= 1) {
return false;
}
for (int i = 2; i <= n / 2; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
public static int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
public static int[] everyOther(int[] arr) {
int size = (arr.length + 1) / 2;
int[] result = new int[size];
int index = 0;
for (int i = 0; i < arr.length; i += 2) {
result[index] = arr[i];
index++;
}
return result;
}
public static int countPrimes(int max) {
int count = 0;
for (int i = 2; i <= max; i++) {
if (isPrime(i)) {
count++;
}
}
return count;
}
public static boolean isSorted(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
return false;
}
}
return true;
}
public static int range(int[] arr) {
int max = arr[0];
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
return max - min;
}
}