code-reviews

roelof 2020-12-29T20:09:00.133100Z

Did I here do a good job : https://github.com/RoelofWobben/clojure_ground_up/blob/main/src/ground_up/chapter7.clj

roelof 2020-12-30T18:36:21.138200Z

do you have time to learn me what you mean

phronmophobic 2020-12-30T18:36:44.138400Z

I can answer a few questions

roelof 2020-12-30T18:37:14.138600Z

you were talking I could make my code better

roelof 2020-12-30T18:37:43.138800Z

step 1 was to find a answer to this question

roelof 2020-12-30T18:37:48.139Z

how to find the maximum element of a lazy sequence with O(1) memory

phronmophobic 2020-12-30T18:37:52.139200Z

right

roelof 2020-12-30T18:38:01.139400Z

and you were talking about reduce

roelof 2020-12-30T18:38:13.139600Z

but then I needed to sleep

roelof 2020-12-30T18:38:34.139800Z

do you mean I have to change map to reduce ?

phronmophobic 2020-12-30T18:39:24.140Z

the map in most-prevalent is fine

phronmophobic 2020-12-30T18:39:59.140200Z

maybe just try try to write a function, find-max that takes a sequence as an argument and returns the maximum value

roelof 2020-12-30T18:40:36.140400Z

oke

phronmophobic 2020-12-30T18:41:46.140600Z

with respect to most-prevalent , the goal is to replace:

(sort-by :prevalance)
      (take-last 10)
eventually with something like:
(map :prevalence)
 (find-largest-elements 10)

roelof 2020-12-30T18:41:49.140800Z

do I now need to use reduce or can I just use the method max ?

phronmophobic 2020-12-30T18:43:07.141Z

max would work, but the next goal is to try and find-max to be able to return the two largest elements rather than just the largest

roelof 2020-12-30T18:44:59.141300Z

oke, I was thinking

(defn find-max [sequence] 
  (reduce max sequence)) 
   
untested

phronmophobic 2020-12-30T18:45:13.141500Z

looks great

phronmophobic 2020-12-30T18:45:51.141700Z

constant memory, and if given a lazy sequence,can process larger than memory data sets

phronmophobic 2020-12-30T18:46:31.141900Z

now, can you improve the function to find the two largest elements?

roelof 2020-12-30T18:47:06.142100Z

if I may use a helper function

👍 1
roelof 2020-12-30T18:48:32.142400Z

