Created
April 8, 2012 01:50
-
-
Save gberenfield/2333594 to your computer and use it in GitHub Desktop.
Fantasy Banking week 3-2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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