<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:blogChannel="http://backend.userland.com/blogChannelModule" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
  <channel>
    <title>Clear Lines Blog</title>
    <description>Mathias Brandewinder on quantitative analysis, .NET applications, Excel, decision making, and a whole lot of other random things.</description>
    <link>http://www.clear-lines.com/blog/</link>
    <docs>http://www.rssboard.org/rss-specification</docs>
    <generator>BlogEngine.NET 1.5.1.14</generator>
    <language>en-GB</language>
    <blogChannel:blogRoll>http://www.clear-lines.com/blog/opml.axd</blogChannel:blogRoll>
    <blogChannel:blink>http://www.dotnetblogengine.net/syndication.axd</blogChannel:blink>
    <dc:creator>Mathias Brandewinder, Clear Lines Consulting</dc:creator>
    <dc:title>Clear Lines Blog</dc:title>
    <geo:lat>0.000000</geo:lat>
    <geo:long>0.000000</geo:long>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/ClearLinesBlog" type="application/rss+xml" /><feedburner:emailServiceId xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">ClearLinesBlog</feedburner:emailServiceId><feedburner:feedburnerHostname xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><item>
      <title>Two level horizontal menu for ASP.NET</title>
      <description>&lt;p&gt;When I decided to have a 2-level horizontal menu for my professional webpage in ASP.NET, it came as a surprise to me that this wasn’t completely straightforward. I expected the standard&amp;#160; ASP menu control to support this, but found out that this wasn’t the case.&lt;/p&gt;  &lt;p&gt;Fortunately, I came across a post by &lt;a href="http://peterkellner.net/2009/03/27/codecampwebsiteseries6-cssfriendly-adapters-aspnet-menu/"&gt;Peter Kellner&lt;/a&gt;, describing how he implemented that for the &lt;a href="http://www.siliconvalley-codecamp.com/Default.aspx"&gt;Silicon Valley Code Camp website&lt;/a&gt;, which was pretty much what I envisioned.&lt;/p&gt;  &lt;p&gt;The one issue I had with his implementation, however, was that the second level menu uses multiple data sources. The Master Page handles the top-level menu, but each page contains a reference to the specific datasource used to populate the sub-menu. As a result, if you decide to add a page, you need to manually add to that page some code to define what sub-menu should show up, which is cumbersome.&lt;/p&gt;  &lt;p&gt;The ideal solution for a lazy developer like me would be to have all the menus handled in the Master Page, so that when you add a new page to your website, you just need to add it to the Sitemap, and the right menu and sub-menu shows up.&lt;/p&gt;  &lt;p&gt;After some tinkering about, I figured out how to get this done. The trick is to use the Attribute StartingNodeOffset of the SiteMapDataSource.&lt;/p&gt;  &lt;p&gt;I used the CSSFriendlyModified.dll Peter presents in his code sample, but modified the MasterPage, which looks like this:&lt;/p&gt;  &lt;pre class="brush: csharp;"&gt;&amp;lt;div id=&amp;quot;Navigation&amp;quot;&amp;gt;
    &amp;lt;asp:SiteMapDataSource ID=&amp;quot;SiteMapMain&amp;quot; runat=&amp;quot;server&amp;quot; 
    showStartingNode=&amp;quot;False&amp;quot;/&amp;gt;
    &amp;lt;div class=&amp;quot;MainMenuSection&amp;quot;&amp;gt;
        &amp;lt;asp:Menu ID=&amp;quot;MainMenu&amp;quot; runat=&amp;quot;server&amp;quot; DataSourceID=&amp;quot;SiteMapMain&amp;quot;
        MaximumDynamicDisplayLevels=&amp;quot;0&amp;quot; Orientation=&amp;quot;Horizontal&amp;quot;&amp;gt;
        &amp;lt;/asp:Menu&amp;gt;
    &amp;lt;/div&amp;gt;
               
    &amp;lt;asp:SiteMapDataSource ID=&amp;quot;SiteMapSecondLevel&amp;quot; runat=&amp;quot;server&amp;quot; 
    showStartingNode=&amp;quot;False&amp;quot; 
    StartingNodeOffset=&amp;quot;1&amp;quot;/&amp;gt;
    &amp;lt;div class=&amp;quot;SecondaryMenuSection&amp;quot;&amp;gt;
        &amp;lt;asp:Menu ID=&amp;quot;SecondaryMenu&amp;quot; runat=&amp;quot;server&amp;quot; 
        DataSourceID=&amp;quot;SiteMapSecondLevel&amp;quot; 
        Orientation=&amp;quot;Horizontal&amp;quot; /&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;&lt;/pre&gt;

&lt;p&gt;The first block (SiteMapMain and MainMenu) declare what DataSource to use for the top-level menu (the SiteMap), and is pretty much identical to Peter’s code.&lt;/p&gt;

&lt;p&gt;The second block declares a second DataSource (SiteMapSecondLevel), which hooks up to the SiteMap. Note the difference with the first DataSource: StartingNodeOffset is set to 1, which essentially tells the DataSource to look one level down in the nodes hierarchy of the SiteMap. The sub-menu “SecondaryMenu” simply uses that DataSource, regardless of the page.&lt;/p&gt;

&lt;p&gt;As a result, now there is no need to add any code for pages to handle the second level menu. As long as a page is listed in the SiteMap, and hooked to the MasterPage, it will automatically populate the second level menu with the nodes that are listed under the top-level node. You can see that in action on &lt;a href="http://www.clear-lines.com/akin.aspx"&gt;this page&lt;/a&gt;, for instance. Enjoy!&lt;/p&gt;

&lt;p&gt;And, give credit where credit is due - thanks a million for Peter Kellner – his code was a total life-saver.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5sNed1tocMbJiFEcMvFF12pO5R4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5sNed1tocMbJiFEcMvFF12pO5R4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5sNed1tocMbJiFEcMvFF12pO5R4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5sNed1tocMbJiFEcMvFF12pO5R4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=yOmyLgV3Z5g:9TrVPVXPNJo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=yOmyLgV3Z5g:9TrVPVXPNJo:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=yOmyLgV3Z5g:9TrVPVXPNJo:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=yOmyLgV3Z5g:9TrVPVXPNJo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=yOmyLgV3Z5g:9TrVPVXPNJo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=yOmyLgV3Z5g:9TrVPVXPNJo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=yOmyLgV3Z5g:9TrVPVXPNJo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/Two-level-horizontal-menu-for-ASPNET.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/Two-level-horizontal-menu-for-ASPNET.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=a33cdb0c-29c7-4a25-98a0-fb081f0521cc</guid>
      <pubDate>Fri, 06 Nov 2009 15:48:48 -1300</pubDate>
      <category>Web Development</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=a33cdb0c-29c7-4a25-98a0-fb081f0521cc</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=a33cdb0c-29c7-4a25-98a0-fb081f0521cc</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/Two-level-horizontal-menu-for-ASPNET.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=a33cdb0c-29c7-4a25-98a0-fb081f0521cc</wfw:commentRss>
    </item>
    <item>
      <title>Excel ScatterPlot with labels, colors and markers</title>
      <description>&lt;p&gt;Recently, a client asked me if it was possible to create an Excel scatter plot of his products, adding a label on each data point, and using different colors and symbols for different types of products. You could think of this as plotting 5 dimensions at once, instead of the usual two.&lt;/p&gt;  &lt;p&gt;I quickly coded a VBA macro to do that, with a &lt;a onclick="javascript: pageTracker._trackPageview(&amp;#39;/downloads/PowerScatterPlot&amp;#39;); " href="http://www.clear-lines.com/downloads/PowerScatterPlot/PowerScatterPlot.xls"&gt;sample workbook&lt;/a&gt; to illustrate the usage. The macro is pretty rough, but was sufficient for my needs as is, so I haven’t put extra efforts in: feel free to improve upon it…&lt;/p&gt;  &lt;p&gt;Here is a sample of the output:&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/ExcelScatterPlotwithlabelscolorsandmarke/5E677B23/PowerScatterPlot.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PowerScatterPlot" border="0" alt="PowerScatterPlot" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/ExcelScatterPlotwithlabelscolorsandmarke/1C1462E0/PowerScatterPlot_thumb.png" width="545" height="362" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;To use it, you will need to enter the values for the chart in 5 columns, anywhere in the worksheet. Columns 1 and 2 contain the X and Y values for the scatter plot, column 3 the labels you want to add to each data point, column 4 and 5 are integers which represent the code for the marker symbol and color for the data point. Columns 4 and 5 are clearly not an elegant solution, and you’ll probably have to play with the values until you find what you want.&lt;/p&gt;  &lt;p&gt;Note that you have to fill in all fields, for every point of the chart.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/ExcelScatterPlotwithlabelscolorsandmarke/5A99B086/PowerScatterPlotUsage.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="PowerScatterPlotUsage" border="0" alt="PowerScatterPlotUsage" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/ExcelScatterPlotwithlabelscolorsandmarke/12D8279F/PowerScatterPlotUsage_thumb.png" width="460" height="237" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Once you have your data, simply select the entire range, all 5 columns of it, not including the headers, and click the “Generate ScatterPlot” button – et voila! &lt;/p&gt;  &lt;p&gt;&lt;a onclick="javascript: pageTracker._trackPageview(&amp;#39;/downloads/PowerScatterPlot&amp;#39;); " href="http://www.clear-lines.com/downloads/PowerScatterPlot/PowerScatterPlot.xls"&gt;Download the ScatterPlot Workbook.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5l4B1GKvcRpI9Q2Z11C7iB8HYxM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5l4B1GKvcRpI9Q2Z11C7iB8HYxM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5l4B1GKvcRpI9Q2Z11C7iB8HYxM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5l4B1GKvcRpI9Q2Z11C7iB8HYxM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=ljwh8xiXn9Q:UWAofrrzEoA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=ljwh8xiXn9Q:UWAofrrzEoA:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=ljwh8xiXn9Q:UWAofrrzEoA:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=ljwh8xiXn9Q:UWAofrrzEoA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=ljwh8xiXn9Q:UWAofrrzEoA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=ljwh8xiXn9Q:UWAofrrzEoA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=ljwh8xiXn9Q:UWAofrrzEoA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/Excel-ScatterPlot-with-labels-colors-and-markers.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/Excel-ScatterPlot-with-labels-colors-and-markers.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=97f00545-339c-4e34-9cad-f3af11484eeb</guid>
      <pubDate>Thu, 29 Oct 2009 10:05:54 -1300</pubDate>
      <category>Excel</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=97f00545-339c-4e34-9cad-f3af11484eeb</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=97f00545-339c-4e34-9cad-f3af11484eeb</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/Excel-ScatterPlot-with-labels-colors-and-markers.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=97f00545-339c-4e34-9cad-f3af11484eeb</wfw:commentRss>
    </item>
    <item>
      <title>Read the contents of a worksheet with C#</title>
      <description>&lt;p&gt;When working with Excel workbooks with C#, I often need to retrieve the entire contents of a particular worksheet, so that I can process the data within C# code. By “the entire contents”, I mean the content of every cell between cell A1 and the &lt;a href="http://clear-lines.com/blog/post/The-Last-Cell-in-an-Excel-Worksheet.aspx"&gt;last cell of the sheet&lt;/a&gt;, that is, the cell such that there is no cell on its right or below it that contains anything.&lt;/p&gt;  &lt;p&gt;To do this, I use the following code, where excelWorksheet is a Worksheet (duh):&lt;/p&gt;  &lt;pre class="c#" name="code"&gt;Excel.Range firstCell = excelWorksheet.get_Range(&amp;quot;A1&amp;quot;, Type.Missing);
Excel.Range lastCell = excelWorksheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);

