Singapore Elections 2011: A Wannabe Hacker’s Point of View

This is a break from the usual tech and startup related posts as I will be voting for the very first time in my life and I thought I ought to do a blurb about it.

As a concerned and vested citizen of Singapore, I am taking a long term perspective on issues and policies. Long term as in a time-frame of decades. I believe to have a 50 year plan, you first need to have a 5 year plan. To have a 5 year plan, you first need to have 1 year plan. So, like most things, the devil is in the detail. Say I want to hire a CMO (Chief Marketing Officer). CMO waltzes in and says: “Ya, I increased visitors to by 5000%. Trust me. Hire me.”

Erm, no?

Basing current performance on historic performance is well, not my cup of tea. Call me a fundamentalist. Here’s a simple exercise. Assume there are 5000 fund managers in the world. At the end of each year, a fund manger either outperforms the market or underperforms it. By the end of year 5, just based on pure probability alone, there would still be 156 fund managers who would have outperformed the market for 5 consecutive years. No skill, just probability.

The first things that come to my mind in testing this CMO would be:

  • How did you increase it?
  • What was the context for the increase?
  • Did you do A/B testing or MVT?
  • How did you account of seasonality?
  • Were your marketing efforts repeatable and hence scalable?
  • What methods are not longer effective?
  • What was your ROI?

You know, stuff like that to make sure this guy really knows his shit. So therein lies the problem for me: No party is giving me the f*cking details. I don’t know how all the parties are going to execute on their rhetoric. I want to know how you’re going to achieve your goals over what period of time and the resources required. You know, kinda like a shareholders AGM where the stakeholders can hold the company accountable?

First for the bored and curious, you can find the manifestoes for each party here: PAP, SDP, NSP, RP, SDA and WP.

Of all the parties, I think the Worker’s Party has the most thought-out and well written manifesto. Even then, they still fall short on details. Let’s take it party by party. I’m just gonna pick up random snippets.


“The government should seek to attract more venture capital firms to Singapore so that they not only provide the funding to promising start ups, but the managerial expertise as well.”

Erm, how? VC’s are chasing returns. How do you have returns when there are no exitsDoing a Yuri Milner might be a better way to help startups in Singapore.


“Target to reduce Singapore’s Gini Coefficient of 0.45 to 0.35 within 10 years, the latter figure being representative of most of the developed countries.” 

Erm, how? This is like a fucking difficult problem can? Are you going to slow down the rate of millionaires in Singapore or what? In any case, why do we have to be on-par with other developed countries? Hell, why not lower?


“Increase funding for healthcare to reduce the financial burden on Singaporeans. Increased investment in public hospitals and polyclinics to cut the waiting time for Singaporeans. More hospital beds are needed for a growing and greying population. The number of hospital beds has remained stagnant at 11,000 to 12,000 over the past 10 years, while our population grew by 26%.”

Erm, how? Where is this money coming from? Is this coming at the expense of another budget? Is there a correlation between population growth and hospital beds? Shouldn’t the right comparison be proportion of aging population versus available hospital beds? Isn’t a lot of this population growth coming from young immigrants anyway?


“Universal health insurance to be funded through current CPF contributions replacing current Medisave and Medishield schemes.”

Universal health care is an age old problem. From my limited understanding, the standard way to provide for universal health care is to have high taxes like in the Nordic countries. But wait, you want to increase GST as well. So, our CPF is gonna be like a magic hat? You pull money of out it to pay for your flat, your retirement and your health insurance? Erm, show me the math please? How is this all coming to work out? Where’s all the money coming from?


“Economically, the influx of cheap foreign labour is causing wages of locals to be depressed. The widen income gap is unsustainable. Socially, the immigration policy is causing tensions that are beginning to manifest in unfortunate and ugly ways. We must check the PAP’s recklessness and stop it from increasing our population by another 30 percent!”

Let’s compare apples with apples here. As far as I can tell, all the cheap foreign labour are doing the jobs that well, Singaporeans don’t want to do. E.g. Driving buses, selling rochor beancurd, atrium sales etc. So when you say wages of locals are being depressed, who are these locals? What are they doing? I think the reason why the PAP is letting so many foreigners into the country is because Singaporeans aren’t f*cking enough. Any culture needs a birth rate of 1.25 to be self-sustaining. Singapore is at 1.16. That’s right guys, we are going to be extinct at this rate of copulation.


” Provide new, high-quality and affordable HDB home”

