Fork me on GitHub
#beginners
<
2023-11-24
>
marc12:11:47

Hi. I am messing around with [plumatic/schema](https://github.com/plumatic/schema) to define a schema for an API to use in [martian](https://github.com/oliyh/martian). How can I set a String value that when nil should be coerced to an empty string?

marc12:11:31

(def brevo-attributes-schema
  {(s/optional-key :NOMBRE) s/Str
   (s/optional-key :FISCAL_GRIST) s/Bool
   (s/optional-key :PERIODICIDAD_DOCS) s/Str})
So, I want the s/Str fields to "know" that when passing nil I want an empty String. Of course, passing the empty String to begin with is an option!

delaguardo12:11:46

https://plumatic.github.io//schema-0-2-0-back-with-clojurescript-data-coercion this article might be helpful. However, adding custom coercers to schema wasn't a pleasant experience for me. IMHO it is much easier to do in malli than schema

💯 1
marc12:11:48

Thanks for the link. I guess I'll just pass an empty String and be done with it!

Aleix Morgadas16:11:07

Is there an equivalent way to create a clojure project with clj like with lein new project?

Aleix Morgadas16:11:29

I found clojure -Tclj-new app :name myname/myapp but I expected the command to be part of clj

Aleix Morgadas16:11:33

I will check it! ty!

Aleix Morgadas16:11:46

Now I'm trying to run the tests within emacs cider but it says no test tu run 😂

Aleix Morgadas16:11:49

If I execute the file with C-c C-k it works, but using C-c C-t p it doesn't

Ed17:11:20

I tend to use C-c C-t C-n to run all the tests in the current namespace. I'll usually rely on a terminal or CI to run all the tests in a project.

practicalli-johnny17:11:22

Crating a Clojure CLI project is very simple, it only requires a deps.edn file with an empty hash-map. clj-new will use existing Leiningen templates, so of which provide a deps.edn configuration deps-new creates Clojure CLI specific projects and is a simple way to create your own templates (as I did with the Practicalli project templates) https://practical.li/clojure/clojure-cli/projects/templates/

1
mrnhrd22:11:16

I'm feeling very silly right now: In AoC 2022 day8p2 I've got a list of numbers [1 3 5 2 1] and a given height 5 and I want to get to the result [1 3 5]. (in order to then do count on that, but that's secondary) I.e. get all elements until we arrive at a value equal or bigger to 5, including that value. I'm trying to do wrangle partial and take-while to do that but I'm not sure it's possible: The 5 needs to be the value on which we stop counting, but it also needs to be included in the result.

mrnhrd22:11:27

I've tried with the take-until impl here: https://clojure.atlassian.net/browse/CLJ-1451?focusedCommentId=15186 as well, but couldn't get it do to that thing either. Do I have to write its own logic for this?

hiredman22:11:21

If you just need the count, do take-while then count and inc

mrnhrd22:11:49

Ah, but then it doesn't work for other inputs:

(t/with-test
    (defn score [height neighbour-list]
      (-> (take-while (partial > height) neighbour-list)
          (count)))
    (t/is (= 1 (score 5 [3])))
    (t/is (= 0 (score 5 [])))
    (t/is (= 2 (score 5 [1 5 3]))))
add inc to the end -> [3] and [] inputs break.

Pavel Klavík22:11:21

You can also write it with a reduce. It can be stopped in the middle by wrapping the result by reduced function.

hiredman22:11:45

Or iteration

hiredman22:11:24

(although you'll need to reduce or count after that I guess)

seancorfield22:11:59

There's #C0GLTDB2T specifically for discussing AoC problems. Just FYI.

mrnhrd23:11:57

Thanks Sean, I'm aware of that channel and tried staring at other people's solution too (perhaps I should go to bed, can't really think anymore 💤). Would that have been more appropriate to post in?

seancorfield23:11:26

I mention it because AoC 2023 starts next week and we'll be "strongly encouraging" people to use that channel instead of posting AoC stuff in #C053AK3F9 or #C03S1KBA2 (it used to get a bit overwhelming before we guided people to #C0GLTDB2T)

👍 1
Jason Bullers23:11:50

The approach I took on this one was to split-at and destructure the result:

(let [[prev [curr & nxt]] (split-at n tree-heights) ...)

gratitude 1
🙀 1
👏 1
Jason Bullers23:11:02

That gives me prev [1 3] curr 5 and nxt [2 1]. I then combine (and reverse) as necessary for the calculations

kennytilton01:11:38

Ah, the "at" in split-at has to be a test, #(>= % n). Test with [1 3 6 2 1]. Should return [1 3 6] given 5.

Jason Bullers01:11:27

@U0PUGPSFR I think you're thinking of split-with

seancorfield05:11:14

user=> (doc split-at)
-------------------------
clojure.core/split-at
([n coll])
  Returns a vector of [(take n coll) (drop n coll)]
nil
Splits at a position, not a value.

oddsor10:11:11

Since the value we “take until” needs to be included I guess a reduce is better for this? thinking-face

(reduce 
  (fn [acc x] 
    (let [xs (conj acc x)]
      (if (= 5 x)
        (reduced xs)
        xs))) 
  []
  [1 3 5 2 1])

mrnhrd10:11:11

Medley's take-upto was up to the task 🙂 https://weavejester.github.io/medley/medley.core.html edit: that "`upto` was up to" pun wasn't intentional I swear.

👀 1
👍 1
pavlosmelissinos10:11:19

For what it's worth, I had to do this at some point and decided to take the implementation of clojure.core/take-while and just make it include the first item that fails the condition:

(defn take-while+1
  "Returns a lazy sequence of successive items from coll while
  (pred item) returns logical true and keeps the next item.
  pred must be free of side-effects."
  [pred coll]
  (lazy-seq
   (when-let [s (seq coll)]
     (if (pred (first s))
       (cons (first s) (take-while+1 pred (rest s)))
       (cons (first s) [])))))

(comment
  (take-while+1 #(<= % 5) [-1 2 4 6 1]) ;; => (-1 2 4 6)
  (take-while+1 #(<= % 5) [3])          ;; => (3)
  (take-while+1 #(<= % 5) [])           ;; => ()
  ,)
edit: I like medley's implementation more though, I might steal that 😄

Ed13:11:48

you can use halt-when for this too ...

(->> [1 2 3 5 2 1]
       (transduce (halt-when #(= % 5) conj) conj)) ;; => [1 2 3 5]

👀 2
seancorfield18:11:23

(again, that needs <= rather than = unless you're guaranteed that the maximum height you're looking for is definitely in your sequence of numbers -- but that look like a nice modern solution)

facepalm 1
👍 2