This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-02
Channels
- # announcements (1)
- # architecture (1)
- # aws (21)
- # babashka (37)
- # beginners (173)
- # boot (12)
- # chlorine-clover (5)
- # cider (36)
- # clara (11)
- # clj-kondo (25)
- # clojure (128)
- # clojure-europe (7)
- # clojure-finland (3)
- # clojure-germany (2)
- # clojure-nl (57)
- # clojure-uk (23)
- # clojurescript (71)
- # clojurex (1)
- # core-async (30)
- # core-typed (5)
- # cursive (35)
- # datomic (8)
- # duct (4)
- # emacs (8)
- # exercism (41)
- # fulcro (116)
- # jackdaw (4)
- # jobs-discuss (6)
- # juxt (4)
- # kaocha (16)
- # leiningen (14)
- # malli (5)
- # observability (4)
- # off-topic (2)
- # pathom (19)
- # pedestal (29)
- # re-frame (64)
- # reitit (18)
- # ring (8)
- # shadow-cljs (3)
- # sql (13)
- # tools-deps (32)
- # tree-sitter (5)
- # yada (17)
Hi everybody, can you help me here?
How to have different main
for every lein profile?
I have got one -main function for DEV and one for TEST.
...
:profiles {:dev [:project/dev :profiles/dev]
:test [:project/test :profiles/test]
:profiles/dev {}
:profiles/test {}
:project/dev {:main xbimonitor2.dev
:source-paths ["src/clj"]}
:project/test {:main xbimonitor2.core
:source-paths ["src/clj"]}
:user {:plugins [[lein-classpath-jar "0.1.0"]]}}
:source-paths ["src/clj"]
:resource-paths ["resources"]
:repl-options {:init-ns xbimonitor2.core}
:plugins [[lein-environ "1.1.0"]
[lein-cljsbuild "1.1.7"]]
:cljsbuild {:builds
[{:id "default"
:source-paths ["src/cljs"]
:compiler {:output-to "resources/public/js/main.js"
:optimizations :whitespace
:pretty-print true}}]}
:main xbimonitor2.core)
When I run
lein with-profile dev run
It will run xbimonitor2.core and not xbimonitor2.dev.
What am I doing wrong?
Thanks!Is my understanding correct, that adding (require '[clojure.tools.trace :refer [trace-vars untrace-vars]])
to :injections
in Lein should make those two functions available in every namespace in every project?
hey guys, I have a quick question related to java interop please : I am playing with a Google text to speech now and I have the following code ;
(let [...
recognize-response (recognize speech-client config audio)
_ (log/info (class recognize-response))
speech-recognition-results (.getResultsList recognize-response)
_ (log/info (class speech-recognition-results))]
speech-recognition-results)
the related output for this is :
20-04-01 16:25:05 bigbeast INFO [backend.google:9] - class com.google.cloud.speech.v1.RecognizeResponse
20-04-01 16:25:05 bigbeast INFO [backend.google:11] - class java.util.Collections$UnmodifiableRandomAccessList
=>
[#object[com.google.cloud.speech.v1.SpeechRecognitionResult
0x5ceda460
"alternatives {\n transcript: \"skildre\"\n confidence: 0.7400255\n}\n"]]
My issue is : :thinking_face:
the first log line is displaying the correct class com.google.cloud.speech.v1.RecognizeResponse
I am retrieving from the call to recognize
fn :
20-04-01 16:25:05 bigbeast INFO [backend.google:9] - class com.google.cloud.speech.v1.RecognizeResponse
but then, when calling (.getResultsList recognize-response)
, I am supposed to get back a List<SpeechRecognitionResult>
, instead what I have is a log line displaying :
20-04-01 16:25:05 bigbeast INFO [backend.google:11] - class java.util.Collections$UnmodifiableRandomAccessList
which is exactly the problem since I have to extract some infos from this List<SpeechRecognitionResult>
. Is there something I am missing ? Do I have to type-hint/coerce something somewhere ?You are still getting back a list, which is a good thing. Did you try logging the contents of the list?
I have found a solution 😉 from an old post on clojurians https://clojurians-log.clojureverse.org/clojure-uk/2016-07-15
thanks a lot anyway @UJRDALZA5
Usually seq
need not be called explicitly. A lot of the core functions internally call seq
when needed.
For debugging purposes, you can call pr-str
on it, this is similar to calling .toString()
in Java.
Well, strictly speaking List<SpeechRecognitionResult>
is just what the java api guarantees. java.util.Collections$UnmodifiableRandomAccessList
implements List
and at runtime generics are erased. So that is correct
So you should be all set to go without any conversions. Most builtin functions will work, and failing that you can use the ones on List that are supported
Maybe a beginner question: I'm trying to use clojure.tools/logging
for logging. I found this blog post explaining what to do, except that I'm using version 2.13.1 of Log4j. Here's my project.clj:
(defproject chat-app "0.1.0-SNAPSHOT"
.....
:dependencies [[org.clojure/clojure "1.10.0"]
;; Logging ( )
[org.clojure/tools.logging "1.0.0"]
[org.apache.logging.log4j/log4j-core "2.13.1" :exclusions [javax.mail/mail
javax.jms/jms
com.sun.jmdk/jmxtools
com.sun.jmx/jmxri]]
.....
]
:main ^:skip-aot chat-app.core
:target-path "target/%s"
:jvm-opts ["-Dclojure.tools.logging.factory=clojure.tools.logging.impl/log4j2-factory"]
:profiles {:prod {:resource-paths ["config/prod"]}
:dev {:resource-paths ["config/dev"]}
:uberjar {:aot :all}
}
)
I have a log4j.properties file identical to the one in the blog post.
However, when I try to log anything, only nil
is returned. No log file is created either.Hi, suppose I have an array list created like so (def some-array-list (ArrayList.)), and it itself contains array-lists. I want to sort this some-array-list based on the first elements of the constituent array lists. How can I do that?
In Clojure at least, sorting a list of lists happens in that order. Compare first elements, if there is a tie, compare second elements and so on.
This is what I'm doing but it's really slow:
(defn largest-area-contour [contours hierarchy]
(loop [contour-index 0 largest-area-contour [0 0 0]]
(if-not (< contour-index (.width hierarchy))
largest-area-contour
(recur
(inc contour-index)
(let [contour (nth (vec contours) contour-index)
contour-area (->
contour
(cv/contour-area))]
(if (< (nth largest-area-contour 1) contour-area) ;; sort based on the second element
[contour contour-area contour-index]
largest-area-contour))))))
it would use a comparator, but I don't know how to create an instance of a comparator in clojure
You are doing so much Java interop, you run the risk of unintentionally converting data structures back and forth. Making the program very slow.
Did you look at projects like these? https://github.com/hellonico/origami
I basically tried to replicate this background removal technique: https://www.codepasta.com/computer-vision/2019/04/26/background-segmentation-removal-with-opencv-take-2.html
so I created my own function
(defn ->mat [vector type]
(let [mat (Mat. (Size. (count (nth vector 0)) (count vector)) type)]
(doseq [x (range (.width mat))
y (range (.height mat))
:let [data1 (nth (nth vector y) x)]]
(.put mat
(int y) (int x)
(double-array data1)))
mat))
To convert the Mat into a clojure vector and a similar ->vec function for the opposite.I don't know enough about image processing etc. to comment on what is the best approach.
Check this: https://clojuredocs.org/clojure.core/reify#example-542692d5c026201cdc32706f
okay. So an array list of array lists and need to sort by the i'th elements of the constituent array lists.
So this works, but only compares the first element,
(sort (comparator (fn [x y] (< (.get x 0) (.get y 0))))
[(java.util.ArrayList. [3 1 2]) (java.util.ArrayList. [1 2 3])])
;; => ([1 2 3] [3 1 2])
So for second, it would be
(sort (comparator (fn [x y] (< (.get x 1) (.get y 1))))
[(java.util.ArrayList. [3 1 2]) (java.util.ArrayList. [1 2 3])])
right?True, but what I was aiming for is a Clojuresque sort, where the tie is broken by comparing the next element and without converting the whole list to a Clojure PersistentList.
public int compareTo(Object o){
IPersistentVector v = (IPersistentVector) o;
if(count() < v.count())
return -1;
else if(count() > v.count())
return 1;
for(int i = 0; i < count(); i++)
{
int c = Util.compare(nth(i),v.nth(i));
if(c != 0)
return c;
}
return 0;
}
(defn vector-ish-comparator
([]
(vector-ish-comparator (Comparator/nullsFirst
(Comparator/naturalOrder))))
([item-comparator]
(reify Comparator
(compare [_ a b]
(cond
(< (count a) (count b))
-1
(> (count a) (count b))
1
:else
(loop [i 0]
(if (>= i (count a))
(let [comparison-result (.compare item-comparator
(nth a i)
(nth b i))]
(if (= comparison-result 0)
(recur (inc i))
comparison-result))
0)))))))
Why does running clj doall.clj
on (doall (pmap print (range 10)))
take so long until the process terminates?
The http://ClojureDocs.org page for pmap
briefly mentions this, and refers to the page on future
where there is a much longer explanation of why, and what to do about it.
(defn wrap-something
([handler]
(fn [req]
(handler req)))
([handler res next]
(fn [req res next]
(handler req res next))))
One more: Doing just (println "Executed job " i)
from various threads concurrently. How come I see multiple Executed job
s on a single line? What's the suggested way to get around.
I don't have a workaround handy. I believe the reason is simply that println
is not atomic.
Logging libraries tend to provide atomicity for "separate log messages"
I'm pretty sure I've worked around this in the past by using an atom
+ clojure.lang.PersistentQueue
+ add-watch
:face_with_raised_eyebrow: http://yellerapp.com/posts/2014-12-11-14-race-condition-in-clojure-println.html
yep, that should work then either (wrap-something my-handler)
or (wrap-something my-handler res next)
(defn wrap-something [handler]
(fn ([req]
(handler req))
([req res next]
(handler req res next))))
Your parens were almost in the right place
I have a simple python file hello.py with contents: `print("Hello World")`, and when I try to run this from the REPL using `(sh "python3 hello.py")`, I get
Execution error (IOException) at java.lang.UNIXProcess/forkAndExec (UNIXProcess.java:-2).
error=2, No such file or directory
Obviously the program runs when I run python3 hello.py in the shell. How do I run a python file from the repl?(sh "python3" "hello.py")
perhaps?
like I want to run some python code and get some data from it on the server. Can I do that on heroku?
If python3
is on your path in the Heroku environment, probably...
Try it and see...
are you using pure python libraries? you may find it easier to “embed” python using jython than running it via shell
clojure is the only language i can think of where it is feasible to have a perfectly idiomatic file using -kebab-case
, snake_case
, camelCase
and PascalCase
all at once
Hi, I'm trying to display an image in the client, so I'm sending it like so as an input stream: (res/response (io/input-stream "img.jpg")), but it doesn't work in the client. I get "no reader function for tag object"
is this ring?
I thought that ring could handle input-stream - you might need to change that to {:body (io/input-stream "img.jpg") :headers {} :status 200}
you might also end up wanting to set content type in the headers etc.
see also file-response
here https://github.com/ring-clojure/ring/wiki/Creating-responses
Sounds like a client side issue of trying to read an object tagged literal because something is serializing a Java object like an input stream into edn
Would have to decide if you want edn with base 64 or a byte stream
if you give ring a file or an input stream in the way it likes, it handles all this for you
What's the simplest way to show that input-stream as the src of an image tag, convert to base64 or a blob?
Simplest way is to just serve the image byte stream from an endpoint and have the browser use that endpoint as the src. If you need to download the bytes to the client yourself and then load them into an image element you can send it over the wire as base64 and then load it as a data url or blob
An input stream is a steam of bytes. If you return an input stream to ring it will send those bytes as the body. You should specify a content type header to help the browser interpret it as an image.
In the scenario of returning the image from the server you would just set the image src tag to the path the server is serving the image at. Like src="/myimage"
And let the browser make the request and consume the response instead of using an http client lib
What's the simplest way to do that. Like (convert-to-blob-or-base64 my-input-stream)
if you use the file-response
function and hand it a File object ring should do the rest for you
based on the file extension iirc