Welcome to Lesson 9!

Learning Objectives

By the end of today's class, you should know...
  • How to make decisions when there are multiple alternatives?
  • When does order matter when making decisions?
  • How do you test multiple conditions using logical operators?
  • How do && and || operate when:
    • both test conditions evaluate to true?
    • both test conditions evaluate to false?
    • one test condition evaluates to true and one to false?
  • What are some pitfalls you might encounter when using logical operators and how can you avoid them?
  • 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?


Announcements

  • Midterm 1 next class (Lesson 2 - Lesson 8)
    • Study over review activities and quizzes
    • Study over programs you have written for homework
    • If there was a homework assignment you struggled with, get help before the midterm!
    • Midterm Review
    • Answer Key
  • Assignment 9 to be due on Tuesday due to midterm.
  • No Quiz on Friday, but there will still be a Lab due


Review Activity:

With a partner, answer the following questions:

  • What will the following program print to the console?

String studentName1 = "Herman";

String studentName2 = "Hank";

if (studentName1.compareTo(studentName2) < 0) {

    System.out.println("Alpha");

} else {

    System.out.println("Beta");

}


  • With a partner, correct the mistakes below

a.

String name = Jane;


if (name = “Jane”) {

    System.out.println("Hi, Jane!");

} else (name != “Jane”) {

    System.out.println(“Hi, Not Jane!”);

}

b.

char = a;



Wrapping Up Making Decisions

Importance of Using if-else-if Structure

  • Note that we cannot remove the else portion of the structure like shown below:

        Scanner input = new Scanner(System.in);
        System.out.print("Enter a magnitude on the Richter scale: ");
        double richter = input.nextDouble();
       
        if (richter >= 8.0) { // Does not use else
            System.out.println("Most structures fall");
        }
        if (richter >= 7.0) {
            System.out.println("Many buildings destroyed");
        }
        if (richter >= 6.0) {
            System.out.println("Many buildings considerably damaged, some collapse");
        }
        if (richter >= 4.5) {
            System.out.println("Damage to poorly constructed buildings");
        }
        if (richter >= 3.5) {
            System.out.println("Felt by many people, no destruction");
        }
        if (richter >= 0) {
            System.out.println("Generally not felt by people");
        }
        if (richter < 0) {
            System.out.println("Negative numbers are not valid");
        }

  • The conditions must be exclusive and we need the else-if conditions to ensure exclusivity
  • Independent if statements may cause a single input to print several messages


When Order Matters

  • In some cases, the order of the tests is important
  • For example, look at the following program from displays a description of the likely impact of an earthquake based on its magnitude on the Richter scale

Program Showing Multiple Alternatives Where Order Matters

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public static void main(String[] args) {
    Scanner input = new Scanner(System.in);

    System.out.print("Enter a magnitude on the Richter scale: "); double richter = input.nextDouble(); if (richter >= 8.0) { System.out.println("Most structures fall"); } else if (richter >= 7.0) { System.out.println("Many buildings destroyed"); } else if (richter >= 6.0) { System.out.println("Many buildings considerably damaged, some collapse"); } else if (richter >= 4.5) { System.out.println("Damage to poorly constructed buildings"); } else if (richter >= 3.5) { System.out.println("Felt by many people, no destruction"); } else if (richter >= 0) { System.out.println("Generally not felt by people"); } else { System.out.println("Negative numbers are not valid"); } }

Order Is Important

  • Note that the order of the tests is important to ensure that the right results are printed
  • If we rearranged the order of the if-else statements, we would get the wrong results
  • For example, if we reversed the order of the tests:
    if (richter >= 0) { // tests in wrong order
        System.out.println("Generally not felt by people");
    } else if (richter >= 3.5) {
        System.out.println("Felt by many people, no destruction");
    } else if (richter >= 4.5) {
        System.out.println("Damage to poorly constructed buildings");
    } else if (richter >= 6.0) {
        System.out.println("Many buildings considerably damaged, some collapse");
    } else if (richter >= 7.0) {
        System.out.println("Many buildings destroyed");
    } else if (richter >= 8.0) {
        System.out.println("Most structures fall");
    } else {
        System.out.println("Negative numbers are not valid");
    }
    
  • This does not work because all values meet the first condition
  • Every other test will never be attempted


Logical Operators

  • In certain situations, we may wish to use more than one test condition inside of an if statement.
  • To do so, we will need to chain the test conditions together using logical operators (either && or ||)
  • For example, recall our guessing game program:
        System.out.println("I'm thinking of a number between 1 and 10.");
    System.out.println("Can you guess it?\n");
    System.out.print("Enter your guess: ");
        
    guess = input.nextInt();
        
    if (guess < 1 || guess > 10) { //if guess is < 1 OR guess > 10
        System.out.println("Invalid entry!");
    } else if (guess < 7) {
        System.out.println("Your guess is too low");
    } else if (guess > 7) {
        System.out.println("Your guess is too high");
    } else {
        System.out.println("*** Correct! ***");
    }

Review of Boolean Variables

  • Sometimes we need to evaluate a logical condition in one part of a program and use it elsewhere
  • To store a condition that can only be true or false, we use a Boolean variable
  • Boolean variables are named after George Boole (1815-1864), a pioneer in the study of logic
  • We specify a Boolean variable using the boolean type, which can hold just one of two values: true or false
    boolean isCool = true;
    boolean lies = false; 


Test Conditions and Boolean Values

  • Remember that test conditions always evaluate to true or false
    if (num > 0)
    
  • Thus we can use a boolean variable as a test condition
    boolean isPositive = (num >= 0);
    if (isPositive)
    
  • Note that we do not need to add a relational expression to a boolean variable, like:
    if (isPositive == true) // avoid!
  • Since the boolean variable already evaluates to true or false, adding the == true is redundant
  • Likewise, we do not need to use:
    if (isPositive != false) // avoid!
  • If we want to reverse the test condition, we can use the not (!) operator
    if (!isPositive)
  • We can see the use of a Boolean variable in the following example


Example Application Using a Boolean Variable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

public static void main(String[] args)
{

    int num;
    Scanner input = new Scanner(System.in);
    System.out.print("Enter a number: "); num = input.nextInt(); boolean isPositive = (num >= 0); System.out.println("The test evaluated to: " + isPositive); if (isPositive) { System.out.println("The number was 0 or positive"); } else { System.out.println("The number was negative"); } }

Introducing &&, || and !

Logical operators and search engines video


Combining Test Conditions with Logical Operators

  • logical operator, or Boolean operator, is an operator that treats operands as Boolean values (true or false)
  • Java has several logical operators, but we only need to use three to create any possible test condition
  • These three operators are andor and not, which are discussed below
  • These logical operators are traditionally written as && (and), || (or) and ! (not)

Truth Tables for AND, OR and NOT

&& (AND) Operator Truth Table
expr1
expr2
expr1 && expr2
Example Result
true true true 5 < 10 && 5 > 2 true
true false false 5 < 10 && 5 < 2 false
false true false 5 > 10 && 5 > 2 false
false false false 5 > 10 && 5 < 2 false
|| (OR) Operator Truth Table
expr1
expr2
expr1 || expr2
Example Result
true true true 5 < 10 || 5 > 2 true
true false true 5 < 10 || 5 < 2 true
false true true 5 > 10 || 5 > 2 true
false false false 5 > 10 || 5 < 2 false
not (!) Operator Truth Table
If expr is... Then ! expr is... Example Result
true false !true false
false true !(5 < 2) true


Testing Multiple Conditions Using Logical Operators

  • Sometimes we need to test for multiple conditions using a single if statement
  • In this case, we will need to chain together the two conditions using a logical operator, either && or ||
  • Note that one either side of the logical operator there must be a stand alone test condition that resolves to true or false

if (age >= 18 && age <= 25) //Correct!!!

if (age >= 18 && <= 25) //No! Incorrect!!

  • For example, we want to test if an age is between 18 and 65
  • We need to test that both parts of are true: is the age >= 18 AND is the age <= 65

int age = 0;
System.out.print("Enter your age: ");
age = input.nextInt();
if (age >= 18 && age <= 65)
{
    System.out.println("Adult!");
} else {
    System.out.println("Child, Teen or Older Adult!");
}


  • Another way to use logical operators to test the age is:
    int age = 0;
    System.out.print("Enter your age: ");
    age = input.nextInt();
    if (age < 18 || age > 65)
    {
        System.out.println("Child, Teen or Older Adult!");
    } else {
        System.out.println("Adult!");
    }
    
  • Many people confuse && and || conditions, especially when learning about logical operators
  • A value lies between 18 and 65 if the value is at least 18 and at most 65
  • A value is outside that range if it is less than (but not equal to) 18 or greater than (but not equal to) 65
  • There is no golden rule; we have to think carefully and test our conditions

Parenthesis

  • Remember that Boolean expressions in an if statement can be enclosed in parenthesis
  • Thus, an if statement with && might look like:
    if ((guess != GUESS1) && (guess != GUESS2))
  • However, relational operators have a higher precedence than logical operators, so the extra parenthesis are not necessary
  • As such, we can remove the inner parenthesis without affecting the logical meaning:
    if (guess != GUESS1 && guess != GUESS2)
  • However, if using parenthesis is easier to understand then use the extra parenthesis