Housing prices must surely be one of the focal points of this election unless you’re MBT. You could have taken this opportunity to address the many concerns of Singaporeans but instead you decided to go with a one-liner. 10 points for being concise, 0 points for empathy. Also, with the whole baby fertility thing? I think you’re treating a social issue as an economic one. Throwing more money (literally) at the problem isn’t going to help FFS. Didn’t anyone of your scholars read Predictably Irrational?

My Conclusion

I am not the target audience for the various political parties ergo my vote is not important to them. Their target audience are the kind of people who would respond to lorries blasting out slogans on a loud hailer. That’s also damn old school style of campaigning man. I cannot connect emotionally with a loud hailer on a lorry. Sorry, I just can’t. Not even if Nicole Seah, Foo Mee Har AND Tin Pei Ling were in the lorry wearing nothing but their birthday suits. Then again, words don’t even count for much these days.

To a certain extent, I almost don’t care what their implementation policies are like. I know this completely contradicts what I’ve just said. But I guess I just want to know that they are actually thinking about these various problems in detail and anticipate that us, the electorate, aren’t just nodding donkeys ready to drink the kool aid that’s being dished out. That they actually have a crack team of guys doing the due diligence that’s required and having the data to support their assertions. You know, data-driven policy making.

To cap off, I think the best outcome is for PAP to win in aggregate but for certain parties to win seats in Parliament. Chen Show Mao is a rockstar and he is the kind of people we need in Parliament to provide expertise and perspective that will ultimately determine the future of Singapore and her inhabitants. We also need to start caring about the details because this isn’t a popularity contest. Maybe that’s the problem — no one cares about the details anymore.

A Basic Django Workflow

Bruce Lee understands flow like no other

Having done about 5 – 6 mini apps in Django now, I’m beginning to get into a sort of rhythm. One of the questions I had early on was “What is a good Django workflow”. The answers were good but kind of high level for my liking. Also, given that I’m not trained in the art of Agile Development, terms like actors, continuous integration and the like mean very little to me. Having said that however, I do understand its importance especially in the context of  Lean Startupbut this is not the time for me to get involved with more jargon and complexity at this stage of my learning.

So this is my current hands-on workflow for a new Django app:

Django Workflow

  1. Create a new project and a new app called mainapp
  2. Edit Fix the following:
    1. Database settings
    2. Installed apps
    3. Media and media admin paths
    4. Most recently, to add CSS and JS paths
  3. Edit in the project folder and
    1. Uncomment the admin paths
    2. Include
  4. Create a new in the mainapp folder
    1. Create a path that display a view called home
  5. Create a new templates folder
  6. Create a base.html file in the templates folder
    1. Create a place-holder variable within base.html
  7. Edit the file. Create a new view called home and return ‘hello world’ using the base.html template and a place-holder variable
  8. Create a media folder the project folder (1 level up from the mainapp folder)
  9. Edit the file
  10. Run syncdb
  11. At this point, you should be able to access both your admin page and your homepage that outputs ‘hello world’ by running the development server
I think this process is applicable to any new Django project and serves to get the ‘paperwork’ out of the way so you can start getting on with the actual coding within your file. If you have any suggestions or if I’ve missed something out (I had to write this post twice x_x), do leave them in the comments.
Lessons Learnt
  1. Django’s strength is also it’s weakness. It’s easy to get a new project going but changing the database structure is a pain. You can’t add new columns to an existing table in your file and expect syncdb to update your database schema. This is a recgonized problem and tools such as South have been created to address this. I haven’t tried using it yet and I really ought to.
  2. I need to start looking at other Django projects to see how others layout their apps. Right now, I’m working on a reporting app for Insync (gdocs sync) and my is very big. I’m not even sure whether others consider it to be big and that what I have is the norm. So when is a good time to split it into another app within the project is a question that is on my mind. So if you’re a Django Jedi Master looking to deposit some goodwill in my goodwill bank because today you, tomorrow me, do let me know 🙂
  3. Think I need to start reading on the forms feature in Django. It takes care of trivial situations like this question I had — remembering a radio button selection.
  4. Also need to start reading up on Django unit testing at some point.

My First Databound Python/Django Powered Webapp

Like a boss

When I first decided to start coding back in January, my initial aim was to have a databound webapp out by June this year. Given that most consumer facing applications follow the CRUD design template, I felt the databound aspect of the application was integral to my learning. My previous apps to date consisted mostly of utilizing API calls to present data so I needed to up my game a notch. Enter the Django  Well, Django’s admin system is so slick and easy to use that I feel a little cheesy saying this but I present to you my very first databound webapp. Made lovingly with Python/Django and hosted not so lovingly on EC2 (I had a bitch of a time setting it up) *drum roll*

