  Second Summer 2002

Iffy Practice Problems: This is textbook chapter 5. Warmups. The Solutions.
Questions:

1. Find the errors in the following `if` statements.

After each statement we list the correct version annotated in blue.

```if quarters > 0 then System.out.println(quarters + "quarters");

if (quarters > 0) then System.out.println(quarters + "quarters");```
Condition must be enclosed in parens, and there is no `then` keyword in Java.

```if (1 + x > Math.pow(x, Math.sqrt(2)) y = y + x;

if (1 + x > Math.pow(x, Math.sqrt(2))) y = y + x;```
Condition must be enclosed in parens, and one parenthesis was missing.

```if (x = 1) y++; else if (x = 2) y = y + 2;

if (x == 1) y++; else if (x == 2) y = y + 2; ```
We should always remember to use `==` to test for equality as `=` is used exclusively for assignment.

```if (x && y == 0) p = new Point2D.Double(x, y);

if (x == 0 && y == 0) p = new Point2D.Double(x, y);```
Presumably we want the condition to mean "both x and y are zero". But in that case we need to write a syntactically correct expression in which we refer to each variable in part: "(x is zero) and (y is zero)". The fact that later x is used as a coordinate eliminates all doubts that x might actually be a boolean variable (in which case the condition, as written originally, was correct).

```if (1 <= x <= 10)
{ System.out.println("Enter y:");
}

if (1 <= x && x <= 10)
{ System.out.println("Enter y:");
} ```
Just like in the previous exercise we need to properly assemble a boolean expression by putting together something that reads as follows: "(x is greater than or equal to 1) and (x is smaller than or equal to 10)"

```if (s != "nickels" || s != "pennies"
|| s != "dimes" || s != "quarters")
System.out.print("Input error!");

if ( !s.equals("nickels" ) &&
!s.equals("pennies" ) &&
!s.equals("dimes"   ) &&
!s.equals("quarters")    )
System.out.print("Input error!");  ```
Remember to use `equals` when comparing `String`s. (`!=` is the negation of `==` ).

Also, overall the code was supposed to implement an input error detection mechanism. If you think carefully about it, the error message should only appear if `s` is not `"nickels"` and `s` is not `"pennies"` and `s` is not `"dimes"` and `s` is not `"quarters"`.

So that was another error in the code, that has been fixed in the solution posted above; and you can simplify this even further with DeMorgan, if you want to.

```if (input.equalsIgnoreCase("N") || "NO")
return;

if (input.equalsIgnoreCase("N") ||
input.equalsIgnoreCase("NO")  )
return;```
The syntax of an OR operator requires a boolean expression on its left and another boolean expression on its right. There's no factoring out any common expression or part thereof.

```int x = console.readDouble();
if (x != null) y = y + x;

y = y + x;```
First off `readDouble` returns a floating point number so the receiving variable should be able to hold the fractional part. Then, a number cannot be compared with `null` because their types are different: primitive vs. reference type.

Finally, to fix the code you have two options: either drop the `if` statement (which is what we did above) or turn the code around by using `try` and `catch` instead (as explained in chapter 2), to specify what needs to be done if the user does not enter a number at all, and just presses `Return` (which presumably the original code was trying to do too).

```language = "English";
if (country.equals("USA"))
if (state.equals("PR")) language = "Spanish";
else if (country.equals("China"))
language = "Chinese";

language = "English";
if (country.equals("USA")) {
if (state.equals("PR")) language = "Spanish";
} else if (country.equals("China"))
language = "Chinese"; ```
The original code was missing a pair of braces. Without them the sequence of decisions will never reach a situation where the `country` variable will be checked for being `"China"` as the `else` statement is actually attached to the second if (the one that checks if state is `"PR"`) which is reached when the `String` variable by the name of `country` is `"USA"` already).

2. Explain the following terms and give an example for each construct:

• Expression

A syntactical construct that is made up of constants, variables, method calls, and operators combining them:

`(a.length() >= 6)`

• Condition

An expression whose type (or final value) is `boolean` (and we have already given an example of that above).

• Statement

A syntactical unit in a program. In Java a statement is either a simple statement, a compound statement, or a block.

`x = x + 1;`

• Simple statement

Simple statements are atomic (more or less).

`System.out.println("Atoms are complicated.");`

• Compound statement

Compound statements contain (are composed of) simple statements but not the other way around. Compound statements can contain other compound statements as well.

`if (x != 0) x = 0; `

• Block

Compound statement that contains one or more statements inside it (simple or compound) and groups them together with the help of curly braces.

```{ x = 10;
x += 1;
x += 1;
} ```
Advanced topic 6.1 (on page 230, in chapter 6, next chapter) contains extremely important information about blocks. Meanwhile we have seen blocks being used here in `if` statements to avoid the dangling `else` problem.

3. Explain the difference between an `if/else  /else` statement and nested if statements. Give an example for each.
The first is a particular case of the second. The particular aspect of the first one is its linear structure: the structure is in fact identical to the one that the `switch` statement has, except the `switch` is not nearly as powerful. (Why?)

As for examples, see pages 195-198 for details.

