Archive

Archive for the ‘programming’ Category

Finding free disk space in Ruby

December 16th, 2008 4 comments

UPDATED I can’t find a standard Ruby idiom for finding out the free/occupied disk space on a partition, so here’s a hack for doing it under Linux:

1
2
3
4
5
6
7
8
9
def disk_used_space( path )
  `df -Pk #{path} |grep ^/ | awk '{print $3;}'`.
    to_i * 1.kilobyte
end

def disk_free_space( path )
  `df -Pk #{path} |grep ^/ | awk '{print $4;}'`.
    to_i * 1.kilobyte
end

The -P (POSIX compliant output) argument to df is important, it forces the output to be more regular, thus easier to parse. Without -P, you’ll run into trouble if the names of the disk devices are particularly long, e.g. if the machine uses LVM:

mymachine:~# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/md0               9614052   2819896   6305788  31% /
/dev/mapper/storage-s1
                     331624912    395808 314383488   1% /mnt/s1
/dev/mapper/storage-s2
                     109681544    192248 103917712   1% /mnt/s2

The 1.kilobyte idiom is available only if you use ActiveSupport, e.g. in a Rails application. If you can’t use ActiveSupport, just write 1024 instead.

Update: the -P option is not enough, you should also use -k to get the output in 1 KB blocks. Thanks to commenter Martin Rehfeld for the tip.

Hope you find this useful.

Categories: linux, programming

Naming and Some Common String and Array Patterns

September 25th, 2008 9 comments

How many times have you had to display a list of items like this:

1
apples - oranges - ququxes - bananas

The newbie programmer (like I myself was and still am in many respects) will often hammer out this piece of code:

1
2
3
4
5
6
7
String output = "";
for( int i = 0; i < fruits.size(); i++ ) {
  output += fruits.get(i);
  output += " - ";
}
// Now remove the last separator
output = output.substring( 0, output.length() - 3 );

Hey, this is convoluted and ugly. There should be a library function that does this for us. Everybody uses arrays and strings. This is such a basic problem that someone must have already implemented it in some library somewhere, if it’s not already in our language’s standard library.

So let’s turn to Google, to find a library that can save us.

But … what search terms should we use?

In other words, what is this problem’s name?

Once you can name something, you can master it. This is a thought that stuck with me while reading the classic introductory textbook to programming, Structure and Interpretation of Computer Programs.

We learn new words, and even make up new words, because it helps us communicate and understand ideas and thoughts of ever increasing complexity.

Take a simple sentence, like The government will lower taxes. Now try to express the same idea, with the same precision, but without using the words government, or taxes. You’ll end up with something like: “The body of individuals elected by the people of a country, with a limited-time mandate to run the country, will lower the amount that each individual must contribute to support the country’s shared expenses.” Not pretty, by any measure.

Enough with the theory, let’s return to the craft of programming.

There exist a bunch of simple but very common problems, involving arrays and strings. And I want to remind you that they have names, and how important it is to know these names. It will help you not only in finding the right library call to do what you are trying to do, but it will also help you recognise these problems in your day to day programming work. You’ll be able to think Hey, this looks like a map followed by a select, I know exactly how to solve it quickly and elegantly.

join

Let’s backtrack for a minute to the start of this post. What we have there is a problem that can be summarised as:

1
2
["apples", "oranges", "ququxes", "bananas"]
=> "apples - oranges - ququxes - bananas"

In plain English: we have an array of strings and we want to join together these items into a single string, with a separator string in between the items.

This problem has a classic name, it’s called a join.

Now we know how this problem is called, we can master it. We started out this example in Java, so we’ll have to find a Java library function that does join. And sure enough, commons-lang’s StringUtils class has a helpful little method called join().

Side note: If you use one of the more friendly languages out there, like Python or Ruby, you’ve got it easier. In Ruby it’s as simple as:

1
2
irb(main):001:0> ["apples", "oranges", "ququxes", "bananas"].join(" - ")
=> "apples - oranges - ququxes - bananas"

split

1
2
"apples - oranges - ququxes - bananas"
=> ["apples", "oranges", "ququxes", "bananas"]

This is the reverse of join. Take a string of items separated by a delimiter, and return an array of the individual item strings.

There’s a split function in the standard library of Python, Ruby, PHP, even Java. Oh yeah, in Java it’s as simple as string.split(pattern).

zip

A zip operation, also called combine, means pairing each corresponding item from two arrays:

1
2
3
4
5
6
7
8
["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
[31,    28,     31,    30,     31,     30   ]
=> ["Jan", 31],
["Feb", 28],
["Mar", 31],
["Apr", 30],
["May", 31],
["Jun", 30]

It’s called array_combine() in PHP, and zip in Ruby.

flatten

Taking a nested array (aka array of arrays) and turning it into a, err, flat array:

1
2
["one", ["two", "three"], "four", ["five", ["six", "seven"]]]
=> ["one", "two", "three", "four", "five", "six", "seven"]

map

map, also called collect, transforms each item of an array through a function that you specify, and returns an array of the transformed values. Classic example: finding out the squares of the first positive integers:

1
2
[1, 2, 3, 4, 5, 6]
=> [1, 4, 9, 16, 25, 36]

To achieve this, you pass in a function that takes the argument x and returns x*x. Exactly how you do this varies according to your language. In some languages it’s braindead simple (Ruby), in others it requires a bit more work but still reasonably simple (PHP, Java)

reduce

reduce, also called inject, combines all the values of an array using a function that you specify, to create a single value. Simple example: the sum of all the elements of an array of numbers:

1
2
[1, 2, 3, 4, 5, 6]
=> 21

is a reduce operation where you pass a function of two arguments a and b that returns a+b.

Just like with map above, how you do it varies according to your language. Take a look at Ruby, PHP. I can’t find a similar function for Java, if you know any, please react in the comments section :)

select, reject

These are filters, they retain or remove items from an array according to a function you pass in.

Let’s filter only the items that start with a vowel:

1
2
["apple", "banana", "cherry", "orange", "plum"]
=> ["apple", "orange"]

All you do is call “select” and pass in a function that returns true if its argument starts with a vowel. That’s a function you’ll have to build for yourself, sorry :-P

reject works the same way but returns the items that do not match the function. Using the same function as above, a call to reject works this way:

1
2
["apple", "banana", "cherry", "orange", "plum"]
=> ["banana", "cherry", "plum"]

Of course, if your language or libraries don’t provide a reject call, you can use select and pass in a function that returns false when it was supposed to return true.

Have a look at array_filter if you’re using PHP, select or reject if you’re using Ruby, or commons-collections’ select and selectRejected if you’re using Java.

OK, kids, I hope you learned something today :-) Start recognising common patterns like join or map in the code that you write, and start thinking in terms of them.

Please feel free to suggest additional code samples and links for the languages I have not covered.

Categories: programming

Not a minute too soon

July 4th, 2008 2 comments

37signals announces their end of support for IE 6. They are actually the second high-profile web app developer to drop IE 6, after Apple did the same with MobileMe. The snowball is rolling. The lives of web developers will improve dramatically when they will no longer have to ensure support for the decrepit browser that IE 6 is.

Categories: programming

JavaScript 2: An alternative proposal

February 17th, 2008 No comments

The ECMAScript version 4 specification is almost ready. ECMAScript 4 will be the basis of JavaScript 2. And, omg, it’s huge! Like, literally huge. Here you can read a digest of the proposed language features.

I feel that the proposal is non-orthogonal (read: bloated) in many ways. The new language will have both class-based OOP, a la Java, and prototype-based OOP; packages and namespaces as logical units of code; static type annotations both of the nominal kind (this object IS A Thing), and of the structural kind (this object responds LIKE a Thing).

What if, instead of striving to clone Java, they focused on making ECMAScript a more pleasant language to develop in? What if they:

  • added interpolated strings. Yes, I like to write
    1
    alert("Hello, ${name}, welcome to JS!");

    instead of

    1
    alert("Hello, " + name + ", welcome to JS!");
  • added a simpler syntax for passing functions as arguments. How about this:
    1
    2
    3
    [1,2,3].each() do (item) {
        alert(item)
    }

    as syntactic sugar for this JavaScript construct:

    1
    2
    3
    [1,2,3].each( function (item) {
        alert(item)
    } );
  • got rid of nominal types. JavaScript can do OOP really well without classes, and it’s a shame to shoehorn classes and interfaces into it just to imitate Java and C#
  • shipped a unit testing framework in the standard library
  • added useful methods on arrays, like map, inject, detect, any, all

Eh? How about you? What do you wish to see in the next major version of Javascript?

Later Edit: Also see Douglas Crockford’s suggested changes.

Categories: programming

Using prototype.js in chrome

February 9th, 2007 12 comments

Are you writing a Firefox/Thunderbird extension, or maybe a XULRunner app, and want to make use of the Prototype JS library? Then you will run into this issue.

Because of a long-standing bug in Mozilla, Function.prototype cannot be extended with the method ‘bind’, and so all the utilities in Prototype.js that make use of bind() won’t work as expected. Once again, this happens with documents loaded from _chrome_, not with normal web pages.

Steve Conover posted a workaround for this bug, about a year ago. I’m happy to offer a patch against Prototype 1.5.0 (final), with that workaround applied. Hope you’ll find it useful.

Categories: programming

2006 AD. Microsoft Still Doesn’t Get It

December 20th, 2006 4 comments

Yes, they have built a XML user interface language. In their docs and tutorials however, there is no mention of CSS. To define style, you use inline attributes.

Proof once again that VB-itis is a chronic and contagious disease.

Further reading: http://www.devx.com/webdev/Article/20834

Categories: programming

Getting groovy with JSON

September 17th, 2006 6 comments

JSON is an informal standard for describing structured data. It is human-readable, less verbose than XML, and has a distinct advantage which I’ll mention later.

Short example: say you want to define an address book entry. In JSON it might look like this:

1
2
3
4
5
 { 'name': 'John Doe',
   'address': '42, Universe Rd.',
   'telephone': [{'home': '1-901-555-2323'},
                 {'cell': '1-888-555-9999'} ]
 }

Compare the verbosity of the above to the equivalent XML here:

1
2
3
4
5
6
7
8
<person>
  <name>John Doe</name>
  <address>42, Universe Rd.</address>
  <telephones>
    <telephone type="home" number="1-901-555-2323" />
    <telephone type="cell" number="1-888-555-9999" />
  </telephones>
</person>

Using JSON, you can nest arbitrarily structured data, making use of maps (comma-separated lists of forms like ‘key’: ‘value’, surrounded by braces) and sequences (comma-separated values, surrounded by brackets).

You can use JSON in lots of places, even in those where the more “enterprisey” developers would use XML; like, say, to write config files.

However there is a particular affinity between JSON and the AJAX techniques. While doing AJAX you’ll often find the need to fetch some data from the server and parse it. Guess what: in JavaScript you don’t need a parser to parse JSON, because JSON syntax is JavaScript syntax. In other words, you parse it by calling eval().
JSON after all stands for ‘JavaScript Object Notation’ :)

And, as you probably guessed, generating JSON is a breeze. Here’s a quick’n'dirty function written in the Groovy programming language, that serializes a construct of Java maps and lists into JSON:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def toJSON( obj ) {
    if( ! obj ) return "";
    if( obj instanceof Map ) {
        return "{" + obj.keySet().inject("") { accu, k |
            (accu.length() == 0? "": "${accu},\\n") +
            "'${k}': ${toJSON(obj[k])}"
        } + "\\n}"
    }
    if( obj instanceof List || obj instanceof Set ) {
        return "[" + obj.inject("") { accu, item |
            (accu.length() == 0? "": "${accu},\\n") +
            toJSON(item)
        } + "]"
    }
    return "'${obj}'"
}
Categories: programming

svn diff when line endings are different

July 26th, 2006 No comments

If you’ve ever worked in mixed-OS environments, you surely ran across this very annoying problem:

A colleague of yours made a slight change to a file and committed it from his Windows computer. You however have modified that file too, on your Linux workstation. It so happens that the file in the repository and the file in your working copy have different line endings. Imagine the “pleasure” of doing a merge now :)

There is hope, though. You can do a SVN diff without taking line endings into consideration, by doing this:

1
svn diff --diff-cmd /usr/bin/diff -x "-u --strip-trailing-cr" yourfilename

This of course assume you have the diff utility installed in /usr/bin. For more about what svn diff can do, run svn help diff.

I’m now grepping the SVNBook for a way to automatically convert line endings upon commit, sort-of what CVS can do. If you know such a way, please share :)

Categories: programming

Scrapbook in Eclipse

June 24th, 2006 2 comments

It’s never too late to read introductory books on Eclipse. More specifically, this book. You may be missing out on some pretty cool features. For example, how could I miss out on something as useful as the Scrapbook?

Essentially a Scrapbook page in Eclipse allows you to type code and execute on the fly. You don’t need to create a function or even a class. This is really sweet if you want to try out something quick and dirty, before incorporating it into your code. In this respect, it resembles the REPL of LISP or Ruby or Perl. Plus you get most of the benefits of the Java editor, such as code completion ;)

Eclipse scrapbook shot

To create a scrapbook page in Eclipse 3.2, go to File->New->Other… then choose Java -> Run/Debug -> Scrapbook page.

Categories: programming