Less code matters: don’t repeat yourself

June 27, 2011 at 9:24 am | Posted in C#, GIMP, Programming, Uncategorized | Leave a comment

I got quite a few reactions on my previous blog post both positive and negative. The message of the negative comments was mostly that short code shouldn’t be a goal since it tends to result in unmaintainable code. Next some people accused me of writing ‘clever code’ like using lambda functions which they reasoned are not going to be understood by those who will maintain my code. Despite of the tone of some of these comments, they are all very interesting and surely hold some value. At least they gave me a couple of new ideas for future blogs.

In this post I’ll show how I removed another 4 lines from the GIMP# AverageBlur plug-in. The following lines of code have been bothering me for a long time but I never took the time for fixing them:

using System;

namespace Gimp.AverageBlur
{
  class AverageBlur : Plugin
  {
    static void Main(string[] args)
    {
      new AverageBlur(args);
    }

    AverageBlur(string[] args) : base(args, "AverageBlur")
    {
    }

    // Remaining code omitted
}

There are 2 things I didn’t like about this code:

  1. The Main function creates an object which is apparently unused. The reason is that in the constructor all kind of magic happens, include a call to gimp_main which starts the actual GIMP plug-in. This is hard to understand: constructors should be straightforward. Just create the object and make sure it is in a defined state. Nothing more than that.
  2. Every GIMP# plug-in is derived from the Plugin class but still seems to need it’s own constructor. The only reason for this is that I have to parse a couple of parameters like the arguments (args) and the package name that is used for translation. However this package name is always the same as the plug-in name.

While it is easy to get rid of the first disadvantage by introducing an explicit function call with the object as parameter, that would still leave me with a constructor for every plug-in I write. However, that was my first attempt to clean up this code:

using System;

namespace Gimp.AverageBlur
{
  class AverageBlur : Plugin
  {
    static void Main(string[] args)
    {
      // Do all magic stuff in GimpMain instead of in constructor
      GimpMain(new AverageBlur(args));
    }

    AverageBlur(string[] args) : base(args, "AverageBlur")
    {
    }

    // Remaining code omitted
}

Now if I just remove the parameters from the constructor and pass them to GimpMain I can use the default constructor so I don’t have to define it anymore:

using System;

namespace Gimp.AverageBlur
{
  class AverageBlur : Plugin
  {
    static void Main(string[] args)
    {
      // Do all magic stuff in GimpMain instead of in the constructor
      GimpMain(new AverageBlur(), args, "AverageBlur");
    }

    // Remaining code omitted
}

We just removed 4 lines of code while at the same time improving readability. We are left with one single line that calls GimpMain where all the magic happens. Still this line looks a bit like boilerplate code since it will be exactly the same for every plug-in. The final code I used looks like:

using System;

namespace Gimp.AverageBlur
{
  class AverageBlur : Plugin
  {
    static void Main(string[] args)
    {
      // Do all magic stuff in GimpMain instead of in the constructor
      GimpMain<AverageBlur>(args);
    }

    // Remaining code omitted
}

The Plugin base class instantiates the object as follows:


abstract public class Plugin
{
   protected static void GimpMain(string[] args) where T : Plugin, new()
   {
      var plugin = new T();
      Catalog.Init(typeof(T).Name, Gimp.LocaleDirectory);

      // Remaining code omitted
   }
}

I introduced a generic method. The type parameter T has the constraints that it should be derived from the Plugin class and that it should have a default constructor. In line 5 an object of this type is created. Line 6 now gets the class name (typeof(T).Name) which I use as catalog name for the locale.

Over time the size history for the AverageBlur plug-in now looks like this:

Current code size is now 54 % of what it once was, down from 60 % in the previous revision.

Some people might wonder if this code isn’t ‘too clever’. Generic methods in C# is not something every programmer might be 100 % comfortable with. In a next blog post I am going to write about clever code and try to quantify this a bit more. Until then, enjoy reading this post and I’m looking forward to any comments and/or improvements!

Less code matters

June 16, 2011 at 9:31 pm | Posted in Agile, C#, GIMP, Programming | 11 Comments

One of Edsger Dijkstra‘s quotes I really like is: If we wish to count lines of code, we should not regard them as “lines produced” but as “lines spent”. This hasn’t changed since those days despite of almost infinite amounts of processing power, memory and powerful IDE support. In fact I would argue that thanks to this power we are now able to build huge systems which makes carefully spending these precious lines of code even more important. The main reason still is that once you start producing code, you have to maintain it. And maintaining code will take effort and therefore will cost money.

Over the years I have worked on a lot of code, both existing (as in maintenance projects) and while building new software. My personal statement was and still is that any non-trivial amount of code can easily be reduced to half it’s size while increasing readability at the same time. There are several ways to reduce code size. As an example I will take 18 revisions (from CVS) from a small GIMP# plug-in and show what I did to gradually reduce the size.

Let’s start with looking at the graph that depicts the code size first:

This is a small plug-in that calculates the average color of all pixels in an image. Next the plug-in sets the color of all pixels in the image to this average color. This functionality is provided as the “Blur Average” filter in Photoshop and I wrote it because it didn’t exist for the GIMP yet.

I took the size in lines of code from CVS. I included all white lines and comment lines, apart from the standard 20 lines of GPL header at the start of every file. Next I used the maximum size (at revision 3) as 100 % and scaled the rest of the revision sizes relative to this maximum. Now let’s see what happened at these 18 revisions:

