12 November 2007

Ford GT

At the McMullen Ford Dealership in Council Bluffs, I happened to see this machine. No one near it, no one drooling over it, just the car, right there.





The Ford GT

05 November 2007

The good shepherd


That's Leela (again). This is the sight that anyone opening the garage door would be greeted with. It also happens to be the first thing the cats see in the morning.

24 October 2007

1000 words


Compare tobacco packaging warnings across the globe.




The ceiling at the Orpheum.



Lego people, made of lego blocks. Would have been a recursive trip if they were made of lego people though..



Leela the lap dog.

02 August 2007

Golf: day 1



The morning started off damp and soggy, but improved to become a crisp sunny day. My game started crisp and went soggy. Two rounds in the bag.

01 August 2007

Halfway there

I'm halfway done and I've made two observations:



  • Blogger seems to perform IP based i18n

  • Windows CE is shit (ok fine- I didn't need to go halfway around the world to figure this one)



I'm in Frankfurt, or more specifically the Frankfurt airport. It doesn't have free wireless internet access. Neither did Chicago. But both had T-Mobile deals. But then my Chicago T-Mobile account didn't seem to take in Frankfurt. Anyway, whatever. Here's the fun part:





Our friends here (in the context of the site you are reading) seem to have a mechanism to convert my IP address into a geographical location. In turn, they've defaulted my language/locale over automatically. Nifty. But after a few minutes of thinking, perhaps a little irritating too. Really- the last time I was at the site, I did everything in English, so why the switcheroo? It wasn't like I was an anonymous user either.. Anyway, +1 on pulling the IP based i18n.



Bullet point number two (the Windows CE being given excrement status), is evidenced by this, in mid-flight (and more irritatingly, mid-movie):





Needless to say, the powers that be at MS were looking down upon me since my particular console (embedded into the back of the seat in front of me) took about a thousand times longer to start than any of the other ones of the plane.

18 July 2007

java final vars != magic constant creator

In general, a lot of us tend to use the final keyword alongside public and static. Quite often too, we use it to declare a constant, perhaps a String, or int value. But, does the final keyword cause the variable to become a constant?

public class FinalExample {

public static final String CONSTANT =
"I can never change!";

}


Alright. We've got a constant. Let's try and make it not so constant:



public class FinalExample {

public static final String CONSTANT =
"I can never change!";

public static void main (String[] args) {
CONSTANT = "I can always change";
}

}

$ javac *.java
FinalExample.java:7: cannot assign a value to final variable CONSTANT
CONSTANT = "I can always change";
^
1 error

So the compiler enforces that you can't try to assign a value to a final variable. It didn't say anything about keeping it constant (that was the variable name). So, let's try and switch this up:

public class FinalExample {

public static final String[] CONSTANT_ARRAY =
{"I", "can", "never", "change"};

public static void main (String[] args) {
for (int x=0; x<CONSTANT_ARRAY.length; x++)
System.out.print(CONSTANT_ARRAY[x] + " ");
System.out.println();
}

}

$ java FinalExample
I can never change


This compiles and runs fine with the output as above. Let's try and break this.


public class FinalExample {

public static final String[] CONSTANT_ARRAY =
{"I", "can", "never", "change"};

public static void main (String[] args) {
CONSTANT_ARRAY[2] = "always";
for (int x=0; x<CONSTANT_ARRAY.length; x++)
System.out.print(CONSTANT_ARRAY[x] + " ");
System.out.println();
}

}

$ java FinalExample
I can always change


So, we just changed a final declared variable. Ok, let's try and change it a little differently.

public class FinalExample {

public static final String[] CONSTANT_ARRAY =
{"I", "can", "never", "change"};

public static void main (String[] args) {
CONSTANT_ARRAY =
{"I", "can", "always", "change"};
}

}

$ javac *.java
FinalExample.java:6: illegal start of expression
CONSTANT_ARRAY = {"I", "can", "always", "change"};
^
1 error


So, what gives?

  • Final declarations ensure that a declared variable is never re-assigned to something else. Once you go: final something = something, you don't get to say something = something_else later on.

  • In the event that your object is mutable- ie: can be changed, you are out of luck in trying to make it a constant using final. So, something like a Calendar object which has setters on it to change its value won't hold some magical constantness by being declared as final. This applies to array elements too, as demonstrated above.

15 May 2007

The Gentoo experiment

Podunk said:
<arnold>Gentoo iss fo getting you pumped uuuup!<arnold>

Well, that an for agonizing over which CFLAGS to use to make programs that already complete in milliseconds do so 3% faster.


My experiment with Gentoo is complete. As it so happens, a coworker got the same hardware that I did, at the same time. He installed Ubuntu 7.04. It turns out that the compile times, and some other benchmarks really were around 0.1% (if that at times) between the two different installs.

I know a learned a huge amount of information about how a Linux install works under the hood. Much props to any Linux distro that moves you through it painlessly. There was also some strange fascination that I derived in watching source get downloaded and compiled so effortlessly. Perhaps its that same feeling you got when you used to see a kernel compile; you're really not that smart- you didn't write the code after all, but compiling it sure feels cool- especially when the screen is dumping debug like there's no tomorrow.

But, back to the point- why is it that there's no real performance difference between an Ubuntu and a Gentoo- one compiled for my machine, and another based off pre-compiled binaries? Maybe that's the beauty of the operating system. Maybe I'm just an ass. I don't know.

I do know this- I like my Debain based distros, and I've switched back to one.

apt-get install happiness

07 May 2007

Idiots

How can it be so difficult to legally buy a song online?



Here's the challenge- find a service to download a song. It has to be adhere to the following standards:



  • Encoded in a standard format (no iTunes m4p), and works on a music player (xmms/vlc/banshee), so music should be a legit (read: standard) sound format

  • Doesn't need an application to interface with the service. (Haven't we been using a browser to search/sort/browse/download fairly well?)

  • Gives me the same flexibility as a CD would: I can back it up, rip to my computer, make copies for my use.



