Colin Eberhardt's Adventures in WPF

Presentation on Agile Development

January 27th, 2010

Last week I gave a presentation on Agile Development for an event hosted by Codeworks and Sunderland Software City. This blog post is a brief review of my presentation and the event itself.

The event was titled, “An Introduction to Agile Methodology – Get a Head Start in 2010″, which was suitably broad for my liking! I have experienced heavyweight, formal methodology in the shape of the Rational Unified Process; At Scott Logic, we prefer the Agile way, keeping it light. However, we have a wide range of customers, each with their own preferred development process, so we must exercise further agility by adapting to their way of working. For this reason, I did not want to highlight a single Agile methodology, rather, the common themes held by all Agile methods. My talk was titled “With Agile Development – Communication is the Key”, which pretty much sums up my own opinion on what makes the Agile approach so successful.

To summarise my presentation in a single paragraph; requirements and estimation are probably two of the greatest challenges to any software project. Requirements are hard to capture and as a result most people would agree that it is better to allow them to evolve. Estimation is something that most software engineers would rather avoid! the most common approach is to turn to the most senior member of the team and go with what they suggest. Agile, iterative methodologies promote communication between team members, and between the team and the stakeholders. In this way, the stakeholders are engaged on a regular basis, hastening the evolution of requirements. As the team learns from their previous iterations, their estimations improve. Furthermore, estimation becomes a team exercise, with the team communicating / discussing the tasks. This provides a far superior estimate of effort and team buy-in. In short, the iterative cycles of any iterative methodology promote communication, and it is this which makes them successful. Or, even-shorter, my last slide pretty much captures what I am trying to say:

Following the talks, which included mine, an introduction to Agile Development from Andrew Rumfitt (Perfect Image), and a discussion of the application of Agile techniques to non software projects by Colin Ashurst (Durham Business School), everyone played the “Ball Point Game”. This is a simple training exercise where small teams are formed, the goal being to pass as many balls between the team members as possible in two minutes. However, the added twist is that before each 2 minutes “iteration” the team has to estimate how many balls they will pass. Interestingly, most teams got better with each iteration, passing more balls, but more importantly as they found their natural velocity, their estimates improved.

The Q&A session followed the game, with myself and Andrew fielding questions. This was certainly an interesting challenge! A few of my favourite questions were as follows:

“If you allow requirements to change, what about the project budget? I cannot see how this would be workable?”

Great question! and not an easy one to answer. The problem with projects where the price and requirements are determined up-front is that one of the two parties involved is probably going to be unhappy with the end result. If the requirements are set-in-stone, forming an immovable contract, their natural evolution is stifled. The customer may get exactly what the described at the start of the project, however, it is probably not what they want now after they have used the software and had a chance to think more deeply about the problem. With an Agile, iterative approach, the requirements change and improve as do the estimates. And, as a result, the original budget (or scope) may prove to be unworkable. However, this extra information empowers the customer, allowing them to make a decision about the financial impact of this change in their own requirements. Although, this will only work if their is good communication and trust. To quote the Agile Manifesto, “Customer collaboration over contract negotiation”.

“I am sure that you getter better at estimating after a few projects, however, if you start a project with an Agile approach, and a few days into an iteration you find that your estimates are totally wrong, do you stop the iteration and start out again?”

This question certainly reveals the fear that a lot of software engineers have of estimation! One important point to note is that the person asking the question indicates that they think you need to run a number of agile projects before you get good at estimating. I think this is a flawed assumption. Every software project is different, and there is a certain amount of learning involved in every project. You learn about the problem being solved and about the capabilities, or velocity, of your team. The “Ball Point Game” we played earlier illustrates this point quite nicely, every team, after a few iterations, started to give very accurate estimate. With short iterations the feedback is very rapid, as a result you do not need a lot of experience from previous projects to start giving accurate estimates.

Regarding the question itself, should you abort the sprint? I don’t think so. If everyone (developers, and stakeholders) has bought into the agile approach, what some might see as a failure should be seen as a valuable lesson. Continue with the sprint, maximise the learning. Do not abort the sprint and try to sweep it under the carpet! This does not promote openness. Besides, can you be sure that your revised estimate after just a few days is better? Have you learnt enough?

“Do you need the right tools and the right people for Agile development?”

Personally I would always value people over tools, regardless of the process or project. Agile development should be quite lightweight. You can probably get away with just a simple spreadsheet, or a few post-it notes!