  1. Revision 1.1. Checked in initial code. This was mainly the boiler plate code that comes with any plug-in written in the GIMP# framework. At that moment this was 50 LOC.
  2. Revision 1.2. Plug-in now fully functional. Wrote two straightforward loops, one to calculate the average, the other one to apply it to all pixels. Code has grown to 63 LOC.
  3. Revision 1.3. A GIMP# co-developer added code for i18n. Code now at it’s maximum size of 68 LOC. Still pretty small of course. Keep in mind that a similar basic plug-in written in C (the default GIMP programming language) takes about twice as much code.
  4. Revision 1.4. Accidentally  in revision 1.3 a key (from a key/value pair) was translated. Fixed that which saved 2 lines. Nice start on my way to a smaller plug-in. 66 LOC left.
  5. Revision 1.5. The i18n initialization that happened in all plug-ins, was moved to the constructor of the base class, removing another 3 lines. 63 LOC left.
  6. Revision 1.6. Until this revision I had to handle all pixels as arrays of 3 (or 4, including alpha channel) bytes which held the RGB(A) values. I abstracted this into a Pixel class and wrote an iterator that calls a delegate for every pixel in this particular image. I added some overloading magic for Pixel objects that allows me to add pixels and easily calculate the average. Of course this added to the main GIMP# library, but my plug-in code shrunk to 55 LOC.
  7. Revision 1.7. A bit of cleaning up, code size stayed at 55 LOC
  8. Revision 1.8. Instead of returning a set of all supported procedures (needed to register a plug-in within GIMP) this same function now returns the C# yield construct, saving another 3 lines. 52 LOC left.
  9. Revision 1.9. Minor clean-up, improving readability. Code still at 52 LOC.
  10. Revision 1.10. Improved algorithm to calculate the average. In previous revisions I was updating a counter (that had to be initialized) inside the first iterator so I could later divide the sum by this counter to calculate the average. Of course the number of pixels within an image (or selection) is already known and can be asked directly from the iterator class. This allowed me to remove another 2 lines, leaving the size now at 50 LOC.
  11. Revision 1.11. The delegate to calculate the average was since the previous revision a short one-liner. No need anymore to spread that over 3 lines, including the curly braces. Inlining this delegate into the iterator call removed 3 lines. Code size at 47 LOC.
  12. Revision 1.12. Oh no! Code has grown to 48 LOC. Reason is that I tried anonymous function support in Mono, concluded that it didn’t work (yet) but left the updated line as a comment in the code.
  13. Revision 1.13.  Still 48 LOC. Only minor textual changes to code.
  14. Revision 1.14. Finally I realized that have commented out code is bad practice. Removed it, reducing the size to 47 LOC again.
  15. Revision 1.15. Mono 1.2.6 supported lambda functions. Did a bit of cheating and removed 1 empty line that divided 3 lines that logically belonged together. Size now at 46 LOC.
  16. Revision 1.16. A new C# 3.0 feature (object initializers) allowed me to remove another 2 lines. Code size at 44 LOC.
  17. Revision 1.17. Another 2 lines moved to the Plugin base class. 42 LOC left.
  18. Revision 1.18. Simplified GIMP# framework API a bit, allowing me to remove another line from almost all plug-ins. This is the most recent version which was checked in on June 10th, 2010. No changes since that time. Code size is 41 LOC.
As you can see I went from a maximum of  68 LOC to the current size of 41 LOC. I didn’t manage to remove half of the code, but 40 % still isn’t bad for such a small amount of code. At least I don’t have to maintain those 27 removed lines anymore. At the same time the readability has improved a lot. In a next blog I will categorize all the methods that can be used to reduce your code size, based on my personal experience.
For completeness the final code:
using System;
using System.Collections.Generic;

namespace Gimp.AverageBlur
{
  class AverageBlur : Plugin
  {
    static void Main(string[] args)
    {
      new AverageBlur(args);
    }

AverageBlur(string[] args) : base(args, "AverageBlur")
    {
    }

