Pages

Friday, 14 January 2011

The Biggest Challenge Faced by Technical Founders

When someone technical decides to step off the cliff and become a founder of a startup there are always going to be challenges. Most programmers and developers believe that these will come from areas outside of their comfort zone - sales, marketing, taxes, fund-raising, design and even just networking! This is why the standard co-founders model partners someone technical with someone more 'businessy'. The reality, however, is very different.

For me the biggest challenge I face as a technical founder is programming. To be more specific: stopping programming. For years I have measured my progress by ticking off features delivered, bugs fixed or user stories completed. It's a well understood system and it's easy to track, but that's not what I should be doing. My job as a founder is to find a repeatable business model that will make money, and the only route to achieving this is via validated learning.

Here's an example:

Earlier this week I was building some new server functionality for @photoPivot. I found myself working through the options of how and where to host a service and what type of communications medium was going to be the absolute best for this. Eventually I realised "Who cares? It doesn't matter!". All I needed to do was test my idea in the quickest way possible. Just stick it in a console app and off we go (sneakernet style!).

Now, this doesn't mean that you should write bad, unmanageable code. You can still test your ideas in a way that isn't going to back you into a nasty corner in the future. Just be a little pragmatic. Do enough to get it working, then step away. I know how difficult it is to know that you could make something better - it's very hard to resist being the perfect craftsman. Once you've proven your idea then you can make it elegant; but why waste your time polishing something that you don't know people want?

For technical founders, programming is chicken soup. On difficult days we find comfort there and, by the evening, we've convinced ourselves that, yes, we made good progress today. Don't be fooled by these false metrics. Test your ideas quickly and build your company.

Monday, 20 December 2010

Time to Move On

For the last 9 months I have been a part-time entrepreneur. From 1st January it'll be full-time.

I have now worked at the same software company for 10 years. I started as a developer and worked my way up to become the Development Director. Over the past 2 years I have transformed the company's development department with changes that will continue to help it deliver working software long after my departure. I moved us from a classic waterfall model, with manual deployment, to an Agile process (Scrum) incorporating SOLID principles, unit tests, continuous integration & build servers and, nearly, fully automated deployment of a dozen commercial websites. I am very proud of the changes I have made and I leave a company which now scores 9/12 on the Joel Test.

I'm giving all that up.

My own, personal, transformation didn't stop there though. Over the last year I have become more and more excited by the business side of software development. I spent countless evenings and weekends consuming all I could find from such luminaries as Dharmesh Shah, Seth Godin, Geoffrey A. Moore, Eric Ries etc. The possibility that a 'simple developer' could expand his horizons and create something more than just an application was exhilarating. During 2010 I had, and still have, a hat-full of ideas; one of which bubbled to the top of the stack quite effortlessly. After the creation of an MVP, a few public demos & pitches and some incredible user feedback I'm now ready to go for it. I've learnt all I can without taking that final step off the cliff.

In 2011 I'll be looking for more people to come join me in helping change the way people interact with social media - starting with TweetPivot. If you want to know what that involves you'll have to follow me on twitter or even just come talk with me!

Finally, I'd like to thank some local groups (e.g. Pitch and Mix), some global groups (e.g. Microsoft's BizSpark program) and an innumerable number of individuals who have supported and encouraged me thus far. Almost any hour of the day can feel like a lonely 3am when you're an entrepreneur and having people that can help you refocus is priceless.

So, wish me luck. 2011 is going to be scary-as-hell but, wow, what a sweet looking ride!

Thanks,

Chris

Saturday, 16 October 2010

What are you scared of?

Finding yourself stood in front of Eric Ries can be somewhat daunting. You have the opportunity to ask a question to, arguably, the leading light in the field of Lean Startup. As soon as you start speaking, though, the guy stood behind you in the queue starts getting restless. So, you better make it a good one!

I was unable to attend the Business of Software in Boston last month so was excited to see that Eric was doing a whistle-stop talk last night at TechHub, London. After a, not too inconvenient, train and tube journey I found myself in a vibrant room packed with budding entrepreneurs. The 'formal' part of Eric's talk was mostly content that I'd already seen online, so no major surprises there. What always makes these events unique, though, is the interaction with the people that turn up. The Q and A hand-raising session was very busy but I did manage to talk with Eric afterwards. Here's what I asked him:

Imagine you're back at IMVU circa 2004, but this time you know what you know now. You've created a Minimum Viable Product for just one Instant Messaging network that's already getting good traction. Geoffrey Moore would have probably suggested that you capture your beachhead in that first IM. Would you agree with that or would your next move be to create an MVP for each IM?
As is often the case in this field there was no short, definitive answer! What follows is paraphrased.

Eric: "What are you scared of?"
Me: "Uh, nothing. I'm an entrepreneur creating a startup - by definition am I not fearless?"
Eric: "No. What's your biggest fear?"
Without any prepared answer for this one I said "Well, probably someone else copying us". Eric rocked back, head shaking "No." I got the impression that he hears this 'wrong answer' often.

The gist of Eric's response was that I needed to look at my assumptions. I'd assumed that because my product 'works' for one social network that it will automatically be greeted in the same manner on all the other networks. The way you reassess these assumptions is to do more measuring against hard targets e.g. I'm currently at 10, I think I can get to 20 by time t. If the increments are 10, 12, 14... you're probably gonna make it, but if they're 10, 11, 11.5... you might have a problem. Testing your worst fears early is key.

MBAs are seen as a hindrance in the startup world, but the remainder of Eric's lesson to me did seem to cross a chasm into this territory. The basics of the Lean Startup are pretty straight forward: iterate through 'the loop' as quickly as you can and learn what works. Simple. Once you get into the guts of it, by talking with Eric, it starts sounding a whole lot more complicated. If I wanted an MBA I would have studied for one. I like my vision of the startup as having less politics, less overheard and, by extension, less rigor; but, again, this is an assumption.

I am, however, extremely grateful for the way Eric makes you question all of your assumptions - sometimes to the point of your own existence!

So, what is my biggest fear? After some considerable thought I think it's that people won't like what I do. I fully agree with Eric's observation that the best way to utterly deject developers is to have them spend time and energy creating something only for it to never see the light of day. Lean helps us avoid wasting everyone's time and for that, alone, it is worth pursuing.

Tuesday, 12 October 2010

Standardising String Cryptography

I was writing the new Twitter Client for TweetPivot when I hit a problem. I needed to store a small amount of information on our users' machines; specifically in isolated storage. Most of this would be fine as plain text but one field needed to be encrypted. This meant I had to solve a problem I seem to come back to again and again - simple string cryptography.

Crypto Rule #1 seems to be "Don't roll your own.". OK fine, so give me something pre-rolled. C# / .Net doesn't contain the method I was looking for:

string Encrypt(string plainText, string password, string salt);

Luckily, @blowdart came to my rescue and posted this code. Now, there's a few things worth pointing out about this:
  1. Barry's book sales suggest he might actually know what he's doing, but who else amongst us has the confidence and knowledge to say that it's safe and reliable?
  2. Did anyone read the code and think "actually, TripleDES would suit my needs, not Rijndael"?
Answer: probably no.

So, given that a) it's hard to do correctly and b) this standard method would probably suit 99% of developers 99% of the time why, then, do we not find this in the BCL? If I want to open a file I can use System.IO.File.OpenRead(string path). If I need to take more control over the process I can use a StreamReader and dictate encodings etc.

I've included my final code below (you deserve something for reading this far!). Porting it into Silverlight simplifies matters - mainly because there's only one implementation of SymmetricAlgorithm. "But Barry defaulted to Rijndael. Does this mean that Silverlight is less secure than standard .Net applications?" Another crypto conundrum!

I do feel that this functionality needs abstracting behind a simplified facade. I genuinely don't care how long my initialisation vector is or whether I'm using DES, DoubleDES or even TripleDES. Cryptography is simply a tool for hiding stuff and it should be easier, safer and more confidence-imspiring than it currently is. @blowdart's subsequent tweet kinda sums up the complexity of the subject. Signatures, really? You might just as well have asked me if I wanted tweeters with it! #referenceToOldJoke
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public static class CryptographicExtensions
{
  public static string Encrypt(this string plainText, string password, string salt)
  {
    var algorithm = new AesManaged();

    algorithm.SetKeyAndIV(password, salt);

    return Encrypt(algorithm, plainText);
  }

  public static string Encrypt(this string plainText, ref byte[] key, ref byte[] iv)
  {
    if (string.IsNullOrEmpty(plainText))
      return plainText;

    var algorithm = new AesManaged();

    if (key != null)
      algorithm.Key = key;
    else
      key = algorithm.Key;

    if (iv != null)
      algorithm.IV = iv;
    else
      iv = algorithm.IV;

    return Encrypt(algorithm, plainText);
  }

  private static string Encrypt(SymmetricAlgorithm algorithm, string plainText)
  {
    var plainTextAsBytes = Encoding.UTF8.GetBytes(plainText);

    using (ICryptoTransform transform = algorithm.CreateEncryptor())
    {
      using (var outputStream = new MemoryStream())
      {
        using (var inputStream = new CryptoStream(outputStream, transform, CryptoStreamMode.Write))
        {
          inputStream.Write(plainTextAsBytes, 0, plainText.Length);
          inputStream.FlushFinalBlock();
          var cipherText = outputStream.ToArray();
          return Convert.ToBase64String(cipherText);
        }
      }
    }
  }

  public static string Decrypt(this string cypherText, string password, string salt)
  {
    var algorithm = new AesManaged();

    algorithm.SetKeyAndIV(password, salt);

    return Decrypt(algorithm, cypherText);
  }

  public static string Decrypt(this string cypherText, byte[] key, byte[] iv)
  {
    if (string.IsNullOrEmpty(cypherText))
      return cypherText;

    if (key == null)
      throw new ArgumentNullException("key");

    if (iv == null)
      throw new ArgumentNullException("iv");

    var algorithm = new AesManaged() { Key = key, IV = iv };

    return Decrypt(algorithm, cypherText);
  }

  private static string Decrypt(SymmetricAlgorithm algorithm, string cypherText)
  {
    var cipherTextAsBytes = Convert.FromBase64String(cypherText);

    using (ICryptoTransform transform = algorithm.CreateDecryptor())
    {
      using (var outputStream = new MemoryStream())
      {
        using (var inputStream = new CryptoStream(outputStream, transform, CryptoStreamMode.Write))
        {
          inputStream.Write(cipherTextAsBytes, 0, cipherTextAsBytes.Length);
          inputStream.FlushFinalBlock();
          var plainTextAsBytes = outputStream.ToArray();

          return Encoding.UTF8.GetString(plainTextAsBytes, 0, plainTextAsBytes.Length);
        }
      }
    }
  }

  public static void SetKeyAndIV(this SymmetricAlgorithm algorithm, string password, string salt)
  {
    string paddedSalt = salt;

    while (paddedSalt.Length < 8)
      paddedSalt += salt;

    var rfc2898 = new Rfc2898DeriveBytes(password, Encoding.UTF8.GetBytes(paddedSalt));

    algorithm.Key = rfc2898.GetBytes(algorithm.KeySize / 8);
    algorithm.IV = rfc2898.GetBytes(algorithm.BlockSize / 8);
  }
}

Tuesday, 21 September 2010

Great, another Pivot!

The word 'Pivot' seems to be somewhat of a favourite amongst the tech community these days. It all started with Pivot tables back in the late 80's. In the past few years we've added 3 new pivots to the list:


If that wasn't enough we now have a fifth! The final Windows Phone 7 SDK launched a couple of days ago and contains, wait for it, a Windows Phone 7 Pivot Application template.

I work with two of these (the Lean Startup and Live Labs) and it's already confusing trying to explain to potential customers which pivots our business uses.

Seriously, no more. Please?

Maybe this is a compelling reason for companies to trademark their products?

Wednesday, 18 August 2010

A Rebuke of Twifficiency

Unless you've been asleep under a stone for the past 48 hours you couldn't have failed to notice the Twitter phenomenon that is Twifficiency. Created by James Cunningham it generated an efficiency score based on your Twitter usage. In order to access the service, though, you had to grant the application access to your Twitter account.

Unwittingly, or not, James had violated one of Twitter's codes of practice re: abuse of privileged access to accounts. Specifically, the application automatically tweeted a message from the user's account in the format:

My Twifficiency score is x%. What's yours? http://twifficiency.com

Generally, this annoyed people but, because of its viral nature, the term "Twifficiency" started trending worldwide.

Now, can we please get some perspective on this?

Yes, it trended. Yes, it spread like wildfire. Yes, everyone's talking about it; but so what? This is the Twitter version of "Britain's Got Talented X-Factor for me Nan". It was hugely popular but, ultimately, worthless. Shouldn't we be discouraging this kind of sensationalism and, instead, be encouraging the trending of remarkable products (to quote Seth Godin). The mere fact that it trended says nothing about its worth - because it trended itself automatically, virally. This is the complete opposite of something that trends because users want to tell their friends about it. In fact self-promotion obfuscates this valuable measure.

James is, undoubtedly, a very nice chap who was just experimenting with an idea, but for some people to be considering offering him a job! Seriously, no. Stop.

Tech Crunch hits the nail on the head in their blog post and I would like to add to that by pointing out that Stephen Fry only scored 3%!!!

Now, if James had created the site with an opt-in option for re-tweeting (as opposed to its new opt-out option) and it had still trended; then, wow! That would have been a truly remarkable feat. The fact is, though, that you've removed any meaningful way of measuring your success.

I have no doubt that James will go on to great things but, I'm afraid, I think he should be infamous, not famous, for Twifficiency.

Monday, 16 August 2010

Immutable, Auto-Implemented Properties in C#

Over the past few months I've been getting a lot more into immutability. If you want to know why you should be using immutable types start with this blog post by Bertrand Le Roy.

Until recently I, like most other developers had been creating my properties like this...

public class Person
{
  public DateTime BirthDate { get; private set; }

  public string FavouriteSong { get; set;}

  public Person(DateTime birthDate)
  {
    BirthDate = birthDate;
  }
}

Pretty straight forward - the BirthDate is required and must be set during construction of the object whilst the FavouriteSong is optional. The other reason for writing properties this way is simplicity and code succinctness. It also allows more 'interesting' properties to be more easily identified. For instance, this new Age property stands out from the other two and 'asks' to be unit tested.

public class Person
{
  public DateTime BirthDate { get; private set; }

  public string FavouriteSong { get; set;}

  public int Age
  {
    get
    {
      var now = DateTime.Today;
      var age = now.Year - bday.Year;

      if (bday > now.AddYears(-age))
        age--;    

      return age;
    }
  }

  public Person(DateTime birthDate)
  {
    BirthDate = birthDate;
  }
}

I should, however, be making the BirthDate property immutable - it isn't gonna change! This does make the code less neat though...

public class Person
{
  private readonly DateTime _birthDate;
  public DateTime BirthDate { get { return _birthDate; } }

  public string FavouriteSong { get; set;}

  public int Age
  {
    get
    {
      var now = DateTime.Today;
      var age = now.Year - bday.Year;

      if (bday > now.AddYears(-age))
        age--;    

      return age;
    }
  }

  public Person(DateTime birthDate)
  {
    _birthDate = birthDate;
  }
}

Auto-implemented properties are a .Net construct and are used as a template, at design-time, to create a 'real' pair of _get _set methods. So, what I'd like to be able to do is this ...

public class Person
{
  public DateTime BirthDate { get; private readonly set; }

  public Person(DateTime birthDate)
  {
    _birthDate = birthDate;
  }
}

Anyone from Microsoft like to chime in?