<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://honestillusion.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Honest Illusion</title><link>http://honestillusion.com/blogs/default.aspx</link><description>&lt;h3&gt;Where Lightning's Still the Biggest Thrill of All...&lt;/h3&gt;Code'n'Stuff from James Curran, simple country programmer.</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>PropertyBagTextWriter (Stream into Dictionary)</title><link>http://honestillusion.com/blogs/blog_0/archive/2011/08/18/propertybagtextwriter-stream-into-dictionary.aspx</link><pubDate>Thu, 18 Aug 2011 18:50:53 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:8133</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;It’s been too long since I posted since .NET code, and I’ve been itching to.  (Actually, I really want to write more about politics, but I figured if I don’t show some code soon, I’m gonna lost my techy audience)  Fortunately, I’ve got a backlog of things I’ve been meaning to write about.  Today’s is the PropertyBagTextWriter.&lt;/p&gt;  &lt;p&gt;The original purpose of this for a particular use in combination with Castle Monorail and Linq-2-Sql, but it has been made general purpose, so you may find a use for it in other environments.  &lt;/p&gt;  &lt;p&gt;Now, when Linq-2-Sql was still in beta, the DataContext object had a property which held, as a string, the SQL generated from the Linq query.  As I was writing a Monorail website, I often assigned that property to a value in the PorpertyBag (which is just a IDictionary, not even a IDictionary&amp;lt;K,V&amp;gt;  -- &lt;font face="Courier New"&gt;&lt;em&gt;PropertyBag[“SQL”] = db.Log;&lt;/em&gt;&lt;/font&gt;), and write it in  an HTML comment on the webpage, so I could see I was getting what I expected.  However, the designer eventually realized that a string property wasn’t good enough, as the Linq query could produce several SQL statement, some of which would be based on the response from the earlier ones.  So, they replaced it with a property which can be set to a TextWriter and have the SQL output written there.  So, to use it the way I was before, I needed a TextWriter-ish object, which would set it’s output to a value in a Dictionary  (&lt;font face="Courier New"&gt;&lt;em&gt;db.Log = new PropertyBagTextWriter(“SQL”, PropertyBag);&lt;/em&gt;&lt;/font&gt; )   The important point here is that it’s self-contained.  Once we set the property to the PropertyBagTextWriter object,  we should never have to interact with it again.  The value should just appear in the dictionary when it’s ready.&lt;/p&gt;  &lt;p&gt;The code itself is fairly straightforward.  Start by deriving a new class from StringWriter, which is usually the best way to create a customized TextWriter.  That way, it’s handle the details of gathering and formatting the data from the stream, and all we have to deal with is the string at the end.&lt;/p&gt;  &lt;pre class="csharpcode"&gt;    &lt;span class="kwrd"&gt;class&lt;/span&gt; ProperyBagTextWriter : StringWriter
    {&lt;/pre&gt;

&lt;p&gt;Next, we’re going to need to know the dictionary the output will be stored in,  and the key, so we accept those in the constructor, and hold on to them for later:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; ProperyBagTextWriter(&lt;span class="kwrd"&gt;string&lt;/span&gt; key, IDictionary bag)
{
    &lt;span class="kwrd"&gt;this&lt;/span&gt;.key = key;
    &lt;span class="kwrd"&gt;this&lt;/span&gt;.bag = bag;
}
&lt;span class="kwrd"&gt;string&lt;/span&gt; key;
IDictionary bag;&lt;/pre&gt;

&lt;p&gt;Then the key point:   When we get a Flush() call, we save the text we gathered so far into the dictionary under that key:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Flush()
{
    &lt;span class="kwrd"&gt;base&lt;/span&gt;.Flush();
    bag[key] = &lt;span class="kwrd"&gt;base&lt;/span&gt;.ToString();
}&lt;/pre&gt;

&lt;p&gt;However, since we can’t count on the Flush always being called when we need it, we’ll force a flush at other times, like during the Dispose() and after writing a line:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;protected&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Dispose(&lt;span class="kwrd"&gt;bool&lt;/span&gt; disposing)
{
    &lt;span class="kwrd"&gt;base&lt;/span&gt;.Dispose(disposing);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (disposing)
        Flush();
}&lt;/pre&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Write(&lt;span class="kwrd"&gt;char&lt;/span&gt;[] buffer, &lt;span class="kwrd"&gt;int&lt;/span&gt; index, &lt;span class="kwrd"&gt;int&lt;/span&gt; count)
{
    &lt;span class="kwrd"&gt;base&lt;/span&gt;.Write(buffer, index, count);
    Flush();
}&lt;/pre&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;That all there is to it.  Besides the Linq2Sql log, I’ve also used it for the output from a XSLT transformation.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Source Code: I’ve decided to get with the times, and create (well, actually “use”… I created it a while ago), a GitHub account.  So, you can find this class, code from my future posts, and when I get around to it, code from my older post, at &lt;a href="http://github.com/jamescurran/HonestIllusion"&gt;http://github.com/jamescurran/HonestIllusion&lt;/a&gt;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email PropertyBagTextWriter+(Stream+into+Dictionary)" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2011/08/18/propertybagtextwriter-stream-into-dictionary.aspx&amp;subject=PropertyBagTextWriter+(Stream+into+Dictionary)"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2011/08/18/propertybagtextwriter-stream-into-dictionary.aspx&amp;title=PropertyBagTextWriter+(Stream+into+Dictionary)" title="Submit PropertyBagTextWriter+(Stream+into+Dictionary) to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/08/18/propertybagtextwriter-stream-into-dictionary.aspx&amp;phase=2" title="Submit PropertyBagTextWriter+(Stream+into+Dictionary) to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/08/18/propertybagtextwriter-stream-into-dictionary.aspx&amp;title=PropertyBagTextWriter+(Stream+into+Dictionary)" title="Submit PropertyBagTextWriter+(Stream+into+Dictionary) to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=8133" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/castle/default.aspx">castle</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/monorail/default.aspx">monorail</category></item><item><title>Mathematical Proof that Birthers are Fools (and Jerome Corsi is a Con-artist)</title><link>http://honestillusion.com/blogs/blog_0/archive/2011/07/11/mathematical-proof-that-birthers-are-fools-and-jerome-corsi-is-a-con-artist.aspx</link><pubDate>Mon, 11 Jul 2011 14:45:41 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:8126</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Jerome Corsi is a right-wing writer, known mainly for writing hatchet-job books about Democrats.  His Swift-Boater opus “Unfit for Command” was a important factor in John Kerry’s loss to GW Bush.  &lt;a href="http://en.wikipedia.org/wiki/Unfit_for_Command" target="_blank"&gt;It was completely discredited too late.&lt;/a&gt;  His latest book tries to “prove” President Obama’s short-form birth certificate is a fake.  Since the book came out within days of Obama released his long form birth certificate, and Corsi still has a paperback edition to sell, to continue his quest to separate gullible Tea-Partiers from their money, he now has to attack that.&lt;/p&gt;  &lt;p&gt;To that end, he’s posted in his column on WorldNetDaily  &lt;a href="http://www.wnd.com/index.php?fa=PAGE.view&amp;amp;pageId=319221" target="_blank"&gt;Mathematical 'proof' Obama birth certificate a forgery&lt;/a&gt;.    In the article, Corsi quotes “a prominent software engineer who works as a high-level programmer for a state government”, who &lt;strong&gt;refuses to be named&lt;/strong&gt;  because he fears he’ll lose his job --- which I think is a legitimate concern, since publically slandering someone with obviously manufactured evidence is frequently a firing offense.&lt;/p&gt;  &lt;p&gt;So, I am also a “prominent software engineer” who is, however, willing to be named (James Curran, in case you missed the masthead) and can even prove his prominence with a &lt;a href="http://www.noveltheory.com/resume" target="_blank"&gt;resume&lt;/a&gt; of top-level jobs, magazine articles, user group talks, and industry awards. And I going to prove that Corsi and his fanciful “prominent software engineer” are liars.&lt;/p&gt;  &lt;p&gt;Much of the start of Corsi’s article deals with the multiple layers in the PDF file which shows their ignorance of how PDFs deal with scanned documents, but that can be explained as merely a matter of stupidity, not deceit, and &lt;a href="http://www.youtube.com/nyatnagarl#p/a/u/1/ZHZQ_SrEiOc" target="_blank"&gt;has been dealt with by others&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;The real fraud comes when they they get to the meat of the article, when they analysis Obama’s mother’s signature.  Here, the “unnamed prominent software engineer” (hereafter UPSE – feel free to pronounce it “oopsie”) claim that by “zooming into the maximum”, the letters in the signature are shown “in perfect alignment across the bottom, exactly one pixel from the bottom line”  -- something that “No person can write with mathematical perfection”.&lt;/p&gt;  &lt;p&gt;The problem here is that the images which show that – exhibits 3 &amp;amp; 4 in Corsi’s article – were deliberately manipulated specifically to create that illusion.&lt;/p&gt;  &lt;p&gt;It easy to see for yourself the manipulation – just look at the images Corsi gives us.  Below are directly from the &lt;a href="http://www.wnd.com/index.php?fa=PAGE.view&amp;amp;pageId=319221" target="_blank"&gt;WND article&lt;/a&gt; (follow the link &amp;amp; see for yourself).&lt;/p&gt;  &lt;p&gt;&lt;a href="http://honestillusion.com/blogs/blog_0/110706dunhamsignature_3CE37EBE.jpg"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="110706dunhamsignature" border="0" alt="110706dunhamsignature" src="http://honestillusion.com/blogs/blog_0/110706dunhamsignature_thumb_5AE18CB2.jpg" width="731" height="320" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This, which Corsi refers to as “Exhibit 5”, is a slightly zoomed selection from the PDF released by the White House.&lt;/p&gt;  &lt;p&gt;   &lt;br /&gt;&lt;a href="http://honestillusion.com/blogs/blog_0/110705birthcertificatesignature3_0C6CFA48.jpg"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="110705birthcertificatesignature3" border="0" alt="110705birthcertificatesignature3" src="http://honestillusion.com/blogs/blog_0/110705birthcertificatesignature3_thumb_32CEDD93.jpg" width="735" height="260" /&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;This, which Corsi refers to as “Exhibit 4”, is what UPSE alleges is a selection of the above, zoomed even further and is what shows the alignment he claims.&lt;/p&gt;  &lt;p&gt;So,  how do we know that “Exhibit 4” is a fraud?  Well, the first clue can be seen just by looking at the two images UPSE gives us.  Look at the first “a” in “Obama” in the top image.  You’ll notice some white in the middle of it.  But, if you look at the same letter in the lower image, that white space it gone.  Similarly, the end stroke of the capital “O” has a little hook in it in the first image, but that’s gone in the second. How could the zoomed in image have &lt;em&gt;less&lt;/em&gt; detail?   (As a side note, it’s rather silly of UPSE to be talking about the “mathematical precision” of the signature, when “Exhibit 5” clearly shows three completely distinct lower-case “a”s.)&lt;/p&gt;  &lt;p&gt;To see the truth, let’s make our own zoomed image. Right-click on the top image (I’m going to assume you are using Windows; You’ll have to adapt if you are using a Mac).  You can use either the image above or the one on WND – they are the same.  From the Context menu, choose “Copy” (or “Copy Image” if you’re use Chrome or Firefox).  Then open a graphic editor.  Anyone will do.  I’ll use Windows Paint here, because I know everyone has it.  So, click Start –&amp;gt; All Programs –&amp;gt; Accessories –&amp;gt; Paint.   Click the “Paste” icon on the toolbar, click twice on the (+) in the lower right to zoom the image to 300%, and it’ll look much like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://honestillusion.com/blogs/blog_0/myImage1_78DF9AA6.jpg"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="myImage1" border="0" alt="myImage1" src="http://honestillusion.com/blogs/blog_0/myImage1_thumb_44CAFB53.jpg" width="1080" height="367" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;This is what “Exhibit 4” should look like if Corsi &amp;amp; UPSE weren’t lying.  Of course, this image completely disproves UPSE’s point:  It’s quite obvious that the letters are NOT “in perfect alignment across the bottom, exactly one pixel from the bottom line”. The upper points of the “m” extend above the top of the first “a”, but are below the top of the second “a”, while the “b” and the lower points of the “m” extend below either “a”.&lt;/p&gt;  &lt;p&gt;So, how did UPSE fake the images used for Exhibit 3 &amp;amp; 4:   Again, simple enough to do, and while most graphics editors can handle the task, Windows Paint can’t.  So, I’ll use the excellent freeware app, “&lt;a href="http://getpaint.net" target="_blank"&gt;Paint.Net&lt;/a&gt;”  (warning that page has several ads which also contain the word “Download” – the one you want is in the upper right).  Install Paint.net if necessary &amp;amp; launch it.  The image should still be on your clipboard, so just choose “Edit –&amp;gt; Paste in to New Image” (If that didn’t work, you may have to do the right-click/copy from the browser image again).  Zoom the image to 300% by clicking the (+)  on the toolbar twice. You should see our friendly large scale image we have above.  Now comes the fun part : Choose “Effects –&amp;gt; Distort –&amp;gt;Pixelate”.  Set the cell size to “5” and click OK.   What you get looks remarkably like UPSE “zoomed” image:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://honestillusion.com/blogs/blog_0/myImage2_01DC005B.gif"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="myImage2" border="0" alt="myImage2" src="http://honestillusion.com/blogs/blog_0/myImage2_thumb_2899F0CE.gif" width="1074" height="403" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;So, what is done when you “Pixelate”?  Well, the fact that it’s in the “Distort” category of effects should tell you a lot.  Basically what happens, is the graphics editor takes 25 pixels (a 5 by 5 block), and replaces them with one big solid color block which is the average of all the pixel that were there.  We are left with 1/25th the information in the original.  In other words, UPSE was only able to “prove” his lies by throwing away 96% of the detail in the image.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;    &lt;p&gt;&lt;strong&gt;And I think that should be our new slogan for Jerome Corsi and WorldNetDaily:  “4% truth and 96% lies”:&lt;/strong&gt;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Mathematical+Proof+that+Birthers+are+Fools+(and+Jerome+Corsi+is+a+Con-artist)" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2011/07/11/mathematical-proof-that-birthers-are-fools-and-jerome-corsi-is-a-con-artist.aspx&amp;subject=Mathematical+Proof+that+Birthers+are+Fools+(and+Jerome+Corsi+is+a+Con-artist)"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2011/07/11/mathematical-proof-that-birthers-are-fools-and-jerome-corsi-is-a-con-artist.aspx&amp;title=Mathematical+Proof+that+Birthers+are+Fools+(and+Jerome+Corsi+is+a+Con-artist)" title="Submit Mathematical+Proof+that+Birthers+are+Fools+(and+Jerome+Corsi+is+a+Con-artist) to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/07/11/mathematical-proof-that-birthers-are-fools-and-jerome-corsi-is-a-con-artist.aspx&amp;phase=2" title="Submit Mathematical+Proof+that+Birthers+are+Fools+(and+Jerome+Corsi+is+a+Con-artist) to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/07/11/mathematical-proof-that-birthers-are-fools-and-jerome-corsi-is-a-con-artist.aspx&amp;title=Mathematical+Proof+that+Birthers+are+Fools+(and+Jerome+Corsi+is+a+Con-artist)" title="Submit Mathematical+Proof+that+Birthers+are+Fools+(and+Jerome+Corsi+is+a+Con-artist) to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=8126" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Politics/default.aspx">Politics</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/fun/default.aspx">fun</category></item><item><title>I am NOT a stalker.</title><link>http://honestillusion.com/blogs/blog_0/archive/2011/07/01/i-am-not-a-stalker.aspx</link><pubDate>Fri, 01 Jul 2011 13:14:18 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:8122</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;Yesterday, I as was stepping out of Penn Station on my way to work, I noticed that the woman walking a few steps ahead of me appeared, from the rear at least, rather pretty.  And as we started to walk up 8th Avenue, it seemed that our routes to work overlapped, so I got to follow her, without actual following her.    &lt;/p&gt;  &lt;p&gt;This reminder me of something which happened a few years ago, when I worked a bit further up Eighth Avenue, and bicycled rather than walked the distance.  That day, right out of Penn Station, I came upon another cyclist, a woman with red hair.  She was a bit stronger cyclist than I was (I had just bought my first bicycle in 30 years, while she had clearly been doing it for a while), so at every green light, she would pull ahead of me, and at every red light, I’d catch up.  This continued the 25 blocks up 8th Ave to my office.  After catch up to her a couple times, she started to give  me dirty looks, and I was convinced that she was starting to think I was a stalker, so as I approached 56th St, I felt relived that I’d be turning off 8th soon, and she could continue on her way up without someone unintentionally following her.  Except she turn down 56th street also.  And, then, even more surprisingly,  pulled into the loading dock of my office building, just feet ahead of me.  We then, in silence, locked our bicycles up on the same bike rack, just feet apart, and then went about our business on separate floors of the building.  A few months later, we did the parallel ride again, and I saw her once or twice in the building cafeteria.  Never did speak to her.&lt;/p&gt;  &lt;p&gt;Which bring as back to today, and the possibly pretty woman walking a few steps ahead of me up 8th Ave, and who was still there as I ended my daydream about past cycling adventures, as I approached my office building, this time a mere 5 blocks from Penn Station at 38th street.  And as I silently bid her back a farewell as I prepared to turn into the door of the building—she did something surprising.  She turned into the building as well.&lt;/p&gt;  &lt;p&gt;The elevator ride up demonstrated that she works five floors below me – and that she really was pretty when viewed from the front.  Didn’t speak to her either.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email I+am+NOT+a+stalker." href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2011/07/01/i-am-not-a-stalker.aspx&amp;subject=I+am+NOT+a+stalker."&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2011/07/01/i-am-not-a-stalker.aspx&amp;title=I+am+NOT+a+stalker." title="Submit I+am+NOT+a+stalker. to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/07/01/i-am-not-a-stalker.aspx&amp;phase=2" title="Submit I+am+NOT+a+stalker. to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/07/01/i-am-not-a-stalker.aspx&amp;title=I+am+NOT+a+stalker." title="Submit I+am+NOT+a+stalker. to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=8122" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/My+Life/default.aspx">My Life</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Random+Thoughts/default.aspx">Random Thoughts</category></item><item><title>Get an ApplicationBarIconButton by name (Redux)</title><link>http://honestillusion.com/blogs/blog_0/archive/2011/05/24/get-an-applicationbariconbutton-by-name-redux.aspx</link><pubDate>Tue, 24 May 2011 13:48:32 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:8117</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Yesterday, I read a blog post on &lt;a href="http://www.ariankulp.com/get-an-applicationbariconbutton-by-name" target="_blank"&gt;getting an ApplicationBarIconButton by name&lt;/a&gt;.  The author made a couple minor errors in the code, which I was going to leave a comment about, except his comment page is broken. So, another excuse to write something for my own blog.&lt;/p&gt;  &lt;p&gt;The basics of the article are that in Windows Phone 7 coding, when referencing the ApplicationBar buttons, you never get an direct reference – you have to look the one you want up by name – and the author provided some code:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; ApplicationBarIconButton GetAppBarIconButton(&lt;span class="kwrd"&gt;string&lt;/span&gt; name)
{
    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (var b &lt;span class="kwrd"&gt;in&lt;/span&gt; ApplicationBar.Buttons)
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (((ApplicationBarIconButton)b).Text == name)
            &lt;span class="kwrd"&gt;return&lt;/span&gt; (ApplicationBarIconButton)b;

    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;That’s rather ugly code for a simple function.  What really bothered me was that he didn’t just cast the object – he casted it &lt;em&gt;twice  &lt;/em&gt;pointlessly.&lt;/p&gt;

&lt;p&gt;The author states that this is a bit uglier than you’d expect (and non-LINQ-able) because ApplicationBar.Button returns an IList, and because “the collection of buttons are of type &lt;em&gt;Object&lt;/em&gt;, so you need to cast them.”   &lt;/p&gt;

&lt;p&gt;Neither of those statements are exactly accurate.  The objects in the collection really are of type ApplicationBarIconButton.  They just appear to be Object types due to the effect of the IList.  Why exactly that property returns an IList instead of the more precise IList&amp;lt;ApplicationBarIconButton&amp;gt; is a mystery known only to the devs at Microsoft. &lt;/p&gt;

&lt;p&gt;So, are we stuck with this?  No, we can improve that code.  “var” is often a very useful keyword, but you must understand what it does.  It says “declare this variable of the type of the object presented to initialize it” – which is expressly what we do &lt;strong&gt;not &lt;/strong&gt;want here.  The IList is presenting the objects in the Buttons collections as Objects; but we know that they are ApplicationBarIconButtons and we want they treated like that.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; ApplicationBarIconButton GetAppBarIconButton(&lt;span class="kwrd"&gt;string&lt;/span&gt; name)
{
    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (ApplicationBarIconButton b &lt;span class="kwrd"&gt;in&lt;/span&gt; ApplicationBar.Buttons)
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (b.Text == name)
            &lt;span class="kwrd"&gt;return&lt;/span&gt; b;

    &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;null&lt;/span&gt;;
}&lt;/pre&gt;

&lt;p&gt;Much cleaner, huh?  But, let’s return to the author’s original point.  He wanted to use LINQ, but was blocked by the ILIST.   However, Microsoft realized that’s often a problem, and wrote a way around it:  The &lt;strong&gt;Cast&amp;lt;T&amp;gt;()&lt;/strong&gt; method.   It takes a non-generic IList, and a type, and transforms it into an generic IList&amp;lt;T&amp;gt;.  With that, the LINQ version is trivial:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; ApplicationBarIconButton GetAppBarIconButton(&lt;span class="kwrd"&gt;string&lt;/span&gt; name)
{
  &lt;span class="kwrd"&gt;return&lt;/span&gt; ApplicationBar.Buttons.Cast&amp;lt;ApplicationBarIconButton&amp;gt;().FirstOrDefault(b=&amp;gt;b.Text == name);
}&lt;/pre&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Get+an+ApplicationBarIconButton+by+name+(Redux)" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2011/05/24/get-an-applicationbariconbutton-by-name-redux.aspx&amp;subject=Get+an+ApplicationBarIconButton+by+name+(Redux)"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2011/05/24/get-an-applicationbariconbutton-by-name-redux.aspx&amp;title=Get+an+ApplicationBarIconButton+by+name+(Redux)" title="Submit Get+an+ApplicationBarIconButton+by+name+(Redux) to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/05/24/get-an-applicationbariconbutton-by-name-redux.aspx&amp;phase=2" title="Submit Get+an+ApplicationBarIconButton+by+name+(Redux) to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/05/24/get-an-applicationbariconbutton-by-name-redux.aspx&amp;title=Get+an+ApplicationBarIconButton+by+name+(Redux)" title="Submit Get+an+ApplicationBarIconButton+by+name+(Redux) to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=8117" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Generics+without+Collections/default.aspx">Generics without Collections</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>Creating an Entity Framework connection from another one.</title><link>http://honestillusion.com/blogs/blog_0/archive/2011/05/02/creating-an-entity-framework-connection-from-another-one.aspx</link><pubDate>Mon, 02 May 2011 14:43:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:8108</guid><dc:creator>James</dc:creator><slash:comments>2</slash:comments><description>
  &lt;p&gt;Database connection strings used to be simple.  Well, simple, once you learned the arcane syntax,  But, at least they had stayed the same for about a decade.  But with the EntityFramework, they took on an even more arcane “connection string – within –a –connection string” format.  And while the inner connection string related to your database, the wrapping connection string was intimately tied to the entity context.&lt;/p&gt;
  
&lt;p&gt;So, in that past, one App.config connect string entry was good for all your DB needs for one database.  Now, if you have several different EF contexts, all referring to tables in the same physical database, you need to have several connection strings, with the outer string different and the inner part the same --- until you need to connect to a different database, then you leave the existing outer strings and change all the inner string in parallel.  This really seems to me to be a design flaw on Microsoft’s part, but let’s see if we can work something to make it easier.  We’d really like to have one connection string for all our EF needs.  &lt;/p&gt;
  
&lt;p&gt;If you’re using more than one EF context, you’re probably using one for most things – your core business objects – and others for more cross-project, framework needs (auditing, logging etc.).   So, let’s say you have one connection string set up for the main context, then all we need do is write a method which takes one EF context, extracts the database connection information, and uses that to build a new EF context.&lt;/p&gt;
  
&lt;p&gt;And the Entity Framework meets us halfway, providing the EntityConnectionStringBuilder class.  We just create an EntityConnectionStringBuilder object, set three properties, and boom—we have our new connection string.  And one of those properties (&lt;strong&gt;Provider&lt;/strong&gt;) is pretty much fixed (usually, "System.Data.SqlClient", but even if it’s for a different vender, you’ll probably be standardized on one database vendor).   The second (&lt;strong&gt;Metadata&lt;/strong&gt;) is basically fixed for the context (I assume there’s sometime a need to vary that, but I haven’t seen one).  That just leaves &lt;strong&gt;ProviderConnectionString, &lt;/strong&gt;which is where things get tricky.  &lt;/p&gt;
  
&lt;p&gt;While that EntityContext object does contain the needed connection string, it’s buried three levels down,  in a property not exposed by the IDbConnection interface that we are given.  We have to cast a property to an EntityConnection object to be able to access it.&lt;/p&gt;
  
&lt;p&gt;Putting all that together, here’s the code:&lt;/p&gt;
  &lt;div class="csharpcode"&gt;   
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   1:  &lt;/span&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; SecondEFContext(FirstEFContext context1)    // new ctor defined in partial class&lt;/pre&gt;
  
&lt;pre&gt;&lt;span class="lnum"&gt;   2:  &lt;/span&gt;{&lt;/pre&gt;
  
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   3:  &lt;/span&gt;            var eb = &lt;span class="kwrd"&gt;new&lt;/span&gt; EntityConnectionStringBuilder();&lt;/pre&gt;
  
&lt;pre&gt;&lt;span class="lnum"&gt;   4:  &lt;/span&gt;            eb.Provider = &lt;span class="str"&gt;"System.Data.SqlClient"&lt;/span&gt;;&lt;/pre&gt;
  
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   5:  &lt;/span&gt;            var context1Conn = context1.Connection &lt;span class="kwrd"&gt;as&lt;/span&gt; EntityConnection;&lt;/pre&gt;
  
&lt;pre&gt;&lt;span class="lnum"&gt;   6:  &lt;/span&gt;            eb.ProviderConnectionString = context1Conn.StoreConnection.ConnectionString;&lt;/pre&gt;
  
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   7:  &lt;/span&gt;            eb.Metadata = &lt;span class="str"&gt;@"res://*/SecondEF.csdl|res://*/SecondEF.ssdl|res://*/SecondEF.msl"&lt;/span&gt;;&lt;/pre&gt;
  
&lt;pre&gt;&lt;span class="lnum"&gt;   8:  &lt;/span&gt; &lt;/pre&gt;
  
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;   9:  &lt;/span&gt;            var entC = &lt;span class="kwrd"&gt;new&lt;/span&gt; EntityConnection(eb.ToString());&lt;/pre&gt;
  
&lt;pre&gt;&lt;span class="lnum"&gt;  10:  &lt;/span&gt; &lt;/pre&gt;
  
&lt;pre class="alt"&gt;&lt;span class="lnum"&gt;  11:  &lt;/span&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; SecondEFContext(entC);&lt;/pre&gt;
  
&lt;pre&gt;&lt;span class="lnum"&gt;  12:  &lt;/span&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;a href="http://dotnetshoutout.com/Honest-Illusion-Creating-an-Entity-Framework-connection-from-another-one"&gt;&lt;img style="border:0px currentColor;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fhonestillusion.com%2Fblogs%2Fblog_0%2Farchive%2F2011%2F05%2F02%2Fcreating-an-entity-framework-connection-from-another-one.aspx" /&gt;&lt;/a&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2011%2f05%2f02%2fcreating-an-entity-framework-connection-from-another-one.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" src="http://honestillusion.com/controlpanel/blogs/http%3A%2F%2Fwww.dotnetkicks.com%2FServices%2FImages%2FKickItImageGenerator.ashx%3Furl%3Dhttp%253a%252f%252fhonestillusion.com%252fblogs%252fblog_0%252farchive%252f2011%252f05%252f02%252fcreating-an-entity-framework-connection-from-another-one.aspx" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Creating+an+Entity+Framework+connection+from+another+one." href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2011/05/02/creating-an-entity-framework-connection-from-another-one.aspx&amp;subject=Creating+an+Entity+Framework+connection+from+another+one."&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2011/05/02/creating-an-entity-framework-connection-from-another-one.aspx&amp;title=Creating+an+Entity+Framework+connection+from+another+one." title="Submit Creating+an+Entity+Framework+connection+from+another+one. to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/05/02/creating-an-entity-framework-connection-from-another-one.aspx&amp;phase=2" title="Submit Creating+an+Entity+Framework+connection+from+another+one. to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/05/02/creating-an-entity-framework-connection-from-another-one.aspx&amp;title=Creating+an+Entity+Framework+connection+from+another+one." title="Submit Creating+an+Entity+Framework+connection+from+another+one. to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=8108" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/EntityFramework/default.aspx">EntityFramework</category></item><item><title>And Now For Some Politics… What If John McCain Had Been Elected?</title><link>http://honestillusion.com/blogs/blog_0/archive/2011/03/23/and-now-for-some-politics-what-if-john-mccain-had-been-elected.aspx</link><pubDate>Wed, 23 Mar 2011 18:24:08 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:8104</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Ok, after three technical articles in a week, it’s about time to branch out a bit, and talk a bit of politics.&lt;/p&gt;  &lt;p&gt;Over at AssociatedContent, which is apparently part of the “Yahoo! Contributor Network”, they seem to let just about any yahoo sign up as a columnist and have their articles published as part of the Yahoo! News feeds, just as if it were written by a pundit who actually knew what they were talking about.  One such commentator is Mark Whittington, who last week penned an article entitled “&lt;a href="http://news.yahoo.com/s/ac/20110316/pl_ac/8074814_what_if_john_mccain_was_president" target="_blank"&gt;What If John McCain was President?&lt;/a&gt;”.    It was…um.. imaginative, to say the least.  So, I thought I’d try a more reality-based rebuttal.  Note: This will be taking the same structure as his article, and following it point-by-point, so I’ll quoting bits of it, so you know what I’m talking about.  Of course, that will lead to charges of “cherry-picking quotes” and taking them out-of-context, so if you feel that way, just read the full article at the link given above.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Health care reform: &lt;/strong&gt;Whittington correctly surmised that the Health Care Reform Bill would never have been brought up.  Hard to argue with that.  However he then goes on to say the a McCain administration might “propose more market-oriented reforms, but nothing would move in a Pelosi/Reid Congress”.  I’m not sure what potential reforms he has in mind, but the important part here is that he apparently believe the Democrats will reject it merely because it was proposed by a Republican.  I guess after years of being a Republican, he just can’t imagine a politician doing something merely because it was in the best interest of the citizens (since clearly Republicans never do)&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Spending:&lt;/strong&gt;  Well, after one mostly accurate prediction, Whittington goes off the rails with his next one.  “&lt;em&gt;There would be no $900 billion dollar spending package&lt;/em&gt;”.  Wait a minute --- Let us not forget that it was McCain who, during the 2008 campaign,  most loudly cried that the economy was in trouble and that we had to act immediately to respond.  The &lt;em&gt;only &lt;/em&gt;way to get a stalled economy moving again is to spend money. Republicans like talking about giving money to businesses to hire more people, but no business is going to hire more workers unless someone is buying their products, no matter how much loose cash they have.  Every plan to stimulate an economy boils down to this: &lt;strong&gt;Money must be spent.&lt;/strong&gt;  If you don’t understand that, you just don’t understand how economies work.  The spending doesn’t have to be by the government—ordinary people could do it instead -- but government spending is the fastest way.  Alternately, you turn to the Republicans one-size-fits-all solution to every problem:  tax-cuts:  People have more money; they spend more money; the economy is happy.  The problem with that is that you have to wait for the money to enter the economy slowly, and hope that the people that get the tax-cut spend it instead of saving it.  Of course, if you cut government spending to pay for the tax-cut, it’s a wash.  The best to can hope for it total spending staying the same, and to help the economy, &lt;em&gt;spending must increase&lt;/em&gt;.    A large portion of the current stimulus package is tax cuts (yes, your taxes are lower than they have been in many years), so it’s safe to assume that a McCain stimulus plan would be just larger cuts. In other words, costing the same amount or nearly so, but less effective.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Energy:&lt;/strong&gt;  Here he gives a list of things a President McCain would have supported: curbing greenhouse gases, cap and trade, no drilling in ANWR – most of which would have put him at odds with his Vice President and the rest of his party.  But this is exactly what the maverick-y John McCain of 2008 would do.  However, since then Sen. McCain has been rushing to fall inline with the far right-wing of his party, to the point of even denying he ever called himself a “Maverick” (despite it being in the subtitle of his autobiography).  We can’t say what a Pres. McCain of 2011 would do, but it’s hard to imagine a Sen. McCain of 2011 supporting those positions.   Then there is the ethanol subsidies, which Whittington says Pres. McCain would “certainly” have opposed.  Except that this subsidy goes mainly to Midwest corn farmers, that is, small business owners in red states.  Generally, it’s bad idea to have your first Presidential act to be to screw over the very people who just elected you.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Foreign Policy:&lt;/strong&gt;  Whittington claims here McCain would “shine”.  Perhaps, but Whittington certainly doesn’t.  He claims McCain would have been more aggressive with Iran and North Korea, and established a no-fly zone in Libya – he was writing before the actual no-fly zone was established, but also before the UN had approved it.  In other words, Whittington thinks we should have acted unilaterally to invade three more countries, while we are still struggling to leave the two countries the last Republican president choose to invade.  Our troops would have been spread so widely and so thin, support cost and causalities would have been enormous.  And by acting without UN endorsement, we would be continuing the foreign policy started by Pres. Reagan: “The United States as the World’s Neighborhood Bully, who goes anywhere he wants and pushes around anyone he doesn’t like”.  This is largely the reason why &lt;em&gt;everyone in the world hates us&lt;/em&gt;!   And this is why Pres. Obama specifically waited until an international consensus had agreed that the no-fly zone was warranted.  (And I’m sure a Pres. McCain would have known that too, so we’ll put this all on Whittington).&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Space Program:&lt;/strong&gt; Whittington claims the McCain would have supported new exploration “perhaps with more funding”.  I cannot argue with that, but its funny that one time he talks specifically about funding a project, he talking about &lt;em&gt;increasing &lt;/em&gt;funding.  This “cutting the fat” to balance the budget thing isn’t as easy as it looks, eh?&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Economy &amp;amp; Politics:&lt;/strong&gt;  I’ll combine the last two, because, even in Whittington’s article, they are clearly linked.  This is because of one basic truth of incumbent presidents – if the economy is good, they will be re-elected; if not, they won’t.  Hence the primary political/economy difference between a McCain and an Obama administration is whether the Republicans want to see the current president re-elected (economy must be good) or defeated (economy must be bad).  Presently, they want the current president defeated, and so, they are doing everything they can to undermine the economy.   They have claimed that their number one priority is “Jobs” and yet they haven’t done a single thing which would produce a job.  In fact, the only economic measures they have done is to cut spending and threaten to lay-off government workers --- two things that will clearly make the economy worse.  &lt;/p&gt;  &lt;p&gt;So, what would be different under a Pres. McCain, where the Republican would want to keep the sitting president in power, and therefore must get the economy moving?  Of course, they don’t want it really strong, as it was under Clinton --- then the workers have power and they start asking for things like raises and time off and health care.  They need it moving just fast enough to keep the people content.   Hence,  they need to do some thing to actual improve it.  So, lots’o’tax cuts, but there would so need to be many infrastructure construction projects as there is under the current stimulus package,  which they would bill as “putting American to Work” and “Restoring America’s Greatness”.  The deficit will skyrocket even more than it is now.  There would be a Tea Party but without the support of their corporate sponsors (FreedomWorks, Fox News, Koch Industries), it would be small and disorganized.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email And+Now+For+Some+Politics%e2%80%a6+What+If+John+McCain+Had+Been+Elected%3f" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2011/03/23/and-now-for-some-politics-what-if-john-mccain-had-been-elected.aspx&amp;subject=And+Now+For+Some+Politics%e2%80%a6+What+If+John+McCain+Had+Been+Elected%3f"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/23/and-now-for-some-politics-what-if-john-mccain-had-been-elected.aspx&amp;title=And+Now+For+Some+Politics%e2%80%a6+What+If+John+McCain+Had+Been+Elected%3f" title="Submit And+Now+For+Some+Politics%e2%80%a6+What+If+John+McCain+Had+Been+Elected%3f to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/23/and-now-for-some-politics-what-if-john-mccain-had-been-elected.aspx&amp;phase=2" title="Submit And+Now+For+Some+Politics%e2%80%a6+What+If+John+McCain+Had+Been+Elected%3f to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/23/and-now-for-some-politics-what-if-john-mccain-had-been-elected.aspx&amp;title=And+Now+For+Some+Politics%e2%80%a6+What+If+John+McCain+Had+Been+Elected%3f" title="Submit And+Now+For+Some+Politics%e2%80%a6+What+If+John+McCain+Had+Been+Elected%3f to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=8104" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Politics/default.aspx">Politics</category></item><item><title>Automating Retry on Exception</title><link>http://honestillusion.com/blogs/blog_0/archive/2011/03/21/automating-retry-on-exception.aspx</link><pubDate>Mon, 21 Mar 2011 16:11:51 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:8102</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Every so often, you run across some action,  which just fails, where the best response it to just try it again.  This is particularly true when dealing with an external source, like a database or web service, which can have network or other temporary problems, which would have cleared up when you repeat the call seconds later.   Often, these actions fail by throwing an exception which makes the process of trying the call again rather cumbersome.  Having to deal with this a number of times in one application, I decided to wrap the full procedure up in a method, which I share here with you:&lt;/p&gt;  &lt;p&gt;OK, this has very weird semantics.  A call will look something like this:&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;var msg = Util.Retry(5, 1,&lt;/pre&gt;

  &lt;pre&gt;            ( ) =&amp;gt; &lt;span class="str"&gt;"Error"&lt;/span&gt;,&lt;/pre&gt;

  &lt;pre class="alt"&gt;            AppLog.Log,   &lt;span class="rem"&gt;// assuming there is an AppLog.Log(Exception ex) method.&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;            ( ) =&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            {&lt;/pre&gt;

  &lt;pre&gt;                    &lt;span class="rem"&gt;// Simulation of a function which fails &amp;amp; succeeds at random times&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;                    Console.WriteLine(DateTime.Now.ToLongTimeString());&lt;/pre&gt;

  &lt;pre&gt;                    &lt;span class="kwrd"&gt;if&lt;/span&gt; ((DateTime.Now.Second &amp;amp; 7) != 7)&lt;/pre&gt;

  &lt;pre class="alt"&gt;                    &lt;span class="kwrd"&gt;throw&lt;/span&gt; &lt;span class="kwrd"&gt;new&lt;/span&gt; Exception(&lt;span class="str"&gt;"Bad"&lt;/span&gt;);&lt;/pre&gt;

  &lt;pre&gt;                    &lt;span class="kwrd"&gt;return&lt;/span&gt; DateTime.Now.ToString();&lt;/pre&gt;

  &lt;pre class="alt"&gt;            });&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The first parameter is the maximum num of time to retry the call before giving up.  &lt;/p&gt;

&lt;p&gt;The second parameter is the time, in seconds, to wait between retries.&lt;/p&gt;

&lt;p&gt;The third parameter is a function (or lambda expression) taking no parameters, and returning the value to return in case of failure. It done as a function to avoid evaluating it unless needed, in case it was a heavy-weight object, or had some side-effect.&lt;/p&gt;

&lt;p&gt;The  fourth parameter (made optional by way of an overload) is a function (or lambda expression) taking an exception as a parameter, and returning nothing.  Can be used to log the final exception on it gives up retrying.&lt;/p&gt;

&lt;p&gt;The last parameter is a function (or lambda expression) taking no parameters, which performs the actual work which may need to be retried. 
  &lt;br /&gt;&lt;/p&gt;

&lt;p&gt;The code looks like this:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; T Retry&amp;lt;T&amp;gt;(&lt;span class="kwrd"&gt;int&lt;/span&gt; retries, &lt;span class="kwrd"&gt;int&lt;/span&gt; secsDelay, Func&amp;lt;T&amp;gt; errorReturn,   Action&amp;lt;Exception&amp;gt; onError,  Func&amp;lt;T&amp;gt; code)&lt;/pre&gt;

  &lt;pre&gt;{&lt;/pre&gt;

  &lt;pre class="alt"&gt;    Exception ex = &lt;span class="kwrd"&gt;null&lt;/span&gt;;&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;do&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;    {&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;try&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        {&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; code();&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;catch&lt;/span&gt; (Exception dde)&lt;/pre&gt;

  &lt;pre class="alt"&gt;        {&lt;/pre&gt;

  &lt;pre&gt;            ex = dde;&lt;/pre&gt;

  &lt;pre class="alt"&gt;            retries--;&lt;/pre&gt;

  &lt;pre&gt;            Thread.Sleep(secsDelay * 1000);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        }&lt;/pre&gt;

  &lt;pre&gt;    } &lt;span class="kwrd"&gt;while&lt;/span&gt; (retries &amp;gt; 0);&lt;/pre&gt;

  &lt;pre class="alt"&gt;    onError(ex);&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; errorReturn();&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The full source code (with comments and everything!) is &lt;a href="http://honestillusion.com/files/folders/c-sharp/entry8103.aspx" target="_blank"&gt;here&lt;/a&gt;:&lt;/p&gt;

&lt;a href="http://dotnetshoutout.com/Honest-Illusion-Automating-Retry-on-Exception"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fhonestillusion.com%2Fblogs%2Fblog_0%2Farchive%2F2011%2F03%2F21%2Fautomating-retry-on-exception.aspx" style="border:0px;" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Automating+Retry+on+Exception" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2011/03/21/automating-retry-on-exception.aspx&amp;subject=Automating+Retry+on+Exception"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/21/automating-retry-on-exception.aspx&amp;title=Automating+Retry+on+Exception" title="Submit Automating+Retry+on+Exception to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/21/automating-retry-on-exception.aspx&amp;phase=2" title="Submit Automating+Retry+on+Exception to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/21/automating-retry-on-exception.aspx&amp;title=Automating+Retry+on+Exception" title="Submit Automating+Retry+on+Exception to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=8102" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>The Evolutionary Guide to C# Lambda Syntax</title><link>http://honestillusion.com/blogs/blog_0/archive/2011/03/17/the-evolutionary-guide-to-c-lambda-syntax.aspx</link><pubDate>Thu, 17 Mar 2011 18:13:50 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:8099</guid><dc:creator>James</dc:creator><slash:comments>2</slash:comments><description>
  &lt;p&gt;Originally (.NET V1.1), we had to explicitly create a Delegate object to wrap a method reference to use it as a callback method, and that method had to named.&lt;/p&gt;  &lt;div class="csharpcode"&gt;   &lt;pre class="alt"&gt;button1.Click += &lt;span class="kwrd"&gt;new&lt;/span&gt; EventHandler(button1_Click);&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="rem"&gt;// :&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="rem"&gt;// :&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;void&lt;/span&gt; button1_Click(&lt;span class="kwrd"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;

  &lt;pre class="alt"&gt;{&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="rem"&gt;DoStuff();&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;}&lt;/pre&gt;

  &lt;pre&gt; &lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;With .NET v2.0, The C# compiler got smart enough to realize that when I used a method reference in code, I needed it wrapped up as a delegate, so it would silently to that for me.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    button1.Click += button1_Click;&lt;/pre&gt;

&lt;p&gt;Better still, C#2 added anonymous methods, which could be written inline.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    button1.Click += &lt;span class="kwrd"&gt;delegate&lt;/span&gt; (&lt;span class="kwrd"&gt;object&lt;/span&gt; s, EventArgs ea) { DoStuff();}&lt;/pre&gt;

&lt;p&gt;Then, C#3, we got lambdas, which were basically anonymous methods with a cleaned up syntax.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    button1.Click += (&lt;span class="kwrd"&gt;object&lt;/span&gt; s, EventArgs ea) =&amp;gt; { DoStuff(); };&lt;/pre&gt;

&lt;p&gt;But, at the same time, the compiler got brighter about figuring things out for itself.  For example,  the Button Click event took a delegate to a method which had an object and an EventArgs parameter.  Giving it anything else is a compile-time error.  So, since we all agree that those are the parameters, why is it necessary for us to stand that out loud.  Why not just let the compile assume it.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    button1.Click += (s, ea) =&amp;gt; { DoStuff(); };&lt;/pre&gt;

&lt;p&gt;From there, we have just a few more refinements, for special (but common) cases, but for these we can no longer use Button Click as the destination of our method reference, so from here on out, we’ll be use Enumerator.Where on an int array.  The important point here is that the lambda we will be writing takes an int, and return a bool.  Within that environment, our last syntax would look like this:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;int&lt;/span&gt;[] x = &lt;span class="kwrd"&gt;new&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt;[] {1,2,3,4};&lt;/pre&gt;

  &lt;pre&gt;    var y = x.Where((x)=&amp;gt;{&lt;span class="kwrd"&gt;return&lt;/span&gt; x % 2 == 0;}).ToList();&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;But, if we have just one parameter, the compiler can figure out where it starts and ends, so we don’t need the parenthesis. &lt;/p&gt;

&lt;pre class="csharpcode"&gt;    var y = x.Where( x =&amp;gt; { &lt;span class="kwrd"&gt;return&lt;/span&gt; x % 2 == 0;}).ToList();&lt;/pre&gt;

&lt;p&gt;Finally, if all the function does is return a value (which is all a true lambda function is supposed to do), we can eliminate the curly braces and even the &lt;strong&gt;return&lt;/strong&gt; :&lt;/p&gt;

&lt;pre class="csharpcode"&gt;    var y = x.Where( x =&amp;gt;  x % 2 == 0).ToList();&lt;/pre&gt;

&lt;p&gt;And that’s really all you need to know to write a lambda function.&lt;/p&gt;

&lt;a href="http://dotnetshoutout.com/Honest-Illusion-The-Evolutionary-Guide-to-C-Lambda-Syntax"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fhonestillusion.com%2Fblogs%2Fblog_0%2Farchive%2F2011%2F03%2F17%2Fthe-evolutionary-guide-to-c-lambda-syntax.aspx" style="border:0px;" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email The+Evolutionary+Guide+to+C%23+Lambda+Syntax" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2011/03/17/the-evolutionary-guide-to-c-lambda-syntax.aspx&amp;subject=The+Evolutionary+Guide+to+C%23+Lambda+Syntax"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/17/the-evolutionary-guide-to-c-lambda-syntax.aspx&amp;title=The+Evolutionary+Guide+to+C%23+Lambda+Syntax" title="Submit The+Evolutionary+Guide+to+C%23+Lambda+Syntax to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/17/the-evolutionary-guide-to-c-lambda-syntax.aspx&amp;phase=2" title="Submit The+Evolutionary+Guide+to+C%23+Lambda+Syntax to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/17/the-evolutionary-guide-to-c-lambda-syntax.aspx&amp;title=The+Evolutionary+Guide+to+C%23+Lambda+Syntax" title="Submit The+Evolutionary+Guide+to+C%23+Lambda+Syntax to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=8099" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>Running An Async Event Handler on the UI thread (with lambdas and extension methods!)</title><link>http://honestillusion.com/blogs/blog_0/archive/2011/03/15/running-an-async-event-handler-on-the-ui-thread-with-lambdas-and-extension-methods.aspx</link><pubDate>Tue, 15 Mar 2011 18:56:01 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:8098</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;So, it’s been a freakishly long time since my last post here.  &lt;/p&gt;  &lt;p&gt;I’ve been trying to get better… I even wrote out a list of topics I wanted to write about.  So, let’s start talking about them.&lt;/p&gt;  &lt;p&gt;As we do more and more work in our applications asynchronously, we’re confronted with the problem of how to communicate the status of the background thread to our users.  Firing an event seems like the best way, except anything the user can see has to be done by the UI thread, which is specifically not the thread the background task is running on. &lt;/p&gt;  &lt;p&gt;Winforms offers a means of redirecting execution onto the UI thread, the Form.Invoke method, but using it makes life difficult.   This is particular true when you throw lambdas into the mix.  Lambdas made it quite easy to write a simple event handler:&lt;/p&gt;  &lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:650px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  backgroundAction.StepCompleted +=
         (s, ea) =&amp;gt; {statusMsg.Text = String.Format("&lt;span style="color:#8b0000;"&gt;Step #{0} Completed&lt;/span&gt;", ea.StepNum);}&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;But when we add is thread marshaling, it gets messy:&lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:958px;padding-right:5px;height:52px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;  backgroundAction.StepCompleted +=
&lt;/pre&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;    (s, ea) =&amp;gt;{&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Invoke((s1,ea1)=&amp;gt;{statusMsg.Text = String.Format("&lt;span style="color:#8b0000;"&gt;Step #{0} Completed&lt;/span&gt;", ea.StepNum);}, s,ea);&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;And that’s with always marshaling it.  If the event could be fired from both a background thread or from the main thread depending on the context, then you should check the InvokeRequired property, if call the action directly if it’s not needed.  But complicates our lives, making us split the action out into a named function:&lt;/p&gt;

&lt;pre style="border-bottom:#cecece 1px solid;border-left:#cecece 1px solid;padding-bottom:5px;background-color:#fbfbfb;min-height:40px;padding-left:5px;width:650px;padding-right:5px;overflow:auto;border-top:#cecece 1px solid;border-right:#cecece 1px solid;padding-top:5px;"&gt;&lt;pre style="background-color:#fbfbfb;margin:0em;width:100%;font-family:consolas,'Courier New',courier,monospace;font-size:12px;"&gt;backgroundTask.StepCompleted += ((s, ea) =&amp;gt;
{
  &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.InvokeRequired)
    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.Invoke(UpdateStatus, s, ea);
  &lt;span style="color:#0000ff;"&gt;else&lt;/span&gt;
    UpdateStatus(s,ea);
});
&lt;span style="color:#008000;"&gt;// ...&lt;/span&gt;
&lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; UpdateStatus(&lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; sender, MessageEventArgs ea)
{
  statusMsg.Text = String.Format("&lt;span style="color:#8b0000;"&gt;Step #{0} Completed&lt;/span&gt;", ea.StepNo);
}
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;Yech!  We have a lambda, but it we’re using it for the boiler-plate code and that we will probably have to repeat.  And the real method we want to perform is in a separate function.&lt;/p&gt;

&lt;p&gt;What we need is a handle utility function which will take a method reference, or, better yet, a lambda, and package it up as we need it. Then we could write it like: &lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;backgroundTask.StepCompleted += &lt;/pre&gt;

  &lt;pre&gt;   ToUIThread&amp;lt;StepEventArgs&amp;gt;((s, ea) =&amp;gt; statusMsg.Text = String.Format(&lt;span class="str"&gt;"Step #{0} Completed"&lt;/span&gt;, ea.StepNo));&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;The tricky part about this is that it must take a function as a parameter, and &lt;em&gt;return&lt;/em&gt; a function. Plus, the compiler can’t figure out the type of the second parameter by itself, so we have to give it some help.  And, we we’ll need a non-generic version, for event which are defined as EventHandle instead of EventHandler&amp;lt;TEventArgs&amp;gt;.   Make it an extension method on Form, and we’ve got:&lt;/p&gt;

&lt;div class="csharpcode"&gt;
  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Threading;&lt;/pre&gt;

  &lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Threading.Tasks;&lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.Windows.Forms;&lt;/pre&gt;

  &lt;pre class="alt"&gt; &lt;/pre&gt;

  &lt;pre&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; FormExt&lt;/pre&gt;

  &lt;pre class="alt"&gt;{&lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; EventHandler&amp;lt;TEventArgs&amp;gt; ToUIThread&amp;lt;TEventArgs&amp;gt;(&lt;span class="kwrd"&gt;this&lt;/span&gt; Form frm, EventHandler&amp;lt;TEventArgs&amp;gt; handler)&lt;/pre&gt;

  &lt;pre class="alt"&gt;                &lt;span class="kwrd"&gt;where&lt;/span&gt; TEventArgs : System.EventArgs&lt;/pre&gt;

  &lt;pre&gt;    {&lt;/pre&gt;

  &lt;pre class="alt"&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; ((sender, e) =&amp;gt;&lt;/pre&gt;

  &lt;pre&gt;        {&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (frm.InvokeRequired)&lt;/pre&gt;

  &lt;pre&gt;                frm.Invoke(handler, sender, e);&lt;/pre&gt;

  &lt;pre class="alt"&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre&gt;                handler(sender, e);&lt;/pre&gt;

  &lt;pre class="alt"&gt;        });&lt;/pre&gt;

  &lt;pre&gt;    }&lt;/pre&gt;

  &lt;pre class="alt"&gt; &lt;/pre&gt;

  &lt;pre&gt;    &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;public&lt;/span&gt; EventHandler ToUIThread(&lt;span class="kwrd"&gt;this&lt;/span&gt; Form frm, EventHandler handler)&lt;/pre&gt;

  &lt;pre class="alt"&gt;    {&lt;/pre&gt;

  &lt;pre&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; ((sender, e) =&amp;gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;        {&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;if&lt;/span&gt; (frm.InvokeRequired)&lt;/pre&gt;

  &lt;pre class="alt"&gt;                frm.Invoke(handler, sender, e);&lt;/pre&gt;

  &lt;pre&gt;            &lt;span class="kwrd"&gt;else&lt;/span&gt;&lt;/pre&gt;

  &lt;pre class="alt"&gt;                handler(sender, e);&lt;/pre&gt;

  &lt;pre&gt;        });&lt;/pre&gt;

  &lt;pre class="alt"&gt;    }&lt;/pre&gt;

  &lt;pre&gt;}&lt;/pre&gt;

  &lt;pre class="alt"&gt; &lt;/pre&gt;
&lt;/div&gt;

&lt;a href="http://dotnetshoutout.com/Honest-Illusion-Running-An-Async-Event-Handler-on-the-UI-thread-with-lambdas-and-extension-methods"&gt;&lt;img alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fhonestillusion.com%2Fblogs%2Fblog_0%2Farchive%2F2011%2F03%2F15%2Frunning-an-async-event-handler-on-the-ui-thread-with-lambdas-and-extension-methods.aspx" style="border:0px;" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Running+An+Async+Event+Handler+on+the+UI+thread+(with+lambdas+and+extension+methods!)" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2011/03/15/running-an-async-event-handler-on-the-ui-thread-with-lambdas-and-extension-methods.aspx&amp;subject=Running+An+Async+Event+Handler+on+the+UI+thread+(with+lambdas+and+extension+methods!)"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/15/running-an-async-event-handler-on-the-ui-thread-with-lambdas-and-extension-methods.aspx&amp;title=Running+An+Async+Event+Handler+on+the+UI+thread+(with+lambdas+and+extension+methods!)" title="Submit Running+An+Async+Event+Handler+on+the+UI+thread+(with+lambdas+and+extension+methods!) to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/15/running-an-async-event-handler-on-the-ui-thread-with-lambdas-and-extension-methods.aspx&amp;phase=2" title="Submit Running+An+Async+Event+Handler+on+the+UI+thread+(with+lambdas+and+extension+methods!) to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2011/03/15/running-an-async-event-handler-on-the-ui-thread-with-lambdas-and-extension-methods.aspx&amp;title=Running+An+Async+Event+Handler+on+the+UI+thread+(with+lambdas+and+extension+methods!)" title="Submit Running+An+Async+Event+Handler+on+the+UI+thread+(with+lambdas+and+extension+methods!) to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=8098" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>Naked Came The Null Delegate : Chapter 1 – “I, Disposable !”</title><link>http://honestillusion.com/blogs/blog_0/archive/2010/10/09/naked-came-the-null-delegate-chapter-1-i-disposable.aspx</link><pubDate>Sat, 09 Oct 2010 08:15:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7954</guid><dc:creator>James</dc:creator><slash:comments>4</slash:comments><description>
  &lt;P&gt;Slowly, as the rest of his coworkers drift off towards home, Seymour Sharpton, continued on in his cubical. He didn't mind. He was trying to look busy, but was really just writing on his Facebook wall. As the hours ticked by, he knew you'd soon be able to update his “Relationship Status”. He knew the one other person working late that night. He had carefully arranged for the new intern – the exotic Vissa Basicova – (a pure virtual, he was certain) – to be swamped with work that just &lt;I&gt;had &lt;/I&gt;to be done by tomorrow morning, and tonight he was going to make his move. He had carefully prepared a command entity with her as he enumerated the worker pool. And he was now the domain controller, and this process was about to leave debug mode. First he'd get her to yield for a break for a soda. Then, after helping her through her workload, a environment exit for dinner... and then, who knows ?&lt;/P&gt;
&lt;P&gt;As he threaded the rows up to her cubical, he was shocked to find it empty – An unknown apartment state! – Had this application terminated before it started ? But her jacket and purse were still at her desk ---- she wouldn't have gone far. Just then he heard a sound --- oddly familiar but nevertheless out of place in the office. He followed the sound down the aisle to the mail room, and peering in, he saw Vissa --- and Bob, the mail room guy – a nullable type if there ever was one – engaged in a double interlocked exchange that he had only ever read about. And, as he watched the perspiration glisten off her naked double value types, the cold reality dawned on Sey: that Bob's bare pointer was implementing an interface the Sey would never get to extend.&lt;/P&gt;
&lt;P&gt;And yet, only one thought clearly entered his head --- “She probably didn't lock her PC.” &lt;/P&gt;
&lt;P&gt;At quick call back to her cubical showed that the condition was true: In her mad lust for a deadly embrace, a simple Win-L had alluded her, leaving her machine open to a little tier interaction.. So, while she engaged in her own unsafe operation, he would seek a new execution plan. &lt;/P&gt;
&lt;P&gt;A indiscreet message “accidentally” emailed to the whole department from her account would be too obviously a set up --- although it would be interesting to hear from her witness where she was at the time it was sent. A more subtle approach was needed. But, as Bob's grunt signaled a premature thread termination, Sey know he must work fast ! Their binding context would soon finalize. &lt;/P&gt;
&lt;P&gt;Deleting some of her completed work would be step one --- she probably won't notice the missing reports until it was time to present them tomorrow. And, locking her out of a needed network would drag the remaining unfinished work out a few extra hours. With a few deft strokes, his work was done, and he was about to leave the PC just as he found it, when she received an (unsigned) email:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;Vissa, Darling&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;Your schema is excellent.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;We must meet soon, by the service port, to enumerate your assertions.&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New"&gt;We mustn't name pipes.&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Sey forwarded the strange message to his account and then deleted her copy. He then hid by his own desk for a few minutes until Vissa returned to hers. Sey then strolled up to her.&lt;/P&gt;
&lt;P&gt;“Vissa … How go the reports?”&lt;/P&gt;
&lt;P&gt;She looked a bit frazzled, and it was clear the her predicate was in a unsatisfied condition – It seemed Bob's pipe stream had closed without a synchronization context.&lt;/P&gt;
&lt;P&gt;“er... um... coming along,” she said.&lt;/P&gt;
&lt;P&gt;“Well, then, keep it up.... We need those first thing in the morning ---- But don't stay too late. You look tired. You should get to bed.......”&lt;/P&gt;
&lt;P&gt;And then, he left the office for his single threaded apartment, wondering if he had played this right. Perhaps he could have been the ternary operator....&lt;/P&gt;
&lt;P&gt;(Continued: &lt;A href="http://www.charlespetzold.com/blog/2010/10/Naked-Came-the-Null-Delegate-Chapter-2-Unhandled-Exception.html" target="_blank"&gt;&lt;FONT color="#669966"&gt;Chapter 2 : “Unhandled Exception” – By Charles Petzold @ charlespetzold.com&lt;/FONT&gt;&lt;/A&gt; )&lt;/P&gt;
&lt;P&gt;For links to all the parts, and the story behind the story, visit: &lt;A title="http://nakedcamethenulldelegate.wordpress.com/2010/10/07/the-story/" href="http://nakedcamethenulldelegate.wordpress.com/2010/10/09/the-story/"&gt;http://nakedcamethenulldelegate.wordpress.com/2010/10/09/the-story/&lt;/A&gt;&lt;/P&gt;&lt;A href="http://dotnetshoutout.com/Honest-Illusion-Naked-Came-The-Null-Delegate-Chapter-1-I-Disposable-"&gt;&lt;IMG style="BORDER-BOTTOM:0px;BORDER-LEFT:0px;BORDER-TOP:0px;BORDER-RIGHT:0px;" alt="Shout it" src="http://dotnetshoutout.com/image.axd?url=http%3A%2F%2Fhonestillusion.com%2Fblogs%2Fblog_0%2Farchive%2F2010%2F10%2F09%2Fnaked-came-the-null-delegate-chapter-1-i-disposable.aspx" /&gt;&lt;/A&gt; &lt;A href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2010%2f10%2f09%2fnaked-came-the-null-delegate-chapter-1-i-disposable.aspx"&gt;&lt;IMG border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2010%2f10%2f09%2fnaked-came-the-null-delegate-chapter-1-i-disposable.aspx" /&gt;&lt;/A&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Naked+Came+The+Null+Delegate+%3a+Chapter+1+%e2%80%93+%e2%80%9cI%2c+Disposable+!%e2%80%9d" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2010/10/09/naked-came-the-null-delegate-chapter-1-i-disposable.aspx&amp;subject=Naked+Came+The+Null+Delegate+%3a+Chapter+1+%e2%80%93+%e2%80%9cI%2c+Disposable+!%e2%80%9d"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2010/10/09/naked-came-the-null-delegate-chapter-1-i-disposable.aspx&amp;title=Naked+Came+The+Null+Delegate+%3a+Chapter+1+%e2%80%93+%e2%80%9cI%2c+Disposable+!%e2%80%9d" title="Submit Naked+Came+The+Null+Delegate+%3a+Chapter+1+%e2%80%93+%e2%80%9cI%2c+Disposable+!%e2%80%9d to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/10/09/naked-came-the-null-delegate-chapter-1-i-disposable.aspx&amp;phase=2" title="Submit Naked+Came+The+Null+Delegate+%3a+Chapter+1+%e2%80%93+%e2%80%9cI%2c+Disposable+!%e2%80%9d to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/10/09/naked-came-the-null-delegate-chapter-1-i-disposable.aspx&amp;title=Naked+Came+The+Null+Delegate+%3a+Chapter+1+%e2%80%93+%e2%80%9cI%2c+Disposable+!%e2%80%9d" title="Submit Naked+Came+The+Null+Delegate+%3a+Chapter+1+%e2%80%93+%e2%80%9cI%2c+Disposable+!%e2%80%9d to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7954" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/fiction/default.aspx">fiction</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/fun/default.aspx">fun</category></item><item><title>Lambda Expressions as Properties</title><link>http://honestillusion.com/blogs/blog_0/archive/2010/06/07/lambda-expressions-as-properties.aspx</link><pubDate>Mon, 07 Jun 2010 23:05:35 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7946</guid><dc:creator>James</dc:creator><slash:comments>6</slash:comments><description>
  &lt;p&gt;Peter recently caused a bit of a stir with his article “&lt;a href="http://codebetter.com/blogs/peter.van.ooijen/archive/2010/05/30/sometimes-an-enum-is-not-the-best-idea.aspx" target="_blank"&gt;Sometimes an enum is not the best idea&lt;/a&gt;”.  In it, he had a very specific problem: When an enum is passed to a method as an Object, and that method converts it to a usable value by calling ToString(), you get that enum’s name and not it’s value.  And he gave a gave very specific solution to that problem.  Peter wanted an simple ad hoc solution that he could just drop into his code.  Peter’s idea was basically a quick fix to replace a bad design with something slightly less bad.   The problem arose when readers inferred that it was intended as a far more general solution, and pointed out different, more architectural solutions.  Bickering started in the comments.&lt;/p&gt;  &lt;p&gt;I think the main problem is that Peter just want a quick fix to his existing design, and viewed a proper design as overkill for his simple needs.  However, since those simple needs were out of scope of his original purpose for the  article, he never got into specifics.  However, knowing the specifics would be key to knowing how complex the design needs to be.  This was the essence of Peter’s follow-up &lt;a href="http://codebetter.com/blogs/peter.van.ooijen/archive/2010/06/02/ask-first.aspx" target="_blank"&gt;article&lt;/a&gt; (which he posted as I was in the middle of writing this)&lt;/p&gt;  &lt;p&gt;So, let’s try looking at this problem to see if we can come up with a better design that still meets the goal of being simple.&lt;/p&gt;  &lt;p&gt;In Peter’s design, he has a Suppliers class (which he occasionally refers to as the Company class), which has several instances --- one for each supplier.  There is also an enum, PublicIds with one entry for each supplier.  PublicIds was used in two places:  In switch statements, and as a parameter in an ADO.NET statement:&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DoWithCompany(PublicIds company)
{
    &lt;span class="kwrd"&gt;switch&lt;/span&gt; (company)
    {
      &lt;span class="kwrd"&gt;case&lt;/span&gt; PublicIds.Company1:
      &lt;span class="rem"&gt;// Do something with Company 1&lt;/span&gt;
      &lt;span class="kwrd"&gt;break&lt;/span&gt;;
      &lt;span class="kwrd"&gt;case&lt;/span&gt; PublicIds.MyCompany:
      &lt;span class="rem"&gt;// Do something with My Company  &lt;/span&gt;
      &lt;span class="kwrd"&gt;break&lt;/span&gt;;
      &lt;span class="kwrd"&gt;case&lt;/span&gt; PublicIds.ThatOtherCompany:
      &lt;span class="rem"&gt;// Do something else&lt;/span&gt;
      &lt;span class="kwrd"&gt;break&lt;/span&gt;;
    }
}&lt;/pre&gt;

&lt;p&gt;cmdExists.Parameters.AddWithValue("@idSupplier", Supplier.PublicIds.MyCompany);&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The second use was the real motivator of Peter’s article – The first was what caused all the hoopla on the blog.&lt;/p&gt;

&lt;p&gt;Commenters proposed some general ideas, basically out of Object-Oriented Design 101 – Creating a new subclass for  each of the Suppliers, with overridden methods.  Peter fought back --- the code in the “do something” blocks is not part of Supplier, but is in other classes.  Subclasses would requiring moving non-related code to where it doesn’t belong.&lt;/p&gt;

&lt;p&gt;Since Peter still hasn’t provided any real-world examples of his problem (which is reasonable, as they might involve proprietary material or just have too many dependencies to post meaningful excerpts), lets try to imagine some scenarios that might fit his description (namely that DoWithCompany is an example of  a method that “is a member of several quite different other classes and comes in many flavors”).&lt;/p&gt;

&lt;p&gt;Ok, so let’s say we have a Order class, with a ProcessOrderToSupplier(Supplier sup) method.   Let’s further say that most of Order processing is the same for all suppliers, but some suppliers offer a discount (or surcharge) under some conditions.  Hence we need custom processing per supplier to handle the discount, but moving order handling into the Supplier class would clearly be wrong.&lt;/p&gt;

&lt;p&gt;So, let’s try three different discounting schemes, and come up with three means of handling them in ways that are scalable, maintainable &amp;amp; understandable.&lt;/p&gt;

&lt;p&gt;#1 – A flat discount rate on all items.&lt;/p&gt;

&lt;p&gt;      That’s simple.  A discount rate property (getter only) in Supplier.  It could be an abstract property which is overridden in derived classes (one for each Supplier), or just set in Supplier’s constructor.  (Could be set to zero for those suppliers not offering a discount).&lt;/p&gt;

&lt;p&gt;#2 -  Several suppliers offering (free shipping on orders over $100).&lt;/p&gt;

&lt;p&gt;       The “free shipping blah-blah-blah” part is handled entirely in the Order class.  The Supplier class just needs a way to say whether of not a particular supplier offers it.  This could be handled by a  Property as described above, or an attribute on the derived class, or by a marker interface (a marker interface has no members, and is just used in statements like:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (sup &lt;span class="kwrd"&gt;is&lt;/span&gt; IOffersFreeShipping)
     ProcessFreeShipping();&lt;/pre&gt;

&lt;p&gt;#3 – One supplier offers 10% off total orders over $100. Another offers 15% off individual items over $25. And a third offers a $1 shipping surcharge on items over 20 lb.&lt;/p&gt;

&lt;p&gt;      Basically,  every supplier offers something different, and each is complex.  We’d think we’d need derived classes with overridden methods here to keep this object-oriented.  But that is exactly “the first step to multiple inheritance or an unmaintainable set of interfaces” which Peter was afraid of.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(My laptop has an interesting way of telling me that I haven’t saved in a while --- the battery falls out.  I’ve now – too late -- discovered Windows Live Writer’s auto-save feature.  Now let’s see if I can recreate what I just lost……).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And besides that, creating a subclass specifically for one instance of a class just feels wrong --- particularly when we would be creating multiple subclass, one for each of several instances.  But how can be package instances of distinct functionality in individual instances of an object.&lt;/p&gt;

&lt;p&gt;By using &lt;strong&gt;Lambda Expressions as Properties.  &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The idea is pretty simple.  We define a property, which, instead of returning some scalar value, returns a lambda expression (or pretty much any form on anonymous function).  The property works just like a instance method, except we can assign and change it at run-time.   If you’ve done any work in JavaScript, you’ve probably seen very much the same thing. &lt;/p&gt;

&lt;p&gt;Let’s look at some code.  We start by defining the Supplier class like this:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Supplier 
{
    &lt;span class="kwrd"&gt;public&lt;/span&gt; PublicIds Id {get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set;}
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;int&lt;/span&gt; IdCode {get { &lt;span class="kwrd"&gt;return&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt;) Id;}}
    &lt;span class="kwrd"&gt;public&lt;/span&gt; Action&amp;lt;OrderItem&amp;gt; PerItem {get; &lt;span class="kwrd"&gt;private&lt;/span&gt; set;}
    
    &lt;span class="kwrd"&gt;public&lt;/span&gt; Supplier(PublicIds id, Action&amp;lt;OrderItem&amp;gt; perItem)
    {
        Id = id;
        PerItem = perItem;
    }
    
    &lt;span class="kwrd"&gt;public&lt;/span&gt; Supplier(PublicIds id) : &lt;span class="kwrd"&gt;this&lt;/span&gt;(id, oi=&amp;gt; oi=oi)
    {}
}&lt;/pre&gt;

&lt;p&gt;Note that the constructor takes a Action delegate, and stores it in the PerItem property.&lt;/p&gt;

&lt;p&gt;Next, define our instances like this:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;Supplier Company1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Supplier(PublicIds.Company1);
Supplier MyCompany = &lt;span class="kwrd"&gt;new&lt;/span&gt; Supplier(PublicIds.MyCompany, oi=&amp;gt; { &lt;span class="kwrd"&gt;if&lt;/span&gt; (oi.Price &amp;gt; 25m) oi.Discount = oi.Price * 0.15m;});
Supplier ThatOtherCompany = &lt;span class="kwrd"&gt;new&lt;/span&gt; Supplier(PublicIds.ThatOtherCompany, oi=&amp;gt; {&lt;span class="kwrd"&gt;if&lt;/span&gt; (oi.Weight &amp;gt;=20) oi.Shipping = 1m;});&lt;/pre&gt;
And used them  like this: 

&lt;br /&gt;

&lt;pre class="csharpcode"&gt;List&amp;lt;OrderItems&amp;gt; items = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;OrderItems&amp;gt;();    
&lt;span class="kwrd"&gt;void&lt;/span&gt; ProcessOrderToSupplier(Supplier sup)
{
    &lt;span class="rem"&gt;// :&lt;/span&gt;
    items.ForEach(sup.PerItem);
    &lt;span class="rem"&gt;//:&lt;/span&gt;
}&lt;/pre&gt;

&lt;p&gt;“Ok“, you say. “We’ve got the distinct behavior without subclasses – but we still have order processing code defined outside of the Order class, and to make matters worse, it moved to the instance definition in a really messy way.”&lt;/p&gt;

&lt;p&gt;No Problem, we just go back to out (new) old friend: Lambda Expression as Properties:&lt;/p&gt;

&lt;p&gt;This time, we’ll create static properties in the Order class:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; Order
{
    List&amp;lt;OrderItem&amp;gt; items = &lt;span class="kwrd"&gt;new&lt;/span&gt; List&amp;lt;OrderItem&amp;gt;();    
    &lt;span class="kwrd"&gt;void&lt;/span&gt; ProcessOrderToSupplier(Supplier sup)
    {
        &lt;span class="rem"&gt;// :&lt;/span&gt;
        items.ForEach(sup.PerItem);
        &lt;span class="rem"&gt;//:&lt;/span&gt;
    }    
    
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt;  Action&amp;lt;OrderItem&amp;gt; Discount15on25
    {
        get
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; oi =&amp;gt; 
                { 
                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (oi.Price &amp;gt; 25m) 
                        oi.Discount = oi.Price * 0.15m;
                };
        }
    }
    
    &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt;  Action&amp;lt;OrderItem&amp;gt; Shipping1Over20
    {
        get
        {
            &lt;span class="kwrd"&gt;return&lt;/span&gt; oi=&amp;gt; 
                {
                    &lt;span class="kwrd"&gt;if&lt;/span&gt; (oi.Weight &amp;gt;=20) 
                        oi.Shipping = 1m;
                };
        }
    }
}&lt;/pre&gt;

&lt;p&gt;And we can now define out Supplier instances like this:&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;pre class="csharpcode"&gt;Supplier Company1 = &lt;span class="kwrd"&gt;new&lt;/span&gt; Supplier(PublicIds.Company1);
Supplier MyCompany = &lt;span class="kwrd"&gt;new&lt;/span&gt; Supplier(PublicIds.MyCompany, Order.Discount15on25);
Supplier ThatOtherCompany = &lt;span class="kwrd"&gt;new&lt;/span&gt; Supplier(PublicIds.ThatOtherCompany, Order.Shipping1Over20);&lt;/pre&gt;

&lt;p&gt;So, what have we accomplished?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;We’ve distinct behavior amongst the different suppliers, without resorting to subclasses or switch/case blocks &lt;/li&gt;

  &lt;li&gt;We’ve all the Order processing code in the Order class. &lt;/li&gt;

  &lt;li&gt;We’ve neat &amp;amp; tidy Supplier instance definitions, which nevertheless indicates the special features of that supplier. &lt;/li&gt;

  &lt;li&gt;And we have those special features as part of the Supplier object. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But, wait.  You’re probably saying that those properties we’ve defined on Order are rather specific to one particular trait.  Would it be nice to be able to have one general algorithm which is customizable?  That can be done too, by just extending the general principle, which involves using a method instead of a property, but the basic idea is still the same:  instead of returning a value, we return a function:&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt;  Action&amp;lt;OrderItem&amp;gt; ShippingByWeight(&lt;span class="kwrd"&gt;int&lt;/span&gt; pounds, &lt;span class="kwrd"&gt;decimal&lt;/span&gt; cost)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; oi=&amp;gt; 
        {
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (oi.Weight &amp;gt;=pounds) 
                oi.Shipping = cost;
        };
}&lt;/pre&gt;

&lt;p&gt;// :&lt;/p&gt;

&lt;p&gt;Supplier ThatOtherCompany = &lt;span class="kwrd"&gt;new&lt;/span&gt; Supplier(PublicIds.ThatOtherCompany, Order.ShippingByWeight(20,1m); &lt;/p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2010%2f06%2f07%2flambda-expressions-as-properties.aspx"&gt;&lt;img border="0" alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2010%2f06%2f07%2flambda-expressions-as-properties.aspx" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Lambda+Expressions+as+Properties" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2010/06/07/lambda-expressions-as-properties.aspx&amp;subject=Lambda+Expressions+as+Properties"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2010/06/07/lambda-expressions-as-properties.aspx&amp;title=Lambda+Expressions+as+Properties" title="Submit Lambda+Expressions+as+Properties to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/06/07/lambda-expressions-as-properties.aspx&amp;phase=2" title="Submit Lambda+Expressions+as+Properties to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/06/07/lambda-expressions-as-properties.aspx&amp;title=Lambda+Expressions+as+Properties" title="Submit Lambda+Expressions+as+Properties to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7946" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>Portable Areas for Castle Monorail, Part 2</title><link>http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail-part-2.aspx</link><pubDate>Thu, 01 Apr 2010 23:15:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7936</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;P&gt;In our last episode, we discussed the PortableAreaController base class, which makes it simple to create a portable area using Monorail.  In this installment, we put that class to use.&lt;/P&gt;
&lt;P&gt;For the purposes of this example, the controller isn’t going to do anything useful – I’m not even going to bother with code in the actions.  The different actions will display different views so you can see the effect, and I’m hoping you’ll just trust that you can put real code in the action methods.&lt;/P&gt;&lt;PRE class="csharpcode"&gt;[Layout(&lt;SPAN class="str"&gt;"default"&lt;/SPAN&gt;,&lt;SPAN class="str"&gt;"patest"&lt;/SPAN&gt;)]
&lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;class&lt;/SPAN&gt; PATest : PortableAreaController
{
    &lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;void&lt;/SPAN&gt; Page1()
    {         }
    &lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;void&lt;/SPAN&gt; Page2()
    {         }
    &lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;void&lt;/SPAN&gt; Page3()
    {         }
}&lt;/PRE&gt;
&lt;P&gt; &lt;/P&gt;
&lt;P&gt;That’s our minimalistic example.  If it looks a lot like an ordinary Monorail controller, that’s the idea.    “PATest” is the name of the controller, which in the case of a Portable Area, is the name of the entire feature, so it’s be something like CoolWiki or MyForum.  &lt;/P&gt;
&lt;P&gt;The Action methods are identical to what you’d have in a normal controller.  In fact, everything in the portable controller is just like it would be if this were a intrinsic part of a website.  &lt;/P&gt;
&lt;P&gt;The rest is just about putting the pieces together in the assembly.   &lt;/P&gt;
&lt;P&gt;&lt;A href="http://honestillusion.com/blogs/blog_0/PortableAreaSolution_7652A1E6.png"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH:0px;DISPLAY:inline;BORDER-TOP-WIDTH:0px;BORDER-BOTTOM-WIDTH:0px;BORDER-LEFT-WIDTH:0px;" title="PortableAreaSolution" border="0" alt="PortableAreaSolution" src="http://honestillusion.com/blogs/blog_0/PortableAreaSolution_thumb_6E5AFF84.png" width="244" height="226" /&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Individual files  (images, css files etc) should be placed in the root level of the project.  When referencing then in a view, just added “.rails” to the end ( &amp;lt;img src=”${siteRoot}/PATest/autolist.png.rails” /&amp;gt;)&lt;/P&gt;
&lt;P&gt;View templates should be in a folder named after the controller, and layouts in a “layouts” folder --- just as if the root level was the website’s “Views” folder.  You don;t have to do anything special to get Monorail to find them – that is handled for you by the base class.&lt;/P&gt;
&lt;P&gt;All those files (not the CS files obviously) should have their Build Action set to Embedded Resource.&lt;/P&gt;
&lt;P&gt;Note that when a view template is needed, Monorail will first look for a physical file in the website’s Views files, and failing there, search in the assembly.  This allows the end user to override the embedded view templates with their own.   In the example I’ve uploaded to the CastleContrib SVN repository, I’ve locally overridden Page2.&lt;/P&gt;
&lt;P&gt;The same holds for layouts, which I’ve put to use in the example.  I assumed that most sites will have a default layout for the site (which I further assumed is called “default”).  The controller uses that layout and adds it’s own child layout.  (The project should also define a simple default layout as just “${childContent}” just in case the website it’s being used in doesn’t define one.)&lt;/P&gt;
&lt;P&gt;The PortableAreaController base class has been added to the ViewComponent project in the CastleContrib SVN repository. (Yes, I know it’s not a ViewComponent, but I didn’t want to create a whole new branch -- particularly not for just one file-- and ViewComponents were the closest available existing project).  The PATest example shown here is a separate project under that branch, with the resulting Castle.MonoRail.PortableAreaExample.dll assembly added to the ViewComponent.TestSite project.  Note that that assembly is the &lt;EM&gt;only&lt;/EM&gt; file added to the website to enable this functionality, and the only other change was to add a reference to it into the web.config.&lt;/P&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Portable+Areas+for+Castle+Monorail%2c+Part+2" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail-part-2.aspx&amp;subject=Portable+Areas+for+Castle+Monorail%2c+Part+2"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail-part-2.aspx&amp;title=Portable+Areas+for+Castle+Monorail%2c+Part+2" title="Submit Portable+Areas+for+Castle+Monorail%2c+Part+2 to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail-part-2.aspx&amp;phase=2" title="Submit Portable+Areas+for+Castle+Monorail%2c+Part+2 to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail-part-2.aspx&amp;title=Portable+Areas+for+Castle+Monorail%2c+Part+2" title="Submit Portable+Areas+for+Castle+Monorail%2c+Part+2 to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7936" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/castle/default.aspx">castle</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/monorail/default.aspx">monorail</category></item><item><title>Portable Areas for Castle Monorail</title><link>http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail.aspx</link><pubDate>Thu, 01 Apr 2010 23:09:59 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7935</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  
&lt;p&gt;Recently I had read a blogger comparing Castle Monorail with ASP.NET MVC.  He chose ASP.NET mainly because it supported Portable Areas while Monorail did not.  As a supporter of Monorail, I was very offended by this, and decided to correct the problem.  The first step… finding out exactly what a “portable area” was.&lt;/p&gt;
&lt;p&gt;A Portable Area is a piece of functionality, with all pieces bundled up into a single assembly, which can be just “dropped into” an existing website.  Think of a forum or a wiki.  The idea is basically, I could just add wiki.dll to my site, and suddenly &lt;a href="http://www.mysite.com/wiki"&gt;www.mysite.com/wiki&lt;/a&gt; just works.&lt;/p&gt;
&lt;p&gt;Now, having a controller and its actions together in a single assembly is a basic design principle of Monorail (and essentially all of MVC design), so that part was done before I even began.  The rest was a bit trickier.&lt;/p&gt;
&lt;p&gt;I would have to store – and retrieve at the right times, the view template files, and all other associated files – images, style sheets, script files, etc.&lt;/p&gt;
&lt;p&gt;Storing the files was in itself trivial -- .NET has a means built right it. The file just need to be added to the project as embedded resources.  In Visual Studio, on the file’s property panel, set the “Build  Action” to “Embedded Resource”.&lt;/p&gt;
&lt;p&gt;Now that the files were in the assembly, we had to get them out of it. For views, which I had assumed were going to be the most trouble, this turned out to be simple, with the plumbing for it was already built into the Monorail framework.  Apparently, someone had planned for portable areas, but never followed through.  View templates are loaded by a class aptly called the FileAssemblyViewSourceLoader.  It looks in the “Views” folder for the template, and failing there, looks among the embedded resources of the assemblies in its collection.  However, nothing in the framework ever added an assembly to that collection, so this feature has always laid fallow.&lt;/p&gt;
&lt;p&gt;The final feature was getting it to load a random file from the resources.  Whenever I need to do something with a name not known in advance, a DefaultAction seems like the way to go.&lt;/p&gt;
&lt;p&gt;With that, all the pieces were in place, I just had a wee bit of code to tie them all together.  Defining a base class which a portable area could be derived from seemed the best approach.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;
  &lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;class&lt;/span&gt; PortableAreaController : SmartDispatcherController&lt;/pre&gt;
&lt;p&gt;{&lt;/p&gt;
&lt;p&gt;The first step was to override the Initialize() method, so that I could add this assembly to the list searched by FileAssemblyViewSourceLoader.  The only trick here is we must make sure that the assembly is only added once, regardless of how many times the controller is initialized.    And, while we are at it, we’ll also get the assembly name and a list of the resources and save them for later.&lt;/p&gt;
&lt;pre class="csharpcode"&gt;
  &lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt;[] resourceNames;
&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; asmName;

&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;override&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Initialize()
{
    &lt;span class="kwrd"&gt;base&lt;/span&gt;.Initialize();
    var asm = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetType().Assembly;
    resourceNames = asm.GetManifestResourceNames();
    asmName = asm.GetName().Name;
    var asminfo = &lt;span class="kwrd"&gt;new&lt;/span&gt; AssemblySourceInfo(asm, asmName.ToLower());
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (!&lt;span class="kwrd"&gt;this&lt;/span&gt;.Context.Services.ViewSourceLoader.AssemblySources.Cast&amp;lt;AssemblySourceInfo&amp;gt;()&lt;br /&gt;                            .Any(asi=&amp;gt;asi.AssemblyName==asminfo.AssemblyName))
        &lt;span class="kwrd"&gt;this&lt;/span&gt;.Context.Services.ViewSourceLoader.AddAssemblySource(asminfo);
}&lt;/pre&gt;
&lt;p&gt;Next is the DefaultAction.  The idea here is that you request somefile.jpg.rails, and we pull somefile.jpg out of the resources, and stream it to the browser.  In Monorail, a DefaultAction is a method which is called when no other method in the controller matches the action.  In our DefaultAction, we’ll generate a resource name from the assembly name and the Action name.  The Action is basically, the name of the “file” requested without the “.rails” extension, so if we ask for file “http://mysite.com/portable/myimage.gif.rails”, then the pseudo-file we are requesting is “myimage.gif.rails” which makes the Action “myimage.gif” which just happens to be the file we really want.  The only tricky part here is the GetContentTypeFromExt() function.  The problem is that there is a very simple way to do this --- which only works under Windows.  Now, while the vast majority of web servers running Monorail are Windows based, Monorail is designed to also run under Mono (Linux).   I couldn’t find a good portable way to handle this, so I just punted (check the source for dirty secrets).&lt;/p&gt;
&lt;p&gt;[DefaultAction] 
  &lt;br /&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; DefaultAction() 

  &lt;br /&gt;{ 

  &lt;br /&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; filename = asmName + &lt;span class="str"&gt;"."&lt;/span&gt; + Action; 

  &lt;br /&gt;    var resourceName = resourceNames.FirstOrDefault(rn=&amp;gt; rn.Equals(filename,StringComparison.InvariantCultureIgnoreCase)); 

  &lt;br /&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt; (resourceName!= &lt;span class="kwrd"&gt;null&lt;/span&gt;) 

  &lt;br /&gt;    { 

  &lt;br /&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; ext = Path.GetExtension(filename); 

  &lt;br /&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.Response.ContentType = GetContentTypeFromExt(ext); 

  &lt;br /&gt;

  &lt;br /&gt;        Stream contents = &lt;span class="kwrd"&gt;this&lt;/span&gt;.GetType().Assembly.GetManifestResourceStream(resourceName); 

  &lt;br /&gt;        &lt;span class="kwrd"&gt;this&lt;/span&gt;.Response.BinaryWrite(contents); 

  &lt;br /&gt;        CancelView(); 

  &lt;br /&gt;    } 

  &lt;br /&gt;} 

  &lt;br /&gt;&lt;/p&gt;
&lt;p&gt;This method is the controller’s Default action by virtue of the [DefaultAction] attribute.  The name is arbitrary – DefaultAction just kept things simple.&lt;/p&gt;
&lt;p&gt;And with that, everything you need to write a portable area in Monorail is neatly contained in a simple base class.  Everything we’ve just gone over, you can now completely ignore.   &lt;/p&gt;
&lt;p&gt;Next, we discuss how you use this base class to write your own portable area.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Portable+Areas+for+Castle+Monorail" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail.aspx&amp;subject=Portable+Areas+for+Castle+Monorail"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail.aspx&amp;title=Portable+Areas+for+Castle+Monorail" title="Submit Portable+Areas+for+Castle+Monorail to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail.aspx&amp;phase=2" title="Submit Portable+Areas+for+Castle+Monorail to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/04/01/portable-areas-for-castle-monorail.aspx&amp;title=Portable+Areas+for+Castle+Monorail" title="Submit Portable+Areas+for+Castle+Monorail to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7935" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/castle/default.aspx">castle</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/monorail/default.aspx">monorail</category></item><item><title>Some Better-Written Custom String Methods using C#</title><link>http://honestillusion.com/blogs/blog_0/archive/2010/02/02/some-better-written-custom-string-methods-using-c.aspx</link><pubDate>Wed, 03 Feb 2010 01:07:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7914</guid><dc:creator>James</dc:creator><slash:comments>2</slash:comments><description>
  &lt;P&gt;In my daily web-surfing, I often stumble upon snippets of C# code posted by people.  Usually, I can tweak  it a bit. Sometimes, I can tweak it a lot.  I usually post a quick comment to the site offering it.  Today, I came upon some code that was so bad --- which the author said was from his forthcoming &lt;B&gt;&lt;I&gt;book! &lt;/I&gt;&lt;/B&gt;--- more drastic measures must be taken.&lt;/P&gt;
&lt;P&gt;First we have a function to put a string into “Title Case” (which the author refers to as “Proper Case”) – Having the first letter of each word capitalized.  Here’s the original:&lt;/P&gt;&lt;PRE class="csharpcode"&gt;&lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; String PCase(String strParam)
 {
     String strProper = strParam.Substring(0, 1).ToUpper();
     strParam = strParam.Substring(1).ToLower();
     String strPrev = &lt;SPAN class="str"&gt;""&lt;/SPAN&gt;;
     &lt;SPAN class="kwrd"&gt;for&lt;/SPAN&gt; (&lt;SPAN class="kwrd"&gt;int&lt;/SPAN&gt; iIndex = 0; iIndex &amp;lt; strParam.Length; iIndex++)
     {         
&lt;SPAN class="kwrd"&gt;         if&lt;/SPAN&gt; (iIndex &amp;gt; 1)
         {
             strPrev = strParam.Substring(iIndex - 1, 1);
         }
         &lt;SPAN class="kwrd"&gt;if&lt;/SPAN&gt; (strPrev.Equals(&lt;SPAN class="str"&gt;" "&lt;/SPAN&gt;) ||
         strPrev.Equals(&lt;SPAN class="str"&gt;"\t"&lt;/SPAN&gt;) ||
         strPrev.Equals(&lt;SPAN class="str"&gt;"\n"&lt;/SPAN&gt;) ||
         strPrev.Equals(&lt;SPAN class="str"&gt;"."&lt;/SPAN&gt;))
         {
             strProper += strParam.Substring(iIndex, 1).ToUpper();
         }
         &lt;SPAN class="kwrd"&gt;else&lt;/SPAN&gt;
         {
             strProper += strParam.Substring(iIndex, 1);
         }
     }
     &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; strProper;
 } &lt;/PRE&gt;
&lt;P&gt;What wrong here?  Lot’s of really bad string handling.  Remember, strings are immutable, so any action on one creates a new string.  So, “strParam.Substring(iIndex, 1)” creates a new string. “strParam.Substring(iIndex, 1).ToUpper()” create two new strings, and “strProper += strParam.Substring(iIndex, 1).ToUpper();” creates three new strings.  And, that’s within a loop.   And, since Substring is always used here to create a one-character string, it easier to just use a char --- except apparently, this book author doesn’t know how to.   Nor, doesn’t he apparently know about StringBuilder.  Then, we get to the algorithm itself, where he does such bizarre things as pointlessly treat the first character as a special case, in two different places. &lt;/P&gt;
&lt;P&gt;Ok, now let’s see the revision:&lt;/P&gt;&lt;PRE class="csharpcode"&gt;    &lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; String PCase(String strParam)
{
         StringBuilder sb = &lt;SPAN class="kwrd"&gt;new&lt;/SPAN&gt; StringBuilder(strParam.Length);
         &lt;SPAN class="kwrd"&gt;char&lt;/SPAN&gt; cPrev = &lt;SPAN class="str"&gt;'.'&lt;/SPAN&gt;;  &lt;SPAN class="rem"&gt;// start with something to force the next character to upper.&lt;/SPAN&gt;
        &lt;SPAN class="kwrd"&gt;foreach&lt;/SPAN&gt;(&lt;SPAN class="kwrd"&gt;char&lt;/SPAN&gt; c &lt;SPAN class="kwrd"&gt;in&lt;/SPAN&gt; strParam)
         {
             &lt;SPAN class="kwrd"&gt;if&lt;/SPAN&gt; (cPrev == &lt;SPAN class="str"&gt;'.'&lt;/SPAN&gt; || Char.IsWhiteSpace(cPrev))
                 sb.Append(Char.ToUpper(c));
             &lt;SPAN class="kwrd"&gt;else&lt;/SPAN&gt;
                 sb.Append(Char.ToLower(c));
             cPrev = c;
         }
         &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; sb.ToString();
     }  &lt;/PRE&gt;
&lt;P&gt;&lt;BR /&gt;First we start with a string builder, preallocated to the size of the string we are building.  The method doesn’t change the length of the string, so we know the length of the final string right from the start.&lt;/P&gt;
&lt;P&gt;Next, since we are going to capitalize every letter after a period, and also the first letter, why not just pretend the mythical initial “last” character was a period?  Suddenly, the first letter is no longer a special case, and we still get what we want.&lt;/P&gt;
&lt;P&gt;Then, we just loop through the letters, raising or lowering letter as we need. Note that it works on characters and not strings, and uses the build-in IsWhitespace method, instead of using a  hardcoded list of a subset of them.  A for() loop can in certain cases (however, not the one used in the original) be faster than a foreach(), but here I figured it was safe to sacrifice a tiny bit of speed for clearer code.&lt;/P&gt;
&lt;P&gt;Next up, Reversing a String.  The Original:&lt;/P&gt;&lt;PRE class="csharpcode"&gt;    &lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; String Reverse(String strParam)
     {
         &lt;SPAN class="kwrd"&gt;if&lt;/SPAN&gt; (strParam.Length == 1)
         {
             &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; strParam;
         }
         &lt;SPAN class="kwrd"&gt;else&lt;/SPAN&gt;
         {
             &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; Reverse(strParam.Substring(1)) + strParam.Substring(0, 1);
         }
     }&lt;/PRE&gt;
&lt;P&gt;Now, here the author might be able to earn a pass.  It’s possible that somewhere in his book he talks about recursive functions, and uses this as an example.  Then, if might be OK.  I mean, it is the only reason I can think of that someone might want a function which reverses a string – despite ubiquity of string reversing functions in libraries like this.  But, he presented it on his blog as a collection of string functions, so we’ll have to judge them on that basis.  &lt;/P&gt;
&lt;P&gt;Again we have lots of string manipulation to accomplish something simple --- where there are already method built into the framework to handle such things:&lt;/P&gt;&lt;PRE class="csharpcode"&gt;&lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; String Reverse(String strParam)
{
     &lt;SPAN class="kwrd"&gt;byte&lt;/SPAN&gt;[] rev = Encoding.ASCII.GetBytes(strParam);
     Array.Reverse(rev);
     &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; Encoding.ASCII.GetString(rev);
}&lt;/PRE&gt;
&lt;P&gt;&lt;STRONG&gt;UPDATE:&lt;/STRONG&gt; One commentator noted (quite rightly) noted that my Reverse() method would only work for strings of ASCII characters and will fail if there are any Unicode characters.   I knew that at the time, but I was hoping no one else would notice.  The problem was I needed a method which converted a string into an array of characters, and being unable to find one in the CLR, I substituted a string to byte array method instead.   I guess this is one of those times where you just have to step away for a while and come back to it, because now, I found the right method in a few seconds:&lt;/P&gt;
&lt;P&gt; &lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; String Reverse(String strParam)&lt;/P&gt;
&lt;DIV class="csharpcode"&gt;&lt;PRE&gt;{&lt;/PRE&gt;&lt;PRE class="alt"&gt;     &lt;SPAN class="kwrd"&gt;char&lt;/SPAN&gt;[] rev = strParam.ToCharArray();&lt;/PRE&gt;&lt;PRE&gt;     Array.Reverse(rev);&lt;/PRE&gt;&lt;PRE class="alt"&gt;     &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;new&lt;/SPAN&gt; String(rev);&lt;/PRE&gt;&lt;PRE&gt;}&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;And while my first version was a big improvement over the original, this is a big improvement over my first version, so you get double the benefits!&lt;/P&gt;
&lt;P&gt;Next, we have a simple function to count the occurrences of a substring.  &lt;/P&gt;&lt;PRE class="csharpcode"&gt;&lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;int&lt;/SPAN&gt; CharCount(String strSource, String strToCount)
{
    &lt;SPAN class="kwrd"&gt;int&lt;/SPAN&gt; iCount = 0;
    &lt;SPAN class="kwrd"&gt;int&lt;/SPAN&gt; iPos = strSource.IndexOf(strToCount);
    &lt;SPAN class="kwrd"&gt;while&lt;/SPAN&gt; (iPos != -1)
    {
        iCount++;
        strSource = strSource.Substring(iPos + 1);
        iPos = strSource.IndexOf(strToCount);
    }
    &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; iCount;}&lt;/PRE&gt;
&lt;P&gt;The revision isn’t much different but the subtle difference is important.  Instead of creating a new, shorter string to search, we tell it to just start looking after the last match.  Instead we now merely look at the string.&lt;/P&gt;&lt;PRE class="csharpcode"&gt;&lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;int&lt;/SPAN&gt; CharCount(String strSource, String strToCount)
{
    &lt;SPAN class="kwrd"&gt;int&lt;/SPAN&gt; iCount = 0;
    &lt;SPAN class="kwrd"&gt;int&lt;/SPAN&gt; iPos = strSource.IndexOf(strToCount);
    &lt;SPAN class="kwrd"&gt;while&lt;/SPAN&gt; (iPos != -1)
    {
        iCount++;
        iPos = strSource.IndexOf(strToCount, iPos+1);
    }
    &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; iCount;
}&lt;/PRE&gt;The next one has a special problem --- It doesn’t do what it claims to do!&lt;BR /&gt;&lt;PRE class="csharpcode"&gt;&lt;SPAN class="rem"&gt;// Trim the string to contain only a single whitepace between words&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE class="csharpcode"&gt;&lt;SPAN class="rem"&gt;&lt;/SPAN&gt;&lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; String ToSingleSpace(String strParam)
{
    &lt;SPAN class="kwrd"&gt;int&lt;/SPAN&gt; iPosition = strParam.IndexOf(&lt;SPAN class="str"&gt;" "&lt;/SPAN&gt;);
    &lt;SPAN class="kwrd"&gt;if&lt;/SPAN&gt; (iPosition == -1)
    {
        &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; strParam;
    }
    &lt;SPAN class="kwrd"&gt;else&lt;/SPAN&gt;
    {
        &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; ToSingleSpace(strParam.Substring(0, iPosition) +        strParam.Substring(iPosition + 1));
    }
}&lt;/PRE&gt;
&lt;P&gt;Now, it says that it should remove repeated space, so that there is only one space between words. However, what it actually does it to remove all spaces.  This gives us a problem: Should my rewritten function do what it claims to do, or what it actually does?  I decided to give you one of each.&lt;/P&gt;
&lt;P&gt;Duplicating the result is quite straightforward:&lt;/P&gt;&lt;PRE class="csharpcode"&gt;&lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; String RemoveAllSpaces(String strParam)
{
    &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; strParam.Replace(&lt;SPAN class="str"&gt;" "&lt;/SPAN&gt;, &lt;SPAN class="str"&gt;""&lt;/SPAN&gt;);
}&lt;/PRE&gt;
&lt;P&gt;Writing a function to do what it is supposed to is a little more involved, but still simple:&lt;/P&gt;&lt;PRE class="csharpcode"&gt;&lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; String ToSingleSpace(String strParam)
{
    var sb = &lt;SPAN class="kwrd"&gt;new&lt;/SPAN&gt; StringBuilder(strParam.Length);
    var prevWS =&lt;SPAN class="kwrd"&gt;true&lt;/SPAN&gt;;
    &lt;SPAN class="kwrd"&gt;foreach&lt;/SPAN&gt;(var c &lt;SPAN class="kwrd"&gt;in&lt;/SPAN&gt; strParam)
    {
        &lt;SPAN class="kwrd"&gt;if&lt;/SPAN&gt; (Char.IsWhiteSpace(c))
        {
            &lt;SPAN class="kwrd"&gt;if&lt;/SPAN&gt; (!prevWS)
                sb.Append(&lt;SPAN class="str"&gt;' '&lt;/SPAN&gt;);
            prevWS = &lt;SPAN class="kwrd"&gt;true&lt;/SPAN&gt;;
        }
        &lt;SPAN class="kwrd"&gt;else&lt;/SPAN&gt;
        {
            sb.Append(c);
            prevWS = &lt;SPAN class="kwrd"&gt;false&lt;/SPAN&gt;;
        }
    }
    &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; sb.ToString();
}&lt;/PRE&gt;We create a string builder the size of our source string, which would be the maximum size our trimmed string could be, and we set prevWS to true.  This way, it will remove all leading whitespace.  Then we just step through the string, character by character, appending that character to our new string if it’s not a whitespace character, and appending a space for the first whitespace character found.  Note that this reduces all forms of whitespace (tabs, newlines, spaces etc) to a single space.  The original just worked on spaces. 
&lt;P&gt;Finally, we have a function to determine is a string is a palindrome.  &lt;/P&gt;&lt;PRE class="csharpcode"&gt;&lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;bool&lt;/SPAN&gt; IsPalindrome(String strParam)
{
    &lt;SPAN class="kwrd"&gt;int&lt;/SPAN&gt; iLength, iHalfLen;
    iLength = strParam.Length - 1;
    iHalfLen = iLength / 2;
    &lt;SPAN class="kwrd"&gt;for&lt;/SPAN&gt; (&lt;SPAN class="kwrd"&gt;int&lt;/SPAN&gt; iIndex = 0; iIndex &amp;lt;= iHalfLen; iIndex++)
    {
        &lt;SPAN class="kwrd"&gt;if&lt;/SPAN&gt; (strParam.Substring(iIndex, 1) != strParam.Substring(iLength - iIndex, 1))
        {
            &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;false&lt;/SPAN&gt;;
        }
    }
    &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;true&lt;/SPAN&gt;;
}&lt;/PRE&gt;
&lt;P&gt;Here the change is subtle (ignore the length calculations at the start, which are a trivial micro-optimization).&lt;/P&gt;&lt;PRE class="csharpcode"&gt;&lt;SPAN class="kwrd"&gt;public&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;static&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;bool&lt;/SPAN&gt; IsPalindrome(String strParam)
{
    var iLength = strParam.Length;
    var iHalfLen = iLength / 2;
    iLength --;
    &lt;SPAN class="kwrd"&gt;for&lt;/SPAN&gt; (&lt;SPAN class="kwrd"&gt;int&lt;/SPAN&gt; iIndex = 0; iIndex &amp;lt; iHalfLen; iIndex++)
    {
        &lt;SPAN class="kwrd"&gt;if&lt;/SPAN&gt; (strParam[iIndex] != strParam[iLength - iIndex])
        {
            &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;false&lt;/SPAN&gt;;
        }
    }
    &lt;SPAN class="kwrd"&gt;return&lt;/SPAN&gt; &lt;SPAN class="kwrd"&gt;true&lt;/SPAN&gt;;
}&lt;/PRE&gt;
&lt;P&gt;In this function, instead of comparing one-character long strings, I compare individual characters.  That change, by itself, cause a 4X speed improvement.&lt;/P&gt;
&lt;P&gt;So, there you have it.  The article had more, but the other were trivial, and I couldn’t make them any better.  And in case you think I’m all talk here, each of those rewrites was benchmarked to run 2 to 5 times faster than the original.&lt;/P&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Some+Better-Written+Custom+String+Methods+using+C%23" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2010/02/02/some-better-written-custom-string-methods-using-c.aspx&amp;subject=Some+Better-Written+Custom+String+Methods+using+C%23"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2010/02/02/some-better-written-custom-string-methods-using-c.aspx&amp;title=Some+Better-Written+Custom+String+Methods+using+C%23" title="Submit Some+Better-Written+Custom+String+Methods+using+C%23 to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/02/02/some-better-written-custom-string-methods-using-c.aspx&amp;phase=2" title="Submit Some+Better-Written+Custom+String+Methods+using+C%23 to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2010/02/02/some-better-written-custom-string-methods-using-c.aspx&amp;title=Some+Better-Written+Custom+String+Methods+using+C%23" title="Submit Some+Better-Written+Custom+String+Methods+using+C%23 to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7914" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>A ViewComponent extension for Castle MonoRail, Part II</title><link>http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail-part-ii.aspx</link><pubDate>Tue, 25 Aug 2009 00:44:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7882</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;P&gt;This was intended to be a two-part article.  It was just after I published &lt;A href="http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx" target="_blank"&gt;the original article,&lt;/A&gt; I noticed that I’d left out a large part of ViewComponentEx. We continue…..&lt;/P&gt;
&lt;HR /&gt;
&lt;PRE class="c#"&gt;&lt;FONT size="4"&gt;        protected bool RenderOptionalSection(string section) 
        protected bool RenderOptionalSection(string section, string defaultText)&lt;/FONT&gt; &lt;/PRE&gt;
&lt;P&gt;Renders the named section of a block component – if the section is present.  If not, it just silently returns.   The second overload lets you provide some text to be rendered, if that section isn’t given:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT size="3"&gt;RenderOptionalSection("tablestart", “&amp;lt;table&amp;gt;”)&lt;/FONT&gt; &lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Returns true if this section was rendered; false, if the section was present.  This seems like a very simple method (and it is), but if your component has a number of different sections for styling (such as the SmartGridViewComponent, which has 18!), this can do wonders to streamline your code.&lt;/P&gt;
&lt;HR /&gt;
&lt;PRE class="c#"&gt;&lt;FONT size="4"&gt;        void RenderComponent&amp;lt;VC&amp;gt;(params string[] componentParams) where VC : ViewComponentEx, new();
        void RenderComponent&amp;lt;VC&amp;gt;(IDictionary componentParams) where VC : ViewComponentEx, new();
        void RenderComponent(ViewComponentEx component, params string[] componentParams); 
        void RenderComponent(ViewComponentEx component, IDictionary componentParams); &lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;This implement, with a slightly different syntax, a technique originally devised by Joey Beninghove.  The idea is to make a ViewComponent which is composite of several other VCs.  The basic syntax is &lt;/P&gt;&lt;PRE class="c#"&gt;&lt;FONT size="4"&gt; RenderComponent&amp;lt;LinkSubmitButtonComponent&amp;gt;("linkText=Search",
             string.Format("formToSubmit={0}", searchFormName));&lt;/FONT&gt;&lt;/PRE&gt;
&lt;P&gt;However, the various overloads allow using an already exist component object, and/or an already built dictionary of options.&lt;/P&gt;
&lt;HR /&gt;

&lt;P&gt;Also include in the source file is the class ViewComponentUsingSiteMap which, like ViewComponentEx, is an abstract base use for creating ViewComponents, but I’ll hold off discussing that until I ready to talk about the VCs the derive from it.&lt;/P&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail-part-ii.aspx&amp;subject=A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail-part-ii.aspx&amp;title=A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II" title="Submit A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail-part-ii.aspx&amp;phase=2" title="Submit A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail-part-ii.aspx&amp;title=A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II" title="Submit A+ViewComponent+extension+for+Castle+MonoRail%2c+Part+II to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7882" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/castle/default.aspx">castle</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/monorail/default.aspx">monorail</category></item><item><title>A ViewComponent extension for Castle MonoRail</title><link>http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx</link><pubDate>Mon, 24 Aug 2009 11:21:08 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7881</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;I’ve been rewriting my website, njtheater.com, (very slowly) as a Castle MonoRail application.  Along the way, I’ve written a number of ViewComponent and other elements.  Many of these were of general use, so I’ve added them to the CastleContib project, and documented them in the using.castleproject.org wiki.&lt;/p&gt;  &lt;p&gt;Two problem there: First, some of the items I wrote don’t fit into an exist category in CastleContrib (There’s one for ViewComponents, which I’ve stick a filter into, but putting a Controller base class there seemed wrong).  Second, CastleContrib &amp;amp; using.castleproject.org seem to be somewhat of a black hole.  No one seems to look there for information about the Castle Project (which is kind of a shame, since that’s exactly it’s purpose).  &lt;/p&gt;  &lt;p&gt;On the other hand, blogs posts about Castle are turning up everywhere.  We’ve even now got an &lt;a href="http://pipes.yahoo.com/pipes/pipe.run?_id=bGjr2c1s3hGi5qx20EypaA&amp;amp;_render=rss&amp;amp;limit=200" target="_blank"&gt;aggregated blog feed specific to Castle&lt;/a&gt;.  So, I figured, I start using my blog to talk about what I’ve written.&lt;/p&gt;  &lt;p&gt;In fact, one article I discovered on that aggregator was Andy Pike’s “Integrating Gravatar with Castle MonoRail” inwhich he discusses a Helper object for Monorail which creates Gravatars for use’s email addresses.  It was written last January.  The only thing is, I’ve written (and added to CastleContrib) a Gravatar component three months earlier.  That was going to be the topic of my first MonoRail blog post (and I will be my second), but first, I figure I should talk about the base class I once for all my ViewComponents, which I’ve given the rather imaginative name of ViewComponentEx.&lt;/p&gt;  &lt;p&gt;ViewComponentEx derives from ViewComponent, and can be used as a “drop-in” replacement for it, as the base class for your ViewComponents.  It provides a number of simple methods to help building ViewComponents.&lt;/p&gt;  &lt;pre class="c#"&gt;&lt;font size="4"&gt;void ConfirmSectionPresent(string section);&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Throws an exception if the given section is not present. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;string GetSectionText(string section);&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Get the text of a section as a string.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;string GetBodyText();&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Get the text of the body of a block component (without section)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;void RenderTextFormat(string format, params object[] args);&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Renders the text, formatted. Just like String.Format() &lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;string GetParamValue(string key, string defaultValue);&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;bool GetParamValue(string key, bool defaultValue);&lt;/font&gt;&lt;/pre&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;E GetParamValue(string key, E defaultValue) where E : struct;&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Gets a parameter value, with a default. Overloaded to handle string, boolean, or Enum value. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;Castle.Core.Logging.ILogger Logger { get; set; }&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;A property for the system Logger. Automatically wired by Windsor, if active and a Logger is defined in the container. Default to NullLogger, otherwise.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;pre class="c#"&gt;&lt;font size="4"&gt;string MakeUniqueId(string prefix);&lt;/font&gt;&lt;/pre&gt;

&lt;blockquote&gt;
  &lt;p&gt;Makes an unique id. The given prefix is prepended to the generated number. The ID isn't actually guaranteed to be unique (which would require using all 32 digits of the guid). But this produce ids sufficiently distinctive to generate multiple controls on a page.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;Code available here: &lt;a href="http://honestillusion.com/files/folders/castle/entry7880.aspx" target="_blank"&gt;ViewComponentex.cs&lt;/a&gt;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email A+ViewComponent+extension+for+Castle+MonoRail" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx&amp;subject=A+ViewComponent+extension+for+Castle+MonoRail"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx&amp;title=A+ViewComponent+extension+for+Castle+MonoRail" title="Submit A+ViewComponent+extension+for+Castle+MonoRail to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx&amp;phase=2" title="Submit A+ViewComponent+extension+for+Castle+MonoRail to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/24/a-viewcomponent-extension-for-castle-monorail.aspx&amp;title=A+ViewComponent+extension+for+Castle+MonoRail" title="Submit A+ViewComponent+extension+for+Castle+MonoRail to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7881" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/castle/default.aspx">castle</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/monorail/default.aspx">monorail</category></item><item><title>#songsincode : The Turtle’s “Happy Together”</title><link>http://honestillusion.com/blogs/blog_0/archive/2009/08/22/songsincode-the-turtle-s-happy-together.aspx</link><pubDate>Sat, 22 Aug 2009 15:26:29 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7879</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;pre class="c#"&gt;
    &lt;font size="4"&gt;(Me + you) &amp;amp;&amp;amp;  (you + me)
var nomatter = dice.toss(); assert (it != null)
me.Only1(you); assert(you == me.Only1());
(Me + you).happy  = so;&lt;/font&gt;
  &lt;/pre&gt;

&lt;pre class="c#"&gt; &lt;/pre&gt;

&lt;p&gt;(more on the meme &lt;a href="http://www.wait-till-i.com/2009/08/21/wow-so-that-is-how-memes-happen-songsincode/" target="_blank"&gt;here&lt;/a&gt;)&lt;/p&gt;

&lt;pre class="c#"&gt; &lt;/pre&gt;

&lt;pre class="c#"&gt; &lt;/pre&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email %23songsincode+%3a+The+Turtle%e2%80%99s+%e2%80%9cHappy+Together%e2%80%9d" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2009/08/22/songsincode-the-turtle-s-happy-together.aspx&amp;subject=%23songsincode+%3a+The+Turtle%e2%80%99s+%e2%80%9cHappy+Together%e2%80%9d"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/22/songsincode-the-turtle-s-happy-together.aspx&amp;title=%23songsincode+%3a+The+Turtle%e2%80%99s+%e2%80%9cHappy+Together%e2%80%9d" title="Submit %23songsincode+%3a+The+Turtle%e2%80%99s+%e2%80%9cHappy+Together%e2%80%9d to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/22/songsincode-the-turtle-s-happy-together.aspx&amp;phase=2" title="Submit %23songsincode+%3a+The+Turtle%e2%80%99s+%e2%80%9cHappy+Together%e2%80%9d to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/22/songsincode-the-turtle-s-happy-together.aspx&amp;title=%23songsincode+%3a+The+Turtle%e2%80%99s+%e2%80%9cHappy+Together%e2%80%9d" title="Submit %23songsincode+%3a+The+Turtle%e2%80%99s+%e2%80%9cHappy+Together%e2%80%9d to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7879" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/music/default.aspx">music</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>Code Tune-Up: Shuffling a List</title><link>http://honestillusion.com/blogs/blog_0/archive/2009/08/16/code-tune-up-shuffling-a-list.aspx</link><pubDate>Sun, 16 Aug 2009 23:14:11 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7877</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>Over on CodeProject, I spotted an article by Mahdi Yousefi called "
&lt;a href="http://www.codeproject.com/KB/validation/aspnet_capcha.aspx" target="_blank"&gt;Creating an ASP.NET captcha using jQuery and s3capcha”.&lt;/a&gt;
&lt;pre class="c#"&gt;&lt;font size="4"&gt;public static List&amp;lt;int&amp;gt; shuffle(List&amp;lt;int&amp;gt; input)
{
    List&amp;lt;int&amp;gt; output = new List&amp;lt;int&amp;gt;();
    Random rnd = new Random();
 
    int FIndex;
    while (input.Count &amp;gt; 0)
    {
        FIndex = rnd.Next(0, input.Count);
        output.Add(input[FIndex]);
        input.RemoveAt(FIndex);
    }
 
    input.Clear();
    input = null;
    rnd = null;
 
    return output;
}&lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;So, what’s wrong with this?  Well, let’s see:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;It takes a List as a parameter and returns a list.  This is rather limiting.  What if we have array we want to shuffle? &lt;/li&gt;

  &lt;li&gt;It takes and returns a list of &lt;strong&gt;integers. &lt;/strong&gt;Again rather limiting.  What if we had strings or say, PlayingCard objects we want to shuffle? &lt;/li&gt;

  &lt;li&gt;It creates a new Random object every time it’s called.  Two problems there.  First, when a Random object is created, a seed is produced.  This is a fairly time-consuming task, which you don’t want to do repeatedly necessarily.  Second, when the default constructor is called, like here, the seed is initialized using the internal clock’s TickCount --- which is the time in &lt;em&gt;milliseconds&lt;/em&gt;.  If you called shuffle() twice within a millisecond -– not unreasonable if you were writing a game – the Random objects would be using the same seed, and produce the same sequence. &lt;/li&gt;

  &lt;li&gt;It creates a new list for output.  This  is a problem only in that it’s a time expense we might as well avoid if possible.  It also builds this list by repeated calls to Add(), but without specifying an initial size, meaning that Add() will frequently have to resize the list to keep expanding it.  The fix to this would be trivial.  Just create the new list as “new List&amp;lt;int&amp;gt;(input.Count);”.  But as you’ll see, this won’t be necessary. &lt;/li&gt;

  &lt;li&gt;It destroys the list input.  In fact, it destroys it three times over: First by removing all of it’s items.  Then by calling Clear() on the empty list.  Then by setting the local reference to null.  That last one might cause it to be garbage-collected a couple microseconds earlier – if the calling routine didn’t hold a reference to it. I don’t want to claim this as a “Problem”, as much as a “Behavior” – It’s just something it does, so if our replacement does that as well (as it will), we haven’t lost anything.  But, if you nevertheless thing that &lt;em&gt;is&lt;/em&gt; a problem, don’t worry, we’ll address that to. &lt;/li&gt;

  &lt;li&gt;It removes that items from the list using Remove() – This is a very time-consuming method on Lists (which, contrary to popular belief are not linked-lists, but are internally implement as arrays).  One call to List.Remove() is O(N) by itself.  Since it’s called in a loop, that makes the complicity of this method O(N^2).  Clearly that’s something we should avoid. &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So,  let’s tackle these.  First the signature.  we say we want a List, but we really only want so features of a list – that usually means we want an interface.  And we want to be usable for List of all types, so it’s wants to be generic:&lt;/p&gt;
&lt;pre class="c#"&gt;&lt;font size="4"&gt;public static IList&amp;lt;T&amp;gt; Shuffle&amp;lt;T&amp;gt;(this IList&amp;lt;T&amp;gt; input)&lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;IList has just the features we need, and allows us to pass different collection types (notably arrays) to the method.  I’ve also implemented it as an extension method, because it seemed more useful that way.  But to be an extension method, it has to be in a static class, which brings us to our next change:&lt;/p&gt;
&lt;pre class="c#"&gt;&lt;font size="4"&gt;static class Helper
{
       static readonly Random rnd = new Random();
    // :&lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;I’ve moved that Random object to be a static member.  That way, only one is created &amp;amp; initialized, and every call to Shuffle reuses the same one.&lt;/p&gt;
&lt;p&gt;Next is that main loop:&lt;/p&gt;
&lt;pre class="c#"&gt;&lt;font size="4"&gt;for(var top = input.Count -1; top &amp;gt; 1; --top)
{
    var swap = rnd.Next(0, top);
    T tmp = input[top];
    input[top] = input[swap];
    input[swap] = tmp;
}&lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;Here’s where we see the major change to the implementation. Both method use basically the same algorithm, but instead of building a new List, I move the elements around within the same list.  Essentially, I’m doing the same thing, if you imagine the two arrays occupying that same space – as one grows small the other grows bigger.  &lt;/p&gt;
&lt;p&gt;And with that, we’re done.  Since the original List is now shuffled, we could return void, but by returning the input, we can allow chaining (and it also maintains the original method signature)&lt;/p&gt;
&lt;p&gt;So, How does it work ?  Here’s a quick example, showing off some of it’s new abilities:&lt;/p&gt;
&lt;pre class="c#"&gt;&lt;font size="4"&gt;        string[] A = {"A", "B", "C", "D", "E", "F", "G"};
        A.Shuffle().Print();

output: D-F-A-G-B-E-C-&lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;Print() is a simple-minded extension method which just takes a list and prints it’s elements separated by dashes.  Good for demos but not much else.  Also for these examples, I’ve hard-coded the seed for Random to be 1234, so the sequence is always repeated.  Again, good for demos, but not for production work.&lt;/p&gt;
&lt;p&gt;But, you said you didn’t want the original list destroyed. (yes, you did in fact say that!).  No problem, we’ll just write a second method, and since the problem definition requires two lists, there’s no shame in eating the cost of creating a copy of the input list.  To keep it simple, I’ll also create &amp;amp; return a List&amp;lt;&amp;gt; regardless of what type of IList&amp;lt;&amp;gt; you passed in.  &lt;/p&gt;
&lt;pre class="c#"&gt; &lt;font size="4"&gt; return new List&amp;lt;T&amp;gt;(input).Shuffle();&lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;But that brings us to another key point.  The only thing that the input is being used for is to seed the new List, and that ctor doesn’t take an IList&amp;lt;&amp;gt;, it takes the much more common IEnumerable&amp;lt;&amp;gt; (which IList just happens to be a descendant of).  So, we might as well make that our input parameter.&lt;/p&gt;
&lt;pre class="c#"&gt;&lt;font size="4"&gt;public static IList&amp;lt;T&amp;gt; ShuffleCopy&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; input)
{        return new List&amp;lt;T&amp;gt;(input).Shuffle();    }&lt;/font&gt;      &lt;/pre&gt;
&lt;p&gt;With this, we can do some interesting things, since you input doesn’t have to be a collection at all:&lt;/p&gt;
&lt;pre class="c#"&gt;&lt;font size="4"&gt;        Enumerable.Range(1,10).ShuffleCopy().Print();

output:  1-5-7-9-10-2-6-3-8-4-&lt;/font&gt;&lt;/pre&gt;
&lt;p&gt;Here’s the full source code:&lt;/p&gt;
&lt;pre class="c#"&gt;&lt;font size="4"&gt;static class Helper
{
    static readonly Random rnd = new Random();
       
    public static IList&amp;lt;T&amp;gt; Shuffle&amp;lt;T&amp;gt;(this IList&amp;lt;T&amp;gt; input)
    {
        for(var top = input.Count -1; top &amp;gt; 1; --top)
        {
            var swap = rnd.Next(0, top);
            T tmp = input[top];
            input[top] = input[swap];
            input[swap] = tmp;
        }
    
        return input;
    }      
    
    public static IList&amp;lt;T&amp;gt; ShuffleCopy&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; input)
    {        return new List&amp;lt;T&amp;gt;(input).Shuffle();    }      
    
    public static void Print&amp;lt;T&amp;gt;(this IList&amp;lt;T&amp;gt; list)
    {
        foreach(T t in list)
        {
                Console.Write("{0}-", t);
        }
        Console.WriteLine();
    }
}&lt;/font&gt;&lt;/pre&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Code+Tune-Up%3a+Shuffling+a+List" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2009/08/16/code-tune-up-shuffling-a-list.aspx&amp;subject=Code+Tune-Up%3a+Shuffling+a+List"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/16/code-tune-up-shuffling-a-list.aspx&amp;title=Code+Tune-Up%3a+Shuffling+a+List" title="Submit Code+Tune-Up%3a+Shuffling+a+List to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/16/code-tune-up-shuffling-a-list.aspx&amp;phase=2" title="Submit Code+Tune-Up%3a+Shuffling+a+List to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/08/16/code-tune-up-shuffling-a-list.aspx&amp;title=Code+Tune-Up%3a+Shuffling+a+List" title="Submit Code+Tune-Up%3a+Shuffling+a+List to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7877" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>A (somewhat) New jQuery plug-in: Wizard</title><link>http://honestillusion.com/blogs/blog_0/archive/2009/07/28/a-somewhat-new-jquery-plug-in-wizard.aspx</link><pubDate>Tue, 28 Jul 2009 22:58:57 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7874</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;As I slowly rewrite NJTheater.com, one task that I was trying to move from a MSAccess application to a webpage would be made much easier if put in a wizard form, with the user being led through the steps.  Since I was using jQuery throughout the site, I figured I could find a plug-in for the job, and I did – sorta.&lt;/p&gt;  &lt;p&gt;After rejecting a couple, I found formwizard by Jan Sundman, which mostly fit my needs.  I would need to make a small change – but, I never can stop at just one small change.   In the end, I’ve got a plugin which has at it’s core Jan’s code, but is nevertheless quite different.  The revision, with docs and examples can be found here: &lt;a href="http://www.noveltheory.com/Wizard" target="_blank"&gt;Wizard&lt;/a&gt;.&lt;a href="http://honestillusion.com/blogs/blog_0/WizardStep_4BDB08AF.png"&gt;&lt;img style="border-right-width:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;" title="WizardStep" border="0" alt="WizardStep" src="http://honestillusion.com/blogs/blog_0/WizardStep_thumb_44BBCC37.png" width="244" height="159" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;The executive summary of it’s use:  You have one form.  It is divided up into several &amp;lt;DIV&amp;gt;s, each marked with the class “step”.  You call $(“#theForm”).Wizard().  Each &amp;lt;div&amp;gt; is displayed to the user individually, and they can click Next or Back buttons to move between the page.  When the users clicks Next on the final page, the form is submitted.  There are a lot of options, and you could choose to make it much more complicated.&lt;/p&gt;  &lt;p&gt;The first thing you’ll note about it, if you are familiar with the original, is that it, to the best of my abilities, now confirms to the jQuery UI standard for interface and CSS theming. I also added a new callback, several new methods, and a couple new options.  Comparing the new code to Jan’s code is a bit tricky because the jQuery UI fra mework wants methods as tag properties of an object (i.e. &lt;font face="Consolas"&gt;SomeFunc : function() {…..}  &lt;/font&gt;rather than &lt;font face="Consolas"&gt;function SomeFunc() {….}&lt;/font&gt;), but the major source code difference really had nothing to to with that nor had any good code-quality reason:  I made some unnamed functions into named function, and alphabetized the methods, just because it made it easier for me to navigate through the code.   However, this does make doing a DIFF between the two source file difficult.&lt;/p&gt;  &lt;p&gt;So what were the more functional changes between the two versions?  Mostly they reflect a somewhat different view of the use of wizards.  In Jan’s code it seems, he largely viewed the wizard as just one big form, divided up into pages with one submit at the end.  There was some infrastructure to alter the flow through the wizard, but it was limited.  (I’m still not quite sure of the utility of the “linkClass” in Jan’s code in real-world situations)&lt;/p&gt;  &lt;p&gt;I see a wizard as guiding the users through a multi-step process, where what you see on step 3 depends on ajax calls based on what you entered in Step 2, and your choices there affects the options in step 4.   So, you’d need more control as the user moved from step to step.  Jan’s apparently saw this need as well, and added the afterBack and afterNext callbacks, but they pass no parameters – you are told that the user has click “next”, but are left to your own devices to know where he is. I figured a developer would be more concerned about where the user was in the wizard, than how he got there.   So I added the “Show” callback (also wired as an event by the framework).  It tells you what step the user has just moved to, by it’s index number and by a jQuery object of the div itself.  It also says if the user got there by moving forward or backward.&lt;/p&gt;  &lt;p&gt;Also, Jan added validation by means of the standard jquery.validate.js plugin.  In that scenario,  the user would click “Next” and then the plugin would tell him to fix things.   That’s not the way Wizards normally work, where the “Next” button is disabled upon the step is complete.  So, I added an option &lt;font face="Consolas"&gt;autoDisabledNext &lt;/font&gt;&lt;font face="tre"&gt;which always displays the Next button grayed initially when moving it a new step, and waits for the script to re-enable it in response to some action by the user.  The “enableNext” method handles that (with “disableNext”, “enableBack” and “disableBack” also added to give the developer complete control in this area).&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;In Jan’s original, the formwizard() method took three parameters, each js objects, the first for the wizard itself while the other two were passed to the forms plugin and the validation plugin respectively, which are optional --- the plugins, not the parameters.  So if you weren’t using those plugins, you had to pass empty objects.  I moved them to named parameters in with the other wizard options, where they could be defaulted. Similarly, the boolean flags which had to be explicitly set, now derive their settings from the environment. You can still explicitly set them if you need to overrule that determination.&lt;/p&gt;  &lt;p&gt;A few other changes just seemed to make more sense to me. formwizard expected the form to have a Submit and Reset buttons, which it converted into the Next and Back respectively.  Submit for Next wasn’t too bad, but Reset for Back just seemed wrong.  If you are going to have a button controlled strictly by Javascript, it should be a &amp;lt;button&amp;gt; element.  So, they are indicated, by default, by the classes “wizard_next” and “wizard_back”.   Another one just seems like fun and I wondered how difficult it would be: You can specify the effect used to display each page, via the “animate” option.  The default is “FadeIn”.&lt;/p&gt;  &lt;p&gt;Finally, I included a “old-school” jQuery plugin called “formwizard” which sets all the defaults I changed back to the way they were in Jan’s original, and then calls Wizard(), so we should have full backward compatibility.&lt;/p&gt;  &lt;p&gt;Note: Despite my best effort to make the docs page look just like one of those for actual jQuery UI widgets, it is not part of the official jQuery UI package, and although submitted to them for review, probably will not be part of the official release any time soon (“not any time soon” == “a few years at least”).  &lt;/p&gt;  &lt;p&gt;Now, how can you help Wizard become part of the official jQuery UI package.  Well, I guess you could mention in your blogs, tweets, forum message (particularly on the jQuery UI Google Group) that “wouldn’t it be great if jQuery UI included a Wizard widget --- just like that one James stolen from Jan”.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email A+(somewhat)+New+jQuery+plug-in%3a+Wizard" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2009/07/28/a-somewhat-new-jquery-plug-in-wizard.aspx&amp;subject=A+(somewhat)+New+jQuery+plug-in%3a+Wizard"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2009/07/28/a-somewhat-new-jquery-plug-in-wizard.aspx&amp;title=A+(somewhat)+New+jQuery+plug-in%3a+Wizard" title="Submit A+(somewhat)+New+jQuery+plug-in%3a+Wizard to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/07/28/a-somewhat-new-jquery-plug-in-wizard.aspx&amp;phase=2" title="Submit A+(somewhat)+New+jQuery+plug-in%3a+Wizard to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/07/28/a-somewhat-new-jquery-plug-in-wizard.aspx&amp;title=A+(somewhat)+New+jQuery+plug-in%3a+Wizard" title="Submit A+(somewhat)+New+jQuery+plug-in%3a+Wizard to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7874" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Javascript/default.aspx">Javascript</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category></item><item><title>Posts from Comments: QuickDataBind</title><link>http://honestillusion.com/blogs/blog_0/archive/2009/07/28/posts-from-comments-quickdatabind.aspx</link><pubDate>Tue, 28 Jul 2009 10:49:49 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7873</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;You may have noticed that I don’t write on this blog much.  But the thing is I &lt;em&gt;do&lt;/em&gt; write a lot on the inter-webs about technical matters --- I just don’t to it here.  Usually, I find something interesting on someone else’s blog, and then write an improvement in the comments.  So, my work goes to helping other people’s pagerank.  I figure this has got to stop… To this end, I start a series where I turn comments I made on other blogs into posts on this one….&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;To start us off, a few days ago, &lt;a href="http://geekswithblogs.net/samerpaul/archive/2009/07/22/listview-extension-i-thought-irsquod-sharehellip.aspx" target="_blank"&gt;Samer wrote about an extension method&lt;/a&gt; he created for ListView: &lt;/p&gt;  &lt;pre class="c#"&gt;public static ListView QuickDataBind(this ListView myListView, object myDataSource)
    {
        myListView.DataSource = myDataSource;
        myListView.DataBind();
        return myListView;
    }&lt;/pre&gt;

&lt;p&gt;Now, this is all well and good.  but why are we limiting ourselves to just ListViews?  Many ASP.NET WebControl take a datasource and use that idiom.  Why not make an generic extension method to handle all of them?&lt;/p&gt;

&lt;pre class="c#"&gt;public static T QuickDataBind(this T myDataBoundControl, object myDataSource) 
        where T: BaseDataBoundControl
{
        myDataBoundControl.DataSource = myDataSource;
        myDataBoundControl.DataBind();
        return myDataBoundControl;
}&lt;/pre&gt;
It's still called exactly the same well: 

&lt;pre class="c#"&gt;       myGridView.QuickDataBind(myDS);&lt;/pre&gt;
but now it can be used on ListViews, GridView, DropDownLists DataGrids, Repeaters or anything else that uses a DataSOurce. 


&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Posts+from+Comments%3a+QuickDataBind" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2009/07/28/posts-from-comments-quickdatabind.aspx&amp;subject=Posts+from+Comments%3a+QuickDataBind"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2009/07/28/posts-from-comments-quickdatabind.aspx&amp;title=Posts+from+Comments%3a+QuickDataBind" title="Submit Posts+from+Comments%3a+QuickDataBind to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/07/28/posts-from-comments-quickdatabind.aspx&amp;phase=2" title="Submit Posts+from+Comments%3a+QuickDataBind to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/07/28/posts-from-comments-quickdatabind.aspx&amp;title=Posts+from+Comments%3a+QuickDataBind" title="Submit Posts+from+Comments%3a+QuickDataBind to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7873" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>Washington vs. Hollywood.</title><link>http://honestillusion.com/blogs/blog_0/archive/2009/06/22/washington-vs-hollywood.aspx</link><pubDate>Mon, 22 Jun 2009 16:51:05 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7872</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;With the pending appointment of Judge Sonia Sotomayor, someone pointed out that if she is approved, there will have been in 120 years, 111 Supreme Court Justices, of whom, only three were women and only two were African American, with all the rest being white men.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;On the other hand:&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;In the past 80 years, The Academy of Motion Picture Art &amp;amp; Sciences has nominated 208 people for the Best Director Oscar™ (some more than once) of which three have been women, and only one African-American, with all the rest being white men.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Washington+vs.+Hollywood." href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2009/06/22/washington-vs-hollywood.aspx&amp;subject=Washington+vs.+Hollywood."&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2009/06/22/washington-vs-hollywood.aspx&amp;title=Washington+vs.+Hollywood." title="Submit Washington+vs.+Hollywood. to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/06/22/washington-vs-hollywood.aspx&amp;phase=2" title="Submit Washington+vs.+Hollywood. to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2009/06/22/washington-vs-hollywood.aspx&amp;title=Washington+vs.+Hollywood." title="Submit Washington+vs.+Hollywood. to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7872" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Politics/default.aspx">Politics</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Random+Thoughts/default.aspx">Random Thoughts</category></item><item><title>Men &amp; Women &amp; Careers in IT.</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/12/22/men-women-careers-in-it.aspx</link><pubDate>Mon, 22 Dec 2008 16:28:19 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7859</guid><dc:creator>James</dc:creator><slash:comments>11</slash:comments><description>
  &lt;p&gt;
    &lt;em&gt;(Ok, this is the third time I'm writing this.  The first time it was in the comment form of a blog.  For some reason, it just swallowed the message without posting it, blanking the editbox, and then giving an error saying the edit box was empty.  So, I tried again.  The second time, not trusting a webpage textarea, I wrote it in a text editor, so I'd have a copy if the website continued to be difficult. But I wrote it in the train into work, so I couldn't post it immediately.  I just close up my laptop with the article unsaved in Crimson Editor.  When I got to work and tried to upload it, my laptop refused to come out of hibernation, forcing me to power cycle it (&lt;strong&gt;twice&lt;/strong&gt;).  Text lost again.  By the time I was half-way through the second version, I decided I should post it to my blog as well.  Fortunately, Live Writer makes saving very easy (you get to skip that "Save File" Dialog), so this time it may actually see the light.)&lt;/em&gt;
  &lt;/p&gt;  &lt;p&gt;&lt;em&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Sara Chipps (aka "Girl Developer") just wrote an article about &lt;a href="http://girldeveloper.com/waxing-dev/i-ve-concluded-that-you-guys-don-t-think-i-m-an-idiot/" target="_blank"&gt;women in software development.&lt;/a&gt;   I see it as a bit more complicated.&lt;/p&gt;  &lt;p&gt;Over my 20+ (gag) years as a professional software developer, I've noticed an interesting thing about the male:female ratio amongst software developers.&lt;/p&gt;  &lt;p&gt;For Chinese developers, it's very close to 1:1.&lt;/p&gt;  &lt;p&gt;For Indians and Russians, it's about 2:1.&lt;/p&gt;  &lt;p&gt;For American-born developers of Western European descent, it's around 20:1.  And that's counting project leaders and other managerial roles.  If we limit it to just coders, it gets close to triple digits --- and it's only that low because I worked with four fine American women programmers at one job back in the 80's -- before the big H-1B explosion.&lt;/p&gt;  &lt;p&gt;I feel this is because programming ability, unlike being a doctor or lawyer, is not respected as a skill.  Development isn't a job one aspires to; it has become just another dead-end job for those that couldn't hack med school.    &lt;/p&gt;  &lt;p&gt;Part of the problem can be traced to the fact that most Americans have absolutely no clue what a "computer person" does.  They may not be able to perform surgery, but they do have a general idea what a surgeon is doing, and they can tell the doctors from the orderlies.  But, very few people know the different between a computer programmer and a computer operator ("It's the different between writing a novel and running a printing press").  Most &lt;em&gt;literally&lt;/em&gt; treat the ability to get a computer to do something as if it were a form of Black Magic (and yes, I do mean "literally" there).  You just type in the memorized incantations  and the computer sudden does your will -- like wizardry, a trait you are born with, not something that can be taught and developed.  Most depictions in movies and TV treat the skill as something that even surprised us --- that we know how to do the spell, but not how the spell works.  (unfortunately, this is becoming true...)&lt;/p&gt;  &lt;p&gt;This, of course, shouldn't be surprising from an American populace that generally seems proud of their inability to do math, and treat anyone who can do even the simplest arithmetic in his head as a freak.  &lt;/p&gt;  &lt;p&gt;Then there is accountability --- we feel that we are able to recognize a good doctor from a bad doctor, and maybe a good lawyer from a bad lawyer, but if you have no clue what a person does, how can you rate them?  They consider the teenage that can a throw together an Html page as much of a "computer genius" as a compiler author (or they would if they had any clue what a "compiler author" was). &lt;/p&gt;  &lt;p&gt;Star doctors save lives; star athletes fill stadiums, and as such deserve huge salaries.  However, star developers, in the public's mind (and unfortunately in the minds of upper management of many companies hiring developers), &lt;a href="http://xkcd.com/519/" target="_blank"&gt;can be replaced by nerdy 16-year-olds&lt;/a&gt;.   Salaries have plateaued --  According to Payscale.com, &lt;a href="http://www.payscale.com/research/US/Job=Sr._Software_Engineer_%2F_Developer_%2F_Programmer/Salary" target="_blank"&gt;a developer with 20 years experience can be expected to make only about 30% more than one with just one year of experience&lt;/a&gt;.   In the same survey, a &lt;a href="http://www.payscale.com/research/US/Job=Attorney_%2f_Lawyer/Salary" target="_blank"&gt;similarly experienced lawyer&lt;/a&gt; can expect double the salary of a beginner.&lt;/p&gt;  &lt;p&gt;We have a profession that is not respected, is not considered a learnable skill, where experience counts for little, has little job security, whose average salary becomes more mediocre with each passing year, which management believes can be out-sourced to third-world countries.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;[side note: The trend to outsourcing that's been underway since the 90's has an interesting dynamic.  It seems hiring has been based on the theory: "Who better to work on the Black Art of programmer than people from the &lt;em&gt;mystical&lt;/em&gt; lands of India and the Orient?".  Now, India does have one of the best Engineering schools in the world, but only a very tiny percentage of the population attends.  It's much like assuming that because I'm American, I must have attended Harvard .  In fact, a far greater percentage of American are Harvard grads than Indians who have graduated from the Indian Institute of Technology.  On the other hand, tall tales of the Far East Mysticism go back nearly a millennium.  So, it seems that hiring has gone from being based on sexism, to being based on racism.]&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So, the real question is, not "&lt;em&gt;Why so few Women?&lt;/em&gt;", but actually, "&lt;em&gt;Why so many men?&lt;/em&gt;".  &lt;/p&gt;  &lt;p&gt;From what I've seen answering question on various programming forums, it appears that every young boy that want to start programming, does so, so that he can write, as his very first program, a First-Person Shooter game.   And why not? Programming is Black Magic.  Writing &lt;strong&gt;Grand Thief Auto&lt;/strong&gt; is no more difficult than writing &lt;strong&gt;Hello World, &lt;/strong&gt;right?  Recently on StackOverflow, someone asked about writing a game.  He mentioned that he wanted to write everything himself, instead of using a framework, because he "wanted it to be fast".  I had to explain the game frameworks were written by teams of experts in the field with, collectively, decades of experience on micro-optimizations to squeeze every last cycle out of each video card, so if he had any hope of it being fast, he'd better use a framework.&lt;/p&gt;  &lt;p&gt;So, where are most women and many men turning to instead of software?  &lt;/p&gt;  &lt;p&gt; Well, if the Reagan/Bush/Bush era (and to a lesser, but still real extent, the Clinton era) has taught us anything, it's that &lt;em&gt;workers are scum&lt;/em&gt;.  Only the very top of the ladder has any hope to true success.  When evaluating career paths, unless someone has a "calling" into a particular job (actor, teacher, priest), based on career potential, the choices basically run : Doctor, lawyer, CEO.  That where the money is.  Developer has become a job you "fall into" -- just slightly above being promoted from store clerk to assistant manger.  &lt;/p&gt;  &lt;p&gt;So, what can we do about this?  &lt;/p&gt;  &lt;p&gt; Damned if I know.&lt;/p&gt;  &lt;p&gt;I suspect that high school biology and social studies classes help us appreciate the skill of doctors and lawyer.  As far as I know, HS classes on computers are largely limited to using MSWord and Excel --- teaching us to appreciate the secretaries we don't have anymore.  &lt;/p&gt;  &lt;p&gt;So, should high schoolers by required to take a semester in programming?  That would be nice, but I figure if you add a required course, that means you'll have to drop an existing required course, and I'm not sure what I'd give the heave-ho to.  What's more, programming isn't even my top choice for course that all should be part of the basic curriculum --- recent event have shown that that clearly needs to be a course in Personal Finance. &lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Men+%26amp%3b+Women+%26amp%3b+Careers+in+IT." href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/12/22/men-women-careers-in-it.aspx&amp;subject=Men+%26amp%3b+Women+%26amp%3b+Careers+in+IT."&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/12/22/men-women-careers-in-it.aspx&amp;title=Men+%26amp%3b+Women+%26amp%3b+Careers+in+IT." title="Submit Men+%26amp%3b+Women+%26amp%3b+Careers+in+IT. to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/12/22/men-women-careers-in-it.aspx&amp;phase=2" title="Submit Men+%26amp%3b+Women+%26amp%3b+Careers+in+IT. to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/12/22/men-women-careers-in-it.aspx&amp;title=Men+%26amp%3b+Women+%26amp%3b+Careers+in+IT." title="Submit Men+%26amp%3b+Women+%26amp%3b+Careers+in+IT. to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7859" width="1" height="1"&gt;</description></item><item><title>Sex &amp; Computers &amp; Rock &amp; Roll : The Cycle of Creativity</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/12/13/sex-computers-rock-roll-the-cycle-of-creativity.aspx</link><pubDate>Sun, 14 Dec 2008 00:55:07 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:7811</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;Ok, there is actually no sex in this article.  The title is merely a tribute to the great Ian Dury &amp;amp; the Blockheads.  But there will be computers and Rock'n'Roll.&lt;/p&gt;  &lt;p&gt;Recently a question of &lt;a href="http://www.StackoverFlow.com" target="_blank"&gt;StackoverFlow.com&lt;/a&gt; asked about "breaking the rules" of programming.  I used it to discuss my theory of the Cycle of Creativity.  Since some questioned it, I figured it would make a good topic for the blog.&lt;/p&gt;  &lt;p&gt;All human creative activity seems to follow a cycle of three phases:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;A period of random experimentation and mimicry:  The results are very hit &amp;amp; miss.  We get some of the very best works, but also some of the very worst. &lt;/li&gt;    &lt;li&gt;The establishment of "The Rules":  Product is produced steadily.  Quality is constant but mediocre. Corporate profits are high.  Product become formulaic. &lt;/li&gt;    &lt;li&gt;The Masters learn when to break the rules: This is the period of greatest creativity.  The rules are there for support most of the time, but, once they are mastered, one knows when is the perfect time to break one, to create a work of true art. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Unfortunately, this is then always followed by people who, having seen the Masters break the rules, decided the best thing to do if just throw out the rules, plunging the whole system back into Phase One.&lt;/p&gt;  &lt;p&gt;I believe anyone familiar with computer programming can see the three phases at work there.  In phase one was the "spaghetti code" era.  Phase two began with the introduction of "structured programming", then "object oriented programming" and finally "Design Patterns".  We're now in phase three, where most of the data structures and algorithms we learned in school are readily available in frameworks as a black box.  Now we can worry about the design of the application itself, and the skillful know the exact time to use a goto or have multiple function exit points.&lt;/p&gt;  &lt;p&gt;The controversial part of that message was an alternate example I gave : That for Rock music, the three phases roughly correspond to the 1960s, 70s and 80s.  Some balked at that, but I stand by it.&lt;/p&gt;  &lt;p&gt;One commenter stated that R'n'R has been going downhill since Buddy Holly.   That's a imprecise comparison since I was talking about an entire industry, and there will always be individual exceptions.  Any observer of the music scene in the late 50s (particularly the part that was true Rock &amp;amp; Roll rather than Rhythm &amp;amp; Blues) would clearly see the random experimentation - Any song that made the Top 40 was follow immediately follows by three or more cover versions by other groups --- which also made the charts.  Bobby Darrin's hit "Mack the Knife" (which you'll recall was a song about a petty thief and murderer from a ten-year old German musical ) was actually the &lt;em&gt;seventh&lt;/em&gt; version of that song on the Top 40 that year!  No one really knew what they were doing.  And Buddy Holly's brief career demonstrated that he had made it through the three phases: his last recording before his death were clearly in the "master knowing when to break the rules" mode.&lt;/p&gt;  &lt;p&gt;This continued into the 60's -- A lot of experimenting (some of it musical) going on.  It produced some of the best music (The Beatles) and some of the worst ("Little Itty-Bitty Yellow Polka-dot Bikini"?).&lt;/p&gt;  &lt;p&gt;In the 70's, the corporations finally reigned in R'n'R, and the rules were set.  The instruments were fixed: (lead guitar, rhythm guitar, bass guitar, drums), bands cranked out a new album every 9 months, songs  were between three and four minutes long; if a band "broke up", it were gone for good.  Top 40 music became formulaic.  The decade culminated with the ultimate in pre-packaged, corporate-friendly music: Disco.&lt;/p&gt;  &lt;p&gt;And yet, at the same time, came the beginnings of the third phase, in the punk movement.  The early players, notably The Clash and the Sex Pistols (especially their manager, Malcolm McLaren) were definitely in the "masters knowing when to break the rules" realm  --- unfortunately, it slide into phase four quite rapidly, where everyone started breaking rules without reason, and it soon became a messy.&lt;/p&gt;  &lt;p&gt;Which brings us to the 80s, which I have deemed the peak of the rock era, and which some dispute.  Now, I spend 1980 thru 1984, in college, DJing at my college's radio station, so some might think I'm a bit biased towards that period, so I'll have to offer some proof.  First of all, on the news this morning, they listed the top concert acts for the year: Bon Jovi, Bruce Springsteen, Madonna, and the Police.   Now, while I think it's should be noted that the top two are both from New Jersey, the important point is when each of them hit their peak:  What was that? Yes, the early 80s.   (Yes, I know that "Born to Run" came out in the mid 70's, but Springsteen was just a one-hit wonder until "Hunger Heart" and "Born in the USA").  And while you might dismiss Jon, Bruce and Madge as just Top 40 fodder, Sting &amp;amp; the Police have proven themselves timeless artist, along with Joe Jackson, Elvis Costello, Thomas Dolby, The Talking Heads, Prince, U2   --- All major talents who established themselves by breaking rules -- under controlled conditions, and did so in the early 80s.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Sex+%26amp%3b+Computers+%26amp%3b+Rock+%26amp%3b+Roll+%3a+The+Cycle+of+Creativity" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/12/13/sex-computers-rock-roll-the-cycle-of-creativity.aspx&amp;subject=Sex+%26amp%3b+Computers+%26amp%3b+Rock+%26amp%3b+Roll+%3a+The+Cycle+of+Creativity"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/12/13/sex-computers-rock-roll-the-cycle-of-creativity.aspx&amp;title=Sex+%26amp%3b+Computers+%26amp%3b+Rock+%26amp%3b+Roll+%3a+The+Cycle+of+Creativity" title="Submit Sex+%26amp%3b+Computers+%26amp%3b+Rock+%26amp%3b+Roll+%3a+The+Cycle+of+Creativity to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/12/13/sex-computers-rock-roll-the-cycle-of-creativity.aspx&amp;phase=2" title="Submit Sex+%26amp%3b+Computers+%26amp%3b+Rock+%26amp%3b+Roll+%3a+The+Cycle+of+Creativity to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/12/13/sex-computers-rock-roll-the-cycle-of-creativity.aspx&amp;title=Sex+%26amp%3b+Computers+%26amp%3b+Rock+%26amp%3b+Roll+%3a+The+Cycle+of+Creativity" title="Submit Sex+%26amp%3b+Computers+%26amp%3b+Rock+%26amp%3b+Roll+%3a+The+Cycle+of+Creativity to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=7811" width="1" height="1"&gt;</description></item><item><title>Predicted</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/11/12/predicted.aspx</link><pubDate>Thu, 13 Nov 2008 04:40:57 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:6912</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Way back into March, my best friend Chris and I made our predictions for the &lt;a href="http://honestillusion.com/blogs/blog_0/archive/2008/03/25/predictions.aspx" target="_blank"&gt;presidential election&lt;/a&gt;.  Since the election is now over (mostly), it's time to review have well we did:&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2"&gt;     &lt;tr&gt;       &lt;td&gt; &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;&lt;strong&gt;Chris's Prediction&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;&lt;strong&gt;James's Prediction&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;&lt;strong&gt;Actual results&lt;/strong&gt;&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p align="center"&gt;President&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;McCain&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;The democrat&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;Obama&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p align="center"&gt;States won by Democratic nominee&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt; 14&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;20&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;27&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p align="center"&gt;Senate seats won by Dems&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;  0&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;+4&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;+6 (maybe +9)&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p align="center"&gt;House of Representatives&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;-8&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;+10&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;+23&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td&gt;         &lt;p align="center"&gt;Governors won by Dems&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;-2&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;+2&lt;/p&gt;       &lt;/td&gt;        &lt;td&gt;         &lt;p align="center"&gt;+1&lt;/p&gt;       &lt;/td&gt;     &lt;/tr&gt;   &lt;/table&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;So, in every category, I was closer, and except for governors, even I was too pessimistic.   &lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Predicted" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/11/12/predicted.aspx&amp;subject=Predicted"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/11/12/predicted.aspx&amp;title=Predicted" title="Submit Predicted to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/11/12/predicted.aspx&amp;phase=2" title="Submit Predicted to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/11/12/predicted.aspx&amp;title=Predicted" title="Submit Predicted to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=6912" width="1" height="1"&gt;</description></item><item><title>jQuery.growl Documentation</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/10/20/jquery-growl-documentation.aspx</link><pubDate>Tue, 21 Oct 2008 02:47:26 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:6416</guid><dc:creator>James</dc:creator><slash:comments>6</slash:comments><description>
  &lt;p&gt;Right now, I'm in the midst of a long-running project to rewrite my other website, &lt;a href="http://www.njtheater.com" target="_blank"&gt;NJTheater.com&lt;/a&gt; (beta at &lt;a href="http://www.njtheater.org/" target="_blank"&gt;njtheater.org&lt;/a&gt;).  In the process, I've discovered jQuery, the hot new javascript library that all the kids are using today.   One of it's key selling points is it's well designed plugin system, which has led to a host of add-ons being written for it.  &lt;/p&gt;  &lt;p&gt;Recently, I stumbled upon one such plugin, &lt;a href="http://www.fragmentedcode.com/jquery-growl"&gt;jQuery Growl Plugin&lt;/a&gt; by &lt;a href="http://www.fragmentedcode.com/"&gt;David Higgins&lt;/a&gt;.  Apparently, Growl is a MacOS application, so the Applist readers should by now figured out what it does.  For the Windows/Linux folk, it displays a little popup alert box, sort-of like the Messenger "toaster" popup, except they come down from the top.  They slide down, stay for a few moments, and then fade out.  If another is displayed while the first is still visible, they stack.  &lt;a href="http://projects.zoulcreations.com/jquery/growl/" target="_blank"&gt;Demos here.&lt;/a&gt; Now, while the demos looked rather cool, library itself does suffer from the main problem that affects most open source code -- the documentation just sucks.  In fact, it goes beyond mere suckage; at one point, you get the feeling the author is just mocking you.&lt;/p&gt;  &lt;p&gt;But no sense in just complaining, or insulting a person who has contributed to the community.  The best thing to do in this case is for one to contribute himself.  And so, here's my documentation for the plugin&lt;/p&gt;  &lt;h2&gt;&lt;u&gt;jQuery.growl&lt;/u&gt;&lt;/h2&gt;  &lt;p&gt;The official calling syntax is:&lt;/p&gt;  &lt;pre class="cpp"&gt;&lt;font size="3"&gt;$.growl(title, message, image, priority); &lt;/font&gt;&lt;/pre&gt;

&lt;p&gt;All four parameters are strings, and all have defaults, so you only need to pass the ones you are using.  However, the first two default to an empty string, so it'll be rather boring unless you specify them.  The third and fourth parameters have reasonable defaults, but, well, we'll get to that in a minute.&lt;/p&gt;

&lt;p&gt;You see, the important thing to realize here is that the HTML displayed is template driven.  So, while the first parameter is called "title", that merely means that it'll be used to replace the string "%title%" in the template.  Similarly, the value of the "message" parameter replaces "%message%" in the template; "image" replaces "%image%", and you guessed it, "priority" replaces "%priority%".&lt;/p&gt;

&lt;p&gt;This is important to know, because, while there is a default template, which uses %title% as the title and %message% as the message, you can define your own template and in that template, you can use the four parameters for whatever you what.  (Templates are defined at the global level, which in this context mean "for the page").&lt;/p&gt;

&lt;p&gt;Here we start getting into the bizarre part:  The replaceable keywords "%image%" and "%priority%" do not appear in the default template at all. Unless you define your own template, the values you pass for them will never be seen. Of course, if you do define your own template, there's nothing requiring that you use"%image%' as an image or "%priority%" as a priority.  The only thing holding them to their preordained role is their defaults: the image parameter defaults to ''growl.jpg", and priority defaults to "normal". (So the parameters aren't used out of the box having meaningful defaults, while the two that are used, have useless defaults).&lt;/p&gt;

&lt;p&gt;The default template is rather minimalist, but functional:&lt;/p&gt;

&lt;pre class="xml"&gt;&amp;lt;div class="notice"&amp;gt;
&amp;lt;h3 style="margin-top: 15px"&amp;gt;%title%&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;%message%&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;An example of a more elaborate template would be:&lt;/p&gt;

&lt;pre class="xml"&gt;&amp;lt;div&amp;gt;
  &amp;lt;div style="float: right; background-image: url(normalTop.png); position: relative; width: 259px; height: 16px; margin: 0pt;"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div style="float: right; background-image: url(normalBackground.png); position: relative; display: block; color: #ffffff; font-family: Arial; font-size: 12px; line-height: 14px; width: 259px; margin: 0pt;"&amp;gt;
    &amp;lt;img style="margin: 14px; margin-top: 0px; float: left;" src="%image%" /&amp;gt;
    &amp;lt;h3 style="margin: 0pt; margin-left: 77px; padding-bottom: 10px; font-size: 13px;"&amp;gt;%title%&amp;lt;/h3&amp;gt;
    &amp;lt;p style="margin: 0pt 14px; margin-left: 77px; font-size: 12px;"&amp;gt;%message%&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div style="float: right; background-image: url(normalBottom.png); position: relative; width: 259px; height: 16px; margin-bottom: 10px;"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;';&lt;/pre&gt;

&lt;p&gt;(That one came from jQuery.growl's author, and we still haven't found a use for the priority parameter!)&lt;/p&gt;

&lt;p&gt;The template is changed by setting the $.growl.settings.noticeTemplate field.  &lt;/p&gt;

&lt;p&gt;$.growl.settings.noticeTemplate = '&amp;lt;div class="%priority%"&amp;gt;&amp;lt;div class="%priority%-heading"&amp;gt;%title%&amp;lt;/div&amp;gt;&amp;lt;div class="%priority%-message"&amp;gt;%message%&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;'&lt;/p&gt;

&lt;p&gt;The other setting that change be changed the same way are:&lt;/p&gt;

&lt;table cellspacing="0" cellpadding="2"&gt;
    &lt;tr&gt;
      &lt;td&gt;
        &lt;p align="center"&gt;&lt;strong&gt;Property&lt;/strong&gt;&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p align="center"&gt;&lt;strong&gt;Description &lt;/strong&gt;&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p align="center"&gt;&lt;strong&gt;Default&lt;/strong&gt;&lt;/p&gt;
      &lt;/td&gt;

      &lt;td&gt;
        &lt;p align="center"&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;/p&gt;
      &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;dockTemplate&lt;/td&gt;

      &lt;td&gt;Element in which the notices are created.&lt;/td&gt;

      &lt;td&gt;'&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;'&lt;/td&gt;

      &lt;td&gt;string &lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;dockCss&lt;/td&gt;

      &lt;td&gt;Style elements applied on dock, generally used to specify it's position.&lt;/td&gt;

      &lt;td&gt;Fixed in the upper right corner of the browser window&lt;/td&gt;

      &lt;td&gt;object whose properties are feed to a css() method call.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;noticeTemplate&lt;/td&gt;

      &lt;td&gt;Template for notice.&lt;/td&gt;

      &lt;td&gt;(see above)&lt;/td&gt;

      &lt;td&gt;string&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;noticeCss&lt;/td&gt;

      &lt;td&gt;Style elements applied on notice.&lt;/td&gt;

      &lt;td&gt;White on Green at 3/4 opacity.&lt;/td&gt;

      &lt;td&gt;object whose properties are fed to a css() method.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;noticeFadeTimeout&lt;/td&gt;

      &lt;td&gt;How fast the notice fades out.&lt;/td&gt;

      &lt;td&gt;'slow'&lt;/td&gt;

      &lt;td&gt;String|Number, suitable for use in an animate() method call.&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;displayTimeout&lt;/td&gt;

      &lt;td&gt;Total time the notice displayed.&lt;/td&gt;

      &lt;td&gt;3500 milliseconds&lt;/td&gt;

      &lt;td&gt;number&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;defaultImage&lt;/td&gt;

      &lt;td&gt;Value used for %image% when not specified in the call.&lt;/td&gt;

      &lt;td&gt;growl.jpg&lt;/td&gt;

      &lt;td&gt;string&lt;/td&gt;
    &lt;/tr&gt;

    &lt;tr&gt;
      &lt;td&gt;defaultStylesheet&lt;/td&gt;

      &lt;td&gt;Gives the name of a stylesheet , which, if specified, is automatically loaded.&lt;/td&gt;

      &lt;td&gt;none&lt;/td&gt;

      &lt;td&gt;string.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/table&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The dock needs a bit more explanation.  It's basically where the notices are drawn, and there's probably little reason to change it from it's default of a vanilla div.  Note that whatever it is, it will have the attributes "id=growlDock" and "class=growl" added to it.  &lt;/p&gt;

&lt;p&gt;If you want to change the look of the dock, and want more control of it than stuffing some html into a property, you can just define an element with an id=growlDock, and $.growl will use that.&lt;/p&gt;

&lt;p&gt;However the dock is defined, the style elements defined in the dockCss property are then added to it, and it's append to the &amp;lt;body&amp;gt; of the page.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2008%2f10%2f20%2fjquery-growl-documentation.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2008%2f10%2f20%2fjquery-growl-documentation.aspx" border="0" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email jQuery.growl+Documentation" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/10/20/jquery-growl-documentation.aspx&amp;subject=jQuery.growl+Documentation"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/10/20/jquery-growl-documentation.aspx&amp;title=jQuery.growl+Documentation" title="Submit jQuery.growl+Documentation to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/10/20/jquery-growl-documentation.aspx&amp;phase=2" title="Submit jQuery.growl+Documentation to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/10/20/jquery-growl-documentation.aspx&amp;title=jQuery.growl+Documentation" title="Submit jQuery.growl+Documentation to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=6416" width="1" height="1"&gt;</description></item><item><title>Fun Fact:  To the Moon, Alice, to the Moon!</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/10/16/fun-fact-to-the-moon-alice-to-the-moon.aspx</link><pubDate>Thu, 16 Oct 2008 16:15:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:6347</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>

&lt;p&gt;I really should bring the subject matter here back around to computers.....&lt;/p&gt;
&lt;p&gt;Lately (if you consider the last year &amp;amp; a half "lately"), I've been working on a project on my laptop using VisualStudio (usually on the train to work).  Every now &amp;amp; then some action (like, say, highlighting a couple lines and pressing Ctrl-C to copy them), will cause VS to lock up for about 30 seconds, and then just pop back to life.   I think it's a bad interaction between a couple of VS addins, but whatever the cause, it does leave me wondering "What the F#©&amp;amp; is it doing??"   This lead to an idea, which after a bit of reseach, lead me to this:&lt;/p&gt;
&lt;p&gt; &lt;font size="+2"&gt;&lt;b&gt;In &lt;i&gt;three minutes &lt;/i&gt;of hourglass-displaying spinning, my dual-core 1.87GHz laptop uses more CPU clock cycles then the entire &lt;i&gt;six day &lt;/i&gt;Apollo 11 mission. &lt;/b&gt;&lt;/font&gt;&lt;br /&gt;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Fun+Fact%3a++To+the+Moon%2c+Alice%2c+to+the+Moon!" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/10/16/fun-fact-to-the-moon-alice-to-the-moon.aspx&amp;subject=Fun+Fact%3a++To+the+Moon%2c+Alice%2c+to+the+Moon!"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/10/16/fun-fact-to-the-moon-alice-to-the-moon.aspx&amp;title=Fun+Fact%3a++To+the+Moon%2c+Alice%2c+to+the+Moon!" title="Submit Fun+Fact%3a++To+the+Moon%2c+Alice%2c+to+the+Moon! to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/10/16/fun-fact-to-the-moon-alice-to-the-moon.aspx&amp;phase=2" title="Submit Fun+Fact%3a++To+the+Moon%2c+Alice%2c+to+the+Moon! to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/10/16/fun-fact-to-the-moon-alice-to-the-moon.aspx&amp;title=Fun+Fact%3a++To+the+Moon%2c+Alice%2c+to+the+Moon!" title="Submit Fun+Fact%3a++To+the+Moon%2c+Alice%2c+to+the+Moon! to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=6347" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Random+Thoughts/default.aspx">Random Thoughts</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category></item><item><title>Yep, I'm a socialist....</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/10/13/yep-i-m-a-socialist.aspx</link><pubDate>Mon, 13 Oct 2008 14:12:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:6345</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
&lt;p&gt;I haven't posted here in a while, so I figure I'll go back to the old "generate content by taking online quizzes" trick.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;table style="border:1px solid black;"&gt;&lt;tr&gt;&lt;td align="center"&gt;      &lt;font size="3"&gt;      You are a     &lt;/font&gt; &lt;font size="3"&gt;    &lt;br&gt;     &lt;font size="4"&gt;&lt;b&gt;Social Liberal&lt;/b&gt;&lt;/font&gt;     &lt;br&gt;     &lt;font size="3"&gt;(66% permissive)&lt;/font&gt;&lt;br&gt;     &lt;/font&gt; &lt;font size="3"&gt;    &lt;br&gt;     and an...     &lt;/font&gt;&lt;font size="3"&gt;&lt;br&gt;      &lt;font size="4"&gt;&lt;b&gt;Economic Liberal&lt;/b&gt;&lt;/font&gt;      &lt;br&gt;     &lt;font size="3"&gt;(20% permissive)&lt;/font&gt;&lt;br&gt;     &lt;/font&gt;  &lt;font size="3"&gt;    &lt;br&gt;     You are best described as a:&lt;br&gt;     &lt;br&gt;&lt;font size="+2"&gt;&lt;u&gt;&lt;b&gt;Socialist &lt;/b&gt;&lt;/u&gt;&lt;/font&gt;     &lt;/font&gt;&lt;br&gt;        &lt;table id="thetable" cellpadding="0" cellspacing="0"&gt;        &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;         &lt;td&gt;&lt;/td&gt;        &lt;/tr&gt;         &lt;tr&gt; &lt;td&gt;&lt;/td&gt;          &lt;td align="left"&gt; &lt;img src="http://cdn.okcimg.com/graphics/politics_you.gif" border="0"&gt;&lt;/td&gt;        &lt;/tr&gt;       &lt;/table&gt;        &lt;br&gt;        &lt;table id="thetable" cellpadding="0" cellspacing="0"&gt;        &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;         &lt;td&gt;&lt;/td&gt;        &lt;/tr&gt;         &lt;tr&gt; &lt;td&gt;&lt;/td&gt;          &lt;td align="left"&gt; &lt;img src="http://cdn.okcimg.com/graphics/politics_you.gif" border="0"&gt;&lt;/td&gt;        &lt;/tr&gt;       &lt;/table&gt;        &lt;br&gt;&lt;br&gt;Link: &lt;a href="http://www.okcupid.com/politics"&gt;&lt;b&gt; The Politics Test &lt;/b&gt;&lt;/a&gt;   on  &lt;a href="http://www.okcupid.com/"&gt;&lt;b&gt;Ok Cupid&lt;/b&gt;&lt;/a&gt;&lt;br&gt; Also : &lt;a href="http://www.okcupid.com/online.dating.persona.test"&gt; The OkCupid Dating Persona Test &lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Now, some people might be a bit concerned about being called a Socialist, but when you consider that the recent governement bailouts of the AIG and the mortgage industry essentailly meant that we've nationalist several large companies, making President Bush and our Congress history's biggest Marxists.&amp;nbsp; It seems Socialism is all the rage.......&lt;br&gt;&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Yep%2c+I%27m+a+socialist...." href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/10/13/yep-i-m-a-socialist.aspx&amp;subject=Yep%2c+I%27m+a+socialist...."&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/10/13/yep-i-m-a-socialist.aspx&amp;title=Yep%2c+I%27m+a+socialist...." title="Submit Yep%2c+I%27m+a+socialist.... to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/10/13/yep-i-m-a-socialist.aspx&amp;phase=2" title="Submit Yep%2c+I%27m+a+socialist.... to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/10/13/yep-i-m-a-socialist.aspx&amp;title=Yep%2c+I%27m+a+socialist...." title="Submit Yep%2c+I%27m+a+socialist.... to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=6345" width="1" height="1"&gt;</description></item><item><title>Contribute to open source, get a shot at a free book</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/09/15/contribute-to-open-source-get-a-shot-at-a-free-book.aspx</link><pubDate>Mon, 15 Sep 2008 19:10:10 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:6106</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;
    &lt;a href="http://encosia.com/" target="_blank"&gt;David Ward&lt;/a&gt; has an interesting &lt;a href="http://encosia.com/2008/09/09/contribute-to-open-source-get-a-shot-at-a-free-book/" target="_blank"&gt;contest&lt;/a&gt;.   Having three copies of &lt;a href="http://search.barnesandnoble.com/Advanced-ASPNET-AJAX-Server-Controls/Adam-Calderon/e/9780321514448/?itm=1" target="_blank"&gt;Advanced ASP.NET AJAX Server Controls&lt;/a&gt; to give away, he's created a &lt;a href="http://codeplex.com/UsernameAvailability" target="_blank"&gt;project on CodePlex&lt;/a&gt;, and is offering the books to people to who contribute the most to it.   One can contribute code or documentation or anything -- one book is raffled off among those who merely participate in the online discussions about it (or post a blog entry about it).  Since these days I'm into Monorail and jQuery rather than asp.net, I can't contribute much in the way of code, but I am very active in the discussion group.  In fact, if you discount the coordinator (Encosia aka David Ward) and JRumerman (who is one of the authors of the book being given away), I think I'm the most active guy there).&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Oh, I guess I should mention the purpose of the project: it's to develop an ASP.Net AJAX web control to accept a potential username and handle automatically checking if that name is already being used by someone else.  &lt;/p&gt;  &lt;p&gt;Now, to contribute, you probably need to know a fair amount about ASP.NET AJAX control --- which means you may not need to book you could win, but it's a fun idea anyway....&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Contribute+to+open+source%2c+get+a+shot+at+a+free+book" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/09/15/contribute-to-open-source-get-a-shot-at-a-free-book.aspx&amp;subject=Contribute+to+open+source%2c+get+a+shot+at+a+free+book"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/09/15/contribute-to-open-source-get-a-shot-at-a-free-book.aspx&amp;title=Contribute+to+open+source%2c+get+a+shot+at+a+free+book" title="Submit Contribute+to+open+source%2c+get+a+shot+at+a+free+book to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/09/15/contribute-to-open-source-get-a-shot-at-a-free-book.aspx&amp;phase=2" title="Submit Contribute+to+open+source%2c+get+a+shot+at+a+free+book to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/09/15/contribute-to-open-source-get-a-shot-at-a-free-book.aspx&amp;title=Contribute+to+open+source%2c+get+a+shot+at+a+free+book" title="Submit Contribute+to+open+source%2c+get+a+shot+at+a+free+book to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=6106" width="1" height="1"&gt;</description></item><item><title>Billions &amp; Billions</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/08/26/billions-billions.aspx</link><pubDate>Wed, 27 Aug 2008 02:48:03 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:6016</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Recently I got a chain email from a friend, showing the magnitude of a billion.&lt;/p&gt;  &lt;ol&gt;   &lt;ol&gt;     &lt;li&gt;&lt;em&gt;A billion seconds ago it was 1959. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;A billion minutes ago Jesus was alive. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;A billion hours ago our ancestors were living in the Stone Age. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;A billion days ago no-one walked on the earth on two feet. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;A billion dollars ago was only 8 hours and 20 minutes, at the rate our government is spending it.&lt;/em&gt; &lt;/li&gt;   &lt;/ol&gt; &lt;/ol&gt;  &lt;p&gt;As I normally do with such things, I immediately went to &lt;a href="http://www.snopes.com" target="_blank"&gt;snopes.com&lt;/a&gt; to find out &lt;a href="http://www.snopes.com/inboxer/trivia/billions.asp" target="_blank"&gt;how accurate it was&lt;/a&gt;. (bottom line: eh....close enough, although it was probably written in the early 1990s).&lt;/p&gt;  &lt;p&gt;The interesting thing about it is that it apparently has gone through three phases.  The first had just that bit above about billions.  I guess the politics in that was too subtle for some people, so, more recently someone added a bit about Hurricane Katrina and New Orleans:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Louisiana Senator, Mary Landrieu (D) is presently asking Congress for 250 BILLION DOLLARS to rebuild New Orleans .. Interesting number... what does it mean? &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;A. Well... if you are one of the 484,674 residents of New Orleans (every man, woman, and child) you each get $516,528. &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;B. Or... if you have one of the 188,251 homes in New Orleans, your home gets $1,329,787.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Snopes dealt with this section as well, but not with their usually efficiency. They pretty much just limited themselves to checking the author's math. (again, close enough, but not perfect, which is odd considering he gave very precise wrong values).  Furthermore, apparently quite recently someone added a bit more, which snopes doesn't cover at all:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Washington, D.C       &lt;br /&gt;&amp;lt; HELLO!&amp;gt;        &lt;br /&gt;Are all your calculators broken?? &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Accounts Receivable Tax       &lt;br /&gt;Building Permit Tax        &lt;br /&gt;CDL License Tax        &lt;br /&gt;Cigarette Tax        &lt;br /&gt;Corporate Income Tax        &lt;br /&gt;Dog License Tax        &lt;br /&gt;Federal Income Tax         &lt;br /&gt;Federal Unemployment Tax (FUTA)         &lt;br /&gt;Fishing License Tax         &lt;br /&gt;Food License Tax         &lt;br /&gt;Fuel Permit Tax         &lt;br /&gt;Gasoline Tax         &lt;br /&gt;Hunting License Tax         &lt;br /&gt;Inheritance Tax         &lt;br /&gt;Inventory Tax         &lt;br /&gt;IRS Interest Charges (tax on top of tax)         &lt;br /&gt;IRS Penalties (tax on top of tax)         &lt;br /&gt;Liquor Tax         &lt;br /&gt;Luxury Tax         &lt;br /&gt;Marriage License Tax         &lt;br /&gt;Medicare Tax         &lt;br /&gt;Property Tax         &lt;br /&gt;Real Estate Tax         &lt;br /&gt;Service charge taxes         &lt;br /&gt;Social Security Tax         &lt;br /&gt;Road Usage Tax (Truckers)         &lt;br /&gt;Sales Taxes         &lt;br /&gt;Recreational Vehicle Tax        &lt;br /&gt;School Tax        &lt;br /&gt;State Income Tax        &lt;br /&gt;State Unemployment Tax (SUTA)         &lt;br /&gt;Telephone Federal Excise Tax         &lt;br /&gt;Telephone Federal Universal Service Fee Tax         &lt;br /&gt;Telephone Federal, State and Local Surcharge Tax         &lt;br /&gt;Telephone Minimum Usage Surcharge Tax        &lt;br /&gt;Telephone Recurring and Non-recurring Charges Tax        &lt;br /&gt;Telephone State and Local Tax         &lt;br /&gt;Telephone Usage Charge Tax         &lt;br /&gt;Utility Tax         &lt;br /&gt;Vehicle License Registration Tax         &lt;br /&gt;Vehicle Sales Tax         &lt;br /&gt;Watercraft Registration Tax         &lt;br /&gt;Well Permit Tax         &lt;br /&gt;Workers Compensation Tax &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;STILL THINK THIS IS FUNNY? &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;Not one of these taxes existed 100 years ago...       &lt;br /&gt;and our nation was the most prosperous in the world. &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;We had absolutely no national debt...        &lt;br /&gt;We had the largest middle class in the world...         &lt;br /&gt;and Mom stayed home to raise the kids. &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;What happened?       &lt;br /&gt;Can you spell 'politicians!' &lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;And I still have to press '1' for English. &lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Now, since Snopes dropped the ball on this on, I figured I'd do my part to correct the misinformation here.  &lt;/p&gt;  &lt;p&gt;First of all, as an aside, you can tell the additions were written by a right-winger, as they blame the $250 million on the state's Democratic senator, when in reality the bill was co-sponsored by her and the state's other senator,  Republican David Vitter -- which points to the other sure sign it was written by a right-winger -- it's riddled with errors.  &lt;/p&gt;  &lt;p&gt;The main error is that the money is not just for New Orleans, but for all areas damaged by Katrina -- which includes large parts of Louisiana, Mississippi and bits of Texas.  That pretty much invalidates his whole premise.  But, even if it were just for New Orleans, his premise would still by wrong, because it's not just to rebuild people's houses, but to rebuild the entire city infrastructure: roads, schools, hospitals, levies, etc.  I imagine Republicans would have might less of a problem with government if any of them actually understood how it works.&lt;/p&gt;  &lt;p&gt;Which brings us to the third section of the email, where the writer just goes off the wall.  By line count, it's half of the whole thing, so clearing this guy like hearing himself talk.  Too bad he was too busy typing away to bother actually fact-checking what we wrote.  &lt;/p&gt;  &lt;p&gt;Of that long list of taxes we didn't have "a hundred years ago", many, granted, we didn't have, but mainly because for the most part, the thing being taxed didn't exist (Phones, Social Security, Motor Vehicles etc).  And we really didn't have an income tax in 1908 -- That came about in 1912.  But, as for the rest -- Real estate, alcohol, tobacco,  marriage licenses etc --- They pretty much all were taxed.  &lt;/p&gt;  &lt;p&gt;It's also a bit questionable if we were "&lt;em&gt;the most prosperous [nation] in the world&lt;/em&gt;" in 1908, as we really didn't start moving past England, France and German until after WWI.&lt;/p&gt;  &lt;p&gt;His assertion that "&lt;em&gt;We had absolutely no national debt... &lt;/em&gt;" is total fantasy.  In 1908, the national debt was &lt;a href="http://www.treasurydirect.gov/govt/reports/pd/histdebt/histdebt_histo3.htm" target="_blank"&gt;$2,626,806,271.54&lt;/a&gt;  (adjusted for inflation that would be nearly $58 billion in 2008 dollars).  Granted, that's a lot less than the &lt;a href="http://www.treasurydirect.gov/NP/BPDLogin?application=np" target="_blank"&gt;$9.6 trillion it is now&lt;/a&gt;, but we'll get to that in a minute.   &lt;a href="http://www.treasurydirect.gov/govt/reports/pd/histdebt/histdebt_histo1.htm" target="_blank"&gt;The last time we paid off the debt was 1834.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;As for "&lt;em&gt;We had the largest middle class in the world... &lt;/em&gt;", again, hard to measure --- Do you count raw number of people (we probably win), or percent of population? (in which case you have to look at England, France and German again).&lt;/p&gt;  &lt;p&gt;"&lt;em&gt;Mom stayed home to raise the kids.&lt;/em&gt;" -- Well, mom did stay at home then, but mostly to run the household, which didn't have electricity, nor, most often, running water.  She had to do this because her husband was working 10 hours a day, 6 days a week at a factory -- earning about a dollar a day.  She didn't spend that much time raising the kids -- because, starting at about age 9 or 10, &lt;a href="http://www.historyplace.com/unitedstates/childlabor/" target="_blank"&gt;they were with the father in the factory.&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Oddly, the writer seems to be blaming the raising national debt on taxes.  Maybe his a fan of Rush Limbaugh, since that's one of his wacky ideas: "The best way to increase government revenue is to cut taxes".  But, in reality, it's a lot like saying "The best way to pay your bills is to quit your job".  A much more reasonably plan would be "The best way to pay your bills is to quit your job,&lt;em&gt;  and get a better job".  &lt;/em&gt;Similarly we could say, "The best way to increase government revenue is to cut taxes, &lt;em&gt;and direct the money to growing the economy&lt;/em&gt;".  But, like the job quitting plan, Republicans seem to leave off the last part --- the important part -- and are happy to let multi-millionaires use their tax breaks to pad out their trust funds.&lt;/p&gt;  &lt;p&gt;Which brings us to the real causes of the national debt:  Wars (historically) and Republican presidents (recently).  The very first time the debt passed &lt;a href="http://www.treasurydirect.gov/govt/reports/pd/histdebt/histdebt_histo2.htm" target="_blank"&gt;$1 billion dollars&lt;/a&gt; was during the Civil War.  That was also it's fastest raise (ten-fold in just two years).  It floated around $2 to $3  billion for about 50 years, when it sudden raises nine-fold in four years just in time for WWI.  Then a slight rise during the Great Depression (tripling over 11 years), followed by a big jump for WWII (five-fold in four years), reaching a &lt;a href="http://www.treasurydirect.gov/govt/reports/pd/histdebt/histdebt_histo3.htm" target="_blank"&gt;quarter of a trillion dollars&lt;/a&gt; by the end.&lt;/p&gt;  &lt;p&gt;The debt grew rather slowly after that, taking 30 years (till 1975) to double again.  Then, under the Reagan administration so-called "Economic boom," it triples, &lt;a href="http://www.treasurydirect.gov/govt/reports/pd/histdebt/histdebt_histo4.htm" target="_blank"&gt;passing one trillion dollars for the first time&lt;/a&gt;.  Overall, Reagan &amp;amp; Bush-41 combined brought the debt from under $1 trillion to over $4 trillion (340%) is just 12 years-- with no significant war.  In contrast, during Clinton's 8 years, it raised only 31%.  And we were poised to start actually paying some of it off.  But with Bush-43, we're back to the old pattern, up 66% in 7 years.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Billions+%26amp%3b+Billions" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/08/26/billions-billions.aspx&amp;subject=Billions+%26amp%3b+Billions"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/26/billions-billions.aspx&amp;title=Billions+%26amp%3b+Billions" title="Submit Billions+%26amp%3b+Billions to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/26/billions-billions.aspx&amp;phase=2" title="Submit Billions+%26amp%3b+Billions to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/26/billions-billions.aspx&amp;title=Billions+%26amp%3b+Billions" title="Submit Billions+%26amp%3b+Billions to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=6016" width="1" height="1"&gt;</description></item><item><title>Lists: Filter, Map and Reduce - and the Magic of IEnumerator.</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/08/25/lists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx</link><pubDate>Mon, 25 Aug 2008 19:16:16 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:6014</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;I have this bad habit.  I will frequently stumble upon a blog post describing some new technique, to which I will post a brilliant comment offering an improvement, which, of course, will get lost in the flotsam and jetsam of the blogosphere.  I have to keep reminding myself that is what I have my own blog for.&lt;/p&gt;  &lt;p&gt;Case in point, I recent found this article by Sarah Taraporewalla about writing tradition &lt;a href="http://sarahtaraporewalla.blogspot.com/2008/08/lists-filter-map-and-reduce.html" target="_blank"&gt;Filter, Map and Reduce methods&lt;/a&gt; for Java Lists.  She wondered if they could be written in C#.  I did so in the comments, and now expanded on them here. &lt;/p&gt;  &lt;p&gt;The main difference between mine and those of Sarah's (and also those of &lt;a href="http://dotnet.org.za/pieter/archive/2008/08/17/filter-and-map-in-c.aspx" target="_blank"&gt;Peter&lt;/a&gt;, by way of whose blog I reached Sarah's) is that they pass in a List&amp;lt;&amp;gt; object, and create a new List to return.  This is limiting and unnecessary.&lt;/p&gt;  &lt;pre class="c#"&gt;namespace FilterMapReduce
{
    static public class FMR
    {
        public static IEnumerable&amp;lt;T&amp;gt; Filter&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; list, Func&amp;lt;T, bool&amp;gt; filter)
        {
            foreach (T item in list)
            {
                if (filter(item))
                    yield return item;
            }
        }

        public static IEnumerable&amp;lt;T&amp;gt; Map&amp;lt;T&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; list, Func&amp;lt;T, T&amp;gt; map)
        {
            foreach (T item in list)
            {
                yield return map(item);
            }
        }

        public static U Reduce&amp;lt;T, U&amp;gt;(this IEnumerable&amp;lt;T&amp;gt; list, Func&amp;lt;T, U, U&amp;gt; reduce, U accum)
        {
            foreach (T item in list)
            {
                accum = reduce(item, accum);
            }
            return accum;
        }
    }
}&lt;/pre&gt;

&lt;p&gt;I used a number of .Net v3.5 features there -- notably extension methods and the Func&amp;lt;&amp;gt; delegate, but neither is vital (the non-extension version has just a little messier calling syntax, and you'd have to define your own Func delegate replacement -- so, UPGRADE!)&lt;/p&gt;

&lt;p&gt;With those, we can now write code like this:&lt;/p&gt;

&lt;pre class="c#"&gt;int[] nums = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int sumOdds10 = nums.Filter(n =&amp;gt; (n % 2) == 1)
                    .Map(n =&amp;gt; n * 10)
                    .Reduce((n, a) =&amp;gt; (n + a), 0);&lt;/pre&gt;

&lt;p&gt;I broke the last line to three lines for easier reading, but you could just string it out of you'd like.&lt;/p&gt;

&lt;p&gt;Now that says, "Take the nums array, filter it so we're left with just the odd numbers, map each remaining value to itself times 10, and then sum each of those."&lt;/p&gt;

&lt;p&gt;The important question here is: "How many times have I looped through that array?"  You might think that since I call all three methods, and each has a foreach loop, that it would be only logical that we've go through the array three time.  Logical, maybe, but wrong.   To understand this, let's split that code up a bit:&lt;/p&gt;

&lt;pre class="c#"&gt;var a = nums.Filter(n =&amp;gt; (n % 2) == 1);
var b = a.Map(n =&amp;gt; n * 10);
int sumOdds10 = b.Reduce((n, a) =&amp;gt; (n + a), 0);&lt;/pre&gt;

&lt;p&gt;First we create object a, which if you recall is IEnumerator&amp;lt;int&amp;gt; object. We haven't looped through the array yet -- we just have an object that &lt;em&gt;will&lt;/em&gt; loop throught the array.&lt;/p&gt;

&lt;p&gt;Next, we create object b.  Again, an IEnumerable&amp;lt;int&amp;gt; object, but notably, one which enumerates over, not our array, but the a object.&lt;/p&gt;

&lt;p&gt;Finally, we call Reduce which actually does the work.  It starts to iterate over the list, which is our b object, which is just an IEnumerable object.  So, as we enter Reduce's foreach, it calls &lt;strong&gt;b&lt;/strong&gt;'s (i.e. Map's) MoveNext() method, and enters it's foreach to iterate over the &lt;strong&gt;a&lt;/strong&gt; object -- for which is calls a's (Filter's) MoveNext method.  &lt;/p&gt;

&lt;p&gt;OK, so now we finally enter FIlter's foreach loop, which iterates over an array, so we get a real number (1 at first). It passes the filter so the yield return sends it back to Map, which call the mapping function on it, and yields it up Reduce, which uses it in the reduce function.&lt;/p&gt;

&lt;p&gt;Then Reduce moves on it the next value, which means calling B's MoveNext, which calls Filter's MoveNext, which gets the next value from the array (2).  This fails the filter, so it gets the next value (3), which passes and goes back to Map, and so on, to Reduce.&lt;/p&gt;

&lt;p&gt;In the end, we've only gone through the array once.&lt;/p&gt;
&lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2008%2f08%2f25%2flists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2008%2f08%2f25%2flists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx" border="0" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator." href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/08/25/lists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx&amp;subject=Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator."&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/25/lists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx&amp;title=Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator." title="Submit Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator. to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/25/lists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx&amp;phase=2" title="Submit Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator. to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/08/25/lists-filter-map-and-reduce-and-the-magic-of-ienumerator.aspx&amp;title=Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator." title="Submit Lists%3a+Filter%2c+Map+and+Reduce+-+and+the+Magic+of+IEnumerator. to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=6014" width="1" height="1"&gt;</description></item><item><title>Dev102's Challenge #13 : Brackets</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/07/21/dev102-s-challenge-13-brackets.aspx</link><pubDate>Mon, 21 Jul 2008 17:18:03 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:5391</guid><dc:creator>James</dc:creator><slash:comments>2</slash:comments><description>
  &lt;p&gt;Many people skipped last week's challenge (like I had planned to).  As it turned out, I was the only blogger to responded.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dev102.com/2008/07/21/a-programming-job-interview-challenge-13-brackets/"&gt;For this week's challenge,&lt;/a&gt; they've gone back to a platform-neutral algorithm question:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Your input is a string which is composed from bracket characters. The allowed characters are:’(', ‘)’, ‘['. ']‘, ‘{’, ‘}’, ‘&amp;lt;’ and ‘&amp;gt;’. Your mission is to determine whether the brackets structure is legal or not.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The simple sentence answer is "use a stack, pushing on an open character, and popping on a close character".  There are a few other things to look out for, but that's the basic concept.  For the actual code, I bypassed any kind of library Stack class, since we wanted the most efficient and for the very limited need of this function, I could jury-rig a faster one out of a char array.  Complexity is speed: O(N), space O(N)&lt;/p&gt;  &lt;pre class="c#"&gt;static bool TestBrackets(string testcase)
{
    // create a very simple stack.  
    // Since we push on open &amp;amp; pop an close, stack need only be half the
    // size of the input string.  The +1 is needed because we only check
    // for too many opens after we've pushed.
    char[] stack = new char[(testcase.Length / 2) +1];
    
    int SP=0;
    foreach(char chr in testcase)
    {
        switch(chr)
        {
            // For each open character, push the close char.
            case '[':
                stack[SP++] = ']';
                break;
            case '&amp;lt;':
                stack[SP++] = '&amp;gt;';
                break;
            case '{':
                stack[SP++] = '}';
                break;
            case '(':
                stack[SP++] = ')';
                break;
                
            case ']':
            case '&amp;gt;':
            case '}':
            case ')':
                // check for stack underflow (too many closes)
                // or a character we weren't expecting (bad  nesting)
                if (SP==0 || stack[--SP] != chr)
                    return false;  
                break;
        }
        // Check for stack overflow (too many opens)
        if (SP==stack.Length)
            return false;
    }
    // Finally, it's good if we've closed everything we've opened.
    return SP==0;
}&lt;/pre&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Dev102%27s+Challenge+%2313+%3a+Brackets" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/07/21/dev102-s-challenge-13-brackets.aspx&amp;subject=Dev102%27s+Challenge+%2313+%3a+Brackets"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/21/dev102-s-challenge-13-brackets.aspx&amp;title=Dev102%27s+Challenge+%2313+%3a+Brackets" title="Submit Dev102%27s+Challenge+%2313+%3a+Brackets to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/21/dev102-s-challenge-13-brackets.aspx&amp;phase=2" title="Submit Dev102%27s+Challenge+%2313+%3a+Brackets to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/21/dev102-s-challenge-13-brackets.aspx&amp;title=Dev102%27s+Challenge+%2313+%3a+Brackets" title="Submit Dev102%27s+Challenge+%2313+%3a+Brackets to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=5391" width="1" height="1"&gt;</description></item><item><title>Dev102's Challenge #12 : Managed &amp; unmanaged</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/07/16/dev102-s-challenge-12-managed-unmanaged.aspx</link><pubDate>Wed, 16 Jul 2008 18:52:52 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:5346</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;My solution(s) for last week's challenge were cited, but, only as an "honorable mention" / "also run".&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dev102.com/2008/07/14/a-programming-job-interview-challenge-12-managed-and-unmanaged/"&gt;This week's challenge&lt;/a&gt; is a different sort of animal.  Not that it is particularly difficult --- actually I suspect it's quite easy --- it's just that it requires a fairly specialize knowledge (Managed Extensions for C++ in this case).  A couple of them in the past required some basic knowledge of .Net &amp;amp; the CLR, but most of the time, the challenge involve a non-platform specific algorithm.&lt;/p&gt;  &lt;p&gt;So, knowing nothing about Managed Extension, I was just going to let this one pass.  But, I happened to run into an old friend (Will Depalo) from my days as a VC++ MVP.  When I went to .Net, I also switched to C#, but he stayed with C++, so I figured he would have some insight.  Reducing the problem to one sentence ("we have a unmanaged class accessing an instance variable of a managed class"), and he immediately  knew the answer ("you'll need to pin it"), and offered some advice ("look up '__pin' in the msdn").  However, didn't realize exactly how good that advice was, as the folk's at DEV102 apparently took the example source code from the __pin article to create the challenge.  So, here's my answer (I love stuff that can be answer via copy'n'paste):&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;pre class="c#"&gt;int main() 
{
   ManagedClass &lt;strong&gt;__pin&lt;/strong&gt; * pMngdClass = new ManagedClass;
   UnmanagedClass* pUnmngd = new UnmanagedClass;
   pUnmngd-&amp;gt;incr(&amp;amp;(pMngdClass-&amp;gt;i));
}&lt;/pre&gt;

&lt;p&gt;The rest is unchanged.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/07/16/dev102-s-challenge-12-managed-unmanaged.aspx&amp;subject=Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/16/dev102-s-challenge-12-managed-unmanaged.aspx&amp;title=Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged" title="Submit Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/16/dev102-s-challenge-12-managed-unmanaged.aspx&amp;phase=2" title="Submit Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/16/dev102-s-challenge-12-managed-unmanaged.aspx&amp;title=Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged" title="Submit Dev102%27s+Challenge+%2312+%3a+Managed+%26amp%3b+unmanaged to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=5346" width="1" height="1"&gt;</description></item><item><title>Dev102's Challenge #11 - Summing Numbers</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/07/08/dev102-s-challenge-11-summing-numbers.aspx</link><pubDate>Tue, 08 Jul 2008 13:55:37 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:5203</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;My answer was acknowledged as correct for last week's challenge.  So, let's see if we can make it two in a row.  &lt;a href="http://www.dev102.com/misc/a-programming-job-interview-challenge-11-summing-numbers/"&gt;This week&lt;/a&gt;: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Given a list of n integers and another integer called m, determine (true / false) if there exist 2 numbers in that list which sum up to m.       &lt;br /&gt;Example: 2,6,4,9,1,12,7 and m=14 -&amp;gt; 2 and 12 sum up to 14, so the answer is true.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This one is rather tricky.  There is no obvious (to me) solution.   I can see three viable methods, each with its own pros &amp;amp; cons.&lt;/p&gt;  &lt;p&gt;Method 1: We'll call this "brute force".  The obvious answer.  We add the values of list[1] and list[2],  then list[1] and list[3], then list[1] and list[4] and so forth, until we reach list[1] and list[ n ].  If we haven't found a match yet, we then move on to adding list[2] to list[3], then list[2] to list[4] etc. In code that would be: &lt;/p&gt;  &lt;pre class="c#"&gt;for(int i= 0; i &amp;lt;N-1; ++i) 
    for(int j= i+1; j &amp;lt; N; ++j) 
       if (list[ i ] + list[ j ] == M) &lt;/pre&gt;

&lt;p&gt;The complexity for this would be Summation N which is officially O(N*N) (although it's closer to O(N*N/2) ).  However, that's the worst case: we can exit early as soon as we find a valid match, making the average case O(N*N/4).  It's also important to note the basic operation that's being repeated (adding two number) is very fast.  Hence, this would be the winner for small values of N (and probably some very large "small values of N").&lt;/p&gt;

&lt;p&gt;Method 2: Which we'll call the "bi-directional search".  This would clearly be the winner, except for it's precondition: start with a sorted list.  Add the first and last elements of the list (list[1] + list[ N ]).  If they equal to goal, we're done. If they are more than the goal, add the first and second-to-last elements(list[1] + list[ N-1 ]).  If they are less, then add the second element to the last element (list[2] + list[ N ]).  Continue this way, moving up from the front when the sum is too low, and down from the back when it's too high until you either find a match, or meet in the middle.  The complexity of this algorithm in O(N) --- for a sorted list.  We're given an unsorted list, which means we'd have to sort it first.  Sorting is, at best, O(N*logN), making the total complexity O(N*logN + N), which I believe is still less than method 1, but the basic task being done for the sort (comparing &lt;em&gt;and&lt;/em&gt;  swapping) is much more expensive than for method 1.  Further, you must complete the sort before you can start the search, so you've taken the big hit before you get a chance for an early exit, making the average case O(NlogN+N/2), so this will win for large values of N, but they'd have to be &lt;em&gt;very&lt;/em&gt; large values of N.&lt;/p&gt;

&lt;p&gt;And, finally, Method 3, which we'll call the "partitioned search". Partition the list into two sublists, one with values less the M/2 and one with values greater than M/2. (The value equal to M/2 can be ignored, as we would need two of them, and we've been assured that the values in the list are unique).  If a solution exists, it will require one from each list; any combination of two from the lower sublist will be two low.  Any two from the upper list will be too high. So we just try every combination of one from each sublist.   In the worst case, that's O((N/2) * (N/2)) or O(N*N/4),  with an average case of O(N*N/8).  To explain with examples: Say we are given a list of 10 numbers.  Method 1 would require 55 additions to try every possibility. If we partitions the list into sublists of 5 &amp;amp; 5, then this method would require only 25 additions.  However, if the numbers break down so that the partitions are 8 &amp;amp; 2, then we'd need only 16 additions.  And, as before, we can exit early as soon as we find a match.  Partitioning can be done in O(N): Start by pointing at the first and last elements, just as in Method 2. Seek forward looking for an element greater than N/2.  When one is found, seek from the end, looking for an element less then N/2. When you have one of each, swap 'em and continue.  When the pointers meet, the list is partitioned in place.  That required only one pass through the list, so the step is O(N), making the total for the average case O(N*N/8 + N).&lt;/p&gt;

&lt;p&gt;Overall, Method 1 wins for small lists, Method 3 for larger lists, and Method 2 for very large lists.  Since memory read/write efficiency is the last bottleneck (how many additions is one swap worth?) the exact point where one method passes another is heavily platform dependant.&lt;/p&gt;

&lt;p&gt;In the back of my mind, two other ideas for other methods keep flowing through. The first tells me that there should be some way to accomplish this through summing the list.  This would be O(N), but I just can't think of a way to make it work.  The other involves building a matrix.  I'm pretty sure I could make that work, in a way that O(N) once the matrix is built, but building it would be greater the O(N) itself, so the whole task would be no faster than the means described above.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Dev102%27s+Challenge+%2311+-+Summing+Numbers" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/07/08/dev102-s-challenge-11-summing-numbers.aspx&amp;subject=Dev102%27s+Challenge+%2311+-+Summing+Numbers"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/08/dev102-s-challenge-11-summing-numbers.aspx&amp;title=Dev102%27s+Challenge+%2311+-+Summing+Numbers" title="Submit Dev102%27s+Challenge+%2311+-+Summing+Numbers to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/08/dev102-s-challenge-11-summing-numbers.aspx&amp;phase=2" title="Submit Dev102%27s+Challenge+%2311+-+Summing+Numbers to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/08/dev102-s-challenge-11-summing-numbers.aspx&amp;title=Dev102%27s+Challenge+%2311+-+Summing+Numbers" title="Submit Dev102%27s+Challenge+%2311+-+Summing+Numbers to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=5203" width="1" height="1"&gt;</description></item><item><title>Dev102's Challenge #10 - The Missing Number</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/07/01/dev102-s-challenge-10-the-missing-number.aspx</link><pubDate>Tue, 01 Jul 2008 18:50:34 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:5140</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;I didn't actually skip last week's challenge for Dev102.  I did write up a solution.  I just forgot to post it.  It was wrong anyway.&lt;/p&gt;  &lt;p&gt;Well, no sense it looking backward... &lt;a href="http://www.dev102.com/net/a-programming-job-interview-challenge-10-the-missing-number/"&gt;This week's&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;Your input is an unsorted list of n numbers ranging from 1 to n+1, all of the numbers are unique, meaning that a number can’t appear twice in that list. ..One of the numbers is missing and you are asked to provide the most efficient method to find that missing number.&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;And Shahar was right, it was rather easy.  We just add up the number we get, and subtract that value from the sum we should have gotten if the missing number wasn't missing.&lt;/p&gt;  &lt;p&gt;int FindMissingNumber(IEnumerable&amp;lt;int&amp;gt; list)    &lt;br /&gt;{     &lt;br /&gt;    int actualSum = 0;     &lt;br /&gt;    int expectedSum = 0;     &lt;br /&gt;    int n = 1;     &lt;br /&gt;    foreach(int i in list)     &lt;br /&gt;    {     &lt;br /&gt;        actualSum += i;     &lt;br /&gt;        expectedSum += n++;     &lt;br /&gt;    }     &lt;br /&gt;    expectedSum += n;     &lt;br /&gt;    return expectedSum - actualSum;     &lt;br /&gt;} &lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Things to note:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The complexity of the algorithm in O(n).   &lt;/li&gt;    &lt;li&gt;I  assured that complexity by using the least powerful collection interface (IEnumerable), and iterated through it only once. &lt;/li&gt;    &lt;li&gt;I summed the expected total manually instead of an formula on list.Count, but for some collection types (such as a linked lists) Count is, by itself, O(n). &lt;/li&gt;    &lt;li&gt;The method will work for an empty sequence, returning 1. &lt;/li&gt; &lt;/ul&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Dev102%27s+Challenge+%2310+-+The+Missing+Number" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/07/01/dev102-s-challenge-10-the-missing-number.aspx&amp;subject=Dev102%27s+Challenge+%2310+-+The+Missing+Number"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/01/dev102-s-challenge-10-the-missing-number.aspx&amp;title=Dev102%27s+Challenge+%2310+-+The+Missing+Number" title="Submit Dev102%27s+Challenge+%2310+-+The+Missing+Number to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/01/dev102-s-challenge-10-the-missing-number.aspx&amp;phase=2" title="Submit Dev102%27s+Challenge+%2310+-+The+Missing+Number to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/07/01/dev102-s-challenge-10-the-missing-number.aspx&amp;title=Dev102%27s+Challenge+%2310+-+The+Missing+Number" title="Submit Dev102%27s+Challenge+%2310+-+The+Missing+Number to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=5140" width="1" height="1"&gt;</description></item><item><title>DEV102's Programming Job Interview Challenge #8</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/06/18/dev102-s-programming-job-interview-challenge-8.aspx</link><pubDate>Wed, 18 Jun 2008 19:23:13 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:5059</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;
    &lt;a href="http://www.dev102.com/net/a-programming-job-interview-challenge-7-coins-of-the-round-table/"&gt;I skipped last week's DEV102 challenge&lt;/a&gt;.   I didn't think my answer was right.  Turns out that it was. I was assuming that it had a limitation that would disqualify it.  I assumed that my solution would only work if you placed the coins in a tight grid with each newly-placed coin touching an existing coin.  As a practical matter, this is true.  It would be virtually impossible to properly place a coin mirroring the freely-placed previous coin without resorting to a tape measure and protractor.  And the placement would have to be exact for it to work.  So I suppressed my solution for lack of practicality, when all they really wanted was a theoretic solution. &lt;/p&gt;  &lt;p&gt;Anyway, onward to &lt;a href="http://www.dev102.com/net/a-programming-job-interview-challenge-8-a-needle-in-a-haystack/"&gt;this week's challenge, #8&lt;/a&gt; (excerpted):&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;You are writing a software component that receives a binary record every 20 millisecond. .... Your component goal is to alert whenever it identifies a specific expression (which is provided at the initialization process) in the stream of records - you are looking for a specific combination of binary records. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The answer is, of course, a &lt;a href="http://en.wikipedia.org/wiki/Finite_State_Machine"&gt;&lt;strong&gt;Finite State Machine&lt;/strong&gt;&lt;/a&gt;. To explain how one works, we need to come up with a example expression to search for.  Let's say these records come it four formats: Type A, type B, type C and Type D, and we are looking a sequence of records in the following pattern: ABACB (if you'd like, you can assume that there are many record types, and Type D represents "any record that's not type A, B or C").  So, we start in state "0". State 0 can be called "looking for first A record".  At state 0, if we find an A record, we move into state 1 ("Find first A, looking for first B").  If we find any other kind of record, we stay in state 0.  This can be expressed in table form as:&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;          &lt;td&gt;Next state&lt;/td&gt;          &lt;td&gt;when &lt;/td&gt;          &lt;td&gt;record &lt;/td&gt;          &lt;td&gt;found&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Current State VV&lt;/td&gt;          &lt;td&gt;A&lt;/td&gt;          &lt;td&gt;B&lt;/td&gt;          &lt;td&gt;C&lt;/td&gt;          &lt;td&gt;D&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;Next when we are in state 1, if we find a B record, we move into state 2, but the other transitions are a bit trickier.  If we find a C or D, we're back to state 0 ("looking for 1st A"), but if we find another A, we have to stay in state 1.  Adding that to our graph:&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;          &lt;td&gt;Next state&lt;/td&gt;          &lt;td&gt;when &lt;/td&gt;          &lt;td&gt;record &lt;/td&gt;          &lt;td&gt;found&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Current State VV&lt;/td&gt;          &lt;td&gt;A&lt;/td&gt;          &lt;td&gt;B&lt;/td&gt;          &lt;td&gt;C&lt;/td&gt;          &lt;td&gt;D&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Ok, now, we are in state 2 ("found AB, looking for 2nd A"), Here if we find an A, we move on to state 3 --- anything else, and we're back to state 0.&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;          &lt;td&gt;Next state&lt;/td&gt;          &lt;td&gt;when &lt;/td&gt;          &lt;td&gt;record &lt;/td&gt;          &lt;td&gt;found&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Current State VV&lt;/td&gt;          &lt;td&gt;A&lt;/td&gt;          &lt;td&gt;B&lt;/td&gt;          &lt;td&gt;C&lt;/td&gt;          &lt;td&gt;D&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;State 3 ("found ABA, looking for C"), is a bit trickier again.  If we find a C, naturally, we move into state 4. And if we find a D, were back into state 0.  But, if we an A, we step back to state 1.  And if we find a B, we step back only to state 2 (ie, we've found "ABAB" and the second "AB" may be the start of the pattern we want.&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;          &lt;td&gt;Next state&lt;/td&gt;          &lt;td&gt;when &lt;/td&gt;          &lt;td&gt;record &lt;/td&gt;          &lt;td&gt;found&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Current State VV&lt;/td&gt;          &lt;td&gt;A&lt;/td&gt;          &lt;td&gt;B&lt;/td&gt;          &lt;td&gt;C&lt;/td&gt;          &lt;td&gt;D&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;At state 4, we enter the endgame.  We're trying to find "ABACB", and so far we're found "ABAC".  If the next record is a B, we have success ("Let loose the pigeons!").  If it's an A, we go to state 1 (as usually). Anything else, and we start over at state 0.&lt;/p&gt;  &lt;div align="center"&gt;   &lt;table cellspacing="0" cellpadding="2" align="center"&gt;       &lt;tr&gt;         &lt;td&gt; &lt;/td&gt;          &lt;td&gt;Next state&lt;/td&gt;          &lt;td&gt;when &lt;/td&gt;          &lt;td&gt;record &lt;/td&gt;          &lt;td&gt;found&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;Current State VV&lt;/td&gt;          &lt;td&gt;A&lt;/td&gt;          &lt;td&gt;B&lt;/td&gt;          &lt;td&gt;C&lt;/td&gt;          &lt;td&gt;D&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;3&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;2&lt;/td&gt;          &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;        &lt;tr&gt;         &lt;td&gt;4&lt;/td&gt;          &lt;td&gt;1&lt;/td&gt;          &lt;td&gt;&lt;strong&gt;*&lt;/strong&gt;&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;          &lt;td&gt;0&lt;/td&gt;       &lt;/tr&gt;     &lt;/table&gt; &lt;/div&gt;  &lt;p&gt;Now, to put this into C# code, we merely need a simple pre-initialize int array following the structure of the chart we just built, and start with our state at 0.&lt;/p&gt;  &lt;p&gt;const int[,] states = new int [5,4]{&lt;/p&gt;  &lt;p&gt;{ 1,0,0,0},&lt;/p&gt;  &lt;p&gt;{1,2,0,0}&lt;/p&gt;  &lt;p&gt;{3,0,0,0}&lt;/p&gt;  &lt;p&gt;{1,2,4,0}&lt;/p&gt;  &lt;p&gt;{1,-1,0,0}&lt;/p&gt;  &lt;p&gt;};&lt;/p&gt;  &lt;p&gt;int state = 0;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Then as a new record comes in, we just determine it's type, and update the state:&lt;/p&gt;  &lt;p&gt;bool MatchFound(Record newRecord)    &lt;br /&gt;{&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;// return 0,1,2 or 3 for record type A,B,C or D respectively.      &lt;br /&gt;// can be assumed to be present, as per the spec.       &lt;br /&gt;int type = GetRecordType(newRecord);&lt;/p&gt;    &lt;p&gt;// Here's where the magic happens      &lt;br /&gt;// just a simple index into an array.       &lt;br /&gt;state = states[state, type];&lt;/p&gt;    &lt;p&gt;return state &amp;lt; 0;    // Report success or failure.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;}&lt;/p&gt;  &lt;p&gt; And that's it.  Total state held between records: one integer.  Total work needed per record to determine pattern: one array lookup and one int comparison. &lt;/p&gt;  &lt;p&gt;And the real beauty of this approach is that if we wanted to look for other patterns &lt;em&gt;at the same time&lt;/em&gt;, it could be done. For example, by just changing the states[] array in the above to this&lt;/p&gt;  &lt;p&gt;const int[,] states = new int [13,4]{&lt;/p&gt;  &lt;p&gt; {1,5,9,0},     &lt;br /&gt; {1,2,9,0},    &lt;br /&gt; {3,6,9,0},    &lt;br /&gt; {1,2,4,0},    &lt;br /&gt; {10,-1,9,0},    &lt;br /&gt; {1, 6, 9, 0},    &lt;br /&gt; {1, 6, 7, 0},    &lt;br /&gt; {10, 5, 8, 0},    &lt;br /&gt; {-2, 5, 9, 0},    &lt;br /&gt; {10,5, 9, 0},  &lt;br /&gt;{1, 11, 9, 0},  &lt;br /&gt;{3, 6, 12, 0},     &lt;br /&gt;{-3, 6, 9, 0} &lt;/p&gt;  &lt;p&gt;};&lt;/p&gt;  &lt;p&gt;Then we'd be able to search for ABACB (as before, found when state = -1) and BBCCA (found when state = -2), plus one more pattern (found when state = -3).&lt;/p&gt;  &lt;h3&gt;Class Homework&lt;/h3&gt;  &lt;p&gt;1) (simple) Try to figure out the third pattern that can be found using that state table. (It's a sequence of 5 records using just A B &amp;amp; C)&lt;/p&gt;  &lt;p&gt;2) (hopefully not possible)  Try to figure out a sequence of records that would cause the state machine to miss one of those patterns (Note: after one is found, we start over at state 0, so it's not intended to find overlapping sequences, such as "ABACBBCCA".  It's find the first but not the second.)&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email DEV102%27s+Programming+Job+Interview+Challenge+%238" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/06/18/dev102-s-programming-job-interview-challenge-8.aspx&amp;subject=DEV102%27s+Programming+Job+Interview+Challenge+%238"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/18/dev102-s-programming-job-interview-challenge-8.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%238" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%238 to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/18/dev102-s-programming-job-interview-challenge-8.aspx&amp;phase=2" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%238 to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/18/dev102-s-programming-job-interview-challenge-8.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%238" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%238 to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=5059" width="1" height="1"&gt;</description></item><item><title>DEV102's Programming Job Interview Challenge #6 </title><link>http://honestillusion.com/blogs/blog_0/archive/2008/06/02/dev102-s-programming-job-interview-challenge-6.aspx</link><pubDate>Mon, 02 Jun 2008 14:16:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4914</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Another week, another C# interview question from the good folk's at Dev102.com -- Although I use the term "good folks" advisedly, as this week they did not even acknowledge the solution I posted for last weeks puzzle (which was both correct, and, I believe, the first blog post about it).&lt;/p&gt;

&lt;p&gt;Anyway, time to move on to &lt;a href="http://www.dev102.com/2008/06/02/a-programming-job-interview-challenge-6-c-games/"&gt;this week's question&lt;/a&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Look at the following Code segment written in C#:&lt;/p&gt;
&lt;div&gt;
&lt;div style="border-style:none;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   1:&lt;/span&gt; ArrayList a = &lt;span&gt;new&lt;/span&gt; ArrayList();&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   2:&lt;/span&gt; ArrayList b = &lt;span&gt;new&lt;/span&gt; ArrayList();&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   3:&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   4:&lt;/span&gt; a.Add(1);&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   5:&lt;/span&gt; b.Add(1);&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   6:&lt;/span&gt; a.Add(2);&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   7:&lt;/span&gt; b.Add(2.0);&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   8:&lt;/span&gt;&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;   9:&lt;/span&gt; Console.WriteLine((a[0] == b[0]));&lt;/pre&gt;
&lt;pre style="border-style:none;margin:0em;padding:0px;overflow:visible;font-size:8pt;width:100%;color:black;line-height:12pt;"&gt;&lt;span&gt;  10:&lt;/span&gt; Console.WriteLine((a[1] == b[1]));&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
What will be typed into the console? And &lt;b&gt;&lt;span style="text-decoration:underline;"&gt;WHY?&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; This one is fairly trivial (They seem to be alternating between difficult and easy questions).  And, as requested, I formulated my answer before typing it into VS (actually, I copy'n'pasted in SnippetCompiler), but the compiler DID confirm the answer I'd already theorized.&lt;/p&gt;
&lt;p&gt;This answer is short enough that we can use the cool "white-on-white; select to see it" trick--- However, RSS feed (and apparently the theme of this blog) seem to ignore the color style, so it's probably visible to you below.. &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;div style="color:white;"&gt;
&lt;p&gt;ArrayList is deep-down, just an object[].  To store an valuetype, like an int or float, in an ArrayList, that value would first have to be boxed.  Each valuetype is boxed separately, in distinct objects, even if they do happen to have the same value. When we get to the WriteLines, we are just performing (object) == (object) (actually, Object.ReferenceEquals(object1, object2); )  ReferenceEquals knows nothing about unboxing.  It just asks, "Are these two references pointing to the exact same object?".  For any two boxed objects, regardless of their value, the answer would be "No".  Hence, both lines print "False".&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;

&lt;p&gt; (select the blank space above)&lt;/p&gt;
&lt;br /&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email DEV102%27s+Programming+Job+Interview+Challenge+%236+" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/06/02/dev102-s-programming-job-interview-challenge-6.aspx&amp;subject=DEV102%27s+Programming+Job+Interview+Challenge+%236+"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/02/dev102-s-programming-job-interview-challenge-6.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%236+" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%236+ to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/02/dev102-s-programming-job-interview-challenge-6.aspx&amp;phase=2" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%236+ to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/06/02/dev102-s-programming-job-interview-challenge-6.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%236+" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%236+ to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4914" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>DEV102's Programming Job Interview Challenge #5</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/05/26/dev102-s-programming-job-interview-challenge-5.aspx</link><pubDate>Mon, 26 May 2008 12:57:20 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4825</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;DEV102 announced the &lt;a href="http://www.dev102.com/2008/05/26/a-programming-job-interview-challenge-5-records-sorting/"&gt;correct responses to last weeks challenge&lt;/a&gt; today.  Since I announced in my blog I got a prominent spot in their post, which is good considering I was one of about 10,000 correct answers and I gave it rather late in the process.  Hopefully, I can improve on both those areas this week.&lt;/p&gt;  &lt;p&gt;Two other things they messages showed.  1) It apparently takes a lot of hunting on this blog to figure out my name (&lt;strong&gt;James Curran&lt;/strong&gt;), and 2) They like it if you hide the solution with HTML tricks.  Unfortunately, while last week's answer was three simple lines of code, this week's so going to be too long to do that effectively.&lt;/p&gt;  &lt;p&gt;Anyway, on to &lt;a href="http://www.dev102.com/2008/05/26/a-programming-job-interview-challenge-5-records-sorting/"&gt;this week's puzzle&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;You are asked to sort a collection of records. The records are stored in a file on the disk, and the size of the file is much bigger than available memory you can work with. Assume a record size is 10 bytes and file size is 1GB. you read and write data to/from disk in units of pages where each page is 1KB big. You have few (less than 10) available pages of physical memory. Assume you are given a method to compare two records.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;&lt;em&gt;How can you sort the records under the described conditions?&lt;/em&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The trick here is to do lots of merge sorts, but we get to that in a minute.  But first to prepare, we have to sort each page, hence, read one page, and sort it's records in memory.  Exactly how it's sorted is irrelevant. A page only has 100 10-byte records so Quicksort is probably overkill -- an Insertion sort is probably best. Then that page is written back to the file in place, and we more to the next one.&lt;/p&gt;  &lt;p&gt;When we finish sorting each page individually, then we begin the Mergesort.  Read two pages and merge them by comparing the first items in each list.  Once the new list fills a page, it's written to a new file.  Repeat this, and eventually, you have half as many segments, each two pages long. Then, do it all over again, merging two-page segments into four page segment.  The trick is, since the two-page segments are already sorted, they can be read in one page at a time, and the output can be written to disk as soon as a page is filled.&lt;/p&gt;  &lt;p&gt;Keep repeating the process, merge four-page segment into eight-page segments, 8-pages into 16-page, etc.  Eventually you will be merging two 512-page segments, and you're done.&lt;/p&gt;  &lt;p&gt;The process own requires three pages of physical memory, and we have a bit more, so some optimizing can be done, but that's essentially it.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email DEV102%27s+Programming+Job+Interview+Challenge+%235" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/05/26/dev102-s-programming-job-interview-challenge-5.aspx&amp;subject=DEV102%27s+Programming+Job+Interview+Challenge+%235"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/26/dev102-s-programming-job-interview-challenge-5.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%235" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%235 to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/26/dev102-s-programming-job-interview-challenge-5.aspx&amp;phase=2" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%235 to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/26/dev102-s-programming-job-interview-challenge-5.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%235" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%235 to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4825" width="1" height="1"&gt;</description></item><item><title>DEV102's Programming Job Interview Challenge #4</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/05/23/dev102-s-programming-job-interview-challenge-4.aspx</link><pubDate>Fri, 23 May 2008 13:58:31 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4766</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;The folks at Dev102.com are offering weekly programming challenges, where they offer questions, and let bloggers post about them.  I meant to write an answer for last week, but never got around to it.  Just as well -- my answer would have been wrong.  SO, let's move on to &lt;a href="http://www.dev102.com/2008/05/19/a-programming-job-interview-challenge-4/"&gt;this week's&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;em&gt;How would you implement the following method: Foo(7) == 17 and Foo(17) == 7. Any other input to that method is not defined so you can return anything you want. Just follow those rules:&lt;/em&gt;&lt;/p&gt;    &lt;ul&gt;     &lt;li&gt;&lt;em&gt;Conditional statements (if, switch, …) are not allowed. &lt;/em&gt;&lt;/li&gt;      &lt;li&gt;&lt;em&gt;Usage of containers (hash tables, arrays, …) are not allowed. &lt;/em&gt;&lt;/li&gt;   &lt;/ul&gt; &lt;/blockquote&gt;  &lt;p&gt;My first thought was, since we can't use conditional statements, to use conditional &lt;em&gt;expressions&lt;/em&gt; instead:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;int foo(int n)      &lt;br /&gt;{      &lt;br /&gt;    return (n==7) ? 17 : (n==17) ? 7 : n;      &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;But clearly, that is just cheating.  (And, besides, it turns out, it's not the best solution).&lt;/p&gt;  &lt;p&gt;My next attempt was to use subtraction to create factors of zero.&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;int foo(int n)      &lt;br /&gt;{      &lt;br /&gt;    return n + (10 * (n-17) * (n-6)) + (-10 * (n-16) * (n-7))  ;      &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;There may be a formula in there that works, but that one doesn't, and before I found it, I stumble upon the &lt;em&gt;correct &lt;/em&gt;solution, which was just sitting there staring me in the face:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;int foo(int n)      &lt;br /&gt;{      &lt;br /&gt;    return 24-n;      &lt;br /&gt;} &lt;/font&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Yep, it's just that simple.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email DEV102%27s+Programming+Job+Interview+Challenge+%234" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/05/23/dev102-s-programming-job-interview-challenge-4.aspx&amp;subject=DEV102%27s+Programming+Job+Interview+Challenge+%234"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/23/dev102-s-programming-job-interview-challenge-4.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%234" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%234 to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/23/dev102-s-programming-job-interview-challenge-4.aspx&amp;phase=2" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%234 to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/05/23/dev102-s-programming-job-interview-challenge-4.aspx&amp;title=DEV102%27s+Programming+Job+Interview+Challenge+%234" title="Submit DEV102%27s+Programming+Job+Interview+Challenge+%234 to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4766" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/dotnet/default.aspx">dotnet</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/csharp/default.aspx">csharp</category></item><item><title>The Need for Common Search Keywords.</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/04/18/the-need-for-common-search-keywords.aspx</link><pubDate>Sat, 19 Apr 2008 00:01:10 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4702</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;if you ever tried to Google something like "how to write a linked list in C#" you may have noticed a problem.  Most search engines have trouble dealing with the pound sign (hash/number sign/octothorpe).  You run into the same problem search for information on ".Net" or "COM" or, for that matter, "Word" or "Access".  &lt;/p&gt;  &lt;p&gt;I hit upon a similar problem a few years ago.  I was trying to set up Microsoft Money to access my bank accounts online.  I went to my banks' websites, but had trouble finding the setup instructions.  Searching a bank's website for "Money" provides many false hits.  Searching for "Microsoft" isn't much better, when every page's footer contains "Best view on Microsoft Internet Explorer 2.0 or later".  Finally, I hit upon the trick:  I searched the site for "Quicken".  The instruction for Microsoft Money were always on the same page as the instruction for Quicken.&lt;/p&gt;  &lt;p&gt;This lead to to the idea to solve the problem I mentioned up top.  Basically, for very technology or product with an inconvenient name, we need a standard searchable keyword, so that whenever someone writes a blog post about a C# topic, if he includes the "csharp" keyword, then someone searching on "csharp" will be able to find it.  Of course, there's two problems with this: first we have to get bloggers to use the keywords and then we have to make sure the seekers know enough to use them.&lt;/p&gt;  &lt;p&gt;Last night I was at a .Net (dotnet) users' group meeting where some folks from MSDN (the website) were soliciting suggestions on improvements.  I presented this suggestion to them, and they were receptive to it, but it really isn't MSDN targeted at them.  The real solution would be to be a list of officially sanctioned keywords coming direct from Microsoft and  promoted by them (so that banks know to put "msmoney" on a page that described the setup for Microsoft Money.&lt;/p&gt;  &lt;p&gt;But in the mean time, I figured I could leverage some of the blogosphere to help push this idea along. &lt;/p&gt;  &lt;p&gt;So, let's start defining the ground rules.&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;A keyword needs to be a single term ("csharp", not "c sharp") &lt;/li&gt;    &lt;li&gt;A keyword needs to uniquely (or very close to it) indicate the subject ("msword", not "word") (If your spell-checker says it's misspelled, that's a good sign) &lt;/li&gt;    &lt;li&gt;A keyword should be a string that is decipherable when written as one word in all lowercase. (so we don't run into the problem of "expertsexchange") &lt;/li&gt;    &lt;li&gt;Unfortunately, there are probably trademark issues to deal with (Microsoft will probably want it to be "microsoftword" instead of "msword") &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So, to start us off, here are a few I thought up.  Be sure to include them in any blog post (in the body or tags or header) on the subject.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;"C#" = "csharp" &lt;/li&gt;    &lt;li&gt;"C++" = "cplusplus" &lt;/li&gt;    &lt;li&gt;".Net" = "dotnet" &lt;/li&gt;    &lt;li&gt;"ASP.NET" = "aspnet"  (or should we go for "aspdotnet"?) &lt;/li&gt;    &lt;li&gt;"ASP.NET Ajax" = "aspnetajax" &lt;/li&gt;    &lt;li&gt;"LINQ" = "linq" (that was easy -- maybe Microsoft is learning). &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt; &lt;/p&gt; &lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2008%2f04%2f18%2fthe-need-for-common-search-keywords.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2008%2f04%2f18%2fthe-need-for-common-search-keywords.aspx" border="0" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email The+Need+for+Common+Search+Keywords." href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/04/18/the-need-for-common-search-keywords.aspx&amp;subject=The+Need+for+Common+Search+Keywords."&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/18/the-need-for-common-search-keywords.aspx&amp;title=The+Need+for+Common+Search+Keywords." title="Submit The+Need+for+Common+Search+Keywords. to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/18/the-need-for-common-search-keywords.aspx&amp;phase=2" title="Submit The+Need+for+Common+Search+Keywords. to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/18/the-need-for-common-search-keywords.aspx&amp;title=The+Need+for+Common+Search+Keywords." title="Submit The+Need+for+Common+Search+Keywords. to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4702" width="1" height="1"&gt;</description></item><item><title>How can I easily log a message to a file for debugging purposes?</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/04/16/how-can-i-easily-log-a-message-to-a-file-for-debugging-purposes.aspx</link><pubDate>Wed, 16 Apr 2008 14:06:47 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4660</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Today, either Bloglines.com or blogs.MSDN.com blinked, and suddenly I'm seeing old entries on the 'C# Frequently Asked Questions' blog as new.  No one has posted anything there in over two years. &lt;/p&gt; &lt;p&gt;Anyway, reading the most recent message, it offered a method for logging a message.  Now, ignoring side debates over log4net vs nLog vs. the Event log vs. Trace, and just concentrating on the code post --- It's not very good.  Look for yourself (then come back here)  &lt;a title="http://blogs.msdn.com/csharpfaq/archive/2006/03/27/562555.aspx" href="http://blogs.msdn.com/csharpfaq/archive/2006/03/27/562555.aspx"&gt;http://blogs.msdn.com/csharpfaq/archive/2006/03/27/562555.aspx&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Despite being written by a C# MVP (*), it shows a lack of understanding of basic .Net library features, and well as C#.  So, I figured, I'd rewrite it.  I limited myself to taking what's there and fixing it instead of going an entirely different way (ie, log4net vs nLog vs etc).  Here's the revised code:&lt;/p&gt; &lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;&lt;pre class="alt"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; LogMessageToFile(&lt;span class="kwrd"&gt;string&lt;/span&gt; msg)&lt;/pre&gt;&lt;pre&gt;{&lt;/pre&gt;&lt;pre class="alt"&gt;    &lt;span class="kwrd"&gt;string&lt;/span&gt; logFilepath = Path.Combine(Environment.GetEnvironmentVariable(&lt;span class="str"&gt;"TEMP"&lt;/span&gt;),&lt;span class="str"&gt;"My Log File.txt"&lt;/span&gt;);&lt;/pre&gt;&lt;pre&gt;    &lt;span class="kwrd"&gt;using&lt;/span&gt; (StreamWriter sw = File.AppendText(logFilepath))&lt;/pre&gt;&lt;pre class="alt"&gt;    {&lt;/pre&gt;&lt;pre&gt;        &lt;span class="kwrd"&gt;string&lt;/span&gt; logLine = String.Format(&lt;span class="str"&gt;"{0:G}: {1}."&lt;/span&gt;, DateTime.Now, msg);&lt;/pre&gt;&lt;pre class="alt"&gt;        sw.WriteLine(logLine);&lt;/pre&gt;&lt;pre&gt;    }&lt;/pre&gt;&lt;pre class="alt"&gt;}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;A few years ago, I bought a number of books, all with the title of same variation of "C# Cookbook".  Again, a lot of bad code.  I've been meaning to start a series of articles about revising them.....&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;(*) Years ago, I was one of the very first C++ MVPs.  After ten years, I was dropped from the program.  Since then I've tried to become a C# MVP, without any luck. I'm beginning to get bitter about it.  ;-)&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/04/16/how-can-i-easily-log-a-message-to-a-file-for-debugging-purposes.aspx&amp;subject=How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/16/how-can-i-easily-log-a-message-to-a-file-for-debugging-purposes.aspx&amp;title=How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f" title="Submit How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/16/how-can-i-easily-log-a-message-to-a-file-for-debugging-purposes.aspx&amp;phase=2" title="Submit How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/04/16/how-can-i-easily-log-a-message-to-a-file-for-debugging-purposes.aspx&amp;title=How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f" title="Submit How+can+I+easily+log+a+message+to+a+file+for+debugging+purposes%3f to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4660" width="1" height="1"&gt;</description><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Code/default.aspx">Code</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/.Net/default.aspx">.Net</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/Programming/default.aspx">Programming</category><category domain="http://honestillusion.com/blogs/blog_0/archive/tags/MVP/default.aspx">MVP</category></item><item><title>Predictions</title><link>http://honestillusion.com/blogs/blog_0/archive/2008/03/25/predictions.aspx</link><pubDate>Wed, 26 Mar 2008 03:16:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4583</guid><dc:creator>James</dc:creator><slash:comments>2</slash:comments><description>
  &lt;P&gt;My friend Chris is, like me, a staunch Democratic.  Unlike me, he's also an incredible pessimist.  In 2006, he made what he called his "optimistic" prediction for the midterm election: The democrats would gain 3 Senate seat, 10 house seats, and 3 governorships. (Actual results: Democrats gained 6 Senate seats, 30 House seats, and 6 Governors).  I didn't make any predictions then.&lt;/P&gt;
&lt;P&gt;Since another election is looming, he's made is his predictions for the elections, and in the interest of balance, I've made mine.  And, since I'm probably going to lose the napkin I wrote them down on before November, I figured I'd record them here, so I know where I can find them, after the election.&lt;/P&gt;
&lt;P&gt;So, here goes:&lt;/P&gt;
&lt;H2&gt;Chris's Predictions&lt;/H2&gt;
&lt;P&gt;Republicans will gain 8 house seats, 2 governorship while the Senate will stay the same.  McCain will become president, winning 36 states.&lt;/P&gt;
&lt;H2&gt;James's Predictions:&lt;/H2&gt;
&lt;P&gt;Democrats will gain 10 House seats, 4 Senate seats, and 2 governorships.  The democrat will win the White House, winning 20 (mostly large) states.&lt;/P&gt;
&lt;P&gt;Neither of us ventured a prediction on who will be the Democratic candidate.  Chris wants Obama, because he things he has the best chance of winning.  I want Clinton, because I think she'll be the best president.&lt;/P&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Predictions" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2008/03/25/predictions.aspx&amp;subject=Predictions"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2008/03/25/predictions.aspx&amp;title=Predictions" title="Submit Predictions to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/03/25/predictions.aspx&amp;phase=2" title="Submit Predictions to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2008/03/25/predictions.aspx&amp;title=Predictions" title="Submit Predictions to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4583" width="1" height="1"&gt;</description></item><item><title>Joins - LINQ's critical, overlooked feature.</title><link>http://honestillusion.com/blogs/blog_0/archive/2007/12/18/joins-linq-s-critical-overlooked-feature.aspx</link><pubDate>Wed, 19 Dec 2007 01:35:00 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4569</guid><dc:creator>James</dc:creator><slash:comments>1</slash:comments><description>
  &lt;p&gt;As i was planning my rewrite of NJTheater.com I looked at a couple different Object-Relationship Mappers (mostly code generators which examined a database schema and produced one class per table to read and write rows to it.  All seemed particularly lacking because of this.  Then I find LINQ, and realized that I had found exact the system I was looking for.&lt;/p&gt;  &lt;p&gt;To understand the problem, consider the main page of NJTheater.com, which on your average day looks something like this:&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;The Blue Bird (11/27/2007 - 12/31/2007)      &lt;br /&gt;by Shakespeare Theatre of New Jersey (at F.M. Kirby Theater in Madison) &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Doubt (11/27/2007 - 12/23/2007)      &lt;br /&gt;by George Street Playhouse (at George Street Playhouse in New Brunswick) &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Seussical: The Musical (12/1/2007 - 12/23/2007)      &lt;br /&gt;by Bergen County Players (at Little Firehouse Theatre in Oradell) &lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;The database is heavily normalized, so to retrieve that data, I need an SQL query that looks like this: &lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Select pl.Title, p.StartDate, p.EndDate, t.Name, v.Name, v.City      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;From Productions P      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;inner join Troupes T on p.TroupeID = t.TroupeID      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;inner join Venues V on p.VenueID = v.VenueID      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;inner join Plays pl on p.PlayID = pl.PlayID      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;where p. FirstDate &amp;gt;= GetDate() and p.FirstDate &amp;lt;= GetDate() + 7&lt;/font&gt;&lt;/p&gt; p&amp;gt;The actual query is a bit more complicated, but we'll go with that for now.   &lt;p&gt;That's one SQL statement which returns 3 to 30 rows (depending on the week) which holds all the data to be displayed.&lt;/p&gt;  &lt;p&gt;Which brings us to the problem.  Most ORM systems would have me translate that into something like&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;ProductionList productions = db.Productions.WhereBetween("StartDate", datetime.Now, DateTime.Now.AddDay(7));&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;And then use it like this:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;foreach (Production prod in productions)      &lt;br /&gt;     Print prod.Play.Title +" ( " +prod.StartDate + " - " + prod.EndDate + ")"       &lt;br /&gt;     Print "by " + prod.Troupe.Name " (at " + prod.Venue.Name + " in "+ prod.Venue.City +")"&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;(I made that syntax up, but it's fairly typical.)&lt;/p&gt;  &lt;p&gt;Which brings us to the problem.  The first line would generate one SQL query  which would look something like this:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Select p.*      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;From Productions P      &lt;br /&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;where p. FirstDate &amp;gt;= GetDate() and p.FirstDate &amp;lt;= GetDate() + 7&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;and would return about 15 records.  However, when it goes into the loop to render the actual page, then we sudden have a lot more SQL queries:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;Select title from play where playid = 123;      &lt;br /&gt;select name from troupe where troupeid=131;       &lt;br /&gt;select name, city  from venue where venueid=102;&lt;/font&gt;&lt;/p&gt; &lt;font face="Courier New"&gt;Select title from play where playid = 143;    &lt;br /&gt;select name from troupe where troupeid=134;     &lt;br /&gt;select name, city  from venue where venueid=202;&lt;/font&gt;   &lt;p&gt;etc etc.  We go from one query returning N rows, to 3N+1 queries.  We've just massively increased the amount of work needed to be done to render the front (and most popular)page on the web site.&lt;/p&gt;  &lt;p&gt;Which brings us back to LINQ.    The LINQ query I use is:&lt;/p&gt;  &lt;p&gt;var productions = from prod in db.Productions    &lt;br /&gt;        where prod.StartDate &amp;lt; DateTime.Now.AddDays(7)     &lt;br /&gt;        &amp;amp;&amp;amp; prod.StartDate &amp;gt; DateTime.Now     &lt;br /&gt;        orderby prod.Play.Title     &lt;br /&gt;        select new  &lt;br /&gt;               {     &lt;br /&gt;                   Title = prod.Play.Title,     &lt;br /&gt;                   Troupe = prod.Troupe.Name,     &lt;br /&gt;                   Venue = prod.Venue.Name,     &lt;br /&gt;                   City = prod.Venue.City,     &lt;br /&gt;                   StartDate = prod.StartDate ,     &lt;br /&gt;                   EndDate = prod.EndDate &lt;/p&gt;  &lt;p&gt;               };&lt;/p&gt; &lt;font face="Courier New"&gt;foreach (Production prod in productions)    &lt;br /&gt;     Print prod.Title +" ( " +prod.StartDate + " - " + prod.EndDate + ")"     &lt;br /&gt;     Print "by " + prod.Troupe " (at " + prod.Venue + " in "+ prod.City +")"&lt;/font&gt;   &lt;p&gt;The first thing you should notice is that except for the verbose select clause, this syntax is rather close to the one for my theoretic ORM.&lt;/p&gt;  &lt;p&gt;A more subtle difference is that I've slipped in a orderby based on one of the JOINs, which I'm not sure how I'd  do in the ORM.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;But the most important thing you should notice is that this will produce a single SQL statement, one that is virtual identical to the hand-crafted one I started this article with.&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;font face="ver"&gt;If you don't believe me, here's output from LINQPad:&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;SELECT [t].[Title], [t2].[ Name ] AS [Troupe], [t3].[ Name ] AS [Venue], [t3].[City],    &lt;br /&gt;       [t0].[FirstPerformance] AS [StartDate], [t0].[LastPerformance] AS [EndDate]     &lt;br /&gt;FROM [Productions] AS [t0]     &lt;br /&gt;INNER JOIN [Plays] AS [t1] ON [t1].[PlayID] = [t0].[PlayID]     &lt;br /&gt;INNER JOIN [Troupes] AS [t2] ON [t2].[TroupeID] = [t0].[TroupeID]     &lt;br /&gt;LEFT OUTER JOIN [Venues] AS [t3] ON [t3].[VenueID] = [t0].[VenueID]     &lt;br /&gt;WHERE ([t0].[FirstPerformance] &amp;lt; @p0) AND ([t0].[LastPerformance] &amp;gt; @p1)     &lt;br /&gt;ORDER BY [t1].[Title]     &lt;br /&gt;    &lt;br /&gt;-- @p0: Input DateTime (Size = 0; Prec = 0; Scale = 0) [12/25/2007 7:00:54 PM]     &lt;br /&gt;-- @p1: Input DateTime (Size = 0; Prec = 0; Scale = 0) [12/18/2007 7:00:54 PM]     &lt;br /&gt;-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.21022.8     &lt;br /&gt;&lt;/p&gt; &lt;a href="http://www.dotnetkicks.com/kick/?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2007%2f12%2f18%2fjoins-linq-s-critical-overlooked-feature.aspx"&gt;&lt;img alt="kick it on DotNetKicks.com" src="http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=http%3a%2f%2fhonestillusion.com%2fblogs%2fblog_0%2farchive%2f2007%2f12%2f18%2fjoins-linq-s-critical-overlooked-feature.aspx" border="0" /&gt;&lt;/a&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email Joins+-+LINQ%27s+critical%2c+overlooked+feature." href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2007/12/18/joins-linq-s-critical-overlooked-feature.aspx&amp;subject=Joins+-+LINQ%27s+critical%2c+overlooked+feature."&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/18/joins-linq-s-critical-overlooked-feature.aspx&amp;title=Joins+-+LINQ%27s+critical%2c+overlooked+feature." title="Submit Joins+-+LINQ%27s+critical%2c+overlooked+feature. to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/18/joins-linq-s-critical-overlooked-feature.aspx&amp;phase=2" title="Submit Joins+-+LINQ%27s+critical%2c+overlooked+feature. to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/18/joins-linq-s-critical-overlooked-feature.aspx&amp;title=Joins+-+LINQ%27s+critical%2c+overlooked+feature." title="Submit Joins+-+LINQ%27s+critical%2c+overlooked+feature. to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4569" width="1" height="1"&gt;</description></item><item><title>My Second CodePlex Project : State Theater</title><link>http://honestillusion.com/blogs/blog_0/archive/2007/12/17/my-second-codeplex-project-state-theater.aspx</link><pubDate>Mon, 17 Dec 2007 17:35:09 GMT</pubDate><guid isPermaLink="false">0c240a87-1bdc-4d60-96f7-7d0531c1460e:4568</guid><dc:creator>James</dc:creator><slash:comments>0</slash:comments><description>
  &lt;p&gt;Well, as I promised months ago, I've created my second CodePlex project.  Actually, I created months ago, while this site was down (as the artist I am, I think I'll refer to that as it's "black period"), But now that I'm back, I guess it's time to make a formal announcement.&lt;/p&gt; &lt;p&gt;The &lt;a href="http://www.codeplex.com/StateTheater" target="_blank"&gt;State Theater Project&lt;/a&gt; is my attempt to completely rewrite my main web site (&lt;a href="http://www.njtheater.com"&gt;www.njtheater.com&lt;/a&gt;).  The original (still at that web address for now) was written by me, mostly 10 years ago, in classic ASP.   The ASP pages are almost purely presentational -- they just read stuff from the database and display it on the screen, using a lot of questionable techniques (in some spots, I was formatting HTML in SQL select statements)&lt;/p&gt; &lt;p&gt;I added a few pages "recently" (i.e. within the last five years) in C#/ASP.NET.  These were interactive, and mostly hidden from view of most users.  Only registered users having certain roles saw them, and those pages allow those users to enter updates directly into the web site's database.&lt;/p&gt; &lt;p&gt;However, most of the theater companies just emailed the details of the shows, and hoped I found time to enter them.  (Especially, since most of the important info can't be entered via the web pages, so only I could do it).&lt;/p&gt; &lt;p&gt;The main problem is that I needed a Ajax-based drop-down listbox, because the database is heavily normalized, so when someone entered "William Shakespeare", I needed to know they really meant Person ID#74.  &lt;/p&gt; &lt;p&gt;Some years ago I paid good cash for one such control, which allowed me to get the few pages working that I did.  But it was rather limited (I still don't think it works with Firefox) and has a spotty update &amp;amp; support history and in general wasn't letting me advance.  When the Ajax craze start two years ago, a number of new, better and &lt;strong&gt;free&lt;/strong&gt; DDL controls became available, so I started to look into a new approach.&lt;/p&gt; &lt;p&gt;Originally, I planned on a complete ASP.NET approach, and started to work on that in the spring of 2006.  The first problem I had was my membership/roles data.  Membership was based on the FORUM_MEMBER table from Snitz Forums, which I had been using for the Forums section of the site.  &lt;/p&gt; &lt;p&gt;Now, Snitz is a fine forums packages, but it's also Classic ASP, but is getting kinda old -- it hasn't had a major update in year, and in fact, has had only two minor updates (most fixing security breaches) in the last 2 1/2 years.  But mostly, the problem with it is that it's membership system was intended to be used strictly for the forums themselves, and any allowance for it to be used as a general web site membership subsystem were clearly an afterthought.&lt;/p&gt; &lt;p&gt;What I wanted to do was to use the ASP.NET membership system that came with v2.0.  The trouble here was that Snitz stored passwords as a one-way hash.  There is no way to convert them back into the original password.  Which means that there's no way to more the account to the new database structure.  I'd have to assign new passwords to my 2000+ users.  That's wasn't workable.&lt;/p&gt; &lt;p&gt;Ah, but the ASP.NET membership system works on the provider model.  The SqlMembershipProvider that comes with 2.0 is just one example.  I could just write my own provider which used the existing table structure as a backing store.  I began this project in the summer of 2006. &lt;/p&gt; &lt;p&gt;The next problem was my laptop.  I was doing most of the work my lunch hour and one the train to &amp;amp; from work.  But my laptop was excessively old. (It was three years old when I bought it on eBay, and that was three years earlier).  It was taking much of the train trip just to awake from hibernation. I was just days away from buying a brand-spanking new laptop when I completely new problem arose -- I was laid off from my job.&lt;/p&gt; &lt;p&gt;Now, I bounced back from that fairly quickly --- but the time out of work chewed up the saving I was planning on using to buy the laptop--- but the new job gave me a laptop --- but the new job took away train ride to work (I had to drive there), and because I was consulting, I had to take short lunches.&lt;/p&gt; &lt;p&gt;Anyway, seven months later, that contract ended, and a new one began -- back on the train to NYC, and this time it was one long ride instead of two short ones, so I could get more done.  After a few weeks of saving, I finally got that new laptop, and I could finally complete the SnitzMembershipProvider which became the first CodePlex project, only a year after I had started it.&lt;/p&gt; &lt;p&gt;And so then I finally began the work on revising the web site. But, by this time, I'd become fascinated with &lt;a href="http://www.castleproject.org/monorail" target="_blank"&gt;Castle Monorail&lt;/a&gt; and LINQ, and decided to try those for the web site.   Plus, as much of the graphic design was mixed with the code, I tried for a more generic, skinnable approach of putting everything in &amp;lt;DIV&amp;gt;s and using CSS for styling it.  Finally, I'm trying to make it generic enough so that some other group in a different state could take the code and create there own similar web site for their state -- with a completely different look, just by changing the CSS file.&lt;/p&gt; &lt;p&gt;For the Ajax work, and pretty much all the interactive forms, I'm using the &lt;a href="http://extjs.com/" target="_blank"&gt;Ext.Js&lt;/a&gt; library, except for large textboxes, for which I'm using &lt;a href="http://tinymce.moxiecode.com/" target="_blank"&gt;TinyMCE&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;You can see what I've done so far as &lt;a href="http://www.NJTheater.org"&gt;www.NJTheater.org&lt;/a&gt;.&lt;/p&gt;
&lt;div class = "shareblock"&gt;&lt;strong&gt;Share this post:&lt;/strong&gt; &lt;a title="Email My+Second+CodePlex+Project+%3a+State+Theater" href = "mailto:?body=Thought you might like this: http://honestillusion.com/blogs/blog_0/archive/2007/12/17/my-second-codeplex-project-state-theater.aspx&amp;subject=My+Second+CodePlex+Project+%3a+State+Theater"&gt;Email it!&lt;/a&gt; | &lt;a href = "http://del.icio.us/post?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/17/my-second-codeplex-project-state-theater.aspx&amp;title=My+Second+CodePlex+Project+%3a+State+Theater" title="Submit My+Second+CodePlex+Project+%3a+State+Theater to del.icio.us" &gt;bookmark it!&lt;/a&gt; | &lt;a href = "http://www.digg.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/17/my-second-codeplex-project-state-theater.aspx&amp;phase=2" title="Submit My+Second+CodePlex+Project+%3a+State+Theater to digg.com"&gt;digg it!&lt;/a&gt; | &lt;a href = "http://reddit.com/submit?url=http://honestillusion.com/blogs/blog_0/archive/2007/12/17/my-second-codeplex-project-state-theater.aspx&amp;title=My+Second+CodePlex+Project+%3a+State+Theater" title="Submit My+Second+CodePlex+Project+%3a+State+Theater to reddit.com"&gt;reddit!&lt;/a&gt;&lt;/div&gt;&lt;img src="http://honestillusion.com/aggbug.aspx?PostID=4568" width="1" height="1"&gt;</description></item></channel></rss>