After a day or two of fruitless searching, I found a couple of candidates: mp3tunes, and maybe emusic. But, both seem to be indie-label oriented.



Maybe I'm missing something obvious here, and there really is an easy way to do what I want to do: get music legally without being encumbered by some third party software. At the moment, the only viable avenues I seem to have are:


  • hit the P2P clouds and "acquire" my music

  • buy a CD and be legal, but land up paying extra for tracks I don't want



I'm not going to hit the P2P could (I have a wife and dog to think about), but perhaps it answers why so many people do lean that way. I know I'd gladly pay a buck a song if I could get it on my terms- but alas, that seems impossible at the moment.



Perhaps the RIAA won't issue a license to someone that wants to provide music in a fairly open way. Perhaps no one has thought of that yet? Is it illegal? I don't know. Have you had better luck finding music online?

17 April 2007

Free internationalized text in Java

The Locale object is absolutely phenomenal. It packs so much, for so little. If you've ever worked with any internationalized app, you know how hard it can be to get things translated and then figure out how to reference it later. Well, you can get a lot of stuff for free with Java. Take the snippet below for example.








import java.text.*;
import java.util.*;
public class DateInLanguage {

  public static void main (String[] args) {
    Locale[] locales = Locale.getAvailableLocales();
    Date d = new Date();
    for (int x=0; x<locales.length; x++) {
      Locale l = locales[x];
      DateFormat df = DateFormat.getDateInstance(DateFormat.FULL, l);
      String country = l.getDisplayCountry();
      String language = l.getDisplayLanguage();      
      String formattedDate = df.format(d);
      System.out.println(l.toString() "\t"+ country + "\t"+language + "\t"+formattedDate);
    }
  }
}




Now, take a look at the output (trimmed):

ar Arabic 17 أبريل, 2007
iw_IL Israel Hebrew יום שלישי 17 אפריל 2007
ja_JP Japan Japanese 2007年4月17日
ko Korean 2007년 4월 17일 화요일
de_LU Luxembourg German Dienstag, 17. April 2007
el Greek Τρίτη, 17 Απρίλιος 2007
en_IE Ireland English 17 April 2007
en_IN India English Tuesday, 17 April, 2007
mk Macedonian вторник, 17, април 2007
tr_TR Turkey Turkish 17 Nisan 2007 Salı
uk Ukrainian вівторок, 17, квітня 2007
en English Tuesday, April 17, 2007


We just got a huge amount of stuff for free! Check it out:

  • translated, in language names for things like the day and month names

  • separators (commas switch to periods) by Locale

  • Ordering of elements in a Locale sensitive manner



