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