One problem with an approach that favours communication is that software engineers are not always the most communicative. A recent codeproject survey confirmed the commonly held belief that most software engineers are introverts (the INTJ personality type was the most common). Whilst it is certainly not necessary that all team members are extroverts, I think it does help if individuals occupying certain key roles, where they facilitate communicati0n (such as the ScrumMaster in the SRUM methodology), are comfortable communicators.

A few questions followed about how you find the right kind of people. At Scott logic, our interviews concentrate far more on people’s problem solving abilities and how they tackle problems than on just writing code.

After these, and other challenging questions, we have a well earned beer and some food …

An interesting and enjoyable events.

Regards, Colin E.

My Mix10k entry – Old Skool demo – plus a few tips

January 7th, 2010

This blog post is about my entry to the Mix10k code competition, and old-skool demo, plus a few tips about how to keep you code size to below 10k.

The mix10k challenge, where you are given 10k to create a Silverlight / HTML5 application, has been on my mind for a while … the Christmas vacation was the perfect excuse to put together my entry. Inspired by the demo’s of the Amiga era, here is my mix10k old-skool demo entry:

You can view my entry (and more importantly vote for it!) at the mix10k gallery.

For me the greatest challenge was the music, not least for the fact that I am no good at writing the stuff myself! The mix10k rules are fairly relaxed, you can download content, such as images and music, allowing you to circumnavigate the 10k limit. However, I thought it would be a more interesting challenge to pack everything into 10k.

Size-limited demos typically use synthesis rather than sampling for the musics. Unfortunately Silverlight isn’t really geared towards sound synthesis, however, a few people have managed to create synthesized media sources. I decided to go the sampling route and use an MP3 track for my music, the idea being to use a short, highly compressed MP3 track and loop it. I posted a message on the 8bitcollective forums and within a day had a funky, and highly compressed, 4 second MP3 clip for my demo. The MP3 filesize of 4,248 bytes left me 5,992 to play with.

However, the next challenge was looping the audio, which is unfortunately something that is not supported out-of-the-box. For longer media clips it is acceptable to catch the MediaEnded event, re-wind and re-start. However, there is a delay of about half a second, which with a 4 second looped audio clip is pretty disruptive! Fortunately Silverlight does expose a lower level API for media via the abstract class MediaStreamSource, which has virtual methods which you can override to supply audio direct from a stream. The codeplex project ManagedMediaHelpers is a great place to start for information on how to load MP3 audio from a file. Typically the code to read and stream an MP3 file is over 10k, however, I was able to trim this down to roughly 1k by removing all the code for parsing the MP3 headers, replacing it with the hard-coded values for my specific MP3 file.

Unfortunately, when the audio was looped, it just didn’t sound right. The trouble is, within MP3 files, the audio is split into frames. Using a useful utility from codeproject, I found that my MP3 file consisted of 56 frames of ~67ms in length. However, the audio loop was not a multiple of 67ms. To rectify this, I downloaded a copy of the free audio editor Audacity, and ’stretched’ the track to fit into an integer number of frames, and re-encoded in MP3 format via lame. Finally, I had looping MP3 audio! (and 4,958 bytes left)

audacity

After the battle I had with the audio, constructing the visuals, the scrolling text, interference patterns, plasma and starfield was a piece of cake!

