Fork me on GitHub
#beginners
<
2019-09-24
>
christian.gonzalez00:09:55

… is place holder for the rest of the values, it’s not valid syntax

noisesmith00:09:02

%& is valid inside #(...) but doesn't work with macros

noisesmith00:09:18

it gathers up all args that aren't referenced by number, as a list

christian.gonzalez15:09:14

i meant the ellipsis 😓

noisesmith17:09:50

there was no elipsis when I looked

kevin.zemon00:09:23

Yeah, figured.

christian.gonzalez00:09:28

hopefully someone chimes in with a better solution

kevin.zemon00:09:28

We'll see. are is actually from a forked version of clojure.test, but getting approvals on a PR with changes to that will be difficult.

kevin.zemon00:09:44

Yeah, I just started looking at that too.

kevin.zemon00:09:00

Trying to find where he gets functionize

christian.gonzalez00:09:07

oh you’re writing tests?

kevin.zemon00:09:39

Yes, this is for a test framework.

christian.gonzalez00:09:11

you might want to stick to is then iterate over your collection

kevin.zemon00:09:18

The tests are in clojure using webdriver to do the test and then a mix of webdriver and ssh to validate.

kevin.zemon00:09:05

is is also a macro that expands to use try

kevin.zemon00:09:32

(`are` actually uses is)

christian.gonzalez00:09:36

so looking at your earlier code (= (attr driver :name (name x) :value) y) this is the template for your assertion

christian.gonzalez00:09:50

you can iterate through a collection with doseq

christian.gonzalez00:09:29

then for each pair of values x y you’re concerned with, you can run that assertion

christian.gonzalez00:09:46

