Methods and Control Structures FRQ
Methods
What are methods?
- Reusable code that performs specific tasks.
- Helps break down programs into manageable parts.
Key Parts of a Method:
- Modifier: Describes the method’s properties.
- Access Modifiers: Determines who can access the method
(e.g., public, private)
.public
: Accessible everywhere.private
: Accessible only within the class.protected
: Accessible within the package and subclasses.- Default (no modifier): Accessible within the package.
- Non-Access Modifiers: Additional properties of the method
(e.g., static, final)
.static
: Belongs to the class, not the object.final
: Cannot be overridden.
- Access Modifiers: Determines who can access the method
- Method name: Defines the method
(e.g., public int add(int a, int b))
. - Return Types: Specifies what the method returns
(int, void, etc.)
. - Parameters: Inputs for dynamic behavior.
- Method Body: Contains the code to be executed.
Types of Methods:
- Instance: Belongs to objects (e.g., myObject.method()).
- Static: Belongs to the class (e.g., ClassName.method()).
Control Structures:
Conditional Statements:
- Use if, else if, and else to make decisions.
- Example:
if (x > 0) { System.out.println("Positive"); }
Loops:
- Repeat code using:
-
for
: Known iterations (e.g.,for (int i = 0; i < 5; i++)
). -
while
: Runs while a condition is true. -
do-while
: Runs at least once.
-
Tips for Tackling Methods and Control Structures FRQs:
- Reuse Existing Methods:
- If methods are already defined, use them instead of writing your own.
- Loops:
- Pay attention to for/while loop limits to avoid infinite loops or skipping conditions.
- Avoid using break or continue unless explicitly required.
- Return Statements:
- Double-check what needs to be returned and ensure the return type matches the expected variable type.
- Be mindful of return placement in loops; returning inside a loop will terminate both the loop and the method.
- Watch for Method Requirements:
- Each question or sub-part may specify, “To get full credit, you must use method XYZ.” Read carefully and follow instructions for each part.
- Single-Class vs. Multi-Class Questions:
- Single-class questions focus on concepts within one class
- Multi-class questions require interactions between classes
- Conditional Statements and Loops:
- Expect basic concepts like
if
,if-else
,while
,for
, and nested loops. - Strings are also common in these questions.
- Expect basic concepts like
- Calling Methods:
- Same Class: Call methods directly (e.g.,
methodName()
). - Multi-Class: Use an instance of the other class (e.g.,
object.methodName()
) or the class name for static methods (e.g.,ClassName.methodName()
).
- Same Class: Call methods directly (e.g.,
- Common Algorithms to Practice:
- Searching (e.g., linear search).
- Finding maximum or minimum values.
- Counting specific occurrences (e.g., vowels in a string, even numbers in an array).
FRQ Question 1 on Control Structures will probably involve:
- A for-loop that probably uses the method’s parameter variables,
- An if statement, probably inside the loop,
- Calls to other class methods given to you,
- A numerical or string value that is calculated by the loop and returned at the end of the method.
- If the question has 2 parts, 1 part will probably require a loop and the other just an expression.
2019 AP CSA FRQ Question 1
public class APCalendar
{
/** Returns true if year is a leap year and false otherwise. */
private static boolean isLeapYear(int year)
{
/* implementation not shown */
}
/**
* Returns the number of leap years between year1 and year2, inclusive.
* Precondition: 0 <= year1 <= year2
*/
public static int numberOfLeapYears(int year1, int year2)
{
/* to be implemented in part (a) */
}
/**
* Returns the value representing the day of the week for the first day of
* year, where 0 denotes Sunday, 1 denotes Monday, ..., and 6 denotes Saturday.
*/
private static int firstDayOfYear(int year)
{
/* implementation not shown */
}
/**
* Returns n, where month, day, and year specify the nth day of the year.
* Returns 1 for January 1 (month = 1, day = 1) of any year. Precondition: The
* date represented by month, day, year is a valid date.
*/
private static int dayOfYear(int month, int day, int year)
{
/* implementation not shown */
}
/**
* Returns the value representing the day of the week for the given date
* (month, day, year), where 0 denotes Sunday, 1 denotes Monday, ..., and 6
* denotes Saturday. Precondition: The date represented by month, day, year is
* a valid date.
*/
public static int dayOfWeek(int month, int day, int year)
{
/* to be implemented in part (b) */
}
// There may be instance variables, constructors, and other methods not shown.
}
A. Write the static method numberOfLeapYears
, which returns the number of leap years between year1
and year2
, inclusive.
In order to calculate this value, a helper method is provided for you.
isLeapYear(year)
returnstrue
ifyear
is a leap year andfalse
otherwise.
Complete method numberOfLeapYears
below. You must use isLeapYear
appropriately to
receive full credit.
/** Returns the number of leap years between year1 and year2, inclusive.
* Precondition: 0 <= year1 <= year2
*/
public static int numberOfLeapYears(int year1, int year2)
First Step
First, identity the information given that you will need to use:
- the parameters
year1
andyear2
- the
isLeapYear(year)
method
Also, identify what the return type of what you need to return. In this case, the return type of numberOfLeapYears
is int and you need to calculate the number of leap years between year1
and year2
and return it. Declare a variable for this return value and return it at the end of the method to get 1 point.
/** Returns the number of leap years between year1 and year2, inclusive.
* Precondition: 0 <= year1 <= year2
*/
public static int numberOfLeapYears(int year1, int year2)
{
int numLeapYears = 0;
// Your loop will go in here
return numLeapYears;
}
Second Step
Next, plan your loop.
Which loop should you use to count the number of leap years between year1 and year2?
i. for loop
ii. while loop
Correct answer: i. for loop because we mainly use it when we know how many times a loop needs to execute. A while loop would be better when when you don’t know how many times a loop needs to execute. But, but would work and give the same answers.
What is the starting and ending values for the loop to count the leap years between year 1 and year 2?
i. Loop from 0 to year1
ii. Loop from 0 to year2
iii. Loop from 2020 to 2030
iv. Loop from year1 to year2
Correct answer: iv. Loop from year1 to year2 because we need to count the number of leap years between year1 and year2. i and ii are incorrect because we need to loop from year1 to year2 and not from the beginning of time. iii is incorrect because it is not related to the problem.
Third Step
Constructing our for loop
/** Returns the number of leap years between year1 and year2, inclusive.
* Precondition: 0 <= year1 <= year2
*/
public static int numberOfLeapYears(int year1, int year2)
{
int numLeapYears = 0;
for (int i = year1; i <= year2; i++) {
}
return numLeapYears;
}
Here, we know we can set the lower bound as year1
because it is guaranteed it is lower than year2
. Also, since it is inclusive of year1
and year2
, we can use i <= year2
as the condition.
Fourth Step
Checking if the year is a leap year and incrementing the numLeapYears
variable if it is. To do this, we can use the isLeapYear
method provided to us.
/** Returns the number of leap years between year1 and year2, inclusive.
* Precondition: 0 <= year1 <= year2
*/
public static int numberOfLeapYears(int year1, int year2)
{
int numLeapYears = 0;
for (int i = year1; i <= year2; i++) {
if (isLeapYear(i)) {
numLeapYears++;
}
}
return numLeapYears;
}
Collegeboard Solution
/** Returns the number of leap years between year1 and year2, inclusive.
* Precondition: 0 <= year1 <= year2
*/
public static int numberOfLeapYears(int year1, int year2)
{
int count = 0;
for (int y = year1; y <= year2; y++) {
if (isLeapYear(y)) {
count++;
}
}
return count;
}
B. Write the static method dayOfWeek
This returns the integer value representing the day of the week for the given date (month, day, year)
, where 0
denotes Sunday, 1
denotes Monday, …, and 6
denotes Saturday. For example, 2019 began on a Tuesday, and January 5 is the fifth day of 2019. As a result, January 5, 2019, fell on a Saturday, and the method call dayOfweek (1, 5, 2019)
returns 6
.
As another example, January 10 is the tenth day of 2019. As a result, January 10, 2019, fell on a Thursday, and the method call dayOfWeek (1, 10, 2019)
returns 4
.
In order to calculate this value, two helper methods are provided for you.
-
firstDayOfYear (year)
returns the integer value representing the day of the week for the first day ofyear
, where0
denotes Sunday,1
denotes Monday, …, and6
denotes Saturday. For example, since 2019 began on a Tuesday,firstDayOfYear (2019)
returns2
. -
dayOfYear (month, day, year)
returnsn
, wheremonth
,day
, andyear
specify the nth day of the year. For the first day of the year, January 1(month = 1, day = 1)
, the value 1 is returned. This method accounts for whether year is a leap year. For example,dayOfYear (3, 1, 2017)
returns60
, since 2017 is not a leap year, whiledayOfYear (3, 1, 2016)
returns61
, since 2016 is a leap year.
Class information for this question
public class APCalendar
private static boolean isLeapYear(int year)
public static int numberOfLeapYears(int year1, int year2)
private static int firstDayOfYear(int year)
private static int dayOfYear(int month, int day, int year)
public static int dayOfWeek(int month, int day, int year)
Complete method dayOfWeek
below. You must use firstDayOfYear
and dayOfYear
appropriately to receive full credit.
/** Returns the value representing the day of the week for the given date
* (month, day, year), where 0 denotes Sunday, 1 denotes Monday, ...,
* and 6 denotes Saturday.
* Precondition: The date represented by month, day, year is a valid date.
*/
public static int dayOfWeek(int month, int day, int year)
First Step
First, identify the information given that you will need to use:
- the parameters
month
,day
, andyear
- the
firstDayOfYear(year)
method: returns the integer value representing the day of the week for the first day of year, where 0 denotes Sunday, 1 denotes Monday, …, and 6 denotes Saturday. For example, since 2019 began on a Tuesday, firstDayOfYear(2019) returns 2. - the
dayOfYear(month, day, year)
method: returns n, where month, day, and year specify the nth day of the year. For the first day of the year, January 1 (month = 1, day = 1), the value 1 is returned. This method accounts for whether year is a leap year. For example, dayOfYear(3, 1, 2017) returns 60, since 2017 is not a leap year, while dayOfYear(3, 1, 2016) returns 61, since 2016 is a leap year.
If you know that 1/1/2019 was a Tuesday (2) using the firstDayYear method, and you know that today is the nth day of the year using the dayOfYear method, you can figure out what day of the week today is by adding those together. Try some examples by revealing the problems below.
If firstDayOfYear(2019)
returns 2 for a Tuesday for 1/1/2019, what day of the week is Jan. 4th 2019?
i. Wednesday (3)
ii. Thursday (4)
iii. Friday (5)
iv. Saturday (6)
Correct answer: iii. Friday (5)
because since 1/1/19 is a Tuesday, Jan. 4th 2019 is 3 days later on a Friday.
Which of the following expressions return the right value for the day of the week (5) for Jan. 4th 2019 given that firstDayOfYear(2019)
returns 2 and dayOfYear(1,4,2019)
returns 4?
i. firstDayOfYear(2019) + dayOfYear(1,4,2019)
ii. firstDayOfYear(2019) + dayOfYear(1,4,2019) - 1
iii. firstDayOfYear(2019) - dayOfYear(1,4,2019)
iv. firstDayOfYear(2019) * dayOfYear(1,4,2019)
Correct answer: ii. firstDayOfYear(2019) + dayOfYear(1,4,2019) - 1
You must start at the firstDayOfYear and add on the days following up until that date - 1 since you start counting at 1.
If firstDayOfYear(2019)
returns 2 for a Tuesday for 1/1/2019, what day of the week from (0-6 where 0 is Sunday) is Jan. 8th 2019?
i. 1
ii. 2
iii. 3
iv. 9
Correct answer: ii. 2 because since 1/1/19 is a 7 days after 1/1/2019, or exactly a week later, it must also be Tuesday.
Second Step
Come up with a formula.
If we used the formula in the exercise above for the date 1/8/2019, we would get 9:
firstDayOfYear(2019) + dayOfYear(1,8,2019) - 1 = 2 + 8 - 1 = 9
But there is no 9th day of week. There are only 7 days of the week. So when we reach a Sunday, we must start back at 0. This is a place where the remainder operator % is useful. Note that 9 % 7 = 2 which means that 1/8/2019 is the 2nd day of the week starting at 0.
* Quick Tip
- Use remainder whenever you need to wrap around to the front if the value goes over the limit (num % limit). For example here for weekdays or for hours and minutes.
- Use remainder to check for odd or even numbers (num % 2 != 0) is odd and (num % 2 == 0) is even. Actually, you can use it to check if any number is evenly divisible by another (num1 % num2 == 0).
- Use % to get the last digit from an integer number (num % 10 gives the last digit on right).
Third Step
Initialize the variables
This is where we will finish the requirement of using methods, firstDayOfYear(year)
and dayOfYear(month, day, year)
.
/** Returns the value representing the day of the week for the given date
* (month, day, year), where 0 denotes Sunday, 1 denotes Monday, ...,
* and 6 denotes Saturday.
* Precondition: The date represented by month, day, year is a valid date.
*/
public static int dayOfWeek(int month, int day, int year) {
int firstDay = firstDayOfYear(year);
int nthDay = dayOfYear(month, day, year);
}
Fourth Step
Construct the formula
Here, we will use the formula returnDay = (firstDay + nthDay - 1) % 7
to get the day of the week.
/** Returns the value representing the day of the week for the given date
* (month, day, year), where 0 denotes Sunday, 1 denotes Monday, ...,
* and 6 denotes Saturday.
* Precondition: The date represented by month, day, year is a valid date.
*/
public static int dayOfWeek(int month, int day, int year) {
int firstDay = firstDayOfYear(year); /* Initialize the the value of the first day of the year */
int nthDay = dayOfYear(month, day, year); /* Initialize the value of the nth day of the year */
int returnDay = (firstDay + nthDay - 1) % 7; /* This is the formula */
}
Fifth Step
Return the value
/** Returns the value representing the day of the week for the given date
* (month, day, year), where 0 denotes Sunday, 1 denotes Monday, ...,
* and 6 denotes Saturday.
* Precondition: The date represented by month, day, year is a valid date.
*/
public static int dayOfWeek(int month, int day, int year) {
int firstDay = firstDayOfYear(year); /* Initialize the the value of the first day of the year */
int nthDay = dayOfYear(month, day, year); /* Initialize the value of the nth day of the year */
int returnResult = ((firstDay + nthDay - 1) % 7); /* This is the formula */
return returnResult;
}
Collegeboard Solution
public static int dayOfWeek(int month, int day, int year)
{
int startDay = firstDayOfYear(year);
int nthDay = dayOfYear(month, day, year);
int returnDay = (startDay + nthDay - 1) % 7;
return returnDay;
}
Scoring Guidlines
Penalty Guidlines
1-Point Penalty
- Array/collection access confusion (
[] get
) - Extraneous code that causes side-effect (e.g., printing to output, incorrect precondition check)
- Local variables used but none declared
- Destruction of persistent data (e.g., changing value referenced by parameter)
- Void method or constructor that returns a value
No Penalty
- Extraneous code with no side-effect (e.g., valid precondition check, no-op)
- Spelling/case discrepancies where there is no ambiguity *
- Local variable not declared provided other variables are declared in some part
private
orpublic
qualifier on a local variable- Missing
public
qualifier on class or constructor header - Keyword used as an identifier
- Common mathematical symbols used for operators (
x • ÷ < ≥ <>#
) []
VS.()
vs.<>
=
instead of==
and vice versalength
/size
confusion for array,String
,List
, orArrayList
; with or without()
- Extraneous
[]
when referencing entire array [i,j]
instead of[i][j]
- Extraneous size in array declaration, e.g.,
int[size] nums = new int[size];
- Missing
;
where structure clearly conveys intent - Missing where indentation clearly conveys intent
- Missing
( )
on parameter-less method or constructor invocations - Missing
( )
aroundif
orwhile
conditions
* Spelling and case discrepancies for identifiers fall under the “No Penalty” category only if the correction can be unambiguously inferred from context, for example, “ArayList
” instead of “ArrayList
”. As a counterexample, note that if the code declares “int G=99, g=0;
”, then uses “while (G < 10)
” instead of “while (g < 10)
”, the context does not allow for the reader to assume the use of the lower-case variable.
Tips
- Helper methods are given to you so you should use them!
- If the method returns something, then you need a return line
Part A Scoring Guidlines
Part B Scoring Guidlines
Homework
Complete 2022 FRQ Question 1
We will post solutions and explanations after due date. Good luck!