Goodbye! (And thanks for all the fish?)

Well, it’s finally time to say goodbye to the Helloworlder blog. There haven’t been many posts over the last few months (and no goods ones) so it’s time to move on to better things.

I’ll be starting a new blog soon (this time focusing almost entirely on code snippets and coding tutorials), as well as moving servers from Slicehost to Rackspace. Slicehost (really great btw) is being incorporated into Rackspace and I’m choosing to manually move my websites before the day comes when my “slice” will be automatically migrated to Rackspace’s cloud servers because it gives me an opportunity to upgrade my server’s OS to a newer version of Ubuntu in the process.

Slightly unrelated, I’m also trying out Mercurial SCM for performance and data redundancy reasons. I think it’s great that with Mercurial (or Git) you don’t need to connect to the remote server just to compare files or to update a file/entire repository to a certain revision. I’m often without an internet connection when moving around and even when the connection is good connecting to the remote server to commit/update (or in fact any operation) can be painfully slow, especially on Windows. I hear that Mercurial also does merges better so it’s probably worth checking out.

Anyway, I’ll be back soon with a new blog. For now, bye!

 

Writing Good Functions

This is a subjective post on what I consider good practices for writing functions (or methods in an OO language like Java). I’m aware that functions are OO languages are technically “methods” but I’m going to use the term “function” for simplicity.

1. Atomic Functions

It started many years ago in uni when a requirement for an assignment was that our functions must not be longer than 20 lines, or else we’d lose marks. The idea was to split up the functions if they exceeded 20 lines. Yes, keeping functions as short as possible can help to reduce confusion and aids with maintenance. But the most important thing is not the length, but to have the function do as little as possible (not a bit of this and a bit of that, but one thing). I don’t think that putting an arbitrary limit on function length is particularly helpful. By the way, in a later uni project, having “learnt” from the previous assignment I split all my functions up so each was tiny – then I lost marks for having too many small functions! Well…that’s uni for you.

2. Descriptive Function Names

Not many argue that a function signature such as incIdx(v) is helpful to anyone – it’s too cryptic. But how about getProducts()? It’s better and will suffice in a compiled language such as Java where the IDE will show the return type. However in an interpreted language such as PHP, it’s not that great unless you use PHPdoc so the IDE will tell you what it expects for the return type, otherwise you have to look in the function to see what it returns.

What if you need a function that returns a product based on the parameter you pass to it? You can pass getProductBy(name) or getProductBy(price). In a language that allows for method overloading, you should make use it of. In a language without method loading, I feel it’s fine to write multiple functions like: getProductByName(name) or getProductByPrice(price). Of course don’t forget PHPDoc. Some people might write getProductBy(value, by) and do a sequence of if/else statements inside the function and use the parameter “type” to determine what to retrieve – but I think that’s unnecessarily confusing.

3. Organizing Functions

Usually I prefer to group functions by relationship first, then by alphabetical order inside of those groups. Only doing it alphabetically isn’t really helpful unless you have a photographic memory and remember the names of each function.

4. Returning Early

I actually read about this on www.debuggable.com quite a while ago. To anyone but beginner programmers this concept is so deeply ingrained, but when I was first getting into coding years back I was confused to see 2 or more returns within a function. Then I discovered how ridiculously simple it all was – when a function encounters a return, it returns the value and the function quits at that point. It returns the value obviously, but most importantly it returns control to the code that called it. You will often have multiple returns in a function, each return within a conditional, and then you will have a default return in case none of the conditions were satisfied.

3. Replacing class variables with functions

There are times when you may want to replace class variables with functions to avoid duplicating data. I consider doing this when the value of a variable is completely dependent on 1 or more other variables. For example, if air pressure is completely dependent on the variable altitude (in reality air pressure is a function of altitude and temperature), then we could write a function getAirPressure() which calculates the air pressure based on the altitude and then returns it. 

VPS Backup Epic Fail

This blog is hosted with Slicehost (soon to be Rackspace) and they have an excellent backup and restore system. I tried it just to test it out and it did a extremely fast and perfect restore. It is essentially a bare metal restore which can be done easily through the control panel. Great thing is, it’s only $5 a month for the backup service. Unfortunately that cannot be said for all web hosts…

I have a website hosted at a VPS in Australia (I don’t name the company), and I’m paying a huge premium for backups (way more than $5). I tried to upgrade Ubuntu from 8.04 LTS to 10.04 LTS and the VPS suffered a catastrophic failure. No problems I thought, I’ll just do the bare meta restore and the site will be up and running within minutes. NOT SO. This is no Slicehost. The so-called bare metal restore was totally impossible (even for the network engineers at the web host) as it was hosted on a remote service and required a remote connection to my VPS. Errr, what?? Considering that the VPS had been damaged to the point where I could not even log in as root, how exactly was a remote connection possible? To me this defeats the entire purpose of a bare metal restore!