(doseq [[x y] [[0 0] [1 1] [2 2]] (is (= x y))) small example… anyway that’s how i’d approach the problem and not do any of that functionize stuff

kevin.zemon00:09:56

Hmm, if I changed the vector to a map (since they are :key "value" anyway) that would work, yes?

christian.gonzalez00:09:48

user=> (doseq [[x y] [[:a "a"] [:b "b"]]] (println x y))
:a a
:b b
I think you’re trying to get something like this

christian.gonzalez00:09:35

(doseq [[x y] [[:a "a"] [:b "b"] [:c "c"]]]
  (is (= (attr driver :name (name x) :value) y))
You can turn your vector into a map like you suggested and i think that’ll work

christian.gonzalez00:09:43

(doseq [[x y] {:a "a" :b "b" :c "c"}]
  (is (= (attr driver :name (name x) :value) y))

christian.gonzalez00:09:07

anyway, if you find yourself having to mess with macro expansion there’s a good chance there’s a better solution for what you’re trying to do

kevin.zemon00:09:18

Hey! Progress! Compiled and runs.

kevin.zemon00:09:26

Let's see if it passes.

christian.gonzalez00:09:53

if you look at the docs for are this is what it’s doing

Example: (are [x y] (= x y)  
              2 (+ 1 1)
              4 (* 2 2))
Expands to: 
         (do (is (= 2 (+ 1 1)))
             (is (= 4 (* 2 2))))

kevin.zemon00:09:04

yup, saw that.

kevin.zemon00:09:37

And of course that's without going into the fact that is will itself expand.

kevin.zemon00:09:37

Well, it through an exception, but I'm on the right track. Thank you so much for your time @christian.gonzalez! I need to get dinner and head home.

ericihli01:09:43

I want to use Clojure to write some web scraping scripts. I'm preferring ClojureScript for the faster startup times and as prep-work to learn how the frontend side of things works. I chose planck for no particular reason. This is where I'm stuck. I fire up Emacs with https://github.com/clojure-emacs/inf-clojure installed. I set inf-clojure-generic-cmd to planck -d.

(require '[planck.http :refer [get]])
(... (:body (get "")))
Now how do I get elements from that string? Is there a library similar to Python's BeatifulSoup? Searching DDG for "clojurescript html parsing" doesn't return anything that stands out as useful and I feel like that might be a silly thing to search for. Maybe the reason there's no library is because this entire ecosystem is built on JavaScript and there's some obvious internal I'm missing? Regardless of how it's really done, I can't even figure out how to get access to something like jQuery which is another question I have. I see the wrapper jayq, but executing (require '[jayq.core :refer [$]]) with planck -D jayq:2.5.5 just results in Execution error (ReferenceError) at (<cljs repl>:1). Can't find variable: jQuery

noisesmith01:09:37

@ericihli in order to use jayq you need too make sure the jquery lib is available, you might have better luck using google's more modern closure library (goog.*) instead https://developers.google.com/closure/library/docs/gettingstarted

noisesmith01:09:59

closure comes with the java cljs compiler, I don't recall if it comes with planck though

mfikes01:09:54

Yeah, Planck ships with Google Closure Library

noisesmith01:09:56

eg. call goog.dom.createDom on your string to get a data structure

noisesmith01:09:04

then use the other goog.dom functions on that structure

noisesmith01:09:27

iirc there might be a cljs version of the enlive scraping / templating lib as well

ericihli01:09:06

Ah hah. That might be what I was looking for. I went to their api docs and searched for document when I realized that's what all their functions worked on and the only thing I saw was xml.createDocument but that gave me the same error that it couldn't find a document to work on. I didn't find dom.createDom. Let me try that.

noisesmith01:09:07

oh wait - I think I had a visual off-by-one error and constHtmlToNode might be the right thing

noisesmith01:09:25

that's the one that takes html string(s)

ericihli01:09:34

Rad! Thanks!

sova05:09:19

I want to keep a ranking of users... what sort of datastructure would be good? a map indexed by rank?

sova05:09:56

user-rank { 1 {:username "hax0r"} 2 {:username "pax0r"}}
for example

sova05:09:04

would that be good? Is there better?

sova05:09:43

orrrr, can I leave it like a vector of maps

sova05:09:52

and then keep a key in there :rank

sova05:09:05

and then do sort-by and reduce-kv or something each time?

sova05:09:19

(maybe too silly and computationally intense for no good reason)

sova05:09:28

lay it on me, what cha think

andy.fingerhut06:09:52

There is a library called data.priority-map that, like a normal map you insert key/value pairs into it, but unlike a normal map when you call seq on it, it is guaranteed to return the key/value pairs in order by the value, which is the "priority" that you pick.

andy.fingerhut06:09:07

Not sure if that would be useful in your case: https://github.com/clojure/data.priority-map

sova06:09:48

that's actually perfect sounding

sova06:09:30

let me see. thanks a lot andy

sova06:09:05

Well, my use-case might be simpler.

sova06:09:03

Select number of users get initial invite codes that work. when a friend submits for their own invite code they have to use a working one as a referral. friend submits a referral and gets their own code. originating user gets a rise in rank.

sova06:09:42

my english at midnight is something to suffer thru, i apologize. beta invites. get your own invite, share it, compete with other users to rise up in ranks so you get one of the beta tester slots.

sova06:09:32

I think using a map that simply has the integers as the base-level keys is good for this, but I'm not sure how to update the order smoothly without messing everything up and klobbering stuff, so maybe priority map be the way.

sova06:09:09

can i force a key to be equal to a number of elements? o.O

sova07:09:43

Hmm. How about just reducing a sorted set into a rank for the item i'm interested in?

dharrigan12:09:56

I can do this, (->> coll :a-key) to return back the value of that key, why does, then (def xf (comp :a-key)) (into [] xf coll) fail (and throw a null pointer)?

mail99212:09:56

(comp :a-key) is the same as :a-key, so your form could be written (into [] :a-key coll)

ataggart14:09:28

Try (def xf (map :a-key))

dharrigan07:09:45

Thanks Alex!

gon12:09:50

:a-key is not a transducer

dharrigan12:09:50

ta hans and paolo! 🙂

sova14:09:42

How to get the position of an element in a sorted set?

sova14:09:14

map-indexed to the rescue!

sova14:09:26

(println (map-indexed (fn [idx p]
               {:name (:firstname p)
                :rank (inc idx)})
             (sort-by :num-verified > @user-atom)))

borkdude14:09:27

I don't know if a sorted set supports index-of like behavior, but you could do it like this:

(reduce (fn [idx e] (if (= e :dude) (reduced idx) (inc idx))) -1 (sorted-set :foo :a :bar :dude :baz))
2
or with map-indexed indeed

sova14:09:57

I was trying to keep it sorted initially, keep the keys as integers of the rank

sova14:09:03

but then i have to use a human brain to move things around the set...

borkdude14:09:40

if you want to lookup something by something, it's often handy to keep it in a map from something to something

sova15:09:38

now i've opted to keep a number of votes in each map and then invoke a sort-by when need be, but i was hoping to avoid all this sorting computation itme.

sova15:09:56

since users might want to know their rank multiple times even in a minute...

danieleneal15:09:26

Not ready yet but once I’ve got the new release out I imagine you could rustle something up with https://github.com/riverford/compound/tree/compound2 - with a primary map index and a secondary sorted set

sova15:09:32

looks really neat , i might not have the number of brain cells required to make sense of it

danieleneal15:09:55

I’ll try and remember to let you know when its out and knock up an example

danieleneal15:09:17

even if you use something else, it would be a fun thing to put in the doco

danieleneal15:09:59

to be clear you’ve got a list of things being voted on and want to be able to access them perhaps by id but also to keep a sorted version around ?

sova15:09:07

actually a little different

sova15:09:13

hacker news mention was a red herring

sova15:09:37

i'm just keeping a list of users ranked by "number verified invites" to give out beta access to the first 50 people

sova15:09:17

I want to know how Hacker News keeps a ranked list of Everything

sova15:09:30

powered by Arc (=lispy)

borkdude15:09:52

@sova maybe (def s (sorted-set-by (fn [x y] (< (:score x) (:score y))) {:score 101} {:score 99})) can also help?

alexmiller15:09:21

You need a total sort

alexmiller15:09:11

Andy’s comparator guide covers this https://clojure.org/guides/comparators

sova16:09:20

I have a vector of maps, I want to update one keyed value in one particular map...

sova16:09:36

I feel like I can use update-in but i'm not sure

lucio17:09:44

As long as you know the index position of the map in your vector you can :)

sova16:09:56

Thanks for mentioning Total Sort

sova16:09:24

ah assoc-in could work, i'm just setting it to true...

sova16:09:30

Thanks ^-^

sova17:09:12

oh no the null pointer exception found out where i live! :x

sova18:09:21

This function returns a null pointer and i don't know why.

sova18:09:32

(:rank (first (filter #(= (:code %) code)  (map-indexed (fn [idx p] {:code (:code p) :rank (inc idx)})  (sort-by :num-verified > @user-rank)))))

sova18:09:32

(:rank (first (filter #(= (:code %) code)  (map-indexed (fn [idx p] {:code (:code p) :rank (inc idx)})  (sort-by :num-verified > @user-rank)))))

lennart.buit18:09:20

stylistic choice: use threading or transducers here, which bracket is which is hard to read here

noisesmith18:09:04

do you mean it throws an npe?

sova18:09:06

basically just a filter, i am trying to insulate around nils but when it finds a matichng entry the GET says nullpointer exception

sova18:09:16

yes when accessed via browser ...

sova18:09:24

i dunno what's wrong with it because it works in repl as expected

noisesmith18:09:35

OK, get never throws, but inc will throw if idx is nil

sova18:09:47

oh! thanks

noisesmith18:09:50

so will > if :num-verified is nil

sova18:09:50

what do i do?

noisesmith18:09:24

either use (fnil inc 0) instead of inc, or do some sort of validation / cleanup of the data

noisesmith18:09:06

(ins)user=> (inc nil)
Execution error (NullPointerException) at user/eval1 (REPL:1).
null
(ins)user=> ((fnil inc 0) nil)
1

sova18:09:29

thanks so much

sova18:09:37

i was really pulling out beard over it

noisesmith18:09:25

umm... actually map-indexed insures idx is never nil

noisesmith18:09:32

so it has to be the > in sort-by

davidomarfch23:09:05

What are the things that allow REPL-driven development to work as fine as it does in Clojure? I suposse immutability is one of the most important ones.