Skip to content

Instantly share code, notes, and snippets.

@jl2
Last active April 5, 2020 10:54
Show Gist options
  • Save jl2/fd324fa3faa919803152465fade14b6b to your computer and use it in GitHub Desktop.
Save jl2/fd324fa3faa919803152465fade14b6b to your computer and use it in GitHub Desktop.
(ql:quickload :cl-csv)
(ql:quickload :zip)
(ql:quickload :cl-strings)
;; Download transit data from this French site:
;; https://www.data.gouv.fr/fr/datasets/transport-donnees-gtfs/
(defun read-transit-data (&key (zip-file-path "~/Downloads/gtfs_current.zip"))
(flet ((csv-name-to-lisp (name)
(string-upcase (cl-strings:replace-all name "_" "-"))))
(zip:with-zipfile (zf zip-file-path)
(loop
with entries = (zip:zipfile-entries zf)
for name being the hash-keys of entries
using (hash-value entry)
collect
(let* ((cls-name (csv-name-to-lisp (pathname-name name)))
(cls-sym (intern cls-name))
(keyword-name (intern cls-name "KEYWORD"))
(data (cl-csv:read-csv
(flexi-streams:octets-to-string
(zip:zipfile-entry-contents entry))))
(keyws (loop
for slot-name in (car data)
for sname = (csv-name-to-lisp slot-name)
for sym = (intern sname)
for keyword = (intern sname "KEYWORD")
collect (list sym :initarg keyword) into members
collect keyword into keywords
collect sym into symbols
finally (return
(progn
(eval `(defclass ,cls-sym ()
( ,@members )))
(eval `(defmethod print-object ((object ,cls-sym) stream)
(with-slots ,symbols object
(format stream "(~a ~{ ~s~^ ~})"
(quote ,cls-sym)
(list ,@symbols)))))
keywords)))))
(cons keyword-name
(loop
for row-values in (cdr data)
collect (apply #'make-instance cls-sym (loop
for keyw in keyws
for val in row-values
collect keyw collect val)))))))))
(defun select (data slot value)
(loop for object in data
when (string= value (slot-value object slot))
collect object))
(defun table (transit-data type)
(assoc-value transit-data type))
;; Read CSV data from Zip file
(defparameter *transit-data* (read-transit-data))
;; Query something
(select
(select (table *transit-data* :trips) 'trip-headsign "L5a - MAISON NEUVE")
'route-id "5-77")
(select (table *transit-data* :trips) 'route-id "5-77")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment