Decisions in an information vacuum


The Buy vs. Build decision process is very interesting to me as it is a small, common process that often leads to the undesired outcome.

I covered before the secondary costs that often block this process in this post: https://bashamer.wordpress.com/2011/04/14/institutionalizing-%e2%80%9cwinging-it%e2%80%9d/

In this new post I’m trying to see if there is a smaller solution that could have the desired outcome.

The decision process at some point has to come down to “if(Cost < Benefit) Buy();” Before I focused on the secondary costs that are added into the process by policies and procedures that exist in organizations. Chancing these procedures in its self would require a high cost and there is no clear and visible benefit to doing so. So the procedures won’t change.

So let’s look if we can make this evaluation easier by attacking the Benefit part of the equation.

The benefit to buying is that you don’t have to build it. Or in other words it is hours saved on initial development plus hours saved on maintenance. For hours saved on maintenance you can probably take 10% of the initial estimate for server components, 20% for components that interact with consumer software (Office for example) and 30% for web components due to the speed of evolution. I imagine mobile will be in the 20-30% range as well. All of these numbers a bit fudgy so apply your own experience.

So our function for benefit now looks like “HoursSaved*(1+(YearlyMaintanceEstimate*ProductLifeExpectency)/100)“. This is neat, but the units don’t work out. We are comparing developer hours to dollars, so we have to add a conversion factor.

Do you know your conversion factor?

Do you know what the company considers the cost of an hour of your time? I’ve only known it in one company and it surprised me. It was about 3x what I thought it was; it was 6x what I was being paid.

Let’s say the companies made this information public; you get your magic factor and learn that an hour of development cost the company $175 (probably in the ballpark w/ QA, defect incidence rate, management, utilities etc.)

When you can all agree that cutting a task in half saves $10,000. How easy would it be to then build up the momentum to put in a request to buy a tool to accomplish that reduction.

By making the benefit side of the equation easy to compute you can determine the opportunity. Knowing the opportunity is there will lead people to explore alternate solutions.

 

Posted in Uncategorized | Leave a comment

Institutionalizing “winging it”


The following is an attempt in improving third party product adoption in software. Third party software often can lead to great savings, but it is often hard to get an actual piece of software on a project in a reasonable amount of time. Part of this may have to do with the process rather than developers who are to use it.

In many companies there are policies and practices that you are to abide by. One of the areas where these policies are strong is when it comes to spending money. In one company I worked for there had to be contracts in place, there had to be master service contracts negotiated and I recall spending an hour on a conference call to create a clause related to the mini-bar for any possible future consultancy services. These were both billion dollar companies, and the meeting had 2 technical resources, ~4 lawyers, and some management & sales. The topic ate about an hour of call time as well as hours of prep time. Assuming a low (but round number) of 100 / hr per person and this clause cost the two companies 1000 USD. I’m not sure what a full mini-bar runs, but I’d be willing to take the chance that we would have never made our money back on that clause. The total cost ofver the first 2 years of the product we were interested in was less than 5,000 USD

This seems like an extreme concept but it happens often in smaller instances. Smaller examples might be long meetings about cheap products; recreating a cheap product rather than going through the hassle of trying to buy one. The reason that these items happen is due to a lack of measuring non- monetary resources, and when things are not measured they have no value. So people take the rational approach of not buying off the shelf products and rather recreate the wheel.

Trying to add measurements to this process so that the costs are tied to time will be extremely laborious and requires relatively large changes in the business. Going this approach does not really resolve anything.

So ideally we want to minimize the costs of the decisions. Although there are many there are many processes to speed up decisions, there is one that is not often mentioned; making decisions in hind sight is very fast and accurate. This seems impossible.

What most purchasing decisions are is a predictive process. Predictions are often inaccurate, and to be more accurate it requires a lot of analysis. The hindsight scenario is a reactive process, where information is cheaper to acquire but it is unable to prevent anything.

For some decisions you want to have a predictive process, for big capital expenses (datacenters), or high risk expenses (people). But for many they are not (3 licenses of a 100 dollar piece of software). So a reactive approach is not always a good path to go. So if you want to institutionalize a reactive approach you do need some limits.

