Welcome to Lesson 9!


Learning Objectives

By the end of today's class, you should know...
  • What is a switch statement?
  • How does a switch statement compare to an if statement?
  • What is the syntax of a switch statement?
  • What is "fall through"?
  • How do you format decimal numbers for printing
  • What is a final and how do you declare one?
  • What is are magic numbers and why should they be avoided?
  • What are the short cut assignment operators for add, subtract, multiply, divide, and modulus?
  • What are the increment and decrement operators?
  • What is the difference between pre and post increment and decrement?
  • What is casting?
  • How do you cast an integer to a double and a double to an integer?


1. Lesson 8 Practice Exam Questions

Question 1:

  • Imagine that a local radio station is holding a contest to give away a year's supply of free pet food to one lucky winner.
  • To win the contest, you must meet the following criteria:
    • You must be caller 19
    • The pet your own must be one of the following: dog, cat, rabbit
    • You must be between the ages of 18 and 65.
  • Which of the following test conditions will correctly determine the winner of the contest
a. if (numCaller == 19 && (pet == "rabbit" || pet == "cat" || pet == "dog") && (age >= 18 && age <= 65))
System.out.println("You are the winner!");

b. if (numCaller == 19 && (pet == "rabbit" || "cat" || "dog") && (age >= 18 && <= 65))
      System.out.println("You are the winner!");

c. 
if (numCaller == 19 || (pet.equals("rabbit") && pet.equals("cat") && pet.equals("dog")) || (age >= 18 && age <= 65))
      System.out.println("You are the winner!");


d. 
if (numCaller == 19 && (pet.equals("rabbit") || pet.equals("cat") || pet.equals("dog")) && (age >= 18 && age <= 65))
      System.out.println("You are the winner!");

e. 
if (numCaller = 19 && (pet.equals("rabbit") || pet.equals("cat") || pet.equals("dog") && (age >= 18) || age <= 65))
   
System.out.println("You are the winner!");

Question 2:

  • What will the following print to the console?

int age = 20;

boolean is_student = true;

if (is_student || age > 21) {

    System.out.println("Fi!");

}

if (!is_student && age < 21) {

    System.out.println("Fo!");

}

if (is_student && age < 21) {

    System.out.println("Fum!");

}


2. Wrapping Up Conditionals: Switch Statements

  • The switch statement gives us an alternative to an if-else-if chain
  • Executes a section of code depending on value of a variable
  • The general syntax is:
    switch (expression) {
       case label1:
          statements
          break;
       case label2:
          statements
          break;
       ...
       case labeln:
          statements
          break;
       default:
          statements
    }
    
  • Where:
    • expression: a value you want to match
    • labelx: a numeric constant
    • statements: the statements to execute when the condition is met
  • Any number of case labels can be placed in any order
  • Any value that does not match starts executing with the statement after default
  • Execution continues until the end of the switch statement or a break statement
  • The break statement causes an immediate exit from the switch statement
  • Just as case identifies possible starting points, break determines end points

Example of a switch Statement:

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

System.out.print("Enter a day of the week: ");
String dayOfWeek = input.next();

switch (dayOfWeek) {
case "Monday":
typeOfDay = "Weekday";
break;
case "Tuesday":
typeOfDay = "Weekday";
break;
case "Wednesday":
typeOfDay = "Weekday";
break;
case "Thursday":
typeOfDay = "Weekday";
break;
case "Friday":
typeOfDay = "Hurray! End of work week!";
break;
case "Saturday":
typeOfDay = "Weekend";
break;
case "Sunday":
typeOfDay = "Weekend";
break;
default:
System.out.println("Error: Invalid day of the week");

}
System.out.println(typeOfDay);
input.close();
}
  • Notice that each case other than the last contains a break statement
  • Ensures that the switch statement is exited after a matching case is found

When to Use switch Statements

  • Switch statements work for exact matches ONLY
  • They can be used with a limited number of data types in Java:
    • byte, short, char, and int primitive data types.
    • It also works with the String class
    • It does not work for type double, float
    • A few special classes that wrap certain primitive types, which you will learn about in 36B: Character, Byte, Short, and Integer
  • The below example highlights the problem of only being able to look for an exact match
    • For example, we are unable to test for scores using >=
    • Thus, we have to use a clever trick - dividing the score by 10 to retrieve the first digit(s) (1-10)


Another example of switch statements involving ints

public static void main(String[] args) {

        Scanner input  = new Scanner(System.in);

        System.out.print("I show a grade based on a"
            + " score.\nEnter your score: ");
        int score = input.nextInt();

        switch (score / 10) { //integer division to convert score to an int from 1 to 10
            case 10:
            case 9:
                System.out.println("You got an A");
                break;
            case 8:
                System.out.println("You got a B");
                break;
            case 7:
                System.out.println("You got a C");
                break;
            case 6:
                System.out.println("You got a D");
                break;
            default:
                System.out.println("Sorry, an F");
        }
    }