The Singapore General Elections are round the corner so I made a little app that aggregates the schedules of each political party. Unfortunately, I’m running a little thin on data due to the lack of information available on their websites. They are also not responding to my emails (apart from The Reform Party). So version 2 is going to include a ‘news’ section which I will be scraping from the websites of each party. The elections will probably be over by the time I am done but whatever. Anyway, the concept of the website is not that important. What’s important is that I went from asking stupid questions like this and this to building a fully functional website by myself. I even re-skinned it! Something was a weird though. I was expecting to feel more pride and satisfaction given that I’ve achieved my goal with 2 months to space. While I am chuffed with my efforts, the overriding emotion that is one of: how can I make the app even cooler. I’ve caught the bug, building stuff is hella fun.

Lessons Learnt

  1. It doesn’t take 6 months to design a simple webapp. You can probably do it within a month easily if you work at it everyday.
  2. Hosting your site is a bitch. Learning about the different layers involved in making an application is also bitch. It’s quite daunting initially but get over the early hurdles and you’ll have a much better picture of what actually happens when someone clicks on the ‘next’ button or refreshes the page.
  3. I’m starting to understand why some techies hold non-techies in contempt. I showed the early versions of the app to some friends and they were *not impressed*. This was probably because the early versions of the site looked like shit. It’s hard to explain how satisfying it was when I figured out how to mod 30 lines of code to generate a HTML calendar that suited my needs. It’s a very good reminder to myself that users don’t care about the underlying tech. For a consumer app, the tech is just a tool to execute the idea and if they don’t get your app, you lose.
  4. You will pick up SQL/HTML/CSS along the way out of necessity. So when you say “I wanna learn to code!”, what you’re really doing is “I wanna learn to code and learn all the other stuff that makes my code come alive on the internet!”
What’s Next
At this stage, I am re-reading all the beginner books on Python. Due to the fact that I was actually doing very little Python, I felt I needed a re-fresher to remind myself of the basic stuff I didn’t use. I was breezing through the chapters, mentally ticking off the concepts in my mind “Yup know this, know that, understand how that works now”. Personally, I found it very encouraging that I had enough know-how to be able to skim the pages. In terms of my day-to-day at Insync (gdocs sync), I am currently working on a reporting system for the in-house analytics. I’m doing this Django (I’m a one trick pony) and using matplotlib to output the charts. Really psyched about being ‘good enough’ to be able to start contributing actively to the company. To infinity and beyond!

Non-techie Guide to setting up Django, Apache, MySQL on Amazon EC2


Bruce Willis is THE SYSADMIN GUY

I don’t like sysadmin. I think someone needs to do a stable non beta version of Heroku for Django ASAP. Hence, I’m putting this little walkthrough to help anyone who might be trying to do what I think is a pretty common setup. Getting Django, Apache, MySQL to play together nicely on the free instance on Amazon EC2.

DISCLAIMER: I’m a sys admin NOOB. I am also teaching myself to code. This is my first time setting up this stack so there are probably going to be some bugs/security issues I conveniently side stepped just to get it to work. Tips from the pros on how to improve this process is greatly appreciated. But I did spend quite a bit of time researching and walking through the process on a new Amazon instance and it worked. So use this guide at your own risk.

The starting point of this guide assumes you have already signed up for an Amazon AWS account and that you have already created your free instance. We will be installing and setting up a test Django project together with Apache, mod_wsgi, phpMyAdmin and MySQL. This tutorial assumes you have basic working knowledge of commands in bash.

Step 1: Connect to your Instance

At some point of the creation of your instance, you should have created and downloaded your PEM key. Navigate to that folder in bash and type:

ssh -i <yourkeyname>.pem ec2-user@<YOUR PUBLIC DNS>

You can get this from right clicking on your instance in your AWS dashboard. I had to change root to ec2-user. Replace the public dns with your own.

Once you’re connected, you should be greeted with some ASCII art. Now change to root user by typing

sudo su

Step 2: Install Stuff

# Install Django (latest version is 1.3) from home directory
tar xzvf Django-1.3.tar.gz
cd Django-1.3
sudo python install
# Run Python interpreter and import django.
# If you get the following error:

