This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-10-05
Channels
- # beginners (46)
- # calva (89)
- # cider (24)
- # clara (7)
- # clj-kondo (36)
- # clojure (33)
- # clojure-australia (4)
- # clojure-dev (9)
- # clojure-europe (15)
- # clojure-israel (1)
- # clojure-nl (1)
- # clojure-uk (13)
- # clojurescript (55)
- # community-development (38)
- # conjure (1)
- # cryogen (12)
- # cursive (16)
- # data-science (4)
- # datomic (39)
- # events (2)
- # fulcro (5)
- # gorilla (3)
- # introduce-yourself (3)
- # jobs (9)
- # kaocha (5)
- # malli (16)
- # music (12)
- # off-topic (11)
- # polylith (4)
- # react (4)
- # reactive (1)
- # reagent (18)
- # remote-jobs (2)
- # reveal (2)
- # sci (4)
- # shadow-cljs (31)
- # timbre (4)
- # tools-build (70)
- # tools-deps (11)
- # vim (33)
- # xtdb (53)
Hi! I am working on https://exercism.org/tracks/clojure/exercises/interest-is-interesting, where I am supposed to calculate interest rate using BigDecimal. I am not able to get some of the tests to pass. There must be something that I am missing about multiplication and percentage with BigDecimal. Any help would be greatly appreciated! SRC
(defn interest-rate
"Get interest rate for balance"
[balance]
(cond (< balance 0) -3.213
(< balance 1000) 0.5
(< balance 5000) 1.621
:else 2.475)
)
(defn annual-balance-update
"Calculate balance update"
[balance]
(bigdec (* balance (+ (* (interest-rate balance) 0.01) 1)))
)
TEST
Test 1
(deftest annual-balance-update-large-positive-balance-test
(is (= 1016.210101621M (interest-is-interesting/annual-balance-update 1000.0001M))))
Result 1
Assertion failed:
Expected :920352587.26744292868451875M
Actual :920352587.267443M
Test 2
(deftest annual-balance-update-small-negative-balance-test
(is (= -0.12695199M (interest-is-interesting/annual-balance-update -0.123M))))
Result 2
Assertion failed:
Expected :-0.12695199M
Actual :-0.11904801M(defn annual-balance-update "Calculate balance update" [balance] ( balance (+ (bigdec ( (interest-rate balance) 0.01)) 1)))
Thank you!
you can use triple-backtick to get a multiline code fragment in slack 🙂
Hello, World!
Thank you Lennart, I edited my post according to your suggestion to make it easier to read.
Just for my understanding, the fix was to convert to bigdec earlier in the process so precision isn't lost?
I have a map of maps. I need the inner map where the value of a particular key matches a given string. Perhaps naively, I started with (filter #(= "string" (:key %)) map-of-maps)
. This does extract the correct map, but the result is a lazy seq now so I cannot use normal hashmap fns to work with the data contained within. As a workaround, I just used (into {} inner-map)
to get a hashmap back instead. It works, but it feels like I've gone roundabout by having the intermediate lazy seq.
{:k1 foo :k2 bar, :k3 {:inner-k1 foo, :inner-k2 "correct map", :inner-k3 bar}, :k4 quux, :k5 {:inner-k1 foo, :inner-k2 "wrong map", :inner-k3 bar}}
oh that did not let me fix the formatting
The outer map has some irrelevant key-value pairs. There is 1 singular inner map which is important, but is only denoted by the "important value"
inside the map.
sort of
i only want 1 of the inner maps.
the other inner maps will not have the same value at :inner-k2
Right, I was just about to say that your example input doesn't really match with what you're saying. 🙂
in that example, i need to extract :k3
's value, where :inner-k2
is "correct map"
In another case, i may need the map at :k5
instead, but that's another day
If you just want to avoid the intermediate lazy seq, you can use the transducer arity of into
:
user=> (def map-of-maps
{:k1 {}
:k2 {}
:k3 {:inner-k1 "foo" :inner-k2 "correct map" :inner-k3 "bar"}
:k4 {}
:k5 {:inner-k1 "foo" :inner-k2 "wrong map" :inner-k3 "bar"}})
#'user/map-of-maps
user=> (into {}
(filter (comp #{"correct map"} :inner-k2 val))
map-of-maps)
{:k3 {:inner-k1 "foo", :inner-k2 "correct map", :inner-k3 "bar"}}
However, whenever I find myself doing linear search, I start thinking about whether I should maybe restructure my data instead. One option is to index the input first and then look up the value by the index:
user=> (into {}
(map (juxt (comp :inner-k2 val) identity))
map-of-maps)
{nil [:k4 {}],
"correct map" [:k3 {:inner-k1 "foo", :inner-k2 "correct map", :inner-k3 "bar"}],
"wrong map" [:k5 {:inner-k1 "foo", :inner-k2 "wrong map", :inner-k3 "bar"}]}
user=> (peek (get *1 "correct map"))
{:inner-k1 "foo", :inner-k2 "correct map", :inner-k3 "bar"}
I'm not sure what approach to take. Something about producing an intermediate sequence seemed incorrect because I just need the single inner map with the correct key-value pair, and then will be using some of the values in that map.
Filtering a map does produce a sequence, but it is lazy, so it only computes as much as is needed. Putting something like
(->> (vals m)
(filter (comp #{"correct map"} :inner-k2))
first)
in a function so you can parametrize the key and value to match against.
This is functionally equivalent to a loop that stops as soon as it finds the correct map.so I shouldn't be concerned with the intermediate sequence, and just take more care to recognize when one will be generated
Thanks to both of you for clarifying some of these things for me!
Ideally you don't want to traverse data. Better than searching your data is querying it. But when restructuring like in the second example of @U4ZDX466T is impractical or has too much overhead, yes you shouldn't have to worry about intermediate lazy sequences.
I don't want to be doing this, but I received it from an API in this outlandish format
Then you can consider whether normalizing it in some way up front makes sense for further processing
And that would be like the example above, finding the kv i'm after and then turning that value into a key of a new map?
I wanted to get an id list according to a numeric string, I believe I'm doing the wrong map, do not know how to proceed, can someone help me
Mapping over the input string like above is a nice way to go about it. A substitution map ch->opt
can be built up like
(let [id-list [{:id "b" :option [2 4]} {:id "a" :option [1 3]}]
ch->opt (into {}
(map (fn [{:keys [id option]}]
(zipmap (map #(Character/forDigit % 10) option) (repeat id))))
id-list)]
(distinct (map ch->opt "1234")))
You might also prefer
(let [id-list [{:id "b" :option [2 4]} {:id "a" :option [1 3]}]
ch->opt (into {} (map (fn [{:keys [id option]}] (zipmap option (repeat id)))) id-list)]
(distinct (map ch->opt (map #(Integer/parseInt %) (str/split "1234" #"")))))
Thanks @UP82LQR9N @U024X3V2YN4 !! you saved me
Does anybody know good resources for Clojure live coding? I am still having trouble adapting to the Clojure way of programming and it would be nice if I could see someone implement a solution to a problem while hearing their thoughts going into the implementation? Any books, blogs, etc that can help in this regard are also highly appreciated
I did a pretty long live coding demo for London Clojurians a while back https://www.youtube.com/watch?v=gIoadGfm5T8 and their are a few shorter ones on my YouTube channel https://www.youtube.com/c/SeanCorfield_A
I think there's some videos linked from the Practicalli site as well. There are probably quite a few other videos out there from individuals.
I watched the above video and can recommend it! This is one Iquite enjoyed too: https://youtu.be/lU3awBr5C7E
Oh and I think there is a very friendly tutorial like channel that someone recommended recently: “on the code again”
The 4Clojure walkthrough videos are examples of thinking through code decisions, most challenges have several approaches to solving the problem https://youtube.com/playlist?list=PLpr9V-R8ZxiDB_KGrbliCsCUrmcBvdW16
Anyone know of a good Web3 library? I couldn’t find anything recent. I saw this but it hasn’t been updated in a while so idk if it still works. https://github.com/district0x/cljs-web3