SlideShare Twitter Mashup

So here’s a SlideShare/Twitter Mashup (command-line ruby code) that does these things:

  1. Gets buzzwords from Twitter. It does this by analyzing tweets and getting popular words (filtering out common ones) with the Twitter API.
  2. Gets the most popular buzz word and searches the SlideShare tag database with it (using the SlideShare API).
  3. Prints out the buzzword and the slideshows that’s associated with it.

The source code might not be a great example of filtering and getting popular words, but it’s a good demo of how simple the Twitter and SlideShare APIs are (REST yay) and how easy Hpricot makes parsing XML docs.

There’s a zip (with the source code, common_words.txt, twitter_words.txt) here: slideshare_twitter.zip. Enjoy. 🙂

Tail Recursion

Ponder this:

fact (0) ->
	1;
fact (N) ->
	N * fact (N - 1).

versus this:

fact(N) ->
	fact_helper(N, 1).
fact_helper(1, T) ->
	T;
fact_helper(N, T) ->
	fact_helper(N - 1, T * N).

The advantage of learning Erlang (albeit very slowly, with lots of interruptions) is that it directly introduces a lot of concepts I’ve been marginally aware of before. For instance, the second example implements factorial using tail recursion. The advantage is that a compiler doesn’t have to implement a call-stack when playing with arguments. See wikipedia entry.

Erlang Deliciousness

Witness: algorithm for finding factorial of a number.

fact(0) -> 1;
fact(N) -> N * fact(N - 1).

That of finding all permutations of a given string. "abc" -> ["abc", "acb", "bac", "bca", "cab", "cba"]:

perms([]) -> [[]];
perms(L) -> [[H|T] || H < - L, T <- perms(L--[H])].

That of getting the ‘next’ iteration of any string. next("a") -> "b". next("z") -> "aa". next("az") -> "ba":

next(L) -> lists:reverse(incr(lists:reverse(L))).
incr(L) when L =:= [] -> [$a];
incr([H|T]) when H =:= $z -> [$a|incr(T)];
incr([H|T]) -> [H + 1|T].

Deliciously, all these are also (with the addition of a module and export line) complete and valid erlang programs.

Stay tuned. I’m loving erlang.

Ruby Magic: Metaprogramming

Rails, if you’ve used it, has a rather elegant way of manipulating time. Stuff like 1.hours and 2.minutes.from_now just work. Let’s see how Ruby modules can be extended really really easily:

#! /usr/bin/env ruby

class Integer
  def seconds
    self
  end

  def minutes
    seconds * 60
  end

  def hours
    minutes * 60
  end

  def days
    hours * 24
  end

  def months
    days * 30
  end

  def years
    months * 12
  end

  def from_now
    Time.now + self
  end

  def before
    Time.now - self
  end
end

class String
  def palindrome?
    self == self.reverse
  end
end

class Time
  def leap_year?
    (year % 4).zero? and ((not (year % 100).zero?) or (year % 1000).zero?)
  end
end

class TrueClass
  def say
    "is"
  end
end

class FalseClass
  def say
    "is not"
  end
end

#2 is an Integer
puts 2.minutes.from_now

#"vishnu" is a String
puts "vishnu".palindrome?
puts "malayalam".palindrome?

puts 2.years.from_now.leap_year?

#Check if n years before is a leap year
puts "How many years before?"
year = Integer(readline)
puts "#{Time.now.year - year} #{year.years.before.leap_year?.say} a leap year."

The interesting thing about Ruby is not that metaprogramming is possible, but Ruby makes it really easy to do it.