WXME0105 ## wxtextwxtabwxmediawximage$(lib "comment-snip.ss" "framework")+(lib "collapsed-snipclass.ss" "framework")drscheme:sexp-snipdrscheme:syntax-snipclass%drscheme:number,(lib "number-snip.ss" "drscheme" "private")drscheme:bindings-snipclass%drscheme:lambda-snip%drscheme:define-snip%"drscheme:vertical-separator-snip%wxbaddrscheme:test-suite:helper%case%def%drscheme:xml-snip(lib "xml-snipclass.ss" "xml")drscheme:scheme-snip"(lib "scheme-snipclass.ss" "xml")wxlocHK ZÁÿZÁÿÁÿ€ÿ€ÿ€ÿÁÿ StandardK-adobe-courierZÁÿZÁÿÁÿ€ÿ€ÿ€ÿÁÿÁÿ?ð\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð"€‹"ÁÿÁÿMatching Parenthesis StyleÁÿ?ð\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð"€‹"ÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð(ÁÿÁÿdrscheme:check-syntax:keywordÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð(ÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿ'drscheme:check-syntax:unbound-variableÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€€ÁÿÁÿ%drscheme:check-syntax:bound-variableÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€€ÁÿÁÿ drscheme:check-syntax:primitiveÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€€ÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð3€‡'ÁÿÁÿdrscheme:check-syntax:constantÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð3€‡'ÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿ€¥ÁÿÁÿ drscheme:check-syntax:tail-callÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿ€¥ÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€¥**ÁÿÁÿdrscheme:check-syntax:baseÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€¥**ÁÿÁÿF?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð?ð?ð?ðÁÿÁÿXMLF?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð?ð?ð?ðÁÿÁÿG?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð?ð?ð?ðÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿG?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿG?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ðdÁÿÁÿK-adobe-courierZÁÿZÁÿÁÿ€ÿ€ÿ€ÿÁÿK-adobe-courierZÁÿZÁÿÁÿ€ÿ€ÿ€ÿÁÿK-adobe-courierZÁÿZÁÿÁÿ€ÿ€ÿ€ÿÁÿK-adobe-courierZÁÿZÁÿÁÿ€ÿ€ÿ€ÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€€ÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ðQQ€ûÁÿÁÿG?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ðQQ€ûÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€¯ÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ðÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€²""ÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ€ÿ€ÿ€ÿÁÿÁÿÁÿ?ðÁÿÁÿÁÿÁÿÁÿÁÿ€²""€ÿ€ÿ€ÿÁÿÁÿÁÿ?ðÁÿÁÿ^ÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿF@\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð?ð?ð?ðÁÿÁÿF?ð\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð?ð?ð?ðÁÿÁÿF?ð\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿF?ðÁþÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð?ð?ð?ðÁÿÁÿF?ðÁþÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿF?ð\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð2€Í2ÁÿÁÿF?ðÁÿÁÿ]ÁÿÁÿÁÿ?ð?ð?ð?ð?ð?ðÁÿÁÿF?ó33@\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð?ð?ð?ðÁÿÁÿF?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿK?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€¥**ÁÿÁÿK?ð\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€™ÁÿÁÿK?ð\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€¥**ÁÿÁÿK?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿK?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð?ð?ð?ðÁÿÁÿF?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð?ð?ð?ðÁÿÁÿF?ðÁÿÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿF?ð\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿF?ø\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð?ð?ð?ðÁÿÁÿK?ð\ÁÿÁÿÁÿÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿF ZÁÿZÁÿÁÿ€ÿ€ÿ€ÿÁÿK-adobe-courier ZÁÿZÁÿÁÿ€ÿ€ÿ€ÿÁÿÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ðÁÿÁÿsyntax-coloring:Java:keywordÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ðÁÿÁÿÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ðdÁÿÁÿsyntax-coloring:Java:stringÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ðdÁÿÁÿsyntax-coloring:Java:literalÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ðdÁÿÁÿÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ðiiiÁÿÁÿsyntax-coloring:Java:commentÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ðiiiÁÿÁÿÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿsyntax-coloring:Java:errorÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ð€ÿÁÿÁÿÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ð€‹ÁÿÁÿ syntax-coloring:Java:identifierÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ð€‹ÁÿÁÿÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ð€©€©€©ÁÿÁÿsyntax-coloring:Java:defaultÁÿ?ðÁÿ\Áÿ]ÁÿÁÿ?ð?ð?ð€©€©€©ÁÿÁÿÁÿ?ð\ÁÿÁÿÁÿÁÿÁÿ€ÿ€ÿÁÿÁÿ„86;ITERATIVE REFINEMENT: REAL-WORLD SOFTWARE DEVELOPMENT  ;;;;INTRODUCTION;;;;   4;Iterative refinement is the process of creating an  num  ;;Returns the number of files in the directory structure d, %no matter how deeply nested they are. ;(define (count-files d) ; ...)  ;S-2: ADD EXAMPLES. ';(count-files vacant-dir) "should be" 0 &;(count-files DIRECTORY) "should be" 7 #;(count-files plt) "should be" 6038   9;S-3: COPY THE TEMPLATE FOR THE DATA TYPE, SUBSTITUTING .CORRECT PARAMETER-NAMES FOR THE GENERIC NAMES.  ;count-files: dir -> num  ;;Returns the number of files in the directory structure d, %no matter how deeply nested they are.  ;(define (count-files d) ; (... (dir-name d) ... ;; ... (func-for-a-list-of-files (dir-files d)) ...  4; ... (func-for-a-list-of-dirs (dir-dirs d)) ...))  +;S-4: DECIDE WHICH PIECES OF DATA WE NEED. ;Do we need all three?   ;;No, we don't need 'dir-name' if we're just counting files in the directory. 4;We're left with this skeleton of the function body:  ;(define (count-files d) ;; (... (func-for-a-list-of-files (dir-files d)) ...  4; ... (func-for-a-list-of-dirs (dir-dirs d)) ...))   8;S-5: SUBSTITUTE CORRECT FUNCTION-NAMES FOR THE GENERIC NAMES IN THE TEMPLATE.  ;count-files: dir -> num  ;;Returns the number of files in the directory structure d, %no matter how deeply nested they are. ;(define (count-files d)  ; (... (-func-for-a-list-of-files (dir-files d)) ...   ; ... (,func-for-a-list-of-dirs (dir-dirs d)) ...))   :;WE DON'T HAVE THESE TWO FUNCTIONS, SO WE CAN'T IMPLEMENT 'count-files' yet.  8;WE COULD JUST WISH FOR THEM, SUBSTITUTE THE WISHED-FOR  8FUNCTION NAMES, AND WRITE THE FUNCTIONS LATER. INSTEAD LET'S CREATE THEM NOW.  *;S-6: CREATE 'func-for-a-list-of-files'.  .;;;WHAT DO WE WANT THIS FUNCTION TO DO FOR US?  &;how-many-files : list-of-files -> num /;Returns the number of files in a list-of-files   :; ... We wish for it ... and it appears: it's built into  DrScheme. -;In the DrScheme documentation, we find this: ;length : (list -> number) 2;purpose: to compute the number of items on a list  8;(Do Help -> Help Desk -> Beginning Student Language -> Lists -> length)   (;S-7: NOW WE CAN WRITE 'length' as our 'func-for-a-list-of-files'.  ;count-files: dir -> num  ;;Returns the number of files in the directory structure d, $no matter how deeply nested they are ;(define (count-files d) ); (... (length (dir-files d)) ...   ; ... (,func-for-a-list-of-dirs (dir-dirs d)) ...))  %;S-8: CREATE 'func-for-list-of-dirs'   ;;AT THIE POINT, WE REPEAT ALL RELEVANT STEPS IN THE DESIGN RECIPE, IN ORDER.  /;What do we *most* want to this function to do?  (;count-files-in-lod: list-of-dirs -> num  :;Returns the number of files in all of the directories in )lod, no matter how deeply nested they are   8;Now write the header and copy the generic template for 'list-of-dirs'. !;(define (count-files-in-lod lod) ; (cond $; [(empty? any-list-of-dirs) ...] =; [else (... (func-for-a-dir (first any-list-of-dirs)) ...  /; ... (func-for-a-list-of-dirs (rest any-list-of-dirs)))]))   <;Change the generic parameter-names to appropriate specific names. !;(define (count-files-in-lod lod) ; (cond ; [(empty? lod) ...] 0; [else (... (func-for-a-dir (first lod)) ... 8; ... (func-for-a-list-of-dirs (rest lod)))]))   <;Replace the generic function-names with names of functions we are actually going to use.  <;In particular, do we have a function that counts the files (in the 'first' of a list-of-directories?   =;What *is* the first element in a list-of-directories if the list is not empty?   5;We look at the data definition and see that it is a  directory.  5;We already have a function that does what we want.   ;;'count-files' counts the files in a directory. Just read the purpose statement!  ;count-files: dir -> num  ;;Returns the number of files in the directory structure d, $no matter how deeply nested they are   3;And we have a function that counts the files in a 1list-of-directories. Read the purpose statement!  (;count-files-in-lod: list-of-dirs -> num  :;Returns the number of files in all of the directories in )lod, no matter how deeply nested they are  ;We're almost done.  !;(define (count-files-in-lod lod) ; (cond ; [(empty? lod) ...] -; [else (... (count-files (first lod)) ... 3; ... (count-files-in-lod (rest lod)))]))   =;We can now finish implementing this function by writing the  9"answer" in the first cond-line, and combining values to .complete the "answer" in the second cond-line. !;(define (count-files-in-lod lod) ; (cond ; [(empty? lod) 0] ; [else (+  %; (count-files (first lod)) /; (count-files-in-lod (rest lod)))]))   :;S-9: RETURN TO THE VERSION OF 'count-files' IN S-7, AND -GIVE 'func-for-a-list-of-dirs' ITS REAL NAME. ;(define (count-files d) ); (... (length (dir-files d)) ...   ; ... (,func-for-a-list-of-dirs (dir-dirs d)) ...))  ;-> ;(define (count-files d) ); (... (length (dir-files d)) ...  /; ... (count-files-in-lod (dir-dirs d)) ...))  ;S-10: NOW WE COMBINE RESULTS. ;(define (count-files d) ; (+ !; (length (dir-files d))  '; (count-files-in-lod (dir-dirs d))))   ";;;HERE IS THE FINISHED PROGRAM:   ;count-files: dir -> num  ;;Returns the number of files in the directory structure d, %no matter how deeply nested they are.  (define (count-files d)  (+  (length (dir-files d)) & (count-files-in-lod (dir-dirs d))))  (;count-files-in-lod: list-of-dirs -> num  :;Returns the number of files in all of the directories in )lod, no matter how deeply nested they are   (define (count-files-in-lod lod)  (cond  [(empty? lod) 0]  [else (+  $ (count-files (first lod)) . (count-files-in-lod (rest lod)))]))  ";Now we run the examples as tests. ';(count-files vacant-dir) "should be" 0 &;(count-files DIRECTORY) "should be" 7 #;(count-files plt) "should be" 6038  5;What to notice about the process we've gone through:   5;The shape of the functions mirrors the shape of the  6templates, which in turn mirror the shape of the data  7definitions. There is a reference in 'count-files' to  )'count-files-in-lod', and a reference in  3'count-files-in-lod' to 'count-files' as well as a self-reference.   8;Each function calls the other, and the second function  Here are the data definitions and contracts for the  functions we need, and examples:  ;du-dir: dir-> num  :;Returns the total size of all the files in the directory  structure d.   ;Examples ";(du-dir vacant-dir) "should be" 0 $;(du-dir DIRECTORY) "should be" 1170 #;(du-dir plt) "should be" 109468078   ;lof-size: list-of-files -> num ;;Returns the total size of all the files in a list-of-files   $;du-dirs-in-lod: list-of-dirs -> num  <;Returns the total size of all the files in all the dirs in a list-of-dirs    :;----> Now the templates, with appropriate parameter- and  7function-names substituted for generic names, and with !unneeded information highlighted:  ;du-dir: dir-> num  :;Returns the total size of all the files in the directory  structure d  ;(define (du-dir d) ; (... ! (dir-name d) ... +; ... (lof-size (dir-files d)) ...  +; ... (du-dirs-in-lod (dir-dirs d)) ...))   ;lof-size: list-of-files -> num ;;Returns the total size of all the files in a list-of-files   ;;Questions: What do we want 'func-for-file' to do in this +case? Do we have a function that does that? ;(define (lof-size lof) ; (cond ; [(empty? lof) ...] ; [else (... (" func-for-file (first lof)) ... ); ... (lof-size (rest lof)))]))  ;(define (lof-size lof) ; (cond ; [(empty? lof) ...] +; [else (... (file-size (first lof)) ... ); ... (lof-size (rest lof)))]))   $;du-dirs-in-lod: list-of-dirs -> num  <;Returns the total size of all the files in all the dirs in a list-of-dirs.  ;(define (du-dirs-in-lod lod) ; (cond ; [(empty? lod) ...] (; [else (... (du-dir (first lod)) ... /; ... (du-dirs-in-lod (rest lod)))]))    =;---->Finally, to get the finished program, we just complete  =the answer in the first line of the cond, and combine values %to get the answer in the second line.  ;du-dir: dir-> num  :;Returns the total size of all the files in the directory  structure d  (define (du-dir d)  (+  (lof-size (dir-files d)) " (du-dirs-in-lod (dir-dirs d))))   ;lof-size: list-of-files -> num ;;Returns the total size of all the files in a list-of-files  (define (lof-size lof)  (cond  [(empty? lof) 0] $ [else (+ (file-size (first lof)) & (lof-size (rest lof)))]))   $;du-dirs-in-lod: list-of-dirs -> num  <;Returns the total size of all the files in all the dirs in a list-of-dirs  (define (du-dirs-in-lod lod)  (cond  [(empty? lod) 0] ! [else (+ (du-dir (first lod)) , (du-dirs-in-lod (rest lod)))]))  ;Tests ";(du-dir vacant-dir) "should be" 0 $;(du-dir DIRECTORY) "should be" 1170 #;(du-dir plt) "should be" 109468078   :;What if we want to locate a particular file or directory?   9;------> contracts, purpose-statements, examples for the functions we'll need:  ;find?: dir, sym -> bool  9;Reports whether or not a file or directory by the given name n is in the directory d   ;Examples .;(find? vacant-dir 'any.txt) "should be" false +;(find? DIRECTORY 'h.txt) "should be" false *;(find? DIRECTORY 'b.txt) "should be" true );(find? plt 'lander.ss) "should be" false %;(find? plt 'dir.ss) "should be" true  (;find-in-lof?: list-of-files,sym -> bool  =;Reports whether one of the files in a list-of-files has the  given name n  (;find-in-lod?: list-of-dirs, sym -> bool  9;Reports whether or not a file or directory by the given  templates for the three functions, with parameter- and function-names substituted  ;(define (find? d n) ; (... (dir-name d) ... .; ... (find-in-lof? (dir-files d) n)  '; ... (find-in-lod? (dir-dirs d) n)))  ;(define (find-in-lof? lof n) ; (cond ; [(empty? lof) ...] +; [else (... (file-name (first lof)) ... /; ... (find-in-lof? (rest lof) n))]))  !;Where did 'file-name' come from?  ;(define (find-in-lod? lod n) ; (cond ; [(empty? lod) ...] %; [else (... (find? (first lod) n) /; ... (find-in-lod? (rest lod) n))]))   8;What are the differences, at this stage, between these  7templates and the templates for the two programs we've written?   6;Values combined in the template ---> finished program  ;find?: dir, sym -> bool  9;Reports whether or not a file or directory by the given name n is in the directory d  (define (find? d n)  (or (symbol=? (dir-name d) n) $ (find-in-lof? (dir-files d) n) % (find-in-lod? (dir-dirs d) n)))   (;find-in-lof?: list-of-files,sym -> bool  =;Reports whether one of the files in a list-of-files has the  given name n  (define (find-in-lof? lof n)  (cond  [(empty? lof) false] 2 [else (or (symbol=? (file-name (first lof)) n) - (find-in-lof? (rest lof) n))]))   (;find-in-lod?: list-of-dirs, sym -> bool  9;Reports whether or not a file or directory by the given  shape-of-template -> 2shape-of-function that processes this kind of data   ;;;;ADDING EVEN MORE DETAILS;;;;   5;We can make our abstraction as useful as we want by  6returning to it as often as we want and progressively  refining it.  <;We know how to ask whether a particular file is present in the directory.  3;What if we wanted to find the *largest* file in a directory-system?  ;largest-file: dir -> num  8;Returns the size of the largest file that can be found  ;anywhere in the directory heirarchy rooted at directory d; !if there are no files, returns 0.  ;(define (largest-file d) ; ...)   6;Using the design recipe as we have, try writing this program.  ;Examples/Tests (;(largest-file vacant-dir) "should be" 0 );(largest-file DIRECTORY) "should be" 400    =;Sometimes we want to know the path to a specified directory or file.  ";find: dir, sym -> list-of-strings  :;Returns a list containing the full pathname of all files 7and directories of the given name in the directory tree  (define (find dir name)  ...)   ;;How would you go about designing a program to do what you want, in this case?  ;Examples/Tests -;(find vacant-dir 'any.txt) "should be" empty  8;(find DIRECTORY 'a.txt) "should be" (list "test/a.txt" "test/one/first/a.txt") 8;(find DIRECTORY 'b.txt) "should be" (list "test/b.txt")  8;(find DIRECTORY 'c.txt) "should be" (list "test/c.txt" "test/one/second/c.txt")  +;(find DIRECTORY 'd.txt) "should be" (list "test/one/first/d.txt")  +;(find DIRECTORY 'e.txt) "should be" (list "test/three/e.txt") *;(find DIRECTORY 'f.txt) "should be" empty