And the winner is…

In the previous post I announced that one person will win a copy of the Brazilian Portuguese translation of JavaScript Patterns. So here's the winner:


He wins a signed copy of "Padrões JavaScript". Waiting for your mailing address, Lou :)

Update: Lou Doesn't speak Portuguese, so he gets an English copy. The second winner is:


Update: Monty is not too proud of his Portuguese skills either, so third is


Asen is an awesome JavaScripter, who actually reviewed the book (thanks a million!) and he already has a copy. Next.


How I picked the winner

By writing some JavaScript in the console, of course.

The winner was to be randomly picked from all those who retweet my tweet or post a comment in the announcement. So I had to collect those.


The tweet page says there has been 27 retweets (worded a bit like 28, but looks like it's 27). The page only shows about 15 people though and I need all of them. Given how Twitter doesn't let you search older stuff, I was afraid it was too late. I had to check the API first. I was expecting I can hit a few URLs and get the data I need. Tough luck. All these auth keys, tokens, secrets and stuff got me floored.

Luckily Twitter's UI is also using the APIs. Checking the network traffic I was able to spot the request I need!

The URL is:
I only needed to change the count to something over 27, so I made it 30. Lo and behold I got the data!

The rest of the stuff I did in Safari's Web Inspector console.

Visiting the URL:

We have a JSON array as a document.

>>> var a = document.body.innerHTML
>>> a
"<pre style="word-wrap: break-word; white-space: pre-wrap;">[{"profile_link_color":"0084B4","verified":false,"not....]</pre>"

Safari puts all in a PRE behind the scenes, so this is how we get the data:

>>> var source = $$('pre')[0].innerHTML;
>>> source

eval() it:

>>> source = eval(source)
[Object, Object...]
>>> source.length

Sounds right. Now let's move all usernames into a new array using the new ECMA5 forEach fancy-ness:

>>> var all = [];
>>> source.forEach(function(e){all.push(e.screen_name)})
>>> all.length
>>> all
["jrfaqcom", "gustavobarbosa", "gabrielsilva", ...."vishalkrsingh"]

Blog comments

I had 4 comments on the original post. WordPress puts all comments in a div with class commentlist, so this allows us to grab all comments:

>>> var comments = $$('.commentlist cite a')
>>> comments.length

Now let's only grab the names, they are in the href's innerHTML:

>>> var all = [];
>>> comments[0].innerHTML
"Fabiano Nunes"
>>> comments.forEach(function(e){all.push(e.innerHTML)})
TypeError: Result of expression 'comments.forEach' [undefined] is not a function.

Eh? What? Oh, the list of HREFs is not an array but a NodeList:

>>> comments
<a href="" rel="external nofollow" class="url">Fabiano Nunes</a>
<a href="" rel="external nofollow" class="url">Gabriel Izaias</a>
<a href="" rel="external nofollow" class="url">João Rodrigues</a>
<a href="" rel="external nofollow" class="url">João Rodrigues</a>
>>> comments.forEach

So, list of nodes converted to array:

>>> comments =

Now forEach is usable:

>>> comments.forEach
function forEach() {
    [native code]
>>> comments.forEach(function(e){all.push(e.innerHTML)})

So we have a list of all names. Lets serialize it, so it can be pasted to the other window where we had the Twitter data.

>>> all
["Fabiano Nunes", "Gabriel Izaias", "João Rodrigues", "João Rodrigues"]
>>> JSON.stringify(all)
"["Fabiano Nunes","Gabriel Izaias","João Rodrigues","João Rodrigues"]"

(Simple array join and then string split will do too in this simple example)

All together

Back to the twitter window. Deserializing the comments array:

>>> comments = JSON.parse('["Fabiano Nunes","Gabriel Izaias","João Rodrigues","João Rodrigues"]')
["Fabiano Nunes", "Gabriel Izaias", "João Rodrigues", "João Rodrigues"]

Merging the two arrays

>>> all = all.concat(comments);
["jrfaqcom", "gustavobarbosa", ...."João Rodrigues"]
>>> all.length

Perfect. 31 entries. Just as many as the days in March when I announced it. So let's take the 19th array element to be the winner.

But shuffle the array a bit first.


Sorting the array by randomness. (I shuffled and reshuffled it three times, just because.)

>> all.sort(function() {return 0 - (Math.round(Math.random()))})
["ravidsrk", "anagami", "lpetrov", ...]

And the winner is:

>>> all[18]

9 Responses to “And the winner is…”

  1. Timur Poperecinii Says:

    Interesting way of doing it :) .
    I would also like to receive as gift a copy of your book.
    What would you like me to do for it ? (BTW I live in Moldova and I think this could be considered as a contribution to developing our Web developers space)

  2. Bernhard Hofmann Says:

    Firstly congratulations to Lou – this is the best JavaScript book I have and he’s sure to love it too!

    But also, this is a fun read on how the winner was selected. I just love messing about in the console as well – it’s so powerful for debugging, prototyping and “dancing with data” as you did. :D

  3. João Rodrigues Says:

    Well, at least @LouMintzer is wearing a green and yellow shirt with a small Brazilian flag on it (according to his profile picture in Twitter). If he’s not Brazilian then he might have bonds with some Brazilians, which is cool anyway. Congratulations to the winners!

  4. wallpaper hot girl Says:

    I’d need to check with you here.Which isn’t some thing I generally do! I enjoy reading a post that will make individuals think.Also, thanks for allowing me to comment!

  5. Tistsmoogma Says:

    Приглашаем присоединится Вас в нашей группе Вконтакте, посвященной заработку в интернет

  6. JSSpy » And the winner is… Says:

    [...] Source: [...]

  7. Parajumpers Outlet Says:

    “), and he is, to borrow Isaac Newton’s phrase, standing on the shoulders of giants. You really can’t go wrong with the basic Honda (Accord/Civic) or Toyota (Corolla/Camry) options,Cheap Parajumpers, although a Mazda or Nissan of the same vintage is probably going to be similarly reliable and low mpg and probably a bit cheaper. Accept the Windows XP Licensing Agreement. This pump is a bit lower than the one featured above. Instead, many companies operate customer loyalty Parajumpers Outleting pr

  8. Cheap Gucci Wallet for Men - Gucci Outlet Online Sale Store Says:

    it is possible to carry off anythingSome colors make moreover size girls appear smaller sized (black, vibrant, or darkish colors) although other colors could make them appear bigger (mild colors). The same goes for somebody who desires to appear gucci wallet for men fuller figured in specific places. Pick out a colour and design and style that appear excellent along with your particular figure. For those who can, always discover where the meeting will get location. Nearly all locations are going

  9. Barbour Wool Coats Says:

    In the international context, the arguments are relatively similar, except it much more difficult to get courts of one nation to apply the laws of another. Mint is said to be an effective mouse deterrent. The cost of parts can add up at an alarming rate, and you at least need to have important maintenance services out of the way before modifying other parts. If you keep having positive experiences where other Barbours respect his or her space they may start to become more receptive to being arou

Leave a Reply