`

(defn top-two [[big1 big2 :as acc] x]
  (cond
    (> x big1) [x big1]
    (> x big2) [big1 x]
    :else acc))

(defn find-two-max [sequence]
  (reduce top-two [0 0] sequencel))

phronmophobic 2020-12-30T18:49:59.142600Z

looks like there's a bug

roelof 2020-12-30T18:50:39.142800Z

then I have to test it

roelof 2020-12-30T18:50:51.143Z

wrote it right of my head

roelof 2020-12-30T18:55:51.143200Z

oke

roelof 2020-12-30T18:56:02.143400Z

this seems to work

(ns clojure.examples.hello
(:gen-class))

 (defn top-two [[big1 big2 :as acc] x]
  (cond
    (> x big1) [x big1]
    (> x big2) [big1 x]
    :else acc))

(defn find-two-max [sequence]
  (reduce top-two [0 0] sequence))

(print (find-two-max '(1 2 3 )))

roelof 2020-12-30T18:56:25.143600Z

but it given (3 2) as answer and not (2 3)

phronmophobic 2020-12-30T18:56:51.143800Z

try (top-two [1 2] 2)

roelof 2020-12-30T18:57:56.144Z

gives [ 2 1] as answer

phronmophobic 2020-12-30T18:59:03.144200Z

the answer should be [2 2]

roelof 2020-12-30T18:59:31.144400Z

oke

roelof 2020-12-30T19:00:49.144600Z

then I think I need to make another arm to the cond

roelof 2020-12-30T19:02:13.144800Z

yep

roelof 2020-12-30T19:02:26.145Z

(defn top-two [[big1 big2 :as acc] x]
  (cond
    (= x big2) [big2 big2 ]  
    (> x big1) [x big1]
    (> x big2) [big1 x]
    :else acc))

(defn find-two-max [sequence]
  (reduce top-two [0 0] sequence))

(print (top-two [1 2] 2))
gives now the right answer

roelof 2020-12-30T19:04:56.145200Z

but this is not good when I want to have a variable number I think

phronmophobic 2020-12-30T19:12:01.145400Z

there's still an issue:

(top-two [1 3] 2) ;; [2 1]

roelof 2020-12-30T19:20:37.145600Z

oops more to investigate

roelof 2020-12-30T19:20:38.145800Z

moment

roelof 2020-12-30T19:25:54.146Z

hmm, still in the dark why this is not working

phronmophobic 2020-12-30T19:27:50.146200Z

(defn top-two [[big1 big2 :as acc] x]
  (cond
    (> x big1) [x big1]
    (> x big2) [big1 x]
    :else acc))
the structure is fine, but you should double check the returns

phronmophobic 2020-12-30T19:28:13.146400Z

which cond branch is the test case taking?

roelof 2020-12-30T19:30:18.146600Z

this one (> x big1) [x big1]

roelof 2020-12-30T19:30:41.146800Z

and it schould return x and big2

👍 1
roelof 2020-12-30T19:31:11.147200Z

yep, then it doing fine

phronmophobic 2020-12-30T19:31:41.147400Z

ok, now how would you extend find-two-max to find-n-max?

roelof 2020-12-30T19:33:08.147600Z

that I find difficult

roelof 2020-12-30T19:33:30.147800Z

the only way I see it , it to use a collection that holds the highest numbers

😁 1
roelof 2020-12-30T19:34:05.148100Z

but then it is possible that too much or too little numbers are in it because it is not fixed

roelof 2020-12-30T19:35:32.148300Z

and I do not see how I can change the arms of the cond then

roelof 2020-12-30T19:37:00.148500Z

so right now im thinking I do not have enough xp to solve this one

phronmophobic 2020-12-30T19:38:12.148700Z

that's ok. sometimes it takes a little bit of time

phronmophobic 2020-12-30T19:38:18.148900Z

to come up with an answer

phronmophobic 2020-12-30T19:38:34.149100Z

especially if it's not similar to other problems you've worked on

roelof 2020-12-30T19:38:57.149300Z

I think I need some sort of loop

roelof 2020-12-30T19:39:31.149500Z

I can destruct in a parts because I do not know how many items the collection is

roelof 2020-12-30T19:39:42.149700Z

or some sort of recursion

roelof 2020-12-30T19:39:58.149900Z

I can destruct in a the first and the rest

roelof 2020-12-30T19:42:30.150100Z

sorry, I do not see it

roelof 2020-12-30T19:43:19.150300Z

get the feeling im close but miss a few pieces or do not know how the pieces fit together

phronmophobic 2020-12-30T19:45:18.150500Z

it might make it easier if acc was sorted

roelof 2020-12-30T19:46:24.150700Z

oke, acc is the outcome we wanted. Right?

roelof 2020-12-30T19:49:08.150900Z

and I have to look what is the acc is when the parameter is a collection

phronmophobic 2020-12-30T19:51:16.151100Z

I was referring to acc in top-two

roelof 2020-12-30T19:52:19.151300Z

oke

roelof 2020-12-30T19:52:40.151500Z

now I m totally confused

phronmophobic 2020-12-30T19:53:37.151700Z

I guess top-two would need to be top-n

roelof 2020-12-30T19:54:06.151900Z

I was thinking you wanted this :

(defn top-n [colllection x] ....] 

phronmophobic 2020-12-30T19:55:01.152100Z

yea

roelof 2020-12-30T20:05:24.152300Z

maybe this better : (def topn [collection :as acc x] ......)

roelof 2020-12-30T20:07:40.152600Z

if so, then I still do not see how the arms of the collection should be

roelof 2020-12-30T20:07:44.152800Z

sorry

phronmophobic 2020-12-30T20:10:32.153Z

arms?

roelof 2020-12-30T20:11:09.153300Z

yep. the arms of the cond where I have to check so I can find the highest n numbers

phronmophobic 2020-12-30T20:12:30.153500Z

so acc is the collection we're accumulating into that will contain the top n items. if acc was sorted, is there a way to check if a new value, x, should be added, replace a value, or not added?

roelof 2020-12-30T20:13:03.153700Z

yep

roelof 2020-12-30T20:13:06.153900Z

I agree

roelof 2020-12-30T20:14:02.154100Z

lets say we have now (1 2 3) and we have the number 5

roelof 2020-12-30T20:14:32.154300Z

then we schould have (2 3 5) right ?

👍 1
roelof 2020-12-30T20:16:49.154600Z

and if we have (2 3 5) and we have 1 nothing have to change

roelof 2020-12-30T20:17:08.154800Z

so the middle is never changed

roelof 2020-12-30T20:17:34.155Z

thinking aloud to see if I can figure out how to do it in code

roelof 2020-12-30T20:18:26.155200Z

no, I see how things schould be but not how to make it work in code

roelof 2020-12-30T20:19:01.155400Z

It looks like im overthinking things

roelof 2020-12-30T20:20:33.155600Z

hmm, I see a pattern

roelof 2020-12-30T20:21:40.155800Z

when I have (1 2) and the number 3 I can compare it to the 2 and keep the 2 and add the 3

roelof 2020-12-30T20:23:06.156Z

when I have (1 5 9) and the number 8 I can compare it to the last in the collection and that is not true so nothing is changed then I can compare it to the second last one and that is true so replace that number with the given number

roelof 2020-12-30T20:23:39.156200Z

so i looks I have to make a reversed loop for comparising

roelof 2020-12-30T20:25:07.156400Z

when I have (1 5 7) and a 8 I can compare it again with the last one that is true so I replace it with the 8

phronmophobic 2020-12-30T20:25:17.156600Z

there often built in data structures that will remain sorted as you add values. I can't think of one for clojure off the top of my head though, but there's probably something if I looked hard enough

roelof 2020-12-30T20:25:38.156800Z

oke

roelof 2020-12-30T20:25:59.157Z

but then still I have to delete one item and add a item

phronmophobic 2020-12-30T20:26:10.157200Z

I was thinking of something simple like: (->> (conj acc x) (sort) (take n))

phronmophobic 2020-12-30T20:26:46.157400Z

it's not the most efficient implementation, but since acc is small, it's probably fine

roelof 2020-12-30T20:27:25.157600Z

oke, but it could be very very big when someone wanted to hold the highest 50 or 100 or 1000 items

phronmophobic 2020-12-30T20:27:49.157800Z

right. it depends on the use case

phronmophobic 2020-12-30T20:28:41.158Z

if I wanted to prepare for that use case, I would probably look for a data structure on https://www.clojure-toolbox.com/ (under data structures) to see if there's already an efficient data structure for that purpose

phronmophobic 2020-12-30T20:29:08.158400Z

I would also investigate sorted-map

phronmophobic 2020-12-30T20:29:16.158600Z

and then run benchmarks

roelof 2020-12-30T20:30:01.158800Z

but I think we are going to far down the rabbit hole

phronmophobic 2020-12-30T20:30:12.159Z

right

roelof 2020-12-30T20:30:22.159200Z

I can live with a collection of 1 - 20 items now

roelof 2020-12-30T20:31:04.159400Z

oke, so now arms of a cond just the code you let me see

roelof 2020-12-30T20:31:30.159600Z

I have to try if that could work

👍 1
roelof 2020-12-30T20:35:33.159900Z

hmm. not what I expect when trying this in a online repl

(ns clojure.examples.hello
(:gen-class))

(defn top-n [[collection :as acc] x n]
  (->> (conj acc x) (sort) (take n)))

(print (top-n [1 2 ] 2 2))

roelof 2020-12-30T20:35:55.160100Z

gives [1 2] where I expect [2 2]

roelof 2020-12-30T20:37:24.160300Z

and when i do this :

(ns clojure.examples.hello
(:gen-class))

(defn top-n [[collection :as acc] x n]
  (->> (conj acc x) (sort) (take n)))

(print (top-n [1 2 ] 2 1))
I get 1 where I expect 2

roelof 2020-12-30T20:37:43.160500Z

so or I do something wrong or the code is not working

roelof 2020-12-30T20:39:41.160700Z

or do we have to add a reverse after the sort

👆 1
roelof 2020-12-30T20:43:38.161Z

yep, this is working

roelof 2020-12-30T20:43:52.161200Z

(ns clojure.examples.hello
(:gen-class))

(defn top-n [[collection :as acc] x n]
  (->> (conj acc x) 
       (sort) 
       (reverse) 
       (take n)
       (reverse)
       ))

(print (top-n [1 5 9 ] 8 2))
gives me a (8 9)

roelof 2020-12-30T20:44:06.161400Z

which is good and I like to see it this way

roelof 2020-12-30T20:44:38.161600Z

so I can use this method/function to do what you wanted to do with replacing code

roelof 2020-12-30T20:45:48.161800Z

I will try it tomorrow .

roelof 2020-12-30T20:45:55.162Z

Thanks for the lessons

phronmophobic 2020-12-30T20:45:59.162200Z

:thumbsup:

phronmophobic 2020-12-30T20:46:03.162400Z

have a good night 😄

roelof 2020-12-30T20:46:09.162600Z

maybe clojure is a nicer language then I thought

roelof 2020-12-30T20:46:25.162800Z

but a totally other one then ruby or c# or haskell

phronmophobic 2020-12-30T20:46:53.163Z

yep, it's definitely in a unique position compared to other languages

roelof 2020-12-30T20:47:19.163200Z

I hope i will once be so profient that I can do AOC or exercism challenges

roelof 2020-12-30T20:47:30.163400Z

and begin learning web development

roelof 2020-12-30T20:47:44.163600Z

I have two projects in mind

roelof 2020-12-30T20:49:43.163800Z

Can clojure work properly on Windows or can I better use linux for it

roelof 2020-12-30T20:50:48.164Z

if I get it working , I will begin with the brave book

roelof 2020-12-30T20:51:40.164200Z

I think this chapter : https://aphyr.com/posts/352-clojure-from-the-ground-up-polymorphism

roelof 2020-12-30T20:51:52.164400Z

is too much for a beginner like me

roelof 2020-12-30T20:54:16.164600Z

sorry, still one question about your feedback

roelof 2020-12-30T20:54:25.164800Z

you wrote this :

I would separate the data processing from the data loading. it's very common to want to load data from different sources and reuse the data processing functions

roelof 2020-12-30T20:54:56.165Z

but I do it , file is only the filename. the loading and parsing to json is done in the load-json method

phronmophobic 2020-12-30T20:58:53.165200Z

right, but most-prevalent is doing both loading and processing

phronmophobic 2020-12-30T20:59:04.165400Z

and there's no way to do just the data processing

phronmophobic 2020-12-30T20:59:31.165600Z

so if you had a different data source, you'd have to copy most of the code from most-prevanent

roelof 2020-12-30T21:00:43.165800Z

sorry, I miss you

roelof 2020-12-30T21:01:26.166Z

you mean if I want to do the same with a file which do not have the same fields

roelof 2020-12-30T21:03:22.166200Z

so you were talking about this part

(map (fn [county]
             {:county     (fips (fips-code county)),
              :prevalance (calculate_prevalance county field-name)
              :report-count (field-name county)
              :population  (:county_population county)
              }))
      (sort-by :prevalance)
and I thought you were talkimng about this part
(->> file
      load-json

roelof 2020-12-30T21:03:52.166400Z

if so, I have to think how to solve that

roelof 2020-12-30T22:11:46.166600Z

maybe a seperate method for that part

roelof 2020-12-31T09:46:35.166800Z

chips, not working

roelof 2020-12-31T09:47:04.167Z

(defn top-n [[collection :as acc] x n]
  (->> (conj acc x) 
       (sort) 
       (reverse) 
       (take n)
       (reverse)
       ))

(defn most-prevalent
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file field-name]
 (->> file
      load-json
      (map (fn [county]
             {:county     (fips (fips-code county)),
              :prevalance (calculate_prevalance county field-name)
              :report-count (field-name county)
              :population  (:county_population county)
              }))
      (map :prevalance)
      (top-n 10)
      (reverse)))


(clojure.pprint/print-table (most-prevalent "2008.json" :auto_thefts))
Error:
; Execution error (ArityException) at ground-up.chapter7/most-prevalent (form-init17204185006522729914.clj:70).
; Wrong number of args (2) passed to: ground-up.chapter7/top-n

roelof 2020-12-31T22:05:58.167600Z

Can you help me figure out what I did wrong ?

phronmophobic 2020-12-31T22:21:32.167800Z

you need a reduce somewhere

phronmophobic 2020-12-31T22:21:51.168Z

you need to have a find-top-n that uses reduce and top-n

phronmophobic 2020-12-31T22:22:30.168200Z

and you'll want find-top-n to have the collection as the last argument so that it works with ->> in most-prevalent

roelof 2020-12-31T22:32:05.168400Z

oke, I will think about that next year

😉 1
roelof 2020-12-31T22:59:09.168700Z

in 2 min i s here 2021

🎉 1
phronmophobic 2020-12-31T23:00:09.169Z

happy new year over there!

roelof 2020-12-31T23:00:26.169200Z

thanks you too

phronmophobic 2020-12-31T23:00:27.169400Z

i've still got 9 more hours of 2020 😕

roelof 2020-12-31T23:04:25.169600Z

oke

roelof 2020-12-31T23:05:24.169800Z

here it is now 00:04 so 2020 is over with a lot of corona lockdowns and so on

roelof 2020-12-31T23:05:32.170Z

I hope 2021 will be better

🤞 1
roelof 2020-12-31T23:20:27.170300Z

think im given up on this : Thought about this :

(def find-top-n [n]
  (reduce ((top-n n))))

roelof 2020-12-31T23:20:46.170500Z

but I need then another argument. the collection which I do not have

roelof 2020-12-31T23:21:10.170700Z

`

