cs046 ยป

Contents

## Comparing Decimals

welcome back. Now that you've seen a bit about comparisons, let's look at some trickier cases. In this program here, I start out with the number 2. I take its square root. Then I square the root, multiply it by itself. If that gets me back to the original value, I print a message, they're the same. And otherwise, I print what the root squared actually is. Go ahead and run this program and tell me what answer you got.

## Comparing Decimals

Okay. When you run this program, you notice that you don't get the answer there the same. But you get that root squared is a value that's close to 2, but not quite. So there's a tiny error in that computation. These errors are unavoidable. Because decimal numbers cannot store an infinite number of digits. And somewhere, some roundoff is going to happen. So when you compare 2 numbers with fractional parts, you're never interested in whether they're exactly the same. You want to know, are they close to each other? Or in other words, is the difference small? Now we want to take the absolute value of the difference. We just care, is that a small positive or negative value? Translated into Java, we compute the absolute value of the difference, and we compare it against a tiny number. In math, one usually calls a tiny number by the name EPSILON. And in many situations, 10 to the minus 12 is a pretty good value to use. Let's do that in our program. Instead of the exact comparison, let's test whether root squared and the original are close to each other. That's the test here. And of course I have to define EPSILON, using the final keyword to indicate that it's a constant. Now when we run the program, we get the expected result. The takeaway is, whenever you compare two decimal numbers, compare whether they're close enough to each other, not whether they're exactly the same.

## Comparing Strings

Perhaps surprisingly, you're going to run into a very similar issue when you compare strings. Check out this code. I have two strings, Uda and city. I concatenated the two together, to form a string that are called firstAndSecond. And over here I have a third string, Udacity. And now I check wether, the first and second which we would expect to be Udacity, is the same as, Udacity. And if so this program prints, they are the same, otherwise it prints what firstAndSecond is. Again, go ahead and run this program yourself and tell me what you find. Just put your output into this box.

## Comparing Strings

Let's compare notes. When I ran this, surprisingly, I did not get the answer, they are the same. Here's what I got. It says, firstAndSecond is Udacity. So why isn't it the same as third, which is also Udacity? Let me explain. FirstAndSecond is a variable. Any object variable contains a reference to the object, like this. The string object contains the letters Udacity. Let's look at our other variable. Again, a variable just holds a reference. Now, reference to which object? Is it a reference to the same string object or to a different one? And that is the key question. The equal equal operator. Checks whether the contents of these two variables is exactly the same. In other words, whether both variables refer the exact same object. Now actually, they don't. Because if you remember what happened, firstAndSecond was obtained by gluing together this string and that string. And a brand new object had to be created to hold that content the third string was initialized with the literal string, Udacity, which came from elsewhere. So, in this case, the objects are different. But we don't actually care about that. What we care about is, do they have the same contents? And to compare the contents, one has to use the equals method. And not the equal, equal operator. Let's do that. Over here, I will check whether firstAndSecond equals third. Here's the test. We call the equals method on firstAndSecond and pass it third as a parameter. Now when we run the program, it will work as expected. The program prints, they are the same. So the take away is, when comparing strings, use the equals method and not the equal equal operator. And as a reminder, when comparing decimal numbers. Be sure to check whether the numbers are close to each other, and also don't use equal equal. Now when do you use equal equal? For integers, of course.

## What Does Null Mean