object[,] cellValues;
object[,] cellFormulas;

Excel.Range worksheetCells = excelWorksheet.get_Range(firstCell, lastCell);
cellValues = worksheetCells.Value2 as object[,];
cellFormulas = worksheetCells.Formula as object[,];&lt;/pre&gt;

&lt;p&gt;The 2 resulting arrays of objects, cellValues and cellFormulas, contain the values and formulas, or null if the cell has no content.&lt;/p&gt;

&lt;p&gt;However, while I was working on &lt;a href="http://www.clear-lines.com/akin.aspx"&gt;Akin&lt;/a&gt; recently, I realized 2 interesting things I had never noted before. First, the resulting array is 1-based, even though “&lt;a href="http://msdn.microsoft.com/en-us/library/aa288453(VS.71).aspx"&gt;C# arrays are zero indexed&lt;/a&gt;; that is, the array indexes start at zero”. Then, this code will fail if your spreadsheet contains only one value, in cell A1.&lt;/p&gt;

&lt;p&gt;To prove my point, here is a snapshot of a QuickWatch of the cellValues array, reading a small spreadsheet. As you can see, the indexing begins at indexes 1 and 1.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/ReadthecontentsofaworksheetwithC/4B6C9605/OneBasedArray.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="OneBasedArray" border="0" alt="OneBasedArray" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/ReadthecontentsofaworksheetwithC/03AB0D1E/OneBasedArray_thumb.png" width="398" height="257" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;It isn’t especially difficult to handle, but it really came as a surprise to me. Once you got used to zero-based indexes, which are pretty much the norm in .NET, this really is an intriguing oddity.&lt;/p&gt;

&lt;p&gt;Once I realized this, I based all my code on the assumption that the array was going to be one-based, and everything went fine, until I realized that the following line was throwing an exception when the worksheet contained only a single populated cell in A1:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;cellValues = worksheetCells.Value2 as object[,];&lt;/pre&gt;

&lt;p&gt;If you want to keep the same code, returning a 2-dimensional array, you have to handle that special case slightly differently, along the lines of:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;if (lastCell.Row == 1 &amp;amp;&amp;amp; lastCell.Column == 1)
{
    cellValues = new object[1,1];
    cellFormulas = new object[1,1];
    cellValues[0, 0] = firstCell.Value2;
    cellFormulas[0, 0] = firstCell.Formula;
}&lt;/pre&gt;

