>> Welcome back. It's great to see you again. >> Welcome back. It's great to see you again. >> Today we'll be talking about repetition. >> Today we'll be talking about repetition. >> Many programs do the same types of actions over and over again. For example, if you're working with a big piece of data, your program will repeatedly read and process each piece of the input. >> I really like to write programs that do this. >> Because it means that I don't have to do the same thing over and over. The computer does it for me. Let's get started learning how to do this. >> Let's get started learning how to do this.
Hello and welcome to Lesson 6. We're going to talk about loops. But more importantly, you're going to learn something that you probably want to know. Namely, how you can become a millionaire, even though if you think about it right now, interest rates. Rates are very low. Get a measly 1% on your bank account. And I don't know about you, but I don't have a lot of money right now. All I have to invest is $100. But, I have a plan. Here's my plan. I'm going to set my time machine to that specific point when my bank account has a million dollars in it. Or maybe if I can't find my time machine, I'll just let myself be chronologically frozen and tell them to wake me up at that moment. All I need to know now is to which date in the future to set my time machine. So, that's what we're going to be writing a program for and that program's going to be using loops. Because it has to keep on adding that interest to the bank account until it reaches $1 million. How long do you think it's going to take?
Alright, did you think about it? It probably won't take a million years. It probably won't take a hundred years, and I'n not even going to try and figure it out. Instead, we're going to write a program that figures it out for us.
Here's the start of our program. I've setup a few variables. Note the initial balance of $100. My target of a million dollars. The interest rate of 1%, and right now we're in year zero. In Java, you use the while loop to repeat statement. And that's exactly what we need. We want to repeat the statements that add the interest. Here, we compute the interest. Here we add the interest to the balance. Each time we do that, we also want to increment the year because after all, we want to keep track of how many years this process takes. And finally, we want to print out. Just so that we have a running total of the current year and the current balance which is what you see here. How long do we want to do this? We want to do it while the balance is less than the target, the balance starts out at a $100 gets larger and larger. Eventually, it'll exceed the target and then the loop will stop. Now, let's run this program and here it runs. Look at this, after 926 years, we've reached a million dollars. That's actually not so bad. So, I have to wait less than a millenium to become a millionaire. You can do the same thing.
Here we have the code that calculates how long it will take $100 to grow to $1 million. How many years would it take to grow to $1 billion, instead? Modify the program and run it.
Previously, the condition was to keep running this loop, and keep counting until we hit $1 million. But now, we want to keep counting the years until we hit $1 billion. So we change the loop condition to go up to 1 billion. Now if I run this, I find out that it'll take about 1600 years for my $100 to grow to grow to a billion.
I'm feeling a little impatient. I don't think that I can wait, a thousand years, for my money to mature to a million dollars. What if the invention of self driving cars, changes the economy so completely, that interest rates go up to 10%. How long would it take to get to 1 billion then, starting with 100? Start with the same code that you started with last time, and modify the program, this time, so that, you change the interest rate.
The rate is included in this line, where we calculate the interest. The interest calculation has to happen inside the loop. Because the balance is incremented by a different amount every year. If we moved this line out of the loop, it would only happen once. And our interest would always be $10. Even when we already have 100,000 in the bank. So I'll put that back. There is some magic numbers still in this code. Maybe these should actually be named variables. So I could take this, and make this into the target. And I can take out the rate, and call it a rate. Now this code is much more readable. We can see that it goes well the balance is less than the target, and the interest increments by the balance plus the rate.
Here's another example of a loop. I haven't figured out what it does yet. What is the last value that this loop prints?
The last value printed by this loop is 2,000. This is a little bit weird, because the loop's condition says that it only runs as long as n is less than values of n, and what gets output. I start by setting n to two. And then I check, n is less than 1,000, which is true. Two is less than 1,000. So I set n to be 10 times 2. And then I print out n. So I print out 20. Now, I'm at the end of the curly braces. So I go back up to the top of the loop and check the condition again. N is 20 now, which is still less than 1000. So I'm going to repeat the steps inside the loop again. I'l set n to 10 times 20. So I get 200. And then I print out 200. I get to the curly brace, so I go back up to the top of the loop again. 200 is less than 1,000, so we'll repeat the loop again. I'll set n to 10 times 200 over 2,000, and then print 2,000. And now I'm at the bottom of the loop, so I come back up and check the ignition. 2000 is less 1000 is no longer true. So I'm going to skip to the bottom and be done. It looks like the last thing that was printed was 2000. And we managed to print a larger value of n than 1000 because the print statement comes after we update the loop variable. It matters when we update the n inside the body of the loop.
You've just worked with Sarah to write and understand several loops, and what will often happen to you that you have a loop that's really mysterious. And I'll give you an example. Here's some code that comes from a program that you will improve in a bit to solve a common problem, namely to identify reverse digits in a credit card. So let's see what this code does. What you always want to do is get out a sheet of paper. Here's my sheet of paper. You make a table. One column for every variable. There's a variable n, there's a variable sum. Now, it's always a good idea to take a marker, I like to use a paper clip to mark where we are. So, we set n to 365 and we set the sum to 0. Now, we enter the loop. Is n greater than 0? It sure is. We get to this statement. Now, we need to compute n modulo 10. That's the last digit of n. That would be 5. and now we have a new variable! We record it, we put in the 5. Moving on, sum is sum plus digit, n is n divided by 10, it's an integer division so we discard the remainder. We move to the top of the loop. Is n greater than 0? Compute n MOD 10, 36 MOD 10 is 6, store that in the digit. Sum is sum plus digit. It is than 0? It barely is, so we stay in the loop. Now, we need to take 3 MOD 10. That's 3. Add it to the sum. Divide n by 10, that's an integer division, so now we get 0. 0 is no longer greater than 0. We fall out of the loop, and go to this statement. And what are we printing? You're printing 14. Okay, well, what's 14? Well, we've computed all of the digits of the number 365, 3, the 6, the 5, and we've computed their sum. 14 is the sum of the digits. And that's almost what one needs to do in order to verify a credit card. You'll see in your next programming assignment what sum of digits you exactly need to do.
If you've ever bought something online, you know how annoying it is to enter all those numbers on a credit card. It's pretty easy to mess up one or two. It's even more annoying for the people trying to charge the credit card so they can sell you things. Luckily, the designers of credit cards back in the day thought about this. All credit card numbers have to follow a kind of pattern, and there's an algorithm that uses the pattern to figure out if the customer has accidentally switched 2 numbers in their credit card. The algorithm has a similar structure for the code for calculating the sum of digits. It starts with the sum of zero, and a count of zero. And then for each digit, starting from the right, we increment the count, and if the count is odd, we add the digit to the sum. Else, if the count is not odd, and the digit is less than 5, we add twice the digit to the sum. Else, if count is even and the digit is greater than 5, we add twice the digit to the sum and subtract 9. And then, after all of that, if the last digit of the sum is 0, the card number is valid. How would you write java code for this algorithm? We'll give you the code for so many digits so you can adapt it, and also, you have this credit card number that you can use to test. And here's a hint: credit card numbers are too big to fit in an int. This problem is tricky, there are a lot of ways to write code which almost works, but not quite. It will be very important to use a tester program. Also, you can write print line statements to get an idea of what's happening while your code is running.
To do this, I first want to look at the structure of credit card and see what I'm given already. I'm implementing a method, is valid, which returns a Boolean. Is valid calculates whether the credit card has a valid number. And returns true if the number's valid and false if it's not. So now I know how to write my test program. I need to create two credit cards. I'll create a valid card. And I have to mark that this is a long, by writing the L at the end. And I switched two digits to get the invalid card. Now I print out the actual value of isValid when called on the valid card, and I expect the valid card to be valid. The actual for the invalid card should be false. Now, it would be easy to test whether our implementation works. In the credit card class we can see that the first part of the pseudocode setting sum to 0 and count to 0, is the same as the code that had before for computing the sum of digits. So I'll keep that the same. The for each digit starting from the right part is the same. So I'll try to keep the code for counting the iterations in place. But now, instead of just adding the digit to the sum, I need to check whether the count is even or odd and how big the digit is, and use that to decide what to do with the sum. So, if the count mod 2 is 1, we add the digit to the sum. Else, if the digit is less than 5. We add twice the digit to the sum. Otherwise, we add twice the digit to the sum and subtract nine. And now, instead of just printing the sum the way we did before, we need to check whether the card number is valid. If the last digit of the sum is zero, the card number is valid. Some mod otherwise. So we return that. For example, if the sum were 24, we would check sum mod 10 would be 4 which is not 0. So, returning this result would return false. If sum were 20, then we would check sum mod 10 is 0. So this would be true, so we would return true, but we can't be sure that this works until we test it. Let's compile and run the tester, huh. One of our tests failed. It's saying that the invalid card is valid. We're going to need more information if we want to debug this. What if I print each digit of the number? So if we run the credit card tester. That's funny. It printed exactly the same thing. My print line statement must not have run. For this statement not to run, we would have to never go into the loop. What's n? If I run it again, I find that n is this weird negative number. That looks a little bit like the result of an integer overflow. Clearly, n can't be an int anymore. Now, if I try to compile. I get a possible loss of precision. So if I want an int digit, I'm going to have to cast this somehow. What if I try casting n mod 10 this way? Looks like I didn't remove the cast that was causing trouble. Now, it looks like it's starting with the correct n. And then taking off one digit at a time correctly. But it's still getting the wrong answer for the valid card. I'll delete this, now that I have that part working. And I think I actually want to print out the digit itself, rather than n. And then I want to get some idea of what I do with each digit. So I'll print the digit. And then, on the same line. I'll print, add it to the sum, add twice the digit to the sum, or add twice the digit and subtract 9. Now, if I run the tester again, I should get much better information. It looks like the first digit is minus 9, but none of the digits should be negative. It looks like this cast didn't work properly. Maybe it's casting n before it takes the mod 10, instead of casting the result of the n mod 10. Let's see if these parentheses fix it. Now, if I run the main method again, you can see I'm still not getting what I expected. But I have some good data here. For 3, I add twice the digit to the sum, 1, I add twice the digit to the sum. And so on. Let's compare that with the example on the web page. In the example, the three shouldn't get doubled. The one should though. The next one shouldn't. The 9 should. In fact, it looks like we're adding twice the digit, way too often here. It's seems like count mod 2, never equals 1. So let's check what count is. With System.out.println("count:" + count). Now the main method says count is always 0. I know how to fix that. I'll increment count. Now, for the validCard I'm getting true when I expected true. And for the invalid card, I'm getting false when I expected false. I have just a tiny bit of cleanup left to do. To remove all of these extra system out print lines, that I added. I removed all of the print statements, in the credit card class. And now when I run the test, the output is much cleaner.
So I want to give you a few tips on how you can deal with, errors that, might creep into your code. And here's a typical example. Have a look at the code on the left. It does something wrong. See if you can figure it out, just by looking at it. Well truth be told, I couldn't either when I saw it the first time. So lets run it and see, how it behaves. Whoa, look at that, the numbers are getting bigger and bigger. That's the bank account I want. But that's not the program that I wanted. I wanted it to stop. When I've reached a million dollars. It's gone way beyond that. This is getting crazy. I've been waiting here for a long time, and the program just is not stopping. So the first question is, how can I make it stop without buying a new computer? So let me show you that first. You see that little barber pole icon here? What you do is you right click on it, and then you select the one and only menu option to reset the virtual machine. And now the program has been killed, and we can figure out what went wrong.
So, first, I have some terminology. This is called an infinite loop, and it's pretty clear why. The loop just keeps on going forever. Let's see what happened. We compute the interest. And actually, that's the same computation that we had before. It's perfectly normal. We increment the year. We print out the result. And you've seen this happening over and over. So the problem must have been with the condition here. Hm. We wanted to keep one going, while the balance didn't reach the million dollars. It clearly overshot the million dollars, so the problem must lie in here and why don't you give it a try to fix it.
The problem is that we don't want to stop when the balance is exactly equal to the target. We want to stop as soon as the balance hits the target. So if the balance is less than the target, we keep growing. And if the balance equals the target or is more, we stop.
Here's another error that many people make. Remember what our goal was? Our goal was that our balance should be bigger than the target. So lots of people, when they write their while loop, they put that goal, which they have firmly in their mind, into the header of the loop. But that's not how the while loop works. The while loop says I want to stay in the loop while the condition is fulfilled, and that's exactly the opposite of the goal. That's a common confusion. I'll let you fix it in just a minute, but here's how I remember it. Look at the board, little girl there. And she's warning, are we there yet? Have I reached my goal, namely to be at the destination? And while loops are not like little girls, they're the exact opposite. They're excited to be going and going and going, so you want to formulate your goal while there's still work to be done, we can do it. You'll get a chance to fix this bug right now.
Let's trace the buggy code that chi showed us and see how it behaves. Here's the code to compute how many years it will take a balance to grow to a target, but it's not working. Trace the year, output and balance.
We initially set, balance to 100, and target to 200. But target won't change, so I wont write that down over here. Rate also wont change. The year, starts at is 200. 100 is not greater than or equal to 200. So we don't go into the body of the loop. We skip down to the bottom. We never output anything. What would you say the bug in this code is? How would you fix it? I won't go over this, but if you're not sure, maybe try it out in BlueJ.
I wrote some broken pseudocode too. It sets temp to n and then while temp is greater than 10, increments count which was originally set to 1 and then divides temp by 10. It was meant to count the number of digits in the number n but it's not doing it. Help me debug this by hand-tracing. If n is 123, what value does count end up with? What if n is 100? What should this loop condition be to get the right answer in all cases?
If n is 123, count will end up as 3, which would be correct. There are three digits. If n is 100, count will end up as 2, which is not the correct number of digits. The loop condition should actually be. While temp is greater than or equal to 10. We can see this by hand tracing the code. The values I'm interested in are count and temp. If n starts out as 123, then count will start as 1, temp will start as 123. Temp is greater than 10, so we increment count. And divide temp by 10 and divide temp by 10.0 which will give us 12.3. Now, we go back to the loop condition. Temp is still greater then 10 so we increment the count and then divide temp by 10.0 again so we have 1.23. Now, when we check again, temp is less than 10. So we skip to the end, and we're done. But what would happen if n was 100? Count would start as 1, the way it did before. And temp would start as 100. Temp is greater than 10, so we would increment count and then divide temp by 10.0. So we would have 10. And then check the condition again. But this time, 10 is not greater than 10. It's equal, so it skips out immediately. When in fact, we still had two digits left. We needed to increment count again. This is why the condition should be temp is greater than or equal to 10.
I wrote a loop with an error. Here it is. Can you fix this code so that it will print out the balance every year for ten years? If you want to run this in debugging, I highly recommend that you use BlueJ. The Udacity IDE won't be able to give you all the feedback that you need.
The year never changed, but year is how we're controlling the loop. So we needed to remember to increment year by 1. Inside the body of the loop. Now if I run this again, the output is much more manageable. It's pretty easy to make this kind of mistake. Where you forget to update the loop counter variable. We're going to show you a way to write a loop that is good for cases like this one, when you know exactly how many times you want to repeat something.
Now you've gotten pretty good at working with simple loops and it's time to introduce another loop type. It often happens that you need to work with consecutive numbers 1, 2, 3, 4, 5, 6. I'll just give you an example. Let's say you want to write a to-do list. Maybe your and my to-do list is really complex. So we'll start with something really simple. My cat, Eliza Doolittle. Her to-do list is stunningly simple, and you can program it. The first thing she does is sleep. That's the second thing she does. And the third, and you guessed it. Sleeping is what she does all day. Your task is to write a program using a while loop that prints this to do list.
You've just wrote a program that prints out Eliza's to do this, and it probably looks somewhat like this. A counter starts at 1, it goes up to 6, we do some work, we increment the counter, keep on doing, until the counter. Has reached its end. There's nothing wrong with it. But if you think about it, the three statements that control the counter. The initialization, the check, and the update. They're spread all over the loop. The full loop is there, to organize it a bit more neatly. Here is the basic outline of the full loop. It has three slots. And, we fill in the right statements, in each one of them. And I'll demonstrate that. In this low tech way. We'll cut out the initialization, the condition, and the update, and we'll put them in the right slot. Initialization goes here. The condition goes here. And the update goes here. Now, you see, they're all neatly together in the hetero of the four loop. Let's have a quick look at the control flow. We start with the initialization. Then we check the condition. We go into the inside of the loop. Then we do the update. Now, the counter is 2. We check the condition. We go into the inside of the loop. We do the update. Now, the counter is 3. We check the condition. We go inside the loop. We do with the update, we check the condition, we go and set the loop. Do with the update, check the condition, go inside the loop, through the update. And eventually, the condition is false, and we leave the loop. Notice that the initialization happens once, the check happens before entering the loop, and the update happens after finishing an iteration of the loop.
Actually, Eliza's To-do List Looks Like This. How would you adapt your for loop to print Eat only on the odd numbered items and sleep on the even numbered items?
The answer is, inside the for loop. Around this line, I need to check, whether I'm on an even or an odd count, before I decide what to print. If the counter mod two is one, then I'm on an odd number. On odd numbers, I want to print out, the counter, and eat. Otherwise, on the even numbers I want to print out sleep. Lets' see how this works. Looks like I missed the quotation mark. I get what we wanted. Here I could have just said if counter is 1 or 3 or 5. Like this. And this would still work, as long as I only print six numbers. But if I wanted to print 12 items, Eliza's list wouldn't have eat after the sixth item.
You've now seen two loops, the while loop and the for loop. And now, you have choices and which loop to take, and choices aren't always easy. So, let's look at a typical problem. Let's say we have $10,000, and we get 10% interest. And we want to know what happens to our nest egg over a period of 30 years. Which loop should we take? Now, in this case, what's going to drive our decision is the fact that we know we want to do something 30 times. And when you know how often you want to do it, then the for loop is what you want to choose. Over here, I've modified our program to do this. Here you see now I've changed the balance to 10,000. I've changed the interest rate to 10%. And I have now that I want 30 years. And then, I just write my loop here, where the year goes from one to the numberOfYears, gets incremented every time. And inside here, you have the familiar computation of the interest. So, notice that in this loop, I know exactly how many times the loop is going to execute, namely, this many times, 30 times. Let me run the program. Here you see the output. You see the interest, and starting at 1, scrolled off at the top, and it went 30 times. That's the classic case for the for loop. Contrast that with, the example of, the first program that we had, where we wanted to become a millionaire. At that point, we used a while loop, because we did not know how many years it was going to take for us to achieve our lofty goal. When you don't know how many iterations you want, the while loop tends to be the better choice. So, that simply is your criterion for decision. Do you know how many times the loop runs? You usually choose a for loop. If you don't know, you usually choose a while loop.
So far, all of our for loops have counted up. But what if we're really excited for a vacation, and we want to print out a countdown. The countdown would print out something like this. How would you change this loop to count down instead of up? Try it yourself, and if you get stuck, I'll show you.
We need to change where the counter variable starts. Because now we want it to start at 20. We want to stop if the counter is less than zero, so we'll need to change the direction of the sign. And we want the variable i to go down every time instead of up, so we replace plus plus with minus minus. Now, for the finishing touches. And if I run the program, it goes like this. Those days counted down a little fast, but that's okay for now. But that's okay. Now you now how to count down.
The full loop is really useful to take words apart into the individual characters. For example, when we have a word like this, we might want to look at one character at a time. And what we're going to do in our sample program, is count how many vowels this word has. Now, why does anyone care how many vowels a word has? When you know how many vowels there are that gives you an issue, an idea of how complicated the word is. And sometimes you actually have to adjust your writing to be simpler. And then it's good to know that so just. So, how do we do such a a thing. We need to, find, out, each of the characters. And then, look at it more closely. Over here, you see how to look at the i'th character. You take the substring, that goes from position i. Up to, but not including position i plus 1. And that is a string containing a single character. And we'll let I vary from 0 to the last valid index. That would be the length minus 1. Notice that I starts at 0. It is less than the length that makes means it goes up to the length minus 1 and if gets incremented by 1 every time. This loop that you see here with this fore header and extracting the ice letter that's what you use every time that you want to break a word into its individual characters. Now, onto our specific problem we want to count vowels. The condition that you see here checks whether the letter is a vowel. it looks a little backwards. We list all of the vowels, and we ask where the, the letter is any one of those. If we have a vowel. We increment a counter. The rest of the program is simple. We print the result and also we need to declare a few variables. Let's run the program. We're supposed to type in a word and we learn that mouse has three vowels which doesn't surprise us. Actually is the bonus fact of the day. Some words have more vowels than you think. Here's the French word for bird, oiseau, and it has five vowels out of six letters. Which is hard to imitate in English.
I keep wanting to post things on Twitter. But the character limit is so small, I can't say what I want to say. Help me write a method to shorten my Twitter posts by only printing the consonants. So how did I ever program without loops, would come out like this. You should put your code in the shortened method of the Twitterizer class.
I already have a tester. So I'll just start filling in the implementation. I want to go through the longPost, each letter of it. And copy the consonants into another shorter post. So I'll start out with a string shortPost. And I'll go one letter at a time. I can't use the increment to skip the vowels. Because I don't know which ones are vowels until I check. Inside the loop, I'll need to check if the ith letter is a vowel or not, and if it's not, I'll add it to shortPost. We've written conditions to look for things that are not vowels before. This is a different way of doing it. Instead of using if it's a or e or i, I made a string that contains all vowels, and then I asked that string If it contains the letter I'm looking at. If this string contains the letter I'm looking at, the letter's a vowel. So, if it does not contain the letter I'm looking for, then it's a consonant. In which case, I'll add it to short post. There's one more important thing that I need to do. I need to actually return the string. Let's see if it works. Here's our actual, and it's exactly like the expected.
What if I decide I only want my close friends to understand my Twitter posts? And I decide to write them all backwards, and only tell my friends. How would you write a method that reverses your Twitter posts?
If I look at my Twitterizer Tester, I now have a test for reversing, how did I ever program without loops? Inside the twitterizer class, I have to implement the reverse method. I want to look at every letter in the string post, but I want to start from the end, and work my way backwards. As I did last time, I'll start with an empty string backwards, that I'm going to add letters to, as I see new letters. But this time I'll start I at the last letter in post. And go as long as i is not less than 0. I mean, as long as i, is not less than 0. Decrimenting i by 1 each time. Inside the loop, I want to record every single letter I see into backwards, and then I want to return backwards. When I run the program, it didn't break the first one, and now reverse works, as well.
We've intercepted a secret message, but it's scrambled. You're going to write a for loop that prints every tenth letter, starting at the zeroth one. You'll use it to decode the secret message. This is the project you'll be working with. The decoder tester has the string with the secret messages embedded in it. You'll write code for the decoder class. So that you can use a decoder to decode messages. Here's the Decoder class, and here's the decode method that you want to fill in.
First, let's look at how we're going to use the decode method. It's going to return a string with the decoded message. And it doesn't need any arguments. So, in the decoder tester, we want to print out the result of decoder.decode. The decoder was made with the coded messages string already in it. So we don't need to pass that string in again. Now, back to the decoder itself. We need to write a for loop that reads every 10th letter, starting with the 0th one. Since we're reading a string, we want to go as long as the index is less than the length of the string. EncodedMessage is the string that we're reading. And instead of incrementing by one at a time I'm going to increment i by 10 every time, so that we only see every tenth letter. Inside the loop, the part that I want to repeat is reading the ith letter, and adding it to decoded message. So decoded message will be itself Plus, encodedMessage.substring from i to i plus this works. Looks like there are more secret messages in here. If you're curious what they are, I guess you'll have to try starting at different indices. Let me talk for a moment about a couple of bugs that you might have encountered. If you accidentally wrote less than or equals to, right here like this. You might encounter a string out of bounds exception. When you try to access too high of an index in encodedMessage. A string index out of bounds exception is a runtime error. That particular runtime error is nice, because it stops the program and tells you, you tried to access a value that doesn't exist. Which is much better than silently messing up your program's result. You could correctly, though, a little clumsily write the condition as, i is less than or equal to encodedMessage.length(), minus 1. That would work, but I don't think it's as clean. When you iterate over a string, it's best, to go, as long, as i, is less than, the length.
Now you've done this already, remember? When you changed all of the pixels from an image into the negative. At the time, I gave you the loop structure to do this, and I told you not to look too closely at it. Now, we're ready to reveal this mystery. On your left we're going to start this program. We have a full loop. Because we want to iterate over all of the pixels, we'll find out soon enough how many pixels there are. The structure's very similar to the structure for working with words. Instead of getting the ith character, we get the ith pixel by getting the color at position i. And we can also set it, presumably after having changed it in some way. So here's your basic loop. Get the pixel, process it, and put it back. Now, how many pixels do we have? We can ask the picture, and it's going to tell us the number of pixels. And that is the exact analogue to the length of a string except that you should think of the pixels as being arranged like this. A row of pixels, another row and they all come one after another. When we ask for them. And eventually we reach all the pixels that way. I starts at zero. It goes up to the total pixel count. Is incremented at every step. We get the i pixel. And that way we get all of the pixels in the image. In our particular example. We simply compute the negative of the color, and then we can put it back. Finally, we want to load the picture, show it to the user, and then start processing it. Let's run the code. Here is Eliza, all positive. And here she is, sadly negative. As you've seen, it's just as easy to work with pictures as it is to work with words.
So I have this picture of the queen Mary. Let's slightly dim this picture by turning every 5th pixel black. You saw how to use the pixels method to get the number of pixels. And how to use the set pixel at method to change the color of a pixel. You'll need a for loop. What should your indices be to avoid index out of bound errors?
We want to iterate, over every pixel in the image. The first index, in the pixels, would be 0. And the last one would the be one, less than, the number of pixels. Since I only need to affect, every fifth pixel, I'll increment, i, by 5 at a time. To turn a pixel black. I'll use the setColorAt() method, and give it the number of the pixel I want, and the color to set that pixel to. So now if I run this, I get the same picture, but dimmed a little. If you look really closely, on your own screen, it's hard to seen on the video, you can actually see the little, black dots. There are probably other ways to do this, but I think this is the simplest. For example, you could count up by 1 at a time and then use mod to decide whether to actually color the pixel or not. Alternatively, instead of checking using mod, you could set the color at 5 times i. But then, you would need to change the condition for stopping the loop. I think that would require a little bit more thinking.
While we're working with some images, what does this code do? It rotates the image 180 degrees. It replaces the bottom half of the image with a rotation of the top half. It has no effect or it crashes and throws an exception. This question is hard. We don't expect you to get it right the first time.
The answer is, it replaces the bottom half with the rotation of the top half. This question should have been really hard. You have to think about the order of the numbering of all of the pixels. And imagine everything that happens in the right order. You haven't seen a problem like this before. If these were all the pixels of the image. This one would be 0. This would be 1. This would be picked up pixels minus 1. And this would be picked up pixels minus 2. Now, in the first iteration of this loop, we would get color c from the ith pixel, which would be the 0th pixel. Then we would find picked up pixels minus 1 minus i which in this case would be picked up pixels minus 1. Minus zero, so the last pixel, and set its color to the color saved in c. So we just copied the color from here into here. Now, on the next iteration, we'll get the color from one, right here. Find the pixel at pic.pixels minus 1, minus 1, so right here, and copy the color into here. It's starting to look like we're just going to rotate the whole image. But not quite. Imagine that I gets to this second to last spot. We'll get the color at the second to last spot, and then we'll get the pixel at the second spot. And we'll copy the color from the second to last spot back into the second spot. But this is the color the second spot already had. So the first half of the image won't change. Only the second half of the image will.
In this segment I will teach you how to count. And I'll start with a simple problem. Look at the fence over here. This fence has ten of these sections. How many posts does it have?
If we have 10 sections: one, two, three, four, five, six, seven, eight, nine, ten. Let's look at the posts: one, two, three, four, five, six, seven, eight, nine, ten. Now, we have one post before every section, and eleven, there's one after. So the answer was the 11 posts.
Now, onto something entirely different. Have a look at the program on the left, and my question is, how many numbers does it print? Well, let's have a look.
We have a count i that goes from 10 to 20. And, so we print 10, 11, 12, 13, over here there was a less than or equal sign. So we print a total of 11 numbers. It's the same as she has with the fencepost, one more number than one might have expected. This is a common error, and people call it a fencepost error. You don't want those fencepost errors, and here it the way to avoid them.
Let's think about how many numbers this loop prints. First of all, which numbers are printed by this loop and how many of them are there?
This loop will print 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 and 0. There are 11 of them. You could think of this as 10 for 1 through 10, plus a fence post at 0.
When I start at some value a, and then it goes up to b including b, with a less than or equal sign here. Then there are b minus a plus 1 values. That plus 1 is a fence post, plus 1. For example, over here, we start at 10, we go to 20, and we have 20 minus 10 plus 1. That's 11 values. What about the case? When i starts at some point and then it goes less to another point, in that case we have b minus a values. For example, if over here we change the less equal to a less than sign. Then we have 20 minus 10, or 10 values. Namely the values, 10, remind you, the situation where you, you have a less than for the upper bound. Is actually very common and you've seen it several times before. For example, now look at your left. There is the program that looks at all of the letters in a string. And when you look at the bounds you again notice a less than sign here. We go less than and the length of the word. So when we look at our formula over here. In this case, a is 0, and b is word.length. So how many iterations do we have? We have word.length minus 0 iterations. And that makes perfect sense. Because we have one iteration for every letter in the word. And word.length is the number of letters in the word.
Here's another for loop. Make sure to read this carefully. I'm asking how many times is the condition evaluated? Not how many times does the body of the loop run.
This condition is evaluated 4 times. This condition is evaluated 4 times. First it's evaluated when i is 1. Then we add two to i. So it's evaluated again when i is three. And when i is five. And then, one more time, when i is 7. At which point, the condition no longer holds and so it skips the rest of the loop.
Here's another example of a loop. What does this one do? Does it count all non vowels? Does it count all lowercase vowels? Does it count all lowercase and uppercase vowels? Or does it do something else?
The answer is, it counts all of the non-vowels. Result is being used as a counter variable. It starts at zero. And then we look at each letter and word. We get the letter out of the word using substring. And then make a string, which is all of the lower case vowels. We take the letter that we got out of word. And convert it to lowercase. So, A and A both become A. And then we check if this string contains whatever the result of that was. If AEIOU doesnt't contain the lowercase version of the letter, then we increment the result. So result goes up when we see a non-vowel.