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.So the (names), (co-names) etc are all zero-arg side-effecting functions that do ... what?
Consuming this https://github.com/paraseba/faker/blob/master/src/faker/company.cljc#L32
โฆ and this: https://github.com/paraseba/faker/blob/master/src/faker/name.cljc#L41
OK yeah this isn't how lazy-seqs work at all
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
What I can do about that when itโs an external library and I only need one name?
See what I posted in the main channel.
And why are you calling seq on the vector?
Because this works for me:
(take 5 (repeatedly #(seq [1 2])))
And this doesnโt:
(take 5 (repeatedly [1 2]))(repeatedly #(vector 1 2))
@somedude314 Can you provide a bit more background on what exactly you're trying to do here?
I am basically trying to populate the vector inline for insert-multi!
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))) ...)
Then (partition 5 ...) over that to get groups of five rows each.
(repeatedly #(rand-nth [true false])) would give you the generator for the archived values in that (map vector ...)
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.
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.
and finally (doseq [row-group (partition 5 (map vector (names) ...))] (jdbc/insert-multi! datasource :class [:name :school :description :archived :teacher_id] row-group)
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.
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.
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=>Thanks for the detailed input! Will try to put this together and see what I can come up with.
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=>(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.