New Productivity Technique

I've noticed that after I finished the 4-hour workweek, I was very productive for a month.

I think I want to theorize that, by reading a productivity book, it will boost my productivity for a period of time.

It's not the technique inside. It is the confirmation that a productivity book tells you that you can be productive.

It's the inspiration...

Well, today I read "Inner Productivity" for like 1 hour, and I was productive afterward.

Maybe I should try this new technique in which I just keep reading productivity books everyday...

Divide a big task into one-hour tasks

Ok,let's try a new plan:

  • Divide a big task into one-hour tasks. Time it!
  • I shall test/debug after finishing the code of an one-hour task.
  • Take a 15-minute rest between 2 tasks

And here is the new mantra:

Either refactor the code immediately or abandon the project.

Refactoring has a big benefit in the long run. The only reason not to refactor is that the project won't exist in the future. If that is the case, just abandon it. It's wasting my time.

The amount of one task

Here is the rule of thumb:

The task should be as big as possible that you can code the whole task without producing errors and without testing.

If a task takes you 30 minutes and you later discover 1 error, the task is in an appropriate size.

If you can code a 30-minute task without producing errors, next time assign a 45-minute task instead.

If you code a 1-hour task and later discover 10 errors, next time assign a 30-minute task instead.

Testing is time-consuming, and it will slow you down. But you cannot ignore testing; you still have to do it...

The new bottleneck -- Test too often

I test too often.

I have to eliminate this impulse. I seem to test every 10-15 minutes. It becomes a bottleneck when the testing takes too long, for example, starting an iPhone app.

New goal: Test only 1 time per hour.

ERP's Journal

ERP stands for Extremely Rapid Prototyping.

Today, I almost finish my third project. So, I think I should write about the 3 projects I have done for the last 3 weeks.

Squeks.com

The first one is Squeks.com. I don't know what goes wrong with this one. It doesn't really attract people.

Squeks.com lets people express political opinions anonymously.

Right now it has like 30 members. It doesn't take off like the previous version of Squeks.com. The previous version of Squeks.com is very risky. It could put me in jail....

The development aspect of this one is not difficult. It's a simple website.

There are test cases to cover the basic flows, though I didn't write the test cases on Selenium because it is too slow to run tests.

Q&A website

The second one is still mine. I have been wanted to build a better web-board for Thai people. However, a web-board is too ambitious.

So, I've built a Q&A website, which looks like StackOverflow.

Its main theme is technology's questions, unlike StackOverflow, which only focus on programming.

A concrete example is someone asking about how to reset his iPhone.

The technology behinds it is kind of good. I used MongoDB with Apache Solr.

There were 2 hiccups in the development though.

I wasted a day to build a custom search engine with MongoDB. Big mistake. It's a crappy search engine. So, I have switched to Apache Solr.

Even though the word-breaking hasn't been done, it is still a good search engine.

Another hiccup is that I spent a day with a designer in order to decorate the website. Big mistake. I don't have to be present. The layout is already done by me. Decoration is just detail, which can be changed later. So, Future Tanin, don't do that anymore.

The Q&A website hasn't been launched yet. Right now I've devising a plan to approach the market.

My current plan is to generate 1,000 questions before launching.

I have built a system to import questions from other web-boards in order to accelerate the process of generating questions.

I will launch it very soon, hopefully.

Studio Stampo

The third one is an iPhone app, and it is not mine.

A girl told me about the story how she was chasing and trying to capture a picture of a bird in the sky. It was a tiring activity. So, she wanted an app that enabled her to put fake birds on a picture.

All my friends don't really understand it. Personally, I thought it was kind of stupid (no offence). But she sounded serious about running it. So, I've helped her build the first prototype.

It's a good app. If I liked to take a picture of birds, I would use it.

I've learned that people have their own perspectives. I think this idea is stupid because I am not her target users. (Well, I once thought iPhone was a stupid and overpriced product, and now I use iPhone and love it....)

I have cut down one feature from her vision. But I think my decision is justified.

She wants to sell birds on the app with the in-app purchase feature. I told her that it would take too long to do (1 full-day, I guess, since I have to read the document).

I told her that if there are more than 300 users, I will add it for her.