In any case, it’s very strange that their engineers could not restore the backup by just re-provisioning the VPS and restoring the backups with the root access that they require.  Now I’m looking for another Australian VPS – I have my eyes on the iinet VPS which looks pretty good. Hopefully their backups are actually restorable!

The lesson I learnt here is to test my backups. There’s no point having one and paying for it if it turns out that you can’t do a restore. Of course I have backups of all the data on more than 1 local computer, so nothing has been lost apart for my sanity. In addition, do not depend only on RAID10 for data safety, it will only give you protection from hardware failure but offers zero protection against intentional or unintentional data corruption.

Securing The Ship: Safeguarding Client Data on Your Notebook

I don’t think you can be too paranoid when it comes to client data. I store a lot of client information on my laptop computer and can imagine the stress it’d cause if the machine were to be stolen or misplaced – not unlikely to happen considering the mobility of a laptop.

It’s not enough just to set a login password, because that can be easily bypassed to reach the information the attacker is after. If you’re using Windows 7/Vista Enterprise/Ultimate versions on your notebook, then you should consider making use of the BitLocker encryption software. Other Windows versions do not come with BitLocker. You can instead use the freeware program TrueCrypt.

Digressing a bit I vaguely remember reading with amusement at the short-lived media frenzy and complaints from law-enforcement agencies over how the BitLocker system could be used by criminals. Disregarding all that – encryption software existed virtually since the beginning of time – using an encryption system to protect your data is very much a sensible and normal thing to do.

The Mac’s counterpart to Windows’ BitLocker is called FileVault and can be accessed through Apple icon->System Preferences->Security->FileVault. It is available with OSX Panther and later. Be aware that FileVault can only protect your Home directory, but that is no major problem.

If you are a web developer using OSX and have websites being served locally (for testing) from the /Applications/XAMPP/htdocs/ directory, as is common when using XAMPP, It is recommended by many that you instead serve it from the Sites folder in your Home directory. You just need to edit the Apache httpd.conf file to point the DocumentRoot and Directory to the new location.

Remember to choose a long and secure password (mine’s over 20 characters). Of course if you forget the password your data practically ceases to exist :-) Finally, get into the habit of shutting down your computer entirely instead of placing it on sleep, as there is an attack vector that can exploit this situation. This applies to both BitLocker and FileVault.

Converting FLA to HTML with Adobe Wallaby

I just tried out the Adobe Wallaby Technology preview and while its functionality is still extremely limited, it’s none the less exciting. You supply an FLA file to the program, and it spits out the HTML, Javascript, CSS and SVG documents. I tested it with a non-animated FLA file with 10 layers.

After the conversion is complete, each layer in the Flash timeline becomes a separate SVG document, and the final result is assembled using the automatically generated HTML, CSS and Javascript code. There are even automatically generated comments in the HTML output so you can easily identify which svg belonged to which Flash timeline layer. Currently only webkit browsers (e.g. Chrome but not Firefox or IE) supports the output from Wallaby.

This tech preview might have brought back some discussion on the misguided Flash vs. HTML5 non-debate, including the equally misguided Flash technology bashing. However, there remains some sensible discussion on this complex topic.

In any case, it would be really silly not to start using the smorgasbord of HTML5 tags right now. There is very little doubt, even among Flash supporters that HTML5 will become the dominant standard for video and multimedia in the years to come. However I still agree with Adobe’s position that HTML5′s rise does not – and is perhaps unable – to come at the total exclusion of the Flash Player and the wider Flash technology platform.

Flash AS3 Externally Load Multiple Images And Display In Order

Let’s say you want to load 5 images into your Flash app externally, and display them in the same order you loaded them. In AS3 loading external assets happens asychronously, so just because you started a load first doesn’t mean it will be the first to finish. So, if you want to display your images in the order that you load them, you’ll need to do a little work. Here’s a way of doing it:

