citizen428.blog()

Try to learn something about everything

Fun With the GitHub API and Ruby

Often when I want to tell someone about cool projects I’m watching on GitHub, I can’t remember their names. Now wouldn’t it be nice if I could look them up without actually having to open a browser tab, logging into the site and so on? Here’s a quick script to do just that:

Example output (shortened):

1
2
3
4
5
mbabineau/cloudviz: Makes nice graphs of Amazon CloudWatch data using ...   (14)
quirkey/sinatra-gen: Rubigen based generator for new sinatra projects        (126)
      jcoglan/heist: Scheme in as little Ruby and as much Scheme as pos...   (125)
        red667/tecc: The Euler Coding Collective                             (7)
       fogus/potion: _why the lucky stiff's little language                  (39)

I know that there are several gems for interacting with GitHub, but thanks to the awesome HTTParty it takes about as long to just implement the relevant part of the API yourself as it would take to actually find said gems, install them and glance over their docs. In case this looks a bit over-engineered, I have a couple more ideas I might add in the future, so I already prepared the code for that (e.g. the API_METHODS hash). Once I do that I’ll also not hardcode the user name, separate out… who am I kidding, it’s just another throwaway script, but at least it’s somewhat useful…

A Ruby Reading List

Since I just compiled this list for the RubyLearning forums, I might as well post it here. Below you’ll find articles I often recommend to our students, plus some personal favorites:

A Poor Man’s REPL in Ruby

I love all the little discussions on RubyLearning, especially when they lead to me writing stupid code the world doesn’t need. ;-) Today: a poor man’s REPL in 2 lines of Ruby 1.9:

1
2
repl = -> prompt { print prompt; puts(" => %s" % eval(gets.chomp!)) }
loop { repl[">> "] }

Behold the wonder:
1
2
3
4
5
6
7
8
>> 2 + 3
 => 5
>> "foo".upcase
 => FOO
>> [].class
 => Array
>> %w(foo bar)[0]
 => foo

Destructuring Binds in Ruby

When we “swap variables in Ruby”, what really happens is something called “a destructuring binding” in other languages:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>> x = 10
=> 10
>> y = 20
=> 20
>> x.object_id
=> 21
>> y.object_id
=> 41
>> x, y = y, x
=> [20, 10]
>> x.object_id
=> 41
>> y.object_id
=> 21

This is only the beginning though:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
>> a = [1, 2, 3, 4, 5]
=> [1, 2, 3, 4, 5]
>> # assign first 2 elements to x and y
>> # throw away the rest
>> x, y = a
=> [1, 2, 3, 4, 5]
>> x
=> 1
>> y
=> 2
>> # assign first 2 elements to x and y
>> # assign rest to z
>> x, y, *z  = a
=> [1, 2, 3, 4, 5]
>> x
=> 1
>> y
=> 2
>> z
=> [3, 4, 5]
>> # assign first 2 elements to x and y
>> # throw away the third
>> # assign the rest to z
>> x, y, _, *z = a
=> [1, 2, 3, 4, 5]
>> x
=> 1
>> y
=> 2
>> z
=> [4, 5]
>> # if there aren't enough rvalues,
>> # remaining lvalues are nil
>> a, b = 1
=> 1
>> b
=> nil

The reason I’m posting this long explanation is that destructuring is often useful and can do much more for you than “just” swap variables, yet I rarely see it used to its full potential in Ruby. If only we could have Clojure’s destructuring in Ruby…

Ruby and the Principle of Least Surprise

I generally observed that people tend to bring up the POLS when they find one specific aspect counter-intuitive. For example you sometimes will hear people complain about how the “modulo operator” (String#% really) is used for formatting strings in Ruby which in their opinion violates the POLS:

1
2
>> "%05d" % 123
=> "00123"

Well, when you start out from the wrong assumption that the percent sign is the “modulo operator”, you can only reach wrong conclusions.

In mathematical textbooks you will generally find ‘mod’ used in this context, which is also the operator used in e.g. Haskell. The surprise in this case stems from the assumption that the symbol % is in some way tied to the modulo operation, which it only is in some programming languages (mod, rem, \, remainder, modulo, |~, %% and IDIV being some other options).

This is not intended to sound harsh, I just think that whenever you feel Ruby violates the POLS, it’s probably a good time to check your own assumptions and find out that for people with a better understanding of the topic at hand, the POLS most likely did not get violated. Don’t confuse “what I would expect” with “what the majority of people knowledgeable in a given area find surprising”. When I traveled in Bulgaria I found it very confusing that people there shake their head for “yes” and nod for “no”. Turns out all the locals were perfectly fine with it… ;-)

Good Math Teachers Are Like Unicorns

There’s a striking similarity between unicorns and good math teachers: both are mythical creatures you really wish existed whereas empirical evidence strongly suggests they don’t.

Looking back at my own experience in Austrian public schools, the average quality of math teaching was atrocious. It’s only partly the teachers’ fault though, since math generally seems to be taught in a rather frustrating way. There’s a definite tendency to leave out vital information like why a mathematical method was created, what problem it was meant to solve and how it evolved over time. Instead of starting from the perspective of a tangible problem and looking at the development of methods to solve it, we get a high-level abstract view and are kinda left in the dark as to how that ever may be useful, leading to the common misconception that “math is useless in everyday life”. It’s a bit like teaching kids about DNA and expecting them to see deer frolicking in the forest before their mental eye. That being said, it still often is the teacher’s fault: sometimes it feels like schools are elephant graveyards where old mathematicians go to die, so poor students often end up with grumpy frustrated people who barely seem to remember why they got into math in the first place and therefore definitely don’t create the spark necessary to ignite a young person’s mind.

