<?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/blog_0/default.aspx</link><description>Where Lightning's still the biggest thrill of all....</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><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><comments>http://honestillusion.com/blogs/blog_0/comments/7914.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7914</wfw:commentRss><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; &lt;/p&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;Nexy, 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;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; &lt;/p&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; &lt;/p&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><comments>http://honestillusion.com/blogs/blog_0/comments/7882.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7882</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/7881.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7881</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/7879.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7879</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/7877.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7877</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/7874.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7874</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/7873.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7873</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/7872.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7872</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/7859.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7859</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/7811.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=7811</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/6912.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=6912</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/6416.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=6416</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/6347.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=6347</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/6345.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=6345</wfw:commentRss><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><comments>http://honestillusion.com/blogs/blog_0/comments/6106.aspx</comments><wfw:commentRss>http://honestillusion.com/blogs/blog_0/commentrss.aspx?PostID=6106</wfw:commentRss><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></channel></rss>