The Case Against Switch Statements

  • Because they can only be used for exact matches (== or .equals()), switch statements are inherently less useful than if-else statements (which can involve test conditions using all 6 comparison operators, including < and >)
  • Also, the syntax is no clearer than if-else statements
  • Note that there is a reason for the limitations of the switch statement
  • Many years ago a compiler could generate more efficient code (using jump tables or binary searches) only within the limitations of the switch statement
  • However, modern compilers are quite capable of optimizing if-else statements to the same degree
  • Thus, we have no reason to ever use a switch statement (depending on your compiler)
  • On the other hand, there are reasons to avoid using a switch statement
  • Every branch of the switch statement must be terminated by a break statement
  • If the break statement is missing, the program falls through and executes the next case without testing
  • There are rare uses for this fall through behavior, such as printing the words for the song, The Twelve Days of Christmas
  • However, according to a study by Peter van der Linden, reported in his book, Expert C Programming, p. 38, the falling through behavior is needed less than 3% of the time
  • Forgetting to type the break statement is a very common error and the source of many bugs
  • Therefore, switch statements are less useful than if statements and potentially more likely to cause bugs in your code.


Example of Fall Through:

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        String typeOfDay="";
        System.out.print("Enter a day of the week: ");
        String dayOfWeek = input.next();
        switch (dayOfWeek) {
             case "Monday":
                
             case "Tuesday":
                 
             case "Wednesday":
                 
             case "Thursday":
                 typeOfDay = "Weekday";
                 break;
             case "Friday":
                 typeOfDay = "Hurray! End of work week!";
                 break;
             case "Saturday":

             case "Sunday":
                 typeOfDay = "Weekend";
                 break;
             default:
                 System.out.println("Error: Invalid day of the week");
                
         }
         System.out.println(typeOfDay);
         input.close();
    }


Activity 9.1: Letter Grades (10 pts)

  • Academic grades in the US are traditionally given as letter grades: A, B, C, D, and F. We need to translate these letter grades into number to calclulate a grade point average (GPA).
  • Write a program that converts a letter grade into it's numerical value using the following conversion table.
    Letter Grade GPA
    A 4.00


    B 3.00


    C 2.00


    D 1.00


    F 0.00
  • Create a new class LetterGrade.java inside of a project folder Activity9
  • In this file, prompt the user for a letter grade of A, B, C, D, or F, and no other input as shown in the Example Output.
  • Add the following starter code to the top of the main method.

String grade;
Scanner input = new Scanner(System.in);
System.out.print("Enter a letter grade: ");
grade = input.next();
  • Then, using a switch statement, convert the letter grade into the numerical equivalent shown above.
  • Display the output using the default formatting and precision for the numbers -- do NOT add any numerical formatting statements to the code.
  • Sample Output: The input prompts and outputs of the program must look like the following for full credit, including the same order of input and wording of the output. For the input shown you must get the same output. However, the output must change properly if the inputs are different.
    Enter a letter grade: B
    The numeric value is 3.0
    
    Enter a letter grade: A
    The numeric value is 4.0
    
    Enter a letter grade: F
    The numeric value is 0.0
    

    In the above three example runs, the user entered "B", "A" and "F" (without the quotes) as the letter grades to convert.

  • After displaying the output, exit the program.
  • When you are finished, submit the program to Canvas.


3. Numbers, Formatting and More About Operators

Decimal Formatting

  • Sometimes programs may not display numbers as you would expect!
  • Consider the following program and what it will display:
    public static void main(String[] args) {
        double price = 78.50;
        System.out.println("The price is $" + price);
    }
    
  • We must explicitly tell Java how to output numbers in our programs!
  • These commands do not produce any output but change how System.out outputs floating-point numbers
System.out.printf("%.3f", value_to_print); 

    System.out.printf("The price of the cookie is $%.2f\n", price_cookie); 

System.out.printf("Your weight on Mars is %.1f lbs and on Earth is %.1f\n", weightMars, weightEarth);
 

  • % is the place holder representing where you wish to place the value to print inside your message
  • .2f indicates that the floating point value should be printed to 2 decimal places
public static void main(String[] args) {

    double price = 78.50;
    System.out.printf("The price is $%.2f\n", price);
    
 }


Final Variables

  • A final variable is a variable that cannot change after being assigned a value
  • To declare a constant, we use the keyword: final
    final int MY_FINAL = 1; //use ALL CAPS for final variable names
  • Note that we must assign a value when the final is declared


Magic Numbers

  • Imagine that you are a programmer hired to modify a payroll program
  • You come across the following section of code:
    double pay;
    pay = hours * 7.5 + (hours / 40)
          * (hours - 40) * 7.5 * 0.5;
    
  • The numbers are important to the program, but what do they mean?
  • Numbers like these are called Magic Numbers.
  • They are magic because the value or presence is unexplainable without more knowledge
    • Often, no one knows what they mean after 3 months, including the author
  • A programmer can often infer the meaning of numbers after reading the code carefully
  • A much better coding style is to use named final variables rather than literal numbers
  • For example:
    final double WAGE = 7.5;
    final double OVER_TIME_ADDER = 0.5;
    final int HOURS_PER_WEEK = 40;
    double pay;
    pay = hours * WAGE + (hours / HOURS_PER_WEEK)
          * (hours - HOURS_PER_WEEK) * WAGE * OVER_TIME_ADDER;
    
  • Now it is much easier to understand the code and see any problems or limitations in it
  • Another reason to use named final variables is that it is easier to change the value of the number
  • In the above example, we can easily change the WAGE without making errors in other parts of our code

More Information


Assignment Operators

  • As we discussed before, we assign values to variables using an equal (=) sign
    int sum = 0;
  • However, the equal sign is really an assignment operator and does not denote equality
  • Thus, unlike math, we can have the same variable on both sides of an equals sign:
    int sum = 25;    // initialize sum to 25
    sum = sum + 10;  // add to sum
    
  • Note that the value of the variable is changed in the second line
  • Reading variables from memory does not change them
  • Values placed into a variable replace (overwrite) previous values:


Shortcut Assignment Operators

  • We can use additional operators to calculate values and assign them to the variable on the left all in one statement
    • Known as shortcut assignment operators
  • The general syntax is:
    variable op= expression;
  • Where op is one of the five arithmetic operators: +-*/%
  • For example, the following two statements create the same result:
    x = x + 3;
    x += 3;
    
  • Shown below are the assignment operators with examples of how they are used:


Summary of Assignment Operators

Operator Description Example Equivalent To
= Assigns the value of the expression on the right to the variable on the left x = 3  
+= Adds the expression on the right to the variable on the left x += 3 x = x + 3
-= Subtracts the expression on the right from the variable on the left x -= 3 x = x - 3
*= Multiplies the expression on the right to the variable on the left and saves the result in the variable on the left x *= 3 x = x * 3
/= Divides the variable on the left by the expression on the right and saves the result in the variable on the left x /= 3 x = x / 3
%= Calculates the remainder from dividing variable on the left by the expression on the right and saves the result in the variable on the left x %= 3 x = x % 3


Increment and Decrement Operators

  • Adding or subtracting one is a common operation in programming
  • Java provides arithmetic shortcuts for these operations with the increment and decrement operators
  • The increment operator (++) adds 1 to a variable's value
  • Pre-increment adds 1 before evaluating an expression
    ++sum;
  • Post-increment evaluates the expression and then adds 1
    sum++;
  • The decrement operator works like the increments operator, except it subtracts 1 from the variable:
    --sum
    sum--
    
  • Pre- and post- increment matters when the operation is part of a larger expression
  • For example, consider the code:
    int x = 5;
    int y = x++;
    System.out.println("x=" + x + " y=" + y);
    
  • We may expect y to be 6 after this code executes
  • Instead, y has the value of 5
  • The reason is that ++ after a variable (post-increment) is equivalent to:
    y = x;
    x = x + 1;
    
  • On the other hand, ++ before a variable (pre-increment) is equivalent to:
    x = x + 1;
    y = x;
    


Casting

  • We often find ourselves converting one data type into another
  • This process is called type conversion or typecasting
  • Java is a strongly-typed language and checks for compatible data types both when compiling and while running
  • To put a value of a different type in a variable, you must convert the type
  • There are two types of conversion: implicit and explicit
  • The term for implicit conversion is sometimes called coercion
  • The most common form of explicit conversion is know as casting

Coercion

  • Type conversion is done automatically (implicitly) when a narrower-type is assigned to a broader-type:
    • Narrower means a smaller number of bytes
    • Broader means a larger number of bytes
  • Data type hierarchy (from narrowest to broadest):
    byte => short => int => long => float => double
                   
    
  • For example:
    double x;
    int n = 5;
    x = n;
    
  • Since n is an integer and x is a double, the value returned by n must be converted to type double before it is assigned to x
  • Note that casting only changes the type of an expression's returned value
    • Not the type of the variable
  • Thus the data type of variable n is unchanged -- it is still an int

