2 ms·
Seems like they could cut out a lot of that code by using macros. Here's a quick and dirty Common Lisp script that reads the CSVs from the .zip file and genera
by jlarocco 7y ago
Seems like they could cut out a lot of that code by using macros. Here's a quick and dirty Common Lisp script that reads the CSVs from the .zip file and generates classes at runtime using the headers in each CSV for the slot names. It also defines a 'select' function to make queries easy to write. It's a little too long to post here:
https://gist.github.com/jl2/fd324fa3faa919803152465fade14b6b https://gist.github.com/jl2/fd324fa3faa919803152465fade14b6b
And here's what it looks like to use it:
CL-USER> (defparameter *transit-data* (read-transit-data "~/Downloads/gtfs_current.zip"))
CL-USER> (select (table *transit-data* :stops) 'stop-name "PIERNE")
((STOPS "PIERNE01" "" "PIERNE" "" "49.102273" "6.179863" "" "http://lemet.fr/screen/index2.php?stop=257" "0" "" "1")
(STOPS "PIERNE02" "" "PIERNE" "" "49.102558" "6.179825" "" "http://lemet.fr/screen/index2.php?stop=234" "0" "" "1"))
CL-USER> (select
(select (table *transit-data* :trips) 'trip-headsign "L5a - MAISON NEUVE")
'route-id "5-77")
((TRIPS "5-77" "SMIN_H1920-CLaS50V2-Lun-Sam-98" "409137-SMIN_H1920-CLaS50V2-Lun-Sam-98" "L5a - MAISON NEUVE" "1" "60112" "50057")
(TRIPS "5-77" "SMIN_H1920-CLaS50V2-Lun-Sam-98" "409138-SMIN_H1920-CLaS50V2-Lun-Sam-98" "L5a - MAISON NEUVE" "1" "60111" "50057")
;; ...
)
- markc 7y ago>reads the CSVs from the .zip file Neat! I can't find anything in Clojure that does that, so I guess I'd have to use java.util.zip via Clojure ineterop. But making records and doing queries is easy: > generate classes at runtime using the headers in each CSV In Clojure: (ns gtfs.core (:require [clojure.data.csv :as csv])) (defn load-records [f] (let [csv-data (csv/read-csv (slurp f))] (map zipmap (->> (first csv-data) ;; First row is the header (map keyword) repeat) (rest csv-data)))) (def agency-maps (load-records "data/agency.txt")) (def routes-maps (load-records "data/routes.txt")) ;; etc. (count routes-maps) ;; 30 (first routes-maps) ;; {: route_id "1-100", ;; :route_short_name "1", ;; :route_long_name "Ligne 1", ;; :route_desc "", ;; :route_type "3", ;; :route_url "", ;; :route_color "#B22E75"} > defines a 'select' function to make queries easy to write ;; Query for long_name and route_color (def route_ln_color (map #(select-keys % [:route_long_name :route_color]) routes-maps)) (take 2 route_ln_color) ;; ({:route_long_name "Ligne 1", :route_color "#B22E75"} ;; {:route_long_name "Ligne 2", :route_color "#B22E75"})