<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><![CDATA[Will's Software Journal]]></title>
<description><![CDATA[Will's Software Journal]]></description>
<link>https://wtfleming.github.io/</link>
<atom:link href="https://wtfleming.github.io/rss.xml" rel="self" type="application/rss+xml" />
<lastBuildDate>Sat, 01 Aug 2026 22:49:37 +0000</lastBuildDate>
<item>
  <title><![CDATA[Rust benchmarking with Criterion]]></title>
  <description><![CDATA[
<p>
I was recently looking into benchmarking some Rust code and thought I would write up how to do so with the <a href="https://github.com/bheisler/criterion.rs">criterion</a> library. Code for this post is available <a href="https://github.com/wtfleming/rust_benchmarking_example">here at GitHub</a>.
</p>

<p>
For this toy example we'll be writing code to determine the distance between 2 points. This is relatively easy to do with the <a href="https://en.wikipedia.org/wiki/Pythagorean_theorem">pythagorean theorem</a>, but the downside is you will need to use a relatively slow square root calculation to do so.
</p>

<p>
Many times you don't need the exact distance. Say you have a point and a vector of points and want to know which one in the vector is the closest - in this case what you care about is the relative distance each point is, and can skip the square root and use distance squared.
</p>

<p>
So how much faster would it be to use squared distance? Lets find out.
</p>
<div id="outline-container-orgde0efac" class="outline-2">
<h2 id="orgde0efac">Create a library</h2>
<div class="outline-text-2" id="text-orgde0efac">
<p>
Lets create a library and add criterion as a dependency.
</p>

<pre class="example" id="org73769c4">
$ cargo new --lib rust_benchmarking_example
$ cd rust_benchmarking_example
</pre>

<p>
Now lets add <code>criterion</code> as a dev-dependency
</p>

<pre class="example" id="org59400af">
cargo add criterion --dev --features html_reports
</pre>

<p>
Your <code>Cargo.toml</code> file should now look something like this
</p>

<pre class="example" id="org791ebba">
[package]
name = "rust_benchmarking_example"
version = "0.1.0"
edition = "2021"

[dependencies]

[dev-dependencies]
criterion = { version = "0.5.1", features = ["html_reports"] }
</pre>
</div>
</div>
<div id="outline-container-orgb8dce8d" class="outline-2">
<h2 id="orgb8dce8d">Code</h2>
<div class="outline-text-2" id="text-orgb8dce8d">
<p>
Open <code>src/lib.rs</code> and add the following code
</p>

<div class="org-src-container">
<pre class="src src-rust">pub struct Vector2 {
    pub x: f64,
    pub y: f64,
}

impl Vector2 {
    pub fn new(x: f64, y: f64) -&gt; Vector2 {
        Vector2 { x, y }
    }

    pub fn distance(&amp;self, rhs: &amp;Vector2) -&gt; f64 {
        let x = self.x - rhs.x;
        let y = self.y - rhs.y;
        (x * x + y * y).sqrt()
    }

    pub fn distance_squared(&amp;self, rhs: &amp;Vector2) -&gt; f64 {
        let x = self.x - rhs.x;
        let y = self.y - rhs.y;
        x * x + y * y
    }
}
</pre>
</div>
</div>
</div>
<div id="outline-container-orgc732ed1" class="outline-2">
<h2 id="orgc732ed1">Unit tests</h2>
<div class="outline-text-2" id="text-orgc732ed1">
<p>
Lets make sure everything is working as expected, add the following tests to <code>src/lib.rs</code>.
</p>

<div class="org-src-container">
<pre class="src src-rust">#[cfg(test)]
mod tests {
    use super::*;

    fn approximately(lhs: f64, rhs: f64) -&gt; bool {
        (lhs - rhs).abs() &lt; f64::EPSILON
    }

    #[test]
    fn distance_test() {
        let a = Vector2::new(1.0, 5.0);
        let b = Vector2::new(-2.0, 1.0);

        let result = a.distance(&amp;b);
        assert!(approximately(result, 5.0), "{result} was not equal to 5.0");

        let result = b.distance(&amp;a);
        assert!(approximately(result, 5.0), "{result} was not equal to 5.0");
    }

    #[test]
    fn distance_squared_test() {
        let a = Vector2::new(0.0, 0.0);
        let b = Vector2::new(3.0, 4.0);

        let result = a.distance_squared(&amp;b);
        assert!(
            approximately(result, 25.0),
            "{result} was not equal to 25.0"
        );

        let result = b.distance_squared(&amp;a);
        assert!(
            approximately(result, 25.0),
            "{result} was not equal to 25.0"
        );
    }
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org6af2f02" class="outline-2">
<h2 id="org6af2f02">Create a benchmark</h2>
<div class="outline-text-2" id="text-org6af2f02">
<p>
Now lets create a benchmark with criterion, these files are put outside of the <code>src</code> directory in a directory called <code>benches</code> that you will need to create. Lets do that and also create a file in it called distance.rs
</p>

<p>
At this point your directory structure should look like this
</p>

<div class="org-src-container">
<pre class="src src-sh">$ tree
.
├── Cargo.lock
├── Cargo.toml
├── benches
│   └── distance.rs
├── src
│   └── lib.rs
</pre>
</div>

<p>
Add the following to your <code>Cargo.toml</code> file.
</p>

<div class="org-src-container">
<pre class="src src-toml">[[bench]]
name = "distance"
harness = false
</pre>
</div>

<p>
and the following code to <code>benches/distance.rs</code>
</p>

<div class="org-src-container">
<pre class="src src-rust">use criterion::{criterion_group, criterion_main, Criterion};
use rust_benchmarking_example::*;

pub fn criterion_benchmark(c: &amp;mut Criterion) {
    c.bench_function("distance", |bench| {
        bench.iter(|| {
            let a = Vector2::new(0.0, 0.0);
            let b = Vector2::new(3.0, 4.0);
            a.distance(&amp;b);
        })
    });
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);
</pre>
</div>

<p>
You can then run the benchmark from the command like with <code>cargo bench</code> which will run the code a number of times
</p>

<p>
In the output look for a line like:
</p>

<div class="org-src-container">
<pre class="src src-sh">distance                time:   [934.09 ps 935.48 ps 937.28 ps]
</pre>
</div>

<p>
Which tells you
</p>

<ul class="org-ul">
<li>934.09 ps - fastest benchmark</li>
<li>935.48 ps - average benchmark</li>
<li>937.28 ps - slowest benchmark</li>
</ul>

<p>
The results are cached, so if you run <code>cargo bench</code> again it will compare the results against the most recently run ones, here we can see that there was no real change detected - which makes sense as other than some background noise on your computer we are running it on the same code.
</p>

<div class="org-src-container">
<pre class="src src-sh">distance                time:   [934.73 ps 935.46 ps 936.38 ps]
                        change: [-0.1119% +0.0493% +0.2134%] (p = 0.55 &gt; 0.05)
                        No change in performance detected.
</pre>
</div>

<p>
And since we enabled the html<sub>reports</sub> feature we can see them by opening <code>target/criterion/report/index.html</code> in a web browser, where you should see something that looks like this
</p>


<figure id="orged4e28c">
<img src="/images/rust-benchmarking-criterion/rust-criterion-distance.jpg" alt="rust-criterion-distance.jpg">

</figure>
</div>
</div>
<div id="outline-container-orgc15d247" class="outline-2">
<h2 id="orgc15d247">Benchmark squared distance implementation</h2>
<div class="outline-text-2" id="text-orgc15d247">
<p>
Now lets benchmark our distance squared code, change
</p>

<div class="org-src-container">
<pre class="src src-rust">c.bench_function("distance", |bench| {
    bench.iter(|| {
        let a = Vector2::new(0.0, 0.0);
        let b = Vector2::new(3.0, 4.0);
        a.distance(&amp;b);
    })
});
</pre>
</div>

<p>
to
</p>

<div class="org-src-container">
<pre class="src src-rust">c.bench_function("distance", |bench| {
    bench.iter(|| {
        let a = Vector2::new(0.0, 0.0);
        let b = Vector2::new(3.0, 4.0);
        a.distance_squared(&amp;b);
    })
});
</pre>
</div>

<p>
and run <code>cargo bench</code> again. On my machine I get this error
</p>

<blockquote>
<p>
Benchmarking distance: AnalyzingCriterion.rs ERROR: At least one measurement of benchmark distance took zero time per iteration. This should not be possible. If using iter<sub>custom</sub>, please verify that your routine is correctly measured.
</p>
</blockquote>

<p>
It appears that the <code>distance_squared()</code> implementation is so fast it effectively takes zero time to run and can't be measured. Which I suppose makes sense as the much slower version using a square root took picoseconds to run.
</p>

<p>
If you really want to have this complete you could artificially make it slower by disabling compiler optimizations when benchmarking by adding this to your <code>Cargo.toml</code>
</p>

<pre class="example" id="org55a60f9">
[profile.bench]
opt-level = 0
</pre>

<p>
but you generally wouldn't want to do so since taking measurements on a dev build won't be very useful. If you were to do so, you would see output like
</p>

<pre class="example" id="org90befe2">
distance                time:   [9.9843 ns 10.000 ns 10.017 ns]

distance                time:   [9.3626 ns 9.3730 ns 9.3848 ns]
                        change: [-6.2155% -6.0317% -5.8404%] (p = 0.00 &lt; 0.05)
                        Performance has improved.
</pre>

<p>
Alternatively you could also do a benchmark run where only the the <code>a.distance(&amp;b);</code> call happens and another where it calls that and <code>a.distance_squared(&amp;b);</code> and you can see that the distance<sub>squared</sub> call does not add any noticeable overhead.
</p>

<p>
But realistically the code in this toy example is probably so fast that it is not a great candidate for benchmarking.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/rust/" class="tag" data-tag="rust" data-index="0">rust</a> </span></div>]]></description>
  <category><![CDATA[rust]]></category>
  <link>https://wtfleming.github.io/blog/rust-benchmarking/</link>
  <guid>https://wtfleming.github.io/blog/rust-benchmarking/</guid>
  <pubDate>Wed, 03 Jul 2024 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Clojure Performace and the Billion Row Challenge]]></title>
  <description><![CDATA[
<p>
I recently discovered <a href="https://www.morling.dev/blog/one-billion-row-challenge/">The One Billion Row Challenge</a> and thought i'd give it a shot using Clojure. TLDR: the solution I ended up with is ~41% faster than the <a href="https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_baseline.java">Java baseline</a> provided by the challenge.
</p>

<p>
The problem is described as:
</p>

<blockquote>
<p>
Write a Java program for retrieving temperature measurement values from a text file and calculating the min, mean, and max temperature per weather station. There's just one caveat: the file has 1,000,000,000 rows!
</p>

<p>
The text file has a simple structure with one measurement value per row:
</p>
</blockquote>

<pre class="example" id="orgf182783">
Hamburg;12.0
Bulawayo;8.9
Palembang;38.8
St. John's;15.2
Cracow;12.6
</pre>

<p>
The challenge has a <a href="https://github.com/gunnarmorling/1brc">GitHub repo</a> with submissions and leaderboards.
</p>

<hr>

<p>
For most of this post i'll be using measurements against 100 million rows because 1 billion takes too long to test solutions, but I will have results on the full data set at the end of this post.
</p>

<p>
When I run the provided Java baseline on my machine (a Mac mini with a 6 core Intel Core i5 and 16GB of RAM) to establish a baseline I get:
</p>

<pre class="example" id="orga018452">
$ time ./calculate_average_baseline.sh
20.80s user 0.65s system 102% cpu 20.948 total
</pre>

<p>
So we are trying to beat roughly <code>21 seconds</code>.
</p>

<p>
To simplify the examples, I'm not actually calculating the average, but the data is there to do so, and it would be relatively straightforward/fast as there are only 413 weather stations in the resulting data set.
</p>
<div id="outline-container-orgc883c79" class="outline-2">
<h2 id="orgc883c79">Attempt 1: 1 minute 57 seconds</h2>
<div class="outline-text-2" id="text-orgc883c79">
<p>
This is a relatively straightforward Clojure implementation. But with a 1:57 runtime, not at all competitive with the 21 second baseline.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns attempt1)

(defn do-calc [acc row]
  (let [[station measurement] (clojure.string/split row #";")
        measurement (Double/parseDouble measurement)
        station-data (get acc station {:min measurement :max measurement :sum 0.0 :count 0})
        new-data (-&gt; station-data
                     (update :min #(min % measurement))
                     (update :max #(max % measurement))
                     (update :sum #(+ % measurement)) ;; This potentially could overflow, but ignoring for the purposes of this blog post
                     (update :count inc))]
    (assoc acc station new-data)))

(defn run [_opts]
  (with-open [rdr (clojure.java.io/reader "./measurements.txt")]
    (-&gt;&gt; (line-seq rdr)
         (reduce do-calc {}))))
</pre>
</div>

<p>
Lets profile the code with <a href="https://github.com/clojure-goes-fast/clj-async-profiler">clj-async-profiler</a>.
</p>


<figure id="org49a6dbb">
<img src="/images/billion-row-challenge/attempt1.png" alt="attempt1.png">

</figure>

<p>
It looks like a lot of time was spent in Clojure functions like <code>clojure.core/update</code>, <code>clojure.string/split</code>, and <code>clojure.core/assoc</code> etc
</p>
</div>
</div>
<div id="outline-container-orgd01a1d9" class="outline-2">
<h2 id="orgd01a1d9">Attempt 2 - 1 minute 37 seconds</h2>
<div class="outline-text-2" id="text-orgd01a1d9">
<p>
Lets try using a <a href="https://clojure.org/reference/transients">transient map</a> for the accumulator in the reduce function
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns attempt2)

(defn do-calc [acc row]
  (let [[station measurement] (clojure.string/split row #";")
        measurement (Double/parseDouble measurement)
        station-data (get acc station {:min measurement :max measurement :sum 0.0 :count 0})
        new-data (-&gt; station-data
                     (update :min #(min % measurement))
                     (update :max #(max % measurement))
                     (update :sum #(+ % measurement))
                     (update :count inc))]
    (assoc! acc station new-data)))

(defn run [_opts]
   (with-open [rdr (clojure.java.io/reader "./measurements.txt")]
     (-&gt;&gt; (line-seq rdr)
          (reduce do-calc (transient {}))
          (persistent!))))
</pre>
</div>

<p>
Better, but at 1:37, not much better! Even though we're using a transient map as an accumulator in the <code>reduce</code>, we're still using persistent maps as values in the transient map.
</p>

<p>
We could try using a transient map with transient maps as keys, but given how transients work in practice that approach seems fraught with peril.
</p>


<figure id="orge31ec46">
<img src="/images/billion-row-challenge/attempt2.png" alt="attempt2.png">

</figure>
</div>
</div>
<div id="outline-container-orge2abee5" class="outline-2">
<h2 id="orge2abee5">Attempt 3 - Did not finish</h2>
<div class="outline-text-2" id="text-orge2abee5">
<p>
Lets try using a Java array to store results instead of a Clojure persistent hash map.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns attempt3)

(defn do-calc [acc row]
  (let [[station measurement] (clojure.string/split row #";")
        measurement (Double/parseDouble measurement)
        station-data (get acc station (double-array [measurement measurement 0.0 0.0]))
        min-measurement (aget station-data 0)
        max-measurement (aget station-data 1)
        sum-measurement (aget station-data 2)
        count-measurement (aget station-data 3)]
    (aset station-data 0 (min min-measurement measurement))
    (aset station-data 1 (max max-measurement measurement))
    (aset station-data 2 (+ sum-measurement measurement))
    (aset station-data 3 (+ count-measurement 1.0))

    (assoc! acc station station-data)))

(defn run [_opts]
  (time
   (with-open [rdr (clojure.java.io/reader "/Users/wtf/src/open-source/1brc/measurements.txt")]
     (-&gt;&gt; (line-seq rdr)
          (reduce do-calc (transient {}))
          (persistent!)))))
</pre>
</div>

<p>
This one was incredibly slow, I had to force quit it before it finished. What is going on here?
</p>

<p>
If we add the expression
</p>

<div class="org-src-container">
<pre class="src src-clojure">(set! *warn-on-reflection* true)
</pre>
</div>

<p>
and rerun, we see a number of lines on stdout that look like:
</p>

<pre class="example" id="orgfec182a">
Reflection warning, attempt3.clj:9:25 - call to static method aget on clojure.lang.RT can't be resolved (argument types: java.lang.Object, int).
</pre>

<p>
Reflection in the Java interop is incredibly slow! Let fix that.
</p>
</div>
</div>
<div id="outline-container-org3b62e2f" class="outline-2">
<h2 id="org3b62e2f">Attempt 4 - 1 minute 6 seconds</h2>
<div class="outline-text-2" id="text-org3b62e2f">
<p>
We can add type hints to the previous solution like so:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns attempt4)

(set! *warn-on-reflection* true)

(defn do-calc [acc ^String row]
  (let [[station measurement] (clojure.string/split row #";")
        measurement (Double/parseDouble measurement)
        station-data ^doubles (get acc station (double-array [measurement measurement 0.0 0.0]))
        min-measurement (aget station-data 0)
        max-measurement (aget station-data 1)
        sum-measurement (aget station-data 2)
        count-measurement (aget station-data 3)]

    (aset station-data 0 ^double (min min-measurement measurement))
    (aset station-data 1 ^double (max max-measurement measurement))
    (aset station-data 2 ^double (+ sum-measurement measurement))
    (aset station-data 3 ^double (+ count-measurement 1.0))
    (assoc! acc station station-data)))

(defn run [_opts]
  (with-open [rdr (clojure.java.io/reader "/Users/wtf/src/open-source/1brc/measurements.txt")]
    (-&gt;&gt; (line-seq rdr)
         (reduce do-calc (transient {}))
         (persistent!))))
</pre>
</div>

<p>
This one is about 30 seconds better than attempt 2, but still significantly slower than the 21 second Java baseline.
</p>
</div>
</div>
<div id="outline-container-orgd94a6fd" class="outline-2">
<h2 id="orgd94a6fd">Attempt 5 - 45 Seconds</h2>
<div class="outline-text-2" id="text-orgd94a6fd">
<p>
Lets try some optimizations: manually loop instead of reduce, use Java's String split instead of <code>clojure.string/split</code> and don't destructure the results.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns attempt5)

(set! *warn-on-reflection* true)

(defn do-calc [acc ^String row]
  (let [split-row (.split row ";")
        station ^String (aget split-row 0)
        measurement ^String (aget split-row 1)
        measurement (Double/parseDouble measurement)
        station-data ^doubles (get acc station (double-array [measurement measurement 0.0 0.0]))
        min-measurement ^double (aget station-data 0)
        max-measurement ^double (aget station-data 1)
        sum-measurement ^double (aget station-data 2)
        count-measurement ^double (aget station-data 3)]
    (aset station-data 0 ^double (min min-measurement measurement))
    (aset station-data 1 ^double (max max-measurement measurement))
    (aset station-data 2 ^double (+ sum-measurement measurement))
    (aset station-data 3 ^double (+ count-measurement 1.0))
    (assoc! acc station station-data)))

(defn run [_opts]
  (let [reader (java.io.BufferedReader. (java.io.FileReader. "./measurements.txt"))]
    (loop [line (.readLine reader)
           acc (transient {})]
      (if line
        (recur (.readLine reader) (do-calc acc line))
        (persistent! acc)))))
</pre>
</div>

<p>
Around 20 seconds faster, but we're still twice the runtime of the Java baseline!
</p>

<p>
Looking at a flamegraph we seem to be spending a lot of time in calls to <code>clojure.lang.RT.get</code> and <code>clojure.core/assoc!</code>
</p>


<figure id="orga12e829">
<img src="/images/billion-row-challenge/attempt5.png" alt="attempt5.png">

</figure>
</div>
</div>
<div id="outline-container-org290cdad" class="outline-2">
<h2 id="org290cdad">Attempt 6 - 30 seconds</h2>
<div class="outline-text-2" id="text-org290cdad">
<p>
Lets try replacing the transient Clojure hash map in the accumulator with a <code>java.util.HashMap</code>
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns attempt6)

(set! *warn-on-reflection* true)

(defn do-calc [^java.util.HashMap acc ^String row]
  (let [split-row (.split row ";")
        station ^String (aget split-row 0)
        measurement ^String (aget split-row 1)
        measurement (Double/parseDouble measurement)
        station-data ^doubles (.getOrDefault acc station (double-array [measurement measurement 0.0 0.0]))
        min-measurement ^double (aget station-data 0)
        max-measurement ^double (aget station-data 1)
        sum-measurement ^double (aget station-data 2)
        count-measurement ^double (aget station-data 3)]
    (aset station-data 0 ^double (min min-measurement measurement))
    (aset station-data 1 ^double (max max-measurement measurement))
    (aset station-data 2 ^double (+ sum-measurement measurement))
    (aset station-data 3 ^double (+ count-measurement 1.0))
    (.put acc station station-data)
    acc))

(defn run [_opts]
  (let [reader (java.io.BufferedReader. (java.io.FileReader. "./measurements.txt"))]
    (loop [line (.readLine reader)
           acc (java.util.HashMap.)]
      (if line
        (recur (.readLine reader) (do-calc acc line))
        acc))))
</pre>
</div>

<p>
At 30 seconds we're getting toward respectable compared with the baseline. However we've gotten so deep into Java interop and away from idiomatic Clojure code that it would probably make more sense to just write this solution in pure Java.
</p>

<p>
Also, maybe we should next try a solution that isn't effectively single threaded.
</p>
</div>
</div>
<div id="outline-container-org04a364b" class="outline-2">
<h2 id="org04a364b">Attempt 7: core.async</h2>
<div class="outline-text-2" id="text-org04a364b">
<p>
Taking the code from attempt 6, but using core.async to fanout to multiple channels ultimately did not go anywhere, we're largely CPU bound and core.async seemed to just add overhead.
</p>

<p>
I'm tempted to try this again in the future to see if I can make it faster. Not sharing the code as I never got it to a place I was happy with and didn't want to spend time optimizing a solution that was unlikely to be the best.
</p>
</div>
</div>
<div id="outline-container-org7f8400e" class="outline-2">
<h2 id="org7f8400e">Attempt 8: Reducers - 27 seconds</h2>
<div class="outline-text-2" id="text-org7f8400e">
<p>
This time we'll go back to using code that looks more like typical Clojure and leverage <a href="https://clojure.org/reference/reducers">reducers</a>. The <a href="https://clojure.github.io/clojure/clojure.core-api.html#clojure.core.reducers/fold">fold</a> function reduces a collection using a (potentially parallel) reduce-combine strategy. Meaning I can easily use all 6 cores on my machine!
</p>

<p>
One problem with <code>fold</code> is that it should be used when source data can be generated and held in memory, which is not necessarily the case with billions of records. However, we can use the <a href="https://github.com/thebusby/iota">iota</a> library to create a seq of the file which is tuned for reducers and can handle files larger than available memory.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns attempt8
  (:require [clojure.core.reducers :as r]
            [iota :as iota]))

(set! *warn-on-reflection* true)

(defn merge-counts
  ([] {})
  ([x y] (merge-with (fn [[x-min x-max x-sum x-count]
                          [y-min y-max y-sum y-count]]
                       [(min x-min y-min) (max x-max y-max) (+ x-sum y-sum) (+ x-count y-count)]) x y)))

(defn do-calc
  ([acc ^String row]
   (let [[station measurement] (clojure.string/split row #";")
         measurement (Double/parseDouble measurement)
         [cur-minimum cur-maximum cur-sum cur-count] (get acc station [measurement measurement 0.0 0])
         new-data [(min measurement cur-minimum) (max measurement cur-maximum) (+ measurement cur-sum) (inc cur-count)]]
     (assoc acc station new-data))))

(defn run [_opts]
  (-&gt;&gt; (iota/seq "./measurements.txt")
       (r/fold merge-counts do-calc)
       println))
</pre>
</div>

<p>
27 seconds isn't bad for a first attempt with this approach.
</p>
</div>
</div>
<div id="outline-container-orga2e0a9d" class="outline-2">
<h2 id="orga2e0a9d">Attempt 9: Reducers with optimizations - 9.6 seconds</h2>
<div class="outline-text-2" id="text-orga2e0a9d">
<p>
Lets try the previous attempt but with optimizations used in previous attempts.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns attempt9
  (:require [clojure.core.reducers :as r]
            [iota :as iota]))

(set! *warn-on-reflection* true)

(defn merge-counts
  ([] (java.util.HashMap.))
  ([^java.util.HashMap x
    ^java.util.HashMap y]
   ;; Convert to clojure.lang.PersistentHashMap so we can use merge-with.
   ;; Probably could be optimized to directly merge the Java HashMaps
   ;; but reducer merges should be relatively infrequent, so probably not worth optimizing
   (let [x (into {} x)
         y (into {} y)
         ^clojure.lang.PersistentHashMap result (merge-with (fn [[x-min x-max x-sum x-count]
                                                                 [y-min y-max y-sum y-count]]
                                                              [(min x-min y-min) (max x-max y-max) (+ x-sum y-sum) (+ x-count y-count)]) x y)]
     (java.util.HashMap. result))))

(defn do-calc
  ([^java.util.HashMap acc ^String row]
   (let [split-row (.split row ";")
         station ^String (aget split-row 0)
         measurement ^String (aget split-row 1)
         measurement (Double/parseDouble measurement)
         [cur-minimum cur-maximum cur-sum cur-count] (.getOrDefault acc station [measurement measurement 0.0 0])
         new-data [(min measurement cur-minimum) (max measurement cur-maximum) (+ measurement cur-sum) (inc cur-count)]]
     (.put acc station new-data))
   acc))

(defn run [_opts]
  (-&gt;&gt; (iota/seq "/Users/wtf/src/open-source/1brc/measurements.txt")
       (r/fold 1028 merge-counts do-calc)
       println))
</pre>
</div>

<p>
9.6 seconds isn't super fast, but we are now handily beating the 21 second Java baseline.
</p>
</div>
</div>
<div id="outline-container-orgaff751c" class="outline-2">
<h2 id="orgaff751c">Results with 1 Billion rows</h2>
<div class="outline-text-2" id="text-orgaff751c">
<p>
Instead of using 100 million rows, we'll finally run against the full 1 billion row dataset:
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-right">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Entry</th>
<th scope="col" class="org-right">Results</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">Java Baseline</td>
<td class="org-right">3:47</td>
</tr>

<tr>
<td class="org-left">Mine</td>
<td class="org-right">2:13</td>
</tr>

<tr>
<td class="org-left">Best competition entry</td>
<td class="org-right">0:16</td>
</tr>
</tbody>
</table>

<p>
We're about a minute faster than the <a href="https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_baseline.java">Java baseline</a>.
</p>

<p>
But we're nowhere close to the 16 second runtime of the <a href="https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_thomaswue.java">best Java entry</a> (or at least best as of the time of writing). That entry describes itself as:
</p>

<blockquote>
<p>
Simple solution that memory maps the input file, then splits it into one segment per available core and uses sun.misc.Unsafe to directly access the mapped memory. Uses a long at a time when checking for collision.
</p>
</blockquote>

<p>
It appears to be using <code>sun.misc.Unsafe</code> to mostly avoid overhead of using <code>java.lang.String</code> (which i'm not sure if it would break if weather stations could contain UTF-8 characters larger than one byte), a custom hash map implementation, a custom implementation of Java's Integer/parseInt, etc. Definitely an impressive runtime, but I almost wonder if it would make more sense to just use C++ with that approach.
</p>

<p>
Though there are some other interesting entries that are fast and don't use <code>sun.misc.Unsafe</code> like <a href="https://github.com/gunnarmorling/1brc/blob/main/src/main/java/dev/morling/onebrc/CalculateAverage_jparera.java">this one</a> that uses the <a href="https://docs.oracle.com/en/java/javase/21/docs/api/jdk.incubator.vector/jdk/incubator/vector/package-summary.html">jdk.incubator.vector package</a> to take advantage of Single Instruction Multiple Data (SIMD) parallelism.
</p>
</div>
</div>
<div id="outline-container-org23f97be" class="outline-2">
<h2 id="org23f97be">Next steps</h2>
<div class="outline-text-2" id="text-org23f97be">
<p>
There are a number of optimizations I could look at to try to get a better time. Looking at a flame graph I think there is a good amount of overhead in the iota code that could be bypassed with a custom solution memory mapping the file into a number of chunks equivalent to the number of processors, but ultimately i'm pretty happy with what I came up with over the course of a Saturday afternoon and probably will call it here.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <link>https://wtfleming.github.io/blog/billion-row-challenge-clojure/</link>
  <guid>https://wtfleming.github.io/blog/billion-row-challenge-clojure/</guid>
  <pubDate>Sun, 21 Jan 2024 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Pong in ClojureScript]]></title>
  <description><![CDATA[
<button id="button">Click to start!</button>
<canvas id="canvas" width="700" height="500" style="background-color: #F8F8FF;"></canvas>

<script src="/js/pong-cljs.js"> </script>

<p>
I'm working predominantly with Clojure at work these days, but I wanted to spend some time with ClojureScript, so I figured making a pong clone would be a fun weekend project.
</p>

<ul class="org-ul">
<li>Every time the ball hits a paddle it increases in speed and it's direction is set to a randomized unit vector.</li>
<li>Player two moves up or down depending on if the ball it above or below it</li>
<li>Player one behaves the same when the ball is moving towards it, otherwise it moves to the middle of the screen.</li>
</ul>

<p>
The code is <a href="https://github.com/wtfleming/pong-cljs">available on GitHub</a>
</p>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> <a href="https://wtfleming.github.io/tags/clojurescript/" class="tag" data-tag="clojurescript" data-index="1">clojurescript</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <category><![CDATA[clojurescript]]></category>
  <link>https://wtfleming.github.io/blog/clojurescript-pong/</link>
  <guid>https://wtfleming.github.io/blog/clojurescript-pong/</guid>
  <pubDate>Sat, 23 Apr 2022 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Create a Clojure AWS Lambda function in Docker and deployed via AWS SAM]]></title>
  <description><![CDATA[
<p>
In this post I will cover using Clojure to write an <a href="https://aws.amazon.com/lambda/">AWS Lambda</a> function that will run on a schedule of once per minute. It will be deployed via the <a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html">AMS SAM</a> CLI tool and use the Docker runtime. The complete code is available at <a href="https://github.com/wtfleming/clojure-aws-lambda-example">this GitHub repo</a>.
</p>

<p>
I'll start with a simple Lambda function that just writes a message to stdout once per minute.
</p>

<p>
The longer term goal is to create a function that will call the <a href="https://www.weather.gov/documentation/services-web-api">National Weather Service API</a>, and then send me a notification if there are any alerts where I live. But that will be a project for another day.
</p>

<blockquote>
<p>
Note that even though Lambda supports Java as a runtime, we'll be running this function in Docker.
</p>

<p>
While everything works great in the cloud, I ran into some compilation issues running the jar file locally with the sam invoke local command. I think the SAM CLI tool may be doing something unexpected with the java classpath, and could only get it to run without errors using the specific combination of Clojure 1.9 and Java 8. However by using Docker we can easily avoid issues like this.
</p>
</blockquote>
<div id="outline-container-org76a9821" class="outline-2">
<h2 id="org76a9821">Project Code</h2>
<div class="outline-text-2" id="text-org76a9821">
<p>
I am using Leiningin for this project, so create a <code>project.clj</code> file with these contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defproject clojure-aws-lambda-example "0.1.0-SNAPSHOT"
  :dependencies [[com.amazonaws/aws-lambda-java-runtime-interface-client "2.0.0"]
                 [org.clojure/clojure "1.10.3"]
                 [org.clojure/data.json "2.4.0"]]
  :repl-options {:init-ns clojure-aws-lambda-example.core}
  :profiles {:uberjar {:aot :all}})
</pre>
</div>

<hr>

<p>
Now lets write our lambda function Create a file called <code>src/clojure_aws_lambda_example/core.clj</code> with these contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns clojure-aws-lambda-example.core
  (:require [clojure.data.json :as json]
            [clojure.java.io :as io]
            [clojure.spec.alpha :as spec])
  (:gen-class
   :implements [com.amazonaws.services.lambda.runtime.RequestStreamHandler]))

;; -------------------- Specs --------------------
;; The json for an inbound scheduled event should look like this
;; {
;;     "version": "0",
;;     "id": "53dc4d37-cffa-4f76-80c9-8b7d4a4d2eaa",
;;     "detail-type": "Scheduled Event",
;;     "source": "aws.events",
;;     "account": "123456789012",
;;     "time": "2015-10-08T16:53:06Z",
;;     "region": "us-east-1",
;;     "resources": [
;;         "arn:aws:events:us-east-1:123456789012:rule/my-scheduled-rule"
;;     ],
;;     "detail": {}
;; }
;;
;; See https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-run-lambda-schedule.html
(spec/def ::version string?)
(spec/def ::id string?)
(spec/def ::detail-type string?)
(spec/def ::source string?)
(spec/def ::account string?)
(spec/def ::time string?)
(spec/def ::region string?)
(spec/def ::resources (spec/coll-of string?))
(spec/def ::detail map?)

(spec/def ::scheduled-event
  (spec/keys
   :req-un [::version ::id ::detail-type ::source ::account ::time ::region ::resources ::detail]))

;; -------------------- Request handling --------------------
(defn- stream-&gt;scheduled-event
  "Transforms an input stream into a scheduled event "
  [in]
  (json/read (io/reader in) :key-fn keyword))

(defn -handleRequest
  "Implementation for RequestStreamHandler that handles a Lambda Function request"
  [_ input-stream _output-stream _context]
  (println "-handleRequest called with event:" (stream-&gt;scheduled-event input-stream)))
</pre>
</div>
</div>
</div>
<div id="outline-container-org71eb91e" class="outline-2">
<h2 id="org71eb91e">Testing</h2>
<div class="outline-text-2" id="text-org71eb91e">
<p>
Lets create a simple unit test. Create a file named <code>test/eventbridge-scheduled-event.json</code> with these contents.
</p>

<div class="org-src-container">
<pre class="src src-json">{
    "version": "0",
    "id": "53dc4d37-cffa-4f76-80c9-8b7d4a4d2eaa",
    "detail-type": "Scheduled Event",
    "source": "aws.events",
    "account": "123456789012",
    "time": "2015-10-08T16:53:06Z",
    "region": "us-east-1",
    "resources": [
        "arn:aws:events:us-east-1:123456789012:rule/my-scheduled-rule"
    ],
    "detail": {}
}
</pre>
</div>

<p>
And a file named <code>test/clojure_aws_lambda_example/core_test.clj</code> with these contents
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns clojure-aws-lambda-example.core-test
  (:require [clojure.test :refer [deftest is]])
  (:require [clojure-aws-lambda-example.core :as lambda-example]
            [clojure.java.io :as io]
            [clojure.spec.alpha :as spec]))

(deftest test-stream-&gt;scheduled-event
  (let [stream (io/input-stream "./test/eventbridge-scheduled-event.json")
        event (lambda-example/stream-&gt;scheduled-event stream)]
    (is (spec/valid? ::lambda-example/scheduled-event event))))
</pre>
</div>

<p>
In the test we:
</p>

<ul class="org-ul">
<li>Load a sample event from disk.</li>
<li>Pass it to the <code>stream-&gt;scheduled-event</code> function.</li>
<li>Use clojure.spec to validate that the return value looks correct.</li>
</ul>

<p>
Note that rather than relying on a single json event, there is a much more we could test using spec's generative testing features, but I will leave that as an exercise for the reader.
</p>

<hr>
</div>
</div>
<div id="outline-container-org9a7712e" class="outline-2">
<h2 id="org9a7712e">Dockerfile</h2>
<div class="outline-text-2" id="text-org9a7712e">
<p>
We will also need a Dockerfile. We will use a <code>clojure:openjdk-11-slim-buster</code> image to build the Java jar, and then run the function inside a <code>eclipse-temurin:11-focal</code> container. By using a separate image to build our app, we can use a final image that doesn't have to ship Clojure build tools like lein with it.
</p>

<p>
Create a file named <code>Dockerfile</code>
</p>

<div class="org-src-container">
<pre class="src src-dockerfile"># Docker container used to build the Clojure app
FROM clojure:openjdk-11-slim-buster as builder

WORKDIR /usr/src/app

COPY project.clj /usr/src/app/project.clj

# Cache deps so they aren't fetched every time a .clj file changes
RUN lein deps

COPY src/ /usr/src/app/src

RUN lein uberjar

# Build the docker container we will use in the lambda
FROM eclipse-temurin:11-focal

RUN mkdir /opt/app

COPY --from=builder /usr/src/app/target/clojure-aws-lambda-example-0.1.0-SNAPSHOT-standalone.jar /opt/app/app.jar

ENTRYPOINT [ "java", "-cp", "/opt/app/app.jar", "com.amazonaws.services.lambda.runtime.api.client.AWSLambda" ]

CMD ["clojure_aws_lambda_example.core::handleRequest"]
</pre>
</div>

<hr>
</div>
</div>
<div id="outline-container-orgcf15aad" class="outline-2">
<h2 id="orgcf15aad">SAM Configuration</h2>
<div class="outline-text-2" id="text-orgcf15aad">
<p>
Finally we will need a SAM template that will have all the information the SAM CLI tool needs to generate a CloudFormation template. We want to create a Lambda function and a CloudWatch event that fires every minute to trigger a run of the function.
</p>

<p>
Create a file <code>template.yaml</code> that looks like:
</p>

<div class="org-src-container">
<pre class="src src-yaml">AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: &gt;
  clojure-aws-lambda-example

  Sample SAM Template for clojure-aws-lambda-example

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 20

Resources:
  ClojureAwsLambdaExampleFunction:
    # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Type: AWS::Serverless::Function
    Properties:
      PackageType: Image
      MemorySize: 256
      Architectures:
        - x86_64
      Events:
        # We want the lambda to run every minute
        # See https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-schedule.html
        MyScheduledEvent:
          Type: Schedule
          Properties:
            Schedule: rate(1 minute)
            Name: MyScheduledEvent
            Description: Event that triggers the lambda every minute
            Enabled: true
    Metadata:
      DockerTag: clojure-aws-lambda-example-v1
      DockerContext: ./
      Dockerfile: Dockerfile

Outputs:
  ClojureAwsLambdaExampleFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt ClojureAwsLambdaExampleFunction.Arn
  ClojureAwsLambdaExampleFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt ClojureAwsLambdaExampleFunctionRole.Arn
</pre>
</div>
</div>
</div>
<div id="outline-container-org424af5a" class="outline-2">
<h2 id="org424af5a">Run the app locally</h2>
<div class="outline-text-2" id="text-org424af5a">
<p>
Prior to deploying to the cloud we'll want to run and test on our local machine.
</p>

<p>
Ensure you have installed the <a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html">AWS SAM CLI</a> installed, and then build the app.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ sam build
</pre>
</div>

<p>
Run it with
</p>

<div class="org-src-container">
<pre class="src src-sh">$ sam local invoke --event test/eventbridge-scheduled-event.json
</pre>
</div>

<p>
You should see output similar to
</p>

<pre class="example" id="org90aa69f">
Invoking Container created from clojureawslambdaexamplefunction:clojure-aws-lambda-example-v1
Building image.................
Skip pulling image and use local one: clojureawslambdaexamplefunction:rapid-1.33.0-x86_64.

START RequestId: 7dfdf5e7-7580-466b-b3da-c24935837cf0 Version: $LATEST
-handleRequest called with event:  {:detail-type Scheduled Event, :time 2015-10-08T16:53:06Z, :source aws.events, :account 123456789012, :region us-east-1, :id 53dc4d37-cffa-4f76-80c9-8b7d4a4d2eaa, :version 0, :resources [arn:aws:events:us-east-1:123456789012:rule/my-scheduled-rule], :detail {}}
END RequestId: 7dfdf5e7-7580-466b-b3da-c24935837cf0
REPORT RequestId: 7dfdf5e7-7580-466b-b3da-c24935837cf0  Init Duration: 0.26 ms  Duration: 795.48 ms     Billed Duration: 796 ms Memory Size: 256 MB  Max Memory Used: 256 MB
</pre>
</div>
</div>
<div id="outline-container-org0d8ca70" class="outline-2">
<h2 id="org0d8ca70">Deploy to the Cloud</h2>
<div class="outline-text-2" id="text-org0d8ca70">
<p>
The first time you deploy run this command to generate a local <code>samconfig.toml</code> file, an S3 bucket, and an ECR repository. When prompted for configuration info you can use the defaults the tool suggests
</p>

<div class="org-src-container">
<pre class="src src-sh">$ sam deploy --guided
</pre>
</div>

<p>
For future deploys you can just run
</p>

<div class="org-src-container">
<pre class="src src-sh">$ sam deploy
</pre>
</div>

<p>
Once the deploy has finished we can check that it is running by tailing the CloudWatch logs.
</p>

<blockquote>
<p>
Use the stack-name you choose when you ran sam deploy &#x2013;guided
</p>
</blockquote>

<pre class="example" id="org9716717">
$ sam logs -n ClojureAwsLambdaExampleFunction --stack-name sam-app --tail
</pre>

<p>
After a few minutes of running you should see output similar to
</p>

<pre class="example" id="orgfcab532">
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:00:14.729000 START RequestId: cc9f8cfd-04bf-44af-9b88-8d0349adf74e Version
: $LATEST
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:00:14.734000 -handleRequest called! with event:  {:detail-type Scheduled Event, :time 2015-10-08T16:53:06Z, :source aws.events, :account 123456789012, :region us-east-1, :id 53dc4d37-cffa-4f76-80c9-8b7d4a4d2eaa, :version 0, :resources [arn:aws:events:us-east-1:123456789012:rule/my-scheduled-rule], :detail {}}
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:00:14.736000 END RequestId: cc9f8cfd-04bf-44af-9b88-8d0349adf74e
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:00:14.736000 REPORT RequestId: cc9f8cfd-04bf-44af-9b88-8d0349adf74e  Durat
ion: 6.05 ms    Billed Duration: 2637 ms        Memory Size: 256 MB     Max Memory Used: 101 MB Init Duration: 2630.22 ms
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:01:15.451000 START RequestId: 4dfa088e-8328-411e-bf34-e70fe0f74691 Version
: $LATEST
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:01:15.457000 -handleRequest called! with event:  {:detail-type Scheduled Event, :time 2015-10-08T16:53:06Z, :source aws.events, :account 123456789012, :region us-east-1, :id 53dc4d37-cffa-4f76-80c9-8b7d4a4d2eaa, :version 0, :resources [arn:aws:events:us-east-1:123456789012:rule/my-scheduled-rule], :detail {}}
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:01:15.475000 END RequestId: 4dfa088e-8328-411e-bf34-e70fe0f74691
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:01:15.475000 REPORT RequestId: 4dfa088e-8328-411e-bf34-e70fe0f74691  Durat
ion: 18.81 ms   Billed Duration: 19 ms  Memory Size: 256 MB     Max Memory Used: 102 MB
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:02:11.605000 START RequestId: 13ae2a9c-3d0d-40eb-8427-1e7807bff399 Version
: $LATEST
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:02:11.609000 -handleRequest called! with event:  {:detail-type Scheduled Event, :time 2015-10-08T16:53:06Z, :source aws.events, :account 123456789012, :region us-east-1, :id 53dc4d37-cffa-4f76-80c9-8b7d4a4d2eaa, :version 0, :resources [arn:aws:events:us-east-1:123456789012:rule/my-scheduled-rule], :detail {}}
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:02:11.609000 END RequestId: 13ae2a9c-3d0d-40eb-8427-1e7807bff399
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:02:11.609000 REPORT RequestId: 13ae2a9c-3d0d-40eb-8427-1e7807bff399  Durat
ion: 1.06 ms    Billed Duration: 2 ms   Memory Size: 256 MB     Max Memory Used: 102 MB
2021/10/17/[$LATEST]e4f5879df90c4d2f90bf036dfc1773c7 2021-10-17T16:03:11.363000 START RequestId: 76b568e8-8fa2-446f-803e-b9252db1b9a7 Version
: $LATEST
</pre>
</div>
</div>
<div id="outline-container-org341962f" class="outline-2">
<h2 id="org341962f">Clean up</h2>
<div class="outline-text-2" id="text-org341962f">
<p>
When you are finished, you can delete the resources associated with the stack
</p>

<blockquote>
<p>
Use the stack-name you choose when you ran sam deploy &#x2013;guided
</p>
</blockquote>

<pre class="example" id="org844d6fb">
$ sam delete --stack-name sam-app
</pre>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <link>https://wtfleming.github.io/blog/clojure-aws-lambda/</link>
  <guid>https://wtfleming.github.io/blog/clojure-aws-lambda/</guid>
  <pubDate>Sun, 17 Oct 2021 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Cats vs Dogs - Part 3 - 99.1% Accuracy - Binary Image Classification with PyTorch and an Ensemble of ResNet Models]]></title>
  <description><![CDATA[
<p>
In 2014 Kaggle ran a <a href="https://www.kaggle.com/c/dogs-vs-cats/overview">competition</a> to determine if images contained a dog or a cat. In this series of posts we'll see how easy it is to use Keras to create a <a href="https://en.wikipedia.org/wiki/Convolutional_neural_network">2D convolutional neural network</a> that potentially could have won the contest.
</p>

<p>
In <a href="/blog/keras-cats-vs-dogs-part-1/">part 1</a> we used Keras to define a neural network architecture from scratch and were able to get to 92.8% categorization accuracy.
</p>

<p>
In <a href="/blog/keras-cats-vs-dogs-part-2/">part 2</a> we used once again used Keras and a VGG16 network with transfer learning to achieve 98.6% accuracy.
</p>

<p>
In this post we'll switch gears to use <a href="https://pytorch.org/">PyTorch</a> with an ensemble of ResNet models to reach 99.1% accuracy.
</p>

<hr>

<p>
This post was inspired by the book <a href="https://www.oreilly.com/library/view/programming-pytorch-for/9781492045342/">Programming PyTorch for Deep Learning</a> by Ian Pointer.
</p>

<p>
Code is available in a <a href="https://github.com/wtfleming/jupyter-notebooks-public/blob/master/dogs-vs-cats/dogs-vs-cats-part-3.ipynb">jupyter notebook here</a>. You will need to download the data from the <a href="https://www.kaggle.com/c/dogs-vs-cats/data">Kaggle competition</a>. The dataset contains 25,000 images of dogs and cats (12,500 from each class). We will create a new dataset containing 3 subsets, a training set with 16,000 images, a validation dataset with 4,500 images and a test set with 4,500 images.
</p>
<div id="outline-container-org78c6c87" class="outline-2">
<h2 id="org78c6c87">Build the networks</h2>
<div class="outline-text-2" id="text-org78c6c87">
<div class="org-src-container">
<pre class="src src-python">import torch
import torch.nn as nn
import torch.optim as optim
import torch.utils.data
import torch.nn.functional as F
import torchvision
import torchvision.models as models
from torchvision import transforms
from PIL import Image
import matplotlib.pyplot as plt
</pre>
</div>

<p>
Download models pretrained on ImageNet with <a href="https://pytorch.org/hub/">PyTorch Hub</a>
</p>

<div class="org-src-container">
<pre class="src src-python">model_resnet18 = torch.hub.load('pytorch/vision', 'resnet18', pretrained=True)
model_resnet34 = torch.hub.load('pytorch/vision', 'resnet34', pretrained=True)
</pre>
</div>

<p>
Since we are doing transfer learning we want to freeze all params except the BatchNorm layers, as here they are trained to the mean and standard deviation of ImageNet and we may lose some signal.
</p>

<div class="org-src-container">
<pre class="src src-python">for name, param in model_resnet18.named_parameters():
    if("bn" not in name):
        param.requires_grad = False

for name, param in model_resnet34.named_parameters():
    if("bn" not in name):
        param.requires_grad = False
</pre>
</div>

<p>
Next we want to replace the classifier so we can make predictions on our dataset, rather than the 1,000 classes from ImageNet the model was trained on.
</p>

<div class="org-src-container">
<pre class="src src-python">num_classes = 2

model_resnet18.fc = nn.Sequential(nn.Linear(model_resnet18.fc.in_features,512),
                                  nn.ReLU(),
                                  nn.Dropout(),
                                  nn.Linear(512, num_classes))

model_resnet34.fc = nn.Sequential(nn.Linear(model_resnet34.fc.in_features,512),
                                  nn.ReLU(),
                                  nn.Dropout(),
                                  nn.Linear(512, num_classes))
</pre>
</div>
</div>
</div>
<div id="outline-container-org1ed84e2" class="outline-2">
<h2 id="org1ed84e2">Functions for training and loading data</h2>
<div class="outline-text-2" id="text-org1ed84e2">
<p>
Create a function we can use to train the model.
</p>

<div class="org-src-container">
<pre class="src src-python">def train(model, optimizer, loss_fn, train_loader, val_loader, epochs=5, device="cpu"):
    for epoch in range(epochs):
        training_loss = 0.0
        valid_loss = 0.0
        model.train()
        for batch in train_loader:
            optimizer.zero_grad()
            inputs, targets = batch
            inputs = inputs.to(device)
            targets = targets.to(device)
            output = model(inputs)
            loss = loss_fn(output, targets)
            loss.backward()
            optimizer.step()
            training_loss += loss.data.item() * inputs.size(0)
        training_loss /= len(train_loader.dataset)

        model.eval()
        num_correct = 0 
        num_examples = 0
        for batch in val_loader:
            inputs, targets = batch
            inputs = inputs.to(device)
            output = model(inputs)
            targets = targets.to(device)
            loss = loss_fn(output,targets) 
            valid_loss += loss.data.item() * inputs.size(0)

            correct = torch.eq(torch.max(F.softmax(output, dim=1), dim=1)[1], targets).view(-1)
            num_correct += torch.sum(correct).item()
            num_examples += correct.shape[0]
        valid_loss /= len(val_loader.dataset)

        print('Epoch: {}, Training Loss: {:.4f}, Validation Loss: {:.4f}, accuracy = {:.4f}'.format(epoch, training_loss,
        valid_loss, num_correct / num_examples))
</pre>
</div>

<p>
Next create some code to load and process our training, test, and validation images.
</p>

<div class="org-src-container">
<pre class="src src-python">batch_size=32
img_dimensions = 224

# Normalize to the ImageNet mean and standard deviation
# Could calculate it for the cats/dogs data set, but the ImageNet
# values give acceptable results here.
img_transforms = transforms.Compose([
    transforms.Resize((img_dimensions, img_dimensions)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225] )
    ])

img_test_transforms = transforms.Compose([
    transforms.Resize((img_dimensions,img_dimensions)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225] )
    ])

def check_image(path):
    try:
        im = Image.open(path)
        return True
    except:
        return False

train_data_path = "/home/wtf/dogs-vs-cats/train/"
train_data = torchvision.datasets.ImageFolder(root=train_data_path,transform=img_transforms, is_valid_file=check_image)

validation_data_path = "/home/wtf/dogs-vs-cats/validation/"
validation_data = torchvision.datasets.ImageFolder(root=validation_data_path,transform=img_test_transforms, is_valid_file=check_image)

test_data_path = "/home/wtf/dogs-vs-cats/test/"
test_data = torchvision.datasets.ImageFolder(root=test_data_path,transform=img_test_transforms, is_valid_file=check_image)

num_workers = 6
train_data_loader = torch.utils.data.DataLoader(train_data, batch_size=batch_size, shuffle=True, num_workers=num_workers)
validation_data_loader = torch.utils.data.DataLoader(validation_data, batch_size=batch_size, shuffle=False, num_workers=num_workers)
test_data_loader = torch.utils.data.DataLoader(test_data, batch_size=batch_size, shuffle=False, num_workers=num_workers)

if torch.cuda.is_available():
    device = torch.device("cuda") 
else:
    device = torch.device("cpu")
</pre>
</div>

<p>
Lets verify that the numbers look correct
</p>

<div class="org-src-container">
<pre class="src src-python">print(f'Num training images: {len(train_data_loader.dataset)}')
print(f'Num validation images: {len(validation_data_loader.dataset)}')
print(f'Num test images: {len(test_data_loader.dataset)}')
</pre>
</div>

<p>
Which should output:
</p>

<pre class="example" id="org87bd8c4">
Num training images: 16000
Num validation images: 4500
Num test images: 4500
</pre>
</div>
</div>
<div id="outline-container-orgc658e95" class="outline-2">
<h2 id="orgc658e95">Train and test the models</h2>
<div class="outline-text-2" id="text-orgc658e95">
<div class="org-src-container">
<pre class="src src-python">def test_model(model):
    correct = 0
    total = 0
    with torch.no_grad():
        for data in test_data_loader:
            images, labels = data[0].to(device), data[1].to(device)
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    print('correct: {:d}  total: {:d}'.format(correct, total))
    print('accuracy = {:f}'.format(correct / total))
</pre>
</div>

<p>
Train the ResNet18 model for a couple epochs. We could let it go longer (and use a larger batch size above), but I've been using a relatively ancient 6 year old GPU for this post, and not wanting to wait forever these settings are good enough for a blog post.
</p>

<div class="org-src-container">
<pre class="src src-python">model_resnet18.to(device)
optimizer = optim.Adam(model_resnet18.parameters(), lr=0.001)
train(model_resnet18, optimizer, torch.nn.CrossEntropyLoss(), train_data_loader, validation_data_loader, epochs=2, device=device)
</pre>
</div>

<pre class="example" id="org282a794">
Epoch: 0, Training Loss: 0.0855, Validation Loss: 0.0358, accuracy = 0.9878
Epoch: 1, Training Loss: 0.0498, Validation Loss: 0.0309, accuracy = 0.9873
</pre>

<p>
Now check against our holdout test set
</p>

<div class="org-src-container">
<pre class="src src-python">test_model(model_resnet18)
</pre>
</div>

<pre class="example" id="org63b1cc1">
correct: 4456  total: 4500
accuracy = 0.990222
</pre>

<p>
And do the same for our ResNet34 network
</p>

<div class="org-src-container">
<pre class="src src-python">model_resnet34.to(device)
optimizer = optim.Adam(model_resnet34.parameters(), lr=0.001)
train(model_resnet34, optimizer, torch.nn.CrossEntropyLoss(), train_data_loader, validation_data_loader, epochs=2, device=device)
</pre>
</div>

<pre class="example" id="orgaf58143">
Epoch: 0, Training Loss: 0.0678, Validation Loss: 0.0239, accuracy = 0.9907
Epoch: 1, Training Loss: 0.0354, Validation Loss: 0.0317, accuracy = 0.9887
</pre>

<p>
And test
</p>

<div class="org-src-container">
<pre class="src src-python">test_model(model_resnet34)
</pre>
</div>

<pre class="example" id="org4804017">
correct: 4450  total: 4500
accuracy = 0.988889
</pre>

<p>
This gives us two models, one with 99.0% accuracy on our test set and 98.9% on the other.
</p>
</div>
</div>
<div id="outline-container-org2986506" class="outline-2">
<h2 id="org2986506">Make some predictions</h2>
<div class="outline-text-2" id="text-org2986506">
<p>
Lets check a couple individual images from the test set.
</p>

<div class="org-src-container">
<pre class="src src-python">import os
def find_classes(dir):
    classes = os.listdir(dir)
    classes.sort()
    class_to_idx = {classes[i]: i for i in range(len(classes))}
    return classes, class_to_idx

def make_prediction(model, filename):
    labels, _ = find_classes('/home/wtf/dogs-vs-cats/test')
    img = Image.open(filename)
    img = img_test_transforms(img)
    img = img.unsqueeze(0)
    prediction = model(img.to(device))
    prediction = prediction.argmax()
    print(labels[prediction])

make_prediction(model_resnet34, '/home/wtf/dogs-vs-cats/test/dogs/dog.11460.jpg')
make_prediction(model_resnet34, '/home/wtf/dogs-vs-cats/test/cats/cat.12262.jpg')
</pre>
</div>

<p>
Which outputs:
</p>

<pre class="example" id="orga49dc48">
dogs
cats
</pre>

<p>
Seems reasonable.
</p>
</div>
</div>
<div id="outline-container-orgc812be1" class="outline-2">
<h2 id="orgc812be1">Save and load models</h2>
<div class="outline-text-2" id="text-orgc812be1">
<p>
Since we don't want to have to train the models again every time we start up a jupyter notebook, lets see how we can save them to disk and then reload them.
</p>

<div class="org-src-container">
<pre class="src src-python">torch.save(model_resnet18.state_dict(), "./model_resnet18.pth")
torch.save(model_resnet34.state_dict(), "./model_resnet34.pth")

# Remember that you must call model.eval() to set dropout and batch normalization layers to
# evaluation mode before running inference. Failing to do this will yield inconsistent inference results.

resnet18 = torch.hub.load('pytorch/vision', 'resnet18')
resnet18.fc = nn.Sequential(nn.Linear(resnet18.fc.in_features,512),nn.ReLU(), nn.Dropout(), nn.Linear(512, num_classes))
resnet18.load_state_dict(torch.load('./model_resnet18.pth'))
resnet18.eval()

resnet34 = torch.hub.load('pytorch/vision', 'resnet34')
resnet34.fc = nn.Sequential(nn.Linear(resnet34.fc.in_features,512),nn.ReLU(), nn.Dropout(), nn.Linear(512, num_classes))
resnet34.load_state_dict(torch.load('./model_resnet34.pth'))
resnet34.eval()
</pre>
</div>
</div>
</div>
<div id="outline-container-orgbd5f2b2" class="outline-2">
<h2 id="orgbd5f2b2">Test with an ensemble</h2>
<div class="outline-text-2" id="text-orgbd5f2b2">
<p>
We'll use a very simple ensemble here. Take the prediction for each image from each model, average them to generate a new prediction for the image.
</p>

<div class="org-src-container">
<pre class="src src-python"># Test against the average of each prediction from the two models
models_ensemble = [resnet18.to(device), resnet34.to(device)]
correct = 0
total = 0
with torch.no_grad():
    for data in test_data_loader:
        images, labels = data[0].to(device), data[1].to(device)
        predictions = [i(images).data for i in models_ensemble]
        avg_predictions = torch.mean(torch.stack(predictions), dim=0)
        _, predicted = torch.max(avg_predictions, 1)

        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print('accuracy = {:f}'.format(correct / total))
print('correct: {:d}  total: {:d}'.format(correct, total))
</pre>
</div>

<p>
Which results in
</p>

<pre class="example" id="org41e92cb">
accuracy = 0.990889
correct: 4459  total: 4500
</pre>

<p>
The magic of ensembles is that given two models with accuracy of <code>0.990222</code> and <code>0.988889</code> we are able to make predictions and get to <code>0.990889</code>, which is higher than any individual model.
</p>

<p>
In this case we aren't seeing a dramatic increase, but ensembles can be very useful. I once had an entry in a Kaggle competition with around 4,000 entrants where my best individual model put me in the top 10%, but by combining a number of entries into an ensemble placed me in the top 2%.
</p>
</div>
</div>
<div id="outline-container-org90db5d6" class="outline-2">
<h2 id="org90db5d6">Next steps</h2>
<div class="outline-text-2" id="text-org90db5d6">
<p>
There is a lot we didn't do here. You could try <a href="https://pytorch.org/docs/stable/torchvision/transforms.html">augmenting the training images with TorchVision</a>, try different ways of creating the ensemble, add a model using a different network like <a href="https://github.com/pytorch/vision/blob/master/torchvision/models/vgg.py">VGG</a> from TorchHub to the ensemble, etc.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/pytorch/" class="tag" data-tag="pytorch" data-index="0">pytorch</a> <a href="https://wtfleming.github.io/tags/machine-learning/" class="tag" data-tag="machine-learning" data-index="1">machine-learning</a> </span></div>]]></description>
  <category><![CDATA[pytorch]]></category>
  <category><![CDATA[machine-learning]]></category>
  <link>https://wtfleming.github.io/blog/pytorch-cats-vs-dogs-part-3/</link>
  <guid>https://wtfleming.github.io/blog/pytorch-cats-vs-dogs-part-3/</guid>
  <pubDate>Sun, 12 Apr 2020 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[CHIP-8 emulator in WebAssembly using Rust]]></title>
  <description><![CDATA[
<p>
Lately I have been working on an emulator for the <a href="https://en.wikipedia.org/wiki/CHIP-8">CHIP-8</a> that can compile to WebAssembly using Rust. The source code is <a href="https://github.com/wtfleming/chip-8-rust-wasm">available on GitHub</a>. And you can <a href="/projects/chip8/index.html">play a game of pong here</a>.
</p>


<figure id="org8cac553">
<img src="/images/rust-chip8/chip8.png" alt="chip8.png">

</figure>

<p>
I've always wanted to write an emulator for an older hardware like the Nintendo Entertainment System or Game Boy Advance, but decided to start with a simpler project that could be finished over the course of a few nights. The CHIP-8 is a great starter emulation project, it has:
</p>

<ul class="org-ul">
<li>A relatively small instruction set (35 instructions)</li>
<li>16 general purpose registers</li>
<li>A 64x32 monochromatic display</li>
<li>A 16 character hex based keypad</li>
<li>No interrupts, but it does have two timer registers that count down at 60 Hz</li>
</ul>

<p>
A few references I found useful to get started are this <a href="http://www.multigesture.net/articles/how-to-write-an-emulator-chip-8-interpreter/">post by Laurence Muller</a>, <a href="http://devernay.free.fr/hacks/chip8/C8TECH10.HTM">Cowgod's Chip-8 Technical Reference</a>, and this <a href="https://blog.scottlogic.com/2017/12/13/chip8-emulator-webassembly-rust.html">post by Colin Eberhardt</a>. If you want to create your own emulator I highly recommend taking a look at the above pages.
</p>
<div id="outline-container-org3e0b9a3" class="outline-2">
<h2 id="org3e0b9a3">Implementation</h2>
<div class="outline-text-2" id="text-org3e0b9a3">
<p>
I won't go too deep into implementations details here, but if you want to know more the <a href="https://github.com/wtfleming/chip-8-rust-wasm">source code is available</a>. I represented the CPU in Rust like this:
</p>

<div class="org-src-container">
<pre class="src src-rust">pub struct Cpu {
    // 4k Memory
    pub memory: [u8; 4096],
    // Program Counter
    pub pc: u16,
    // 16 general purpose 8-bit registers, usually referred to as Vx, where x is a hexadecimal digit (0 through F)
    pub v: [u8; 16],
    // Index register
    pub i: u16,
    // The stack is an array of 16 16-bit values
    pub stack: [u16; 16],
    // Stack pointer
    pub sp: u8,
    // Display - 64x32 pixels
    pub display: [u8; 64 * 32],
    // Delay timer
    pub dt: u8,
    // Sound timer
    pub st: u8,
    // Keyboard
    pub keys: [bool; 16],
}
</pre>
</div>
</div>
<div id="outline-container-org1170da9" class="outline-3">
<h3 id="org1170da9">Memory</h3>
<div class="outline-text-3" id="text-org1170da9">
<p>
The system's memory map looks like:
</p>

<ul class="org-ul">
<li>0x000-0x1FF - In original implementations the CHIP 8 interpreter.</li>
<li>0x050-0x0A0 - In emulators stores the 4x5 pixel font set (0-F).</li>
<li>0x200-0xFFF - Program ROM and work RAM.</li>
</ul>

<p>
One of the first things you will need to do is load the program into memory starting at position 0x200.
</p>
</div>
</div>
<div id="outline-container-org10e0d32" class="outline-3">
<h3 id="org10e0d32">Opcodes</h3>
<div class="outline-text-3" id="text-org10e0d32">
<p>
The CHIP-8 has <a href="http://en.wikipedia.org/wiki/CHIP-8#Opcode_table">35 opcodes</a> you will need to handle, all of which are two bytes long. First you need to extract the opcode, since memory elements are 8 bits and an opcode is 16 bits, we need to fetch two locations from memory and do some bit shifting to get a <code>u16</code> opcode.
</p>

<div class="org-src-container">
<pre class="src src-rust">let code1: u16 = self.memory[self.pc as usize] as u16;
let code2: u16 = self.memory[(self.pc + 1) as usize] as u16;
let opcode: u16 = code1 &lt;&lt; 8 | code2;
</pre>
</div>

<p>
An opcode will look something like <code>0x7301</code>. I highly recommend writing a disassembler to make it easier to read. An example of doing so is <a href="https://github.com/wtfleming/chip-8-rust-wasm/blob/master/chip_8_lib/src/disassembler.rs">here</a>. In this case the <code>0x7301</code> is displayed as <code>ADD V3, 01</code> or in other words, add 1 to the current value of register V3.
</p>

<p>
Thanks to Rust's support for pattern matching over ranges, handling each opcode is relatively easy to do:
</p>

<div class="org-src-container">
<pre class="src src-rust">match opcode {
    0x7000..= 0x7FFF =&gt; {
        // 7xkk - ADD Vx, byte
        // Set Vx = Vx + kk.
        let x = ((opcode &amp; 0x0F00) &gt;&gt; 8) as usize;
        let kk = (opcode &amp; 0x00FF) as u8;

        // Note the overflowing_add, since addition values are 8 bits adding
        // 255 + 2 should overflow and result in 1.
        let (result, _) = self.v[x].overflowing_add(kk);
        self.v[x] = result;
        // Increment the program counter to point at the next opcode.
        self.pc += 2;
    },

    // ...
    // code to handle the remaining opcodes would go here
    // ...

    _ =&gt; {
        // This is an opcode we don't know how to handle yet
        self.pc += 2;
        // EmulateCycleError is a custom error defined elsewhere in the code
        let error = EmulateCycleError { message: format!("{:X} opcode not handled", opcode) };
        return Err(error);
    }
}
</pre>
</div>
</div>
</div>
<div id="outline-container-org038faa1" class="outline-3">
<h3 id="org038faa1">Handling keyboard input in JavaScript</h3>
<div class="outline-text-3" id="text-org038faa1">
<p>
Running the emulator and communicating between JavaScript and WebAssembly is easy thanks to the Rust <a href="https://rustwasm.github.io/docs/wasm-pack/">wasm-pack</a> tool.
</p>

<p>
In this case we annotate this Rust code with <code>#[wasm_bindgen]</code> so we can call it from JavaScript. Note that we are using the unsafe keyword here because CPU is a static value that we hold it's state in.
</p>

<div class="org-src-container">
<pre class="src src-rust">#[wasm_bindgen]
pub fn key_down(key: u8) {
    unsafe {
        CPU.keys[key as usize] = true;
    }
}
</pre>
</div>

<p>
Then in JavaScript we can call update the state of the keypad on the WebAssembly side like this:
</p>

<div class="org-src-container">
<pre class="src src-js">import("./crate/pkg/index.js").then(wasm =&gt; {
  document.addEventListener("keydown", event =&gt; {
    let keyCode = keyMap[event.key];
    if (keyCode &gt;= 0 &amp;&amp; keyCode &lt;= 0xf) {
      wasm.key_down(keyMap[event.key]);
    }
  });
});
</pre>
</div>

<p>
The keyMap is a mapping from the user's keyboard to the hex based keypad on the CHIP-8, and looks like this:
</p>

<div class="org-src-container">
<pre class="src src-js">// CHIP-8 Keypad    User Keyboard
// +-+-+-+-+        +-+-+-+-+
// |1|2|3|C|        |1|2|3|4|
// +-+-+-+-+        +-+-+-+-+
// |4|5|6|D|        |Q|W|E|R|
// +-+-+-+-+   &lt;=   +-+-+-+-+
// |7|8|9|E|        |A|S|D|F|
// +-+-+-+-+        +-+-+-+-+
// |A|0|B|F|        |Z|X|C|V|
// +-+-+-+-+        +-+-+-+-+

const keyMap = {
  '1': 0x1,
  '2': 0x2,
  '3': 0x3,
  '4': 0xc,

  'q': 0x4,
  'w': 0x5,
  'e': 0x6,
  'r': 0xd,

  'a': 0x7,
  's': 0x8,
  'd': 0x9,
  'f': 0xe,

  'z': 0xa,
  'x': 0x0,
  'c': 0xb,
  'v': 0xf,
};
</pre>
</div>
</div>
</div>
<div id="outline-container-orgacfaed3" class="outline-3">
<h3 id="orgacfaed3">Running the emulator</h3>
<div class="outline-text-3" id="text-orgacfaed3">
<p>
We use <a href="https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame">window.requestAnimationFrame()</a> to run 9 cycles on the cpu 60 times per second, then update the HTML canvas display and the UI. We run 9 cycles because the CHIP-8 seems to run at about 500hz, and calling 9 cycles 60 times per second gets us to 540 hZ, which is close enough for this project.
</p>

<p>
Note that with <code>window.requestAnimationFrame()</code>
</p>

<pre class="example" id="org0281641">
The number of callbacks is usually 60 times per second
but will generally match the display refresh rate in most web
browsers as per W3C recommendation.
</pre>

<p>
So if your monitor's refresh rate is not 60 Hz the emulator will likely run either too fast or slow. For this project it is a compromise i'm ok with, but it is something that could be improved.
</p>
</div>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/rust/" class="tag" data-tag="rust" data-index="0">rust</a> <a href="https://wtfleming.github.io/tags/webassembly/" class="tag" data-tag="webassembly" data-index="1">webassembly</a> </span></div>]]></description>
  <category><![CDATA[rust]]></category>
  <category><![CDATA[webassembly]]></category>
  <link>https://wtfleming.github.io/blog/chip8-webassembly-rust/</link>
  <guid>https://wtfleming.github.io/blog/chip8-webassembly-rust/</guid>
  <pubDate>Sun, 26 Jan 2020 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Ray Tracing with Rust and WebAssembly]]></title>
  <description><![CDATA[

<figure id="org8e0fa4f">
<img src="/images/rust-raytracer-1/example.png" alt="example.png">

</figure>

<p>
I have been working through the book <a href="https://pragprog.com/book/jbtracer/the-ray-tracer-challenge">The Ray Tracer Challenge: A Test-Driven Guide to Your First 3D Renderer</a> by Jamis Buck. It is a fantastic book, there is almost no code (other than a little bit of pseudocode), instead there is an explanation of how to build a <a href="https://en.wikipedia.org/wiki/Ray_tracing_(graphics)#Recursive_ray_tracing_algorithm">Whitted ray tracer</a> and a large number of unit tests to walk you through implementing it yourself.
</p>

<p>
I decided to try to implement the ray tracer in Rust and compile to both a native app and <a href="https://webassembly.org/">WebAssembly</a>. Source code is <a href="https://github.com/wtfleming/rust-ray-tracer">available at GitHub</a>. Currently i've worked through chapter 9 (of 17) so there are a number of features my implementation is missing (and I haven't done any optimization yet).
</p>

<p>
Unsurprisingly the native app is much faster (by about an order of magnitude by my very unscientific measurements), but I was quite pleased how easy it was to generate the WebAssembly code using Rust.
</p>

<p>
Above is a pregenerated image, but you can click the button below to generate a smaller lower quality picture on demand. I am using <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers">Web Workers</a> to do the rendering calculations in multiple threads (each Web Worker runs some WebAssembly).
</p>

<p>
If you are using Safari there is an issue with <code>window.navigator.hardwareConcurrency</code> and this app will default to a single thread. Try in a browser like Firefox or Chrome to see better performance.
</p>

<button id="raytracer-button">Click to Render with Web Workers and WebAssembly</button>
<canvas id="raytracer-canvas" width="350" height="250"></canvas>

<p>
I have been quite impressed with the Rust tooling and how easy it was to generate a WebAssembly app in the browser. I'm now intrigued with the idea of being able to write WebAssembly modules in languages like C/C++/Rust/Go etc which can interop with each other, and then have the ability to write a smallish frontend in JavaScript or Python (using something like the <a href="https://wasmtime.dev/">Wasmtime</a> package) to glue it all together.
</p>

<script src="/js/rust-raytracer-1/index.js"></script>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/rust/" class="tag" data-tag="rust" data-index="0">rust</a> <a href="https://wtfleming.github.io/tags/webassembly/" class="tag" data-tag="webassembly" data-index="1">webassembly</a> </span></div>]]></description>
  <category><![CDATA[rust]]></category>
  <category><![CDATA[webassembly]]></category>
  <link>https://wtfleming.github.io/blog/raytracing-webassembly-rust/</link>
  <guid>https://wtfleming.github.io/blog/raytracing-webassembly-rust/</guid>
  <pubDate>Fri, 17 Jan 2020 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Cats vs Dogs - Part 2 - 98.6% Accuracy - Binary Image Classification with Keras and Transfer Learning]]></title>
  <description><![CDATA[
<p>
In 2014 Kaggle ran a <a href="https://www.kaggle.com/c/dogs-vs-cats/overview">competition</a> to determine if images contained a dog or a cat. In this series of posts we'll see how easy it is to use Keras to create a <a href="https://en.wikipedia.org/wiki/Convolutional_neural_network">2D convolutional neural network</a> that potentially could have won the contest.
</p>

<hr>

<p>
In this post we'll see how we can fine tune a network pretrained on ImageNet and take advantage of transfer learning to reach 98.6% accuracy (the winning entry <a href="https://www.kaggle.com/c/dogs-vs-cats/leaderboard">scored 98.9%</a>).
</p>

<p>
In <a href="/blog/keras-cats-vs-dogs-part-1/">part 1</a> we used Keras to define a neural network architecture from scratch and were able to get to 92.8% categorization accuracy.
</p>

<p>
In <a href="/blog/pytorch-cats-vs-dogs-part-3/">part 3</a> we'll switch gears a bit and use PyTorch instead of Keras to create an ensemble of models that provides more predictive power than any single model and reaches 99.1% accuracy.
</p>

<hr>

<p>
The code is available in a <a href="https://github.com/wtfleming/jupyter-notebooks-public/blob/master/dogs-vs-cats/dogs-vs-cats-part-2.ipynb">jupyter notebook here</a>. You will need to download the data from the <a href="https://www.kaggle.com/c/dogs-vs-cats/data">Kaggle competition</a>. The dataset contains 25,000 images of dogs and cats (12,500 from each class). We will create a new dataset containing 3 subsets, a training set with 16,000 images, a validation dataset with 4,500 images and a test set with 4,500 images.
</p>
<div id="outline-container-org41da750" class="outline-2">
<h2 id="org41da750">VGG16</h2>
<div class="outline-text-2" id="text-org41da750">
<p>
We'll use the VGG16 architecture as described in the paper <a href="https://arxiv.org/abs/1409.1556">Very Deep Convolutional Networks for Large-Scale Image Recognition</a> by Karen Simonyan and Andrew Zisserman. We're using it because it has a relatively simple architecture and Keras ships with a model that has been pretrained on ImageNet.
</p>

<p>
Keras includes a <a href="https://keras.io/applications/">number of additional pretrained networks</a> if you want to try with a different one. You could also build the VGG16 network yourself, the code for the Keras implementation is <a href="https://github.com/keras-team/keras-applications/blob/master/keras_applications/vgg16.py">here</a>. It is just a number of Conv2D and MaxPooling2D layers with a dense network on top with a final softmax activation function.
</p>
</div>
</div>
<div id="outline-container-orgb5c9540" class="outline-2">
<h2 id="orgb5c9540">Predict what an image contains using VGG16</h2>
<div class="outline-text-2" id="text-orgb5c9540">
<p>
First we'll make predictions on what one of our images contained. The Keras VGG16 model provided was trained on the <a href="http://www.image-net.org/challenges/LSVRC/">ILSVRC ImageNet</a> images containing 1,000 categories. It will be especially useful in this case since it 90 of the 1,000 categories are species of dogs.
</p>

<p>
First lets take a peek at an image.
</p>

<div class="org-src-container">
<pre class="src src-python">from keras.preprocessing import image
from matplotlib.pyplot import imshow

fnames = [os.path.join(train_dogs_dir, fname) for fname in os.listdir(train_dogs_dir)]
img_path = fnames[1] # Choose one image to view
img = image.load_img(img_path, target_size=(224, 224)) # load image and resize it
x = image.img_to_array(img) # Convert to a Numpy array with shape (224, 224, 3)

x = x.reshape((1,) + x.shape)

plt.imshow(image.array_to_img(x[0]))
</pre>
</div>


<figure id="org00565c1">
<img src="/images/dogs-vs-cats-part-two/terrier.png" alt="terrier.png">

</figure>

<p>
Now lets ask the model what it thinks the picture is.
</p>

<div class="org-src-container">
<pre class="src src-python">from keras.applications.imagenet_utils import decode_predictions
from keras.applications import VGG16

model = VGG16(weights='imagenet', include_top=True)

features = model.predict(x)
decode_predictions(features, top=5)
</pre>
</div>

<pre class="example" id="orgf21943b">
[[('n02097298', 'Scotch_terrier', 0.84078884),
  ('n02105412', 'kelpie', 0.07755529),
  ('n02105056', 'groenendael', 0.048816346),
  ('n02106662', 'German_shepherd', 0.006882491),
  ('n02104365', 'schipperke', 0.005642254)]]
</pre>

<p>
It thinks there is an 84% chance it's a Scotch Terrier, and the other top predictions are all dogs. Seems pretty reasonable.
</p>
</div>
</div>
<div id="outline-container-orgcb23def" class="outline-2">
<h2 id="orgcb23def">Train a Cats vs Dogs classifier</h2>
<div class="outline-text-2" id="text-orgcb23def">
<p>
We can also ask Keras to provide us with the model trained on ImageNet, but without the top dense layers. Then it is just a matter of adding our own dense layers (note that since we are doing binary classification we've used a sigmoid activation function in the final layer). And tell the model to only train the dense layers we created (we don't want to retrain the lower layers that have learnt from ImageNet).
</p>

<p>
In this case it works so well because ImageNet has a large number of animal pictures, so the lower layers already have a sort of conception of what is "dogness" and "catness".
</p>

<div class="org-src-container">
<pre class="src src-python">from keras import layers, models, optimizers

conv_base = VGG16(weights='imagenet',
                  include_top=False,
                  input_shape=(224, 224, 3))

model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

conv_base.trainable = False

model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=2e-5),
              metrics=['acc'])
</pre>
</div>

<p>
Lets create a generator for the images
</p>

<div class="org-src-container">
<pre class="src src-python">from keras.applications.vgg16 import preprocess_input
from keras.preprocessing.image import ImageDataGenerator

train_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)
test_datagen = ImageDataGenerator(preprocessing_function=preprocess_input)

# The list of classes will be automatically inferred from the subdirectory names/structure under train_dir
train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=(224, 224), # resize all images to 224 x 224
    batch_size=50,
    class_mode='binary') # because we use binary_crossentropy loss we need binary labels

validation_generator = test_datagen.flow_from_directory(
    validation_dir,
    target_size=(224, 224), # resize all images to 224 x 224
    batch_size=50,
    class_mode='binary')
</pre>
</div>

<pre class="example" id="orgbeb2634">
Found 16000 images belonging to 2 classes.
Found 4500 images belonging to 2 classes.
</pre>

<p>
And train.
</p>

<div class="org-src-container">
<pre class="src src-python">history = model.fit_generator(
    train_generator,
    steps_per_epoch=320, # batches in the generator are 50, so it takes 320 batches to get to 16000 images
    epochs=30,
    validation_data=validation_generator,
    validation_steps=90) # batches in the generator are 50, so it takes 90 batches to get to 4500 images
</pre>
</div>

<pre class="example" id="org5c460ed">
Epoch 1/30
320/320 [==============================] - 139s 434ms/step - loss: 0.7365 - acc: 0.9238 - val_loss: 0.2217 - val_acc: 0.9751
Epoch 2/30
320/320 [==============================] - 137s 428ms/step - loss: 0.2950 - acc: 0.9689 - val_loss: 0.2579 - val_acc: 0.9736
...
...
...
Epoch 29/30
320/320 [==============================] - 137s 429ms/step - loss: 0.0206 - acc: 0.9977 - val_loss: 0.2079 - val_acc: 0.9818
Epoch 30/30
320/320 [==============================] - 137s 429ms/step - loss: 0.0146 - acc: 0.9982 - val_loss: 0.2063 - val_acc: 0.9824
</pre>

<p>
Lets take a look at what accuracy and loss looked like during training. The code to generate the plot is available in the posts <a href="https://github.com/wtfleming/jupyter-notebooks-public/blob/master/dogs-vs-cats/dogs-vs-cats-part-2.ipynb">jupyter notebook here</a>.
</p>


<figure id="org3ce7cae">
<img src="/images/dogs-vs-cats-part-two/accuracy-loss-1.png" alt="accuracy-loss-1.png">

</figure>

<p>
We seem to be overfitting (and probably could have trained for far fewer than 30 epochs), but the results are still pretty good. Lets compare against the holdout test set.
</p>

<div class="org-src-container">
<pre class="src src-python">test_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size=(224, 224),
    batch_size=50,
    class_mode='binary')

test_loss, test_acc = model.evaluate_generator(test_generator, steps=90)
print('test acc:', test_acc)
</pre>
</div>

<pre class="example" id="org71cb3eb">
Found 4500 images belonging to 2 classes.
test acc: 0.9833333353201549
</pre>

<p>
A validation accuracy of 98.2% and test of 98.3%. Not bad, but lets see if we can do better.
</p>
</div>
</div>
<div id="outline-container-org6de9e90" class="outline-2">
<h2 id="org6de9e90">Transfer learning / Fine tune model</h2>
<div class="outline-text-2" id="text-org6de9e90">
<p>
We can also retrain the later convolutional layers. Here is how we can do it with VGG16.
</p>

<div class="org-src-container">
<pre class="src src-python">conv_base = VGG16(weights='imagenet',
                  include_top=False,
                  input_shape=(224, 224, 3))

conv_base.trainable = True

set_trainable = False
for layer in conv_base.layers:
    if layer.name == 'block5_conv1':
        set_trainable = True
    if set_trainable:
        layer.trainable = True
    else:
        layer.trainable = False

model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dropout(0.5))
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-5),
              metrics=['acc'])
