Nouveau widget de graphiques dans AsciiArt for Java

Pour la version 1.1 à venir de ma librairie d’Ascii Art pour Java, je prépare un nouveau composant permettant d’afficher des graphiques.

La première étape est le support de courbes simples. Le composant offre une grande flexibilité puisque l’utilisateur peut configurer la taille de la matrice ASCII du résultat, fournir les données sous forme d’implémentation de l’interface CurveModel et enfin l’échelle d’abscisse (l’ordonnée est calculée dynamiquement).

Voici un exemple tiré de la version en cours de développement:

package org.alcibiade.samples.asciiartsample;

import java.io.IOException;
import org.alcibiade.asciiart.coord.TextBoxSize;
import org.alcibiade.asciiart.raster.CharacterRaster;
import org.alcibiade.asciiart.raster.ExtensibleCharacterRaster;
import org.alcibiade.asciiart.raster.RasterContext;
import org.alcibiade.asciiart.widget.ChartWidget;
import org.alcibiade.asciiart.widget.model.CurveModel;

public class ChartSine {

    public static void main(String... args) throws IOException {

        ChartWidget widget = new ChartWidget(new TextBoxSize(80, 12),
                new CurveModel() {

                    public Double getValue(double x) {
                        return Math.cos(x - 1);
                    }
                }, -1, 10);

        // Create a character raster that will store the ASCII outputs
        CharacterRaster raster = new ExtensibleCharacterRaster(' ');
        // Render the widget on the character raster
        widget.render(new RasterContext(raster));
        // Now we display the raster contents in the console output
        System.out.println(raster.toString());
    }
}

Le résultat est le suivant:

Capture d’écran 2015-04-13 à 13.52.36

Il reste encore pas mal de choses à prévoir avant la release 1.1.0:

  • Permettre plusieurs courbes
  • Fournir des implémentations du modèle permettant de grapher directement depuis une Map x ->y existante, ou depuis une fonction JavaScript, …
  • Graduer les axes et afficher les valeurs
  • Afficher des « aires » entre les axes et la courbe
  • Rendre les modes de rendu paramétrables

Le support de l’injection de la fonction via une closure est prévu avec le reste du support Java 8 pour la v2.0.

Lien du projet: http://sourceforge.net/projects/asciiart/

Java Nashorn vs. Node.js

Pour ceux qui l’ignoraient encore, Java 8 intègre Nashorn, un interpréteur JavaScript entièrement conçu pour tirer parti des dernières évolutions de la JVM, et en particulier l’usage du « invoke-dynamic ».

Le résultat: des performances d’exécution JavaScript à des années lumière de Rhino, l’implémentation vieillissante qui était livrée depuis Java SE 6. Un exemple concret avec une bonne vieille suite de fibonacci:

yk@helios-pc11:~/Desktop$ /usr/local/java/jdk1.8.0_40/bin/jrunscript fibonacci.js 32
Fibonacci(32) = 3524578
Duration: 127ms
yk@helios-pc11:~/Desktop$ /usr/local/java/jdk1.7.0_21/bin/jrunscript fibonacci.js 32
Fibonacci(32) = 3524578
Duration: 23887ms

Un temps d’éxécution divisé par 200 entre Java SE 7 et Java SE 8, pas mal !! :-)

Et Node.js dans tout ça ? Il faut monter un peu le challenge:

yk@helios-pc11:~/Desktop$ /usr/local/java/jdk1.8.0_40/bin/jrunscript fibonacci.js 42
Fibonacci(42) = 433494437
Duration: 3970ms
yk@helios-pc11:~/Desktop$ node fibonacci.js 42
Fibonacci(42) = 433494437
Duration: 3710ms

Des temps relativement comparables… Bien entendu ce test n’est pas représentatif de performances effectives sur du code applicatif, mais cela va dans le sens de la crédibilisation de la JVM comme support d’exécution JavaScript.

Mode « graphique » dans GnuChess 6.1

Le moteur d’échecs de référence du monde Open Source fonctionne toujours en ligne de commande. Il est conçu pour être embarqué dans des applications graphiques, mais il est toujours possible de jouer manuellement si on est très motivé. Les parties ressemblent alors à ça:

