550 likes | 686 Vues
This chapter delves into the concept of compound data structures in Scheme, illustrating how to effectively combine multiple pieces of data into cohesive units. It introduces the "posn" structure, which represents a pixel by its x and y coordinates, and guides you through writing functions to manipulate these structures, such as calculating the distance to the origin. Furthermore, it emphasizes the importance of formalizing data definitions using a design recipe that includes contracts, examples, and a structured approach to coding.
E N D
Scheme: Compound Data Chapter 6 of HTDP Ms. Knudtzon September 19
Checkpoint • Homework: check-color Exercise
Introduction • Rarely do we have such simple data that we can represent it with a single number, string, symbol, or boolean • Usually we have several pieces of data about one object that we are interested in • Example: A cd with artist name, title, price, etc • We compound several pieces of data into one • In Scheme, this is a structure
Representing Pixels • A pixel is like a Cartesian point, with x & y coordinates (but the y direction is downwards) • In Scheme, there is a posn structure that combines two numbers • To create a posn: (make-posn 3 4) • To get the individual numbers back: (posn-x myPosn) (posn-y myPosn)
Distance to 0 • Let’s write a function that computes how far a pixel is from the origin ;; distance-to-0: posn --> number ;; computes distance of a-posn to the origin ;; Example: (distance-to-0 (make-posn 8 6)) = 10 (define (distance-to-0 a-posn) • What is our next step? • Let’s start with what we know about the data
Distance Function (define (distance-to-0 a-posn) … (posn-x a-posn) … … (posn-y a-posn) … ) This is basically our template for any posn function - then we can just fill in the parts that are specific to this specific problem: (define (distance-to-0 a-posn) (sqrt (+ (sqr (posn-x a-posn)) (sqr (posn-y a-posn))))) ;; Test Cases should follow
Structure Definitions • You’ve seen how to use an already defined structure, but how do you create your own structures? • Let’s look at how posn is written as an example
Posn Definition (define-struct posn (x y)) • When DrScheme evaluates this definition, it automatically creates three operations for use to create data and to program: • make-posn, the constructor, which creates posn structures • posn-x, a selector, which extracts the x coordinate • posn-y, a selector, which extracts the y coordinate
Another Example (define-struct entry (name zip phone)) To use: (make-entry “Ms. K” 20016 ‘537-2932) (define x (make-entry “Ms. K” 20016 ‘537-2932)) Think of the structure as a box with a compartment for each field: And you can access each compartment separately: (entry-name x) or (entry-zip x) or (entry-phone x) Just gives the struct a name x
Formalizing Matters • What if we said: (define p (make-posn ‘Albert ‘Einstein)) and then tried to use the “posn” with: (distance-to-0 p) • We would get errors! • So we need to formalize how we intend to use out structures and how we construct the elements of those structures • We do this with a Data Definition
Data Definition • Combination of English and Scheme that is the contract for that structure • Scheme doesn’t check the contract, but you assume that users of your structure or functions will follow what you have specified • For example, we would say ; A posn is a structure ; (make-posn x y) ; Where x and y are numbers
Design Recipe • Let’s see how the Design Recipe scales to make it easy to think out the problems for programs with structures • Data Definition • Examples of Data • Template • Contract & Purpose • Examples (Test Cases) • Header and Body
Data Definition • Search the problem statement for descriptions of the objects needed and design data representations based on that (define-struct student (last first teacher)) ; A student is a structure: (make-student l f t) where l, f & t ; are symbols Or a shortcut I use: (define-struct student (last first teacher)) ; A student is a structure: (make-student symbol symbol symbol)
Examples of Data • Then show (or define) the kinds of data that are acceptable with your data definition (make-student ‘henry ‘mills ‘Ms.K) (define nickI (make-student ‘nick ‘ink ‘Ms.K)) (define nickM (make-student ‘nick ‘m ‘ms.k))
Template • A function that inputs a structure is likely to compute its results from the components of the structure, so it helps to start with those (using the selector expressions) ;; student-func: student --> ???? ;; purpose: (define (student-func aStudent) … (student-last aStudent) … … (student-first aStudent) … … (student-teacher aStudent) … )
Rest of Recipe • Contract & Purpose: do these for the specific functions you are writing • Examples: Write examples (test cases) for the function • Use the data examples you wrote earlier (that’s why I recommend using the defines) (my-s-func nickM) • Header & Body: Using the template, formulate an expression that computes the answer from the available data and other Scheme functions
Putting It All Together • Class Exercise: Create data for boas containing name, length, what they eat • Write a function isShorter? that determines whether a boa is shorter than a given amount • Design Recipe • Data Definition • Examples Of Data • Template • Contract & Purpose • Examples (Test Cases) • Header & Body
Scheme Mini-Project • Draw Teachpack: Introduces simple graphics operations using posn structures • draw-solid-line: posn posn • draw-solid-rect: posn number number color • draw-solid-disk: posn number color • draw-circle: posn number color • Each operation produces boolean • Each has a matching clear- operation • Your Scheme mini-project (see project handout) will use this drawing package
Scheme: Mixed Data Chapter 7 of HTDP Ms. Knudtzon September 20
Checkpoint • 80-point Quiz #3
Graphical Test Cases • Special > Insert Test Case
Structures • Yesterday our structures were made up of symbols, numbers, booleans & strings • Today, let’s consider structures that can be made of other structures • We will also look at how to do some error checking in our functions to make sure we get the expected kind of data
Distinguishing Data • The other day, I introduced the symbol? and string? operators called predicates • They recognize particular kinds of data • Also available: number? boolean? struct? • For each structure that we make, Scheme also makes a predicate • posn? • student? • boa? • Etc • So any function we write can check the type of its inputs
Mixed Data • We can have one name refer to multiple types of data • Yesterday we defined a dillo and a boa • Let’s do a data definition for an animal ; An animal is either ; a boa structure: ; (make-boa symbol number), or ; a dillo stucture ; (make-dillo symbol number number boolean)
Animal-func • So given that we can use predicates to distinguish our data, let’s make a template for animal data ; animal-func: animal --> ??? (define (animal-func an-ani) (cond [(boa? an-ami) … (boa-name an-ami) (boa-length an-ami) (boa-food an-ami) … ] [(dillo? an-ami) … (dillo-name an-ami) (dillo-age an-ami) (dillo-timesRunOver an-ami) (dillo-dead? an-ami) … ]))
New template • Make a cond block to distinguish the different kind of available data • Pull out the available data for each case • Then you can put this all in a comment box • When you need to write a new function, you can copy the template, fill in the blanks and erase the stuff you don’t need anymore
Animal Function • Let’s add a length field to the dillo definition so that we could compare animal lengths • Using our template, we could then create a new animal function, tooShort? which takes an animal and returns true if the boa is shorter than 6 or 2 for a dillo
Another Example • Lets define a shape class which can be circle or square structures (which also need to be defined), each of which require a posn and a number • The posn is the circle’s center and the upper left corner of the square • The number is the circle’s radius and the square’s length • Follow the design recipe to sketch out everything for a shape • Then write a perimeter function for a shape
Scheme: Mixed Data Cont’d and Lists Chapter 7 & 9 of HTDP Ms. Knudtzon September 21
Shapes Continued • Lets define a shape class which can be circle or square structures (which also need to be defined), each of which require a posn and a number • The posn is the circle’s center and the upper left corner of the square • The number is the circle’s radius and the square’s length • Follow the design recipe to sketch out everything for a shape • Then write a perimeter function for a shape
Error checking • Note: the predicates (type questions) that we have been using to check type for functions could also be used for simple input checking • If we expect a function to only receive numbers and we get something else, we could cause an error, which input a symbol (the function name) and a string (the error message you want displayed) (define (my-func foo) (cond [ (number? foo) …] [ else (error ‘my-func “number expected”)])) • This way you aren’t returning something that isn’t expected (like a string message when the function contract says it returns a number)
Lab Exercise (Homework) • Develop structure and data definitions for a collection of vehicles. The collection should include at least buses, limos, cars, and police-cars. All vehicles should have a licensePlate, milesDriven, and gasTankCapacity. Add a structure-specific attribute for each class of vehicle. Then develop a template for functions that inputs a vehicle. • Expanding on the template, write a function that checks the license plate of a vehicle against a “wantedVehicle” and returns true if it is a match (inputting two vehicles to the function) • Make another function that calculates the miles per gallon that a given vehicle has gotten, assuming it has used a whole tank.
Lists The wonderful world of arbitrary-length structures
Lists • We all understand what a list is - we make them all the time • So the question is how do we make these lists in Scheme? • When we form a list, we always start with the empty list and then we add elements to it
Lists in Scheme • In Scheme, the empty list is simply: empty • And then to construct a longer list, we use the cons operator: (cons “Buy milk” empty)
And again • To add more items, we keep using cons again: (cons “Water plants” (cons “Buy milk” empty)) First rest “Water plants” Etc
Lists of Numbers • We can makes lists of anything - here’s a list of 10 numbers: (cons 0 (cons 1 (cons 2 (cons 3 (cons 4 (cons 5 (cons 6 (cons 7 (cons 8 (cons 9 empty ))))))))))
Mixed Data Lists • Lists can also have values of multiple kinds: (cons ‘APCS (cons 3 (cons “testing testing” (cons true empty))))
Using Lists • Let’s says we are given a list a numbers and we want to add the numbers on the list. How do we do this? • For simplicity, let’s say that we only have a list of three numbers ;; A list-of-3-nums is ; (cons x (cons y (cons z empty))) ;; where x, y, and z are numbers
Writing add-up-3 ;; add-up-3: list-of-3-nums --> number ;; to add up 3 numbers in a list ;; example/test case: ;; (= (add-up-3 (cons 2 (cons 1 (cons 3 empty)))) 6) (define (add-up-3 mylist) …)
Selectors for lists • first and rest are the operators we need to pull out parts of a list • The data definitions for first and last are: • ;; first: non-empty-list --> value • ;; rest: non-empty-list --> list (define li (cons 10 (cons 20 (cons 5 empty))) What is: • (rest li) • (first (rest li)) • (rest (rest li)) • (first (rest (rest li))) • (rest (rest (rest li)))
Add-up-3 So what do we need to do here? ;; add-up-3: list-of-3-nums --> number ;; to add up 3 numbers in a list ;; example/test case: ;; (= (add-up-3 (cons 2 (cons 1 (cons 3 empty)))) 6) (define (add-up-3 mylist) …)
List Data Definitions • We need a way to describe the lists we want to store and the kind of data they store. • The data definitions good references and they remind us how to build data • Example: ;; A list-of-symbols is either: ; the empty list, empty, or ; (cons s los) where s is a symbol and los is a list of symbols • Note here we have the data definition referring back to itself
LOS or LOST?? ;; A list-of-symbols is either: ; the empty list, empty, or ; (cons s los) where s is a symbol and los is a list of symbols • How does this work? Does it make sense? • We can construct elements from it (the data definition) • It works for any cases of our list that we can think of
Using the Design Recipe • Everything is as before, but the template needs to have cond-expressions for each clause in the data definition • In the case of a list, empty and cons ;; General Template for list-of-symbols ;; alos-func: list-of-symbols --> ??? (define (alos-func alos) (cond [ (empty? alos) … ] [ (cons? alos) … (first alos) … … (alos-func (rest alos)) …. ])) Same number of arrows as in data definition
LOS Function Example 1 ;; length : list-of-symbols --> number ;; consumes a list of symbols and returns ;; the number of items in the list (define (length alos) … ) Try this together in Scheme
Homework • Lab Exercise from yesterday (Vehicle Structures) • Review lengthof function from class
(Thursday Lecture) • Review and practice on the whiteboard about lists and list functions • Individual students should have notes
Scheme: Lists Cont’d Chapter 9-10 of HTDP Ms. Knudtzon September 23
Checkpoint • 80 point quiz #4b (instead of yesterday’s) • List exercises • dollar-store? • delta • check-range1? • check-range? • average-price we will do together