Welcome to Lesson 15!


Learning Objectives
By the end of today's class, you should know...
  • What is the problem caused by newline characters when mixing next(), nextInt() and nextDouble() with nextLine()?
  • How do you write a method?
  • How do you write a method call?
  • What is the order of the statements that are executed when a method call is made?

Announcements

  • Last day to drop with a "W" is this Friday.
  • Quiz 6 after the break
  • Midterm 2 one week from today - lesson 9 - lesson 15
    • Same format as Midterm 1: ~15 multiple choice/short answer/true-false questions and 1 full program
    • Study old quizzes and review activities
    • Review your homework assignments and get help on any you struggled with
  • Don't forget to complete Lab 7 on Friday


Review Activity:

With a partner, answer the following questions:

  • What is the advantage of using a do-while loop instead of a while loop?
  • Change the following while loop into a do-while loop:

System.out.print("Please enter your 9 digit password: ");

String password = input.next();

while (password.length() != 9) {

    System.out.print("Please enter your 9 digit password: ");

    password = input.next();

}


  • Write a for loop to print the following String named sport out character-by-character:
String sport;
System.out.println("Enter your favorite sport: ");
sport = input.next();
//write your for loop here

  • What will the following display to the console?

String message = "I love cookies!";

    System.out.print(message.substring(8, 10));
  • Add in the missing lines of code to the program below to handle the case where a user enters a String when you are expecting a double:

          double gpa;
    Scanner input = new Scanner(System.in);
    System.out.print("Please enter your gpa: ");
    while(                ) { //fill in the missing test condition here
            System.out.println("Please enter numbers not text!");

           

            System.out.print("Please enter your gpa: ");
        }
        gpa = input.nextDouble();


Wrapping Up Strings

  • When you press the Enter key, a newline character ('\n') is inserted as part of the input
  • The newline character can cause problems when you mix input.next(), input.nextInt() or input.nextDouble() with input.nexLine()
  • Recall that input.next(), as well as nextInt() and nextDouble():
    1. Skips whitespace
    2. Reads non-whitespace characters into the variable
    3. Stops reading when whitespace is found
  • Since whitespace includes newline characters, using input.next() will leave a newline character in the input stream
  • However, input.nextLine() just stops reading when it first finds a newline character
  • This can lead to mysterious results in code like the following:
    System.out.print("Enter your age: ");
    int age = input.nextInt();
    System.out.print("Enter your full name: ");
    String name = input.nextLine();
    System.out.println("Your age: " + age + "\n"
         + "Your full name: " + name);
    
  • To correct this problem we add an additional input.nextLine() just before input.nextLine()

System.out.print("Enter your full name: "); 
input.nextLine(); //clear out the \n
String name = input.nextLine();

  • We can see how to use this fix in the following example

Example Using an additional input.nextLine()


public static void main(String[] args) {
    Scanner input = new Scanner(System.in);

    System.out.print("Enter your age: ");
    int age = input.nextInt();

    System.out.print("Enter your full name: ");
    input.nextLine(); //clear out the \n
    String name = input.nextLine();     System.out.println("Your age: " + age + "\n"     + "Your full name: " + name); }

Activity 15.1: Sentence Continued (10 pts)
  • Let's add to our program involving sentences from the last activity. We will also calculate the number of letters in the sentence and take in a user guess for a number of letters.
  • At the end of the program, we will confirm whether their guess was correct or not.
  • Declare a new variable beneath the other two at the top of the program. This variable will be used to store our calculation for the number of letters. 
  • Also, add a variable to store the user input for their guess. 
  • The variable declaration section of your program should now look like this:
String sentence;
int numWords = 1;
int numLetters = 0;
int start_index = 0;
int guess;
Scanner input = new Scanner(System.in);
  • Now alter your first System.out.println statement to reflect the additional uses of this program. Remove the original message in your System.out.println statement and replace it with the one below:
Think of a sentence in your mind.
Later I will tell you how many words and letters are in your sentence.

  • Now, ask the user to enter a guess for how many letters are in the sentence. We want the user to guess without counting the number of letters.