</pre>
</div>

<p>
And lets fit the model
</p>

<div class="org-src-container">
<pre class="src src-python">history = model.fit_generator(
    train_generator,
    steps_per_epoch=320, # batches in the generator are 50, so it takes 320 batches to get to 16000 images
    epochs=30,
    validation_data=validation_generator,
    validation_steps=90) # batches in the generator are 50, so it takes 90 batches to get to 4500 images
</pre>
</div>

<pre class="example" id="org06ac396">
Epoch 1/30
320/320 [==============================] - 151s 471ms/step - loss: 0.7004 - acc: 0.9150 - val_loss: 0.1462 - val_acc: 0.9720
Epoch 2/30
320/320 [==============================] - 150s 469ms/step - loss: 0.1335 - acc: 0.9716 - val_loss: 0.0935 - val_acc: 0.9784
...
...
...
Epoch 29/30
320/320 [==============================] - 151s 470ms/step - loss: 0.0035 - acc: 0.9998 - val_loss: 0.1489 - val_acc: 0.9858
Epoch 30/30
320/320 [==============================] - 151s 470ms/step - loss: 0.0040 - acc: 0.9996 - val_loss: 0.1471 - val_acc: 0.9867
</pre>

<p>
Lets take a look at accuracy and loss again.
</p>


