Saturday, December 4, 2010

Samsung: Korean for Fail

I've just looked up "Samsung" on Wikipedia. They confirmed that Samsung is in fact a company. I checked because I'd started to believe that it was a long running practical joke.

I've just given up attempting to upgrade my Samsung Galaxy S to Android 2.2 (Froyo). I was hoping that Froyo would resolve some of the deficiencies of the SGS such as:
  • Periodic jam ups including a few when I was trying to answer a phone call.
  • Failure to automatically switch between 3G and Wifi (the work-around is to switch it to airplane mode and back or if that fails, turn the phone off and on again, what fun).
  • Popping up an alert (day or night) to tell you that it's finished charging. Please wake me at 3 in the morning to tell me you've finished charging, I'd hate to sleep through that event.
  • Requiring debug mode to connect to a computer running any OS other than Windows.
But of course if you run OS X or Linux you're out of luck anyway because it only provides support software for Windows software for essential operations like upgrading the damned thing. Not that it matters because it has such a shonky support software that it's hit and miss whether it will even recognise that a phone is connected at all. I've just given up trying to get it to work for now having read that many users have bricked their phones just attempting to do the manufacturer sanctioned upgrade.

I read reviews before I bought this thing. They raved about it's screen. Yes, the screen is nice. They pointed out how fast the processor was and I got the one with the built-in 16GB SD card. Having read the reviews, my biggest concern was that it didn't have a flash for the camera.

I know better now. It's the little things that make this such a pain to use. Things that must not occur to a reviewer in the short period of time he or she is using it.

Before I had this I had an iPhone 3G. I liked it. The browser was a bit slow compared to modern phones, it didn't have a compass so it wasn't great for navigation but it worked. There was a load of good quality software. I mean sure not everything in the Apple App Store is a gem but have you seen the Android Market? I'll take the curated experience thanks.

When I went to Android because I thought I'd be keeping all of what I had with the Apple and gaining better Google interoperability. It just isn't so. Samsung has made a powerful case for Steve Job's conjecture that you can't guarantee a quality user experience unless you provide the full hardware and software stack.

Is this completely one sided? No. Android's killer feature (compared to the iDevices) is the "back" button. I think that it's more than having a physical button, it's how the OS works but having a consistent way to go back to the previous app is a big thing and I miss it when I borrow my wife's iPad.

The freedom to choose install alternate input methods is also good (but not essential). Apple seem to resist that level of customization. Their "you don't need it" policy at work. Maybe if I'd bought an HTC Desire I'd be feeling better about the whole Android thing but Samsung have left me more than willing to give up some freedom just to get something that works.

What I find amusing is that Samsung sent a free Galaxy S to a few prominent twitterers who complained about the reception problems with the iPhone 4. I can only imagine that it was to make them appreciate how lucky they really were.

Thursday, November 25, 2010

Coding Karma's Gonna Get You

If you're writing a server based web application (in any language) and you're not following MVC principles, then please stop and go Google "Model View Controller".

I've recently inherited a site with pretty much no documentation and a mess of legacy PHP code with some Java and Perl thrown in. Am I having a good time? No, not really. What would have made it better?

Well, it's tempting to say documentation. If well written, that may help. An overview from a business perspective would have been really welcome. But even if I'd had that, it would help only a little to work out how the system itself works.

Every time I try to work out what's going on, I trawl through pages of procedural PHP interspersed with SQL queries to a non-normalised database. It's confusing and exhausting. Please don't inflict this on your successor.

Am I just whinging? Well...yes. But with a purpose. There is a certain amount of inherent complexity in any system but there's no need to complicate it further by not employing tried and tested techniques and mechanisms available to you. If you do, you're doing yourself, your employer and your successor a disservice.

Use frameworks people. I'd recommend Ruby on Rails. But if that's not for you, pick one that is. If your application displays a web page, takes some user input, accesses a database and displays another web page then please use an MVC framework.

Here's what a decent framework brings to the table:

 - DRYness. Don't Repeat Yourself. Copy and pasted code is annoying for the person who has to read it. Copy and pasted code is annoying for the person who has to read it.

For every request that comes in, your application will have to do certain things. Every time it accesses the database, there is a certain amount of common code that gets run. A framework's job is to implement this boiler-plate code and hide it so that your program consists of the things that differentiate it from every other web application.

 - Separation of concerns; If you're doing SQL queries in the same that generates HTML then (seriously) please stop coding now and do some reading. It's quite possible, and highly desirable to separate your CSS, HTML, Javascript, View, Controller and Domain logic into separate files.


 - Testing; Manually testing applications is expensive in terms of time. You really need a batch of tests that run every time you make a change to ensure that no existing functionality has been lost. The best time to write these tests is before you right the code. That's called test driven development and (done right) will save you and your users much time and frustration.