4. Give an example for an `if/else /else` statement where the order of the tests does not matter. Give an example where the order of the tests matter.
```if (score >= 96 ) grade = "A+";       if (score >= 96) grade = "A+";
else if (score >= 90 && score < 96)   else if (score >= 90)
else if (score >= 88 && score < 90)   else if (score >= 88)
The problem asks for one and the same structure so in our examples the two structures are identical. But if we move the conditions (and their corresponding alternatives, of course) around (for example by first checking for an `A-`) then the first of the two examples will still produce the right result, whereas the second one will produce only `A-`'s and `B`'s.

The difference between the two implementations, of course, is that in the first one the conditions are distinct, disjoint, non-overlapping, whereas in the second one they're not.

5. Of the following pairs of strings, which comes first in lexicographic order?
```"Tom"             , "Dick"
"Tom"             , "Tomato"
"church"          , "Churchill"
"car manufacturer", "carburetor"
"Harry"           , "hairy"
"C++"             , "Car"
"Tom"             , "Tom"
"Car"             , "Carl"
"car"             , "bar"```
The question is, of course, why -- because the actual answers can be easily checked with the help of a computer:
```frilled.cs.indiana.edu%cat Check.java
public class Check {
public static void main(String[] args) {
System.out.println(
"Tom vs. Dick " +
"Tom".compareTo("Dick"));
System.out.println(
"Tom vs. Tomato " +
"Tom".compareTo("Tomato"));
System.out.println(
"church vs. Churchill " +
"church".compareTo("Churchill"));
System.out.println(
"\"car manufacturer\" vs. carburetor " +
"car manufacturer".compareTo("carburetor"));
System.out.println(
"Harry vs. hairy " +
"Harry".compareTo("hairy"));
System.out.println(
"C++ vs. Car " +
"C++".compareTo("Car"));
System.out.println(
"Tom vs. Tom " +
"Tom".compareTo("Tom"));
System.out.println(
"Car vs. Carl " +
"Car".compareTo("Carl"));
System.out.println(
"car vs. bar " +
"car".compareTo("bar"));
}
}
frilled.cs.indiana.edu%javac Check.java
frilled.cs.indiana.edu%java Check
Tom vs. Dick 16
Tom vs. Tomato -3
church vs. Churchill 32
"car manufacturer" vs. carburetor -66
Harry vs. hairy -32
C++ vs. Car -54
Tom vs. Tom 0
Car vs. Carl -1
car vs. bar 1
frilled.cs.indiana.edu%```
For the why of it check pp. 191-192 in the book.

6. Complete the following truth table by finding the truth values of the Boolean expressions for all combinations of the Boolean inputs `p`, `q`, and `r`.

`p` `q` `r` `(p && q) || !r` `!(p && (q || !r))`
false false false true true
false false true false true
false true false true true
false true true false true
true false false true false
true false true false true
true true false true false
true true true true false

How do we check if we are right or wrong? We ask the computer:

```frilled.cs.indiana.edu%cat Boole.java
public class Boole {
public static void main(String[] args) {
boolean p, q, r;
p = false; q = false; r = false;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = false; q = false; r = true;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = false; q = true;  r = false;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = false; q = true;  r = true;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = true;  q = false; r = false;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = true;  q = false; r = true;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = true;  q = true;  r = false;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = true;  q = true;  r = true;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );

}
}
frilled.cs.indiana.edu%javac Boole.java
frilled.cs.indiana.edu%java Boole
true true
false true
true true
false true
true false
false true
true false
true false
frilled.cs.indiana.edu%```

7. True or false: `A && B ` is the same as `B && A ` for any Boolean conditions `A` and `B`?

For all practical purposes in this class: yes, but check at the bottom of page 208 for "lazy evaluation". We will revisit this question later, in chapter 7.

8. Explain the difference between
```s = 0;
if (x > 0) s++;
if (y > 0) s++;```
and
```s = 0;
if (x > 0) s++;
else if (y > 0) s++;```
The first of the two contains three statements one after another. The second one only two. For x > 0 and y > 0 the first code sets s to 2, while the second one to 1, incrementing only once. Draw the diagrams to see the effect of the `else` alternative.

9. Use De Morgan's law to simplify the following Boolean expressions.
```!(x > 0 && y > 0)

