280 likes | 614 Vues
LOOPS. “Life is just one damn thing after another.” -- Mark Twain “Life isn’t just one damn thing after another...it’s the same damn thing over and over and over again.” -- Edna St. Vincent Millay. LOOPS. while loops do while loops for loops. Turtle (courtesy of Logo).
E N D
LOOPS “Life is just one damn thing after another.” -- Mark Twain “Life isn’t just one damn thing after another...it’s the same damn thing over and over and over again.” -- Edna St. Vincent Millay
LOOPS • while loops • do while loops • for loops
Turtle (courtesy of Logo) • Before we see loops, we need some tools • Turtle: will draw on the screen for us; based on Seymour Papert’s Logo, a language for beginners* • GeometricPatterns: instructions for turtle • Turtles know where they are and what direction they are facing • Turtles draw lines behind them as they move around screen • Now let’s look at Turtle’s public interface *See his Mindstorms, a provocative book on how kids “learn by doing”, and also the instrumented Legos, Mindstorms. Loops
Turtle’s Public Interface (1 of 2) • We have written Turtle class: public class Turtle extends gfx.Shape { /* some instance variables here */ /* constructor for Turtle takes panel where turtle “lives” as parameter to setup an association */ public Turtle(DrawingPanel panel) { // some code here, including storing panel } /* reset turtle to center of container */ public void home() { // some code here } /* turn right specified number of degrees */ public void right(int degrees) { // some code here } /* turn left specified number of degrees */ public void left(int degrees) { // some code here } // continued... Loops
Turtle’s Public Interface (2 of 2) /* move forward specified distance, drawing line as turtle moves */ public void forward(int distance) { // some code here } /* move backward specified distance, drawing line as turtle moves */ public void back(int distance) { // some code here } /* move turtle to specified position without drawing line */ public void setLocation(java.awt.Point loc) { // some code here } /* returns turtle’s drawing panel */ public DrawingPanel getPanel() { // some code here } } // end of class Turtle Loops
Drawing with Turtle • Need class to tell Turtle how to draw some basic shapes • First, determine what shapes we want • this lecture: square, random walk • next lecture: recursive spiral, tree, fractal • How will we code it? • create GeometricPatterns class which defines methods for drawing each shape • methods control turtle, so it needs a reference to the instance, _turtle • geometric patterns do not contain a Turtle, so use a standard pattern of passing a Turtle reference in the constructor and storing it. • Time for some code! public class GeometricPatterns { private Turtle _turtle; // draws each pattern public GeometricPatterns(Turtle newTurtle){ _turtle = newTurtle; } // methods for each geometric pattern to // follow... } Loops
A Repetitive Solution • Let’s write the drawSquare method in the GeometricPatterns class • Brute force: write line of code for each side public void drawSquare(int sideLen) { _turtle.forward(sideLen); _turtle.right(90); _turtle.forward(sideLen); _turtle.right(90); _turtle.forward(sideLen); _turtle.right(90); _turtle.forward(sideLen); _turtle.right(90); } • What if we wanted to make more general method that handles pentagons or octagons? • need to call forward and right for each side • cannot fix how many sides we need in generic method • There must be an easier way! Loops
Looping • Causes computer to execute section of code repeatedly • uses booleans (true and false) as loop conditions; when boolean is false, the loop condition equals the exit condition and the loop is terminated • as with conditionals, section of code can be single line or many lines enclosed in curly braces • section of code executed is typically called the loop’s body • Three loop structures in Java • while loop • do while loop • for loop • Differ only in relation between body and loop condition • some loops execute body and then test; others test before executing body • Let’s look at while loops first Loops
The while loop • Execute while certain condition is true • tests loop condition before executing body • if loop condition is false first time through, the body is not executed at all while (<loop condition>) { <loop body> } • Examples of loop conditions: • numClasses < 30 • peopleStanding <= maxPeople • this.checkAmount() <= acctBalance • isSquare() // predicate; returns boolean • Multiple conditions can be combined using logical operators (and, or, not) (numClasses >= 3) && (numClasses <=5) (peopleStanding <= maxPeople) || (maxPeople < 50) Loops
A while Flowchart • while loops continue while loop condition is true • Loop condition can be any boolean expression <previous statement> Is <loop condition> TRUE? Yes <loop body> No <rest of program> Loops
Syntax: Random Walk Using While • Method of GeometricPatterns class: • draws random lines while turtle is within its frame public void randomWalk() { DrawingPanel turtlePanel = _turtle.getPanel(); /* while _turtle’s position is inside its frame, move _turtle randomly. */ while (turtlePanel.contains( _turtle.getLocation())) { _turtle.forward ((int)(Math.random()*15)); //cast _turtle.right ((int)(Math.random()*360)); //cast } } • On last step of walk, turtle will end up moving forward out of panel but line will not be drawn • it is clipped by Swing since we don’t explicitly tell it to wrap • no point in continuing to walk outside of the panel Loops
The do while Loop • do while always executes loop body at least once by switching order of test and body • <loop condition> is boolean expression. <previous statement> <loop body> Is <loop condition> TRUE? Yes No <rest of program> Loops
Example: Another Random Walk • Method of GeometricPatterns class: • draws random lines while turtle is within its panel • starts turtle in center of drawing panel, so first step is guaranteed to be within drawing panel public void centeredRandomWalk() { DrawingPanel panel = _turtle.getPanel(); // moves turtle to Frame’s center _turtle.home(); // moves turtle randomly within frame do { _turtle.forward ((int)(Math.random()*15)); _turtle.right ((int)(Math.random()*360)); } while (panel.contains (_turtle.getLocation())); //note semicolon at end of while statement } Loops
do while vs. while • In both loops • stops executing body if loop condition is false • you must make sure loop condition becomes false by some computations lest you “infinite loop” • infinite loop means your loop’s loop condition is such that it will never turn false, i.e., the exit condition never occurs • do while • body always executed at least once • loop condition tested at bottom of loop • while • may not execute at all • loop condition tested before body; loop condition variables must be set before loop entry • useful for screening bad data that might cause statements within loop to fail (e.g., while (ref != null) ) • What is the difference between these two? while(!_stomachIsFull) do { this.eatIceCream(); this.eatIceCream(); } while (!_stomachIsFull); Loops
for Loops • Most specialized loop construct for (<init-expr>; <loop condition>; <update>) { <loop body> } • <init-expr>: expression for setting initial value of loop counter (traditionally use single character identifier; e.g., i); counter aka index • <loop condition>: (true or false) test involving loop counter to determine if loop should execute • <update>: expression that modifies loop counter • <init-expr> is executed at start of loop code, <loop condition> is checked at the start of every loop (including the first), and <update> is run at the end of every <loop body>, just before returning to the top of the loop . • Typically used to execute loop body predetermined number of times • while and do while loops can execute body for undetermined number of times; based on boolean Loops
drawSquare Revisited • Better way of drawing square than explicitly drawing each side: public void drawSquare(int sideLen) { /* start with integer i initialized to 0; execute as long as i < 4; each execution increments i by 1 */ for (int i = 0; i < 4; i++) { _turtle.forward(sideLen); _turtle.right(90); } } Loops
for Flowchart • for loop has four parts • initialize value of counter • test loop condition • loop body • counter update <init-counter> <update counter> Is <loop condition> TRUE? Yes <loop body> No <rest of program> Loops
Choosing the Right Loop • for loop is called definite loop because you can typically predict how many times it will loop. while and do while loops are indefinite loops, as you do not know a priori when they will end. • for loop is typically used for math-related loops like counting finite sums • while loop is good for situations where boolean condition could turn false at any time • do while loop is used in same type of situation as while loop, but when code should execute at least once • When more than one type of loop will solve problem, use the cleanest, simplest one Loops
Syntax: Nested Loops • Loops, much like we saw with if statements, can be nested! • Example: drawFilledSquare public void drawFilledSquare(int sideLen) { // fill in concentric squares for (int i = 0; i < (sideLen / 2); i++) { // drawSquare (slide #16) contains a loop this.drawSquare(sideLen - (2*i)); // position turtle for next iteration _turtle.right(90); _turtle.forward(1); _turtle.left(90); _turtle.forward(1); } } • What does this do? Loops
Turtle starts upright Rotate 90 degrees right Move forward 1 unit Rotate 90 degrees left Move forward 1 unit Nested Loops in English • Turtle is represented by • What is outer loop doing? • first draws concentric square • then the last 4 lines move turtle right and up 1 unit • drawFilledSquare draws square using nested loop Loops
Decrementing Counter • We can count backwards in our loop too • just change counter update expression • in fact, we can update however we want public void countFingers() { /* change counter to decrement, and change the loop condition accordingly */ for (int i = 4; i > 0; i--) hand.hideFinger(i); // hide a finger } • for loops end in one of two ways • when counter value equals limit (for < or >) • when counter value “goes past” limit (for <= or >=) • thus, countFingers() would hide 5 fingers if we used i >= 0 (not a good idea because Grover only has 4 fingers) • Beware of such “off-by-one” errors!!! Four little fingers, Three little fingers, Two... Loops
break • As with switch, break causes immediate exit from a flow-of-control structure (e.g., while, do while, for ) • Example: //we’d like to eat 10 cookies (they’re small!) for (int i = 0; i < 10; i++) { if(_cookieJar.numberOfCookies() == 0 ){ break;// if there are no cookies left, // we should break out of the loop // because we can’t eat any more! } this.eatACookie(); //we know there are some //left } // execution continues here after loop is done // or after break statement • Execution continues with first line of code after the structure • There are other ways to do this loop… Loops
continue • When executed in while, for, do while structure, continue skips remaining statements in body of that structure, and proceeds with next iteration of loop • useful if there is list of data that you are looping over and you want to skip processing of data that is somehow “illegal” • Example: // we’d like to try on shirts that hang on a // rack for (int i = 0; i < 20; i++) { if( !rack.isShirtOnHanger(i) ) { // if there’s no shirt on the current // hanger, skip to the next iteration continue; }// only do this if there’s a shirt on the // hanger Shirt toTry = rack.shirtOnHanger(i); //get // the shirt this.tryOnShirt( toTry ); // try the shirt on } // more code here • In while and do while structure, execution continues by evaluating loop-continuation condition • In for structure, execution continues by incrementing counter and then evaluating loop condition Loops
Boolean Flags • A boolean flag is a boolean variable that denotes a condition (e.g., done, working, available) • set in one place, tested in another • Boolean flags can also be used as the loop condition • Example (implementing a for loop, using while): boolean done = false; int i = 0; while (!done) { i++; if (i == 5) done = true; } • Notice that boolean flag is set within loop • in previous slides all checking was done through delegation, here we do it ourselves Loops
Empty Intervals • What happens if we try to add integers in this loop? public int sum() { int temp_sum = 0; for (int i = 1; i < 1; i++) temp_sum += i; return temp_sum; } • Answer: Body of loop is not executed • Why? • boolean is false for initial value of counter • Correct example: /* This method sums all numbers from 1 up to and including the number specified */ public int sum(int number) { int temp_sum = 0; for (int i = 1; i <= number; i++) temp_sum += i; return temp_sum; } Loops
Off-by-one Errors • Occur when loop executes one too many or one too few times • Example: Add even integers from 2 to number, inclusive ... count = 2; result = 0; while (count < number) { result += count; count += 2; } • Produces incorrect result if number is assigned an even value. Values from 2 to number-2 will be added (i.e., number excluded) • Should be: while (count <= number) { ... } • Now, value of number is included in summation Loops
Syntax: Other Loop Errors • Make sure test variables have proper values before loop is entered ... product = 0; do { product *= 2; } while (product < 100); /* what will happen here? */ • Make sure tests check proper conditions ... for (int i = 1; i != 100; i += 2) { // do something here } /* will we ever get here? */ • ALWAYS HAND SIMULATE first, last, and typical case through a loop to avoid off-by-one or infinite loop errors • the first and last cases of a loop’s execution are called boundary or edge conditions • hand simulation doesn’t just apply to loops, use it for everything! Trust us – it saves debugging time!!! Loops
Which Loop to Use? • You want to bake a pie for each of your twelve friends • Your job is to stand at the end of the bowling alley, and pick up all the pins, one by one, that have been knocked over • Ask a question. Keep asking while the answer is incorrect Loops