Enter a guess for the number of letters in your sentence (don't count!): _
  • Store the user guess as the guess variable using input.nextInt().
  • Next, prompt the user to enter the sentence. Your prompt should remain the same from the last exercise and, as before, you should use input.nextLine() to store the user input as the sentence variable.
Please enter your sentence: _
  • Verify that your code inside main looks like identical to the code below:

  • Now, run your program. You should notice a problem.
  • How can we fix this problem?
  • Add an additional input.nextLine() above your sentence = input.nextLine();
input.nextLine();
sentence = input.nextLine();
  • Compile and run your code again and verify that it is now working properly.
  • Now let's alter the code inside the for loop to calculate how many letters are in the sentence.
  • Since we don't want to count any blank spaces, we only want to increment the numLetters variable when we are NOT incrementing the numWords variable. 
  • Therefore, we need to add an else statement to our for loop. Make sure your if-else in the for loop looks like this:
if (sentence.charAt(i) == ' ') {
    numWords++;
    System.out.println(sentence.substring(start_index, i));
    start_index = i+1; //new starting index
} else {
    numLetters++;
}
  • Now, let's add another print statement below the for loop to print out the number of letters in the sentence,
System.out.println("And, " + numLetters + " letters.");
  • Did our user guess the number of letters correctly? Now is the time to let him or her know. Add the following if-else block at the bottom of main.
if (guess == numLetters) {
    System.out.println("You guessed right!");
} else {
    System.out.println("You guessed wrong!");
}
  • Run your program again and you should get the following output. Note: if you don't get the output below, compare your program to the final version at the end of this exercise. When you are finished, upload to Canvas.

  • The revised portion of your code should look like the following:


Introducing Methods

Java comes with predefined methods

  • Example:  sqrt method returns, or computes, the square root of a number
double the_root = Math.sqrt(9.0);
  • The number, 9.0, is called the argument
  • the_root will contain 3.0

Method Calls

  • sqrt(9.0) is a "method call."
  • It invokes, or sets in action, the sqrt method
  • The argument (9), can also be a variable or an expression
  • A method call can be used like any expression:
double bonus =  Math.sqrt(sales) / 10;

System.out.println("The side of a square with area " + area
         + “ is “
         + Math.sqrt(area));


What methods have we seen so far in this class?

  • pow(base, exponent)
  • sqrt(number)
  • length()
  • substring(start_index, end_index)
  • charAt(index);
  • nextLine(), nextInt(), etc
  • Any others?
  • What do they all have in common? Notice any similarities in their syntax?

Method Call Syntax

  • Method_name (Argument_List)
  • Argument_List is a comma separated list:  (Argument_1, Argument_2, … , Argument_Last)   

side = Math.sqrt(area);
System.out.println("2.5 to the power 3.0 is "
         + Math.pow(2.5, 3.0));


Writing Our Own Methods

Grouping Repeated Commands

  • Some of the main() methods in our programs have been getting lengthy and complicated (See above activity with Strings!)
  • The biggest problem in developing software is managing the complexity of programs
  • We can improve our code by organizing it into smaller pieces known as methods
  • Methods are a key tool in creating easy-to-understand programs that can be changed easily

Video: Chris Bosh Explains Functions (methods)

What is a Method?

  • As developers, we need to know how to write and call methods

    Method = a named block of statements that can receive input, perform an action, and optionally return a value

  • Methods are like little programs in our larger program
  • We give each little method commands we want executed
  • We call the method whenever we want the commands executed
  • When the method has finished running, program execution returns to the point just after the code that called the method

Example Application for a Method

  • As an example, recall our test code to validate user input:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

public static void main(String[] args) {
    double number = 0.0; // initialize value
    Scanner input = new Scanner(System.in);    

    while (number <= 0) { System.out.print("Enter a positive number: "); number = input.nextDouble(); if (number <= 0.0) { System.out.println("You must enter a positive number\n"); } } System.out.println("\nYou entered: " + number); }
  • What if we need to enter two validated numbers into a program?
  • We want to process the first number after input and then input the second number
  • Doing so, we would end up with code like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

public static void main(String[] args) {
    double number = 0.0; // initialize value
    Scanner input = new Scanner(System.in);    

    while (number <= 0) { System.out.print("Enter a positive number: "); number = input.nextDouble(); if (number <= 0.0) { System.out.println("You must enter a positive number\n"); } } System.out.println("\nYou entered: " + number);
    

    while (number <= 0) { System.out.print("Enter a second positive number: "); number = input.nextDouble(); if (number <= 0.0) { System.out.println("You must enter a positive number\n"); } }

    System.out.println("\nYou entered: " + number);

 }
  • Our program would be easier to write if we could get the second input without repeating the code
  • With methods, we give the list of commands a name and then run the list by calling the name
  • Using methods we keep all the code in one place and avoid duplication
  • Avoiding duplication reduces the complexity of our code and makes it easier to understand and change

Programming Style: Avoid Duplicating Code

  • Duplicate code can lead to problems such as:
    • Long repeated sections that are more difficult to understand than shorter sequences
    • Repetition of largely identical code within which it is difficult to see the different purposes of each section
    • Update problems where we make changes in some sections but overlook making changes in other sections
  • If we find ourselves writing similar code of three or more lines multiple times, we should consider writing a method

Defining a Method

  • In this section we look at method definition syntax and examine a simple example method
  • After we understand the syntax we can write more complicated methods

Method Syntax

  • The general syntax for defining a method is:
    public static returnType methodName(parameter1, ..., parametern) {
        statements
    }
    
  • Where:
    • returnType: the data type of the value returned
    • methodName: the name you make up for the method
    • parameterx: the input values, if any
    • statements: the list of statements to execute when the method is called

Example Program with a Method

  • As an example, the following program has a simple method to add two numbers
  • Notice that the code has two methods: add() and main()
  • The second method add() can be placed anywhere outside of main().
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

public static int add(int num1, int num2) {
    int sum = num1 + num2;
return sum;
}

public static void main(String[] args) {

int result;
System.out.print("The sum of 2 and 5 is: ");
result = add(2,5); //first "call" to the add method
System.out.println(result);

System.out.print("The sum or 7 and 9 is: ");
result = add(7,9); //second "call" to the add method
System.out.println(result);
}

Method Name

  • Every method must have a name that identifies the method
  • Method names follow the same rules as variable names
  • Technically, we can use any valid identifier for a method name
  • However, we should use a name that suggests the action the method performs
  • In our example, add suggests that the method will return the sum of two numbers

Method Structure

  • The first line of a method is known as the method signature
    public static int add(int a, int b)
    
  • The curly braces {...} contain the method body
  • The method body is the list of statement the method executes when called
  • The method signature describes the name, inputs and output of a method
  • We will look at these features in more detail in the following sections

Parameters

  • When defining a method, it is worth thinking about what helpful action it will perform
  • We can make the method more useful if we give it parameters
  • The parameters for an add method would be the two numbers to sum
  • Read through the following code to identify how the code makes use of the parameters

Example Code with Method Parameters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    public static int add(int num1, int num2) {
int sum = num1 + num2;
return sum;
}

public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter two numbers to add: ");
int num1 = input.nextInt();
int num2 = input.nextInt();
System.out.print("The sum of " +num1 + " and " + num2 + " is: ");
int result = add(num1, num2);
System.out.println(result);

}