A simplistic model of a reactive approach is to offer people a budget per year of X (let’s say 1000 per developer). And allow people to re-claim this money by getting forgiveness. In effect a developer or group of developers can decide to buy a license on an afternoon, and if it works, and they can show the results they can go to the budget process and say “we want to have reimbursed 580 to buy a product that has shown these benefits (and savings)”. There is no risk and getting an accurate decision is cheap. People that make good decisions get to make more decisions, people who make bad decisions run out of money.

If the decisions process gets streamlined then hopefully third party tools become more attractive and people will spend less time re-inventing the wheel.

Posted in Uncategorized | 1 Comment

Making it tangible


Tangible things are easy to care about; this is because we are humans. We like things that we can hear see & feel. Even in religion you will see all of these sense engaged; idols, symbols, incense & liturgy are common across religions and provide an anchor for people to focus their energy into.

In software we have not really learned this lesson. For instance defect prevention is trying to prevent something from existing in something that doesn’t exist yet. Trying to rally people around defect prevention is doomed to fail because people can’t anchor their energy on anything. Some people will be able to force themselves and implement practices on sheer force of will, but even those people are spending enough effort on willing themselves into new habits that the opportunity cost should not be ignored.

For me this has been very hard to come to terms with; I like the abstract, can enjoy it and care about it deeply. But I also realize that it can become incredibly hard to force yourself to stay motivated on a bad project. Part of this is because there is nothing to focus your energy on; these projects often have no physical aspects. One thing I find myself do is create to-do lists so that I can create small things that I can focus on so I can check them off. In effect I made it tangible because that made it easier for me. I now realize this, but this is a recent thing.

Some of the development practices that actually are getting traction also have these physical aspects. For Agile for instance you have the board that holds the tasks, and the physical act of moving a task is quite gratifying. Kanban has the cards that are being walked through the company and the act of handing it to someone else really brings home that something was completed so something else could start. Even in the least agile implementation of agile you will most often see the physical artifacts survive where as the more abstract elements get warped or forgotten.

The physical is very powerful, and it is worth using that power to drive your project. Try and focus on giving a project a physical identity and meaning; something as seemingly silly as creating a project logo or mascot can actually help people focus on the project easier. They can keep it on their desk as a physical reminder as to why they are doing this and who they are doing it for. Rewarding people with small tokens that can be displayed also makes things more real. Especially in an age where money has become abstract; and along with that has lost some it’s power as a reward.

You could for instance reward people with Lego™ bricks. Again this sounds silly; but it is something that people can use, they can display them on their desk, they can touch, feel and change them when the motivation is lacking and they can realize that they can build something new if they only had a few more bricks.

It is hard to measure these effects, but if you go looking around you will see that a lot of people have symbols at their desk. A picture from their kid, a gift from a client, a token from their school, hobby or favorite team. All of these symbols and idols allow people to channel energy easier and are valuable for that.

Try and get your project on peoples mind, and start by getting on to their desk.

Posted in Software Engineering | Tagged , , , , | Leave a comment

Requirements: Accuracy and Precision.


For reference:

http://en.wikipedia.org/wiki/Accuracy_and_precision

Requirements are interesting in software development. It is used as the contract that the developer has to fulfill to succeed, if there is something missing then the requirements are incomplete, missing, wrong. This is surprising, because we expect the Business analysts or whichever groups writes the requirements, to envision how something that doesn’t exist would work and interact in great detail. In effect developers are asking for precision, we want to know how things work exactly so that we can fulfill the contract. Accuracy really does not have much value to developers until they find out that what they build was not what was needed and they have to re-work it. On the other hand the Business want accuracy.

Precision has an interesting effect on the development life cycle. First of the developer will have fewer questions as they have the details they need. This will reduce the communication between the developer and the business since there is no reason to initiate by the developer. In the ideal scenario the developer would implement the entire feature without asking a question. Deliver the feature and succeed, hand it over and …. Get bugs.

These “bugs” are then often referred to as bad requirements, missing requirements etc. The developers are annoyed because they succeeded at fulfilling the contract and then a fast one was pulled on them. The contract changed and they are held accountable to the new terms after meeting the original ones.