package  {

	import flash.display.MovieClip;
	import flash.net.URLLoader
	import flash.net.URLRequest
	import flash.events.*;
	import flash.errors.*;
	import flash.display.Loader;

	public class OrderedLoaderSpike extends MovieClip {

		private var urlsArray:Array;

		public function OrderedLoaderSpike() {

			// provide your own images
			urlsArray = new Array();
			urlsArray.push("1.jpg");
			urlsArray.push("2.jpg");
			urlsArray.push("3.jpg");
			urlsArray.push("4.jpg");
			urlsArray.push("5.jpg");
			startLoading();
		}

		private function startLoading()
		{
			var numToLoad:Number = urlsArray.length;
			var numLoaded:Number = 0;
			var currentYOffset:Number = 0;
			var imgArray:Array = new Array();
			var imgIdx:Number = 0;

			for(var i=0; i < urlsArray.length; i++){
				var imageHolder:ImageHolder = new ImageHolder(imgIdx);
				imgArray.push(imageHolder);
				imgIdx++;

				var tempLdr = new Loader();
				var imgReq:URLRequest = new URLRequest(urlsArray[i]);
				tempLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete(imageHolder) );
				tempLdr.load(imgReq);
			}

			function onComplete(imageHolder:ImageHolder)
			{
				return function(e:Event)
				{
					var img:Loader = e.target.loader;
					imageHolder.setLoader(img);
					numLoaded++;

					if(numLoaded == numToLoad)
					{
						for(var i=0;i < imgArray.length; i++)
						{
							for(var j=0; j < imgArray.length;j++)
							{
								if(i == imgArray[j].getIdx())
								{
									addChild(imgArray[j].getLoader());
									imgArray[j].getLoader().y = currentYOffset;
									currentYOffset += imgArray[j].getLoader().height + 20;
								}
							}
						}
					}
				};
			}
		}
	}
}

package  {

	import flash.display.Loader;

	public class ImageHolder {

		private var idx:Number;
		private var loader:Loader;

		public function ImageHolder(theIdx:Number) {
			loader = null;
			idx = theIdx;
		}

		public function setLoader(v:Loader)
		{
			loader = v;
		}

		public function getLoader():Loader
		{
			return loader;
		}

		public function getIdx():Number
		{
			return idx;
		}

	}

}

Another (perhaps simpler) way is to not load the images in a loop at all, and instead have an array with the URL of the images to load. Then, you start to load the first image in a function, let’s call it loadExternalImage(). Once the load completes, you call loadExternalImage() again to load the next URL in the array, and so on, until you’ve traversed the entire array. Your choice really.

Zend_Form Check For Existing Email Address In Database

If you’re coding a registration form you will either want to check if a username or an email address is already present in the database. This is very easy to do, assuming you are familiar with using Zend_Form:

 $validator = new Zend_Validate_Db_NoRecordExists('user', 'email'); // user is the table name, and email is the column
        $validator->setMessage("Error: The e-mail has already been registered"); // set your own error message
        $this->addElement('text', 'email', array(
            'label' => 'E-mail Address',
            'required' => true,
            'filters' => array('StringTrim'),
            'validators' => array(
                'EmailAddress',
                $validator
            )
        ));

That’s all. NOTE: This might be obvious but you cannot chain the setMessage(…) function directly to the end of new Zend_Validate_Db_NoRecordExists(‘user’, ‘email’);

If you are unfamiliar Zend_Form, here’s a full example:


/* application/forms/Register.php */

class Default_Form_Register extends Zend_Form {

public function init($options = null) {
$this->setMethod('post');

$this->addElement('text', 'firstName', array(
'label' => 'First Name',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
array('validator' => 'StringLength', 'options' => array(1, 255))
)
));

$this->addElement('text', 'lastName', array(
'label' => 'Last Name',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
array('validator' => 'StringLength', 'options' => array(1, 255))
)
));

$validator = new Zend_Validate_Db_NoRecordExists('user', 'email');
$validator->setMessage("Error: The e-mail has already been registered");
$this->addElement('text', 'email', array(
'label' => 'E-mail Address',
'required' => true,
'filters' => array('StringTrim'),
'validators' => array(
'EmailAddress',
$validator
)
));

$password = $this->addElement('password', 'password', array(
'filters' => array('StringTrim'),
'validators' => array(
array('StringLength', false, array(8, 20)),
),
'required' => true,
'label' => 'Password',
'id' => 'password'
));

$register = $this->addElement('submit', 'register', array(
'required' => false,
'ignore' => true,
'label' => 'Register Now',
));

}

WD Caviar Black 1TB WD1002FAEX Noise Levels

I’m currently using a WD Caviar Black 1TB WD1002FAEX with my new rig. I also have a Seagate Barracuda 7200.12 1TB that’s sitting on the shelf as a backup drive that I haven’t broke out from the packaging yet. I am a pretty noise sensitive person, but I chose to install the WD Caviar Black despite reports of it being noisy as I was overpowered by curiosity – how loud is this thing really? And supposedly the performance of the Caviar Black has a bit of an edge over the Barracuda (though I’m not sure how significant it is).

There are lots of objective tests based on sound measurement by dB measuring equipment. But when it comes to sound objective tests are almost completely pointless – you can read a thesis on sound theory and still not understand if the noise generated by an HDD is within your tolerable range. You have to hear the thing for yourself. And I have.

