![]() | Monkeys at Keyboards: APE Antics © Michael James Heron and Pauline Belford | ||||
| Topic: Java Programming Level: 1 Version: alpha | |||||
8 - While You Were Sleeping | |||||
| Previous | Table of Contents | Next |
| Forum |
| Chapter Objectives |
By the end of this chapter, the reader will be able to: |
In Chapter 5 we looked at the first of the repetition structures, known as for loops. For loops enable us to get Java to do the hard work for us, and repeat code as many times as we need it repeated. In short, they take the work away from us, and put int onto Java - something of which we should always be proud. For loops are known as bounded loops because we always know how many times they are going to run (and they run within the bounds of the numbers we have for them). Consider a simple for loop:
With this loop, no matter how many times we run the program, that loop will always execute 20 times, and we can tell this in advance. However, for loops don't cover all the situations we might need loops for. There are many situations where we would like code to be repeated, but we don't know how many times to repeat it until the program is running. We aren't able to use for loops in this situation, and so we need to look elsewhere to satiate our desires. For example, suppose a user is trying to log on to a computer network using the network password. Being generous individuals, you realise that people who get the password wrong are not always trying to break into a network to which they should not have access, but may simply be forgetful or bad at typing. With this in mind, you want the user to be prompted to enter their username and password until they get their password correct. We couldn't do this using a for loop, as we don't know how many times the user will get the password wrong. If we used a for loop and asked it to repeat 4 times, say, then the user will need to enter the password 4 times, which would be very annoying for them if they got it right first time. (You can break out of for loops, but it is almost always bad practice, so we'll ignore that dirty little secret just now...) If we use a while loop, however, we don't have this problem of pointless repetition. With a while loop, the code inside the while loop will only execute until the condition is no longer met. This means that the code might never have to execute, or it may mean that the code many, many times.
The basic structure of a while loop is as follows:.
The condition is the criteria you want to asess before executing the code within the while loop. This is just the same kind of thing as with an if statement - in fact, the syntax is identical. To take a simple example, if you wanted a while loop to execute, with code that continued to multiply x by 2 if x was less than or equal to 50, and to output the current value of x to the console window, then you would write the code as follows:
Note that x has been initialised to 2. If you forget to initialise x, then by default Java initialises integer variables to 0. The would result in an infinite loop as x will always remain as 0 because any number multiplied by 0 is 0. Infinite loops are to be avoided as they will prevent your program from getting past that section of code. So what will happen with this While loop?
We can check if something is equal to, greater than, or less than a numerical variable in our condition. Check out chapter seven for a fuller discussion on this, We can also check if a String is equal to or not equal to another String, but this needs to be done in a different way because Strings are more complicated variables than simple numbers.
String variables are slightly different to, and more complex than, our numerical variable types. We will look at this in a lot more detail in the chapter on Strings, but for the moment we just want to look at how to compare the values of two Strings. To go back to the password example, we are looking to keep checking the value that the user has entered until it is the same as the password we are expecting. We will use the APE Pacman tool for this example, as it provides an easy method of obtaining input from the user. We can build it into the program as a whole - let's say we wanted to password protect the running of certain programs. We could use the structure we discuss here. What we need is a while loop which continues to prompt the user to enter their password until the password they enter is correct. Rather than using the equivalence operator (==) to compare two Strings, we need to use something different. Strings have a comparison method which enables us to check is one String is the same as another. This takes the form of:
This checks if both strings match. If they do, the method returns true. If they don't, it returns false. When we talk about strings being 'matched', what we mean is that they both contain the same number of letters, and they contain exactly the same letters, in exactly the same order. The casing (upper or lower case) is important in this particular example, but there are other comparison methods provided by the string class that don't bother about capitalization. We will discuss these in due course. So our program to check the password would be something like this.
Suppose you are a little bit thick in the head, and have forgotten your password. You know it's one of three possibilities, but you can't remember whether you chose the word 'pirates', or 'wizards', or 'monkeys'. A nightmare situation to be sure, but you put on a brave face and decide to try them out in that order. This program uses two variables internally. correctPassword is used to store the correct password (the one that will permit access to the juicy functionality that lies beyond the while loop), and userPassword is used to hold the string entered by the user. This is initialised to an empty string "" before we try doing any comparisons. Our while condition checks that the password the user has entered is not equal to the correct password.
If the condition is never violated (as in, the user never types in the correct password), they will be stuck inside our while loop forever, caught within our cunning web. And we, as guardians of the true passwords, can laugh from our fortified sanctury as our foes battle fruitlessly with our iron-clad pacman security.
As with if statements, While loops can have more than one condition. We could for instance have a program which checked both the users username and password. We could do this using two while loops, like so:
However, we could make our program more compact and efficient by having just one while loop, which will continue to loop whilst either the username or password entered is incorrect.
The more compact and neat the code, the easier it is to make changes in the future. Within a while condition, we can link together various conditionals as compound as discussed in chapter seven.
With While loops, the condition is checked before the code within the loop is executed. This means that the code within the while loop will never execute if the condition is not met. There is a second, related, structure called the do - while loop. With a do - while loop, the condition for repetition of the loop is put at the end of the loop. This means that the code within the do-while loop executes at least once. Other than this small distinction, they are functionally identical. There can be situations where we would rather check the condition at the end of the loop rather than at the start of the loop, but the while loop is far more frequently used. Our program to check usernames and passwords needs the loop to be executed at least once - as we need the user to enter these details at least once. If they get them correct first time then the loop does not need to repeat. so we could rewrite this program to use a do-while loop. The loop would then become:
Note that the while condition comes after the closing bracket for the do - while loop. The loop executes fully, and then the condition is checked. Note also that the condition statement needs a semi-colon at the end of the line as it is not followed by an opening or closing brace.
As our programs become more complex, we can see that we could write several different programs to do the same thing. for example, to make pacman do three clockwise tours of the map we can
Another thing about programming concerns how general the solution may be. The question for the code you are writing should always be 'would the same code work for a different but similar map?'. Obviously sometimes the answer will have to be 'no', but if you are faced with two maps that have roughly the same problem to be solved, the code for one should ideally be transferable to the other. When working as a programmer, you will find that though the programs you write are different, many have some similarities and there are certain things that will be included in many programs. If you can write code which is less specific and can be used in more situations, then you will have to do far less re-inventing of the wheel, and can spend more time relaxing with your feet up. Let us look at a few different ways we could write a program to solve the follow_the_yellow_brick_road map. The map has a trail of dots which spiral in an anti-clockwise direction towards the centre of the map.
How could we get Pacman to follow the trail of dots until he gets to the centre of the map? Our first option is sequential statements. We could start with with a call for pacman to turn right, followed by nineteen invocations of the move method... but no-one in their right mind would choose this as the sensible option! Such ideas lead to anger, and anger leads to fear, and fear leads to the dark side of programming. Another option would be to use for loops. We still need to turn Pacman to the right, but then we can count the number of dots and use for loops for each line of dots. Note that we can still use one nested loop (to get to the top left hand corner of the map), but we mainly need to use single for loops after this as the length of the lines is not uniform - they get shorter as you move in. The code for this is fairly unwieldy:
As you can see, this gets tedious and long-winded. The solution is also specific to this particular map. If we were to try to use it in another map, with a different route, then pacman would not be able to solve it. He would follow this path determinedly and wander off the path to meet a terrible fate. His downfall would be our fault, and we would have to live with the guilt - a weighty burden indeed. If we use while loops, we can make the solution more transferable to other maps. Using while loops we can write a solution which would solve all continuous paths (i.e. without side branches or breaks in the dots). How great would that be!? No matter what path we give him we can be confident he will find his way, without us having to type another word of code! So, how can we achieve this miraculous feat? The strategy is simply this:
We could do this using separate while loops for each length of path, much as we did with the for loops. But that would not be as generalisable- it would only work for a map with this number of bends in the road or less. What we need is to wrap our basic strategy in a loop. We can use a while (true) loop which will loop forever. these are often a bad idea, but as there is nothing to tell us we have reached the end of the path, this is what we will do on this occasion.
And that's all there is to it. The outer while loop ensures pacman keeps moving no matter how long the path is. the first of the inner while loops carries out the first part of our strategy. Pacman checks to see if there is a dot ahead. If there is no dot ahead, he turns right. this process continues until he sees a dot ahead, at which point we break out of that while loop and move onto the second of the inner while loops. This loop checks to see if there is a dot ahead, and whilst there is, pacman continues to move forward, one step at a time, until there is no longer a dot in front of him. the while true outer loop then brings us back to the start of the inner while loop and he starts turning around looking for a dot again. The beauty of this solution is that it will work on other maps as is. Try it in the "bimble" map, for example, and see what happens.
So, that's all we need to know about while loops for now. Unlike for loops, these are unbounded loops and we do not know at the outset of the program how many times our while loops will execute. they will keep looping until the while condition is no longer met. While loops do not have a built-in counter, so if you want to keep track of how many times they have executed you will have to create your own counter variable, and increment it within the loop. Once you are able to use these then you will have yet another technique in your growing programming toolkit to help you write better and more complex programs. Further ReadingThe following table details further reading on the topic in this chapter, and also any external resources that you may find useful.
|
| Previous | Table of Contents | Next |
© 2004-2006 Michael James Heron and Pauline Belford