Wednesday, August 26, 2009

Love your programming environment

Do you love the tools and environment you use as a programmer?

Dijkstra says you should E.W.Dijkstra Archive: Some meditations on Advanced Programming (EWD 32) :
"The tool should be charming, it should be elegant, it should be worthy of our love. This is no joke, I am terribly serious about this. In this respect the programmer does not differ from any other craftsman: unless he loves his tools it is highly improbable that he will ever create something of superior quality.


At the same time these considerations tell us the greatest virtues a program can show: Elegance and Beauty"
[my bolding]

Monday, August 24, 2009

Image scaling and GCD (greatest common divisor)

Whilst embedding an image in a wiki page I found it was too big (wide) and therefore caused lots of layout issues. The obvious solution to this was to scale the image (by editing the HTML and adding a style attribute style="width:80%;") unfortunately this caused the image (a diagram) to be unreadable - due to image artefacts.

After looking at the image properties, I saw the cause of problem - its dimensions (865 x 596). As there is no common divisor of these two numbers there is now way to scale it down without one of the dimensions being rounded - for example at a scale of ½ the dimensions become (432.5 x 298). And you can't have half a pixel...

So I suspect (intuitively rather than by proof) that images scale best if they have a GCD (greatest common divisor), a quick port of the binary GCD from wikipedia in C#:

        static uint gcd(uint u, uint v)
        {
            int shift;

            /* GCD(0,x) := x */
            if (u == 0 || v == 0)
                return u | v;

            /* Let shift := lg K, where K is the greatest power of 2
               dividing both u and v. */
            for (shift = 0; ((u | v) & 1) == 0; ++shift)
            {
                u >>= 1;
                v >>= 1;
            }

            while ((u & 1) == 0)
                u >>= 1;

            /* From here on, u is always odd. */
            do
            {
                while ((v & 1) == 0)  /* Loop X */
                    v >>= 1;

                /* Now u and v are both odd, so diff(u, v) is even.
                   Let u = min(u, v), v = diff(u, v)/2. */
                if (u < v)
                {
                    v -= u;
                }
                else
                {
                    uint diff = u - v;
                    u = v;
                    v = diff;
                }
                v >>= 1;
            } while (v != 0);

            return u << shift;
        }
Port of code from wikipedia

Development's Naive Cynicism

Development is the process of creating a new product or release. In any development team or group there is a generally an accepted "right way" to develop a product (especially in the pathological team of one). However what I've observed in practice is that individuals in the team rarely follow the "right way” and bizarrely act (or report) as if the team is – I’m naming this behaviour as “Development's Naive Cynicism” (DNC)

Being cynical about the "right way"
We are cynical as we know what the "right way" is, but chose not to follow it. "Our process says do X and Y, but no-one does that!" is a common line. I'm not suggesting what the right way is or that there is only one "right way". The definition of "right way" changes dependent on approach (agile, lean and waterfall etc), constraints (time, money and skills etc) and suitability (complexity, duration and urgency etc) etc. Also two teams can have very different views of what the "right way" is, however within a team an agreement of "right way" is possible and desirable.

Being naive
We are naive as know that everyone is cynically not following the "right way", but chose to behave as though we do not know this. This becomes extreme in the case of a team of one, where we default to a sub-optimal approach as the "right way" is too much effort. Given that the definition of "right way" is under our own control (as we define it) this behaviour is bizarre - we chose not to redefine the "right way" (as we secretly know it IS the right way), but instead betray ourselves.

Why does Development's Naive Cynicism exist?
Let us recap: Development's Naive Cynicism = we know the right way, we don’t follow it, but pretend we are following it. What would cause us to exhibit this behaviour?
  • Incorrect definition: the "right way" is not the right way, at some level we don't really believe in our definition of "right way". But do we ever make the effort to fix/redefine it?
  • Self analysis: introspection is hard, and generalising our behaviour difficult. But why spend so much time learning if we don't seek to improve our core (kernel process) competence.
  • Time: I've got a product/release to ship, get out of the way! But surely (and don't call me Shirley) we know that we would be faster, quicker and lighter etc if we did it the “right way”.
  • Laziness: it's too much effort, no one else is doing either! Not really going to be a professional with this line of thinking

I think one of the main reason that DNC continues is the effort/reward perception, and durability of desire - only a slow steady improvement in process seems to work (big bang changes fail), which yields slow rewards, factored in the difficulty in persisting with continuous improvement makes it a difficult for an individual let alone a collective to eradicate it. A secondary issue is complexity, as technology progresses it tends to create complexity, however there is not a matching effort put in to change processes to cope with this - so overtime all processes become unfit for purpose.

That leaves us with two choices:

  • Stop DNC: either by living up to the promises made by our "right way", or redefine our "right way" to reflect what we actually do
  • Continue with DNC: maybe it does not exists, maybe it’s not that important or maybe it’s too painful to face into?