#lang racket (require racket/cmdline) (define dirname (command-line #:args (dn) dn)) ;;(displayln dirname) (define files (sort (for/list ((fn (in-directory dirname))) fn) (lambda (a b) (stringstring a) (path->string b))))) (define (load-balances fn) (define slst (with-input-from-file fn (thunk (for/list ((l (in-lines)) #:when (not (string-prefix? l "---"))) (map string-trim (string-split l "|")))))) (define header (car slst)) ;(writeln header) (define data0 (filter (lambda (l) (> (length l) 1)) (cdr slst))) (define data (for/list ((row (in-list data0))) (match-define (list id name acctype crbalance) row) (cons (string->number id) (string->number crbalance)))) (define name (car (reverse (explode-path fn)))) (cons name (make-immutable-hash (sort data (lambda (a b) (< (car a) (car b))))))) ;;(displayln (length files)) (define balances (time (for/list ((fn (in-list files))) (load-balances fn)))) ;;(displayln (length balances)) ;;(displayln "================") (define (calc-difference prev0 next0) (define prev (cdr prev0)) (define next (cdr next0)) (define pname (car prev0)) (define nname (car next0)) (define keys (set-union (list->set (hash-keys prev)) (list->set (hash-keys next)))) (define all (for/hash ((key (in-set keys))) (values key (- (hash-ref next key 0) (hash-ref prev key 0))))) (cons (cons pname nname) (for/hash (((k v) (in-hash all)) #:when (not (zero? v))) (values k v)))) (define (print-difference prev next) (define diff0 (calc-difference prev next)) (define diff (cdr diff0)) (define dname (car diff0)) (when (> (hash-count diff) 0) (displayln (format ":: ~a -> ~a" (car dname) (cdr dname))) (for (((k v) (in-hash diff))) (displayln (format "~a ~a" k (real->decimal-string v)))))) (for ((prev (in-list balances)) (next (in-list (cdr balances)))) (print-difference prev next))