  Second Summer 2002

Lecture Notes Six: Boolean values, expressions, and if statements.
 What's this? `x < 15` A `boolean` expression: an expression whose value is either `true` or `false`.

 Can you define `boolean` variables in Java? Sure, `boolean` is a primitive type in Java.

 `boolean b;` `b` can only hold `true` and `false` values.

 What are the primitive types in Java? `int, byte, short, long` `double, float` `boolean` `char` There are four kinds: whole numbers floating-point numbers boolean values characters

 We've seen `int`, and `double` values... ... we now take a look at `boolean` values.

 How do you read this? `x <= 15` "x is less than or equal to 15"

 How do you write "x is in between 9 and 15"? First, what value does it have: `true` or `false`?

 We don't know yet, it depends on what x is. So we might as well call it p (x).

 Very well; now we can look at it for particular values of x. p (3) is `false`

 p (20) also is `false` Come to think of it, p (x) is `false` for many values.

 What's p (x) again? A statement about x being between 9 and 15.

 When is it `true`? When `x <= 15` and at the same time `x >= 9`

 How do you write AND in Java? `&&`

 So p (x) can be written as: `&&` is read as AND
`(x >= 9) && (x <= 15)`

 And `||` is read as OR. While `!` stands for NOT in Java.

 I like A201 `!` I do `!` think `this` is that funny...

 So `&&`, `||`, and are operators for truth values. Yes. How do they work?

 Let me draw a table.
 `p` `q` `p && q` `p || q` `! q` `true ` `true ` `true ` `true ` `false ` `true` `false` `false` `true` `true` `false` `true` `false` `true` `false` `false` `false` `false` AND OR NOT
 So `&&` works in the following way: you graduate if you satisfy both of two requirements.

 Otherwise you don't graduate. `||` is a bit more lenient.

 You graduate if you satisfy at least one of the two requirements. And only when none of them has been satisfied you do not graduate.

 And `!` is easy. It is, indeed.

 The `boolean` type is called after mathematician George Boole, a pioneer in the study of logic. Logic is tricky: suppose `a` is a `boolean` value, `true` or `false`. What value does `a || !a`

 Doesn't it depend on the value of `a`? No.

 Well, then let's look at all possible cases:
 `a` `! a` `a || (! a)` `true` `false` `true` `false` `true` `true`
 Doesn't it look easy now?

 Yes, and there weren't even too many cases. How do you compute? `3 + 5 * 2`

 Why are you bringing this up? Because as you know there is an implicit order of evaluation for arithmetic expressions.

 Does a similar set of rules apply to `boolean` expressions? Yes. In arithmetic, unary minuses are taken into account before we do any multiplications...

 ... and only after that we may do addtions, if any. If there are no parentheses, otherwise the parens dictate the order of evaluation.

 What rules govern the order of evaluation for `&&`, `||`, and `!` ? `!` has the highest priority. Then comes `&&`, and the `||` has the lowest priority.

 So if you look at `a || b && ! c` It's evaluated as `a || (b && (! c))`

 What is the truth table for `!a && !b` Let's build it at the same time for `!(a || b)`
 `a` `b` `a && b` `!(a && b)` `!a` `!b` `!a || !b` `true` `true` `true` `false` `false` `false` `false` `true` `false` `false` `true` `false` `true` `true` `false` `true` `false` `true` `true` `false` `true` `false` `false` `false` `true` `true` `true` `true`

 We have just proved one of DeMorgan's law. What is the other one?

 It's the dual of this: `!(a || b)` is the same as `!a && !b`

 There are many other identities that one can prove. Perhaps we can do that later, as needed.

 Yes, but let me give some examples, in case you get bored and want to practice. Sure.

 This ... is the same as this

 `a && (b || c)` `a && b || a && c`

 `a || true` `true`

 `a && true` `a`

 `a || false` `a`

 `a && false` `false`

 `a == true` `a`

 `a == false` `! a`

 Let's face it: `boolean`s can make you dizzy. Yes, but they are clearly necessary.

 For example, the programs we have seen so far are fairly inflexible. Except for variations in the input they work the same way with every program run.

 One of the essential features of nontrivial computer programs is the ability to make decisions... ... and to carry out different actions, depending on the nature of the inputs.

 With `boolean`s one can program simple and complex decisions. Learning that will greatly increase our expressive power in Java.

 In some of the previous assignments we went to great length to either avoid,... ... or fake decisions by building them into clever formulas.

 Being able to make decisions would greatly simplify those programs. The `if/else` statement is used to implement a decision in a program. The `if/else` statement has three parts: a test (a `boolean` expression), a then branch, and an else alternative.

 If the test succeeds, the body of the then branch, ... also known as the body of the `if` statement,

 ... is executed. Here's an example, as a flowchart: This is from problem P2.3 of last week. And in Java: ```if (x > y) { max = x; } else { max = y; } ``` The condition is red, the body of the `if` statement is blue, while the body of the else alternative appears in green.

 A statement such as `max = x;` is called a simple statement. A conditional statement, such as: ```if (x > 0) { y = x; } else { y = -x; } ``` is called a compound statement.

 By the way, this last compound statement could be replaced by (as it's equivalent to): `y = Math.abs(x);` I know, but that's only because it's so simple.

 Our programs remain sequences of statements, we just allow compound statements, such as `if` statements, in. But remember: Your programs now become essentially two-dimensional.

 Quite often the body of an `if` statement consists of multiple statements that must be executed in sequence whenever the test is succesful. These statements must be grouped together to form a block statement by enclosing them in braces: `{` and `}`.

 Also, while an `if` statement must have a test and a body, the `else` alternative is optional. I want to see examples.

 Here's one, a bit contrived: ```if (x < y) { temp = x; x = y; y = temp; } ``` We assume, of course, that `x`, `y`, and `temp` have been declared, and that `x` and `y`, at least, have been initialized already.

 Can you briefly say what the code is doing? It makes sure that of the two values the larger one is always in `x`.

 Very good. What were we saying about braces? They group statements together.

 What if we drop them? Then the code no longer works as intended.

 So what is the syntax of an `if` statement? The body of an `if` statement (or an `else` alternative) must be a statement (just one).

 But it can be: a simple statement a compound statement (such as another `if` statement), or a block statement
 It's good to get into the habit of using braces (and thus block statements) all the time.

 Yes, as we will see when we get to exercises, shortly. I can hardly wait. But first, let's analyze the `if` statement closer, and look at what makes a test.

 Its outcome is either `true` or `false`. In many cases the test compares two values.

 Comparison operators such as `<=` are called relational operators. Java has six relational operators.
Java Math Description
`>` > Greater than
`>=` Greater than or equal
`<` < Less than
`<=` Less than or equal
`==` = Equal
`!=` Not equal

 The `==` operator is initially confusing to most newcomers to Java. In Java, the `=` symbol already has a meaning, namely assignment.

 The `==` denotes equality testing:
```a = 5; // assign 5 to a
if (a == 3) // tests whether a equals 3
System.out.println("a is equal to 3");
else
System.out.println("a is not equal to 3"); ```
 You will have to remember to use `==` for equality testing and to use `=` for assignment.

 Floating point numbers have only a limited precision, and calculations can introduce roundoff errors. That means we need to be careful when we want to test if two floating point quantities are representing the same thing.

 Here's an example:
```double r = Math.sqrt(2);
if (r * r == 2)
System.out.println(r * r + " == 2");
else
System.out.println(r * r + " != 2"); ```
 Unfortunately such roundoff errors are unavoidable.

 In most circumstances it does not make a lot of sense to compare floating point numbers exactly. Instead we should test whether they're close enough.

 That is, the absolute value of their difference should be less than some threshold. Mathematically, x and y are close enough if ... for a very small number, . Greek letter epsilon is commonly used to denote a very small quantity.

 It is common to set to 10-14 when comparing `double` numbers. However, this is not always good enough.

 Indeed, if the two numbers are very big, then one can be a roundoff of the other even if their difference is much bigger than 10-14. To overcome this problem we need to normalize: we divide by the magnitude of the numbers before comparing how close they are.

 So x and y are close enough if And to avoid division by zero it is better to test whether In Java, this is:
`Math.abs(x - y) <= EPSILON * Math.max(Math.abs(x), Math.abs(y))`
 OK, I think I understand how I test numbers (integers or floating point) for equality.

 What else can we test for equality? How about `String`s?

 To test whether two strings are equal to each other, ... ..., that is, that their contents is the same, ...

 ... one must use method `equals`. Why not use `==` like for numbers?

 `String`s are objects. And so are `Rectangle`s.

 If you compare two object references with the `==` operator, ... ... you test whether the references refer to the same object.

 That's because you check to see whether the two locations contain the same thing. Which is in each case an address, to an actual object.

 Let's see some examples.
```Rectangle a = new Rectangle(5, 10, 20, 30);
Rectangle b = a;
Rectangle c = new Rectangle(5, 10, 20, 30); ```
 The comparison `a == b` is `true`.

 Both object variables refer to the same object. But the comparison `a == c` is `false`.

 The two object variables refer to different objects. It does not matter that the objects have identical contents.

 You can use the `equals` method to test whether two rectangle have the same contents. Thus `a.equals(c)` is `true`.

 And so is `c.equals(b)` obviously. Same with `String`s, so we will have to remember to use `equals` for string comparison.

 In Java letter case matters. Thus `"harry".equals("HARRY")` evaluates to `false`. But `"harry".equalsIgnoreCase("HARRY")` evaluates to `true`.

 Even if two strings don't have "identical" contents we may still want to know the relationship between them. The `compareTo` method compares strings in dictionary order.

 If `string1.comparesTo(string2) < 0` ... then `string1` comes before `string2` in dictionary order.

 If `string1.comparesTo(string2) > 0 ` ... then `string1` comes after `string2` in dictionary order.

 If `string1.comparesTo(string2) == 0 ` ... then the two strings have identical contents.

 You should look this method up in class `String`. Actually the dictionary ordering used by Java is slightly different from that of a normal dictionary.

 Java is case-sensitive and sorts characters by listing numbers first, then uppercase characters, then lowercase characters. For example `1` comes before `B` which comes before `a`.

 And the space character comes before all other characters. Can we describe the comparison process a little bit in greater detail?

 When comparing two strings, corresponding letters are compared until one of the strings ends or the first difference is encountered. If one of the strings ends, the longer string is considered the later one.

 If a character mismatch is found, compare the characters to determine which string comes later in the dictionary sequence. The process is called lexicographic comparison.

 That's why `"car"` comes before `"cargo"`, And `"cathode"` comes after `"cargo"` in lexicographic ordering.

 Time for a break. I sure think so.

 And some exercises too. Yes, but the break first, please.

 OK, here's what we'll do: we'll put the exercises into the break altogether. And combine the useful with the necessary.

 The text of the problem is always the same. I know it: "What is the output produced by the following snippets of code when embedded in a complete program."

 Let's see the snippets.
 Snippet 1: ```int x = 3; if (2 > x) System.out.print(1); else System.out.print(2); if (x < 2) System.out.println(3); System.out.print(4);``` Easy. Draw a diagram.

 Snippet 2: ```int x = 3; if (x > 5) { if (x < 10) System.out.print(1); } else System.out.print(2); System.out.print(3);``` Messy. The curly braces change everything.

 What if you take them out? The diagram changes significantly.

 And you have experienced a dangling else. That's right.

 Snippet 3:
```int x = 3;
if (x > 0) System.out.print(x + 1);
else if (x > 1) System.out.print(x);
else if (x > 2) System.out.print(x - 1);
else if (x > 3) System.out.print(2 * x);
else System.out.print(x * x);```
 Easy. Diagram it.

 Snippet 4 (and last):
```int x = 3;
if (x > 0) System.out.print(x + 1);
else if (x > 1) System.out.print(x);
else if (x > 2) System.out.print(x - 1);
else if (x > 3) System.out.print(2 * x);
else System.out.print(x * x);```
 Who would ever do that in a program?

 Nobody. It's for practice. Messy again. You have to redraw everything.

 I agree it's messy, but is it hard? No. Is this the last one?

 Yes. Can we do a reasonable example now?

 OK, here's problem 19 from problem set 1.
```/* Solution to problem nineteen in the first problem set. Use
ConsoleReader from lab notes 2 as explained. The trick here (as
hinted in the text) is to transform a number for a month in a
position (index) in the string where the month name is starting,
all names being made of the same length, and then concatenated
together in one final string. */

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

String monthNames = "January   " +
"February  " +
"March     " +
"April     " +
"May       " +
"June      " +
"July      " +
"August    " +
"September " + // longest
"October   " +
"November  " +
"December  "    ;

// open a connection with the keyboard

// greet the user, and ask for input
System.out.println("Please enter a month number from 1 to 12.");
// get month name
// report the name of the month
System.out.println(
monthNames.substring("September ".length() * (month-1),
"September ".length()*month));

// formula uses the length of the longest name
}
}```

 Here is it with `if` statements:
```public class P19 {
public static void main(String[] args) {

System.out.println("Please enter a month number from 1 to 12.");

if      (month == 12) System.out.println("December");
else if (month == 11) System.out.println("November");
else if (month == 10) System.out.println("October");
else if (month ==  9) System.out.println("September");
else if (month ==  8) System.out.println("August");
else if (month ==  7) System.out.println("July");
else if (month ==  6) System.out.println("June");
else if (month ==  5) System.out.println("May");
else if (month ==  4) System.out.println("April");
else if (month ==  3) System.out.println("March");
else if (month ==  2) System.out.println("February");
else if (month ==  1) System.out.println("January");
}
}```
 I thought we agreed to use block statements (with curly braces) for the bodies of `if` statements and `else` alternatives all the time. Yes, but just for once I wanted to keep the code somewhat shorter.

 Well, then, just for once, I have two more exercises. OK, I will remember to put braces from now on, always.

 Too late. Show me the first exercise.

 Here it is: Can't be `true`!
```if (false && false || true) {
System.out.print(false);
} else {
System.out.print(true);
}```

 Snippet 2: I can see the difference.
```if (false && (false || true)) {
System.out.print(false);
} else {
System.out.print(true);
}```

 I'm sure you do. That's probably `true` or `false`.

Last updated: Jun 16, 2002 by Adrian German for A201