Order multiple columns in Incanter for stacked bar chart - clojure

I want to order the stack elements (group-by-k) while keeping order in the global bars (col-k).
The $order function doesn't allow ordering multiple columns at once. So the function twice, though, the last sort will not preserve the previous sort. So I can either have the global bars sorted, or the stacked elements of a bar, but not both!
How can I achieve this? I suspect we would need a sorted-map working inside a $fn but not sure how to implement this...
Here the function I've written to attempt multiple ordering.
(require
(incanter '[core :as core]
'[charts :as charts])
(defn sorted-barchart [data col-k & {:keys [group-by-k
order-k
order-sign
order-group-k
order-group-sign
title
x-label
y-label
legend]}]
(core/with-data
(let [d (core/to-dataset data)
d1 (core/$where {group-by-k {:$fn #(not (empty? %))}} d)
d2 (core/$where {col-k {:$fn #(not (empty? %))}} d1)
d3 (core/$rollup :count :counts (if group-by-k [col-k group-by-k] [col-k]) d2)
d4 (core/$order (or order-k col-k) (or order-sign nil) d3)
d5 (core/$order (or order-group-k group-by-k)
(or order-group-sign nil) d4)]
d5)
(let [chart (charts/stacked-bar-chart col-k :counts
:group-by group-by-k
:vertical false
:x-label (or x-label " ")
:y-label (or y-label " ")
:title (or title " ")
:legend (or legend true)
:series-label "Total")]
chart)))
EDIT: this actually works when sorting by col-k and group-by-k. But when you want to first sort by counts it gets trickier to preserve col-k order when sort by count when you also want to get the stack elements sorted.

We can index the counts on main key only (col-k), then sort by index and stacked key (group-by-k).
So, in the sorted-barchart function, we can replace d4 and d5 by the following:
(if
(and group-by-k order-k (not= order-k col-k))
(let [d-count (core/$ col-k
(core/$order :c
:desc
(core/$rollup :count :c [col-k] d2)))
d-index (core/dataset [:index col-k]
(map-indexed vector d-count))
d-join (core/$join [col-k col-k] d-index d3)]
(->> d-join
(core/$order (or order-group-k group-by-k)
(or order-group-sign :asc))
(core/$order :index :asc)))
(let [d-new (if group-by-k
(core/$order (or order-group-k group-by-k)
(or order-group-sign :asc) d3)
d3)]
(core/$order (or order-k col-k) (or order-sign :desc) d-new)))

Related

From list of pairs ((3 . #\J) (5 . #\Q)) to list of strings (("3J") (5Q)) in Scheme

I have a list of pairs ((3. #\K) (5 . #\J)) ... and I would like to create a function in scheme that returns the list as this: ("3K", "5J")...
I've beeing trying but I cannot make it.
This is what I have.
; The deckCards will contain the list of pairs;
; The real Deck will contain the empty list.
(define (deck->strings deckCards realDeck)
(let lenOfItem ([n (my-lenght deckCards)])
(if (= 1 n)
(list (card->string (first deckCards)))
(append realDeck (deck->strings (cdr deckCards) realDeck))))
)
I did try doing with cond but for some reason it doesnt return the list and it seems impossible to append the list to the realDeack before calling itself recursively.
I think I found an approach and it worked. Not sure if it good to use it. However, this prints all the strings from top to boottom in a new line... Will this matter? I think its because I have 48 elements.
(map (lambda (i) (card->string i))
clubs)

Clojure: speccing a couple of constraints; forced to "break out" into a predicate. Any better way?

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.

Convert nested vector maps in clojure

I need to collect and transfer :c/name values into nested vector to first level same way.
Input example:
[:a/name "name" :a/vals [{:b/val [{:c/name "one"}{:c/name "two"}]}
{:b/val [{:c/name "three"}]}]]
Output:
[:a/name :a/vals "one, two, three"]
This produces the output from the input, is this what you want?
(defn f [[k1 _ k2 rels]]
[k1 k2
(clojure.string/join ", "
(map :c/name (apply concat (mapcat vals rels))))])

How to check whether a value is fall into a range or not in clojure

The range could be defined by maxInclude, maxExclude,minInclude,minExclude
(defn check-range [value maxInclude maxExclude minInclude minExclude] ...)
And the following should hold true.
(check-range 100 100 nil nil 10) ;; should return true since 100<=100 and 100>10
(check-range 100 nil 200 nil 10) ;; should return true since 100<200 and 100>10
(check-range 100 100 nil 101 nil) ;; should return false since 100<=101 is not true
Is there any simple solution? I am using a long code which looks like imperative solution. I think in clojure there must be some nice solutions.
update: my code is as below, but not complete and need help to complete it
(defn check-range [value maxInclude maxExclude minInclude minExclude]
(
let [value1 (if (and maxInclude (< value maxInclude)) false true)
value2 (if (and maxExclude (<= value maxExclude)) false true)
value3 (if (and minInclude (> value minInclude)) false true)
value4 (if (and minExclude (>= value minExclude)) false true)
]
;;; then how to combine value1,2,3,4 into final result as false or true.
)
)
)
I'm not sure what it means for a range to have both an inclusive and exclusive maximum (or similarly, minimum). It seems like those options should be mutually exclusive, which suggests you shouldn't let clients opt into choosing both. Otherwise, how do you decide if it's more important for inclusion to win, or exclusion? The choice seems like it would have to be pretty arbitrary.
I suggest that it would be better to have a different way of constructing the range. This would have the additional benefit of avoiding all the nil hoops you're talking about jumping through and let users be explicit about the kind of range that they're making.
Perhaps something like:
(defn make-range-checker [bottom-check top-check]
(fn [n]
(and (bottom-check n)
(top-check n))))
So that for your initial 3 examples, you'd do something like these to create range-checking functions that you could apply to your input of 100:
(make-range-checker (partial < 10) (partial >= 100))
(make-range-checker (partial < 10) (partial > 200))
(make-range-checker (partial <= 100) (partial > 101))
(your third example is not correct, incidentally: "100<=101 is not true")
Someone wanting to create a range that extends to infinity in either direction could simply pass a predicate that always returns true.
(make-range-checker (partial < 10) (constantly true))
(make-range-checker (constantly true) (partial > 10))

wrapping knockout.js using clojurescript

I'm trying to wrap knockout.js in clojurescript but its turning to be very difficult. The problem that I'm having is the reference to the 'this' variable. I'm thinking of giving up and just using javascript directly.
I've taken examples off http://knockoutjs.com/examples/helloWorld.html and http://knockoutjs.com/examples/contactsEditor.html
I've managed to wrap easy functions with some macros. For example:
var ViewModel = function() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
this.fullName = ko.computed(function() {
// Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName.
return this.firstName() + " " + this.lastName();
}, this);
};
becomes:
(defviewmodel data
(observing :first_name "Bert")
(observing :last_name "Bertington")
(computing :name [:first_name :last_name]
(str :first_name " " :last_name)))
However, for something harder like:
var BetterListModel = function () {
this.itemToAdd = ko.observable("");
this.allItems = ko.observableArray(["Fries", "Eggs Benedict", "Ham", "Cheese"]); // Initial items
this.selectedItems = ko.observableArray(["Ham"]); // Initial selection
this.addItem = function () {
if ((this.itemToAdd() != "") && (this.allItems.indexOf(this.itemToAdd()) < 0)) // Prevent blanks and duplicates
this.allItems.push(this.itemToAdd());
this.itemToAdd(""); // Clear the text box
};
this.removeSelected = function () {
this.allItems.removeAll(this.selectedItems());
this.selectedItems([]); // Clear selection
};
this.sortItems = function() {
this.allItems.sort();
};
};
ko.applyBindings(new BetterListModel());
I'm not sure what I can do in clojurescript to match code like this: this.allItems.push(this.itemToAdd())
Any thoughts?
After lots of trial and error, I figured out how to have the same structure for clojurescript as for javascript.
The this-as macro has a few idiosyncrasies and only works when the method is put into the class
for example I want to create something that looks like this in javascript:
var anobj = {a: 9,
get_a: function(){return this.a;}};
I have to do a whole lot more coding to get the same object in clojurescript:
(def anobj (js-obj))
(def get_a (fn [] (this-as me (.-a me))))
(aset anobj "a" 9)
(aset anobj "get_a" get_a)
which is seriously ugly for a language as beautiful as clojure. Things get worse when you have got functions that link to each other, like what happens in knockout.
I found that the best way to create an js-object with lots of this's in there is to define a __init__ method, add it to the class and then run it, then remove it from the class. For example, if I wanted to make another object:
var avobj = {a: this,
b: 98,
c: this.a
get_a: function(){return str(this.a) + str(this.c);}};
written as clojurescript with and __init__ method looks like this:
(def avobj (js-obj))
(def av__init__
#(this-as this
(aset this "a" this)
(aset this "b" 9)
(aset this "c" (.-a this))
(aset this "get_a" (fn [] (str (.-a this) (.-c this))))))
(aset avobj "__init__" av__init__)
(. avobj __init__)
(js-delete stuff "__init__")
There's still a whole bunch more code than javascript... but the most important thing is that you get the same object as javascript. Setting all the variables using this form also allows the use of macros to simplify. So now I have defined a macro:
(defmacro defvar [name & body]
(list 'do
(list 'def name
(list 'map->js
{
:__init__
(list 'fn []
(list 'this-as 'this
(list 'aset 'this "a" "blah")))
}))
;(. js/console log ~name)
(list '. name '__init__)
(list 'js-delete name "__init__")))
and with map->js taken from jayq.utils:
(defn map->js [m]
(let [out (js-obj)]
(doseq [[k v] m]
(aset out (name k) v))
out))
Now I can write code like this:
(defvar avobj
a this
b 9
c (.-a this)
get_a (fn [] (str (.-a this) (.-c this))))
and for the answer to knockout:
(defvar name_model
first_name (observable "My")
last_name (observable "Name")
name (computed (fn [] (str (. this first_name) " " (. this last_name)))))
(. js/ko (applyBindings name_model));
Which is really nice for me as it matches javascript really well and its entirely readable!
If you need an explicit reference to JavaScript's this dynamic binding, ClojureScript provides a this-as macro:
https://github.com/clojure/clojurescript/blob/master/src/clj/cljs/core.clj#L324