(defn most-prevalent
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file field-name]
 (->> file
      load-json
      (map (fn [county]
             {:county     (fips (fips-code county)),
              :prevalance (calculate_prevalance county field-name)
              :report-count (field-name county)
              :population  (:county_population county)
              }))
      (map :prevalance)
      (find-top-n 10)
      (reverse)))

phronmophobic 2020-12-31T23:27:16.171Z

(def find-top-n [n coll]
  (reduce (fn [acc x] (top-n acc x n)
           coll)))

phronmophobic 2020-12-31T23:27:31.171200Z

I haven't tested, but I think something like that should work

roelof 2020-12-31T23:30:54.171400Z

nope, it does not work

roelof 2020-12-31T23:30:58.171600Z

; Execution error (ArityException) at ground-up.chapter7/find-top-n (form-init4053567356004708660.clj:58).
; Wrong number of args (1) passed to: clojure.core/reduce

phronmophobic 2020-12-31T23:32:25.171800Z

oops

phronmophobic 2020-12-31T23:32:38.172Z

that's what I get for not typing into a repl

roelof 2020-12-31T23:32:44.172200Z

NP

phronmophobic 2020-12-31T23:32:51.172400Z

(def find-top-n [n coll]
  (reduce (fn [acc x] (top-n acc x n))
           coll))

