Recently in Programming Category

Binary Chop, Functional

This time I decided to not use any previous versions as a starting point. Again I made mistakes that ended up causing endless loops on some of the test cases. The previous solution was somewhat in the functional style, using recursion instead of looping. I went further this time and passed array slices rather than indices for good measure.

No doubt in my mind this is the worst implementation so far. It's verbose and hard to understand. It has special case checks. It uses a lot of stack for storing array slices. I particularly dislike the special handling needed for the second recursive call — when the top half of the array is searched, a correction must be applied to the index for the whole array.

I've had one lesson hammered into my skull. When the array slice gets to two elements, size/2 stays at one. Hence, when the value is in the first half of the array, it is vital to search the array up to the item before the midpoint. It's surprising that this is required for correctness as well as in order to avoid unnecessary work.

module BinChopper

    def chop(n,a)
        if a.empty?
            return -1
        end
        if n == a.midpoint_value
            return a.midpoint
        end
        if a.size == 1
            return -1
        elsif n < a.midpoint_value
            return chop(n, a[0 .. a.midpoint - 1])
        elsif n > a.midpoint_value
            return apply_correction(a.midpoint,
                        chop(n, a[a.midpoint + 1 .. a.size - 1]))
        end
    end

    def apply_correction(mid, target)
        if target < 0
            return target
        else
            return 1 + mid + target
        end
    end

end

class Array

    def midpoint
        return size / 2
    end

    def midpoint_value
        return self[midpoint]
    end

end

Binary Chop, Recursively

| No Comments

Doing it recursively is a simple re-write. The while changes to an if and the asignments of hi and lo turn into recursive calls. In a language with tail call removal, this would not be any worse than the iterative version. I don't think Ruby is one of those languages. However, I do think this version is a bit easier to read than the first one.

module BinChopper

    def chop(n, a)
        return recursive_chop(n, a, a.length - 1, 0)
    end

    def recursive_chop(n, a, hi, lo)
        if lo > hi
            return -1
        end
        mid = (lo + hi) / 2
        if a[mid] == n
            return mid
        elsif (a[mid] > n)
            return recursive_chop(n, a, mid - 1, lo)
        else
            # a[mid] must be less than n
            return recursive_chop(n, a, hi, mid + 1)
        end
    end

end

Binary Chop

| No Comments

Now that I have a laptop from work I don't need to exile myself the spare bedroom in order to try things out on the computer. Thanks to wi-fi I have ruby and vim, which means I can look at kata again.

Actually, I wanted to try out binary chop, as it's something I can use on a work project. Stupidly, I tried first to write the code cold. That didn't work. Not only did I have the fencepost errors and the endless loops — the code was getting uglier as I kept thinking of special cases. It probably didn't help that my Ruby is rusty from lack of use. I've been spoiled by IDEs and auto-completion: one almost forgets what it's like to get compile errors.

So I resorted to pen and paper. A funny thing happened: all Dave's tests passed at once. The code was easier to read and more coherent. Binary chop is about the simplest problem I know for which it's really worth taking a break from the keyboard.

Interesting to compare with other people's work. Jim Weirich did a version three years ago. Here's mine:

module BinChopper

    def chop(n, a)
        lo = 0
        hi = a.length - 1
        while lo <= hi
            mid = (lo + hi) / 2
            if a[mid] == n
                return mid
            elsif (a[mid] > n)
                hi = mid - 1
            elsif (a[mid] < n)
                lo = mid + 1
            end
        end
        return -1
    end

end

Originally, I was using single letter variable names but I like Jim's short but meaningful names better. I thought of the invariant a little differently: I decided the loop would terminate after the high and low markers went past each other. (By the way I think his calculation of the midpoint is buggy. I should lay off the crack pipe. His calculation is obviously correct and I'm stealing it.)

Now of course coming up with one implementation of binary chop is straightforward. I'll have to see how motivated I am to find four more ways to do it.

A Note on Delegation

| No Comments

I'm reading Joshua Bloch's Effective Java and getting quite a lot of it. The book is a catalogue of numbered items of advice, some standard, some controversial, with fairly detailed exposition on each.

Item 14: Favor composition over inheritance is uncontroversial, being a restatement of the second principle of object-oriented design in Design Patterns, the famous Gang of Four book by Gamma and company. However, in his discussion, Bloch writes that

Sometimes the combination of composition and forwarding is erroneously known as delegation. Technically, it's not delegation unless the wrapper object passes itself to the wrapped object [Gamma95, p. 20].

I think Bloch misread page 20 and, thanks to the reference, I was able look at page 20 over his shoulder:

Delegation is a way of making composition as powerful for reuse as inheritance [...] [W]ith inheritance, an inherited operation can always refer to the receiving object through the this member in C++ [...]. To achieve the same effect with delegation, the receiver passes itself to the delegate to let the delegated operation refer to the receiver.

This text is suggestive, however the example that follows makes no attempt to achieve the this effect. In the example, Window object delegates an Area() operation to a Rectangle object. The Window object does not pass itself to the Rectangle.

In the Glossary of the GoF book, on page 360, there is another definition of delegation: An implementation mechanism in which an object forwards or delegates a request to another object. The delegate carries out the request on behalf of the original object. I haven't edited anything out this time.

