Using else if

Figure 147. Enhanced readability: if ... else if ... else Slide presentation
if ('A' == grade || 'B' == grade) {
   result = "Excellent";
} else if ('C' == grade) {
   result = "O.k.";
} else if ('D' == grade) {
   result = "Passed";
} else {
   result = "Failed";
}
Enhanced readability: if ... else if ... else

Figure 148. if ... else if ... else syntax Slide presentation
if (booleanExpression)
   (block | statement)
[else if (booleanExpression)
   (block | statement) ]* 
[else
  (block | statement) ] 

The pair of braces [...] indicates an optional clause. The asterisk * indicates an arbitrary number of repetitions (zero to infinity).

The second pair of braces [...] again indicates an optional clause.

Thus only the if (booleanExpression) (block | statement) clause is mandatory.


exercise No. 58

Replacing else if (...){...} by nested if ... else statements

Q:

A computer newbie did not yet read about the else if(...) branch construct but nevertheless tries to implement the following logic:

if (a < 7) {
  System.out.println("o.K.");
} else if (5 == b) {
  System.out.println("Maybe");
} else {
  System.out.println("Wrong!");
}

a and b are supposed to be int variables. Please help our newbie using just if(...){...} else {...} avoiding else if(...) {} branch statements!

Tip

As the title suggests you may want to nest an inner if(...) inside an outer one.

A:

The solution requires replacing the else if(...) branch by a nested if(...){ ...} else {...} statement by moving the final else block into the nested one.

if (a < 7) {
    System.out.println("o.K.");
} else {
    if (5 == b) {
        System.out.println("Maybe");
    } else {
        System.out.println("Wrong!");
    }
}
Figure 149. User input recipe Slide presentation
import java.util.Scanner;

public class App {
  public static void main(String[] args){

    final Scanner scan = 
        new Scanner(System.in);
    System.out.print("Enter a value:");
    final int value = scan.nextInt();
    System.out.println("You entered "
       + value);
  }
}
Enter a value:123
You entered 123

See nextBoolean(), nextByte() and friends.


exercise No. 59

Post modifying an exam's marking

Q:

A lecturer marks an exam having a maximum of 12 reachable points:

Name Mark
Aaron 3
Maureen 11
Sally 1
... ...

The lecturer is dissatisfied with the overall result. He wants to add 3 bonus points but still keeping the maximum of 12 points to be reachable:

Name Mark 3 bonus points augmented mark
Aaron 3 6
Maureen 11 12
Sally 1 4
... ... ...

Complete the following code by assigning this modified number of points to the variable newResult.

public static void main(String[] args) {

  int pointsReached = 7;         // May range from 0 to 12 points
  final int maximumPoints = 12;
  final int pointsToAdd = 3;

  final int augmentedMark;

  // TODO: Assignment to variable augmentedMark

  System.out.println("New Result:" + augmentedMark);
}

A:

We present three different solutions:

  1. The basic task is to add up the values of pointsReached and pointsToAdd. This sum however must not exceed the maximumPoints limit. We use an if statement for constraint safeguarding:

    public static void main(String[] args) {
    
      final int pointsReached = 7;
      final int maximumPoints = 12;
      final int pointsToAdd = 3;
    
      final int augmentedMark;
    
      if (maximumPoints <= pointsReached + pointsToAdd) {
        augmentedMark = maximumPoints;
      } else {
        augmentedMark = pointsReached + pointsToAdd;
      }
    
      System.out.println("New Result:" + augmentedMark);
    }
  2. Java's ternary operator ? : allows for replacing the if clause:

    final int pointsReached = 7;
    final int maximumPoints = 12;
    final int pointsToAdd = 3;
    
    final int augmentedMark = maximumPoints <= pointsReached + pointsToAdd ? maximumPoints : pointsReached + pointsToAdd;
    
    System.out.println("New Result:" + augmentedMark);
  3. The augmented points value equals the minimum of pointsReached + pointsToAdd and maximumPoints. In favour of upcoming methods we may code as well:

    public static void main(String[] args) {
    
      final int pointsReached = 7;
      final int maximumPoints = 12;
      final int pointsToAdd = 3;
    
      final int augmentedMark = Math.min(maximumPoints, pointsReached + pointsToAdd);
    
      System.out.println("New Result:" + augmentedMark);
    }

    You will fully understand the above Math.min(...) expression after finishing the Static Final Variables section of [Kurniawan].

exercise No. 60

At the bar

Q:

This example uses existing program code to be explained later. You'll implement an interactive application which implements a dialogue with a user asking for input to be entered in a terminal like window as being shown in the following video:

Figure 150. Using a Scanner class collecting user input.

A bar uses a software system for picking up orders. The bar will serve just orange juice and beer. For legal reasons the latter will only be served to persons of at least 16 years of age. We show three possible user dialogues:

  1. On offer:
      1=Beer
      2=Orange juice
    
    Your choice:>1
    Tell me your age please:>15
    Sorry mate, you are too young
  2. On offer:
      1=Beer
      2=Orange juice
    
    Your choice:>2
    o.K.
  3. On offer:
      1=Beer
      2=Orange juice
    
    Your choice:>4
    Sorry, invalid choice value »4«

Since you may not yet know how to enable Java applications asking for user input simply use the following recipe to get started:

public static void main(String[] args) {

    final Scanner scan = new Scanner(System.in); // Creating a scanner for reading user input

    System.out.print("Please enter a value:");
    final int userInput = scan.nextInt();

    System.out.println("You entered: " + userInput);
    // TODO: Implement «at the bar» logic
}

