Computing Pet Peeves?
Matthaeus asks: "I'm a 3rd-year CS student who will most likely be writing end-user applications after graduation. Naturally, I would like my apps to sell well, so I want to minimize user annoyance as much as possible. In an effort to improve my coding skills, what are Slashdot readers' biggest pet peeves when it comes to software? For example, my largest pet peeve is when a program steals the focus from another program while I'm typing. Maybe other software developers could take notice of this discussion also."
Also, programs jumping to the front 50 times while they are starting up is really annoying. For a good laugh, start Word and VC++ at the same time and watch how many times they pull the "my splash screen is on top, "no, MY splash screen is on top" crap. If I start VC++ and then start another program right afterwords, I want to use the second program until I explicitly switch away. I do not want VC++ deciding that I need to see every step of startup - "Oops, the user has switched to another app, but never got to see me update this toolbar - better jump to the front, even though I am only 12% done starting up!"
Some other things:
1.) Favor self documenting code over separate comments when possible. Comments need to be maintained separately from code. Self documenting code does not get out of sync with the documentation, and is readable anywhere you use it. For example, if you are writing a function which converts an audio frequency to a wavelength, instead of calling the function CnvtFreqToWaveLen(), and documenting the fact that it takes KHz and returns inches, call it CnvtKHzToInches(). This way, any user of the function knows in what format to supply the input and in what format the return value will be, without relying on the docs being up to date.
2.) Try to construct your variable and function names such that your code reads like English. Rather than "if(hardwareInstalledFlag)" which does not tell you the meaning of the two states of the flag, use "if(hardwareInstalled)" and make sure that hardwareInstalled is TRUE if the hardware is installed. There are few things more annoying than something like runningFlag, where 0 means running and 1 means not running. If that is the case, call it hwNotRunning so you can say, "if(hwNotRunning)".
3.) Write stable code. The common myth that software is too complex to be truly stable is total BS. We have had extremely complex systems running out in the field for several years without a power cycle. Always check your assumptions (the hardest part can be identifying the assumptions you are making). If you find yourself saying that X or Y can never occur, then test for it.
4.) Never assume that the software understands the situation better than the user. MS Word's assumption that it understands the English language better than you possibly could is one of the worst examples (I used to work at Orban - Word 97 by default would silently fix any occurances of "Orban" behind your back with NO confirmation, and change them to what you OBVIOUSLY meant to type, "organ"). Something MS does not understand is that I am the user, and I may happen to decide that I WANT to start a sentence with a lowercase letter ("cvGetStub() is a function which...."). I should not have to be an expert at reconfiguring Word just to get it to allow me to decide what I want to type.
5.) Write self teaching programs. Instead of "Could not complete the requested operation," have your dialog explain what was missing, like, "one or more tracks must be enabled for RECORD in order to enter RECORD mode."
6.) Use descriptive variable names. Even most uses of 'i' in a 'for' loop are inapropriate. Instead of 'i', call it what it is, like dbRecordNum, rather than relying on the context ("oh, this loops maxDbRecordNum times, therefore 'i' must be the record index").
7.) Don't blame the user for your bugs. Never come across as condescending, as you do not know the context in which a message is actually going to be displayed. When the user can see that they are clearly running into a bug, but the software is chastising them for doing something wrong, that is very annoying. Dave Barry talks about the ScanDisk startup message in this context. "To avoid seeing this message in the future, behave, stupid user," is really annoying when you know that the problem was directly caused by the mistakes of the same programmers who are now blaming you. Sarcastically, it should read, "to avoid seeing this message in the future, run an OS which does not arbitrarily crash after having write-cached a bunch of crap that it never bothered to write back to the hard drive." Realistically, "This error could have been caused by turning off the computer without shutting down properly, or the system may have become too unstable to shut down properly."
8.) Use the mouse cursor CONSISTENTLY to tell the user about the state of the app. If you have a mouse arrow, the program should respond to your input. If you have an hourglass cursor, the program should ignore your input, not save it up to deluge the system with when it becomes un-busy. If the program is processing user input while performing some other task (therefore it is honoring your input, but may not get to processing it right away), there is a pointer/hourglass cursor that says just that.
9.) In general, get the user feedback right. This lets the user know that he really clicked the button that he thought he did, etc.. Don't mix control and status in general (some exceptions). It should be obvious which screen elements are used to do something, and which are used to report feedback.
10.) Do not try to maintain multiple copies of the same state information; for example, if you have a dialog box with 10 settings, don't maintain the state of the dialog elements as one thing, and the state of the internal settings as another. Always maintain a master copy of the state and update everybody who cares from that. So when you open the dialog, you don't display the last state of the dialog, you recalculate the state of the dialog from the master state of the program. So if you are maintaining a field in a dialog which contains a username: a) when opening the dialog, update username from the master state. Do not try to keep the dialog state in sync with the master state as you go. b) when closing the dialog, update the master state from the contents of the dialog. c) When the username changes (as a result of the dialog or anything else), perform the appropriate action to respond to it. d) When your program needs username, get it from the master state.
Enough rambling for now....
Why is Grand Theft Auto a much more serious crime than Reckless Driving?