Skip to content

Le scaphandre et le papillon

Le scaphandre et le papillonJe viens de voir pour la première fois Le scaphandre et le papillon. Ce film raconte l’histoire vraie d’un homme atteint d’un locked-in syndrome, et qui ne peut plus communiquer qu’en clignant d’un oeil. Et malgré ce handicap, il parvient à écrire un livre entier, avec l’aide d’une « traductrice », qui utilise une technique mise au point par une orthophoniste.
La traductrice égrène les lettres de l’alphabet, de la plus fréquemment utilisée (E) jusqu’à la moins fréquemment utilisée (W). Lorsque la bonne lettre est atteinte, l’écrivain cligne de l’oeil, et on recommence pour la lettre suivante.
Malgré la beauté du film, je n’ai pu m’empêcher de penser que si l’un des protagonistes avait été informaticien, cette tâche dantesque aurait été bien plus rapide. Au lieu d’utiliser une liste de lettres, on utilise un arbre: on place les 26 lettres de l’alphabet dans 3 groupes (1, 2 et 3), comportant chacun 8 ou 9 lettres. Dans chaque groupe, on sépare les lettres en trois autres groupes de 2 ou trois lettres (a, b et c).
La traductrice égrène les groupes: 1, 2, 3, et l’écrivain cligne de l’oeil lorsque le bon groupe est atteint. On recommence pour le sous-groupe: a, b et c. Et ensuite pour les 2 ou trois lettres du sous-groupe. Au pire, il faut donc 9 propositions avant de tomber sur la bonne lettre. En moyenne, il doit falloir entre 3 et 4 propositions.

Suis-je un geek irrécupérable? Tous les développeurs ont-ils les mêmes réflexions en regardant un film?

J’ai testé pour vous le dernier produit de Google

Un ex-collègue, tout récent Googler à Londres, m’a fait parvenir le dernier produit de Google. Le premier qui, visiblement, n’est pas lancé en version beta : Google Cahuètes. Merci Cyril. Ca doit être la panique chez Bénénuts !

I tried git

git
It’s been a while that I wanted to try Git. At work, I’ve used CVS, Merant PVCS, MS SourceSafe and even the worst SCM ever conceived: Serena Dimensions. For the last few years, I’ve been using Subversion at work and at home, and it hasn’t been too hard. The only difficulties I’ve had with Subversion were all related to merging, and merge tracking. One of the few things you always hear about git is how branching is so easy, and how merging is a breeze. So I wanted to give git a try, even if the distributed nature of git has always seemed like a feature nobody cares about (at least in the enterprise).
First of all, I must mention the Pro Git book (freely available online), which does miracles in explaining how git works. But even with the help of the book, git has a learning curve. Fortunately, I’m not an early adopter, and git already has good support: msysgit and TortoiseGit work pretty well on Windows.
I’m only at the beginning and, unfortunately, I can’t use it on a medium-sized multi-developer project yet, but some of the aspects of Git already seem just right compared to SVN :
The logs of a git project, displaying branches and merges

  • In git, as far as I know, you can’t work on a subset of a project. A branch, a working copy, and every operation applies to the whole project. This might seem like a limitation, but it really simplifies things. For example, it avoids one of the annoying things in SVN: when someone merges a subtree, or even individual files, you end up with merge-tracking information being recorded on a whole bunch of files. Merging at the root of the project afterwards records new changes on all of these files, even if these files are not concerned by the merge. This can’t happen in Git. Another advantage is that you just have one .git directory, instead of one .svn per directory. Exporting the project tree is just a matter of copy/pasting. And there is no risk of accidentally copying the .svn files from one directory to another.
  • The fact that a commit points to its parent commit seems so simple and right, and solves so many problems, that you wonder why it hasn’t been done before. Just being able to view the branches and the merges, in no time, in the log history, is really really helpful.
  • And one of the killer features, in my humble opinion, is stashing. You’re in the middle of a change, and suddenly, you must fix an unrelated bug, as soon as possible. With SVN, my solution has often been to checkout a whole new working copy and fix the bug in this new working copy, in order not to interfere with (or loose) the unfinished work in the original working copy. With git, it’s really really simpler : you stash your unfinished work, switch to the branch where the bug must be fixed (if necessary), fix the bug, go back to the initial branch (if necessary), and unstash to find your working copy in the same state as before. Since the whole repository is available locally, this is really fast, and much more secure.

SQL strangeness