macpro:~ yk$ gnuchess
GNU Chess 6.1.1
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
White (1) : e4
TimeLimit[0] = 0
TimeLimit[1] = 0
1. e4

black  KQkq  e3
r n b q k b n r 
p p p p p p p p 
. . . . . . . . 
. . . . . . . . 
. . . . P . . . 
. . . . . . . . 
P P P P . P P P 
R N B Q K B N R 

Thinking...

white  KQkq  e6
r n b q k b n r 
p p p p . p p p 
. . . . . . . . 
. . . . p . . . 
. . . . P . . . 
. . . . . . . . 
P P P P . P P P 
R N B Q K B N R 

My move is : e5
White (2) : 

...

C’est quand même très austère :-)

Dans la dernière release, les dévelopeurs ont tiré partie de la présence de caractères représentant les pièces d’échecs dans le jeu de caractères unicode. Ce mode s’active avec le paramètre ‘-g’ au démarrage. Doublé avec des codes ANSI pour l’affichage des couleurs, cela devient presque utilisable:

Capture d’écran 2014-01-01 à 16.31.46

Les détails sur les codes de caractères utilisés sont disponibles ici http://en.wikipedia.org/wiki/Chess_symbols_in_Unicode

 

Utilisation de Homebrew sur OSX

Les utilisateurs Mac venant du monde UNIX sont souvent amenés à utiliser un système d’installation et mise à jour complémentaire à celui du système pour installer des applications libres. Après des années d’utilisation de Fink, puis de MacPorts comme système de gestion de packages, je viens de découvrir Homebrew. Comme avec ses deux ancètres, on administre ses packages via la ligne de commande.

Je l’ai découvert via une recommandation de Spring car il permet l’installation de packages de façon proche de ce que je faisais à l’époque où j’installais des packages depuis leurs sources: chaque outil ou librairie est installé dans son propre répertoire dans /usr/local, puis des liens symboliques viennent le référencer dans /usr/local/bin /usr/local/lib …

J'adore l'icône bière !
J’adore l’icône bière !
macpro:local yk$ cd /usr/local/Cellar/
 macpro:Cellar yk$ ls -l
 total 0
 drwxr-xr-x 3 yk admin 102 Dec 28 12:37 freetype
 drwxr-xr-x 3 yk admin 102 Dec 28 12:37 imagemagick
 drwxr-xr-x 3 yk admin 102 Dec 28 12:37 jpeg
 drwxr-xr-x 3 yk admin 102 Dec 28 12:37 libpng
 drwxr-xr-x 3 yk admin 102 Dec 28 12:37 libtool
 macpro:Cellar yk$ ls -l /usr/local/bin
 total 216
 lrwxr-xr-x 1 yk admin 49 Dec 28 12:37 Magick++-config -> ../Cellar/imagemagick/6.8.7-7/bin/Magick++-config
 lrwxr-xr-x 1 yk admin 47 Dec 28 12:37 Magick-config -> ../Cellar/imagemagick/6.8.7-7/bin/Magick-config
 lrwxr-xr-x 1 yk admin 51 Dec 28 12:37 MagickCore-config -> ../Cellar/imagemagick/6.8.7-7/bin/MagickCore-config
 lrwxr-xr-x 1 yk admin 51 Dec 28 12:37 MagickWand-config -> ../Cellar/imagemagick/6.8.7-7/bin/MagickWand-config
 lrwxr-xr-x 1 yk admin 45 Dec 28 12:37 Wand-config -> ../Cellar/imagemagick/6.8.7-7/bin/Wand-config
 lrwxr-xr-x 1 yk admin 41 Dec 28 12:37 animate -> ../Cellar/imagemagick/6.8.7-7/bin/animate
 -rwxr-xr-x 1 yk admin 703 Dec 28 12:30 brew
 lrwxr-xr-x 1 yk admin 27 Dec 28 12:37 cjpeg -> ../Cellar/jpeg/8d/bin/cjpeg
 lrwxr-xr-x 1 yk admin 41 Dec 28 12:37 compare -> ../Cellar/imagemagick/6.8.7-7/bin/compare
 lrwxr-xr-x 1 yk admin 43 Dec 28 12:37 composite -> ../Cellar/imagemagick/6.8.7-7/bin/composite
 lrwxr-xr-x 1 yk admin 41 Dec 28 12:37 conjure -> ../Cellar/imagemagick/6.8.7-7/bin/conjure
 lrwxr-xr-x 1 yk admin 41 Dec 28 12:37 convert -> ../Cellar/imagemagick/6.8.7-7/bin/convert
 lrwxr-xr-x 1 yk admin 41 Dec 28 12:37 display -> ../Cellar/imagemagick/6.8.7-7/bin/display
 lrwxr-xr-x 1 yk admin 27 Dec 28 12:37 djpeg -> ../Cellar/jpeg/8d/bin/djpeg