    override protected IEnumerable<Procedure> ListProcedures()
    {
      yield return new Procedure("plug_in_average_blur",
                                 _("Average blur"),
                                 _("Average blur"),
                                 "Maurits Rijk",
                                 "(C) Maurits Rijk",
                                 "2006-2009",
                                 _("Average"),
                                 "RGB*, GRAY*")
        {MenuPath = "<Image>/Filters/Blur"};
    }

    override protected void Render(Drawable drawable)
    {
      var iter = new RgnIterator(drawable, _("Average"));

      var average = drawable.CreatePixel();
      iter.IterateSrc(pixel => average.Add(pixel));
      average /= iter.Count;

      iter.IterateDest(() => average);
    }
  }
}

GIMP# 0.17 released

December 2, 2010 at 1:10 pm | Posted in C#, GIMP | 10 Comments

Yesterday evening I released GIMP# 0.17. Highlights for this release:

  • a new plug-in to generate QR-codes. See also my previous blog post about this.
  • a new Trim plug-in. Not really earth-shattering but it behaves in exactly the same way as the Photoshop version. I needed this to make more Photoshop action files runnable within GIMP.

  • There are now 400+ Unit tests guarding the quality of the code.
  • Major code clean-up, using C# 4.0 features. The caveat is that you now have to use Mono 2.8 or higher to build GIMP#

Enjoy!

QR-codes in Ministeck

November 28, 2010 at 6:09 pm | Posted in C#, GIMP, Programming | 1 Comment

My previous blog about fixed-price projects attracted a whopping 5000 visitors in one single day. This one is probably going to be a bit less spectacular. Lately I have been using Google Charts quite a lot. One of the charts that stands apart from the usual charts are the QR codes. Although it is easy to enter an URL to generate such a QR code I figured it might be fun to write a GIMP# plug-in to do this. The result after a couple of hours hacking can be seen in the next screenshot:

I didn’t implement the QR code functionality myself. All the plug-in does is collect the parameters, build an URL, fetch an image from Google Charts and finally render the result either in the preview of the plug-in or as an image in GIMP. To make it a bit more interesting I used the Ministeck plug-in that comes with GIMP# and borrowed some Ministeck from my kids. Next I implemented the following probably very first ever QR code using black Ministeck pieces:

Ministeck

Believe it or not, I was actually able to read it, using a barcode scanner on my Android phone. This plugin will be included in the next GIMP# release.

Making C# code a bit more DSL like

March 10, 2010 at 9:17 pm | Posted in C#, GIMP, Programming | 12 Comments

Recently I was cleaning up some of my GIMP# code. One of the constructions that is often used is something like this:

var image = new Image(width, height, ImageBaseType.Rgb);
image.AddLayer(new Layer(image, "layer", ImageType.Rgb), 0);

The code above creates a new RGB image with a certain width and height and adds a new layer to that image. As you can see to just add the layer I need a reference to image twice. The GIMP API dictates that you can only create a layer if you know the image ID. What I was looking for was something with a bit more DSL (Domain Specific Language) like syntax. Something like in the next code fragment:

var image = new Image(width, height, ImageBaseType.Rgb) {
   {new Layer("layer", ImageType.Rgb), 0}};

This code uses the C# collection initializer that was introduced in version 3.0. The first step to make this work is to make Image implement the IEnumerable interface. The slightly weird thing is that this interface doesn’t even have to be functional:

public IEnumerator GetEnumerator()
{
   throw new NotImplementedException();
}

The above code is already sufficient. Instead of the AddLayer we now have to supply an Add method with the following signature:

public void Add(Layer layer, int position)

Now a problem becomes visible: in the original code we first construct image and use this variable as the first paramter in the layer constructor. However, when we use a collection initializer, we don’t have this variable available. And constructing a layer without an image is not possible in the GIMP API. To solve this problem I introduced a delayed constructor and do the actual construction in the Image.Add method, where the image is available as the this parameter. The Layer class looks like this:

public class Layer
{
   readonly Func<Image, Layer> _delay;

