Comment Scene Like Instagram

In my short stint with iOS programming thus far, I found that one of the most difficult and crucial part of the process is deciding which controller to use. Conceivably, you could use a plain UIViewController to design everything but that’s a poor man’s way of going about it. Here’s how I did the comment page for Instagram.

There are a few requirements:

  • Comment box should stick to the bottom
  • Autolayout should be used
  • UITableViewCell should resize accordingly to the amount of text required to fit the cell nicely
  • Bonus: works in landscape and portrait modes. Instagram doesn’t support landscape.

2014-04-24 12.26.36

2014-04-24 12.23.33







General process:

  • Insert a TableView into a UIViewController
  • Add a subview programmatically or via storyboard
  • Set the constraints up correctly
  • Animate the bottom constraint from the comment box to it’s superview as and when the keyboard appears

Some gotchas:

  • You can’t do this using a UITableViewController and then laying a subview into it.
    • The view will move along with the tableview as you scroll which is not the behaviour you want
  • You can’t do this using a UITableViewController and then adding the comment box in the footer
    • The footer will always be below the last cell in the tableview which is not what you want


Buying AmazonGlobal Eligible Products From Singapore

Amazon free shipping to Singapore! Yay~~

Amazon free shipping to Singapore! Yay~~

Singapore recently came under Amazon’s GlobalSaver programme. What this means is that orders above $125 USD will have free shipping. Do note that if you’re spending over $400 SGD, you will probably need to pay taxes on those items.

So how does one go about buying these free shipping goodies?

To check if your product qualifies for the free shipping, use the following steps:

  1. Begin your search here:
  2. On the left hand nav bar, select the specific department e.g. Books or Electronics
  3. This should refresh the page with the left hand nav bar fully expanded. Scroll down until you find AmazonGlobal Eligible
  4. Check the box to filter it again
  5. The product must be sold by LLC and not one of its re-sellers.
  6. On checkout, choose
    1. Group products into as few shipments as possible
    2. AmazonGlobal Eligible

However, at this point in time, there seems to be a bug with the system. Having gone through this process, I still see delivery charges on my checkout page. I emailed customer service about this and essentially this is the workaround:

  1. Make sure what you what to buy is eligible for AmazonGlobal Eligible by going through the search above
  2. Pay for your product under the normal
  3. Submit a refund request under through this link:

I would however make sure to first email the CS reps before proceeding with the purchase to confirm the refund process. The service is pretty prompt.

Relevant Links

Install Graphite on OSX 10.7 Lion

Installing Graphite locally on my machine was a bit annoying. Hope this helps the next person.

1. Virtualenv

Because we are clean and tidy people, let’s start by first creating a new virtualenv

mkvirtualenv graphite

2. Pip

This installs graphite into the default location at /opt/graphite

pip install whisper
pip install carbon
pip install graphite-web

3. Install py2cairo

Follow the instructions here

    1. Download, unpack, and cd into the the py2cairo directory
    2. Activate your virtual environment
    3. Follow the standard build procedure
./waf configure --prefix=$VIRTUAL_ENV
./waf build
./waf install

4. Configure conf files

cp /opt/graphite/carbon.conf.example /opt/graphite/carbon.conf
cp /opt/graphite/storage-schemas.conf.example /opt/graphite/storage-schemas.conf

5. Configure graphite

cp /opt/graphite/webapp/graphite/ /opt/graphite/webapp/graphite/

Then edit