Activity 9.1: What's Your Generation? (10 pts)

  • There are 6 generations living in America, side-by-side, today.
  • Your program will determine to which generation a user belongs.
  • Find a partner for pair programming, then open up a new project and name it Generation.
  • You will need to take as input the year of his or her birth.
  • Then, you will need a series of test conditions (think if - else if - else) to determine the generation of your user.
  • You will also need to use logical operators (&&, ||, !).
  • Below is a chart with the range of birth years for each generation.
  • Note the double quotes around each generation's name. For full credit, you must include the " when you output the generation.
Years of Birth                    Generation
1900-1927                           "The Greatest Generation"
1928-1945                           "The Silents"
1946-1964                           "The Baby Boomers"
1965-1979                           "Generation X"
1980-1999                           "The Millennial Generation"
2000-2018                           "Generation Z"

  • Your goal is to prompt the user for his or her year of birth and then print out a message about which generation he or she belongs to.
  • To start, print the following message to the user:

    What's your generation?
  • Then, you will need a variable to store the user's year of birth:
int year_of_birth;
  • Next, prompt your user to enter his or her year of birth with a statement like the following:
Please enter the year of your birth: _
  • Subsequently, you will need 6 if and if else statements like the following:
if ( year_of_birth >= 1900 && year_of_birth < 1928)
{
    System.out.println("You belong to the \"Greatest Generation\"");
}
else if ( year_of_birth >= 1928 && year_of_birth < 1946)
{
    System.out.println("You belong to the \"The Silents\"");
}
//rest of your else ifs and your else clause go here
  • Important: Why are we using && here and not ||?
  • Finally, you will need to do some error checking of the user input.
  • If the user inputs a date that is either too high or too low, your program must print out the following message:
Invalid entry. Please enter a birth year in the range 1900 - 2018.
  • The above should go in your else clause
  • Make sure your output is identical to the sample output below before you submit.
  • When you are finished, upload Generation.java to Canvas

What's your generation?
Please enter the year of your birth: 1926
You belong to the "Greatest Generation".

Alternately,

What's your generation?
Please enter the year of your birth: 2020
Invalid entry! Please enter a birth year in the range 1900 - 2018.

More Information on Logical Operators

Conditional Pitfalls

  • Below are some common mistakes when using logical operators.
  • Fortunately, Java gives you an error message when you make the below mistakes.

Using = Instead of ==

  • One common mistake is to use = when you meant to use ==
  • For example, look at the test condition in the following code:
    if (guess = 7) {
        System.out.println("*** Correct! ***");
    } else {
        System.out.println("Sorry, that is not correct.");
    }
    
  • Fortunately, if you make this mistake, the Java compiler will not allow your code to run.

  • However, if you correctly use == then your code will compile
    if (7 == guess) {

Strings of Inequalities

  • Do NOT use a string of inequalities like the following:
    int a = 5, b = 1, c = 10;
    if (a < b < c) {
        System.out.println("b is between a and c");
    } else {
        System.out.println("b is NOT between a and c");
    }
    
  • Again, your code will not compile

  • Instead, the correct way is to use && as follows:
    int a = 5, b = 1, c = 10;
    if (a < b && b < c) {
        System.out.println("b is between a and c");
    } else {
        System.out.println("b is NOT between a and c");
    }
    

Strings of Logical Operators

  • Logical expressions often read like "normal" English.
  • However, Java requires more exactness than English
  • For example, the following code will compile and run but give wrong results:
    int guess;
    System.out.print("Enter a guess: ");
    guess = input.nextInt();
    if (guess == 7 || 8) {
        System.out.println("*** Correct! ***");
    } else {
        System.out.println("Sorry, that is not correct.");
    }
    
  • The above produces an error when you try to compile your code.

  • Instead, the correct way is to use || as follows:
int guess;
System.out.print("Enter a guess: ");
guess = input.nextInt();
if (guess == 7 || guess == 8) {
    System.out.println("*** Correct! ***");
} else {
    System.out.println("Sorry, that is not correct.");
}


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
  • "Magic Formula" to force decimal places:
    System.out.printf("%.2f", value_to_print); 
    
  • % 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
  • Once we set the decimal formatting, it stays set.
public static void main(String[] args) {

    double price = 78.50;
    System.out.printf("The price is $%.2f", 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;
  • 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)

  • Find a partner for pair programming
  • Open up Eclipse, create a new Java project named Price
  • 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
  • Find a partner and answer the questions from today's learning objectives

Upcoming Assignments

~See You Thursday!~