one more reader, plus shortened the names of the functions

This commit is contained in:
Matthias Felleisen 2010-04-16 10:49:21 -04:00
parent da312ac680
commit a2af09a445
3 changed files with 72 additions and 52 deletions

View File

@ -11,28 +11,31 @@
;; -- f must be a file name (string) in the same folder as the program ;; -- f must be a file name (string) in the same folder as the program
read-file ;; String -> String read-file ;; String -> String
;; read the file f as a string ;; read the specified file as a string
read-file-as-lines ;; String -> [Listof String] read-as-1strings ;; String -> [Listof 1String]
;; read the file f as a list of strings, one per line ;; read the specified file as a list of 1strings (characters)
read-file-as-words ;; String -> [Listof String]
;; read the file f as a list of white-space separated tokens
read-file-as-1strings ;; String -> [Listof 1String]
;; read the file f as a list of 1strings (characters)
read-file-as-csv ;; String -> [Listof [Listof (U Any)]] read-as-lines ;; String -> [Listof String]
;; -- f must be formated as a a file with comma-separated values (Any) ;; read the specified file as a list of strings, one per line
;; read the file f as a list of lists---one per line---of values (Any)
read-file-as-csv/rows ;; String ([Listof Any] -> X) -> [Listof X] read-as-words ;; String -> [Listof String]
;; read the specified file as a list of white-space separated tokens
read-as-words/line ;; String -> [Listof [Listof String]]
;; read the specified file as a list of lines, each line as a list of words
read-as-csv ;; String -> [Listof [Listof (U Any)]]
;; -- f must be formated as a a file with comma-separated values (Any) ;; -- f must be formated as a a file with comma-separated values (Any)
;; read the file f as a file of comma-separated values, apply the second ;; read the specified file as a list of lists---one per line---of values (Any)
read-as-csv/rows ;; String ([Listof Any] -> X) -> [Listof X]
;; -- f must be formated as a a file with comma-separated values (Any)
;; read the specified file as a file of comma-separated values, apply the second
;; argument to each row, i.e., list of CSV on one line ;; argument to each row, i.e., list of CSV on one line
write-file ;; String String -> Boolean write-file ;; String String -> Boolean
;; write the second argument to file f in the same folder as the program ;; write the second argument to specified file in the same folder as the program
;; produce false, if f exists ;; produce false, if f exists
;; produce true, if f doesn't exist ;; produce true, if f doesn't exist
) )
@ -51,22 +54,27 @@
(def-reader (read-file f) (def-reader (read-file f)
(list->string (read-chunks f read-char drop-last-newline))) (list->string (read-chunks f read-char drop-last-newline)))
(def-reader (read-file-as-1strings f) (def-reader (read-as-1strings f)
(map string (read-chunks f read-char drop-last-newline))) (map string (read-chunks f read-char drop-last-newline)))
(def-reader (read-file-as-lines f) (def-reader (read-as-lines f)
(read-chunks f read-line reverse)) (read-chunks f read-line reverse))
(def-reader (read-file-as-words f) (def-reader (read-as-words f)
(define lines (read-chunks f read-line reverse)) (define lines (read-chunks f read-line reverse))
(foldr (lambda (f r) (append (split f) r)) '() lines)) (foldr (lambda (f r) (append (split f) r)) '() lines))
(def-reader (read-file-as-csv f) (def-reader (read-as-words/line f)
(read-file-as-csv/func f)) ;; String -> [Listof [Listof String]]
;; read the specified file as a list of lines, each line as a list of words
(map split (read-chunks f read-line reverse)))
(def-reader (read-file-as-csv/rows f row) (def-reader (read-as-csv f)
(check-proc 'read-file-as-cvs row 1 "one argument" "row") (read-as-csv/func f))
(read-file-as-csv/func f row))
(def-reader (read-as-csv/rows f row)
(check-proc 'read-as-cvs row 1 "one argument" "row")
(read-as-csv/func f row))
;; ----------------------------------------------------------------------------- ;; -----------------------------------------------------------------------------
;; writer ;; writer
@ -84,7 +92,7 @@
;; auxiliaries ;; auxiliaries
;; String [([Listof X] -> Y)] -> [Listof Y] ;; String [([Listof X] -> Y)] -> [Listof Y]
(define (read-file-as-csv/func f [row (lambda (x) x)]) (define (read-as-csv/func f [row (lambda (x) x)])
(local ((define (reader o) (local ((define (reader o)
(make-csv-reader o '((strip-leading-whitespace? . #t) (make-csv-reader o '((strip-leading-whitespace? . #t)
(strip-trailing-whitespace? . #t))))) (strip-trailing-whitespace? . #t)))))

View File

@ -25,14 +25,14 @@ eos
(check-true (string=? (read-file file) test2) "read-file 2") (check-true (string=? (read-file file) test2) "read-file 2")
(write-file file test1) (write-file file test1)
(check-equal? (read-file-as-lines file) (list test1) "as-lines 1") (check-equal? (read-as-lines file) (list test1) "as-lines 1")
(write-file file test2) (write-file file test2)
(check-equal? (read-file-as-lines file) test2-as-list "as-lines 2") (check-equal? (read-as-lines file) test2-as-list "as-lines 2")
(define as-1strings1 (map string (string->list test1))) (define as-1strings1 (map string (string->list test1)))
(write-file file test1) (write-file file test1)
(check-equal? (read-file-as-1strings file) as-1strings1 "as-1strings 1") (check-equal? (read-as-1strings file) as-1strings1 "as-1strings 1")
(define as-1strings2 (define as-1strings2
(map string (map string
@ -43,7 +43,7 @@ eos
test2-as-list)))))) test2-as-list))))))
(write-file file test2) (write-file file test2)
(check-equal? (read-file-as-1strings file) as-1strings2 "as-lines 2") (check-equal? (read-as-1strings file) as-1strings2 "as-lines 2")
(define test3 #<< eos (define test3 #<< eos
word1, word2 word1, word2
@ -52,12 +52,15 @@ eos
) )
(write-file file test3) (write-file file test3)
(check-equal? (read-file-as-csv file) '(("word1" "word2") ("word3" "word4")) (check-equal? (read-as-words file) '("word1," "word2" "word3," "word4")
"as-cvs 1")
(check-equal? (read-file-as-csv/rows file length) '(2 2)
"as-words/rows")
(check-equal? (read-file-as-words file) '("word1," "word2" "word3," "word4")
"as-words") "as-words")
(check-equal? (read-as-words/line file) '(("word1," "word2") ("word3," "word4"))
"as-words")
(check-equal? (read-as-csv file) '(("word1" "word2") ("word3" "word4"))
"as-cvs 1")
(check-equal? (read-as-csv/rows file length) '(2 2)
"as-words/rows")
(check-exn exn:fail:contract? (lambda () (write-file 0 1))) (check-exn exn:fail:contract? (lambda () (write-file 0 1)))
(check-exn exn:fail:contract? (lambda () (write-file '("test") 1))) (check-exn exn:fail:contract? (lambda () (write-file '("test") 1)))
@ -66,8 +69,8 @@ eos
(check-exn exn:fail:contract? (lambda () (read-file 0))) (check-exn exn:fail:contract? (lambda () (read-file 0)))
(check-exn exn:fail:contract? (lambda () (read-file '("test")))) (check-exn exn:fail:contract? (lambda () (read-file '("test"))))
(check-exn exn:fail:contract? (lambda () (read-file-as-lines 0))) (check-exn exn:fail:contract? (lambda () (read-as-lines 0)))
(check-exn exn:fail:contract? (lambda () (read-file-as-lines '("test")))) (check-exn exn:fail:contract? (lambda () (read-as-lines '("test"))))
(check-exn exn:fail:contract? (lambda () (read-file-as-1strings 0))) (check-exn exn:fail:contract? (lambda () (read-as-1strings 0)))
(check-exn exn:fail:contract? (lambda () (read-file-as-1strings '("test")))) (check-exn exn:fail:contract? (lambda () (read-as-1strings '("test"))))

View File

@ -56,36 +56,45 @@ assuming the file named @scheme["data.txt"] has this shape:
Note how the leading space in the second line translates into the space Note how the leading space in the second line translates into the space
between the newline indicator and the word @scheme["good"] in the result.} between the newline indicator and the word @scheme["good"] in the result.}
@item{@reading[read-file-as-lines (listof string?)]{a list of strings, one per line} @item{@reading[read-as-1strings (listof 1string?)]{a list of one-char strings, one per character}
@examples[#:eval (examples-batch-io) @examples[#:eval (examples-batch-io)
(read-file-as-lines "data.txt") (read-as-1strings "data.txt")
]
Note how this function reproduces all parts of the file faithfully,
including spaces and newlines.}
@item{@reading[read-as-lines (listof string?)]{a list of strings, one per line}
@examples[#:eval (examples-batch-io)
(read-as-lines "data.txt")
] ]
when @scheme["data.txt"] is the name of the same file as in the preceding when @scheme["data.txt"] is the name of the same file as in the preceding
item. And again, the leading space of the second line shows up in the item. And again, the leading space of the second line shows up in the
second string in the list.} second string in the list.}
@item{@reading[read-file-as-words (listof string?)]{a list of strings, one per white-space separated token in the file} @item{@reading[read-as-words (listof string?)]{a list of strings, one per white-space separated token in the file}
@examples[#:eval (examples-batch-io) @examples[#:eval (examples-batch-io)
(read-file-as-words "data.txt") (read-as-words "data.txt")
] ]
This time, however, the extra leading space of the second line of This time, however, the extra leading space of the second line of
@scheme["data.txt"] has disappeared in the result. The space is considered @scheme["data.txt"] has disappeared in the result. The space is considered
a part of the separator that surrounds the word @scheme["good"]. a part of the separator that surrounds the word @scheme["good"].
} }
@item{@reading[read-file-as-1strings (listof 1string?)]{a list of one-char strings, one per character} @item{@reading[read-as-words/line (listof string?)]{a list of lists, one per line; each line is represented as a list of white-space separated tokens}
@examples[#:eval (examples-batch-io) @examples[#:eval (examples-batch-io)
(read-file-as-1strings "data.txt") (read-as-words/line "data.txt")
] ]
Note how this function reproduces all parts of the file faithfully, The results is similar to the one that @scheme[read-as-words] produces,
including spaces and newlines.} except that the organization of the file into lines is preserved.
}
@item{@reading[read-file-as-csv (listof (listof any/c))]{a list of lists of comma-separated values} @item{@reading[read-as-csv (listof (listof any/c))]{a list of lists of comma-separated values}
@examples[#:eval (examples-batch-io) @examples[#:eval (examples-batch-io)
(read-file-as-csv "data.csv") (read-as-csv "data.csv")
] ]
where the file named @scheme["data.csv"] has this shape: where the file named @scheme["data.csv"] has this shape:
@(file-is "data.csv") @(file-is "data.csv")
@ -94,16 +103,16 @@ length. Here the third line of the file turns into a row of three
elements. elements.
} }
@item{@defproc[(@read-file-as-csv/rows [f (and/c string? file-exists?)][s @item{@defproc[(@read-as-csv/rows [f (and/c string? exists?)][s
(-> (listof any/c) X?)]) (listof X?)]{reads the content of file @scheme[f] and (-> (listof any/c) X?)]) (listof X?)]{reads the content of file @scheme[f] and
produces it as list of rows, each constructed via @scheme[s]} produces it as list of rows, each constructed via @scheme[s]}
@examples[#:eval (examples-batch-io) @examples[#:eval (examples-batch-io)
(read-file-as-csv/rows "data.csv" (lambda (x) x)) (read-as-csv/rows "data.csv" (lambda (x) x))
(read-file-as-csv/rows "data.csv" length) (read-as-csv/rows "data.csv" length)
] ]
The first example shows how @scheme[read-file-as-csv] is just a short form The first example shows how @scheme[read-as-csv] is just a short form
for @scheme[read-file-as-csv/rows]; the second one simply counts the for @scheme[read-as-csv/rows]; the second one simply counts the
number of separated tokens and the result is just a list of numbers. number of separated tokens and the result is just a list of numbers.
In many cases, the function argument is used to construct a structure from In many cases, the function argument is used to construct a structure from
a row.} a row.}