This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-11-14
Channels
- # announcements (8)
- # babashka (37)
- # beginners (4)
- # biff (19)
- # cider (18)
- # clj-kondo (52)
- # clojure (26)
- # clojure-brasil (5)
- # clojure-dev (12)
- # clojure-europe (34)
- # clojure-nl (1)
- # clojure-norway (32)
- # clojure-uk (7)
- # core-logic (1)
- # data-science (5)
- # emacs (14)
- # honeysql (11)
- # hyperfiddle (37)
- # jobs (1)
- # malli (4)
- # off-topic (38)
- # pedestal (7)
- # portal (30)
- # releases (1)
- # remote-jobs (1)
- # tools-build (8)
- # vim (12)
fake news: > Above 8 cores, the scheduler interval remains constant rather than increasing further
Og den resulterende CSV-fila ser helt jævlig ut med doble quotes ""
rundt både nøkler og verdier, etc. Så jeg må også finne ut av det 😅 Antagelig pga. nøsta maps? :thinking_face:
"{""creationDate"" ""2021-11-18T12:53:02.566Z"", ""labelId"" ""ABC123"", ""transmission"" {""transmissionCount"" 0, ""lastSuccessfulTransmissionDate"" ""2021-12-14T10:08:14.928Z"" [...]
Tipper det også til gå til helvete når jeg kjører den for å hente 2.8 millioner rader. Antagelig må all data lastes inn i minne før det skrives til CSV. Så jeg må vel også finne ut av hvordan jeg kan "streame" til CSV-fil én side av gangen.Problemet er at du kanksje ikke skal skrive det som csv, men bare anta at det er csv og skrive det rett til disk?
Jeg får JSON (dypt nøsta) fra et eksternt API, som jeg forsøker å gjøre flatt og dumpe ut som CSV til disk for en kis som skal jobbe med dataene i Excel 😅
Jeg er usikker på hvordan en kan gjøre et array av dypt nøsta JSON objekter til en flat CSV. Det er nok der problemet ligger mistenker jeg.
Hvis du heller ville prøve iteration
, kunne det vært noe a la:
;; fake server
(def total-count 2799733)
(def page-size 100)
(def page-count (inc (long (/ total-count page-size))))
(defn count-on-page [page-num]
(min page-size
(- total-count (* page-size (dec page-num)))))
;; du kan swappe inn din get-page her eller i step under,
;; men assoce inn page-num og page-size for å få :kf under til å funke
;; normalt vil vel disse komme i retur fra api-et
(defn produkter-api [page-num page-size]
(assert (pos? page-num))
{:my/page-size page-size
:my/page-num page-num
:count total-count
:values (repeatedly (count-on-page page-num) #(rand-int Integer/MAX_VALUE))})
;; client
(defn get-pages [page-size]
(fn get-page [page-num]
(produkter-api page-num page-size)))
(->>
(iteration
(get-pages page-size)
:initk 1
:somef (fn did-get-values? [step-res] (boolean (seq (-> step-res :values))))
:kf (fn next-page-num [step-res] (when (= (-> step-res :my/page-size)
(-> step-res :values count))
(inc (-> step-res :my/page-num))))
:vf (fn values-from-step [step-res] (-> step-res :values)))
(sequence cat)
(into [])
(count))
For å skrive (streame?) til CSV, f.eks. bytte siste der til:
(with-open [w (io/writer "/tmp/demo.csv")]
(->>
(iteration
(get-pages page-size)
:initk 1
:somef (fn did-get-values? [step-res] (boolean (seq (-> step-res :values))))
:kf (fn next-page-num [step-res] (when (= (-> step-res :my/page-size)
(-> step-res :values count))
(inc (-> step-res :my/page-num))))
:vf (fn values-from-step [step-res] (-> step-res :values)))
(run! #(csv/write-csv w [%]))))
Wow, der var det mange fine tips, @U0523NZUF! Tusen takk! min
var veldig smooth også!
Mye penere enn: (if (> page-count 0) page-count 1))
Der var voldsomt mye greier man måtte sende inn til iteration
. Jeg ble ikke klok på https://clojuredocs.org/clojure.core/iteration og det var ikke så mange konkrete eksempler der enda. Jeg sliter faktisk en del med å lese offisielle Clojure "docstrings" generelt. De er nesten for kortfattet og kompakte til at jeg klarer å forstå hva det betyr i praksis 😅 Særlig for "higher-order greier."
https://hackage.haskell.org/package/base-4.19.0.0/docs/Prelude.html#v:foldr
foldr :: (a -> b -> b) -> b -> t a -> b

Når man leser samme setning ti ganger og fortsatt er like dum som når man startet 😂
Egentlig kunne jeg trengt en generell tutorial på "How to Read and Understand ClojureDocs"
Noe som forklarer "formatet," de noe kryptiske begrepene og forkortelsene som blir brukt oftest. Fraværet av typer gjør det egentlig mer vanskelig å lese synes jeg, fordi en kan ikke umiddelbart se hva et parameter skal være. Er dette en funksjon eller en map eller hva?
Det er en del konsepter man må ha oversikt over i det første eksemplet også, så vet ikke hvor lett det er å se/forstå hva den koden egentlig gjør? Jeg også slet med å skjønne nytten/bruken av iteration ut fra docstringen, og trengte noen eksempler. Nå som jeg har lært mønsteret, foretrekker jeg iteration for denne typen operasjon. iteration (k er ‘continuation token’): • step-fn for å gjøre hvert steg • initk optional start-verdi inn til step-fn, ellers nil (f.eks. første side eller id, eller whatever, kan også være en map/vector) • somef får resultatet fra steget og avgjør om man fikk noen verdier • kf får resultatet fra steget, og returnerer token for eventuelt neste steg - ellers (nil) avbrytes iterasjonen • vf får resultatet fra steget og samler opp verdiene, hvis man fikk noen (hvis true fra :somef) Men ja.. docstringen er mer matematisk/presis enn min oppsummering der:) Må nesten bare akseptere at en del docstrings i core er for eksakt definisjon inkl edge cases, og så må man bruke andre kilder for å lære seg bruken.
inc
og dec
er for øvrig også veldig nice!
Mye penere enn (+ n 1)
og (- n 1)
som jeg driver med :man-facepalming:
Jeg vet ikke om jeg er helt stø i alle Clojure-begrepene, men vf (value fn) henter ut verdien fra steget, ikke at den ‘akkumulerer’ noe. iteration lager en seqable/reducible, så i eksemplet med write-csv/run! der så tror jeg den ‘streamer’ det. Jeg testet med -Xmx1g og stoppet en CSV-fil etter 5 GB (hvis jeg gjorde det riktig, da). Eksemplet med sequence/into vil derimot putte alt i én vector. (Derfor docstrings;)
La merke til nå at det er linket til et regnerark i denne kanalen "bedrifter som bruker clojure i norge". Vedlikeholdes denne listen? I så fall må vi få http://anteo.no inn der 😄