In the previous unit, we've worried about two object references that pointed to different objects. Now we're going to look at a different situation, when object reference doesn't point anywhere at all. Let me explain that. Over here, you have a situation with which you are very familiar. We have a variable that references an object, [INAUDIBLE] cat. Now, my favorite cat is in fact my cat, Eliza. But maybe Sarah doesn't like cats and her favorite wouldn't be any cat at all. That is in the variable her favorite, there wouldn't be any reference to any cat object. In Java, she denote such a reference to no object at all with the keyword null. So this variable here holds this special null reference. This variable here holds a reference to some cat object. Generally, you would use this distinction meaning either a reference to a specific object or a null reference if the object is optional to test whether a variable is null or not. You use equal, equal and you test, is this reference the null reference? Now, if there is a chance that a object contains null. It actually is important that you make that test. Because if you invoke a method on a null reference, then something bad happens and the method called blows up. Well, it doesn't really blow up, of course. But it does terminate your program with a null pointer exception. It is simply illegal to call any method on null, don't do it. Instead, make this test first. I've prepared a little quiz here, where I'm going to ask you about several kinds of tests. So here's the situation, our intrepid reporter went to city hall to get a statement from the mayor. And now I'd like you to give me the java code to test whether the statement was one of the following. Did the mayor say no comment? Just type in here, what you would put inside the parentheses of an if statement to check for that a couple more. Did the mayor say nothing at all? And finally, did the reporter not manage to get a statement? Maybe he was stuck in traffic. So, just type in the conditions for each one of them.

## What Does Null Mean

Well, let's compare our answers. Here, we're checking whether the statement equals the string No comment note the use of equals. When you compare two strings, you should use equals. Here, we checked where the mayor said nothing at all. Nothing at all is the empty string, the string that has no contents. And again, we use equals. Alternatively, you could use this test here, where we check whether the length of the statement is 0. That's the same thing as checking whether it equals the empty string. The third test is different. Here, we don't invoke a method. We're checking whether the statement is the null reference. Whether nothing has ever been assigned to the statement.

## Find The Error

Remember in lesson three how we stored the friends of a person? We had an instance variable friends, and when we added friends, we added their names to the friends instance variable. To remove friends, we replaced their names, with an empty string. What if I decided to add some methods that comment on the number of friends a person has? And try to use these conditions. Match each condition to a description of its error. The errors are; strings are objects and should be compared using equals. The strings friends will never be null. Loss of precision may prevent this condition from being true even when a person would see that it should be true. And this if statement tries to change the value of the variable instead of comparing it.

## Find The Error

The first one is d. The second one is b. The third one is a. And the fourth one is c. Using equals instead of equals equals or .equals is an easy mistake to make. This won't compile. If I create a string friends, and set it equal to the empty string. And now, if friends is the empty screen. And I'm going to use Shift Enter to go down a line without running it. Then I'll print out no friends left. Now if I run this, I get an error incompatible types, because friends equals the empty string, isn't a condition. It can't go inside of an if check. In the second one, friends will never be null. No matter how many friends we remove we just erase their names from the string, we don't reset the string to be null. In this third one, we're comparing using equals, equals. But strings are objects so we always want to use dot equals to compare them. In this last one, we say if the number of friends equals, equals the number of people times 0.33. Then you're friends with one in three people. But these are doubles, and doubles have precision loss. So, you could actually find out that numFriends equals numPeople times 0.33333 or 0.339, or something like that, and this wouldn't be true. Even though that person is basically friends with one in three people. When comparing doubles, you always want to find the difference between them, and then compare it to a threshold. Pick an epsilon, that is the biggest difference you want to accept, and compare the actual difference with your epsilon.

## And Or Not

