Anagrammatically Ruby

For the past few weeks, I have been looking into Ruby. I’m still learning, but I have been playing with Sinatra and Rails, and along the way, I have conducted some experiments to understand the language a bit better.

Two of the things I like the most with Ruby came very handy for this one: iterators and the way you can chain function calls. Inspired by this, I wanted to solve this problem. The first result was doing it with a Java reflex:

words = {}
IO.readlines("/usr/share/dict/words").each do |word|
  hash = word.chomp.downcase.split(//).sort.join
  if !words.has_key?(hash)
    words[hash] = []
  end
  words[hash] << word.chomp
end
words.values.each do |value|
  if value.length > 1
    puts value.join(",")
  end
end

Symptomatic of this Java-flavoured version is the if !words.has_key?(hash), testing for the presence if the hash key to initialize the value with an array. But we’ll get back to that later.

The other Java-looking thing is the test if value.length > 1 for filtering out single values. As you can use closures in Ruby, this piece can be neatly rewritten as follows:

words = {}
IO.readlines("words").each do |word|
  hash = word.chomp.downcase.split(//).sort.join
  if !words.has_key?(hash)
    words[hash] = []
  end
  words[hash] << word.chomp
end
words.values.find_all{|elt| elt.length > 1}.each do |value|
    puts value.join(",")
end

Now is time to get rid of the test for the presence of the key. A little search gives an interesting result indicating how the value can be automatically initialized with an array when the key is not present:

words = Hash.new { |h,k| h[k] = [] }
IO.readlines("words").each do |word|
  words[word.chomp.downcase.split(//).sort.join] << word.chomp
end
words.values.find_all{|elt| elt.length > 1}.each do |value|
    puts value.join(",")
end

Then, it is just a laugh, you can rewrite the blocks so that they hold on a single line:

words = Hash.new { |h,k| h[k] = [] }
IO.readlines("words").each{ |word| words[word.chomp.downcase.split(//).sort.join] << word.chomp }
words.values.find_all{|elt| elt.length > 1}.each{ |value| puts value.join(",") }

Pretty cool stuff. This little experiment shows how handy the blocks in Ruby are; again, I’m still learning, but I somehow have the feeling that this could be reduced a bit further — albeit at the expense of readibility.

Draw the Character You’re Looking For

You’re writing some nice LaTeX document, and there is some character whose command you can’t remember. Well, Detexify is a nifty little webapp that allows you to draw the symbol or character you’re looking for, and returns you a list of potential candidates. Pretty cool stuff, since you can “teach” the beast to recognize your symbols, and the code is available on git (have to get back to Ruby these days… looking at the code makes you wonder why you still bother with all that Java overhead).

Simple and smart.

Ecology and Font

That’s Ecofont, a font with “holes” mentioned by National Geographic. A (Dutch) font with holes, which therefore “uses up to 20% less ink” according to the ecofont website. It is based on Vera sans, the omnipresent font on Linux platforms these days. It is available and sounds like a creative marketing coup more than anything (I guess not printing still remains the best solution, though).

Installing Latin Modern Fonts in LaTeX

The UK TUG FAQ page is a wonderful treasure for anything LaTeX-related, but after I spent quite some time trying to install the Latin Modern fonts on my Ubuntu box, it appears that this entry could do with a bit more details.

First, you obviously have to have a local texmf directory, hashed properly:

mkdir ~/texmf
texhash ~/texmf

You can then stick all your “local” LaTeX files in there (as the TDS spec indicates, it is unclear what “local” means, either any file outside your TeX distribution, or a file created locally. Whatever you prefer, I guess); it is all very well explained there: https://help.ubuntu.com/community/LaTeX.

Now, I happened to want to install Latin Modern after reading the frenchb documentation (Goodness me, memories, memories…), and the FAQ linked above seemed to be indicating that it was a mere piece of cake. Well, if you happened to download the gzipped tar version of the archive like I did (as opposed to the zip archive), the files are stored like this:

/tex-archive/fonts/lm/

And then, you have the correct tex, doc, fonts structure. These are the folders you must stick right under ~/texmf — the fonts folder right under tex-archive really got me there. You then run as per the FAQ:

updmap --enable Map lm.map

(Not sure if this matters — I’m not familiar with updmap yet… — but I ran this in /tex-archive/fonts/lm/). Import lmodern and fontenc with the T1 option, and that should be it.

Now, I’ve not played with LaTeX for quite a long time, but man this looks good…

4.png

Find a Class in Jars

I often have to find a class (or its different occurrences) in a list of jars located in a folder (or its sub-folders). The Jython script below parses all the jars in a location, and display the name of all the jars containing the class I’m looking for. Stick it into a file called “searchjar.py.”


import os, sys, traceback

from os.path import isdir,join

from java.util.zip import *

from java.util.jar import *

from java.io import *

    def scan_directory(class_name, directory=’.’):
        for f in os.listdir(directory):
                if os.path.isdir(join(directory, f)):
                        scan_directory(class_name, join(directory, f))
                if os.path.basename(f).lower().endswith(’.jar’) > 0 \\
                and not os.path.isdir(join(directory, f)):
                        scan_jar(class_name, join(directory, f))

    def scan_jar(class_name, jar_file):
        try:
                jar = JarFile(jar_file)
                entries = jar.entries()
                while entries.hasMoreElements():
                        entry = entries.nextElement()
                        if entry.toString().find(class_name) >= 0:
                                print ‘%s: %s’ \\
                                % (os.path.abspath(jar_file), entry)

        except ZipException:
                print ‘Error trying to open %s’ % jar_file
                traceback.print_exc(file=sys.stdout)

    if name  ’__main__’:
    if not len(sys.argv)  3:
        print “Usage: jython search_jar.py  “
        sys.exit(1)
    scan_directory(sys.argv[1] + ’.class’, sys.argv[2])

It can be called as follows:

jython search_jar.py MyNiceStub C:\\application_server\\lib

This script is quite handy when investigating issues related to ClassNotFoundException, or ClassCastException, or classloading-related problems. Watch out, the script appends “.class” to the name of the class you’re passing to the script, so if you’re looking for something other than a class (a resource file, for example), it won’t find it. It doesn’t look for classes which are not in jars either – but adding this to the script is trivial!