Good times.

If there is no accuracy then the developer will be handed some piece of paper that will function as little more than a conversation topic to have with the business. A requirement that states that the application needs to “add X’s to customers” is useless for building the feature because there is no information about where this feature should be, any of the details of the relationship like one to many, many to many, etc. The only thing this will do is create a bunch of questions that the developer needs to ask before wring a line of code.

This is because software can’t be un-precise. Software is the act of locking actions down into a concrete system that will be absolutely precise. To be un-precise is to have randomness, and that is one of the hardest software problems to solve.

For a successful project it is therefore important that the direction is accurate because the precision will be forced by the translation to software.

This direction comes from the requirements. Requirements should be accurate, if you don’t know exactly how something should work, don’t write it down. Let the process find the accuracy during implementation.

Accuracy is more valuable than precision; not only that, precision becomes a cost when accuracy is not there. The later in the process a change is found the higher the cost. And the more precise the requirements the later in the project the communication will be started.

Posted in Architecture, Software Engineering | Tagged , , | Leave a comment

Reframing the bug backlog


A lot of places where I end up have a bug backlog; usually around 200-800 defects features and other assorted stuff in there. But mostly bugs.

This creates an interesting dynamic, first of all trying to attack the backlog leads to analysis paralysis. Trying to go through 200+ items to find the most important one is not that feasible and without some order the developers will spend more time browsing for their next bug than fixing it. Setting a goal of resolving the backlog is usually meaningless because it can’t be translated into concrete useful steps. Developers ask for a code freeze for a month to just fix bugs, and business is usually not very interested in that. In the end it steadily grows and few and people come to accept it.

I think that a lot of this has to do with how the backlog is framed. First of it is accepted that you have one, it is even expected that you have software that helps you track them, and that there are reports, meetings and even departments dedicated to managing this backlog. It is also framed as a point in the now, it is a point measurement that often has no future or past reported with it.

A bug backlog to me is like carrying a balance on your credit card. It is the result of actions and gives you a point in time measurement of where you are at financially or in developer terms Stability. So the steps for getting out of bugs are similar to getting out of debt.

The most important thing is change.

How did the total chance over time, put it into excel and put some regressions on it to predict the future. How long until you would double your current troubles, how long until you hit the next nice & big round number. Try and create a prediction of the future and use that prediction as your baseline to improve against.

This means that if your group generates 20 bugs a weeks and you go to 15 bugs a week there is an accomplishment that can be celebrated. It isn’t good, but it’s better.

There is an important reason to attack the rate rather than the total. It is like a car traveling in the wrong direction at 65 mph (km/h) and you set a goal of going backwards 100 ft. putting the car in reverse isn’t really an option, you first need to break, change gears to reverse and then speed up again. The same needs to happen to the bug backlog. You first need to generate fewer bugs, then you need to make sure that bugs that are fixed stay fixed, and then you can comb through the back log to get them resolved.

Focusing on the rate focuses on behaviors. It focuses on evolution, sustained change rather than revolution.

Revolution takes a lot of energy, and quite often you need that energy to keep getting the new requests done.

Celebrate that a team prevented 500 bugs in the last 6 months as compared to their previous track record.

As to how to change the behaviors, chances are that the team already knows. Find the members that have good output and low bug rates and find how they do it. Every team is different, every company is different. There is no new technology that will fix this, there is no magic pill that someone can sell you. Mind you that this won’t stop people from selling them to you, an on occasion they might even work. But in general it faces “adoption” problems and falls short of expectations.

Find what already works and embrace it.

Posted in Software Engineering | Tagged , , | Leave a comment

Adam Smith on software


Adam Smith famously wrote of ‘a man of humanity in Europe’ who would not ‘sleep tonight’ if ‘he was to lose his little finger tomorrow’ but would ‘snore with the most profound security’ if a hundred million of his Chinese brethren were ‘suddenly swallowed up by an earthquake, “because” he had never seen them.

