2015-02-14 12:33 GMT+01:00 Cecil Westerhof <cldwester...@gmail.com>: > > 2015-02-11 8:32 GMT+01:00 Cecil Westerhof <cldwester...@gmail.com>: > >> >> I needed a function to get the percentage as an int. Input is place and >> total-count. >> I want the normal definition (which is the default) and a high and low >> variant. >> >> I came up with the following code: >> (defn get-percentage >> ([place total-count] (get-percentage :normal place total-count)) >> ([mode place total-count] >> (let [percentage >> >> (/ (* place 100.0) total-count)] >> (condp = mode >> :high (int (Math/ceil percentage)) >> :low (int (Math/floor percentage)) >> :normal (int (Math/round percentage)) >> (throw (Exception. "ERROR: get-percentage >> [:high|:low|:normal] <PLACE> <TOTAL_COUNT>")))))) >> >> Is this a good version, or could it be done better? >> > > Everyone thanks for the comments. I did the following. > > I made three round functions: > (defn round [x] (int (Math/round x))) > (defn round-high [x] (int (Math/ceil x))) > (defn round-low [x] (int (Math/floor x))) > > And rewrote get-percentage to: > (defn get-percentage > ([place total-count] (get-percentage :normal place total-count)) > ([mode place total-count] > > (let [mode-fn (case mode > :high round-high > :low round-low > :normal round > (throw (Exception. > "ERROR: get-percentage [:high|:low|:normal] > <PLACE> <TOTAL_COUNT>")))] > (-> place (* 100.0) (/ total-count) mode-fn int)))) > > But I wanted to do it a little neater. > > I wrote a new round function: > (defn round > ([x] (round :normal x)) > ([mode x] > (println mode) > (println x) > (case mode > :high (Math/ceil x) > :low (Math/floor x) > :normal (Math/round x) > (throw (Exception. > "ERROR: round [:high|:low|:normal] <VALUE>"))))) > > Then I tried to rewrite get-percentage: > (defn get-percentage > ([place total-count] (get-percentage :normal place total-count)) > ([mode place total-count] > > (if-not (contains? #{:high :low :normal} mode) > (throw (Exception. > "ERROR: get-percentage [:high|:low|:normal] > <PLACE> <TOTAL_COUNT>"))) > (round mode (/ (* place 100.0) total-count)))) > > But this gives on the last line: > CompilerException java.lang.RuntimeException: Unable to resolve > symbol: in this context, > > When I put before that statement: > (println mode) > (println place) > (println total-count) > (println (/ place total-count)) > (println (/ (* place 100.0) total-count)) > > I get the same error on: > (println (/ place total-count)) > > What is happening here? > > I am using Clojure 1.6.0 on Linux. >
I have now something that is working OK I think. This is what it has become: (defmacro static-fn [f] `(fn [x#] (~f x#))) (defn round ([x] (round :normal x)) ([mode x] (let [fn (case mode :high (static-fn Math/ceil) :low (static-fn Math/floor) :normal (static-fn Math/round) (throw (Exception. "ERROR: round [:high|:low|:normal] <VALUE>")))] (long (fn x))))) (defn get-percentage ([place total-count] (get-percentage :normal place total-count)) ([mode place total-count] (if-not (contains? #{:high :low :normal} mode) (throw (Exception. "ERROR: get-percentage [:high|:low|:normal] <PLACE> <TOTAL_COUNT>"))) (round mode (/ (* place 100.0) total-count)))) I made two other handy functions: (defn round-precision [value precision] (let [multiplier (Math/pow 10.0 precision)] (/ (Math/round (* value multiplier)) multiplier))) (defn round-div-precision [dividend divisor precision] (round-precision (/ (float dividend) divisor) precision)) For example: (round-div-precision 22000 7 3) gives: 3142.857 and: (round-div-precision 22000 7 -3) gives: 3000.0 -- Cecil Westerhof -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.