code-reviews

adam 2020-07-03T02:19:25.117500Z

Hey guys. How does this function look (generating some fixture data):

(defn- insert-classes! [datasource]
  (let [teachers (db/find-by-keys datasource :user {:role (db/enum (:teacher user/roles))} {:columns [:id] :limit 2})]
    (doseq [t teachers]
      (db/insert-multi!
        datasource
        :class
        [:name :school :description :archived :teacher_id]
        (take 5 (repeatedly #(seq
                               [(first (names))
                                (first (co-names))
                                (join " " (take 3 (sentences)))
                                (rand-nth [true false])
                                (:user/id t)])))))
    (println "Inserted  classes")))
Particularly the (take 5 (repeatedly #(seq part. Is it alright or it can be simplified? Still new to lazy seqs.

seancorfield 2020-07-03T02:47:34.118400Z

So the (names), (co-names) etc are all zero-arg side-effecting functions that do ... what?

seancorfield 2020-07-03T02:48:10.119200Z

And why are you calling seq on the vector?

seancorfield 2020-07-03T02:49:42.119900Z

@somedude314 Can you provide a bit more background on what exactly you're trying to do here?

adam 2020-07-03T02:56:42.123700Z

… and this: https://github.com/paraseba/faker/blob/master/src/faker/name.cljc#L41

adam 2020-07-03T02:58:02.124Z

Because this works for me:

(take 5 (repeatedly #(seq [1 2])))
And this doesn’t:
(take 5 (repeatedly [1 2]))

2020-07-03T02:58:22.124200Z

OK yeah this isn't how lazy-seqs work at all

2020-07-03T02:58:57.124400Z

on each call you are generating a lazy stream of names, and only consuming one, and on the next call you make a new stream

adam 2020-07-03T02:58:59.124600Z

I am basically trying to populate the vector inline for insert-multi!

seancorfield 2020-07-03T03:00:17.124800Z

(repeatedly #(vector 1 2))

1👍
seancorfield 2020-07-03T03:01:38.126100Z

Looks like you should map over the various lazy fakers and make a vector: (map vector (names) (co-names) (map #(str/join " " %) (partition 3 (sentences))) ...)

seancorfield 2020-07-03T03:02:11.126800Z

Then (partition 5 ...) over that to get groups of five rows each.

adam 2020-07-03T03:03:03.127300Z

What I can do about that when it’s an external library and I only need one name?

seancorfield 2020-07-03T03:03:22.127900Z

(repeatedly #(rand-nth [true false])) would give you the generator for the archived values in that (map vector ...)

seancorfield 2020-07-03T03:05:18.129300Z

I'd probably create the teacher ID series with (mapcat #(repeat 5 %) (map :user/id teachers)) and that would be the last sequence in that (map vector ...) -- the fifth and final of the sequence arguments.

seancorfield 2020-07-03T03:06:35.130200Z

That would also cause the number of teachers to control how many groups of 5 rows you got, so it would automatically grow as you changed the :limit to different values.

seancorfield 2020-07-03T03:08:01.131800Z

and finally (doseq [row-group (partition 5 (map vector (names) ...))] (jdbc/insert-multi! datasource :class [:name :school :description :archived :teacher_id] row-group)

seancorfield 2020-07-03T03:08:24.131900Z

See what I posted in the main channel.

seancorfield 2020-07-03T03:09:56.133500Z

So the key here is to take a series of (infinite) lazy sequences and use map vector to take corresponding elements from all of them and put them together in rows -- so this in turn would be an (infinite) lazy sequence of rows.

seancorfield 2020-07-03T03:11:34.134800Z

The (partition 5 ...) and the #(repeat 5 %) (inside the mapcat over the teachers) are related so pulling the 5 out of both as a local binding to class-size or something similar would make sure they stay in sync.

seancorfield 2020-07-03T03:14:26.136200Z

So you can see what I'm taking about on a small scale:

user=> (defn names [] (cycle ["Sean" "Adam"]))
#'user/names
user=> (defn co-names [] (cycle ["ACME" "Saint Mary's" "Collyer's"]))
#'user/co-names
user=> (take 2 (partition 5 (map vector (names) (co-names))))
((["Sean" "ACME"] ["Adam" "Saint Mary's"] ["Sean" "Collyer's"] ["Adam" "ACME"] ["Sean" "Saint Mary's"]) (["Adam" "Collyer's"] ["Sean" "ACME"] ["Adam" "Saint Mary's"] ["Sean" "Collyer's"] ["Adam" "ACME"]))
user=>

adam 2020-07-03T03:16:25.137Z

Thanks for the detailed input! Will try to put this together and see what I can come up with.

seancorfield 2020-07-03T03:19:13.137400Z

Here's the above with fake sentences added:

user=> (defn sentences [] (cycle (str/split "The quick brown fox jumped over the lazy dog" #" ")))
#'user/sentences
user=> (take 2 (partition 5 (map vector (names) (co-names) (map #(str/join " " %) (partition 3 (sentences))))))
((["Sean" "ACME" "The quick brown"] ["Adam" "Saint Mary's" "fox jumped over"] ["Sean" "Collyer's" "the lazy dog"] ["Adam" "ACME" "The quick brown"] ["Sean" "Saint Mary's" "fox jumped over"]) (["Adam" "Collyer's" "the lazy dog"] ["Sean" "ACME" "The quick brown"] ["Adam" "Saint Mary's" "fox jumped over"] ["Sean" "Collyer's" "the lazy dog"] ["Adam" "ACME" "The quick brown"]))
user=>

1👌
adam 2020-07-03T14:30:58.138100Z

(defn- insert-classes! [datasource]
  (let [teachers (db/find-by-keys datasource :user {:role (db/enum (:teacher user/roles))} {:columns [:id :email] :limit 2})
        class-size 5]
    (doseq [row-group (partition
                        class-size
                        (map vector
                             (names)
                             (co-names)
                             (map #(join " " %) (partition 3 (sentences)))
                             (repeatedly #(rand-nth [true false]))
                             (mapcat #(repeat class-size %) (map :user/id teachers))))]
      (db/insert-multi! datasource :class [:name :school :description :archived :teacher_id] row-group)))
  (println "Inserted  classes"))
Learned a lot, truly appreciated.

1
adam 2020-07-03T14:30:58.138100Z

(defn- insert-classes! [datasource]
  (let [teachers (db/find-by-keys datasource :user {:role (db/enum (:teacher user/roles))} {:columns [:id :email] :limit 2})
        class-size 5]
    (doseq [row-group (partition
                        class-size
                        (map vector
                             (names)
                             (co-names)
                             (map #(join " " %) (partition 3 (sentences)))
                             (repeatedly #(rand-nth [true false]))
                             (mapcat #(repeat class-size %) (map :user/id teachers))))]
      (db/insert-multi! datasource :class [:name :school :description :archived :teacher_id] row-group)))
  (println "Inserted  classes"))
Learned a lot, truly appreciated.

1