SlideShare uma empresa Scribd logo
1 de 128
Baixar para ler offline
Sentiment Analysis of 
the Twittersphere 
@APassionForCode
Leiningen Versus the Ants! 
Clojure Versus Java! 
FP Versus OOP
Apache Ant 
Leiningen Versus the Ants! 
Clojure Versus Java! 
FP Versus OOP
Apache Ant 
Leiningen Versus the Ants 
Clojure Versus Java! 
FP Versus OOP
Apache Ant 
Leiningen Versus the Ants 
Clojure Versus Java 
Functional Versus Object Oriented
“You wanted a banana but what you got was a 
gorilla holding the banana and the entire jungle.” 
Joe Armstrong - inventor of Erlang
“Sometimes, the elegant implementation is just 
a function. Not a method. Not a class. Not a 
framework. Just a function.” 
John Carmack - Lead on Doom, Quake, Rage
Blood aches pain 
sick shivers spasm 
vomit dizzy fainting 
colic and in a 
coma! 
1 FAVORITE
Blood aches pain 
sick shivers spasm 
vomit dizzy fainting 
colic and in a 
coma! 
1 FAVORITE 
Scores HIGH for flu symptoms
Blood aches pain 
sick shivers spasm 
vomit dizzy fainting 
colic and in a 
coma! 
1 FAVORITE 
Who is Catalina Rubottom?
Blood aches pain 
sick shivers spasm 
vomit dizzy fainting 
colic and in a 
coma! 
1 FAVORITE 
30 million geo-tagged 
tweets sent from UK 
HDFS/Hadoop 
Mongo/Aggregation 
Mongo/MapReduce 
Postgres
How can we do fast, real time analytics of 
social media?
Store t his! 
Not this!
WARNING! 
You’re about to see real Clojure code!
increment (1)
(increment 1)
increment (1)
(increment 1) 
Co ng ratu lat io ns - yo u’re no w fu lly qualifie d!
ptaoussanis/carmine
(:require 
[taoensso.carmine :as car]) 
! 
! 
(defn create-tweet-id [] 
(first 
(wcar* 
(car/incr "global:tweet.id")))) 
! 
! 
(defn set-values [sentiment location created-at] 
(let [tweed-id (create-tweet-id)] 
(wcar* 
(car/setbit sentiment tweet-id 1) 
(car/setbit location tweet-id 1) 
(car/setbit created-at tweet-id 1))))
(:require 
[taoensso.carmine :as car]) 
! 
! 
(defn create-tweet-id [] 
(first 
(wcar* 
(car/incr "global:tweet.id")))) 
! 
! 
(defn set-values [sentiment location created-at] 
(let [tweed-id (create-tweet-id)] 
(wcar* 
(car/setbit sentiment tweet-id 1) 
(car/setbit location tweet-id 1) 
(car/setbit created-at tweet-id 1))))
(:require 
[taoensso.carmine :as car]) 
! 
! 
(defn create-tweet-id [] 
(first 
(wcar* 
(car/incr "global:tweet.id")))) 
! 
! 
(defn set-values [sentiment location created-at] 
(let [tweed-id (create-tweet-id)] 
(wcar* 
(car/setbit sentiment tweet-id 1) 
(car/setbit location tweet-id 1) 
(car/setbit created-at tweet-id 1))))
(:require 
[taoensso.carmine :as car]) 
! 
! 
(defn create-tweet-id [] 
(first 
(wcar* 
(car/incr "global:tweet.id")))) 
! 
! 
(defn set-values [sentiment location created-at] 
(let [tweed-id (create-tweet-id)] 
(wcar* 
(car/setbit sentiment tweet-id 1) 
(car/setbit location tweet-id 1) 
(car/setbit created-at tweet-id 1))))
(:require 
[taoensso.carmine :as car]) 
! 
! 
(defn create-tweet-id [] 
(first 
(wcar* 
(car/incr "global:tweet.id")))) 
! 
! 
(defn set-values [sentiment location created-at] 
(let [tweed-id (create-tweet-id)] 
(wcar* 
(car/setbit sentiment tweet-id 1) 
(car/setbit location tweet-id 1) 
(car/setbit created-at tweet-id 1)))) 
find value for key 
set bit to 1 
find bit of index
(wcar* 
(car/bitcount "SCOTLAND") 
(car/bitcount "JOVIALITY") 
(car/bitcount "26062014114532"))
ENG 
SCT 
WAL 
NIR 
key value
key tweet-id 
(car/setbit “ENG” 0 1) 
ENG 1 
SCT 0 
WAL 0 
NIR 0 
key value
key tweet-id 
(car/setbit “SCT” 1 1) 
ENG 0 1 
SCT 1 0 
WAL 0 0 
NIR 0 0 
key value
key tweet-id 
(car/setbit “ENG” 2 1) 
ENG 1 0 1 
SCT 0 1 0 
WAL 0 0 0 
NIR 0 0 0 
key value
key tweet-id 
(car/setbit “SCT” 15 1) 
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 
SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 
WAL 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 
NIR 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
key value
(car/bitcount "ENG") 
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 
SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 
WAL 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 
NIR 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
8 
key value
(car/bitcount "SCT") 
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 
SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 
WAL 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 
NIR 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
8 
4 
key value
(car/bitcount "WAL") 
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 
SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 
WAL 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 
NIR 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
8 
4 
3 
key value
(car/bitcount "NIR") 
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 
SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 
WAL 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 
NIR 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 
8 
4 
3 
1 
key value
JOVIAL 
SHY 
HOSTILE 
FATIGUE 
key value
key tweet-id 
(car/setbit “JOVIAL” 0 1) 
JOVIAL 1 
SHY 0 
HOSTILE 0 
FATIGUE 0 
key value
key tweet-id 
(car/setbit “HOSTILE” 1 1) 
JOVIAL 0 1 
SHY 0 0 
HOSTILE 1 0 
FATIGUE 0 0 
key value
key tweet-id 
(car/setbit “SHY” 2 1) 
JOVIAL 0 0 1 
SHY 1 0 0 
HOSTILE 0 1 0 
FATIGUE 0 0 0 
key value
key tweet-id 
(car/setbit “JOVIAL” 15 1) 
JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 
SHY 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 
FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 
key value
(car/bitcount [*]) 
JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 
SHY 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 
HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 
FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 
8 
1 
3 
4 
key value
How many people in England are Happy 
about the referendum result? 
(wcar* 
(car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY") 
(car/expire “ENGLAND&JOVIALITY" 10) 
(car/bitcount “ENGLAND&JOVIALITY"))
How many people in England are Happy 
about the referendum result? 
(wcar* 
(car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY") 
(car/expire “ENGLAND&JOVIALITY" 10) 
(car/bitcount “ENGLAND&JOVIALITY"))
How many people in England are Happy 
about the referendum result? 
(wcar* 
(car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY") 
(car/expire “ENGLAND&JOVIALITY" 10) 
(car/bitcount “ENGLAND&JOVIALITY"))
How many people in England are Happy 
about the referendum result? 
(wcar* 
(car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY") 
(car/expire “ENGLAND&JOVIALITY" 10) 
(car/bitcount “ENGLAND&JOVIALITY"))
How many people in England are Happy 
about the referendum result?
How many people in England are Happy 
about the referendum result? 
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1
How many people in England are Happy 
about the referendum result? 
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 
JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1
How many people in England are Happy 
about the referendum result? 
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 
JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 
1 
AND 
(car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY")
How many people in England are Happy 
about the referendum result? 
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 
JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 
0 1 
AND 
(car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY")
How many people in England are Happy 
about the referendum result? 
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 
JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 
0 0 1 
AND 
(car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY")
How many people in England are Happy 
about the referendum result? 
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 
JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 
0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 
AND 
(car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY")
ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 
JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 
0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 
(car/bitcount “ENGLAND&JOVIALITY") 
4 
How many people in England are Happy 
about the referendum result?
How many people in Scotland are Tired 
and Grumpy after the referendum? 
(wcar* 
(car/bitop "OR" "FATIGUE|HOSTILITY" "FATIGUE" “HOSTILITY") 
(car/expire "FATIGUE|HOSTILITY" 10) 
(car/bitop "AND" "SCOTLAND&(FATIGUE|HOSTILITY)" 
"SCOTLAND" "FATIGUE|HOSTILITY") 
(car/expire "SCOTLAND&(FATIGUE|HOSTILITY)" 10) 
(car/bitcount "SCOTLAND&(FATIGUE|HOSTILITY)"))
How many people in Scotland are Tired 
and Grumpy after the referendum? 
(wcar* 
(car/bitop "OR" "FATIGUE|HOSTILITY" "FATIGUE" “HOSTILITY") 
(car/expire "FATIGUE|HOSTILITY" 10) 
(car/bitop "AND" "SCOTLAND&(FATIGUE|HOSTILITY)" 
"SCOTLAND" "FATIGUE|HOSTILITY") 
(car/expire "SCOTLAND&(FATIGUE|HOSTILITY)" 10) 
(car/bitcount "SCOTLAND&(FATIGUE|HOSTILITY)"))
How many people in Scotland are Tired 
and Grumpy after the referendum? 
(wcar* 
(car/bitop "OR" "FATIGUE|HOSTILITY" "FATIGUE" “HOSTILITY") 
(car/expire "FATIGUE|HOSTILITY" 10) 
(car/bitop "AND" "SCOTLAND&(FATIGUE|HOSTILITY)" 
"SCOTLAND" "FATIGUE|HOSTILITY") 
(car/expire "SCOTLAND&(FATIGUE|HOSTILITY)" 10) 
(car/bitcount "SCOTLAND&(FATIGUE|HOSTILITY)"))
How many people in Scotland are Tired 
and Grumpy after the referendum? 
(wcar* 
(car/bitop "OR" "FATIGUE|HOSTILITY" "FATIGUE" “HOSTILITY") 
(car/expire "FATIGUE|HOSTILITY" 10) 
(car/bitop "AND" "SCOTLAND&(FATIGUE|HOSTILITY)" 
"SCOTLAND" "FATIGUE|HOSTILITY") 
(car/expire "SCOTLAND&(FATIGUE|HOSTILITY)" 10) 
(car/bitcount "SCOTLAND&(FATIGUE|HOSTILITY)"))
How many people in Scotland are Tired 
and Grumpy after the referendum?
How many people in Scotland are Tired 
and Grumpy after the referendum? 
HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0
How many people in Scotland are Tired 
and Grumpy after the referendum? 
HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 
FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0
HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 
FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 
BOTH 
OR 
How many people in Scotland are Tired 
and Grumpy after the referendum?
HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 
FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 
BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 
OR 
How many people in Scotland are Tired 
and Grumpy after the referendum?
HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 
FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 
BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 
OR 
How many people in Scotland are Tired 
and Grumpy after the referendum?
How many people in Scotland are Tired 
and Grumpy after the referendum? 
HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 
FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 
BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 
SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0
HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 
FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 
BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 
SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 
BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 
AND 
How many people in Scotland are Tired 
and Grumpy after the referendum?
HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 
FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 
BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 
SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 
BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 
0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 
2 
How many people in Scotland are Tired 
and Grumpy after the referendum?
RING 
Journaling 
Syncing 
Business logic 
What 
Where 
When 
Memory 
Web API 
Incoming Data
RING 
Journaling 
Syncing 
Business logic 
What 
Where 
When 
Memory 
Web API 
Incoming Data 
adamwynne/twitter-api
RING 
Journaling 
Syncing 
Business logic 
What 
Where 
When 
Memory 
Web API 
Incoming Data 
clojurewerkz/meltdown 
LMAX-Exchange/disruptor
RING 
Journaling 
Syncing 
Business logic 
What 
Where 
When 
Memory 
Web API 
Incoming Data 
dakrone/clojure-opennlp
“I’m loving #XConfMCR! ”
Positive Affect: enthusiastic, active, alert 
! 
Negative Affect: subjective distress 
! 
Emerged as distinctive, orthogonal dimensions
PANAS 
2 3 
153 2 
4 
5 
1 
1 
3 
3 
3 
5 
345 
2 
2 
1
PANAS 
2 3 
153 2 
4 
5 
1 
1 
3 
3 
3 
5 
345 
2 
2 
1 
1 
3 
5 
9 
10 
12 
14 
16 
17 
19 
2 
4 
6 
7 
8 
11 
13 
15 
18 
20
PANAS 
positive affect! negative affect 
3 2 
4 
5 
1 
1 
5 
3 
3 
1 
3 2 
5 3 
4 3 
5 2 
2 1 
1 
3 
5 
9 
10 
12 
14 
16 
17 
19 
2 
4 
6 
7 
8 
11 
13 
15 
18 
20 
39 19
PANAS-x 
General Dimension Scales! 
Negative Affect (10) 
Positive Affect (10) 
Basic Positive Emotions Scales! 
Joviality (8) 
Self-assurance (6) 
Attentiveness (4) 
Basic Negative Emotions Scales! 
Fear (6) 
Hostility (6) 
Guilt (6) 
Sadness (5) 
Other Affective States! 
Shyness (4) 
Fatigue (4) 
Serenity (3) 
Surprise (3)
PANAS-t 
Accounts for bias on social media! 
Outlines sanitisation 
Validate against 10 real events
dakrone/clojure-opennlp 
Sanitisation 
• Exclude media/advertising/spam 
• Account for text speak 
• Account for smileys & emoj’s 
• Word stemming (or lemmatisation) 
• Part of Speech Tagging (POS) 
LMAO 
GetRichQuick.com
SHYNESS 
FATIGUE 
SERENITY 
SURPRISE 
FEAR 
HOSTILITY 
GUILT 
SADNESS 
JOVIALITY 
SELF ASSURANCE 
ATTENTIVENESS 
We have sentiment keys!
RING 
Journaling 
Syncing 
Business logic 
What 
Where 
When 
Memory 
Web API 
Incoming Data 
mbostock/d3
[-75.14310264, 40.05701649]
Reverse Geocoding Issues 
• Don’t want external services 
• Don’t want heavy IO 
• Don’t want round trips to the database 
• Accuracy not too much of a concern
Equirectangular Projection
Courtesy of Eric Gaba (Wikimedia Commons User: Sting)
Tissot's indicatrix of deformation 
x = λcosφ1 
y = φ 
Courtesy of Eric Gaba (Wikimedia Commons User: Sting)
x (px) 
y (px)
x (px) 
y (px) 
[lon, lat] = [55.86140, -4.26477] 
[x, y] = [329, 601] 
[x, y] = = Scotland!
x (px) 
y (px) 
[lon, lat] = [55.86140, -4.26477] 
[x, y] = [329, 601] 
[x, y] = = Scotland!
x (px) 
y (px) 
[lon, lat] = [55.86140, -4.26477] 
[x, y] = [329, 601] 
[x, y] = = Scotland!
x (px) 
y (px) 
[lon, lat] = [55.86140, -4.26477] 
[x, y] = [329, 601] 
[x, y] = = Scotland!
x (px) 
y (px) 
[lon, lat] = [55.86140, -4.26477] 
[x, y] = [329, 601] 
[x, y] = = Scotland!
x (px) 
y (px) 
[lon, lat] = [55.86140, -4.26477] 
[x, y] = [329, 601] 
[x, y] = = Scotland!
Ser ver si de! 
(JavaFX ) 
Mike Bostock & Nick Rabinowitz
(:require 
[hiccup.page :as hiccup]) 
(:import 
(javafx.scene.web WebView)) 
! 
(def scripts ["uk-data.js" "topojson.v1.min.js" "d3.v3.min.js" "geocoder.js"]) 
! 
(defn create-browser [html] 
(-> WebView. 
.getEngine 
(.loadContent html))) 
! 
(defn build-page [script-paths] 
(hiccup/html5 
[:head 
(for [path script-paths] 
Java F X 
[:script (slurp (io/resource path))])])) 
! 
(defn coordinates->name [longitude latitude] 
(let [browser (-> scripts build-page create-browser)] 
(.executeScript browser 
(str "geo.decode([" longitude "," latitude "])"))))
(:require 
[hiccup.page :as hiccup]) 
(:import 
(javafx.scene.web WebView)) 
! 
(def scripts ["uk-data.js" "topojson.v1.min.js" "d3.v3.min.js" "geocoder.js"]) 
! 
(defn create-browser [html] 
(-> WebView. 
.getEngine 
(.loadContent html))) 
! 
(defn build-page [script-paths] 
(hiccup/html5 
[:head 
(for [path script-paths] 
Java F X 
[:script (slurp (io/resource path))])])) 
! 
(defn coordinates->name [longitude latitude] 
(let [browser (-> scripts build-page create-browser)] 
(.executeScript browser 
(str "geo.decode([" longitude "," latitude "])"))))
(:require 
[hiccup.page :as hiccup]) 
(:import 
(javafx.scene.web WebView)) 
! 
(def scripts ["uk-data.js" "topojson.v1.min.js" "d3.v3.min.js" "geocoder.js"]) 
! 
(defn create-browser [html] 
(-> WebView. 
.getEngine 
(.loadContent html))) 
! 
(defn build-page [script-paths] 
(hiccup/html5 
[:head 
(for [path script-paths] 
Java F X 
[:script (slurp (io/resource path))])])) 
! 
(defn coordinates->name [longitude latitude] 
(let [browser (-> scripts build-page create-browser)] 
(.executeScript browser 
(str "geo.decode([" longitude "," latitude "])"))))
(:require 
[hiccup.page :as hiccup]) 
(:import 
(javafx.scene.web WebView)) 
! 
(def scripts ["uk-data.js" "topojson.v1.min.js" "d3.v3.min.js" "geocoder.js"]) 
! 
(defn create-browser [html] 
(-> WebView. 
.getEngine 
(.loadContent html))) 
! 
(defn build-page [script-paths] 
(hiccup/html5 
[:head 
(for [path script-paths] 
Java F X 
[:script (slurp (io/resource path))])])) 
! 
(defn coordinates->name [longitude latitude] 
(let [browser (-> scripts build-page create-browser)] 
(.executeScript browser 
(str "geo.decode([" longitude "," latitude "])"))))
(:require 
[hiccup.page :as hiccup]) 
(:import 
(javafx.scene.web WebView)) 
! 
(def scripts ["uk-data.js" "topojson.v1.min.js" "d3.v3.min.js" "geocoder.js"]) 
! 
(defn create-browser [html] 
(-> WebView. 
.getEngine 
(.loadContent html))) 
! 
(defn build-page [script-paths] 
(hiccup/html5 
[:head 
(for [path script-paths] 
Java F X 
[:script (slurp (io/resource path))])])) 
! 
(defn coordinates->name [longitude latitude] 
(let [browser (-> scripts build-page create-browser)] 
(.executeScript browser 
Stuart Sier ras 
Co mpo nent lib!! 
(str "geo.decode([" longitude "," latitude "])"))))
RING 
Journaling 
Syncing 
Business logic 
What 
Where 
When 
Memory 
Web API 
Incoming Data 
KirinDave/clj-time
“Thu Jun 26 14:35:57 +0000 2014” 
over 86 thousand seconds in a day 
over 31 million seconds in a year
mm:260620141435
HH:260620141400
dd:260620140000 
Monday Tuesday Wednesday Thursday Friday Saturday Sunday 
1 
2 3 4 5 6 7 8 
9 10 11 12 13 14 15 
16 17 18 19 20 21 22 
23 24 25 27 28 29 
30 31
MM:010620140000 
JAN FEB MAR APR 
MAY JUL AUG 
SEP OCT NOV DEC
2013 
2015 
yy:010120140000
(:require 
[clj-time.format :as time]) 
! 
! 
(def input-formatter "EE MMM d HH:mm:ss Z yyyy") 
(def formats { "mm:" "ddMMyyHHmm" "HH:" "ddMMyyHH00" ... }) 
! 
! 
(defn create-key [date [prefix formatter]] 
(let [out-date (time/unparse formatter date)] 
(str prefix out-date))) 
! 
! 
(defn date->keys [created_at] 
(let [date (time/parse input-formatter created_at)] 
(map #(create-key date %) formats)))
(:require 
[clj-time.format :as time]) 
! 
! 
(def input-formatter "EE MMM d HH:mm:ss Z yyyy") 
(def formats { "mm:" "ddMMyyHHmm" "HH:" "ddMMyyHH00" ... }) 
! 
! 
(defn create-key [date [prefix formatter]] 
(let [out-date (time/unparse formatter date)] 
(str prefix out-date))) 
! 
! 
(defn date->keys [created_at] 
(let [date (time/parse input-formatter created_at)] 
(map #(create-key date %) formats)))
(:require 
[clj-time.format :as time]) 
! 
! 
(def input-formatter "EE MMM d HH:mm:ss Z yyyy") 
(def formats { "mm:" "ddMMyyHHmm" "HH:" "ddMMyyHH00" ... }) 
! 
! 
(defn create-key [date [prefix formatter]] 
(let [out-date (time/unparse formatter date)] 
(str prefix out-date))) 
! 
! 
(defn date->keys [created_at] 
(let [date (time/parse input-formatter created_at)] 
(map #(create-key date %) formats)))
RING 
Journaling 
Syncing 
Business logic 
What 
Where 
When 
Memory 
Web API 
Incoming Data 
ptaoussanis/carmine
We have 11 keys in total! 
SENTIMENT 
! 
LOCATION 
! 
mm:date-time 
HH:date-time 
dd:date-time 
MM:date-time 
yy:date-time 
What 
Where 
When
(:require 
[taoensso.carmine :as redis]) 
! 
! 
(defn create-tweet-id [] 
(redis/incr "global:tweet.id")) 
! 
! 
(defn set-bits [data-keys tweet-id] 
(doseq [data-key data-keys] 
(redis/setbit data-key tweet-id 1))) 
! 
! 
(defn data->analytics [data-keys] 
(let [tweet-id (create-tweet-id)] 
(set-bits data-keys tweet-id)))
(:require 
[taoensso.carmine :as redis]) 
! 
! 
(defn create-tweet-id [] 
(redis/incr "global:tweet.id")) 
! 
! 
(defn set-bits [data-keys tweet-id] 
(doseq [data-key data-keys] 
(redis/setbit data-key tweet-id 1))) 
! 
! 
(defn data->analytics [data-keys] 
(let [tweet-id (create-tweet-id)] 
(set-bits data-keys tweet-id)))
(:require 
[taoensso.carmine :as redis]) 
! 
! 
(defn create-tweet-id [] 
(redis/incr "global:tweet.id")) 
! 
! 
(defn set-bits [data-keys tweet-id] 
(doseq [data-key data-keys] 
(redis/setbit data-key tweet-id 1))) 
! 
! 
(defn data->analytics [data-keys] 
(let [tweet-id (create-tweet-id)] 
(set-bits data-keys tweet-id)))
{ 
'query-type': 'count', 
'params': { 
'sentiments': [ 
'FATIGUE', 
'HOSTILITY' 
], 
'locations': [ 
'SCT' 
] 
} 
} 
weavejester/compojure 
JSON quer y
{ 
'query-type': 'count', 
'params': { 
'sentiments': [ 
'FATIGUE', 
'HOSTILITY' 
], 
'locations': [ 
'SCT' 
] 
} 
} 
weavejester/compojure 
JSON quer y 
/ap i?_quer y={jso n}
(defmulti execute :query-type) 
! 
! 
(defmethod execute “count" [] 
… logic here) 
! 
! 
(defmethod execute “p-affect“ [] 
… logic here) 
! 
! 
(defmethod execute “n-affect“ [] 
… logic here) 
{ 
'query-type': 'count', 
'params': { 
'sentiments': [ 
'FATIGUE', 
'HOSTILITY' 
], 
'locations': [ 
'SCT' 
] 
} 
} 
weavejester/compojure 
JSON quer y 
/ap i?_quer y={jso n}
(defmulti execute :query-type) 
! 
! 
(defmethod execute “count" [] 
… logic here) 
! 
! 
(defmethod execute “p-affect“ [] 
… logic here) 
! 
! 
(defmethod execute “n-affect“ [] 
… logic here) 
{ 
'query-type': 'count', 
'params': { 
'sentiments': [ 
'FATIGUE', 
'HOSTILITY' 
], 
'locations': [ 
'SCT' 
] 
} 
} 
weavejester/compojure 
JSON quer y 
/ap i?_quer y={jso n}
weavejester/compojure 
(defmulti execute :query-type) 
! 
! 
(defmethod execute “count" [] 
… logic here) 
! 
! 
(defmethod execute “p-affect“ [] 
… logic here) 
! 
! 
(defmethod execute “n-affect“ [] 
… logic here) 
JSON quer y 
{ 
'query-type': 'count', 
'params': { 
'sentiments': [ 
'FATIGUE', 
'HOSTILITY' 
], 
'locations': [ 
'SCT' 
] 
} 
} 
/ap i?_quer y={jso n}
weavejester/compojure 
(defmulti execute :query-type) 
! 
! 
(defmethod execute “count" [] 
… logic here) 
! 
! 
(defmethod execute “p-affect“ [] 
… logic here) 
! 
! 
(defmethod execute “n-affect“ [] 
… logic here) 
JSON quer y 
{ 
'query-type': ‘p-affect', 
'params': { 
'sentiments': [ 
'FATIGUE', 
'HOSTILITY' 
], 
'locations': [ 
'SCT' 
] 
} 
} 
/ap i?_quer y={jso n}
weavejester/compojure 
(defmulti execute :query-type) 
! 
! 
(defmethod execute “count" [] 
… logic here) 
! 
! 
(defmethod execute “p-affect“ [] 
… logic here) 
! 
! 
(defmethod execute “n-affect“ [] 
… logic here) 
JSON quer y 
{ 
'query-type': ‘p-affect', 
'params': { 
'sentiments': [ 
'FATIGUE', 
'HOSTILITY' 
], 
'locations': [ 
'SCT' 
] 
} 
} 
/ap i?_quer y={jso n}
Using Clojure for Sentiment Analysis of the Twittersphere

Mais conteúdo relacionado

Mais de Thoughtworks

Design System as a Product
Design System as a ProductDesign System as a Product
Design System as a ProductThoughtworks
 
Designers, Developers & Dogs
Designers, Developers & DogsDesigners, Developers & Dogs
Designers, Developers & DogsThoughtworks
 
Cloud-first for fast innovation
Cloud-first for fast innovationCloud-first for fast innovation
Cloud-first for fast innovationThoughtworks
 
More impact with flexible teams
More impact with flexible teamsMore impact with flexible teams
More impact with flexible teamsThoughtworks
 
Culture of Innovation
Culture of InnovationCulture of Innovation
Culture of InnovationThoughtworks
 
Developer Experience
Developer ExperienceDeveloper Experience
Developer ExperienceThoughtworks
 
When we design together
When we design togetherWhen we design together
When we design togetherThoughtworks
 
Hardware is hard(er)
Hardware is hard(er)Hardware is hard(er)
Hardware is hard(er)Thoughtworks
 
Customer-centric innovation enabled by cloud
 Customer-centric innovation enabled by cloud Customer-centric innovation enabled by cloud
Customer-centric innovation enabled by cloudThoughtworks
 
Amazon's Culture of Innovation
Amazon's Culture of InnovationAmazon's Culture of Innovation
Amazon's Culture of InnovationThoughtworks
 
When in doubt, go live
When in doubt, go liveWhen in doubt, go live
When in doubt, go liveThoughtworks
 
Don't cross the Rubicon
Don't cross the RubiconDon't cross the Rubicon
Don't cross the RubiconThoughtworks
 
Your test coverage is a lie!
Your test coverage is a lie!Your test coverage is a lie!
Your test coverage is a lie!Thoughtworks
 
Docker container security
Docker container securityDocker container security
Docker container securityThoughtworks
 
Redefining the unit
Redefining the unitRedefining the unit
Redefining the unitThoughtworks
 
Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22Thoughtworks
 
A Tribute to Turing
A Tribute to TuringA Tribute to Turing
A Tribute to TuringThoughtworks
 
Rsa maths worked out
Rsa maths worked outRsa maths worked out
Rsa maths worked outThoughtworks
 

Mais de Thoughtworks (20)

Design System as a Product
Design System as a ProductDesign System as a Product
Design System as a Product
 
Designers, Developers & Dogs
Designers, Developers & DogsDesigners, Developers & Dogs
Designers, Developers & Dogs
 
Cloud-first for fast innovation
Cloud-first for fast innovationCloud-first for fast innovation
Cloud-first for fast innovation
 
More impact with flexible teams
More impact with flexible teamsMore impact with flexible teams
More impact with flexible teams
 
Culture of Innovation
Culture of InnovationCulture of Innovation
Culture of Innovation
 
Dual-Track Agile
Dual-Track AgileDual-Track Agile
Dual-Track Agile
 
Developer Experience
Developer ExperienceDeveloper Experience
Developer Experience
 
When we design together
When we design togetherWhen we design together
When we design together
 
Hardware is hard(er)
Hardware is hard(er)Hardware is hard(er)
Hardware is hard(er)
 
Customer-centric innovation enabled by cloud
 Customer-centric innovation enabled by cloud Customer-centric innovation enabled by cloud
Customer-centric innovation enabled by cloud
 
Amazon's Culture of Innovation
Amazon's Culture of InnovationAmazon's Culture of Innovation
Amazon's Culture of Innovation
 
When in doubt, go live
When in doubt, go liveWhen in doubt, go live
When in doubt, go live
 
Don't cross the Rubicon
Don't cross the RubiconDon't cross the Rubicon
Don't cross the Rubicon
 
Error handling
Error handlingError handling
Error handling
 
Your test coverage is a lie!
Your test coverage is a lie!Your test coverage is a lie!
Your test coverage is a lie!
 
Docker container security
Docker container securityDocker container security
Docker container security
 
Redefining the unit
Redefining the unitRedefining the unit
Redefining the unit
 
Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22Technology Radar Webinar UK - Vol. 22
Technology Radar Webinar UK - Vol. 22
 
A Tribute to Turing
A Tribute to TuringA Tribute to Turing
A Tribute to Turing
 
Rsa maths worked out
Rsa maths worked outRsa maths worked out
Rsa maths worked out
 

Último

TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Jeffrey Haguewood
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdflior mazor
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDropbox
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxRustici Software
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelDeepika Singh
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...apidays
 

Último (20)

TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot ModelNavi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Navi Mumbai Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
Apidays Singapore 2024 - Scalable LLM APIs for AI and Generative AI Applicati...
 

Using Clojure for Sentiment Analysis of the Twittersphere

  • 1. Sentiment Analysis of the Twittersphere @APassionForCode
  • 2.
  • 3.
  • 4. Leiningen Versus the Ants! Clojure Versus Java! FP Versus OOP
  • 5. Apache Ant Leiningen Versus the Ants! Clojure Versus Java! FP Versus OOP
  • 6. Apache Ant Leiningen Versus the Ants Clojure Versus Java! FP Versus OOP
  • 7. Apache Ant Leiningen Versus the Ants Clojure Versus Java Functional Versus Object Oriented
  • 8. “You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.” Joe Armstrong - inventor of Erlang
  • 9. “Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function.” John Carmack - Lead on Doom, Quake, Rage
  • 10.
  • 11. Blood aches pain sick shivers spasm vomit dizzy fainting colic and in a coma! 1 FAVORITE
  • 12. Blood aches pain sick shivers spasm vomit dizzy fainting colic and in a coma! 1 FAVORITE Scores HIGH for flu symptoms
  • 13. Blood aches pain sick shivers spasm vomit dizzy fainting colic and in a coma! 1 FAVORITE Who is Catalina Rubottom?
  • 14. Blood aches pain sick shivers spasm vomit dizzy fainting colic and in a coma! 1 FAVORITE 30 million geo-tagged tweets sent from UK HDFS/Hadoop Mongo/Aggregation Mongo/MapReduce Postgres
  • 15. How can we do fast, real time analytics of social media?
  • 16. Store t his! Not this!
  • 17. WARNING! You’re about to see real Clojure code!
  • 21. (increment 1) Co ng ratu lat io ns - yo u’re no w fu lly qualifie d!
  • 23. (:require [taoensso.carmine :as car]) ! ! (defn create-tweet-id [] (first (wcar* (car/incr "global:tweet.id")))) ! ! (defn set-values [sentiment location created-at] (let [tweed-id (create-tweet-id)] (wcar* (car/setbit sentiment tweet-id 1) (car/setbit location tweet-id 1) (car/setbit created-at tweet-id 1))))
  • 24. (:require [taoensso.carmine :as car]) ! ! (defn create-tweet-id [] (first (wcar* (car/incr "global:tweet.id")))) ! ! (defn set-values [sentiment location created-at] (let [tweed-id (create-tweet-id)] (wcar* (car/setbit sentiment tweet-id 1) (car/setbit location tweet-id 1) (car/setbit created-at tweet-id 1))))
  • 25. (:require [taoensso.carmine :as car]) ! ! (defn create-tweet-id [] (first (wcar* (car/incr "global:tweet.id")))) ! ! (defn set-values [sentiment location created-at] (let [tweed-id (create-tweet-id)] (wcar* (car/setbit sentiment tweet-id 1) (car/setbit location tweet-id 1) (car/setbit created-at tweet-id 1))))
  • 26. (:require [taoensso.carmine :as car]) ! ! (defn create-tweet-id [] (first (wcar* (car/incr "global:tweet.id")))) ! ! (defn set-values [sentiment location created-at] (let [tweed-id (create-tweet-id)] (wcar* (car/setbit sentiment tweet-id 1) (car/setbit location tweet-id 1) (car/setbit created-at tweet-id 1))))
  • 27. (:require [taoensso.carmine :as car]) ! ! (defn create-tweet-id [] (first (wcar* (car/incr "global:tweet.id")))) ! ! (defn set-values [sentiment location created-at] (let [tweed-id (create-tweet-id)] (wcar* (car/setbit sentiment tweet-id 1) (car/setbit location tweet-id 1) (car/setbit created-at tweet-id 1)))) find value for key set bit to 1 find bit of index
  • 28. (wcar* (car/bitcount "SCOTLAND") (car/bitcount "JOVIALITY") (car/bitcount "26062014114532"))
  • 29. ENG SCT WAL NIR key value
  • 30. key tweet-id (car/setbit “ENG” 0 1) ENG 1 SCT 0 WAL 0 NIR 0 key value
  • 31. key tweet-id (car/setbit “SCT” 1 1) ENG 0 1 SCT 1 0 WAL 0 0 NIR 0 0 key value
  • 32. key tweet-id (car/setbit “ENG” 2 1) ENG 1 0 1 SCT 0 1 0 WAL 0 0 0 NIR 0 0 0 key value
  • 33. key tweet-id (car/setbit “SCT” 15 1) ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 WAL 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 NIR 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 key value
  • 34. (car/bitcount "ENG") ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 WAL 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 NIR 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 8 key value
  • 35. (car/bitcount "SCT") ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 WAL 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 NIR 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 8 4 key value
  • 36. (car/bitcount "WAL") ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 WAL 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 NIR 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 8 4 3 key value
  • 37. (car/bitcount "NIR") ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 WAL 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 NIR 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 8 4 3 1 key value
  • 38. JOVIAL SHY HOSTILE FATIGUE key value
  • 39. key tweet-id (car/setbit “JOVIAL” 0 1) JOVIAL 1 SHY 0 HOSTILE 0 FATIGUE 0 key value
  • 40. key tweet-id (car/setbit “HOSTILE” 1 1) JOVIAL 0 1 SHY 0 0 HOSTILE 1 0 FATIGUE 0 0 key value
  • 41. key tweet-id (car/setbit “SHY” 2 1) JOVIAL 0 0 1 SHY 1 0 0 HOSTILE 0 1 0 FATIGUE 0 0 0 key value
  • 42. key tweet-id (car/setbit “JOVIAL” 15 1) JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 SHY 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 key value
  • 43. (car/bitcount [*]) JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 SHY 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 8 1 3 4 key value
  • 44. How many people in England are Happy about the referendum result? (wcar* (car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY") (car/expire “ENGLAND&JOVIALITY" 10) (car/bitcount “ENGLAND&JOVIALITY"))
  • 45. How many people in England are Happy about the referendum result? (wcar* (car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY") (car/expire “ENGLAND&JOVIALITY" 10) (car/bitcount “ENGLAND&JOVIALITY"))
  • 46. How many people in England are Happy about the referendum result? (wcar* (car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY") (car/expire “ENGLAND&JOVIALITY" 10) (car/bitcount “ENGLAND&JOVIALITY"))
  • 47. How many people in England are Happy about the referendum result? (wcar* (car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY") (car/expire “ENGLAND&JOVIALITY" 10) (car/bitcount “ENGLAND&JOVIALITY"))
  • 48. How many people in England are Happy about the referendum result?
  • 49. How many people in England are Happy about the referendum result? ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1
  • 50. How many people in England are Happy about the referendum result? ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1
  • 51. How many people in England are Happy about the referendum result? ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 1 AND (car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY")
  • 52. How many people in England are Happy about the referendum result? ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 0 1 AND (car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY")
  • 53. How many people in England are Happy about the referendum result? ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 0 0 1 AND (car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY")
  • 54. How many people in England are Happy about the referendum result? ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 AND (car/bitop "AND" “ENGLAND&JOVIALITY" "ENGLAND" "JOVIALITY")
  • 55. ENG 0 0 1 0 1 1 0 1 0 0 1 0 1 1 0 1 JOVIAL 1 0 1 0 1 1 1 0 0 1 0 1 0 0 0 1 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 1 (car/bitcount “ENGLAND&JOVIALITY") 4 How many people in England are Happy about the referendum result?
  • 56. How many people in Scotland are Tired and Grumpy after the referendum? (wcar* (car/bitop "OR" "FATIGUE|HOSTILITY" "FATIGUE" “HOSTILITY") (car/expire "FATIGUE|HOSTILITY" 10) (car/bitop "AND" "SCOTLAND&(FATIGUE|HOSTILITY)" "SCOTLAND" "FATIGUE|HOSTILITY") (car/expire "SCOTLAND&(FATIGUE|HOSTILITY)" 10) (car/bitcount "SCOTLAND&(FATIGUE|HOSTILITY)"))
  • 57. How many people in Scotland are Tired and Grumpy after the referendum? (wcar* (car/bitop "OR" "FATIGUE|HOSTILITY" "FATIGUE" “HOSTILITY") (car/expire "FATIGUE|HOSTILITY" 10) (car/bitop "AND" "SCOTLAND&(FATIGUE|HOSTILITY)" "SCOTLAND" "FATIGUE|HOSTILITY") (car/expire "SCOTLAND&(FATIGUE|HOSTILITY)" 10) (car/bitcount "SCOTLAND&(FATIGUE|HOSTILITY)"))
  • 58. How many people in Scotland are Tired and Grumpy after the referendum? (wcar* (car/bitop "OR" "FATIGUE|HOSTILITY" "FATIGUE" “HOSTILITY") (car/expire "FATIGUE|HOSTILITY" 10) (car/bitop "AND" "SCOTLAND&(FATIGUE|HOSTILITY)" "SCOTLAND" "FATIGUE|HOSTILITY") (car/expire "SCOTLAND&(FATIGUE|HOSTILITY)" 10) (car/bitcount "SCOTLAND&(FATIGUE|HOSTILITY)"))
  • 59. How many people in Scotland are Tired and Grumpy after the referendum? (wcar* (car/bitop "OR" "FATIGUE|HOSTILITY" "FATIGUE" “HOSTILITY") (car/expire "FATIGUE|HOSTILITY" 10) (car/bitop "AND" "SCOTLAND&(FATIGUE|HOSTILITY)" "SCOTLAND" "FATIGUE|HOSTILITY") (car/expire "SCOTLAND&(FATIGUE|HOSTILITY)" 10) (car/bitcount "SCOTLAND&(FATIGUE|HOSTILITY)"))
  • 60. How many people in Scotland are Tired and Grumpy after the referendum?
  • 61. How many people in Scotland are Tired and Grumpy after the referendum? HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0
  • 62. How many people in Scotland are Tired and Grumpy after the referendum? HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0
  • 63. HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 BOTH OR How many people in Scotland are Tired and Grumpy after the referendum?
  • 64. HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 OR How many people in Scotland are Tired and Grumpy after the referendum?
  • 65. HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 OR How many people in Scotland are Tired and Grumpy after the referendum?
  • 66. How many people in Scotland are Tired and Grumpy after the referendum? HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0
  • 67. HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 AND How many people in Scotland are Tired and Grumpy after the referendum?
  • 68. HOSTILE 0 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 FATIGUE 0 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 SCT 1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 BOTH 0 1 0 1 0 0 0 1 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 2 How many people in Scotland are Tired and Grumpy after the referendum?
  • 69. RING Journaling Syncing Business logic What Where When Memory Web API Incoming Data
  • 70. RING Journaling Syncing Business logic What Where When Memory Web API Incoming Data adamwynne/twitter-api
  • 71. RING Journaling Syncing Business logic What Where When Memory Web API Incoming Data clojurewerkz/meltdown LMAX-Exchange/disruptor
  • 72. RING Journaling Syncing Business logic What Where When Memory Web API Incoming Data dakrone/clojure-opennlp
  • 74. Positive Affect: enthusiastic, active, alert ! Negative Affect: subjective distress ! Emerged as distinctive, orthogonal dimensions
  • 75. PANAS 2 3 153 2 4 5 1 1 3 3 3 5 345 2 2 1
  • 76. PANAS 2 3 153 2 4 5 1 1 3 3 3 5 345 2 2 1 1 3 5 9 10 12 14 16 17 19 2 4 6 7 8 11 13 15 18 20
  • 77. PANAS positive affect! negative affect 3 2 4 5 1 1 5 3 3 1 3 2 5 3 4 3 5 2 2 1 1 3 5 9 10 12 14 16 17 19 2 4 6 7 8 11 13 15 18 20 39 19
  • 78. PANAS-x General Dimension Scales! Negative Affect (10) Positive Affect (10) Basic Positive Emotions Scales! Joviality (8) Self-assurance (6) Attentiveness (4) Basic Negative Emotions Scales! Fear (6) Hostility (6) Guilt (6) Sadness (5) Other Affective States! Shyness (4) Fatigue (4) Serenity (3) Surprise (3)
  • 79. PANAS-t Accounts for bias on social media! Outlines sanitisation Validate against 10 real events
  • 80. dakrone/clojure-opennlp Sanitisation • Exclude media/advertising/spam • Account for text speak • Account for smileys & emoj’s • Word stemming (or lemmatisation) • Part of Speech Tagging (POS) LMAO GetRichQuick.com
  • 81. SHYNESS FATIGUE SERENITY SURPRISE FEAR HOSTILITY GUILT SADNESS JOVIALITY SELF ASSURANCE ATTENTIVENESS We have sentiment keys!
  • 82. RING Journaling Syncing Business logic What Where When Memory Web API Incoming Data mbostock/d3
  • 84. Reverse Geocoding Issues • Don’t want external services • Don’t want heavy IO • Don’t want round trips to the database • Accuracy not too much of a concern
  • 85.
  • 86.
  • 88. Courtesy of Eric Gaba (Wikimedia Commons User: Sting)
  • 89. Tissot's indicatrix of deformation x = λcosφ1 y = φ Courtesy of Eric Gaba (Wikimedia Commons User: Sting)
  • 90.
  • 91. x (px) y (px)
  • 92. x (px) y (px) [lon, lat] = [55.86140, -4.26477] [x, y] = [329, 601] [x, y] = = Scotland!
  • 93. x (px) y (px) [lon, lat] = [55.86140, -4.26477] [x, y] = [329, 601] [x, y] = = Scotland!
  • 94. x (px) y (px) [lon, lat] = [55.86140, -4.26477] [x, y] = [329, 601] [x, y] = = Scotland!
  • 95. x (px) y (px) [lon, lat] = [55.86140, -4.26477] [x, y] = [329, 601] [x, y] = = Scotland!
  • 96. x (px) y (px) [lon, lat] = [55.86140, -4.26477] [x, y] = [329, 601] [x, y] = = Scotland!
  • 97. x (px) y (px) [lon, lat] = [55.86140, -4.26477] [x, y] = [329, 601] [x, y] = = Scotland!
  • 98. Ser ver si de! (JavaFX ) Mike Bostock & Nick Rabinowitz
  • 99. (:require [hiccup.page :as hiccup]) (:import (javafx.scene.web WebView)) ! (def scripts ["uk-data.js" "topojson.v1.min.js" "d3.v3.min.js" "geocoder.js"]) ! (defn create-browser [html] (-> WebView. .getEngine (.loadContent html))) ! (defn build-page [script-paths] (hiccup/html5 [:head (for [path script-paths] Java F X [:script (slurp (io/resource path))])])) ! (defn coordinates->name [longitude latitude] (let [browser (-> scripts build-page create-browser)] (.executeScript browser (str "geo.decode([" longitude "," latitude "])"))))
  • 100. (:require [hiccup.page :as hiccup]) (:import (javafx.scene.web WebView)) ! (def scripts ["uk-data.js" "topojson.v1.min.js" "d3.v3.min.js" "geocoder.js"]) ! (defn create-browser [html] (-> WebView. .getEngine (.loadContent html))) ! (defn build-page [script-paths] (hiccup/html5 [:head (for [path script-paths] Java F X [:script (slurp (io/resource path))])])) ! (defn coordinates->name [longitude latitude] (let [browser (-> scripts build-page create-browser)] (.executeScript browser (str "geo.decode([" longitude "," latitude "])"))))
  • 101. (:require [hiccup.page :as hiccup]) (:import (javafx.scene.web WebView)) ! (def scripts ["uk-data.js" "topojson.v1.min.js" "d3.v3.min.js" "geocoder.js"]) ! (defn create-browser [html] (-> WebView. .getEngine (.loadContent html))) ! (defn build-page [script-paths] (hiccup/html5 [:head (for [path script-paths] Java F X [:script (slurp (io/resource path))])])) ! (defn coordinates->name [longitude latitude] (let [browser (-> scripts build-page create-browser)] (.executeScript browser (str "geo.decode([" longitude "," latitude "])"))))
  • 102. (:require [hiccup.page :as hiccup]) (:import (javafx.scene.web WebView)) ! (def scripts ["uk-data.js" "topojson.v1.min.js" "d3.v3.min.js" "geocoder.js"]) ! (defn create-browser [html] (-> WebView. .getEngine (.loadContent html))) ! (defn build-page [script-paths] (hiccup/html5 [:head (for [path script-paths] Java F X [:script (slurp (io/resource path))])])) ! (defn coordinates->name [longitude latitude] (let [browser (-> scripts build-page create-browser)] (.executeScript browser (str "geo.decode([" longitude "," latitude "])"))))
  • 103. (:require [hiccup.page :as hiccup]) (:import (javafx.scene.web WebView)) ! (def scripts ["uk-data.js" "topojson.v1.min.js" "d3.v3.min.js" "geocoder.js"]) ! (defn create-browser [html] (-> WebView. .getEngine (.loadContent html))) ! (defn build-page [script-paths] (hiccup/html5 [:head (for [path script-paths] Java F X [:script (slurp (io/resource path))])])) ! (defn coordinates->name [longitude latitude] (let [browser (-> scripts build-page create-browser)] (.executeScript browser Stuart Sier ras Co mpo nent lib!! (str "geo.decode([" longitude "," latitude "])"))))
  • 104. RING Journaling Syncing Business logic What Where When Memory Web API Incoming Data KirinDave/clj-time
  • 105. “Thu Jun 26 14:35:57 +0000 2014” over 86 thousand seconds in a day over 31 million seconds in a year
  • 106.
  • 107.
  • 110. dd:260620140000 Monday Tuesday Wednesday Thursday Friday Saturday Sunday 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 27 28 29 30 31
  • 111. MM:010620140000 JAN FEB MAR APR MAY JUL AUG SEP OCT NOV DEC
  • 113. (:require [clj-time.format :as time]) ! ! (def input-formatter "EE MMM d HH:mm:ss Z yyyy") (def formats { "mm:" "ddMMyyHHmm" "HH:" "ddMMyyHH00" ... }) ! ! (defn create-key [date [prefix formatter]] (let [out-date (time/unparse formatter date)] (str prefix out-date))) ! ! (defn date->keys [created_at] (let [date (time/parse input-formatter created_at)] (map #(create-key date %) formats)))
  • 114. (:require [clj-time.format :as time]) ! ! (def input-formatter "EE MMM d HH:mm:ss Z yyyy") (def formats { "mm:" "ddMMyyHHmm" "HH:" "ddMMyyHH00" ... }) ! ! (defn create-key [date [prefix formatter]] (let [out-date (time/unparse formatter date)] (str prefix out-date))) ! ! (defn date->keys [created_at] (let [date (time/parse input-formatter created_at)] (map #(create-key date %) formats)))
  • 115. (:require [clj-time.format :as time]) ! ! (def input-formatter "EE MMM d HH:mm:ss Z yyyy") (def formats { "mm:" "ddMMyyHHmm" "HH:" "ddMMyyHH00" ... }) ! ! (defn create-key [date [prefix formatter]] (let [out-date (time/unparse formatter date)] (str prefix out-date))) ! ! (defn date->keys [created_at] (let [date (time/parse input-formatter created_at)] (map #(create-key date %) formats)))
  • 116. RING Journaling Syncing Business logic What Where When Memory Web API Incoming Data ptaoussanis/carmine
  • 117. We have 11 keys in total! SENTIMENT ! LOCATION ! mm:date-time HH:date-time dd:date-time MM:date-time yy:date-time What Where When
  • 118. (:require [taoensso.carmine :as redis]) ! ! (defn create-tweet-id [] (redis/incr "global:tweet.id")) ! ! (defn set-bits [data-keys tweet-id] (doseq [data-key data-keys] (redis/setbit data-key tweet-id 1))) ! ! (defn data->analytics [data-keys] (let [tweet-id (create-tweet-id)] (set-bits data-keys tweet-id)))
  • 119. (:require [taoensso.carmine :as redis]) ! ! (defn create-tweet-id [] (redis/incr "global:tweet.id")) ! ! (defn set-bits [data-keys tweet-id] (doseq [data-key data-keys] (redis/setbit data-key tweet-id 1))) ! ! (defn data->analytics [data-keys] (let [tweet-id (create-tweet-id)] (set-bits data-keys tweet-id)))
  • 120. (:require [taoensso.carmine :as redis]) ! ! (defn create-tweet-id [] (redis/incr "global:tweet.id")) ! ! (defn set-bits [data-keys tweet-id] (doseq [data-key data-keys] (redis/setbit data-key tweet-id 1))) ! ! (defn data->analytics [data-keys] (let [tweet-id (create-tweet-id)] (set-bits data-keys tweet-id)))
  • 121. { 'query-type': 'count', 'params': { 'sentiments': [ 'FATIGUE', 'HOSTILITY' ], 'locations': [ 'SCT' ] } } weavejester/compojure JSON quer y
  • 122. { 'query-type': 'count', 'params': { 'sentiments': [ 'FATIGUE', 'HOSTILITY' ], 'locations': [ 'SCT' ] } } weavejester/compojure JSON quer y /ap i?_quer y={jso n}
  • 123. (defmulti execute :query-type) ! ! (defmethod execute “count" [] … logic here) ! ! (defmethod execute “p-affect“ [] … logic here) ! ! (defmethod execute “n-affect“ [] … logic here) { 'query-type': 'count', 'params': { 'sentiments': [ 'FATIGUE', 'HOSTILITY' ], 'locations': [ 'SCT' ] } } weavejester/compojure JSON quer y /ap i?_quer y={jso n}
  • 124. (defmulti execute :query-type) ! ! (defmethod execute “count" [] … logic here) ! ! (defmethod execute “p-affect“ [] … logic here) ! ! (defmethod execute “n-affect“ [] … logic here) { 'query-type': 'count', 'params': { 'sentiments': [ 'FATIGUE', 'HOSTILITY' ], 'locations': [ 'SCT' ] } } weavejester/compojure JSON quer y /ap i?_quer y={jso n}
  • 125. weavejester/compojure (defmulti execute :query-type) ! ! (defmethod execute “count" [] … logic here) ! ! (defmethod execute “p-affect“ [] … logic here) ! ! (defmethod execute “n-affect“ [] … logic here) JSON quer y { 'query-type': 'count', 'params': { 'sentiments': [ 'FATIGUE', 'HOSTILITY' ], 'locations': [ 'SCT' ] } } /ap i?_quer y={jso n}
  • 126. weavejester/compojure (defmulti execute :query-type) ! ! (defmethod execute “count" [] … logic here) ! ! (defmethod execute “p-affect“ [] … logic here) ! ! (defmethod execute “n-affect“ [] … logic here) JSON quer y { 'query-type': ‘p-affect', 'params': { 'sentiments': [ 'FATIGUE', 'HOSTILITY' ], 'locations': [ 'SCT' ] } } /ap i?_quer y={jso n}
  • 127. weavejester/compojure (defmulti execute :query-type) ! ! (defmethod execute “count" [] … logic here) ! ! (defmethod execute “p-affect“ [] … logic here) ! ! (defmethod execute “n-affect“ [] … logic here) JSON quer y { 'query-type': ‘p-affect', 'params': { 'sentiments': [ 'FATIGUE', 'HOSTILITY' ], 'locations': [ 'SCT' ] } } /ap i?_quer y={jso n}