2013-09-23

Weebly

Over the past few years I've been looking after the website of my mother's organisation, the Hera Art Centre community which runs art classes in Newport, south Wales. Frustrated with trying to update Joomla for the nth time with an uncooperative hosting company, I looked around for something else. I found Weebly, a tool that lets you design, write, and publish a website through a WYSIWYG interface for a small fee.

I'm rather impressed with Weebly. It hits the sweet spot between configurability and constraint (for its target audience anyway). Joomla was always overkill for my mother's simple site and I never had time to make it look as good as I wanted; Weebly does that for me and as a bonus I won't have to spend time fixing it and upgrading it every few months.

2013-09-02

Code Incomplete

I'm currently reading Code Complete by Steve McConnell.

So far I'm not very impressed. I'm rather disappointed given the rave reviews and recommendations. He says a lot of sensible stuff, but it's all very basic to an experienced programmer.

There are a few howlers, like claiming Perl and Basic are acronyms.

What annoys me though is his repeated references to 7±2, the supposed magic number of items that the human mind can keep in short-term memory. Although this is a common belief, it is based on outdated science carried out when we did not understand the chunking mechanisms of memory. We now know that it is more like 4, or a bit less.

In McConnell's partial defence, the 7±2 figure is widely believed (and is more prominently mentioned on Wikipedia - at least until I change it!) However, it shows a lack of research for something he relies on so fundamentally.

Near the start of Chapter 7, McConnell uses the 7±2 figure to give an upper limit for the number of parameters to a function as 7. 7! That's hopelessly unmanageable and the sign of a very poorly written function. If he had used the correct(ish) figure of 4, or a bit less, I'd agree with him.

The main saving grace of the book is that he writes quite engagingly but new stuff is pretty sparse. I'm only 1/5th of the way through the book and I'm not sure if I'll make it to the end. 

2013-08-22

Ropey Examples in "Clean Code"

I've been (re)reading Clean Code by Robert Martin recently and I've been struck by how poor some of the code examples are. Clean Code is admittedly a classic, and few books have made me think more about the art of programming, but "Uncle Bob" seems to be better at writing about code than, well, writing code.

This is Listing 2-1, one of the first examples in the book.

This gets refactored into Listing 2-2:


This code isn't just not very good, it's actually worse than the original. What's wrong with it? Let me count the ways...

The biggie with this code is that Martin is introducing state into his program where there is no need to do so. I'm guessing Martin is not a fan of functional programming! Three of his methods set instance variables rather than returning values. This is a possible source of bugs if methods are called in the wrong order; possibly not an issue with a class this simple, but still better avoided.

More seriously, state causes issues with concurrency. What happens if another thread enters createPluralDependentMessageParts() when a previous thread is still completing make()? Martin might protest that he was writing this method as part of a single-threaded program, but who knows what that code might be used for in the future? You can't plan for every eventuality, but creating state where there's no need for it is just asking for trouble.

On the subject of that method, createPluralDependentMessageParts(): yuck! It's not the world's worst name -- it does actually say what it is literally doing -- but it's terribly awkward. It takes a little mental processing to work it out.

Next, Martin's code is not very orthogonal. What happens if we decide, for reasons of aesthetics, to add an apostrophe, or an "e", before the plural "s"? (Leaving aside the question of correctness of punctuation here!) In Martin's new code, this would have to be changed in two different methods. Not very orthogonal, and worse, the same change would have to be made: oops, we're violating the One Point of Authority principle.

Finally, Martin's code is longer than the original, both in line count and number of methods (from one to five). Usually when I've improved some code the refactored version is smaller and simpler than the original. Of course, if increasing the number of lines makes the code more correct, or easier to read, then no problem: it's a win. But if everything else is equal (or approaching equal) then more LoC is less quality. Each extra line is a possible source of bugs, extra complexity, and is more to read through or grep through.

So, how would I write the method? I'm glad you asked... well just for comparison, this is how I'd probably write it:


This is less complicated than Martin's version, easier to read (in my opinion), does not introduce state, and is more orthogonal (you can see how changing the plural form would be easy in my version). As a bonus, it is shorter than the original, and much shorter than Martin's version.

I have used the ternary operator liberally, which is not to everyone's taste, but the above all applies if you translate my version into if statements.

If you forced me to write according to Martin's philosophy (e.g. taking "one method, one action" as far as it can possibly go, putting this in its own class; all of these ideas have a fair amount of merit), then I'd come up with something like this:


Again, there's no state but the program is more modular. I'm very often in favour of breaking methods down into smaller methods but at some point you can take it a bit too far and lose the benefits. That point is in between the two code fragments I've written.

Although I don't like some of his code, the rest of Martin's book is rammed with useful tips and (thought-) provoking ideas. Just don't take it all as gospel!

2013-07-21

Getting your computer to send you emails (Linux command line + mutt and Google Apps)

It's useful to be able to send email from the command line. As well as being an occasionally useful timesaver, it's handy for automation. For example, my computer sends me an email if it fails to complete a backup for whatever reason.

There are lots of tools for this on Linux but for ease of setup I can recommend mutt + Google Apps. Assuming you have a Google Apps account (you can of course also do this with a standard GMail account):

  1. Add a user to Google Apps. For example, if your PC is called "andromeda" and your domain is "example.com", you could add a user "andromeda@example.com". Or you could add a user for a specific task such as "backup@example.com".
  2. Enable IMAP access for this user.
  3. Install mutt: "sudo apt-get install mutt".
  4. Set up mutt to access GMail (here is a nice simple guide). Note that when editing .muttrc that for Google Apps the imap username is in the form username@domain, and the smtp_url is of the form username@domain@smtp.gmail.com:587 (yep, you have two "@"s in the line, even if that does look a bit weird!) Note that you may want to set this up on your root account if you're using it to notify you of backup failures etc.
  5. echo "Test mail" | mutt -s "Chimp test" you@example.com
  6. Voila!