added a function for parsing contest files more easily

This commit is contained in:
Matthias Felleisen 2012-12-26 19:28:46 -05:00
parent a15ae19d46
commit cdcbdfaf8c
4 changed files with 128 additions and 2 deletions

View File

@ -35,6 +35,9 @@
read-words/line ;; String -> [Listof [Listof String]] read-words/line ;; String -> [Listof [Listof String]]
;; read the specified file as a list of lines, each line as a list of words ;; read the specified file as a list of lines, each line as a list of words
read-words-and-numbers/line ;; String -> [Listof [Listof String]]
;; read the specified file as a list of lines, each line as a list of words
read-csv-file ;; String -> [Listof [Listof (U Any)]] read-csv-file ;; 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 specified file as a list of lists---one per line---of values (Any) ;; read the specified file as a list of lists---one per line---of values (Any)
@ -77,6 +80,12 @@
;; read the specified file as a list of lines, each line as a list of words ;; read the specified file as a list of lines, each line as a list of words
(read-words/line/internal f cons)) (read-words/line/internal f cons))
(def-reader (read-words-and-numbers/line f)
;; String -> [Listof [Listof (U String Number)]]
;; read the specified file as a list of lines, each line as a list of words and numbers
(read-words/line/internal f (lambda (line1 r)
(cons (for/list ((t (in-list line1))) (or (string->number t) t)) r))))
(define (read-words/line/internal f combine) (define (read-words/line/internal f combine)
(define lines (read-chunks f *read-line (lambda (x) x))) (define lines (read-chunks f *read-line (lambda (x) x)))
(foldl (lambda (f r) (foldl (lambda (f r)

View File

@ -0,0 +1,107 @@
#lang racket
;; test for pr11445
(require 2htdp/batch-io)
(define batch-io3
#<<eos
2
4 2
3 hamburger 3.00
2 cheeseburger 1.50
1 hamburger 1.00
1 fries 0.75
hamburger
fries
2 1
4 jackets 42.34
2 jackets 21.17
jackets
eos
)
(define batch-io3-expected
#<<eos
You sold 4 hamburgers for a total of $4.00.
You sold 1 fries for a total of $0.75.
You sold 6 jackets for a total of $63.51.
eos
)
(define batch-io3.sexpr
'((2)
(4 2)
(3 "hamburger" 3.00)
(2 "cheeseburger" 1.50)
(1 "hamburger" 1.00)
(1 "fries" 0.75)
("hamburger")
("fries")
(2 1)
(4 "jackets" 42.34)
(2 "jackets" 21.17)
("jackets")))
(with-output-to-file "batch-io3.txt"
#:exists 'replace
(lambda ()
(printf batch-io3)))
(define batch-io3.read
(read-words-and-numbers/line "batch-io3.txt"))
(with-handlers ((exn:fail:filesystem? void))
(delete-file "batch-io3.txt"))
;; ---------------------------------------------------------------------------------------------------
;; time to test results
(module+ test
(require rackunit)
(check-equal? batch-io3.read batch-io3.sexpr))
(module+ test
(define (split file n)
(values (drop file n) (take file n))))
(module+ test
;; String -> Void
;; read input, process queries, write output
(define (solution file-name)
;; S-expression [Dataset -> String] -> String
(define (input->output i)
(let loop ((ds# (first (first i))) (file (rest i)))
(cond
[(zero? ds#) ""]
[else
(let*-values ([(file sales-records# queries#) (apply values (rest file) (first file))]
[(file sales-records) (split file sales-records#)]
[(file queries) (split file queries#)])
(string-append (process-dataset sales-records queries) "\n" (loop (sub1 ds#) file)))])))
;; Dataset -> String
;; process one dataset
(define (process-dataset sales-records queries)
(foldr (λ (query r) (string-append (total-message sales-records (first query)) r)) "" queries))
;; [Listof [List Number String Number]] String -> String
;; compute query result and turn into string
(define (total-message sales-records query)
(define good* (filter (λ (sales-record) (string=? (second sales-record) query)) sales-records))
(define count (apply + (map first good*)))
(define value (apply + (map third good*)))
(format "You sold ~a ~a for a total of $~a.\n"
count (add-s query (length good*)) (real->decimal-string value 2)))
;; String Natural -> String
;; add s to string if plurality calls for it
(define (add-s str n)
(if (and (> n 1) (not (string=? (substring str (- (string-length str) 1)) "s")))
(string-append str "s")
str))
;; -- in -- ;; should be write-file from batch io
(with-output-to-string (λ () (printf (input->output batch-io3.sexpr)))))
(check-equal? (solution "don't care") batch-io3-expected))

View File

@ -15,6 +15,8 @@ run bad-draw.rkt
run error-in-tick.rkt run error-in-tick.rkt
run error-in-draw.rkt run error-in-draw.rkt
run -t batch-io.rkt run -t batch-io.rkt
run -t batch-io2.rkt
run -t batch-io3.rkt
run clause-once.rkt run clause-once.rkt
run full-scene-visible.rkt run full-scene-visible.rkt
run image-too-large.rkt run image-too-large.rkt

View File

@ -89,7 +89,7 @@ This time, however, the extra leading space of the second line of
a part of the separator that surrounds the word @racket["good"]. a part of the separator that surrounds the word @racket["good"].
} }
@item{@reading[read-words/line (listof string?)]{a list of lists, one per line; each line is represented as a list of white-space separated tokens} @item{@reading[read-words/line (listof string?)]{a list of lists, one per line; each line is represented as a list of strings}
@examples[#:eval (examples-batch-io) @examples[#:eval (examples-batch-io)
(read-words/line "data.txt") (read-words/line "data.txt")
@ -99,6 +99,14 @@ except that the organization of the file into lines is preserved.
In particular, the empty third line is represented as an empty list of words. In particular, the empty third line is represented as an empty list of words.
} }
@item{@reading[read-words-and-numbers/line (listof (or number? string?))]{a list of lists, one per line; each line is represented as a list of strings and numbers}
@examples[#:eval (examples-batch-io)
(read-words-and-numbers/line "data.txt")
]
The results is like the one that @racket[read-words/line] produces,
except strings that can be parsed as numbers are represented as numbers.}
@item{@reading[read-csv-file (listof (listof any/c))]{a list of lists of comma-separated values} @item{@reading[read-csv-file (listof (listof any/c))]{a list of lists of comma-separated values}
@examples[#:eval (examples-batch-io) @examples[#:eval (examples-batch-io)