Parameter List

  • We must have parenthesis after a method name
  • Inside the parenthesis, we define a list of zero or more parameters
  • Parameters are the inputs to a method
  • In our example, we have two parameters inside the parenthesis
    int add(int a, int b)
    
  • Parameters are the declaration of a new variable, even though they are declared inside parenthesis
  • Each parameter must have both a type and a name, just like a regular variable
  • If we have more than one parameter, we separate them with commas
  • Any parameter that we declare must be given an argument when we call the method
  • In the following image, the value of arguments num1 and num2 are copied to the parameters a and b

Passing Arguments to Method Parameters


Arguments and Parameters

  • Depending on our background, we might use the term arguments or parameters for the values passed to methods
  • The terminology is not that important
  • However, the way I will use the terms is:
    • A method definition has parameters
      public static int add(int a, int b) { // a and b are parameters
          // ...
      }
      
    • A method call passes arguments
      add(num1, num2); // num1 and num2 are arguments
      
  • Arguments are values we pass into methods
  • When the argument drops into a method, it lands in a parameter
  • A parameter is just like other variables in the method
    • Except that a parameter gets initialized by an argument
  • The important part is:

    We must pass every method parameter an argument.

  • The arguments must be in the same order as the parameters
  • Also, the argument value must be compatible with the type of the parameter
  • For example, we cannot call add() with: add("Jennifer", "Parrish")



Returning a Value

  • The first word after public static in the method signature is the return type
    public static int add(int a, int b)
    
  • The return type specifies the type of data the method outputs
  • In our example the return type is an int

Return Statement

  • Methods that return a value must execute a return statement
    return result;
    
  • For instance, our example method add() has a return statement
    public static int add(int a, int b) {
        int sum = a + b;
        return sum;
    }
    
  • Note that the type of the returned valued must be compatible with the method return type
  • The returned value is substituted for the method call in the calling code
    sum =>[replaces]=> add(num1, num2)
    
  • We must save the returned value if we want to process it later in the program
    int total = add(num1, num2);
    