Python 2.6.6 (r266:84292, Jan 18 2011, 10:20:48)
[GCC 4.4.4 20100726 (Red Hat 4.4.4-13)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named django

# To fix this, run the following

ln -s /django-1.3/django /usr/lib/python2.6/site-packages/django
ln -s /django-1.3/django/bin/ /usr/local/bin

# Install Apache
yum install httpd

# Install PHP libraries
yum install php libmcrypt libmcrypt-devel php-mcrypt php-mbstring

# Start Apache. The 2nd command starts the Apache service whenever
# your server reboots
service httpd start
sudo chkconfig httpd on 

# At this point, if you go to your public Amazon DNS in your browser, you should see the Apache test page.
# For my case, I entered into my browser

# Install mod_wsgi
yum install mod_wsgi

# Install MySQL and related libraries
yum install mysql mysql-server MySQL-python

# Set password for MySQL root user
/usr/bin/mysqladmin -u root password '12345'

# create a dummy database
mysql -r root -p
# enter password. in this example we used 12345
create database test;

# Start MySQL
service mysqld start
sudo chkconfig mysqld on

Install phpMyAdmin by following the steps here (Warning: It’s quite long. You can skip this part if you want).

Step 3. Edit http.conf and create django.wsgi files and other stuff

First, create a new user and a new Django project

useradd djangotest
su - djangotest startproject helloworld

Switch back to root user and open your httpd.conf file

sudo su
vim /etc/httpd/conf/httpd.conf

Towards the end of the document, uncomment

NameVirtualHost *:80

Then change <VirtualHost *:80> </VirtualHost> to this

<VirtualHost *:80>
    DocumentRoot /home/djangotest/helloworld
    ErrorLog /home/djangotest/helloworld/logs/apache_error.log
    CustomLog /home/djangotest/helloworld/logs/apache_access.log combined
    WSGIScriptAlias / /home/djangotest/helloworld/apache/django.wsgi

    Alias /phpmyadmin /var/www/html/phpmyadmin    
    <Location /phpmyadmin>        
        SetHandler None    
    <Directory /home/djangotest/helloworld/media>
        Order deny,allow
        Allow from all

    <Directory /home/djangotest/helloworld/apache>
        Order deny,allow
        Allow from all

    LogLevel warn

    Alias /media/ /home/djangotest/helloworld/media/

I also had to change the user and group from apache to djangotest.

# use ?User within vi to search for this
User djangotest
Group djangotest

Now navigate into the folder where you ran startproject helloworld earlier and run this

mkdir apache
cd apache
vi django.wsgi

# paste this in 

import os,sys

apache_configuration = os.path.dirname(__file__)
project = os.path.dirname(apache_configuration)
workspace = os.path.dirname(project)

os.environ['DJANGO_SETTINGS_MODULE'] = 'helloworld.settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()

Whilst you’re in the project directory, create the log folder and files

mkdir logs
cd logs
vim apache_error.log #save using :wq
vim apache_access.log #save using :wq

The paths here should match with the ErrorLogs in the httpd.conf you edited earlier.

ErrorLog /home/djangotest/helloworld/logs/apache_error.log

Step 4: The Easy Part

So all the hard parts are done, what’s left is to fill in the Django specific parts. I’ll just show the relevant parts of each code snippet

    'default': {
        'ENGINE': 'mysql',
        'NAME': 'test',
        'USER': 'root',
        'PASSWORD': '12345',
        'HOST': '',
        'PORT': '',

Create a new document and add the following in

from django.http import HttpResponse

def home(request):
    return HttpResponse('Hello World')

from django.conf.urls.defaults import patterns, include, url

urlpatterns = patterns('',
    url(r'^home/', 'helloworld.views.home', name='home'),

Fire up your browser and navigate to your <public dns>/home and you should see Hello World, <public dns>/phpmyadmin to get to phpMyAdmin if you installed it.

I ran into some issues trying to log into phpmyadmin. If you are having problems as well, leave a comment and I’ll try to help you out.

Note that after making changes to the httpd.conf file, it’s a good idea to restart Apache by typing this command:

service httpd restart

Also, in creating your security groups for your Amazon instance, you have to allow access to the ports 80 (for browsers) and 3306 (for MySQL) and any others that you need like Port 8000 and 22 (SSH).

P.S This is my first ever ‘technical’ tutorial. Feedback and comments welcome!
P.P.S This is obviously not secure enough for a ‘production’ environment. But it should be enough for you to host your own mini projects and share them with your friends/family for feedback!

Useful Links and Credits