<figure id="org20f23d5">
<img src="/images/dogs-vs-cats-part-two/accuracy-loss-2.png" alt="accuracy-loss-2.png">

</figure>

<p>
We still seem to be overfitting, suggesting we could potentially improve performance. The params on the top dense layers were fairly arbitrarily for this post. I'll leave improving performance further as an exercise for the reader. We've also trained on just 16,000 of the 25,000 images available. If the contest was still going we could retrain with the additional 9k images and likely have better results.
</p>

<p>
Finally lets compare to the test set.
</p>

<div class="org-src-container">
<pre class="src src-python">test_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size=(224, 224),
    batch_size=50,
    class_mode='binary')

test_loss, test_acc = model.evaluate_generator(test_generator, steps=90)
print('test acc:', test_acc)
</pre>
</div>

<pre class="example" id="orgd5db8cc">
Found 4500 images belonging to 2 classes.
test acc: 0.9862222280767229
</pre>

<p>
98.6% accuracy. Not bad at all, it goes to show how lucky we have it these days. This would have been competitive with a state of the art solution not that many years ago, and now we can achieve it with Keras and just a few lines of Python.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/keras/" class="tag" data-tag="keras" data-index="0">keras</a> <a href="https://wtfleming.github.io/tags/machine-learning/" class="tag" data-tag="machine-learning" data-index="1">machine-learning</a> </span></div>]]></description>
  <category><![CDATA[keras]]></category>
  <category><![CDATA[machine-learning]]></category>
  <link>https://wtfleming.github.io/blog/keras-cats-vs-dogs-part-2/</link>
  <guid>https://wtfleming.github.io/blog/keras-cats-vs-dogs-part-2/</guid>
  <pubDate>Sun, 12 May 2019 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Cats vs Dogs - Part 1 - 92.8% Accuracy - Binary Image Classification with Keras and Deep Learning]]></title>
  <description><![CDATA[
<p>
In 2014 Kaggle ran a <a href="https://www.kaggle.com/c/dogs-vs-cats/overview">competition</a> to determine if images contained a dog or a cat. In this series of posts we'll see how easy it is to use Keras to create a <a href="https://en.wikipedia.org/wiki/Convolutional_neural_network">2D convolutional neural network</a> that potentially could have won the contest.
</p>

<p>
We will start with a basic neural network that is 84% accurate at predicting whether an image contains a cat or dog. Then we'll add dropout and finally add data augmentation to get to 92.8% categorization accuracy.
</p>

<p>
In <a href="/blog/keras-cats-vs-dogs-part-2/">part 2</a> we'll see how we can fine tune a network pretrained on ImageNet and take advantage of transfer learning to reach 98.6% accuracy (the winning entry <a href="https://www.kaggle.com/c/dogs-vs-cats/leaderboard">scored 98.9%</a>).
</p>

<p>
In <a href="/blog/pytorch-cats-vs-dogs-part-3/">part 3</a> we'll switch gears and use PyTorch instead of Keras to create an ensemble of models that provides more predictive power than any single model and reaches 99.1% accuracy.
</p>

<p>
The code is available in a <a href="https://github.com/wtfleming/jupyter-notebooks-public/blob/master/dogs-vs-cats/dogs-vs-cats-part-1.ipynb">jupyter notebook here</a>. You will need to download the data from the <a href="https://www.kaggle.com/c/dogs-vs-cats/data">Kaggle competition</a>. The dataset contains 25,000 images of dogs and cats (12,500 from each class). We will create a new dataset containing 3 subsets, a training set with 16,000 images, a validation dataset with 4,500 images and a test set with 4,500 images.
</p>
<div id="outline-container-orge85d4d4" class="outline-2">
<h2 id="orge85d4d4">Build the first network</h2>
<div class="outline-text-2" id="text-orge85d4d4">
<p>
We'll use the Keras sequential API to build a pretty straightforward network that consists of a number of Conv2D and pooling layers with a dense network at the end that makes the cat or dog prediction.
</p>

<div class="org-src-container">
<pre class="src src-python">from keras import layers, models, optimizers

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])
</pre>
</div>

<p>
We'll create some generators that will do some preprocessing on the images and resize them to be 224x224 pixels.
</p>

<div class="org-src-container">
<pre class="src src-python">from keras.preprocessing.image import ImageDataGenerator

# Rescale pixel values from [0, 255] to [0, 1]
train_datagen = ImageDataGenerator(rescale=1./255) 
test_datagen = ImageDataGenerator(rescale=1./255)

# The list of classes will be automatically inferred from the subdirectory names/structure under train_dir
train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=(224, 224), # resize all images to 224 x 224
    batch_size=50,
    class_mode='binary') # because we use binary_crossentropy loss we need binary labels

validation_generator = test_datagen.flow_from_directory(
    validation_dir,
    target_size=(224, 224),
    batch_size=50,
    class_mode='binary')
</pre>
</div>

<pre class="example" id="org8deb535">
Found 16000 images belonging to 2 classes.
Found 4500 images belonging to 2 classes.
</pre>

<p>
Now lets fit the network for 30 epochs.
</p>

<div class="org-src-container">
<pre class="src src-python">history = model.fit_generator(
    train_generator,
    steps_per_epoch=320, # 50 batches in the generator, so it takes 320 batches to get to 16000 images
    epochs=30,
    validation_data=validation_generator,
    validation_steps=90) # 90 x 50 == 4500
</pre>
</div>

<pre class="example" id="org5ee29f7">
Epoch 1/30
320/320 [==============================] - 48s 150ms/step - loss: 0.6070 - acc: 0.6579 - val_loss: 0.5263 - val_acc: 0.7413
Epoch 2/30
320/320 [==============================] - 45s 142ms/step - loss: 0.5145 - acc: 0.7433 - val_loss: 0.5812 - val_acc: 0.6971
...
...
...
Epoch 29/30
320/320 [==============================] - 46s 143ms/step - loss: 0.0133 - acc: 0.9959 - val_loss: 0.9195 - val_acc: 0.8349
Epoch 30/30
320/320 [==============================] - 46s 143ms/step - loss: 0.0133 - acc: 0.9965 - val_loss: 0.8704 - val_acc: 0.8351
</pre>

<p>
Plotting the results (code to generate the graphs is available in the <a href="https://github.com/wtfleming/jupyter-notebooks-public/blob/master/dogs-vs-cats/dogs-vs-cats-part-1.ipynb">jupyter notebook</a>) we can see that the model begins to overfit the training data almost immediately. The training accuracy continues to improve until it gets close to 100%, while the validation set tops out at around 84% and loss degrades as training continues.
</p>


<figure id="orgf9f3d5b">
<img src="/images/dogs-vs-cats-part-one/first-model-accuracy-loss.png" alt="first-model-accuracy-loss.png">

</figure>

<p>
In the final epoch we reached 83.5% accuracy on the validation set, lets quickly double check on the test set to compare.
</p>

<div class="org-src-container">
<pre class="src src-python">test_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size=(224, 224),
    batch_size=50,
    class_mode='binary')

test_loss, test_acc = model.evaluate_generator(test_generator, steps=90)
print('test acc:', test_acc)
</pre>
</div>

<pre class="example" id="org58f4bbf">
Found 4500 images belonging to 2 classes.
test acc: 0.8406666629844242
</pre>

<p>
On one hand this isn't horrible, a baseline where we pick dog every time would have 50% accuracy. But on the other hand we can do much better.
</p>
</div>
</div>
<div id="outline-container-org5b547c0" class="outline-2">
<h2 id="org5b547c0">Add Dropout</h2>
<div class="outline-text-2" id="text-org5b547c0">
<p>
We can add dropout to regularize the model. Adding dropout randomly removes a percentage of neurons (sets their value to 0) at each update during training time, which helps prevent overfitting. By randomly throwing out data this will help to prevent the network from becoming too smart and essentially memorizing the training data, and thereby generalize to new data better.
</p>

<div class="org-src-container">
<pre class="src src-python">from keras import layers, models, optimizers

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(224, 224, 3)))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPool2D(2, 2))
model.add(layers.Flatten())
model.add(layers.Dropout(0.5)) # Note the only change is that we added dropout here
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer=optimizers.RMSprop(lr=1e-4),
              metrics=['acc'])
</pre>
</div>

<p>
How does this model perform?
</p>

<pre class="example" id="org9cfd866">
Epoch 1/30
320/320 [==============================] - 46s 145ms/step - loss: 0.6166 - acc: 0.6449 - val_loss: 0.5348 - val_acc: 0.7378
Epoch 2/30
320/320 [==============================] - 46s 143ms/step - loss: 0.5280 - acc: 0.7364 - val_loss: 0.4777 - val_acc: 0.7733
...
...
...
Epoch 29/30
320/320 [==============================] - 46s 144ms/step - loss: 0.1037 - acc: 0.9603 - val_loss: 0.3722 - val_acc: 0.8720
Epoch 30/30
320/320 [==============================] - 46s 144ms/step - loss: 0.1030 - acc: 0.9604 - val_loss: 0.3444 - val_acc: 0.8780
</pre>


<figure id="org1928b8b">
<img src="/images/dogs-vs-cats-part-one/first-model-accuracy-loss-add-dropout.png" alt="first-model-accuracy-loss-add-dropout.png">

</figure>

<p>
We still seem to be overfitting, but not as badly. We've also increase validation accuracy to 87.8%, so this is a bit of a win. We could try tuning the network architecture or the dropout amount, but instead lets try something else next.
</p>
</div>
</div>
<div id="outline-container-org38b5bfe" class="outline-2">
<h2 id="org38b5bfe">Add Data Augmentation</h2>
<div class="outline-text-2" id="text-org38b5bfe">
<p>
Keras includes an <a href="https://keras.io/preprocessing/image/">ImageDataGenerator</a> class which lets us generate a number of random transformations on an image. Since we're only training on 16,000 images, we can use this to create "new" images to help the network learn. There are limits to how much this can help, but in this case we will get a decent accuracy boost.
</p>

<div class="org-src-container">
<pre class="src src-python">from keras.preprocessing.image import ImageDataGenerator

datagen = ImageDataGenerator(
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    fill_mode='nearest')
</pre>
</div>

<p>
The above creates a data generator that will take in an image from the training set and return an image that has been slightly altered. Lets visualize what this looks like.
</p>

<div class="org-src-container">
<pre class="src src-python">from keras.preprocessing import image

fnames = [os.path.join(train_cats_dir, fname) for fname in os.listdir(train_cats_dir)]
img_path = fnames[4] # Choose one image to augment
img = image.load_img(img_path, target_size=(224, 224)) # load image and resize it
x = image.img_to_array(img) # Convert to a Numpy array with shape (224, 224, 3)
x = x.reshape((1,) + x.shape)

# Generates batches of randomly transformed images.
# Loops indefinitely, so you need to break once three images have been created
i = 0
for batch in datagen.flow(x, batch_size=1):
    plt.figure(i)
    imgplot = plt.imshow(image.array_to_img(batch[0]))
    i += 1
    if i % 3 == 0:
        break
plt.show()
</pre>
</div>


<figure id="org47a62b4">
<img src="/images/dogs-vs-cats-part-one/image-augmentation.png" alt="image-augmentation.png">

</figure>

<p>
We'll use the same network architecture as the previous step, but generate images like this
</p>

<div class="org-src-container">
<pre class="src src-python">train_datagen = ImageDataGenerator(
    rescale=1./255,
    rotation_range=40,
    width_shift_range=0.2,
    height_shift_range=0.2,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1./255) # Note that validation data should not be augmented

train_generator = train_datagen.flow_from_directory(
    train_dir,
    target_size=(224, 224),
    batch_size=50,
    class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
    validation_dir,
    target_size=(224, 224),
    batch_size=50,
    class_mode='binary')
</pre>
</div>

<pre class="example" id="org25f94c1">
Found 16000 images belonging to 2 classes.
Found 4500 images belonging to 2 classes.
</pre>

<p>
And then increase the steps per epoch 3x so that we are training on 48,000 images instead of 16,000. This takes awhile as in the example I'm running on a 5 year old GPU I had laying around the house, training should be much faster if you can use more recent hardware or rent time on a GPU in the cloud.
</p>

<div class="org-src-container">
<pre class="src src-python">history = model.fit_generator(
    train_generator,
    steps_per_epoch=960, # 960 x 50 = 48000 (we are showing different augmented images more than once per epoch)
    epochs=30,
    validation_data=validation_generator,
    validation_steps=90) # 90 x 50 == 4500
</pre>
</div>

<pre class="example" id="org440fe06">
Epoch 1/30
960/960 [==============================] - 411s 429ms/step - loss: 0.6202 - acc: 0.6428 - val_loss: 0.5285 - val_acc: 0.7413
Epoch 2/30
960/960 [==============================] - 410s 427ms/step - loss: 0.5495 - acc: 0.7141 - val_loss: 0.5082 - val_acc: 0.7447
...
...
...
Epoch 29/30
960/960 [==============================] - 409s 426ms/step - loss: 0.2323 - acc: 0.9057 - val_loss: 0.2284 - val_acc: 0.9136
Epoch 30/30
960/960 [==============================] - 413s 430ms/step - loss: 0.2330 - acc: 0.9040 - val_loss: 0.1821 - val_acc: 0.9222
</pre>


<figure id="org8393ddd">
<img src="/images/dogs-vs-cats-part-one/add-data-augmentation.png" alt="add-data-augmentation.png">

</figure>

<p>
And finally compare to the holdout test set.
</p>

<div class="org-src-container">
<pre class="src src-python">test_generator = test_datagen.flow_from_directory(
    test_dir,
    target_size=(224, 224),
    batch_size=50,
    class_mode='binary')

test_loss, test_acc = model.evaluate_generator(test_generator, steps=90)
print('test acc:', test_acc)
</pre>
</div>

<pre class="example" id="org7b43325">
Found 4500 images belonging to 2 classes.
test acc: 0.928444442484114
</pre>

<p>
Yet another improvement, we've reached 92.8% on the test set, are seeing similar numbers on the validation data, and overfitting doesn't seem to be nearly as much of a problem.
</p>

<p>
We could work to improve these results, but that's all for today. In the next post we'll see how we can take advantage of transfer learning to reach 98.6% accuracy.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/keras/" class="tag" data-tag="keras" data-index="0">keras</a> <a href="https://wtfleming.github.io/tags/machine-learning/" class="tag" data-tag="machine-learning" data-index="1">machine-learning</a> </span></div>]]></description>
  <category><![CDATA[keras]]></category>
  <category><![CDATA[machine-learning]]></category>
  <link>https://wtfleming.github.io/blog/keras-cats-vs-dogs-part-1/</link>
  <guid>https://wtfleming.github.io/blog/keras-cats-vs-dogs-part-1/</guid>
  <pubDate>Tue, 07 May 2019 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[MNIST Image Classification using Deep Learning and Keras]]></title>
  <description><![CDATA[
<p>
In this post we'll use Keras to build the hello world of machine learning, classify a number in an image from the <a href="http://yann.lecun.com/exdb/mnist/index.html">MNIST</a> database of handwritten digits, and achieve ~99% classification accuracy using a <a href="https://en.wikipedia.org/wiki/Convolutional_neural_network">convolutional neural network</a>.
</p>

<p>
Much of this is inspired by the book <a href="https://www.manning.com/books/deep-learning-with-python">Deep Learning with Python</a> by François Chollet. I highly recommend reading the book if you would like to dig deeper or learn more.
</p>

<p>
If you would like to follow along, the code is also available in a <a href="https://github.com/wtfleming/jupyter-notebooks-public/blob/master/mnist-keras.ipynb">jupyter notebook here</a>.
</p>

<div class="org-src-container">
<pre class="src src-python">from keras import models, layers
from keras.datasets import mnist
from keras.utils import to_categorical
import matplotlib.pyplot as plt
import numpy as np
</pre>
</div>

<p>
Since working with the MNIST digits is so common, Keras provides a function to load the data. You can see a full <a href="https://keras.io/datasets/">list of datasets</a> Keras has packaged up.
</p>

<p>
Let's load the data:
</p>

<div class="org-src-container">
<pre class="src src-python">(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
</pre>
</div>

<p>
The training set consists of 60,000 28x28 pixel images, and the test set 10,000.
</p>

<div class="org-src-container">
<pre class="src src-python">train_images.shape, test_images.shape
</pre>
</div>

<pre class="example" id="orgcfe4f32">
((60000, 28, 28), (10000, 28, 28))
</pre>

<p>
Lets look at the first ten training images. They are each 28x28 grayscale images with one color value between 0 and 255.
</p>

<div class="org-src-container">
<pre class="src src-python">_, ax = plt.subplots(1, 10, figsize=(10,10))

for i in range(0, 10):
    ax[i].axis('off')
    ax[i].imshow(train_images[i], cmap=plt.cm.binary)
</pre>
</div>


<figure id="orgdd419f6">
<img src="/images/mnist-keras/mnist-example-images.png" alt="mnist-example-images.png">

</figure>

<p>
And the labels representing which class the image represents.
</p>

<div class="org-src-container">
<pre class="src src-python">train_labels[0:10]
</pre>
</div>

<pre class="example" id="orgcce067c">
array([5, 0, 4, 1, 9, 2, 1, 3, 1, 4], dtype=uint8)
</pre>
<div id="outline-container-orga5ef684" class="outline-2">
<h2 id="orga5ef684">Build the neural network</h2>
<div class="outline-text-2" id="text-orga5ef684">
<p>
Now build the neural network. We'll be using a number of convolutional layers. Note that we only have to specify the input shape in the first layer. The last layer provides the output. It has 10 units (one for each digit 0 to 9) and uses a softmax activation to map the output of a network to a probability distribution over the predicted output classes.
</p>

<div class="org-src-container">
<pre class="src src-python">model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), activation='relu'))
model.add(layers.Flatten())
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(10, activation='softmax'))

model.compile(optimizer='rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
</pre>
</div>

<p>
One way to see what the network looks like is to use the summary() function:
</p>

<div class="org-src-container">
<pre class="src src-python">model.summary()
</pre>
</div>

<pre class="example" id="orgd0b3004">
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_1 (Conv2D)            (None, 26, 26, 32)        320       
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 13, 13, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 11, 11, 64)        18496     
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 5, 5, 64)          0         
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 3, 3, 64)          36928     
_________________________________________________________________
flatten_1 (Flatten)          (None, 576)               0         
_________________________________________________________________
dense_1 (Dense)              (None, 64)                36928     
_________________________________________________________________
dense_2 (Dense)              (None, 10)                650       
=================================================================
Total params: 93,322
Trainable params: 93,322
Non-trainable params: 0
_________________________________________________________________
</pre>