Here are a few quick tips for keeping your filesize under 10k.

  • Use the var keyword wherever possible
     
  • Use the using for aliasing frequently used types

    For example:

    using K = System.Windows.Media.MediaSourceAttributesKeys;
    using J= System.Windows.Media.MediaStreamAttributeKeys;
    using M = System.Math;

    With type names as long as MediaSourceAttributesKeys, you only need to use them three times for a using alias to make sense!

  • chain initialisation of variables

    The following code:

    int x1 = sin1(8) + 200
    int y1 = sin1(3) * 10 + 100
    int g = (tx - x1) * (tx - x1);

    Can be shortened to:

    int x1 = sin1(8) + 200, y1 = sin1(3) * 10 + 100, g = (tx - x1) * (tx - x1);
  • Tabs not spaces

    If you are not to bothered about squeezing the most out of those 10k bytes and want your code to look pretty, at least save yourself a bit of room by using Tabs!

  • Choose wisely between XAML and C#

    One big advantage that XAML has over C# is its use of value converters, compare the following XAML:

    <Ellipse Fill="White"/>

    to its equivalent in C#:

    var el = new Ellipse()
    {
       Fill = new SolidColorBrush(Color.FromArgb(255,255,255,255))
    };

    In this case, XAML is a clear winner.

  • Use lambda expressions for event handlers

    You can achieve great savings by including your event handling logic within anonymous delegates (via lambda expressions), it also means that you can move variables from class scope (i.e. files) to method scope and use the var keyword. Compare:

    WriteableBitmap bitmap = new WriteableBitmap(200,200);
     
    MyPage()
    {
    	var t = new DispatcherTimer();
    	t.Tick +=new EventHandler(t_Tick);
    }
     
    void  t_Tick(object sender, EventArgs e)
    {
    	// do stuff with the bitmap
    	bitmap.Invalidate();
    }

    to:

    MyPage()
    {
    	var bitmap = new WriteableBitmap(200,200);
    	var t = new DispatcherTimer();
    	t.Tick += (s,e) =>
    		{
    			// do stuff with the bitmap
    			bitmap.Invalidate();
    		};
    }
  • Ditch that App!

    The App.xaml and App.xaml.cs full of template code that you do not need. Simply ditch these files entirely and replace with a minimal application that indicates the page to display:

    public class A : Application
    {
        public A()
        {
            Startup += (i, j) => RootVisual = new MainPage();
        }
    }
  • Minify your code

    Perhaps the greatest savings can be achieved by ‘minifying’ your code, i.e. removing any extra whitespace and reducing variable, method, types names to single characters. The problem is that in doing so, your code will become unreadable!

    In order to minify my code yet maintain readability I created a very simple console application that read my application source and performed a bunch of string replacements in order to reduce its size …

    static Dictionary<string, string> reps = new Dictionary<string, string>()
    {
      {System.Environment.NewLine, ""}, 
      {"  ", " "},
      {" = ", "="},
      {" == ", "=="},
      {" * ", "*"},
      {" > ", ">"},
      {" < ", "<"},
      ...
     
      // methods 
      {"Timer_Tick", "T"},
      {"CreateLine", "g"},
      {"DrawLines", "ln"},
      ...
     
      // xaml
      {"grid", "q"},
      {"image", "o"},
      {"canvas", "c"},
      {"MainPage", "Y"},
      ...
    };

    The output of this console application is sent to another project which builds my final entry. The result of this was to make my reasonably compact code 47% smaller!

You can download my thoroughly messy and unreadable code: mix10ksrc.zip

And vote for it on the mix10k site (Did I say that already?)

Regards, Colin E.

Rippling Reflection Effect with Silverlight 3’s WriteableBitmap

December 16th, 2009

This blog post demonstrates how Silvelight 3’s WriteableBitmap can be used to create a UserControl that renders the content of any other Framework Element as a reflection with an animated ripple effect

I was sad to hear the news earlier this year that Yahoo! was pulling the plug on GeoCities. Somewhere buried deep within GeoCities is the first web page I ever created, complete with “Under Construction” banner, animated GIFs, guestbooks, and nasty background music. Unfortunately, I have no idea what the URL for that page was, and this is long before Google ran my life!

This blog post is a tribute to one of the many dynamic effects that were popular in the 90’s, animated reflections. These Java applets were quite popular for a while, but have gone the same way as GeoCities. Perhaps it is time for a revival?

The Silverlight application shown above contains a UserControl which renders an animated reflection of a referenced FrameworkElement.

The code which produces the ripple is very simple, A DispatcherTimer increments _time and redraws the reflection. The reflection itself is achieved by constructing a WriteableBitmap from the referenced element, allowing us to grab its pixel values. Another WriteableBitmap is constructed for the reflection image, and rows of pixels are copied across with a suitable Y offset to produce the ripple effect:

private double _time = 0.0;
 
private void Timer_Tick(object sender, EventArgs e)
{
    // increment phi and update the reflection
    _time += 0.4;
    UpdateReflection();
}
 
