How to Design Programs phần 2 pps

56 255 0
How to Design Programs phần 2 pps

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

-58- Section 6 Compound Data, Part 1: Structures The input of a function is seldom a single measurement (number), a single switch position (boolean), or a single name (symbol). Instead, it is almost always a piece of data that represents an object with many properties. Each property is a piece of information. For example, a function may consume a record about a CD; the relevant information might include the artist's name, the CD title, and the price. Similarly, if we are to model the movement of an object across a plane with a function, we must represent the position of the object in the plane, its speed in each direction, and possibly its color. In both cases, we refer to several pieces of information as if they were one: one record and one point. In short, we COMPOUND several pieces of data into a single piece of data. Scheme provides many different methods for compounding data. In this section, we deal with structures. A structure combines a fixed number of values into a single piece of data. In section 9, we will encounter a method for combining an arbitrarily large number of values into a single piece of data. 6.1 Structures Suppose we wish to represent the pixels (colored dots) on our computer monitors. A pixel is very much like a Cartesian point. It has an x coordinate, which tells us where the pixel is in the horizontal direction, and it has a y coordinate, which tells us where the pixel is located in the downwards vertical direction. Given the two numbers, we can locate a pixel on the monitor, and so can a computer program. DrScheme's teachpacks represent pixels with posn structures. A posn structure combines two numbers. That is, a posn is a single value that contains two values. We can create a posn structure with the operation make-posn , which consumes two numbers and makes a posn . For example, (make-posn 3 4) (make-posn 8 6) (make-posn 5 12) are posn structures. Each of these structures has the same status as a number as far as computations are concerned. Both primitive operations and functions can consume and produce structures. Now consider a function that computes how far some pixel is from the origin. The contract, header, and purpose statement are easy to formulate: ;; distance-to-0 : posn -> number ;; to compute the distance of a-posn to the origin TEAMFLY TEAM FLY PRESENTS -59- (define (distance-to-0 a-posn) ) In other words, distance-to-0 consumes a single value, a posn structure, and produces a single value, a number. We already have some input examples, namely, the three posn structures mentioned above. What we need next are examples that relate inputs and outputs. For points with 0 as one of the coordinates, the result is the other coordinate: (distance-to-0 (make-posn 0 5)) = 5 and (distance-to-0 (make-posn 7 0)) = 7 In general, we know from geometry that the distance from the origin to a position with coordinates x and y is distance Thus, (distance-to-0 (make-posn 3 4)) = 5 (distance-to-0 (make-posn 8 6)) = 10 (distance-to-0 (make-posn 5 12)) = 13 Once we have examples, we can turn our attention to the definition of the function. The examples imply that the design of distance-to-0 doesn't need to distinguish between different situations. Still, we are stuck now, because distance-to-0 has a single parameter that represents the entire pixel but we need the two coordinates to compute the distance. Put differently, we know how to combine two numbers into a posn structure using make-posn and we don't know how to extract these numbers from a posn structure. Scheme provides operations for extracting values from structures. 18 For posn structures, Scheme supports two such operations: posn-x and posn-y . The former operation extracts the x coordinate; the latter extracts the y coordinate. To describe how posn-x , posn-y , and make-posn are related, we can use equations that are roughly analogous to the equations that govern addition and subtraction: (posn-x (make-posn 7 0)) = 7 and (posn-y (make-posn 7 0)) = 0 TEAMFLY TEAM FLY PRESENTS -60- The equations only confirm what we already know. But suppose we introduce the following definition: (define a-posn (make-posn 7 0)) Then we can use the two operations as follows in the Interactions window: (posn-x a-posn) = 7 (posn-y a-posn) = 0 Naturally, we can nest such expressions: (* (posn-x a-posn) 7) = 49 (+ (posn-y a-posn) 13) = 13 Now we know enough to complete the definition of distance-to-0 . We know that the function's a-posn parameter is a posn structure and that the structure contains two numbers, which we can extract with (posn-x a-posn) and (posn-y a-posn) . Let us add this knowledge to our function outline: (define (distance-to-0 a-posn) (posn-x a-posn) (posn-y a-posn) ) Using this outline and the examples, the rest is easy: (define (distance-to-0 a-posn) (sqrt (+ (sqr (posn-x a-posn)) (sqr (posn-y a-posn))))) The function squares (posn-x a-posn) and (posn-y a-posn) , which represent the x and y coordinates, sums up the results, and takes the square root. With DrScheme, we can also quickly check that our new function produces the proper results for our examples. Exercise 6.1.1. Evaluate the following expressions: 1. (distance-to-0 (make-posn 3 4)) 2. (distance-to-0 (make-posn (* 2 3) (* 2 4))) 3. (distance-to-0 (make-posn 12 (- 6 1))) by hand. Show all steps. Assume that sqr performs its computation in a single step. Check the results with DrScheme's stepper. 6.2 Extended Exercise: Drawing Simple Pictures TEAMFLY TEAM FLY PRESENTS -61- DrScheme provides the graphics teachpack draw.ss , which introduces simple graphics operations: 1. draw-solid-line , which consumes two posn structures, the beginning and the end of the line on the canvas, and a color. 2. draw-solid-rect , which consumes four arguments: a posn structure for the upper-left corner of the rectangle, a number for the width of the rectangle, another number for its height, and a color. 3. draw-solid-disk , which consumes three arguments: a posn structure for the center of the disk, a number for the radius of the disk, and a color. 4. draw-circle , which consumes three arguments: a posn structure for the center of the circle, a number for the radius, and a color. Each of the operation produces true , if it succeeds in changing the canvas as specified. We refer to the action to the canvas as an EFFECT, but we will ignore studying the precise nature of effects until part VII. Also, if anything goes wrong with the operation, it stops the evaluation with an error. Each drawing operation also comes with a matching clear- operation: clear-solid-line , clear-solid-rect , clear-solid-disk , and clear-circle . If these functions are applied to the same arguments as their matching draw- function, they clear the corresponding shapes of the canvas. 19 Drawing operations on computers interpret the screen as follows: First, the origin of the plane is in the upper-left corner. Second, y coordinates grow in the downwards direction. Understanding the difference between this picture and the more conventional Cartesian plane is critical for drawing shapes with programs. Exercise 6.2.1. Evaluate the following expressions in order: 1. (start 300 300) , which opens a canvas for future drawing operations; 2. (draw-solid-line (make-posn 1 1) (make-posn 5 5) 'red) , which draws a red line; 3. (draw-solid-rect (make-posn 20 10) 50 200 'blue) , which draws a blue rectangle of width 50 parallel to the line; and 4. (draw-circle (make-posn 200 10) 50 'red), which draws a red circle of radius 50 and a center point at the upper line of the rectangle. 5. (draw-solid-disk (make-posn 200 10) 50 'green), which draws a green disk of radius 50 and a center point at the height of the upper line of the rectangle. 6. (stop), which closes the canvas. TEAMFLY TEAM FLY PRESENTS -62- Read the documentation for draw.ss in DrScheme's HelpDesk. The definitions and expressions in figure 8 draw a traffic light. The program fragment illustrates the use of global definitions for specifying and computing constants. Here, the constants represent the dimensions of the canvas, which is the outline of the traffic light, and the positions of three light bulbs. ;; dimensions of traffic light (define WIDTH 50) (define HEIGHT 160) (define BULB-RADIUS 20) (define BULB-DISTANCE 10) ;; the positions of the bulbs (define X-BULBS (quotient WIDTH 2)) (define Y-RED (+ BULB-DISTANCE BULB-RADIUS)) (define Y-YELLOW (+ Y-RED BULB-DISTANCE (* 2 BULB- RADIUS))) (define Y-GREEN (+ Y-YELLOW BULB-DISTANCE (* 2 BULB- RADIUS))) ;; draw the light with the red bulb turned on (start WIDTH HEIGHT) (draw-solid-disk (make-posn X-BULBS Y-RED) BULB-RADIUS 'red) (draw-circle (make-posn X-BULBS Y-YELLOW) BULB-RADIUS 'yellow) (draw-circle (make-posn X-BULBS Y-GREEN) BULB-RADIUS 'green) Figure 8: Drawing a traffic light Exercise 6.2.2. Develop the function clear-bulb . It consumes a symbol that denotes one of the possible colors: 'green , 'yellow , or 'red , and it produces true. Its effect is ``to turn off'' the matching bulb in the traffic light. Specifically, it should clear the disk and display a circle of the matching color instead. Choice of Design Recipe: See section 5 for designing functions that consume one of an enumeration of symbols. TEAMFLY TEAM FLY PRESENTS -63- Testing: When testing functions that draw shapes into a canvas, we ignore test expressions. Although it is possible to implement appropriate test suites, the problem is beyond the scope of this book. Combining Effects: The primitive operations for drawing and clearing disks and circles produce true if they successfully complete their task. The natural way to combine the values and the effects of these functions is to use an and-expression. In particular, if exp1 and exp2 produce effects and we wish to see the effects of exp2 after those of exp1 , we write (and exp1 exp2) Later we will study effects in more detail and learn different ways to combine effects. Exercise 6.2.3. Develop a function draw-bulb . It consumes a symbol that denotes one of the possible colors: 'green , 'yellow , or 'red , and produces true . Its effect is ``to turn on'' the matching bulb in the traffic light. Exercise 6.2.4. Develop the function switch . It consumes two symbols, each of which stands for a traffic light color, and produces true . Its effects are to clear the bulb for the first color and then to draw the second bulb. Exercise 6.2.5. Here is the function next : ;; next : symbol -> symbol ;; to switch a traffic light's current color and to return the next one (define (next current-color) (cond [(and (symbol=? current-color 'red) (switch 'red 'green)) 'green] [(and (symbol=? current-color 'yellow) (switch 'yellow 'red)) 'red] [(and (symbol=? current-color 'green) (switch 'green 'yellow)) 'yellow])) It consumes the current color of a traffic light (as a symbol) and produces the next color that the traffic light shows. That is, if the input is 'green , it produces 'yellow ; if it is 'yellow , it produces 'red ; and if it is 'red , it produces 'green . Its effect is to switch the traffic light from the input color to the next color. Replace the last three lines of the program fragment in figure 8 with (draw-bulb 'red) . This creates a traffic light that is red. Then use next to switch the traffic light four times. 6.3 Structure Definitions In the preceding section we explored one particular class of structures: the posn structures. A posn structure combines two numbers, and it is useful to represent pixels. If we wish to represent employee records or points in three-dimensional space, however, posn s are useless. DrScheme therefore permits programmers to define their own structures so that they can represent all kinds of objects with a fixed number of properties. TEAMFLY TEAM FLY PRESENTS -64- A STRUCTURE DEFINITION is, as the term says, a new form of definition. Here is DrScheme's definition of posn: (define-struct posn (x y)) When DrScheme evaluates this structure definition, it creates three operations for us, which we can use to create data and to program: 1. make-posn , the CONSTRUCTOR, which creates posn structures; 2. posn-x , a SELECTOR, which extracts the x coordinate; 3. posn-y , also a selector, which extracts the y coordinate. In general, the names of these new operations are created by prefixing the name of the structure with ``make-'' and by postfixing the name with all the field names. This naming convention appears to be complicated but, with some practice, it is easy to remember. Now consider the following example: (define-struct entry (name zip phone)) The structure represents a simplified entry into an address book. Each entry combines three values. We also say that each entry structure has three fields: name , zip , and phone . Because there are three fields, the constructor make-entry consumes three values. For example, (make-entry 'PeterLee 15270 '606-7771) creates an entry structure with 'PeterLee in the name -field, 15270 in the zip -field, and '606- 7771 in the phone -field. One way to think of a structure is as a box with as many compartments as there are fields: name zip phone 'PeterLee 15270 15270 'PeterLee15270'606-7771 The italicized labels name the fields. By putting values in the compartments, we illustrate specific entry structures. The define-struct definition of entry also introduces new selectors: entry-name entry-zip entry-phone Here is how we can use the first one: (entry-name (make-entry 'PeterLee 15270 '606-7771)) = 'PeterLee If we give the structure a name, (define phonebook (make-entry 'PeterLee 15270 '606-7771)) TEAMFLY TEAM FLY PRESENTS -65- then we can use the selectors in the Interactions window to extract the data from the three fields: (entry-name phonebook) = 'PeterLee (entry-zip phonebook) = 15270 (entry-phone phonebook) = '606-7771 Put more graphically, a constructor creates a box with several compartments and puts values in it. A selector reveals the contents of a particular compartment, but leaves the box alone. Here is one final example, a structure for representing rock stars: (define-struct star (last first instrument sales)) It defines the class of star structures, each of which has four fields. Accordingly, we get five new primitive operations: make-star star-last star-first star-instrument star-sales The first is for constructing star structures; the others are selector operations for extracting values from a star structure. To create a star structure, we apply make-star to three symbols and a positive integer: (make-star 'Friedman 'Dan 'ukelele 19004) (make-star 'Talcott 'Carolyn 'banjo 80000) (make-star 'Harper 'Robert 'bagpipe 27860) To select the first name of a star structure called E , we use (star-first E) Other fields are extracted with other selectors. Exercise 6.3.1. Consider the following structure definitions: 1. (define-struct movie (title producer)) 2. (define-struct boyfriend (name hair eyes phone)) 3. (define-struct cheerleader (name number)) 4. (define-struct CD (artist title price)) 5. (define-struct sweater (material size producer)) What are the names of the constructors and the selectors that each of them adds to Scheme? Draw box representations for each of these structures. TEAMFLY TEAM FLY PRESENTS -66- Exercise 6.3.2. Consider the following structure definition (define-struct movie (title producer)) and evaluate the following expressions: 1. (movie-title (make-movie 'ThePhantomMenace 'Lucas)) 2. (movie-producer (make-movie 'TheEmpireStrikesBack 'Lucas)) Now evaluate the following expressions, assuming x and y stand for arbitrary symbols: 1. (movie-title (make-movie x y)) 2. (movie-producer (make-movie x y)) Formulate equations that state general laws concerning the relationships of movie-title and movie-producer and make-movie . Functions both consume and produce structures. Suppose we need to record an increase of sales for one of our stars. This act should be recorded in the star's record. To do so, we should have a function that consumes a star structure and produces a star structure with the same information except for the sales component. Let's assume for now that the function adds 20000 to the star's sales. First, we write down a basic description of the function, using our contract, header, and purpose format: ;; increment-sales : star -> star ;; to produce a star record like a-star with 20000 more sales (define (increment-sales a-star) ) Here is an example of how the function should process star structures: (increment-sales (make-star 'Abba 'John 'vocals 12200)) should produce (make-star 'Abba 'John 'vocals 32200)) The three sample star structures from above are also good examples of potential inputs. ;; increment-sales : star -> star ;; to produce a star record like a-star with 20000 more sales (define (increment-sales a-star) (make-star (star-last a-star) (star-first a-star) (star-instrument a-star) (+ (star-sales a-star) 20000))) Figure 9: The complete definition of increment-sales The increment-sales function must construct a new star structure with make-star, but to do so, it must also extract the data in a-star . After all, almost all of the data in a-star is a part of TEAMFLY TEAM FLY PRESENTS -67- the star structure produced by increment-sales . This suggests that the definition of increment-sales contains expressions that extract the four fields of a-star : (define (increment-sales a-star) (star-last a-star) (star-first a-star) (star-instrument a-star) (star-sales a-star) ) As we have seen with the examples, the function adds 20000 to (star-sales a-star) and assembles the four pieces of data into a star structure with make-star . Figure 9 contains the complete definition. Exercise 6.3.3. Provide a structure definition that represents an airforce's jet fighters. Assume that a fighter has four essential properties: designation ( 'f22 , 'tornado , or 'mig22 ), acceleration, top-speed, and range. Then develop the function within-range . The function consumes a fighter record and the distance of a target from the (fighter's) base. It determines whether the fighter can reach the intended target. Also develop the function reduce-range . The function consumes a fighter record and produces one in which the range field is reduced to 80% of the original value. 6.4 Data Definitions Consider the following expression: (make-posn 'Albert 'Meyer) It constructs a posn structure from two symbols. If we now apply distance-to-0 to this structure, the computation fails miserably: (distance-to-0 (make-posn 'Albert 'Meyer)) = (sqrt (+ (sqr (posn-x (make-posn 'Albert 'Meyer))) (sqr (posn-y (make-posn 'Albert 'Meyer))))) = (sqrt (+ (sqr 'Albert) (sqr (posn-y (make-posn 'Albert 'Meyer))))) = (sqrt (+ (* 'Albert 'Albert) (sqr (posn-y (make-posn 'Albert 'Meyer))))) That is, it requires us to multiply 'Albert with itself. Similarly, (make-star 'Albert 'Meyer 10000 'electric-organ) does not produce a star structure according to our intentions. In particular, the structure is not suitable for processing by increment-sales . To avoid such problems and to assist with the development of functions, we must add a data definition to each structure definition. TEAMFLY TEAM FLY PRESENTS [...]... monitor In figure 13, for example, a simplistic face is moved from the left part of the canvas toward the right border For simplicity, our pictures consist of many colored circles and rectangles From section 6 .2, we already know, for example, how to draw and erase a circle Here we learn to translate a circle, that is, to move its representation along some line In sections 7.4, 10.3, and 21 .4 we learn to. .. (make-word '_ 'l 'l) The first one shows what happens when the guess does not occur in the word; the second one shows what happens when it does occur; and the last one shows what happens when it occurs twice Y L F M Hints: (1) Remember to develop auxiliary functions when a definition becomes too large or too complex to manage (2) The function reveal consumes two structures and one atomic value (a letter) This... problem object) Contract Purpose and Header to name the name the function, the classes of input data, the class of function; output data, and specify its purpose: to specify its ;; name : in1 in2 > out classes of ;; to compute from x1 input data and its (define (name x1 x2 ) ) class of output data; to describe its purpose; to formulate a header Examples to characterize the search the problem statement... provides an optional tool that permits programmers to check whether users and programmers respect the data definition for a particular structure To do so, a programmer must state data definitions in a special language Although checking the adherence to data definitions is important for large programs, an introductory course can avoid this topic 20 21 This series of sections was inspired by Ms Karen... This series of sections was inspired by Ms Karen Buras and her son -79TEAM FLY PRESENTS In reality, we would want to play the game with words of arbitrary length, but a game based on three-letter words is easier to implement for now We return to the problem in exercise 17.6 .2 22 23 Thanks to Mr John Clements for the artistic version of draw-next-part Y L F M A E T -80TEAM FLY PRESENTS Section 7 The Varieties... permits us to describe this class of points succinctly: (make-posn 6 6) for A; (make-posn 1 2) for B; and 1, 2, and 3 for C, D, and E, respectively If we now wish to define the function distance -to- 0, which consumes such point representations and produces their distance to the origin, we are confronted with a problem The function may be applied to a number or a posn Depending on the class to which the... false otherwise -82TEAM FLY PRESENTS Hence a function can distinguish a structure from a number as well as a posn structure from an airplane structure Exercise 7.1.1 Evaluate the following expressions by hand: 1 2 3 4 5 (number? (make-posn 2 3)) (number? (+ 12 10)) (posn? 23 ) (posn? (make-posn 23 3)) (star? (make-posn 23 3)) Check the answers in DrScheme Now we can develop distance -to- 0 Let's start... pixel -2 is either 1 a number, or 2 a posn structure Y L F M Stating the contract, purpose, and header is straightforward: ;; distance -to- 0 : pixel -2 -> number ;; to compute the distance of a-pixel to the origin (define (distance -to- 0 a-pixel) ) A E T As mentioned before, the function must distinguish between its two kinds of inputs, which can be accomplished with a cond-expression: (define (distance -to- 0... circle structure: 2 (make-circle p s) Y L F M where p is a posn and s is a number; or 3 a square structure: 4 (make-square p s) A E T where p is a posn and s is a number Together, the two classes make up the class of shapes: The next step of our design recipe requires that we make up examples Let's start with input examples: 1 (make-square (make-posn 20 20 ) 3), 2 (make-square (make-posn 2 20) 3), and 3... compound data Contract Purpose and Header to name the function; to specify its classes of input data and its class of output data; to describe its purpose; to formulate a header Y L F M name the function, the classes of input data, the class of output data, and specify its purpose: ;; name : in1 in2 > out ;; to compute from x1 (define (name x1 x2 ) ) A E T Examples to characterize the create examples . following expressions: 1. (distance -to- 0 (make-posn 3 4)) 2. (distance -to- 0 (make-posn (* 2 3) (* 2 4))) 3. (distance -to- 0 (make-posn 12 (- 6 1))) by hand. Show all steps. Assume that sqr. fighters. Assume that a fighter has four essential properties: designation ( 'f 22 , 'tornado , or 'mig 22 ), acceleration, top-speed, and range. Then develop the function within-range use to create data and to program: 1. make-posn , the CONSTRUCTOR, which creates posn structures; 2. posn-x , a SELECTOR, which extracts the x coordinate; 3. posn-y , also a selector,

Ngày đăng: 12/08/2014, 19:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan