Affichage des articles dont le libellé est programming. Afficher tous les articles
Affichage des articles dont le libellé est programming. Afficher tous les articles

mardi, septembre 01, 2009

J'avions bien dit que ça ne prendrait qu'un (long) week-end! Mon système de documentation est maintenant fonctionnel.



Told you it would be just a matter for a (long) week-end! My documentation system is now up and running.

samedi, août 22, 2009

J'étais une fois de plus en train de farfouiller dans mon épaisse pile de papelards plus ou moins importants, rêvant d'une fonction "recherche" qui fonctionnerait sur le bois. Et encore, maintenant que de plus en plus de factures sont envoyées électroniquement, on ne peut même pas tout mettre au même endroit à moins de faire chauffer l'imprimante, ce qui réduit fortement l'intérêt écologique de la manoeuvre. Sûrement, il y a une manière moins pénible de retrouver un document! Après tout, classifier et rechercher, c'est ce que les ordinateurs savent faire le mieux, non?

Il y a plein de solutions commerciales, mais quelle est la difficulté de se monter ça chez soi pour pas un rond?

A y regarder de plus près, probablement pas grand chose. Toutes les briques sont déjà là:
- Tout d'abord, le document, disons un PDF, soit scanné (gscan2pdf), soit directement reçu.
- Ensuite, le contenu du document (l'on doit pouvoir chercher via le texte). Si c'est du scan, gocr en extraira le texte. La qualité est décevante, mais dans notre cas, c'est amplement suffisant. Si l'on a le pdf d'origine, un bête pdftotext fera l'affaire.
- Maintenant, l'on peut enregistrer notre document dans une base de données. Prenons Postgresql, le document en lui-même dans une colonne, le contenu sous une forme qui permettra le "Full Text Search". Rajoutons quelques tags pour faire bonne mesure, histoire de différencier une facture d'eau de son relevé de cotisations retraite.

Et voilà, un système de documentation! Rajoutons le support pour de plus nombreux types de document, peut-être un aperçu, un chiffrage des données (pas si évident si l'on veux également chiffrer les index de Full Text Search), et enfin une interface graphique intégrée, et nous y voilà. Donnez moi deux week-ends, et je ponds ça!


I was once again deep under my heavy pile of more or less important administrative documents, bills and all, dreaming of a "search" function that would work on wood. That would be notwithstanding the numerous bills that are now being sent electronically, preventing from at least trying to consolidate the stuff, unless you start printing everything, defeating the ecological purpose. Surely, there is a less painful way of finding a document. After all, classifying and searching, that is what computers are good at, isn't it?

There are many commercial solutions, but how hard is it to build an amateur system for free?

Looking closely, it does not look that hard. All the bricks are already there:
- First of all, the document, let's say a PDF, either scanned, or received through an e-mail.
- Then, the contents of the document. If it's a scan, gocr will extract the text. Quality is disappointing, but good enough for our purpose. If we have the original PDF, a simple pdftotext will do the job.
- Now, we can save our document in a database. Let's take Postgresql, with the document in a column, and the contents under a format that will allow for full text search in another one. Let's add a simple tagging system, so that we can differentiate a water bill from a pension summary.

And here we are, a documentation system! Let's add support for more numerous document systems, maybe thumbnails, encrypted data (not that easy to encrypt the full search text index, actually!), and an integrated graphical user interface, and we're in. Give me two week-ends, and I make it!

mardi, septembre 02, 2008

Je cross

Depuis un certain temps, je maintiens un autre blog, plus concentré sur la programmation et les logiciels. Maintenant que la chose commence à avoir de la substance, j'ai rajouté un lien dans la section appropriée,

mercredi, août 20, 2008

Pour les quelques-uns d'entre vous qui ont jamais eu à créer une classe avec Visual Studio, vous savez que MS a la fâcheuse habitude de préfixer ses classes avec un C, du type CSocket ou CFrame, et que donc lorsque l'on crée une classe CSocket, par exemple, l'éditeur créé alors le fichier Socket.h et Socket.cpp.

Tout se gâte lorsque l'on créé la classe Canard, pour laquelle l'éditeur va créer les fichiers anard.h et anard.cpp...

Eh bien, c'est réparé! Dans VS 2005, La classe Canard créé bien les fichiers Canard.h et Canard.cpp. D'où vient ce miracle?

Autant la classe Canard donne le fichier Canard, autant la classe CAnard donne le fichier Anard. VS regarde donc la casse du deuxième caractère pour se décider. Voilà qui sent, pour une fois, les développeurs qui ont écouté leurs utilisateurs, et qui débarquent avec une solution qui contentera tout le monde. Ouf!


For the few of you who ever had to create a new class in Visual Studio, you know that Microsoft has the annoying habit of prefixing their classes with a C, like for example CSocket or CFrame, and that therefore when creating a class through the new class interface, creating the CSocket class will generate the Socket.h and the Socket.cpp files.

Everything goes down the drain when you try to create the class Cook, for which the editor will generate the files ook.h and ook.cpp.

Well, that is very much a solved problem! In VS 2005, the Cook class generates the Cook.h and the Cook.cpp files!

Although the Cook class generates Cook files, the COok class generates Ook files. VS looks at the case of the second character to decide which situation it should be. That feels like, for once, developers listening to their users, and come up with the solution that will make everyone happy. Cool!

lundi, juillet 28, 2008

Disclaimeur: mes statistiques sont tout sauf scientifiques, donc prenez mes chiffres avec des pincettes géantes.

Cela faisait un certain temps que je ne m'étais pas plongé dans la comparaison des langages les plus demandés par l'industrie. Voici donc un beau diagramme du nombre de jobs proposés à Londres dans les 7 derniers jours par langage, sur deux sites majeurs, l'un plus généraliste, et l'autre plus orienté vers la finance.

La grosse surprise, c'est de voir que le C++, largement mené par Java et C# chez les généralistes, se rattrape particulièrement bien dans le monde de la finance. Est-ce parce que le pricing se fait principalement dans ce langage? Ou qu'il y a plus de projets de maintenance, avec de gros systèmes développés dans les années 90?

Toujours est-il que en ce qui concerne les langages Web, la finance n'en veux pas (ce qui est plutôt étrange, mais bon, passons). Et enfin, au passage, Ruby fait une maigre percée, mais uniquement on-rails. Chez les généralistes, l'Asp se taille la part du lion.




Disclaimer: my stats are everything but scientific, so take them with a handful of salt

It had been a long time I did not regenerate my comparisons of the languages most being sought after by the industry. Therefore, here is a pretty diagram of the number of jobs advertised for London in the last 7 days, classified by language, and taken on two major job websites, one more generalist, the other more oriented toward finance.

The big surprise is to see C++, lagging behind Java and C# for the generalists, is actually in front for finance. Is it because most pricing systems are written in C++? Or that there are more legacy systems in finance written in the 90s?

Anyway, for web languages, it seems that finance could not care less (which sounds strange, by the way). And finally, Ruby is vaguely showing, but only in its "on rails" version. Among the generalists, ASP takes the share of the lion.

samedi, mars 08, 2008

Hop, je ressors une vieillerie, mais cette fois-ci en vidéo! Cela m'a donné l'occasion de tester d'une part "istanbul", pour capturer la vidéo, et d'autre part les capacités d'affichage du blog en lui-même.




I bring back some old stuff, but this time in video! It first gave me an opportunity to test "istanbul", to capture the video, but also the video capabilities of the blog.

lundi, février 18, 2008

Chris Okasaki, auteur du très bon Purely Functional Data Structures, tient un blog très intéressant ici. J'encourage vivement toute personne un tant soit peu intéressée par les langages de programmation à aller y faire un tour de temps en temps.


Chris Okasaki, author of the very good Purely Functional Data Structures, is writing a blog here. I encourage any one interested in programming languages to sneak there times to times.

jeudi, décembre 13, 2007

Are you pluggable?

C'est le nouveau buzzword (marrant, le mot "buzzword" est lui-même un buzzword): pluggable. Si votre architecture est pluggable, elle regarde clairement vers l'avenir!

Moi, ça m'énerve (bon, j'avoue, il y a beaucoup de choses qui m'énervent). C'est typiquement le mot utilisé par un manager qui veut vendre sa solution: "Nan, mais c'est pluggable!". Dans le monde merveilleux du middle management, tout est pluggable. Les applications, bien sûr, mais également le petit personnel (également appelé "ressource"). Par exemple, aujourd'hui, alors que je me remettais d'une longue soirée à batailler avec une release récalcitrante, comme tout remerciement, on m'a pluggé sur un autre projet à faire des fiches Excel pour comparer des nombres dont je suis de toutes façons déjà persuadé qu'ils sont faux. Pluggés du monde entier, unissez-vous!

La photo du précédent post est une omelette qui m'avait frappé par sa propension à agir comme un volcan sous-marin inversé: j'ai retrouvé dans l'oeuf au contact de l'huile chaude la même structure en coussins, qui se gonflent et finissent par s'ouvrir et immédiatement se re-figer, que dans les images de lave dans l'eau que l'on peut admirer dans le documentaire du dimanche après-midi.


That's the new buzzword (funny how "buzzword" is itself a buzzword): pluggable. If your architecture is pluggable, you are definitely looking into the way of the future.

It gets on my nerves (okay, many things get on my nerves). It's typically the word of the manager who wants to sell you his solution: "No, but it's pluggable!". In the wonderful world of the middle management, everything is pluggable. Applications, of course, but also people (also known as "resources"). For example, today, I was just recovering from an evening battling with a painful release, and as a thanks for the work done, I was plugged on another project to write Excel spreadsheets to compare some numbers which I already knew would not match. Plugged from the world, do unite!

The picture in the previous post is an omelette that struck me as acting as an inversed submarine volcano: I found the same behavour in the egg in contact with hot oil, creating a pillow that eventually burst open and immediately clot again in the oil, than on the images of underwater lava that one can see on Sunday afternoon documentaries.

mardi, décembre 11, 2007

Une heure entière d'insomnie, qu'il m'a fallu pour résoudre le problème des 12 poids dont l'un est légèrement différent des autres, à trouver avec 3 pesées. Heureusement qu'à force de chercher, j'ai enfin trouvé, sinon j'aurais passé une nuit blanche (déjà que je n'étais pas frais ce matin...).

J'ai également redoublé d'efforts sur les problèmes du Projet Euler, d'une part parce que c'est intéressant, et d'autre part parce que je me suis fait méchamment distancer par un des commentateurs de ce blog :)

Est-ce qu'il va me rester du temps pour travailler?




An entire hour of insomnia was necessary for me to solve the problem of the 12 weights, among which one is slightly off the others, to find with 3 runs on a balance. Thankfully, I eventually found the solution, otherwise I would have spent the night thinking about it (and I wasn't too fresh this morning anyway...).

I also doubled my efforts on the problems of Project Euler, first because it's interesting, and second because I was left in the dust by one of the commenters of this blog :)

Will there be any time left for me to do some actual work?

jeudi, novembre 01, 2007

Depuis quelques semaines, je me suis mis aux problèmes du projet Euler, site regroupant 165 (pour le moment) problèmes associant mathématiques et informatique, le but étant de résoudre un problème généralement algorithmique de la manière la plus efficace possible. J'ai résolu les problèmes 1 à 10, et je pense avoir enfin trouvé la méthode pour le problème 12. Pour l'instant, au vu des solutions proposées par les autres participants, je serais plutôt dans la catégorie "semi-bourrin".


Since a few weeks I have started on the problems from project Euler, website regrouping about 165 problems (so far) associating maths and computing, the goal being to resolve an algorithmic problem as efficiently as possible. For the moment, I have solved problems 1 to 10, and I believe that I have the right method for problem 12. In regard to solutions proposed by others, I would be in the "half-brute" category.

jeudi, septembre 20, 2007

Est-ce que vous aimez la "Task-list" de Visual Studio? Moi, je la déteste. Cette horreur sans nom a le don pour me mettre en boule. J'imagine bien qu'elle puisse parfois être utile, mais elle a surtout un très gros défaut lorsque l'on programme en C++: elle surgit à chaque compilation pour lister les erreurs de compilation. Et ça, c'est moche.

Problème numéro 1: il est difficile de savoir d'où sort l'erreur. Je veux pouvoir très facilement savoir quel fichier était en train de compiler, mais également s'il s'agissait d'un fichier d'inclusion, et dans ce cas quel était le fichier de base. D'ailleurs, je commence très souvent à lire le message d'erreur alors que la compilation n'est pas finie. Ce n'est pas pour que tout d'un coup il me soit caché au profit du tas d'immondices s'autoproclamant Task List!

Problème numéro 2: Un message d'erreur, en C++, c'est long. Surtout si l'on combine STL, boost, et ses propres templates. Or, l'horrible Task List s'évertue à mettre tout sur une ligne, et à tronquer ce qui vient après. Résultat, on ne voit rien.

Problème numéro 3: Cette cochonne de task list réordonne parfois les erreurs! On perd inutilement du temps à essayer de comprendre pourquoi un bout de code foire, alors qu'il suffisait de corriger l'erreur précédente pour que tout fonctionne. Quelle idée saugrenue.

Je vais donc oeuvrer pour le bien public, et rappeler qu'il existe une solution imparable à ce problème. Ouvrez bien grand vos esgourdes!

Tools -> Options -> Projects and Solutions -> décocher "Show Task List window if build finishes with errors"


Do you like the Task List of Visual Studio? I personally hate it. This unnamed horror unnerves me to the highest point. I imagine that it can sometimes be useful, but it has a major flaw when coding in C++: it jumps out on the programmer's face to list compile errors. And that's bad.

Problem number 1: it's very difficult to know where the error comes from. When something fails, I want to know where, but also, if for example it is in a header file, what was the target cpp file in the first place. By the way, I very often start reading the error message before the compilation finishes. And in the middle of my reading, the steaming pile of tasks jumps over.

Problem number 2: An error message, in C++, can be very long. Especially when combining STL, Boost, and one's own templates. And this stupid thing keeps truncating errors, hiding useful information, and making it difficult to access.

Problem number 3: This silly thing sometimes reorder error messages! One can loose time stupidly by trying to fix an error that does not even exist, as it may be solved with the first problem, but with the reordering, good luck to find out which line was causing the mess in the first place. What a strange idea.

I will therefore act for the greater good, and remind everyone that there is a solution to this. Open your ears!

Tools -> Options -> Projects and Solutions -> uncheck "Show Task List window if build finishes with errors"

vendredi, juin 01, 2007

Allez, encore une image pour la route! Après tout, mon blog m'autorise à uploader jusqu'à 1 gig d'images... Ceci est représente donc une octave de bruit de Perlin, avec les normales déduites des faces, ce qui donne cet aspect "carrelage de cuisine sous ectasy". Mon but, c'est d'arriver à corriger ma fonction qui renvoie les normales procédurales sur un bruit de Perlin, et qui devrait donc donner des résultats bien meilleurs. Ça fait plusieurs jours que je suis coincé...




Another image for the road! After all, my blog authorizes me to upload up to 1 gig of images... This shows an octave of Perlin noise, with normals deducted from the faces, which gives this "kitchen tiles under ecstasy" feeling. My goal is to debug my function that returns the normals over a Perlin noise, and that should give much better results. I've been struggling with that for a few days...

lundi, mai 28, 2007

Une petite image de plus pour la route! Pour une fois, au lieu de calculer bêtement les normales par rapport aux faces (une moyenne plus ou moins heureuse des normales aux 4 faces sur le vertex), j'utilise directement le gradient de ma fonction génératrice (ça fait toujours du bien de se calculer un gradient à la main). De plus en plus, j'essaie d'avoir une approche complètement procédurale, à la recherche d'images moins variées, peut-être, mais beaucoup moins imparfaites. Voici le résultat, sur une grille de 250 000 polygones.




Another small image gor the road! For once, instead of calculating simply the normals from the faces (as an average of the normals for the 4 faces generated from a vertex), I directly use the gradient of my generating function (it's always a good refreshment to calculate a gradient by hand). More and more, I try to have a completely procedural approach, looking for images that are less varied, maybe, but much less imperfect too. Here is the result, on a 250 000 polygons grid.

dimanche, mai 13, 2007

Un petit update de mon graphe de scènes: sphère texturée!




A small update from my scene graph: textured sphere!

lundi, mai 07, 2007

Voilà quelques captures du projet sur lequel je codouille dans mes moments de lassitude. Il s'agit d'un graphe de scènes, semblable par exemple à Open Scene Graph. La différence vient de ce que le mien est un graphe fonctionnel pur, écrit en Ocaml.

Fonctionnel pur, c'est à dire que chacun des nodes du graphe est immutable (pour ceux que le C++ parle plus, cela revient à n'avoir que des classes aux méthodes et attributs constants). Cela veut dire également qu'à chaque changement, il faut reconstruire le graphe. Cela peut sembler vaguement inefficace, mais c'est en tous cas très pratique à programmer. La garantie, une fois que le noeud a été crée, qu'il ne changera pas, permet une forte réutilisation du graphe. De plus, il y a un noeud spécial qui permet de placer les noeuds fils dans une liste compilée, afin d'accélérer le rendu. Enfin, (mais ce n'est pas lié à la contrainte de fonctionnalité pure), le GC d'Ocaml aide beaucoup à ne pas se soucier des problèmes mémoire. Pour comparaison, le compteur de références d'Open Scene Graph est un poil compliqué à utiliser au premier abord, et il est trop facile de faire des erreurs.

On verra bien ce que cela donnera et si j'arriverai à en faire quelque chose!






Here are a few screen captures of the project on which I am vaguely working now at my idle time. This is a scene graph, similar for example to Open Scene Graph. The difference is that mine is a purely functional graph written in Ocaml.

Purely functional means that each node of the graph is immutable (for those more on the C++ side, it would be more or less equivalent to have classes with only constant methods and attributes). It means that for each change of the scene, the graph needs to be reconstructed. It can seem inefficient, but it is very easy to program with such a data structure. The guarantee that once a node has been created, it will not change during its lifetime, is extremely useful for reusing entire pieces of the graph. In addition to that, I've created a node that creates a compiled list of the children nodes, to accelerate rendering. Finally (but that's not related to the purely functional side of the things), Ocaml's GC helps a lot for all the complex memory issues that arise with a complex graph. By comparison, the reference counter used in Open Scene Graph is slightly complicated to understand, and quite error-prone.

We'll see how it will evolve, and if I'll be able to do something out of this!

vendredi, avril 27, 2007

Je lis de bas en haut.

Enfin, pas exactement. Au sein d'un paragraphe, je vais lire de haut en bas (sinon, ça serait vraiment le bordel), mais je vais naturellement commencer par le paragraphe en bas de la page. Ça me fait le coup pour les journaux, ce qui à priori n'est pas trop ennuyeux, mais quand je lis un bouquin, il devient alors un peu plus difficile de suivre l'histoire sans se faire des noeuds au cerveau.

Tout cela, c'est bien entendu la faute à Internet!

Lorsque l'on répond à un mail, on a tendance à écrire au dessus du message initial, ce qui fait généralement sens: notre correspondant sait ce qu'il a envoyé, et peut donc lire directement la réponse sans avoir à la chercher dans le mail, et peut toujours se reporter au contenu initial s'il en a besoin. A noter que l'Usenet français combat ce genre de pratique avec force, et que je me fais régulièrement engueuler lorsque je mets ma réponse au dessus.

Même souci avec les blogs, qui mettent le sujet le plus récent en haut.

Et là où tout se gâte, c'est que l'on a effectivement inversé la chronologie. Si je veux savoir ce qui s'est passé avant, je n'ai plus qu'à lire à l'envers. Et vu que cela arrive tout le temps, c'est maintenant dans les médias traditionnels que je me fais avoir. La pratique intensive de la programmation n'arrange pas les choses: l'information intéressante est rarement au tout début, où se trouvent les initialisations, et plutôt que de faire bouger mes yeux, je scrolle afin de maintenir la ligne qui m'intéresse toujours au milieu de l'écran (la molette est mon amie!). Et bien sûr, la plupart des langages se lisent en dépit du bon sens, comme cette déclaration de pointeur qui se lit de droite à gauche:

const int * const var => pointeur constant vers un entier constant.

Peut-être devrais-je faire les pieds au mur?


I read from bottom to top.

Well, not exactly. Inside a paragraph, I will read from top to bottom (otherwise, that would be really messy!), but I will naturally start with the bottom paragraph and make my way up to the top one. When I read newspapers, it's not too annoying, but when reading a novel, following the story becomes something of a nightmare.

And this, of course, is Internet's fault!

When answering to a e-mail, we have the tendency to write on top of the initial message, and that generally makes sense: our reader knows what he has sent (hopefully!), and can directly read the answer without having first to look for it inside the e-mail. To note that the French Usenet fights this kind of habit with force, and I got several messages urging me to write with my answer below.

Same problem with blogs, that put the most recent subject on the top.

And that's where everything becomes messy, because we inverted the chronology. If I want to know what happened before, I have to read upside down. And since it's happening all the time, I have built something of an habit, even in traditional medias. Intensive programming is somewhat at fault, too: the interesting information in the source code is rarely at the beginning, where all the boring initialization lies, and since I'm too lazy to move my eyes, I generally scroll the screen so that what I'm reading is always in the middle of the screen (the wheel is my friend!). And, of course, most programming languages should be read in an esoteric order, like this declaration that needs to be read right to left:

const int * const var => constant pointer to a constant integer.

Go figure!

samedi, mars 17, 2007

Comment faire planter un programme en C++ rapidement et efficacement:

std::string MyString(false);

Radical. Sous MSVC, c'est le crash immédiat, tandis que gcc lève une exception. Et j'ai poursuivi ce maudit bug pendant 1 heure vendredi. Ce n'était pas aussi évident que cette bête ligne: l'horreur était planquée dans 2 couches de templates.

Histoire d'ajouter à la bizarrerie, on remarquera que la même chose avec un "true" à la place du "false" revoie une belle erreur de compilation. L'explication étant, je suppose, que "false" est casté en 0, lequel est casté en pointeur nul, lequel est accepté par le constructeur de std::string, tandis que true est casté en 1, lequel ne peut pas se caster implicitement en pointeur. Et nous sommes sauf!

Grrr!


How to crash a C++ program quickly and efficiently:
std::string MyString(false);

Under MSVC, it's an immediate crash, while gcc raises an exception. And it took one hour for me to debug the thing, last Friday. Of course, it was not as obvious as this single line, as it was buried through 2 layers of templates.

So that the thing looks even stranger, the same thing with a "true" in place of the "false" will actually raise a nice compilation error. The explanation is, I suppose, that "false" is casted as 0, then casted as the null pointer, taken by the constructor of std::string. On the other hand, "true" will be casted as 1, and there will be no implicit casting in a pointer. We're safe!

Grrrr!