I’ve been caught several times on the same bug recently : some method takes a collection as argument, and must execute a SQL (actually, a Hibernate query) to find all foos having their ID in the given collection:

    public List<Foo> findByIds(Set<Long> ids) {
        String hql = "select foo from Foo foo where foo.id in (:ids) order by foo.bar";
        Query query = session.createQuery(hql);
        query.setParameterList("ids", ids);
        return query.list();
    }

This generates a SQL query looking like

    select f.ID, f.BAR from FOO f where f.ID in (?, ?, ?) order by f.BAR

Everything goes well, until the method is executed with an empty set as argument. The SQL query becomes invalid and a runtime exception is thrown. Could anyone tell me why the SQL standard doesn’t allow an IN without any parameter in the list? It’s not like the SQL engine couldn’t optimize the query and return nothing instantly.

By the way, Hibernate could also play a role here, and translate an no-parameter IN clause by WHERE 0 = 1. But no, you have to take care of this yourself, and rewrite the method as this:

    public List<Foo> findByIds(Set<Long> ids) {
        if (ids.isEmpty()) {
            return Collections.emptyList();
        }
        String hql = "select foo from Foo foo where foo.id in (:ids) order by foo.bar";
        Query query = session.createQuery(hql);
        query.setParameterList("ids", ids);
        return query.list();
    }

This is easy when the method is as simple as this one. But when the IN clause is embedded inside a subquery, things aren’t always as straightforward. Why an empty set is considered invalid in SQL is an mystery. But at least, SQL doesn’t force me to write

    select f.ID, f.BAR from FOO f where f.ID = ? order by f.BAR

each time the set contains only one element.

Eric Woerth et Liliane Bettencourt

Eric Woerth est attaqué de toute part en ce moment, mais ces attaques et sa défense, pour ce que j’en ai entendu, sont exclusivement axées sur son honnêteté (ou sa malhonnêteté, c’est selon), sur l’aspect légal, et sur le conflit d’intérêt qu’il y a entre ses positions de ministre, trésorier de l’UMP, et mari d’une gestionnaire de la fortune de Liliane Bettencourt.
Personnellement, c’est sur un axe moral que je l’attaquerai.
A mon sens, l’intérêt général devrait représenter l’alpha et l’omega d’un ministre du budget ou du travail. Or Eric Woerth partage la vie (et donc, j’imagine, les valeurs) d’une femme dont le métier est de mettre tout en oeuvre pour que la femme la plus riche de France, qui ne manquera jamais de rien, qui ne sait que faire de son argent tant elle en a, paie le moins possible d’impôt. Que cela aille jusqu’à l’évasion fiscale illégale, ça n’a pas vraiment d’importance : l’impôt, c’est l’intérêt général. Vouloir y échapper, c’est être contre l’intérêt général. Pour le ministre Woerth, le nombre de zéros sur le compte en banque de la femme la plus riche de France compte plus que l’intérêt général. C’est ça qui est inacceptable, et devrait forcer la démission du ministre.

What I like about linux…

What I like about Linux is that the install CDs are also live CDs.

Every once in a while, I decide to try out the latest linux distro that will conquer the desktop market. Having a live CD is really useful : you don’t have to install anything. No risk corrupting your hard disk and losing everything installed and running like a charm (under Windows). But the end result is always the same : after some time trying to get everything up and running, reading obscure forum posts with countless lines of CLI commands and config files to update, I abort, and go back to my working Windows install.

This time, I received an old NEC laptop, with only 256 Mo of RAM,  Windows XP installed on it and running, but slowly. Since my girlfriend wanted a laptop just to be able to download some pictures and take them anywhere she wants, I thought a lightweight version of Linux would be a good replacement of XP. Since this laptop is really old, hardware support would not be a problem. I downloaded the latest version of Xubuntu, supposed to be running fine with only 256Mo, and tried in on the laptop, using the live CD.

Everything ran fine until I tried to connect to my wifi network. A small icon indicated that I had no connection, although wireless networking was enabled. The problem seems to come from a button on top of the keyboard, which enables or disables the wireless network card. Pressing the button changed nothing : the led stayed off, and no networking was possible. I thus googled, already thinking : why is Linux unable to handle a network switch on a 5 year old laptop?

Anyway, I found forum posts indicating that rfswitch was perhaps the solution. So I downloaded it, put it on a USB stick, and plugged the stick into the laptop. Nothing happened. A quick look at the Removable Media parameters : yes, removable media are supposed to be mounted automatically at insertion. But nothing happened. Great!

So I plugged an ethernet cable into the laptop, and downloaded rfswitch. Look at this project. No description of what it does and how it works, and a dowload which gives you two C files, a Makefile, and a README giving no instruction whatsoever on how to install and run the « software ».