STORAGE_DIR = os.environ.get('GRAPHITE_STORAGE_DIR', join(GRAPHITE_ROOT, 'storage'))

    'default': {
        'NAME': os.path.join(STORAGE_DIR, 'graphite.db'),
        'ENGINE': 'django.db.backends.sqlite3',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': ''

# Default sqlite db file
# This is set here so that a user-set STORAGE_DIR is available
#if 'sqlite3' in DATABASE_ENGINE \
    #and not DATABASE_NAME:
  #DATABASE_NAME = join(STORAGE_DIR, 'graphite.db')

SECRET_KEY = '<insert your secrey key>'


This makes the settings file compatible with Django 1.5. You can get a secret key generator here.

6. Syncdb

cd /opt/graphite/webapp/graphite
sudo python syncdb

You should see a file called graphite.db in /opt/graphite/storage

7. Run

sudo python /opt/graphite/bin/ start
sudo python /opt/graphite/bin/ /opt/graphite

This is the expected output

graphite hello world

Here’s a test script to see if your graphite is working locally. Got it off

Then under tree, graphite, you should see foo/bar/.

Updates to my Vim workflow

I know vimfu

I know vimfu

The best way to improve your vim-fu is to do so incrementally. There have been a few inefficiencies in my current workflow that I’ve tolerated for the longest time. I’ve squashed a few of them today.

The first is auto-completing brackets. I used delimitMate for this. So now typing < automatically results in <> with my cursor in insert mode inside the triangular brackets.

The next one is auto-completing HTML tags. I have no idea why I’ve waited this long to get it fixed but closetag does the job well. To use, simple type <div> followed by ctrl-_.

The last one is great for finding bugs in your HTML. What matchit does is that when you press %, it cycles between the opening and closing tag where your cursor is currently located. Again, I’ve waited too long to fix this annoyance. This probably says more about my laziness than my patience.

Here’s a quick glance at all my plugins and my dotfiles for anyone interested.

Vim Plugins

Vim Plugins

Auto Start MongoDB Mac OSX

Follow the instructions to install MongoDB, after that, run through the creation of the database. The default location is /data/db but if you’re using Macports to install, you can choose to install your database alongside mongodb in /opt/local/var/db/mongodb.

To start the mongo server, simply run mongodb. MongoDB doesn’t auto launch itself. To do so, we have to edit the plist and add it to LaunchDaemon.

This is based on a MacPorts installation. If you’re using Brew, your mileage might vary.

  1. Edit /Library/LaunchDaemons/org.macports.mongodb.plist. My plist file looks like this.
  2. sudo launchctl load /Library/LaunchDaemons/org.macports.mongodb.plist
  3. Restart your system
  4. Go back into terminal and run mongo. You should be able to get into the interactive Mongo shell directly.

To stop this auto-start behaviour, simply use the unload command like so: sudo launchctl unload /Library/LaunchDaemons/org.macports.mongodb.plist

Installing MySQL51 Using MacPorts from Scratch for Lion

  1. Install the packages
    1. sudo port install mysql51 mysql51-server
  2. Initialize the db
    1. sudo -u _mysql /opt/local/lib/mysql51/bin/mysql_install_db
  3. Make mysql51 the default
    1. sudo port select mysql mysql51
  4. Run the daemon
    1. cd /opt/local ; sudo /opt/local/lib/mysql51/bin/mysqld_safe &
  5. Check to see its working by running mysql -uroot which should bring you into the interactive mysql shell as root user
  6. Setup
    1. /opt/local/lib/mysql51/bin/mysql_secure_installation

Other Notes:

  • For MySQL51, running cd /opt/local/mysql-test ; perl results in an error Can’t open perl script “”: No such file or directory. This is a reported bug.
  • Using zsh, running which mysql results in mysql: aliased to nocorrect mysql. To see the path. If you’re having problems getting mysql command to work, try this solution.
  • If you’re running into this error while connecting to MySQL Work Bench or Sequel Pro, MySQL said: Lost connection to MySQL server at ‘reading initial communication packet’, system error: 61, the fix is to comment out skip-networking in the my.cnf or macports-default.cnf file found at /opt/local/etc/mysql51

My Top 6 Productivity Tips for Developers or People Who Spend a Lot of Time on the Computer

Top Hit for 'Dilbert Productivity'

Top Hit for ‘Dilbert Productivity’

Every developer has their own little ‘secret’ cache of productivity tricks. Here are some of mine that I use every single day.


Cinch is an awesome free app that allows you to snap your opened windows to the side of the screen. This feature is first introduced in Windows 7 (I believe) as Snap and it’s probably one of  the best UX features that have been introduced by the Windows team. My typical setup is to have my browser on snapped on the left side and my terminal screen on my right.

Clip Menu

There are quite a few clipboard managers around, the one that I use is called Clip Menu. If you’re not using a clipboard manager, you’re seriously under-changing yourself. cmd-1 brings up a history of my recently copied items and pressing the corresponding number allows me to paste the contents.

zsh (not applicable for non-developers)

I discovered zsh and oh-my-zsh recently and boy oh boy, am I loving every minute of it. Essentially, it’s gives you all the power of bash but with autocomplete goodness on steroids. Depending on your development setup, you will need to install the relevant plugins by modifying the .zshrc file which replaces the your bashrc/bash_profile settings.


Does your work involve you needing to share an image/document/anything? I guess most of you would answer ‘yes’. Cloudapp enables you to do this by dragging and dropping the item you want to share onto it’s icon. It uploads the file and spits out a link which you can share immediately. A nice touch is that you get to see the number of times that file has been accessed.

Hot Key Your Mouse

I use two different mice. At home, I have a Razor Naga which I have configured the side buttons to do the following:

  • next/prev tab in chrome hotkeyed to numbers 1 & 2
  • back/forward in hotkeyed to 4 & 5
  • open/close tabs to 3 & 6

At work, I use a Logitech M705. The two side buttons I’ve set to back/forward. I’ve not had to change the batteries in this baby since I’ve gotten it 2 years ago (roughly). Logitech isn’t joking when it says its the ‘Marathon Mouse’.

Also, as any gamer would tell you, a good mouse pad helps.

Always Be Learning While Travelling

You can only do that many days of people watching and blanking out on your commute to work. Why not learn something new everyday instead? Two of my favourite podcasts that I like to tune in to work are: Radiolab and 99% Invisible.

Bonus Hack: Conversation Starter

One of my favourite questions to ask a newly acquainted friend or someone whom I haven’t met for a while is this: what’s the most interesting/meaningful thing that has happened to you since we last met/this year. It’s an awesome starting point to start a conversation as it gets the person talking about something close to his/her heart.

Do you know any good productivity tips? Do share!

A List of Sites for People Looking to get into Web Development/Programming

Just a list of resources I’ve come across. Thought I put them all in one list. If you come across anything new, that’s good, do add them to the comments and I’ll update this list accordingly.


Massive Online Open Courses (MOOC) and Stuff I can’t Categorise


Language Specific








User Groups in Singapore (That’s where I live)

Lastly, if you’re wondering what language you should use for your next startup…

Thanks to Michael for helping me out with the PHP resources and other useful links.

What Every New Python/Django Web Developer Should Know in 3 Months

This is a collection of things I think any beginner web developer working on the Python/Django stack ought to know. This assumes zero knowledge in web development or programming to begin with.

  1. Web Related
    1. What is a GET and POST request
    2. 200/301/302/403/404/500 status codes
    3. What is a cookie and how is it used
    4. Learn how to search and read documentation
    5. Basic SEO knowledge
      1. Best book to read: The Art of SEO
  2. Frontend
    1. How a page is loaded in the browser (DOM)
    2. Working/basic knowledge of HTML/CSS/JS – You will learn this by osmosis
    3. What is AJAX
    4. What is HTML5
    5. Basic UX/UI understanding
      1. Best book to read: Don’t make me Think
  3. Python
    1. Write Fizzbuzz
    2. Read Learn Python the Hard Way then an intermediate book like Dive into Python or one of the O’Reilly series
  4. Django
    1. Do the tutorial project at
    2. Read Definitive Guide to Django Development Done Right
    3. Be able to setup a new project from scratch using virtualenv locally with a skeletal folder structure and settings that caters to a production and development environment
    4. What a view function does
      1. GET/POST paradigm within a view function
    5. What a model class does
    6. What does a template do
      1. What is template inheritance
    7. Basic Regex and URLS
    8. How do urls, views, models and template relate with one another
    9. Difference between model forms and forms
      1. How does form validation occur
    10. How to write a test that tests the view functions, models and utility methods
    11. How to debug and find the source of a problem
  5. Database/Models
    1. How to model Foreignkey relations
    2. How to model M2M relations
    3. Basic data types
  6. Tools in your Employ
    1. iPython
    2. South
      1. How does a migration work
      2. How to do an initial migration
      3. How to migrate subsequent changes to a schema
      4. Trouble shoot migration conflicts
    3. Git
    4. IDE of choice, preferably VIM
    5. Firebug
    6. Fabric
  7. Processes
    1. Deployment process at your team. How it works, what git hooks are used for what purposes. What fabric scripts do what etc
    2. Git Flow
      1. How to add, commit, release, rollback, fix, merg and conflict management
  8. Soft Skills
    1. Communication with product owners
    2. Communication with colleagues
    3. Cultivating a Growth mindset
  9. Graduating Project!
    1. Create a one page Django project that will allow me to:
      1. View all the users on the project
      2. Edit the details of the users
      3. Create a new user
      4. Delete a user

A note on doing too much reading:

Oftentimes as a beginner, we’re overwhelmed by the amount of information we need to do something. The knee jerk reaction, a badge of the fine education doctrines what have been ingrained in us, is to read about the topic/subject. I find this hits a wall of diminishing returns quickly.

For the reading to be truly effective, you need a certain amount of wisdom to absorb it. This can only be done by reading backwards. What this means is that say you’re tasked to create a dashboard page from scratch. In your mind you’ll probably think something like: whoaaaa, I have on idea how to do this. I need to do some research! And then you try to do random reading at djangoproject or various books and then bite off more than you can chew. The human brain has a tendency to make things more complex than it really is. The right question you should be asking in your mind is: how do I first load a page and then present a form on this page to manipulate data? This will make your reading much more directed and effective.

Display Current Git Branch for Mac Bash iTerm

As a developer using git, it’s always good to know which branch you’re currently on. I wish I’ve done this a lot earlier but I now have the following snippet pasted into my ~/.bash_profile. Some other blog posts have this snippet in ~/.bashrc, some in ~/.profile. To be honest, I’m not exactly sure of the difference between each one, even after reading stuff like his:

So if you open a new terminal and nothing happens when you go into a folder that has been git initialised, you might need to paste the code in one of the other files.

parse_git_branch() {
	git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(git::\1)/'

PS1="\[33[00m\]\u@\h\[33[01;34m\] \w \[33[31m\]\$(parse_git_branch) \[33[00m\]$\[33[00m\] "