Hi !
You could rewrite the code like that :
(defn get-percentage
([place total-count] (get-percentage :normal place total-count))
([mode place total-count]
(let [mode-fn (case mode
:high Math/ceil
:low Math/floor
:normal Math/round
(throw
(Exception. "ERROR: get-percentage [:high|:low|:normal] <PLACE>
<TOTAL_COUNT>")))]
(-> place (* 100.0) (/ total-count) mode-fn int))))
I don't know if it's really better, it just removes duplicated code.
You can separate the function in two :
(defn to-mode-fn [mode]
(if (keyword? mode)
(case mode :high Math/ceil
:low Math/floor
:normal Math/round
(throw (Exception. "ERROR: get-percentage [:high|:low|:normal]
<PLACE> <TOTAL_COUNT>")))
mode))
(defn get-percentage
([place total-count] (get-percentage :normal place total-count))
([mode-fn place total-count]
(-> place (* 100.) (/ total-count) (to-mode-fn mode-fn) int)))
;usage
(get-percentage :normal 10 100)
(get-percentage Math/floor 10 100)
Have a nice day,
Jon
On Thu, Feb 12, 2015 at 3:20 AM, Matching Socks <[email protected]>
wrote:
>
> There was also some discussion of this back in November, where Fluid
> Dynamics suggested higher-order functions, and tbc++, multimethods(!).
>
> The main source of complexity in get-percentage has to do with
> selecting what it should do. Also, both percentage computation and
> rounding could potentially be useful on their own without the other.
> Those considerations recommend higher order functions. Using
> higher-order functions can make the code shorter, clearer, and more
> flexible.
>
> First, there's the essential computation:
>
> (defn pct [p t] (/ (* p 100.0) t))
>
> Second, various general-purpose ways to round floating-point numbers:
>
> (defn round-up [x] (int (Math/ceil x)))
> (defn round-down [x] (int (Math/floor x)))
> (defn round [x] (int (Math/round x)))
>
> To put them together, get-percentage took a hint about the rounding
> function, dispatched on the hint, and took upon itself responsibility
> for detecting a bogus hint. Instead of a hint from a closed set, why
> not let the caller pass in the rounding function itself? Now
> get-percentage is down to one line:
>
> (defn get-percentage* [f p t] (f (pct p t)))
>
> For example
>
> (get-percentage* round-up 4 30)
> 14
> (get-percentage* round-down 4 30)
> 13
>
> Alternatively, the standard function "comp" can produce your canned
> combinations, so you might not need get-percentage* itself anymore:
>
> (def get-percentage-high (comp round-up pct))
>
> For example:
>
> (get-percentage-high 4 30)
> 14
>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to [email protected]
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> [email protected]
> 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 [email protected].
> For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
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 [email protected].
For more options, visit https://groups.google.com/d/optout.