We might argue this statement these days, and the earth quake in Japan in 2011 provides compelling evidence. And that was something that took 20,000 lives as of the latest estimates. But back when the statement was originally written this would likely be very true. If an earthquake did hit China or any other far away land the information would arrive in Europe about a month later, and it would be closer to a myth like Atlantis sinking into the sea than what we have these days of video footage of a wall of water swallowing a town and the images of what it looked like after the water retreated.

That is because things that can’t be seen, heard or felt are not real to the emotional self.

To the emotional self the closer it is to the self the more real it is. There is the self, the things that the self sees and experiences directly, and the further it is removed, and the fewer senses are engaged the less real it becomes. This about watching a sad movie, and compare it to hearing a sad account of a friend of a friend. Chances are that you may have cried during the movie, but when you are just hearing an account that is much harder. That is because it is less real, and harder to emotionally bond with.

Enter software in the organization.

How far is software from the emotional self; for a developer you might argue that it is extremely close. A developer pours a little of themselves into every line they write. It is something they create, their baby if you will. They care a lot.

But if you look over the whole company people likely don’t care. Even of the people that know of the project, or the people that are going to be end users of the product, the level of caring will not be substantial. They will care about the problem it is trying to solve, but as for caring about the actual thing that has to do the work, likely not so much. And this makes sense. A side effect of this is that people that think the software is real will communicate at a very different level than the people who have not had that experience yet. Think of it as a teacher handing you the class statistics on a sheet vs. the statistics on your child. They will put much more effort into the delivery of the second set of statistics because they know you care a lot about your child. This can lead to unfortunate side effects where you get adversarial behavior between departments because of the large discrepancy between caring in the people involved.

Software is not real until people get an experience with it. And this could mean a demo, a video a screenshot, provide a forum to have it feed on itself; all of these things will make it more real, and make people care more. In effect a software project should make a dedicated effort to do public relations work in the company on behalf of the project. Make it real, make people care, and bridge the gap between the developers and the rest of the company. This will help a lot in communications, and this caring can be used to motivate people across the organization.

There is one sub industry of software that does do this. The video game industry, most video games that are in support or under development will have tidbits of information coming out just about every day of the week; taking a look at Star Wars : The Old Republic, Rift, Guild Wars 2, Mass Effect 3, Diablo 3, etc. All of these games have not been released (as of writing this) but you will find rabid fans (granted the IP helps a lot). But these games are real to a lot of people who have never played them.

There is a risk in taking this approach, you do raise the stakes. If you make people care, make it real; they will also care if things go wrong. And in software that is more the norm than the exception. But I think part of the reason why things go badly so often is because it is expected. The bar is set low, and to change this you often run into motivational issues; which happen because people have a hard time caring about the software that they can’t experience as real.

If software wants to change we have to change our consumers who will then give us the drive to change. Because once we make it real to our consumers; failure is a far less attractive option and success will have to become the norm.

Posted in Software Engineering | Tagged | Leave a comment

Some syntactic sugar around locking & threading


One of the things that make debugging threading easier is to reduce the amount of code that you are debugging. This makes syntactic sugar actually quite important when it comes to this problem space.

The lock keyword and sections are very valuable when it comes to this, but it falls short when it comes to more complex threading problems. The drawback is that the lock is always exclusive, there is no option for read & write locks. This in turn makes the read lock a bottleneck; but often worth it due to the simplicity.

The area where they start to fall short is in scenarios where there are many readers and only a few writers. In this scenario we would want to allow concurrent reads while locking writes are exclusive. This becomes even more important as people enjoy Linq and the foreach statements. Both of these would crash if the collection would change during the iteration of the collection.

