CS115 lecture notes, Spring 1999 Week 4, Friday Reading: Chapter 4 Regarding Part Three on the exam... A few weeks ago when we talked about the use of + for String concatenation, you all seemed to think I was crazy for talking about good programming language design and bad programming language design. Having banged your heads on the insidious bug I created, do you see my point? Homework 3 ---------- A note on the homeworks: the lab time is intended to get you started; you have the rest of the week to finish. If you get off to a good start and then hit a wall, stop. Bounding box = abstract parameter --------------------------------- Literally it's four integers. Figuratively it's a single parameter that specifies the location and size of a rectangle. The rectangle is invisible; it is only used as a guideline. drawOval and fillOval take bounding boxes as arguments and use them to determine the boundaries of the oval. drawRectangle and fillRectangle take bounding boxes as arguments and use them to determine the boundaries of the Rectangle. In the case of rectangles, the shape that is drawn is the same as the bounding box, but in general that is not true. Where do the bounding boxes come from? ------------------------------------- When main invokes draw, it passes a BB that is the size of the whole window. In effect, it gives draw permission to draw anywhere on the screen. When draw invokes drawSnowperson, it passes a BB that is the same height as the window, one third the width, and centered. Strictly, drawSnowperson should not draw outside the box, although there is actually nothing to prevent it. drawSnowperson then calculates bounding boxes for the head, thorax and abdomen. It uses each BB twice, as an argument to drawOval, and as arguments to drawFace, drawShirt, and, recursively, drawSnowperson. Tricky things ------------- Algebra in coordinate space is a little tricky, so don't worry if it takes a while to sink in. You have to choose some numbers to determine the proportions of the snowman, but you should minimize the number of constants that appear in the code. Instead of making the programmer do computations at programming time, make the computer do it at run-time. That way, if you change any of the proportions, everything gets updated. Recursion --------- Now that we have method invocations and conditionals, we have a complete programming language! Anything that can be computed can be computed using only the language features we have so far. (Well, we would need some primitive commands for accessing input and output devices, but other than that). Let's see an example of how that works: public static void countdown (int n) { if (n == 0) { System.out.println ("Blastoff!"); } else { System.out.println (n); countdown (n-1); } } This method invokes itself! At first glance, you would think it would run forever. The key is that it does not ALWAYS invoke itself... 1) there is one case where it does not (when n=0) 2) if we start with any positive value of n, we will eventually reach the base case. Draw a stack diagram for this method when n=3. Recursion example #2: -------------------- We've already seen newLine and threeLine and TwoHundredFiftySixLine. Wouldn't it be nice if we could do something more general, like nLines? Now we can public static void nLines (int n) { if (n > 0) { System.out.println (""); nLines (n-1); } } Fractals -------- A fractal shape is something that is self-similar. That is, small parts of it look just like big parts, just smaller. Coastlines, clouds, trees, ferns, cauliflower. There is a natural connecion between fractal shapes and recursive methods. Snowpeople ---------- A snowperson is three ovals with a face, a t-shirt, and a snowperson, which is three ovals, a face, a t-shirt and a snowperson, which is three ovals, a face, a t-shirt and a snowperson, which is three ovals, a face, a t-shirt and a An so on until we get to a really small snowperson, at which point we can stop the recursion. QUIZ MONDAY ON CHAPTER 4.