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.
  • 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. image

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++)).

      for loop

    • while: Runs while a condition is true.

      while loop

    • do-while: Runs at least once.

      do-while loop


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.
  • 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()).
  • 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

Link to 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) returns true if year is a leap year and false 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 and year2
  • 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 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.

  • dayOfYear (month, day, year) 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.

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, and year
  • 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 or public 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 versa length / size confusion for array, String, List, or ArrayList; 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 ( ) around if or while 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! image image
  • If the method returns something, then you need a return line image image

Part A Scoring Guidlines

Screenshot 2025-01-08 at 7 44 36 AM

Screenshot 2025-01-08 at 7 45 32 AM


Part B Scoring Guidlines

Screenshot 2025-01-08 at 7 56 12 AM

Screenshot 2025-01-08 at 7 56 47 AM


Homework

Complete 2022 FRQ Question 1

Link to 2022 FRQ Question 1

We will post solutions and explanations after due date. Good luck!