&lt;p&gt;But now this creates its own particular problem, because cellValues and cellFormulas are of course 0-based. I looked around and couldn’t find a way to declare a one-based array in C# (does anyone know if this is feasible?), so your best options are to either transform the array obtained in the standard case into a 0-based array, or, much less elegant, read the “special case” into a 0-based array which can be read through as a 1-based array:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;if (lastCell.Row == 1 &amp;amp;&amp;amp; lastCell.Column == 1)
{
    cellValues = new object[2,2];
    cellFormulas = new object[2,2];
    cellValues[1, 1] = firstCell.Value2;
    cellFormulas[1, 1] = firstCell.Formula;
}&lt;/pre&gt;
I am frankly a bit torn between the 2 approaches. On the one hand, I feel much more comfortable working with a standard, 0-based array. On the other hand, while I strongly dislike having a method which returns sometimes a non-standard 1-based array, and sometimes a 0-based array but should be handled as a 1-based array (just describing this makes me queasy), it seems counter-productive to incur the cost of transforming a larger array most of the times, for the sake of the one-cell case, which is clearly an unusual boundary case. I’ll let you decide how you want to handle this!
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wMjA0oPuNd65-rZ_XRFV2VgsRRI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wMjA0oPuNd65-rZ_XRFV2VgsRRI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wMjA0oPuNd65-rZ_XRFV2VgsRRI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wMjA0oPuNd65-rZ_XRFV2VgsRRI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=mZNVD10Y6Ng:lujChqSfEZo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=mZNVD10Y6Ng:lujChqSfEZo:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=mZNVD10Y6Ng:lujChqSfEZo:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=mZNVD10Y6Ng:lujChqSfEZo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=mZNVD10Y6Ng:lujChqSfEZo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=mZNVD10Y6Ng:lujChqSfEZo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=mZNVD10Y6Ng:lujChqSfEZo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/Read-the-contents-of-a-worksheet-with-C.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/Read-the-contents-of-a-worksheet-with-C.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=2a442caa-13eb-488c-9fb3-3c54cecf5420</guid>
      <pubDate>Tue, 20 Oct 2009 10:46:18 -1300</pubDate>
      <category>.NET</category>
      <category>Excel</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=2a442caa-13eb-488c-9fb3-3c54cecf5420</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=2a442caa-13eb-488c-9fb3-3c54cecf5420</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/Read-the-contents-of-a-worksheet-with-C.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=2a442caa-13eb-488c-9fb3-3c54cecf5420</wfw:commentRss>
    </item>
    <item>
      <title>The Art of Unit Testing</title>
      <description>&lt;a href="http://www.manning.com/osherove/"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="TheArtOfUnitTesting" border="0" alt="TheArtOfUnitTesting" align="left" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/TheArtofUnitTesting/256422A3/TheArtOfUnitTesting.jpg" width="154" height="190" /&gt;&lt;/a&gt;   &lt;p&gt;I recently finished reading &lt;a href="http://www.manning.com/osherove/"&gt;the Art of Unit Testing&lt;/a&gt;, by &lt;a href="http://weblogs.asp.net/rosherove/default.aspx"&gt;Roy Osherove&lt;/a&gt; (Manning); here are a few thoughts on the book.&lt;/p&gt;  &lt;h1&gt;Who to give it too&lt;/h1&gt;  &lt;p&gt;This is an &lt;strong&gt;excellent&lt;/strong&gt; book for the C# developer with solid foundations in object-oriented design, who has already some exposure to writing unit tests. If you have worked on a decent-scale project, and found yourself thinking “hmmm, I am sure there is a smarter way to write these tests”, you should definitely get that book. Note that while it will be extremely useful to the test-driven development practitioner, this is NOT a book on TDD.&lt;/p&gt;  &lt;h1&gt;3 things I liked about it&lt;/h1&gt;  &lt;p&gt;&lt;strong&gt;Writing maintainable tests&lt;/strong&gt;: this topic has its own chapter, but you could argue that it is the underlying theme of the book, and Osherove does a great job covering what to look for in a test, and why. I really loved this part. &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Design for testability&lt;/strong&gt;: Osherove presents various refactoring approaches to make code more testable, and goes into it some more in an appendix. Besides the fact that this is a very important topic, I found this part of the book very stimulating, because, as is usually the case for design questions, the answers are not clear cut, and Osherove discusses the pros and cons very honestly.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Mocks and Stubs&lt;/strong&gt;: not surprisingly, Osherove gives a very good exposition to isolation. I really liked that before going into specific frameworks, he takes the time to show how one would roll stubs and mocks manually. This is very helpful: it focuses the attention on why a mock is needed, and avoids the distraction that the framework syntax can be – and only then introduces the frameworks, showing how they simply reduce the amount of repetitive work needed, and how to use them. This is one of the clearest explanations on stubs and mocks I have seen so far (thank you!).&lt;/p&gt;  &lt;h1&gt;3 ways to make me happier&lt;/h1&gt;  &lt;p&gt;&lt;strong&gt;Keep the example straight&lt;/strong&gt;: the LogAnalyzer class is used throughout chapter 2 and 3 as an example. In chapter 2, it is used how to unit test a feature which validates whether a file name is valid, based on the file extension. In chapter 3, however, the same feature is still there, but somehow another rule has mysteriously been added – in addition to the extension, the file name is also supposed to be longer than 5 characters. The code isn’t very complex, but I think the chapter would have gained clarity by either keeping the same example throughout, or by clearly exposing in the beginning of chapter 3 what the feature was, and which class was responsible for it.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Code layout&lt;/strong&gt;: two small layout gripes. First , the indentation of the code is odd. The curly braces which open and close the class definition are indented with a tab space, the attribute are not aligned with the name of the class… Minor things, but displeasing to the eye. Then, it would be nice if the code examples were entirely on the same page. They are short enough that it seems it should be possible, and having the code visible in its entirety without needing to turn pages back and forth would be nice. On the plus side, I like the annotations/comment of the code.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;Arrange, Act, Assert&lt;/strong&gt;: I wish the section on AAA was a bit more developed. This is of course a matter of opinion, but I find this approach much clearer than record/replay – and it also seems that’s where most isolation frameworks are headed. I would have liked more guidance on this pattern / style - maybe using this as the default would be beneficial.&lt;/p&gt;  &lt;h1&gt;Final thoughts&lt;/h1&gt;  &lt;p&gt;As should be clear from the previous paragraphs, I really liked this book, and wish it had been available to me earlier. My experience with unit testing has gone through phases. When I came across Test-Driven Development, I began writing unit tests – lots and lots of them. This worked very well for the type of code I was writing, and I embraced unit testing with enthusiasm. But over time, I came to realize that, just like for “regular” code, it took work and experience to write maintainable tests, and learnt the hard way that some things worked well and some, not so well.&lt;/p&gt;  &lt;p&gt;This is where the book shines. Every problem I encountered is listed in here, and some more, of course; the book provides a solid frame to write better, more maintainable tests, as well as guidance on how to better integrate them in the process and the organization.&lt;/p&gt;  &lt;p&gt;That being said, I think that maintenance is a bit of an abstract concept. Until you had to maintain a real-size project, it is hard to fully grasp what maintainable code is, and why it is so important – and the same goes for tests. While I am sure this book would have helped me avoid pitfalls in my early attempts at writing good unit tests, I would probably have missed some of the points the book is making, not because there are complex, but because I would not have understood how they applied.&lt;/p&gt;  &lt;p&gt;For that reason, I really recommend “the Art of Unit Testing” to the more seasoned developer. It will be an excellent companion, and will help bring your unit-testing game to the next level. If you are just getting started with unit testing, I would recommend starting with something else, like Kent Beck’s “Test Driven Development, by Example”, because it might give you a better sense of how to “do” things, and what it feels like to develop code and unit tests together.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ywZw-tXnFH5bInazmDa0Mxu96nY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ywZw-tXnFH5bInazmDa0Mxu96nY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ywZw-tXnFH5bInazmDa0Mxu96nY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ywZw-tXnFH5bInazmDa0Mxu96nY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0dSdw0cFH4U:OgcJQ3bxAG4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0dSdw0cFH4U:OgcJQ3bxAG4:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=0dSdw0cFH4U:OgcJQ3bxAG4:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0dSdw0cFH4U:OgcJQ3bxAG4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=0dSdw0cFH4U:OgcJQ3bxAG4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0dSdw0cFH4U:OgcJQ3bxAG4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=0dSdw0cFH4U:OgcJQ3bxAG4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/The-Art-of-Unit-Testing.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/The-Art-of-Unit-Testing.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=c7c01ab4-0462-41f3-8542-5dab693b6341</guid>
      <pubDate>Thu, 15 Oct 2009 18:03:47 -1300</pubDate>
      <category>Reviews</category>
      <category>Design and Patterns</category>
      <category>.NET</category>
      <category>Software development</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=c7c01ab4-0462-41f3-8542-5dab693b6341</pingback:target>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=c7c01ab4-0462-41f3-8542-5dab693b6341</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/The-Art-of-Unit-Testing.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=c7c01ab4-0462-41f3-8542-5dab693b6341</wfw:commentRss>
    </item>
    <item>
      <title>VSTO add-in with multiple assemblies</title>
      <description>&lt;p&gt;I just found a solution to an issue which has been bothering me for a while. The reference article by Microsoft which describes how to deploy a &lt;a href="http://msdn.microsoft.com/en-us/library/aa537179(office.11).aspx"&gt;Visual Studio 2005 Tools for Office&lt;/a&gt; solution using Windows Installer (a life-saver) doesn’t say anything about how to grant trust to multiple assemblies. This is a problem if you want to use satellite dlls in your add-in.&lt;/p&gt;  &lt;p&gt;I figured out a &lt;a href="http://clear-lines.com/blog/post/VSTO-Add-In-installation-woes.aspx"&gt;workaround&lt;/a&gt; a while back, but I wasn’t convinced this was a good solution. Today, I came across &lt;a href="http://social.msdn.microsoft.com/forums/en-US/vsto/thread/cec6abb6-4716-4bde-91f2-25fb68abd54e/"&gt;this thread&lt;/a&gt;, where the second post (by Lex007) describes a simple way to do that, by modifying the SetSecurity project. Instead of passing only one dll, the tweak allows to pass a comma-separated list of dlls. I just tried it out, and it works like a charm.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/EGbV7uX7Vl1cHIWzje-4ZkRaXqo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EGbV7uX7Vl1cHIWzje-4ZkRaXqo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/EGbV7uX7Vl1cHIWzje-4ZkRaXqo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/EGbV7uX7Vl1cHIWzje-4ZkRaXqo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=TF36zZeMAmQ:dtL1B76FaKk:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=TF36zZeMAmQ:dtL1B76FaKk:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=TF36zZeMAmQ:dtL1B76FaKk:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=TF36zZeMAmQ:dtL1B76FaKk:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=TF36zZeMAmQ:dtL1B76FaKk:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=TF36zZeMAmQ:dtL1B76FaKk:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=TF36zZeMAmQ:dtL1B76FaKk:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/VSTO-add-in-with-multiple-assemblies.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/VSTO-add-in-with-multiple-assemblies.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=2790101f-c00d-4b34-b037-fd768cf2f9b8</guid>
      <pubDate>Mon, 12 Oct 2009 10:54:03 -1300</pubDate>
      <category>Excel</category>
      <category>.NET</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=2790101f-c00d-4b34-b037-fd768cf2f9b8</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=2790101f-c00d-4b34-b037-fd768cf2f9b8</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/VSTO-add-in-with-multiple-assemblies.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=2790101f-c00d-4b34-b037-fd768cf2f9b8</wfw:commentRss>
    </item>
    <item>
      <title>Duct tape post-mortem</title>
      <description>&lt;p&gt;Much ado on the interwebs has followed Joel’s recent post on the now-infamous &lt;a href="http://www.joelonsoftware.com/items/2009/09/23.html"&gt;Duct Tape Programmer&lt;/a&gt;. You have to give it to Joel, he has a talent for writing pieces which get lots of people really worked up – what in some circles is called &lt;a href="http://www.urbandictionary.com/define.php?term=troll"&gt;trolling&lt;/a&gt;. Out of curiosity, I looked up Google Trends, and unless some other piece of hot news related to duct tape surfaced on Sept 23rd, you can see with your naked eye the amount of buzz this one single post managed to generate. Impressive.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/0940692a3085/50BBA425/DuctTape.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="DuctTape" border="0" alt="DuctTape" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/0940692a3085/283CC211/DuctTape_thumb.png" width="603" height="439" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;At that point I think the question of whether design patterns are an evil over-engineering practice has been discussed to death, by people much more qualified than me. For what it’s worth, I think Joel’s position has merits, to a point. There &lt;strong&gt;IS&lt;/strong&gt; a natural tendency for developers to over-engineer, and I believe it’s a good practice when designing something to keep a dialogue going between two guiding voices: &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;“how should I design this, if I was not under time or budget constraint?”&lt;/p&gt;    &lt;p&gt;“what’s the easiest solution which would get the job done?”&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&lt;a href="http://www.dartmouthindependent.com/archives/Tug-O-War.jpg"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Tug-O-War" border="0" alt="Tug-O-War" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/0940692a3085/66C20FB7/TugOWar.jpg" width="414" height="281" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;em&gt;From &lt;/em&gt;&lt;em&gt;&lt;a href="http://www.dartmouthindependent.com/"&gt;http://www.dartmouthindependent.com/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;One of the issue I have with the glorification of the Duct Tape Programmer is that Duct Tape programming is defined as a negative: to be a Duct Tape programmer, you should&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;avoid C++, templates, multiple inheritance, multithreading, COM, CORBA, and a host of other technologies that are all totally reasonable, when you think long and hard about them, but are, honestly, just a little bit too hard for the human brain&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So how do you become a Duct Tape Programmer? Well, you don’t.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Duct tape programmers have to have a lot of talent to pull off this shtick. They have to be good enough programmers to ship code, and we’ll forgive them if they never write a unit test&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is where I take issue with Joel’s post. In essence, what he is saying is that some people are just so good at what they are doing that no matter how many rules they break, they will smoke your best effort - and that he likes these guys because they are good. That’s obvious – and it’s also both useless and dangerous. Even if you are a genius, you should start by mastering the classics – and then you can start breaking the rules. If you want to become a better software engineer, go study patterns, unit testing, and learn as much as you can. And then, once you &lt;a href="http://en.wikipedia.org/wiki/Outliers_(book)"&gt;clocked in your 10,000 hours&lt;/a&gt;, go ahead: pick your tools, and chose what to do and what to ignore.&lt;/p&gt;  &lt;p&gt;I came across Joel a long time ago, through the &lt;a href="http://www.joelonsoftware.com/articles/fog0000000043.html"&gt;Joel Test&lt;/a&gt;. This post was at the time tremendously useful to me, because it provided simple and actionable guidance on what to aim for to establish good practices for my software team. It was good advice on where to start to get better. This Duct Tape Programmer business is doing exactly the opposite. I wish Joel went back to constructive advice – and in the meanwhile, take that duct tape roll out of the software engineering best practices room, and bring it back where it belongs, the garage. But before that, maybe take a strip to close this discussion?&lt;/p&gt;  &lt;p&gt;&lt;a href="http://failblog.org/2009/10/10/duct-tape-illustration-fail/"&gt;&lt;img class="mine_2697090816" title="epic-fail-duct-tape-fail" alt="epic fail pictures" src="http://failblog.wordpress.com/files/2009/10/epic-fail-duct-tape-fail.jpg" /&gt;&lt;/a&gt;    &lt;br /&gt;see more &lt;a href="http://failblog.org"&gt;Epic Fails&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/YQQrO22LgawDylvT5e-Mgwl-lc0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YQQrO22LgawDylvT5e-Mgwl-lc0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/YQQrO22LgawDylvT5e-Mgwl-lc0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YQQrO22LgawDylvT5e-Mgwl-lc0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=_tFF-B5bp2s:T6NaLdKtI0M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=_tFF-B5bp2s:T6NaLdKtI0M:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=_tFF-B5bp2s:T6NaLdKtI0M:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=_tFF-B5bp2s:T6NaLdKtI0M:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=_tFF-B5bp2s:T6NaLdKtI0M:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=_tFF-B5bp2s:T6NaLdKtI0M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=_tFF-B5bp2s:T6NaLdKtI0M:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/Duct-tape-post-mortem.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/Duct-tape-post-mortem.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=6bac428c-678f-45e2-8be0-28cfbb2e31be</guid>
      <pubDate>Sat, 10 Oct 2009 07:36:02 -1300</pubDate>
      <category>Design and Patterns</category>
      <category>Software development</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=6bac428c-678f-45e2-8be0-28cfbb2e31be</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=6bac428c-678f-45e2-8be0-28cfbb2e31be</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/Duct-tape-post-mortem.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=6bac428c-678f-45e2-8be0-28cfbb2e31be</wfw:commentRss>
    </item>
    <item>
      <title>I survived another SVCC iteration</title>
      <description>&lt;p&gt;&lt;a href="http://www.siliconvalley-codecamp.com/"&gt;Silicon Valley Code Camp&lt;/a&gt; version 4.0 took place this week-end, and was a big success, judging by the numbers and the happy faces. Congratulations to &lt;a href="http://peterkellner.net/"&gt;Peter Kellner&lt;/a&gt; and the team for a tremendous organization!&lt;/p&gt;  &lt;p&gt;Personally, I wanted to give a big thank-you to the people who attended my session on Test-Driven Development – and for bearing with my voice, which was pretty shaky. I got sick this week and wasn’t sure until Saturday evening if I could do it, because on Thursday my voice was totally gone. I think I had more herbal tea with honey this week than in my entire life, but you guys made it all worth it: I had a great time giving my presentation, and you guys rocked!&lt;/p&gt;  &lt;p&gt;As I said during the session, the theory behind TDD is pretty succinct, so there isn’t much in the slides themselves worth posting. Instead, I thought I would list a few pointers:&lt;/p&gt;  &lt;p&gt;NUnit: you can find it &lt;a href="http://www.nunit.org"&gt;here&lt;/a&gt;. I recommend checking out the &lt;a href="http://www.nunit.org/index.php?p=quickStart&amp;amp;r=2.5.2"&gt;Quick Start&lt;/a&gt; page, which covers most of what you need to start writing unit tests. I have written a post on &lt;a href="http://clear-lines.com/blog/post/Data-driven-tests-with-NUnit-25.aspx"&gt;data-driven tests&lt;/a&gt; here.&lt;/p&gt;  &lt;p&gt;While we are talking about tools, I haven’t presented it during the session, but I really like &lt;a href="http://testdriven.net/"&gt;TestDriven.Net&lt;/a&gt;. There is a free community version for your personal use. It’s a Visual Studio add-on which allows you to run and debug your tests from Visual Studio.&lt;/p&gt;  &lt;p&gt;Even though it’s a Java book, and this session was for .NET developers, I really recommend &lt;a href="http://www.threeriversinstitute.org/Kent%20Beck.htm"&gt;Kent Beck&lt;/a&gt;’s book &lt;a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530"&gt;Test-Driven Development by Example&lt;/a&gt;. It’s very easy to read, and will get you started on the right foot. It’s also very well written – one of my favorite books!&lt;/p&gt;  &lt;p&gt;The other book I recommend is the &lt;a href="http://www.artofunittesting.com/"&gt;Art of Unit Testing&lt;/a&gt;, by &lt;a href="http://weblogs.asp.net/rosherove/"&gt;Roy Osherove&lt;/a&gt;. I just finished it, and I wish I had it with me a few years ago, when I began writing tests seriously :) The book is technically about unit testing and not TDD, and it is a .NET book. I highly recommend it, it is chock-full of good advice, and covers way more than just testing.&lt;/p&gt;  &lt;p&gt;That’s it! If you are interested in either the slides or code, let me know, and I’ll gladly post them, too. In the meanwhile, thanks again for coming, and… happy testing!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/L174S5ndcc0N99RzuGUlu10COvs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/L174S5ndcc0N99RzuGUlu10COvs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/L174S5ndcc0N99RzuGUlu10COvs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/L174S5ndcc0N99RzuGUlu10COvs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=qr5HOKnyyYE:2UmTMQE-1CA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=qr5HOKnyyYE:2UmTMQE-1CA:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=qr5HOKnyyYE:2UmTMQE-1CA:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=qr5HOKnyyYE:2UmTMQE-1CA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=qr5HOKnyyYE:2UmTMQE-1CA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=qr5HOKnyyYE:2UmTMQE-1CA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=qr5HOKnyyYE:2UmTMQE-1CA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/I-survived-another-SVCC-iteration.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/I-survived-another-SVCC-iteration.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=b8003f8d-afef-440f-a92f-97feded989ef</guid>
      <pubDate>Tue, 06 Oct 2009 06:09:23 -1300</pubDate>
      <category>Software development</category>
      <category>.NET</category>
      <category>Design and Patterns</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=b8003f8d-afef-440f-a92f-97feded989ef</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=b8003f8d-afef-440f-a92f-97feded989ef</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/I-survived-another-SVCC-iteration.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=b8003f8d-afef-440f-a92f-97feded989ef</wfw:commentRss>
    </item>
    <item>
      <title>Akin 0.5.0 released</title>
      <description>&lt;p&gt;The current version of Akin, my &lt;a href="http://www.clear-lines.com/akin.aspx"&gt;free Excel worksheet comparison&lt;/a&gt; application, has been out for a bit now, and people have sent me some interested suggestions on how to make it better. However, my biggest personal issue so far has been speed. Opening large file hasn’t been an issue, but displaying comparisons of large worksheets (say, 200 x 200 cells) was taking a long time. The typical user for Akin is likely to be working with large files (tracking differences wouldn’t be an issue otherwise), so I had to do something about it.&lt;/p&gt;  &lt;p&gt;I have bitten the bullet – I &lt;a href="http://www.clear-lines.com/blog/post/Movement-is-relative.aspx"&gt;changed the design&lt;/a&gt;, and completely re-wrote the user interface where the comparison is displayed, and I hope that you will be pleased with the performance improvement. Where a 200 x 200 cells comparison took over 20 seconds to display, a 500 x 500 cells comparison is now virtually instantaneous. While I was at it, I did some cosmetic improvements on the looks as well.&lt;/p&gt;  &lt;p&gt;You can &lt;a href="http://clear-lines.com/Akin.aspx"&gt;download the new version here&lt;/a&gt;. Now that this performance problem is out of the way, I can get back to implementing the features that have been suggested so far. Stay tuned!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/jmoyNlYbyLY7uv2qzFYetVwiSzQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jmoyNlYbyLY7uv2qzFYetVwiSzQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/jmoyNlYbyLY7uv2qzFYetVwiSzQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jmoyNlYbyLY7uv2qzFYetVwiSzQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=8eNgMkF3JBw:nrTJXstZPBU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=8eNgMkF3JBw:nrTJXstZPBU:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=8eNgMkF3JBw:nrTJXstZPBU:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=8eNgMkF3JBw:nrTJXstZPBU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=8eNgMkF3JBw:nrTJXstZPBU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=8eNgMkF3JBw:nrTJXstZPBU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=8eNgMkF3JBw:nrTJXstZPBU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/Akin-050-released.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/Akin-050-released.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=f29a1878-0c01-4f83-9b87-0b364e420dc9</guid>
      <pubDate>Sat, 03 Oct 2009 15:10:34 -1300</pubDate>
      <category>Akin</category>
      <category>News</category>
      <category>Excel</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=f29a1878-0c01-4f83-9b87-0b364e420dc9</pingback:target>
      <slash:comments>3</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=f29a1878-0c01-4f83-9b87-0b364e420dc9</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/Akin-050-released.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=f29a1878-0c01-4f83-9b87-0b364e420dc9</wfw:commentRss>
    </item>
    <item>
      <title>Movement is relative</title>
      <description>&lt;p&gt;I had an Eureka moment today, and realized that I was trying hard to resolve the wrong problem, when what was needed was a change of frame.&lt;/p&gt;  &lt;p&gt;I have been developing an application which tracks differences between Excel worksheets, and displays them in a layout similar to Excel itself. The user can navigate through the sheet on display by using two scrollbars, just like he would with Excel.&lt;/p&gt;  &lt;p&gt;To achieve this, my approach so far has been to read the data, create a grid using WPF, adding one cell control to the grid for each cell in the spreadsheet, and navigate “over” that grid using the scroll bars.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/Movementisrelative/4A0CDA33/OldModel.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="OldModel" border="0" alt="OldModel" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/Movementisrelative/21FA2B14/OldModel_thumb.png" width="489" height="280" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;This approach works well as long as the spreadsheet is small, but for larger sheets – say, 200 x 200 cells - the time needed to create the cells and add them to the grid was getting pretty long, so I focused my attention on figuring out a way to populate the grid faster, without much success.&lt;/p&gt;  &lt;p&gt;Then yesterday, someone wrote this on &lt;a href="http://stackoverflow.com/questions/1489559/how-can-i-speed-up-adding-controls-to-a-wpf-grid"&gt;StackOverflow&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;I'm going to go out on a limb here and say that trying to add 40,000 controls is your real bottleneck; not so much as to how you're adding the controls.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Indeed – that’s completely correct.This didn’t answer my issue directly, but it has been liberating, and got me to rethink the question from a different angle – do I really need 40,000 cells?&lt;/p&gt;  &lt;p&gt;The answer is no: I just need controls for the cells which are currently on screen. Rather than compute a graphical representation for the entire spreadsheet, and then display only a small portion of it, I can create just enough cells to cover the visible area, and dynamically update their content to display the content of the visible cells. The cells you see are always the same, only their content gets updated (In hindsight, I looked back at Excel, and I believe that’s how it works). The grid contains a fixed number of cells, independent of the size of the worksheet, and should eliminate the problem altogether.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.womeninislam.org/march%2008%20womens%20hist.htm"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; margin-left: 0px; border-top: 0px; margin-right: 0px; border-right: 0px" title="astrolabe" border="0" alt="astrolabe" align="left" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/Movementisrelative/79E77BF4/astrolabe.gif" width="192" height="244" /&gt;&lt;/a&gt; In a way, this is a small change of perspective. When you take a few steps forward, you can describe it two ways. You are moving forward, relative to the world, or you are immobile and the entire world is moving around you. Both descriptions are correct, but one comes more naturally than the other. My initial representation was similar to moving the whole entire world around the user, whereas the new approach is to simply determine what the user is seeing, and not worry about the world.&lt;/p&gt;  &lt;p&gt;Why did it take me so long to accept that I should change my design? In large part, it’s due to the fact that the old design, while not scaling well, did work – and it took me a lot of work to get it to where it is now. I had to go through a few stages of design grief (denial: “What problem? Let’s not go into premature optimization”…), before reaching acceptance – it was a nice design, but it just didn’t fit the problem, so it’s time to let go, call it a proof-of-concept, and restart from fresh with a new design that won’t hold me back! Back to the drawing board…&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/J_huLWx6WqGZT0fk59na_n8iqjg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J_huLWx6WqGZT0fk59na_n8iqjg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/J_huLWx6WqGZT0fk59na_n8iqjg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/J_huLWx6WqGZT0fk59na_n8iqjg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=I1n2e5wgb-U:RoPnJ8dJ_kU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=I1n2e5wgb-U:RoPnJ8dJ_kU:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=I1n2e5wgb-U:RoPnJ8dJ_kU:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=I1n2e5wgb-U:RoPnJ8dJ_kU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=I1n2e5wgb-U:RoPnJ8dJ_kU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=I1n2e5wgb-U:RoPnJ8dJ_kU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=I1n2e5wgb-U:RoPnJ8dJ_kU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/Movement-is-relative.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/Movement-is-relative.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=baf5c4fd-3bf8-4897-b4ef-8c6df68d06c5</guid>
      <pubDate>Tue, 29 Sep 2009 16:02:00 -1300</pubDate>
      <category>Akin</category>
      <category>Design and Patterns</category>
      <category>Software development</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=baf5c4fd-3bf8-4897-b4ef-8c6df68d06c5</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=baf5c4fd-3bf8-4897-b4ef-8c6df68d06c5</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/Movement-is-relative.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=baf5c4fd-3bf8-4897-b4ef-8c6df68d06c5</wfw:commentRss>
    </item>
    <item>
      <title>The PuzzlOR</title>
      <description>&lt;p&gt;I was recently inspired by an article in OR/MS mag to write 2 posts on using &lt;a href="http://clear-lines.com/blog/post/More-What-If-analysis-with-Excel-Data-Table.aspx"&gt;Excel data tables&lt;/a&gt; to &lt;a href="http://clear-lines.com/blog/post/Find-an-optimal-solution-with-Excel-Data-Table.aspx"&gt;resolve optimization problems&lt;/a&gt;. As it turns out, these puzzles are not only published in the magazine: they also have their online home at &lt;a href="http://puzzlor.com/"&gt;Puzzlor.com&lt;/a&gt;. So if you like optimization and math problems in general, and like puzzles, check it out!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gqgTNF57n-uz9IgYyWge_d11wTk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gqgTNF57n-uz9IgYyWge_d11wTk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gqgTNF57n-uz9IgYyWge_d11wTk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gqgTNF57n-uz9IgYyWge_d11wTk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=aI1aQBW0KHo:TMVyK8Mvh4o:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=aI1aQBW0KHo:TMVyK8Mvh4o:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=aI1aQBW0KHo:TMVyK8Mvh4o:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=aI1aQBW0KHo:TMVyK8Mvh4o:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=aI1aQBW0KHo:TMVyK8Mvh4o:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=aI1aQBW0KHo:TMVyK8Mvh4o:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=aI1aQBW0KHo:TMVyK8Mvh4o:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/The-PuzzlOR.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/The-PuzzlOR.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=4c929983-6414-4217-99a9-ed22cef6d4de</guid>
      <pubDate>Sun, 20 Sep 2009 07:10:32 -1300</pubDate>
      <category>Math</category>
      <category>quantitative modeling</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=4c929983-6414-4217-99a9-ed22cef6d4de</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=4c929983-6414-4217-99a9-ed22cef6d4de</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/The-PuzzlOR.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=4c929983-6414-4217-99a9-ed22cef6d4de</wfw:commentRss>
    </item>
    <item>
      <title>Bugs hiding in plain sight</title>
      <description>&lt;p&gt;&lt;a href="http://mantiskingdom.com/images/ghost.JPG"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="ghostmantis" border="0" alt="ghostmantis" align="left" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/Unittestsareyourfriend/0104A4E6/ghostmantis.jpg" width="244" height="184" /&gt;&lt;/a&gt;I found a bug in my code the other day. It happens to everybody - apparently I am not the only one to &lt;a href="http://www.codinghorror.com/blog/archives/000099.html"&gt;write bugs&lt;/a&gt; – but the bug itself surprised me. In my experience, once you know a piece of code is buggy, it’s usually not too difficult to figure out what the origin of the problem might be (fixing it might). This bug surprised me, because I knew exactly the 10 lines of code where it was taking place, and yet I had no idea what was going on – I just couldn’t see the bug, even though it was floating in plain sight (hint: the pun is intended).&lt;/p&gt;  &lt;p&gt;Here is the context. The code reads a double and converts it into a year and a quarter, based on the following convention: the input is of the form yyyy.q, for instance, 2010.2 represents the second quarter of 2010. Anything after the 2nd decimal is ignored, 2010.0 is “rounded up” to 1st quarter, and 2010.5 and above rounded down to 4th quarter.&lt;/p&gt;  &lt;p&gt;Here is my original code:&lt;/p&gt;  &lt;pre class="c#" name="code"&gt;public class DateConverter
{
    public static int ExtractYear(double dateAsDouble)
    {
        int year = (int)dateAsDouble;
        return year;
    }

    public static int ExtractQuarter(double dateAsDouble)
    {
        int year = ExtractYear(dateAsDouble);
        int quarter = (int)(10 * (Math.Round(dateAsDouble, 1) - (double)year));
        if (quarter &amp;lt; 1)
        {
            quarter = 1;
        }
        if (quarter &amp;gt; 4)
        {
            quarter = 4;
        }
        return quarter;
    }
}&lt;/pre&gt;