Sure- the Locale object is programmed to do this. It should behave like so. But the translations are there too, and you get them on the house. If you look at Locale closely, you can even use it to get language and country names, in other Locales, thereby allowing you to generate a list of languages, with each language in the language it is in. Really helpful when you want to try and present a language or country selection.

16 April 2007

A new favorite: Gentoo

The folks at work delivered a spanking new machine to me about a week ago. A dual-dual-core Xeon. It looks a little like a mini-refrigerator. Pohl once posed a question to me after I had finished building my dream rig some four years back: "So, what operating system do you intend to run all that nice hardware with?"

My new rule is not to get comfortable. Ubuntu had become too easy. And mind-numbing: I didn't know what was going on under the hood any more, or I didn't have to worry about it. But isn't that half the fun?

I downloaded the Gentoo 2006.1 CD, and peeked at the excellent installation documentation. Even if you aren't going to install Gentoo, but want a good reference on what a Linux installation does, this is a fantastic resource. Going through the installation is like a practical exercise in understanding a lot of basics. The documentation even has links to further reading.

The biggest hurdle I encountered was trying to get my new kernel to boot. The problem turned out to be a non-issue. I didn't realize that the box was equipped with Serial Attached SCSI, and assumed that the disks were attached to a regular SATA-2 port. With that figured out, things went real smooth. The last time I had built a kernel must have been on 2.4.x, but with the 2.6.x builds, the process is really much simpler.

The package management system on Gentoo, Portage is about as simple to use as the APT system. Except, that you get to configure what your builds compile in via a make.conf file that provides explicit flags on library support you want or not. I've eschewed gnome, and found XFCE to be a comfortable, light environment that really does everything that Gnome did for me, with a little more ease, and quicker. Really- when was the last time that the wireless-networking applet worked better then a couple of iwconfig calls?

Oh, and then I accidentally stumbled on a fancy little music player called waif. Dubbed the "Console Audio Unfrontend", it approaches the concept of an audio player without the need for a front-end at all. Needless to say, I'm hooked.

09 March 2007

mini ExecutorService & Future how-to for Java 5

I'd been meaning to get a little example that scrapes the surface of the java.util.concurrent package online. Here's what I came up with:




import java.util.concurrent.*;
import java.util.*;

public class Example implements Runnable {

private static Random random = new Random();

private String payload;

public Example (String someString) {
this.payload = someString;
}

public String getPayload() {
return this.payload;
}

public void run () {
int seconds = random.nextInt(10);
long totalSleep = 1000l*seconds;
try {
Thread.sleep(totalSleep);
} catch (InterruptedException tie) {
throw new RuntimeException("I got interrupted");
}
System.out.println(this.payload);
}

public static void main (String[] args) {
ExecutorService es = Executors.newFixedThreadPool(3);
List<Future<Example>> tasks = new ArrayList<Future<Example>>();
for (int x=0; x<10; x++) {
String name = "I am thread number: " + x;
Example e = new Example(name);
Future<Example> future = es.submit(e, e);
tasks.add(future);
}
// -- all threads should be launching, let's get the Example objects
try {
for (Future<Example> future : tasks) {
Example e = future.get();
System.out.println(" [future complete]: " + e.getPayload());
}
es.shutdown();
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}
}

}


It's a very simple thread. It gets constructed with a String (payload). When run, it sleeps for an arbitrary amount of time (less than 10 seconds), and then prints out the payload it was constructed with.



There's really nothing new with the Runnable interface and the run method here. The fun part is what we get to play with from the java.util.concurrent package.



The first major point to note is that we aren't going to launch Threads the old-fashioned way [Thread t = new Thread(someRunnable); t.start();]. Instead, we're going to create an ExecutorService and submit our Runnable objects to it. There are a variety of ExecutorService implementations that can be created from the Executors factory, but the simplest of the lot might be the one created by the newFixedThreadPool(int size) method. The method name in this case is fairly self-documenting.