So after two hours trying to find a solution to a problem that should not exist, after having discovered that USB sticks didn’t work, after Firefox crashed twice, I decided that I would stay with Windows and wait for the next linux distro that would conquer the desktop market.

Les élèves mentent

C’est l’une des mantras du Dr. House : « les patients mentent ». En plongée, c’est la même chose : les élèves mentent.

Je reviens de mon premier stage technique de formation de N2 en tant qu’encadrant, et c’est ce que j’ai pu constater. Le premier jour était notamment dévolu au test du lestage. Une tendance générale des plongeurs est de se sur-lester. C’est particulièrement vrai des plongeurs peu expérimentés, qui maîtrisent mal leur ventilation. Deux tests classiques peuvent donc être réalisés.

Premier test : au début de la plongée, avant de s’immerger, on dégonfle les gilets, on respire normalement, et l’eau doit atteindre approximativement le milieu du masque. Si on coule ou que l’eau arrive plus haut, c’est qu’on est sur-lesté.

Deuxième test : en fin de plongée, au palier, le plongeur doit se maintenir à niveau, stab vide, en respirant normalement.

Le problème de ces deux techniques est le même. Elles visent à corriger un sur-lestage. Ce sur-lestage est provoqué par un manque, voire une absence totale, de maîtrise de la ventilation. Or ces deux techniques requièrent la même capacité du plongeur : respirer normalement dans l’eau. Posez la question à un plongeur peu expérimenté en début de stage : il vous répondra qu’il respire normalement alors qu’il est en « ventilation haute ». Les poumons sont pleins, et il ne les vide que légèrement pour respirer.

Conclusions : cet exercice doit impérativement, à mon sens, se préparer calmement avant de se mettre à l’eau, pour que l’élève puisse évaluer plus correctement son niveau de ventilation. Il doit aussi être répété au cours du stage. Le stress diminuant et l’assurance augmentant, la ventilation aura tendance à se stabiliser et à se normaliser, et de nouveaux kilos supplémentaires pourront être enlevés, pour le confort et la sécurité du plongeur et de sa palanquée.

Bienvenue au vingtième siècle

Barack Obama a promulgué aujourd’hui sa loi sur l’assurance maladie. Une avancée énorme pour les Etats-Unis, qui ne sont en retard que d’une soixantaine d’année sur les pays européens. On n’attend plus que l’abolissement de la peine de mort pour que les USA deviennent enfin une démocratie moderne.

Vu d’ici, il est proprement incompréhensible que les Etats-Unis aient mis si longtemps à créer un système de protection sociale. Le fait même que près de la moitié de la population y soit opposée est sidérant. Ces américains préfèrent-ils vraiment risquer la banqueroute au moindre incident de santé, ou enrichir les actionnaires des compagnies d’assurance privées, qui assurent un service médiocre à un coût beaucoup plus important que celui pratiqué par nos systèmes publics ? Ah, l’efficacité du privé !

Quoi qu’il en soit, il est rafraichissant de voir que les Etats-Unis avancent dans la bonne direction, alors que les libéraux qui nous gouvernent en France continuent à affaiblir le secteur public au profit des assurances et banques privées si efficaces, qui viennent de plomber l’économie mondiale.

Cobertura on Google App Engine reloaded

In a previous article, I explained how to get the code coverage data generated by Cobertura, for integrations tests of an application deployed on Google App Engine.

Cobertura just released a new version (1.9.4), which is supposed to be up to 10 times faster (kudos for that), but is not backward compatible. I thus had to rewrite the method to get the project data. Here it is.

    public Resolution flushCobertura() throws ClassNotFoundException,
                                              SecurityException,
                                              NoSuchMethodException,
                                              IllegalArgumentException,
                                              IllegalAccessException,
                                              InvocationTargetException,
                                              IOException,
                                              InstantiationException {
        String projectDataClassName = "net.sourceforge.cobertura.coveragedata.ProjectData";
        Class< ?> projectDataClass = Class.forName(projectDataClassName);
        Object projectData = projectDataClass.newInstance();

        String touchCollectorClassName = "net.sourceforge.cobertura.coveragedata.TouchCollector";
        Class< ?> touchCollectorClass = Class.forName(touchCollectorClassName);

        String methodName = "applyTouchesOnProjectData";
        java.lang.reflect.Method applyTouchesOnProjectDataMethod =
            touchCollectorClass.getDeclaredMethod(methodName, new Class[] {projectDataClass});
        applyTouchesOnProjectDataMethod.invoke(null, projectData);

        getContext().getResponse().setContentType("application/octet-stream");
        OutputStream out = getContext().getResponse().getOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(out);
        try {
            oos.writeObject(projectData);
        }
        finally {
            oos.close();
        }

        return null;
    }

