<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" 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:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>General</title>
        <link>http://www.ridgway.co.za/category/14.aspx</link>
        <description>General</description>
        <language>en-ZA</language>
        <copyright>Eden Ridgway</copyright>
        <managingEditor>eden@ridgway.co.za</managingEditor>
        <generator>Subtext Version 1.9.5.176</generator>
        <item>
            <title>Fibonacci Solution Approaches</title>
            <link>http://ridgway.co.za/archive/2008/01/30/fibonacci-solution-approaches.aspx</link>
            <description>&lt;p&gt;Looking at technical interview questions on the Internet it appears that getting candidates to write some code that prints out the Fibonacci series is quite popular. I personally prefer giving candidates slightly more relevant practical questions, but I thought I'd present the various solutions that one may take. For those of you who are unfamiliar with the Fibonacci series you should take a look at the &lt;a href="http://en.wikipedia.org/wiki/Fibonacci_number"&gt;Wikipedia page on it&lt;/a&gt;. Each number in the series is the sum of the previous two values except for the first and second numbers which are zero and one respectively. So the interviewer is expecting to see the following series of numbers:&lt;/p&gt;
&lt;p&gt;0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584...&lt;/p&gt;
&lt;p&gt;The Fibonacci series is often used by computer science teachers to teach recursion, even though this it is a poor fit (see: &lt;a href="http://blogs.msdn.com/ericlippert/archive/2004/05/19/135392.aspx"&gt;How Not To Teach Recursion&lt;/a&gt;). However in all likelihood this is what the interviewer is after, so the expected standard solution should look like this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;font color="#0000ff"&gt;internal static int &lt;/font&gt;&lt;font color="#000000"&gt;GetFibonacciValue(&lt;/font&gt;&lt;font color="#0000ff"&gt;int &lt;/font&gt;&lt;font color="#000000"&gt;number)      &lt;br /&gt;
{       &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;if &lt;/font&gt;&lt;font color="#000000"&gt;(number &amp;lt; &lt;/font&gt;&lt;font color="#800000"&gt;0&lt;/font&gt;&lt;font color="#000000"&gt;)      &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#0000ff"&gt;throw new &lt;/font&gt;&lt;font color="#000000"&gt;InvalidOperationException(&lt;/font&gt;&lt;font color="#808080"&gt;"Negative numbers are not supported by this implementation"&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#0000ff"&gt;;      &lt;br /&gt;
&lt;br /&gt;
    if &lt;/font&gt;&lt;font color="#000000"&gt;(number &amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;1&lt;/font&gt;&lt;font color="#000000"&gt;)      &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#0000ff"&gt;return &lt;/font&gt;&lt;font color="#000000"&gt;number&lt;/font&gt;&lt;font color="#0000ff"&gt;;      &lt;br /&gt;
&lt;br /&gt;
    return &lt;/font&gt;&lt;font color="#000000"&gt;GetFibonacciValue(number - &lt;/font&gt;&lt;font color="#800000"&gt;1&lt;/font&gt;&lt;font color="#000000"&gt;) + GetFibonacciValue(number - &lt;/font&gt;&lt;font color="#800000"&gt;2&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#0000ff"&gt;;      &lt;br /&gt;
&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt; &lt;/div&gt;
&lt;p&gt;A lot of people forget to check for a negative number check, so including it may even earn you "bonus points". If you want to have a little fun you could always use a terse lambda expression to solve it like this:&lt;/p&gt;
&lt;div class="code"&gt;&lt;font color="#000000"&gt;Func&amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;font color="#000000"&gt;, &lt;/font&gt;&lt;font color="#0000ff"&gt;int&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt; fibonacci &lt;/font&gt;&lt;font color="#0000ff"&gt;= null;      &lt;br /&gt;
&lt;/font&gt;&lt;font color="#000000"&gt;fibonacci &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;n &lt;/font&gt;&lt;font color="#0000ff"&gt;=&lt;/font&gt;&lt;font color="#000000"&gt;&amp;gt; n &amp;gt; &lt;/font&gt;&lt;font color="#800000"&gt;1 &lt;/font&gt;&lt;font color="#000000"&gt;? fibonacci(n - &lt;/font&gt;&lt;font color="#800000"&gt;1&lt;/font&gt;&lt;font color="#000000"&gt;) + fibonacci(n - &lt;/font&gt;&lt;font color="#800000"&gt;2&lt;/font&gt;&lt;font color="#000000"&gt;) : n&lt;/font&gt;&lt;font color="#0000ff"&gt;;&lt;/font&gt; &lt;/div&gt;
&lt;p&gt;The problem with the approaches above is that they perform really badly because of their recursive nature, so you could always show off and tell them that there is a closed form of the solution which allows you to solve it in the following manner:&lt;/p&gt;
&lt;div class="code"&gt;&lt;font color="#0000ff"&gt;private readonly static double &lt;/font&gt;&lt;font color="#000000"&gt;rootOfFive &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;Math.Sqrt(&lt;/font&gt;&lt;font color="#800000"&gt;5&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#0000ff"&gt;;     &lt;br /&gt;
private readonly static double &lt;/font&gt;&lt;font color="#000000"&gt;goldenRatio &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#800000"&gt;1 &lt;/font&gt;&lt;font color="#000000"&gt;+ rootOfFive) / &lt;/font&gt;&lt;font color="#800000"&gt;2&lt;/font&gt;&lt;font color="#0000ff"&gt;;     &lt;br /&gt;
&lt;br /&gt;
internal static int &lt;/font&gt;&lt;font color="#000000"&gt;GetFinbonacciValue(&lt;/font&gt;&lt;font color="#0000ff"&gt;int &lt;/font&gt;&lt;font color="#000000"&gt;number)     &lt;br /&gt;
{      &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;return &lt;/font&gt;&lt;font color="#000000"&gt;Convert.ToInt32((Math.Pow(goldenRatio, number) - Math.Pow(-goldenRatio, -number)) / rootOfFive)&lt;/font&gt;&lt;font color="#0000ff"&gt;;     &lt;br /&gt;
&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt; &lt;/div&gt;
&lt;p&gt;If you forget the closed form you could also tell the interviewer that using a simple for loop is far more efficient and ask him if he would be satisfied with that:&lt;/p&gt;
&lt;div class="code"&gt;&lt;font color="#0000ff"&gt;internal static int &lt;/font&gt;&lt;font color="#000000"&gt;GetFinbonacciValue(&lt;/font&gt;&lt;font color="#0000ff"&gt;int &lt;/font&gt;&lt;font color="#000000"&gt;number)      &lt;br /&gt;
{       &lt;/font&gt;&lt;font color="#000000"&gt;&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;if &lt;/font&gt;&lt;font color="#000000"&gt;(number &amp;lt; &lt;/font&gt;&lt;font color="#800000"&gt;0&lt;/font&gt;&lt;font color="#000000"&gt;)      &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#0000ff"&gt;throw new &lt;/font&gt;&lt;font color="#000000"&gt;InvalidOperationException(&lt;/font&gt;&lt;font color="#808080"&gt;"Negative numbers are not supported by this implementation"&lt;/font&gt;&lt;font color="#000000"&gt;)&lt;/font&gt;&lt;font color="#0000ff"&gt;;      &lt;br /&gt;
&lt;/font&gt;&lt;br /&gt;
&lt;font color="#000000"&gt;     &lt;/font&gt;&lt;font color="#0000ff"&gt;if &lt;/font&gt;&lt;font color="#000000"&gt;(number &amp;lt;&lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;1&lt;/font&gt;&lt;font color="#000000"&gt;)      &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#0000ff"&gt;return &lt;/font&gt;&lt;font color="#000000"&gt;number&lt;/font&gt;&lt;font color="#0000ff"&gt;;      &lt;br /&gt;
&lt;br /&gt;
    int &lt;/font&gt;&lt;font color="#000000"&gt;runningTotal &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;1&lt;/font&gt;&lt;font color="#0000ff"&gt;;      &lt;br /&gt;
    int &lt;/font&gt;&lt;font color="#000000"&gt;twoValuesBack &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;1&lt;/font&gt;&lt;font color="#0000ff"&gt;;      &lt;br /&gt;
&lt;br /&gt;
    for &lt;/font&gt;&lt;font color="#000000"&gt;(&lt;/font&gt;&lt;font color="#0000ff"&gt;int &lt;/font&gt;&lt;font color="#000000"&gt;n &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#800000"&gt;2&lt;/font&gt;&lt;font color="#0000ff"&gt;; &lt;/font&gt;&lt;font color="#000000"&gt;n &amp;lt; number&lt;/font&gt;&lt;font color="#0000ff"&gt;; &lt;/font&gt;&lt;font color="#000000"&gt;n++)      &lt;br /&gt;
    {       &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#0000ff"&gt;int &lt;/font&gt;&lt;font color="#000000"&gt;previousTotal &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;runningTotal&lt;/font&gt;&lt;font color="#0000ff"&gt;;      &lt;br /&gt;
        &lt;/font&gt;&lt;font color="#000000"&gt;runningTotal &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;twoValuesBack + runningTotal&lt;/font&gt;&lt;font color="#0000ff"&gt;;      &lt;br /&gt;
&lt;br /&gt;
        &lt;/font&gt;&lt;font color="#000000"&gt;twoValuesBack &lt;/font&gt;&lt;font color="#0000ff"&gt;= &lt;/font&gt;&lt;font color="#000000"&gt;previousTotal&lt;/font&gt;&lt;font color="#0000ff"&gt;;      &lt;br /&gt;
    &lt;/font&gt;&lt;font color="#000000"&gt;}      &lt;br /&gt;
&lt;br /&gt;
    &lt;/font&gt;&lt;font color="#0000ff"&gt;return &lt;/font&gt;&lt;font color="#000000"&gt;runningTotal&lt;/font&gt;&lt;font color="#0000ff"&gt;;      &lt;br /&gt;
&lt;/font&gt;&lt;font color="#000000"&gt;}&lt;/font&gt; &lt;/div&gt;
&lt;p&gt;That should be enough for you to ace that question during your technical interview. You may be curious as to how significant the performance differences between the approaches are, so I timed how long each took to generated numbers from 0 to 121393. The graph below shows the average number of ticks it took to complete the operations.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/FibonacciSolutionApproaches_69A7/image_2.png"&gt;&lt;img width="443" height="278" border="0" src="http://ridgway.co.za/images/ridgway_co_za/WindowsLiveWriter/FibonacciSolutionApproaches_69A7/image_thumb.png" alt="image" style="border: 0px none ;" /&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p&gt;If you are busy doing interviews, I hope this helps you out. Good luck!&lt;/p&gt;&lt;img src="http://ridgway.co.za/aggbug/194.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Eden Ridgway</dc:creator>
            <guid>http://ridgway.co.za/archive/2008/01/30/fibonacci-solution-approaches.aspx</guid>
            <pubDate>Wed, 30 Jan 2008 06:06:08 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2008/01/30/fibonacci-solution-approaches.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/194.aspx</wfw:commentRss>
        </item>
        <item>
            <title>CruiseControl Statistics Graphs</title>
            <link>http://ridgway.co.za/archive/2007/03/23/180.aspx</link>
            <description>&lt;p&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;[&lt;/span&gt;&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;Update&lt;/span&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;: &lt;/span&gt;Please note that this approach has been replaced by  a Dojo based solution available from &lt;a href="http://www.ridgway.co.za/archive/2007/04/22/Dojo-Based-CruiseControl-Statistics-Graphs.aspx"&gt;http://www.ridgway.co.za/archive/2007/04/22/Dojo-Based-CruiseControl-Statistics-Graphs.aspx&lt;/a&gt;] &lt;br /&gt;
&lt;/p&gt;
&lt;p&gt; Lets face it, the new CruiseControl Statistics report is damn ugly and is not as useful as it could be.  So I decided to remedy this by replacing the standard statistics xslt transform with one that generates both graphs and tables.  The results are graphs in CruiseControl that look something like the images below.  So what my new CruiseControl Statistics report gives you at the moment is as follows:&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;span style="font-weight: bold;"&gt;Build Report Graph&lt;/span&gt; - the number of failed/successful builds per day and the last build of each day&lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;span style="font-weight: bold;"&gt;Build Duration Graph&lt;/span&gt; - the average and maximum build duration per day&lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;span style="font-weight: bold;"&gt;Test Summary Graph&lt;/span&gt; - the average number of tests that passed, failed or were ignored&lt;/li&gt;
    &lt;li&gt;&lt;span style="font-weight: bold;"&gt;FxCop Summary Graph&lt;/span&gt; - the average number of warnings and errors per day&lt;/li&gt;
    &lt;li&gt;&lt;span style="font-weight: bold;"&gt;Build Summary Statistics Table&lt;/span&gt; - a table containing the data that was used to generate the daily stats&lt;/li&gt;
    &lt;li&gt;&lt;span style="font-weight: bold;"&gt;Build Detailed Statistics Table&lt;/span&gt; - contains the original detailed statistics data as would have been displayed in the old statistics report&lt;/li&gt;
&lt;/ul&gt;
&lt;table width="100%"&gt;
    &lt;tbody&gt;
        &lt;tr&gt;
            &lt;td valign="top" align="center"&gt;    &lt;a target="_blank" href="http://www.flickr.com/photos/47913250@N00/453488193/"&gt;&lt;img width="187" height="240" border="0" alt="BuildReportGraphs" src="http://farm1.static.flickr.com/247/453488193_0d4daf9344_m.jpg" /&gt;&lt;/a&gt; &lt;/td&gt;
            &lt;td valign="top" align="center"&gt; &lt;a href="http://www.flickr.com/photos/47913250@N00/431068505/" title="Photo Sharing" target="_blank"&gt;&lt;img width="240" height="99" border="0" src="http://farm1.static.flickr.com/152/431068505_4e1aec6aaf_m.jpg" alt="Build Statics Tables" /&gt;&lt;/a&gt;    &lt;/td&gt;
        &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;br /&gt;
&lt;a name="InstallationInstructions"&gt;&lt;/a&gt;&lt;span style="font-weight: bold; text-decoration: underline;"&gt;Installation Instructions&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I'll get on to the actual implementation in &lt;a href="http://www.ridgway.co.za/archive/2007/03/23/181.aspx"&gt;another post&lt;/a&gt;, but for now here is how to get it working on your CruiseControl.Net build server:&lt;a href="http://ridgway.co.za/archive/2007/03/23/181.aspx"&gt; &lt;/a&gt;
&lt;ol&gt; &lt;a href="http://ridgway.co.za/archive/2007/03/23/181.aspx"&gt;    &lt;/a&gt;
    &lt;li&gt;Download the latest stable release: &lt;a href="http://www.ridgway.co.za/Demos/CCNetStatisticsGraphs-1.3.zip"&gt;CCNetStatisticsGraphs-1.3.zip&lt;/a&gt;    .  Updates are also present at the end of this post if you feel adventurous.  &lt;span style="font-weight: bold; font-style: italic; color: rgb(255, 0, 0);"&gt;[Note: I have a new version available that uses the Dojo library]&lt;/span&gt;&lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;Unzip the webdashboard folder over the current CruiseControl webdashboard folder (usually found at C:\Program Files\CruiseControl.NET)&lt;/li&gt;
    &lt;li&gt;Open the dashboard.config file in the webdashboard folder and change the the projectStatisticsPlugin setting to point to the new StatisticsGraphs.xsl stylesheet, like this:&lt;br /&gt;
    &lt;br /&gt;
    &lt;div class="code"&gt; &lt;font color="blue"&gt;&amp;lt;&lt;/font&gt;&lt;font color="maroon"&gt;projectStatisticsPlugin&lt;/font&gt;&lt;font color="red"&gt; xslFileName&lt;/font&gt;&lt;font color="blue"&gt;="xsl\StatisticsGraphs.xsl"&lt;/font&gt;&lt;font color="red"&gt; &lt;/font&gt;&lt;font color="blue"&gt;/&amp;gt;&lt;/font&gt; 	&lt;/div&gt;
    &lt;/li&gt;
&lt;/ol&gt;
If it everything is in order you should see the following type of report when viewing your project statics:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;a title="Photo Sharing" target="_blank" href="http://www.flickr.com/photos/47913250@N00/431084927/"&gt;&lt;img width="240" height="124" border="0" alt="Build Report in CruiseControl" src="http://farm1.static.flickr.com/149/431084927_273e0aad54_m.jpg" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;
Future improvements to this will largely depend on the interest generated by this post.  If enough people find it useful I'll add new features.  Of course if you extend it, please let me know about it.  Some potential enhancements are:&lt;br /&gt;
&lt;ul&gt;
    &lt;li&gt;The ability to filter the report data&lt;/li&gt;
    &lt;li&gt;Additional reports such as code coverage and complexity reports (based on whether or not the stats are present of course)&lt;/li&gt;
    &lt;li&gt;Static table headers and sorting&lt;/li&gt;
&lt;/ul&gt;
&lt;span&gt;&lt;/span&gt;&lt;hr style="width: 100%; height: 2px;" /&gt;
&lt;br /&gt;
&lt;span&gt;&lt;span style="font-weight: bold; text-decoration: underline; color: rgb(0, 0, 0);"&gt;Notes&lt;/span&gt;&lt;br style="color: rgb(0, 0, 0);" /&gt;
&lt;br style="color: rgb(0, 0, 0);" /&gt;
&lt;span style="color: rgb(0, 0, 0);"&gt;Using PlotKit as the graph rendering engine unfortunately also results in the following issues in the graphs:&lt;/span&gt;&lt;br /&gt;
&lt;/span&gt;
&lt;ol&gt;
    &lt;li&gt;Graphs where you would only expect integer values, display decimals.  There does not seem to be any easy solution to this apart from modifying PlotKit code or ignoring the auto-scaled y-axis figures and writing one's own routine to determine the values and specify the y-axis tick values. [&lt;a style="font-style: italic;" href="#Updates"&gt;Integer y-axis values were implemented in version 1.4&lt;/a&gt;]     &lt;/li&gt;
    &lt;li&gt;There are problems with the labels being truncated on both the vertical and horizontal axis.  One can alleviate the problem somewhat using different margins but at some point you run into trouble.  The space required really needs to be determined dynamically (by the graphing engine).  [&lt;a style="font-style: italic;" href="#Updates"&gt;Problem mostly removed in version 1.5&lt;/a&gt;]&lt;/li&gt;
    &lt;li&gt;With the FxCop report it is difficult to predict whether or not the errors will be greater than warnings and vice-a-versa and hence you cannot use a filled line graph because it may cover up the one set of values.  What would be nice is if you could have the one set of values peek through the other using alpha blending.  Canvas does provide the ability to do this to some degree through the globalCompositeOperation property on the canvas, however this does not work in the IECanvas emulation layer.&lt;/li&gt;
&lt;/ol&gt;
Given the problems mentioned above I may very well switch to using another graphing approach or roll a modified version of Plotkit out.&lt;br /&gt;
&lt;br /&gt;
Some of the suggested enhancements I have received are:&lt;br /&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;span style="font-weight: bold;"&gt;Removal of outliers&lt;/span&gt; - Severe spikes completely mess up the scaling of the graphs.  This one requires some thought because obviously it could also have the affect of making people believe that the graphs are incorrect when in fact the outliers have been removed.&lt;/li&gt;
    &lt;li&gt;&lt;span style="font-weight: bold;"&gt;Horizontal scaling&lt;/span&gt; - Add in zero values to the graphs for missing days from the start of recorded builds. [&lt;a style="font-style: italic;" href="#Updates"&gt;Implemented in version 1.4&lt;/a&gt;]&lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;span style="font-weight: bold;"&gt;Removal of graphs if there no values&lt;/span&gt; - This one I had considered before and since someone else has asked for it, I'm going to implement it it.  It's most obvious when you are not using FxCop and end up with a horrible empty grey block in your report. [&lt;a style="font-style: italic;" href="#Updates"&gt;Implemented in version 1.4&lt;/a&gt;]&lt;/li&gt;
&lt;/ol&gt;
&lt;hr style="width: 100%; height: 2px;" /&gt;
&lt;a name="Updates"&gt;&lt;/a&gt;&lt;strong&gt;&lt;u&gt;Updates&lt;/u&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;span&gt; [Version 1.2 - 8 April 2007] - Fixed an issue caused by apostrophes in the generated statistics (new version 1.2 released) (reported by Grant Drake).&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&lt;a href="http://www.ridgway.co.za/Demos/CCNetStatisticsGraphs-1.3.zip"&gt;Version 1.3&lt;/a&gt; - &lt;/span&gt;&lt;span&gt;8 April 2007] - Fixed an issue in the duration calculation where the duration had an int + string value which of course resulted in a string concatenation :) &lt;/span&gt;&lt;span&gt;(reported by Grant Drake).&lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;span&gt;[&lt;a href="http://www.ridgway.co.za/Demos/CCNetStatisticsGraphs-1.4.zip"&gt;Version 1.4&lt;/a&gt; - 9 April 2007] - Implemented the following features:&lt;/span&gt;
    &lt;ol&gt;
        &lt;li&gt;&lt;span&gt;Graphs are not displayed when there are no values for them&lt;/span&gt;&lt;/li&gt;
        &lt;li&gt;&lt;span&gt;The x-series values are now a timeline not just all the builds next to each other.  So if there was a build on the 1st of a month and the next build was only on the 4th, zero values are filled in for the 2nd and 3rd of the month.  This has a down side though because at the moment it is displaying weekends for which most projects will have no activity and if a project is worked on sporadically you have large gaps in the graph.  I do believe however there is value in seeing the activity over time in this way and maybe it it worth having some sort of filtering option that allows one to remove weekends and/or days for which there are no statistics.&lt;br /&gt;
        &lt;/span&gt;&lt;/li&gt;
        &lt;li&gt;&lt;span&gt;The y-axis no longer displays values (I manually determined the y-ticks and added them to the graph).&lt;br /&gt;
        &lt;/span&gt;&lt;/li&gt;
    &lt;/ol&gt;
    Only download this release if you are curious about the new functionality.  I will be writing a series of WatiN tests to ensure that everything is working as expected as the mini-project evolves.  My biggest concern for this version is with locales specifically in relation to dates.  To fill in missing days I've used JavaScript date functions and there is an assumption that the browser's locale is the same as that of the server.  Unfortunately this is due to the fact that the CruiseControl month in the statistics xml file is a short name.  Furthermore I cannot use the StartTime value because it is possible that the format of that information is not consistent: one of my example statistics files has StartTime values in both yyyy/MM/dd and dd/MM/yyyy format.&lt;br /&gt;
    &lt;em style="color: rgb(255, 0, 0);"&gt;I found out on the 22 April 2007 that this version suffers from a daylight savings time bug that affected projects that started when daylight savings was in effect.  I have fixed this release.&lt;/em&gt;&lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;span&gt;[&lt;a href="http://www.ridgway.co.za/Demos/CCNetStatisticsGraphs-1.5.zip"&gt;Version 1.5&lt;/a&gt; - 10 April 2007] - Modified the PlotKit canvas to allow rendering of HTML labels (i.e. it won't escape your tags) and now draws the graph border and tick marks in the same colour as the axis label colour (I may remove this modification and simply create a new custom canvas).  This has allowed me to reduce the font size of the x-axis labels and put the date on a separate line to the build label.  Unfortunately it has also meant that I'm now distributing the uncompressed version of the PlotKit library (I may use a JavaScript compressor on them later).&lt;/span&gt; &lt;em style="color: rgb(255, 0, 0);"&gt;I found out on the 22 April 2007 that this version suffers from a daylight savings time bug that affected projects that started when daylight savings was in effect.  I have fixed this release.&lt;/em&gt;&lt;br /&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;span&gt;[Version 2.1] - This is available from &lt;a href="http://www.ridgway.co.za/archive/2007/04/22/Dojo-Based-CruiseControl-Statistics-Graphs.aspx"&gt;this post&lt;/a&gt;.&lt;br /&gt;
    &lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://ridgway.co.za/aggbug/180.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Eden Ridgway</dc:creator>
            <guid>http://ridgway.co.za/archive/2007/03/23/180.aspx</guid>
            <pubDate>Fri, 23 Mar 2007 05:04:17 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2007/03/23/180.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/180.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Finally Converted my blog from Dasblog to Subtext</title>
            <link>http://ridgway.co.za/archive/2007/01/04/173.aspx</link>
            <description>After using Dasblog as my blogging engine for quite some time I decided that it was time to change to an engine that had a few more features.  I was also getting a bit fed up with various issues I had with Dasblog that may very well have been due to my hosting configuration.  In any case, Dasblog was great but I'm hoping that Subtext will be better.  The conversion from Dasblog to &lt;a href="http://www.subtextproject.com/"&gt;Subtext &lt;/a&gt;was no small feat.&lt;br /&gt;
&lt;br /&gt;
After doing quite a bit of looking around it was pretty obvious that using &lt;a href="http://codeplex.com/Wiki/View.aspx?ProjectName=BlogML"&gt;BlogML&lt;/a&gt; as the intermediate conversion format was the way to go.  However Dasblog 1.9 does not support exporting of the blog content as BlogML.  On a few forum posts it was mentioned that you could get a proof of concept implementation from Scott Hanselman, but I didn’t see why I should bother him.  He obviously has good reason not to release it yet.  So I decided to see what alternatives I had.&lt;br /&gt;
&lt;br /&gt;
The approach I picked was to use the blog mirroring feature of Community Server that effectively allows you to use an RSS feed to populate your blog.  Once I had mirrored my blog I exported it to BlogML and then imported it into my local Subtext installation.  I copied the all the binary content from my Dasblog content folder to the relevant Subtext images folder and then proceeded to use a combination of database updates and manual post edits to fix the links.  I was hoping that once I had done that the Subtext export would embed all the images and the related post content in the BlogML for me.  Unfortunately this is not the case.  The BlogML feature only exports the related images as embedded attachments.  I then had to manual edit the blog XML file to ensure that when I imported the BlogML file on my live web site that the links would point to the correct folders on that server.  The Subtext “clear blog content” feature was a real life saver, because I had to repeat the import process a few times before I was happy with it.  I still concerned that I hadn’t found all the links in the blog so I used &lt;a href="http://www.dead-links.com"&gt;http://www.dead-links.com&lt;/a&gt; to spider my blog and catch anything else I had missed.&lt;br /&gt;
&lt;br /&gt;
It ended up taking a lot longer than I expected but I’m hoping that it will be well worth the effort.&lt;img src="http://ridgway.co.za/aggbug/173.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Eden Ridgway</dc:creator>
            <guid>http://ridgway.co.za/archive/2007/01/04/173.aspx</guid>
            <pubDate>Thu, 04 Jan 2007 05:01:58 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2007/01/04/173.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/173.aspx</wfw:commentRss>
        </item>
        <item>
            <title>WebResource.axd Security Issue</title>
            <link>http://ridgway.co.za/archive/2006/07/04/webresourceaxdsecurityissue.aspx</link>
            <description>Today one of my colleagues had an issue with IIS authentication of requests going to .Net 2's WebResource.axd file to serve embedded control resources.  The problem was that we wanted the site to run under integrated security, but there was one page in the site that needed to run under basic authentication because it was being portalised (through Plumtree).  That page used a web control that had an embedded resource which of course resulted in a call to  WebResource.axd being made.  This call however was breaking when it was being proxied by Plumtree.  If we set the whole application to use basic authentication, access to WebResource.axd worked just fine.  This indicated to us that it was inheriting the permissions of the root folder so we came up with a little workaround that allowed us to set the IIS security for the virtual file.  The process we followed was as follows:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;
Create a blank WebResource.axd file in the root of the application&lt;/li&gt;
&lt;li&gt;
Go into IIS manager and set the authentication on the file to "Basic Authentication"&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;
Using explorer delete the WebResource.axd file&lt;/li&gt;
&lt;/ol&gt;
This seems to work like a charm.  Our rational for why it works is that the IIS
Metadatabase entry for WebResource.axd still exists and therefore it applies those
custom security settings as opposed to simply taking the parent's settings.&lt;br /&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img src="http://ridgway.co.za/aggbug/168.aspx" width="1" height="1" /&gt;</description>
            <guid>http://ridgway.co.za/archive/2006/07/04/webresourceaxdsecurityissue.aspx</guid>
            <pubDate>Tue, 04 Jul 2006 01:26:43 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2006/07/04/webresourceaxdsecurityissue.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/168.aspx</wfw:commentRss>
        </item>
        <item>
            <title>TrueCrypt Utility</title>
            <link>http://ridgway.co.za/archive/2006/01/13/truecryptutility.aspx</link>
            <description>&lt;p&gt;
While reading &lt;a href="http://www.hanselman.com/blog/"&gt;Scott Hanselman's blog&lt;/a&gt; I
discovered &lt;a href="http://www.truecrypt.org/"&gt;TrueCrypt&lt;/a&gt;.  The utility allows
you to create an encrypted file and mount it as a drive.  You can also encrypt
an entire device, eg. Flash Disk, or hard drive.
&lt;/p&gt;
&lt;img src="http://ridgway.co.za/aggbug/158.aspx" width="1" height="1" /&gt;</description>
            <guid>http://ridgway.co.za/archive/2006/01/13/truecryptutility.aspx</guid>
            <pubDate>Fri, 13 Jan 2006 00:42:00 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2006/01/13/truecryptutility.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/158.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Blog Posting Application</title>
            <link>http://ridgway.co.za/archive/2005/10/03/blogpostingapplication.aspx</link>
            <description>&lt;p&gt;
I found a free alternative to &lt;a href="http://blogjet.com/"&gt;BlogJet&lt;/a&gt; today called &lt;a href="http://www.qumana.com/"&gt;Qumana&lt;/a&gt;. 
It supports the following APIs: 
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
metaWeblog - which DasBlog supports 
&lt;/li&gt;&lt;li&gt;
Blogger 
&lt;/li&gt;&lt;li&gt;
MoveableType 
&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="http://ridgway.co.za/aggbug/143.aspx" width="1" height="1" /&gt;</description>
            <guid>http://ridgway.co.za/archive/2005/10/03/blogpostingapplication.aspx</guid>
            <pubDate>Mon, 03 Oct 2005 01:57:49 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2005/10/03/blogpostingapplication.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/143.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Alchemi.Net - Grid Computing Framework</title>
            <link>http://ridgway.co.za/archive/2005/09/11/alcheminetgridcomputingframework.aspx</link>
            <description>&lt;p&gt;
The &lt;a href="http://www.alchemi.net/"&gt;Alchemi&lt;/a&gt; framework claims to allow you to
create a virtual supercomputer through a grid of computers.  Grid computing is
nothing new, but what is cool about this project is that it is .Net based.  This
is something I would love to play with just to see how effective a grid really is. 
A free 10 computer grid is available &lt;a href="http://www.private-grid.nl/"&gt;here&lt;/a&gt; if
anyone is interested.
&lt;/p&gt;
&lt;img src="http://ridgway.co.za/aggbug/132.aspx" width="1" height="1" /&gt;</description>
            <guid>http://ridgway.co.za/archive/2005/09/11/alcheminetgridcomputingframework.aspx</guid>
            <pubDate>Sun, 11 Sep 2005 15:32:45 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2005/09/11/alcheminetgridcomputingframework.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/132.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Replacing Notepad</title>
            <link>http://ridgway.co.za/archive/2005/08/13/replacingnotepad.aspx</link>
            <description>&lt;p&gt;
If you want to replace notepad with a program of your choice, head over to &lt;a href="http://www.shahine.com/omar/HowToReplaceNotepadexeWithNotepad2exe.aspx"&gt;Omar's
blog&lt;/a&gt; for instructions on how to do it.
&lt;/p&gt;
&lt;img src="http://ridgway.co.za/aggbug/118.aspx" width="1" height="1" /&gt;</description>
            <guid>http://ridgway.co.za/archive/2005/08/13/replacingnotepad.aspx</guid>
            <pubDate>Sat, 13 Aug 2005 06:12:26 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2005/08/13/replacingnotepad.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/118.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Trackback Spam</title>
            <link>http://ridgway.co.za/archive/2005/08/13/trackbackspam.aspx</link>
            <description>&lt;p&gt;
If you are being irritated by trackback spam and you use Dasblog you'll want to head
over to &lt;a href="http://briandela.com/blog/archive/2005/06/29/652.aspx"&gt;Dela's blog&lt;/a&gt; and
install his ASP.Net HTTP module.  Great work dude!
&lt;/p&gt;
&lt;img src="http://ridgway.co.za/aggbug/117.aspx" width="1" height="1" /&gt;</description>
            <guid>http://ridgway.co.za/archive/2005/08/13/trackbackspam.aspx</guid>
            <pubDate>Sat, 13 Aug 2005 05:53:33 GMT</pubDate>
            <comments>http://ridgway.co.za/archive/2005/08/13/trackbackspam.aspx#feedback</comments>
            <wfw:commentRss>http://ridgway.co.za/comments/commentRss/117.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>
