How do I get data out of a Uint8Array in ClojureScript? - clojurescript

I am getting a MIDI message from a midiAccess object as an Uint8Array in a ClojureScript site but I can't seem to convert it to something I can get values from. (js/console.log message) generates Uint8Array(3) [128, 65, 0] in the browser console.
Actually, 'first' on the message gets the first value, but then 'second' does not. Using js->clj doesn't seem to convert it into anything usable. How do I wrangle the data out of it? I tried js->clj but that seemed to keep it the same.

Here are some examples:
(let [ui8a (Uint8Array.from [0 1 2 3 4 5])]
then
ui8a => #object[Uint8Array 0,1,2,3,4,5]
(.-length ui8a) => 6
(first ui8a) => 0
(second ui8a) => 1
(aget ui8a 3) => 3
(into [] ui8a) => [0 1 2 3 4 5] ; either one works
(vec ui8a) => [0 1 2 3 4 5]
You may find this list of documentation sources helpful. Be especially sure to study the Clojure CheatSheet daily!

Related

Clojurescript — PersistentArrayMap → Object → PersistentArrayMap — transferring data between web worker

I'm trying to pass a clojurescript map to a webworker.
Before I pass it, it is of type PersistentArrayMap.
cljs.core.PersistentArrayMap {meta: null, cnt: 3, arr: Array(6), __hash: null, cljs$lang$protocol_mask$partition0$: 16647951…}
However, when it gets to the worker, it's just a plain old Object
Object {meta: null, cnt: 3, arr: Array(6), __hash: null, cljs$lang$protocol_mask$partition0$: 16647951…}
with the data seemingly intact. At this point I'd like to turn it back into a PersistentArrayMap so that I can work with it in cljs again.
Using clj->js and js->clj doesn't really work because it doesn't distinguish between keywords and strings, so some data is lost.
What's the best way to handle this situation? It's possible that I'm going about this in the entirely wrong way.
The built-in solution is to serialize the data to EDN and reading it back. clj->js is inherently lossy and should be avoided.
You start by turning the object into a string and send that over to the worker.
(pr-str {:a 1})
;; => "{:a 1}"
In the worker you read it back via cljs.reader/read-string
(cljs.reader/read-string "{:a 1}")
;; => {:a 1}
This will usually be good enough but the transit-cljs library will be slightly faster. Depending on the amount of data you plan on sending it may be worth the extra dependency.
Did you use keywordize-keys in the code?
(def json "{\"foo\": 1, \"bar\": 2, \"baz\": [1,2,3]}")
(def a (.parse js/JSON json))
;;=> #js {:foo 1, :bar 2, :baz #js [1 2 3]}
(js->clj a)
;;=> {"foo" 1, "bar" 2, "baz" [1 2 3]}
(js->clj a :keywordize-keys true)
;;=> {:foo 1, :bar 2, :baz [1 2 3]}
Full documentation is here.

Is there a Counter object in Julia?

In Python, it's possible to count items in list using a high-performance object collections.Counter:
>>> from collections import Counter
>>> l = [1,1,2,4,1,5,12,1,51,2,5]
>>> Counter(l)
Counter({1: 4, 2: 2, 5: 2, 4: 1, 12: 1, 51: 1})
I've search in http://docs.julialang.org/en/latest/search.html?q=counter but I can't seem to find a counter object.
I've also looked at http://docs.julialang.org/en/latest/stdlib/collections.html but I couldn't find it either.
I've tried the histogram function in Julia and it returned a wave of deprecation messages:
> l = [1,1,2,4,1,5,12,1,51,2,5]
> hist(l)
[out]:
WARNING: sturges(n) is deprecated, use StatsBase.sturges(n) instead.
in depwarn(::String, ::Symbol) at ./deprecated.jl:64
in sturges(::Int64) at ./deprecated.jl:623
in hist(::Array{Int64,1}) at ./deprecated.jl:646
in include_string(::String, ::String) at ./loading.jl:441
in execute_request(::ZMQ.Socket, ::IJulia.Msg) at /Users/liling.tan/.julia/v0.5/IJulia/src/execute_request.jl:175
in eventloop(::ZMQ.Socket) at /Users/liling.tan/.julia/v0.5/IJulia/src/eventloop.jl:8
in (::IJulia.##13#19)() at ./task.jl:360
while loading In[65], in expression starting on line 1
WARNING: histrange(...) is deprecated, use StatsBase.histrange(...) instead
in depwarn(::String, ::Symbol) at ./deprecated.jl:64
in histrange(::Array{Int64,1}, ::Int64) at ./deprecated.jl:582
in hist(::Array{Int64,1}, ::Int64) at ./deprecated.jl:645
in hist(::Array{Int64,1}) at ./deprecated.jl:646
in include_string(::String, ::String) at ./loading.jl:441
in execute_request(::ZMQ.Socket, ::IJulia.Msg) at /Users/liling.tan/.julia/v0.5/IJulia/src/execute_request.jl:175
in eventloop(::ZMQ.Socket) at /Users/liling.tan/.julia/v0.5/IJulia/src/eventloop.jl:8
in (::IJulia.##13#19)() at ./task.jl:360
while loading In[65], in expression starting on line 1
WARNING: hist(...) and hist!(...) are deprecated. Use fit(Histogram,...) in StatsBase.jl instead.
in depwarn(::String, ::Symbol) at ./deprecated.jl:64
in #hist!#994(::Bool, ::Function, ::Array{Int64,1}, ::Array{Int64,1}, ::FloatRange{Float64}) at ./deprecated.jl:629
in hist(::Array{Int64,1}, ::FloatRange{Float64}) at ./deprecated.jl:644
in hist(::Array{Int64,1}, ::Int64) at ./deprecated.jl:645
in hist(::Array{Int64,1}) at ./deprecated.jl:646
in include_string(::String, ::String) at ./loading.jl:441
in execute_request(::ZMQ.Socket, ::IJulia.Msg) at /Users/liling.tan/.julia/v0.5/IJulia/src/execute_request.jl:175
in eventloop(::ZMQ.Socket) at /Users/liling.tan/.julia/v0.5/IJulia/src/eventloop.jl:8
in (::IJulia.##13#19)() at ./task.jl:360
while loading In[65], in expression starting on line 1
**Is there a Counter object in Julia?**
If you are using Julia 0.5+, the histogram functions has been deprecated and you are supposed to use the StatsBase.jl module instead. It is also described in the warning:
WARNING: hist(...) and hist!(...) are deprecated. Use fit(Histogram,...) in StatsBase.jl instead.
But if you are using StatsBase.jl, probably countmap is closer to what you need:
julia> import StatsBase: countmap
julia> countmap([1,1,2,4,1,5,12,1,51,2,5])
Dict{Int64,Int64} with 6 entries:
4 => 1
2 => 2
5 => 2
51 => 1
12 => 1
1 => 4
The DataStructures.jl package also has Accumulators / Counters with a more
general set of methods for using and combining counters.
Once you've added the package
using Pkg
Pkg.add("DataStructures")
you can count the elements of a sequence by constructing a counter
# generate some data to count
using Random
seq = [ Random.randstring('a':'c', 2) for _ in 1:100 ]
# count the elements in seq
using DataStructures
counts = counter(seq)

Nesting displayed when mapping collection in HAML

I'm working on a Rails application, using HAML. I needed to present a list to the user, when I stumbled upon this weird behaviour:
This code generates no output, obviously.
- 5.times.map do |n|
- n + 1
This code generates 1 2 3 4 5, as it's outputting the return value for the inner statement.
- 5.times.map do |n|
= n + 1 # Notice the =
This code generates [1, 2, 3, 4, 5], as it's outputting the mapped array.
= 5.times.map do |n| # Notice the =
- n + 1
So far, so good...
This code generates 1 2 3 4 5 [0, 0, 0, 0, 0], as it doesn't like humans.
= 5.times.map do |n| # Notice the =
= n + 1 # on both lines
This code generates 1 2 3 4 5 [1, 1, 1, 1, 1], as it's nested in the <p>.
%p # Here we are nested one <p> deep
= 5.times.map do |n|
= n + 1
This code generates 1 2 3 4 5 [2, 2, 2, 2, 2], as it's double nested (and so on).
%p # Here we are nested two <p> deep
%p
= 5.times.map do |n|
= n + 1
Does anyone have an explanation for what is happening here in the HAML internals? Is = n+1 both adding a string to some output buffer, and then returning it's nesting level?
Actually, what you are asking is very version dependent. I mean it will produce different results in upcoming version of Haml (v4.1.0).
But first let's find out why this output in version < 4.1.0?
Under the hood, Haml translates templates into executable Ruby code. This job is done in Haml::Compiler class and you can easily debug this code:
require 'haml'
puts Haml::Engine.new(%q{
%p
%p
%p
= 5.times.map do |i|
= i
}).render # => produces the output
# you have in last example
to find out what the associated Ruby code looks like.
With some simplifications, it looks like this:
haml_temp = 5.times.map do |i|
_hamlout.push_text(" #{_hamlout.format_script_false_false_false_false_false_true_false(( i ));}\n", 0, false);
end
You can easily see by now, that your values are mapped to the expression:
_hamlout.push_text(...)
_hamlout here is an instance of Haml::Buffer and this is the last line, which returns value from the push_text method:
#real_tabs += tab_change
#real_tabs is indent level. If we use no indent, then it's 0, when one %p is involved, it becomes 1 and so on. tab_change argument is 0 (see debugged code).
So the output for Haml version 4.0.7 is equal to the level of nesting. This is exactly how your output looks like.
But this behavior will be probably "broken" in upcoming version 4.1.0. Compare the last line of the same method from current master branch:
#buffer << text
which will return some textual value.

scikit learn - converting features stored as strings into numbers

I'm currently dipping my toes into machine learning using the scikit-learn python library and am trying to use some .CSV data in the format
Date Name Average_Price_SA
1995-01-01 Barking And Dagenham 70885.331285935
1995-01-01 Barnet 99567.4268042005
1995-01-01 Barnsley 49608.33494746
....
....
....
2005-01-01 Barking And Dagenham 13294.12321312
I have read them in using panda using the line
data = pd.read_csv('data.csv')
From what I have learned so far, I think I'm supposed to convert those 'Name' category strings into floats so that they can be accepted into a model.
I'm not sure how to go about this. Any help would be greatly appreciated.
Thanks
You can use scikit's LabelBinarizer to convert the strings to one hot vectors. These have N zeros (where N is the number of unique strings) with a one at a single component.
from __future__ import print_function
from sklearn import preprocessing
names = ["Barking And Dagenham", "Barnet", "Barnsley"]
lb = preprocessing.LabelBinarizer()
vectors = lb.fit_transform(names)
for name, vector in zip(names, vectors):
print("%s => %s" % (name, str(vector)))
Output:
Barking And Dagenham => [1 0 0]
Barnet => [0 1 0]
Barnsley => [0 0 1]

Egg dropping in worst case

I have been trying to write an algorithm to compute the maximum number or trials required in worst case, in the egg dropping problem. Here is my python code
def eggDrop(n,k):
eggFloor=[ [0 for i in range(k+1) ] ]* (n+1)
for i in range(1, n+1):
eggFloor[i][1] = 1
eggFloor[i][0] = 0
for j in range(1, k+1):
eggFloor[1][j] = j
for i in range (2, n+1):
for j in range (2, k+1):
eggFloor[i][j] = 'infinity'
for x in range (1, j + 1):
res = 1 + max(eggFloor[i-1][x-1], eggFloor[i][j-x])
if res < eggFloor[i][j]:
eggFloor[i][j] = res
return eggFloor[n][k]print eggDrop(2, 100)
```
The code is outputting a value of 7 for 2eggs and 100floors, but the answer should be 14, i don't know what mistake i have made in the code. What is the problem?
The problem is in this line:
eggFloor=[ [0 for i in range(k+1) ] ]* (n+1)
You want this to create a list containing (n+1) lists of (k+1) zeroes. What the * (n+1) does is slightly different - it creates a list containing (n+1) copies of the same list.
This is an important distinction - because when you start modifying entries in the list - say,
eggFloor[i][1] = 1
this actually changes element [1] of all of the lists, not just the ith one.
To instead create separate lists that can be modified independently, you want something like:
eggFloor=[ [0 for i in range(k+1) ] for j in range(n+1) ]
With this modification, the program returns 14 as expected.
(To debug this, it might have been a good idea to write out a function to pring out the eggFloor array, and display it at various points in your program, so you can compare it with what you were expecting. It would soon become pretty clear what was going on!)