Encore des élections sans moi

Les élections régionales approchent, et une fois encore, je n’irai pas voter.

Et pourquoi donc ? Parce que je n’en ai pas le droit. Et oui, j’habite en France depuis plus de neuf ans maintenant, mais je suis toujours Belge, et je n’ai donc pas le droit de voter, ce qui me fait enrager.

Tout d’abord, il faut noter que cet état de fait est, me semble-t-il, général. Je n’ai pas connaissance d’une démocratie dans le monde qui autorise ses résidents étrangers à voter. Cela inclut bien sûr la Belgique, qui souffre du même déficit démocratique que la France. Pas question de me plaindre d’un manque de réciprocité. Là n’est pas le problème.

Ça n’est pas tout à fait exact cependant. Au sein de l’Union Européenne,  les membres de l’Union ont le droit de voter dans le pays où ils résident, mais uniquement aux élections européennes, et aux élections locales (municipales en France, communales en Belgique). Certains pays (dont la Belgique, mais pas la France), accordent le droit de vote aux élections locales à tous les étrangers, même non résidents de l’UE. Cela signifie donc qu’on considère à présent qu’il est normal qu’un résident prenne part aux choix concernant les ronds-points de sa commune, ses crèches, l’école primaire que fréquente ses enfants, ses logements sociaux. En revanche, pas question pour lui d’avoir son mot à dire sur la politique de transport, la politique économique et sociale, la justice, ni même sur le collège et le lycée que fréquentent ses enfants.

Il y a donc deux classes de citoyens en France. Tous ont les mêmes devoirs (respecter la loi, payer ses impôts et ses charges sociales, répondre de ses actes devant la justice), mais tous n’ont pas les mêmes droits.

Pourquoi est-ce ainsi ? Je n’ai pas trouvé de réponse satisfaisante. L’explication est à mon avis historique: les fondements de la démocratie ont été établis lorsque la mobilité était quasi inexistante. On naissait quelque part, et on y restait jusqu’à la fin de sa vie. A l’heure où la mondialisation, l’Europe et la mobilité sont sur toutes les lèvres, il serait temps à mon avis d’accorder les principes démocratiques avec la réalité.

J’ai bon espoir cependant. Le droit de vote a fini par être accordé aux pauvres, puis aux femmes, puis aux SDF. L’histoire finira par l’accorder aux étrangers.

Aidons-là un peu, et examinons les arguments contre une telle évolution.

C’est normal que tu ne puisses pas voter. Tu n’es pas citoyen français.

Si la citoyenneté se résumait à la nationalité, je serais d’accord. Wikipedia décrit la citoyenneté par ces mots :

La citoyenneté est le fait pour une personne, pour une famille ou pour un groupe, d’être reconnu comme membre d’une cité (aujourd’hui d’un État) nourrissant un projet commun et qu’ils souhaitent y prendre une part active. La citoyenneté comporte des droits civils et politiques, et des devoirs définissant le rôle du citoyen dans la cité et face aux institutions. Au sens juridique, c’est un principe  de légitimité : un citoyen est un sujet de droit.

Il me semble que cette définition s’applique parfaitement à ma situation, hormis justement cette absence de droit de vote. Elle ne s’applique par contre pas à de nombreux Français qui ont pourtant le droit de vote, mais qui, en s’évadant fiscalement, refusent de prendre une part active au projet commun.

Pourquoi t’accorder le droit de vote alors que tu peux retourner en Belgique dès que tu veux ?

N’importe quel Français peut également aller vivre en Belgique dès qu’il le veut. Par ailleurs, refuse-t-on à un Français d’origine bretonne le droit de vote aux régionales d’Ile-de-France s’il y réside ? Pourquoi alors refuser le droit de vote à un étranger qui a choisi de vivre en France ?

Si tu veux voter en France, pourquoi ne demandes-tu pas la nationalité française ?

C’est sans doute ce que je vais finir par faire si ce droit continue à m’être refusé. Il n’en reste pas moins que le déficit démocratique reste entier. Si demain je partais à Londres, je trouverais logique de voter en Angleterre. Et j’arrêterais bien sûr de voter en France, puisque ce vote n’aurait aucune incidence sur moi. Je ne vote d’ailleurs plus en Belgique depuis que j’habite en France. Cela ne me concerne plus.