screwlisp proposes kittens

Common lisp series and simple gnuplot climate data

One of my most-useful-to-me pages common lisp simple gnuplot which even got included in Edrx’s emacs eev resources, kitten says basically no-one has visited.

Here, in preparation for the show tomorrow, I fed thirty megabytes of New Zealand climate data to it and asked it how hot 1980 was day-by-day in Christchurch, New Zealand. (Do you have an idea for a cooler graph?).

Tell me on the Mastodon (Before The Live Show In 15 Hours).

The data comes from data.mfe.govt.nz.

(gnuplot
 "Daily max-avg-min celsius in Christchurch, NZ in 1980."
 (get-daily-temps 1980
		  "Maximum"
		  "Christchurch (Canterbury)")
 (get-daily-temps 1980
		  "Average"
		  "Christchurch (Canterbury)")
 (get-daily-temps 1980
		  "Minimum"
		  "Christchurch (Canterbury)"))

Setup emacs eev, sbcl, series, split-sequence, screwlisps-knowledge

Find cl-series split-sequence and the prev. temperature zip your self, sorry!

Define the function used above.

This was my exploratory Series declarative lazy programming. I will do a cleaned up version of this post after the show if anyone is interested. I kinda ran out of time. It is pretty cool!

My intent was to super-simply look-directly-at publically available metric pronouncements by the New Zealand government, for example. I ran out of time to do a bigger analysis myself before tomorrow.

 (eepitch-shell)
mkdir -p ~/common-lisp
cd ~/common-lisp
git clone http://codeberg.org/tfw/screwlisps-knowledge
cd
mkdir -p ~/temps 

 (eepitch-sbcl)
 (eepitch-kill)
 (eepitch-sbcl)

(asdf:load-system :series)
(series::install)

(asdf:load-system :split-sequence)
(use-package :split-sequence)

(asdf:load-system :screwlisps-knowledge/simple-gnuplot)
(use-package :screwlisps-knowledge/simple-gnuplot)

(defun date2utime (date-string)
  (let ((list (split-sequence #/ date-string)))
    (apply 'encode-universal-time  0 0 0
	   (mapcar 'parse-integer (reverse list)))))

(defun get-daily-temps (year metric place)
  "
year should be an integer in the range of about (1922 2022)
metric one of
\"Average\" \"Maximum\" \"Minimum\"
Place one of
\"Lake Tekapo (Canterbury)\"
\"Christchurch (Canterbury)\"
\"Timaru (Canterbury)\"

Returns a fresh list of
(seconds-into-the-year temperature-in-celsius)

specifically from
~/tempts/daily-temperature-30-sites-state-1909-2022.csv
"
  (let* ((lines
	   (scan-file
	    (merge-pathnames
	     #P"daily-temperature-30-sites-state-1909-2022.csv"
	     #p"~/temps/")
	    #'read-line))
	 (lists (#Msplit-sequence (series #,) lines))
	 (data (choose (#Mnot (#Mzerop (scan-range)))
		       lists))
	 (lake-tekapo (choose (#Mequal (series place)
				       (#Msecond data))
			      data))
	 (%lt-averages (choose (#Mequal
				(series metric)
				(#Mfourth lake-tekapo))
			       lake-tekapo))
       (lt-averages (choose
		     (#Mnot (#Mequal (#Mfifth %lt-averages)
				     (series "NA")))
		     %lt-averages))
	 (utimes (#Mdate2utime (#Mthird lt-averages)))
	 (celsiuses (#Msplit-sequence (series #.)
				      (#Mfifth lt-averages)))
	 (truncated (#Mparse-integer (#Mfirst celsiuses)))
	 (decimal (#M/
		   (#Mparse-integer
		    (#Mor (#Msecond celsiuses) (series "0")))
		   (#M* (series 10.0)
			(#Mlength
			 (#Mor (#Msecond celsiuses)
			       (series "0"))))))
	 (points (#Mlist utimes (#M+ truncated decimal))))
    (sort
     (collect
	 (choose
	  (#M< (series (encode-universal-time
			0 0 0 1 1 year))
	       utimes
	       (series (encode-universal-time
			0 0 0 1 1 (1+ year))))
	  points))
     '<=
     :key 'car)))

Get the header line as a list using series

This is basically how we are going to access the csv.

(let* ((lines
	 (scan-file
	  (merge-pathnames
	   #P"daily-temperature-30-sites-state-1909-2022.csv"
	   #p"~/temps/")
	  #'read-line))
       (lists (#Msplit-sequence (series #,) lines)))
  (collect-first lines))

being:

("ï»żWKT" "site" "date" "statistic" "temperatur" "lat" "lon" "site_simpl"
 "GEOMETRY_X" "GEOMETRY_Y
")

Zero the year’s time util

In this case, orange, yellow and magenta were 2022.

To get two years in the same place.

(defun decf-t0 (list)
	   (loop
	     :with t0 := (caar list)
	     :for l :in list
	     :do
		(decf (car l) t0)
	     :finally 
		(return list)))
screwlisp proposes kittens