Returning a Value from a Method


Returning an Expression

  • The value after the word return can be an expression
  • It does not have to be just the name of a variable
  • We could rewrite our return statement to the following:
    return a + b;
    

Multiple return Statements

  • We can have more than one return statement in a method
  • The first return statement reached is the one executed
  • We might have multiple returns if we have if-statements with alternate actions, like:
    if (x > 400) {
        return 1;
    } else {
        return 0;
    }
    
  • We do not have alternate actions in our simple add method and so have only one return statement

Activity 15.2: Writing a Method (10 pts)

In this exercise we define our own method.

Specifications

  1. Open a new Java project called Sub
  2. Copy the following program method above or below your main method compile and run the starter program to make sure you copied it correctly.
    public static int add(int num1, int num2) {
    int sum = num1 + num2;
    return sum;
    }
  3. Alter the signature for a method named sub that receives two int numbers and returns an int value, like we did for the add() method
    returnType sub(two_int_parameters)
    
  4. Inside the method body, subtract the second parameter from the first and return the value, like we did for the add() method.
        int sum = a + b; // from add() method, CHANGE THIS!
        return sum;
    
  5. Compile and run your code. 
  6. Inside the main() method, enter these statements:
        System.out.print("Enter two numbers to subtract: ");
        int num1 = input.nextInt();
        int num2 = input.nextInt();
        int diff = sub(num1, num2);
        System.out.println("Difference=" + diff);
    

    The fourth line contains the method call.

  7. Compile and run your modified program and verify the output looks like:
    Enter two numbers to subtract: 3 1
    Difference=2
    
  8. Save your file and submit it to Canvas.

Completed Program

When finished, your application should look like the following:



Variable Scope and Parameters


Variable and Parameter Scope

  • A variable declared inside a method can only be used within that method

    Local variable: a variable that can only be accessed within a method or block.

  • Parameters are a local variable and thus can only be used inside the method in which they are declared as well
  • As an example of a local variable, we declared sum inside the add() method:
    int sum = a + b;
    
  • In addition, we declared another variable named total inside main():
    int total = add(num1, num2);
    
  • These variables cannot be accessed outside the method they were declared within

Scope

  • The area of code that a variable can operate within is known as it's scope

    Scope: the enclosing area within which a variable exists

  • Because of scope, we can use variables with the same name in different methods
  • To send information to a methods we must include a parameters:
    public static int add(int a, int b)
    
  • When the method call is made, we send the arguments to the parameters:
    add(num1, num2)
    
  • The values of num1 and num2 are copied to the parameter variables a and b

Example of Scope - Below num1 and sum are out of scope.



Flow of Control for a Method Call

  • To use methods well, we must understand their flow of control
  • In our example, the program starts executing in the main() method
  • When our program gets to the following statement, it stops executing in main() and jumps to our method:
    int total = add(num1, num2);
    
  • The program executes the statements in the method and then returns to the statement from which it jumped
  • When the method returns, the returned value replaces the method call
  • After returning, the program completes processing the calling statement and then moves on to the next statement
  • In our example, the statement saves the returned value in the variable: total
  • Every time the flow of control reaches a method call, the program:
    1. Temporarily stops executing in the current method
    2. Jumps to the called method and executes the statements of that method
    3. Returns to the point in the code from which it jumped

Method Call Flow


  1. Every program starts executing at the start of main().
  2. When reaching a method call, arguments are copied to the parameters.
  3. Method code executes until reaching a return statement.
  4. Return statement returns a value to the method call.
  5. Calling method continues after the method returns.


Activity 15.3: Tracing a Method Call (10 pts)

  1. Create a text file named trace.txt.
  2. In the trace.txt file, list the line numbers of each statement of your program from Activity 16.1 in the order the lines are executed. For example, if main() starts on line 9, statements are executed as follows:
    9, 10, 11, 12, ...
    

    Do not bother to list blank lines or lines containing only a curly brace (}) of a method definition.

  3. Review the hand trace with another student in the class. Then add a comment to the top of the file that contains the name of the person with whom you reviewed the code, like:
    Reviewed trace with Fred George.
  4. Save the trace.txt to submit to Canvas


Wrap Up

  • With your partner, answer the questions from today's learning objectives


Upcoming Assignments
  • Assignment 15 due Tuesday at 11:20am on Canvas
  • Lab 7 due Friday at midnight