Homebrew [http://brew.sh/]

AsciiArt for Java: Nouveau convertisseur

Nouvelle évolution de l’algorithme de conversion image vers texte pour mieux prendre en compte les zones moins contrastées. Il propage désormais un gradient permettant un affichage plus réaliste de ces zones:

ShapeRasterizer_Delta

Ces évolutions seront inclues dans prochaine release 0.5 du projet.

Nouveau projet sur SourceForge: Alcibiade Chess

Cela fait maintenant plusieurs années que je ne fais plus évoluer mon projet Open Source le plus populaire: MKGI Chess Club. J’en avais assez du PHP et le moteur de jeu, repris depuis un autre projet Open Source, n’est pas assez évolutif.

J’avais entrepris une ré-écriture Java avec GWT en 2010, mais je ne suis jamais allé au bout… Depuis cette année, je me suis remotivé et j’ai choisi de bâtir ce nouveau système sur Grails côté serveur et JQuery / Bootstrap côté client. Le projet est loin d’être complet, mais c’est déjà jouable.

Java 7 dans les applications GWT

La version 2.6 de GWT qui devrait sortir très prochainement en version finale permettra d’utiliser la syntaxe Java SE 7 dans le code compilé en JavaScript…

Release notes GWT 2.6.0 RC1: http://www.gwtproject.org/release-notes.html#Release_Notes_2_6_0_RC1

Ascii Art for Java: évolutions pour la v0.5

Je viens d’entreprendre une ré-écriture complète du code gérant de rendu ASCII d’images bitmap. La version actuelle dans la version 0.4 de la la librairie avait un algorithme de conversion qui donnait de bons résultats mais est très long…

Ici je redéfinis une interface Java commune et vais proposer différentes implémentations de conversion:

  • DashRasterizer va faire une approximation monochrome
  • ShapeRasterizer est en cours de développement pour améliorer l’approximation aux bordures à partir d’algorithme de sous-échantillonnage déterministe
  • D’autres implémentations arriveront pour couvrir les besoins d’images photographiques
  • Le projet Ascii Art sur SourceForge: http://sourceforge.net/projects/asciiart/
  • Le projet contenant les exemples sur GitHub: https://github.com/alcibiade/ascii

Mise en place d’un cache applicatif avec Spring et EHCache

Un résumé des étapes pour utiliser EHCache pour cacher des opérations sur des composants Spring en Java:

Ajouter les dépendances Java au projet:

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.2.1.RELEASE</version>
</dependency>

<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.5</version>
</dependency>

Ajouts au contexte Spring:

<cache:annotation-driven cache-manager="cacheManager" />
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">

<property name="cacheManager" ref="ehcache" />
</bean>

<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="ehcache.xml"/>

Définition d’un fichier de configuration EHCache:

<?xml version="1.0" encoding="UTF-8"?>

<ehcache>
<defaultCache eternal="true" maxElementsInMemory="100" overflowToDisk="false"  />
<cache name="friends" maxBytesLocalHeap="10000000" />
<cache name="followers" maxBytesLocalHeap="10000000" />
<cache name="timelines" maxBytesLocalHeap="10000000" />
</ehcache>

Utilisation des annotations directement sur les composants Spring:

@Override
@Cacheable(value = "followers")
public Set getFollowersIDs(Long id) throws TwitterException {
return getIDsAsSet(getTwitterInstance().getFollowersIDs(id, -1));
}

@Override
@CacheEvict(value = {"friends", "followers"}, allEntries = true)
public void createFriendship(long newUserID) throws TwitterException {
getTwitterInstance().createFriendship(newUserID);
}