<div class="org-src-container">
<pre class="src src-python">(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
</pre>
</div>

<p>
We need to do some preprocessing of the images. We'll also use the first 50,000 training images for training, and the remaining 10,000 training examples for cross validation.
</p>

<div class="org-src-container">
<pre class="src src-python">train_images = train_images.reshape((60000, 28, 28, 1))
train_images= train_images.astype('float32') / 255 # rescale pixel values from range [0, 255] to [0, 1]

test_images = test_images.reshape((10000, 28, 28, 1))
test_images= test_images.astype('float32') / 255

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

validation_images = train_images[50000:]
validation_labels = train_labels[50000:]

train_images = train_images[:50000]
train_labels = train_labels[:50000]

history = model.fit(train_images, train_labels, epochs=5, batch_size=64, validation_data=(validation_images, validation_labels))
</pre>
</div>

<pre class="example" id="org1cad03c">
Train on 50000 samples, validate on 10000 samples
Epoch 1/5
50000/50000 [==============================] - 20s 391us/step - loss: 0.1959 - acc: 0.9387 - val_loss: 0.0798 - val_acc: 0.9760
Epoch 2/5
50000/50000 [==============================] - 19s 380us/step - loss: 0.0509 - acc: 0.9845 - val_loss: 0.0513 - val_acc: 0.9849
Epoch 3/5
50000/50000 [==============================] - 19s 382us/step - loss: 0.0343 - acc: 0.9892 - val_loss: 0.0408 - val_acc: 0.9880
Epoch 4/5
50000/50000 [==============================] - 19s 379us/step - loss: 0.0257 - acc: 0.9918 - val_loss: 0.0448 - val_acc: 0.9874
Epoch 5/5
50000/50000 [==============================] - 19s 377us/step - loss: 0.0208 - acc: 0.9938 - val_loss: 0.0356 - val_acc: 0.9903
</pre>

<div class="org-src-container">
<pre class="src src-python">test_loss, test_acc = model.evaluate(test_images, test_labels)
print('Accuracy:', test_acc)
print('Loss: ', test_loss)
</pre>
</div>

<pre class="example" id="org439ebdc">
10000/10000 [==============================] - 1s 122us/step
Accuracy: 0.992
Loss:  0.027386048025220953
</pre>

<p>
Looks pretty good we're seeing ~99% accuracy on the test set.
</p>
</div>
</div>
<div id="outline-container-org8ae6237" class="outline-2">
<h2 id="org8ae6237">Visualize training</h2>
<div class="outline-text-2" id="text-org8ae6237">
<p>
Now lets create a function that lets us graph the accuracy and loss values during training.
</p>

<div class="org-src-container">
<pre class="src src-python">def plot_accuracy_and_loss(history):
    acc = history.history['acc']
    val_acc = history.history['val_acc']
    loss = history.history['loss']
    val_loss = history.history['val_loss']

    epochs = range(1, len(acc) + 1)

    plt.plot(epochs, acc, 'bo', label='Training acc')
    plt.plot(epochs, val_acc, 'b', label='Validation acc')
    plt.title('Training and validation accuracy')
    plt.legend()
    plt.show()

    plt.plot(epochs, loss, 'bo', label='Training loss')
    plt.plot(epochs, val_loss, 'b', label='Validation loss')
    plt.title('Training and validation loss')
    plt.legend()
    plt.show()

plot_accuracy_and_loss(history)
</pre>
</div>


<figure id="org34284fc">
<img src="/images/mnist-keras/plot-accuracy-loss.png" alt="plot-accuracy-loss.png">

</figure>

<p>
The above looks pretty good, we appear to be starting to overfit the data as we get further in, but training and validation sets are pretty close to each other.
</p>

<p>
Now lets look at a prediction, first we'll generate predictions for the test set.
</p>

<div class="org-src-container">
<pre class="src src-python">preds = model.predict(test_images)
</pre>
</div>

<p>
We'll use the network to try to figure out what the first digit in the test set is. If we manually look, it appears to be a 7.
</p>

<div class="org-src-container">
<pre class="src src-python"># reload the test images so it will be in a format imshow() will understand
(_, _), (test_images, _) = mnist.load_data()

plt.imshow(test_images[0], cmap=plt.cm.binary)
</pre>
</div>


<figure id="org1c59f8f">
<img src="/images/mnist-keras/test-prediction.png" alt="test-prediction.png">

</figure>

<p>
Since the output of the network was a layer with 10 units and a softmax activation, we will get an array of length 10 with a prediction for each potential number. Here you can see that the network is 99.9% certain it is a seven.
</p>

<div class="org-src-container">
<pre class="src src-python">print(preds[0])
</pre>
</div>

<pre class="example" id="org9e515b2">
[2.6081236e-12 1.8943378e-09 1.0174886e-08 6.8640638e-08 2.3309353e-11
 1.9539477e-10 7.4824168e-19 9.9999988e-01 4.3342949e-10 8.6599723e-09]
</pre>

<p>
We can also find the class with the highest prediction score with a numpy function:
</p>

<div class="org-src-container">
<pre class="src src-python">np.argmax(preds[0])
</pre>
</div>

<pre class="example" id="org6cbd0b2">
7
</pre>

<p>
The next step would be to retrain the model with all 60,000 training examples (remember that in the model above we trained on 50,000 examples and validated on the remaining 10,000). I'll leave that as an exercise to the reader.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/keras/" class="tag" data-tag="keras" data-index="0">keras</a> <a href="https://wtfleming.github.io/tags/machine-learning/" class="tag" data-tag="machine-learning" data-index="1">machine-learning</a> </span></div>]]></description>
  <category><![CDATA[keras]]></category>
  <category><![CDATA[machine-learning]]></category>
  <link>https://wtfleming.github.io/blog/keras-mnist/</link>
  <guid>https://wtfleming.github.io/blog/keras-mnist/</guid>
  <pubDate>Sun, 21 Apr 2019 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Ray Tracing in the Browser using ReasonML]]></title>
  <description><![CDATA[

<figure id="org2c788f3">
<img src="/images/raytracing-reason/raytracing1.png" alt="raytracing1.png">

</figure>

<p>
I was reading Peter Shirley's little book <a href="http://in1weekend.blogspot.com/2016/01/ray-tracing-in-one-weekend.html">Ray Tracing in One Weekend</a> which provides code in C and for fun wanted to try to implement it in <a href="https://reasonml.github.io/">Reason</a>. Source code is <a href="https://github.com/wtfleming/reason-examples/tree/master/ray-tracer">available here</a>.
</p>

<p>
Above is a pregenerated image, but you can click the button below to generate a smaller lower quality picture on demand (it takes about 5 seconds to generate on my laptop).
</p>

<button id="calculate">Click Me And Lets Do Some Ray Tracing In The Browser</button>
<br />
<canvas id="demo" width="200" height="100"></canvas>

<p>
I can't think of many reasons you'd want to do ray tracing in JavaScript, but for now this was a fun little weekend project.
</p>

<script src="/js/reason-raytracer/Main.bs.695be687.js" charset="utf-8"></script>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/reasonml/" class="tag" data-tag="reasonml" data-index="0">reasonml</a> </span></div>]]></description>
  <category><![CDATA[reasonml]]></category>
  <link>https://wtfleming.github.io/blog/raytracing-with-reason/</link>
  <guid>https://wtfleming.github.io/blog/raytracing-with-reason/</guid>
  <pubDate>Fri, 23 Nov 2018 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Drawing Tilemaps on an HTML Canvas with ReasonML]]></title>
  <description><![CDATA[
<script src="/js/reason-canvas-tilemap-1/App.bs.js" charset="utf-8"> </script>

<p>
I was curious about using <a href="https://reasonml.github.io/">Reason</a> to draw 2D tilemaps in the browser using a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API">Canvas</a> element. If you need an overview of tiles, tilemaps, etc. there is a great introduction over at <a href="https://developer.mozilla.org/en-US/docs/Games/Techniques/Tilemaps">developer.mozilla.org</a>.
</p>

<p>
We will end up drawing this level of what could be a roguelike game, with an adventurer, monsters, and treasure chests:
</p>

<canvas id="demo" width="256" height="256"></canvas>

<p>
A full project with the source code is <a href="https://github.com/wtfleming/reason-examples/tree/master/bs-canvas-tilemap">available here</a>.
</p>
<div id="outline-container-orgf68428d" class="outline-2">
<h2 id="orgf68428d">Sprites</h2>
<div class="outline-text-2" id="text-orgf68428d">
<p>
We will be using a sprite atlas modified from <a href="http://files.sablab.net/Games/Angband/Angband/lib/xtra/graf/16x16.bmp">this Angband tileset</a> with a permissive <a href="http://angband.oook.cz/forum/showpost.php?p=316&amp;postcount=16">license</a>. It looks like this:
</p>


<figure id="org7c45271">
<img src="/images/reason-canvas-tilemap-1/tiles16.png" alt="tiles16.png">

</figure>

<p>
The level data is stored in a list, each number represents the index of the sprite atlas to use when drawing that tile.
</p>

<div class="org-src-container">
<pre class="src src-ocaml">let tiles = [ 
     2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
     2, 1, 1, 1, 1, 2, 5, 1, 1, 1, 1, 1, 1, 1, 1, 2, 
     2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 
     2, 1, 1, 4, 1, 2, 2, 2, 2, 2, 0, 0, 0, 2, 1, 2,
     2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 
     2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 
     2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 
     0, 2, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 
     0, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 3, 1, 1, 2, 
     0, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 
     0, 2, 1, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 
     0, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 
     0, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 
     0, 0, 2, 1, 1, 3, 1, 1, 2, 1, 1, 1, 1, 5, 1, 2, 
     0, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 
     0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 
   ];
</pre>
</div>
</div>
</div>
<div id="outline-container-org88d4efa" class="outline-2">
<h2 id="org88d4efa">Working with the DOM</h2>
<div class="outline-text-2" id="text-org88d4efa">
<p>
Reason (and <a href="https://bucklescript.github.io/">BuckleScript</a>) allows us to write type safe code to work with the browser DOM, but we will need to write some code for the interop. You could just use <code>bs.raw</code> and use <a href="https://reasonml.github.io/docs/en/interop.html">JavaScript directly</a>, but doing it this way will provide some type safety and let you catch some errors at compile time instead of runtime.
</p>

<p>
<i>Note</i>: If you need to work with the DOM you should use the excellent <a href="https://github.com/reasonml-community/bs-webapi-incubator">bs-webapi</a> library instead. The code below is just something I used for learning Reason/JavaScript interop.
</p>

<div class="org-src-container">
<pre class="src src-ocaml">module Window = {
  type t;
  [@bs.val] external t : t = "window";

  [@bs.send]
  external addEventListener : (t, string, unit =&gt; unit) =&gt; unit =
    "addEventListener";
};

module Document = {
  type t;
  [@bs.val] external t : t = "document";
};

module HtmlImageElement = {
  type t;
  [@bs.new] external make : unit =&gt; t = "Image";

  [@bs.set] external setSrc : (t, string) =&gt; unit = "src";

  [@bs.send]
  external addEventListener : (t, string, unit =&gt; unit) =&gt; unit =
    "addEventListener";

  /* Create a html &lt;img&gt; element, and return a promise that resolves when the */
  /* image has finished loading. */
  let loadFromSrc = imageSrc =&gt; {
    let imageEl = make();

    let loadImagePromise =
      Js.Promise.make((~resolve, ~reject) =&gt; {
        addEventListener(imageEl, "load", () =&gt; resolve(. imageEl));
        addEventListener(imageEl, "error", () =&gt;
          reject(. Invalid_argument("Could not load image: " ++ imageSrc))
        );
      });

    setSrc(imageEl, imageSrc);
    loadImagePromise;
  };
};

module Canvas = {
  type t;
  [@bs.send]
  external getElementById : (Document.t, string) =&gt; t = "getElementById";
};

module Context = {
  type t;

  /* JavaScript equivalent: canvas.getContext('2d'); */
  [@bs.send]
  external getContext2d : (Canvas.t, [@bs.as "2d"] _) =&gt; t = "getContext";

  [@bs.send]
  external drawImage :
    (
      t,
      ~image: HtmlImageElement.t,
      ~dx: int,
      ~dy: int,
      ~dWidth: int,
      ~dHeight: int,
      ~sx: int,
      ~sy: int,
      ~sWidth: int,
      ~sHeight: int
    ) =&gt;
    unit =
    "drawImage";
};
</pre>
</div>
</div>
</div>
<div id="outline-container-org3e30cfa" class="outline-2">
<h2 id="org3e30cfa">SpriteAtlas</h2>
<div class="outline-text-2" id="text-org3e30cfa">
<p>
The sprite atlas is an image with all the sprites in it, it looks like:
</p>


<figure id="org594f6e1">
<img src="/images/reason-canvas-tilemap-1/tiles16.png" alt="tiles16.png">

</figure>

<p>
This code allows us to load the atlas into memory and draw one of the sprites into the context.
</p>

<div class="org-src-container">
<pre class="src src-ocaml">module SpriteAtlas = {
  type t = {
    imageElement: HtmlImageElement.t,
    spriteWidth: int,
  };

  let make = (src: string, spriteWidth: int) =&gt;
    HtmlImageElement.loadFromSrc(src)
    |&gt; Js.Promise.then_(imageElement =&gt;
         Js.Promise.resolve({imageElement, spriteWidth})
       );

  let drawSprite = (~atlas: t, ~ctx, ~atlasNumber, ~x, ~y) =&gt;
    Context.drawImage(
      ctx,
      ~image=atlas.imageElement,
      ~dx=atlasNumber * atlas.spriteWidth,
      ~dy=0, /*  In this code we only support atlases with a single row of images */
      ~dWidth=atlas.spriteWidth,
      ~dHeight=atlas.spriteWidth,
      ~sx=x,
      ~sy=y,
      ~sWidth=atlas.spriteWidth,
      ~sHeight=atlas.spriteWidth,
    );
};
</pre>
</div>
</div>
</div>
<div id="outline-container-org507a141" class="outline-2">
<h2 id="org507a141">Tilemap</h2>
<div class="outline-text-2" id="text-org507a141">
<p>
The tilemap describes what our level looks like, it has a reference to a sprite atlas and a number of rows and columns representing what to draw in the level.
</p>

<div class="org-src-container">
<pre class="src src-ocaml">module TileMap = {
  type t = {
    atlas: SpriteAtlas.t,
    numRows: int,
    numCols: int,
    tileSize: int, /* pixels */
    tiles: list(int) /* Maybe should be an array so it is mutable? */
  };

  let make = (~atlas, ~numRows, ~numCols, ~tileSize, ~tiles) =&gt; {
    atlas,
    numRows,
    numCols,
    tileSize,
    tiles,
  };

  /* Given an index in a tilemap, get the row and column as if it was a 2D array */
  let getRowAndColumn = (idx: int, tilemap: t) : (int, int) =&gt; {
    let col: int = idx mod tilemap.numCols;
    let row: int =
      Js.Math.floor(float_of_int(idx) /. float_of_int(tilemap.numCols));
    (row, col);
  };

  let render = (ctx: Context.t, tilemap: t) =&gt;
    List.iteri(
      (i, num) =&gt; {
        let (row, col) = getRowAndColumn(i, tilemap);
        SpriteAtlas.drawSprite(
          ~atlas=tilemap.atlas,
          ~ctx,
          ~atlasNumber=num,
          ~x=col * tilemap.tileSize,
          ~y=row * tilemap.tileSize,
        );
      },
      tilemap.tiles,
    );
};
</pre>
</div>
</div>
</div>
<div id="outline-container-orgfb33056" class="outline-2">
<h2 id="orgfb33056">Drawing the tilemap</h2>
<div class="outline-text-2" id="text-orgfb33056">
<p>
Here we do the actual work. Setup the canvas, load the sprites, create a tilemap, then render it in the browser.
</p>

<div class="org-src-container">
<pre class="src src-ocaml">let doWindowOnload = () =&gt; {
  let canvas: Canvas.t = Canvas.getElementById(Document.t, "demo");
  let ctx: Context.t = Context.getContext2d(canvas);
  SpriteAtlas.make("./tiles16.png", 16)
  |&gt; Js.Promise.then_(atlas =&gt; {
     let tiles = [ 
          2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 
          2, 1, 1, 1, 1, 2, 5, 1, 1, 1, 1, 1, 1, 1, 1, 2, 
          2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 
          2, 1, 1, 4, 1, 2, 2, 2, 2, 2, 0, 0, 0, 2, 1, 2,
          2, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 
          2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 
          2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 
          0, 2, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 
          0, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 3, 1, 1, 2, 
          0, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 
          0, 2, 1, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 
          0, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 
          0, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 2, 
          0, 0, 2, 1, 1, 3, 1, 1, 2, 1, 1, 1, 1, 5, 1, 2, 
          0, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 
          0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 
        ]; 

       let tilemap = 
         TileMap.make(~atlas, ~numRows=16, ~numCols=16, ~tileSize=16, ~tiles);

       TileMap.render(ctx, tilemap);

       Js.Promise.resolve();
     })
  |&gt; Js.Promise.catch(err =&gt; {
       Js.log2("Failure!", err);
       Js.Promise.resolve();
     })
  |&gt; ignore;
};

Window.addEventListener(Window.t, "load", doWindowOnload);
</pre>
</div>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/reasonml/" class="tag" data-tag="reasonml" data-index="0">reasonml</a> </span></div>]]></description>
  <category><![CDATA[reasonml]]></category>
  <link>https://wtfleming.github.io/blog/reason-html-canvas-tilemap/</link>
  <guid>https://wtfleming.github.io/blog/reason-html-canvas-tilemap/</guid>
  <pubDate>Sun, 17 Jun 2018 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Exploring Geospatial data in Elixir with Phoenix, D3, and PostGIS]]></title>
  <description><![CDATA[
<p>
I noticed that Kaggle has started hosting some publicly available datasets. One of which is <a href="https://www.kaggle.com/kaggle/climate-data-from-ocean-ships">Ocean Ship Logbooks (1750-1850)</a>. I thought it would be interesting to visualize Captain Cook's travels on the <a href="https://en.wikipedia.org/wiki/HMS_Endeavour">HMS Endeavour</a> using the <a href="http://www.phoenixframework.org/">Phoenix Web Framework</a>, the <a href="http://d3js.org/">D3</a> JavaScript library, and <a href="http://postgis.net/">PostGIS</a>.
</p>

<p>
Source code is available at <a href="https://github.com/wtfleming/phoenix-postgis-example">this GitHub repo</a>.
</p>
<div id="outline-container-orgca1a713" class="outline-2">
<h2 id="orgca1a713">Captain Cook's Journeys on the Endeavor</h2>
<div class="outline-text-2" id="text-orgca1a713">
<div id="d3_map"></div>

<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>

<script>
  var shipData;
  var width = 500;
  var height = 500;
  var projection = d3.geo.mercator()
    .scale(80)
    .translate([width / 2, height / 2]);

  var mapLoaded = false;

  var svg = d3.select("#d3_map")
    .append("svg")
    .attr("width", width)
    .attr("height", height);

  
  d3.json("/js/phoenix-captain-cook/world.geojson", createMap);

  function createMap(countries) {
    var geoPath = d3.geo.path().projection(projection);
    d3.select("svg").selectAll("path").data(countries.features)
      .enter()
      .append("path")
      .attr("d", geoPath)
      .attr("class", "countries");
    mapLoaded = true;
  };

  function makeRequest(url) {
    httpRequest = new XMLHttpRequest();
    if (!httpRequest) {
      console.log('Cannot create an XMLHTTP instance');
      return false;
    }
    httpRequest.onreadystatechange = jsonContents;
    httpRequest.open('GET', url);
    httpRequest.send();
  }

  function jsonContents() {
    if (httpRequest.readyState === XMLHttpRequest.DONE) {
      if (httpRequest.status === 200) {
        var response = JSON.parse(httpRequest.responseText);
        shipData = response.ship_data;
        drawCircle(shipData.slice(0));
      } else {
        console.log('There was a problem with the request.');
      }
    }
  }

  
  function drawCircle(shipDataCopy) {
    if (mapLoaded == false) {
      setTimeout(function() { drawCircle(shipData.slice(0))}, 50);
      return;
    }

    // if no data, erase the circles from the map and start over
    if (shipDataCopy.length == 0) {
      svg.selectAll("circle").remove();
      setTimeout(function() { drawCircle(shipData.slice(0))}, 50);
      return;
    }

    shipDatum = shipDataCopy.shift();

    d3.select("svg")
      .append("circle")
      .style("fill", "red")
      .attr("r", 2)
      .attr("cx", function(d) {return projection([shipDatum.lon,shipDatum.lat])[0]})
      .attr("cy", function(d) {return projection([shipDatum.lon,shipDatum.lat])[1]});

    setTimeout(function() { drawCircle(shipDataCopy) }, 50);
 }

makeRequest("/js/phoenix-captain-cook/ship_data.json");

</script>
</div>
</div>
<div id="outline-container-org5c5c301" class="outline-2">
<h2 id="org5c5c301">Docker</h2>
<div class="outline-text-2" id="text-org5c5c301">
<p>
For simplicity in this example we'll be using the <a href="https://hub.docker.com/r/mdillon/postgis/">mdillon/postgis</a> Docker image. If you already have PostGIS installed or do not want to use Docker feel free to skip this section.
</p>

<div class="org-src-container">
<pre class="src src-sh"># Create a persistent data volume
$ sudo docker create -v /var/lib/postgresql/data \
    --name postgres-ocean-ships-data busybox

# Create the postgis container
$ sudo docker run --name postgres-ocean-ships -p 5432:5432 \
    -e POSTGRES_PASSWORD=postgres -d --volumes-from postgres-ocean-ships-data \
    mdillon/postgis:9.4
</pre>
</div>

<p>
You can double check everything is working by connecting to Postgres. When prompted, the password will be "postgres", but you should consider using a much better one.
</p>

<p>
If you have psql installed locally you can do it like so:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ psql -h localhost -p 5432 -U postgres
</pre>
</div>

<p>
Otherwise you can also use the one in the container and connect with these commands:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ sudo docker exec -i -t postgres-ocean-ships bash
root@10499abd059e:/# psql -h localhost -p 5432 -U postgres
</pre>
</div>

<p>
Now that the containers are set up, in the future you can start and stop the PostGIS container like this:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ sudo docker start postgres-ocean-ships
$ sudo docker stop postgres-ocean-ships
</pre>
</div>
</div>
</div>
<div id="outline-container-org080acda" class="outline-2">
<h2 id="org080acda">Phoenix</h2>
<div class="outline-text-2" id="text-org080acda">
<p>
Create the Phoenix app:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ mix phoenix.new ocean_ship_logbooks
$ cd ocean_ship_logbooks/
$ mix ecto.create
</pre>
</div>

<p>
Add these Elixir <a href="https://github.com/beatrichartz/csv">CSV</a> and <a href="https://github.com/bryanjos/geo">Geo</a> libraries to your mix.exs dependencies.
</p>

<pre class="example" id="orgebf6db4">
{:csv, "~&gt; 1.2.3"}
{:geo, "~&gt; 1.0"}
</pre>

<p>
Fetch them
</p>

<div class="org-src-container">
<pre class="src src-sh">$ mix deps.get
</pre>
</div>

<p>
We are going to be using be using the CSV library to parse the data, and the Geo library to work with PostGIS (via <a href="https://github.com/elixir-lang/ecto">Ecto</a>), so add to your config files (dev.exs, test.exs, and prod.secret.exs):
</p>

<div class="org-src-container">
<pre class="src src-elixir">extensions: [{Geo.PostGIS.Extension, library: Geo}]
</pre>
</div>

<p>
For example, the database section of tour config/dev.exs should now look something like:
</p>

<div class="org-src-container">
<pre class="src src-elixir"># Configure your database
config :ocean_ship_logbooks, OceanShipLogbooks.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: "postgres",
  password: "postgres",
  database: "ocean_ship_logbooks_dev",
  hostname: "localhost",
  pool_size: 10,
  extensions: [{Geo.PostGIS.Extension, library: Geo}]
</pre>
</div>
</div>
</div>
<div id="outline-container-org70d04fa" class="outline-2">
<h2 id="org70d04fa">Create database migrations</h2>
<div class="outline-text-2" id="text-org70d04fa">
<p>
First we will want to enable the PostGIS extension in Postgres for our database. Lets generate a migration.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ mix ecto.gen.migration enable_postgis
* creating priv/repo/migrations
* creating priv/repo/migrations/20160128183445_enable_postgis.exs
</pre>
</div>

<p>
Edit 20160128183445<sub>enable</sub><sub>postgis.exs</sub> so that the contents are this:
</p>

<div class="org-src-container">
<pre class="src src-elixir">defmodule OceanShipLogbooks.Repo.Migrations.EnablePostgis do
  use Ecto.Migration

  def up do
    execute "CREATE EXTENSION IF NOT EXISTS postgis"
  end

  def down do
    execute "DROP EXTENSION IF EXISTS postgis"
  end

end
</pre>
</div>

<p>
Now lets create ship data table.
</p>

<p>
Since the ship data will be accessed via a JSON API, you normally might generate a resource with the mix <a href="http://hexdocs.pm/phoenix/Mix.Tasks.Phoenix.Gen.Json.html">phoenix.gen.json</a> task to create the model, migration, view, etc. code, but since we are using custom types from the Geo library we'll just create them manually.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ mix ecto.gen.migration create_ship_data
* creating priv/repo/migrations
* creating priv/repo/migrations/20160128223253_create_ship_data.exs
</pre>
</div>

<p>
We'll want to store the name of the ship, a timestamp, and a geometry object in the database, and we will be querying on the ship's name. Alter the file so that it has the following contents:
</p>

<div class="org-src-container">
<pre class="src src-elixir">defmodule OceanShipLogbooks.Repo.Migrations.CreateShipData do
  use Ecto.Migration

  def change do
    create table(:ship_data) do
      add :ship,     :string
      add :utc,      :integer
      add :geom,     :geometry
    end
    create index(:ship_data, [:ship])
  end

end
</pre>
</div>

<p>
Run the migrations:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ mix ecto.migrate
</pre>
</div>
</div>
</div>
<div id="outline-container-orgac93ad0" class="outline-2">
<h2 id="orgac93ad0">ShipData Model</h2>
<div class="outline-text-2" id="text-orgac93ad0">
<p>
Create a file at web/models/ship<sub>data.ex</sub> with these contents:
</p>

<div class="org-src-container">
<pre class="src src-elixir">defmodule OceanShipLogbooks.ShipData do
  use OceanShipLogbooks.Web, :model
  schema "ship_data" do
    field :ship, :string
    field :utc,  :integer
    field :geom, Geo.Point
  end
end
</pre>
</div>

<p>
This is a pretty straightforward model. We are using the Geo library so we can use a geometry column type that is specific to PostGIS.
</p>
</div>
</div>
<div id="outline-container-orgca7c867" class="outline-2">
<h2 id="orgca7c867">ShipData View</h2>
<div class="outline-text-2" id="text-orgca7c867">
<p>
Create a file web/views/ship<sub>data</sub><sub>view.ex</sub> with these contents:
</p>

<div class="org-src-container">
<pre class="src src-elixir">defmodule OceanShipLogbooks.ShipDataView do
  use OceanShipLogbooks.Web, :view

  def render("show_ships.json", %{ships: ships}) do
   %{ship_data: render_many(ships, OceanShipLogbooks.ShipDataView, "ship_data.json")}
  end

  def render("ship_data.json", %{ship_data: ship}) do
    {lat, lon} = ship.geom.coordinates

    %{ship: ship.ship,
      utc: ship.utc,
      lat: lat,
      lon: lon}
  end

end
</pre>
</div>
</div>
</div>
<div id="outline-container-org5225df9" class="outline-2">
<h2 id="org5225df9">Router</h2>
<div class="outline-text-2" id="text-org5225df9">
<p>
Look in web/router.ex for the api block. Uncomment it and change to look like this:
</p>

<div class="org-src-container">
<pre class="src src-elixir"># Other scopes may use custom stacks.
scope "/api", OceanShipLogbooks do
  pipe_through :api
  resources "/ship_data", ShipDataController, only: [:index]
end
</pre>
</div>
</div>
</div>
<div id="outline-container-orgc7ffa35" class="outline-2">
<h2 id="orgc7ffa35">Ship Data Controller</h2>
<div class="outline-text-2" id="text-orgc7ffa35">
<p>
Create a file web/controllers/ship<sub>data</sub><sub>controller.ex</sub> with these contents:
</p>

<div class="org-src-container">
<pre class="src src-elixir">defmodule OceanShipLogbooks.ShipDataController do
  use OceanShipLogbooks.Web, :controller
  alias OceanShipLogbooks.ShipData

  def index(conn, _params) do
    # For simplicity in this example we hard code against
    # a specific ship name.
    query = from s in ShipData,
    where: s.ship == "Endeavour",
    order_by: [asc: s.utc],
    select: s

    ships = Repo.all(query)
    render(conn, "show_ships.json", ships: ships)
  end

  # These next two functions probably do not belong in a controller,
  # since they are for manually importing data, but we put them in here
  # for this example.
  def import_from_csv() do
    File.stream!("ship-data.csv")
    |&gt; CSV.decode(headers: true)
    |&gt; Stream.filter(fn(x) -&gt; x["Lat3"] != "NA" and x["Lon3"] != "NA" end)
    |&gt; Stream.map(&amp;build_ship/1)
    |&gt; Enum.each(&amp;OceanShipLogbooks.Repo.insert!/1)
  end

  defp build_ship(row) do
    {lat, _} = Float.parse(row["Lat3"])
    {lon, _} = Float.parse(row["Lon3"])
    {utc, _} = Integer.parse(row["UTC"])
    geom = %Geo.Point{ coordinates: {lat, lon}, srid: 4326}
    %OceanShipLogbooks.ShipData{ship: row["ShipName"], utc: utc, geom: geom}
  end

end
</pre>
</div>
</div>
</div>
<div id="outline-container-org33fa08c" class="outline-2">
<h2 id="org33fa08c">Download and clean the data.</h2>
<div class="outline-text-2" id="text-org33fa08c">
<p>
Ensure you have downloaded the data the <a href="https://www.kaggle.com/kaggle/climate-data-from-ocean-ships">ship data from Kaggle</a>. Extract the file CLIWOC15.csv into the root directory of your project (this file should be about 200 megabytes in size).
</p>

<p>
Unfortunately the Elixir CSV parser we are using <a href="https://github.com/beatrichartz/csv/issues/13">is not RFC 4180 compliant</a> and the ship data includes fields with escaped newlines. I did not investigate other Elixir or Erlang CSV parsers, so while not ideal, until this is fixed I removed the newlines with the following python script called transform<sub>csv.py</sub>:
</p>

<div class="org-src-container">
<pre class="src src-python">import csv

with open("CLIWOC15.csv", 'rU') as csvIN:
    with open('ship-data.csv', 'wb') as csvOUT:
        writer = csv.writer(csvOUT, delimiter=',', quoting=csv.QUOTE_ALL)
        for line in csv.reader(csvIN, delimiter=','):
            line = [x.replace('\n', '') for x in line]
            writer.writerow(line)
</pre>
</div>

<p>
Run the script to remove extraneous newlines:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ python transform-csv.py
</pre>
</div>
</div>
</div>
<div id="outline-container-orgc7071c9" class="outline-2">
<h2 id="orgc7071c9">Load the data into PostGIS</h2>
<div class="outline-text-2" id="text-orgc7071c9">
<p>
Run the app inside IEx (Interactive Elixir):
</p>

<div class="org-src-container">
<pre class="src src-sh">$ iex -S mix phoenix.server
iex(1)&gt; OceanShipLogbooks.ShipDataController.import_from_csv
# Exit iex
</pre>
</div>

<p>
Now verify the data is in PostGIS. Your session should look something like this:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ psql -h localhost -p 5432 -U postgres ocean_ship_logbooks_dev

ocean_ship_logbooks_dev=# select count(*) from ship_data;
 count  
--------
 252917
(1 row)

ocean_ship_logbooks_dev=# select * from ship_data where ship = 'Endeavour' limit 4;
  id   |   ship    |    utc     |                        geom                        
-------+-----------+------------+----------------------------------------------------
 41085 | Endeavour | 1768110915 | 0101000020E610000024287E8CB97B35C03333333333D342C0
 41084 | Endeavour | 1768093011 | 0101000020E61000006666666666E62F40423EE8D9ACAA35C0
 41083 | Endeavour | 1768090513 | 0101000020E6100000545227A08988454000000000000024C0
 41082 | Endeavour | 1768090413 | 0101000020E6100000AE47E17A14CE4540D7A3703D0A5724C0
</pre>
</div>

<p>
You can also query the data via the phoenix app:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ iex -S mix phoenix.server

iex(1)&gt; import Ecto.Query, only: [from: 2]
iex(2)&gt; query = from s in OceanShipLogbooks.ShipData,
...(2)&gt; where: s.ship == "Endeavour",
...(2)&gt; limit: 4,
...(2)&gt; select: s
iex(3)&gt; ships = OceanShipLogbooks.Repo.all(query)
[%OceanShipLogbooks.ShipData{__meta__: #Ecto.Schema.Metadata&lt;:loaded&gt;,
  geom: %Geo.Point{coordinates: {-21.4833, -37.65}, srid: 4326}, id: 41085,
  ship: "Endeavour", utc: 1768110915},
 %OceanShipLogbooks.ShipData{__meta__: #Ecto.Schema.Metadata&lt;:loaded&gt;,
  geom: %Geo.Point{coordinates: {15.95, -21.6667}, srid: 4326}, id: 41084,
  ship: "Endeavour", utc: 1768093011},
 %OceanShipLogbooks.ShipData{__meta__: #Ecto.Schema.Metadata&lt;:loaded&gt;,
  geom: %Geo.Point{coordinates: {43.0667, -10.0}, srid: 4326}, id: 41083,
  ship: "Endeavour", utc: 1768090513},
 %OceanShipLogbooks.ShipData{__meta__: #Ecto.Schema.Metadata&lt;:loaded&gt;,
  geom: %Geo.Point{coordinates: {43.61, -10.17}, srid: 4326}, id: 41082,
  ship: "Endeavour", utc: 1768090413}]
</pre>
</div>

<p>
Feel free to delete the CSV files to clear up a few hundred megs of disk space.
</p>
</div>
</div>
<div id="outline-container-orgcc87ad5" class="outline-2">
<h2 id="orgcc87ad5">Download Countries GeoJSON</h2>
<div class="outline-text-2" id="text-orgcc87ad5">
<p>
Get the GeoGSON data from <a href="http://emeeks.github.io/d3ia/world.geojson">this GitHub repo</a> and put the geojson file at priv/static/js/world.geojson
</p>

<p>
This will let us draw a map of the world in D3.
</p>
</div>
</div>
<div id="outline-container-org66b0f40" class="outline-2">
<h2 id="org66b0f40">HTML and Javascript code</h2>
<div class="outline-text-2" id="text-org66b0f40">
<p>
Edit web/templates/page/index.html.eex to look like this:
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;div class="jumbotron"&gt;
  &lt;h2&gt;Captain Cook's travels&lt;/h2&gt;
&lt;/div&gt;

&lt;div id="d3_map"&gt;&lt;/div&gt; 

&lt;script src="//d3js.org/d3.v3.min.js" charset="utf-8"&gt;&lt;/script&gt;

&lt;script&gt;
  var shipData;
  var width = 500;
  var height = 500;
  var projection = d3.geo.mercator()
    .scale(80)
    .translate([width / 2, height / 2]);

  var svg = d3.select("#d3_map")
    .append("svg")
    .attr("width", width)
    .attr("height", height);

  d3.json("/js/world.geojson", createMap);

  function createMap(countries) {
    var geoPath = d3.geo.path().projection(projection);
    d3.select("svg").selectAll("path").data(countries.features)
      .enter()
      .append("path")
      .attr("d", geoPath)
      .attr("class", "countries");
  };

  function makeRequest(url) {
    httpRequest = new XMLHttpRequest();
    if (!httpRequest) {
      console.log('Cannot create an XMLHTTP instance');
      return false;
    }
    httpRequest.onreadystatechange = jsonContents;
    httpRequest.open('GET', url);
    httpRequest.send();
  }

  function jsonContents() {
    if (httpRequest.readyState === XMLHttpRequest.DONE) {
      if (httpRequest.status === 200) {
        var response = JSON.parse(httpRequest.responseText);
        shipData = response.ship_data;
        drawCircle(shipData.slice(0));
      } else {
        console.log('There was a problem with the request.');
      }
    }
  }

  function drawCircle(shipDataCopy) {
    // if no data, erase the circles from the map and start over
    if (shipDataCopy.length == 0) {
      svg.selectAll("circle").remove();
      setTimeout(function() { drawCircle(shipData.slice(0))}, 50);
      return;
    }

    shipDatum = shipDataCopy.shift();

    d3.select("svg")
      .append("circle")
      .style("fill", "red")
      .attr("r", 2)
      .attr("cx", function(d) {return projection([shipDatum.lon,shipDatum.lat])[0]})
      .attr("cy", function(d) {return projection([shipDatum.lon,shipDatum.lat])[1]});

    setTimeout(function() { drawCircle(shipDataCopy) }, 50);
 }

makeRequest("/api/ship_data");

&lt;/script&gt;
</pre>
</div>

<p>
Now start the server
</p>

<div class="org-src-container">
<pre class="src src-sh">$ mix phoenix.server
</pre>
</div>

<p>
Open a web browser to <a href="http://localhost:4000">http://localhost:4000</a> to see an animation like at the top of this post and a page that should look something like this:
</p>


<figure id="orgff44aab">
<img src="/images/phoenix-postgis-captain-cook/cooks-travels.jpg" alt="cooks-travels.jpg">

</figure>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/erlang/" class="tag" data-tag="erlang" data-index="0">erlang</a> <a href="https://wtfleming.github.io/tags/elixir/" class="tag" data-tag="elixir" data-index="1">elixir</a> <a href="https://wtfleming.github.io/tags/postgis/" class="tag" data-tag="postgis" data-index="2">postgis</a> </span></div>]]></description>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[elixir]]></category>
  <category><![CDATA[postgis]]></category>
  <link>https://wtfleming.github.io/blog/geospatial-app-elixir-postgis-phoenix/</link>
  <guid>https://wtfleming.github.io/blog/geospatial-app-elixir-postgis-phoenix/</guid>
  <pubDate>Thu, 28 Jan 2016 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Getting started with OpenGL in Elixir]]></title>
  <description><![CDATA[
<p>
I was curious about using OpenGL with Elixir and couldn't find much very information. Other than a kludge for working with constants defined in Erlang .hrl files it turned out to be not too difficult.
</p>

<p>
The final result draws a triangle on the screen and looks like this:
</p>


<figure id="org350fe60">
<img src="/images/elixir-opengl-01/triangle.png" alt="triangle.png">

</figure>
<div id="outline-container-orgc52a911" class="outline-2">
<h2 id="orgc52a911">wxWidgets and Erlang</h2>
<div class="outline-text-2" id="text-orgc52a911">
<p>
Erlang/OTP ships with a port of <a href="http://www.erlang.org/doc/man/wx.html">wxWidgets</a>, so creating a window and obtaining an OpenGL context is relatively easy.
</p>

<p>
To see some examples and the associated Erlang code start iex and run the following command:
</p>

<div class="org-src-container">
<pre class="src src-elixir">iex(1)&gt; :wx.demo
</pre>
</div>

<p>
A window that looks something like this should appear.
</p>


<figure id="org21632a2">
<img src="/images/elixir-opengl-01/wxerlang.png" alt="wxerlang.png">

</figure>

<p>
Next we want to do something similar, but in Elixir instead.
</p>
</div>
</div>
<div id="outline-container-org5df99e6" class="outline-2">
<h2 id="org5df99e6">Create an Elixir project</h2>
<div class="outline-text-2" id="text-org5df99e6">
<p>
Run these commands in a shell
</p>

<div class="org-src-container">
<pre class="src src-sh">$ mix new elixir_opengl
$ cd elixir_opengl

# To make this work we are also going to need to create a couple Erlang source files
$ mkdir src
</pre>
</div>
</div>
</div>
<div id="outline-container-org7b2e9d0" class="outline-2">
<h2 id="org7b2e9d0">Erlang modules</h2>
<div class="outline-text-2" id="text-org7b2e9d0">
<p>
If you look inside your Erlang/OTP distribution directory at the file lib/wx/include/wx.hrl you will see a number of defines that look like:
</p>

<div class="org-src-container">
<pre class="src src-erlang">-define(wxID_ANY, -1).
</pre>
</div>

<p>
I found <a href="https://groups.google.com/forum/#!topic/elixir-lang-talk/VbGTz7rKebM">this discussion</a> about how to access them from Elixir - create an Erlang module with functions that return the value. You can then reference it from Elixir with a function call like this:
</p>

<div class="org-src-container">
<pre class="src src-elixir">:wx_const.wx_id_any()
</pre>
</div>

<p>
Now create an Erlang file named src/wx<sub>const.erl</sub> with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-erlang">-module(wx_const).
-compile(export_all).

-include_lib("wx/include/wx.hrl").

wx_id_any() -&gt;
  ?wxID_ANY.

wx_sunken_border() -&gt;
  ?wxSUNKEN_BORDER.

wx_gl_rgba() -&gt;
  ?WX_GL_RGBA.

wx_gl_doublebuffer() -&gt;
 ?WX_GL_DOUBLEBUFFER.

wx_gl_min_red() -&gt;
  ?WX_GL_MIN_RED.

wx_gl_min_green() -&gt;
  ?WX_GL_MIN_GREEN.

wx_gl_min_blue() -&gt;
  ?WX_GL_MIN_BLUE.

wx_gl_depth_size() -&gt;
  ?WX_GL_DEPTH_SIZE.
</pre>
</div>

<p>
Next create a file src/gl<sub>const.erl</sub> with these contents:
</p>

<div class="org-src-container">
<pre class="src src-erlang">-module(gl_const).
-compile(export_all).

-include_lib("wx/include/gl.hrl").

gl_smooth() -&gt;
  ?GL_SMOOTH.

gl_depth_test() -&gt;
  ?GL_DEPTH_TEST.

gl_lequal() -&gt;
  ?GL_LEQUAL.

gl_perspective_correction_hint() -&gt;
  ?GL_PERSPECTIVE_CORRECTION_HINT.

gl_nicest() -&gt;
  ?GL_NICEST.

gl_color_buffer_bit() -&gt;
  ?GL_COLOR_BUFFER_BIT.

gl_depth_buffer_bit() -&gt;
  ?GL_DEPTH_BUFFER_BIT.

gl_triangles() -&gt;
  ?GL_TRIANGLES.

gl_projection() -&gt;
  ?GL_PROJECTION.

gl_modelview() -&gt;
  ?GL_MODELVIEW.
</pre>
</div>

<p>
We're now done with Erlang.
</p>
</div>
</div>
<div id="outline-container-org6c95029" class="outline-2">
<h2 id="org6c95029">Elixir Code</h2>
<div class="outline-text-2" id="text-org6c95029">
<p>
Change lib/elixir<sub>opengl.ex</sub> to look like this:
</p>

<div class="org-src-container">
<pre class="src src-elixir">defmodule ElixirOpengl do
  @behaviour :wx_object
  use Bitwise

  @title 'Elixir OpenGL'
  @size {600, 600}

  #######
  # API #
  #######
  def start_link() do
    :wx_object.start_link(__MODULE__, [], [])
  end

  #################################
  # :wx_object behavior callbacks #
  #################################
  def init(config) do
    wx = :wx.new(config)
    frame = :wxFrame.new(wx, :wx_const.wx_id_any, @title, [{:size, @size}])
    :wxWindow.connect(frame, :close_window)
    :wxFrame.show(frame)

    opts = [{:size, @size}]
    gl_attrib = [{:attribList, [:wx_const.wx_gl_rgba,
                                :wx_const.wx_gl_doublebuffer,
                                :wx_const.wx_gl_min_red, 8,
                                :wx_const.wx_gl_min_green, 8,
                                :wx_const.wx_gl_min_blue, 8,
                                :wx_const.wx_gl_depth_size, 24, 0]}]
    canvas = :wxGLCanvas.new(frame, opts ++ gl_attrib)

    :wxGLCanvas.connect(canvas, :size)
    :wxWindow.reparent(canvas, frame)
    :wxGLCanvas.setCurrent(canvas)
    setup_gl(canvas)

    # Periodically send a message to trigger a redraw of the scene
    timer = :timer.send_interval(20, self(), :update)

    {frame, %{canvas: canvas, timer: timer}}
  end

  def code_change(_, _, state) do
    {:stop, :not_implemented, state}
  end

  def handle_cast(msg, state) do
    IO.puts "Cast:"
    IO.inspect msg
    {:noreply, state}
  end

  def handle_call(msg, _from, state) do
    IO.puts "Call:"
    IO.inspect msg
    {:reply, :ok, state}
  end

  def handle_info(:stop, state) do
    :timer.cancel(state.timer)
    :wxGLCanvas.destroy(state.canvas)
    {:stop, :normal, state}
  end

  def handle_info(:update, state) do
    :wx.batch(fn -&gt; render(state) end)
    {:noreply, state}
  end

  # Example input:
  # {:wx, -2006, {:wx_ref, 35, :wxFrame, []}, [], {:wxClose, :close_window}}
  def handle_event({:wx, _, _, _, {:wxClose, :close_window}}, state) do
    {:stop, :normal, state}
  end

  def handle_event({:wx, _, _, _, {:wxSize, :size, {width, height}, _}}, state) do
    if width != 0 and height != 0 do
      resize_gl_scene(width, height)
    end
    {:noreply, state}
  end

  def terminate(_reason, state) do
    :wxGLCanvas.destroy(state.canvas)
    :timer.cancel(state.timer)
    :timer.sleep(300)
  end

  #####################
  # Private Functions #
  #####################
  defp setup_gl(win) do
    {w, h} = :wxWindow.getClientSize(win)
    resize_gl_scene(w, h)
    :gl.shadeModel(:gl_const.gl_smooth)
    :gl.clearColor(0.0, 0.0, 0.0, 0.0)
    :gl.clearDepth(1.0)
    :gl.enable(:gl_const.gl_depth_test)
    :gl.depthFunc(:gl_const.gl_lequal)
    :gl.hint(:gl_const.gl_perspective_correction_hint, :gl_const.gl_nicest)
    :ok
  end

  defp resize_gl_scene(width, height) do
    :gl.viewport(0, 0, width, height)
    :gl.matrixMode(:gl_const.gl_projection)
    :gl.loadIdentity()
    :glu.perspective(45.0, width / height, 0.1, 100.0)
    :gl.matrixMode(:gl_const.gl_modelview)
    :gl.loadIdentity()
    :ok
  end

  defp draw() do
    :gl.clear(Bitwise.bor(:gl_const.gl_color_buffer_bit, :gl_const.gl_depth_buffer_bit))
    :gl.loadIdentity()
    :gl.translatef(-1.5, 0.0, -6.0)
    :gl.'begin'(:gl_const.gl_triangles)
    :gl.vertex3f(0.0, 1.0, 0.0)
    :gl.vertex3f(-1.0, -1.0, 0.0)
    :gl.vertex3f(1.0, -1.0, 0.0)
    :gl.'end'()
    :ok
  end

  defp render(%{canvas: canvas} = _state) do
    draw()
    :wxGLCanvas.swapBuffers(canvas)
    :ok
  end
end
</pre>
</div>

<p>
Now lets run the program, start iex like this:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ iex -S mix
</pre>
</div>

<p>
And run this command
</p>

<div class="org-src-container">
<pre class="src src-elixir">iex(1)&gt; ElixirOpengl.start_link
</pre>
</div>

<p>
A window should appear that looks like this:
</p>


<figure id="orgd58d34b">
<img src="/images/elixir-opengl-01/triangle.png" alt="triangle.png">

</figure>

<p>
I suspect this can be improved on, but we've got an OpenGL context which is good enough for now.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/erlang/" class="tag" data-tag="erlang" data-index="0">erlang</a> <a href="https://wtfleming.github.io/tags/elixir/" class="tag" data-tag="elixir" data-index="1">elixir</a> </span></div>]]></description>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[elixir]]></category>
  <link>https://wtfleming.github.io/blog/getting-started-opengl-elixir/</link>
  <guid>https://wtfleming.github.io/blog/getting-started-opengl-elixir/</guid>
  <pubDate>Sun, 03 Jan 2016 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Erlang clustering on the Raspberry Pi and BeagleBone with Elixir]]></title>
  <description><![CDATA[
<p>
I have been looking at Elixir/Erlang clustering with credit card sized computers and using the <a href="http://www.phoenixframework.org">Phoenix web framework</a> to communicate from the cluster to an Android tablet in realtime.
</p>

<p>
I am pleasantly surprised at how easy it has been and how little code I had to write for this demo.
</p>

<iframe width="420" height="315" src="https://www.youtube.com/embed/p8XyvRWchEI" frameborder="0" allowfullscreen></iframe>

<p>
In the above video I am running an Erlang cluster consisting of a desktop x86 based PC on Ubuntu, a Raspberry Pi, a BeagleBone Black, and an Android tablet. Each of the nodes are running Erlang/OTP 18.1 and Elixir 1.1.1.
</p>

<p>
A process written in Elixir on the PC periodically communicates with the Raspberry Pi and BeagleBone to turn on and off LEDs connected via a <a href="https://en.wikipedia.org/wiki/General-purpose_input/output">GPIO pin</a> to a breadboard, and concurrently sends a message to the tablet over a WebSocket in realtime.
</p>


<figure id="orgae0bc31">
<img src="/images/embedded-elixir-cluster.dot.png" alt="embedded-elixir-cluster.dot.png">

</figure>
<div id="outline-container-orgff00296" class="outline-2">
<h2 id="orgff00296">Android code</h2>
<div class="outline-text-2" id="text-orgff00296">
<p>
I simply took this <a href="https://github.com/bryanjos/AndroidPhoenixDemo">Android Phoenix Demo on GitHub</a>, followed the instructions to update the host value, and installed in on a Nexus 7.
</p>
</div>
</div>
<div id="outline-container-org18cf86e" class="outline-2">
<h2 id="org18cf86e">Raspberry Pi and BeagleBone Code</h2>
<div class="outline-text-2" id="text-org18cf86e">
<p>
On both your Pi and BeagleBone create a file called gpio-led.ex with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-elixir">defmodule GPIO.LED do
  use GenServer

  #####
  # External API
  def start_link(pin) do
    :os.cmd(to_char_list "echo #{pin} &gt; /sys/class/gpio/export")
    :os.cmd(to_char_list "echo out &gt; /sys/class/gpio/gpio#{pin}/direction")
    :os.cmd(to_char_list "echo 0 &gt; /sys/class/gpio/gpio#{pin}/value")
    GenServer.start_link(__MODULE__, pin, name: __MODULE__)
  end

  def led_on! do
    GenServer.cast __MODULE__, :led_on
  end

  def led_off! do
    GenServer.cast __MODULE__, :led_off
  end

  #####
  # GenServer implementation
  def handle_cast(:led_on, pin) do
    :os.cmd(to_char_list "echo 1 &gt; /sys/class/gpio/gpio#{pin}/value")
    {:noreply,  pin}
  end

  def handle_cast(:led_off, pin) do
    :os.cmd(to_char_list "echo 0 &gt; /sys/class/gpio/gpio#{pin}/value")
    {:noreply,  pin}
  end
end
</pre>
</div>

<p>
This is a pretty straightforward GenServer. For simplicity I am not using any supervisors in this example, i'll leave that as an exercise for the reader.
</p>

<p>
If you are curious about what is happening with the GPIO and want to learn more I have written up some information about getting started with Erlang/Elixir and GPIO on the <a href="/blog/embedded-elixir-beaglebone/">BeagleBone</a> and <a href="/blog/embedded-elixir-raspberry-pi/">Raspberry Pi</a>.
</p>
</div>
</div>
<div id="outline-container-orgca707e3" class="outline-2">
<h2 id="orgca707e3">Web server code</h2>
<div class="outline-text-2" id="text-orgca707e3">
<p>
I started with the <a href="https://github.com/chrismccord/phoenix_chat_example">Phoenix chat example on GitHub</a>. Clone the repo to your desktop or laptop.
</p>

<p>
Next create a file called phoenix<sub>chat</sub><sub>example</sub>/lib/chat/led<sub>controller.ex</sub> with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-elixir">defmodule Chat.LedController do

  def blink_leds() do
    # Ensure we are connected
    true = Node.connect :"beagle@beaglebone.local"
    true = Node.connect :"pi@raspberrypi.local"

    # Ensure the GPIO.LED servers have started on the Raspberry Pi and BeagleBone
    :rpc.call(:"beagle@beaglebone.local", GPIO.LED, :start_link, [23])
    :rpc.call(:"pi@raspberrypi.local", GPIO.LED, :start_link, [4])

    loop()
  end

  defp loop() do
    Chat.Endpoint.broadcast! "rooms:lobby", "new:msg", %{user: "server",
                                                         body: "BeagleBone ON"}
    :rpc.call(:"beagle@beaglebone.local", GPIO.LED, :led_on!, [])
    :timer.sleep(1000)
    :rpc.call(:"beagle@beaglebone.local", GPIO.LED, :led_off!, [])

    Chat.Endpoint.broadcast! "rooms:lobby", "new:msg", %{user: "server",
                                                         body: "Pi ON"}
    :rpc.call(:"pi@raspberrypi.local", GPIO.LED, :led_on!, [])
    :timer.sleep(1000)
    :rpc.call(:"pi@raspberrypi.local", GPIO.LED, :led_off!, [])

    loop()
  end
end
</pre>
</div>

<p>
This is also straightforward.
</p>

<ul class="org-ul">
<li>Send a message to a <a href="http://www.phoenixframework.org/docs/channels">Phoenix Channel</a> (which in turn gets forwarded to the Android app via websocket).</li>
<li>Periodically make <a href="http://www.erlang.org/doc/man/rpc.html">rpc</a> calls to the nodes on the Raspberry Pi and Beaglebone to turn on and off the LEDs</li>
<li>Sleep for a second</li>
<li>Repeat</li>
</ul>

<p>
Once started the code will recursively loop forever.
</p>
</div>
</div>
<div id="outline-container-org8f9ca8b" class="outline-2">
<h2 id="org8f9ca8b">Run the code</h2>
<div class="outline-text-2" id="text-org8f9ca8b">
<p>
ssh to the Raspberry Pi as the root user
</p>

<div class="org-src-container">
<pre class="src src-sh"># Start an Erlang node
root@raspberrypi:~# iex --name pi@raspberrypi.local --cookie peanut-butter

# Compile
iex(pi@raspberrypi.local)1&gt; c("gpio-led.ex")
</pre>
</div>

<p>
ssh to the BeagleBone as the root user
</p>

<div class="org-src-container">
<pre class="src src-sh">root@beaglebone:~# iex --name beagle@beaglebone.local --cookie peanut-butter
iex(beagle@beaglebone.local)1&gt; c("gpio-led.ex")
</pre>
</div>

<p>
On your desktop or laptop run the code as an <a href="http://elixir-lang.org/docs/v1.1/elixir/Task.html">Elixir Task</a> :
</p>

<div class="org-src-container">
<pre class="src src-sh"># Start the Phoenix app
$ iex --name desktop@desktop.local --cookie peanut-butter -S mix phoenix.server

# Blink the LEDs
iex(1)&gt; {:ok, pid} = Task.start(fn -&gt; Chat.LedController.blink_leds end)
</pre>
</div>

<p>
The LEDs should be turning on and off and you should be seeing messages from Elixir in the Android app.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/erlang/" class="tag" data-tag="erlang" data-index="0">erlang</a> <a href="https://wtfleming.github.io/tags/elixir/" class="tag" data-tag="elixir" data-index="1">elixir</a> <a href="https://wtfleming.github.io/tags/raspberry-pi/" class="tag" data-tag="raspberry-pi" data-index="2">raspberry-pi</a> <a href="https://wtfleming.github.io/tags/beaglebone/" class="tag" data-tag="beaglebone" data-index="3">beaglebone</a> </span></div>]]></description>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[elixir]]></category>
  <category><![CDATA[raspberry-pi]]></category>
  <category><![CDATA[beaglebone]]></category>
  <link>https://wtfleming.github.io/blog/erlang-cluster-elxir-raspberry-pi-beaglebone/</link>
  <guid>https://wtfleming.github.io/blog/erlang-cluster-elxir-raspberry-pi-beaglebone/</guid>
  <pubDate>Fri, 11 Dec 2015 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Elixir on the Raspberry Pi - Blinking an LED]]></title>
  <description><![CDATA[
<p>
In this post we will see how to run the "Hello, World" of embedded devices, blinking an LED on a breadboard. We will be using the Elixir programming language and a Raspberry Pi.
</p>

<p>
I have also written up similar <a href="/blog/embedded-elixir-beaglebone/">instructions for the BeagleBone Black</a>.
</p>

<p>
The final result will look like this:
</p>

<iframe width="420" height="315" src="https://www.youtube.com/embed/w6T2HXzHXRs" frameborder="0" allowfullscreen></iframe>
<div id="outline-container-org12d7463" class="outline-2">
<h2 id="org12d7463">Elixir programming language</h2>
<div class="outline-text-2" id="text-org12d7463">
<p>
<a href="http://elixir-lang.org/">Elixir</a> describes itself:
</p>

<pre class="example" id="orgfa59d62">
Elixir is a dynamic, functional language designed for building scalable and
maintainable applications.

Elixir leverages the Erlang VM, known for running low-latency, distributed and
fault-tolerant systems, while also being successfully used in web development and
the embedded software domain.
</pre>

<p>
Some of Elixir's selling points are:
</p>

<ul class="org-ul">
<li>Runs on the rock solid Erlang Virtual Machine.</li>
<li>Offers trivial interop with Erlang code, libraries, and frameworks including the <a href="https://en.wikipedia.org/wiki/Open_Telecom_Platform">OTP</a>.</li>
<li>Code looks a fair bit like Ruby which many may find easier to grok than Erlang's Prolog inspired syntax.</li>
</ul>

<p>
So far it has been an absolute joy to use.
</p>
</div>
</div>
<div id="outline-container-org88601de" class="outline-2">
<h2 id="org88601de">Raspberry Pi</h2>
<div class="outline-text-2" id="text-org88601de">
<p>
The <a href="https://www.raspberrypi.org/">Raspberry Pi</a> is a series of small (credit card sized) and relatively low cost computers capable of running Linux with a number of <a href="https://en.wikipedia.org/wiki/General-purpose_input/output">general-purpose input/output (GPIO)</a> pins which can interface with the outside world.
</p>


<figure id="orge7a3028">
<img src="/images/raspberry-pi.jpg" alt="raspberry-pi.jpg">

</figure>

<sub>Image by Lucasbosch (Own work) [<a href="http://creativecommons.org/licenses/by-sa/3.0">CC BY-SA 3.0</a>], <a href="https://commons.wikimedia.org/wiki/File%3ARaspberry_Pi_B%2B_top.jpg">via Wikimedia Commons</a></sub>

<p>
Now lets install the software dependencies.
</p>
</div>
</div>
<div id="outline-container-org45e65cb" class="outline-2">
<h2 id="org45e65cb">Install Erlang and Elixir</h2>
<div class="outline-text-2" id="text-org45e65cb">
<p>
Elixir currently requires Erlang 17.0 or later, the debian packages in the default repositories are too old so we will need an alternative installation method.
</p>

<p>
One possibility would be to use the <a href="http://nerves-project.org/">nerves project</a>. I recently watched the <a href="https://www.youtube.com/watch?v=kpzQrFC55q4">ElixirConf 2015 - Embedded Elixir in Action by Garth Hitchens</a> presentation and am excited to see where it goes, but for this example it would probably be overkill.
</p>

<p>
On a desktop PC another option is to use one of the <a href="https://packages.erlang-solutions.com/erlang/">Erlang Solutions repos</a>, but as far as I can tell the debian packages are only built for x86 architectures and the ones for Raspbian have not been updated since Erlang 15.
</p>

<p>
So it looks like we'll be installing from source.
</p>

<div class="org-src-container">
<pre class="src src-sh"># ssh in and run these commands on your Raspberry Pi
# It should take you about an hour from start to finish

# Download, compile, and install Erlang
$ apt-get install wget libssl-dev ncurses-dev m4 unixodbc-dev erlang-dev
$ wget http://www.erlang.org/download/otp_src_18.1.tar.gz
$ tar -xzvf otp_src_18.1.tar.gz
$ cd otp_src_18.1/
$ export ERL_TOP=`pwd`
$ ./configure
$ make
$ make install

# Download a precompiled elixir release from
# https://github.com/elixir-lang/elixir/releases/
$ apt-get install unzip
$ wget https://github.com/elixir-lang/elixir/releases/download/v1.1.1/Precompiled.zip
$ unzip Precompiled.zip -d elixir

# Add elixir to your path
# You may want to add this to your .bashrc so you do not have to every time you
# log on
$ export PATH="/home/pi/elixir/bin:$PATH"

# Ensure Elixir is working
$ iex
Erlang/OTP 18 [erts-7.1] [source] [async-threads:10] [hipe] [kernel-poll:false]
Interactive Elixir (1.1.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)&gt; 1 + 2
3
iex(2)&gt;
# Press Ctrl+C twice to exit iex
</pre>
</div>

<p>
We're now ready to explore GPIO (general purpose I/O) on the Pi.
</p>
</div>
</div>
<div id="outline-container-org6e78735" class="outline-2">
<h2 id="org6e78735">Wire up the LED</h2>
<div class="outline-text-2" id="text-org6e78735">

<figure id="org79ee2a0">
<img src="/images/raspberry-pi-led-fritzing.png" alt="raspberry-pi-led-fritzing.png">

</figure>

<hr>

<p>
Note: The GPIO pins can only handle 3.3 volts, so be very careful that you do not accidentally connect a jumper to one of the 5 volt source pins. If you are unsure of what you are doing I would highly recommend reading all of the <a href="https://www.raspberrypi.org/documentation/">Raspberry Pi documentation</a> to make sure you do not damage your board.
</p>

<hr>

<ol class="org-ol">
<li>Using a jumper wire connect GND (ground) on the Pi to the negative rail on the breadboard.</li>
<li>Place an LED in the breadboard.</li>
<li>Using a jumper wire connect the cathode (shorter) wire of the LED to the negative rail.</li>
<li>Connect one end of a 100 ohm resistor to the anode (longer) wire of the LED.</li>
<li>Using another jumper wire connect the other end of the resistor to GPIO 4.</li>
</ol>

<p>
Once wired up we can proceed.
</p>
</div>
</div>
<div id="outline-container-orgbea6602" class="outline-2">
<h2 id="orgbea6602">Turn an LED on and off on the command line</h2>
<div class="outline-text-2" id="text-orgbea6602">
<p>
In this example we'll be using the built in <a href="https://en.wikipedia.org/wiki/Sysfs">sysfs</a> to control the GPIO pins. Wikipedia describes it:
</p>

<pre class="example" id="orgb8ad17e">
sysfs is a virtual file system provided by the Linux kernel that exports information
about various kernel subsystems, hardware devices, and associated device drivers
from the kernel's device model to user space through virtual files. In addition to
providing information about various devices and kernel subsystems, exported virtual
files are also used for their configuring.
</pre>

<p>
This allows us to treat the pins like a file, and while not the most efficient way to work with the GPIO pins, it is very convenient for some use cases.
</p>

<p>
When you follow along with the example below on a Pi it should make sense.
</p>

<div class="org-src-container">
<pre class="src src-sh"># To make it easier in this example we run commands as root
pi@raspberrypi ~ $ sudo -i

# Add elixir to your root user's path
# You may want to add this to your .bashrc so you do not have to every time you
# log on
root@raspberrypi:~# export PATH="/home/pi/elixir/bin:$PATH"

# One gpio pin already exists
root@raspberrypi:~# ls /sys/class/gpio
export  gpiochip0  unexport

# Export a new one
root@raspberrypi:~# echo 4 &gt; /sys/class/gpio/export

# Notice that gpio4 has now appeared
root@raspberrypi:~# ls /sys/class/gpio
export  gpio4  gpiochip0  unexport

# What we can do with gpio4
root@raspberrypi:~# ls /sys/class/gpio/gpio4
active_low  device  direction  edge  subsystem  uevent  value

# Set the direction to out
root@raspberrypi:~# echo out &gt; /sys/class/gpio/gpio4/direction

# Turn on the LED
root@raspberrypi:~# echo 1 &gt; /sys/class/gpio/gpio4/value

# Turn off the LED
root@raspberrypi:~# echo 0 &gt; /sys/class/gpio/gpio4/value

# Now use Elixir to turn the LED on and then off
root@raspberrypi:~# iex
iex(1)&gt; :os.cmd('echo 1 &gt; /sys/class/gpio/gpio4/value')
[]
iex(2)&gt; :os.cmd('echo 0 &gt; /sys/class/gpio/gpio4/value')
[]

# Press Ctrl+C twice to exit iex

# Clean up
root@raspberrypi:~# echo 4 &gt; /sys/class/gpio/unexport
</pre>
</div>

<p>
Now lets make a module.
</p>
</div>
</div>
<div id="outline-container-orgb3d29c9" class="outline-2">
<h2 id="orgb3d29c9">Elixir Code</h2>
<div class="outline-text-2" id="text-orgb3d29c9">
<p>
On your Raspberry Pi create a file called blink-led.ex with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-elixir">defmodule BlinkLED do
  @moduledoc """
  Blink an LED on a Raspberry Pi

  ## Examples

  iex&gt; c("blink-led.ex")
  [BlinkLED]
  iex&gt; {:ok, pid} = BlinkLED.start_link()
  {:ok, #PID&lt;0.102.0&gt;}

  """

  @doc """
  Setup and start the process
  """
  def start_link() do
    :os.cmd('echo 4 &gt; /sys/class/gpio/export')
    :os.cmd('echo out &gt; /sys/class/gpio/gpio4/direction')
    {:ok, spawn_link(fn -&gt; loop() end)}
  end

  defp loop() do
    :os.cmd('echo 1 &gt; /sys/class/gpio/gpio4/value')
    :timer.sleep(1000)
    :os.cmd('echo 0 &gt; /sys/class/gpio/gpio4/value')
    :timer.sleep(1000)
    loop()
  end
end
</pre>
</div>

<p>
To run the code you can start iex and do the following:
</p>

<div class="org-src-container">
<pre class="src src-sh">iex&gt; c("blink-led.ex")
iex&gt; {:ok, pid} = BlinkLED.start_link()
</pre>
</div>

<p>
The LED on the breadboard should now turn on for one second, turn off for a second, and repeat indefinitely.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/erlang/" class="tag" data-tag="erlang" data-index="0">erlang</a> <a href="https://wtfleming.github.io/tags/elixir/" class="tag" data-tag="elixir" data-index="1">elixir</a> <a href="https://wtfleming.github.io/tags/raspberry-pi/" class="tag" data-tag="raspberry-pi" data-index="2">raspberry-pi</a> </span></div>]]></description>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[elixir]]></category>
  <category><![CDATA[raspberry-pi]]></category>
  <link>https://wtfleming.github.io/blog/embedded-elixir-raspberry-pi/</link>
  <guid>https://wtfleming.github.io/blog/embedded-elixir-raspberry-pi/</guid>
  <pubDate>Thu, 10 Dec 2015 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Elixir on the BeagleBone Black - Blinking an LED]]></title>
  <description><![CDATA[
<p>
In this post we will see how to run the "Hello, World" of embedded devices, blinking an LED on a breadboard. We will be using the Elixir programming language and a BeagleBone Black.
</p>

<p>
I have also written up similar <a href="/blog/embedded-elixir-raspberry-pi/">instructions for the Raspberry Pi</a>.
</p>

<p>
The final result will look like this:
</p>

<iframe width="560" height="315" src="https://www.youtube.com/embed/QR_su_rn74A" frameborder="0" allowfullscreen></iframe>
<div id="outline-container-orgc9dbb75" class="outline-2">
<h2 id="orgc9dbb75">Elixir programming language</h2>
<div class="outline-text-2" id="text-orgc9dbb75">
<p>
<a href="http://elixir-lang.org/">Elixir</a> describes itself:
</p>

<pre class="example" id="org60c3bc1">
Elixir is a dynamic, functional language designed for building scalable and
maintainable applications.

Elixir leverages the Erlang VM, known for running low-latency, distributed and
fault-tolerant systems, while also being successfully used in web development and
the embedded software domain.
</pre>

<p>
Some of Elixir's selling points are:
</p>

<ul class="org-ul">
<li>Runs on the rock solid Erlang Virtual Machine.</li>
<li>Offers trivial interop with Erlang code, libraries, and frameworks including the <a href="https://en.wikipedia.org/wiki/Open_Telecom_Platform">OTP</a>.</li>
<li>Code looks a fair bit like Ruby which many may find easier to grok than Erlang's Prolog inspired syntax.</li>
</ul>

<p>
So far it has been an absolute joy to use.
</p>
</div>
</div>
<div id="outline-container-org8bc95a0" class="outline-2">
<h2 id="org8bc95a0">BeagleBone Black</h2>
<div class="outline-text-2" id="text-org8bc95a0">
<p>
The <a href="http://beagleboard.org/Products/BeagleBone+Black">BeagleBone Black</a> is a small and relatively low cost 1Ghz ARM board with 512Mb of RAM capable of running Linux. It is similar to a Raspberry Pi (and most of the information here will be applicable to a Pi as well).
</p>


<figure id="org2181eda">
<img src="/images/beagleboneblack.jpg" alt="beagleboneblack.jpg">

</figure>

<p>
These instructions assume that your BeagleBone is using Debian 2015-03-01 and running commands as the root user. You can obtain this version of the operating system <a href="http://beagleboard.org/latest-images">here</a>.
</p>

<p>
If unsure what version is running you can determine it by running this command on the board:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ cat /etc/dogtag
BeagleBoard.org Debian Image 2015-03-01
</pre>
</div>

<p>
Now lets install the software dependencies.
</p>
</div>
</div>
<div id="outline-container-orgfc5af6a" class="outline-2">
<h2 id="orgfc5af6a">Install Erlang and Elixir</h2>
<div class="outline-text-2" id="text-orgfc5af6a">
<p>
Elixir currently requires Erlang 17.0 or later, the debian packages in the default repositories are too old so we will need an alternative installation method.
</p>

<p>
One possibility would be to use the <a href="http://nerves-project.org/">nerves project</a>. I recently watched the <a href="https://www.youtube.com/watch?v=kpzQrFC55q4">ElixirConf 2015 - Embedded Elixir in Action by Garth Hitchens</a> presentation and am excited to see where it goes, but for this example it would probably be overkill.
</p>

<p>
On a desktop PC another option is to use one of the <a href="https://packages.erlang-solutions.com/erlang/">Erlang Solutions repos</a>, but as far as I can tell they only provide recent versions of Erlang built for x86 architectures and the BeagleBone uses an ARM chip.
</p>

<p>
So it looks like we'll be installing from source.
</p>

<div class="org-src-container">
<pre class="src src-sh"># ssh in and run these commands on your BeagleBone Black
# It should take you about an hour from start to finish

# Download, compile, and install Erlang
$ apt-get install wget libssl-dev ncurses-dev m4 unixodbc-dev erlang-dev
$ wget http://www.erlang.org/download/otp_src_18.1.tar.gz
$ tar -xzvf otp_src_18.1.tar.gz
$ cd otp_src_18.1/
$ export ERL_TOP=`pwd`
$ ./configure
$ make
$ make install

# Download a precompiled elixir release from
# https://github.com/elixir-lang/elixir/releases/
$ apt-get install unzip
$ wget https://github.com/elixir-lang/elixir/releases/download/v1.1.1/Precompiled.zip
$ unzip Precompiled.zip -d elixir

# Add elixir to your path
# You may want to add this to your .bashrc so you do not have to every time you
# log on
$ export PATH="$HOME/elixir/bin:$PATH"

# Ensure Elixir is working
$ iex
Erlang/OTP 18 [erts-7.1] [source] [async-threads:10] [hipe] [kernel-poll:false]
Interactive Elixir (1.1.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)&gt; 1 + 2
3
iex(2)&gt;
# Press Ctrl+C twice to exit iex
</pre>
</div>

<p>
We're now ready to explore GPIO (general purpose I/O) on the BeagleBone.
</p>
</div>
</div>
<div id="outline-container-orgeec6b23" class="outline-2">
<h2 id="orgeec6b23">Wire up the LED</h2>
<div class="outline-text-2" id="text-orgeec6b23">

<figure id="orga4a926b">
<img src="/images/beaglebone-clojure-blink-led-fritzing.png" alt="beaglebone-clojure-blink-led-fritzing.png">

</figure>

<hr>

<p>
Note: The GPIO pins can only handle 3.3 volts, so be very careful that you do not accidentally connect a jumper to one of the 5 volt source pins. If you are unsure of what you are doing I would highly recommend reading the <a href="https://github.com/CircuitCo/BeagleBone-Black/blob/master/BBB_SRM.pdf?raw=true">BeagleBone System Reference Manual</a> to make sure you do not damage your board.
</p>

<hr>

<ol class="org-ol">
<li>Using a jumper wire connect Pin 2 on Header P9 (ground) on the BeagleBone to the negative rail on the breadboard.</li>
<li>Place an LED in the breadboard.</li>
<li>Using a jumper wire connect the cathode (shorter) wire of the LED to the negative rail.</li>
<li>Connect one end of a 100 ohm resistor to the anode (longer) wire of the LED.</li>
<li>Using another jumper wire connect the other end of the resistor to Pin 13 on Header P8</li>
</ol>

<p>
Once wired up we can proceed.
</p>
</div>
</div>
<div id="outline-container-org1378a68" class="outline-2">
<h2 id="org1378a68">Turn an LED on and off on the command line</h2>
<div class="outline-text-2" id="text-org1378a68">
<p>
In this example we'll be using the built in <a href="https://en.wikipedia.org/wiki/Sysfs">sysfs</a> to control the GPIO pins. Wikipedia describes it:
</p>

<pre class="example" id="orgafd3423">
sysfs is a virtual file system provided by the Linux kernel that exports information
about various kernel subsystems, hardware devices, and associated device drivers
from the kernel's device model to user space through virtual files. In addition to
providing information about various devices and kernel subsystems, exported virtual
files are also used for their configuring.
</pre>

<p>
This allows us to treat the pins like a file, and while not the most efficient way to work with the GPIO pins, it is very convenient for some use cases.
</p>

<p>
When you follow along with the example below on a BeagleBone it should make sense.
</p>

<div class="org-src-container">
<pre class="src src-sh"># A few gpio pins already exist
$ ls /sys/class/gpio
export gpiochip0  gpiochip32  gpiochip64  gpiochip96  unexport

# Export a new one
$ echo 23 &gt; /sys/class/gpio/export

# Notice that gpio23 has now appeared
$ ls /sys/class/gpio
export gpio23  gpiochip0  gpiochip32  gpiochip64  gpiochip96  unexport

# What we can do with gpio23
$ ls /sys/class/gpio/gpio23
active_low  direction  edge  power  subsystem  uevent  value

# Set the direction to out
$ echo out &gt; /sys/class/gpio/gpio23/direction

# Turn on the LED
$ echo 1 &gt; /sys/class/gpio/gpio23/value

# Turn off the LED
$ echo 1 &gt; /sys/class/gpio/gpio23/value

# Now use Elixir to turn the LED on and then off
$ iex
iex(1)&gt; :os.cmd('echo 1 &gt; /sys/class/gpio/gpio23/value')
[]
iex(2)&gt; :os.cmd('echo 0 &gt; /sys/class/gpio/gpio23/value')
[]
</pre>
</div>

<p>
Now lets make a module.
</p>
</div>
</div>
<div id="outline-container-org3605a41" class="outline-2">
<h2 id="org3605a41">Elixir Code</h2>
<div class="outline-text-2" id="text-org3605a41">
<p>
On your BeagleBone create a file called blink-led.ex with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-elixir">defmodule BlinkLED do
  @moduledoc """
  Blink an LED on a BeagleBone Black

  ## Examples

  iex&gt; c("blink-led.ex")
  [BlinkLED]
  iex&gt; {:ok, pid} = BlinkLED.start_link()
  {:ok, #PID&lt;0.102.0&gt;}

  """

  @doc """
  Setup and start the process
  """
  def start_link() do
    :os.cmd('echo 23 &gt; /sys/class/gpio/export')
    :os.cmd('echo out &gt; /sys/class/gpio/gpio23/direction')
    {:ok, spawn_link(fn -&gt; loop() end)}
  end

  defp loop() do
    :os.cmd('echo 1 &gt; /sys/class/gpio/gpio23/value')
    :timer.sleep(1000)
    :os.cmd('echo 0 &gt; /sys/class/gpio/gpio23/value')
    :timer.sleep(1000)
    loop()
  end
end
</pre>
</div>

<p>
To run the code you can start iex and do the following:
</p>

<div class="org-src-container">
<pre class="src src-sh">iex&gt; c("blink-led.ex")
iex&gt; {:ok, pid} = BlinkLED.start_link()
</pre>
</div>

<p>
The LED on the breadboard should now turn on for one second, turn off for a second, and repeat indefinitely.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/erlang/" class="tag" data-tag="erlang" data-index="0">erlang</a> <a href="https://wtfleming.github.io/tags/elixir/" class="tag" data-tag="elixir" data-index="1">elixir</a> <a href="https://wtfleming.github.io/tags/beaglebone/" class="tag" data-tag="beaglebone" data-index="2">beaglebone</a> </span></div>]]></description>
  <category><![CDATA[erlang]]></category>
  <category><![CDATA[elixir]]></category>
  <category><![CDATA[beaglebone]]></category>
  <link>https://wtfleming.github.io/blog/embedded-elixir-beaglebone/</link>
  <guid>https://wtfleming.github.io/blog/embedded-elixir-beaglebone/</guid>
  <pubDate>Wed, 09 Dec 2015 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Creating an Apache Commons Daemon using Component with Clojure]]></title>
  <description><![CDATA[
<div id="outline-container-orgc40b0d9" class="outline-2">
<h2 id="orgc40b0d9">Introduction</h2>
<div class="outline-text-2" id="text-orgc40b0d9">
<p>
One way to write a long running server application that runs on the JVM with proper start/stop semantics is to the the <a href="http://commons.apache.org/proper/commons-daemon/">Apache Commons Daemon</a>. In this post we'll see how we can do so in Clojure and also use the <a href="https://github.com/stuartsierra/component">Component</a> framework to structure our application.
</p>

<p>
The full source for this post is <a href="https://github.com/wtfleming/clojure-examples/tree/master/apache-commons-daemon">available on Github</a>.
</p>
</div>
</div>
<div id="outline-container-org11d7771" class="outline-2">
<h2 id="org11d7771">Component</h2>
<div class="outline-text-2" id="text-org11d7771">
<p>
Component describes itself as:
</p>

<pre class="example" id="org64deaae">
A tiny Clojure framework for managing the lifecycle and dependencies
of software components which have runtime state.

This is primarily a design pattern with a few helper functions. It can be seen as a
style of dependency injection using immutable data structures.
</pre>

<p>
There are two concepts to be aware of:
</p>

<ul class="org-ul">
<li>Components</li>
</ul>

<pre class="example" id="orgf9cd67a">
A collection of functions or procedures which share some runtime state.
</pre>

<ul class="org-ul">
<li>Systems</li>
</ul>

<pre class="example" id="orgc4157e0">
Components are composed into systems. A system is a component which knows how to
start and stop other components. It is also responsible for injecting dependencies
into the components which need them.
</pre>

<p>
I won't go into very much detail about Component in this post, to learn more the <a href="https://github.com/stuartsierra/component">documentation</a> is excellent.
</p>
</div>
</div>
<div id="outline-container-org2b78fab" class="outline-2">
<h2 id="org2b78fab">The Application</h2>
<div class="outline-text-2" id="text-org2b78fab">
<p>
We will be building an app with two components and one system.
</p>

<p>
The <b>first component</b> will store application metrics and the <b>second component</b> will repeatedly print "tick" to stdout and increment a tick counter in the metrics component once a second.
</p>

<p>
The <b>system</b> will bring them together and handle the metrics component being a dependency of the tick one.
</p>
</div>
</div>
<div id="outline-container-orga7e9b23" class="outline-2">
<h2 id="orga7e9b23">Leiningen Project</h2>
<div class="outline-text-2" id="text-orga7e9b23">
<p>
Our <i>project.clj</i> looks like this:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defproject apache-commons-daemon "0.1.0-SNAPSHOT"
  :description "Example of running a daemon"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [commons-daemon/commons-daemon "1.0.15"]
                 [com.stuartsierra/component "0.3.0"]]
  :main apache-commons-daemon.core
  :aot :all)