&lt;p&gt;Can you spot the bug?&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Here is another hint – only one of these tests fails:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;[TestCase(2010.1, Result = 1)]
[TestCase(2010.2, Result = 2)]
[TestCase(2010.3, Result = 3)]
[TestCase(2010.4, Result = 4)]
[TestCase(2010.0, Result = 1)]
[TestCase(2010.5, Result = 4)]
public int ValidateQuarter(double dateAsDouble)
{
    return DateConverter.ExtractQuarter(dateAsDouble);
}&lt;/pre&gt;

&lt;p&gt;My first thought was, “Oops I did it again, must have made a silly mistake with either rounding or casting somewhere”. But when I saw that the only failing test case was for 2010.3, I knew the logic of the calculation wasn’t the problem.&lt;/p&gt;

&lt;p&gt;After some head-scratching, I realized what it was – &lt;strong&gt;my&lt;/strong&gt; math is perfectly OK, thank you, but in the &lt;a href="http://www.extremeoptimization.com/resources/Articles/FPDotNetConceptsAndFormats.aspx"&gt;floating point&lt;/a&gt; world of the computer, things happen &lt;a href="http://www.codinghorror.com/blog/archives/001266.html"&gt;a bit differently&lt;/a&gt;. Like,&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;[Test]
public void HmmmRight()
{
    Assert.AreEqual(0.3, 0.3 - 0.0);
    // all the following fail miserably
    Assert.AreEqual(0.3, 0.4 - 0.1);
    Assert.AreEqual(0.3, 1.3 - 1.0);
    Assert.AreEqual(0.3, 2010.3 - 2010.0);
}&lt;/pre&gt;