I think Bloch took something optional and made it an essential part of the definition of delegation. The paragraph I quoted from the GoF is a little ambiguous, but the rest of the book seems clear: it is still delegation even if the delegating object does not pass itself as part of the request to its delegate.

To be sure, this is a detail of no importance. The definition of delegation doesn't really depend on the GoF. My quibble hardly affects my opinion of Effective Java: it's still a book I'm glad I bought. It's just a case where the reference doesn't give support to the author the way it appears to.

On the Value of Duplication

| 2 Comments

Laurent has some thoughts on the value of duplication. They are laudably contrarian.

However, I can't quite bring myself to think duplication is often a good thing. Certainly, for a manager who needs to get a quick assessment of whether a given chunk of code is good enough, it can be expedient to compare it to another chunk that is known to be good.

This approach of looking for duplication will work if the aim is very short term. Humans are good at pattern recognition. We can assume that there are other practices in place to make sure the code works properly (testing for one). If it looks okay and works okay, it probably is okay.

I see a couple of problems here.

For one, why is a manager having to judge whether a given chunk is okay? I know that every manager who has been in the trenches is tempted to go back, even if only vicariously. However, the best people to judge code are programmers who work in the same area. And nobody likes to look bad in front of their peers.

For another, it only applies if the two code chunks really should look alike. Sometimes that will be true: if we are employed it is often because we have experience solving the same type of problem. But new code jury-rigged to fit into a template of the old code, that might be a positively bad thing. Looking at it would not be enough to tell if that was the case.

I Hate Internet Explorer

| No Comments

I have a web application that uses XML fairly heavily. One advantage: I can generate XHTML output and test it with an XML parser. All goes well, until it comes to trying out the application with Internet Explorer.

Forms are displayed with the dreaded &apos; and friends: XML entities.

The trouble is this: XHTML defines the textarea element as containing PCDATA, which means characters like ' and & must be escaped or an XML parser will choke. IE however will display the entities in all their glory, as if textarea contained unvarnished CDATA

So, I have two choices: I can either have well-formed XHTML or I can have the page display properly in IE. Which is to say I have no choice at all.

Ruby on Rails on MySql

A couple of small problems. For the first one, a fix from LaughingMeme. When I tried to set up my first scaffold, I got a message complaining about

No such file or directory - /tmp/mysql.sock

I needed to edit config/database.yml to change the host to 127.0.0.1 (or, equivalently, localhost.localdomain).

The second error was easier:

Access denied for user 'root'@'localhost.localdomain' (using password: NO)

I just had to specify my own username in database.yml instead of leaving the field empty. (I expected it to default to my username but for some reason it wanted to default to root.)

On the Theme of Unexpected Behaviour...

| No Comments

I was processing a file with UTF-8 text and finding that my output was coming out in ISO-8859-1 (a.k.a. latin1). I verified this first using od -c | less and then by running recode latin1..utf8. Either Perl, XML::Parser or my code was silently converting the text.

It turned out that Perl was responsible this time. Or at least, the fix was at the Perl level. Again, the answer is in the friendly man pages, specifically in perluniintro. There are three alternatives:

  1. open FH, ">:utf8", "file";
  2. binmode(STDOUT, ":utf8");
  3. use open ’:utf8’; # open as a pragma

That makes not one but two cases recently solution was in the man pages. It helps that these are new style man pages, with lots of tasty example code.

Least Helpful Error Message Ever

| No Comments

XML::Parser is useful for testing XML output, mainly because it's in the standard Perl distribution and it's stable. However, I ran into a problem with it yesterday that cost me some time.

Here's some (simplified) code

$parser = new XML::Parser(Style => 'Tree');
$parser->parse($file_name);

Those who know the module well will have spotted the error already. I was faced with this error message:

not well-formed (invalid token) at line 1, column 0, byte 0 at /usr/lib/perl5/[...]/XML/Parser.pm line 187

I tried making my XML output smaller and smaller until it was just one self-closing element. Still I was getting the invalid token error.

Turned out I was calling the wrong method on the parser. A lot of Perl methods are pretty liberal about what they accept, perhaps too liberal at times. $parser->parse accepts a file handle or a string, but not a file name. My fault for not reading the documentation carefully, because it says, right at the top, $p1->parsefile('REC-xml-19980210.xml').

Perhaps not literally the least helpful error message ever. Certainly misleading for anyone unfortunate enough to run into it.

A Real Use for Closures

| No Comments

I think I read about closures first a few years ago in the Camel book (first edition). At the time they seemed to be a neat toy, but not something I would ever need. Now, I've finally come across a scenario where closures provide the best solution.

I'm using XML::Parser (no doubt that's old school but I need something that's solid and portable). With that, I get to define a bunch of callbacks. I want the callbacks to be methods in an object I've created. Problem: XML::Parser wants references to subroutines, not objects. Solution: pass references to anonymous subroutines created on the spot. There's a $self reference in lexical scope, so I can just refer to that in the anonymous subroutine. Thanks to the magic of closures, it's available, even when the sub is being called back later.

    my $parser = new XML::Parser(ErrorContext => 2);
    $parser->setHandlers(
        Start => sub { $self->handle_start(@_) },
        Char  => sub { $self->handle_characters(@_) },
        End   => sub { $self->handle_end(@_) }
    );

I find this surprisingly readable. Even if I didn't know about closures, I would be able to read and understand this code: DWIM at its best. (By the way, syntactic closures seem to have been invented as recently as 1988.)