</pre>
</div>
</div>
</div>
<div id="outline-container-org7a0a7fc" class="outline-2">
<h2 id="org7a0a7fc">Code</h2>
<div class="outline-text-2" id="text-org7a0a7fc">
<p>
Next create a file called <i>src/apache<sub>commons</sub><sub>daemon</sub>/core.clj</i>
</p>

<p>
Insert the following at the top of the file:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns apache-commons-daemon.core
  (:require [com.stuartsierra.component :as component])
  (:import [org.apache.commons.daemon Daemon DaemonContext])
  (:gen-class
   :implements [org.apache.commons.daemon.Daemon]))
</pre>
</div>
</div>
</div>
<div id="outline-container-orgc6c8052" class="outline-2">
<h2 id="orgc6c8052">Metrics Component</h2>
<div class="outline-text-2" id="text-orgc6c8052">
<p>
For simplicity the first component simply stores the number of times the other component has ticked, however we could easily store additional metrics.
</p>

<p>
We also provide a constructor and a function to increment the tick count.
</p>

<div class="org-src-container">
<pre class="src src-clojure">;; Application Metrics Component
(defrecord MetricsComponent [num-ticks]
  ;; Implement the Lifecycle protocol
  component/Lifecycle
  (start [component]
    (println ";; Starting MetricsComponent")
    (reset! (:num-ticks component) 0)
    component)
  (stop [component]
    (println ";; Stopping MetricsComponent")
    (println (str ";; Metric num ticks: " @(:num-ticks component)))
    component))

(defn make-metrics-component
  "Constructor for a metrics component"
  []
  (map-&gt;MetricsComponent {:num-ticks (atom 0)}))

(defn inc-num-ticks-metric [metrics-component]
  (swap! (get metrics-component :num-ticks) inc))
</pre>
</div>
</div>
</div>
<div id="outline-container-orgab87a84" class="outline-2">
<h2 id="orgab87a84">Tick Component</h2>
<div class="outline-text-2" id="text-orgab87a84">
<p>
At startup the tick component creates a future which repeatedly outputs "tick" to stdout for as long as the component's state is set to :running.
</p>

<div class="org-src-container">
<pre class="src src-clojure">;; Tick Component
(defn do-ticks
  "Print to stdout and increment the ticks metric once a second when the component
  is running"
  [state metrics-component]
  (while (= :running @state)
    (println "tick")
    (inc-num-ticks-metric metrics-component)
    (Thread/sleep 1000)))

(defrecord TickComponent [state metrics-component]
  ;; Implement the Lifecycle protocol
  component/Lifecycle
  (start [component]
    (println ";; Starting TickComponent")
    (reset! (:state component) :running)
    ;; Do some work in another thread
    (future (do-ticks (:state component) metrics-component))
    component)
  (stop [component]
    (println ";; Stopping TickComponent")
    (reset! (:state component) :stopped)
    component))

(defn make-tick-component
  "Constructor for a tick component"
  []
  (map-&gt;TickComponent {:state (atom :stopped)}))
</pre>
</div>
</div>
</div>
<div id="outline-container-org8eac923" class="outline-2">
<h2 id="org8eac923">Application System</h2>
<div class="outline-text-2" id="text-org8eac923">
<p>
Here we have a system which creates the two components. It also indicates that the metrics component is a dependency of the tick component, so it will ensure the metrics component is started first and provide an instance of it to the tick component.
</p>

<div class="org-src-container">
<pre class="src src-clojure">;; Application System
(defn make-app-system []
  (component/system-map
   :metrics-component (make-metrics-component)
   :tick-component (component/using
                    (make-tick-component)
                    [:metrics-component])))
</pre>
</div>

<p>
Now we create the system and provide functions to start and stop it. The start and stop methods make it easy to develop and test in a REPL (without the need for jsvc in that environment).
</p>

<div class="org-src-container">
<pre class="src src-clojure">(def app-system (make-app-system))