Copy this boilerplate code into your IDE. The IDE will assist you adding a required import java.util.Scanner; statement in your code's header section. Execute this code. You should see a dialogue like:

Please enter a value:112
You entered: 112

Then extend the above code implementing the desired behaviour.

A:

Nested if conditional allows for implementing the desired logic:

import java.util.Scanner;

public class BarOrder {

    public static void main(String[] args) {

        final Scanner scan = new Scanner(System.in);
        System.out.print("Please choose:\n  1=Beer\n  2=Orange juice\n\nYour choice:>" );

        final int beverageChoice = scan.nextInt(); // Read user input

        if (1 == beverageChoice) {
            System.out.print("Tell me your age please:>");
            final int age = scan.nextInt();
            if (age < 16) {
                System.out.println("Sorry mate, you are too young");
            } else {
                System.out.println("o.K.");
            }
        } else if (2 == beverageChoice) {
            System.out.println("o.K.");
        } else {
            System.err.println("Sorry, invalid choice value »" + beverageChoice + "«");
        }
    }
}

With respect to upcoming switch statements a different approach reads:

...
final int beverageChoice = scan.nextInt(); // Read user input

switch (beverageChoice) {
  case 1:
    System.out.print("Tell me your age please:>");
    final int age = scan.nextInt();
    if (age < 16) {
      System.out.println("Sorry, we are not allowed to serve beer to underage customers");
    } else {
      System.out.println("o.K.");
    }
    break;

  case 2:
    System.out.println("o.K.");
    break;

  default:
     System.err.println("Sorry, invalid choice value »" + beverageChoice + "«");
     break;
}  ...

exercise No. 61

Roman numerals

Q:

Write an application which turns a positive integer values up to and including 10 into Roman numeral representation:

Enter a number:>9
IX

Regarding user input you may start from ??? again. If the user enters a value smaller than one or greater than ten the following output is to be expected:

Enter a number:>11
Decimal value 11 not yet implemented

Tip

You may use a series of if () {...} else if () {...} ... statements.

A:

final Scanner scan = new Scanner(System.in);

System.out.print("Enter a number:>");
final int number = scan.nextInt();

if (1 == number) {
   System.out.println("I");
} else if (2 == number) {
   System.out.println("II");
} else if (3 == number) {
    System.out.println("III");
} else if (4 == number) {
    System.out.println("IV");
} else if (5 == number) {
    System.out.println("V");
} else if (6 == number) {
    System.out.println("VI");
} else if (7 == number) {
    System.out.println("VII");
} else if (8 == number) {
    System.out.println("VIII");
} else if (9 == number) {
    System.out.println("IX");
} else if (10 == number) {
    System.out.println("X");
} else {
    System.out.println("Decimal value " + number + " not yet implemented");
}
Figure 151. Converting numbers to day's names Slide presentation

Task: Convert day's numbers to day's names

1 Monday
2 Tuesday
3 Wednesday
4 Thursday
5 Friday
6 Saturday
7 Sunday

Figure 152. Numbers to day's names: The hard way Slide presentation
final Scanner scan = new Scanner(System.in));
System.out.print("Enter a weekday number (1=Monday, 2=Tuesday,...) : ");

final int number = scan.nextInt();

if (1 == number) {
   System.out.println("Monday");
} else if (2 == number) {
   System.out.println("Tuesday");
   ...

} else if (7 == number) {
   System.out.println("Sunday");
} else {
   System.out.println("Invalid number " + number);
}

exercise No. 62

Leap years

Q:

We want to write an application telling whether a given year is a leap year or not. The following dialogue may serve as an example:

Enter a year:>1980
Year 1980 is a leap year
Enter a year:>1900
Year 1900 is no leap year

You may reuse the user input handling code from the previous examples.

Tip

Read about the leap year algorithm.

A:

A first straightforward rule translation based solution reads:

package start;

import java.util.Scanner;

public class LeapYear {

 public static void main(String[] args) {

    final Scanner scan = new Scanner(System.in));

    System.out.print("Enter a year:>");
    final int year = scan.nextInt();

    if (0 == year % 400) {                   // Every 400 years we do have a leap year.
       System.out.println(
        "Year " + year + " is a leap year");
     } else if (0 == year % 4 &&              // Every 4 years we do have a leap year
                0 != year % 100) {           // unless year is a multiple of 100.
        System.out.println("Year " + year + " is a leap year");
     } else {
        System.out.println("Year " + year + " is no leap year");
     }
  }
}

This solution contains two identical println("Year " + year + " is a leap year") statements. Developers don't favour redundancies: Rearranging and combining the first and third if branch into one resolves the issue:

public static void main(String[] args) {
 ...
  if (0 == year % 400 ||            // Every 400 years we do have a leap year.
    (0 == year % 4 &&               // Every 4 years we do have a leap year
     0 != year % 100)) {            // unless year is a multiple of 100.
    System.out.println("Year " + year + " is a leap year");
  } else {
    System.out.println("Year " + year + " is no leap year");
  }
...

Some enthusiasts prefer compact expressions at the expense of readability (Geek syndrome) sometimes referred to as syntactic sugar. The following code based on the ...? ...: ... operator is fully equivalent:

...

System.out.println("Year " + year +
    (year % 400 == 0 || year % 4 == 0 &&  0 != year % 100 ? " is a leap year" : " is no leap year"));
}