Coercion in an Arithmetic Expression

  • Some arithmetic expressions have a mix of data types
  • All values implicitly cast to the highest level before the calculation
  • For example:
    double a;
    int n = 2;
    double y = 1.33;
    a = n / y;
    
  • n is automatically cast to type double before performing the arithmetic

Explicit Casting

  • Explicit casting changes the data type for a single use of the variable
  • To cast, precede the variable name with the new data type in parentheses:
    (typeName) variableName
    
  • Where:
    • typeName: one of the Java data types
    • variableName: the name of the variable
  • For example:
    int n;
    double x = 2.0;
    n = (int) x;
    
  • The value of x is converted from type double to int before assigning the value to n
  • Note that explicit casting is required to assign a broader type to a narrower type
  • ILLEGAL: Implicit casting to a lower data type:
    int n;
    double x = 2.1;
    n = x; // illegal in Java
    

    Illegal since x is double, n is an int, and double is a higher data type than int

  • LEGAL: Explicit casting to a lower data type:
    int n;
    double x = 2.1;
    n = (int) x; // legal in java
    
  • You can use an explicit cast even when an implicit one will be done automatically

Truncation When Casting double to Integer type

  • Converting (casting) a double to integer type does not round -- it truncates
  • The fractional part is lost (discarded, ignored, thrown away)
  • For example:
    int n;
    double x = 3.99999;
    n = (int) x; // x truncated
    
  • Value of n is 3

Activity 9.2: Prices (10pts)

  • Open up Eclipse, create a new Java project named Price inside of your Activity9 project folder.
  • Copy the following program into a class file named Price.java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    
    public static void main(String[] args) {
        String name;
        double price = 0;
      Scanner input = new Scanner(System.in);

    System.out.print("Enter the product name: "); name = input.nextLine();
     
    System.out.print("Price of the " + name + ": "); price = input.nextDouble(); // Insert new statements here System.out.println("Total price: $" + price); }
  • Alter the block comments to include your name and section information to the top of the program.
  • Compile and run the starter program to make sure you entered it correctly.

    When you run the program, the output should look like this:

    Enter the product name: iPod Nano
    Price of the iPod Nano: 149.50
    Total price: $149.5
    

    Note the format of the numbers output for the total price. We will address this formatting issue later in the exercise.

  • Run the program again for a product with a very high cost, like a Boeing 777:
    Enter the product name: Boeing 777
    Price of the Boeing 777: 212345678
    Total price: $2.12345678E8
    

    Note the format of the numbers output for the total price. This format is called exponential notation. You may have encountered it in some of your math classes.

  • Let us correct the formatting of the total price. Alter the System.out statement that prints the total price:
    System.out.printf("Total price: $%.2f\n", price);
    
    Compile and run your program again and verify the output looks like:
    Enter the product name: Boeing 777
    Price of the Boeing 777: 212345678
    Total price: $212345678.00
    
  • Let us add a final variable that we will use later in our program. Enter the following code after the printf statement and before the statement that prints the total price:
    final int PERCENT = 100;
    

    We are declaring this variable rather than using a magic number.

  • Now we will add sales tax to the price of the product. Enter the following code after the percent variable and before the statement that prints the total price:
    double taxRate = 0;
    System.out.print("Enter sales tax rate (%): ");
    taxRate = input.nextDouble();
    double tax = price * taxRate / PERCENT;
    price += tax;
    

    Notice the last statement: price += tax;. This is an alternate way to code the statement: price = price + tax;.

  • Compile and run your modified program and verify the output looks like:
    Enter the product name: iPod nano
    Price of the iPod nano: 89.50
    Enter sales tax rate (%): 9.5
    Total price: $98.00
    
  • Now we will find the whole dollars and cents of the amount to demonstrate casting. Enter the following code after the statement that prints the total price and before the closing curly brace of main:
    int dollars = (int) price;
    System.out.println("In whole dollars: $" + dollars);
    

    Notice the (int) in the first statement. This is known as a type cast or just cast

  • Compile and run your modified program and verify the output looks like:
    Enter the product name: iPod nano
    Price of the iPod nano: 89.50
    Enter sales tax rate (%): 9.5
    Total price: $98.00
    In whole dollars: $98
    



Wrap Up

  • Write one statement to print out the value of the following variable to exactly 5 decimal places:
final double PI = 3.1415926535;
  • The below code contains some magic numbers. Fix the problem without changing the outcome of the program:
System.out.println("The area of the triangle is: " + (.5 * 7 * 8));
  • Write the equivalent of the below statement in 3 ways
        x = x + 1;


Upcoming Assignments

  • Activities 9.1 and 9.2 due Tuesday at 11:59pm on Canvas
  • Assignment 9 due Friday at 11:59pm on Canvas
  • Quiz 5 due Friday at 11:59pm on Canvas

~Have a Great Day!~