I am trying to create a dstu2 client from clojure using hapi fhir. As a template i use https://github.com/jamesagnew/hapi-fhir/blob/master/examples/src/main/java/example/GenericClientExample.java
But I am not able to execute
ctx.setPerformanceOptions(PerformanceOptionsEnum.DEFERRED_MODEL_SCANNING);
in clojure
What i do is the following:
(def fhir-context (. FhirContext forDstu2))
=> #'emrspp.fhir-resources/fhir-context
(def opts PerformanceOptionsEnum/DEFERRED_MODEL_SCANNING)
=> #'emrspp.fhir-resources/opts
But then the followint fails:
(.setPerformanceOptions fhir-context opts)
=>
CompilerException java.lang.IllegalArgumentException: No matching method found: setPerformanceOptions for class ca.uhn.fhir.context.FhirContext
clojure reflection gives the following :
(pprint (filter #(= "setPerformanceOptions" (str (:name %))) (:members (r/reflect fhir-context))))
=>
~
({:name setPerformanceOptions,
:return-type void,
:declaring-class ca.uhn.fhir.context.FhirContext,
:parameter-types [ca.uhn.fhir.context.PerformanceOptionsEnum<>],
:exception-types [],
:flags #{:varargs :public}}
{:name setPerformanceOptions,
:return-type void,
:declaring-class ca.uhn.fhir.context.FhirContext,
:parameter-types [java.util.Collection],
:exception-types [],
:flags #{:public}})
nil
The imports section is:
(:import [org.hl7.fhir.instance.model.api IBaseOperationOutcome IBaseResource ]
7 [ca.uhn.fhir.context FhirContext PerformanceOptionsEnum]
8 [ca.uhn.fhir.model.base.resource BaseOperationOutcome ]
9 [ca.uhn.fhir.model.dstu2.resource Bundle
10 Conformance Observation
11 OperationOutcome
12 Organization Parameters
13 Patient Provenance]
14 [ca.uhn.fhir.model.dstu2.valueset AdministrativeGenderEnum IssueSeverityEnum]
15 [ca.uhn.fhir.model.primitive DateDt IdDt InstantDt]
16 [ca.uhn.fhir.rest.api MethodOutcome SummaryEnum ]
17 [ca.uhn.fhir.rest.client IGenericClient ServerValidationModeEnum interceptor.LoggingInterceptor ]
18 [ca.uhn.fhir.rest.method.SearchStyleEnum ]
19 [ca.uhn.fhir.rest.param.DateRangeParam ]
20 [ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException ]
21 )
with no :requires except pprint and reflection
Any hits of what happens regarding the method setPerformanceOptions that appears to be there but be executed ????
I figured it out after hours. I closer look at the namespace : http://hapifhir.io/apidocs/ca/uhn/fhir/context/FhirContext.html
reveals that the passing argument needs to be a java collection and thus
(.setPerformanceOptions fhir-context opts)
must be changed to
(.setPerformanceOptions fhir-context (java.util.ArrayList. [opts]))
or simplier
(.setPerformanceOptions fhir-context [opts] )
Related
I have this structure to tile the 2D plane with squares:
A "strip" is an ensemble of "squares" with the same x coordinate.
A struct-map representing the strip holds said x coordinate as ::sq-x and a map of squares at that x coordinate as ::squares.
The keys of the map of squares are the square's y-coordinates.
The values of the map of squares are the squares.
A square is a struct-map with the x and y coordinates of the square as ::sq-x and ::sq-y respectively, and a vector of "vertices" ::vtxs.
There are of course equality constraints between the square ::sq-x and the strip's ::sq-x as well as the square ::sq-y and the map key.
As we don't declare these structures in Clojure, speccing them becomes somewhat the backbone that is class/type declarations in Java.
It is rather clear how to spec the basic structure, but in order to spec the map and the two constraints I have to "break out" into a predicate check-squares-map.
(ns foo.bar
(:require
[clojure.spec.alpha :as s]
[clojure.test :as t]))
(s/def ::sq-x integer?)
(s/def ::sq-y integer?)
(s/def ::vtxs sequential?)
(s/def ::square (s/keys :req [::sq-x ::sq-y ::vtxs]))
; ---
; Additional constraining of values
; ---
; Receive: the "strip", which is dezz'd ("destructured") into the "sq-x"
; master value and the "squares" map.
; What is done:
; - Transform the "squares" map into a lazy seq of booleans where "true"
; means constraints for that map entry passed.
; - Use every? on that seq for early return.
(defn- check-squares-map [{sq-x-master ::sq-x squares ::squares}]
(every?
(fn [key+val]
; dezz the pair key+val into: "sq-y-as-key" and a dezz'd "square"
(let [[ skey { sq-x ::sq-x sq-y ::sq-y vtxs ::vtxs } ] key+val ]
(and
(= sq-x sq-x-master)
(= skey sq-y))))
squares))
; ---
; spec-ing the "map of 'square' structs"
; ---
; We need a "map?" predicate because "s/every-kv" actually accepts
; '[]' as valid "associative collection".
; Note that s/every-kv will not necessarily check every "square" when
; called (it breaks off at some point)
(s/def ::squares
(s/and
map?
(s/every-kv ::sq-y ::square)))
; ---
; spec-ing the "strip" struct
; ---
; This spec constrains the "strip" struct.
; .. which transitively constrains the "squares" map.
; .... which transitively constrains the individual "square" structs in
; the "squares" map.
; But we need to enforce a "remote constraint" between a "square",
; the keys of the "squares" map the "strip". Which is done by calling the
; "check-squares-map" predicate. This is unsatisfying, as calling the predicate
; breaks good spec-reporting.
(s/def ::strip
(s/and
(s/keys :req [::sq-x ::squares])
#(check-squares-map %)))
Note that the spec ::squares will not necessarily check every square: every-kv.
The "breakout" is unfortunate because then s/explain will just say "the predicate failed" but not where exactly:
(s/explain ::strip
{::sq-x 500
::squares
{0 { ::sq-x 66 ::sq-y 66 ::vtxs [] }}})
#:foo.bar{:sq-x 500, :squares
{0 #:foo.bar{:sq-x 66, :sq-y 66, :vtxs []}}}
- failed: (check-squares-map %) spec: :foo.bar/strip
We have a failure because ::sq-x is 500 on the "strip" but 66 on the "square". Similar mismatch between the key at 0 and the ::sq-y at 66. But the message is pretty general.
Is there a coding style or a way to amend the above to increase the "spec-icity" of ::strip spec so that the breakout into a predicate can be minimized? In particular, the constraint between values of separate structure-maps seems hard to express. speccing is rather "local" (or is it?)
This question shows the limits of using types to catch errors in data.
A type in Java, for example, can easily distinguish between int or float. It is not so good as separating out valid values of int or float, such as odd is OK but even is bad, or only values in the range [0..12). Indeed, some types (such as irrational numbers) cannot be represented exactly at all.
A better approach (if practicable for your problem) would be to re-organize the data structure to avoid possible internal conflicts (such as conflicting :sq-x values). For example, you could define a "strip" more like this:
- x ; the x value (lower-left corner)
- y-min ; the lowest y value (also LL corner)
- len ; y-max = y-min + len (inclusive or exclusive both work here)
- size ; the width/height of each square (if necessary)
Using the above, you could also compute the vertexes of each square whenever needed. You could also number the squares from min to max as [0..(len-1)] in case you ever wanted to access the coordinates of a specific square.
After reflection, I have found this.
That's not it yet, as some tests pass that should fail. BRB.
(ns foo.bar
(:require
[clojure.spec.alpha :as s]
[clojure.test :as t]))
(s/def ::sq-x integer?)
(s/def ::sq-y integer?)
(s/def ::vtxs sequential?)
(s/def ::square (s/keys :req [::sq-x ::sq-y ::vtxs]))
; ---
; spec-ing the "map of 'square' structs"
; ---
; We need a "map?" predicate because "s/every-kv" actually accepts
; '[]' as valid "associative collection".
; Note that s/every-kv will not necessarily check every "square" when
; called (it breaks off at some point)
(s/def ::squares
(s/and
map?
(s/every-kv ::sq-y ::square)))
; ---
; Is this right?
; ---
; Here we assemble a new spec to be used in ::strip).
; The assemble function takes two parameters and returns a spec,
; i.e. a function taking a "strip" struct.
; (Can I even return a spec function from inside a let? Should work,
; no impediment to this orthogonality that I can see)
(defn assemble-new-spec [sq-x-master squares]
(fn [strip]
(let [squares (get strip ::squares)]
((s/and
(s/every (fn [keey vaal] (= sq-x-master (get vaal ::sq-x))))
(s/every (fn [keey vaal] (= keey (get vaal ::sq-y)))))
strip)))) ; and here we pass "strip" to the s/and for evaluation
(s/def ::strip
(s/and
(s/keys :req [::sq-x ::squares])
#(assemble-new-spec (get % ::sq-x) (get % ::squares)))) ; hmm....
This sadly fails at the REPL.
Take the erroneous structure
#:foo.bar{:sq-x 1, :squares {0 #:foo.bar{:sq-x 66, :sq-y 0, :vtxs []}}}
where sq-x is 1 on one side, but 66 on the other side.
Doesn't work:
$ lein repl
(require '[clojure.test :as t :refer [deftest testing is]]
'[clojure.spec.alpha :as s :refer [valid?]]
'[foo.bar :as sut])
(def borked {
::sut/sq-x 1
::sut/squares {0 { ::sut/sq-x 66 ::sut/sq-y 0 ::sut/vtxs [] }}})
(valid? ::sut/strip borked)
;=> true
Aiee.
Instaparse can pprint nice error messages to the REPL
=> (negative-lookahead-example "abaaaab")
Parse error at line 1, column 1:
abaaaab
^
Expected:
NOT "ab"
but I can not find a built-in function to get the message as a String. How to do that?
You could always wrap it using with-out-str:
(with-out-str
(negative-lookahead-example "abaaaab"))
You may also be interested in using with-err-str documented here.
(with-err-str
(negative-lookahead-example "abaaaab"))
I can't remember if instaparse writes to stdout or stderr, but one of those will do what you want.
Let's look at the return type of parse in the failure case:
(p/parse (p/parser "S = 'x'") "y")
=> Parse error at line 1, column 1:
y
^
Expected:
"x" (followed by end-of-string)
(class *1)
=> instaparse.gll.Failure
This pretty printing behavior is defined like this in Instaparse:
(defrecord Failure [index reason])
(defmethod clojure.core/print-method Failure [x writer]
(binding [*out* writer]
(fail/pprint-failure x)))
In the REPL this prints as a helpful human-readable description, but it can also be treated as a map:
(keys (p/parse (p/parser "S = 'x'") "y"))
=> (:index :reason :line :column :text)
(:reason (p/parse (p/parser "S = 'x'") "y"))
=> [{:tag :string, :expecting "x", :full true}]
And you could do this:
(with-out-str
(instaparse.failure/pprint-failure
(p/parse (p/parser "S = 'x'") "y")))
=> "Parse error at line 1, column 1:\ny\n^\nExpected:\n\"x\" (followed by end-of-string)\n"
Or write your own version of pprint-failure that builds a string instead of printing it.
Tutfe is a profiling library which is a great fit for understanding the composition of runtime, especially in complicated call stacks.
When I ran it in my project, a section of code I expected to be performance-expensive didn't register as a high-offender in the results, which led to the discovery that Tufte (reasonably) had only captured the thread-local results.
The docs indicate that it has built-in binding to instrument accumulated time on other threads using the {:dynamic? true} option, but there appears to be more needed in order to capture the time accumulated on other threads, such as those initiated by pmap
Here's the original Tufte demo, with some multithreading introduced:
(require '[taoensso.tufte :as tufte :refer (defnp p profiled profile)])
;; We'll request to send `profile` stats to `println`:
(tufte/add-basic-println-handler! {})
;;; Let's define a couple dummy fns to simulate doing some expensive work
(defn get-x [] (Thread/sleep 500) "x val")
(defn get-y []
(pmap
#(do
(Thread/sleep 500)
(print %))
(range 10)))
;; How do these fns perform? Let's check:
(profile ; Profile any `p` forms called during body execution
{:dynamic? true} ; Profiling options; we'll use the defaults for now
(dotimes [_ 5]
(p :get-x (get-x))
(p :get-y (get-y))))
The output indicates that the println statements forced the threads to evaluate. And yet, the get-y accumulated time does not show up in the results:
2187306594=> nil
=> #{:basic-println}
=> #'user/get-x
=> #'user/get-y
8904365271703695842110783956243415760829=> nil
pId nCalls Min Max MAD Mean Time% Time
:get-x 5 500.52ms 504.84ms 1.44ms 502.44ms 100 2.51s
:get-y 5 90.67μs 581.91μs 162.2μs 269.29μs 0 1.35ms
Clock Time 100 2.51s
Accounted Time 100 2.51s
Answer: lazy initialization. Though the data was being printed to the screen, it was the end of the (profile...) form that was doing it, outside of the spied-upon form get-y.
This would yield the same effect:
(profile ; Profile any `p` forms called during body execution
{:dynamic? true} ; Profiling options; we'll use the defaults for now
(dotimes [_ 5]
(p :get-x (get-x))
(doall (p :get-y (get-y)))))
30167894521045768392530798241651268940371023657894=> nil
pId nCalls Min Max MAD Mean Time% Time
:get-x 5 500.07ms 504.58ms 1.41ms 503.08ms 50 2.52s
:get-y 5 80.25μs 126.18μs 15.98μs 104.84μs 0 524.18μs
Clock Time 100 5.03s
Accounted Time 50 2.52s
Whereas this one realizes the lazy sequences inside the get-y profile:
(profile ; Profile any `p` forms called during body execution
{:dynamic? true} ; Profiling options; we'll use the defaults for now
(dotimes [_ 5]
(p :get-x (get-x))
(p :get-y (doall (get-y)))))
12037645987105892436354169872031089546721058729634=> nil
pId nCalls Min Max MAD Mean Time% Time
:get-x 5 502.54ms 504.71ms 705.6μs 503.5ms 50 2.52s
:get-y 5 501.69ms 505.68ms 1.05ms 503.06ms 50 2.52s
Clock Time 100 5.03s
Accounted Time 100 5.03s
This is important to know for the profiling experience, because when dealing with lazy sequences, you're realizing the performance of how they are used, not the sequences themselves:
(profile ; Profile any `p` forms called during body execution
{:dynamic? true} ; Profiling options; we'll use the defaults for now
(dotimes [_ 5]
(p :get-x (get-x))
(p ::realize-y
(doall (p :get-y (get-y))))))
06538947123410695278450678913223071958645126380479=> nil
pId nCalls Min Max MAD Mean Time% Time
:user/realize-y 5 503.29ms 504.86ms 458.12μs 504.37ms 50 2.52s
:get-x 5 500.13ms 505.06ms 1.4ms 503.64ms 50 2.52s
:get-y 5 86.0μs 1.15ms 331.81μs 322.94μs 0 1.61ms
Clock Time 100 5.04s
Accounted Time 100 5.04s
I am new to Clojure and functional programming and now I am stuck with a problem. I get such a data structure:
{
:service1 \a
:service2 \b
:service3 \c
:default \d
:alert-a {
:duration "00:00-23:59"
:if-alert true
:continuous-times 2
:time-interval [2 6 9 15 30 60]
:times -1
}
:alert-b {
:duration "09:00-23:00"
:if-alert true
:continuous-times 2
:time-interval [2 6 9 15 30 60]
:times -1
}
:alert-c {
:duration "00:00-23:59"
:if-alert true
:continuous-times 5
:time-interval [5]
:times 1
}
:alert-d {
:duration "00:00-23:59"
:if-alert true
:continuous-times 5
:time-interval [5 15 30 60]
:times -1
}
}
This is something read from a config file. I want to change all the :duration value to a DateTime object using clj-time. So I can get something like:
{
:service1 \a
:service2 \b
:service3 \c
:default \d
:alert-a {
:duration DateTime Object
:if-alert true
:continuous-times 2
:time-interval [2 6 9 15 30 60]
:times -1
}
:alert-b {
:duration DateTime Object
:if-alert true
:continuous-times 2
:time-interval [2 6 9 15 30 60]
:times -1
}
:alert-c {
:duration DateTime Object
:if-alert true
:continuous-times 5
:time-interval [5]
:times 1
}
:alert-d {
:duration DateTime Object
:if-alert true
:continuous-times 5
:time-interval [5 15 30 60]
:times -1
}
}
But the data structure is immutable. This is an easy problem in other languages but now I don't know how to do it after a whole afternoon.
So can anyone give me some suggestions? Am I using a bad data structure? Or this problem can be somehow solved in a functional way.
Although you are working with immutable datastructures, you can easily and efficiently return new datastructures that are based on the originals.
In this case, the simplest (if repetitive) solution would be:
(-> m
(update-in [:alert-a :duration] parse-duration)
(update-in [:alert-b :duration] parse-duration)
(update-in [:alert-c :duration] parse-duration)
(update-in [:alert-d :duration] parse-duration))
The important thing to realize here is that update-in does not mutate the datastructure it's working on. Instead it returns a new datastructure with the modifications applied.
The threading macro -> allows the new datastructure to be threaded through the update-in operations, so that the final returned value is the original datastructure with all of the updates applied.
The parse-duration function would probably look a bit like this:
(defn parse-duration
"Convert duration in HH:MM-HH:MM format"
[s]
(let [[t1 t2] (clojure.string/split s #"-"))
(Period. (clj-time.coerce/to-date-time t1)
(clj-time.coerce/to-date-time t2)))
In functional programming you don't modify collection, but instead create new collection with needed values substituted by new ones. Fortunately, Clojure comes with a bunch of useful functions for this. For your case update-in should work well. It takes a collection (e.g. map), sequence of nested keys and a function to apply to the most nested value defined by key sequence. For example:
> (def m {:a 1 :b 2 :c {:c1 1 :c2 2}})
#'sandbox5448/m
> m
{:a 1, :c {:c1 1, :c2 2}, :b 2}
> (update-in m [:c :c1] str)
{:a 1, :c {:c1 "1", :c2 2}, :b 2}
Note how value 1 from key sequence [:c :c1] was converted to "1".
So, converting :duration field of :alert-a to DateTime is as easy as writing:
> (update-in your-map [:alert-a :duration] string-to-date)
where string-to-date is you converter function.
I'm working on a Compojure application that serves json files. I'm using clojure.java.jdbc library to retrieve the files from sqlite database:
(defn grid-result [z x y]
(j/with-connection db-specs
(j/with-query-results results ["SELECT grid FROM grids WHERE zoom_level = ? AND tile_column = ? AND tile_row = ?" z x y]
(doall results))))
The result of the query is this:
({:grid #<byte[] [B#7e88dd33>})
In order to display it as json, I update the headers, and strip the query result to byte array and use ByteArrayInputStream:
(defn grid-response [grid]
{:status 200
:headers {"Content-Type" "application/json"}
:body (new java.io.ByteArrayInputStream (:grid (first grid)))})
This is how the request is handled:
(defroutes app-routes
(GET "/api/:z/:x/:y.grid.json" [z x y] (grid-response (grid-result z x y))
(route/not-found "Page not found"))
All above results in:
"xœ«VJ/ÊLQ²ŠVR (éŒ1jĨ£FŒ1jĨ£FŒ1jĨÄEÊPP¨¨ªQl„
Å®€ƒQ#F5b¤«£”ZYÈ�gh`jndaXƒf†æ0†Œa¨[�7ð+k"
Json that I'm trying to retrieve has a format of:
grid({"keys": ["""], "data": {"105803": {"predicti_9": 0.0257, "prediction": "3B2", "OA01CDOLD": "15UFGH0011"}, "106178": {"predicti_9": 0.0265, "prediction": "6B1", "OA01CDOLD": "15UHFE0001"}, "106171": {"predicti_9": 0.0257, "prediction": "3B2", "OA01CDOLD": "15UHFC0001"}, "105721": {"predicti_9": 0.0257, "prediction": "3B2", "OA01CDOLD": "15UFGC0013"}, "106170": {"predicti_9": 0.0257, "prediction": "3B2", "OA01CDOLD": "15UHFB0001"}}, "grid": [" ", " "]});
What I've also tried:
Changed grid-response function to convert byte array to String:
:body (String. (:grid (first grid)) "UTF-8")
Results in ((with UTF-8 or without):
x??VJ/?LQ??VR?(?1j??F?1j??F?1j??E?PP????Ql?
???Q#F?5b?????ZY?�gh`jndaX?f??0??a?[�7?
Mapped each char to str:
(apply str (map #(char (bit-and % 255)) (:grid (first grid))))
Results in:
xœ«VJ/ÊLQ²ŠVR (éŒ1jĨ£FŒ1jĨ£FŒ1jĨÄEÊPP¨¨ªQl„
Å®€ƒQ#F5b¤«£”ZYÈ�gh`jndaXƒf†æ0†Œa¨[�7ð+k
(Same as with ava.io.ByteArrayInputStream).
Any advice on how to convert that byte stream to json will be greatly appreciated.
The grids are compressed with zlib. So this is the solution I used:
(defn zlib-decompress
[input]
(with-open [input (-> input io/input-stream InflaterInputStream.)]
(slurp input)))
This function returns a string representation of the json, so when I set the response's content type to "application/json", everything works.
You're trying to read GZIP compressed data. You can try using something like:
(java.io.BufferedInputStream.
(java.util.zip.GZIPInputStream.
(new java.io.ByteArrayInputStream (:grid (first grid)))))
to decompress it before displaying it.