document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. (ns ex.money
  2.   "Provides functions to parse bank statement JSON account data and
  3.  calculate current balances."
  4.   (:require [cheshire.core :as json]
  5.             [clojure.string :as str]))
  6.  
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8.  
  9. (defn as-currency
  10.   "Money amounts are transmitted as \\"$2.44\\".
  11.  Parse this and return a numeric type."
  12.   [currency-amount]
  13.   ;; strip off the leading "$"
  14.   (-> (subs currency-amount 1)
  15.       (bigdec)))
  16.  
  17. (defn sum-transactions [transactions]
  18.   (let [amounts (map :amount transactions)
  19.         currencies (map as-currency amounts)]
  20.     (reduce + currencies)))
  21.  
  22. (defn current-balance [accounts]
  23.   ;; Recursively loop over all accounts,
  24.   (loop [balance 0
  25.          accounts accounts]
  26.     (if (first accounts) ;; test to know when to end looping
  27.       (let [[account transactions] (first accounts)]
  28.         (recur (+ balance (sum-transactions transactions))
  29.                accounts))
  30.       balance)))
  31.  
  32. (defn convert-accounts [accounts-json]
  33.   (json/parse-string accounts-json true))
  34.  
  35. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  36.  
  37. (comment
  38.  
  39.   ;; A collection of accounts, each with a list of transactions.
  40.   ;; Formatted as a JSON string e.g. to mimic an API call response.
  41.   (def account-data-json
  42.     "{\\"savings\\":
  43.    [{\\"day\\":0,\\"amount\\":\\"$1200.20\\"},
  44.     {\\"day\\":22,\\"amount\\":\\"$0.03\\"}],
  45.  \\"checking\\":
  46.   [{\\"day\\":0,\\"amount\\":\\"$120.00\\"},
  47.    {\\"day\\":2,\\"amount\\":\\"$5.99\\"},
  48.    {\\"day\\":3,\\"amount\\":\\"$20\\"},
  49.    {\\"day\\":3,\\"amount\\":\\"$12.33\\"},
  50.    {\\"day\\":3,\\"amount\\":\\"-$4.50\\"},
  51.    {\\"day\\":5,\\"amount\\":\\"$30\\"}]}")
  52.  
  53.   ;; Exercise the code using this test data:
  54.   (-> account-data-json
  55.       convert-accounts
  56.       current-balance)
  57.  
  58.   ;; Code never completes...
  59.  
  60.   )
');