The fewer dependencies it has, the easier code is to test. If you need to setup a web server, database server, and an ActiveDirectory domain to test that your code works you're very likely not to do it at all. This was one of the reasons why separation of concerns (above) was desirable. The separate units can be tested individually without the overhead of bringing up a complete system. Your framework should provide tools and instruction in how to do this.


 - Convention; How much does it matter to you what you call the folder containing your controllers (that's the C in MVC)? Surely very little so long as:

 a. There is one and it only contains controllers.
 b. Its called the same thing and in the same place for every project.
 c. The next person to work on the project can reasonably be expected to identify it.

 - Business Continuity; Not only is the interchangeability of developers essential for the business, it's probably in your interest too. Do you really want to stay in this job forever? Do you really want to the be one person who can debug it? Your system will tie you down to it until someone eventually replaces it and you. A framework acts as a label in a job ad. Yes, I am a SpringMVC developer. Yes, I'm a Django developer. I understand the concepts and conventions employed by this framework. I know where to get help if I need it. I know that I can walk into that job and quickly understand your system.

 - Experience; If your framework is a good one, preferably developed over a period of time with many people in a meritocratic environment then the result will be far more refined than anything you could hope to achieve on your own. By all means, learn from first principles. It's good to understand the lifecycle of an HTTP request by writing a CGI script or even a PHP page. And when you're done, save it in a folder called "Learning" and start using a framework.

Friday, March 5, 2010

Missing images with JQTouch on Rails Production

It's generally a good idea to use the ":cache=>true" argument to stylesheet_link_tag to ensure that all your stylesheets are loaded in a single request in production. Eg:


= stylesheet_link_tag '/jqtouch/jqtouch.min.css', '/themes/apple/theme.min.css', 'mobile', :cache=>true

This can cause problems though if the stylesheet:
  1. References resources (such as background images) via relative URLs
  2. Lives somewhere other than public/stylesheets
The reason it's a problem is that the :cache=>true option causes stylesheet_link_tag to bundle all listed stylesheets into /public/stylesheets/all.css. Suddenly, every URL is relative to public/stylesheets.
I encountered this problem when using JQTouch in a Rails app.

The theme stylesheet for jqtouch was located in /public/themes/apple/ and it expected to find all images in an img sub-folder. This worked fine in development but in production, suddenly no images appeared.

My fix for this was simply to create a symbolic link in the stylesheets folder thus:

cd stylesheets
ln -s ../themes/apple/img img

This seems to do the trick, even on Heroku.

Ruby Dates to Javascript the Easy Way

Whilst writing the queue management for Cafebop in Javascript using the excellent JQTouch library I came across a problem that I thought would be trivial to solve. In the end it was trivial but maybe it's so trivial that nobody ever mentions it so I couldn't find any info on it.

Basically, I wanted to instantiate a Javascript Date object from a Ruby Date object via a JSON call. The problem is that Javascript's Date object constructor can't parse the default string output by Ruby's Date#to_s.

However, it can parse an integer which is milliseconds since the Unix epoch. Ruby's Date#to_i outputs the number of seconds since the unix epoch. So, using my mad arithmetic skillz, I figured I can create a Javascript Date with:

new Date(rubyGeneratedInteger * 1000);

So my usage of it went something like this. In my rails model, I generate an appropriate integer representation of the timestamp:



I make that available to a JSON client through the controller:

And consume it from the Javascript client thus:

Monday, March 23, 2009

ALP to Protect You from Yourself

In an opinion piece for the Sydney Morning Herald, Helen Razer stated:

It is claimed the blacklist will prohibit access to child pornography - and no rational person would argue with that. Not even Evelyn Hall or Voltaire. And certainly not me.

Well. I'll give it a go and you can tell me after if I'm in my right mind or not.


Police receive a tip-off that members of a nefarious crime gang will be meeting in a particular building in the near future. Should the police:

A) Discreetly survey the building from a distance and attempt to identify those who enter.
B) Send uniformed officers in a marked police car to erect a barricade in front of the door and turn away anybody attempting to enter.

Much has been made of the technical reasons that the Rudd government's plans for mandatory net filtering are a bad idea. There are many and it is right to point them out. But even if there were no technical or security issues, would the filters be a good idea?

The primary argument put forward in favor of the filters seems to be keeping children safe. Nobody sensible would argue against keeping children safe but it's important to consider what we're keeping them safe from.

My biggest fear as a parent is not that my children will see something inappropriate on the Internet. It might happen and it might be upsetting but its not life-threatening.

What does disturb me greatly, however, is the possibility of a real-life encounter with a pedophile. This can be life-threatening or life-ruining.

I am very much in favour of identifying people who are a likely threat to children (eg viewers of child-pornography) and taking appropriate action against them. As you may have guessed, they are the nefarious crime gang in the analogy.

One concern I have with the proposed mandatory filters is that it is very much option B. The net filter is a very expensive barricade with flashing lights. Not even the dimmest criminal could miss it. So does our barricade prevent the crime from taking place? Absolutely not. This building has many entrances and the barricade only blocks the front entrance. Those intent on entering will still do so. Only now they know that the police are watching the front entrance.

So was option A possible? Is it possible to discreetly monitor those who access websites known to contain illegal material? Technically, the answer is yes. In fact, it's common practice to identify would be wrong-doers on the net by monitoring accesses to a particular address. Security experts actually set up computers to tempt intruders. They're known as honeypots. The illegal sites are pre-made honeypots. It's quite possible to monitor access to them discreetly and non-obtrusively.

So why is the government opting instead for a far more expensive and intrusive system? I can only think that it is because it has nothing to do with protecting children and everything to do with enforcing their own ideology on the rest of us.

You are all witnesses to the dawn of the era of the World Wide Web. Have you seen society tear itself apart? Where is the evidence that we need protection from all those naughty pictures and ideas. The answer, I believe, is in the imaginations of Stephen Conroy, Kevin Rudd and Steven Fielding. 


Saturday, March 14, 2009

Django on App Engine Gotchas

I've been trying to use Google App Engine (GAE) of late. As a Python newbie its a fairly steep learning gradient. App engine as it ships is fairly simple but missing many of the conveniences I've grown accustomed to from using other web frameworks so I thought I'd drop Django in to the mix.

Out of the box, Django is designed to work with relational databases. The GAE doesn't have a relational database, instead it has Google's clustered non-relational database BigTable. This changes a lot for Django. The models change, the forms which were based on the models change. The built-in management app which was based on the previously mentioned items has to change. So, there's a project to patch all of that and get it working again - google-app-engine-django

As I mentioned above, I'm new to Python and perhaps if I weren't many of the things I'll mention below would be no big deal. But here are the issues that I've found with using google-app-engine-django so far:

  • Check it out of subversion. I think that this project is still fairly new. At the time of writing, the latest release was r52. The latest subversion release fixed at least one bug for me that had cost several hours of my time so I highly recommend getting the latest version you can.

  • You need to install a late version of Django in the django folder under your project. I didn't feel that this was made clear in the install instructions and it wasn't until I found this that I started to make some progress.

  • Use
    python manage.py shell
    To play around and experiment with your models.

  • Set the USER_EMAIL environment variable to your email address. I noticed this when trying to instantiate a model that had a line:
    created_by = db.UserProperty(auto_current_user_add=True)

    It seems that the add_current_user_add=True requires that environment variable to be set. I haven't tried deploying the app yet but I suspect that it's not an issue when running on Google's servers because there really is a concept of a current user.

Those are the crux of what I've learned so far. Looks easy but there are lots of rocky outcrops on which to get snagged.

Tuesday, July 8, 2008

Changing your Ubuntu hostname and dnsdomain name at the command line

Changing your hostname and dnsdomainname at the command line on Ubuntu is easy but you have to be careful not to lock yourself out while you're doing it.

To change it safely, follow these steps carefully. Varying from these can leave your system in an awkward state:
  1. Enter:

    sudo su

    Enter your password if/when prompted. You should at now have a ‘#’ prompt. The sudo command may stop working during this process so it’s important that you have a privileged shell already open from which to fix it.

  2. Edit the /etc/hosts file and replace the hostnames on the line starting with 127.0.1.1 with your FQDN and unqualified host name. This may look something like this:

    127.0.1.1 myhost.example.com myhost

  3. Edit the /etc/dnsdomainname file and replace the contents there (if any) with your desired domain name (eg “example.com”).

  4. Use the hostname command to set the hostname to your desired value (eg “myhost”):

    hostname myhost

  5. Edit /etc/resolv.conf and add a “search” line for your new domain name. Eg:

    search example.com

    You may also wish to remove the search line for the old domain.

  6. Verify that the sudo command works by typing:

    sudo ls

    You should get a directory listing. If you get a message saying that sudo is unable to resolve something, go back and check your work. You must be able to run sudo successfully before pressing ^D to exit from the root shell.