First of all, there is NO palpable vibration – nothing. There is also NO loud whirring/ramping up like an optical drive. It is silent in those regards – at least overpowered by my 23cm slow spinning exhaust fan on top of my Thermaltake v9 case – which is pretty quiet anyway.

The type of noise I can distinguish coming from the Caviar Black is the rapid low-pitched “chirp-chirp-chirp” sound it makes when accessing data. In my opinion, it isn’t really that annoying, and I wouldn’t call it loud, just clearly audible. Of course, you’ll need to buy and use the drive to make up your own mind about this, don’t waste your time looking at dB graphs.

As for the temperature, I haven’t as of yet observed anything above 29 degrees Celcius using HD Tune 2.5.5, which is pretty cool, so I’m a bit befuddled with others saying the hard-drive gets to 47 degrees C (maybe in summer?). But then, I also have a front intake fan on my case; the HDD sits right behind it enjoying the breeze. This LED fan comes installed with the Thermaltake v9 case (I have the BlackX edition). If you’re doing a mid to high-end build it’s probably not the best idea to buy the cheapest case you can find. Even if you’re not overclocking give yourself peace of mind by spending an extra bit of dough on a case with good airflow. Poor cases may also be typified by very loud fans and poor HDD mounts causing unnecessary vibration.

I have the Seagate Barracuda 7200.12 1TB sitting ready, but I have no desire to swap it with the Caviar Black just now. If and when I muster up the effort to do that, I’ll write up a comparison of the 2 drives in the noise department as well as performance.

EDIT: Another computer in my house uses a WD Caviar Green HDD; the Caviar Green is the low noise, low temperature and eco-friendly option in the WD HDD lineup. Surprisingly HDD Tune gives me 33 degrees C at idle, more than my Caviar Black. Note that the case has no front intake so there is no active HDD cooling.

Slow Computer? Try Upgrading The HDD

There’s one thing I don’t understand – why is there so incredibly little emphasis put on the hard-drive when it comes to computer performance? It doesn’t matter if you’ve got an i7 2600K and 12GB of RAM, if you have a $50 hard-drive with slow read and write speeds (yes it matters) you’re still going to get unnecessary slow downs when you’re working on the computer, because the HDD is being a bottleneck. So why spend all those thousands of dollars on top end gear if you’re just going to choke yourself with a crappy HDD? It doesn’t make any sense. If you’re going low-end then go all low end components. If you’re going mid-end then go all mid-end, etc.

I do lots of development and design work on my PC and yes the HDD light is blinking like mad a lot of the time. E.g. with SVN commits there are thousands or tens of thousands of .svn files to commit. Yes, the HDD really does have to read those files, because your graphics card won’t do it. Then there’s constant compiling, opening and closing large applications like Photoshop and Flash, etc etc. And let’s not forget the more basic stuff like copying, moving and deleting lots of files which can take a long time on a good HDD, and maybe you can grow a beard waiting for something to finish copying on a cheap HDD. A crap HDD basically says “f*** you” to the expensive components you paid hard earned cash for.

Years Later, Back To Java Programming

The first time I remember programming in Java was at Swinburne TAFE in 2004 when I was 18 and full of energy and enthusiastic about programming (oh I’m still enthusiastic it’s just that University assignments kind of killed a lot of that youthful energy). Sometimes those fun TAFE classes still seem like yesterday. Going to bars and movies between classes, etc. It’s sad how quickly time goes. Sentiments aside, one of the things I remember learning was that you don’t use == to compare strings. I didn’t know why, nor did I really care, but it was a rule: always use the equals() method instead. Now I know that == compares whether 2 references point to the same object (assuming we’re not testing primitive values and Strings are NOT primitive values). equals() actually checks to see if the 2 strings have the same characters in the same sequence.

Then a few days ago I started programming in Java again, because I wanted to try developing for Android. I need to use Text To Speech so I was reading the Android developer’s manual. One example stated:

public void onUtteranceCompleted(String uttId) {
    if (uttId == "end of wakeup message ID") {
        playAnnoyingMusic();
    }
}

SOURCE: http://developer.android.com/resources/articles/tts.html

Vaguely thinking back to my first experiences with Java, I thought that example was wrong, but I trusted it anyway and thought I just misremembered what the teacher said…after all it was so many years ago and could an official doc make such a fundamental mistake? Stupidly I just copied and pasted that example into my program and assumed it was correct. I spent over an hour changing other bits and pieces of code, to no avail. Then finally…changing == to equals() was the answer! Lesson: Learn to trust yourself.

I wish I could comment on the mistake but the page doesn’t allow you to leave comments like many other documentation sites. Surely this is going to give some others a headache too!