/// <summary>
/// Copies an inverted image of the referenced FrameworkElement
/// with a 'ripple' effect
/// </summary>
private void UpdateReflection()
{
    FrameworkElement reflectedFE = ReflectedElement as FrameworkElement;
 
    if (reflectedFE == null)
        return;
 
    // synchronize the element width
    Width = reflectedFE.ActualWidth;
 
    // copy the source into a writeable bitmap
    WriteableBitmap sourceBitmap = new WriteableBitmap(reflectedFE, null);
 
    // create a target which is the same width / height as the reflection element
    WriteableBitmap targetBitmap = new WriteableBitmap((int)ActualWidth, (int)ActualHeight);
 
    // copy the reflection
    for (int y = 0; y < targetBitmap.PixelHeight; y++)
    {
        double amplitude = ComputeAmplitude(y, targetBitmap.PixelHeight);
        double sinusoid = ComputeRipple(y, targetBitmap.PixelHeight, _time);
 
        // the offset to the y value index caused by the ripple
        int yOffset = (int)(sinusoid * amplitude);
 
        // compute the Y position of the line to copy from the source image
        int sourceYLocation = sourceBitmap.PixelHeight - 1 -
            ((y + yOffset) * sourceBitmap.PixelHeight) / targetBitmap.PixelHeight;
 
        // check that this value is in range
        sourceYLocation = Math.Min(sourceBitmap.PixelHeight - 1, Math.Max(0, sourceYLocation));
 
        // copy the required row
        int sourceIndex = sourceYLocation * sourceBitmap.PixelWidth;
        int targetIndex = y * targetBitmap.PixelWidth;
        for (int i = 0; i < targetBitmap.PixelWidth; i++)
        {
            targetBitmap.Pixels[targetIndex++] = sourceBitmap.Pixels[sourceIndex++];
        }                
    }
 
    targetBitmap.Invalidate();
 
    LayoutRoot.Source = targetBitmap;
}
 
/// <summary>
/// Compute the amplitude of the oscillations at a given Y position
/// </summary>
private double ComputeAmplitude(int y, int height)
{
    // our amplitude range is 1 to 3
    return ((double)y * 2) / (double)height + 1.0;
}
 
/// <summary>
/// Compute the sinusoid applied to teh image at the given location
/// </summary>
private double ComputeRipple(int y, int height, double time)
{
    // provide a ripple that is the combination of two out of phase sine waves
    double phaseFactor = (double)y / (double)height;
    return Math.Sin(time + phaseFactor * 16) + Math.Sin(time + phaseFactor * 30)
        + Math.Sin(time + phaseFactor * 62);
}

The XAML for this user control is simply an image with an opacity gradient:

<UserControl x:Class="SilverlightShimmer.ReflectionControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Width="300" Height="300">
    <Image x:Name="LayoutRoot">
        <Image.OpacityMask>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF000000" Offset="0"/>
                <GradientStop Color="#00000000" Offset="1"/>
            </LinearGradientBrush>
        </Image.OpacityMask>
    </Image>
</UserControl>

This control is associated with our Christmas-ey image as follows:

<UserControl x:Class="SilverlightShimmer.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:SilverlightShimmer" Width="320" Height="260">
 
    <Grid Background="Black">
 
        <StackPanel Orientation="Vertical" Margin="10">            
            <Border  x:Name="controlToReflect" BorderThickness="5" BorderBrush="LightGray"
                     CornerRadius="3" HorizontalAlignment="Center">
                <Image  Source="christmas.jpg" Margin="3"
                        Stretch="None"/>
            </Border>
            <local:ReflectionControl x:Name="shimmer" Height="80" Margin="3"
                       ReflectedElement="{Binding ElementName=controlToReflect}"/>
        </StackPanel>
    </Grid>
</UserControl>

One interesting point here is the way in which the Border and Image are associated with the ReflectionControl. The ReflectedElement property is bound to the Border via an ElementName binding, however this binding has no Path. Therefore, rather than binding to a property of the referenced element, the ReflectedElement is bound to the element itself. Hence, no need for any code behind to associated the ReflectionControl with the element(s) to render.

This control can be used to render a reflection of anything (even a reflection of a reflection if you so wish). Here is a more complex example:

You can download the full sourcecode here: SilverlightShimmer.zip

Regards, Colin E.

Simple Logging Façade released on codeplex today

December 2nd, 2009

Today, Philipp Sumi and I and are proud to announce the release of SLF – the Simple Logging Façade:

slf

SLF is a framework with a simple but ambitious mission: To provide every developer with the means to easily plug in logging functionality into her application.
As such, it aims at two fundamental goals:

  • Simplicity: SLF allows you to plug in solid logging functionality into your application with literally one line of code, while providing you with an upgrade path to complex logging scenarios at any time.
  • Flexibility: SLF provides you with a common interface that decouples the logging framework of your choice (e.g. log4net, EntLib, or NLog) from your code. This eliminates dependencies on a given framework, thus allowing you to switch (or even combine!) frameworks at any time. Furthermore, SLF’s modular architecture allows you to plug-in custom logging strategies very easily.

You can:

Regards, Colin E.