phronmophobic 2020-12-31T23:32:55.172600Z

do those parens match?

phronmophobic 2020-12-31T23:33:26.172800Z

i'm blind without my repl

roelof 2020-12-31T23:35:20.173Z

Im going to sleep,

roelof 2020-12-31T23:35:23.173200Z

NP

roelof 2020-12-31T23:35:41.173400Z

no a wierd error message :

; Execution error (UnsupportedOperationException) at ground-up.chapter7/top-n (form-init704639222239290302.clj:49).
; nth not supported on this type: Float

roelof 2020-12-31T23:36:13.173600Z

we can look at it tomorrow or later

roelof 2020-12-31T23:38:23.173800Z

really time to sleep here . it's now 00:38

phronmophobic 2020-12-31T23:38:59.174Z

ok, have a good night

roelof 2020-12-31T23:43:05.174200Z

maybe you have your repl back

roelof 2020-12-31T23:43:18.174400Z

happy new year to you

roelof 2021-01-01T16:48:22.175300Z

if you have time and have a repl could you help me with this annoying one

roelof 2021-01-01T19:59:24.175500Z

ping

phronmophobic 2021-01-01T19:59:44.175700Z

yo

roelof 2021-01-01T20:00:04.175900Z

can we work on ther code which is still not working

roelof 2021-01-01T20:00:13.176100Z

or are you busy or do not have a repl

phronmophobic 2021-01-01T20:00:38.176300Z

I can answer some questions

phronmophobic 2021-01-01T20:01:00.176500Z

what's the code look like now?

roelof 2021-01-01T20:01:19.176700Z

(ns ground-up.chapter7 (:require [cheshire.core :as json] [clojure.pprint]))

(defn load-json
  "Given a filename, reads a JSON file and returns it, parsed, with keywords."
  [file]
  (json/parse-string (slurp file) true))


(def fips
  "A map of FIPS codes to their county names."
  (->> "fips.json"
       load-json
       :table
       :rows
       (into {})))


(defn fips-code
  "Given a county (a map with :fips_state_code and :fips_county_code keys),
   returns the five-digit FIPS code for the county, as a string."
  [county]
  (str (:fips_state_code county) (:fips_county_code county)))