I'm learning to say NO directly, and, surprisingly, she took it very nicely.

Anyway, the app will not be launched this week, because we have to wait for the artwork.

Loca

This will be my fourth project with another friend. She wants to do a location-based check-in deal. It's kind of like Groupon but used through mobile phones.

Anyway, the idea is not new. Probably, more than a thousand people try to do it already.

It's all about the execution. She seems serious about it.

I will help her build and test the first prototype.

The Lessons

Probably, one lesson that I've learn from Stampo is that I should design an architecture (classes and stuffs) which is ready for changes, especially for UI's changes.

I did it pretty well though. I just need to keep going.

Loca is a bigger app with a server and web interface. Let's see if I can finish that in one week.

Extremely Rapid Prototyping's lessons

I have decided that I'm going to launch something, a new product or a new version of a previous product every week.

I've figured out that nobody really tries to ship 20 products within 6 months before. This is a worthy thing to try.

At least, what I will learn is how to build a good product in an extremely fast way. I hope, at the end of this crash course, I will be able to work with the speed of light and still produce a good product.

And I will get to work with various people and learn how to handle various kinds of people. What I did is talking to someone who:

  • Has an idea
  • Is serious about running it

Then, I help build the first prototype and get it off the ground, hopefully.

I shall take no stock, no equity, and no money. The other person owns the product 100%.

Yeah, I will work for free. I'm waiting to start at Twitter. I don't really need money. What I need are the skills; the coding skill that is god-like; the management skill that can finish a product in time with an acceptable quality; the skill to build great UI interactions; and, hopefully, one of them will get high traffic, and I will get to learn how to scale a server and a team.

Here is what I have learned during the last 2 weeks:

Wake up in the morning and spend all the attention to the work

I have tried this for 2 weeks, and it works really well. I am not stressful anymore because I feel that I have achieved so much during the day.

I work non-stop from 7:30am to 11:30am, go out for lunch, and then work from 1pm to 5pm.

No facebooking or tweeting, and no listening to music in the morning. Morning's attention is very pure. Don't contaminate it.

In the afternoon, you are allowed to slack off... it's ok.

After 5pm, I just relax.

Remember, Time without attention is worthless.

I'm trying to wake up at 6am though and work until noon. That will be a great way to work faster.

Build things vertically and build features that matter first -- Don't go too much into detail

Don't try to support things horizontally, for example, several types of user authorization.

Prototyping is to prove that the concept works; Supporting things horizontally is for acquiring more users, not proving it works.

Don't try to take over the detail of the project -- Let the other person be the owner.

Right now I try to pair with a person who will run the product (I build).

I have a very high tendency to take the ownership of the product and direct it toward the way I want.

I need to learn to let go. That person will run it. This means he/she is going to spend time with the product every day and night. It's a lot more encouraging if the product is theirs.

And another thing is I've built so many things that users don't want... so... maybe it's time to listen to other people.

Arrange the right layout at the first try -- Leave the decoration for later

Try to place things at the right position in the first try. It makes me work so much faster.

And don't forget to leave all the decorations for later.

Force users to login to do things -- It will simplify so many interactions

I used to, stupidly, make a website that allows user to post as a guest, a Facebook member, and as our own member.

The post's page is extremely complicated, and it takes a long time to do...

And don't support guest. Supporting both guest's and member's use cases is too complicated.

And it is not the point of the product anyway.

Leave it for later! much later!

Only do server validation

Don't do the validation of any form on the client side.

Performance is not concerned in the early prototypes.

You're not going to have 10,000 users (or even 1,000 users) that soon, trust me...

Researching stuffs, e.g. word-breaking, are hard problems -- Don't try to solve it. It should be its own product.

With Qri, I was trying to build my own search technology. It took me like 6 hours to build a really really really bad one.

Two days later, I switched to Apache Solr.

Those are 6 hours I will never get back....

Researching stuffs are hard. They should be a separate product.

Scaling Basics

Ok, so here is the script for scaling a server.

sysctl -w net.core.somaxconn=40000
sysctl -w net.core.netdev_max_backlog=40000
ulimit -n 100000

And edit the open-file-limit for the user who runs Nginx.

Edit /etc/security/limits.conf, and add these lines:

* soft nofile 4096
* hard nofile 100000

And Do not forget about Passenger forking.

Amazon EC2 setup for Ruby on Rails

This works with Amazon EC2 with its original OS

Here is the steps:

  1. Uninstall Ruby 1.8.7
  2. Uninstall Rubygems
  3. Install Ruby 1.9.3
  4. Make a link from ruby1.9 to ruby
  5. Install Rubygems for Ruby 1.9.3
  6. Make a link from gem1.9 to gem
  7. Install aws-amitools-ec2 (No idea what is it, but it was uninstalled because of Ruby 1.8.7)
  8. Install Passenger
  9. Install Git

The current draft

Warning: sometimes Rubygems mysteriously doesn't include /usr/local/bin into PATH. This causes the command passenger-install-nginx-module to fail.

Use Root to run the script

Run it with nohup ./ror_install.sh &.

#!/bin/bash

# Ruby stuff
yum erase -y ruby rubygems

# Ruby 1.9.3 dependencies (MUST NOT FORGET, otherwise many gems will be error at their installation)
yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison iconv-devel

yum install -y ruby19-devel
ln -s /usr/bin/ruby1.9 /usr/bin/ruby
ln -s /usr/bin/gem1.9 /usr/bin/gem

yum install -y aws-amitools-ec2

# Install Passenger gem
gem install passenger

# Install Nginx dependencies
yum install -y curl-devel

# Reload bash for passenger-related binary
source ~/.bashrc

# Install Nginx with Passenger
# with a sequence of key 
# 1. Enter (Skip Intro)
# 2. 1 and Enter (Install Nginx)
# 3. Enter (Install PCRE) 
# 4. Enter (Use default dir)
# 5. Enter (Skip the end)
echo -e "\n1\n\n\n\n" | /usr/local/bin/passenger-install-nginx-module

# Install Git
yum install -y git

# Now don't forget to configure Nginx. That's it.

PHP Database Migration

I've just built a PHP Database Migration Library in order to manage changes in the database's structure, for example, adding columns.

It generates a unique identifier for each migration script, therefore, 2 programmers can make changes to the database's structure and sync the changes later in time with a single command.

It mimics the database migration procedure of Ruby on Rails.

If you have a headache of managing changes in the database's structure from different programmers, you should give it a try.

PHP Database Migration Library

Update

I have just added the UI for ones who cannot execute PHP through a command line.

Check it out!

Automate Ruby on Rails setup on EC2

Works only on Amazon EC2 with Red Hat Linux

It starts getting annoying when I have to deploy like 3 Ruby-on-Rails apps.

I'll build a script to ease the process.

Here is the rough outline of all the required installation:

  1. RVM
  2. Ruby 1.9.3
  3. Git
  4. Nginx Passenger

The current draft for Red Hat Linux

Run it with nohup ./<file>.sh & and tail -f nohup.out to track the output.

Here is the script:

#!/bin/bash
# Install RVM
bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)

# Reload shell for RVM command
source /etc/profile.d/rvm.sh

# Install Ruby dependencies
yum install -y gcc-c++ patch readline readline-devel zlib zlib-devel libyaml-devel libffi-devel openssl-devel make bzip2 autoconf automake libtool bison iconv-devel libxml2-devel libxslt-devel

# Install Ruby 1.9.3
rvm install 1.9.3

# Make 1.9.3 default
rvm alias create default 1.9.3

# Install Passenger gem
gem install passenger

# Install Nginx dependencies
yum install -y curl-devel

# Install Nginx with Passenger
# with a sequence of key 
# 1. Enter (Skip Intro)
# 2. 1 and Enter (Install Nginx)
# 3. Enter (Install PCRE) 
# 4. Enter (Use default dir)
# 5. Enter (Skip the end)
echo -e "\n1\n\n\n\n" | passenger-install-nginx-module

# Install Git
yum install -y git

# Now don't forget to configure Nginx. That's it.

Setting up deploy user: (It doesn't work because the change of users.)

#!/bin/bash
useradd deploy
su deploy
echo -e "\n\n\n" | ssh-keygen -t rsa -C "deploy@youremail.com"

Here is an extension that install Mongo and MySQL:

(I haven't done it yet)