public static void main (String[] args) {
ExecutorService es = Executors.newFixedThreadPool(3);


The next fancy object that we encounter is Future. The ExecutorService's submit method can accept a Runnable as well as an arbitrary object, in this case, an Example. In return, it will provide a Future<Example>. (Note that in our case, even though we are submitting the same instance variable (e), it is treated as a Runnable, and then an Example in the context of the submit method). We've also got a List of Future of Examples that we augment with our freshly returned Future<Example> object.




List<Future<Example>> tasks = new ArrayList<Future<Example>>();
for (int x=0; x<10; x++) {
String name = "I am thread number: " + x;
Example e = new Example(name);
Future<Example> future = es.submit(e, e);
tasks.add(future);
}


At this point, the ExecutorService has already begun to start all the Runnables it can (3 concurrently in this case). As soon as one completes, it will replace it with another. However, all of that action is happening in a separate thread, and our main method proceeds execution. And our main method is still chugging along, which gets us here:




try {
for (Future<Example> future : tasks) {
Example e = future.get();
System.out.println(" [future complete]: " + e.getPayload());
}
es.shutdown();
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}


We loop over the list, and recover the Future<Example> objects that we threw in there as a result of the Runnable submissions. Note that we're doing this in the same order as we created and submitted our threads to the pool. We then get() the Example object that we asked the ExecutorService to return to us upon thread completion. As you can see, the Future is the conduit for this activity. Finally, we shutdown the pool.



Here's the output from the execution:



~/Code/concurrency keerat$ java Example
I am thread number: 1
I am thread number: 2
I am thread number: 4
I am thread number: 0
[future complete]: I am thread number: 0
[future complete]: I am thread number: 1
[future complete]: I am thread number: 2
I am thread number: 5
I am thread number: 6
I am thread number: 8
I am thread number: 9
I am thread number: 3
[future complete]: I am thread number: 3
[future complete]: I am thread number: 4
[future complete]: I am thread number: 5
[future complete]: I am thread number: 6
I am thread number: 7
[future complete]: I am thread number: 7
[future complete]: I am thread number: 8
[future complete]: I am thread number: 9


As evident, our threads finish execution in an arbitrary order. However, using the List of Future objects, we are able to join them in the same order we put them in the queue.



There's nothing here that we couldn't have done with a little bit of good, old-school threading. But, we got a reliable, clean and easy pool in one line. We got a simple mechanism to join on a thread and get something in return- something that the thread could have mutated or worked on.

26 February 2007

Very cold

After flying for what seemed like an eternity (we were behind bloody baby row, and some French woman with a dog that kept yelping), we flew over Chicago. Leaving nice warm Bangalore, Chicago sure looked welcoming. The frozen lake Michigan was the icing (literally) on the cake.



Speaking of icing on the cake (or lake), we got home to a very frozen lake, and picturesque icicles. If you like that sort of bone-chilling, mind numbing, snot freezing, ear crunching cold.

23 February 2007

Breezing through India

We visited India for a lightning fast trip that lasted about 8 days earlier this month. It was fun, and a little frantic. At Delhi, I really wanted to visit Humanyun's tomb.



This is the gateway to the actual tomb. As we were walking toward it, Steph noticed something that I'd always taken for granted: the six pointed stars. While we might be most familiar with the incarnation used in Jewish symbolism, it is interesting to note that many faiths including Islam have long histories with the same symbol.





The tomb remained as large as my memory had remembered. The grounds have improved dramatically though, and the signs around the place are a lot better. In addition, there's far better handicap access. I learned that all of this was a result of the Aga Khan's interest and philanthropy in the site.





While it is easy to see that the buildings are all very symmetric, the same theme has been carried over to the layout of the grounds and waterways. Symmetry is an underlying theme in a lot of Islamic architecture, atleast from what I saw in Delhi.





Many of the precious stones have been stolen, and much of the color faded in the dome over where Humayun's grave lies. Yet, you can still see the original architecture clearly. Quite amazing even by today's standards, and more so when you consider that it was constructed in the 1500s.





The disparity between the have and the have-not's is always visible in India. Small impromptu dwellings like this slum are common in many Indian cities.



Back in Bangalore, we took life a little easier, and just spent the days eating, drinking and driving around town.





Yes, if only we could all be Java Masters. Baldwin's where we (from MAIS) got whipped at soccer every now and then.





Near Koramangala, we drove past the multitude of marble shops. There must be around 50 of these where enormous sheets of marble lie stacked in the open for people to look and make purchases.





As you might expect, there's a variety in how well these stores do, especially if they are all packed close together. Some manage by specializing in specific types of marble. Others like the Marble Palace evidently have good sales people.





I'd never seen much advertising for CITU. They are evidently, the Center for Indian Trade Unions. More evident, they seem to be a bunch of commies. While communism might not be a common theme across India, public urination is a prevalent across. This gent clearly didn't think much of the "Against the American Imperialism" slogan, and seemed quite content to pee all over CITU's proud notice of a conference. Nifty.





Walls in many cities in India that protect a private space typically have a topping of smashed glass embedded in concrete to thwart would-be wall climbing and scaling folks.





Towards the end of the trip, we got to spend some time with old friends. Alok and Jennifer shared some Hennessey with us at their place, and now I'm afraid that we will be spending some coin on the stuff.

15 January 2007

The premium blend


While my wife was hunting for valuable stuff for the house at a store last night, I wandered around and found a canister of Buck Urine. Who knew that they made such a thing. On closer inspection, I was amazed at bullet point #2 on the packaging: "Proven, premium, blended scent." Evidently, the art of buck urine manufacturing (or god forbid, collection and packaging) has some parallels with the Whiskey industry (Premium, blended McPee?). I just know that Foxworthy (You might be a redneck if..) will get to this soon.

12 January 2007

cmus is the bomb

I want to play music from my machine. Simple.

I don't want a running encyclopedia (a'la Amarok) while I play my tunes. I'd like something lightweight, simple, and clean. It doesn't need to make toast, integrate with my browser, or take a shit in my panel. Just play the tunes, Holmes.

Hello cmus. An amazingly feature packed audio player. For starters, you can throw just about any codec at it, and it doesn't get phased. Better still, it's an ncurses application that can pump to just about any audio output schema. And in the cluster of my Linux sound system, it seems to be able to understand (or maybe just intelligently default to) the right thing.



Here's the most freakish part. For a text based program that executes within my shell, it seems to boast more views and a better user interface than any other audio player I've used. Now, I just need to find the rest of my collection...

07 January 2007

How many processors am I executing on?

If you're writing threaded code that's meant to be portable, it might behoove you to know how many processors the executing system has.

OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
int numProcessors = osBean.getAvailableProcessors();
System.out.println("Available Processors: " + numProcessors);

You could also interrogate the OperatingSystemMXBean to gather information about architecture that you are executing on. For those not of the faint-of-heart, you could cast the object returned from the getOperatingSystemMXBean call to the VM specific implementation to gather additional goodies. This dangerous assumption would predicate itself on the knowledge of the executing VM though- so probably not a safe bet.

04 January 2007

Solaris, please don't overwhelm me

A few weeks back, I decided to try and play with Solaris. It's from Sun, it has some really nifty analysis that can be done on Java executables, and I had fond memories of it from a few years ago.

Install went great. Kind of. It takes forever, and it comes with all kinds of shit that I don't need. But then, I probably don't know what I need.. I'll say this much: it didn't have any trouble with any hardware at all. And, it even has the courtesy to let me know that my ethernet link is "copper".

Foolishly, I decided to opt for a DHCP setup knowing that I'd be switching to a static IP soon.
Once the box was up and running, changing from DHCP to a static IP was not quite fun. First, you've got to tell Solaris not to acquire an address on boot. From what I gathered, this meant deleting your NIC from a set of DHCP seeking set:

rm /etc/dhcp/nic.dhcp

Then, you've got to reconfigure the rest of the stuff. Which isn't as simple as what I'm used to on Linux. Multiple files, in multiple redundant directories.

ls /etc/net

gives you:

ticlts/ ticots/ ticotsord/

Anyway, lots of googling later, I stumbled through it and made the needful happen.

Then, I saw an ugly. For some reason, root is created with home set as /. And, you log in to CDE as root, as the first thing you do, which means that your root file system now has CDE's turd files for root sitting in it. Of course, there are some other goodies that get dropped in there too from anything you start as root. Quick change to /etc/passwd and this was resolved, but it was mighty irritating.

Pkgadd is marvelous. It's the equivalent of apt-get for Solaris, and it works fine. Until I ran out of space.

The auto-partitioning on Solaris didn't mesh with what I needed. And I seem to have filled it up in the wrong places so bad that I'm pretty much handicapped right now. I could spend some time debugging it and re-partitioning to get the system healthy, but then I remembered why I loved Solaris so much when I used it before. It's because I used it, and I didn't administer it.

If someone is willing to manage and administer it, I'd hop on in a heartbeat. Alas, I just don't have the time to make it my workstation just yet. Maybe at home, down the road.

Hello there xubuntu... Care to dance?