In retrospect, this makes me quite angry. As long as I can remember I have loved numbers in an almost obsessive way. When I get bored I start counting things around me, try to find patterns in tiles or do random calculations. So of course I always loved math in school and tended to do very well. Then 7th grade came and the subject slowly started to get more abstract. Bad methodology, combined with awful teaching and beginning puberty on my part were enough to make math my most feared subject in the years to come. Occasionally my original enthusiasm for the subject resurfaced and my grades got a bit better again when we began with calculus. Math still mainly was a major pain in the behind for me though. This only changed when at age 17 I finally convinced my parents of how broken the Austrian public school system was and switched to a private school where class attendance was voluntary and everything more or less worked like it later would at uni. This was the only time I can remember where I was lucky enough to have a good math teacher. In fact he wasn’t only good, he was excellent and is probably one of the main reasons why I’m now studying math. He did an incredible job making us understand the beauty of the subject and managed to get good results out of almost everyone by never accepting an “I don’t understand this”. He would just go back to the last line the student understood and start working from there: “How did we get to this line?”, “Do you see what substitution we did?”, “Now how do you think we got from B to C?” etc. Using this method, the students generally managed to solve the exercises and obviously were proud and therefore slowly got over the “math is not for me” type of thinking. As an additional benefit everyone who was afraid of asking also got a very detailed explanation and would be more likely to ask a question him- or herself next time. Our teacher also was very good at assessing a student’s level and therefore could give you tailor-made exercises to avoid frustration or boredom. His classes were definitely among the best I saw in almost 20 years of formal education.

Anyway, when it was time to decide what to study at uni, part of me wanted to do math because of my original love for the subject and the great classes I just had experienced. The greater part however still hadn’t gotten over the feeling of insufficiency accumulated over the years of lost interest due to bad teaching, so in the end I settled on studying Chinese, which was fun but a rather random choice and not all that useful in hindsight. Only after I turned 30 last summer I finally decided I want to give math at university level a try and signed up for an undergrad math degree at a distance learning university. So far everything seems to be going well – given the fact that I didn’t do much math in the last 10 years except for reading the occasional book on the subject – and I’m really enjoying it.

I don’t really believe I will ever become a great mathematician, but it is quite frustrating that school almost stopped me from at least trying.

Incanter and the Birthday Paradox

As a little follow-up to my recent post on the Birthday Paradox I decided to clean up the code and also plot the relationship between group size and the probability of a shared birthday with Incanter (mostly because I wanted to show off 1.2’s hot new default theme).

Code:

Screenshot:

Birthday Paradox plotted by Incanter on Twitpic

I just love how easy it is to explore problems like this with Clojure and then use Incanter go get some cute little plot too! :-)

Update: Incanter’s author David Liebke sent me a version of the above that fits into one tweet and another one with a Latex annotation! I updated my code to incorporate some of his suggestions.

Wouldn’t It Be Nice if Ruby…?

I love questions that start with “Wouldn’t it be nice if Ruby <insert perceived missing feature>?” because more often than not the answer is: “Just tell it to!”

Something like this happened on RubyLearning today, when fellow mentor José asked “Wouldn’t it be nice if Ruby was smart enough to realize that when a division has a remainder then it should use a floating result?” and once again the answer was “You mean like this?”:

I’m definitely not saying monkey-patching core classes with unexpected behavior is a smart idea (it’s NOT), but I always like how you can add behavior to Ruby if you really feel it’s necessary (and once again, I don’t in this case).

The Birthday Paradox in Clojure

The Birthday Paradox is an interesting little problem in probability theory. To quote Wikipedia:

[…] the birthday problem, or birthday paradox pertains to the probability that in a set of randomly chosen people some pair of them will have the same birthday. In a group of at least 23 randomly chosen people, there is more than 50% probability that some pair of them will have the same birthday. Such a result is counter-intuitive to many.

I don’t really find this counter-intuitive, but as Kalid from BetterExplained accurately observed “exponents aren’t intuitive” and “humans are a tad bit selfish”. Here’s a quote regarding that last comment:

In a room of 23, do you think of the 22 comparisons where your birthday is being compared against someone else’s? Probably.

Do you think of the 231 comparisons where someone you don’t know is being checked against someone else you don’t know? Do you realize there are so many? Probably not.

The fact that we neglect the 10 times as many comparisons that don’t include us helps us see why the “paradox” can happen.

So let’s use Clojure to see why math works better than people’s intuition:

Happy birthday everyone!

Curious? Clojure to the Rescue!

When reading John Derbyshire’s excellent book Prime Obsession, I stumbled upon the following interesting footnote about Euler’s number:

Here is an example of e turning up unexpectedly. Select a random number between 0 and 1. Now select another and add it to the first. Keep doing this, piling on random numbers. How many random numbers, on average, do you need to make the total greater than 1? Answer: 2.71828…

Personally I found this rather intriguing, so I decided to try this out for myself. Clojure seemed to be an obvious choice for this, since it’s very easy to express ones thoughts in code.

Let’s start with a function that will tell us how many random numbers we needed to sum up to get over 1:

Next we will create a function that will take n elements from an infinite list generated from another function:

We are doing this because def-ing a seq will cache it:

Now we have to find out how many numbers it takes on average to go over 1:

Let’s wrap it all up and also display the results as floats:

Sure enough, the results seem to be around the value of e, curiosity satisfied. Last but not least the final program in all its glory:

Note: this will die with an OOM error when you try to calculate the average of a too long list. Fixing this is left as an exercise for the reader (“holding on to the head” will probably be useful as a search term).