I have a clojure application. It accepts a POST request with the following payload.
[
{
"key1": value1,
"key2": value2,
"key3": value3,
"key4": value4
},
{
"key1": value1,
"key2": value2,
"key3": value3,
"key4": value4
}
]
For each element of the array we make a SELECT call to DB using jdbc like so
(defn my-definition [db payload]
(->> payload
(map (fn [p]
(if-let [da (my-db-call-method db)]
(assoc da :key1 (:key1 p))
{:key2 (:key2 p)
:key3 (:key3 p)
})))))
DB call
(defn my-db-call-method [db json-params]
(with-sql-handling "my-db-call-method"
(jdbc/query db [my-query
(to long (:key1 json-params))
(to long (:key2 json-params))
)))
my-query.txt would look something like belowSelect * from my_table where col_name1 = ? and col_name2 =? Now, if 1 DB call takes 100 ms then 100 batch size would take 10 sec. This is too long. Is there a way to batch process the request in Clojure? Please note that code is in working condition but taking a long time due to sequential processing. How can we parallel process this? Can we use any third-party library to achieve this?
I have a window with an xyz-panel that holds a bunch of labels. Now some of them have to overlap and I can't figure out how to set the Z-order.
(defn- mk-smhi-frame
"create the frame"
[]
(sc/window
:width 1920
:height 1080
:content
(sc/xyz-panel :items [
; begin snip
(sc/label :id :clock
:bounds [1000 0 920 500]
:paint draw-clock)
;----------------------------------------------
; how do make :radar be on top of :clock?
;----------------------------------------------
(sc/label :id :radar
:bounds [1200 100 500 300]
:paint draw-radar)
; end snip
])))
I'm using the following:
(defn dollars [input] (str "$" (format "%.2f" input)))
(which doesn't do the commas)
But I think there must be a method using pprint/cl-format.
My question is: How to idiomatically print currency in Clojure?
If you have more to work with money, than just formatting it, you might consider using https://github.com/clojurewerkz/money (see the section Formatting), which wrapps joda-money. This not only covers formatting, but also other common problems like rounding.
user=> (mf/format (ma/amount-of mc/USD 10000))
"$10,000.00"
user=> (mf/format (ma/amount-of mc/USD 10000) java.util.Locale/GERMANY)
"USD10.000,00"
edit
You can pass the amount-of means of rounding. E.g.
user=> (mf/format (ma/amount-of mc/USD 10.111111111111111))
ArithmeticException Scale of amount 10.11111111111111 is greater than the scale of the currency USD org.joda.money.Money.of (Money.java:74)
user=> (mf/format (ma/amount-of mc/USD 10.111111111111111 (java.math.RoundingMode/HALF_DOWN)))
"$10.11"
See also Bankster: https://github.com/randomseed-io/bankster
(money/of :EUR 25)
; => #money[25.00 EUR]
(money/of 25 :EUR)
; => #money[25.00 EUR]
(money/of crypto/BTC 10.1)
; => #money/crypto[10.10000000 BTC]
(money/of BTC 10.1)
; => #money/crypto[10.10000000 BTC]
#money EUR
; => #money[0.00 EUR]
#money/crypto ETH
; => #money/crypto[0.000000000000000000 ETH]
#money[PLN 2.50]
; => #money[2.50 PLN]
#currency USD
; => #currency{:id :USD, :domain :ISO-4217, :kind :FIAT, :numeric 840, :scale 2}
(currency/symbol :USD)
; => "USD"
(currency/symbol :USD :en_US)
; => "$"
(currency/symbol :USDT)
; => "₮"
(currency/name :USDT)
; => "Tether"
(money/format #money[10 EUR])
; => "10,00 €"
(money/format #money[10 EUR] :en_US)
; => "€10.00"
(money/format #money[10 EUR] :pl {:currency-symbol-fn currency/name})
; => "10,00 euro"
New to Clojure and wondering how to use it to make other languages I program in easier.
One thing I would like to be able to do is use Clojure for code generation.
For example, given the input from a data file (EDN format) how should I (1) walk this structure or (2) push the data into an existing templating mechanism?
Data below would be for defining simple REST API so that you could generate Clients from it. Generate clients in multiple languages by using different templates.
(:restcall "GetAccountBalance"
{:method "GET" :path "account/balance"}
{:id int})
(:restcall "GetLastTransactions"
{:method "GET" :path "account/transactions"}
{:page int})
resulting code would be something like
public void GetAccountBalance(int id)
{
var input = new { id = id };
callIntoRestLibrary("GET", "account/balance", input);
}
public void GetLastTransactions(int page)
{
var input = new { page = page };
callIntoRestLibrary("GET", "account/transactions", input);
}
Note: my end goal would having these as System.Net.Http.HttpClient calls via C#, but also be able to translate these into JavaScript/Ajax calls also
You have several choices for templating with Clojure. One place to look is the Clojure Toolbox.
Here is an example with clostache, a small library (358 loc) implementation of mustache.
(ns so.core
(:require [clostache.parser :refer (render)]))
(def template "
public void {{restcall}}({{id}} id)
{
var input = new { id = id };
callIntoRestLibrary(\"{{method}}\", \"{{path}}\", input);
}")
(def data
{:restcall "GetAccountBalance"
:method "GET" :path "account/balance" :id "int"})
(print (render template data))
Output:
public void GetAccountBalance(int id)
{
var input = new { id = id };
callIntoRestLibrary("GET", "account/balance", input);
}
To clear up confusion about what it means to read EDN.
(spit "foo.txt" (prn-str data))
Now the file foo.txt contains a textual representation of data, presumably your starting point.
(def data2 (with-open [r (java.io.PushbackReader. (java.io.FileReader. "foo.txt"))]
(clojure.edn/read r)))
(= data data2) ;=> true
So, read doesn't just pull in text, but also parses it into its data representation.
Because I'm working with a very complex table with nasty repeated values in variable places, I'd like to do a string search between specific rows and columns.
For example:
table={{"header1", "header2", "header3",
"header4"}, {"falsepositive", "falsepositive", "name1",
"falsepositive"}, {"falsepositive", "falsepositive", "name2",
"falsepositive"}, {"falsepositive", "falsepositive",
"falsepositive", "falsepositive"}}
%//TableForm=
header1 header1 header1 header1
falsepositive falsepositive name1 falsepositive
falsepositive falsepositive name2 falsepositive
falsepositive falsepositive falsepositive falsepositive
How do I look for a string, for example, in column three, rows one through two?
I'd like to use Which to assign values based on a string's location in the table.
E.g.,
Which[string matched in location one, value, matched in location two, value2]
As I understand it you want a test whether or not a given string is in a certain subsection of a matrix. You can pick these subsections using Part ([[...]]) and Span (;;), with which you can indicate ranges or subsamples of ranges. Testing whether or not this subsection contains your pattern can be done by MemberQ, like this:
MemberQ[table[[1 ;; 2, 3]], "name2"]
(* ==> False *)
MemberQ[table[[1 ;; 2, 3]], "header3"]
(* ==> True *)
In this way, your Which statement could look like this:
myVar =
Which[
MemberQ[table[[1 ;; 2, 3]], "name2"], 5,
MemberQ[table[[2 ;; 3, 4]], "falsepositive"], 6,
...
True, 20
]
Length[Cases[Position[table, "name1"], {1 | 2, 3}]] >= 1
Output -> True
Or
Cases[Position[table, "name1"], {1 | 2, 3}]
Output -> {{2, 3}}
Perhaps, if I understand you:
f[table_, value_, rowmin_, rowmax_, colmin_, colmax_] :=
Select[Position[table, value],
rowmin <= First## <= rowmax && colmin <= Last## <= colmax &]
f[table, "name1", 1, 10, 1, 10]
(*
-> {{2, 3}}
*)