Skip to content

Instantly share code, notes, and snippets.

@gberenfield
Created April 8, 2012 01:50
Show Gist options
  • Save gberenfield/2333594 to your computer and use it in GitHub Desktop.
Save gberenfield/2333594 to your computer and use it in GitHub Desktop.
Fantasy Banking week 3-2
(ns codelesson.week3-2)
(def fees { :checking {:interest 0.02 :overdraft 0.10}
:savings {:interest 0.04 :overdraft 0.075}
:money-market {:interest 0.06 :overdraft 0.05}})
(def overall-overdraft (atom 100000))
(def accounts (atom []))
(defn random-account-type []
(rand-nth [:checking :savings :money-market]))
(defn random-account-age []
(rand-int 11))
(defn bonus [account]
(let [age (:age account) bal (:bal account) rate (:interest ((:type account) fees))]
(cond
(< age 2) 0
(and (<= age 5) (>= age 2) (< bal 500)) (/ rate 32)
(and (<= age 5) (>= age 2) (>= bal 500)) (/ rate 24)
(and (> age 5) (< bal 500)) (/ rate 16)
(and (> age 5) (>= bal 500)) (/ rate 8))))
(defn create-accounts [n]
(dotimes [i n]
(swap! accounts conj {:type (random-account-type) :bal 500 :age (random-account-age)
:transaction-count 0 :overall-overdraft-charges 0})))
(defn update! [n k v]
(let [acct (get @accounts n) new-acct (assoc acct k v)]
(swap! accounts assoc n new-acct )))
(defn process-overdraft [n amt]
(let [acct (get @accounts n) bal (:bal acct)
overdraftcharge (* amt (:overdraft ((:type acct) fees)))
full-charge (+ overdraftcharge amt)
new-bal (- bal full-charge)]
(if (<= @overall-overdraft 0)
(update! n :overall-overdraft-charges (+ 10 (:overall-overdraft-charges acct)))
(if (>= new-bal -1000)
(do
(update! n :bal new-bal)
(swap! overall-overdraft - amt))))))
(defn bonus-eligible? [account]
(and (> (:bal account) 0) (= 0 (mod (:transaction-count account) 10))))
(defn interest-eligible? [account]
(and (> (:bal account) 0) (= 0 (mod (:transaction-count account) 25))))
(defn overdrawn? [acct amt]
(or (< (:bal acct) 0) (< (- (:bal acct) amt) 0)))
(defn process-withdrawel [n amt]
(let [acct (get @accounts n)]
(if (overdrawn? acct amt)
(process-overdraft n amt)
(update! n :bal (- (:bal acct) amt)))))
(defn process-deposit [n amt]
(let [acct (get @accounts n)]
(if (overdrawn? acct amt)
(do
(update! n :bal (+ amt (:bal acct)))
(swap! overall-overdraft + amt))
(update! n :bal (+ amt (:bal acct))))))
(defn create-transaction [n]
(let [amt (rand-nth (range 100 510 10)) acct (get @accounts n)
withdrawel? (fn [] (= :withdrawel (rand-nth [:deposit :withdrawel])))]
(update! n :transaction-count (inc (:transaction-count acct)))
(if (withdrawel?)
(process-withdrawel n amt)
(process-deposit n amt))
(if (bonus-eligible? acct)
(update! n :bal (+ (* (bonus acct) (:bal acct)) (:bal acct))))
(if (interest-eligible? acct)
(update! n :bal (+ (* (:interest ((:type acct) fees)) (:bal acct)) (:bal acct))))))
(defn show-accounts []
(doseq [i @accounts]
(println (:type i) (format "%.2f and %d transactions" (:bal i) (:transaction-count i))))
(println "\nOverall Overdraft balance: "@overall-overdraft))
(defn go [n]
(create-accounts n)
(dotimes [i (* 100 n)]
(create-transaction (rand-int (count @accounts))))
(show-accounts))
(defn -main[n] ; lein trampoline run 10
(go (Integer/parseInt n)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment