In the last lesson, we implemented several classes but their behavior was pretty simple. But, what if we want to do something a little bit more complicated, like the day class? >> In that case, you'd need to know more about working with numbers and Java. That's what we'll cover in this lesson. I think I work with text more than numbers when I program. Well, actually, that's what I do too and we'll cover text processing, as well. In this lesson, you'll learn what java has to offer for working with numbers and text.
My name's Ingrid Avendaåo and I'm an intern at Jawbone. I'm, I've been going to school for art for three years and then I switched over to electrical engineering. The reason I started that was it started off as a bet with another friend and then the notion started off that I couldn't learn how to program. And I kind of feel a little bit spiteful, and be like no I can do this, I, I can prove them wrong. I, I signed up for, or into the computer science course and that whole semester like it was really, really like terrifying to get into. Because I had no idea what I was doing, but by the time finals rolled around and I'm just. The whole semester had passed where I'm like, I can't do this, I don't think I can do this and I got my final grade. And then I was like, wow, I actually enjoyed this. Which was kind of something I wasn't expecting, but after that I kind of decided, you know what, this is something that I haven't enjoyed in years. Just having challenging problems that, like I'm excited to sit there and program for hours. I'm like I'm going to solve this, I'm going to do it and so I decided I had to do something different and I decided well I'm going to try to do electrical engineering. Its a little bit more hands on with hardware. But I still got that programming element. So that's what leads me to do an internship at Jawbone and I've been doing three years of electrical engineering at the University of Pittsburgh.
Hello, and welcome to Lesson 4. In Lesson 4, you will be working with numbers and with strings. You already know that you use integers for whole numbers and the type called double for numbers that can have fractional parts. So far, that seems pretty easy, but there's some things that you need to know so that you stay out of trouble. Let me give you an example. Have a look at this statement over here. We initialize the variable one million with well, one million. We multiply one million by itself, that gives us one trillion, which is a number with a lot of zeroes. And we put this into mystery, now you can already tell that something is going to go wrong. Otherwise, I wouldn't have name this variable a mystery. So go ahead, fire up BlueJ and type these statements into the code pad. Or if you prefer, use the Udacity ID. When you're done, tell me what you got for mystery.
Wow what I got is this value here. Seems hard to believe so let me show you how I did it. Here is the code pattern in BlueJ. I defined my variable one million. I defined mystery as the product of one million by itself and I asked BlueJ, whats mystery and here I get this very mysterious number. So what's with that? It looks like we need to understand a bit more about number types in Java than just the difference between integers and floating point numbers.
You've just run into the phenomenon called Overflow. Just like a glass of orange soda can overflow when the foam goes wild, the same can happen with integers. The largest integer that java can represent is this number over here. don't worry about the exact number, but you do want to remember that it's about longer hold the value in an integer, and the most common remedy is to use the double type. Give it a try. Here, one million is typed as a floating point number, as a double. Now multiply it by itself, and what do you get for mystery?
Well, when I tried it, I got 1.0E12, that's Java's way of using scientific notation. 1.0 times 10 to the 12th. That's a 1 with 12 zeros. So, in this case, changing from integers to floating numbers solved our problem. But it's not always that simple.
With floating point numbers, you sometimes run into the issue of limited precision. Look at this example. Go ahead, try it out, and tell me what value do you get for total price. When you're done, just put your answer here.
Well here's what I got and it's a bit surprising isn't it because 4.35 times internally in a different number system called the binary number system. And there's no exact representation for 4.35 in that system. It's kind of similar to the pocket calculator when you divide 10 by 3, you get 3.33333 and so on. And then when you multiply again with 3, you would get 9.9999999 and so on. The reason is that there's no exact representation for the fraction 10 over 3 in the decimal system. Now, as programmers, we don't usually worry about the detailed reasons why these round off errors occur. We just have to generally intuition that floating point numbers are a little bit fuzzy. Just like the fuzzy photo over here, you can't quite rely. On every last pixel so when you get a number like 434.999 and so on that's just something we have to deal with. Now in this case, if we don't want to lose any pennies, the remedy would be to use integers and work in pennies. If this had been 435 pennies as an integer types in Java that you may need in more technical situations. We've prepared a fact sheet for you. Go ahead, read through the worksheet and then work with Sarah on a few quiz questions.
Choosing the right data types can make or break your programs. We've prepared a fact sheet on numbers for you that tells you what numbers can be represented in each type. Write variable declarations by matching each of these variables, with the type and a literal. Write an appropriate type here, here, here and here. And an appropriate literal here, here, here and here.
The visitor count for a small doctor's office today would be relatively small. Something like 123, and wouldn't need a very long number or a very precise number, so it could be an int. The number of gallons of waters used per day could be pretty much anything. We don't know what it's being used for, so it could be two or it could be two million. It probably doesn't have to be an integer. You could have 2.5 gallons of water. So, this should be a double and we might write it as something like 123 point or 1.23 E2. Either would work fine. They mean the same thing. The userCount, the number of visitors to your website today, could be a very high number, but it has to be an integer number because it's a count. So, we use a long. And a long when you write it as a literal looks like this. halfLife, a measure of how long it takes a signal from radioactively tagged oxygen to decrease by half is another double. There's nothing to guarantee that we'll have an integer value and it might look like one 123 or 1.23 E2. Good work if you got all of those, but if you didn't its kind of a matter opinion how you might write these different values so no worries.
You've now seen the integer operations and it's time for the fine print. After reading the fact sheet, what do you expect a to contain? How about b? What about c? Try out the code in BlueJ. What do you actually get, in b, in c.
These should have given 42, 16 and 4. This last one should have surprised you if you haven't coded before. Mostly Java follows the same rules that you learn in algebra. Here x is 3 and y is 4. Multiplication happens before addition and then we add 4 to 3 and get 7. 2 and 4 gives us 6 and we multiply it to get 42. It's possible that your algebra sense took over here and you read xy as x times y. But it should actually be 11 because xy is a variable. Then y over 2 and 3, miscalculated. I would've expected this to be 4 plus 5, which is 9 over 2. Which would be 4.5. Let's go back to [UNKNOWN] to talk about what happened.
You just worked with Sarah on a few questions on arithmetic operations. But I want to talk about the somewhat trickier aspect on how to do division with integers. Let's say I have a piggy bank full of pennies, and then I want to know how many dollars do I have. In Java, I can computer that with a division operation, and there's a bit of a catch. When both operands on the left and on the right hand side of the division slash our integers, then the quotient is formed, and the remainder is discarded. Mathematically, 435 divided by 100 is of course 4.35. And then, the 0.35 is gone. The leftover is 4 as an integer. And that number here is now saved as the dollars. That's just what we want, right? 435 pennies is $4. What if we also want the pennies, for that we have a different operator called the modulus operator, and we often just pronounce it as mod. By the operand on the right, let's try that out with 435. 435 divided by 100 is 4. So, there's 4 times 100 going in here. When we take those off, we're left with a remainder of 35. That was no longer divisble by 100. That's what the remainder operator yields. You can see that by making an integer division by 100, and then also a reminder operation with 100 then we get the dollars and the cents value. Now, it's time for you try this tell me what is. Pennies integer divided by ten and pennies mod 10.
Pennies divided by 10, it's 43, because we have 435 divided by 10. That would be 43.5. The 0.5 is erased. We're left with 43. Now that means we have ten times 43 of 430 accounted for. And the remainder is 5. In general the remainder by 10 is always the last digit of a number. That's a useful fact to remember.
Now that you've seen some of the quirks of Java math syntax and why they happen. It's time to practice writing your own Java expressions for math calculations. We started a class for you that has a method for each of these expressions. Can you fill in the Java code for each of the methods? As well as the skeleton for these three methods? There's a test program you can run to test your work as you go, because these are a little bit tricky. Don't change the test program. Here's a hint. You may want to change some of the parameters of a method, but don't change them too much, because then the main method won't work anymore.
Let's go to BlueJ. Initially, if we run the tester, all the methods are returning zeroes. Let's fix this one first. So, ugly fraction is meant to calculate this fraction. What if I just write it in sort of the way it is? Did it work? Let's see. Hmm. It's calculating 5.3 repeating instead of just 0.3 repeating. So, when operators have the same precedence, it just go left to right. So, what this is going to do, is say y and divide that by x, and then multiply the result by 1 plus x, but we wanted 1 plus x to be in the denominator. So, we need to put in parenthesis to show that these pieces go together, and now it should work. Here's the output for the second run, we've got 0.3 repeating and 0.3 repeating, sweet, what's the next one? This is a lot like the last one. We'll need to add parenthesis to keep the numerator together and to keep the denominator together. There's my numerator, and there's my denominator. Oh, hey, look. I made an error. I can't just say 3X, I've got to add the times. And I did it twice. Three times. Alright, maybe it'll work now. Our new output is here. So, the first one's still good. That's good. We didn't break the old one. And now, the second one is working as well. All right. How about that third method? This one's a little bit trickier. So, if we do it the obvious way, just add them all up and divide by 4 when we run the tester program, we'll get 3 but the average should have been 3.25. If we look at the tester, it's calculating the average of 3, 4, 3 and 3 which should in fact be So, this division ends up in being integer division and tossing out all of the extra decimal points. There are few things we could do to fix this. We could write 4 as 4 point to say that that's a double, and then if we run it, it should work. We get 3.25, as expected. Or, we could change the inputs. They don't have to be ints, we could make these doubles. And then, we wouldn't need the point. This would still give us 3.25. This is a really easy thing to mix up. This looks right to us, but the computer's going to read it wrong. And the compiler won't warn you. This will end up being a run time error. This is an example of why it's really good to think about what you want an answer to be beforehand. Calculate one example, and then write your code. Good work on this quiz.
So when learning like order of operations. That was something that I never really thought twice of, especially you know when you're a kid and you're in the math class and then you're in high school and college. And I mean you're told that there's different order of operations but when you're programming it's a little bit different because then you know you've got you know doubles and ints and floats and that's something that like off the bat, like I kind of struggled with, like sometimes my, like I would run my code and it would work, other times it didn't work. And I ended up learning that one of the most important things is being able to know the answer before it comes out and understanding how that answer works. And understanding the sequence like the operations like, what, what different things would work and what wouldn't work. And, one of the things for me, like, you know, even just sitting down with a piece of paper and understanding, okay, so if I divide by an int, will I get an int back. Like, if it's a double that I was dividing by. Like, what, what's the actual way to do this that's right. And then if that something wasn't right, I really needed to work hard to understand why at first and now, I mean, it's more instinctive that I like, I'll, I'll even write it not thinking twice about it. But, when you're learning this, it's something that, like you don't realize is actually important to keep things, I guess together and concise. Something like that.
Let's put to work what we learned about arithmetic with a pretty interesting problem. The digital camera in your smart phone takes pictures where a red green and blue values can be any number between 0 and 255. That's 256 possibilities for red, the same for green and for blue and that's millions of possibilities, giving you pretty big files. Now here on planet Earth that's not a problem. But here on our rocket ship that's exploring a distant planet and it wants to send photos back, maybe a less arrange of colors would preferably suffice. So, I'd like to cut down this range into the much smaller range from 0 to 5. And I'd like to do that in a uniform way. What I mean was that if I look at the interval of numbers between 0 and 255, that approximately 1/6th of them should amount to 0. The next 1/6th to 1, the next 1/6th to 2 and so on. Here's a way of doing that. First multiply by 6. And then divide by the length of this interval. Then all the numbers in here will be 0, all the numbers in here will be 1, here they will be 2 and the the last region there will be 5. Now I'll give you a number of choices for the Java code for doing this. And I'm asking you to pick the right one.
This one here is the correct answer. Let's see why. The first two can't be right, because we're multiplying with a decimal number here. And then when we divide, we're not going to get an integer. We're going to get some fractional number, 0.0 and a little bit, 0.9 maybe at this end, and so on. But that's not what we want. We wanted to reduce these, this range of integers to that range of integers. So it's gotta be one of these two, and now the question is do we divide by 256 or do we divide by 255? And it doesn't seem like it would matter much, but it really does, namely if value happens to be the very last element, if it happens to be 255. Then this equation wouldn't work, 255 times 6, again, divided by 255 would be 6, and we're only supposed to get values between 0 and Java.
You've just seen how to take a value between zero and 255 and change it to a value between zero and five, so go ahead and do that. Then multiply by five so, you get a value that's one of these six. The reason to multiply by five is, if you just left the zero to five in place, then all of the colors would be almost black and you wouldn't be able to see them. So, here what we've done is we've taken a large color range, turn it into much smaller one and then spread it out again into the original range. Now remember you have to do that separately for the red value, the green value, and the blue value. So, go ahead and complete this program.
All right, here's what I did. I first of all computed the reduction 0 to 5 that you've seen just a few minutes ago and multiply that by 51 to get one of these six values. That's the job for red. It's the exact same for green, and for blue. Let's try it out. When I run the program, I can pick an image. I get to see it before the change is applied. And when I click on OK, then the change is applied. And when you look carefully, you'll now see that the image looks coarser. It has fewer colors, for example, in this range here. Now fortunately, my cat Eliza isn't on a distant planet. But if she was, then it would take far fewer pixels to send her image to me. The exact equations that we just used aren't really important to remember. But the point that I wanted to make is that even though integer division doesn't sound like the most interesting thing in the world. It can be put to good use and give you a fun application. Go ahead and practice that a bit more with Sarah.
So I'm thinking about Sally Ride again. On June 18th 1983 she became the first American woman to enter a low earth orbit. I'd like to sort of mentally recreate that day, so let's start with something relatively simple that we can do. What day of the week was that? I'm going to assign numbers to the days of the week. So Sunday it'll be 0, Monday will be 1, Tuesday 2, and so on. Write a program that takes a date and tells you what day of the week that was. You'll need a reference day to start with, so I'll tell you that January 1st, 1900, was a Monday. You'll want to write a program that uses this fact to count the right number of days To get to the right day of the week. You can use the fact that January 1st, 1900 was a Monday in your program.
Before I write the code for this, I want to work it out for a couple other examples. Probably the easiest example would be January 2nd, 1900 since I know that would be a Tuesday. I can calculate the days that January 2nd is after January 1st, by using the daysFrom method on the day object. In this case, it would give 1. Now, the day of the week would be the reference day plus the number of days that we are away from it. So, in our case, Monday, plus the number of days after. And this will work for this case. But if I take a slightly farther away case, like January 8th, 1900. I know that would be a Monday again. But it's seven days after. So, I would get that it was 1 plus 7, which is weekday 8. Weekday 8 doesn't exist. We only have up to weekday six. So, what I really mean to do is start on Monday, and add seven days. One, two, three, four, five. Six, seven. So, instead of continuing up to, day 7 and day In this case mod 7. So, the uncorrected value in that case would of been 8, and to correct it, I would calculate that the actual day of the week was the original one, the uncorrected one, mod 7. The first thing I need to do is create a day for the reference day and I'm actually not going to use birthday in this case. So, this is actually the wrong way to do this, because I might want to use this program to calculate lots of different days. While I'm testing, I'll make this an easy day, like I just mentioned so, January 8th, between the referenceDay and the desiredDay. Using that good old daysFrom method and now the uncorrectedWeekDay would be the weekday of the referenceDay. I'll call is referenceWeekDay. Which is a Monday, plus the number of days between the referenceDay and the day we're interested in. And now to get the correctedWeekDay, we take mod 7 from the uncorrectedWeekDay. Lets check if I made any mistakes. I'm pretty sure that my answers should be Monday, that was what I calculated before. Forgot to say that this is a day. And that one too and the referenceWeekDay was an int and I can't find a variable weekday. Because what I called correctedWeekDay should actually just be weekday and that one should work better. So, now if I run the method, I get that weekday is minus 6. Must be a bug. So, where could I have gone wrong? Somehow I got a negative number here. I must have got a negative number because referenceWeekDay plus daysBetween is a negative number. ReferenceWeekDay is definitely 1. So, daysBetween must have been negative. It looks like referenceDay.daysFrom desiredDay is a negative number, but I'm here assuming that I'm using it to count up. I'm going to check that using the debugger. I'll put a break point in and I'll run the method. So, when I step over the line where I initialized daysBetween, I can now see that daysBetween is coming out as negative seven. So, my suspicion is confirmed. Instead of calling referenceDay.daysFrom desiredDay, I should have called desiredDay.daysFrom referenceDay. Let's try this one out. Now I actually get the weekday I expected. And I'm ready to go back and reset this day to the day I was interested in, which was June 18th, 1983. Looks like Sally Ride entered low Earth orbit on a Saturday.
What if we wee painting all of the spaces in a checkerboard, and we were painting them blue and red? When we're drawing this rectangle we need to figure out whether it's going to blue or red based on the number of its indexes. We want to write a method that takes the row and the column of a space, and then gives us a one. If the space should be red and a zero if the space should be blue. The public interface of this method might look like this. So, we need some mathematical expression which takes a row and a column and gives back a one or a zero. If the row and the column are both even or both odd, you should get back a zero. If the row is odd but the column is even, then you should get back a one for red. And if the row is even but the column is odd, you should also give back a one. In the checkerboard project that we provided for you in blue jay, you'll want to implement checkerboard painter, and write a test method in checkerboard painter tester. Try running the main method of painted checkerboard. Once you've finished, if you need a hint, think about what happens if you add an even number to an odd number. Do you get an even number or an odd number?
This problem could get pretty complicated, so let's write some test cases out. I'll index spots by row and column. So 2, 2 would be right here, and that spot should be blue. So, we need an expression that when given 2 and 2 gets 0. The spot 3, 3 should also be blue. So again, we need a zero. 2, 3 should be red. So, that should be a 1. And 3, 2 should be red. So, also 1. So, what's an expression I could try to use to turn 2 and 2 into 0, 3 and 3 into 0, 2 and 3 into 1, and 3 and 2 into 1. It kind of looks like maybe I'm taking the mod of these and adding that together. So, row mod 2 plus column mod 2. Let's see what this gives in each case. 2 mod 2 would be 0. 0 and 0 gives 0, so that's good. 3 mod 2 is 1 and 2 mod 2 is 0, so that gives 1. The same will happen here. This one doesn't quite work. 3 mod 2 is 1 and 3 mod 2 is also 1, so I would get 2. But then maybe if I just mod the whole thing by 2 again, then I would get 0 which is the same. The 2 would turn into 0 and the ones would stay. So, this expression might work. Let's test it out in BlueJ. First, I'll check my test and put some actual values in it. The test cases I came up with were 2, 2; 3, should be good to go. Now, I'll try putting that expression into the actual program. In the checker board painter, instead of returning five, I want to return row mod 2, plus col mod 2, and then all mod 2. I don't have to put these in parentheses because the plus has lower precedence. And let's try it. If I run the tester, my actual and expected values match up. But could we make this any simpler? What if I noticed that adding an even number plus an even number gives me another even number. And an odd number plus an odd number gives me another even number, but odd plus even or even plus odd both give odd numbers. Then I can just add row and column, and take the mod 2 right at the end. Because if they match, their sum is even. And if they don't match, the sum is odd. So, I'll just get rid of the mod 2 and the mod 2. If I change it in the checkerboard painter, erase that and erase that. What will my test say? Is this still the same? And if I run the test again, still works. As a bonus question, what if instead of returning 0 when they match and 1 when they don't match, I wanted to return one when they match and zero when they don't match. How would you do that? I won't go over it, but it's something to think about.
Well hello again. Remember a while ago we had that fancy cat food, $4.35, a jar. And then we did some computations, and there were round off errors, and I said, oh, just convert it to pennies. I guess like this. Go ahead and give this a try. Does it work for you? Or do you get a compiler error? Or are you off by one penny? Or do you get something that's almost the right answer, but off by a few fractions of a penny? Do it yourself, and let me know.
When you try this, you will get an error; and the reason is that the type of double, then the entire value is also a fractional number. And the java compiler will not let you move a double value into a int variable. That's a bit of a pain. Here is how you convince the Java compiler to do it anyway. This is a very strange syntax whose origins are somewhere in the mist of time, of programming languages, and we won't dwell on that. But here's what you need to do. This value here is of type double. Now, we don't want it to be a double, we want it to be an integer. Then you have to put the name of the type that you want int. Put parenthesis around it, and put it before the expression you want to convert. What now happens is this expression here is computed. The fractional part is discarded, the integer part is moved over here. This operation is called a cast. That's a curious name. Are we casting out a fishing rod? Is it a cast around a broken foot? The cast of characters in a play. Well, I guess it's mostly like the later, because we have this value here that actually is a fractional number, and we want to cast it not as the hero in the play but as an integer. Whatever, that's just what it's called. Every once in a while you need to do this. You have something that is not of the type that you want. You want to change its type, and the cast notation does that for us.
Go ahead and do this computation using the code pattern BlueJ. What answer do you get?
Well, if you actually tried this, you will see that you get 434. That's a little unfortunate. The reason here is if you remember that 4.35 times 100 because of round off was 434.99 something. And the 0.99 something is the fractional part, and that was thrown away to get this integer. To really do this right in Java, you have to use a pretty arcane formula that's in fact so arcane that I have to look it up. You use a mathematical function called round that gets you the closest integer. So, 4.35 times 100 may be 434.999. But the closest integer to that is 435. And then, for reasons that are too depressing to have to get into, you still have to cast that into int. We have a fact sheet that you can consult if you actually run into this situation. The round function here is one example of a mathematical function. There's a bunch of them, and we'll take them up soon, but first let's do another programming exercise.
So, one of things when I was learning how to program was casting. And that was something that [LAUGH] I feel like I learned casting a little bit later than everyone else because its just that it was very foreign for me to really understand like how everything was set up initially. And so when I learned about like you know oh I have variables. I got that. Okay? So, there's variables. But then you know, you've got ints you've got doubles, and that, that was one of those things I didn't understand the importance of it. And for a while I kind of dismissed it as like I don't want to ask for help, like it's okay. Like I'm just going to, I'm just going to go right through this, and then I'd have problems where I'd be running my code. And then like all of a sudden I got a crazy long number back and I'm like what did I do wrong? The person next to me just got six. How did I had, how did I mess up here? And the email was one of the thing that's like, I think my pride was a little bit got in the way, I probably should have just like, hey, why isn't my number working? By the time I understood, like the difference it's like a whole number versus like you know, number of the decimal like the know like oh, I get it, like. Now, it's just, like, instinctive. Like, whenever I'm, you know, writing something, like, I know which number like, what kind of custom I have with it. And it's those little things that, like, they kind of stand in the way, at first, where it's, it's silly looking back but, I mean once you get the, like major concepts down. It's like, you wouldn't even think twice about it. It's like, I've got a hand and well, I've got an int. [LAUGH]
In the olden days, cameras couldn't record glorious color, they only had grey. And sometimes we want to take a photograph and turn it back into grey to give it that old fashioned effect. Now, you might thing that all you'd have to do is average the red, green, and blue values. But it's not quite that simple. As it turns out, the receptors that we have in our eyes have different sensitivities to colors. And what you actually have to do is take the red, green and blue values weighted by these factors, and then turn them into grey. And then, when you're done with that, you can set red to these value green and blue, because they're all the same, that's what makes the color grey. And then, you're done. But we have the same problem that you just saw. Red, green, blue are integers. These weighing constants are fractional numbers. So, the whole expression is a fractional number. And I want to put it back into an integer. So, the solution is again, to inject a cast, put this expression in parentheses and put parenthesis int before that. And then, you get it truncated down to the nearest integer. Once again, I'd like you to try that, so you can see it with your own eyes. Go ahead. Again, in the color class, implement a new method. In this case, it's the turnGray method. Take the red, green and blue values, combine them to a gray value using the equation that you just saw. Make sure that you get an integer. And then, take that integer and put it back into red, green and blue. Go ahead and do it now.
Here, I'm computing the weighted average of the red, green and blue values using these funny numbers. By the way that can work, the result here is a double because it involves fractional numbers. And I can't put a double into an end, that's where the cast comes in. Now I have my gray value. And I stick that into red, green, and blue and I'm done. Lets check it out. Here is Eliza in color and here she is in black and white like in the olden days. That's pretty nifty and it shows the reason to worry about casts. We had a situation where we had a decimal number expression that we needed to put back into an integer.
Sometimes basic arithmetic isn't enough to solve a problem and you need to use one of the many math functions that Java has to offer. In fact, there's so many that you couldn't possibly remember them all, and we prepared a fact sheet for you. Let me just go over the most important one. Let's say you need to compute a power such as 2 to the 10th. You can't write that exponent neatly in Java, instead you use a function and the syntax looks like this. The function name is pow, it's in a class called Math. You have to reference it as Math.pow. Then, you give it to the two operands, the 2 goes here, and the 10 becomes the second one. If you need to compute the square root, you use the square root function. Again, it's in the Math class, Math.sqrt, and whatever it goes inside the root symbol in Math notation goes inside the parentheses here. For absolute values, there is another function. It's called abs and whatever you put between the vertical bars in Math notation goes on inside here. Now, these kinds of functions come up often enough that I want you to practice this a little bit. Here, I have a bunch of function calls, and I'd just like you to tell me for each of them, what is the result? If you like, you can compute it in BlueJ, or you can just do it in your head.
Now let's see here, 10 raised to the 3rd power, that's 10x10x10. That's 1,000. The square root of 4, well 2 times 2 is 4, so that's 2. The absolute value of 3 minus 5, that's the absolute value of minus 2. Absolute value takes away the minus sign, and that's 2. Intuitively, what it means it's the magnitude of the distance to go from 3 to 5. So you have to go two steps, you use the absolute value, so that the direction doesn't matter. The absolute value of 5 minus 3 is the same as the absolute value of 3 minus 5. It's just the distance between these two values. Now, I've tossed in a couple of others just to see if you can guess these. Min and max are the smaller and the larger of these arguments here. So the miniumn of 300 and 255 is the smaller one, 255. The larger one of zero and minus 1. Well, zero is pretty small, but it is larger than minus 2 so that's zero. And our next image processing exercise will put min and max to good use.
I'll show you a nifty photot that needs math function to work. We want to take any old photo and make it appear as if it happened at sunset. And the idea is simple. We'll just add some extra red, like this. But there's a potential problem. What if red is already 255 or close to it. Then if we ad 25 to it, then we'll get a value that's larger than 255 and that won't work. So I want red to be red plus 25 but at most 255. And one of the math functions that we've just seen will solve this for you. I'll even give you a hint. It's either Math.max or Max.min. So go ahead and implement the redden method in the color class and then try out the effect.
Okay, let's work through this together. We want to add 25 to the redness, but we don't want it to get larger than 255. So, do we want to take the max, or the min? Do we want the larger of 255 plus 25, or do we want the smaller? We want the smaller because we never want it to get larger than 255. And that's the answer. Let's run this program. Here's the original image, which I took around noon. And here it is transformed into a beautiful sunset. And thanks to our friend mass dot min, none of the colors overflowed. Like I said, these math functions can be pretty useful.
Now, there's just one little blemish to the program that we've just written. It uses what programmers refer to as magic numbers. Look at this line over here, and it begs to question why 25, why 255? Those look like values that a magician picked out of a hat. Instead of using magic numbers, it's a good idea to use constants. Here is how you do this in Java. The keyword, final, indicates a number that can never be changed that has assumed it's final value. Or like we would say in math, it's a constant value. So here, are the 25, I'll call it added red and the 255 here, called max red. I defined these as variables just like you would define any other variable, except for the keyword final in front. And also, it's a convention amongst Java programmers, that constants should be written in upper case. Maybe with an occasional underscore. Now, go ahead and rewrite the statement here, using these two constants instead of the magic numbers. And put your answers into this box.
Here's what it should look like. Note that instead of the 25 we use the constant. Same for the 255 here and now when you look at the whole thing it reads pretty nicely doesn't it? We take the smaller of the original red plus the added red and the maximum. No more magic is involved. You always want to do that in your programs when you find yourself using numbers. whose meaning is not totally clear, just make them into constants.
You've written a lot of interesting programs already and that's great. But one capability that was lacking so far was to be able to ask the user to supply input. Here's how you do it in Java. Just like you use System.out for output. You use System.in to get input from the user. But as it turns out System.in is not very smart and to really read numbers and strings from the keyboard you use an object of the scanner class. You construct a scanner with a new operator, new scanner and this is the scanner that can read from System.in. Usually, you want to read more than one input, so it makes sense to save the scanner in a variable. Here it is. It's called in and of course it's of type scanner. Then, when the time has come to read something you call one of the methods of the scanner class. Here, I called the nextInt method. It reads an integer that the user types in. And returns it, and here I'm saving that integer in the age variable. So, you should think of a scanner, kind of like a supermarket scanner, except a supermarket scanner of course reads a bar code. And our scanner here reads something from the user, and also produces some number. The program snippet that I've written here is not quite complete. After all, how is the user supposed to know that then I'll ask for their age. So, before calling a scanner method that reads user input, you always want to alert the user first with the statement such as this one. The string here, how old are you, is called a prompt string. It prompts the user to then take the next step and provide an input. Note that with the prompt string, we put a blank space here, that just looks prettier, so that the users input is a little bit separated. When you print the prompt it looks prettier when both the prompt and the user input are on the same line. That's why we're using print and not print on here. And then, you want to have a blank space to separate the prompt from the user input. Here, we write an integer, you can also read a decimal number by calling nextDouble that returns a double. And again, you would then want to capture it in a variable. Let me demo this in BlueJ, so you can see what it looks like before you get to try it yourself.
Here, you can see the declaration of the scanner. Here, we are reading an integer. Here, we are reading a decimal number. And before we read anything, we have a prompt. One prompt for the age, one prompt for the weight. Finally, there is an important piece that you've not seen so far, look up here. This is what's called an import statement. As it happens, the scanner class is in a different location than the classes that you've used so far. That location is called java.util, it's a utility class, and we have to tell the compiler that's the place to find it. Whenever you use the scanner, simply place this statement at the top of your code. Let's go ahead and run this. The console window pops up. Here is my prompt. Okay. I'm going to lie about my age here. Now, if that had been my age of course the program would be right next here. I'd be 22. Not much one can do about one's age. It does increase every year. And I lie about my weight too. But I appreciate the sentiment that hopefully next year, it'll be less. That at least should be under my control. All right. Now, you've seen how to read input, and I'd like you to do it in another program. Remember this program, in which we added the sunset effect to a photo. Now here, we used a value of 25 to increase the redness. It might be nice to experiment with other numbers. But instead of recompiling the program with all sorts of different numbers, let's turn this one into a user input. Now, we can't put the input statement here. Because this method is called for every single pixel, and we only want to supply the input once. So, here's the plan. Take out this constant, and add a parameter here. Then here, in the main method, prompt and read the input here before entering this piece of code. by the way, don't worry about this loop statement here. We're going to be covering that in a couple of lessons. Now, here is the place that the method is called. That's where you should pass the added red variable, so that each time the redden method adds that amount of red. Go ahead and do that now. If you have BlueJ, it would be best if you first develop the program in BlueJ, and then when you're done, put your result into the Udacity IDE. If you don't have BlueJ, that's okay, just do it straight in the IDE. But then you won't be able to supply your own input. You'll have to live with the input that Udacity gives you.
Let me show you what I did. I removed this line. I added a parameter, then I used the parameter here. And am I done here? not quite. I still have to document the parameter. Pat yourself on the back if you did that. Now, onto the main method. Here, I want to read the input. So, I declare a scanner and I use it to read the added redness over here, I'd pass that value through the redden method. Now, there's a couple of things that I soon need to do. First off, the prompt, here it is, notice print not print on and the extra space. And finally, up here. I need the import statement. Now, we're ready to go. When running the program, I'm prompted for the added redness. I'm going to go and crank it way up here. And, woah, that's pretty red. Now, the benefit of having the input provided by the user, is I can now experiment with other values, I simply run the program again. And just to see if it works, I'll supply a negative number. And as you can see, now the image got a little bluer, greener, whatever, less red. Now, you know how to read user input in Java.
Now that you've seen user input, let's turn to another topic, formatted output. Let me show you why we need to know about it. Let's look at this program here. I want to buy 100 cans of my super premium cat food at $4.35 a can. So, my total price is going to be the quantity times the unit price. So, I'll print it. There's also 8% tax so, here I'm figuring up the tax, and then I'm printing that. Let's see what this program does. Well, look at it. It's ugly, ugly. Here, I expected to see $435, and the tax, you never see tax like that on your store receipt. It would say $34.80. So that's what I want. And by the way, I want these decimal points here to line up. It turns out, that's pretty easy to do. Here, instead of just calling println, we'll call a different method. It's called printf for print formatted, and here, we need to add a formatting string. The formatting string is here, it looks a little arcane. The percent says we're now going to be printing something. The 8 means we want it to be 8 characters wide, the 0.2 means, we went 2 digits after the decimal point. The f means it's a floating point or decimal number. The \n means, and afterwards, please give us a new line. As you can see, there's a whole mini language in these formatting strings and you'll practice a few of them with Sarah, after I'm done here. But truth be told, if you simply memorize this one. Or even better just copy and paste it when you need it. That's 90% of what you need. Let me do just that. So, here again, I'm going to be using a printer. I'm saying I want field with 8. 2 digits after decimal point. Now, when we run the program everything is nice and beautiful. Both numbers have two digits after the decimal point. Both of them occupy eight characters. As a general rule, whenever you display prices, go ahead and use printf. You'll practice that with Sara right now.
I'm printing a table and need to format some strings. Help me write the formatting strings for printing each of these values. What width goes here and what letter goes here if I want to print six characters wide? What format string goes here if I want two decimal places four characters wide? And format string goes here. The types of the variables are important.
CookiesPerDay is an int. So I'll use percent d and I want the width to be six. Cereal boxes per day is a double so in quotes I'll need percent f. And I wanted to be four characters wide with two decimals. Name of the string and I haven't gotten any special width requirement, so this one is just percent s.
I'm actually making the table, because here at Udacity we have a micro-kitchen where we keep shared snacks. And I want to find out where all of the cookies are going. So I'm compiling data and I want to print it out in a table, like this. Can you complete the code in MicroKitchenTable? To print out this table, a couple quick hints, this vertical bar character on an American keyboard is right below the Delete key, right here. You'll need to hold down Shift to make it work. Also, make sure to print a row for me and a row for Cay. I've started you off with some variables for cookies per day, cereal boxes per day for Sara and for Cay.
There are multiple ways to do this, but here is the one I chose. I chose to make one printf statement for each row. We want eight spaces with the number of cookies, followed by a vertical bar. Followed by eighth spaces with the number of boxes of cereal. Followed by another bar, followed by the name. I'll need to print all three variables, so I'll include them as parameters separated by commas. The format string will start with int value, so I'll use a d. And it'll be eight wide, so I have 8. Then, that vertical bar, then the decimal value, percent f with a width of 8 and 2 decimal places and then the string. The formatting string will look the same for my row and for cay's row, but I'll use cay's variables instead of mine. Since I'm using this pattern twice, maybe I would want to make a variable for it. And call it, Row Pattern or something like that, but since I'm only using it twice, I'm going to leave it for now. So far it looks like I'm eating all of the cookies on my own. But I haven't surveyed all of my coworkers yet, the answer could change. Now, if I'm going to collect more data, I may want to change my program to use a scanner to take in input and put it in the table. We'll leave that for now though.
We've talked a lot about working with numbers, how to compute with them, how to read them, how to display them, and you're written quite a few programs. But there's one important point that I'd like to talk about for a few minutes, and that is, first do things by hand before you open the programming environment. The natural urge of every programmer is to go ahead and open BlueJ, or whatever environment you're using, and start typing code. But that's rarely productive. Let me give you an example problem, and show you how I would work it out by hand. So, here's the problem. We're supposed to be putting tiles white and red ones alternating along a wall, and we are told the total width of the wall. We are also told the tile size. The architect tells us, we are suppose to start and end with the tile of the same color, and the question is how many tiles does one need to order? It's pretty clear that you need one more white tile than the red tiles. But how many clearly depends on the size of the tiles and the total width of the wall. So, let's say that your assignment is to write a computer program that helps the builder with this problem. Like I said, this is not the time to open your coding environment. Instead, do a couple of these by hand first so you get a feel for what the computations really are.
So lets say we have a width of a hundred inches and each of these tiles is five by five inches. Note that except for the first tile, the others come in pairs. Each pair is ten inches long. So if I take my width, subtract the 5 inches here then I have 95 inches left and how many 10 inch pairs can I put in there? But if divide 95 by 10, that's 9.5. I discard the remainder, so I know I have nine pairs, and the white one for a total of 19 tiles, 10 white, and 9 red. Great, that's my answer in this particular instance. Now the next step is to figure it out for arbitrary values after which and the tile sides
Now that you've seen the computation with specific values, let's do it in general. So what did we do? We started with the width of the floor, subtracted the size of the first white tile. Divide it by the sizes of the pairs, took the integer part. And that gave us the number of pairs. Now that's of course the same as the number of red tiles, because every pair has one red tile. And, the white tile says one more. All right, now, we're ready to program, and what I'd like you to do is to complete the program that we started for you. The program will read as inputs, the width of the floor and the tile sizes. And your job will be to run the computation that I've just developed, and to print the answer. Here's the program for you to fill in. You already give the commands for the input and for the output and your job was to put in the part of the program that asked computation. Now we did this by hand, and let me show you again the formula that we obtain. That's the formula here. So we take the width minus the tile size divided by twice the tile size, take the integer part.
Here is that formula written out in Java. Have a close look at the parenthesis. I was very careful to compute the entire expression, then have parenthesis around it, and only then take the integer part of the final answer. Now we are almost home free. The red tiles was the same as the pairs and the y tiles as the pairs plus one. Here I'm running the program and when I supply the same inputs as in the example problem, a 100 inches for the width. Tile size of 5, then I get the expected answer. Now the important part of this entire exercise is to first do it by hand. If you can't do it by hand, you can't program it. And doing it by hand gives you valuable intuition that you need to write the Java code. You'll get to practice this with another example that Sarah will show you.
Now you've done a lot of work with numbers and most people think that numbers are what computers are really good at. But truth be told many programmers work more with text than numbers. In Java the technical term for text is a string. Why a string? You can think of text being a sequence of individual letters that are strung together. You have already seen strings. In Java, their enclosed in quotes and there's some text inside. You've seen string variables, here is one, it's called name and it's type is string. You've seen a bunch of string methods and here are a few more. In the interest of learn by doing, go ahead, fire up BlueJ. And tell me what happens when you call each of these methods, or in the last case, when you execute this piece of code.
Here are the answers that I got. The length method returns the number of individual characters in the string. There were 7. The substring method extracts a substring that sits inside the bigger string. In our case, it extracted this string. Whenever you want to extract substrings, you have to understand how the positions in a string are numbered. In Java the initial position is 0, that may sound strange but it's actually pretty useful, and then it goes from there. The string has length 7 and the position's in it are 0, 1, here. That is the position of the first character that we want to include in the substring. The seven here is the first position that we don't want to have anymore. We don't want position seven. In fact, there is no position seven. We want the ones from three to six. That sounds a bit odd to most people when they see it the first time. But there is an advantage. When you subtract these two numbers, 7 minus 3, that's 4, and that's the length of the substring that you're extracting. The next method here, the indexOf method finds the position of a given character. So, over here I want to know where does the C occur for the first time. And it will go through and say, that's at position three. And finally, you already seen this plus operator in lesson two. It takes two strings and glues them together or as we like to say in programming is, it concatenates them. So, here is the concatenation of Hello and Udacity, notice there's no space in between because there was no space in either this or that string. If you wanted a space, you'd have to add a space. Strings are really useful when you work with text. Sarah has a couple of nifty exercises prepared for you when you get to work with a rather long text and take it apart. And put pieces back together by using some of the string methods that you've seen here. Enjoy.
Being able to modify strings quickly and cleanly is probably the most commonly used programming skill. So let's practice a bunch of these. We're going to be working with the Alice Project. We've given you a program book, which does some magic to read in a book from a file. It's down here, but you don't have to look at it if you don't want to. Check out the link to the fact sheet on string methods, and then use them to complete the methods for this program.
Objects in the book class know how to read the text of a book into a string. We've included the text in a text file, you can see it in the directory with all of the code for the project. Soon objects of the book class will be able to return all types of information about the text they include. But first, you'll need to add the methods, starting with this one. Right now, getNum characters just returns zero, but it should be returning the number of characters in the entire book text string. And I mean characters like letters and punctuation, not people in the book. There's also a book tester with a main method you can use to check your answers. Happy coding.
From the cheat sheet, we can learn about the length method. If we return book text dot length, that will return the number of characters in all of book text. If I run the book tester, which might take a second since the book is pretty long, I will get the actual number of characters and the expected number of characters
For your next feet of coding magic, I'd like you to write a method that returns the location of the first occurrence of Mad Hatter in the text. I'd also like you to add a line to the tester program, so that it prints the location of the first occurrence in Mad hatter. For this one it's okay if you just print the actual and not the expected. What is the actual value? What is the location it prints?
So after the get number of characters method I'll add another method. From the fact sheet we can see that the index of method will help us. We want to return bookText.indexOf Mad hatter. Now we need to add that line to our test program, BookTester which prints out the actual value of Alice.firstOccurrenceOfMadHatter, looks like I capitalized it wrong. Alright, now let's see what this actually gives us. Huh, the actual value is negative one. That doesn't sound like a location. There shouldn't be a minus one character in the book. Let's look at the documentation. In my browser, I'll search for java 7 string and find the official documentation. And then I'm going to look for the index of method. Methods, index of, we're giving it a string. Alright, returns the index within this string of the first occurrence of the specified substring. That's what we were expecting. The returned index is the smallest value, k, for which this dot starts with stir, k. Not sure what that means yet, we can think about that later. If no such value of k exists. Then minus 1 is returned. Okay, so minus 1 means that there are no occurrences of Mad Hatter as we wrote it in the book. This might be surprising. The Mad Hatter is a famous charater. But it turns out, in the book, he's always just called the Hatter, not the Mad Hatter.
What if we just want to print the first sentence of the book, including the period at the end? What method would you use to print just a piece of a string, not the whole thing? And at what index does the first sentence end? Here's the text from Alice in Wonderland that we gave you, or at least the first couple of sentences. We could sit here and count to find exactly how many characters come before the period. Or we could use the methods we already know. Implement to get first sentence method. If it's working it should return this. If you're not sure what methods to use to get started, you'll have the link to the fact sheet.
To do this, we need to add a method to our book class. We're going to want to use the substring method to print out just the text from the beginning to the first period. So, the first index we should put in is zero because that's the first index of the character in the book, and then we need to find the end of the first sentence. We can do this using the indexOf method that we used before to look for Mad hatter. And now the key here is that substring for the second argument, wants to take the character after the last character to print. So, if the last character we want to print is the period and that's our endOfSentence, we want to give substring endOfSentence plus one. Now in our tester, we'll want to add another line where we test out our new method and compare it to the expected value, which is a little long. So, we'll need to split it across a few different lines. And see how this worked. So, the actual is exactly what we expected and the expected is missing some line breaks and goes to the side for a long time. But other than that, it looks like this is basically doing what we wanted.
Now that you know where the first sentence ends, you also know where the second sentence starts. Write a method, public String getSecondSentence that returns a piece of the book, starting after the first sentence and ending after the end of the second sentence. Here's a hint, indexOf has several versions, one of them just finds the first occurrence of something but there are others that are more flexible.
Here's our trusty book class again. And we're adding a method, getSecondSentence. Last time we could just use the zero as the beginning, but this time we're going to need to start where the first one left off. So we calculate the beginning the same way we calculated the end. But then start right after the period instead of at it. To get the end of the sentence, we'll need to use a different version of the indexOf method. We're still looking for a period. But now we want to start at the beginning of our sentence, that we're working on. And now we use the sub string method the same way as we did before. And return book text dot sub string from begining of sentence to end of sentence plus one. I added a couple lines to the book tester, so we can actually test our second sentence method, and now I'll run the book tester again. Here's the result. I don't remember the second sentence by heart, let's look at the Alice text again. It looks like the second sentences match, good work.
What if we want to know how many times the word Alice shows up in the book. It's got to be a lot right. But is it 20 or 200 or 2000. Next, we're going to write a method. public int occurrencesOfAlice that returns the number of times that Alice occurs in the text. Here is a hint. How much will the length of the book change if we remove all the occurrences of Alice?
If we replace all occurrences of Alice with no letters, then the length of the book will decrease by five times the number of occurrences of Alice. Because Alice has five letters. So if we calculate the length of the book with Alice and the length of the book without Alice, and take the difference. We can divide the difference by 5 and get the number of occurrences. So, here again, is our book class with our new method, occurrences of Alice. First, we'll calculate the original length and then the length after we remove all the occurrences of Alice, by replacing Alice with an empty string. Then we return the difference between the 2 all divided by 5. Let's add a line to our book tester to see how many times Alice actually occurs. And if we're in the main method again it now tells us that Alice occurs 395 times. It's not totally clear or obvious that this will be correct, but you could check it a few ways. For example, you could open up the text and use some other program to search for the number of occurrences of Alice. Or you could find some word, that only appears once. Or maybe a string of words so you can be pretty sure that it would only occur once. And try using that to debug your code.
I guess that was kind of okay as a one off. But it would be better, if the method allowed us to supply any word, not just Alice. And counted how many times the given word occurs. So, let's write a method. Public int occurrencesOf String word that works for any word.
The method to find the number of occurrences of any word is going to be pretty similar to the one for occurrences of Alice. But instead of using specific references to the word Alice, like Alice, and the length of Alice. It'll use the given word, and the length of the given word. The calculation of the length won't change. But the calculation of the length without the word will. Looks like I need to actually take in a parameter. And now I return the length, minus the length without the word. Over the length of the word. Let's add something to our booktester, to test our new method. To check it we could compare it to our answer for Alice. Looks like I didn't actually make a method occurrences of. Ops. Occurrences of Alice. Should be more general. Hopefully now it'll compile better. Here we know to expect 395 from before, and there's another word that we checked how many times it occurs. We saw before that Mad Hatter doesn't occur at all. Let's try this out. Looks like we got the answers we expected.
Now that we have this book object and we've tested it, let's put it to use. You're going to write a program that takes a user input word, and tells how many times it occurs. Your code will be able to do this. When you're done with this you'll be able to run look up any word. It'll ask you to type a word and it'll look it up. So, I'll type Hatter and press Enter. And it tells me Hatter occurs 55 times. I'm going to give you some pointers. You'll want to make a new book, like we do in BookTester. You'll also need to use a scanner, don't forget the import. Also, you saw how to read and enter a double, but you didn't see how to read a string with the scanner. You'll need to look at the scanner documentation. Scanner has a lot of methods, you'll want to use one of the ones that starts with next and returns a string. If picking the right scanner method makes your head hurt, click the link that says hints. I'll go over this part in detail in the answer video.
So, here's the empty shell of our program. We'll need a scanner to read the user input, but right now the code won't compile. It doesn't know what a scanner is. We need to import java.util.Scanner to tell the program where to find the code for the scanner. That's better. Now, we want to print the prompt. And I remember my colon and space at the end. So that there would be space for the user input and I now read in the word. I'm going to use the next line, I'll explain that in another minute. I'll make my book so that I can use it to do the calculations. And now, I can calculate the number of occurrences and print the result in a nice format. I'm safe I made any syntax errors with all that typing. Sure enough, misspelled occurrences. Thank goodness for the compiler. You saw this run before, so I won't run it again. There is that one question left over though. The next versus nextline. Let's look at the documentation. If I search for scanner and Java 7, go to the official documentation, and then search for the methods. Here they are, there are a lot of them, but here are the ones that start to be nextFloat. And next, nextBigDecimal. All right. The ones that return strings are next, next with a pattern, next with another pattern. Next line, all right. And these look like something else. nextLine has slightly awkward language. Advances this scanner past the current line and returns the input that was skipped. But what this means for us is that the scanner will give us a line of input. So, everything the user types before they hit Enter will get loaded in with next. If I find the documentation for next without the line. Here's next. It says finds and returns the next complete token from this scanner. Wants a complete token. Maybe there's more information. It says, a complete token is preceded and followed by input that matches the delimiter pattern. And then, talks about blocking while waiting for input to scan. You don't need to worry about that part too much. Basically, it's saying it'll wait until the user actually enters something. But this delimiter thing, maybe somewhere on this page it says what the delimiter is. Let's look for it using Ctrl+F. Delimiter. This looks like it's in the summary near the top of the page. A scanner breaks its input into tokens using a delimiter pattern, which by default, matches whitespace. We saw whitespace before, that was things like spaces and tabs that you can't see. I guess that makes sense. So, it gives you a chunk that is separated from other things by something like spaces. So, it seems like next would work fine by default if the user just wanted to search for one word, like Alice. But if they wanted to search for two words, like Mad Hatter, you would want to use nextLine.
It kind of feels like our Alice in Wonderland code is done now, but there are a few more things we would want to do before presenting or sharing it. Our book class has a lot of methods: getNumCharacters, getfirstOccurrenceOfMadHatter, getFirstSentence, second sentence, occurrences of Alice, occurrences of something else. But in general we called it book, we didn't call it any thing specific to Alice. We would probably want to fix or generalize, or remove some of the methods that are overly Alice specific. Which methods should we remove or generalize? Write the names of the methods here.
We need to fix firstOccurrenceOfMadHatter and occurrencesOfAlice. FirstOccurrenceOfMadHatter should probably be generalized to take in any word. Technically I should probably test that change, but I won't bore you. And occurencesOfAlice should probably be removed since we have a general veresion.
A farmer has irrigation systems that work for circular fields. He wants to lay out the fields, so that he wastes as little land as possible and wastes no water at all. So, the fields can't overlap and there can't be factional fields because then he will be watering somebody else's lands. He is looking at many different pieces of land and computing how many circular fields will fit on a rectangular piece of land. It's a bit of a pain. Let's write a program to help.
Let's say that the circles are laid out. So that the fields touch the sides of the fields that they're right next to. And fields are nestled an equal distance from the field just above them on the left and the right. This calculation takes a few steps, so we'll need to go through an example by hand first.
Imagine that the farmer is looking at a plot of land that's 1,900 meters wide and 4,000 meters long. The irrigation system makes fields with a radius of 400 meters. To save some time, I did some of the math. And hopefully you can read from my drawing, that the first row will need 800 meters of length. To get two rows, you'll need 800 plus 400, times the square root of 3. Meters of length. To get three rows, you'll need 800 plus 2, times 400 times the square root of 3 meters of length. How many rows will fit on a piece of land that's 4,000 meters long? My goal isn't to test you on geometry. Just to show an example of how to solve a mathematical problem with Java. Try a few times, and watch the solution carefully if it doesn't work.
The answer should be 5 rows. We'll always have the first one, and then each additional row is another 400 times root 3 meters of length. So, to get the total number, we can do 4000 minus 800 over how much we need for another additional row. So, 400 root 3, and then we add 1 because there's that first row that took up 800. This calculation would give us 5.61. But we said that we couldn't have fractional rows. So, we just get 5. Let's generalize what we just did, if you already know the equation for the number of rows given the length of the field, write it down and skip to the next question. Based on what we did up here, the equation should be, rows equals the length, minus the diameter over the radius times the square root of 3 plus 1. Remember the radius was the calculation, we would drop the decimal. Save this, you're going to need it later.
Now we want to figure out how many columns there are in each row, and the land is 1900 meters wide. But it looks like depending on where we cut this off, some of the rows might have different lengths than others. I've done a little math for you here. This first field in the second row starts 400 meters away from this edge. Let's give names to these two different kinds of rows. The first and third are odd rows. The second and fourth and so on would be even rows. How many columns are in each odd row? How many columns are in each even row?
The number of columns in each odd row will be 2, and in each even row will be we can fit 800 plus another 800 is 1600, but not another 800, which would give us 2400. So, that calculation was 1900 Over 800 and then we lost the decimal. In the even row, we had to subtract 400 from 1900 because we can't use this first 400 meters. Then we can fit 800 and at this point we're at 1200, and if we add another 800 we would be at 2000. But that's more than 1900, so that wouldn't fit. So, that calculation was 1900 minus 400 over 800 and then we dropped the decimal. Let's write the equation for this. Write it down and skip if you know the rest. Calculate the number of ColsPer EvenRow. We calculated the width, which was 1900. Divided by the diameter. And then dropped the decimal. To calculate the cols PerOdd Row, we start with a width. Subtract the this down and save it for later.
We know from earlier that the total number of rows was 5. How many odd rows are there and how many even rows?
If there are five rows: the first, third, and fifth would be odd rows, and the second and fourth would be even rows. But how would we generalize this, to figure this out let's look at a couple more examples. If the total number of rows was 6, then even rows would be 3 and odd rows would also be 3. If the number of rows was 7, then odd rows would be 4 and even rows would still be 3. So, it looks like the number of odd rows is something like half of the total number of rows, but 4 isn't exactly half of 7 over 2. It would be half of 7+1 over 2. What would happen if we added 1 on to this 6 as well. Then we will get is 3, that one works. And 7 over 2 is pretty close to 3. In Javaland that's 3. So, if I just divide by 2 and throw away the remainders, it looks like I get the numbers of even rows. If you don't believe me, you can try a few more examples. So, it looks like the total number of odd rows is the total number of rows plus 1, over 2, and then drop the decimal. Whereas the number of even rows is just the total number of rows over 2, and we drop the decimal. There's another way you could calculate the odd rows. You could say that the odd rows are always the total number of rows divided by two and then you add one if the total number of rows is odd. So, that would be the total number over 2 plus one if 7 is odd. And if 7 is odd then 7 mod two would be one. So, total mod 2. Save these for later. And you could also try this one.
Now we are ready to put all the subs together to get an answer. How many circles fits in a field that is 1900m wide and 4000m long. You can use any of the information you have calculated so far, the total number of rows was 5. The number of columns in an even row was 1. And the number of columns in an odd row was 2. The number of even rows was 2, and the number of odd rows was 3. If you are getting stuck, think about how many of each type of row there are? And how many circles are in that type of row?
And the answer should be 8. There are 3 odd rows and each odd row has 2 circles, so we get 6 circles from odd rows. And there are 2 even rows and each of those has 1 circle, so we add 2. In general, that would be the number of odd rows times the number of circles per odd row. Plus the number of even rows times the circles per even row. You'll want to use this equation in your program.
You've seen one example all the way through, and have equations for each step. Implement the method getNumberOfFields which takes a width and a length of a piece of land and returns the number of fields that fit on that piece of land. Use each of the steps that we walked through together.
So, let's start out what we know first. We know what we want to test. So, I'll go into the plot tester and I'll create a new plot of the size that we did the example for. And then, I'll print out the actual which should be the number of fields, if the radius is 400. And then, I'll print out the expected number that we calculated, which was 8. Now, to actually do the calculation, first thing I do is calculate the number of rows, which should be an int. And the way that we did that was to calculate the length minus the diameter, divided by the radius times the square root of 3. But that wasn't counting the first row, so I've gotta add the first row back. And since there are some doubles in here, I won't automatically get integer division. So, to drop the fractional part, I'll need to actually cast this. Now, I haven't actually defined diameter. But that's just twice the radius. After that, I calculated the number of odd rows. Which was the total number of rows, plus one, divided by two. And the number of even rows, was just n rows over two. The number of columns in each odd row, was based on the width and the diameter. I want to make sure that I actually get an int here. So, I notice that the width is an int and the diameter is also an int. So, that's good. The column is an even row was the width, but we couldn't use that first space at the left. So, we have to subtract off one radius before we divide to see how many diameters fit across. And then, the total number of fields is the odd rows times the number of columns per odd row. And then, the number of even rows times the number of columns per even row and this number of fields is what we wanted to return. Let's find all my typos, oh got lucky that time. Let's see if the plot tester agrees, look's like it at least works for the example we checked. That's a good sign. That was a pretty tricky problem. If you struggled, way to stick with it.
So, one of the things for me going into programming and even engineering, was that it was an area that I never thought was actually like important to me as a person. growing up with a very strong art background. I went to an arts high school, like, my mother is an artist, my grandmother is an artist. Like, I just, I never really realized like off the bat, like how applicable it is. Like nowadays, I'm, so I tie the two together. I I make large paintings that have circuits embedded into the canvas. And I use an adreno which I program, so that I can do sequence of like, different light displays at the time. Or, like I'll use like capasitive sensors which I can like program like, and tweak like how the can work and what distances. These are things like me, a couple years ago, would have been like, oh, wait, I, I didn't even know I could do this. This is like a whole new form of art. And I think that's one of the things that people don't initially think like, oh, you know, someone's programming. They're just sitting at a computer, but like even the way that you program is an art. Like you can be so meticulous about it, like the same work ethic that I use towards making like a painting is the same one I use towards programming. And it's something that like, the two are so entwined for me that I can't see how, like, it wouldn't be for other areas. Like, I have friends that are writers and it's, it's also the same kind of, they have the same kind of feelings towards it as well. And it's like, it's something that where even now if I'm doing like an interactive art piece. I want to do a simulation, like that's an art in itself, and like to sit down and like program with open frameworks or something. And like that's just something like for me is like how could you not want to think that these two go together. Like they totally go together.
Yeah, one of my big advice big pieces of advice that I'd give for someone learning how to program is, it's okay to look stupid like, it's okay not to know what you're doing. Like it's, it's funny one of my big things going into like, learning how to program was I had pride issues, where I was like I don't want to look dumb, I don't want to ask for help. And asking for help like, whether it's, you know, Googling it like Googling is my best friend when it comes to things that I don't know or you know, even just asking someone next to me. Like hey can you look over this code or forums like, there's so many things, so many resources out there that are available. And you know, everyone in constantly learning, that's the thing, is that like. For me like, looking back the people that I was asking now that I know like what year they were when I was asking its like, wow they are where I am now. And they were still learning cause I'm still learning and so just knowing that its like its okay. People you're always going to have someone that's like oh you're new but that's OK you have to start somewhere.