Created
April 13, 2012 15:35
-
-
Save gberenfield/2377760 to your computer and use it in GitHub Desktop.
Fantasy Banking week 4 using Swing
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.week4-1 | |
(:require clojure.string) | |
(:import (org.slf4j.impl.StaticLoggerBinder)) | |
(:import (javax.swing JFrame JPanel JButton JLabel JTextField JTextArea JScrollPane)) | |
(:import java.awt.event.ActionListener) | |
(:import (javax.swing.event DocumentListener)) | |
(:import (java.awt GridBagLayout GridBagConstraints Dimension)) | |
(:import (java.util.concurrent TimeUnit))) | |
(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 [] | |
(let [s (cons (str "Overall Overdraft balance: " @overall-overdraft "\n\n") (map #(format "%s %.2f and %d transactions\n" (:type %1) (:bal %1) (:transaction-count %1)) @accounts))] | |
(clojure.string/join s ))) | |
(defn go [n] | |
(create-accounts n) | |
(dotimes [i (* 100 n)] | |
(create-transaction (rand-int (count @accounts)))) | |
(show-accounts)) | |
(defn run-bank [item sp n] | |
(. item addActionListener | |
(proxy [java.awt.event.ActionListener] [] | |
(actionPerformed [e] (.setViewportView sp (JTextArea. (go (Integer/parseInt (.getText n))))))))) | |
(defn gui [] | |
(let [panel (JPanel. (GridBagLayout.)) | |
sp (JScrollPane.) | |
n (JTextField. 2) | |
button (JButton. "Run") | |
c (GridBagConstraints.) | |
_ (set! (. c gridx) 0) | |
_ (set! (. c gridy) 0)] | |
(doto sp | |
(.setVerticalScrollBarPolicy JScrollPane/VERTICAL_SCROLLBAR_ALWAYS) | |
(.setPreferredSize (Dimension. 350 200)) | |
(.setMinimumSize (Dimension. 100 100))) | |
(doto panel | |
(.add (JLabel. "# of accounts") c) | |
(do (set! (. c gridx) 1) (set! (. c gridy) 0)) | |
(.add n c) | |
(do (set! (. c gridx) 2) (set! (. c gridy) 0)) | |
(.add button c) | |
(do (set! (. c gridx) 0) (set! (. c gridy) 2)) | |
(.add sp c)) | |
(run-bank button sp n) | |
(doto (JFrame. "Banking Fantasy") | |
(.setBounds 300 300 600 600) | |
(.setContentPane panel) | |
(.setVisible true)))) | |
(defn -main [] ; lein trampoline run | |
(gui)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment