Toronto Demo Camp 16

Tonight is Toronto Demo Camp 16, there are still free seats available:

http://democamp.eventbrite.com/ 

Location
Toronto Board of Trade
1 First Canadian Place
Toronto, Ontario M5X 1C1
Canada

An awesome customer service experience!

It is so rare to have an awesome customer service experience; I have to share this one.

I came home Friday night to find my computers in my office all shut off and the damn replace battery alarm beeping every five seconds on my UPS (highly annoying.) So it was time to order some new batteries, I went to APC(Canada) and ordered the replacement batteries via CDW, and then tried to figure out how to stop the infernal beeping (which took nearly 3 hours and 2 bourbons.) On Monday morning I got a call from a very nice person Natashe informing me that I had placed my order with the CDW US and not CDW Canada, but that she had canceled my order in the US and placed a new order here in Canada and that my batteries would arrive tomorrow. This is jaw dropping amazing service as far as I’m concerned, and my batteries arrived around 10am on Tuesday.

Three cheers for CDW the left hand really knows what the right hand is doing and thanks again.

Esoteric Ant Hacks

When debugging ant build scripts (fun wow,) sometimes you want to view the contents of a path reference, this handy hack does just the trick:

<echo message="${toString:pathref}"/>

It probably also works for other “classes” as well.

After a little more digging around (my ant is a little rusty) the proper way to do this is to convert your path reference to a property:

<property name="class.path" refid="class.path.ref"/>

Finally a little sugar to print out your classpath in a human readble form:

<!-- pretty print the class path so it is human readable -->
<macrodef name=\"print_classpath\">
 <attribute name=\"path\"></attribute>
 <attribute name=\"description\" default=\"=== CLASSPATH ===\"></attribute>
 <sequential>
    <echo>@{description}</echo>
    <for list=\"@{path}\" param=\"pathitem\" delimiter=\";\">
       <sequential>
          <echo>pathitem == @{pathitem}${line.separator}</echo>
       </sequential>
    </for>
    </sequential>
</macrodef>

Note you will need the for loop from ant contrib to use this macro/task

<<taskdef resource=\"net/sf/antcontrib/antlib.xml\" classpathref=\"ant.classpath.tools.lib\">

Coding Horror

Given the rate that I’m running accross these little horrors, this may become a regular post.

public static String trimLeadingZeros( String trimString )
{
         String retVal = trimString;
         boolean nonZeroFound = false;
         StringBuffer rtnString = new StringBuffer();
         if ( trimString != null ) {
                  for ( int index = 0; index < trimString.length(); index++ ) {
                                char c = trimString.charAt( index );
                                if ( c == '0' && nonZeroFound == false ) {
                                         // skip all leading zeros
                                } else {
                                         nonZeroFound = true;
                                         rtnString.append( c );
                                }
                  }
         }
         if ( rtnString.length() > 0 ) {
                  retVal = rtnString.toString();
         }

         return retVal;
}

Obviously this person doesn’t have a degree in computer science or they failed out.

  • The have an empty if statement, what you’re not capable of doing the necessary boolean algebra in your head to invert the conditional, give me a break
  • Hey lets scan every character whether you need to or not, making this O(n) where n is the total number of charaters in all strings being scanned (sheesh)
  • How many damn variables do you need to do this 5! Could we make this any more complex
  • The real shame is that the JDK doesn’t have a general strip/trim function, they have a trim whitespace, so why not generalize it.

So in about 5 minutes I put a more general  version together which O(f(x)) << O(n), in the general case my version is 2.5 times faster than the horror. For the pathalogical case my versio is only.8 time faster, and for the ideal case we’re 3 times faster. This was all done over 1 million iterations using the same string that was 20 characters long.

public static String trimLeadingChar( String trimString, char trimChar )
{
        try {
                String tempString = trimString;
                int offset = 0;
                while( tempString.indexOf( trimChar, offset ) == offset )
                        offset++;

                tempString = tempString.substring( offset );

                if( tempString.length() == offset )
                        return trimString;

                return tempString;
        } catch( NullPointerException ex ) {
                return trimString;
        }
}

I’m using a very Pythonic idom here, which is to not care about the NullPointerException, so instead of explicitly checking
for trimString == null, we just catch the excetption and do no harm. I could have made the while loop empty, but frakly I find
that a little bit vulgar.

Coding Horror

I ran across this gem today…

static public Date getYesturdaysDate() {
        Date yesterday = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24);
        return yesterday;
}

All I can say is WTF? How does something like this get through and then hang around without being cleaned up.

WebSiteGrader is pretty handy

This is a great site for getting the measure of your site via a series of very common metrics all in one place. What I really like, is that WebSiteGrader red flags omissions in your page content and design.

If covers:  google, alexa, technorati, yahoo, delicious

See it here: http://www.websitegrader.com/ 

Seen via Social Media Today

YUI why do you tempt me so?

I’ve been trying to use the YUI web tools and I have to say it isn’t easy. So far I haven’t been able to get one of their menu examples to work inside my web app. They work fine in their simple example files, but I haven’t been able to incorporate one of the examples so far. Deeply frustrating, anyways I’ll poke around to see if I can find a simpler toolkit or perhaps role my own if I get desperate enough.

One thing that would be nice, is to have an integration guide for YUI, with emphasis on CSS and Javascript gotcha’s. Also almost every example I look at has a different group of CSS/JS files, and I know that YUI is a quickly evolving toolkit and that segmenting CSS and JS files makes for better download performance, but both of these factors really steepen the learning curve.

Handy CPU benchmark tool

When upgrading machines it always handy to know what your options are. This is the best benchmark comparison tool I’ve seen, you can select two processes from an extensive list of CPUs. Of course you can find it at Tom’s Hardware: CPU Chart 2007

In praise of open source

When it comes to the merits of many open source software systems I’m not the most generous guy (in terms of compliments), but in general open is always better then closed!

I had to release a new version of rTunes this weekend because of a wincom id change with iTunes 7.4.2.4. There was this nagging issue with rTunes and really slow web serving when I was using a remote computer, this was really irking me and since I was updating the source I thought I’d track this down. So off I went and started dropping in some profiling code, after the first test I had a pretty good idea of what was going on (and also why no one had complained about this issue yet.) Python’s BaseHTTPServer generates a log entry when you send a response, the problem as it turns out, the log entry wants to print the host name which means it does a DNS “fully qualified name lookup” and there’s the rub; I’m running DNS at home (and yes it’s not properly setup where Windows is concerned but it works for my purposes) but these name lookups were taking 4 secs on my network which is ridiculous performance, so it was simple to override the address_string to simply return the IP. If you’ve ever setup Apache you know they strongly recommend turning off name lookups, no kidding, so why this library has this as a default is kind of weird and a little bit dumb. After changing this behaviour performance improved by two orders of magnitude, woohoo.

The whole point of this story is that given the documentation of the BaseHTTPServer library and most other libraries of all sorts (free and commercial), without the source I would have spent significantly more time tracking down this issue with a closed source opaque library.

Vive la open source!

rTunes 0.9.1 released for Windows and iTunes 7.4.2.4

I’m happy to get this out the door along with a major fix for DNS Fully Qualified Name look ups, “use the IP Luke”.

The remote versions for windows will follow shortly.

Enjoy, and let me know if there are any new features you’d like to see.

Get rTunes here:  http://agwego.com/rtunes