x <= 0 || y <= 0
```

!(x != 0 || y != 0) x == 0 && y == 0

!(country.equals("USA") && !state.equals("HI") && !state.equals("AK")) !country.equals("USA") || state.equals("HI") || state.equals("AK")

!(x % 4 != 0 || !(x % 100 == 0 && x % 400 == 0))

x % 4 == 0 && (x % 100 == 0 && x % 400 == 0)

This can be further simplified to

`x % 400 == 0`

10. Make up another Java code example that shows the dangling`-else` problem, using the following statement. A student with a GPA of at least 1.5, but less than 2, is on probation. With less than 1.5, the student is failing.
```if (gpa > 1.5)  {
if (gpa < 2)
System.out.println("Probation.");
} else System.out.println("Failing.");```
Without the curly braces the `else` would migrate (change position).

11. Explain the difference between the `==` operator and the `equals` method when comparing strings.

The first operator checks if the two `String`s are stored in the same place (which means that they are in fact one and the same object). The other one checks to see if they would look the same if printed (case sensitive). You should always use the second one over the first.

Also see sections 5.2.3 and 5.2.4 in the book.

12. Explain the difference between the tests
`r == s`
and
`r.equals(s)`
where both `r` and `s` are of type `Rectangle`.

The first operator checks if the two `Rectangle`s are stored in the same place (which means that they are one and the same object). The other one checks to see if you knew you drew more than one if you were to draw them (if one `equals` the other they'd be drawn on top of each other and as such you wouldn't be able to tell two have been drawn instead of one).

Also see sections 5.2.3 and 5.2.4 in the book.

13. What is wrong with this test to see whether `r` is `null`? What happens when this code runs?
```Rectangle r;
...
if (r.equals(null))
r = new Rectangle(5, 10, 20, 30);```
If the variable does not get initialized before the test we would get an error message at compile time. Otherwise it depends how the `equals` method is implemented in class `Rectangle` and you would find that here. (If the variable `r` points to a real `Rectangle` the result can only be `false`). To check if `r` is `null` or not use the `==` operator.

14. Note: For this exercise some facts from Chapter 4 are needed.

Write Java code to test whether two objects of type `Line2D.Double` represent the same line when displayed on the graphics screen. Do not use `a.equals(b)`.

```Line2D.Double a;
Line2D.Double b;

if (a.getP1().equals(b.getP1()) && a.getP2().equals(b.getP2()) ||
a.getP1().equals(b.getP2()) && a.getP2().equals(b.getP1()) ||
)
g2.drawString("They look the same!", x, y);```
Hint: If `p` and `q` are points, then `Line2D.Double(p, q)` and `Line2D.Double(q, p)` look the same.

Check the API for accessors used in the condition above (which is implementing the hint).

15. Explain why it is more difficult to compare floating-point numbers than integers. Write Java code to test whether an integer `n` equals 10 and whether a floating-point number `x` equals 10.

Inevitable lack of precision, with floating-point numbers.

For an integer `n` this would be a good test:

`n == 10`
For a floating-point number `x` this would be a good test:
`Math.abs(x - 10) <= 1E-14 * Math.max(Math.abs(x), Math.abs(y))`
Also see section 5.2.2 in the book and the following (next) exercise in this quiz.

16. Give an example for two floating-point numbers `x` and `y` such that `Math.abs(x - y)` is larger than 1000, but `x` and `y` are still identical except for a roundoff error.

For example

`1E18`
vs.
`(1E18 + 1001)`
To see how this could happen consider the following:
```frilled.cs.indiana.edu%cat Test.java
class Test{
public static void main(String[] args) {
double x = 10.0;                        // original value
double y = Math.sqrt(x);                // compute square root
double z = y * y;    // recover the original number (hopefully)
System.out.println("x = " + x + " y = " + y + " z = " + z);

// so z and x are "the same" now -- hopefully we agree on that

double result = (x - z);

// but result is > 0 (though small enough)

// so yes, x and z are one and the same (really)

System.out.println(x + " - " + z + " = " + result);

// so x and z are equal (approximately)

x = x * 1E18;
z = z * 1E18;

// they're still equal, aren't they - multiplied by the same number

System.out.println(x + " is a roundoff error of\n" + z);

System.out.println("Their difference: " + (x - z));

// so look at their difference now, equal as x and z are

// difference is now 2,048 but absolute value means nothing

// it's the ratio of this error to the magnitude of the two
// numbers that really counts 2,048/1e18 is still 1e-14...

}
}
frilled.cs.indiana.edu%javac Test.java
frilled.cs.indiana.edu%java Test
x = 10.0 y = 3.1622776601683795 z = 10.000000000000002
10.0 - 10.000000000000002 = -1.7763568394002505E-15
1.0E19 is a roundoff error of
1.0000000000000002E19
Their difference: -2048.0
frilled.cs.indiana.edu%```

17. Note: For this exercise some facts from Chapter 4 are needed.

Consider the following test to see whether a point falls inside a rectangle.

```Point2D.Double p = ...
boolean xInside = false;
if (x1 <= p.getX() && p.getX() <= x2)
xInside = true;
boolean yInside = false;
if (y1 <= p.getY() && p.getY() <= y2)
yInside = true;
if (xInside && yInside)
g2.drawString("p is inside the rectangle.", x1, y1);```
Rewrite this code to eliminate the explicit `true` and `false` values, by setting `xInside` and `yInside` to the values of Boolean expressions.
```Point2D.Double p = ...
boolean xInside = (x1 <= p.getX() && p.getX() <= x2);
boolean yInside = (y1 <= p.getY() && p.getY() <= y2);
if (xInside && yInside)
g2.drawString("p is inside the rectangle.", x1, y1);```
We mentioned in class that
```boolean a;
if (<condition>)
a = true;
else
a = false; ```
is equivalent to
`boolean a = <condition>;`
always. So we can often simplify, as needed.

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