&lt;p&gt;It is such simple math, and it is so obvious to me that 2010.3 – 2010.0 equals 0.3, that I didn’t even consider this was a source of potential errors.&lt;/p&gt;

&lt;p&gt;I have changed my code to the following version, which uses doubles as little as possible, and seems to work just fine:&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public static int ExtractQuarter(double dateAsDouble)
{
    int year = ExtractYear(dateAsDouble);
    int quarter = (int)(10 * dateAsDouble) - 10 * year;
    if (quarter &amp;lt; 1)
    {
        quarter = 1;
    }
    if (quarter &amp;gt; 4)
    {
        quarter = 4;
    }
    return quarter;
}&lt;/pre&gt;

&lt;p&gt;I am not sure this is the smartest way to deal with the issue - any suggestions are greatly appreciated! In the meanwhile, for me, the moral of story is that:&lt;/p&gt;

&lt;p&gt;1) Write unit tests. For “any piece of code that has some form of logic in it, small as it may be” (&lt;a href="http://www.artofunittesting.com/"&gt;The Art of Unit Testing&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;2) Beware of floating point arithmetic!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/SP3on6KI6A7VsTRrScaUGPx65Ig/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SP3on6KI6A7VsTRrScaUGPx65Ig/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/SP3on6KI6A7VsTRrScaUGPx65Ig/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/SP3on6KI6A7VsTRrScaUGPx65Ig/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=oiHTq3qCZPU:7e51FtnnHVc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=oiHTq3qCZPU:7e51FtnnHVc:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=oiHTq3qCZPU:7e51FtnnHVc:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=oiHTq3qCZPU:7e51FtnnHVc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=oiHTq3qCZPU:7e51FtnnHVc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=oiHTq3qCZPU:7e51FtnnHVc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=oiHTq3qCZPU:7e51FtnnHVc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/Bugs-hiding-in-plain-sight.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/Bugs-hiding-in-plain-sight.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=c3df0143-03ee-458e-a97a-681665595c98</guid>
      <pubDate>Fri, 18 Sep 2009 06:12:05 -1300</pubDate>
      <category>.NET</category>
      <category>Math</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=c3df0143-03ee-458e-a97a-681665595c98</pingback:target>
      <slash:comments>0</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=c3df0143-03ee-458e-a97a-681665595c98</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/Bugs-hiding-in-plain-sight.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=c3df0143-03ee-458e-a97a-681665595c98</wfw:commentRss>
    </item>
    <item>
      <title>One month to Silicon Valley Code Camp!</title>
      <description>&lt;p&gt;It’s that time of the year again: &lt;a href="http://www.siliconvalley-codecamp.com/Default.aspx"&gt;Silicon Valley Code Camp&lt;/a&gt; is coming up on October 3rd and 4th, at Foothill College. If you live in the Bay Area and like to talk code, this is an event you don’t want to miss. The previous editions rocked, and this year looks like it’s going to rock even harder, with well over 100 sessions and close to 1,000 registered! Oh, and did I mention it’s free?&lt;/p&gt;  &lt;p&gt;This year again, I will give an introduction to &lt;a href="http://www.siliconvalley-codecamp.com/Sessions.aspx?id=163"&gt;Test-Driven Development&lt;/a&gt; for .NET developers. It’s a topic which is dear to my heart; in his book on TDD, &lt;a href="http://www.amazon.com/Test-Driven-Development-Kent-Beck/dp/0321146530"&gt;Kent Beck&lt;/a&gt; says that it “is a way of managing fear during programming”, and I have to say that my life as a developer got significantly more peaceful after reading it. I can’t guarantee that you will feel the same, but I’ll do my best to share the goods!&lt;/p&gt;  &lt;p&gt;The session is targeted for beginners. My goal is to get you quick-started so that you are ready to use it when you leave the room. I will write some code live, to show the methodology in action, using only tools you can get for free. This year, I think I will focus mostly on NUnit and keep it to a minimum on the tools provided in Visual Studio, unless there is strong popular demand; hopefully this will give me enough time to squeeze in a few minutes on mocks. I also just ordered Roy Osherove’s “&lt;a href="http://www.manning.com/osherove/"&gt;The Art of Unit Testing&lt;/a&gt;”, which looks very promising, and may push me to modify my plan a bit.&lt;/p&gt;  &lt;p&gt;I hope to see you there – and if you have questions or suggestions, let me know in the comments section!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/gSfnbzOHcF38CQ9ZAMkegBeDlIE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gSfnbzOHcF38CQ9ZAMkegBeDlIE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/gSfnbzOHcF38CQ9ZAMkegBeDlIE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/gSfnbzOHcF38CQ9ZAMkegBeDlIE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=W9IodoePvkI:soNUfPUvIlc:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=W9IodoePvkI:soNUfPUvIlc:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=W9IodoePvkI:soNUfPUvIlc:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=W9IodoePvkI:soNUfPUvIlc:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=W9IodoePvkI:soNUfPUvIlc:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=W9IodoePvkI:soNUfPUvIlc:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=W9IodoePvkI:soNUfPUvIlc:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/One-month-to-Silicon-Valley-Code-Camp!.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/One-month-to-Silicon-Valley-Code-Camp!.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=44479334-7336-48ae-9fb0-c8d9e7c25074</guid>
      <pubDate>Mon, 07 Sep 2009 13:14:36 -1300</pubDate>
      <category>.NET</category>
      <category>Software development</category>
      <category>Design and Patterns</category>
      <category>News</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=44479334-7336-48ae-9fb0-c8d9e7c25074</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=44479334-7336-48ae-9fb0-c8d9e7c25074</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/One-month-to-Silicon-Valley-Code-Camp!.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=44479334-7336-48ae-9fb0-c8d9e7c25074</wfw:commentRss>
    </item>
    <item>
      <title>More What-If analysis with Excel Data Table</title>
      <description>&lt;p&gt;In my &lt;a href="http://clear-lines.com/blog/post.aspx?id=21fb3782-9e29-4814-8ed1-1c5e5971ffc4"&gt;last post&lt;/a&gt;, I illustrated how to quickly to pick the best value from a selection to get the optimal result, by using Excel Data Tables. This time, we will see how to pick the best possible pair of values.&lt;/p&gt;  &lt;p&gt;We are trying to figure out which 2 bridges we should build, in order to minimize the overall travel time for the inhabitants of the island.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/566ECD8B/Island.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="Island" border="0" alt="Island" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/74D90E74/Island_thumb.png" width="448" height="381" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I worked out the math for one bridge last time. We will start we a similar setup, but adjust our spreadsheet so that for each islander, we compute the travelling distance for 2 bridges, and select the shortest route.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/0CFC78D0/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/16E16A3B/image_thumb.png" width="512" height="261" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;The ranges B1 and B2 are named Bridge1 and Bridge2. Column I now contains the formula computing the shortest route for each islander. For row 5 for instance, the formula is &lt;/p&gt;  &lt;p&gt;=MIN(D5+E5-H5,F5+G5-H5)&lt;/p&gt;  &lt;p&gt;Cell I10 is the total of the vertical distances travelled by each individual. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;We can select from 4 bridge locations: 2, 4, 7 and 12. What we need is to find out which 2 numbers give us the lowest total travel. Let’s build our data table, this time using 2 bridge positions. &lt;/p&gt;  &lt;p&gt;Our first bridge can be located at either 2,4,7 and 12:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/3CD71A91/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/31415D52/image_thumb.png" width="337" height="136" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Our second bridge can have the same positions:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/14C46B72/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/6913A175/image_thumb.png" width="324" height="137" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In the upper-left corner, we specify what value we are interested in. What we want is the total travel distance, so we simply set cell A13 to =I10, the total travel distance:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/7A84024D/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/20E5E599/image_thumb.png" width="321" height="140" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Almost done. Now we select the entire table A13:E17, go to What-If Analysis, and select Data Table. In the pop-up window, we select B2 as the Row input cell, so that the row of values in B13:E13 corresponds to the second bridge location, and B1 as the Column input cell, so that Bridge1 positions will be selected from the values in A14:A17. &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/0E30EBE2/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/108A6DE0/image_thumb.png" width="510" height="452" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Once we select OK, the table fills in with the corresponding distances:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/55C2C509/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/7C24A854/image_thumb.png" width="313" height="127" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Looking into the table, we see that the lowest value is achieved for one bridge in position 4, the other one in position 12 – the bridges labeled “One” and “Third”.&lt;/p&gt;  &lt;p&gt;We could even check if we could do any better, by trying out every possible bridge, including the ones which were not proposed. We would build a table like the following:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/3B825BE5/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/MoreWhatIfanalysiswithExcelDataTable/7856DDB7/image_thumb.png" width="644" height="263" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;I highlighted the original 4 options. Looking into the table, we can see that there is no better solution – but three other solutions are just as good. The 4 optimal solutions are (4, 11), (4, 12), (5,11) and (5,12).&lt;/p&gt;  &lt;p&gt;The data table approach is a bit of an overkill for the specific problem at hand. After all, there are only 4 x 3 x 2 x 1 = 24 options, and it would be feasible to just try them all by hand. However, if you started from scratch and wanted to figure out the best option, that would be 12 x 11 x 10 x 11 possibilities, and checking all 11,880 by hand would turn out to be a serious headache… &lt;/p&gt;  &lt;p&gt;It’s interesting to see how the 2-bridges solution differs from the 1-bridge solution. The best single bridge is bridge “Two”, which is more or less in the middle – an average solution which is great for no one, but a decent compromise. The 2-bridge solution picks more extreme locations, serving better specific sub-groups. In a sense, this is similar to picking up a team. If you have a team of one, you would probably pick someone average, with no glaring weakness. If you can pick two, you’ll probably try to mix it up, and select team mates complementing each other, and compensating each other’s weaknesses.&lt;/p&gt;  &lt;p&gt;One thing I like about data tables is that it is a good option for small discrete choices problems. The solver (or &lt;a href="http://clear-lines.com/blog/post.aspx?id=e244045b-9c53-4d8f-b5a5-0518c773f2a3"&gt;goal seek&lt;/a&gt;) are well suited to optimize for continuous values, but have issues dealing with problems were the solutions are a set of pre-determined values – and data tables handle these well. On the other hand, data tables won’t go beyond 2 values, which is a clear limitation. What if you had to pick the 3 best bridges?&lt;/p&gt;  &lt;p&gt;This question actually got me thinking, so here it is a bonus problem. If you could build as many bridges as you wanted, in any location, where should you build them? To be more specific, what is the minimum number of bridges you should build so that everybody’s travel distance is minimal? I started playing with the question, and couldn’t find a satisfactory answer yet, but if I do, I’ll share. Hints and ideas appreciated!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZYngTrR8Y03bpnjGqvMtNsNGsXc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZYngTrR8Y03bpnjGqvMtNsNGsXc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZYngTrR8Y03bpnjGqvMtNsNGsXc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZYngTrR8Y03bpnjGqvMtNsNGsXc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0e6m57gy1M8:gRcgKF-sdD0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0e6m57gy1M8:gRcgKF-sdD0:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=0e6m57gy1M8:gRcgKF-sdD0:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0e6m57gy1M8:gRcgKF-sdD0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=0e6m57gy1M8:gRcgKF-sdD0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0e6m57gy1M8:gRcgKF-sdD0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=0e6m57gy1M8:gRcgKF-sdD0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/More-What-If-analysis-with-Excel-Data-Table.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/More-What-If-analysis-with-Excel-Data-Table.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=0af06f49-e7c9-40d5-8f10-c64fd126b9ae</guid>
      <pubDate>Thu, 03 Sep 2009 17:50:37 -1300</pubDate>
      <category>Excel</category>
      <category>Math</category>
      <category>quantitative modeling</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=0af06f49-e7c9-40d5-8f10-c64fd126b9ae</pingback:target>
      <slash:comments>1</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=0af06f49-e7c9-40d5-8f10-c64fd126b9ae</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/More-What-If-analysis-with-Excel-Data-Table.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=0af06f49-e7c9-40d5-8f10-c64fd126b9ae</wfw:commentRss>
    </item>
    <item>
      <title>Find an optimal solution with Excel Data Table</title>
      <description>&lt;p&gt;In the current issue of OR/MS Today, I came across this nice optimization puzzle, “&lt;a href="http://viewer.zmags.com/publication/98349279#/98349279/14"&gt;Bridges to Somewhere&lt;/a&gt;”. There are these two islands. Five people A, B, C, D and F live on the first island, and need to commute to work to the second island. Individual A lives in the spot marked A, and needs to go to spot A on the second island – and so on for the 4 others. People can travel only vertically and horizontally (no diagonals), and will always take the shortest path available.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/65D3D721/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/0C35BA6D/image_thumb.png" width="448" height="381" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;There is currently no bridge between the islands, but a budget for 2 bridges has been approved (the island just received a stimulus package). There are 4 bridge proposals to chose from (One, Two, Three and Four on the map). Which 2 bridges should be built to minimize the travel distance of the population?&lt;/p&gt;  &lt;p&gt;Before trying to figure out which 2 bridges are best, I thought it would be interesting to investigate a simpler problem: if you could build one bridge anywhere, where should you build it?&lt;/p&gt;  &lt;p&gt;There are a number of ways you could resolve this using Excel; I will illustrate how to find the best solution, using Excel Data Tables.&lt;/p&gt;  &lt;h2&gt;Good bridges, bad bridges&lt;/h2&gt;  &lt;p&gt;What makes a bridge better or worse for an islander?&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;a href="http://failblog.org/2008/01/03/fail-bridge/"&gt;&lt;img alt="failbridge.jpg" src="http://failblog.wordpress.com/files/2008/01/failbridge.jpg" width="240" height="186" /&gt;&lt;/a&gt;    &lt;br /&gt;see more &lt;a href="http://failblog.org"&gt;Fail Blog&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;First, note that no matter where the bridge is located, C (who I will call Charlie) needs to travel the same distance horizontally (8 squares, or 7 moves). What this means is that the horizontal position of each individual doesn’t matter: the only thing which matters is where the bridge is located, on the vertical axis.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/04AA4B00/image.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/79148DC0/image_thumb.png" width="449" height="378" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Then, any bridge located in the yellow rectangle is optimal for Charlie, who needs to travel only 4 squares down, and 8 squares right. Bridges which are located outside the bounds of the rectangle require extra vertical travel – in our example, an extra 3 squares up and 3 squares down.&lt;/p&gt;  &lt;p&gt;Working the math, you can check that the extra travel a bridge requires from Charlie can be written as&lt;/p&gt;  &lt;p&gt;Extra Travel = vertical distance from home to brige + vertical distance from work to bridge – vertical distance from home to work.&lt;/p&gt;  &lt;p&gt;In our example, the Good bridge has an extra travel of 3+1-4=0 (no extra travel required), and the Bad bridge has an extra travel of 3+7-4=6.&lt;/p&gt;  &lt;h2&gt;The best bridge&lt;/h2&gt;  &lt;p&gt;Using this formula, we can now compute the extra cost of a bridge for each islander, and set up a worksheet to compute the total extra travel for each possible bridge.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/439BCB9B/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/3C105C2E/image_thumb.png" width="503" height="240" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;In cell B1, we enter the vertical position of the bridge, and name the range “Bridge” (I am using the coordinates that are on the first map).&lt;/p&gt;  &lt;p&gt;In range B4:C8, we enter the vertical position of the home and workplace of each of the 5 islanders.&lt;/p&gt;  &lt;p&gt;In columns D and E, we compute the vertical distance from home and work to the bridge as shown, and we compute the vertical distance from work to home in column F.&lt;/p&gt;  &lt;p&gt;In column G, we compute the extra travel as G4 = D4+E4-F4, and we compute the total extra travel in G9. Entering various values in B1 will show you the value of each possible location of the bridge.&lt;/p&gt;  &lt;p&gt;You could now use a variety of approaches to find the best solution, from trying out all solutions manually, to using the solver. I’ll illustrate how you could find the optimal solution using Data Table, one of the What-If Analysis features of Excel.&lt;/p&gt;  &lt;p&gt;In a nutshell, a Data Table allows you to specify a range of values, and record the result of a formula in your worksheet using each of them as an input.&lt;/p&gt;  &lt;p&gt;What we will do here is try every possible location for a bridge, from 1 to 13, and record the Total Extra Travel for each scenario. First, let’s create the range of locations we want to try out:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/295B6277/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/0FF35F3D/image_thumb.png" width="210" height="315" /&gt;&lt;/a&gt;&amp;#160; &lt;/p&gt;  &lt;p&gt;Then, one column to the right, and one row above the input values, let’s set the formula we want to evaluate. In this case, I want to see the impact on the total extra travel, so that’s what I will set it equal to.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/6199D98F/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/1A44839D/image_thumb.png" width="507" height="129" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Next, select the range containing your input values and the formula:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/2EC9D31B/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/67747D28/image_thumb.png" width="179" height="311" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Almost there! Let’s go to Data Table in What-If Analysis…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/4E0C79EE/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/2D853A3C/image_thumb.png" width="314" height="98" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Your input data is organized in columns, so use “Column Input Cell”, and select B1, the bridge location, which is the input value you want to replace.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/25F9CACF/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/1E02286D/image_thumb.png" width="441" height="373" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Press OK, and voila! Range B12:B24 has now been filled with data, which are the extra cost computed for each possible bridge value.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/58E95B36/image.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://www.clear-lines.com/blog/image.axd?picture=WindowsLiveWriter/FindanoptimalsolutionwithExcelDataTable/2A8FD589/image_thumb.png" width="189" height="311" /&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;If you had one bridge to build only, you should locate it at position 7 or 8, which have the lowest extra travel for the population. Neat, no? In this example, this approach is probably not much faster that trying out various solutions by hand, but if there were more possible locations (and a less obvious solution…), this would prove very handy.&lt;/p&gt;  &lt;p&gt;Next time, we’ll see how we would go about figuring out which 2 bridges are best! &lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/oYry4pfUDG75QKZoelaHnrh7ivM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oYry4pfUDG75QKZoelaHnrh7ivM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/oYry4pfUDG75QKZoelaHnrh7ivM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/oYry4pfUDG75QKZoelaHnrh7ivM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0Ukrk8r9wOM:PMh39Xllmi0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0Ukrk8r9wOM:PMh39Xllmi0:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=0Ukrk8r9wOM:PMh39Xllmi0:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0Ukrk8r9wOM:PMh39Xllmi0:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=0Ukrk8r9wOM:PMh39Xllmi0:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=0Ukrk8r9wOM:PMh39Xllmi0:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=0Ukrk8r9wOM:PMh39Xllmi0:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/Find-an-optimal-solution-with-Excel-Data-Table.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/Find-an-optimal-solution-with-Excel-Data-Table.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=21fb3782-9e29-4814-8ed1-1c5e5971ffc4</guid>
      <pubDate>Fri, 28 Aug 2009 17:54:45 -1300</pubDate>
      <category>Excel</category>
      <category>quantitative modeling</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=21fb3782-9e29-4814-8ed1-1c5e5971ffc4</pingback:target>
      <slash:comments>4</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=21fb3782-9e29-4814-8ed1-1c5e5971ffc4</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/Find-an-optimal-solution-with-Excel-Data-Table.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=21fb3782-9e29-4814-8ed1-1c5e5971ffc4</wfw:commentRss>
    </item>
    <item>
      <title>Create an Excel Line – Column combination chart in C#, revisited</title>
      <description>&lt;p&gt;I wrote a post a few days ago describing how to generate a &lt;a href="http://www.clear-lines.com/blog/post/Create-Excel-Line-Column-Chart-from-C.aspx"&gt;Line – Column chart&lt;/a&gt; in Excel through C#. And then a few things happened. &lt;a href="http://peltiertech.com/WordPress/"&gt;Jon Peltier&lt;/a&gt; proposed a much nicer approach, I realized that my code worked for Excel 2003 but not Excel 2007, and someone asked for my code, “Jon-Peltier style”. So here we go: assuming your chart has more than one series, and you want the second series to be formatted as a line, all the rest as columns, you would do something like this:&lt;/p&gt;  &lt;pre class="c#" name="code"&gt;// Create your chart object first
