RU beehive logo ITEC dept promo banner
ITEC 120
2008fall
aaray,
ejderrick,
ibarland,
jmdymacek

homeinfolabshwsexams
textbookjava.lang docsjava.util docsarchive

lect08b
Introducing `while`

Review &&, ||, !, and booleans as values

You can pass in and return booleans from methods. (A method which returns a boolean is called a “predicate”.)

You can connect two booleans with && (“and”) and || (“or”). && looks at the boolean expressions on each side, and the entire && will evaluate to true if (and only if) the left side and the right side evaluate to true:

expr1 expr2 (expr1&&expr2)
false false false
false true false
true false false
true true true
(expr1 and expr2 can be any other boolean expression—including more-deeply-nested and/or expressions!)
Complementing &&, an entire || expression evaluates to true if (and only if) one side or the other evaluates to true:
expr1 expr2 (expr1||expr2)
false false false
false true true
true false true
true true true
expr !expr
false true
true false
Really, you can think of && as a function with the signature boolean &&( boolean b1, boolean b2 ) (although, like arithmetic1, we write them in infix notation, with the function-name coming inbetween its two inputs, rather than in-front-of-them-with-parentheses).

It's worth a mention that in English, “or” is used in two different ways: The inclusive-or, which is what || means, means “one or the other or both”. For example, if the question on the tax form asks “are you over 18, or had income of more than $20,000”, and you meet both criteria, then the answer is true. (People might use “and/or” to emphasize they include the “and” part.) However, sometimes English uses “or” to mean one or the other but not both. For instance, “You can eat veal, or you can be morally responsible” is implying that one option precludes the other. (You may or may not agree with that presumption, of course.) Similarly, if you are told “Keep dating your me, or hook up with your ex!”, don't presume that the option of both is included in the “or”!

Let's revisit mustRegisterForDraft. The current laws are a bit different from what is shown: only men aged 18-25 must register. Update our function accordingly:

/**
 * @param age The age (in years) of the person in question.  E.g., 18months is age 1.
 * @param ___  _______________________________________________
 * @return whether or not the person must register with Selective Service.
 *   mustRegisterForDraft_v2( 0, ___) == false
 *   mustRegisterForDraft_v2( 0, ___) == false
 *   mustRegisterForDraft_v2(17, ___) == false
 *   mustRegisterForDraft_v2(18, ___) == true
 *   mustRegisterForDraft_v2(22, ___) == true
 *   mustRegisterForDraft_v2(22, ___) == false
 *   mustRegisterForDraft_v2(25, ___) == _______
 *   mustRegisterForDraft_v2(27, ___) == _______
 */
boolean mustRegisterForDraft_v2( int age, ____ ______ ) {
  return _ (age >= 18) __ ________ __ _______ _;
  }

solution

/**
 * @param age The age (in years) of the person in question.  E.g., 18months is age 1.
 * @param isFemale  Is the person in question female?
 * @return whether or not the person must register with Selective Service.
 *   mustRegisterForDraft_v2( 0, true ) == false
 *   mustRegisterForDraft_v2( 0, false) == false
 *   mustRegisterForDraft_v2(17, false) == false
 *   mustRegisterForDraft_v2(18, false) == true
 *   mustRegisterForDraft_v2(22, false) == true
 *   mustRegisterForDraft_v2(22, true ) == false
 *   mustRegisterForDraft_v2(25, false) == true
 *   mustRegisterForDraft_v2(27, false) == false
 */
boolean mustRegisterForDraft_v2( int age, boolean isFemale ) {
  return ( (age >= 18) && (age <= 25) && !isFemale );
  }
By the way, now we see more clearly, the advantage of making this its own function -- we don't have to update the rules in several places. In fact, we'll need to update our function further, to account for whether the person is a U.S. citizen, or an alien living in the U.S. In fact, ultimately your code should be a direct translation of the actual regulations, which can be fairly detailed.

Practice

Various javabat.com problems, such as:

homeinfolabshwsexams
textbookjava.lang docsjava.util docsarchive


Introducing `while`

Suppose we have a RoachPopulation. Most people don't notice a RoachPopulation until it grows to 1000 — then they start to do something about it. Let's think about writing a method which repeatedly grows a population until it's 1000 or bigger:

class RoachPopulation {
  // ... other methods and fields ...


  void growTilBig() {
     if (this.getPopulation() <= 1000) {
       this.breed();
       }
     if (this.getPopulation() <= 1000) {
       this.breed();
       }
     if (this.getPopulation() <= 1000) {
       this.breed();
       }
     if (this.getPopulation() <= 1000) {
       this.breed();
       }
     if (this.getPopulation() <= 1000) {
       this.breed();
       }
     if (this.getPopulation() <= 1000) {
       this.breed();
       }
     }
Hmm, this only works if six or fewer generations will bring us there. What if it takes longer? (What else should we fix about this code, btw?)

If we want to keep doing something over and over and over, rather than cut-and-paste, we can use a while loop:

  public static final INFESTATION_THRESHOLD = 1000;

  void growTilBig() {
     while (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       }
     }
We say that this.getPopulation() <= INFESTATION_THRESHOLD is the condition, and this.breed(); is the body.

Variant: we want to know how many generations it takes to reach an infestation level?
Solution: First, think about how you'd (try to) do this without a loop:

  int generationsTilBig() {
     int numGens = 0;
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     if (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     return numGens;
     }
This gives us the idea of how our while loop should look:
  int generationsTilBig() {
     int numGens = 0;
     while (this.getPopulation() <= INFESTATION_THRESHOLD) {
       this.breed();
       numGens = numGens + 1;
       }
     return numGens;
     }
We call numGens a “accumulator variable”, because it accumulates information as we continue processing. (More precisely: it captures all the information2 we need to remember about past processing.)
tip: When writing a loop, first figure out the body — that is, what action do you want to do, over and over and over?
tip: When writing the condition for a loop, explain to yourself why you are sure this loop will eventually finish. Hey — now that I think about it, these above loops aren't guaranteed to finish; sometimes they might run forever: an infinite loop. When, exactly, does that happen? How to fix it? (Or should it even be fixed, in this case?)
tip (BlueJ): You recognize an infinite loop by the fact that your IDE stops responding. In BlueJ, you'll see the progress bar (underneath the compile button) churning away like a red and white barber pole (see image on left). You can halt your program by right-clicking on that progress bar (see image on right):


Practice: I want a method for BankAccounts which keeps making a $5 deposit until the balance is more than $500. (Not bad!)
Question: are you sure this loop will always finish?


1Just like we think of + and * as functions which take in two numbers, and return a number.      

2 To be really technical: information from “past processing” also involves the mutation to the population field. In fact, this method is arguably poor style, since it both returns a value and updates the state of the RoachPopulation object.      

homeinfolabshwsexams
textbookjava.lang docsjava.util docsarchive


©2008, Ian Barland, Radford University
Last modified 2008.Oct.22 (Wed)
Please mail any suggestions
(incl. typos, broken links)
to iba�rlandrad�ford.edu
Powered by PLT Scheme