For today I had very low expectations as I am travelling. The goal was to read some of Chapter 7 (which covers the way a Clojure project is structured -- it's called logistics for a reason). It's a long one too so the expectation is not to finish it. I expect to take very little notes as it is more akin to discover how the projects are structured, rather than learn anything.
I tagged along this chapter by creating a new folder ./code/cftgu-chapter7/
.
A namespace is set like this (ns namespace-name.core)
. This will dictate how to retrieve symbols. A symbol is always accessible by prepending the namespace name as well: (namespace-name/foo)
.
Note that namespaces automatically include clojure.core
which includes all the standard functions.
To set a namespace and include another one as well one can use (ns user (:require [scratch.core]))
. It means that the user namespace needs access to scratch.core
. It's also possible to give a shortname to an imported namespace like this (**ns **user (:require [scratch.core :as c]))
. It's even possible to avoid writing the namespace entirely for a specific function by importing it like this (ns user (:require [scratch.core :refer [foo]]))
: foo
will be accessible without the namespace.
To explore JSON in Clojure we use a library called Cheshire that we get from the NPM of Clojure, Clojars. We just need to add it to the dependencies in project.clj
.
user=> (use 'cheshire.core)
user=> (first (parse-string (slurp "2008.json") true))
{:robbery 22,
:aggravated_assaults 33,
:coverage_indicator 97,
:drug_abuse_violationstotal 203,```
So we got this array of objects and they all have the same properties. We can get the values of all of the same keyword:
```clojure
user=> (->> data (map :driving_under_influence))
(198
1095
114
98
...)
To get the max user=> (->> data (map :driving_under_influence) (apply max))
, or to get the n largest (10):
user=> (->> data (map :driving_under_influence) sort (take-last 10))
(8589 10432 10443 10814 11439 13983 17572 18562 26235 45056)
To get the frequencies, user=> (->> data (map :driving_under_influence) frequencies)
.
To produce some sort of histogram:
user=> (->> data (map :driving_under_influence) frequencies (sort-by key) pprint)
([0 227]
[1 24]
[2 17]
[3 20]
It means that 227 counties report no DIUs.
We can "zoom out" of the data set and see the other key values too:
user=> (->> data (sort-by :driving_under_influence) (take-last 10) pprint)
({:other_assaults 3096,
:gambling_all_other 3,
:arson 106,
:have_stolen_property 698,
We use mapcat
to map and concatenate at the same time.
:auto_thefts :bookmaking_horsesport :burglary :county_population
:coverage_indicator :curfew_loitering_laws :disorderly_conduct
We can extract several keywords at the same time:
user=> (->> data (sort-by :driving_under_influence) (take-last 10) (map #(select-keys % [:driving_under_influence :fips_county_code :fips_state_code])) pprint)
({:fips_state_code "06",
:fips_county_code "067",
:driving_under_influence 8589}
{:fips_state_code "48",
:fips_county_code "201",
:driving_under_influence 10432}
Today I learned the basics of setting up a Clojure project, how namespaces work and the basics of Clojure testing. Nothing very complicated which was perfect for today. I am glad we covered tests (I don't like writing them, at all, but they serve a purpose).
Also got an introduction of how to process JSON and extract the relevant information. I'm looking forward to finishing this chapter tomorrow.
Let's end the day with a tally of what I completed:
- More than half of Chapter 7 of Clojure From the Ground Up
- Setting up a dummy project