(define (my-even? n) (cond [(zero? n) true] [(positive? n) (my-odd? (sub1 n))])) (define (my-odd? n) (cond [(zero? n) false] [(positive? n) (my-even? (sub1 n))]))Let's continue with the same data definitions from Wednesday. A person is a:
(make-person symbol number list-of-person) ; The necessary define-struct: (define-struct person (name year eye-color kids)) A list-of-persons is either - empty, or - (cons [person] [list-of-persons])Write a program at-least-two-children, which consumes a person and returns a list of names of all that person's descendents who have at least two children.
;; at-least-two-children : person --> list-of-symbol ;; Returns a list of all people in tree with at least two children. ;; (define (at-least-two-children a-person) (cond [(> (length (person-kids a-person)) 2) (cons (person-name a-person) (children-with-two-children (person-kids a-person)))] [else (children-with-two-children (person-kids a-person))])) ;; children-with-two-children : list-of-persons --> list-of-symbol ;; Returns a list of all children with at least two children. ;; (define (children-with-two-children a-loc) (cond [(empty? a-loc) empty] [(cons? a-loc) (append (at-least-two-children (first a-loc)) (children-with-two-children (rest a-loc)))]))
Write the program find-birth-year, which consumes a person and a symbol and returns a number. The returned number is the year in which the named person was born. Assume that the named person does appear in the family tree.
;; find-birth-year : person sym --> num ;; determine the birth year of the named person (define (find-birth-year a-person name) (cond [(symbol=? (person-name a-person) name) (person-year a-person)] [else (find-year-in-children (person-kids a-person) name)])) ;; find-year-in-children : list-of-persons sym --> num ;; Finds the birth year of the named person in a list of children. ;; (define (find-year-in-children a-loc name) (cond [(empty? a-loc) ...] [(cons? a-loc) ..(find-birth-year (first a-loc) name) .. ..(find-year-in-children (rest a-loc) name) .. ]))Notice that it's not clear how to fill in the template for find-year-in-children. What do we put into the base case? There is no meaningful number to return if the child list becomes empty. Note also that, even though we've assumed that the named person does appear in the tree, we don't know which of the list-of-persons they might be in. So DrScheme may reach this case while running find-birth-year.
We need some way to indicate that we did not find the person we're looking for in a given list of children. False is a good choice, but returning false would violate our contract. However, in this case we can convince ourselves that our original contract was indeed wrong. Both functions must be able to return either a num or false.
With this in mind, here are the corrected versions.
;; A num-or-false is either ;; - a number, or ;; - false ;; Find-birth-year : person sym --> num-or-false ;; Determine the birth year of the named person. ;; (define (find-birth-year a-person name) (cond [(symbol=? (person-name a-person) name) (person-year a-person)] [else (find-year-in-children (person-kids a-person) name)])) ;; find-year-in-children : list-of-persons sym --> num-or-false. ;; Finds the birth year of the named person in a list of children. ;; (define (find-year-in-children a-loc name) (cond [(empty? a-loc) false] [(cons? a-loc) (select-num-input (find-birth-year (first a-loc) name) (find-year-in-children (rest a-loc) name))])) ;; select-num-input : num-or-false num-or-false --> num-or-false ;; Returns whichever input is a num, or false if neither one is. ;; (define (select-num-input n-or-f1 n-or-f2) (cond [(number? n-or-f1) n-or-f1] [(number? n-or-f2) n-or-f2] [else false]))
Notice what happened here. Despite our assumption that the person named is in the family tree, we still ended up writing a program that works if the person is not in the family tree. There are two morals to this story:
To ponder:
How to model a hard-drive (where you have data-files, and directories).
Hint: Have a data defn for list-of-file.
But what, exactly, is a "file"?
Does the problem-description above, give any clues?