530 likes | 602 Views
Scheme: Lists Cont’d. Chapter 9-10 of HTDP Ms. Knudtzon September 26. Producing Lists in a Function. Remember the wage function we wrote: (define hour-rate 12) (define (wage h) (* hour-rate h))
E N D
Scheme: Lists Cont’d Chapter 9-10 of HTDP Ms. Knudtzon September 26
Producing Lists in a Function • Remember the wage function we wrote: (define hour-rate 12) (define (wage h) (* hour-rate h)) • What if we wanted to extend the function - a company really wants us to compute the wages for all its employees • We want to input the list of the hours each employee worked and output the list of the wages for each employee
List Template ;; hours-->wages: list-of-numbers --> lists-of-numbers ;; to create a list of weekly wages from a list of weekly hours (alon) (define (hours-->wages alon)(cond [ (empty? alon) … ] [ else … (first alon) … … (hours-->wages (rest alon)) … ] )) • But how do we fill in this template to return a list? Could also do (cons? alon) here
hours-->wages • We want to compute the wage for the first item in the list of weekly hours • So we will probably want to use our wage function that computes the wage for one set of hours worked • Then we want to construct a list that represents the wages for alon, using the first weekly wage that we’ve computed and the list of weekly wages for (rest alon) • The (rest alon) in the template reminds us that the function we write can process this list recursively • Any ideas on how to do this?
Completed: hours-->wages ;; hours-->wages: list-of-numbers --> listsof-numbers ;; to create a list of weekly wages from a list of weekly hours (alon) (define (hours-->wages alon)(cond [ (empty? alon) empty ] [ else (cons (wage (first alon)) (hours-->wages (rest alon)) ] ))
Practice! • Exercise 10.1.4. Develop the function convert-euro, which converts a list of U.S. dollar amounts into a list of euro amounts. Assume the exchange rate is 1.22 euro for each dollar. • Generalize convert-euro to the function convert-euro-1, which consumes an exchange rate and a list of dollar amounts and converts the latter into a list of euro amounts.
Adding even more complexity… • So far we have dealt with lists of simple data types, but in the real world, we could have lists with structures (instead of just atomic values) • Maybe we want to keep track of an inventory for a store in which they want to keep track of all the items and the item’s price
An Inventory Record (define-struct ir (name price) ;; An inventory-record (ir) is a structure: ; (make-ir symbol number) (define ir1 (make-ir ‘robot 500)) Don’t forget to write the template for the ir: ;; ir-func: ir --> ?? ;; purpose: (define (ir-func record) … (ir-name record)… … (ir-price record)…)
An inventory • An inventory would then be a list of irs • So use the ir structure as the basis for our list: ;; An inventory is either ;; empty or ;; (cons ir inv), where ir is an inventory record & inv is an inventory Note: this data definition actually has two arrows One back to the definition of ir One back to the definition of itself (inventory)
Inventory Template ;; inv-func: inventory --> ??? ;; Purpose: Consumes an inventory (list of irs) and …. (define (inv-func an-inv) (cond [ (empty? an-inv) …] [ else … (ir-func (first an-inv)) … … (inv-func (rest an-inv)) … ]))
Extract Function • Define the extract1 function, which takes an-inv and removes anything that costs less than $1 ;; extract1: inventory --> inventory (define (extract an-inv) (cond [ (empty? an-inv) empty] [ else (cond [ (<= (ir-price (first an-inv)) 1.00) (cons (first an-inv) (extract1 (rest an-inv)))] [else (extract1 (rest an-inv)) ] ) ])) Here we just pull out the piece because it’s just one item
Exercise: convert-euro • Develop the function convert-euro, which converts a list of U.S. dollar amounts into a list of euro amounts. Assume the exchange rate is 1.22 euro for each dollar. • Generalize convert-euro to the function convert-euro-1, which consumes an exchange rate and a list of dollar amounts and converts the latter into a list of euro amounts.
Exercise: Something Fun Provide a data definition and a structure definition for an inventory that includes pictures with each inventory record. Develop the function show-picture. The function consumes a symbol, the name of a toy, and one of the new inventories. It produces the picture of the named toy or false if the desired item is not in the inventory • You can define images and use them in your program by using: Special > Insert Image
List shortcut • (list 1 2 3) will make: (cons 1 (cons 2 (cons 3 empty))) • (list (make-posn 3 4) (make-posn 2 3) (make-posn 5 6)) will do: (cons (make-posn 3 4) (cons (make-posn 2 3) (cons (make-posn 5 6) empty))) • You can use this for making lists, but remember, Scheme still constructs the list with cons and that is what you will need for your data definitions and for your templates
List Project • The person responsible for counting the votes in a recent Washington DC primary election needs some help. Given the recent problems with vote counting across the nation, he is concerned that the old system might cause controversy. As an expert programmer, you have been asked to help develop a new system that will correctly count the votes in a recent election, as well as providing some statistics about the election. Unfortunately, the person you are working for is very busy, and has only provided you with some raw data and told you what you are expected to program. It is your job to figure out a way to finish the tasks before the deadline next Thursday.
Scheme: Composing Functions, More on Recursion Chapter 12 of HTDP Ms. Knudtzon September 27
Auxiliary Functions • We talked about defining auxiliary functions for every dependency between quantities in the problem statement. • Today we are going to look at other situations in which we may want to design auxiliary functions.
Designing Complex Functions • When we analyze a problem statement, we may find: • That the formulation of an answer requires different cases of values • Use a cond expression • That the computation requires knowledge of a particular domain • Us an auxiliary function • That a computation must process a list or some other data of arbitrary size • Use an auxiliary function • That we need a specific kind of answer • Maybe the general case could be placed in an auxiliary function
“Wish Lists” • Often we end up with a problem that may require several auxiliary functions • We should keep a list of functions (with contract, header & purpose) that need to be developed in order to complete the function • Once you have a list of functions that need to be completed, you can see if there might be something existing in Scheme already, or decide which needs to be implemented next, depending on what information we already have • The (extra-credit) winning judge part of the List Project requires this
Recursive Auxiliary Function: Sorting • Write a program that takes a list of numbers and sorts it, returning the new, sorted list of numbers ;; sort: list-of-numbers --> list-of-numbers ;; to create a sorted list of numbers from all the ;; numbers in alon (define (sort alon) ….)
Function template for Sort Examples of data? (sort empty) “should be” …… (sort (cons 324 (cons 634 (cons -343 empty)))) “should be” ……. ;; sort: list-of-numbers --> list-of-numbers ;; to create a sorted list of numbers from all the ;; numbers in alon (define (sort alon) (cond [ (empty? alon) …] [ else … (first alon) … (sort (rest alon)) …]))
What next? • For the empty case, the answer is empty, as seen in the example. • What do we want to happen in the else case? • We want to put together the two pieces • (first alon) extracts the first number • (sort (rest alon)) produces a sorted version of (rest alon) • So we want to insert the first number into the correct place in the sorted list
Insert • We know we want to insert (first alon) into the sorted rest of the list • But how do we find the right place to insert our number? -- We have to find the proper place in the list • An auxiliary function that will handle this task is a good idea here! ;;insert: number list-of-numbers --> list-of-numbers ;; to create a list of numbers from n and the list alon ;; that is sorted in descending order; alon is already sorted (define (insert n alon) … )
Sort • So with that auxiliary function, we could finish our sort definition: [else (insert (first alon) (sort (rest alon))) ] • But we still need to develop the insert auxiliary function
insert • Sample cases to figure out what is happening • Template of insert function: (cond [ (empty? alon) …] [else … (first alon) … (insert n (rest alon)) …] • What do we want to happen in each case?
Insert cases • Empty case: (cons n empty) • What about when alon is not empty? • Consider examples: (insert 7 (cons 6 (cons 5 (cons 4 empty)))) (insert 3 (cons 6 (cons 1 (cons -1 empty)))) (insert 3 (cons 6 (cons 3 (cons -1 empty)))) • --> How many new cases do we have?
Cases (cond [ (>= n (first alon)) …] [(< n (first alon)) …]) So what do we need to do in each case?
Insert Function ;;insert: number list-of-numbers --> list-of-numbers ;; to create a list of numbers from n and the list alon ;; that is sorted in descending order; alon is already sorted (define (insert n alon) (cond [ (empty? alon) (cons n empty)] [else (cond [ (>= n (first alon)) (cons n alon)] [ else (cons (first alon) (insert n (rest alon)))]) ]))
Scheme: Exercises Ms. Knudtzon September 28
Exercises • Exercise 12.2.1. Develop a program that sorts lists of mail messages by name. Mail structures are defined as follows: (define-struct mail (from date message)) ;; A mail-message is a structure: ;;(make-mail name n s) ;; where name is a string, n is a number, and s is a string. To compare two strings alphabetically, use the string<? primitive
Exercises • Exercise 12.2.2. Here is the function search: ;; search : number list-of-numbers-->boolean (define (search n alon) (cond [(empty? alon) false] [else (or (= (first alon) n) (search n (rest alon)))])) It determines whether some number occurs in a list of numbers. The function may have to traverse the entire list to find out that the number of interest isn't contained in the list. Develop the function search-sorted, which determines whether a number occurs in a sorted list of numbers. The function must take advantage of the fact that the list is sorted.
Scheme: Trees Chapter 14 of HTDP Ms. Knudtzon September 29
Family Trees • Let’s sketch out how we would design a family tree • First, let’s actually sketch a sample family tree. • What are the major components? • What structures do we need? • How do we do the data definition for the tree?
The data (define-struct person (name year eye-color mother father)) ;;A person is ;;(make-person string number symbol person person) ;; ;; Note: [[circles back to make-person]] • But can we actually create data from the definition? • We have self-referential data, but no additional “stopping” clauses (like empty for lists)
Child Node • While we could use empty, let’s introduce a new symbol ‘unknown and make a new date definition ;; A child node is a ;; (make-person name year eye-color mom dad) ;; where mom and dad are ‘unknown or child nodes ;; name is a string, eye-color is a symbol, year is a number • But now we have two alternatives for the last two components … which is no good
Family Tree Node (ftn) • Instead, let’s define the collection of nodes in the tree ;; A family-tree-node (ftn) is either ;; - ‘unknown or ;; (make-person name year eye-color mom dad) ;; where mom and dad are family-tree-nodes ;; name is a string, eye-color is a symbol, year is a number • Now we can define an example that works
Tree Example (define tree1 (make-person “Mary” 1985 ‘blue (make-person “Anna” 1960 ‘green ’unknown (make-person “Hal” 1930 ‘blue ‘unknown ‘unknown) ) (make-person “Joe” 1958 ‘green ‘unknown ‘unknown))) Or Better to see the information: ;; Oldest generation (define Hal (make-person “Hal” 1930 ‘blue ‘unknown ‘unknown) ;; middle generation (define Anna (make-person “Anna” 1960 ‘green ’unknown Hal) (define Joe (make-person “Joe” 1958 ‘green ‘unknown ‘unknown))) ;;youngest generation (define mary (make-person “Mary” 1985 ‘blue Anna Joe) (define tree1 mary)
Template for FTN • Now that we have the data definition for a family tree node (ftn) let’s make the template: ;; Contract: ft-func: family-tree --> xxx ;; Purpose: (define (ft-func aft) (cond [(symbol=? ‘unknown aft) xxx] • oops -- we need a symbol here and aft isn’t necessarily a symbol - a make-person would produce an error: so instead use...
Template ;; Contract: ft-func: family-tree --> xxx ;; Purpose: (define (ft-func aft) (cond [(symbol? aft) xxx] [(person? aft) (person-name aft) (person-year aft) (person-eye-color aft) (ft-func (person-mother aft)) ;;do arrows (ft-func (person-father aft))] ) ) ;;do arrows ;; This says any symbol is a terminator ;; generic equality checking operator might be better: (eq? ‘unknown aft) ;; to enforce unknown
is-in? (Using template) ;; Contract: is-in?:string family-tree --> boolean ;; Purpose: To determine wheter a given name appears in family tree ;; Tests (is-in? “Anna”‘unknown) “should be” false (is-in? “Anna” tree1) “should be” true (is-in? “Fred” tree1) “should be” false (define (is-in? name aft) (cond [(symbol? aft) false] ;; remember, this is any symbol [(person? aft) (or (string=? name (person-name aft) (is-in? (person-mother aft)) ;;do arrows (is-in? (person-father aft))) ] ) ) ;;do arrows
Count function ;; count: family-tree --> number ;; produce number of people in the family tree (define (count aft) (cond [(symbol? aft) 0] [(person? aft) (+ 1 (count (person-mother aft)) (count(person-father aft))) ] ) )
Count-ww2-babies ;; count-ww2-babies: family-tree --> number ;; produce number of people in tree born between 1941-1945 inclusive define (count-ww2-babies aft) (cond [(symbol? aft) 0] [(person? aft) (+ (ww2-baby (person-year aft)) (count-ww2-babies (person-mother aft)) (count-ww2-babies(person-father aft))) ] ) ) ;; helper ww2-baby: number --> number ;; Return 0 if not, 1 is is (define (ww2-baby? year) (cond [ (<= 1941 year 1945) 1] [ else 0] ))
Blue-eyed-ancestor? • Write a function that determines whether a family tree contains a child structure with ‘blue in the eyes field
Average-age • Develop the function average-age which consumes a family tree and the current year. It produces the average age of all people in the family tree.
Scheme: Binary Trees Ms. Knudtzon September 29
Checkpoint • How did last night’s exercise go? • Count-ww2-babies • Average-age • blueEyedAncestor • Let’s look at the solutions together
Binary Tree Node • We are going to define a new kind of tree that contains nodes: (define-struct node (data left right)) ;; A node is a ;; (make-node d l r) ;; where d is a number, and l&r are nodes or empty)
Binary Trees • A binary tree is one in which every node has one left and one right child node (or empty to indicate lack of node): A binary-tree (BT) is either: - empty (make-node number BT BT)
Binary Search Tree • A binary search tree (bst) is a special kind of binary tree that manages information in a way that makes it easy to store and retrieve • The items in the left tree are all less than the node • The items in the right tree are all greater than or equal to the node
Trees (Pictures) Binary Search Tree Binary Tree