Many times, when you have complicated conditions, you want to combine them. For example, maybe you want to do something if one condition is true, or another one. In Java, there are three operators that you can use to combine conditions. They look like this. The two ampersands are an and these two vertical bars are on or. And the exclamation mark somewhat is a not. You might find it useful to remember that the not equal operator that you've seen a few units ago also has the exclamation mark. Let me show you a few examples for using these operators. And once again, we'll be looking at flags where the visual appearance should help you. Let's start with this maritime flag for the letter d. Here, I made a sketch of this flag. When you're in the middle, the pixel should be blue. And otherwise, it should be yellow. So how do we express when you're in the middle? When the y-value is greater than this level. And less than this level, that's where our and comes in, then we're in the middle. This here is 1 5th of the total height. So, we have two conditions, namely y is at least height over 5, and the other condition is y is at most height times 4 over 5. Both conditions have to be fufilled for us to be in the middle, so we use the and operator. Here it is. Let's just try this out. Here is the condition that you just saw with the and operator here. And in this case, we return blue. Otherwise, we return yellow. In this case, I will make a square flag and here it is. So, the and operator worked out for us. Because we wanted y to be at least here at most, here. Both conditions had to be true for the blue color. Now, let's look at another flag. I've sketched up the flag here. And the question is, when should a pixel be blue. In this case, there are four conditions. The x-value should be at least width over third. That means it's over here. The x-value should be at most, width times two thirds. That makes it over here. The y-value should be the height over 3, and the y-value should be at most the height times two third. All those four conditions need to be fulfilled for a pixel to be built. Now, it's your turn. You'll get to write a program that draws this flag here with a bit of blue on the inside and white on the outside.

## And Or Not

Here's how I solve this problem. There are four different conditions. All four had to be true. So I join them with the and operator. So let's start with the x-axis. x has to be at least width over 3, and it should be at most twice that. The y value should be at least height over 3, and it should be at most twice that. So, here are my four conditions joined by and. When all of them are true, then the pixel should be blue, otherwise it should be white. Now, you may be wondering, what's the deal with the greater equals versus less thans, particularly, if you didn't do it just so and your answer wasn't counted correctly. This is easiest to see with a specific example. So let's say we have want each of these three areas to have equal size, so the first one goes from 0 to 99, the next one from 100 to 199, and the last one from 200 to 299. So to be within the second, of these, you want to be greater equal 100 and less than seems like a fine point, but it is worth paying attention to. And here is what it looks like, when I run it.

## Or

Now you've seen a couple examples of the use of the hand operator, so how about or? We'll put or to use for drawing this Charlie flag. Again, here is my sketch and we have blue at the top or the bottom. If Y is less than height over 5 or if Y is height times 4 over 5 or larger, then the pixel is blue. So we'll put an or operator here to join these two conditions. Once again, it's your turn to complete this program. Use the or operator for the blue ones, and for the middle strip here, you get to use the and operator one more time. Go for it.

## Or

Well, here's how I did it. This is the condition for y's in the top fifth. This is the condition for y's in the bottom fifth. If it's in the top or the bottom, that's where the or comes in, then the pixel is blue. If it's in the middle here, well, that's the case if it's at least at this point, and at most at this point. Notice the and, then it's red, and otherwise it's just white. So now you've gotten good practice with using ands and ors to form complex conditions.

## Both Threes

Suppose that x and y are 2 die values. How would you check whether both of them are 3? How would you check whether at least one of them is 3? Write a condition here.

## Both Threes

To check whether both of them are 3, you want to check whether the first one is equals 3 and, and y equals, equals 3. To check whether at least one of them is which is the vertical bar twice, y equals, equals 3.

## Exactly One Three

How would you test whether exactly one of them is a 3?

## Exactly One Three

To test whether exactly one of them is a three, you would be interested in two cases. One where x is 3, and y is not. And the other where y is 3, and x is not. If this case is true, or this case is true, then exactly one of them is a

## Boolean