(defn calculate_prevalance
  [county field-name]
  ( if (zero? (:county_population county))
         0
    (float (/ (field-name county) (:county_population county)))))
    

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
 (->> file
      load-json
      (map (fn [county]
             {:county     (fips (fips-code county)),
              :prevalance (calculate_prevalance county :driving_under_influence)
              :report-count (:driving_under_influence county)
              :population  (:county_population county )
              }))
      (sort-by :prevalance)
      (take-last 10)
      (reverse)))

(clojure.pprint/print-table (most-duis "2008.json"))

(defn top-n [[acc] x n]
  (->> (conj acc x) 
       (sort) 
       (reverse) 
       (take n)
       (reverse)
       ))

(defn find-top-n [n coll]
  (reduce (fn [acc x] (top-n acc x n))
           coll))


(defn most-prevalent
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file field-name]
 (->> file
      load-json
      (map (fn [county]
             {:county     (fips (fips-code county)),
              :prevalance (calculate_prevalance county field-name)
              :report-count (field-name county)
              :population  (:county_population county)
              }))
      (map :prevalance)
      (find-top-n 10)
      (reverse)))


(clojure.pprint/print-table (most-prevalent "2008.json" :auto_thefts))

roelof 2021-01-01T20:01:48.176900Z

and it produces this error :

; Execution error (UnsupportedOperationException) at ground-up.chapter7/top-n (form-init704639222239290302.clj:49).
; nth not supported on this type: Float

roelof 2021-01-01T20:02:08.177100Z

but we are not using nth anywhere

phronmophobic 2021-01-01T20:10:12.177300Z

if you type *e

phronmophobic 2021-01-01T20:10:17.177500Z

it should print the full stack trace

phronmophobic 2021-01-01T20:11:05.177700Z

lots of sequence functions use nth under the hood

phronmophobic 2021-01-01T20:11:41.177900Z

oh, I think I see it:

(defn top-n [[acc] x n]
  (->> (conj acc x) 
       (sort) 
       (reverse) 
       (take n)
       (reverse)
       ))

phronmophobic 2021-01-01T20:11:51.178100Z

[acc] should just be acc

phronmophobic 2021-01-01T20:12:01.178300Z

tricky

roelof 2021-01-01T20:13:24.178500Z

nope, then I get another error :

; Execution error (ClassCastException) at ground-up.chapter7/top-n (form-init3018563272993570646.clj:50).
; class java.lang.Float cannot be cast to class clojure.lang.IPersistentCollection (java.lang.Float is in module java.base of loader 'bootstrap'; clojure.lang.IPersistentCollection is in unnamed module of loader 'app')

phronmophobic 2021-01-01T20:17:17.178700Z

it seems like the issue is in top-n. do you have a guess as to what might be causing the error?

roelof 2021-01-01T20:18:51.178900Z

not complete

roelof 2021-01-01T20:19:16.179100Z

it looks like we are using something as a float where the compiler wants a collection

roelof 2021-01-01T20:19:41.179300Z

thinking now to print acc x and n

👍 1
roelof 2021-01-01T20:19:57.179600Z

to see what they exactly contains

roelof 2021-01-01T20:21:36.179800Z

he

roelof 2021-01-01T20:21:44.180Z

2.861667E-41.8142852E-4 nil10

roelof 2021-01-01T20:21:51.180200Z

so x seems to be nill

roelof 2021-01-01T20:21:55.180400Z

wonder why

phronmophobic 2021-01-01T20:25:45.180600Z

this bug is also kinda tricky

phronmophobic 2021-01-01T20:26:04.180800Z

it's because reduce isn't called with a an initial state

phronmophobic 2021-01-01T20:26:33.181Z

(defn find-top-n [n coll]
  (reduce initial-val 
          (fn [acc x] (top-n acc x n))
           coll))

roelof 2021-01-01T20:26:38.181200Z

oke, I saw that coll in the find-top-n was also not right

phronmophobic 2021-01-01T20:26:50.181400Z

with initial-val being the starting value for the reduce state

phronmophobic 2021-01-01T20:27:06.181600Z

do you know what the initial val should be?

roelof 2021-01-01T20:27:31.181800Z

doubt between 1 and 0

phronmophobic 2021-01-01T20:27:49.182Z

what type should acc be?

roelof 2021-01-01T20:29:15.182200Z

a vector

roelof 2021-01-01T20:29:19.182400Z

so I tried

roelof 2021-01-01T20:29:34.182600Z

(defn find-top-n [n coll]
  (reduce [0 0] 
          (fn [acc x] (top-n acc x n))
           coll))

phronmophobic 2021-01-01T20:30:19.182800Z

it should probably just be []

roelof 2021-01-01T20:30:24.183Z

