Sunday, February 26, 2012

What are we doing next month?

I'm happy to announce the latest version of Gigantt. The long anticipated and much requested "Team View" is now live. Finally you can see what every team member is doing at any given time.

You can see Team View in action in the following two-minute video: 

Learn more on our help wiki.

If you think Team View looks awesome you can sign-up for the private beta program. More invites will be going out in about two weeks.

Tuesday, February 14, 2012

Screenshots Straight into

If you tend to use lots of screen-shots (like me) you should probably know SnagIt. It's the number-one screen-shot application for Windows. It takes over of your PrintScreen keyboard button and when you click it you can then choose the screen area to capture.

If you create lots and lots of screen-shots you can configure SnagIt to automatically write the files to some directory. But what if you always need to upload these image files to some public location?

That's where imgur comes into play. They'll gladly host your image files and give you permanent links to them. The cool thing about this is that they have an API. So, yes, you've guessed it, you can connect SnagIt to imgur!

Here's how:

  1. You need Python (if you're not a programmer, this isn't for you, sorry...)
  2. Save this script somewhere in your machine:
  3. Then configure SnagIt to output into this script as a program. You might need to wrap it with a CMD file, depending on your local python setup.
That's it. Now when you snag a new screen-shot it will automatically be uploaded to imgur and the URL will be copied into your clipboard. PrintScreen -> Paste URL into your blog or Facebook status -> Bang, you're done.

Tuesday, February 7, 2012

A Programmer's Guide to Successful Outsourcing Online

Gigantt outsources much of its work online through sub-contractors. If it's not part of our core intellectual property then we get someone else to do it. It's much more cost-effective. Every full-time employee gets a discretionary outsourcing budget used to get work done, no questions asked as long as it's within the following guidelines.

1. It's amazing how much you can actually outsource effectively once you do the mental switch. It ain't about the jobs you can't or don't want to be doing, it's about the jobs you shouldn't be doing.
Let's say you need to learn about a new technology and whether or not integrating it into the product is a smart move. The auto-didactic hacker approach would automatically lead you through the path of reading manuals, searching forums, asking questions online and generally satisfying your intellectual curiosity through hours of reading and playing around with new toys. Now let's say you value your time as a developer at $100/hour (it can actually be much more). If you spend only three hours figuring out a new technology - that's $300. But why not pay someone who's already an expert at this technology to tutor you on Skype for one hour? That person probably values their time roughly the same as you do. You just got the best tutorial you could get and saved $100 in the process. 
Notice this particular example only really works if people don't need to get their boss's approval for every job they wish to outsource. Not many people would be comfortable approaching their boss and asking him to pay for an hour's worth of tutoring, but often that's the most cost-effective thing to do.
The point is to be mindful of the possibility of outsourcing and really think twice before deciding to do something on your own. 

2. Get to know oDesk. It's probably the smoothest running outsourcing engine out there, with more than a million sub-contractors. Posting a new contract takes us no more than 5 minutes now. And, if you know what you're doing, deciding on a candidate and hiring can take about 10 additional minutes. That's about 15 minutes we can put down as cost-of-transaction. At the above rate that's $25 overhead. Naturally this means if you can do the job yourself faster than that then you should. But most jobs take more than 15 minutes.

3. Insist on superb English communications skills. That is, of course, assuming English is your work language. This cannot be stressed enough. 90% of outsourcing success and failure is attributable to communication quality. If you aren't speaking exactly the same language, literally, it's not going to work. Be very selective when evaluating candidate's CVs and cover letters. We automatically disqualify based on the tiniest spelling, punctuation, grammatical and style errors. If a candidates can't be bothered to proofread his own profile then you're probably not going to get a 100% perfectionist performance our of them.

4. Plant some non-obvious requirement into your job post. You need to be able to identify (and disqualify) those that send out applications en-masse without really investing time into their cover letter. We sometimes ask for a sample of their English writing work in the job description, even if the job itself is completely unrelated to writing. If candidates don't attach such a link they obviously either didn't read the job description (don't care enough) or can't follow simple instructions.

5. If it's a long-term job or requires any amount of talking over phone or Skype then be sure you can understand the person's accent. Many sub-contractors, especially in Asia, are just not that easy for westerners to understand. It's a matter of accent and also a matter of connection quality - Skype can really a problem in this respect. So do a Skype interview. It can be as short as five minutes. Again, this often does not apply because some jobs require no Skyping to get done at all.

6. Use an hourly rate instead of a fixed-price for the job. Don't worry so much about people billing too many hours. That never happened to us and we've employed dozens of people. Using an hourly rate even for stuff that initially seems like a very clear cut and properly estimated job has a few advantages. Unless your job description is superbly clear and comprehensive, realize that you might not get exactly what you asked for. People will misunderstand and then have to repeat work for you, and if they start losing money while doing so you'll get hurried, resentful work. Unless you've worked with the particular sub-contractor before and he's doing the same exact job again you can't really trust their fixed-price bid to be spot on. The point of outsourcing is to not worry about the job, and this means you have to employ people who are willing to redo and improve their work up to your standards, which may be higher than theirs.

7. Be very clear about I/O. It's just like design by contract. Specify exactly what your input is going to be and how you expect to get their output. It can be trivial stuff like which file formats or applications to use. But it can also be about progress updates - how often do you expect them to occur, etc. Our job descriptions often ask sub-contractors to spend not more than X hours initially on the job, then stop working and report to us with their progress so we can evaluate it and adjust expectations.* The clearer you are about breaking down the work into milestones and receivables the less you'll be disappointed.

8. Coordinate expectations about the amount of work that needs to be done and realize that sub-contractors usually work on more than one job at a time. Specify exactly how many hours per day or week you expect them to work. If the work is occasional in nature then coordinate expectations and realize they might not always be available on a day's notice.

9. Consider over-hiring. Need some data-entry work to be done? Hire two or three people for the same job (usually $2-$3 an hour - very cheap in western standards) and see which one performs best on a smaller initial milestone - that's the one you keep for the long term. Be honest and upfront about the fact that work will start on a smaller evaluation basis. Let people prove themselves to you by working (and getting paid). The cost of hiring and firing is very, very low and we developers are accustomed to the very opposite (recruiting takes forever and mistakes are very costly).
If the work is repetitive and error prone, people will become fatigued and make mistakes, especially the 17th time they basically do the same thing. In such cases it's perfectly reasonable to hire more people for the job than strictly necessary. Redundancy is your friend because it's unlikely two people will do make the exact same mistake. It also helps with the issue of availability mentioned earlier.

10. Finally, be respectful and courteous. Yes, hiring and firing on oDesk can take five minutes and have little implications for you, but the people working for you deserve your respect, even when they occasionally don't live up to your high expectations. It sounds silly to have to even mention this as a tip... Outsourcing online usually happens across cultural boundaries and not everyone has the same work attitude, conversational style and politeness (Israelis, I'm looking at you!). So be extra nice.

This is actually a tip by Tim Ferris. Read his book, or at least the chapter on outsourcing. Another great chapter on outsourcing can be found on

Saturday, February 4, 2012

Clear Browser Cache - a Saturday Project

UPDATE: Because of embedded iframes in this post I highly recommend you read it out of your RSS reader.

Woke up today with an idea that must have its day. So, you know how web applications sometimes ask you to clear your browser's cache. It's the equivalent of "turning it off an on again". A general cure for everything.
But how do you explain to very simple users the steps to clearing their browser cache? Most users probably don't even know what sort of browser they're using. You need to detect it for them and present them with step-by-step instructions (with screen-shots), and practically nobody does this. It's just too much work.

We need a website that does just this - it detects your browser and shows nothing but the steps to clear your cache. Web developers could then just refer to it instead of recreating it on their own over and over again. They could even embed it as an iframe...

So this is my Saturday project. Let's see how far I can get today.

