Thursday, April 30, 2009

i18n as second citizen in KDE

Sadly it seems that i18n (short for internationalization), that is, making your program available for non english speakers is a second citizen between KDE developers.

Programmers are treating bugs reported against i18n as non critical when effectively they are making their program unavailable for lots of users.

You may think this is a personal perception, but let's mention some examples:
* Plasma: Category names ("Application Launchers", "Astronomy") in the drop down box of the "Add Widget" dialog are untranslatable. Plasma developers excuse themselves saying i18n is not their best aptitude
* Places names are set after first use and don't follow the user locale
* KMail view names have a similar problem, can't find the bug number right now
* Places names for devices are not translatable
* Amarok: Items in the playlist layout editor are not translated
* Amarok: Default layout names are not translatable

These are just some examples, don't feel finger pointed if your app is here.

You'll notice that some of this bugs/reports have patches or suggestions on how to fix it, yet nothing has been done to fix them.

So please, don't treat i18n as second citizen, you *really* don't want to alienate so much users from your program.

Wednesday, April 29, 2009

Fix for broken hplip in Jaunty upgraded from Intrepid

If hp-toolbox fails to start for you with

Traceback (most recent call last):
File "/usr/bin/hp-toolbox", line 246, in
from ui4.devmgr5 import DevMgr5
File "/usr/share/hplip/ui4/", line 45, in
from dbus.mainloop.qt import DBusQtMainLoop
ImportError: No module named qt

The solution is purging and reinstalling the python-qt4-dbus package

Tuesday, April 21, 2009

Book reviews

This week is Saint George's Day and in Catalonia it's typical to buy/gift books so i'm commenting over the fours last books i've read.

El Códice de la Atántida (Decipher) by Stel Pavlov: A Science Fiction book that carries the tag "Best Seller in USA and Italy". Well, i'm not going to comment on these countries taste for books, but this is a book you should avoid, it's a mix of Atlants, nanobots, armies, earth to be destroyed, misc adventures and all, but at the end i just had no interest for keep reading another page, and i just finished the book because it's what i do will all books.

Los hombres que no amaban a las mujeres (The Girl with the Dragon Tattoo) by Stieg Larsson: A noir novel, you should read it if you are not scared of a book were some pages talk about crimes on women being killed by cutting their head and putting it on the fire. It's a book i got addicted fast and could not stop reading it until the end. It features kidnaped girls, assassins, investigators and more important Lisbeth Salander, best good-evil character since Wolverine.

La chica que soñaba con una cerilla y un bidón de gasolina (The Girl Who Played with Fire) by Stieg Larsson: Second part of The Girl with the Dragon Tattoo. You'll have to read it after reading the first one, the story is less macabre than in the first book but as vibrating as the first one and involves some "I'm your father" Star Wars-like scenes that even feature everywhere still impacts the reader.

La verdad (The Truth) by Terry Pratchett: It's for sure not the best Discworld novel, but still worth a read, Pratchett can create jokes from almost everything, and newspapers are not going to be an excempion. In this novel a new character is introducted William de Worde that will try to do real journalism and investigate the charges of embezzlement and attempted murder against Lord Vetinari.

So all in all, don't buy Decipher, read Stieg Larsson books if you like noir novels and The Truth is just another Discworld novel, so it's of course worth a read.

P.S: Stieg Larsson books since to have a much more catchier name in Spanish than in English, wonder which is more closed to the original swedish though.

Saturday, April 11, 2009

How to make foreach loops that don't suck

Calling values in Hashes/Maps/Sets

QHash<QString,Plasma::Meter*> meters;
foreach (Plasma::Meter *w, meters.values()) {
  w->setLabelColor(0, theme->color(Plasma::Theme::TextColor));

This code is iterating over the values of a hash and doing something over them. Everything seems ok, but it's not, it's calling values() on the hash and that's causing the creation of a temporary list with all the values of the list, effectively causing a bigger memory usage and iterating over the list twice (one to get the values and other to do something over them).

You can write something that does the same without these two problems doing

QHash<QString,Plasma::Meter*> meters;
foreach (Plasma::Meter *w, meters) {
  w->setLabelColor(0, theme->color(Plasma::Theme::TextColor));

So if you are using values() in a foreach, just remove it and your code will be instantaneously faster.

Calling keys in Hashes/Maps

QHash<QString,Plasma::SignalPlotter*> plotters;
foreach (const QString& key, plotters.keys()) {
  plotters.value(key)->setShowLabels(detail == SM::Applet::High);
  plotters.value(key)->setShowHorizontalLines(detail == SM::Applet::High);

This is calling keys() over the hash, this, as values(), means going across the container and creating a temporary list containing all the keys of the hash, that's a waste of memory when you could simply use a proper
and just iterate keys one by one.

Then it does plotters.value(key) twice, ok, accessing a value in a hash is amortized O(1) but still you are going to calculate the qHash of the string twice for no reason.

But more important, what the code is doing is actually iterate over the values, so the proper way is doing

QHash<QString,Plasma::SignalPlotter*> plotters;
foreach (Plasma::SignalPlotter *plotter, plotters) {
  plotter->setShowLabels(detail == SM::Applet::High);
  plotter->setShowHorizontalLines(detail == SM::Applet::High);

Probably in this case the net benefit is not much because probably the number of element of plotters is small, but there's no need to write inefficient code when the efficient one is as easy to write.

And of course it could be worse. If plotters was a map instead of a hash, lookup would be O(log(n)).

So if you are using keys() in a foreach, please think twice what you are doing and if you only need the value, iterate of the container and if you really need the key use a proper iterator to avoid constructing the temporary list.

Wednesday, April 01, 2009

3 years and 8 months later...

...i got my University Engineering diploma. I wonder what's the reason for taking so much for printing a paper :D

The nice swindler inside Apple

Apple has just gone a step higher in my list of companies i hate. Let me explain my last experience with them.

So i am browsing the net and see there's an iPhoneOS 3.0 pre-release, you have to register, pay something like 80€ and then you are part of the developer program and can download the SDK. So as my daywork involves working with phones i decide to register and pay with my boss credit card, something i've done lots of times already and never had any problem with.

But seems Apple is special and needs the names to match. No problem, i can accept that.

What i can not accept is they charging my boss the 80€ and then denying me the access to the developer zone because names do not match. That's what i call a swindle.

And the even more wonderful thing is the people that answers my mails don't see Apple did anything wrong and is asking me to send a fax (to US that i don't want to know how much it cost) of my and my boss ID cards with a notary sign saying it's ok (i don't know elsewhere, but in Spain a notary is NOT CHEAP). And won't return the 80€ either. Wonder if the only chance is asking the bank not to pay that 80€ :-(

That's what i get for dealing with Apple :-/