;; Separate start/stop functions for easier development in a REPL
(defn start []
  (alter-var-root #'app-system component/start))

(defn stop []
  (alter-var-root #'app-system component/stop))
</pre>
</div>
</div>
</div>
<div id="outline-container-org1ae95be" class="outline-2">
<h2 id="org1ae95be">Commons Daemon</h2>
<div class="outline-text-2" id="text-org1ae95be">
<p>
Finally we provide an implementatation of the <a href="http://commons.apache.org/proper/commons-daemon/apidocs/org/apache/commons/daemon/Daemon.html">Daemon interface</a>. This will allow us to start and stop the application with jsvc.
</p>

<div class="org-src-container">
<pre class="src src-clojure">;; Commons Daemon implementatation
(defn -init [this ^DaemonContext context])

(defn -start [this]
  (start))

(defn -stop [this]
  (stop))

(defn -destroy [this])
</pre>
</div>
</div>
</div>
<div id="outline-container-org03f087f" class="outline-2">
<h2 id="org03f087f">Running the Application</h2>
<div class="outline-text-2" id="text-org03f087f">
<p>
Build with Leiningen:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ lein uberjar
</pre>
</div>

<p>
To interact with the daemon you will need <a href="http://commons.apache.org/proper/commons-daemon/jsvc.html">jsvc</a> as well. On Ubuntu 14.04 it is as easy as:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ sudo apt-get install jsvc
</pre>
</div>

<p>
Start/stop like this (change your java home to what is appropriate for you):
</p>

<div class="org-src-container">
<pre class="src src-sh">$ sudo /usr/bin/jsvc -java-home /usr/lib/jvm/java-8-oracle/jre/ \
  -cp "$(pwd)/target/apache-commons-daemon-0.1.0-SNAPSHOT-standalone.jar" \
  -outfile "$(pwd)/out.txt" \
  apache_commons_daemon.core

# Wait a few seconds...

$ sudo /usr/bin/jsvc -java-home /usr/lib/jvm/java-8-oracle/jre/ \
  -cp "$(pwd)/target/apache-commons-daemon-0.1.0-SNAPSHOT-standalone.jar" \
  -stop \
  apache_commons_daemon.core

$ sudo cat out.txt
</pre>
</div>

<p>
You should see output that looks something like this:
</p>

<pre class="example" id="org17660c0">
;; Starting MetricsComponent
;; Starting TickComponent
tick
tick
tick
tick
tick
;; Stopping TickComponent
;; Stopping MetricsComponent
;; Metric num ticks: 5
</pre>

<p>
Note that jsvc can be a bit finicky and you may need to make some changes depending on your environment. If you do not see anything in the file, try adding the <b>-debug</b> flag to the jsvc calls which will provide useful information.
</p>
</div>
</div>
<div id="outline-container-org222e27b" class="outline-2">
<h2 id="org222e27b">Next Steps</h2>
<div class="outline-text-2" id="text-org222e27b">
<p>
You will likely want to do is create a script to start the application. There is much more to jsvc than we covered here, Sheldon Neilson has written an excellent <a href="http://www.neilson.co.za/creating-a-java-daemon-system-service-for-debian-using-apache-commons-jsvc/">article</a> for Debian based systems which I encourage you to read.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <link>https://wtfleming.github.io/blog/apache-commons-daemon-component-clojure/</link>
  <guid>https://wtfleming.github.io/blog/apache-commons-daemon-component-clojure/</guid>
  <pubDate>Thu, 29 Oct 2015 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Exploring Stack Exchange data with Clojure using Apache Spark and Flambo]]></title>
  <description><![CDATA[
<div id="outline-container-org675e296" class="outline-2">
<h2 id="org675e296">Introduction</h2>
<div class="outline-text-2" id="text-org675e296">
<p>
<a href="https://spark.apache.org/">Apache Spark</a> is a is a fast and general engine for large-scale data processing (as in terabytes or larger data sets), and <a href="https://github.com/yieldbot/flambo">Flambo</a> is a Clojure DSL for working with Spark. Stack Exchange is a network of question and answer websites with a variety of topics (the most popular one being <a href="http://stackoverflow.com/">Stack Overflow</a>). They periodically provide a <a href="https://archive.org/details/stackexchange">creative commons licensed database dump</a>. We'll be using data from the <a href="http://gaming.stackexchange.com/">Stack Exchange Gaming Site</a> as a toy dataset to work with them.
</p>

<p>
First we will use Spark to convert the Stack Exchange files provided in XML into <a href="https://parquet.apache.org/">Apache Parquet</a> format and then later we will use it to run some queries to find out things like which users have the highest reputation, as well as which ones like to play <a href="https://en.wikipedia.org/wiki/Dwarf_Fortress">Dwarf Fortress</a>.
</p>

<hr>

<p>
This post assumes you are using leiningen, some basic familiarity with either the Java or Scala Spark API, Spark 1.3.1 is installed in ~/bin/spark and that the March 2015 Gaming Stack Exchange Data Dump has been downloaded and extracted to ~/data/gaming-stackexchange The full code for this post is also <a href="https://github.com/wtfleming/clojure-examples/tree/master/apache-spark/flambo-gaming-stack-exchange">available on Github</a>.
</p>
</div>
</div>
<div id="outline-container-orgcefe08d" class="outline-2">
<h2 id="orgcefe08d">Leiningen Project</h2>
<div class="outline-text-2" id="text-orgcefe08d">
<p>
Our project.clj looks like this:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defproject flambo-gaming-stack-exchange "0.1.0-SNAPSHOT"
  :description "Example of using Spark and Flambo"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :profiles {:uberjar {:aot :all}
             :provided {:dependencies
                        [[org.apache.spark/spark-core_2.10 "1.3.1"]]}}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [yieldbot/flambo "0.6.0"]
                 [commons-codec/commons-codec "1.10"]
                 [org.clojure/data.xml "0.0.8"]
                 [org.apache.spark/spark-sql_2.10 "1.3.1"]])
</pre>
</div>
</div>
</div>
<div id="outline-container-org083c4e5" class="outline-2">
<h2 id="org083c4e5">Step 1: ETL Users</h2>
<div class="outline-text-2" id="text-org083c4e5">
<p>
The Stack Exchange data is provided in XML format. While it would be possible to leave it as is and load the XML into one of Spark's <a href="https://spark.apache.org/docs/1.3.1/api/java/org/apache/spark/rdd/RDD.html">Resilient Distributed Dataset (RDD)</a> when we query (this might be desirable if you are building a <a href="http://martinfowler.com/bliki/DataLake.html">data lake</a>), here we will be building a <a href="https://en.wikipedia.org/wiki/Data_mart">data mart</a> with a subset of the data, stored in Parquet format, and queried using <a href="https://spark.apache.org/docs/1.3.1/api/java/org/apache/spark/sql/DataFrame.html">Spark DataFrames</a>.
</p>

<p>
We want to take a line from the Stack Exchange Users.xml file that looks something like this:
</p>

<div class="org-src-container">
<pre class="src src-xml">&lt;row Id="2" Reputation="101" CreationDate="2010-07-07T16:01:11.480"
DisplayName="Geoff Dalgas" LastAccessDate="2015-03-06T05:00:48.087"
WebsiteUrl="http://stackoverflow.com" Location="Corvallis, OR"
AboutMe="&amp;lt;p&amp;gt;Developer on the StackOverflow team." Views="98" UpVotes="20"
DownVotes="1" Age="38" AccountId="2" /&gt;
</pre>
</div>

<p>
And convert it into a DataFrame represented like this:
</p>

<pre class="example" id="orgceae487">
| id | name         | reputation|
|----+--------------+-----------|
| 2  | Geoff Dalgas | 101       |
</pre>

<p>
We'll use the following code:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns flambo-gaming-stack-exchange.etl-users
  (:require [flambo.conf :as conf]
            [flambo.api :as f]
            [flambo.sql :as sql]
            [clojure.data.xml :as xml])
  (:import [org.apache.spark.sql RowFactory]
           [org.apache.spark.sql.types StructType StructField Metadata DataTypes])
  (:gen-class))

(defn build-sql-context
  "Returns a Spark SQLContext"
  [app-name]
  (let [c (-&gt; (conf/spark-conf)
              (conf/master "local[*]")
              (conf/app-name app-name))
        sc (f/spark-context c)]
    (sql/sql-context sc)))

(defn xml-&gt;row
  "Parse a row of user xml and return it as a Spark Row"
  [user-xml]
  (let [user (xml/parse-str user-xml)
        {{:keys [Id DisplayName Reputation]} :attrs} user]
    [(RowFactory/create (into-array Object [(Integer/parseInt Id) DisplayName  (Integer/parseInt Reputation)]))]))

"Spark function that reads in a line of XML and potentially returns a Row"
(f/defsparkfn parse-user
  [user-xml]
  (if (.startsWith user-xml  "  &lt;row")
    (xml-&gt;row user-xml)
    []))

(def user-schema
  (StructType.
   (into-array StructField [(StructField. "id" (DataTypes/IntegerType) true (Metadata/empty))
                            (StructField. "name" (DataTypes/StringType) true (Metadata/empty))
                            (StructField. "reputation" (DataTypes/IntegerType) true (Metadata/empty))])))

(defn -main [&amp; args]
  (let [home (java.lang.System/getenv "HOME")
        sql-ctx (build-sql-context "ETL Users")
        sc (sql/spark-context sql-ctx)
        xml-users (f/text-file sc (str home "/data/gaming-stackexchange/Users.xml"))
        users (f/flat-map xml-users parse-user)
        users-df (.createDataFrame sql-ctx users user-schema)]
    (.saveAsParquetFile users-df (str home "/data/gaming-stack-exchange-warehouse/users.parquet"))))
</pre>
</div>

<p>
Now build and run. For simplicity in these examples we will run everything in local mode.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ lein uberjar
$ ~/bin/spark/bin/spark-submit --class flambo_gaming_stack_exchange.etl_users \
target/flambo-gaming-stack-exchange-0.1.0-SNAPSHOT-standalone.jar
</pre>
</div>

<p>
You should now have a directory at ~/data/gaming-stack-exchange-warehouse/users.parquet containing the user data in Parquet format.
</p>
</div>
</div>
<div id="outline-container-org53bc9c2" class="outline-2">
<h2 id="org53bc9c2">Step 2: ETL Posts</h2>
<div class="outline-text-2" id="text-org53bc9c2">
<p>
Next we want to load posts. This is almost identical to loading users. I'll omit most of the code here, but it is <a href="https://github.com/wtfleming/clojure-examples/blob/master/apache-spark/flambo-gaming-stack-exchange/src/flambo_gaming_stack_exchange/etl_posts.clj">available on GitHub</a>. However I will include the schema here to make following along with the queries easier.
</p>

<div class="org-src-container">
<pre class="src src-clojure">
(def post-schema
  (StructType.
   (into-array StructField
     [(StructField. "ownerId" (DataTypes/IntegerType) true (Metadata/empty))
      (StructField. "postType" (DataTypes/IntegerType) true (Metadata/empty))
      (StructField. "tags" (DataTypes/StringType) true (Metadata/empty))])))
</pre>
</div>

<p>
Now ETL the posts into Parquet format.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ ~/bin/spark/bin/spark-submit --class flambo_gaming_stack_exchange.etl_posts \
target/flambo-gaming-stack-exchange-0.1.0-SNAPSHOT-standalone.jar
</pre>
</div>

<p>
Like with the users step, you should now have a directory at ~/data/gaming-stack-exchange-warehouse/posts.parquet containing the post data in Parquet format.
</p>
</div>
</div>
<div id="outline-container-org14981b8" class="outline-2">
<h2 id="org14981b8">Step 3: Query the data</h2>
<div class="outline-text-2" id="text-org14981b8">
<p>
Now lets run some queries. The code here will be broken up and be pseudo-Clojure for demonstration purposes. The code this is derived from is <a href="https://github.com/wtfleming/clojure-examples/blob/master/apache-spark/flambo-gaming-stack-exchange/src/flambo_gaming_stack_exchange/core.clj">available here at GitHub</a>. And can be run like this:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ ~/bin/spark/bin/spark-submit --class flambo_gaming_stack_exchange.core \
target/flambo-gaming-stack-exchange-0.1.0-SNAPSHOT-standalone.jar
</pre>
</div>

<p>
It's worth noting that the gaming site data is not particularly large, in all likelihood you'd be better off loading the files into RAM with your programming language of choice or into a relational database and querying them that way. However if the data was significantly larger (terabytes or more) you'd be able to use the exact same code and horizontally scale your data processing over a cluster of machines.
</p>
</div>
</div>
<div id="outline-container-org9f0fe80" class="outline-2">
<h2 id="org9f0fe80">Query 1 - Top users</h2>
<div class="outline-text-2" id="text-org9f0fe80">
<p>
Lets find the top 10 users by reputation who have at least a 30,000 reputation score.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(:require [flambo.conf :as conf]
          [flambo.api :as f]
          [flambo.sql :as sql])
(:import [org.apache.spark.sql Column]
         [org.apache.commons.codec.binary Hex])

(defn build-sql-context
  "Returns a Spark SQLContext"
  [app-name]
  (let [c (-&gt; (conf/spark-conf)
              (conf/master "local[*]")
              (conf/app-name app-name))
        sc (f/spark-context c)]
    (sql/sql-context sc)))

(let [home (java.lang.System/getenv "HOME")
      sql-ctx (build-sql-context "Stack Exchange Queries")

      ;; Read in the users Parquet file
      users (sql/parquet-file sql-ctx (string-array (str home "/data/gaming-stack-exchange-warehouse/users.parquet")))

      ;; This is one way to query a DataFrame.
      query (-&gt; users
                (.select (column-array (.col users "name") (.col users "reputation")))
                (.filter "reputation &gt; 30000")
                (.orderBy (column-array (-&gt; users
                                            (.col "reputation")
                                            (.desc))))
                (.limit 10))

      ;; This is another way to run the same query, but to do it this way
      ;; we must first register any tables we will be using.
      _ (sql/register-temp-table users "users")
      sql-query (sql/sql sql-ctx "SELECT name, reputation FROM users WHERE reputation &gt; 30000 ORDER BY reputation DESC LIMIT 10")]
    (.show sql-query))
</pre>
</div>

<p>
Running either of the the above queries will output:
</p>

<pre class="example" id="org229dc05">
name             reputation
Raven Dreamer    123648
agent86          89947
z  '             54792
LessPop_MoreFizz 51582
kalina           41496
Oak              40572
tzenes           40458
StrixVaria       38108
badp             37688
fredley          35584
</pre>
</div>
</div>
<div id="outline-container-org4d968ce" class="outline-2">
<h2 id="org4d968ce">Query 2 - Top users, names obfuscated</h2>
<div class="outline-text-2" id="text-org4d968ce">
<p>
Next lets say we've been given the requirement that we need to obfuscate user names prior to displaying them. Here we will use a SHA-1 hash function and the <a href="https://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/binary/Hex.html">Apache Commons Hex encoder</a>.
</p>

<p>
This is obviously not a good way to obfuscate the name and not how you would want to do it in a production environment, but for the purposes of demonstrating calling arbitrary functions in Spark it is "good enough" for this example.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn hash-string
  "Returns a hexidecimal encoded SHA-1 hash of a string"
  [data]
  (-&gt; (java.security.MessageDigest/getInstance "SHA-1")
      (.digest (.getBytes data))
      (Hex/encodeHexString)))

;; "Hash name in a row with the schema [name reputation], returning a
;;  vector with the name hashed."
(f/defsparkfn hash-name
  [row]
  (let [[name reputation] row
        hashed-name (hash-string name)]
    [hashed-name reputation]))

;; We can also turn a DataFrame to an RDD and use Flambo functions.
;; Here we hash the users name prior to displaying it.
rdd-query (-&gt; sql-query
              (.toJavaRDD)
              (f/map sql/row-&gt;vec)
              (f/map hash-name)
              (f/foreach (f/fn [x] (println x))))
</pre>
</div>

<p>
A few things to note:
</p>

<ul class="org-ul">
<li>sql-query is the DataFrame from the previous query example.</li>
<li>We need to turn the DataFrame into a RDD.</li>
<li>At this time not all of the Spark SQL functions are wrapped in Clojure, so we have to call the Java method .toJavaRDD directly on the DataFrame object rather than a function provided by Flambo.</li>
<li>We need to use Flambo's defsparkfn macro to to define the function we will be using.</li>
</ul>

<p>
Running the above code will output:
</p>

<pre class="example" id="org05a08a0">
[74cfefcff37f81e278398e4de6ce6ada68e7c80e 123648]
[e6eaf112ecf8020e9e1d389ca1e432488bfc7476 89947]
[a8d6f6c81225d88c1797dfc0592935a879d3b626 54792]
[aaa0b19e5e4db300832368b88871e39b695693fe 51582]
[6109e96245bc6d375d942e1cd0d88da8c8172f4a 41496]
[7badddf11e798303d6321ad096d5b2b447f97293 40572]
[7572126b4fd86ccd3610c5280a116c51f186781f 40458]
[8af617f985b18b676f6d809d9b1a9615b72a187b 38108]
[e122e7f4d0fc01a52a909621b43e67ddab506889 37688]
[9f9b1f7ec647cec6f9a4477face2216a81fee0dc 35584]
</pre>
</div>
</div>
<div id="outline-container-org01e9493" class="outline-2">
<h2 id="org01e9493">Query 3 - People who like to play Dwarf Fortress</h2>
<div class="outline-text-2" id="text-org01e9493">
<p>
Finally lets run one more query to find out which users have created the most questions about the game <a href="https://en.wikipedia.org/wiki/Dwarf_Fortress">Dwarf Fortress</a>. In order to answer this we'll need to join users against posts and can do so like this:
</p>

<div class="org-src-container">
<pre class="src src-clojure">;; Top 10 users by number of questions asked about the
;; game Dwarf Fortress.
(let [df-query (sql/sql sql-ctx
                        "SELECT u.name, count(1) as cnt
                        FROM users u, posts p
                        WHERE p.tags LIKE '%dwarf-fortress%'
                        AND u.id = p.ownerId
                        GROUP BY u.name
                        ORDER BY cnt DESC
                        LIMIT 10")]
  (.show df-query))
</pre>
</div>

<p>
Running the query gives us these users and how many questions they have asked:
</p>

<pre class="example" id="org877dd95">
name           cnt
antony.trupe   37
aslum          32
Anna           31
C. Ross        29
Paralytic      15
David Grinberg 15
user5781       14
Mechko         13
andronikus     10
Menno Gouw     9
</pre>
</div>
</div>
<div id="outline-container-orgaa9bc42" class="outline-2">
<h2 id="orgaa9bc42">Conclusion</h2>
<div class="outline-text-2" id="text-orgaa9bc42">
<p>
While this post looked mostly at Spark SQL and DataFrames, support for them in Flambo is currently a bit rudimentary. It still provides access to the underlying Java objects, and the examples above demonstrated this is not a problem. I suspect more of it may get wrapped in Clojure land in future releases.
</p>

<p>
Flambo seems to be currently geared more towards working with Resilient Distributed Datasets. There are a number of <a href="https://github.com/yieldbot/flambo#rdds">RDD operations</a> we didn't touch on here. I highly recommend exploring the documentation to see more of what is available.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/spark/" class="tag" data-tag="spark" data-index="0">spark</a> <a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="1">clojure</a> </span></div>]]></description>
  <category><![CDATA[spark]]></category>
  <category><![CDATA[clojure]]></category>
  <link>https://wtfleming.github.io/blog/exploring-stack-exchange-database-dumps-with-spark-and-flambo/</link>
  <guid>https://wtfleming.github.io/blog/exploring-stack-exchange-database-dumps-with-spark-and-flambo/</guid>
  <pubDate>Tue, 07 Jul 2015 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Adventures in Clojure with core.async - Part 2 - Timeouts and Working with Multiple Channels via Parking and alts!]]></title>
  <description><![CDATA[
<div id="outline-container-org578526e" class="outline-2">
<h2 id="org578526e">Introduction</h2>
<div class="outline-text-2" id="text-org578526e">
<ul class="org-ul">
<li>In <a href="/blog/adventures-with-core-async-part-one-channels-messages/">part 1</a> of this series we looked at the basics of core.async via channels and messages.</li>
<li>In part 2 we will explore timeouts and working with multiple channels using examples of calling out to web APIs.</li>
</ul>

<p>
We will be using the example of a web site that wants to display weather information and will be making mock calls to the <a href="http://openweathermap.org/api">OpenWeatherMap API</a> and <a href="http://www.wunderground.com/weather/api">Weather Underground API</a> to demonstrate using multiple channels with core.async
</p>
</div>
</div>
<div id="outline-container-org1500894" class="outline-2">
<h2 id="org1500894">Helper Function</h2>
<div class="outline-text-2" id="text-org1500894">
<p>
First we define a function that will be used repeatedly in the examples.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn set-inner-html!
  "Helper function to set contents of a DOM element."
  [elem value]
  (set! (.-innerHTML (goog.dom/getElement elem)) value))
</pre>
</div>

<p>
It modifies DOM elements using the Google Closure Library.
</p>
</div>
</div>
<div id="outline-container-org8dcc992" class="outline-2">
<h2 id="org8dcc992">Working with Timeouts</h2>
<div class="outline-text-2" id="text-org8dcc992">
<p>
Let say that when a button is clicked we want to wait a second before continuing. Click the button below to see it in action.
</p>

<hr>

<section>
<span>Output: </span>
<span id="timeout-output"></span>
</section>
<button id="timeout-button">Run Code</button>

<hr>

<p>
The steps taken look like this:
</p>


<figure id="orge62c731">
<img src="/images/core-async-part-two/timeout.png" alt="timeout.png">

</figure>

<p>
In Clojure we could run in a different thread and use the Thread/sleep method provided by the Java virtual machine. But since ClojureScript uses a JavaScript runtime (which is single threaded) we don't have as straightforward of a solution.
</p>

<p>
One approach would be to call js/setTimeout and pass it a call back function. But here we will use the <a href="https://clojure.github.io/core.async/#clojure.core.async/timeout">timeout</a> function provided by core.async.
</p>

<p>
Given a html fragment like:
</p>

<div class="org-src-container">
<pre class="src src-html">&lt;section&gt;
  &lt;span&gt;Output: &lt;/span&gt;
  &lt;span id="timeout-output"&gt;&lt;/span&gt;
&lt;/section&gt;
&lt;button id="timeout-button"&gt;Click me&lt;/button&gt;
</pre>
</div>

<p>
When the button is clicked we can wait for 1 second and then make a DOM change like this:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn handle-timeout-button-click
  "Example of timeouts."
  [_]
  (set-inner-html! "timeout-output" "Button clicked, waiting...")
  (go
    (&lt;! (timeout 1000))
    (set-inner-html! "timeout-output" "Finished after waiting 1 second.")))
</pre>
</div>

<p>
<b>timeout</b> returns a channel that will close and <b>&lt;!</b> will park until a value becomes available or the channel is closed.
</p>
</div>
</div>
<div id="outline-container-orgef8a4ea" class="outline-2">
<h2 id="orgef8a4ea">Mock API Call Functions</h2>
<div class="outline-text-2" id="text-orgef8a4ea">
<p>
The remaining examples will use these functions to simulate calling out to a couple APIs.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn mock-api-call
  "Wait ms milliseconds. Returns a channel containing the message"
  [ms msg]
  (go
    (&lt;! (timeout ms))
    msg))

(defn weather-underground-api-call []
  (mock-api-call (rand-int 1500) "Weather Underground responded."))

(defn open-weather-map-api-call []
  (mock-api-call (rand-int 1500) "OpenWeatherMap responded."))
</pre>
</div>

<p>
They take a random amount of time (up to 1.5 seconds) to return results. Note that a go block returns a channel which in this case will contain the message from the API.
</p>
</div>
</div>
<div id="outline-container-org50efb8c" class="outline-2">
<h2 id="org50efb8c">Working with Multiple Channels via Parking</h2>
<div class="outline-text-2" id="text-org50efb8c">
<p>
In this example we will demonstrate calling out to two APIs, waiting for both to return results, and then display both of them.
</p>


<figure id="org08df76f">
<img src="/images/core-async-part-two/parking.png" alt="parking.png">

</figure>

<div class="org-src-container">
<pre class="src src-clojure">(defn handle-parking-button-click
  "Call two APIs. Output results from both."
  [_]
  (set-inner-html! "parking-output" "Calling APIs, waiting for results.")
  (go
    (let [weather-underground-chan    (weather-underground-api-call)
          open-weather-map-chan       (open-weather-map-api-call)
          weather-underground-message (&lt;! weather-underground-chan)
          open-weather-map-message    (&lt;! open-weather-map-chan)
          msg (str weather-underground-message " " open-weather-map-message)]
      (set-inner-html! "parking-output" msg))))
</pre>
</div>

<section>
<span>Output: </span>
<span id="parking-output"></span>
</section>
<button id="parking-button">Run Code</button>

<hr>

<p>
Under the hood the go block will transform its body to a state machine and wait until both of the calls to <a href="https://clojure.github.io/core.async/#clojure.core.async/%3C!">&lt;!</a> have received a value.
</p>
</div>
</div>
<div id="outline-container-orgd32241d" class="outline-2">
<h2 id="orgd32241d">Working with Multiple Channels via alts!</h2>
<div class="outline-text-2" id="text-orgd32241d">
<p>
In this example we will demonstrate calling out to two APIs, return results from the one that finishes the fastest, and then display it.
</p>

<p>
Since these are both weather services, in all likelihood they will return similar values, so we might do this if all we care about is getting a result and displaying it as fast as possible.
</p>


<figure id="orga903714">
<img src="/images/core-async-part-two/alts.png" alt="alts.png">

</figure>

<div class="org-src-container">
<pre class="src src-clojure">(defn handle-alts-button-click
  "Call two APIs. Output results from the first to return."
  [_]
  (set-inner-html! "alts-output" "Calling APIs, waiting for results.")
  (go
    (let [weather-underground-chan (weather-underground-api-call)
          open-weather-map-chan    (open-weather-map-api-call)
          [msg]                    (alts!
                                     [weather-underground-chan
                                     open-weather-map-chan])]
      (set-inner-html! "alts-output" msg))))
</pre>
</div>

<section>
<span>First API to return results: </span>
<span id="alts-output"></span>
</section>
<button id="alts-button">Run Code</button>

<hr>

<p>
<a href="https://clojure.github.io/core.async/#clojure.core.async/alts!">alts!</a> will park until the first channel has a result. Since there is some randomness in the amount of time each API takes to respond in this example, click the button above a few times and we will potentially get results from a different one on multiple runs.
</p>

<script src="/js/core-async-examples-part-two.js"> </script>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> <a href="https://wtfleming.github.io/tags/clojurescript/" class="tag" data-tag="clojurescript" data-index="1">clojurescript</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <category><![CDATA[clojurescript]]></category>
  <link>https://wtfleming.github.io/blog/adventures-with-core-async-part-two-parking-timeouts-alt/</link>
  <guid>https://wtfleming.github.io/blog/adventures-with-core-async-part-two-parking-timeouts-alt/</guid>
  <pubDate>Wed, 27 May 2015 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Adventures in Clojure with core.async - Part 1 - Channels and Messages]]></title>
  <description><![CDATA[
<div id="outline-container-org3a82f3c" class="outline-2">
<h2 id="org3a82f3c">Introduction</h2>
<div class="outline-text-2" id="text-org3a82f3c">
<ul class="org-ul">
<li>In part 1 of this series we will look at the basics of core.async via channels and messages.</li>
<li>In <a href="/blog/adventures-with-core-async-part-two-parking-timeouts-alt/">part 2</a> we explore timeouts and working with multiple channels using examples of calling out to web APIs.</li>
</ul>

<p>
<a href="https://github.com/clojure/core.async">core.async</a> is a Clojure/ClojureScript library to facilitate asynchronous programming using channels.
</p>

<p>
I wanted to show some simple examples with live demos in the browser using Clojurescript, but if you would like to read a more thorough overview there is a great <a href="http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html">overview of core.async at the clojure.com blog</a>. Code related to this post is also available at <a href="https://github.com/wtfleming/clojurescript-examples/tree/master/core-async-examples">GitHub</a>.
</p>

<p>
It builds upon the <a href="http://en.wikipedia.org/wiki/Communicating_sequential_processes">Communicating Sequential Processes (CSP) model</a> described by Tony Hoare in the late 1970's, but seems to have seen a resurgence in popularity due to its usage in the Go programming language.
</p>
</div>
</div>
<div id="outline-container-org730bd2b" class="outline-2">
<h2 id="org730bd2b">Sending Messages</h2>
<div class="outline-text-2" id="text-org730bd2b">
<p>
These are some of the functions available for writing to and reading from a channel.
</p>

<table>


<colgroup>
<col  class="org-left">

<col  class="org-left">
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Function</th>
<th scope="col" class="org-left">&#xa0;</th>
</tr>
</thead>
<tbody>
<tr>
<td class="org-left">put!</td>
<td class="org-left">Write a message asynchronously to a channel.</td>
</tr>

<tr>
<td class="org-left">take!</td>
<td class="org-left">Take a message asynchronously from a channel.</td>
</tr>

<tr>
<td class="org-left">&gt;!!</td>
<td class="org-left">Write a message to a channel, blocks if no buffer space is available.</td>
</tr>

<tr>
<td class="org-left">&lt;!!</td>
<td class="org-left">Read a message from a channel, blocks if nothing is available.</td>
</tr>

<tr>
<td class="org-left">&gt;!</td>
<td class="org-left">Write a message to a channel, parks if no buffer space is available. Must be called in a go block.</td>
</tr>

<tr>
<td class="org-left">&lt;!</td>
<td class="org-left">Read a message from a channel, parks if nothing is available. Must be called within a go block.</td>
</tr>
</tbody>
</table>

<p>
Note that &gt;!! and &lt;!! are not available in ClojureScript as the underlying JavaScript runtime is single threaded, and blocking that thread would be undesirable.
</p>
</div>
</div>
<div id="outline-container-org10fe272" class="outline-2">
<h2 id="org10fe272">go Blocks</h2>
<div class="outline-text-2" id="text-org10fe272">
<p>
We can use the <b>go</b> macro provided by core.async to create new processes. It will turn any channel operations within into a state machine, which parks on a blocking operation, and resumes when the blocking operation completes.
</p>

<p>
The concept of parking will be covered in more depth in a future post.
</p>
</div>
</div>
<div id="outline-container-orgb96854f" class="outline-2">
<h2 id="orgb96854f">Code</h2>
<div class="outline-text-2" id="text-orgb96854f">
<p>
For the sake of completeness here is a helper function to set DOM values in the browser using the <a href="https://developers.google.com/closure/library/">Google Closure Library</a>.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn set-inner-html!
  "Helper function to set contents of a DOM element."
  [elem value]
  (set! (.-innerHTML (goog.dom/getElement elem)) value))
</pre>
</div>

<p>
We will use in the examples below.
</p>
</div>
</div>
<div id="outline-container-orge7b421c" class="outline-2">
<h2 id="orge7b421c">Unbuffered Channels</h2>
<div class="outline-text-2" id="text-orge7b421c">
<p>
The simplest channel is unbuffered and created using the <b>chan</b> function with no arguments.
</p>

<p>
Writing to an unbuffered channel blocks further writes until the message is read by a consumer of the channel. So in this example we must read from and write to the channel in separate go blocks, which will allow them to appear to run concurrently.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn handle-example-zero-button-click
  "Write to and read from an unbuffered channel."
  [_]
  (let [ch (chan)]
    ;; Write to a channel
    (go
      (&gt;! ch "Hello from an unbuffered channel!"))

    ;; Read from the channel
    (go
      (let [msg (&lt;! ch)]
        (set-inner-html! "example-zero-output" msg)
        (close! ch)))))
</pre>
</div>

<section>
<span>Unbuffered channel output: </span>
<span id="example-zero-output"></span>
</section>
<button id="example-zero-button">Run Code</button>
</div>
</div>
<div id="outline-container-org841d02b" class="outline-2">
<h2 id="org841d02b">Buffered Channels</h2>
<div class="outline-text-2" id="text-org841d02b">
<p>
Calling <b>chan</b> with a single argument that is a number creates a channel with a buffer. This allows us to write more than one message to the channel before it blocks. In the example below we create a channel with a buffer of 5.
</p>

<p>
Note that since this is not an unbuffered channel (and we are not writing more messages than the size of the buffer) we do not need to run the reads and writes in separate go blocks.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn handle-example-one-button-click
  "Write to and read from a buffered channel."
  [_]
  (go
    (let [ch (chan 5)
          _ (&gt;! ch "Hello from a buffered channel!")
          msg (&lt;! ch)]
      (set-inner-html! "example-one-output" msg)
      (close! ch))))
</pre>
</div>

<section>
<span>Buffered channel output: </span>
<span id="example-one-output"></span>
</section>
<button id="example-one-button">Run Code</button>
</div>
</div>
<div id="outline-container-org13bae43" class="outline-2">
<h2 id="org13bae43">Dropping Buffers</h2>
<div class="outline-text-2" id="text-org13bae43">
<p>
We can also create a channel with a dropping-buffer. In this case writes will complete when the buffer is full, but the value will be dropped.
</p>

<p>
We are also using the onto-chan function here, which will write the contents of a collection onto a channel. In this case we are writing the elements of the list (0 1 2 3 4 5 6 7 8 9) to the channel. Note that onto-chan will also close the channel.
</p>

<p>
We are also using the specialized into function provided by core.async, which returns a channel containing a message consisting of the items in the channel conjoined to the collection passed in.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn handle-example-two-button-click
  "Write to and read from a channel with a dropping buffer."
  [_]
  (go
    (let [ch (chan (dropping-buffer 5))
          _ (onto-chan ch (range 0 10))
          msg (&lt;! (async/into [] ch))]
      (set-inner-html! "example-two-output" msg))))
</pre>
</div>

<section>
<span>Dropping buffer output: </span>
<span id="example-two-output"></span>
</section>
<button id="example-two-button">Run Code</button>
</div>
</div>
<div id="outline-container-org39275b4" class="outline-2">
<h2 id="org39275b4">Sliding Buffers</h2>
<div class="outline-text-2" id="text-org39275b4">
<p>
A sliding-buffer is similar to a dropping-buffer, except that when the buffer is full, writes will continue to succeed but the oldest element in the buffer will be dropped.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn handle-example-three-button-click
  "Write to and read from to a channel with a sliding buffer."
  [_]
  (go
    (let [ch (chan (sliding-buffer 5))
          _ (onto-chan ch (range 0 10))
          msg (&lt;! (async/into [] ch))]
      (set-inner-html! "example-three-output" msg))))
</pre>
</div>

<section>
<span>Sliding buffer output: </span>
<span id="example-three-output"></span>
</section>
<button id="example-three-button">Run Code</button>
</div>
</div>
<div id="outline-container-org61dca40" class="outline-2">
<h2 id="org61dca40">Conclusion</h2>
<div class="outline-text-2" id="text-org61dca40">
<p>
We've barely scratched the surface of core.async in this introductory post. In future posts we'll see more of what the library provides, show some practical examples (including some very neat things we can do with the state machine that go blocks provide).
</p>

<ul class="org-ul">
<li>In part 1 of this series we looked at the basics of core.async via channels and messages.</li>
<li>In [part 2][part-2] we will explore timeouts and working with multiple channels using examples of calling out to web APIs.</li>
</ul>

