Nested Selections

Things To Do First

Things To Do Later

Nested If's

Sometimes a program's decision making needs to be a little bit more complex. For example, imagine a situation where you ask the user for a log-in name. If they enter a valid name, ask them for a password. If the password is valid, display a message on the screen. If either the password or login name is not valid, display a specific message to the user.

To perform this task, you will first need an if statement to check the log-in name and possibly display a message if it's invalid:

import java.util.Scanner;

public class Nested {

    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        System.out.print("Enter your name: ");

        String name = in.nextLine();

        if (name.equals("Kaluha")) {

            // check password

        } else {
            System.out.println("Invalid Login Name");
        }

    }
}

Next, we can add another if statement inside the if-block to test the password:

import java.util.Scanner;

public class Nested {

    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        System.out.print("Enter your name: ");

        String name = in.nextLine();

        if (name.equals("Artemesia")) {

            // check password
            System.out.print("Enter your password: ");
            String pass = in.next();

            if (pass.equals("chicken")) {
                System.out.println("Welcome to Arti's Cat House!");
            } else {
                System.out.println("Invalid password.");
            }

        } else {
            System.out.println("Invalid Login Name");
        }
    }
}

Be careful when working with nested if's that have no braces. To see why, examine the following code:

public class IfThing {
    public static void main(String[] args) {
        int x = 5;
        int y = 10;
        if (x < 2)
            if (y > 5)
                System.out.println("Meow");
        else
            System.out.println("hi");
        System.out.println("bye");
    }
}

What do you think the output will be? Run the program - what is the output you actually get? Why?

In this example, the else-block appears to belong to the top if statement. However, without the braces, an else-block will always belong to the if-statement directly above it. In this case, the else-block actually belongs to the if (y > 5) statement. When working with nested Ifs, it's best to use braces to avoid such confusion.

Nesting vs. Stacking

Don't confuse nesting if-statements with stacking if-statements. Nesting occurs when an if-statement appears inside the block or body of another if:

String paymentLate = "";
double penalty = 0;
if ( (month <= 12) && (month >= 1) ) {
     if ( (day >= 1) && (day <= MAX_PAY_DATE) ) {
          paymentLate = "Payment is on time.";
     } else {
          paymentLate = "Payment is late.";
          penalty = (day - MAX_PAY_DATE) * PENALTY;
     }
} else {
     System.out.println("Invalid month number!");
}

In the above example, the if-statement checking the day variable is nested inside the if-statement checking the month variable.

The example below does not nest if-statements; it stacks them on top of one another:

if (age >= 65) {
	discount = .1;
} else {
	discount = 0;
}
if (memberStatus == 2) {
	shippingCost *= .5;
}

Exercises

[Solutions]

  1. What is the output of each of the following code segments:
    1. int x = 5;
      int y = 10;
      int z = 2;
      if (x > y) {
      System.out.println("twice x is " + (x * 2));
      if (x * z == y) {
      System.out.println("xz equals y");
      }
      } else {
      System.out.println(y /= z);
      }
    2. int x = 5;
      int y = 10;
      int z = 2;
      if (x > y) {
      System.out.println("twice x is " + (x * 2));
      }
      if (x * z == y) {
      System.out.println("xz equals y");
      } else {
      System.out.println(y /= z);
      }
  2. A program at a video store calculates the cost of renting a certain number of DVD's. Some members have purchased a special Rewards Program membership that allows them to rent DVDs for only $3.59 per DVD. For all other customers, DVD rentals are $4.99 per DVD unless they rent more than 4 DVDs at one time, in which case the cost per DVD rental is $3.99. Write the part of the program that calculates the sub total before taxes.

    With this kind of problem, a decision table might be helpful (if you haven't done decision tables in logic class, then don't worry about this):

    Charge per Rental 1 2 3
    Number of Rentals  -- <=4  >4
    Rewards Program? Y N N
    $4.99 per Rental X
    $3.99 per Rental X
    $3.59 per Rental X

    What if the psuedocode for this problem was written as:

    Print "Enter number of DVDs:"
    Get numDvds
    Print "Is customer in Rewards Program?"
    Get rewardsMember
    If rewardsMember = "Y" Then
       subTotal = numDVDs * 3.59;
    End If
    If numDvds <= 4 Then
        subTotal = numDvds * 4.99;
    Else
        subTotal = numDvds * 3.99;
    End If
    Print "Sub Total: ", subTotal

    What is the output when the user enters 5 DVDs and "Y" for the Rewards Program?

    The problem with this code is that even though we calculate the correct sub total when we evaluate that rewardsMember = "Y" is true, we later encounter a true condition for "numDvds > 4", which resets the sub total to numDvds * 3.99. This would output 19.95 instead of the correct result 17.95!

    Write this program correctly!

  3. The decision table below shows the Residence Assignment policy for a local university:
    Residence AssignmentRules
    1 2 3
    Student Age <21<21>=21
    Residence Type Co-EdNon Co-Ed--
    Residence Assigned TrudeauMacDonaldLaurier

    Write a program that prompts the user to enter the student's age and whether or not the student wants a co-ed dorm room. Then display the student's residence hall on the screen using the criteria in the table. Write the most efficient code possible.

  4. The decision table below shows the Medical Insurance Policy that defines how much of a reimbursement patients receive:

    Medical Insurance PolicyRules
    1 2 3 4
    Deductible StatusMetMetMetNot Met
    Type of visitDoctorHospitalLab--
    Amt. of Reimbursement50%80%70%0%

    Write a program that prompts the user to enter the total amount due for the medical visit, then find out if the client has paid the deductible. If they have, then ask the user which type of visit the client had. Display the appropriate reimbursement amount percentage based on the table. Write the most efficient code possible

  5. Write a program that validates a date entered by the user. The user will enter a month number and then a day number. Your program should display a message, "Invalid date!" if the date is not valid. e.g. if the inputs are 2 and 30 (30th of February) or the inputs are 6 and 31 (31st of June) then message should appear. If a date is valid, display the message "This is a valid date." For now, assume Feb 29 is invalid. BONUS: in addition, as for the year and include leap years.