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 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)]]
;; -- 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)
@ -77,6 +80,12 @@
;; read the specified file as a list of lines, each line as a list of words
(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 lines (read-chunks f *read-line (lambda (x) x)))
(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-draw.rkt
run -t batch-io.rkt
run -t batch-io2.rkt
run -t batch-io3.rkt
run clause-once.rkt
run full-scene-visible.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"].
}
@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)
(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.
}
@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}
@examples[#:eval (examples-batch-io)