You've been working a lot with and and or now, and the expressions got kind of complicated. In fact, so complicated that they've attracted the interest of mathematicians, such as this stern looking fellow. His name is George Boole. And he figured out the rules for working with conditions that could be true or false. And ever since, that's been called Boolean logic. Now, why do we care? We want our programs to be simpler to read. And so, when we have a long and complex condition, such as this one, we might want to put it in a separate method. Let's think about what this test here was. This was the test for the s flag, where you had a blue square in the middle. And this test you checked, is our pixel, in the middle. Alright, so if we had a method that could test that, we could say, if x and y is in the middle, then we want blue, otherwise white. Much easier to read. Lets go and write this method. Here it is, isInMiddle, takes and x and a y, coordinate. And here, you have the exact same condition that we've had before. And we simply compute, and return that. There's just one catch. We have to specify a return type for this method. And what is this thing that's being returned? Well it's either true or false. In Java, the type, that has two values, true and false, is called, Boolean, in honor, of our friend George. Here it is. So when you have a method, that can return a condition, that's true or false, you declare it as a Boolean method. Then you can use that method inside an if statement just as much as you can use the relational operator. You would want to do that whenever a condition has become so complicated, that you want to put it inside its own method. You can also declare variables of Boolean type. Let me give you a quick example. [SOUND]. I've reimplemented the isInMiddle method to use two Boolean variables. Let's check it out. The first variable, x in middle, checks where the x is between 1 Or to false if it's not. And similarly. This variable over here, yInMiddle, is set to true when this condition is fulfilled, and to false if it's not. Why might I want to do this? Because each of those conditions is complicated enough that by saving it in a variable, it makes the code easier to read. Now over here, I say if both of these conditions are fulfilled then the point is in the middle, so I return the and of these two. Generally, you use a Boolean variable if you want to remember a value that's true of false, so that you can use it later. Sarah has an example of that for you, in a different context.

## Using Booleans

A while back, the person class had the ability to return the number of friends someone has. We printed the number of friends like this, which works pretty well most of the time. But what if you only have one friend? It would print out, this person has 1 friends. If you want a program to look professional and have output with good grammar, you often need to have the plural form and the singular form of a word. We're going to tackle that problem in a minute. But in preparation, let's write a word class with a method for figuring out if a letter is a consonant or a vowel. Here's the word class. It saves its letters in an instance variable, letters. The is vowel method takes in an index, and then checks to see if the letter at that index is an a. You've probably noticed that this method implementation doesn't really match the description of the method. isVowel should recognize a, e, i, o, and u. Call y a consonant for now. This isConsonant method is completely empty at the moment. It's your turn. Fix the condition in isVowel and implement the isConsonant method. Here's a hint, you shouldn't need to do 21 checks to implement isConsonant.

## Using Booleans

In is vowel, we want to return true if letters.substring equals a or e or i or o, so we add those comparisons using or. So, it would look like this. I had to type letters dot substring a whole bunch of times maybe I should have made that a variable. And then, every word I used letters.substring i to i plus 1, I could replace them with letter. That looks a lot better now for is consonant a letter is a consonant if its not a vowel. So, I can take a shortcut here and just return not is vowel for the given index. I don't need to tell it that it's an int. And I didn't actually initialize letter. If I want to test my method, I can make a new word. I'll fill it with sleep. And now, if I ask if the first letter is a vowel, I get that it's not because it's an s. If I ask if it's a consonant, I get true. I would probably want to test a couple more cases if I was going to ship this code to somebody. But, this looks like it's working for now.

## Nested If

Now let's implement the method which returns the plural form of a word. We'll make some simplifying assumptions because plurals in English has a lot of rules. Check out the Wikipedia article if you don't believe me, or if you think phoenetics are interesting. We're just going to look at regular plurals, like dish, which becomes dishes. Or cherry, which becomes cherries. Or clock, which becomes clocks. Here are the rules I want you to implement for the initial version. If you want to make a more comprehensive version, nothing's stopping you, but get these ones down first. If the word ends in y, preceded by a consonant, take away the y an add ies, like in cherries. If the word ends in y preceded by a vowel, just add s, like in day which becomes days. If the word ends in o, s, sh, or ch, add es, likes in dishes. Otherwise, just add an s. You can use the is vowel and is consonant methods that you wrote before, as well as another method that I added. The method is takes an index, and the letter to compare it to, and returns true if the letter at that index matches the letter. There's also a tester program with a bunch of examples of correct plural spellings of the words. As a bonus, what happens if you give your program a single letter word, like a. What if you give it an empty string? Does it crash?