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.

Reply via email to