The following code tries to get the best of both worlds, having the syntax of a lock and power of a more complex construct.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ReaderWriterLock
{
    /// <summary>
    /// Wrapper for the ReaderWriterLockSlim
    /// </summary>
    public class ReaderWriterLockManager
    {
        private ReaderWriterLockSlim lockHost = new ReaderWriterLockSlim();

        /// <summary>
        /// Use with a Using statement, While in the using you have a read lock
        /// </summary>
        /// 
        public ReaderLock ReadLock() { return new ReaderLock(lockHost); }

        /// <summary>
        /// Use with a Using statement, while in the using you have a write lock
        /// </summary>
        /// 
        public WriterLock WriteLock() { return new WriterLock(lockHost); }

        /// <summary>
        /// Use with a Using statement, while in the using you have a upgradable lock
        /// </summary>
        /// 
        public UpgradableLock UpgradeLock() { return new UpgradableLock(lockHost); }

        /// <summary>
        /// Syntax helper for the ReaderWriterLockSlim
        /// </summary>
        public class ReaderLock : IDisposable
        {
            /// <summary>
            /// Reader Lock
            /// </summary>
            /// The ReaderWriterLockSlim
            public ReaderLock(ReaderWriterLockSlim host)
            {
                lockHost = host;
                lockHost.EnterReadLock();
            }

            private ReaderWriterLockSlim lockHost = new ReaderWriterLockSlim();

            /// <summary>
            /// IDisposable implementation
            /// </summary>
            public void Dispose() { lockHost.ExitReadLock(); }
        }

        /// <summary>
        /// Syntax helper for the ReaderWriterLockSlim
        /// </summary>
        public class WriterLock : IDisposable
        {
            /// <summary>
            /// Writer lock
            /// </summary>
            /// The ReaderWriterLockSlim
            public WriterLock(ReaderWriterLockSlim host)
            {
                lockHost = host;
                lockHost.EnterWriteLock();
            }

            private ReaderWriterLockSlim lockHost = new ReaderWriterLockSlim();

            /// <summary>
            /// IDisposable implementation
            /// </summary>
            public void Dispose() { lockHost.ExitWriteLock(); }
        }

        /// <summary>
        /// Syntax helper for the ReaderWriterLockSlim
        /// </summary>
        public class UpgradableLock : IDisposable
        {
            /// <summary>
            /// Creates an upgradable list
            /// </summary>
            /// The ReaderWriterLockSlim
            public UpgradableLock(ReaderWriterLockSlim host)
            {
                lockHost = host;
                lockHost.EnterUpgradeableReadLock();
            }

            private ReaderWriterLockSlim lockHost = new ReaderWriterLockSlim();
            private bool isUpgraded = false;

            /// <summary>
            /// Upgrade the lock
            /// </summary>
            public void Upgrade()
            {
                if (isUpgraded) return;

                lockHost.EnterWriteLock();
                isUpgraded = true;
            }

            /// <summary>
            /// IDisposable implementation
            /// </summary>
            public void Dispose()
            {
                if (isUpgraded) lockHost.ExitWriteLock();

                lockHost.ExitUpgradeableReadLock();
            }
        }
    }
}

A sample for a read / write scenario

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ReaderWriterLock
{
    class SafeReporting
    {
        ReaderWriterLockManager dataLock = new ReaderWriterLockManager();
        private Queue _data;

        void AddRecord(object record)
        {
            using (dataLock.WriteLock())
            {
                _data.Enqueue(record);
            }
        }

        object GetRecord()
        {
            using (dataLock.WriteLock())
            {
                return _data.Dequeue();
            }
        }

        string RunQueueReport()
        {
            using (dataLock.ReadLock())
            {
                return _data.Select(x=>x.ToString()).Aggregate((a, x) => a + ", " + x);
            }
        }
    }
}

A sample for an upgrade scenario

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ReaderWriterLock
{
    public class SimpleCache
    {
        ReaderWriterLockManager dataLock = new ReaderWriterLockManager();
        private object _data;

        public object Data
        {
            get
            {
                using (var l = dataLock.UpgradeLock())
                {
                    if (_data == null)
                    {
                        l.Upgrade();
                        if (_data == null)
                        {
                            _data = new object();
                        }
                    }
                    return _data;
                }
            }
        }
    }
}

There were a few design decisions that were made in here. First of the calls to enter the locks are methods. My original idea was to do it with properties to make it even cleaner; but this created an interesting bug. The bug will not actually manifest when you have the application run normally, but it does show up when you run it in debug mode. This happens when the IDE evaluates the property when you hover over it. The property creates a new lock, and the lock does not get disposed. The end result can cause some impressive head scratching.

The end result work well, and creates some nice clean code.

Posted in C#, Syntax | Tagged , , | Leave a comment