   public Layer(string name, ImageType type)
   {
      _delay = (image) => {return new Layer(image, name, type);};
   }

   // internal since it is only used by the Image class
   internal Layer DelayedConstruct(Image image)
   {
      return _delay(image);
   }
}

The code for Image.Add now becomes straightforward:

public void Add(Layer layer, int position)
{
   AddLayer(layer.DelayedConstruct(this), position);
}

This delayed constructor trick works quite nice. In the same way I can add GIMP channels and vectors. It is even possible to add channels, layers and vectors in one collection initializer since the Add methods all have different signatures.

So, where is the catch? There is a (minor) one: since I now have added a layer constructor without the image parameter, it is possible to call the constructor outside the collection initializer context:

var layer = new Layer("layer", ImageType.Rgb);
// layer is unusable: all methods will fail!
image.Add(layer, 0);
layer = image.Layers["layer"];
// only now can you use layer
Console.WriteLine("Layer width: " + layer.Width);

Personally I think the benefits of this approach outweigh this small disadvantage. I’m interested to hear alternative implementations.

GIMP# 0.16 released

January 26, 2010 at 10:34 pm | Posted in C#, GIMP, Programming | 12 Comments

Before I summarize the changes in GIMP# 0.16 I need to apologize to Alexandre Prokoudine. He is a great guy that updates the SourceForge news for GIMP#, reminds me very friendly on a regular basis that I really should release a new version, handles all kinds of feedback from users that somehow end up in his e-mail instead of mine, provides the Russian translation, etc. And now I forgot to include his latest translation in 0.16 :(

The new stuff in this GIMP# release:

  • Finally support for GIMP 2.6
  • Added Oxygene sample
  • Export layers to JavaFX
  • Support for GIMP 2.6 API and Mono 2.4
  • Improved test coverage (300+ unit tests)
  • Major code clean-up

Enjoy. Oh, and if you want to follow the latest GIMP# developments, follow me on twitter: @mauritsrijk

Twitter

August 25, 2009 at 8:25 am | Posted in GIMP, Programming | Leave a comment

I started using Twitter last week. My interest was triggered by a very cool workshop on programming in Scala that was given at the company I work for. Twitter has a nice API which is very easy to use from Scala or any other programming language. I still try to figure out what the business case could be for using Twitter, but for the moment it’s quite fun to do a few daily updates on what keeps me busy and/or interested.

My Twitter ID is @mauritsrijk (direct link). I probably am going to use it to give more frequent updates on my GIMP# activities.

GIMP# with Mono 2.4 and GIMP 2.6

June 8, 2009 at 1:38 pm | Posted in C#, GIMP | 3 Comments

I finally took some time to get GIMP# up and running with the latest Mono and GIMP releases. Not sure how I’m going to continue from here, but I will probably first update the code with the latest C# language features. Also since GIMP 2.6 has been out now for more than half a year, I will only support this version. Stay tuned for a maintenance release soon!

Writing GIMP plug-ins in Object Pascal

October 23, 2008 at 2:46 pm | Posted in GIMP, Programming | 5 Comments

I slowly picked up GIMP# development again. To get my brain in the right mode I added a plug-in in yet another .NET language: Oxygene which is a kind of Object Pascal. From what I’ve seen it is a pretty decent language although I never understood why people would like to type 10 characters (“begin;” and “end;”) instead of 2 curly braces just to open and close a block ;)

For those interested: currently I run Mandriva 2009 with VirtualBox 2.0.2 on my loyal MacBook Pro for development. The fancy IDE I use is called Emacs.

IronRuby and the Fan Programming Language will probably be my next targets.

GIMP# 0.15 released

May 12, 2008 at 9:05 am | Posted in C#, GIMP | 36 Comments

Finally a new GIMP# release. Major highlights for this release:

  • Many improvements to get the Photoshop actions plug-in usable: 10 copyright-free actions are now verified and can be downloaded from SourceForge
  • An abandoned plug-in to load GEM image files was ported
  • The Russian translation was updated (thanks Alexandre!)

The next GIMP# version will be released as soon as I’ve got 20 correctly working Photoshop action files.

Next Page »

Blog at WordPress.com. | The Pool Theme.
Entries and comments feeds.

Follow

Get every new post delivered to your Inbox.