|
2 | 2 | (:require [clj-http.client :as client]
|
3 | 3 | [cheshire.core :as json]))
|
4 | 4 |
|
5 |
| -(defn TODO [msg] |
6 |
| - (throw (Exception. msg))) |
| 5 | +;;;; MODULE 4 |
7 | 6 |
|
8 |
| -(defn parse-json [str] |
9 |
| - (json/parse-string str true)) |
10 |
| - |
11 |
| -;; WORLD BANK API CALLS |
12 | 7 | (defn get-api
|
13 | 8 | "Returns map representing API response."
|
14 | 9 | [path params]
|
15 |
| - (let [base-path (str "http://api.worldbank.org" path) |
| 10 | + (let [url (str "http://api.worldbank.org" path) |
16 | 11 | query-params (merge params {:format "json" :per_page 10000})
|
17 |
| - response (parse-json (:body (client/get base-path {:query-params query-params}))) |
| 12 | + response (json/parse-string |
| 13 | + (:body (client/get url {:query-params query-params})) true) |
18 | 14 | metadata (first response)
|
19 | 15 | results (second response)]
|
20 | 16 | {:metadata metadata
|
21 | 17 | :results results}))
|
22 | 18 |
|
23 |
| -(defn get-values |
24 |
| - "Returns a relation of two keys from API response." |
25 |
| - [path query-params key1 key2] |
26 |
| - (let [response (get-api path query-params)] |
27 |
| - (for [item (:results response)] |
28 |
| - [(key1 item) (key2 item)]))) |
| 19 | +(defn get-country-and-value |
| 20 | + [response] |
| 21 | + (for [item (:results response)] |
| 22 | + (vector (get-in item [:country :value]) (get item :value)))) |
29 | 23 |
|
30 | 24 | (defn remove-aggregate-countries
|
31 | 25 | "Remove all countries that aren't actually countries, but are aggregates."
|
32 | 26 | [countries]
|
33 | 27 | (remove (fn [country]
|
34 | 28 | (= (get-in country [:region :value]) "Aggregates")) countries))
|
35 | 29 |
|
36 |
| -(def indicators |
37 |
| - (delay (get-values "/topics/16/indicators" {} :name :id))) |
38 |
| - |
39 | 30 | ;; Get set of country ids so we can filter out aggregate values.
|
40 |
| -(def country-ids |
| 31 | +(def countries |
41 | 32 | (delay
|
42 | 33 | (let [countries (remove-aggregate-countries (:results (get-api "/countries" {})))]
|
43 |
| - (set (map :iso2Code countries))))) |
| 34 | + (set (map :name countries))))) |
| 35 | + |
| 36 | +(defn get-indicator-values |
| 37 | + "Returns indicator values for a specified year for all countries." |
| 38 | + [indicator-code year] |
| 39 | + (let [response (get-api (str "/countries/all/indicators/" indicator-code) |
| 40 | + {:date (str year)}) |
| 41 | + values (get-country-and-value response)] |
| 42 | + (for [[country value] values |
| 43 | + :when (and (not (nil? value)) |
| 44 | + (contains? @countries country))] |
| 45 | + [country (read-string value)]))) |
| 46 | + |
| 47 | +;;;; MODULE 5 |
| 48 | + |
| 49 | +(defn take-top-values |
| 50 | + [indicator-values num-values] |
| 51 | + (take num-values |
| 52 | + (sort-by second > indicator-values))) |
| 53 | + |
| 54 | +(defn get-values |
| 55 | + "Returns a relation of two keys from API response." |
| 56 | + [path query-params key1 key2] |
| 57 | + (let [response (get-api path query-params)] |
| 58 | + (for [item (:results response)] |
| 59 | + [(key1 item) (key2 item)]))) |
| 60 | + |
| 61 | +(def indicators |
| 62 | + (delay (get-values "/topics/16/indicators" {} :name :id))) |
44 | 63 |
|
45 | 64 | (defn get-indicators []
|
46 | 65 | "Gets vector of indicators.
|
|
50 | 69 | /indicators: All Indicators (about 8800)"
|
51 | 70 | @indicators)
|
52 | 71 |
|
53 |
| -(defn get-indicator-values |
54 |
| - "Returns indicator values for a specified year for all countries." |
55 |
| - [indicator year list-size] |
56 |
| - (let [values (get-values (str "/countries/all/indicators/" indicator) |
57 |
| - {:date (str year)} |
58 |
| - :country :value)] |
59 |
| - (take list-size |
60 |
| - (sort-by second > |
61 |
| - (for [[country value] values |
62 |
| - :when (and (not (nil? value)) |
63 |
| - (contains? @country-ids (:id country)))] |
64 |
| - [(:value country) (read-string value)]))))) |
65 |
| - |
66 | 72 | (defn -main
|
67 | 73 | [& args]
|
68 |
| - (let [indicator-values (get-indicator-values "EN.POP.DNST" 2010 10)] |
69 |
| - (doseq [value indicator-values] |
| 74 | + (let [indicator-values (get-indicator-values "EN.POP.DNST" 2010) |
| 75 | + top-10-values (take-top-values indicator-values 10)] |
| 76 | + (doseq [value top-10-values] |
70 | 77 | (println (str (first value) " " (second value))))))
|
0 commit comments