-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
testing_ns.cljc
110 lines (94 loc) · 2.61 KB
/
testing_ns.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
(ns omni-trace.testing-ns)
(def coin-values
{:quarter 0.25
:dime 0.10
:nickel 0.05
:penny 1})
(defn- calc-coin-value
[coins]
(->> coins
(keep coin-values)
(apply +)))
(defn- round-to-pennies
"Because floating-point inaccuracy"
[v]
(-> v
(* 100)
Math/round
(/ 100.0)))
(defn- calc-change-to-return*
[amount-to-return coins]
(let [value (calc-coin-value coins)]
(cond
(= value amount-to-return) coins
(> value amount-to-return) nil
:else (->> coin-values
(map first)
(map #(conj coins %))
(keep #(calc-change-to-return* amount-to-return %))
first))))
(defn- calc-change-to-return
[machine selection]
(let [amount-to-return (-> machine
:coins-inserted
calc-coin-value
(- (:price selection))
round-to-pennies)]
(calc-change-to-return* amount-to-return [])))
(defn- get-selection
[machine button]
(-> machine
:inventory
button))
(defn valid-selection
[machine button]
(when-let [selection (get-selection machine button)]
(and (some-> selection :qty (>= 1))
(>= (-> machine
:coins-inserted
calc-coin-value)
(:price selection)))))
;; dispense item
;; decrement qty
;; return change
(defn process-transaction
[machine button]
(let [selection (get-selection machine button)]
(-> machine
(update-in [:inventory button :qty]
dec)
(assoc :dispensed
selection)
(assoc :coins-returned
(calc-change-to-return machine
selection))
(assoc :coins-inserted []))))
(defn show-err-message
[machine]
(assoc machine :err-msg true))
(def machine-init {:inventory {:a1 {:name :taco
:price 0.85
:qty 10}}
:coins-inserted []
:coins-returned []
:dispensed nil
:err-msg nil})
(defn insert-coin
[machine coin]
(update-in machine
[:coins-inserted]
conj
coin))
(defn press-button
[machine button]
(if (valid-selection machine button)
(process-transaction machine button)
(show-err-message machine)))
(defn retrieve-dispensed
[machine]
[(:dispensed machine)
(dissoc machine :dispensed)])
(defn retrieve-change-returned
[machine]
[(:change-returned machine)
(dissoc machine :change-returned)])