09:30 - Wrote the into above and checking online that nobody has already done this.

09:31 - This can be a totally static website with just Javascript to detect the browser. So it can be hosted in its entirety from S3. I always wanted to do that. Let's read up on how.

09:38 - Seems simple enough. Just create a HTML page and upload it to a new bucket on S3. Then turn the "website" switch in the bucket properties. 
Created a bucket called "clearcache" (I already have a Amazon account).
Created a new local directory for this project on the best source control system - DropBox :)
Created a hello world html file called index.html
Now just s3cmd sync . s3://clearcache

Oops! Amazon says access denied when I tried to view the website at

Giving "View Permissions" to the bucket doesn't seem to solve the problem.. but making the index.html file public does. But that's no good - would I need to do this for every file I upload?

09:56 - Time to RTFM...
09:57 - Argh.. they ask you to create a "bucket policy" and upload it. Common, Amazon, couldn't this have been a checkbox?
Ok, so the site is up.

10:10 - Let's give it a nice name like Amazon suggest adding a cname in the domain DNS records.
That doesn't seem to work. Gives a permission error..
The manual says the bucket name has to be the same as the domain name.. rats! 
Ok, let's rename the bucket to
Great, now I get to wait 30 minutes for the dns cache to expire. I guess that's a good a time as any to eat breakfast.

10:42 - And we're back. And the new cname works:
Time for a little design. 
This website should be dead simple. You visit it and all you see is instruction on how to clear your browser. So we need some javascript that can detect browser, OS (because screen-shots will look different on each OS) and browser version. Probably also language, but let's start with just English for now.
I'm thinking the index page should just contain enough js to determine the right version and then fetch the appropriate html. So it's basically a dictionary of browsers identifiers to HTML manuals. Which also means we need to show a default in case we don't have a manual for the specific browser at hand. That can probably be some 3rd party web site that explains the same steps but doesn't detect the version.

10:53 - Cool. There's a JS library that does browser detection pretty well. We'll make our index.html file link to it and also add JQuery just for good measure.

10:58 - Here's our skeleton HTML. We'll worry about validation later:

It prints:

Your Browser is Chrome 16

11:06 - Let's figure out the dictionary we're going to use. I want it to degrade gracefully, so if we have instructions for FireFox but maybe not the specific version in question then it's probably better to show instructions for some other version than to fallback to the options of last resort (linking to an external page). So the keys need to be Language / Browser / Version / OS - in that order. This order makes sense because the same instructions on different OSs are much more similar to each other than instructions for different browsers on the same OS....

First let's shove all the JS into one main file:

12:10 - Here's main.js. It looks for the best match and tries to load the relevant instruction manual:

12:23 - Now I just need to populate the directory structure lang/browser/version/os.html with a few initial manuals. Let's create the first one for Chrome, then style it a bit.

12:48 - First manual for Chrome is ready. The html page itself has no styling at all:

And it looks like this:

So obviously it needs some nicer styling.

12:53 - Let's add CSS to this thing. First, we want it to be mobile friendly from the get-go. So we'll keep the snapshots as narrow as possible and the design itself should be dead simple. Just a centered narrow page with ordered instructions.

Nothing too fancy. 

13:55 - Let's DRY things up. I really don't feel like writing the same html template for each manual. Only three things change, basically: the logo, the instruction text and the image that goes with each instruction. Everything else can and should be generated automatically.
We want the entire manual HTML file above to be reduced to the following JS snippet:

14:34 - Here's the code that generates our HTML from the above JS dictionary:

Even the image names are auto-generated (image1.png, image2.png, ...) and each browser has its logo specified just once. Here is the resulting directory structure:

14:39 - Lunch time. Afterwards I'll add Firefox and IE.

15:48 - Firefox 10 and IE 9 are done. Now it's just a matter of adding more browsers and OSs. But I think I'll offload this to an outsourcing contract on oDesk.

That was fun. Visit to see the finished product.

Sources: main.js, index.html, manual.css