(define (wages emp)
  (* (string->number (cadr emp))
     (string->number (caddr emp))))

(define (string-trim-left s)
  (let ((c (string-ref s 0)))
    (if (char-whitespace? c)
        (string-trim-left
          (substring s 1
            (string-length s)))
        s)))

(define (string-trim-right s)
  (let* ((len (- (string-length s) 1))
         (c (string-ref s len)))
    (if (char-whitespace? c)
        (string-trim-right
          (substring s 0 len))
        s)))

(define (string-trim s)
  (string-trim-left (string-trim-right s)))

(define (a-cons key value a-list)
  (cons (cons key value) a-list))

(define (a-sort lt? a-list)
  (define (foldl op base lst)
    (if (null? lst) base
      (foldl op (op base (car lst)) (cdr lst))))
  (define (insert lst x)
    (cond ((null? lst) (list x))
          ((lt? (car x) (caar lst)) (cons x lst))
          (else (cons (car lst) (insert (cdr lst) x)))))
  (foldl insert '() a-list))

(define emp-data-fixed
  (let ((out (open-output-string)))
    (with-input-from-file "emp.data"
      (lambda ()
        (for-each-port
          read-delim-record
          (lambda (emp)
            (write-fixed-record emp 22
              '((0 5) (6 11) (12 14) (15 20)) out)))))
    (get-output-string out)))

(define emp-data-pipe
  (let ((out (open-output-string)))
    (with-input-from-file "emp.data"
      (lambda ()
        (for-each-port
          read-delim-record
          (lambda (emp)
            (write-delim-record
              emp #\| out)))))
    (get-output-string out)))

(define emp-data-newline
  (let ((out (open-output-string)))
    (with-input-from-file "emp.data"
      (lambda ()
        (for-each-port
          read-delim-record
          (lambda (emp)
            (write-delim-record
              emp #\newline out)))))
    (get-output-string out)))

(define emp-data-null
  (let ((out (open-output-string)))
    (with-input-from-file "emp.data"
      (lambda ()
        (for-each-port
          read-delim-record
          (lambda (emp)
            (write-delim-record
              emp out)))))
    (get-output-string out)))

(define emp-data-csv
  (let ((out (open-output-string)))
    (with-input-from-file "emp.data"
      (lambda ()
        (for-each-port
          read-delim-record
          (lambda (emp)
            (write-csv-record emp out)))))
    (get-output-string out)))

(define emp-data-tab
  (let ((out (open-output-string)))
    (with-input-from-file "emp.data"
      (lambda ()
        (for-each-port
          read-delim-record
          (lambda (emp)
            (write-name-value-record
              (a-cons "name" (list-ref emp 0)
              (a-cons "rate" (list-ref emp 1)
              (a-cons "hrs" (list-ref emp 2)
              (a-cons "dept" (list-ref emp 3) '()))))
              #\tab out)))))
    (get-output-string out)))

(and ; should return \#t

  (= 1344.5
    (let ((in (open-input-string emp-data-fixed)))
      (fold-port
        (lambda (port) (read-fixed-record 22 '((0 5) (6 11) (12 14) (15 20)) port))
        (lambda (base emp) (+ base (* (string->number (string-trim (list-ref emp 1)))
                                      (string->number (string-trim (list-ref emp 2))))))
        0
        in)))

  (= 1344.5
    (let ((in (open-input-string emp-data-pipe)))
      (fold-port
        (lambda (port) (read-delim-record #\| port))
        (lambda (base emp) (+ base (wages emp)))
        0
        in)))

  (= 1344.5
    (let ((in (open-input-string emp-data-newline)))
      (fold-port
        (lambda (port) (read-delim-record #\newline port))
        (lambda (base emp) (+ base (wages emp)))
        0
        in)))

  (= 1344.5
    (let ((in (open-input-string emp-data-null)))
      (fold-port
        (lambda (port) (read-delim-record port))
        (lambda (base emp) (+ base (wages emp)))
        0
        in)))

  (= 1344.5
    (let ((in (open-input-string emp-data-csv)))
      (fold-port
        (lambda (port) (read-csv-record port))
        (lambda (base emp) (+ base (wages emp)))
        0
        in)))

  (= 1344.5
    (let ((in (open-input-string emp-data-tab)))
      (fold-port
        (lambda (port) (read-name-value-record #\tab port))
        (lambda (base emp) (+ base (* (string->number (cdr (assoc "rate" emp)))
                                      (string->number (cdr (assoc "hrs" emp))))))
        0
        in))))

Follow

Get every new post delivered to your Inbox.

Join 616 other followers

%d bloggers like this: