Thursday, January 28, 2010

Paint.NET updater

Wow - I just opened up Paint.NET, and there was an update to the software available.  Now I didn't open up Paint.NET to apply an update - I opened it to use the software.  Instead of nagging me the way FileZilla, Adobe, Firefox, and the Java updaters do, Paint.NET gave me a dialog with the option of applying the update once I close the application.  What that means is that I can go ahead an do what I was going to do with only a minor interruption to my train of thought, and then when I'm done Paint.NET applies the update behind the scenes.  Cool - I really like it when developers pay attention to the little details.

Wednesday, January 27, 2010

High speed rail system


According to this article and this article and this one, president Obama will be announcing another major spending initiative - a high cost speed rail system.  It will be touted as a job creation mechanism and a push towards more green transit options.  I have a lot of questions, including:
  • Is their $8 billion budget really enough to make this work?
  • Will they use existing track, or build new?  How much new?
  • Whose land will they take to build it?
  • Is this really a cost-effective means of travel?  There's a lot of infrastructure and up-front cost required.
  • Is this really the right time to do this, with record deficits and out of control spending in Washington?
  • Are the jobs that are supposed to be created good for us only in the short term, or is this really a long term strategy?
  • Can they change our car-culture enough that people will actually want to use it?
  • Will it go enough places that people will be able to use it?
  • Does this really lessen the environmental impact of our travel habits?
  • Is the problem with Amtrak really that it doesn't go fast enough?  (I'll give you a hint - no!).  If not, then how will this help solve the other problems that have plagued Amtrak.
  • And most importantly, if they get people to actually use it, how will they secure thousands of miles of track just ripe for a terrorism plot?  Roads, bridges, subways, ferries and airplanes are all susceptible too, but not to the extent that an interstate railway would be.
I'm not the only one asking questions either.

Friday, January 22, 2010

Personhood - 1-22-10

Beth, Caleb, Ian and I got to hear Baby's heartbeat today. Beth and I heard it loud and clear at Beth's first appointment on 12/14 at 10(ish) weeks. But it was pretty special to take the boys and have them hear it too. 140 beats per minute. Ian thinks he'll have a sister. Caleb, another brother. Me - I'm just amazed at the beauty of God's creation, and excited for the joys and wonders of fatherhood to the 3rd power.

C# Corner - fun with 'yield' and extension methods

All .NET developers learn about IEnumerable and IEnumerator in their first day of development, whether they realize it or not.  Every foreach statement written utilizes the .GetEnumerator() call to iterate over a collection of objects.  The For Each concept is a really nice piece of syntactic sugar.  However, one of its limitations is that it doesn't give you a counter to track which loop iteration you're on.  If you want to do that, you have to keep track of it yourself in your own variable.  Not a big deal really, just a fact of programming life.  This manifests itself in two ways - you can write a for;; loop which has the counter built in and then you get the object you want by indexing the collection as shown here:

var names = new List { "You", "Me", "Dupree" };

// for;; loop
Console.WriteLine("Method 1:");
for (var i = 0; i < names.Count; i++) {
   var name = names[i];
   Console.WriteLine("{0}-{1}", i, name);
}

This method isn't bad, but it has a fatal flaw - it only works on collections that are fully populated.  In other words, the collection has to be indexable and cannot be lazy loaded.  If you have a collection that dynamically loads or calculates its next value, you have to do something much more kludgy.  You must maintain a variable external to your loop that keeps track of your current item index as shown here:

var names = GetLazyLoadedNames();

// outside variable
Console.WriteLine("Method 2:");
var j = 0;
foreach (var name in names) {
   Console.WriteLine("{0}-{1}", j, name);
   j++;
}

This method works on every IEnumerable collection, and is a good general purpose tactic that every .NET dev will need in their toolkit.  But, it has the frustrating consequence that it requires a variable outside the scope of the loop, and takes a couple extra lines of code to accomplish.  Both of which adversely affect the signal-to-noise ratio of your code.

As a thought experiment, I wondered if I could get the clarity of a simple and tight foreach loop while still maintaining the index.  It turns out it's really simple (in C# at least) to accomplish with a small immutable helper class and an extension method.  Here's the code:

public static class IEnumerableExtensions {
   public static IEnumerable<IndexedItem<T>> GetIndexedEnumerator<T>(this IEnumerable<T> me) {
      var index = 0;
      foreach (T item in me) {
         yield return new IndexedItem<T>(item, index);
         index++;
      }
   }
}

public class IndexedItem<T> {
   private T _item;
   private int _index;

   public T Item { get { return _item; } }
   public int Index { get { return _index; } }

   public IndexedItem(T item, int index) {
      _item = item;
      _index = index;
   }
}

Now, if you import the namespace containing this extension method, every IEnumerable collection you have gets a method called .GetIndexedEnumerator() which means that instead of iterating over the objects in the collection, you iterate over a new container object called IndexedItem that has the current item in the collection as well as the index of that item.  This means that now your foreach code can look like this:

var names = GetLazyLoadedNames();

// extension method
Console.WriteLine("Method 3:");
foreach (var name in names.GetIndexedEnumerator()) {
   Console.WriteLine("{0}-{1}", name.Index, name.Item);
}

This definitely isn't a revolutionary improvement by any means.  In fact, in exchange for clarity, you likely will see an ever-so-slightly reduced performance for very large collections since you have the added overhead of the IndexedItem class.  Also, unfortunately due to the lack of a 'yield' statement, VB devs (like myself) have a whole lot more work to do to implement this solution.  But overall, this is just one more example of why I love .NET.  The framework and languages are continually evolving, and while some purists may scoff at the syntactic sugar, I say it's all syntactic sugar over top of zeros and ones, and I have a serious sweet tooth.

Thursday, January 21, 2010

Bad Supremes! Bad, bad, bad!

Today the Supreme Court overturned a decades-old established precedent on campaign finance without any identifiable or compelling reason.  I'm no lawyer, nor am I a student of constitutional law, but as a plain old common citizen I just cannot fathom how today's decision is a step in the right direction for our country.  This, in my opinion, is a perfect example of the highest court in the land acting in the personal and political self-interest of its members and not in the interest of this country or in the spirit of the law with respect to established precedent.  Activist judges - shame on them all.

While I do believe that there are some specific issues where established precedent is very much wrong and that past decisions should be overturned (tomorrow being the anniversary of one of the worst in the history of this country), I expect those situations to be few and far between.  When they come up, there should be a real and compelling reason to overturn the established interpretation of the law.  Without that standard, 5 lifetime justices can systematically undermine the fabric of our country.  We expect the ever swinging pendulum of right-vs-left policies in Congress, but the justices are meant to remain consistent and steadfast, but also be free of political pressure in order to right grievous wrongs - not commit them themselves.

Wednesday, January 20, 2010

That's gotta hurt...

Just before the president's one year anniversary of having taken the oath of office, Massachusetts, the 3rd bluest state in the union, elects its first freshman Republican senator since Edward Brooke won in 1967.  That sound you hear is the late Ted Kennedy and his 'healthcare legacy' spinning at 3600 RPM.

You think the president got the message to quit piddling around with healthcare and climate and all those other pet projects and focus some real attention to the deficit and jobs and the economy?

Sunday, January 17, 2010

Life, according to Beth

My wife wisely asked herself aloud today -
Why is there manly and womanly and girly, but not 'boyly'?
 Indeed.

Monday, January 11, 2010

XHTML layout converter for ceTe’s Dynamic PDF library

At work, we are using ceTe’s PDF libraries for .NET.  They have a pretty easy to use, versatile set of tools for building PDFs.  However, after building a few of them, it became painfully obvious that assembling all but the most anemic PDF layouts was painful.  The Tweak-Compile-Generate-View-Repeat method takes quite some time.  Too much time.

The Tweak-Refresh-Repeat model for HTML+CSS seemed to me to be a much better method of building a layout, but the Dynamic PDF API doesn’t support anything like that.  It speaks a little bit of pseudo-HTML3 with <font>, <b>, <u>, <i>, and <p> tags.  But that is about the extent of it.  So, I decided to build a converter that takes full advantage of our existing tools for XHTML generation and converts those XHTML+CSS documents into a PDF.  It turned out to be surprisingly easy.  My converter is less than 600 lines of nicely commented VB, with a few little utility functions for things like parsing CSS.  I was even able to account for the “cascading” part of CSS, where I look to page level styles, then tag level styles, followed by classes, tag IDs, and finally the style attribute.

Currently what I have will support tables (including colspans and rowspans), images, rotated items (using the IE only { writing-mode:tb-rl; filter: flipv; } syntax), nested <div>s, various positioning techniques, and text alignment and styling.  I’m using NVelocity to dynamically generate the XHTML (though T4 or really anything would do), so all the dynamic parts of the PDF are done on the front end rather than intermingled with the proprietary ceTe API calls.  Since XHTML is both renderable HTML and parsable XML, I didn’t need to put in any effort there.  The Linq-to-XML functionality in .NET made that part a snap.

One of the decisions I had to make is what specific subset of XHTML would I support.  Obviously, a PDF is much different than a web page in the way you layout the elements.  One example would be that a PDF isn’t designed to have a flow layout.  In other words, when you resize the PDF, everything stays put rather than wrapping around the way a properly designed web page would.  So, my XHTML assumes you will be absolutely positioning everything, and the converter throws errors if you don’t.  You simply have to specify the X and Y coordinates, as well as specifying the height and width too.   Actually, that's not entirely true - as a convenience I do auto-calculate height/width in certain circumstances but mostly you ought to specify.  Height and Width are defined in point units, or “Pt”s, which is most commonly thought of as a unit for fonts, but in fact is equivalent to the units ceTe uses in its box layout API.  This means that your HTML output will line up size-wise with the PDF that gets generated.  Again, I wasn’t looking to take just any old HTML and make a PDF, but if you tailor your XHTML output to the PDF layout concept, it’s not too constraining.

There are quite a few things I don’t support.  I didn’t do anything too fancy like CSS2 selectors.  Another consideration was that the XHTML had to renderable exactly like the PDF version for this to make any sense, but since you can do lots more in XHTML than I actually support, you could technically go off the deep end.  In addition, I chose to support only IE as my primary renederer.  Firefox will work, and looks fairly close, but my purpose wasn’t really to make a standards compliant HTML output.  The idea is to have a RAD tool for PDF generation, and IE-only was okay for me to meet that goal.  Also, there’s no support for any JavaScript (and really no need for it in a PDF anyway).  CSS that isn’t understood is just ignored, as well as tags or attributes that aren’t understood.  The key parts are that everything has to have an x, y, height,and width specified in the proper units.

There are some things I still want to add as well.  I’d like to add support for the !important CSS directive.  Also, currently I don’t support changing fonts.  CeTe’s tool seems to require quite a bit of config to set up a new font.  You have to specify the .ttf file for the bold version, and the italic version, and the bold/italic version, and then there’s the underlining iterations – you get the idea.  It’s on my TODO list to figure that one out.  I also don’t have support for multiple pages.  Currently I’m only set up to do a 1-to-1 of XHTML doc to PDF page.  And finally, I need to figure out how to do relative positioning of items (offset this element from that one by X,Y) as well as doing dynamic sizing of items to support an undetermined amount of text.  It might also be nice to specify an analyzer that lets you know whether your XHTML input has unsupported tags/css for debugging purposes.

All and all, this was a really fun side project.  There was a lot of up-front work, but it will pay off in no time.  Now we can crank out new PDFs in hours instead of days, and not have to be in the guts of ceTe’s API.  I’d like to highlight some of the more interesting bits of code, but since I did this for work, I’m not sure what I can/should showcase.  Perhaps I’ll rewrite it in C#  – though I’m not inclined to buy the Dynamic PDF tools for my personal use.

Friday, January 8, 2010

Nexus One

Good - I'm glad someone is saying it.  While the announcement of Nexus One is pretty interesting, I can't imagine plopping down for one without having seen a few of them in the wild, and having been able to play around with it myself first.  It's not as if this is the first Android phone, so you won't get too many of the early adopters looking for a new toy.  And with the release of the Droid being so recent, I think that the biggest announcement from Google isn't the Nexus One, but the fact that they are laying down the gauntlet as far as separating the hardware from the mobile carrier.  That's a revolution I'd like to see.  But I think that may be mostly wishful talk since I'd really like a CDMA iPhone on Verizon...

Thursday, January 7, 2010

Site redesign part 2 - Comments

Today, I was looking at my RSS feeds and came across this post by Ayende.  I had never thought of a comment system as a plugable feature for a website, but there is was - disqus.  Blogger's built-in comment system has, well, frustrated many people.  So, I decided to check it out over lunch, and as you can see by my new comment system below, I like it :-)

I uploaded my blogger template, it made the changes it needed me to make for me, and then I saved the template.  Then, it let me import my existing comments.  Wonderful!  So, within 20 minutes I'm up-and-running with Disqus, and I can finally ditch Blogger's crippled comment system as part of my site overhaul.  And, it's free.  Oh so nice.

A new look

When I first created this blog, the idea was to get me to start writing again. And, it's mostly worked. I don't have as much time or motivation to do it as I'd like, but little by little I'm penning a small percentage of my thoughts. And as I did that last year, I noticed some limitations of the Blogger layout I picked.

The theme itself was too pedestrian and distracting.  It was also pretty common amongst other folks that use blogger.  It wasn't me.  It wasn't distinct.  The centered content pane with the side gutters was just too small, and made it difficult to talk about and showcase code.  A friend of mine underwent an overhaul of his blog's look awhile ago and it looks nice and is distinctly his and leaves you with an impression.  Of course, he hardly ever posts to it, so it has to be beautiful in order to have any significance on the net (hint, hint... dig, dig).

So now that I've begun to understand how I want to use my blog, I wanted a theme that would fit with my style.  It's simple and understated - highlighting content and not design.  It's functional, and allows more room for the type of stuff that I want to write about.  And it's easily customized rather than just taken as-is from Blogger's can-o-themes.

Also, I have this habit of naming all my machines at home after water features, and there's something about it that really appeals to me.  So, in keeping with my tradition, the header image here is ice in a glass, and the favicon is an ice cube.  Once I set that up, I plugged in jQuery, Google Analytics, made my external links open in a new windows again, added corner roundings, and made few other small tweaks to the template.  We'll see how this all pans out, but on initial inspection, I really like it.




Wednesday, January 6, 2010

Special, Special Daddy

My most favorite thing to be called in the whole world is "Special, Special Daddy".  It's Ian's name for me when he's feeling especially attached to his daddy.  I can always tell when he's having a good day by the little pet names he uses for the rest of us in the family.  However, tonight it was Caleb who needed his daddy...

Tonight I met the rest of the fam at Spageddies after work.  As I was walking in, Beth was giving a stern lecture to the boys, and they seemed pretty cranky about it.  Caleb especially.  Ian had gotten hurt at school today, and has a pretty bad mark on the back of his neck, but was reasonably okay as far as demeanor.  Caleb had no obvious reason - other than perhaps being hungry - but he was a cranky-pants.  He didn't like where he was seated (by me), got mad at the puzzle in his menu and was just plain surly.

Well, I happened to be feeling especially patient for some reason and so I started to use a little psychology on Caleb and within minutes we were happily drawing each other mazes on the paper table covering.  By the end of the meal, Caleb was sitting on my lap and I was singing both parts to Mahna Mahna to him back and forth between his ears as he grinned uncontrollably.  By the end of the night, I has both boys doubled over laughing hysterically at bath time over the "jungle bells, Batman smells" song (I'm ashamed to admit).

There are many days where I come home and am swept up in the current of everyone else's attitude.  But, every once in awhile I figure out how to take the initiative and set a different tone and get everyone else to follow it. For whatever reason, I often find it easier to work on Caleb's attitude, as Ian is too much like me at times, and that makes me somehow less able to sympathize and validate him.  It's something I need to work on because he needs that validation so much, and without it he is quite stubborn and will have a hard time deciding to set a better course.  Regardless of emotion and, as CS Lewis put it, "good digestion" - Beth and I both do our best to make sure both the boys know that they will always get unconditional love from us.

Test the edge cases

In yesterday's post, I argued that for an easy method like calculating age, the first block of C# had a real "code smell" to it that made it obvious that there were a couple of bugs and that it looked overly complicated.  I went and dug out code from my codebase at work - code I didn't write, but it's code that gets hit all the time.  But did you notice that that block of VB code has an insidious bug that the first block of C# code doesn't have? I didn't at first either.  Have a look again and see if you can spot it.

.......

Here's a test that will highlight the problem:

Dim dob = #6/2/1979#
Dim dt = #6/1/2009# ' day before 30th b-day
Assert.AreEqual(Util.Age(dob, dt), 29) ' WORKS!

dob = #6/2/1978# ' Lets use 1978 now...
Dim dt = #6/1/2008# ' day before 30th b-day
Assert.AreEqual(Util.Age(dob, dt), 29) ' FAILS!  WHAT!?

What happened here?  The second method, the one I argued yesterday was terse and still readable and therefore better has a bug in it on leap years.  Let me state Matt's axioms of programming 101 -
  1. All significant code has bugs.
  2. If you think your code is bug free, see axiom #1
  3. Code that looks bad has obvious bugs
  4. Code that looks elegant still has bugs, but you're less likely to see them
 The only defense against bugs - and it isn't foolproof - is testing.  If your code doesn't have tests, you don't know where the bugs are.  If your code only has simple tests, then you've only protected against the simple bugs.  One of the most important skills to have as a developer is the ability to see the edge cases, and test against them.  We don't have good tests written at my work, and it's one of my New Years resolutions to fix that problem.

Tuesday, January 5, 2010

Terse and readable code

I found a new blog today while searching for the answer to a tech question.  I always love finding blogs this way.  When a real IT person is able to share the solutions to their real problems in real English - well that's just a gem I can't resist.  So I subscribed to his RSS feed, and noticed a recent post about adding an extension method to the DateTime class in .NET so that you can easily calculate Age.

Debate about whether age calculation is an appropriate use of an extension method aside, this is the code that was posted:

public static int Age(this DateTime dob, DateTime fromDate)
{
   int dobYear = dob.Year;
   int fromDateYear = fromDate.Year;
   int age = fromDate.Year - dob.Year;
   //your birthdate month has not occurred yet
   if ((fromDate.Month - dob.Month) < 0)
   {
       return age == 0 ? age : age - 1;
   }
   //the day of the month of your birthday has not occurred
   if ((fromDate.Day - dob.Day) < 0)
   {
       return  age == 0 ? age : age - 1;
   }
   return age;
}

public static int AgeFromNow(this DateTime dob)
{
   return dob.Age(DateTime.Now);
}

Now, it may be a bit unfair to pick on this person's code - especially when I think the blogger in question has a really great blog.  But when you name your blog "Awesome Code" (not the real name, but that's the gist), and you post code like this, it seems only right to have some level of scrutiny of the code you post.  Not sure why dobYear and fromDateYear were even declared only to never be used again, but even if you take out those two lines this code is much more verbose than it needs to be.

I went to my codebase from work and pulled out our Age calculation method.  Here it is: 

Public Shared Function GetAge(ByVal dob As DateTime) As Integer
   Return GetAge(dob, DateTime.Now)
End Function

Public Shared Function GetAge(ByVal dob As DateTime, ByVal dt As DateTime) As Integer
   If dt.Date < dob.Date Then Return 0
   Dim factor = If(dt.DayOfYear < dob.DayOfYear, 1, 0)
   Return dt.Year - dob.Year - factor
End Function

Even though VB is more verbose by nature, this code is still much nicer.  As long as the code stays readable, I have a lot of respect for a terse, to-the-point solution to simple problems.  It's like Larry Wall says - the easy things should be easy, and the hard things possible.

Monday, January 4, 2010

Movie Recommendation

I just read this, and have to agree 100%.  Amazing flick.  I saw that one with a friend, and it, along with this one, were the two best movies I saw in the theater in '09.

Saturday, January 2, 2010

Recently... 1-2-10 ed.

In the spirit of blogging more, here's a list of some of the things I've been tuned into:

  • What I'm reading:  The Peace Maker, by Ken Sande
  • What I've been watching:  Beth and I just finished up DVR-ing and re-watching all the old episodes of Frasier.  Now I have to find something new.
  • What I'm listening to:  I've been downloading a lot of music from Amazon's MP3 store, and one of my new favorites is Big Daddy Weave.
  • Recent Podcasts:  HowStuffWorks.com has zillions of great Podcasts.  Also, of course, Hanselminutes and .NET Rocks.  I've also got a bunch of NPR stuff, and This American Life at the recommendation of my neighbor, Jos.  All of it's free (but This American Life is only free for the latest episode).
  • Recent movies:  I DVR-ed Cinderella Man - good, but pretty brutal... the movie preferred the term pugilistic.
  • Recent RSS additions:  Bing and Newsvine both have local news feeds, which are GREAT!  Then there's TechDirt, Los Techies, and Devlicio.us which make great additions to my old standbys of Slashdot and Ars Technica.
  • Recent Games:  Just finished World Of Goo for the Wii.   Now I am puzzling through the OCD challenges for all the levels.  Really fun stuff.
  • Best Satire - Hot Air suggested a modest proposal that we should be entitled to government funded legal care too.  Brilliant!
  • Best Event of 2010 so far - The Rose Bowl!