How to: Tell your users they are not worth your time
If you're a programmer, you're writing programs for your users. You are there performing a service for your users, not the other way around. Here's an excellent way to insult your users by letting them know that they are not worth one minute of your time:
print "Now showing $n item(s)";
The parenthetical (s) as a shorthand for saying "This could be singular or plural and still let me off the hook" is a throwback to times before computers, when people worked on paper forms. It is now unacceptable.
my $s = ($n == 1) ? '' : 's'; print "Now showing $n item$s";
Is it a pain to write that out? Hardly. Maybe a twinge of discomfort at worst. However, to take the shortcut of (s) says that you are so lazy as a programmer that you don't care about the user, and it says that every single time the user sees that message.
The module Lingua::EN::Inflect can help with this. It provides the subroutine PL_N() which takes a word and a quantity and returns the word as a plural when the quantity is not 1, and in singular form when the quantity is 1. E.g. (from the docs):
print "I saw $N ", PL_N('animal',$N), "\n";
Output when $N == 1: I saw 1 animal
Output when $N == 10: I saw 10 animals
It even handles words with irregular plurals like "sheep" or "woman".
I definitely agree with you that the small user experience tweaks are worthwhile and I would never deploy a program without them (well, without the mostly trivial ones).
I have read that Russian has extremely complicated rules for plurals--WKA's advice sounds good in that case.
Or how about this one-liner, which I saw somewhere in perldoc:
printf( "Now showing %d item%s", $x, ( $x > 1 ? 's' : '' ) );
Ambrose: You have match $x == 1, not $x > 1. In the case of $x == 0, you still want the "s".
0 items
1 item
2 items
...
It's not singular & plural so much as singular & everything else.
Yes, it gets much more complicated when you have to consider localization. :-)
Otherwise, I really like this point. It's good to take that tiny extra time to get the polish that makes the difference between a good program and a great program.
-Max
I usually use something like this:
my $items = ($n == 1) ? 'item' : 'items'; print "Now showing $n $items";It seems to me that the cost of the repeated string is very small, and is outweighed by the improved readability, but maybe the readability gain is minimal too.
I think the improvement is clearer in a case like this:
my $ies = ($n == 1) ? 'y' : 'ies'; print "Now showing $n entr$ies";Where my version would be:
my $entries = ($n == 1) ? 'entry' : 'entries'; print "Now showing $n $entries";In general, I like strings to contain whole entities, rather than partial entities whenever, reasonable.
Good point. Although thinking about it, isn't "now showing zero items" just another example of the same negative user experience we're trying to avoid?
I did think about it after posting and I think if the number of items found was zero I'd branch to a whole other "no items found, why not try [some other things]?" screen.
Whenever I build a tool for techie users, I simply do not care about these things. They probably won't either. They're using my program because it solves a problem, not because I'm so polite to the user.
When building something for non-techie users, indeed you better pay some attention to this. Although it increases complexity and maintenance overhead, especially if you use localization and/or templating, I still think it's worth it.
The problem can be avoided by formatting differently. "Results: 1" is something you may get away with in certain contexts, and IMHO improves readability anyway, if you have multiple variables and the screen space to lay them out vertically.