`; Execution error (ArityException) at ground-up.chapter7/find-top-n (form-init3018563272993570646.clj:58). ; Wrong number of args (2) passed to: clojure.lang.PersistentVector

phronmophobic 2021-01-01T20:30:35.183200Z

oh whoops

phronmophobic 2021-01-01T20:30:42.183400Z

args in the wrong order

phronmophobic 2021-01-01T20:30:57.183600Z

(defn find-top-n [n coll]
  (reduce (fn [acc x] (top-n acc x n))
          [] 
           coll))

roelof 2021-01-01T20:31:49.183800Z

; Execution error (IllegalArgumentException) at ground-up.chapter7/eval22508 (form-init3018563272993570646.clj:80).
; Don't know how to create ISeq from: java.lang.Float

roelof 2021-01-01T20:33:13.184Z

(ns ground-up.chapter7 (:require [cheshire.core :as json] [clojure.pprint]))

(defn load-json
  "Given a filename, reads a JSON file and returns it, parsed, with keywords."
  [file]
  (json/parse-string (slurp file) true))


(def fips
  "A map of FIPS codes to their county names."
  (->> "fips.json"
       load-json
       :table
       :rows
       (into {})))


(defn fips-code
  "Given a county (a map with :fips_state_code and :fips_county_code keys),
   returns the five-digit FIPS code for the county, as a string."
  [county]
  (str (:fips_state_code county) (:fips_county_code county)))

(defn calculate_prevalance
  [county field-name]
  ( if (zero? (:county_population county))
         0
    (float (/ (field-name county) (:county_population county)))))
    

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
 (->> file
      load-json
      (map (fn [county]
             {:county     (fips (fips-code county)),
              :prevalance (calculate_prevalance county :driving_under_influence)
              :report-count (:driving_under_influence county)
              :population  (:county_population county )
              }))
      (sort-by :prevalance)
      (take-last 10)
      (reverse)))

(clojure.pprint/print-table (most-duis "2008.json"))

(defn top-n [acc x n]
  (->> (conj acc x) 
       (sort) 
       (reverse) 
       (take n)
       (reverse)
       ))

(defn find-top-n [n coll]
  (reduce (fn [acc x] (top-n acc x n))
          [] 
           coll))


(defn most-prevalent
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file field-name]
 (->> file
      load-json
      (map (fn [county]
             {:county     (fips (fips-code county)),
              :prevalance (calculate_prevalance county field-name)
              :report-count (field-name county)
              :population  (:county_population county)
              }))
      (map :prevalance)
      (find-top-n 10)
      (reverse)))


(clojure.pprint/print-table (most-prevalent "2008.json" :auto_thefts))

phronmophobic 2021-01-01T20:34:08.184200Z

it's not showing a line number for the error

phronmophobic 2021-01-01T20:34:28.184400Z

is there a way to do something like eval-buffer?

phronmophobic 2021-01-01T20:34:51.184600Z

usually that will fix the exception not showing a proper file and line number

roelof 2021-01-01T20:35:53.184800Z

no idea if that is possible

roelof 2021-01-01T20:36:25.185Z

is line 80 now the culprit ?

roelof 2021-01-01T20:36:37.185200Z

I use vs code with calva

phronmophobic 2021-01-01T20:36:47.185400Z

I use emacs

phronmophobic 2021-01-01T20:36:59.185600Z

line 80 might be it

phronmophobic 2021-01-01T20:37:03.185800Z

what's line 80?

roelof 2021-01-01T20:39:01.186Z

I see it

roelof 2021-01-01T20:39:04.186200Z

I think

roelof 2021-01-01T20:39:10.186400Z

the code gives now

roelof 2021-01-01T20:39:17.186600Z

(0.0051150895 0.004174161 0.0036036037 0.0030321407 0.00243309 0.002319513 0.0018750526 0.0016433854 0.0015932024 0.0015475558)
nil

phronmophobic 2021-01-01T20:40:05.186800Z

success!?

roelof 2021-01-01T20:40:20.187Z

print-table wants this :

Prints a collection of maps in a textual table. Prints table headings

roelof 2021-01-01T20:41:06.187200Z

so we loose somewhere the rest of the data

phronmophobic 2021-01-01T20:41:15.187400Z

ah, I get it

roelof 2021-01-01T20:42:28.187600Z

the old code printed the name, the prevelance, population and the number of dui

phronmophobic 2021-01-01T20:44:46.187800Z

right

roelof 2021-01-01T20:44:52.188Z

hmm, I have to think now how we can hold the data

roelof 2021-01-01T20:45:13.188200Z

it looks our find-top-n looses it

phronmophobic 2021-01-01T20:45:36.188400Z

the extra info is discarded before find-top-n is called

phronmophobic 2021-01-01T20:45:46.188600Z

do you see where?

roelof 2021-01-01T20:46:05.188800Z

o, I deleted the map but that makes another error message

phronmophobic 2021-01-01T20:47:02.189Z

right, because find-top-n expects a list of comparables (like a list list of numbers)

roelof 2021-01-01T20:47:09.189200Z

If I delete the (map : prevelance)``

roelof 2021-01-01T20:47:23.189400Z

jthen I see this :

; Execution error (ClassCastException) at java.util.TimSort/countRunAndMakeAscending (TimSort.java:355).
; class clojure.lang.PersistentArrayMap cannot be cast to class java.lang.Comparable (clojure.lang.PersistentArrayMap is in unnamed module of loader 'app'; java.lang.Comparable is in module java.base of loader 'bootstrap')

phronmophobic 2021-01-01T20:47:52.189600Z

you'll need to update find-top-n and top-n to accept a key function to sort with

phronmophobic 2021-01-01T20:47:59.189800Z

check out the docs for sort-by

phronmophobic 2021-01-01T20:48:31.190Z

and see if you can think of a way to update find-top-n and top-n to also accept a keyfn

roelof 2021-01-01T20:48:56.190200Z

oke, so I have to change (sort) by sort-by ?

phronmophobic 2021-01-01T20:49:57.190400Z

that's a good start

roelof 2021-01-01T20:50:24.190600Z

then I see this :

({:county TX, Kenedy, :prevalance 0.0051150895, :report-count 2, :population 391} {:county NM, Grant, :prevalance 0.004174161, :report-count 123, :population 29467} {:county OR, Gilliam, :prevalance 0.0036036037, :report-count 6, :population 1665} {:county OR, Sherman, :prevalance 0.0030321407, :report-count 5, :population 1649} {:county TX, Hudspeth, :prevalance 0.00243309, :report-count 8, :population 3288} {:county TX, Hall, :prevalance 0.002319513, :report-count 8, :population 3449} {:county MO, Jackson, :prevalance 0.0018750526, :report-count 1514, :population 807444} {:county TX, Refugio, :prevalance 0.0016433854, :report-count 12, :population 7302} {:county AK, Prince of Wales-Outer Ketchikan, :prevalance 0.0015932024, :report-count 3, :population 1883} {:county MD, Baltimore city, :prevalance 0.0015475558, :report-count 982, :population 634549})
nil

roelof 2021-01-01T20:51:10.190800Z

he, the names has changed, not good

roelof 2021-01-01T20:54:05.191Z

it sorts on name not on prevelance

roelof 2021-01-01T20:54:21.191200Z

|      :county |  :prevalance | :report-count | :population |
|--------------+--------------+---------------+-------------|
|  AL, Autauga |  2.861667E-4 |            15 |       52417 |
|  AL, Baldwin | 1.8142852E-4 |            32 |      176378 |
|  AL, Barbour | 1.4354926E-4 |             4 |       27865 |
|     AL, Bibb |  9.219989E-5 |             2 |       21692 |
|   AL, Blount | 1.9146418E-4 |            11 |       57452 |
|  AL, Bullock |          0.0 |             0 |       10705 |
|   AL, Butler |  3.988036E-4 |             8 |       20060 |
|  AL, Calhoun |  5.771285E-4 |            67 |      116092 |
| AL, Chambers | 4.6220067E-4 |            16 |       34617 |
| AL, Cherokee |  8.107998E-5 |             2 |       24667 |

roelof 2021-01-01T20:54:47.191400Z

when I do this :

(defn top-n [acc x n]
  (->> (conj acc x) 
       (sort-by :prevelance) 
       (reverse) 
       (take n)
       (reverse)
       ))

roelof 2021-01-01T20:55:39.191600Z

this is not funny anymore

phronmophobic 2021-01-01T20:56:48.191800Z

this list is different:

({:county TX, Kenedy, :prevalance 0.0051150895, :report-count 2, :population 391} {:county NM, Grant, :prevalance 0.004174161, :report-count 123, :population 29467} {:county OR, Gilliam, :prevalance 0.0036036037, :report-count 6, :population 1665} {:county OR, Sherman, :prevalance 0.0030321407, :report-count 5, :population 1649} {:county TX, Hudspeth, :prevalance 0.00243309, :report-count 8, :population 3288} {:county TX, Hall, :prevalance 0.002319513, :report-count 8, :population 3449} {:county MO, Jackson, :prevalance 0.0018750526, :report-count 1514, :population 807444} {:county TX, Refugio, :prevalance 0.0016433854, :report-count 12, :population 7302} {:county AK, Prince of Wales-Outer Ketchikan, :prevalance 0.0015932024, :report-count 3, :population 1883} {:county MD, Baltimore city, :prevalance 0.0015475558, :report-count 982, :population 634549})

phronmophobic 2021-01-01T20:56:55.192Z

and is actually sorted on prevalance

phronmophobic 2021-01-01T20:57:15.192200Z

where's the other list coming from?

roelof 2021-01-01T20:57:41.192400Z

which other list

roelof 2021-01-01T20:57:43.192600Z

?

phronmophobic 2021-01-01T20:57:50.192800Z

the list sorted by names?

roelof 2021-01-01T20:58:09.193Z

I found out make a typo

roelof 2021-01-01T20:58:37.193200Z

used : prevelance in place of prevalance

roelof 2021-01-01T20:58:50.193400Z

so I think the code is working again

roelof 2021-01-01T20:59:15.193600Z

this looks better

roelof 2021-01-01T20:59:22.193800Z

|                             :county |  :prevalance | :report-count | :population |
|-------------------------------------+--------------+---------------+-------------|
|                          TX, Kenedy | 0.0051150895 |             2 |         391 |
|                           NM, Grant |  0.004174161 |           123 |       29467 |
|                         OR, Gilliam | 0.0036036037 |             6 |        1665 |
|                         OR, Sherman | 0.0030321407 |             5 |        1649 |
|                        TX, Hudspeth |   0.00243309 |             8 |        3288 |
|                            TX, Hall |  0.002319513 |             8 |        3449 |
|                         MO, Jackson | 0.0018750526 |          1514 |      807444 |
|                         TX, Refugio | 0.0016433854 |            12 |        7302 |
| AK, Prince of Wales-Outer Ketchikan | 0.0015932024 |             3 |        1883 |
|                  MD, Baltimore city | 0.0015475558 |           982 |      634549 |
nil

phronmophobic 2021-01-01T21:01:17.194Z

:thumbsup:

roelof 2021-01-01T21:11:09.194200Z

I only do not know if the data is allright

roelof 2021-01-01T21:11:14.194400Z

but it looks well

roelof 2021-01-01T21:11:18.194600Z

thanks

😁 1
roelof 2021-01-01T21:12:42.194900Z

I hope I did not costs you too much with my stupid questions

roelof 2021-01-01T21:13:36.195100Z

and not much people here have the time for feedback

roelof 2021-01-01T21:15:05.195300Z

see still something wierd

roelof 2021-01-01T21:15:25.195500Z

on prevelance I sayit must be a float

roelof 2021-01-01T21:15:37.195700Z

(float (/ (field-name county) (:county_population county)))))

roelof 2021-01-01T21:15:55.195900Z

but this is not a float 8.70322E-4

roelof 2021-01-01T21:23:11.196100Z

ping any idea why this happens ?

roelof 2021-01-01T21:24:42.196500Z

this one does it right :

(defn most-duis
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file]
 (->> file
      load-json
      (map (fn [county]
             {:county     (fips (fips-code county)),
              :prevalance (calculate_prevalance county :driving_under_influence)
              :report-count (:driving_under_influence county)
              :population  (:county_population county )
              }))
      (sort-by :prevalance)
      (take-last 10)
      (reverse)))

roelof 2021-01-01T21:25:16.196700Z

and this one not :

(defn most-prevalent
  "Given a JSON filename of UCR crime data for a particular year, finds the
  counties with the most DUIs."
  [file field-name]
 (->> file
      load-json
      (map (fn [county]
             {:county     (fips (fips-code county)),
              :prevalance (calculate_prevalance county field-name)
              :report-count (field-name county)
              :population  (:county_population county)
              }))
      (find-top-n 10)
      (reverse)
      ))

phronmophobic 2021-01-01T21:29:29.196900Z

what makes you think 8.70322E-4 is not a float?

roelof 2021-01-01T21:29:45.197100Z

looks to me more scientific

phronmophobic 2021-01-01T21:29:50.197300Z

I think there are just fewer responses because it's around the holidays

phronmophobic 2021-01-01T21:30:08.197500Z

I think it's just printing it out differently

roelof 2021-01-01T21:30:26.197700Z

one does display 0.008 and the other 8e-4

roelof 2021-01-01T21:30:42.197900Z

yep, and I wonder why

roelof 2021-01-01T21:30:48.198100Z

I want both to display the same

roelof 2021-01-01T21:30:54.198300Z

if possible

phronmophobic 2021-01-01T21:31:31.198500Z

how it's formatted depends on how you're printing it and what formatter is being used

phronmophobic 2021-01-01T21:31:54.198700Z

if you care how it's formatted, you should explicitly format it

roelof 2021-01-01T21:32:04.198900Z

oke

roelof 2021-01-01T21:32:22.199100Z

so clojure.pprint/print-table can display two things different

phronmophobic 2021-01-01T21:33:26.199300Z

¯\(ツ)/¯

phronmophobic 2021-01-01T21:33:52.199500Z

> (type (float 8.70322E-4))
java.lang.Float
> (float 8.70322E-4)
8.70322E-4

roelof 2021-01-01T21:39:36.200300Z

thanks, I let it be

roelof 2021-01-01T21:41:02.200500Z

and tomorrow try to make the challenges of chapter2 of the brave book

roelof 2021-01-01T21:41:22.200700Z

Thanks a lot with all the patience with me

roelof 2021-01-01T21:41:32.200900Z

and I hope Im a good "student"

phronmophobic 2021-01-01T21:41:39.201100Z

😄

roelof 2021-01-01T21:44:08.201300Z

why the smile ?

roelof 2021-01-01T21:44:19.201500Z

I think im older then you 😛

roelof 2021-01-01T21:54:08.201700Z

GN

roelof 2020-12-29T20:09:57.133600Z

these are challenges from this page

phronmophobic 2020-12-29T20:29:13.133700Z

looks pretty good. a few thoughts: • it seems like most-duis could be written in terms of most-prevalent • most-prevalent receives a file and immediately calls load-json. I would separate the data processing from the data loading. it's very common to want to load data from different sources and reuse the data processing functions • calculate_prevalence should probably be calculate-prevalence • sort-by requires loading the full data set into memory. since you only need the 10 most prevalent values, most-prevalent could be re-written to keep at most 10 values in memory so that a larger than memory data set could be processed

roelof 2020-12-29T21:30:46.133900Z

oke, and how could I do the last point

roelof 2020-12-29T21:31:33.134100Z

the challemge said only to display the 10 most

roelof 2020-12-29T21:37:43.134300Z

the given dataset is some 18 thousand entries

phronmophobic 2020-12-29T21:38:50.134500Z

I think rewriting it so that the memory consumption is O(1) rather than O(n) is a good exercise.

phronmophobic 2020-12-29T21:40:27.134800Z

if no solution comes to mind, I would try first figuring out 1. how to find the maximum element of a lazy sequence with O(1) memory 2. how to find the 2 largest elements ... 3. finally, how to find the n largest elements ...

roelof 2020-12-29T21:40:39.135Z

may I have then hints how to do so

roelof 2020-12-29T21:40:51.135200Z

jus learning clojure for a week

🎉 1
phronmophobic 2020-12-29T21:41:54.135500Z

the same techniques would apply in just about any language

roelof 2020-12-29T21:42:37.135700Z

oke, give me then time to find the answer to the first question

roelof 2020-12-29T21:43:07.135900Z

right now no idea how I can find that out

phronmophobic 2020-12-29T21:44:28.136100Z

are you familiar with reduce?

roelof 2020-12-29T21:45:18.136300Z

yep. I have learned that

roelof 2020-12-29T21:45:50.136500Z

like (reduce + [1 2 3 4 5])

roelof 2020-12-29T21:47:36.137200Z

to add up all items of a collection

roelof 2020-12-29T21:48:05.137400Z

but it late here so if you do not mind im heading to bed

phronmophobic 2020-12-29T21:48:51.137600Z

no problem. have a good night

roelof 2020-12-29T21:48:59.137800Z

thanks

roelof 2020-12-29T21:49:27.138Z

if you still wants , we can tomorrow talk on this when it's not so late here