// formatted as column
Chart chart = ExcelCharts.AddChart(targetWorkbook, “my chart”, “the chart title”, XlChartType.xlColumnClustered, dataRange, XlRowCol.xlRows);
// Select the second series and make it a line
Series series = (Series)chart.SeriesCollection(2);
series.ChartType = XlChartType.xlLine;&lt;/pre&gt;

&lt;p&gt;Here is a simplified version of my AddChart method, which creates the base chart. Nothing fancy, but gets the job done.&lt;/p&gt;

&lt;pre class="c#" name="code"&gt;public static Excel.Chart AddChart(Workbook workbook, string chartSheetName, string title, XlChartType chartType, Range dataRange, XlRowCol byRowOrCol)
{
    Excel.Chart chart;
    chart = (Excel.Chart)workbook.Charts.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
    chart.ChartType = chartType;
    chart.Location(XlChartLocation.xlLocationAsNewSheet, chartSheetName);
    chart.SetSourceData(dataRange, byRowOrCol);
    chart.HasTitle = true;
    chart.ChartTitle.Text = title;
    return chart;
}&lt;/pre&gt;

&lt;p&gt;As an aside, I was not happy with myself when I realized the code didn’t run on Excel 2007. I tend to write Excel-related code against Excel 2003 first, assuming it is the smallest common denominator and will likely work with Excel 2007 – but this is a perfect illustration that while it will typically be correct, it will sometimes fail, sometimes in very unexpected and trivial places, like in this example. Moral of the story: as Lenin allegedly said, “Trust is good, control is better”…&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7R0n4v17GUrwfQnTSuQdBBYYENI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7R0n4v17GUrwfQnTSuQdBBYYENI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7R0n4v17GUrwfQnTSuQdBBYYENI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7R0n4v17GUrwfQnTSuQdBBYYENI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=kEmqGJ_sC0o:4AoCAubUxD4:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=kEmqGJ_sC0o:4AoCAubUxD4:D7DqB2pKExk"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=kEmqGJ_sC0o:4AoCAubUxD4:D7DqB2pKExk" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=kEmqGJ_sC0o:4AoCAubUxD4:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=kEmqGJ_sC0o:4AoCAubUxD4:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ClearLinesBlog?a=kEmqGJ_sC0o:4AoCAubUxD4:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ClearLinesBlog?i=kEmqGJ_sC0o:4AoCAubUxD4:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;</description>
      <link>http://www.clear-lines.com/blog/post/Create-an-Excel-Line-e28093-Column-combination-chart-in-C-revisited.aspx</link>
      <author>mathias</author>
      <comments>http://www.clear-lines.com/blog/post/Create-an-Excel-Line-e28093-Column-combination-chart-in-C-revisited.aspx#comment</comments>
      <guid>http://www.clear-lines.com/blog/post.aspx?id=3328d0f9-93e3-4b02-bf72-b7c66dcbd6ca</guid>
      <pubDate>Thu, 20 Aug 2009 05:55:24 -1300</pubDate>
      <category>Excel</category>
      <category>.NET</category>
      <dc:publisher>mathias</dc:publisher>
      <pingback:server>http://www.clear-lines.com/blog/pingback.axd</pingback:server>
      <pingback:target>http://www.clear-lines.com/blog/post.aspx?id=3328d0f9-93e3-4b02-bf72-b7c66dcbd6ca</pingback:target>
      <slash:comments>2</slash:comments>
      <trackback:ping>http://www.clear-lines.com/blog/trackback.axd?id=3328d0f9-93e3-4b02-bf72-b7c66dcbd6ca</trackback:ping>
      <wfw:comment>http://www.clear-lines.com/blog/post/Create-an-Excel-Line-e28093-Column-combination-chart-in-C-revisited.aspx#comment</wfw:comment>
      <wfw:commentRss>http://www.clear-lines.com/blog/syndication.axd?post=3328d0f9-93e3-4b02-bf72-b7c66dcbd6ca</wfw:commentRss>
    </item>
  </channel>
</rss>
