Category Archives for Programming/Development
Why CSS should not be used for layout
“CSS is really cool. It is useful for a lot of things. The basic idea of separating content from presentation is sound. But when it comes to layout, the design of CSS is fundamentally flawed.”
Effective Keyword Use as an SEO Ranking Factor – The Most Important SEO Factors
“Having done the research and analysis, here are the most important SEO factors, from the highest priority to the lowest.”
This is just a mini rant about MYOB. I hate MYOB. I hate it with a passion.
I remember seeing a demo of the original version of MYOB back in the late 1980s at the Apple Users’ Group in Sydney. I remember clearly the guy saying that he’d written it himself, although a quick refresher course on Wikipedia seems to suggest otherwise. Being a hard core Apple IIer at the time, my mates and I thought strange name, but its still Mac shit as we rather affectionately called it.
I didn’t realise that 20 years later I’d be using it myself. My first mistake was actually choosing MYOB to do my accounts. I was thinking that its been around a long time, so its probably the Microsoft Word of the accounting world. Wrong. My second mistake was buying the Windows version, assuming that the Windows version would be better than the Mac version, due to how many Windows MYOB users are out there. Wrong again.
MYOB has been around for around 20 years now, yet the user interface (of the Windows version) is almost unusable. I’ve been struggling with it for four years now, and every six months when an update comes out I think to myself “ahh, this will be the update where they refactor the UI”.
For those who don’t use MYOB, here’s a few of the stupid braindead things that it does. The developers should be ashamed of themselves letting a bad quality interface like this out the door.
- You cannot open more than one transaction at a time. I can’t remember invoice details off the top of my head, so I just copy the information from the previous invoice. Things like the item title, the purchase order number, and regular monthly invoice totals that never change. In MYOB you cannot open an old one and edit a new one at the same time. It’s impossible. You have to open the old one, write the details down on paper, then close that and create a new transaction, and hand enter what’s written on the paper. Unbelievable. There is absolutely no reason why I shouldn’t be able to do this.
- Window content in many windows is fixed size with scroll bars. If you make the window larger, the scrolling pane inside the window stays the same size. So you end up with a scrolling list and hundreds of pixel of blank padding between it and the window edge. Why allow me to resize it if its not going to make any difference. There’s absolutely no reaon why the window shouldn’t resize its content. That’s what a window is for!
- If you’re creating a transaction and you click on account number cell, the first cell you edit in a new transaction, then it will not let you leave that cell unless you enter a valid account number. You cannot hit Esc to exit, Delete to clear it and exit or anything else. You have to enter a valid dashed account number to get past it, and this gives you a new line in your transaction which you don’t want. Hitting tab at the end of an item line also starts a new item and puts the cursor in the account number cell, causing the same problem when all you did is accidentally tab off the end of a line. And once the new unwanted entry is created, the only way to delete it is to erase the entire transaction.
- Key presses seem to be randomly assigned across the application. Its as if different people wrote different parts of the interface, and they all had their own master interaction style guide, which was different to anyone elses.
- Finding anything is impossible. There are so many menus which give no indication of whats inside them, and finding a particular function is very difficult when there could arguably be a half dozen different menu items where it might be hiding.
- The BAS tool is just plain buggy. It runs outside of MYOB, which is braindead considering it is the only really mandatory accounting task for every Australian business. Once you’ve entered your data, you can save it, but it only saves some information. It doesn’t save your name, phone number and business name for example, things that don’t change from BAS to BAS. So if you open up the current BAS from the saved version, it won’t print or validate, because your name and phone number, of all things, are missing!
I’ve had it, I really have. I understand its a Windows application, so my expectations are already pretty low, but they don’t even meet that. I understand that Windows developer are on the whole pretty stupid and ignorant, and that Windows developers can get away with not knowing what interaction design is. But if their millions of Windows users aren’t complaining about their shit UI, then surely their test team complain every time they have to jump through hooops just to enter test data for each release?
Using MYOB is like pulling teeth. Every month I sit down and wrestle with something that hasn’t even been designed properly for its primary audience: small businesses who need to do their accounts, quickly and easily, so they can get on any do things they do better, like building their business and satisfying their customers. The most basic requirement of MYOB I would have thought, aside from it actually doing accounts. And after 20 years, these idiots still can’t get it right.
I need to change, but I don’t know what to change to. I’d prefer a Mac app, which is what I should have done from the start, but are there any good ones for Australian accounting standards?
I tend to be pretty passionate about programming language coding
conventions, and communicating best practice can be difficult at times
when there’s a plethora of bad conventions out on the interwebs. And if
universities are actually teaching conventions, then they’re not
teaching them particularly well, or perhaps by lecturers with limited
real world experience.
Consider this code fragment:
// check for aaaa. We need to use bbbb because cccc doesn't dddd if (condition1) { // optional comment on code ..code goes here } elseif (condition2) { // optional comment on code ..code goes here }
All good so far, but what if we need to comment on condition2? Not a
comment for the code contained within, but the condition itself. If code
is a narrative (as the analogy goes), then logically the code should
look like this:
// check for aaaa. We need to use bbbb because cccc doesn't dddd if (condition1) { // optional comment on code ..code goes here // check eeee next, because ffff } elseif (condition2) { // optional comment on code ..code goes here }
The code reads linearly, which is what we want, but the new comment in
column 1 breaks the readability. So how about indenting it?
// check for aaaa. We need to use bbbb because cccc doesn't dddd if (condition1) { // optional comment on code ..code goes here // check eeee next, because ffff } elseif (condition2) { // optional comment on code ..code goes here }
It reads better now from condition to condition, but our condition2
comment is now slightly out of scope and our peripheral reading. The
alternative would be to put the comment inside the code block:
// check for aaaa. We need to use bbbb because cccc doesn't dddd if (condition1) { // optional comment on code ..code goes here } elseif (condition2) { // check eeee next, because ffff // optional comment on code ..code goes here }
Now the code isn’t that readable because we get to condition2 and
there’s no explanation of it. Sure we could drop inside the condition to
read it, but it’s still outside the context of the if/else block, plus
it now runs into any comments for the code in the block, which would
mean either an intervening newline, or a combined comment that wouldn’t
read as clearly.
Remember that condition2 isn’t just a simple condition, we said that it
needed to be documented, probably because it needs to call a function or
perform some logic that’s not immediately obvious.
This is a good argument for using newlined elses:
// check for aaaa. We need to use bbbb because cccc doesn't dddd if (condition1) { // optional comment on code ..code goes here } // check eeee next, because ffff elseif (condition2) { // optional comment on code ..code goes here }
But again, the code’s starting to split apart into illegibility, and
there’s a dozen reasons why newlined conditions are bad anyway.
One argument would be that the code needs to be rewritten so that it’s
simpler. If possible, all the comments could be pulled up into a single
pre-if comment, but the further the else is from the if, the less
readable that’s going to be. If it could be split into a switch
(depending on the language), then that would be an option.
Most switch conventions I’ve seen allow case condition comments to be
above and flush with the case statement, so that would seem to be an
argument for allowing pre-elseif comments, but indented or not?
I could only find two references to this if/else comment case on the
web. The first was on Dave Hyatt’s Surfin’ Safari blog (for WebKit), in
a post by Maciej Stachowiak:
http://webkit.org/blog/25/webkit-coding-style-guidelines/
It shows a comment above an else if condition, however, the code isn’t
clear whether the “comment on else case” (sic) is a comment on the
condition, or on the code within the else. It would seem to imply the
code inside the else, and so isn’t useful to us.
The only other reference I could find was on in the Adobe ActionScript
in Flash CS3 documentation:
The example code shows exactly what we’re talking about, and shows the
case that I’ve always used these past 30 years, an indented comment above the
else/elseif.
So assuming that the convention is that all conditionals have blocks and
that block openings must be on the same line as the condition, which
convention do or would you use?
There’s an absence of information on how to get a Subversion server running on Mac OS X, and what information there is on the web gives the impression that it’s difficult. It’s not.
I used to run an application called Mac SVN Server – MAS, a standalone app with Apache and a Subversion server all built in, by Uli Kusterer. You just run it and you have an instant web based svn server. But it’s all packaged up, meaning it’s not that easy to upgrade to new versions of svn, and is pretty heavy weight considering it’s an entire Apache 2 web server.
Instead, contrary to what most web sites seem to say, you can just run svnserve, the Subversion custom server component with Mac OS X. Here’s how I did it:
- Download the Subversion package from Martin Ott’s .mac page and install it on the Mac running 10.5 (Leopard) or later, that you’re going to use as your Subversion server. This includes the svn client and the server. It’s a standard Mac package installer, so just run it and you’re done. All the binaries will end up in /usr/local/bin.
- Create a new user called “svnuser”.
- Create a directory for your repository. Use mkdir /Users/svnuser/svn, or if you need to, use sudo mkdir /Users/svnuser/svn.
- Create your repository. Use sudo svnadmin create /Users/svnuser/svn. Check the directory to make sure it has correct ownership for svnuser, and if not do a sudo chown -R /Users/svnuser/svn to set it correctly.
- If you have a repository from another Subversion server then you can simply copy it over the top of the new directory, and it will work fine, so long as the repository version is supported. For Subversion 1.5, it will also support a 1.4 repository. I copied my old 1.4 repository from MAS, and it’s worked perfectly. You may need to do another chown to make sure the ownership is correct.
The server is now installed. To run it, simply log in as svnuser and run the server with svnserve -d -r /Users/svnuser/svn. You can now access it from any client (1.4 is built into Mac OS X 10.5 so no need to install the client anywhere) by doing a standard svn check out: svn co svn://ipaddress-of-svnmac/repositorypath
But instead of running it manually, we can run it automatically when the server Mac starts up by using launchd. You can read up on Getting Started with launchd, but basically it’s the new startup process in Mac OS X 10.4 (Tiger). So, to start svnserve automatically, create the file /Library/LaunchDaemons/org.tigris.subversion.svnserve.plist, and put the following in it:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Disabled</key> <false/> <key>Label</key> <string>org.tigris.subversion.svnserve</string> <key>UserName</key> <string>svnuser</string> <key>ProgramArguments</key> <array> <string>/usr/local/bin/svnserve</string> <string>--inetd</string> <string>--root=/Users/svnuser/svn</string> </array> <key>ServiceDescription</key> <string>Subversion Standalone Server</string> <key>Sockets</key> <dict> <key>Listeners</key> <array> <dict> <key>SockFamily</key> <string>IPv4</string> <key>SockServiceName</key> <string>svn</string> <key>SockType</key> <string>stream</string> </dict> <dict> <key>SockFamily</key> <string>IPv6</string> <key>SockServiceName</key> <string>svn</string> <key>SockType</key> <string>stream</string> </dict> </array> </dict> <key>inetdCompatibility</key> <dict> <key>Wait</key> <false/> </dict> </dict> </plist>
This automatically starts the server when it boots. It also switches it from a standalone daemon to running under inetd, but it makes no real difference. There are a lot of different versions of this plist out there, but this is the only one I got to work. Unfortunately I can’t remember the site I borrowed it from. Email me if it’s you.
You’re done.
Note that the UserName property defines the user to runs svnserve as, but launchd only allows this property when it is running as root. There are two launchds on the system, one running as root (process 1), and one running as each user. The one running as root loads its plists from /Library/LaunchDaemons.
Updated from comments over time.
[..] Be aware however that the eval function is extremely unsafe. If there is the slightest chance that the server is not encoding the JSON correctly, then use the parseJSON method instead. The parseJSON method uses a regular expression to ensure that there is nothing dangerous in the text. The next edition of JavaScript will have parseJSON built in. For now, you can get parseJSON at http://www.JSON.org/json.js. [..]
[..] The right thing is frequently a monolithic piece of software, but for no reason other than that the right thing is often designed monolithically. That is, this characteristic is a happenstance. [..] The lesson to be learned from this is that it is often undesirable to go for the right thing first. It is better to get half of the right thing available so that it spreads like a virus. Once people are hooked on it, take the time to improve it to 90% of the right thing. [..]