• Hier pour la Saint Valentin, j'ai offert un jeu vidéo inspiré de Flappy Bird à ma chérie, en utilisant uniquement des photos retravaillées de sa boutique Jolie Geekette comme graphismes.

    Je l'ai développé avec le framework Game Closure en 3 jours, un vrai petit défi :-)

    Voici le rendu sur navigateur :

    Une fois chargé, cliquez dessus pour commencer une partie. Attention, il faut être réactif !

     Il y a aussi une version Android téléchargeable ici :

     

    Télécharger Flappy Jolie Geekette
    sur Android

     

    J'ai open sourcé le jeu, vous pouvez donc le récupérer sur Github et le modifier si vous le souhaitez. C'est d'ailleurs une bonne occasion de tester le framework Game Closure.

    Pour être tenu au courant des mises à jour ou de la mise en ligne sur Play Store / iTunes, ou simplement pour donner votre avis, laissez un petit commentaire ;-)


    24 commentaires
  • Cette année, j'ai travaillé sur un projet de recherche avec Ronan au sein de l'ISEP : nous nous sommes fixé pour but de développer une application open source de catégorisation automatique de documents, fournissant une API RESTful.

    Son nom est un habile jeu de mots : SortDC

    Concrètement, à quoi ça sert ?

    Les utilisations possibles sont variées, elles peuvent être par exemple :

    • Antispam (catégories spam / non spam)
    • Catégorisation par thématiques (sport, cinéma, cuisine, politique...)
    • Détection de la langue

    Dans quelques jours, EklaBlog commencera à l'utiliser comme antispam, puis nous l'utiliserons pour catégoriser les articles (plus de 2 millions à ce jour) par thématiques.

    Quelles technologies ?

    L'application est en Java et repose sur peu de bibliothèques. L'API qu'elle fournie dépend de Jersey. Elle est loin d'être optimisée, mais elle est propre et fonctionne bien.

    Les données (documents et catégories) peuvent être stockées au choix dans une base MongoDB ou MySQL. Pour l'instant, nous avons obtenu de meilleures performances avec MongoDB.

    L'algorithme utilise le théorème de Bayes, il est décrit dans l'article anglophone que nous avons rédigé pour la présentation du projet :

    Télécharger le PDF

    Open source

    Nous avons dès le départ décidé de publier cette application sous licence GNU/GPL3, les sources sont disponibles sur Github :
    https://github.com/sortdc/SortDC

    Ne vous privez donc pas pour la tester, l'utiliser dans un projet commercial ou non (les sources  que vous ajoutez et modifiez doivent rester libres, mais votre application qui contacte l'API peut être propriétaire), et pourquoi pas aussi pour participer en l'améliorant.

    SortDC n'en est qu'à ses prémices, on va continuer à l'améliorer et on espère que ça servira à d'autres !


    20 commentaires
  • On a souvent besoin de connaitre le nombre d'entrées dans une table, avec certaines conditions. Par exemple le nombre d'articles par catégories dans le cas d'un blog. Faire un SELECT COUNT(*) peut vite devenir très lourd quand le nombre d'entrées devient significatif, surtout si le moteur utilisé est InnoDB.

    En effet, on peut arriver vite à de gros problèmes de performances avec des COUNT(*) s'exécutant en plusieurs secondes si vous commencez à avoir beaucoup d'entrées (1M entrées par exemple).

    Je vous propose donc une astuce pour remplacer avantageusement ces disgracieux COUNT(*). On va garder ici l'exemple des articles et des catégories, avec une table posts et une table categories de structure basique :

    CREATE TABLE `categories` (
     `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
     `title` VARCHAR(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
     `nbposts` INT UNSIGNED NOT NULL DEFAULT '0'
     ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci;
     
     CREATE TABLE `posts` (
     `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
     `category_id` INT UNSIGNED NOT NULL,
     `title` VARCHAR(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
     `content` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
     `time` INT UNSIGNED NOT NULL,
     INDEX (`category_id`),
     INDEX (`time`)
     ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci;
     
     ALTER TABLE `posts` ADD FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE;
    [code=mysql]CREATE TABLE `categories` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `title` VARCHAR(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    `nbposts` INT UNSIGNED NOT NULL DEFAULT '0'
    ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci;

    CREATE TABLE `posts` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `category_id` INT UNSIGNED NOT NULL,
    `title` VARCHAR(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    `content` TEXT CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
    `time` INT UNSIGNED NOT NULL,
    INDEX (`category_id`),
    INDEX (`time`)
    ) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_general_ci;

    ALTER TABLE `posts` ADD FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE;[/code]

    Le champ nbposts va nous servir à garder en mémoire le nombre d'articles dans chaque catégorie. Certains diront que du coup on peut perdre de la consistance, eh bien oui... mais il faudrait avoir un sacré coup de pas de bol ou modifier la valeur du champ à la bourrin pour fausser les valeurs.

    Pour actualiser le champ nbposts, on va utiliser des triggers ("déclencheurs" en français), qui l'incrémenteront à chaque insertion et le décrémenteront à chaque suppression :

    DELIMITER ;;
     CREATE TRIGGER `posts_insert_after` AFTER INSERT ON `posts`
     FOR EACH ROW BEGIN
     UPDATE `categories` SET `nbposts` = `nbposts`+1 WHERE id=NEW.`category_id` LIMIT 1;
     END ;;
     CREATE TRIGGER `posts_delete_after` AFTER DELETE ON `posts`
     FOR EACH ROW BEGIN
     UPDATE `categories` SET `nbposts` = `nbposts`-1 WHERE id=OLD.`category_id` LIMIT 1;
     END ;;
     DELIMITER ;
    [code=mysql]DELIMITER ;;
    CREATE TRIGGER `posts_insert_after` AFTER INSERT ON `posts`
    FOR EACH ROW BEGIN
    UPDATE `categories` SET `nbposts` = `nbposts`+1 WHERE id=NEW.`category_id` LIMIT 1;
    END ;;
    CREATE TRIGGER `posts_delete_after` AFTER DELETE ON `posts`
    FOR EACH ROW BEGIN
    UPDATE `categories` SET `nbposts` = `nbposts`-1 WHERE id=OLD.`category_id` LIMIT 1;
    END ;;
    DELIMITER ;[/code]

    Et voilà, votre champ nbposts s'actualise maintenant automatiquement, plus besoin de faire des COUNT(*) !


    10 commentaires
  • Pendant l'été 2004, en vacances à la plage, Clément et moi avons choisi nos pseudonymes : "divarvel" pour lui, et "Skreo" pour moi. J'ai donc utilisé le pseudo Skreo pendant un peu plus de 6 ans jusqu'à maintenant un peu partout sur la toile.

    Mais je n'ai pas envie de garder ce pseudo plus longtemps, j'ai un prénom assez original pour que je puisse l'utiliser sans trop risquer qu'on me confonde avec quelqu'un d'autre, et je pense qu'utiliser son prénom fait plus sérieux.

    J'ai donc décidé de remplacer progressivement un peu partout mon pseudo "Skreo" par "Godefroy" sur le web. À commencer par :

    Et j'en profite pour changer de design de blog :-)

    Merci à Sébastien (@sebg) pour l'astuce pour récupérer un compte Twitter inactif.


    8 commentaires
  • Il peut arriver que des fichiers ayant des fins de ligne CRLF traînent dans un projet à cause d'un développeur windowsien ou adepte de la pomme qui a mal réglé son IDE. (troll inside ?) Je vais vous présenter une petite astuce pour trouver ces fichiers et les corriger.

    Pour rappel, on utilise généralement les fins de lignes LF sous Linux, CR sous Mac, et CRLF sous Windows. Dans la plupart des langages de programmation, CR est représenté par \r, et LF par \n. Là, le but est d'enlever les CR.

    Placez-vous dans le dossier à vérifier, puis entrez la commande :

    grep -rlIP '\r\n' ./
    [code=bash]grep -rlIP '\r\n' ./[/code]

    Vous obtiendrez la liste des fichiers en CRLF.
    Pour bien comprendre, détaillons les options utilisées :

    • r : cherche récursivement dans les dossiers
    • l : affiche uniquement le nom de fichier (on s'arrête à la première occurrence dans chaque fichier
    • I : ignore les fichiers binaires (images...etc)
    • P : expression régulière Perl

    Pour supprimer les CR, et n'avoir donc plus que des LF dans ces fichiers, on va utiliser sed

    grep -rlIP '\r\n' ./ | xargs sed -i -r 's/\r//g'
    [code=bash]grep -rlIP '\r\n' ./ | xargs sed -i -r 's/\r//g'[/code]

    Attention, n'oubliez pas d'exclure les dossiers / fichier que vous ne voulez pas traiter avec grep -v. Par exemple pour exclure les fichiers de Git :

    grep -rlIP '\r\n' ./ | grep -v .git | xargs sed -i -r 's/\r//g'
    [code=bash]grep -rlIP '\r\n' ./ | grep -v .git | xargs sed -i -r 's/\r//g'[/code]
     


    9 commentaires



    Suivre le flux RSS des articles
    Suivre le flux RSS des commentaires