Computer Science A
2015 FRQ 4
- FRQ Question Part A
- 💻 Code Builder: NumberGroup Interface
- Code Runner Challenge
- Scoring Guidelines Part A (2pts)
- ❓ Popcorn Hack: What's Wrong With This Interface?
- There are THREE major errors:
- ❓ Popcorn Hack: What's Wrong With This Interface?
- FRQ Question Part B
- Code Runner Challenge
- Scoring Guidelines Part B (5pts)
- FRQ Question Part C
- Code Runner Challenge
- Scoring Guidelines Part C (2pts)
- ❓ Popcorn Hack: Test Your Understanding
- All return TRUE! Here's why:
- ❓ Popcorn Hack: Test Your Understanding
- Question-Specific Penalties
FRQ Question Part A
A number group represents a group of integers defined in some way. It could be empty, or it could contain one or more integers.
Write an interface named NumberGroup that represents a group of integers. The interface should have a single contains method that determines if a given integer is in the group. For example, if group1 is of type NumberGroup, and it contains only the two numbers -5 and 3, then group1.contains(-5) would return true, and group1.contains(2) would return false.
Write the complete NumberGroup interface. It must have exactly one method.
💻 Code Builder: NumberGroup Interface
Click the correct code pieces to build the interface
Why use an interface instead of just a range class?
Flexibility: Range, EvenNumbers, PrimeGroup all behave as NumberGroups
Real-world parallel: Java Collections (List interface → ArrayList, LinkedList)
Testability: Can swap implementations without changing MultipleGroups
// All valid because of the interface
NumberGroup group1 = new Range(1, 10);
NumberGroup group2 = new OddNumbers();
NumberGroup group3 = new PrimeNumbers();
NumberGroup group4 = new DivisibleBy(7);
// MultipleGroups doesn't care about the implementation
List<NumberGroup> list = Arrays.asList(group1, group2, group3, group4);
MultipleGroups mg = new MultipleGroups(list);
What would happen if we did this with concrete classes only?
Code Runner Challenge
FRQ Part A — NumberGroup Interface
View IPYNB Source
// CODE_RUNNER: FRQ Part A — NumberGroup Interface
public class Main {
public interface NumberGroup
{
boolean contains(int num);
}
// Simple test implementation so we can run it
static class TestGroup implements NumberGroup
{
public boolean contains(int num)
{
return num == -5 || num == 3;
}
}
public static void main(String[] args)
{
NumberGroup group1 = new TestGroup();
System.out.println(group1.contains(-5)); // true
System.out.println(group1.contains(3)); // true
System.out.println(group1.contains(2)); // false
}
}
Main.main(null);
Scoring Guidelines Part A (2pts)
+1 interface NumberGroup (point lost if visibility private)
+1 boolean contains(int num); (point lost if visibility not public or extraneous code present)
❓ Popcorn Hack: What's Wrong With This Interface?
private interface NumberGroup {
public boolean contains(int num) {
return false;
}
}
There are THREE major errors:
private interface NumberGroup
- Interfaces must be
public(or package-private with no modifier) - Why: Interfaces are meant to be implemented by other classes, so they need to be accessible
- Fix:
public interface NumberGroup
public boolean contains(int num) {
return false; // WRONG!
}
- Interface methods should only have signatures, not bodies
- Why: Interfaces define the contract (what methods exist), but implementing classes provide the actual code
- Fix:
boolean contains(int num);(just the signature with a semicolon)
public boolean contains(int num)
- Interface methods are implicitly public, so the
publickeyword is redundant - Best practice: Just write
boolean contains(int num); - Note: The AP exam scoring guidelines penalize this
public interface NumberGroup {
boolean contains(int num);
}
- ✓
public interface(not private) - ✓ Method signature only (no body
{}) - ✓ No
publicmodifier on the method (it's implicit)
FRQ Question Part B
A range represents a number group that contains all (and only) the integers between a minimum value and a maximum value, inclusive.
Write the Range class, which is a NumberGroup. The Range class represents the group of int values that range from a given minimum value up through a given maximum value, inclusive. For example,the declaration
NumberGroup range1 = new Range(-3, 2);
Numbergroup: Interface type - defines what methods are available
new Range: Concrete class - defines how methods work represents the group of integer values -3, -2, -1, 0, 1, 2.
Write the complete Range class. Include all necessary instance variables and methods as well as a constructor that takes two int parameters. The first parameter represents the minimum value, and the second parameter represents the maximum value of the range. You may assume that the minimum is less than or equal to the maximum.
Code Runner Challenge
FRQ Part B — Range Class
View IPYNB Source
// CODE_RUNNER: FRQ Part B — Range Class
public class Main {
interface NumberGroup
{
boolean contains(int num);
}
public class Range implements NumberGroup
{
private int min;
private int max;
public Range(int min, int max)
{
this.min = min;
this.max = max;
}
public boolean contains(int num)
{
return num >= min && num <= max;
}
}
public static void main(String[] args)
{
NumberGroup range1 = new Main().new Range(-3, 2);
System.out.println(range1.contains(-3)); // true
System.out.println(range1.contains(0)); // true
System.out.println(range1.contains(2)); // true
System.out.println(range1.contains(3)); // false
}
}
Main.main(null);
Scoring Guidelines Part B (5pts)
+1 class Range implements NumberGroup (point lost if visibility private)
+1 Declares appropriate private instance variable(s)
+1 Uses correct constructor header
+1 Initializes instance variables within constructor using parameters (point lost if bounds errors occur in container use)
+1 Computes and returns correct value from contains (point lost for incorrect method header)
FRQ Question Part C
The MultipleGroups class (not shown) represents a collection of NumberGroup objects and is a NumberGroup. The MultipleGroups class stores the number groups in the instance variable groupList (shown below), which is initialized in the constructor.
private List<NumberGroup> groupList;
Write the MultipleGroups method contains. The method takes an integer and returns true if and only if the integer is contained in one or more of the number groups in groupList.
For example, suppose multiple1 has been declared as an instance of MultipleGroups and consists of the three ranges created by the calls new Range(5, 8), new Range(10, 12), and new Range(1, 6). The following table shows the results of several calls to contains.
| Call | Result |
|---|---|
| multiple1.contains(2) | true |
| multiple1.contains(9) | false |
| multiple1.contains(6) | true |
Enhanced For-loop
for (NumberGroup group : groupList) {
if (group.contains(num)) { ... }
}
x
Loop variable type matches interface and works with any class that implements NumberGroup
Code Runner Challenge
FRQ Part C — MultipleGroups
View IPYNB Source
// CODE_RUNNER: FRQ Part C — MultipleGroups
import java.util.List;
import java.util.ArrayList;
public class Main {
interface NumberGroup
{
boolean contains(int num);
}
static class Range implements NumberGroup
{
private int min;
private int max;
public Range(int min, int max)
{
this.min = min;
this.max = max;
}
public boolean contains(int num)
{
return num >= min && num <= max;
}
}
class MultipleGroups implements NumberGroup
{
private List<NumberGroup> groupList;
public MultipleGroups(List<NumberGroup> groups)
{
groupList = groups;
}
public boolean contains(int num)
{
for (NumberGroup group : groupList)
{
if (group.contains(num))
{
return true;
}
}
return false;
}
}
public static void main(String[] args)
{
NumberGroup g1 = new Range(5, 8);
NumberGroup g2 = new Range(10, 12);
NumberGroup g3 = new Range(1, 6);
List<NumberGroup> list = new ArrayList<>();
list.add(g1);
list.add(g2);
list.add(g3);
MultipleGroups multiple1 = new Main().new MultipleGroups(list);
System.out.println(multiple1.contains(2)); // true
System.out.println(multiple1.contains(9)); // false
System.out.println(multiple1.contains(6)); // true
}
}
Main.main(null);
Scoring Guidelines Part C (2pts)
+1 Calls contains on elements of groupList in context of loop (no bounds errors)
+1 Computes and returns correct value
❓ Popcorn Hack: Test Your Understanding
Given these Range objects, what should these method calls return?
Range r1 = new Range(5, 5);
r1.contains(5); // ???
Range r2 = new Range(-10, -5);
r2.contains(-7); // ???
Range r3 = new Range(0, 100);
r3.contains(0); // ???
r3.contains(100); // ???
All return TRUE! Here's why:
Range(5, 5)
- Why: A range can have the same min and max!
- Logic:
5 >= 5 && 5 <= 5is true - Result: This range contains only the number 5
Range(-10, -5)
- Why: Ranges work with negative numbers too!
- Logic:
-7 >= -10 && -7 <= -5is true - Result: -7 is between -10 and -5 (inclusive)
Range(0, 100)
- Why: The boundaries are INCLUSIVE (uses >= and <=)
- For 0:
0 >= 0 && 0 <= 100is true - For 100:
100 >= 0 && 100 <= 100is true - Result: Both minimum and maximum values are included in the range
The contains method uses >= and <= (not > and <)
This means the range includes both the minimum and maximum values.
public boolean contains(int num) {
return num >= min && num <= max;
// ^^ ^^
// Equal signs make it INCLUSIVE!
}
If you used > and < instead:
return num > min && num < max; // WRONG!
Then Range(0, 100).contains(0) and .contains(100) would both return false—you'd lose a point!
Question-Specific Penalties
-1 (s) Inappropriate use of static
Other common mistakes Part B: Forgetting private on instance variables (-1) Part B: Using > and < instead of >= and <= (-1) Part A: Adding method body to interface (-1) Part C: Messing up loop logic (-1 or -2)
Alternate Solutions
// Solution 1
public class Range implements NumberGroup {
private int min, max;
public Range(int minimum, int maximum) {
min = minimum;
max = maximum;
}
public boolean contains(int num) {
return num >= min && num <= max;
}
}
// Solution 2
public class Range implements NumberGroup {
private int minVal;
private int maxVal;
public Range(int min, int max) {
this.minVal = min;
this.maxVal = max;
}
public boolean contains(int value) {
if (value >= minVal && value <= maxVal)
return true;
return false;
}
}
// Solution 3
public class Range implements NumberGroup {
private int low, high;
public Range(int a, int b) {
low = a;
high = b;
}
public boolean contains(int num) {
return (num >= low && num <= high);
}
}