<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-15487481</id><updated>2012-03-15T16:34:33.199-04:00</updated><category term='windows7phone'/><category term='technology'/><category term='tools'/><category term='admin'/><category term='refactoring'/><category term='web'/><category term='development'/><category term='music'/><category term='algorithm'/><category term='links'/><category term='test'/><category term='quickfix'/><category term='archeology'/><category term='agile'/><category term='software'/><category term='telephony'/><category term='rss'/><category term='history'/><category term='fun'/><category term='testing'/><category term='continuousintegration'/><category term='reader'/><category term='noise'/><category term='hardware'/><category term='nhibernate'/><category term='google'/><title type='text'>MackelWhat?</title><subtitle type='html'>seeking loopholes in the law of unintended consequences...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-15487481.post-4584722277768879263</id><published>2010-10-04T12:22:00.000-04:00</published><updated>2010-10-04T12:22:14.837-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='windows7phone'/><title type='text'>Windows 7 Phone Development</title><content type='html'>Well, I'd like to win a free phone, so as &lt;a href="http://www.hanselman.com/blog/WINAFREEPhoneWithLikeNOEffortAndAttendTheWindowsPhone7DeveloperLaunch.aspx"&gt;Scott Hanselman&lt;/a&gt; says on his website, here's my attempt to win a phone with almost no effort ;-)&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.msdnevents.com/wp7devlaunch/"&gt;&lt;img border="0" src="http://2.bp.blogspot.com/_r267morZGNM/TKn-7JlaEJI/AAAAAAABsks/kdmvgqpBnAM/s1600/wp7_signature_banner_sm.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Here's to winning.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-4584722277768879263?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/4584722277768879263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=4584722277768879263&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/4584722277768879263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/4584722277768879263'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2010/10/windows-7-phone-development.html' title='Windows 7 Phone Development'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_r267morZGNM/TKn-7JlaEJI/AAAAAAABsks/kdmvgqpBnAM/s72-c/wp7_signature_banner_sm.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-566347364322563449</id><published>2009-03-27T11:10:00.004-04:00</published><updated>2009-03-27T11:34:28.679-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='telephony'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><title type='text'>Google Voice</title><content type='html'>I'm setup with Google Voice now.  It's a very nice service.  I think it's going to radically transform how the phone works.  As a simple example, try giving me a call with the enclosed Google Voice gadget I've just put in the side panel.  It will call your phone, then connect back to me via their servers.  A nice way to provide connectivity without having to advertise your number.  I can't wait to see the pricing for this service.  It obsoletes normal voicemail (since it provides a decent transcribed version of the voice mail).  The management of voicemail is the same as email is in gmail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-566347364322563449?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/566347364322563449/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=566347364322563449&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/566347364322563449'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/566347364322563449'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2009/03/google-voice.html' title='Google Voice'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-4937751941875221999</id><published>2009-01-07T13:19:00.002-05:00</published><updated>2009-01-07T13:41:15.238-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='nhibernate'/><title type='text'>NHibernate.MappingException: Unknown entity class</title><content type='html'>&lt;p class="MsoNormal"&gt;&lt;span style=";font-family:Arial;font-size:100%;"  &gt;I spent an hour finding and fixing a problem that should have been much faster last night.  This post is to make sure I don't forget what I learned :-)  &lt;span style=""&gt;&lt;/span&gt;I’m experimenting with NHibernate, and specifically the FluentNHibernate functionality.&lt;span style=""&gt;  &lt;/span&gt;I was trying to get a test running, and I kept getting the error: “&lt;/span&gt;&lt;span style=";font-family:&amp;quot;;font-size:100%;"  &gt;NHibernate.MappingException: Unknown entity class BLAH&lt;/span&gt;&lt;span style=";font-family:Arial;font-size:100%;"  &gt;” (where BLAH was the persistable class I was building) during the mapping setup of the test.&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style=";font-family:Arial;font-size:100%;"  &gt;I dug all over the place (assuming I had a typo in a namespace or some other stupid thing like that), and couldn’t find the problem until I ran Reflector on the assembly that held the mappings. &lt;span style=""&gt; &lt;/span&gt;Only then did I notice that the mapping class was grayed out (in other words, I’d failed to make the map public -- in fact when I created the class, I failed to set accessibility at all so it was set to the default accessibility of &lt;span style="font-family:courier new;"&gt;internal&lt;/span&gt;). &lt;span style=""&gt; &lt;/span&gt;Once I set access to the class to &lt;span style="font-family:courier new;"&gt;public&lt;/span&gt;, the test ran as expected, and I was able to finish setting things up.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style=";font-family:Arial;font-size:100%;"  &gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="font-family: courier new;"&gt;&lt;span style=";font-size:100%;" &gt;&lt;span style=";color:red;" &gt;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; &lt;span style=";color:blue;" &gt;class&lt;/span&gt; &lt;span style="color: rgb(43, 145, 175);"&gt;BLAHMap&lt;/span&gt; : &lt;span style="color: rgb(43, 145, 175);"&gt;ClassMap&lt;/span&gt;&lt;&lt;span style="color: rgb(43, 145, 175);"&gt;BLAH&lt;/span&gt;&gt; {&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p style="font-family: courier new;font-family:courier new;" class="MsoNormal" &gt;&lt;span style="font-size:100%;"&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public&lt;/span&gt; BLAH() {...}&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style=""&gt;&lt;span style=";font-family:&amp;quot;;font-size:100%;"  &gt;&lt;span style="font-family: courier new;font-family:courier new;" &gt;  &lt;/span&gt;&lt;span style="font-family: courier new;font-family:courier new;" &gt;&amp;nbsp;&amp;nbsp;}&lt;/span&gt;&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style=";font-family:Arial;font-size:100%;"  &gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style=";font-family:Arial;font-size:100%;"  &gt;I’m sure this is in the docs somewhere, but the bottom line is: don’t forget to make mapping classes public. &lt;span style=""&gt;  &lt;/span&gt;The other takeaway from this is that it’s good to have multiple ways of looking at something – reflector showed the problem because it had a different way of displaying information that wasn’t visible just by looking at the editor.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;span style=";font-family:Arial;font-size:100%;"  &gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-4937751941875221999?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/4937751941875221999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=4937751941875221999&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/4937751941875221999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/4937751941875221999'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2009/01/nhibernatemappingexception-unknown.html' title='NHibernate.MappingException: Unknown entity class'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-5164869103807756709</id><published>2008-06-10T17:25:00.002-04:00</published><updated>2008-06-10T19:43:15.993-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reader'/><category scheme='http://www.blogger.com/atom/ns#' term='admin'/><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><category scheme='http://www.blogger.com/atom/ns#' term='test'/><title type='text'>Live Writer Test Post</title><content type='html'>&lt;p&gt;Microsoft just released a technical preview of the newest version of Windows Live Writer.&amp;#160; Since this has a couple of features I’ve really been looking for, I’m going to try it out.&amp;#160; If it works well, I’ll start using it for all my (very infrequent) posts.&amp;#160; I apologize in advance for all the random content – I just want to try out the new features to make sure they work how I want them to.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Here’s a picture:&lt;/strong&gt; &lt;/p&gt;  &lt;p align="center"&gt;&lt;a href="http://lh5.ggpht.com/mmackelprang/SE7xIL96ulI/AAAAAAAAAEQ/Yv8Ci9NwJhI/s1600-h/IMG_2049%5B8%5D.jpg"&gt;&lt;img title="IMG_2049" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="180" alt="IMG_2049" src="http://lh6.ggpht.com/mmackelprang/SE7xJEUrBNI/AAAAAAAAAEU/p5InhZAVYBQ/IMG_2049_thumb%5B6%5D.jpg?imgmax=800" width="240" border="0" /&gt;&lt;/a&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Here’s a table:&lt;/strong&gt;&lt;/p&gt;  &lt;table cellspacing="0" cellpadding="2" width="400" border="1"&gt;&lt;tbody&gt;     &lt;tr&gt;       &lt;td valign="top" width="200"&gt;&lt;strong&gt;Heading 1&lt;/strong&gt;&lt;/td&gt;        &lt;td valign="top" width="200"&gt;&lt;strong&gt;Heading 2&lt;/strong&gt;&lt;/td&gt;     &lt;/tr&gt;      &lt;tr&gt;       &lt;td valign="top" width="200"&gt;Row 1 Column 1&lt;/td&gt;        &lt;td valign="top" width="200"&gt;Row 1 Column 2&lt;/td&gt;     &lt;/tr&gt;   &lt;/tbody&gt;&lt;/table&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Here’s a map (our old house in Tucson):&lt;/strong&gt;&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:84E294D0-71C9-4bd0-A0FE-95764E0368D9:b436f341-d1e5-4e2e-b8ef-2c35c065b91d" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;a href="http://maps.live.com/default.aspx?v=2&amp;amp;cp=pcr9715rbb92&amp;amp;lvl=1&amp;amp;style=o&amp;amp;scene=7965695&amp;amp;mkt=en-US&amp;amp;FORM=LLWR" id="map-22b4d8d9-5000-4a2d-be29-54252c1bd9f0" alt="Click to view this map on Live.com" title="Click to view this map on Live.com"&gt;&lt;img src="http://lh6.ggpht.com/mmackelprang/SE7xO36gjwI/AAAAAAAAAEY/9DeAuECwSqo/map-a3173047cba5.jpg?imgmax=800" width="320" height="240" alt="Map image"&gt;&lt;/a&gt;&lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Here is a video:&lt;/strong&gt;&lt;/p&gt;  &lt;div class="wlWriterSmartContent" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:8a5b3155-d425-4e70-ad7c-ccdbb92ef90f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px"&gt;&lt;div id="72e94d2c-9ca6-4109-b022-66fba309e262" style="margin: 0px; padding: 0px; display: inline;"&gt;&lt;div&gt;&lt;a href="http://video.msn.com/video.aspx?vid=8a96c975-1668-4ea4-8094-25d3ea7f049d&amp;amp;from=writer" target="_new"&gt;&lt;img src="http://lh6.ggpht.com/mmackelprang/SE7xPrDp1nI/AAAAAAAAAEc/uUF_lJfZub8/video183c8beb9823%5B3%5D.jpg?imgmax=800" galleryimg="no" onload="var downlevelDiv = document.getElementById('72e94d2c-9ca6-4109-b022-66fba309e262'); downlevelDiv.innerHTML = &amp;quot;&amp;lt;div&amp;gt;&amp;lt;embed src=\&amp;quot;http://images.video.msn.com/flash/soapbox1_1.swf\&amp;quot; quality=\&amp;quot;high\&amp;quot; width=\&amp;quot;432\&amp;quot; height=\&amp;quot;364\&amp;quot; wmode=\&amp;quot;transparent\&amp;quot; type=\&amp;quot;application/x-shockwave-flash\&amp;quot; pluginspage=\&amp;quot;http://macromedia.com/go/getflashplayer\&amp;quot; flashvars=\&amp;quot;c=v&amp;amp;v=8a96c975-1668-4ea4-8094-25d3ea7f049d&amp;amp;from=writer&amp;amp;mkt=en-US\&amp;quot; &amp;gt;&amp;lt;\/embed&amp;gt;&amp;lt;\/div&amp;gt;&amp;quot;;" alt=""&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style="clear:both;font-size:.8em;"&gt;Emily's Birthday&lt;/div&gt;&lt;/div&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Here is a code snippet:&lt;/strong&gt;&lt;/p&gt;  &lt;div class="csharpcode-wrapper"&gt;   &lt;div class="csharpcode"&gt;     &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; background-color: #f4f4f4"&gt;       &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;         &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Reflection;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;&amp;#160; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; ExternalDSL {&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;   &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; DslExecuter {&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; Hashtable parameters = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Hashtable(StringComparer.InvariantCultureIgnoreCase);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;&amp;#160; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; AddParameter(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; name, &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; parameter) {&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;       parameters[name] = parameter;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;     }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;&amp;#160; &lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; Invoke(ActionExpression expression) {&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; obj = parameters[expression.Left];&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (obj == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #006080"&gt;&amp;quot;Could not find parameter with name: &amp;quot;&lt;/span&gt; + expression.Left);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;       MethodInfo method =&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;         obj.GetType().GetMethod(expression.Operator,&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;                                 BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (method == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; InvalidOperationException(&lt;span style="color: #006080"&gt;&amp;quot;Could not find method operator &amp;quot;&lt;/span&gt; + expression.Operator + &lt;span style="color: #006080"&gt;&amp;quot; on &amp;quot;&lt;/span&gt; +&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  22:&lt;/span&gt;                                             expression.Left);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  23:&lt;/span&gt;       ParameterInfo[] methodParams = method.GetParameters();&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  24:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (methodParams.Length != 1)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  25:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; InvalidOperationException(expression.Operator + &lt;span style="color: #006080"&gt;&amp;quot; should accept a single parameter&amp;quot;&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  26:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;object&lt;/span&gt; converted;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  27:&lt;/span&gt;       Type paramType = methodParams[0].ParameterType;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  28:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (paramType.IsEnum)&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  29:&lt;/span&gt;         converted = Enum.Parse(paramType, expression.Right, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  30:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  31:&lt;/span&gt;         converted = Convert.ChangeType(expression.Right, paramType);&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  32:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; method.Invoke(obj, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;object&lt;/span&gt;[] {converted});&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  33:&lt;/span&gt;     }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  34:&lt;/span&gt;   }&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;        &lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &amp;#39;Courier New&amp;#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  35:&lt;/span&gt; }&lt;/pre&gt;&lt;br /&gt;      &lt;/div&gt;&lt;br /&gt;    &lt;/div&gt;&lt;br /&gt;  &lt;/div&gt;&lt;br /&gt;&lt;/div&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-5164869103807756709?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/5164869103807756709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=5164869103807756709&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/5164869103807756709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/5164869103807756709'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2008/06/live-writer-test-post.html' title='Live Writer Test Post'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh6.ggpht.com/mmackelprang/SE7xJEUrBNI/AAAAAAAAAEU/p5InhZAVYBQ/s72-c/IMG_2049_thumb%5B6%5D.jpg?imgmax=800' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-979395325670491676</id><published>2008-05-14T22:35:00.004-04:00</published><updated>2008-05-14T22:57:16.500-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>The Immense Value of Failure</title><content type='html'>&lt;p class="MsoNormal"&gt;A number of years back, I had the (dis)pleasure of developing software that had to interface with systems managed by a remote team that was paralyzed by the fear of failure.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;There was so much fear over making any wrong decision, that failure was guaranteed.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;The desire to “not be wrong” drove intense “&lt;a href="http://en.wikipedia.org/wiki/Big_Design_Up_Front"&gt;Big Design Up Front&lt;/a&gt;” (BDUF) discussions and over-large meetings to “build consensus” and “get buy-in” that slowed progress to a crawl on good days, and moved the project backwards on the (frequent) bad days.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;It made even trivial decisions painful.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;This delayed the project to the point that it was eventually cancelled.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;&lt;span style="font-size:+0;"&gt;&lt;/span&gt;The desire to not fail had let to failure.&lt;/p&gt;&lt;p class="MsoNormal"&gt;I can see two root causes for this problem:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;A Dysfunctional Work Environment:&lt;span style="font-size:+0;"&gt; &lt;/span&gt;Anyplace fear is a major behavior-inducing factor.&lt;/li&gt;&lt;li&gt;An Incorrect View Of Mistakes: &lt;span style="font-size:+0;"&gt;&lt;/span&gt;A belief that being making any wrong decision will cause permanent harm.&lt;/li&gt;&lt;/ol&gt;&lt;p class="MsoNormal"&gt;I’m only going to talk about #2 today – I’ve had several thoughts about this subject.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;#1 would be a topic for another article, but it’s not what I’m interested in right now. &lt;span style="font-size:+0;"&gt;&lt;/span&gt;My premise is that just about every “good” thing we have in the world today came about because of a whole bunch of mistakes.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;For every system we have that works well, there are a nearly infinite number of them that failed for some reason, and which led the next person/team to try something slightly better.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;This failure (aka progress) is extremely valuable.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;This insight leads to two points:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;No real discoveries were ever made without significant effort and trials.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;Edison with the light bulb.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;Newton with the laws of motion.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;Einstein with the general theory of relativity.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;There was a great show on PBS a long time ago called “&lt;a href="http://www.amazon.com/gp/product/0394556631/ref=olp_product_details?ie=UTF8&amp;amp;me=&amp;amp;seller="&gt;The Ring of Truth&lt;/a&gt;” hosted by Phillip Morrison that went into great detail on this historically recurring theme.&lt;/li&gt;&lt;li&gt;A “good” mistake is small enough and made quickly enough that fixing it is not difficult and it teaches about the problem.&lt;/li&gt;&lt;/ol&gt;&lt;p class="MsoNormal"&gt;An often used analogy for project development is driving.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;When I get in the car, I usually know pretty much where I want to go.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;I don’t know what traffic will be like, so I’ll have to adjust for it along the way.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;I also don’t know if I’ll have to adjust for road construction, weather conditions, a flat tire, etc.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;All of those things get fed into the course corrections I make as I’m &lt;b&gt;&lt;i&gt;MOVING&lt;/i&gt;&lt;/b&gt; towards my destination.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;I could spend a long time working out a plan for each of these contingencies before I left, but even if I did, there are certainly things I would have forgotten, and would still have to adjust to.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;I’m not advocating doing NO planning beforehand, but doing “just enough and no more”.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;Of course the amount of planning should vary in direct proportion to the uncertainty of the terrain, and the size of the trip. &lt;/p&gt;&lt;p class="MsoNormal"&gt;So, getting back to a project perspective, my belief is that every team should use the following loop:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Iterate&lt;/li&gt;&lt;li&gt;Fail Early&lt;/li&gt;&lt;li&gt;Fail Often&lt;/li&gt;&lt;li&gt;Learn From Small Successes &amp;amp; Save Them&lt;/li&gt;&lt;li&gt;Be willing to say “I Don’t Know”, but be willing to find out.&lt;/li&gt;&lt;/ul&gt;&lt;p class="MsoNormal"&gt;Being an “agile” team provides many of these tools.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;Small iterations keep you from getting hurt too bad along the project.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;They also allow direction changes to come from stakeholders (although I’ve never seen an actual stakeholder remain a part of an agile team long term – the stakeholders I’ve seen have always assigned a second-rate proxy after the first couple of iterations).&lt;span style="font-size:+0;"&gt; &lt;/span&gt;The tests written during development and keep the successes alive and in the knowledgebase.&lt;span style="font-size:+0;"&gt; &lt;/span&gt;They also encourage the “I don’t know” behavior.&lt;/p&gt;&lt;p class="MsoNormal"&gt;The bottom line is that we should be justifiably proud of our failures, much in the same way we are of our successes – as long as we’ve learned the lesson those failures are trying to teach.&lt;/p&gt;&lt;p class="MsoNormal"&gt;There are a few quotes regarding this topic that I really like: &lt;/p&gt;&lt;p class="MsoNormal" style="FONT-WEIGHT: bold; FONT-STYLE: italic"&gt;Samuel Smiles&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;blockquote&gt;It is a mistake to suppose that men succeed through success; they much oftener succeed through failures. Precept, study, advice, and example could never have taught them so well as failure has done.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;a name="003147"&gt;&lt;/a&gt;&lt;/p&gt;&lt;blockquote&gt;We learn wisdom from failure much more than from success. We often discover what will do, by finding out what will not do; and probably he who never made a mistake never made a discovery.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="FONT-STYLE: italic"&gt;&lt;span style="FONT-WEIGHT: bold"&gt;Mohandas K. Gandhi&lt;/span&gt; &lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;blockquote&gt;Freedom is not worth having if it does not connote freedom to err.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="FONT-WEIGHT: bold; FONT-STYLE: italic"&gt;Robert F. Kennedy&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;blockquote&gt;Only those who dare to fail greatly can ever achieve greatly.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="FONT-WEIGHT: bold; FONT-STYLE: italic"&gt;Robert Frost&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;blockquote&gt;The best way out is always through.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-979395325670491676?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/979395325670491676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=979395325670491676&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/979395325670491676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/979395325670491676'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2008/05/number-of-years-back-i-had-displeasure.html' title='The Immense Value of Failure'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-780944678941063467</id><published>2008-05-14T21:02:00.007-04:00</published><updated>2008-05-14T21:14:28.804-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='admin'/><category scheme='http://www.blogger.com/atom/ns#' term='test'/><title type='text'>Word 2007 Test Post</title><content type='html'>This is a post to see how things look when posting from Word 2007.  If this works out ok, I'll be using this for my publishing from now on.&lt;span xmlns=""&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-size:130%;"&gt;Photo Test&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_r267morZGNM/SCuMa9RJYpI/AAAAAAAAAEA/QrwljsXmdVs/s1600-h/Anderson+Clan.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://bp1.blogger.com/_r267morZGNM/SCuMa9RJYpI/AAAAAAAAAEA/QrwljsXmdVs/s400/Anderson+Clan.jpg" alt="" id="BLOGGER_PHOTO_ID_5200404589480338066" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;This is a picture of my extended family on my Mom's side (Anderson).  My Grandpa Anderson is standing in the middle of everybody.  I'm the little boy standing up on the far right side.  This was taken in the late 60's sometime.  I'm sure one of my sisters will tell me exactly when it was :-)&lt;/p&gt;&lt;p&gt;Added note @ 9:10 5/14/2008 - MS Word 2007 isn't going to cut it as a Blog editor.  I tried posting this from Word, and the image didn't make it, I also had several sections below where I had code fragments and other formatting things embedded in this post.  None of them worked as I expected them to.  Looks like I'll keep using the online editor for posting for the near term.  If anybody has found something better, please let me know in the comments.&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-780944678941063467?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/780944678941063467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=780944678941063467&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/780944678941063467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/780944678941063467'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2008/05/word-2007-test-post.html' title='Word 2007 Test Post'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://bp1.blogger.com/_r267morZGNM/SCuMa9RJYpI/AAAAAAAAAEA/QrwljsXmdVs/s72-c/Anderson+Clan.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-3080759319350425584</id><published>2008-04-15T09:25:00.009-04:00</published><updated>2008-04-15T09:42:18.900-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='quickfix'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><title type='text'>Sharing A USB Drive On XP / Vista</title><content type='html'>&lt;span style="font-family:verdana;"&gt;I recently needed to share my USB hard drive on the network, and had a lot of problems making it consistently available as a share.  After trolling around on the internet, I found the answer -- since this took a while to find and debug, I'm documenting it here.&lt;br /&gt;&lt;br /&gt;In regedit, find the key in HKLM (HKey Local Machine):&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;\System\CurrentControlSet\Services\LanmanServer\Parameters&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;Set the parameter &lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;a href="http://support.microsoft.com/kb/285089"&gt;IRPStackSize&lt;/a&gt; &lt;span style="font-family:verdana;"&gt;to a value 3 higher than it currently is, and reboot.  You may have to do this more than once.  If this key doesn't exist, create a DWORD key and set the value.&lt;br /&gt;&lt;br /&gt;On the two systems I did this to, I ended up with values of 17 and 18.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-3080759319350425584?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/3080759319350425584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=3080759319350425584&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/3080759319350425584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/3080759319350425584'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2008/04/sharing-usb-drive-on-xp-vista.html' title='Sharing A USB Drive On XP / Vista'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-2475897608965129749</id><published>2008-04-15T08:58:00.005-04:00</published><updated>2008-04-15T15:09:35.761-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><title type='text'>The Parable of Everybody, Somebody &amp; Nobody</title><content type='html'>&lt;span style="font-family:verdana;"&gt;I need to attribute this, but this story popped into my head last night.  I believe I heard it in church about 30 years ago (man, it's embarrassing to say that)...&lt;br /&gt;&lt;br /&gt;All the people wanted to get back to Heaven, and there were many tasks to perform to get there.  Everybody was &lt;span style="font-weight: bold; font-style: italic;"&gt;sure &lt;/span&gt;that Somebody would do the work.  Anybody could have done it, but was waiting for SomebodyElse to do it.  &lt;/span&gt;&lt;span style="font-family:verdana;"&gt;Somebody got angry because it was Everybody’s job. Everybody got angry because he thought that Anybody or SomebodyElse should do it.  Somebody said that she thought it was already done, but didn't bother to check.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:verdana;"&gt;&lt;br /&gt;Finally the day of reckoning came.  Everybody fought to be first in line for the rewards.  Somebody was crying because SomebodyElse was pushing and giving cuts.   Nobody was patiently waiting for her turn.&lt;br /&gt;&lt;br /&gt;Nobody was the only one who made it into Heaven.  She was the only one that did the tasks that Everybody, Somebody, and SomebodyElse should have done.&lt;br /&gt;&lt;br /&gt;The Moral: Don't Procrastinate.  Don't let Nobody be rewarded for things &lt;span style="font-weight: bold; font-style: italic;"&gt;YOU &lt;/span&gt;can do.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-2475897608965129749?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/2475897608965129749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=2475897608965129749&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/2475897608965129749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/2475897608965129749'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2008/04/parable-everybody-somebody-nobody.html' title='The Parable of Everybody, Somebody &amp; Nobody'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-1727968120482644339</id><published>2008-04-15T08:37:00.004-04:00</published><updated>2008-04-15T09:06:44.370-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><title type='text'>Small Teams</title><content type='html'>&lt;span style="font-family:verdana;"&gt;My wife and I went to the "Engineering Open House" at NC State with my son Richard last Saturday.  They had many cool things on display, and there were a lot of people there.  Richard is very interested in doing something technical, but isn't sure what yet.&lt;br /&gt;&lt;br /&gt;The most interesting thing that &lt;span style="font-weight: bold; font-style: italic;"&gt;I&lt;/span&gt; did there was spending about a half hour talking with &lt;a href="http://www.youtube.com/watch?v=Y2FcTTuiVnQ"&gt;Grayson Randall&lt;/a&gt; who designed the &lt;a href="http://www.csc.ncsu.edu/news/491"&gt;Lone Wolf&lt;/a&gt; autonomous vehicle that NC State entered into the &lt;a href="http://www.darpa.mil/GRANDCHALLENGE/"&gt;DARPA Urban Challenge&lt;/a&gt; contest.  Grayson is a really interesting guy and has a lot of cool stories to tell.  I was asking him about the development process and team they used to produce the control and management software for the 9 dual core computers they have embedded in the trunk of their Lotus plus the 4 single board computers they have in the front of the car.  He said that there were 6-9 people who spent a couple of years developing this software, with various teams implementing hardware at the same time.&lt;br /&gt;&lt;br /&gt;Having been involved in systems design, I can know how hard it is to develop both hardware and software at the same time, so getting it all running is amazing all by itself.  The point that sticks out to me most of all though is that a&lt;span style="font-weight: bold; font-style: italic;"&gt; small motivated&lt;/span&gt; team can accomplish more than a large one in nearly all cases.&lt;br /&gt;&lt;br /&gt;As teams grow beyond single digits two things happen:&lt;br /&gt;&lt;/span&gt;&lt;ol&gt;&lt;li&gt;Inertia kills agility.  Too many people are too hard to switch quickly.  With small teams a quick meeting can convey the essence of the change.  Large teams take exponentially larger amounts of time and effort to simply communicate.&lt;/li&gt;&lt;li&gt;Inertia kills motivation.  This is obviously not true in all cases, but in the teams I've seen, there is a direct relationship between the motivation of the team and the size of the team.  I've seen too many cases on large teams where "&lt;a href="http://mackelwhat.blogspot.com/2008/04/parable-everybody-somebody-nobody.html"&gt;everybody thought somebody would fix it&lt;/a&gt;".&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-family:verdana;"&gt;Note that I'm not saying that small teams are the only ones that can succeed.  Simply that in my experience, small teams are more likely to.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-1727968120482644339?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/1727968120482644339/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=1727968120482644339&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/1727968120482644339'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/1727968120482644339'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2008/04/small-teams.html' title='Small Teams'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-1224086585066991021</id><published>2008-04-08T09:57:00.004-04:00</published><updated>2008-04-08T10:05:50.463-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Hosted Services</title><content type='html'>&lt;span style="font-family:verdana;"&gt;First Amazon created &lt;a href="http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=84"&gt;EC3&lt;/a&gt;, now there's &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;.  I think companies providing 3rd party hosting environments are in for a tough time in the future.  It's going to be tough to compete on volume / size / price.  They're going to have to provide niche features that Amazon / Google don't have.&lt;br /&gt;&lt;br /&gt;For developers and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;startups&lt;/span&gt;, I think this is a Very Good Thing.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-1224086585066991021?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/1224086585066991021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=1224086585066991021&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/1224086585066991021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/1224086585066991021'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2008/04/hosted-services.html' title='Hosted Services'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-3600995992646018276</id><published>2008-03-27T21:52:00.002-04:00</published><updated>2008-03-27T22:00:14.096-04:00</updated><title type='text'>New Blog Elements</title><content type='html'>&lt;span style="font-family: verdana;"&gt;If you're reading this in an aggregator, you won't be able to see this, but on my blog home page, I've added a few new interesting time wasters.  Specifically:&lt;br /&gt;&lt;/span&gt;&lt;ul style="font-family: verdana;"&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Visitor Map - This is from ClustrMaps and shows how few readers I actually have :-)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Recent Interesting Sites And Articles - This has three things:&lt;/span&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Recently "&lt;a href="http://www.google.com/reader/shared/user/09554567595996974205/state/com.google/broadcast"&gt;Shared&lt;/a&gt;" Google Reader Items&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Recently "&lt;a href="http://www.google.com/reader/shared/user/09554567595996974205/state/com.google/starred"&gt;Starred&lt;/a&gt;" Google Reader Items&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;Recent &lt;a href="http://del.icio.us/mmackelprang"&gt;del.icio.us&lt;/a&gt; Links&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;span style="font-family: verdana;"&gt;So for all those times you don't have anything better to do, you can see what I'm looking at...&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-3600995992646018276?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/3600995992646018276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=3600995992646018276&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/3600995992646018276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/3600995992646018276'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2008/03/new-blog-elements.html' title='New Blog Elements'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-376035611378984604</id><published>2008-03-27T21:32:00.002-04:00</published><updated>2008-03-27T21:39:51.402-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Google Apps</title><content type='html'>&lt;span style="font-family:verdana;"&gt;I've recently setup a couple of my domains with Google Apps, and I'm very happy with it.  6G+ of email space per account, 10G+ of space per domain for wiki stuff, and lots of document and spreadsheet goodness all around.  You can check out either &lt;a href="http://start.mackelprang.com"&gt;http://start.mackelprang.com&lt;/a&gt; or &lt;a href="http://start.mackelprang.org"&gt;http://start.mackelprang.org&lt;/a&gt; to see what's there.&lt;br /&gt;&lt;br /&gt;The main site for me will be the mackelprang.com one (&lt;a href="http://www.mackelprang.com"&gt;http://www.mackelprang.com&lt;/a&gt;).  The mackelprang.org site will be used for the "family at large".&lt;br /&gt;&lt;br /&gt;Setting up the domains was a very painless experience compared to what it would take doing it at a hosting site.  I've migrated nearly all of my local hosting dependencies to my Google Apps sites, and I'm very pleased.  I'll keep you up to date as things progress.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-376035611378984604?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/376035611378984604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=376035611378984604&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/376035611378984604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/376035611378984604'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2008/03/google-apps.html' title='Google Apps'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-2149615938056474184</id><published>2008-03-27T21:28:00.002-04:00</published><updated>2008-03-27T21:32:31.304-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='noise'/><title type='text'>Starting Up.  Again.</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="font-family: verdana;"&gt;So &lt;a href="http://zbarzone.blogspot.com/"&gt;Andy&lt;/a&gt; tells me he wants to blog again, and guilts me into joining him.  I have a lot of article topics pending, so I'm going to spend a couple of hours a week getting them out here.  Hopefully I'll be more diligent this time than last...&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-2149615938056474184?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/2149615938056474184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=2149615938056474184&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/2149615938056474184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/2149615938056474184'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2008/03/starting-up-again.html' title='Starting Up.  Again.'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-1119913834767514607</id><published>2006-12-04T15:23:00.000-05:00</published><updated>2006-12-04T15:31:20.955-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='archeology'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithm'/><title type='text'>How Many Digits In That Number?</title><content type='html'>&lt;p style="font-family: verdana;" class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;This is the first article in a series of “interesting things I’ve found that I haven’t seen used elsewhere”.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;This will discuss a technique I used a couple of times in college when writing contrived software for CS and EE assignments.&lt;/span&gt;&lt;/p&gt;    &lt;p style="font-family: verdana;" class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;One of the assignments I had required formatting numbers for output.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;For the algorithm I was using, it was important to know how many digits were in an integer number before I output it.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;This would make the formatting significantly easier than not knowing ahead of time.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;In thinking about how to do this, I realized there were several ways to do this.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;The first was to find modulo 10 and divide by 10 until the number was 0.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;This figured out the length, and found the individual parts of the number nicely, but it started from the least significant digit and worked up.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;I wanted something that would go the other direction.&lt;/span&gt;&lt;/p&gt;    &lt;p style="font-family: verdana;" class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;I remembered my algebra class, and the log (base 10) function.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;I remembered that if log x = n, 10^n = x.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;In thinking about this, I realized that the ceiling of log x is the number of digits in x.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;In other words, since log 12345 =4.something, 12345 has 5 digits.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;This meant I could code something like the following:&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;int GetLength(int num) {&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;    return ceil(log(num));&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;/p&gt;    &lt;p class="MsoNormal"&gt;&lt;/p&gt;&lt;p style="font-family: verdana;" class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;And could print out the digits of the number like this:&lt;/span&gt;&lt;/p&gt;    &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;for(int j=GetLength(num); j&gt;0; j--) {&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;    &lt;/span&gt;cout &lt; num / 10^j;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;    &lt;/span&gt;num \= 10^j;&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;/p&gt;    &lt;p style="font-family: verdana;" class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;So for base 10, it worked really well. &lt;/span&gt;&lt;span style=";font-size:100%;" &gt; &lt;/span&gt;&lt;span style="font-size:100%;"&gt;The epiphany occurred when I needed to do the same thing with binary (base 2), octal (base 8), and hexadecimal (base 16) numbers.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;It turns out that this algorithm is extensible to arbitrary bases.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;To get that, we just have to make a couple of minor changes:&lt;/span&gt;&lt;/p&gt;    &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;int GetLength(int num, int base) {&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;    &lt;/span&gt;return ceil(log(num)/log(base));&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;/p&gt;&lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;    &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;int num = 12345;&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;int base = 2;&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;for(int j=GetLength(num, base); j&gt;0; j--) {&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;    &lt;/span&gt;cout &lt; num / base^j;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style=""&gt;    &lt;/span&gt;num \= base^j;&lt;/span&gt;&lt;/p&gt;  &lt;p  class="MsoNormal" style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;}&lt;/span&gt;&lt;/p&gt;    &lt;p style="font-family: verdana;" class="MsoNormal"&gt;&lt;span style="font-size:100%;"&gt;There are a couple of special cases that you have to take care of when using this. &lt;/span&gt;&lt;span style=";font-size:100%;" &gt; &lt;/span&gt;&lt;span style="font-size:100%;"&gt;Specifically:&lt;/span&gt;&lt;/p&gt;  &lt;ul style="margin-top: 0in; font-family: verdana;" type="disc"&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style="font-size:100%;"&gt;Negative      numbers – you need to make sure to pass positive numbers into the digit      counter. &lt;/span&gt;&lt;span style=";font-size:100%;" &gt; &lt;/span&gt;&lt;span style="font-size:100%;"&gt;Logs of negative numbers      aren’t real, and most math libraries don’t handle them well.&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style="font-size:100%;"&gt;Fractional      numbers – for numbers with decimal places, this technique doesn’t work      right. &lt;/span&gt;&lt;span style=";font-size:100%;" &gt; &lt;/span&gt;&lt;span style="font-size:100%;"&gt;To make them work, you’d      have to decide on how may decimal places you want, multiply by that number      to start, then put the decimal point in the “right” place when emitting      the value.&lt;/span&gt;&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;span style="font-size:100%;"&gt;Digit      representation – for bases greater than 10, you’d need a mapping to handle      the digits to output.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;In the      example given above (with no digit mapping), the cout will emit a “13”      instead of a “D” as expected for a hexadecimal conversion.&lt;/span&gt;&lt;span style=";font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="font-size:100%;"&gt;Some kind of simple digit mapping scheme      would have to be added to take care of this case.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-1119913834767514607?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/1119913834767514607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=1119913834767514607&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/1119913834767514607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/1119913834767514607'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/12/how-many-digits-in-that-number.html' title='How Many Digits In That Number?'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-2786225209287368281</id><published>2006-11-02T21:33:00.000-05:00</published><updated>2006-11-02T21:38:02.534-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>USB Drive Adapter</title><content type='html'>Like any true geek, I have a bunch of old hard drives laying around my office.  It's a pain to install them in a system just to copy data to them or to get data from them, but this week I bought a very cool device from &lt;a href="http://www.newegg.com/"&gt;NewEgg&lt;/a&gt;.  It's a small square adapter that has hard drive plugs around three of it's sides.  One adapter for 2.5 inch laptop drives, one for 3.5 inch normal system drives (which also works in CD/DVD drives), and another for SATA drives.  There is a power supply for the drive motor, since many 3.5 inch drives draw more that USB can supply.  It's a &lt;a href="http://www.newegg.com/Product/Product.asp?Item=N82E16812156102"&gt;BYTECC BT-300 USB 2.0 to IDE/SATA Adapter&lt;/a&gt;, and it's less than $25 at NewEgg.&lt;br /&gt;&lt;br /&gt;This will make migrating stuff between computers a breeze.  I wish I would have thought of this first.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-2786225209287368281?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/2786225209287368281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=2786225209287368281&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/2786225209287368281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/2786225209287368281'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/11/usb-drive-adapter.html' title='USB Drive Adapter'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-6262819117251695237</id><published>2006-10-18T13:43:00.000-04:00</published><updated>2006-10-18T13:43:27.515-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>I Code Like A Rock Star!</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Originally Posted On: DATE: 10/07/2005 11:27:57&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Today I was working with one of my office mates on reproducing a problem reported at a field site.  He had already gotten the source from the tip, built, and tested it, and then added a test case to demonstate the problem we were seeing in the field.  The conversation went something like this:&lt;br /&gt;&lt;blockquote&gt;Him: "I added the test, and it all works."&lt;br /&gt;Me: "Really? That change should have caused a failure.  Let's take a look."&lt;br /&gt;&lt;span style="font-style: italic;"&gt;We looked at the code, and sure enough, the test that should fail was in the test case.&lt;/span&gt;&lt;br /&gt;Me: "This is really strange..."&lt;br /&gt;&lt;span style="font-style: italic;"&gt;I added a fail(...) to the test case, and it still didn't cause any failures.&lt;/span&gt;&lt;br /&gt;Me: "This is &lt;i&gt;&lt;b&gt;really &lt;/b&gt;&lt;/i&gt;bothering me..."&lt;br /&gt;&lt;span style="font-style: italic;"&gt;I added a compile time error to the test case, and the compiler did complain this time.&lt;/span&gt;&lt;br /&gt;&lt;/blockquote&gt;Finally, we looked in the test suite (this is a fairly old class that's still using NUnit 1.x) and found that the suite wasn't including this test class.  We added the class to the suite, and the failures happened in the way we were expecting.  We then backed all the cruft we had just added to the test class back out, and  worked on the problem  from the beginning.  It was very disconcerting to be able to add errors to the test class but not have them show up.&lt;br /&gt;&lt;br /&gt;Two lessons I learned from this episode:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Don't Take Short Cuts&lt;/span&gt;.  There's a great article on &lt;a href="http://www.butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd"&gt;The Three Rules Of TDD&lt;/a&gt; by Bob Martin.  We should not have added anything to a class that wasn't really being called.  There are ways to validate that the classes are actually included.  This problem would be alleviated by using NUnit 2 somewhat, since the tests there are tagged instead of named, and the Suite class is unneeded.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Don't Trust Anything&lt;/span&gt;.  Whenever something smells wrong, there's probably a good reason.  Start with the simplest thing (like - is the editor, the compiler, and test running all pointing at the same place?) and work up in complexity to find where things start to stink.  Then iterate around there until you find the problem.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-6262819117251695237?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/6262819117251695237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=6262819117251695237&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/6262819117251695237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/6262819117251695237'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/09/i-code-like-rock-star_20.html' title='I Code Like A Rock Star!'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-7677156087822742019</id><published>2006-10-18T13:40:00.003-04:00</published><updated>2008-05-09T08:46:52.122-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><category scheme='http://www.blogger.com/atom/ns#' term='music'/><title type='text'>Another One Bites The Dust</title><content type='html'>&lt;span style="FONT-WEIGHT: bold"&gt;Originally Posted On: DATE: 09/18/2005 10:59:45&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When I was in high school in the early eighties, a friend of mine (David Jackson) told me that there were hidden lyrics in a song by the rock group &lt;a href="http://www.queenonline.com/"&gt;Queen&lt;/a&gt;. I didn't believe him, so he put my copy of the LP (we had vinyl LP records then) on my record player, and turned the record backwards by hand. On the song "Another One Bites The Dust", there were some very interesting lyrics. Take a listen to both versions and see if you can hear what I thought I heard in the backwards version. (Note that before you listen to any of this that this song is (c) Queen, and I have no rights to it whatsoever. I'm just making an interesting observation about a 5 second snippet of it.)&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Here's the snippet I'm talking about played &lt;a href="http://xq0ndg.blu.livefilestore.com/y1pnFIMU7eJCAJT7tBDOnB7LsQbutSQOCuacW2qiugGCqBpGB7GxLcSPk0quU7-7W19fktdpsPyn9gRu4dAnR2wCQ/OBTD_Forwards.mp3"&gt;normally&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Here's the exact same snippet played &lt;a href="http://xq0ndg.blu.livefilestore.com/y1pnFIMU7eJCAJxq_VeoUoBAFgFSpNhC8Zw8kuCf_cfpj76jRqGP6clQEpwJn84d5Ue3OfWB0x4tsMot95iJDc8jA/OBTD_Backwards.mp3"&gt;backwards&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;To me, it sounds like the backwards version says "it's fun to smoke marijuana" several times. Now that you think I heard that when I listened to it, listen to the backwards version again. Did the things I heard affect what you heard? There are a couple of interesting thoughts here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If it really says that, how did the guys in the band manage to make it say that?&lt;/li&gt;&lt;li&gt;If it doesn't, how much does your expectation that something will say something affect what you actually hear?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Personally I can imagine a bunch of guys messing around with audio equipment, trying to find something to write a song about and finding out that "i like to smoke marijuana" sounds like "another one bites the dust" backwards, and using that in a song.&lt;br /&gt;&lt;br /&gt;In the end, it doesn't really matter. I seriously doubt that there's any subconscious decoding that will take lyrics backwards, and put them in your memory, and further, I still think that the song is a fun song.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-7677156087822742019?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/7677156087822742019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=7677156087822742019&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/7677156087822742019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/7677156087822742019'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/09/another-one-bites-dust.html' title='Another One Bites The Dust'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-7124723600586302335</id><published>2006-10-18T13:07:00.000-04:00</published><updated>2006-10-18T13:10:26.009-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='links'/><title type='text'>Excellent Fowler Article</title><content type='html'>I saw an excellent &lt;a href="http://martinfowler.com/bliki/ImprovementRavine.html"&gt;article&lt;/a&gt; by &lt;a href="http://en.wikipedia.org/wiki/Martin_Fowler"&gt;Martin Fowler&lt;/a&gt; today.  It hits the nail on the head of why it's so hard to do something new even though it has a very good chance of being easier/better than how we do it today.  This was my experience in learning &lt;a href="http://en.wikipedia.org/wiki/Test_driven_development"&gt;Test Driven Development&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-7124723600586302335?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://martinfowler.com/bliki/ImprovementRavine.html' title='Excellent Fowler Article'/><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/7124723600586302335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=7124723600586302335&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/7124723600586302335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/7124723600586302335'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/10/excellent-fowler-article.html' title='Excellent Fowler Article'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-7487218254384010380</id><published>2006-10-10T13:11:00.000-04:00</published><updated>2006-10-10T13:26:46.176-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='continuousintegration'/><title type='text'>Automatically Dismissing The Unhandled Exception Dialog</title><content type='html'>On our build system, we were having two problems.  First of all, there was a &lt;a href="http://en.wikipedia.org/wiki/Smoketest"&gt;smoke test&lt;/a&gt; that was throwing an unhandled exception.  Second of all, the .net framework was presenting a dialog to ask the user what to do about the exception.  In the spirit of &lt;a href="http://en.wikipedia.org/wiki/Fail_Fast"&gt;fail fast&lt;/a&gt;, this was causing a big problem for the entire build, since we normally don't have somebody staring at the build box, expecting to give user input.  It's very important that the build box be headless and input-less.  It's OK to have a management console like &lt;a href="http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET"&gt;CruiseControl &lt;/a&gt;to request builds, but there should never be an interactive dialog.&lt;br /&gt;&lt;br /&gt;I googled for an answer on how to automatically dismiss the dialog, and finally found the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconenablingjit-attachdebugging.asp"&gt;answer&lt;/a&gt;.  Essentially, all you have to do is modify the registry key:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:78%;"&gt;HKEY_LOCAL_MACHINE\Software\Microsoft\ .NETFramework\DbgJITDebugLaunchSetting&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;and change it's value to 1.  This will allow the process throwing the unhandled  exception to terminate with a stack dump with no user interaction.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-7487218254384010380?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/7487218254384010380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=7487218254384010380&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/7487218254384010380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/7487218254384010380'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/10/automatically-dismissing-unhandled.html' title='Automatically Dismissing The Unhandled Exception Dialog'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-9159137179881535712</id><published>2006-10-06T16:16:00.000-04:00</published><updated>2006-10-06T16:20:19.016-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>Upgrading From NAnt 0.84+ to NAnt 0.85 rc4</title><content type='html'>I converted our nightly and integration builds from NAnt 0.84 (with some local mods) to NAnt 0.85 rc4 today.  Overall, the upgrade was pretty painless.  There were several changes that I had to make to our build file to make it work, plus there were many warnings that I wanted to remove after trying things out.  Here's the list of things I did:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Copied the support dlls from the NAnt contrib project into the nant/bin directory.  This was required for several support tasks and attributes.  It also makes it easier to upgrade the build file later since everything will be available.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Copied support tasks created locally into the nant/bin directory.  These tasks were still compatible with the new version of NAnt, and didn't even require a rebuild.&lt;/li&gt;&lt;li&gt;Used to have to set an environment variable with inline C# code, but we can now take advantage of the setenv command.  This even speeds up the build slightly since the dll that sets the env. variable doesn't have to be compiled and loaded.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Changed all includes and excludes to include and exclude respectively.  There were many filesets in the build file.  This was by far the most common change.  This was not required, but removed &lt;span style="font-weight: bold; font-style: italic;"&gt;many &lt;/span&gt;warnings.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Changed all user in vssget and vsslabel to username.  Again, this was not required, but generated deprication warnings.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Had to add some code to ensure the write-only bit was off before touching some files to change the timestamp (this was necesssary because of making sure IIS saw the webservice files as new).  This was a required change due to some new behavior in NAnt.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Used to have some code to remove a service before we installed it for Smoke Tests.  With the newer NAnt (in the contrib project), there is a service::is-installed() check we can use.  This eliminates severa lof the warnings we used to get on our &lt;a href="http://en.wikipedia.org/wiki/Smoke_testing"&gt;Smoke Tests&lt;/a&gt;.  This was a nice enhancement made possible by the new check.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;In our nunit2 tasks, we formerly used haltonerror attributes.  These are now "failonerror".&lt;/li&gt;&lt;li&gt;In our Acceptance Tests, we formerly only used the basedir attribute.  With the newer NAnt, we now need to set both the basedir and workingdir attributes.  This is necessary only for programs that expect data/config files to be in the executable directory.  If running a program that takes no input, this would not be necessary.  This was a required change to allow the tests to run.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;All of the nunit (aka Nunit1) test suites are tagged as depricated, and generate warnings in the build logs.  I like this because it will encourage us to upgrade those tests over the next while. &lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-9159137179881535712?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/9159137179881535712/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=9159137179881535712&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/9159137179881535712'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/9159137179881535712'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/10/upgrading-from-nant-084-to-nant-085-rc4.html' title='Upgrading From NAnt 0.84+ to NAnt 0.85 rc4'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-4558419387035613555</id><published>2006-09-29T23:02:00.000-04:00</published><updated>2006-09-29T23:12:10.713-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reader'/><category scheme='http://www.blogger.com/atom/ns#' term='rss'/><title type='text'>Google Reader Update</title><content type='html'>Google has updated their &lt;a href="http://www.google.com/reader/view/"&gt;RSS reader&lt;/a&gt;.  I liked what they had before, but the new features are pretty cool.  They had "&lt;a href="http://www.google.com/reader/view/user/09554567595996974205/state/com.google/starred"&gt;starred&lt;/a&gt;" items (i.e. items you wanted to keep track of for later which you can see in the sidebar of this blog, but now there's a new feature called "&lt;a href="http://www.google.com/reader/shared/09554567595996974205"&gt;shared&lt;/a&gt;" items.  This is like a poor man's plagaristic blog.  You can even add an &lt;a href="http://www.google.com/reader/public/atom/user/09554567595996974205/state/com.google/broadcast"&gt;rss feed&lt;/a&gt; for your shared items.&lt;br /&gt;&lt;br /&gt;Overall, I'm very happy with it.  I tried several readers before going with Google's.  I normally use two or three different computers each day, so it's really nice to have all my feeds synced.&lt;br /&gt;&lt;br /&gt;Check it out if you're looking for a reader.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-4558419387035613555?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.google.com/reader/' title='Google Reader Update'/><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/4558419387035613555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=4558419387035613555&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/4558419387035613555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/4558419387035613555'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/09/google-reader-update.html' title='Google Reader Update'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-162423236996927550</id><published>2006-09-28T12:46:00.001-04:00</published><updated>2006-09-28T12:54:26.829-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><category scheme='http://www.blogger.com/atom/ns#' term='test'/><title type='text'>Windows Live Writer Test Post</title><content type='html'>&lt;p&gt;With images no less! &lt;/p&gt; &lt;p&gt;&lt;a href="http://www.mackelprang.com/blogimage/WindowsLiveWriterTestPost_B387/RichardNantahala1.jpg" atomicselection="true"&gt;&lt;img style="border: 0px none ;" src="http://www.mackelprang.com/blogimage/WindowsLiveWriterTestPost_B387/RichardNantahala.jpg" border="0" height="159" width="240" /&gt;&lt;/a&gt;&lt;/p&gt; &lt;p&gt;This picture or Richard was from summer camp last July. I believe this was on the Nantahala river.&lt;/p&gt; &lt;div class="wlWriterSmartContent" id="0767317B-992E-4b12-91E0-4F059A8CECA8:f771d5c8-1dcf-4681-9715-639371c9cee3" contenteditable="false" style="margin: 0px; padding: 0px; display: inline; float: none;"&gt;&lt;a href="http://mackelwhat.blogspot.com/search/label/test" rel="tag"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-162423236996927550?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/162423236996927550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=162423236996927550&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/162423236996927550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/162423236996927550'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/09/windows-live-writer-test-post.html' title='Windows Live Writer Test Post'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-1397095071967667120</id><published>2006-09-20T23:03:00.000-04:00</published><updated>2006-09-20T23:12:03.960-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><title type='text'>VMWare Appliances</title><content type='html'>I've installed the (free) &lt;a href="http://www.vmware.com/download/server/"&gt;VMWare server&lt;/a&gt; on my development server at home and I frequently use a couple of their appliances on it.  Specifically:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.vmware.com/vmtn/appliances/directory/556"&gt;Twiki &lt;/a&gt;- This is an awesome idea to be able to install and use TWiki without all the hassles of getting it going on a server.  Especially if your server is Windows based.  This appliance already has Samba installed, so getting files on and off the box is very simple, as are backups.  It also sets itself up with a netbios name, so connecting to it is cake.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.vmware.com/vmtn/appliances/directory/328"&gt;Helix &lt;/a&gt;- This has Trac installed along with subversion.  Two very nice tools for managing development.  I'm currently only using subversion (since Trac is a little over the top for what I do by myself).&lt;/li&gt;&lt;/ul&gt;I've installed the Twiki appliance at work, and converted some fairly old (2+ year old version of Twiki) data to the new appliance.  This took about 3 hours in all to do.&lt;br /&gt;&lt;br /&gt;Overall, I'm very happy with this tool as a solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-1397095071967667120?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/1397095071967667120/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=1397095071967667120&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/1397095071967667120'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/1397095071967667120'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/09/vmware-appliances.html' title='VMWare Appliances'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-5632143891187382930</id><published>2006-09-20T22:41:00.000-04:00</published><updated>2006-09-20T22:42:31.589-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><title type='text'>Tests Don't Save You From Being Stupid</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Originally Posted On: DATE: 08/29/2005 04:18:31&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A couple of weeks back I worked on adding some new capabilities to a software system at work called the `listener'.  Essentially, this software receives socket messages (events), assembles, parses (from various protocols), generates `model' events, and passes these off to a subsystem to let various business logic handlers deal with the events and do interesting things with them.&lt;span style=""&gt;  &lt;/span&gt;The piping internal to the system to move events around includes (among other things) the &lt;a href="http://en.wikipedia.org/wiki/Visitor_pattern"&gt;Visitor Pattern&lt;/a&gt;, which is normally very explicit about not being able to handle a new type if a new type has been added.&lt;br /&gt;&lt;br /&gt;The capabilities I needed to add depended on creating a new event type that the visitor pattern would pass to the appropriate handler on the back end (like visitor patterns do).  I built the acceptance test, ran it, watched everything fail as I expected, then got into modifying the interfaces to force the creation of the new event type, and force the various implementations to implement a `visit' method for the new event.  All of this went swimmingly, and after working for about three or four hours, I had the whole system back together with new UT's for the classes that needed changed, and with the original AT that started the whole thing working.&lt;br /&gt;&lt;br /&gt;So, I had added about 50 UTs, and about 3 ATs and everything looked copacetic.  I took the finished code off to run it on a test system with real data.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span style="font-style: italic;"&gt;It didn't work.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;After spending a couple of hours digging through the logs, tests, and finally the code, I found that when we built the system, we had added a base class beneath some of the implementations of the visitor for some reason. This base class provided default behavior for unknown types coming in. &lt;span style=""&gt; &lt;/span&gt;Since this base class was embedded in the plumbing, the default handler was taking the new event type, and wasn't letting it get to the endpoint implementation, so the new event wasn't being handled. &lt;span style=""&gt; &lt;/span&gt;Once I found that, I found several tests that I had missed on the first pass through the system that would have pointed out these problems, but I had glossed over them.&lt;br /&gt;&lt;br /&gt;If I knew then what I know now, I'd:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Make sure that if I'm using Visitor, I make the compiler warn me about problems.  The fact that I'm using Visitor means that I'm SURE I'll be adding new types.  Let the compiler do its job when the types aren't wired up correctly.&lt;/li&gt;&lt;li&gt;If there is a compelling reason to stick a base class in there (i.e. a default visit handler), add a test that does reflection to count the number of visit types between the end point implementations and the interface.  This might be a little hairy, but the 2-3 hours spent will save me several times in the future.&lt;/li&gt;&lt;li&gt;If you're in a situation like this, and the base class is causing you pain, remove the base class.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;It was a good learning experience. It just points out once again that hindsight is awesome.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-5632143891187382930?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/5632143891187382930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=5632143891187382930&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/5632143891187382930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/5632143891187382930'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/09/tests-dont-save-you-from-being-stupid.html' title='Tests Don&apos;t Save You From Being Stupid'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-2607861262430488136</id><published>2006-09-20T22:26:00.001-04:00</published><updated>2006-09-20T22:26:54.515-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Kent Beck / Alan Cooper Smackdown</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Originally Posted On: 08/22/2005 09:11:55&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I read a &lt;A href="http://www.fawcette.com/interviews/beck_cooper/default.asp"&gt;very interesting article&lt;/A&gt; today.  One of the most interesting things I've read in the last several months.  I completely agree with Beck that the XP methodologies would work best and provide a nice process for solving the difficult problems of software development, but my experience has been that getting a "customer" is one of the most painfully difficult things there is.  In my experience, it's &lt;STRONG&gt;&lt;EM&gt;NEVER&lt;/EM&gt;&lt;/STRONG&gt; been successful for more than a few weeks.  I had lunch with some XPers from GSK (GalaxoSmithKline) a couple of weeks ago, and their experience mirrored mine.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-2607861262430488136?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/2607861262430488136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=2607861262430488136&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/2607861262430488136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/2607861262430488136'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/09/kent-beck-alan-cooper-smackdown.html' title='Kent Beck / Alan Cooper Smackdown'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-3336096626376961023</id><published>2006-09-20T22:13:00.000-04:00</published><updated>2006-09-20T22:14:24.902-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='software'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><title type='text'>Computer Science Challenge List</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Originally Posted On: 06/20/2005 03:05:45&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Several years ago, I found a document called &lt;a href="http://www.research.att.com/%7Edsj/nsflist.html"&gt;Challenges for Theoretical Computer Science&lt;/a&gt;.&amp;nbsp;&amp;nbsp;It describes a bunch of 'challenges' that haven't been solved in the computer science area.&amp;nbsp; The information written in this list is 5+ years old now, and it's amazing how many items on the list are still outstanding.&amp;nbsp; I don't claim to be able to understand all of the challenges (like 'Make Quantum Computing a Reality'), but there are a lot of them that apply directly to TDD methodoligies (like 'Software Specification').&amp;nbsp; It would be interesting to track this list (or one like it) over many years.&lt;br /&gt;&lt;/br&gt;&lt;br /&gt;I think it's useful to take a step back every once in a while and see where we've come, and where we're headed.&amp;nbsp; A couple of useful things can come out of it:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;Correction/Validataion of your current course.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Realization that most problems have been around longer than our recognition of them, and that some smart people may have spent time thinking about them. &lt;/li&gt;&lt;br /&gt;  &lt;li&gt;Insight into a problem outside of your current vicinity can give a great new angle on your immediate problem.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;New product ideas.&amp;nbsp; You may have the insight to solve some problem that nobody else has.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-3336096626376961023?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/3336096626376961023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=3336096626376961023&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/3336096626376961023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/3336096626376961023'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/09/computer-science-challenge-list.html' title='Computer Science Challenge List'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-3992811383253654722</id><published>2006-09-20T22:06:00.000-04:00</published><updated>2006-09-20T22:10:23.939-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><title type='text'>Mickey Mouse Show</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Originally Posted On: 06/17/2005 04:22:42&lt;/span&gt;&lt;br /&gt;Rob Selph commented to me that he liked the name of the blog, but that I should explain a little about the name.  My name is Mark Mackelprang, and with a last name like that, the blog name is pretty natural.&amp;nbsp; Growing up, it was intimidating to learn to spell an 11-character surname, so my older sister came up with a nice mnemonic trick to do it.  I just so happens that there are also 11 characters in the name "Mickey Mouse", and it just so happens that the cadence and flow of the letters is very similar if you sing the &lt;a href="http://www.walkthroughlife.com/midis/kidsmidis/mickeyms.mid"&gt;Mickey Mouse Club Theme Song&lt;/a&gt; with the letters of my last name (What's the surname we adore that's made for you and me? M - A - C - K - E - L - P - R - A - N - G...).  It's how I learned it, how my wife and kids learned it, and it's how I teach people I meet now to remember to spell it.  Songs are amazing tools for learning things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-3992811383253654722?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/3992811383253654722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=3992811383253654722&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/3992811383253654722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/3992811383253654722'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/09/mickey-mouse-show.html' title='Mickey Mouse Show'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-4664657968832389319</id><published>2006-09-20T21:34:00.000-04:00</published><updated>2006-09-20T21:37:59.455-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Namespace Refactoring</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Originally Posted On: 06/16/2005 12:05:04&lt;/span&gt;&lt;br /&gt;Over the last week or so, I've spend some time refactoring some namespaces in the C# codebase at work.  There were some things that had just been languishing in the wrong&lt;br /&gt;place for a long time.  We had a few days to spend cleaning up things that we normally have to live with, so this is one of the things we decided to fix.  Like any other refactoring, NS refactoring shouldn't change any system functionality, but just improve the overall design.  It's a lot like renaming a class, and maybe it boils down to the exact same thing in the end.  Luckily, this codebase is well covered with tests.  We have unit tests (class level functionality), acceptance tests (system or subsystem level functionality), and smoke tests (installation functionality).&lt;br /&gt;&lt;br /&gt;This process would have taken many times longer with much higher risks without the tests.  Even with these tests, there was plenty of pain to feel.  I'm a sharing kind of guy, so here's what hurt:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;  &lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;File Names&lt;/span&gt;&lt;/span&gt;:  Don't ever use a object type for any part of a configuration file, log (thanks to Andy Sipe for the catch here) file, etc.  For the actual code itself, there isn't a problem since all you have to do is rename the file.  Whenever the config or logfile depends on the namespace, however, there are several locations you have to go to fix things up again.  This bubbles through the system, and clear up to the install process.  For upgrades, there will be difficulties merging from old to new when configuration file names change from version to version.  For me, it helped to think about the fully qualified type as a unique ID in the db.  Whenever that ID is used for something other than identity, trouble follows.  The same is true for types. The rule here is name all files after their intended use, not after their location or namespace.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Object Identifiers&lt;/span&gt;&lt;/span&gt;: We used a persistable object layer to insulate the code from the db in the system.  When we implemented the object identifier subsystem, we had the object ID's generated from the type of the object.  This means that we had an OID table in the database, with type names in one of the columns.  This makes the design very resistant to NS refactoring, since it would require a db upgrade to change the code.  We ended up putting a mapping layer in the OID layer that takes a type and returns the "name" of the OID object to use.  For now, we're using the  "old" OID names to prevent an immediate database upgrade.  In a future refactoring, that's another thing we'll want to fix.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Configuration File Locations&lt;/span&gt;&lt;/span&gt;: Use the "once and only once" (DRY) principle ruthlessly when setting up config files.  We use VSS (don't start with me) and had originally shared various files between all of the projects that needed them.  After going through the process of NS refactoring, I believe the correct way to do this would be to store any shared configuration files in a single location, then make it part of the build process (NAnt) to copy the configuration file from the one location to the test location before running the test.  For files that are used only once, put them where they're used, but if they ever become shared, spend the time to put them in the single location, and change the build/test to get them there.&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Tests&lt;/span&gt;&lt;/span&gt;: Don't even try to do this over a large set of files without good tests around them.  The unit tests aren't really useful for this refactoring.  The compiler tells you most of the errors that are at this level.  The acceptance tests are good since they pull all the parts of the system together, but they can be fairly long running (some of ours take many minutes to run).  The best tests for this kind of refactoring are the smoke tests.  These validate the installation for the various end products, and generally only take a few seconds to run for each one (plus file copy &amp;amp; startup time).&lt;/li&gt;&lt;br /&gt;  &lt;li&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;: Overall I think this kind of maintenance should be a regular activity.&amp;nbsp; Company names change, the overall design change.&amp;nbsp; Failure to update the NS is another "broken window" or "smell" that Andy Hunt and Dave Thomas mention in their Pragmatic Programming book.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-4664657968832389319?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/4664657968832389319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=4664657968832389319&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/4664657968832389319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/4664657968832389319'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/09/namespace-refactoring.html' title='Namespace Refactoring'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-15487481.post-115869431078233190</id><published>2006-09-19T15:30:00.000-04:00</published><updated>2006-09-19T15:31:50.783-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='admin'/><title type='text'>Trying out Blogger...</title><content type='html'>Instead of hosting my blog on my home computer, I'm seriously thinking about simplifying things and using Blogger.  We'll see how hard it is to import everything into it before I make any permanent decisions...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/15487481-115869431078233190?l=mackelwhat.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mackelwhat.blogspot.com/feeds/115869431078233190/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=15487481&amp;postID=115869431078233190&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/115869431078233190'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/15487481/posts/default/115869431078233190'/><link rel='alternate' type='text/html' href='http://mackelwhat.blogspot.com/2006/09/instead-of-hosting-my-blog-on-my-home.html' title='Trying out Blogger...'/><author><name>Mark Mackelprang</name><uri>http://www.blogger.com/profile/16045229021564564591</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
