---
layout: ../Site.layout.js
---
# Common lisp series and simple gnuplot climate data
- - «.setup eev sbcl series»	(to "setup eev sbcl series")
- - «.get year place metric»	(to "get year place metric")
- - «.csv header»	(to "csv header")
- - «.zero the year»	(to "zero the year")

One of [my most-useful-to-me pages *common lisp simple gnuplot*](/programming/screwlisps-knowledge-simple-gnuplot) which even got included in Edrx's emacs eev resources, kitten says basically no-one has visited.

<img src="../chchch1980temps.png">

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](https://gamerplus.org/@screwlisp/114618477188819714) ([Before The Live Show In 15 Hours](https://anonradio.net)).

<img src="../chchch2022temps.png">

The data comes from [data.mfe.govt.nz](https://data.mfe.govt.nz/layer/115376-daily-temperature-30-sites-state-1909-2022/).

```
(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
- - «setup eev sbcl series»  (to ".setup eev sbcl series")

Find [cl-series](https://gitlab.common-lisp.net/rtoy/cl-series/\-/wikis/Series-User's-Guide) [split-sequence](https://github.com/sharplispers/split-sequence) and the prev. temperature zip your self, sorry!

## Define the function used above.
- - «get year place metric»  (to ".get year place metric")

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
- - «csv header»  (to ".csv header")

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
- - «zero the year»  (to ".zero the year")

<img src="/programming/chchch2280temps.png">

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)))
```