<script src="/js/core-async-examples.js"> </script>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> <a href="https://wtfleming.github.io/tags/clojurescript/" class="tag" data-tag="clojurescript" data-index="1">clojurescript</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <category><![CDATA[clojurescript]]></category>
  <link>https://wtfleming.github.io/blog/adventures-with-core-async-part-one-channels-messages/</link>
  <guid>https://wtfleming.github.io/blog/adventures-with-core-async-part-one-channels-messages/</guid>
  <pubDate>Wed, 15 Apr 2015 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Visualizing Twitter Connections with D3 and ClojureScript]]></title>
  <description><![CDATA[
<div id="outline-container-org500b0aa" class="outline-2">
<h2 id="org500b0aa">Introduction</h2>
<div class="outline-text-2" id="text-org500b0aa">
<p>
I was curious about the connections between some of the people I follow on Twitter and wanted to try visualizing it using <a href="http://d3js.org/">D3</a> and ClojureScript using a <a href="https://github.com/mbostock/d3/wiki/Force-Layout">force directed graph</a>. The end result looks like this:
</p>

<div class="app"></div>
<script src="/js/d3-force-directed-graph.js"> </script>
<script>
force_directed_graph.core.main('/js/d3-force-directed-graph.json');
</script>

<p>
Not a lot of surprises, there are a few clusters around common interests: Emacs, food, Dwarf Fortress, Hadoop, etc.
</p>
</div>
</div>
<div id="outline-container-orgec65919" class="outline-2">
<h2 id="orgec65919">Code</h2>
<div class="outline-text-2" id="text-orgec65919">
<p>
In this post i'll just share a minimum of ClojureScript code, but a <a href="https://github.com/wtfleming/clojurescript-examples/tree/master/d3-force-directed-graph">code for a full example is available at Github</a>. I highly recommend checking out the code, running the commands in the README file, and then viewing the results in a browser.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns force-directed-graph.core
  (:require cljsjs.d3))

(defn- build-force-layout [width height]
  (.. js/d3
      -layout
      force
      (charge -140)
      (linkDistance 40)
      (size (array width height))))

(defn- setup-force-layout [force-layout graph]
  (.. force-layout
      (nodes (.-nodes graph))
      (links (.-links graph))
      start))

(defn- build-svg [width height]
  (.. js/d3
      (select ".app")
      (append "svg")
      (attr "width" width)
      (attr "height" height)))

(defn- build-links [svg graph]
  (.. svg
      (selectAll ".link")
      (data (.-links graph))
      enter
      (append "line")
      (attr "class" "link")
      (attr "stroke" "grey")
      (style "stroke-width" 1)))

(defn- build-nodes [svg graph force-layout]
  (.. svg
      (selectAll ".node")
      (data (.-nodes graph))
      enter
      (append "text")
      (attr "cx" 12)
      (attr "cy" ".35em")
      (text #(.-name %))
      (call (.-drag force-layout))))

(defn on-tick [link node]
  (fn []
    (.. link
        (attr "x1" #(.. % -source -x))
        (attr "y1" #(.. % -source -y))
        (attr "x2" #(.. % -target -x))
        (attr "y2" #(.. % -target -y)))
    (.. node
        (attr "transform" #(str "translate(" (.. % -x) "," (.. % -y) ")")))))

(defn ^:export main [json-file]
  (let [width 960
        height 600
        force-layout (build-force-layout width height)
        svg (build-svg width height)]
    (.json js/d3 json-file
           (fn [error json]
             (.. json
                 -links
                 (forEach #(do (aset %1 "weight" 1.0)
                               (aset %1 "index" %2))))
             (setup-force-layout force-layout json)
             (let [links (build-links svg json)
                   nodes (build-nodes svg json force-layout)]
               (.on force-layout "tick"
                    (on-tick links nodes)))))))
</pre>
</div>

<p>
We are pulling in D3 via <a href="http://cljsjs.github.io/">CLJSJS</a> packages, which makes adding dependencies on Javascript libraries very easy. Otherwise, it is all pretty straightforward and not too different from an <a href="http://bl.ocks.org/mbostock/4062045">example like this in Javascript</a>.
</p>
</div>
</div>
<div id="outline-container-org122f285" class="outline-2">
<h2 id="org122f285">Sample input</h2>
<div class="outline-text-2" id="text-org122f285">
<p>
The one thing to be aware of is how the JSON that will be passed in needs to be formatted. You will need to define nodes and links between the nodes.
</p>

<p>
Here is a simple example with four nodes, in this case the node named A follows B and C, while B follows D.
</p>

<div class="org-src-container">
<pre class="src src-json">{
  "nodes": [
    {
      "name": "A",
      "index": 0
    },
    {
      "name": "B",
      "index": 1
    },
    {
      "name": "C",
      "index": 2
    },
    {
      "name": "D",
      "index": 3
    }
  ],
    "links": [
    {
      "target": 1,
      "source": 0
    },
    {
      "target": 2,
      "source": 0
    },
    {
      "target": 3,
      "source": 1
    }
  ]
}
</pre>
</div>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/d3/" class="tag" data-tag="d3" data-index="0">d3</a> <a href="https://wtfleming.github.io/tags/clojurescript/" class="tag" data-tag="clojurescript" data-index="1">clojurescript</a> </span></div>]]></description>
  <category><![CDATA[d3]]></category>
  <category><![CDATA[clojurescript]]></category>
  <link>https://wtfleming.github.io/blog/d3-force-directed-graph/</link>
  <guid>https://wtfleming.github.io/blog/d3-force-directed-graph/</guid>
  <pubDate>Thu, 19 Feb 2015 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Writing a Kafka Producer and High Level Consumer in Clojure]]></title>
  <description><![CDATA[
<div id="outline-container-orgf898e08" class="outline-2">
<h2 id="orgf898e08">Introduction</h2>
<div class="outline-text-2" id="text-orgf898e08">
<p>
Kafka is a platform for handling real-time data feeds. In some ways it is like a database that exposes semantics of a messaging system.
</p>

<p>
The <a href="https://kafka.apache.org/documentation.html">Kafka documentation</a> provides an excellent overview which I have provided an extract from:
</p>

<pre class="example" id="org4ae9ad5">
Kafka is a distributed, partitioned, replicated commit log service. It provides the
functionality of a messaging system, but with a unique design.

* Kafka maintains feeds of messages in categories called topics.
* We'll call processes that publish messages to a Kafka topic producers.
* We'll call processes that subscribe to topics and process the feed of published
messages consumers.
* Kafka is run as a cluster comprised of one or more servers each of which is called
a broker.
</pre>

<p>
In this post we'll use Clojure to write a producer that periodically writes random integers to a Kafka topic, and a High Level Consumer that reads them back. I am using Kafka 0.8.1.1 and assume it and ZooKeeper are running on localhost. A <a href="http://kafka.apache.org/07/quickstart.html">quickstart</a> is available that can walk you through downloading and starting the services.
</p>

<p>
The source code for this project is <a href="https://github.com/wtfleming/clojure-examples/tree/master/kafka/hello-world-kafka">available on GitHub</a>.
</p>
</div>
</div>
<div id="outline-container-orgcf59b51" class="outline-2">
<h2 id="orgcf59b51">Create a Project</h2>
<div class="outline-text-2" id="text-orgcf59b51">
<p>
We'll be using <a href="http://leiningen.org/">Leiningen</a> to build and run our app.
</p>

<p>
Create a file called project.clj with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defproject hello-world-kafka "0.1.0"
  :description "Create a kafka producer and high level consumer"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [org.apache.kafka/kafka_2.9.2 "0.8.1.1" :exclusions [javax.jms/jms
                                                                      com.sun.jdmk/jmxtools
                                                                      com.sun.jmx/jmxri]]]
  :aot [hello-world-kafka.core]
  :main hello-world-kafka.core)
</pre>
</div>

<p>
Next create a file /src/hello<sub>world</sub><sub>kafka</sub>/core.clj with these contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns hello-world-kafka.core
  (:import (kafka.consumer Consumer ConsumerConfig KafkaStream)
           (kafka.producer KeyedMessage ProducerConfig)
           (kafka.javaapi.producer Producer)
           (java.util Properties)
           (java.util.concurrent Executors))
  (:gen-class))
</pre>
</div>
</div>
</div>
<div id="outline-container-org9316909" class="outline-2">
<h2 id="org9316909">Producer Code</h2>
<div class="outline-text-2" id="text-org9316909">
<div class="org-src-container">
<pre class="src src-clojure">(defn- create-producer
  "Creates a producer that can be used to send a message to Kafka"
  [brokers]
  (let [props (Properties.)]
    (doto props
      (.put "metadata.broker.list" brokers)
      (.put "serializer.class" "kafka.serializer.StringEncoder")
      (.put "request.required.acks" "1"))
    (Producer. (ProducerConfig. props))))

(defn- send-to-producer
  "Send a string message to Kafka"
  [producer topic message]
  (let [data (KeyedMessage. topic nil message)]
    (.send producer data)))
</pre>
</div>

<p>
Creating a producer and sending a message is pretty straightforward. Call the create-producer function with a list of Kafka brokers, and when you want to send a message pass the producer to the send-to-producer method along with the name of the topic and the message.
</p>
</div>
</div>
<div id="outline-container-org57a1d80" class="outline-2">
<h2 id="org57a1d80">Consumer Code</h2>
<div class="outline-text-2" id="text-org57a1d80">
<div class="org-src-container">
<pre class="src src-clojure">(defrecord KafkaMessage [topic offset partition key value-bytes])

(defn- create-consumer-config
  "Returns a configuration for a Kafka client."
  []
  (let [props (Properties.)]
    (doto props
      (.put "zookeeper.connect" "127.0.0.1:2181")
      (.put "group.id" "group1")
      (.put "zookeeper.session.timeout.ms" "400")
      (.put "zookeeper.sync.time.ms" "200")
      (.put "auto.commit.interval.ms" "1000"))
    (ConsumerConfig. props)))

(defn- consume-messages
  "Continually consume messages from a Kafka topic and write message value to stdout."
  [stream thread-num]
  (let [it (.iterator ^KafkaStream stream)]
    (println (str "Starting thread " thread-num))
    (while (.hasNext it)
      (as-&gt; (.next it) msg
            (KafkaMessage. (.topic msg) (.offset msg) (.partition msg) (.key msg) (.message msg))
            (println (str "Received on thread " thread-num ": " (String. (:value-bytes msg))))))
    (println (str "Stopping thread " thread-num))))

(defn- start-consumer-threads
  "Start a thread for each stream."
  [thread-pool kafka-streams]
  (loop [streams kafka-streams
         index 0]
    (when (seq streams)
      (.submit thread-pool (cast Callable #(consume-messages (first streams) index)))
      (recur (rest streams) (inc index)))))
</pre>
</div>

<p>
A few things to take note of:
</p>

<ul class="org-ul">
<li>The message is stored in Kafka as bytes, so in this case we need to turn the bytes into a String.</li>

<li>In consume-messages the call to the KafkaStream iterator .hasNext function is reading from a single partition of it's topic and will block until a message is received. So to read from multiple partitions we will need to run multiple threads of the consume-messages function.</li>

<li>The threads will run in a thread pool we later create with a java.util.concurrent.Executors</li>

<li>Clojure functions implement both Runnable and Callable, but since the executor's submit function is overloaded and can accept either, we must explicitly cast the function to a Callable.</li>
</ul>
</div>
</div>
<div id="outline-container-org5c62581" class="outline-2">
<h2 id="org5c62581">Application code</h2>
<div class="outline-text-2" id="text-org5c62581">
<div class="org-src-container">
<pre class="src src-clojure">(defn -main
  "Pull messages from a Kafka topic using the High Level Consumer"
  [topic num-threads]
  (let [consumer (Consumer/createJavaConsumerConnector (create-consumer-config))
        consumer-map (.createMessageStreams consumer {topic (Integer/parseInt num-threads)})
        kafka-streams (.get consumer-map topic)
        thread-pool (Executors/newFixedThreadPool (Integer/parseInt num-threads))
        producer (create-producer "127.0.0.1:9092")]

    ;; Clean up on a SIGTERM or Ctrl-C
    (.addShutdownHook (Runtime/getRuntime)
                      (Thread. #(do (.shutdown consumer)
                                    (.shutdown thread-pool))))

    ;; Connect and start listening for messages on Kafka
    (start-consumer-threads thread-pool kafka-streams)

    ;; Send a random int to Kafka every 500 milliseconds
    (loop []
      (let [num (str (rand-int 1000))]
        (println (str "Sending to Kafka topic " topic ": " num))
        (send-to-producer producer topic num)
        (Thread/sleep 500)
        (recur)))))
</pre>
</div>

<p>
The above code sets up our thread pools, creates and starts some consumers, and then sends a random integer between 0 and 999 to a topic every 500 milliseconds.
</p>

<p>
Running from the command line expects arguments like this:
</p>

<pre class="example" id="org697294a">
$ lein trampoline run &lt;topic&gt; &lt;num consumer threads&gt;
</pre>

<p>
We use lein trampoline so we can catch a SIGTERM or Control-C and clean up prior to shutting down.
</p>

<p>
If we want to send and read messages from a topic called random<sub>numbers</sub> and use 2 threads for the consumers we can start the app like this:
</p>

<pre class="example" id="org12a4c61">
$ lein trampoline run random_numbers 2
</pre>

<p>
You should see output that looks something like this:
</p>

<pre class="example" id="orgb2c1c88">
Starting thread 0
Starting thread 1
Sending to Kafka topic random_numbers: 753
Received on thread 1: 753
Sending to Kafka topic random_numbers: 971
Received on thread 1: 971
Sending to Kafka topic random_numbers: 56
Received on thread 1: 56
Sending to Kafka topic random_numbers: 536
Received on thread 1: 536
Sending to Kafka topic random_numbers: 589
Received on thread 1: 589
Stopping thread 0
Stopping thread 1
</pre>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> <a href="https://wtfleming.github.io/tags/kafka/" class="tag" data-tag="kafka" data-index="1">kafka</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <category><![CDATA[kafka]]></category>
  <link>https://wtfleming.github.io/blog/kafka-clojure-producer-consumer/</link>
  <guid>https://wtfleming.github.io/blog/kafka-clojure-producer-consumer/</guid>
  <pubDate>Wed, 14 Jan 2015 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Running a Dockerized Clojure Web App on CoreOS]]></title>
  <description><![CDATA[
<div id="outline-container-org9fa4ac1" class="outline-2">
<h2 id="org9fa4ac1">Introduction</h2>
<div class="outline-text-2" id="text-org9fa4ac1">
<p>
In the <a href="/blog/dockerize-clojure-compojure-http-kit-web-application/">previous post</a> we created a Clojure web service and ran it in a Docker container. Here we will deploy that container on a 3 node CoreOS cluster running in <a href="https://www.vagrantup.com/">Vagrant</a> on a local development machine.
</p>
</div>
</div>
<div id="outline-container-org973d8f1" class="outline-2">
<h2 id="org973d8f1">CoreOS</h2>
<div class="outline-text-2" id="text-org973d8f1">
<p>
CoreOS is a minimal version of Linux meant for large scale server deployments.
</p>

<p>
It has a very different model than a Debian/Red Hat/etc distribution. The OS runs on a read-only partition, and applications/services run in Docker containers on a read-write filesystem.
</p>

<p>
It's web page describes it as:
</p>

<pre class="example" id="org591ad4d">
A new Linux distribution that has been rearchitected to provide features needed
to run modern infrastructure stacks. The strategies and architectures that influence
CoreOS allow companies like Google, Facebook and Twitter to run their services at
scale with high resilience.
</pre>

<p>
The components to be aware of are:
</p>

<hr>

<ul class="org-ul">
<li><b><a href="https://coreos.com/">CoreOS</a></b> - The underlying operating system.</li>
<li><b><a href="https://www.docker.com/">Docker</a></b> - CoreOS applications run in containers. At this time only Docker is supported. However, the CoreOS team recently announced a new container runtime called <a href="https://github.com/coreos/rocket">Rocket</a> they will also be adding support for.</li>
<li><b><a href="https://coreos.com/using-coreos/etcd/">etcd</a></b> - A highly-available key value store for shared configuration and service discovery. This fulfills a role similar to ZooKeeper.</li>
<li><b><a href="https://github.com/coreos/fleet">fleet</a></b> - You will use this to start/stop containers, define a cluster topology, etc. It ties together systemd and etcd into a distributed init system. Think of it as an extension of systemd that operates at the cluster level instead of the machine level.</li>
</ul>

<hr>

<p>
We won't be really be going into etcd in this post, but there are some interesting things you can do with it. For instance, you could configure a trigger so that when a new web service comes online it can detect this and automatically change an nginx configuration to proxy traffic to it (or remove it from the rotation when the service is stopped).
</p>
</div>
</div>
<div id="outline-container-org7cdc835" class="outline-2">
<h2 id="org7cdc835">Start Vagrant</h2>
<div class="outline-text-2" id="text-org7cdc835">
<p>
I am assuming you are on either a Linux or OS X machine, if you are on Windows you will likely need to make a few changes.
</p>

<p>
If you run into any problems there is also a guide to using Vagrant on the CoreOS <a href="https://coreos.com/blog/coreos-clustering-with-vagrant/">blog</a> and <a href="https://coreos.com/docs/running-coreos/platforms/vagrant/">documentation</a> which may help you troubleshoot.
</p>

<p>
Ensure you have installed Vagrant on you development machine, then use git to clone the <a href="https://github.com/coreos/coreos-vagrant">coreos-vagrant repo</a>.
</p>

<pre class="example" id="org5517ab7">
$ git clone git@github.com:coreos/coreos-vagrant.git
$ cd coreos-vagrant
</pre>

<p>
Rename the file <i>config.rb.sample</i> to <i>config.rb</i> and change the lines:
</p>

<pre class="example" id="org7b926a7">
#$num_instances=1
#$update_channel='alpha'
</pre>

<p>
to
</p>

<pre class="example" id="org6cbf91a">
$num_instances=3
$update_channel='stable'
</pre>

<p>
Next rename the file <i>user-data.sample</i> to <i>user-data</i> and then browse to <a href="https://discovery.etcd.io/new">[[https://discovery.etcd.io/new</a>]] and copy the what was on the page then uncomment and insert it on the the line that looks like this:
</p>

<pre class="example" id="org431e642">
#discovery: https://discovery.etcd.io/&lt;token&gt;
</pre>

<p>
Every time you start a new cluster you will need a new token. If you do not want to use the discovery service you can instead include the network addresses of the machines that will be running etcd yourself. The CoreOS team provide the discovery.etcd.io service as a convenience to make it easier to bootstrap a cluster, but you are not required to use it.
</p>

<p>
Now run this command:
</p>

<pre class="example" id="org769d5f6">
$ vagrant up
</pre>

<p>
and Vagrant will launch 3 VirtualBox machines running CoreOS.
</p>

<pre class="example" id="org27d8212">
$ vagrant status
Current machine states:
core-01                   running (virtualbox)
core-02                   running (virtualbox)
core-03                   running (virtualbox)
</pre>

<p>
As you can see, there are 3 machines running.
</p>
</div>
</div>
<div id="outline-container-orgb3ee00a" class="outline-2">
<h2 id="orgb3ee00a">SSH to your cluster</h2>
<div class="outline-text-2" id="text-orgb3ee00a">
<p>
In order to forward your SSH session to other machines in the cluster you will need to use a key that is installed on all machines. In this case one from Vagrant will already be installed on the machines and we can add it like this:
</p>

<pre class="example" id="orgefa2b5c">
$ ssh-add ~/.vagrant.d/insecure_private_key
</pre>

<p>
Now SSH into one of the boxes with agent forwarding:
</p>

<pre class="example" id="org3efb013">
$ vagrant ssh core-01 -- -A
</pre>

<p>
We'll use the fleetctl tool to control our cluster. First lets see that we can see all 3 machines:
</p>

<pre class="example" id="org3c43d65">
$ fleetctl list-machines
MACHINE         IP              METADATA
c313e784...     172.17.8.102    -
c3ddc4fd...     172.17.8.101    -
d0f027da...     172.17.8.103    -
</pre>

<p>
You should see something like the above. We haven't defined any metadata, but you could do something like tag a machine backed by a SSD drive, and then when you launch a service like PostgreSQL tell fleet that it should only run on a machine with that metadata.
</p>
</div>
</div>
<div id="outline-container-orgede844f" class="outline-2">
<h2 id="orgede844f">Create A Service File</h2>
<div class="outline-text-2" id="text-orgede844f">
<p>
CoreOS runs applications as Docker containers. We will be running a simple web server written in Clojure that just displays the text "Hello World". The source code is <a href="https://github.com/wtfleming/docker-compojure-hello-world">available on GitHub</a> and the Docker container is also <a href="https://registry.hub.docker.com/u/wtfleming/docker-compojure-hello-world/">published at Docker Hub</a>.
</p>

<p>
Ensure that you are logged onto a machine in the cluster via SSH and create a file named <i>clojure-http@.service</i>. The file format is a <a href="http://freedesktop.org/wiki/Software/systemd/">systemd</a> service file.
</p>

<pre class="example" id="org46ca5eb">
[Unit]
Description=clojure-http

[Service]
ExecStart=/usr/bin/docker run --name clojure-http-%i --rm -p 5000:5000 -e PORT=5000 wtfleming/docker-compojure-hello-world
ExecStop=/usr/bin/docker stop clojure-http-%i

[X-Fleet]
Conflicts=clojure-http@*.service
</pre>

<p>
This file provides the instructions about how the service should run. There are a few things to note:
</p>

<ul class="org-ul">
<li>We are running a docker container and exposing port 5000.</li>
<li>The wtfleming/docker-compojure-hello-world container is publicly hosted on Docker Hub, it will be automatically downloaded to the CoreOS cluster.</li>
<li>The %i refers to the string between the @ and the suffix when we start the service (which we will do shortly, and should make sense then).</li>
<li>The X-Fleet directive indicates that this service should only one instance of the service on a machine. Since we've bound to port 5000 if we start up a second copy of this service we don't want it here, fleet will launch it on another machine in the cluster.</li>
</ul>

<p>
Now submit the service file and check that it registered:
</p>

<pre class="example" id="org94bcecd">
$ fleetctl submit clojure-http@.service

$ fleetctl list-unit-files
UNIT                    HASH    DSTATE          STATE           TARGET
clojure-http@.service   aab3979 inactive        inactive        -
</pre>

<p>
If you see the file listed we are ready to move on.
</p>
</div>
</div>
<div id="outline-container-orga10d7ad" class="outline-2">
<h2 id="orga10d7ad">Start the Web Services</h2>
<div class="outline-text-2" id="text-orga10d7ad">
<p>
We will be running 2 copies of the service, lets start them:
</p>

<pre class="example" id="orgd26c4c2">
$ fleetctl start clojure-http@1.service
Unit clojure-http@1.service launched on c313e784.../172.17.8.102

$ fleetctl start clojure-http@2.service
Unit clojure-http@2.service launched on c3ddc4fd.../172.17.8.101
</pre>

<p>
You can check the status of running units:
</p>

<pre class="example" id="orgd690789">
$ fleetctl list-units
UNIT                    MACHINE                         ACTIVE  SUB
clojure-http@1.service  c313e784.../172.17.8.102        active  running
clojure-http@2.service  c3ddc4fd.../172.17.8.101        active  running
</pre>

<p>
You can view logs like this:
</p>

<pre class="example" id="org6573899">
$ fleetctl journal clojure-http@1.service
Dec 03 04:44:48 core-02 systemd[1]: Starting clojure-http...
Dec 03 04:44:48 core-02 systemd[1]: Started clojure-http.
Dec 03 04:44:52 core-02 docker[711]: Listening on port 5000
</pre>

<p>
Finally lets view each of the pages:
</p>

<pre class="example" id="org952a1aa">
$ curl http://172.17.8.101:5000
Hello World

$ curl http://172.17.8.102:5000
Hello World
</pre>

<p>
Hopefully you'll have gotten output similar to above.
</p>
</div>
</div>
<div id="outline-container-orga0eda19" class="outline-2">
<h2 id="orga0eda19">Stop the Services and Clean Up</h2>
<div class="outline-text-2" id="text-orga0eda19">
<p>
Lets stop the services:
</p>

<pre class="example" id="org5c1f2ce">
$ fleetctl stop clojure-http@1.service
Unit clojure-http@1.service loaded on c313e784.../172.17.8.102

$ fleetctl stop clojure-http@2.service
Unit clojure-http@2.service loaded on c3ddc4fd.../172.17.8.101
</pre>

<p>
Notice that they have now entered a failed state, but remain listed.
</p>

<pre class="example" id="orgafd609d">
$ fleetctl list-units
UNIT                    MACHINE                         ACTIVE  SUB
clojure-http@1.service  c313e784.../172.17.8.102        failed  failed
clojure-http@2.service  c3ddc4fd.../172.17.8.101        failed  failed
</pre>

<p>
We could restart them, but instead we will remove them like this:
</p>

<pre class="example" id="org8ebddc2">
$ fleetctl destroy clojure-http@1.service
Destroyed clojure-http@1.service

$ fleetctl destroy clojure-http@2.service
Destroyed clojure-http@2.service

$ fleetctl list-units
UNIT    MACHINE ACTIVE  SUB
</pre>

<p>
Now lets remove our service file.
</p>

<pre class="example" id="org2775a28">
$ fleetctl destroy clojure-http@.service
Destroyed clojure-http@.service

$ fleetctl list-unit-files
UNIT    HASH    DSTATE  STATE   TARGET
</pre>

<p>
Now exit the cluster, shut it down, and clean up Vagrant.
</p>

<pre class="example" id="org93f283a">
$ exit

$ vagrant halt
==&gt; core-03: Attempting graceful shutdown of VM...
==&gt; core-02: Attempting graceful shutdown of VM...
==&gt; core-01: Attempting graceful shutdown of VM...

$ vagrant destroy
...
</pre>

<p>
And we're done!
</p>
</div>
</div>
<div id="outline-container-org0ea2a97" class="outline-2">
<h2 id="org0ea2a97">Next Steps</h2>
<div class="outline-text-2" id="text-org0ea2a97">
<p>
So far we created a CoreOS cluster and ran a web server on it, but we have just barely scratched the surface of what is possible.
</p>

<p>
In a production environment you would want expose the web services to the world. If you are on EC2 you might want to register the services with an Elastic Load Balancer. One way to do that is with a <a href="https://coreos.com/docs/launching-containers/launching/launching-containers-fleet/#run-a-simple-sidekick">"sidekick" container</a> for each web service.
</p>

<p>
The CoreOS team provides <a href="https://github.com/coreos/elb-presence">code to create a container on github</a> that will register a service with an ELB, and <a href="https://github.com/coreos/unit-examples/tree/master/blog-fleet-intro">example of how to use it</a>.
</p>

<p>
Marcel de Graaf has also <a href="http://marceldegraaf.net/2014/04/24/experimenting-with-coreos-confd-etcd-fleet-and-cloudformation.html">written about running on EC2 and using nginx to proxy</a>. If you want to know more, I highly recommend taking the time to read his post and the CoreOS documentation, they both go into much greater detail about what is possible and issues you should be aware of running a service in a production setting.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> <a href="https://wtfleming.github.io/tags/docker/" class="tag" data-tag="docker" data-index="1">docker</a> <a href="https://wtfleming.github.io/tags/coreos/" class="tag" data-tag="coreos" data-index="2">coreos</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <category><![CDATA[docker]]></category>
  <category><![CDATA[coreos]]></category>
  <link>https://wtfleming.github.io/blog/run-dockerized-clojure-app-on-coreos/</link>
  <guid>https://wtfleming.github.io/blog/run-dockerized-clojure-app-on-coreos/</guid>
  <pubDate>Sat, 06 Dec 2014 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Dockerizing a Clojure, Compojure, and HTTP Kit Web Application]]></title>
  <description><![CDATA[
<p>
<a href="https://www.docker.com/">Docker</a> is "an open platform for developers and sysadmins to build, ship, and run distributed applications. With Docker, developers can build any app in any language using any toolchain. Dockerized apps are completely portable and can run anywhere - colleagues' OS X and Windows laptops, QA servers running Ubuntu in the cloud, and production data center VMs running Red Hat."
</p>

<p>
Here we will build a very simple web site using the Clojure <a href="https://github.com/weavejester/compojure">Compojure</a> and <a href="https://www.http-kit.org/">HTTP Kit</a> libraries. The source code for this article is also available <a href="https://github.com/wtfleming/docker-compojure-hello-world">here</a>.
</p>
<div id="outline-container-org8ec3bf8" class="outline-2">
<h2 id="org8ec3bf8">Create a Compojure Application</h2>
<div class="outline-text-2" id="text-org8ec3bf8">
<p>
First create a file named <i>project.clj</i> with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defproject hello-world "0.1.0"
  :description "Compojure hello world web app"
  :url "https://github.com/wtfleming/docker-compojure-hello-world"
  :min-lein-version "2.0.0"
  :dependencies [[org.clojure/clojure "1.6.0"]
                 [compojure "1.2.1"]
                 [http-kit "2.1.16"]]
  :main hello-world.core
  :aot [hello-world.core])
</pre>
</div>

<p>
And then create a file named <i>src/hello<sub>world</sub>/core.clj</i> with these contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns hello-world.core
  (:require [compojure.core :refer :all]
            [org.httpkit.server :refer [run-server]])
  (:gen-class))

(defroutes myapp
  (GET "/" [] "Hello World"))

(defn -main []
  (let [port (Integer/parseInt (or (System/getenv "PORT") "8080"))]
    (run-server myapp {:port port})
    (println (str "Listening on port " port))))
</pre>
</div>

<p>
This is a very basic Compojure/HTTP Kit app with a single route that displays a web page with the contents "Hello World". We also check to see if an environment variable PORT has been defined, and if so bind to it, otherwise default to port 8080.
</p>

<p>
Now build with <a href="http://leiningen.org/">Leiningen</a>.
</p>

<pre class="example" id="orgbb64e2a">
$ lein uberjar
</pre>

<p>
You could now run locally like this
</p>

<pre class="example" id="org6e550c4">
$ java -jar target/hello-world-0.1.0-standalone.jar
</pre>

<p>
Browse to <a href="http://localhost:8080">http://localhost:8080</a> and you should see a page that displays "Hello World".
</p>
</div>
</div>
<div id="outline-container-orga51ea4d" class="outline-2">
<h2 id="orga51ea4d">Create a Dockerfile</h2>
<div class="outline-text-2" id="text-orga51ea4d">
<p>
Now create a file called <i>Dockerfile</i> with these contents
</p>

<pre class="example" id="orgc149e83">
#
# Dockerfile for a compojure hello world app
#

FROM java:openjdk-8-jre
MAINTAINER Will Fleming &lt;wfleming77@gmail.com&gt;
ENV REFRESHED_AT 2014-11-25

COPY target/hello-world-0.1.0-standalone.jar hello-world-0.1.0-standalone.jar

ENV PORT 4000

EXPOSE 4000

CMD ["java", "-jar", "hello-world-0.1.0-standalone.jar"]
</pre>

<p>
The Dockerfile is a set of instructions to build a docker container.
</p>

<ul class="org-ul">
<li>We copy the jar file from our file system to the docker filesystem.</li>

<li>Define a environment variable PORT with the value 4000.</li>

<li>Expose port 4000 to other docker containers.</li>

<li>Provide a default command to be run when starting the container.</li>
</ul>

<p>
There is much more you can do, the <a href="https://docs.docker.com/reference/builder/">Dockerfile documentation</a> goes into further detail.
</p>
</div>
</div>
<div id="outline-container-org9f8a0e6" class="outline-2">
<h2 id="org9f8a0e6">Build a Docker Image</h2>
<div class="outline-text-2" id="text-org9f8a0e6">
<p>
Now lets build a Docker image.
</p>

<pre class="example" id="org785ae70">
$ docker build -t wtfleming/compojure-hello-world .
</pre>

<p>
We can see that it was built:
</p>

<pre class="example" id="org78cb16b">
$ docker images
REPOSITORY                        TAG     IMAGE ID       CREATED      VIRTUAL SIZE
wtfleming/compojure-hello-world   latest  b1c798937b9d   6 days ago   351.1 MB
</pre>

<p>
We can use an image as the basis to launch a container.
</p>
</div>
</div>
<div id="outline-container-orgd17a576" class="outline-2">
<h2 id="orgd17a576">Run a Docker container</h2>
<div class="outline-text-2" id="text-orgd17a576">
<pre class="example" id="org03849d8">
$ docker run --rm -p 4000:4000 wtfleming/compojure-hello-world
Listening on port 4000
</pre>

<p>
In the above we:
</p>

<ul class="org-ul">
<li>Start a container from the wtfleming/compojure-hello-world image.</li>
<li>&#x2013;rm will delete the container when it stops</li>
<li>-p will publish a container's port to the host</li>
</ul>

<p>
Open a web browser to <a href="http://localhost:4000">http://localhost:4000</a> and you will see the page.
</p>

<p>
Browse to <a href="http://localhost:4000">http://localhost:4000</a> or if you are on a Mac or Windows using boot2docker find the ip address like
</p>

<pre class="example" id="orgb86e9ce">
$ boot2docker ip
The VM's Host only interface IP address is: 192.168.59.103
</pre>

<p>
and browse to the ip provided by boot2docker like <a href="http://192.168.59.103:4000">http://192.168.59.103:4000</a>
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> <a href="https://wtfleming.github.io/tags/docker/" class="tag" data-tag="docker" data-index="1">docker</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <category><![CDATA[docker]]></category>
  <link>https://wtfleming.github.io/blog/dockerize-clojure-compojure-http-kit-web-application/</link>
  <guid>https://wtfleming.github.io/blog/dockerize-clojure-compojure-http-kit-web-application/</guid>
  <pubDate>Sat, 29 Nov 2014 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Geospatial queries with elasticsearch]]></title>
  <description><![CDATA[
<p>
Recently I was investigating the geospatial capabilities of <a href="http://www.elasticsearch.org/">elasticsearch</a> for a project (in this case I am using version 1.3.4). While I ultimately ended up not using it for this project I thought I would write up an example using the command line.
</p>

<hr>
<div id="outline-container-orgda05ef5" class="outline-2">
<h2 id="orgda05ef5">Create a mapping</h2>
<div class="outline-text-2" id="text-orgda05ef5">
<p>
First we need to create a mapping for the geotest index. A mapping allows us to tell elasticsearch how an index is structured. In this case we expect our documents to have two fields: a user identifier, and a location (in this case we are using a 2 dimensional point to represent lat/lon).
</p>

<div class="org-src-container">
<pre class="src src-sh">curl -XPUT http://localhost:9200/geotest -d '
{
    "mappings": {
        "usergeo": {
            "properties": {
                "udid": {"type": "string"},
                "location": {"type": "geo_point"}
            }
        }
    }
}
'
</pre>
</div>
</div>
</div>
<div id="outline-container-org05feb1f" class="outline-2">
<h2 id="org05feb1f">Add users to the index</h2>
<div class="outline-text-2" id="text-org05feb1f">
<div class="org-src-container">
<pre class="src src-sh">curl -XPOST 'http://localhost:9200/geotest/usergeo' -d '
{
    "udid" : "foo-udid",
    "location": {"lat": "38.897676", "lon": "-77.03653"}
}
'
curl -XPOST 'http://localhost:9200/geotest/usergeo' -d '
{
    "udid" : "bar-udid",
    "location": {"lat": "28.897676", "lon": "-81.03653"}
}
'
</pre>
</div>
</div>
</div>
<div id="outline-container-org429aaea" class="outline-2">
<h2 id="org429aaea">Run a query</h2>
<div class="outline-text-2" id="text-org429aaea">
<p>
Find all users located within a polygon.
</p>

<div class="org-src-container">
<pre class="src src-sh">curl -XGET 'http://localhost:9200/geotest/usergeo/_search?pretty=true' -d '
{
  "query": {
    "filtered" : {
        "query" : {
            "match_all" : {}
        },
       "filter" : {
            "geo_polygon" : {
                "location" : {
                    "points" : [
                        {"lat" : 30, "lon" : -70},
                        {"lat" : 30, "lon" : -80},
                        {"lat" : 40, "lon" : -80},
                        {"lat" : 40, "lon" : -70}
                    ]
                }
            }
        }
    }
  }
}
'
</pre>
</div>

<p>
You should see output similar to the following. As you can see, elasticsearch only returned the one user that was within the polygon.
</p>

<div class="org-src-container">
<pre class="src src-json">{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "geotest",
      "_type" : "usergeo",
      "_id" : "_R-YQd-eS-2vc3rBzhibAQ",
      "_score" : 1.0,
      "_source":
{
    "udid" : "foobar-udid",
    "location": {"lat": "38.897676", "lon": "-77.03653"}
}

    } ]
  }
}
</pre>
</div>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/elasticsearch/" class="tag" data-tag="elasticsearch" data-index="0">elasticsearch</a> </span></div>]]></description>
  <category><![CDATA[elasticsearch]]></category>
  <link>https://wtfleming.github.io/blog/elasticsearch-polygon/</link>
  <guid>https://wtfleming.github.io/blog/elasticsearch-polygon/</guid>
  <pubDate>Fri, 24 Oct 2014 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Clojure on the BeagleBone part 4 - Digital Input with ClojureScript]]></title>
  <description><![CDATA[
<div id="outline-container-org3d80d0d" class="outline-2">
<h2 id="org3d80d0d">Intro</h2>
<div class="outline-text-2" id="text-org3d80d0d">
<ul class="org-ul">
<li>In <a href="/blog/clojure-beaglebone-part-1-install-java-leiningen/">part 1</a> of this series we saw how to install Java and <a href="https://github.com/technomancy/leiningen">Leiningen</a> on a <a href="https://beagleboard.org/black">BeagleBone</a>.</li>
<li>In <a href="/blog/clojure-beaglebone-part-2-blink-led-clojure/">part 2</a> we used the BeagleBone to blink an LED on a breadboard using Clojure.</li>
<li>In <a href="/blog/clojure-beaglebone-part-3-blink-led-clojurescript/">part 3</a> we blinked an LED using ClojureScript.</li>
<li>In part 4 we read digital inputs via polling and interrupts.</li>
</ul>

<p>
The BeagleBone is a 1GHz ARM board with 512Mb of RAM capable of running Linux. The Debian image ships with node.js and a javascript library in [Bonescript][bonescript] for interacting with the hardware. Clojurescript provides a compiler for Clojure that targets Javascript, here we will use it to and two methods of reading digital input and light an LED on a breadboard using the BeagleBone GPIO.
</p>
</div>
</div>
<div id="outline-container-org7462e93" class="outline-2">
<h2 id="org7462e93">Reading from digital input via polling</h2>
<div class="outline-text-2" id="text-org7462e93">

<figure id="org028b2bc">
<img src="/images/beaglebone-cljs-digital-input-fritzing.png" alt="beaglebone-cljs-digital-input-fritzing.png">

</figure>

<hr>
</div>
</div>
<div id="outline-container-org9eeb2f2" class="outline-2">
<h2 id="org9eeb2f2">Wire up the LED circuit</h2>
<div class="outline-text-2" id="text-org9eeb2f2">
<ol class="org-ol">
<li>Using a jumper wire connect Pin 1 on Header P9 (ground) on the BeagleBone to the ground rail on the breadboard.</li>
<li>Place an LED in the breadboard.</li>
<li>Using a jumper wire connect the cathode (shorter) wire of the LED to the negative rail.</li>
<li>Connect one end of a 100 ohm resistor to the anode (longer) wire of the LED.</li>
<li>Using another jumper wire connect the other end of the resistor to Pin 14 on Header P8</li>
</ol>

<hr>
</div>
</div>
<div id="outline-container-org1dfe987" class="outline-2">
<h2 id="org1dfe987">Wire up the push button circuit</h2>
<div class="outline-text-2" id="text-org1dfe987">
<ol class="org-ol">
<li>Using a jumper wire connect Pin 3 on Header P9 (3.3 volts) on the BeagleBone to the positive rail on the breadboard.</li>
<li>Place a push button in the breadboard.</li>
<li>Using a jumper wire connect one lead of the push button to the positive rail.</li>
<li>Connect a 10K ohm pull down resistor to the negative rail and the button's other lead.</li>
<li>Using a jumper wire connect Pin 18 on Header P9 to the same button lead we connected the 10k resistor in step four.</li>
</ol>

<hr>

<p>
Note: The GPIO pins can only handle 3.3 volts, so be very careful that you do not accidentally connect a jumper to one of the 5 volt source pins. If you are unsure of what you are doing I would highly recommend reading the system reference manual to make sure you do not damage your board.
</p>

<hr>
</div>
</div>
<div id="outline-container-orgc41e00a" class="outline-2">
<h2 id="orgc41e00a">ClojureScript code</h2>
<div class="outline-text-2" id="text-orgc41e00a">
<p>
SSH into your BeagleBone and create a file named <i>project.clj</i> with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defproject cljs-beaglebone-digital-input "0.0.1"
  :description "Demonstrates reading digital inputs on a beaglebone"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :plugins [[lein-cljsbuild "1.0.3"]]
  :cljsbuild {
    :builds [{
        :source-paths ["src"]
        :compiler {
          :output-to "lib/digital-input.js"
          :optimizations :simple
          :target :nodejs
          :pretty-print true}}]}
  :dependencies [[org.clojure/clojurescript "0.0-2197"]])
</pre>
</div>

<p>
And create a file name <i>src/cljs<sub>digital</sub><sub>input</sub>/core.cljs</i> with these contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns cljs-digital-input.core
  (:require [cljs.nodejs :as nodejs]))

(def bone (nodejs/require "bonescript"))

; Bonescript identifiers related to pins
(def OUTPUT (aget bone "OUTPUT"))
(def INPUT (aget bone "INPUT"))

; Pins
(def led-pin "P8_14")            ; GPIO pin 14 on header P8
(def digital-input-pin "P8_18")  ; GPIO pin 18 on header P8

(defn setup-pins! []
  (.pinMode bone led-pin OUTPUT)
  (.pinMode bone digital-input-pin INPUT))

(defn read-input []
  "Reads state of the digital input pin then turns the LED on or off"
  (let [input-pin-state (.digitalRead bone digital-input-pin)]
    (.digitalWrite bone led-pin input-pin-state)))

(defn -main [&amp; args]
  (setup-pins!)
  (js/setInterval read-input 1)) ; poll every millisecond

(set! *main-cli-fn* -main)
</pre>
</div>

<p>
Now compile the clojurescript to javascript and run it on your BeagleBone.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ lein cljsbuild once
$ node lib/digital-input.js
</pre>
</div>

<p>
When you press the push button the LED should turn on, and when you release it will turn off.
</p>

<hr>
</div>
</div>
<div id="outline-container-org0d08f8c" class="outline-2">
<h2 id="org0d08f8c">Reading from digital input via interrupts</h2>
<div class="outline-text-2" id="text-org0d08f8c">
<p>
In the previous example we polled a pin once a millisecond to determine whether or not the push button was being pushed, an alternative is to use interrupts. We will use the same circuit that we wired up in the previous example. We now can be notified and react to an event (a button being pressed in this case) rather than continually having to check to see if something has happened. We use the [attachInterupt()][attach-interrupt] function bonescript provides.
</p>

<p>
On your BeagleBone and create a new directory and a file named <i>project.clj</i> with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defproject cljs-beaglebone-digital-input-interrupts "0.0.1"
  :description "Demonstrates reading digital inputs on a beaglebone"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :plugins [[lein-cljsbuild "1.0.3"]]
  :cljsbuild {
    :builds [{
        :source-paths ["src"]
        :compiler {
          :output-to "lib/digital-input-interrupts.js"
          :optimizations :simple
          :target :nodejs
          :pretty-print true}}]}
  :dependencies [[org.clojure/clojurescript "0.0-2197"]])
</pre>
</div>

<p>
And create a file name <i>src/cljs<sub>digital</sub><sub>input</sub><sub>interrupts</sub>/core.cljs</i> with these contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns cljs-digital-input-interrupts.core
  (:require [cljs.nodejs :as nodejs]))

(def bone (nodejs/require "bonescript"))

; Bonescript identifiers related to pins
(def OUTPUT (aget bone "OUTPUT"))
(def INPUT (aget bone "INPUT"))
(def HIGH (aget bone "HIGH"))
(def LOW (aget bone "LOW"))
(def CHANGE (aget bone "CHANGE"))

; Pins
(def led-pin "P8_14")            ; GPIO pin 14 on header P8
(def digital-input-pin "P8_18")  ; GPIO pin 18 on header P8

(defn setup-pins! []
  (.pinMode bone led-pin OUTPUT)
  (.pinMode bone digital-input-pin INPUT))

(defn button-callback [x]
  (if (= (.-value x) HIGH)
    (.digitalWrite bone led-pin HIGH)
    (.digitalWrite bone led-pin LOW)))

(defn do-nothing []
  "Does nothing"
  (do))

(defn -main [&amp; args]
  (setup-pins!)
  (.attachInterrupt bone digital-input-pin true CHANGE button-callback)

  ; Endlessly loop doing nothing but prevents node.js from exiting
  (js/setInterval do-nothing 1000))

(set! *main-cli-fn* -main)
</pre>
</div>

<p>
Now compile the clojurescript to javascript and run it on your BeagleBone.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ lein cljsbuild once
$ node lib/digital-input-interrupts.js
</pre>
</div>

<p>
Once again, when you press the push button the LED should turn on, and when you release it will turn off.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> <a href="https://wtfleming.github.io/tags/beaglebone/" class="tag" data-tag="beaglebone" data-index="1">beaglebone</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <category><![CDATA[beaglebone]]></category>
  <link>https://wtfleming.github.io/blog/clojure-beaglebone-part-4-digital-input-clojurescript/</link>
  <guid>https://wtfleming.github.io/blog/clojure-beaglebone-part-4-digital-input-clojurescript/</guid>
  <pubDate>Thu, 23 Oct 2014 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Clojure on the BeagleBone part 3 - Blinking an LED with ClojureScript]]></title>
  <description><![CDATA[
<div id="outline-container-org5dd0659" class="outline-2">
<h2 id="org5dd0659">Intro</h2>
<div class="outline-text-2" id="text-org5dd0659">
<ul class="org-ul">
<li>In <a href="/blog/clojure-beaglebone-part-1-install-java-leiningen/">part 1</a> of this series we saw how to install Java and <a href="https://github.com/technomancy/leiningen">Leiningen</a> on a <a href="https://beagleboard.org/black">BeagleBone</a>.</li>
<li>In <a href="/blog/clojure-beaglebone-part-2-blink-led-clojure/">part 2</a> we used the BeagleBone to blink an LED on a breadboard using Clojure.</li>
<li>In part 3 we will blink an LED using ClojureScript.</li>
<li>In <a href="/blog/clojure-beaglebone-part-4-digital-input-clojurescript/">part 4</a> we will read digital inputs via polling and interrupts.</li>
</ul>

<p>
The BeagleBone is a 1GHz ARM board with 512Mb of RAM capable of running Linux. The Debian image ships with node.js and a javascript library in <a href="https://beagleboard.org/Support/BoneScript">BoneScript</a> for interacting with the hardware. Clojurescript provides a compiler for Clojure that targets Javascript, here we will use it to blink an LED on a breadboard using the BeagleBone GPIO.
</p>
</div>
</div>
<div id="outline-container-org2901aa1" class="outline-2">
<h2 id="org2901aa1">Hello World with Clojurescript and node.js</h2>
<div class="outline-text-2" id="text-org2901aa1">
<p>
First we will ensure that ClojureScript and node.js are setup. Ensure you have followed the instructions in the first part of this series to install Leiningen.
</p>

<p>
SSH into your BeagleBone and create a file named <i>project.clj</i> with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defproject cljs-nodejs-hello-world "0.0.1"
  :description "Hello World example for clojurescript on node.js"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :plugins [[lein-cljsbuild "1.0.3"]]
  :cljsbuild {
    :builds [{
        :source-paths ["src"]
        :compiler {
          :output-to "lib/hello-world.js"
          :optimizations :simple
          :target :nodejs
          :pretty-print true}}]}
  :dependencies [[org.clojure/clojurescript "0.0-2197"]])
</pre>
</div>

<p>
And create a file name <i>src/cljs<sub>helloworld</sub>/core.cljs</i> with these contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns cljs-helloworld.core
  (:require [cljs.nodejs :as nodejs]))

(defn -main [&amp; args]
  (println (apply str (map [\space "world" "hello"] [2 0 1]))))

; Let println work
(nodejs/enable-util-print!)

; Tell node which function to use as main
(set! *main-cli-fn* -main)
</pre>
</div>

<p>
Now compile the clojurescript to javascript and run it on your BeagleBone.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ lein cljsbuild once
$ node lib/hello-world.js
</pre>
</div>

<p>
You should see hello world output.
</p>
</div>
</div>
<div id="outline-container-org2063a81" class="outline-2">
<h2 id="org2063a81">Blinking an LED</h2>
<div class="outline-text-2" id="text-org2063a81">
<p>
This is inspired by an example from the excellent book [Getting Started With BeagleBone][beaglebone-book] by [Matt Richardson][matt-richardson].
</p>


<figure id="org958a3a4">
<img src="/images/beaglebone-clojure-blink-led-fritzing.png" alt="beaglebone-clojure-blink-led-fritzing.png">

</figure>

<p>
Schematic above was generated using the open source <a href="https://fritzing.org/home/">Fritzing</a>.
</p>

<hr>

<p>
Note: The GPIO pins can only handle 3.3 volts, so be very careful that you do not accidentally connect a jumper to one of the 5 volt source pins. If you are unsure of what you are doing I would highly recommend reading the system reference manual to make sure you do not damage your board.
</p>

<hr>
</div>
</div>
<div id="outline-container-orgf19c7b6" class="outline-2">
<h2 id="orgf19c7b6">Wire up the LED</h2>
<div class="outline-text-2" id="text-orgf19c7b6">
<ol class="org-ol">
<li>Using a jumper wire connect Pin 2 on Header P9 (ground) on the BeagleBone to the negative rail on the breadboard.</li>
<li>Place an LED in the breadboard.</li>
<li>Using a jumper wire connect the cathode (shorter) wire of the LED to the negative rail.</li>
<li>Connect one end of a 100 ohm resistor to the anode (longer) wire of the LED.</li>
<li>Using another jumper wire connect the other end of the resistor to Pin 13 on Header P8</li>
</ol>

<p>
Now we are ready to write the code.
</p>
</div>
</div>
<div id="outline-container-org2f0369f" class="outline-2">
<h2 id="org2f0369f">ClojureScript code</h2>
<div class="outline-text-2" id="text-org2f0369f">
<p>
SSH into your BeagleBone and create a file named <i>project.clj</i> with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defproject cljs-beaglebone-blink-led "0.0.1"
  :description "Hello World example for clojurescript on node.js"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :plugins [[lein-cljsbuild "1.0.3"]]
  :cljsbuild {
    :builds [{
        :source-paths ["src"]
        :compiler {
          :output-to "lib/blink.js"
          :optimizations :simple
          :target :nodejs
          :pretty-print true}}]}
  :dependencies [[org.clojure/clojurescript "0.0-2197"]])
</pre>
</div>

<p>
And create a file named <i>src/cljs<sub>blink</sub><sub>led</sub>/core.cljs</i> with these contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns cljs-blink-led.core
  (:require [cljs.nodejs :as nodejs]))

(def bone (nodejs/require "bonescript"))

; Bonescript identifiers related to pins
(def OUTPUT (aget bone "OUTPUT"))
(def HIGH (aget bone "HIGH"))
(def LOW (aget bone "LOW"))

; LEDs
(def led-pin "P8_13")    ; GPIO pin 13 on header P8
(def onboard-led "USR3") ; One of the onboard LEDs

; State of our LEDs
(def led-pin-state (atom LOW))

; Set both pins as an output
(defn setup-pins []
  (.pinMode bone led-pin OUTPUT)
  (.pinMode bone onboard-led OUTPUT))

(defn toggle-digital-pin-state []
  (if (= @led-pin-state HIGH)
    (reset! led-pin-state LOW)
    (reset! led-pin-state HIGH)))

(defn blink-leds []
  (toggle-digital-pin-state)
  (.digitalWrite bone led-pin @led-pin-state)
  (.digitalWrite bone onboard-led @led-pin-state))

(defn -main [&amp; args]
  (setup-pins)
  (js/setInterval blink-leds 1000))

(set! *main-cli-fn* -main)
</pre>
</div>

<p>
Now compile the clojurescript to javascript and run it on your BeagleBone.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ lein cljsbuild once
$ node lib/blink.js
</pre>
</div>

<p>
Your LED should now blink on and off every second.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> <a href="https://wtfleming.github.io/tags/beaglebone/" class="tag" data-tag="beaglebone" data-index="1">beaglebone</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <category><![CDATA[beaglebone]]></category>
  <link>https://wtfleming.github.io/blog/clojure-beaglebone-part-3-blink-led-clojurescript/</link>
  <guid>https://wtfleming.github.io/blog/clojure-beaglebone-part-3-blink-led-clojurescript/</guid>
  <pubDate>Mon, 14 Jul 2014 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Clojure on the BeagleBone part 2 - Blinking an LED with Clojure]]></title>
  <description><![CDATA[
<div id="outline-container-orga0e9e36" class="outline-2">
<h2 id="orga0e9e36">Intro</h2>
<div class="outline-text-2" id="text-orga0e9e36">
<ul class="org-ul">
<li>In <a href="/blog/clojure-beaglebone-part-1-install-java-leiningen/">part 1</a> of this series we saw how to install Java and <a href="https://github.com/technomancy/leiningen">Leiningen</a> on a <a href="https://beagleboard.org/black">BeagleBone</a>.</li>
<li>In part 2 we use the BeagleBone to blink an LED on a breadboard using Clojure.</li>
<li>In <a href="/blog/clojure-beaglebone-part-3-blink-led-clojurescript/">part 3</a> we will blink an LED using ClojureScript.</li>
<li>In <a href="/blog/clojure-beaglebone-part-4-digital-input-clojurescript/">part 4</a> we will read digital inputs via polling and interrupts.</li>
</ul>

<p>
This is inspired by an example from the excellent book <a href="https://www.amazon.com/gp/product/1449345379/">Getting Started With BeagleBone</a> by <a href="https://mattrichardson.com/">Matt Richardson</a>.
</p>


<figure id="orgdac0936">
<img src="/images/beaglebone-clojure-blink-led-fritzing.png" alt="beaglebone-clojure-blink-led-fritzing.png">

</figure>

<p>
Schematic above was generated using the open source <a href="https://fritzing.org/home/">Fritzing</a>.
</p>

<hr>

<p>
Note: The GPIO pins can only handle 3.3 volts, so be very careful that you do not accidentally connect a jumper to one of the 5 volt source pins. If you are unsure of what you are doing I would highly recommend reading the system reference manual to make sure you do not damage your board.
</p>

<hr>
</div>
</div>
<div id="outline-container-orgb96b218" class="outline-2">
<h2 id="orgb96b218">Wire up the LED</h2>
<div class="outline-text-2" id="text-orgb96b218">
<ol class="org-ol">
<li>Using a jumper wire connect Pin 2 on Header P9 (ground) on the BeagleBone to the negative rail on the breadboard.</li>
<li>Place an LED in the breadboard.</li>
<li>Using a jumper wire connect the cathode (shorter) wire of the LED to the negative rail.</li>
<li>Connect one end of a 100 ohm resistor to the anode (longer) wire of the LED.</li>
<li>Using another jumper wire connect the other end of the resistor to Pin 13 on Header P8</li>
</ol>
</div>
</div>
<div id="outline-container-orgd70b0d4" class="outline-2">
<h2 id="orgd70b0d4">Clojure code</h2>
<div class="outline-text-2" id="text-orgd70b0d4">
<p>
SSH into your BeagleBone and create a file named <i>project.clj</i> with the following contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defproject clj-blink-led "0.1.0"
  :description "Blink a LED on a BeagleBone"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]]
  :main clj-blink-led.core)
</pre>
</div>

<p>
And create a file name <i>src/clj<sub>blink</sub><sub>led</sub>/core.clj</i> with these contents:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns clj-blink-led.core
  (:require [clojure.java.io :as io]))

(defn write-to-filesystem
  "Helper function for setting pins"
  [location val]
  (with-open [f (io/output-stream location)]
    (.write f (.getBytes val))))

(defn cleanup
  "Tidy up when a user presses Ctrl-C to exit"
  []
  (println "Shutting down...")
  (write-to-filesystem "/sys/class/gpio/unexport" "23"))

(defn setup
  "Export pin and set the direction"
  []
  (.addShutdownHook (Runtime/getRuntime) (Thread. cleanup))
  (write-to-filesystem "/sys/class/gpio/export" "23")
  (write-to-filesystem "/sys/class/gpio/gpio23/direction" "out"))

; Pin states
(def HIGH "1")
(def LOW "0")

(defn -main []
  (println "Blinking LED, press Ctrl-C to exit")
  (setup)
  (loop [pin-state HIGH]
    (write-to-filesystem "/sys/class/gpio/gpio23/value" pin-state)
    (Thread/sleep 1000)
    (recur (if (= pin-state HIGH) LOW HIGH))))
</pre>
</div>

<p>
Now run it on your BeagleBone as the root user.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ lein run
</pre>
</div>

<p>
Your LED should now blink on and off every second.
</p>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> <a href="https://wtfleming.github.io/tags/beaglebone/" class="tag" data-tag="beaglebone" data-index="1">beaglebone</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <category><![CDATA[beaglebone]]></category>
  <link>https://wtfleming.github.io/blog/clojure-beaglebone-part-2-blink-led-clojure/</link>
  <guid>https://wtfleming.github.io/blog/clojure-beaglebone-part-2-blink-led-clojure/</guid>
  <pubDate>Sun, 25 May 2014 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Clojure on the BeagleBone part 1 - Installing Java, Leiningen, and Emacs 24]]></title>
  <description><![CDATA[
<div id="outline-container-org7cf3f95" class="outline-2">
<h2 id="org7cf3f95">Intro</h2>
<div class="outline-text-2" id="text-org7cf3f95">
<ul class="org-ul">
<li>In part 1 of this series we see how to install Java and <a href="https://github.com/technomancy/leiningen">Leiningen</a> on a <a href="https://beagleboard.org/black">BeagleBone</a>.</li>
<li>In <a href="/blog/clojure-beaglebone-part-2-blink-led-clojure/">part 2</a> we use the BeagleBone to blink an LED on a breadboard using <a href="https://clojure.org/">Clojure</a>.</li>
<li>In <a href="/blog/clojure-beaglebone-part-3-blink-led-clojurescript/">part 3</a> we will blink an LED using <a href="https://github.com/clojure/clojurescript">ClojureScript</a>.</li>
<li>In <a href="/blog/clojure-beaglebone-part-4-digital-input-clojurescript/">part 4</a> we will read digital inputs via polling and interrupts.</li>
</ul>

<p>
The <a href="https://beagleboard.org/black">BeagleBone</a> is a small and low cost ($55) 1Ghz ARM board with 512Mb of RAM capable of running Linux.
</p>


<figure id="orged82f7f">
<img src="/images/beagleboneblack.jpg" alt="beagleboneblack.jpg">

</figure>

<p>
These instructions assume that you are using Debian 2014-05-14 as the root user. You can obtain the latest versions of Debian and Angstrom <a href="https://beagleboard.org/latest-images">here</a>.
</p>

<p>
If you are using a different operating system or version you may need to make some changes.
</p>
</div>
</div>
<div id="outline-container-org8087b74" class="outline-2">
<h2 id="org8087b74">Java</h2>
<div class="outline-text-2" id="text-org8087b74">
<p>
I started with the <a href="https://beagleboard.org/project/java/">BeagleBone Oracle JDK instructions</a>, but needed to make some changes (for instance because I am using Debian I can use "hard float" JDK - however if you are using Angstrom Linux you may need the "soft float" version - or you may want to use Java 8 instead).
</p>

<p>
SSH into your BeagleBone and do the following:
</p>

<div class="org-src-container">
<pre class="src src-sh"># You must accept the Oracle Binary Code License Agreement for Java SE.
# The license and download links are available at:
# http://www.oracle.com/technetwork/java/javase/downloads/jdk7-arm-downloads-2187468.html
# You can accept the license via wget like this:
$ wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/7u55-b13/jdk-7u55-linux-arm-vfp-hflt.tar.gz
$ tar xzf jdk-7u55-linux-arm-vfp-hflt.tar.gz
$ export PATH=$PATH:/root/jdk1.7.0_55/bin
$ export JAVA_HOME=/root/jdk1.7.0_55
$ java -version
java version "1.7.0_55"
Java(TM) SE Runtime Environment (build 1.7.0_55-b13)
Java HotSpot(TM) Client VM (build 24.55-b03, mixed mode)
</pre>
</div>

<p>
You will want to store all the exports from this post in your .bashrc so you do not need to type them in every time you log in.
</p>
</div>
</div>
<div id="outline-container-org3b3d7c8" class="outline-2">
<h2 id="org3b3d7c8">Leiningen</h2>
<div class="outline-text-2" id="text-org3b3d7c8">
<p>
Install following the <a href="https://github.com/technomancy/leiningen">installation instructions here</a>:
</p>

<div class="org-src-container">
<pre class="src src-sh">$ mkdir bin
$ cd bin
$ wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein
$ chmod 755 lein
$ export PATH=$PATH:/root/bin

# Generally you do not want to run as root, but since we will want access
# to the GPIO pins it is easier to develop on a BeagleBone as root.
# Turn off leiningen's warning about running as root.
$ export LEIN_ROOT=1
</pre>
</div>

<p>
Now lets fire up a REPL and make sure it works.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ lein repl
user=&gt; (println "Hello BeagleBone!")
Hello BeagleBone
nil
</pre>
</div>
</div>
</div>
<div id="outline-container-org85bde02" class="outline-2">
<h2 id="org85bde02">Emacs 24.4</h2>
<div class="outline-text-2" id="text-org85bde02">
<p>
The latest version of Emacs in the Debian package list is 23, here is how to download and install 24.4. Note that generally you will be happier running Emacs on you laptop/desktop and using tramp-mode to edit files from there.
</p>

<p>
Run the following on your BeagleBone and go get a cup of coffee, it will take at least an hour.
</p>

<div class="org-src-container">
<pre class="src src-sh">$ apt-get install build-essential libncurses5-dev
$ wget http://ftp.gnu.org/gnu/emacs/emacs-24.4.tar.gz
$ tar xzvf emacs-24.4.tar.gz
$ cd emacs-24.4
$ ./configure --with-xpm=no --with-gif=no --without-x
$ make
$ make install
</pre>
</div>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/clojure/" class="tag" data-tag="clojure" data-index="0">clojure</a> <a href="https://wtfleming.github.io/tags/beaglebone/" class="tag" data-tag="beaglebone" data-index="1">beaglebone</a> </span></div>]]></description>
  <category><![CDATA[clojure]]></category>
  <category><![CDATA[beaglebone]]></category>
  <link>https://wtfleming.github.io/blog/clojure-beaglebone-part-1-install-java-leiningen/</link>
  <guid>https://wtfleming.github.io/blog/clojure-beaglebone-part-1-install-java-leiningen/</guid>
  <pubDate>Sat, 24 May 2014 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Blinking an LED with the MSP430]]></title>
  <description><![CDATA[
<hr>

<p>
I recently bought a <a href="http://processors.wiki.ti.com/index.php/MSP430_LaunchPad">MSP430 Launchpad</a> from Texas Instruments. The <a href="http://en.wikipedia.org/wiki/TI_MSP430">MSP430</a> is a family of low power, low cost microcontrollers. To make sure my development environment was setup correctly I wanted to start with one of the simplest things to do, blink a LED.
</p>


<figure id="orgb389f3f">
<img src="/images/msp430-led-blink.jpg" alt="msp430-led-blink.jpg">

</figure>

<p>
I have a wire connected to P1.0, another connected to GND, a 180 ohm resistor, and an LED 180 Ohm resistor. The code is compiled with GCC.
</p>

<p>
blink.c
</p>

<div class="org-src-container">
<pre class="src src-c">#include &lt;msp430.h&gt;

int main(void) {
  WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
  P1DIR = 0x01; // Set pin to output, 0b00000001

  for (;;) {
    volatile unsigned int i;
    P1OUT ^= 0x01; // toggle LED1 (P1.0) on/off, 0b00000001
    i = 50000;
    do (i--);
    while (i != 0);
  }
}
</pre>
</div>

<hr>

<p>
Makefile
</p>

<pre class="example" id="org3726511">
CC=msp430-gcc
CFLAGS=-Os -Wall -g -mmcu=msp430g2553

OBJS=main.o

all: $(OBJS)
        $(CC) $(CFLAGS) -o main.elf $(OBJS)

%.o: %.c
        $(CC) $(CFLAGS) -c $&lt;

clean:
        rm -fr main.elf $(OBJS)
</pre>

<p>
We build, then use <a href="http://mspdebug.sourceforge.net/">mspdebug</a> to load the program onto the chip from the command line.
</p>

<pre class="example" id="orga309b1d">
$ make
$ mspdebug rf2500
(mspdebug) prog main.elf
Erasing...
Programming...
Writing  108 bytes at c000 [section: .text]...
Writing   32 bytes at ffe0 [section: .vectors]...
Done, 140 bytes total
(mspdebug) exit
</pre>

<p>
Now we have a LED blinking.
</p>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/msp430/" class="tag" data-tag="msp430" data-index="0">msp430</a> </span></div>]]></description>
  <category><![CDATA[msp430]]></category>
  <link>https://wtfleming.github.io/blog/msp430-blink/</link>
  <guid>https://wtfleming.github.io/blog/msp430-blink/</guid>
  <pubDate>Wed, 06 Nov 2013 00:00:00 +0000</pubDate>
</item>
<item>
  <title><![CDATA[Querying Stack Exchange database dumps with Cascalog]]></title>
  <description><![CDATA[
<hr>

<p>
<a href="https://github.com/nathanmarz/cascalog">Cascalog</a> is a fully-featured data processing and querying library for Clojure. The main use cases for Cascalog are processing Big Data on top of Hadoop or doing analysis on your local computer from the Clojure REPL. Cascalog is a replacement for tools like Pig, Hive, and Cascading.
</p>

<hr>

<p>
We will use Cascalog to run some basic queries on the <a href="http://gaming.stackexchange.com">Arqade</a> Stack Exchange site database dump. Arqade is a website dedicated to video game questions and answers.
</p>

<p>
Every 3 months the team at <a href="http://stackexchange.com">Stack Exchange</a> provides an <a href="https://archive.org/details/stackexchange">data dump</a> of all creative commons licensed questions and answers from network of websites (the largest of which being <a href="http://stackoverflow.com">Stack Overflow</a>.
</p>
<div id="outline-container-org842d4fb" class="outline-3">
<h3 id="org842d4fb">Getting Started</h3>
<div class="outline-text-3" id="text-org842d4fb">
<p>
The code and data for this post is available <a href="https://github.com/wtfleming/wtfleming.github.io/tree/master/code/cascalog-stack-exchange">here</a>. The relevant file is <i>queries.clj</i>.
</p>

<p>
I encourage you to follow along in a REPL. Run the commands that begin with:
</p>

<pre class="example" id="org024e039">
user=&gt;
</pre>

<p>
Fire up a <a href="https://github.com/technomancy/leiningen">leiningen</a> REPL in the project's directory and switch to the demo namespace:
</p>

<pre class="example" id="orgded143e">
user=&gt; (use 'cascalog_stack_exchange.queries)
</pre>

<p>
At the start of the <i>queries.clj</i> we have pulled in the following:
</p>

<div class="org-src-container">
<pre class="src src-clojure">(ns cascalog_stack_exchange.queries
  (:use cascalog.api)
  (:require [cascalog.ops :as ops]
            [clojure.data.xml :as xml]
            [clojure.string :as str]))
</pre>
</div>

<p>
This provides everything we will need to run the queries.
</p>
</div>
</div>
<div id="outline-container-org4e9d449" class="outline-2">
<h2 id="org4e9d449">Parsing the XML</h2>
<div class="outline-text-2" id="text-org4e9d449">
<p>
In <i>queries.clj</i> we have defined a function that will parse a line of XML representing a user, and extract the user id, display name, and reputation.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defmapop user-xml-parser [user-xml]
  "Parse a line of xml representing a stack exchange user."
  (try
    (let [user (xml/parse-str user-xml)
          {{:keys [Id DisplayName Reputation]} :attrs} user]
      [Id DisplayName (Integer/parseInt Reputation)])
    (catch Exception _ [nil nil nil])))
</pre>
</div>

<p>
It takes input that looks like this
</p>

<div class="org-src-container">
<pre class="src src-xml">&lt;row Id="3" Reputation="3272" CreationDate="2010-07-07T16:10:54.360"
DisplayName="David Fullerton" LastAccessDate="2013-06-02T00:58:32.237"
WebsiteUrl="http://careers.stackoverflow.com/dfullerton" Location="New York, NY"
AboutMe="&amp;lt;p&amp;gt;Stack Exchange &amp;lt;a href=&amp;quot;http://meta.stackoverflow.com/
a/121542/146719&amp;quot;&amp;gt;VP of Engineering&amp;lt;/a&amp;gt;.&amp;lt;/p&amp;gt;&amp;#xA;&amp;#xA;&amp;lt;p&amp;gt;"
Views="106" UpVotes="2163" DownVotes="18" Age="28"
EmailHash="7ec7e363b18de72c5ac1f3931b9d56ba" /&gt;
</pre>
</div>

<p>
and returns
</p>

<div class="org-src-container">
<pre class="src src-clojure">["3" "David Fullerton" 3272]
</pre>
</div>
</div>
<div id="outline-container-orgb4a9727" class="outline-3">
<h3 id="orgb4a9727">Querying Users</h3>
<div class="outline-text-3" id="text-orgb4a9727">
<p>
Our first query will iterate over all lines in the file storing user information. Extract their id, reputation score. And finally output the results to standard out.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn user-query
  "Run a query that outputs user id, reputation, and display name."
  []
  (let [file-tap (hfs-textline "data/users.xml")]
    (?&lt;-
      (stdout)
      [?id ?reputation ?display-name]
      (file-tap ?line)
      (user-xml-parser ?line :&gt; ?id ?display-name ?reputation))))
</pre>
</div>

<ol class="org-ol">
<li>Indicate that this is a Cascalog query which will run immediately.</li>
</ol>

<pre class="example" id="org196639f">
?&lt;-
</pre>

<ol class="org-ol">
<li value="2">Specify that the results will written to standard out. It is possible to store the output in any format and wherever you want (HDFS, a relational database, Amazon S3, etc.). But for simplicity we will just be using stdout in these examples.</li>
</ol>

<pre class="example" id="org57a689b">
(stdout)
</pre>

<ol class="org-ol">
<li value="3">Tell Cascalog that we want to output the <i>?id</i> <i>?reputation?</i> and <i>?display-name</i> variables.</li>
</ol>

<pre class="example" id="org434b9d8">
[?id ?reputation ?display-name]
</pre>

<ol class="org-ol">
<li value="4">We earlier defined <i>file-tap</i> as a generator for each line of text in the file <i>data/users.xml</i>. We put each of them in <i>?line</i> variable.</li>
</ol>

<pre class="example" id="org612525c">
(file-tap ?line)
</pre>

<ol class="org-ol">
<li value="5">Parse each line and use the :&gt; keyword to bind them to the variables <i>?id</i>, <i>?display-name</i>, and <i>?reputation</i>.</li>
</ol>

<pre class="example" id="orgf35d3a5">
(user-xml-parser ?line :&gt; ?id ?display-name ?reputation)
</pre>

<p>
Now lets run the query, and look at the output:
</p>

<pre class="example" id="orgee91cf0">
user=&gt; (user-query)
RESULTS
-----------------------
3       3272    David Fullerton
4       101     Robert Cartaino
5       238     Jin
-----------------------
</pre>
</div>
</div>
<div id="outline-container-org1c44f54" class="outline-3">
<h3 id="org1c44f54">Query with a filter</h3>
<div class="outline-text-3" id="text-org1c44f54">
<p>
We will now run a similar query, but this time we want to only include users with more than 200 reputation.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn user-minimum-reputation-query
  "Run a query showing users with a reputation greater than 200."
  []
  (let [file-tap (hfs-textline "data/users.xml")]
    (?&lt;- 
      (stdout)
      [?display-name ?reputation]
      (file-tap ?line)
      (user-xml-parser ?line :&gt; _ ?display-name ?reputation)
      (&gt; ?reputation 200))))
</pre>
</div>

<p>
Running gives us:
</p>

<pre class="example" id="org72af502">
user=&gt; (user-minimum-reputation-query)
RESULTS
-----------------------
David Fullerton 3272
Jin     238
-----------------------
</pre>
</div>
</div>
<div id="outline-container-orgce787a0" class="outline-3">
<h3 id="orgce787a0">Counting with built in operations</h3>
<div class="outline-text-3" id="text-orgce787a0">
<p>
Cascalog provides a number of <a href="https://github.com/nathanmarz/cascalog/wiki/Built-in-operations">built in operations</a>. Here we want to know the total number of users with a reputation greater than 200.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn user-minimum-reputation-count-query
  "Run a query counting the number of users with a reputation greater than 200."
  []
  (let [file-tap (hfs-textline "data/users.xml")]
    (?&lt;- 
      (stdout)
      [?count]
      (file-tap ?line)
      (user-xml-parser ?line :&gt; _ ?display-name ?reputation)
      (&gt; ?reputation 200)
      (ops/count :&gt; ?count))))
</pre>
</div>

<p>
Everything looks good:
</p>

<pre class="example" id="orgb1474a8">
user=&gt; (user-minimum-reputation-count-query)
RESULTS
-----------------------
2
-----------------------
</pre>
</div>
</div>
<div id="outline-container-orga4382cd" class="outline-3">
<h3 id="orga4382cd">Querying Posts</h3>
<div class="outline-text-3" id="text-orga4382cd">
<p>
Once again we need to define a function to parse XML, this time for a post (a question or answer).
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defmapop post-xml-parser [post-xml]
  "Parse a line of xml representing a stack exchange post."
  (try
    (let [post (xml/parse-str post-xml)
          {{:keys [OwnerUserId PostTypeId Tags]} :attrs} post]
      [OwnerUserId PostTypeId Tags])
    (catch Exception _ [nil nil nil])))
</pre>
</div>

<p>
The following query is very similar to the user-query above. But note that in this case we are using <i>!tags</i> rather than <i>?tags</i>. Variables beginning with a ? are non-nullable, Cascalog will filter out any records in which a non-nullable is bound to null.
</p>

<p>
Variables beginning with ! are nullable and will not be filtered out. Here we are demonstrating that posts with a post-type-id are answers, and do not contain tags. If you wanted to know which tags are associated with the answer it is possible to join on the answer's parent id.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn post-query
  "Run a query that outputs post owner-id, type-id, and tags"
  []
  (let [file-tap (hfs-textline "data/posts.xml")]
    (?&lt;-
     (stdout)
     [?owner-user-id ?post-type-id !tags]
     (file-tap ?line)
     (post-xml-parser ?line :&gt; ?owner-user-id ?post-type-id !tags))))
</pre>
</div>

<p>
Running the query this is what we should see:
</p>

<pre class="example" id="org894b95b">
user=&gt; (post-query)
RESULTS
-----------------------
4       1       &lt;team-fortress-2&gt;
3       1       &lt;steam&gt;&lt;hosting&gt;&lt;source-engine&gt;
3       1       &lt;monkey-island&gt;&lt;steam&gt;
4       2       null
5       1       &lt;world-of-warcraft&gt;
4       2       null
-----------------------
</pre>
</div>
<div id="outline-container-org52ccab1" class="outline-4">
<h4 id="org52ccab1">Aggregating Tags</h4>
<div class="outline-text-4" id="text-org52ccab1">
<p>
If we wanted to see all the tags used by each user we can run a query like this.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defbufferop aggregate-tags
  "Function to combine string containing tags"
  [tuples]
  [(reduce str (map first tuples))])

(defn post-aggregate-query
  "Run a query to get a list of all tags by each user"
  []
  (let [file-tap (hfs-textline "data/posts.xml")]
    (?&lt;-
     (stdout)
     [?owner-user-id ?tags]
     (file-tap ?line)
     (post-xml-parser ?line :&gt; ?owner-user-id _ ?tags1)
     (aggregate-tags ?tags1 :&gt; ?tags))))
</pre>
</div>

<p>
Which will output:
</p>

<pre class="example" id="orgec2be1a">
user=&gt; (post-aggregate-query)
RESULTS
-----------------------
3       &lt;steam&gt;&lt;hosting&gt;&lt;source-engine&gt;&lt;monkey-island&gt;&lt;steam&gt;
4       &lt;team-fortress-2&gt;
5       &lt;world-of-warcraft&gt;
-----------------------
</pre>
</div>
</div>
<div id="outline-container-orge8139a4" class="outline-4">
<h4 id="orge8139a4">Joining users and posts</h4>
<div class="outline-text-4" id="text-orge8139a4">
<p>
We will now combine what we have learnt to create a query that will output the display name and list of tags used by users with more than 200 reputation.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(defn user-tags-join-query
  "Run a query on users and posts that joins on user id and output user
  display name and tags by all users with more than 200 reputation."
  []
  (let [users-tap (hfs-textline "data/users.xml")
        posts-tap (hfs-textline "data/posts.xml")]

    (?&lt;-
     (stdout)
     [?display-name ?tags]

     (posts-tap ?posts-line)
     (post-xml-parser ?posts-line :&gt; ?user-id _ ?raw-tags)
     (aggregate-tags ?raw-tags :&gt; ?tags)

     (users-tap ?users-line)
     (user-xml-parser ?users-line :&gt; ?user-id ?display-name ?reputation)
     (&gt; ?reputation 200))))
</pre>
</div>

<p>
Since display name is stored in users.xml and the questions are in posts.xml, we will need to join on user id, since that is in both files.
</p>

<p>
In the following code posts-line and users-line are from two different sources of data. Since they are both binding to a variable <i>?user-id</i>, behind the scenes Cascalog will using a join to resolve the query.
</p>

<div class="org-src-container">
<pre class="src src-clojure">(post-xml-parser ?posts-line :&gt; ?user-id _ ?raw-tags)
(user-xml-parser ?users-line :&gt; ?user-id ?display-name ?reputation)
</pre>
</div>

<p>
We can now run the query, and everything looks good:
</p>

<pre class="example" id="org46d78d2">
user=&gt; (user-tags-join-query)
RESULTS
-----------------------
David Fullerton &lt;steam&gt;&lt;hosting&gt;&lt;source-engine&gt;&lt;monkey-island&gt;&lt;steam&gt;
Jin     &lt;world-of-warcraft&gt;
-----------------------
</pre>
</div>
</div>
</div>
</div>
<div class="taglist"><a href="https://wtfleming.github.io/tags/"><span class="tag-label">Tags</span></a><span class="tag-separator">: </span><span class="taglist__tags"><a href="https://wtfleming.github.io/tags/cascalog/" class="tag" data-tag="cascalog" data-index="0">cascalog</a> </span></div>]]></description>
  <category><![CDATA[cascalog]]></category>
  <link>https://wtfleming.github.io/blog/cascalog-stack-exchange/</link>
  <guid>https://wtfleming.github.io/blog/cascalog-stack-exchange/</guid>
  <pubDate>Sun, 11 Aug 2013 00:00:00 +0000</pubDate>
</item>
</channel>
</rss>
