lundi 15 février 2016

Une alternative européenne à waze


Une application européenne

Un petit billet pour faire connaître icoyote, la dernière version mobile de coyote qui, à mes yeux, est une alternative crédible à waze. Si waze est une application géniale j'ai toujours un peu peur de l'utilisation qui peut être faite des données que je génère. L'application coyote est en effet payante, mais mes données n'ont pas vocation à être réutilisées par un quelconque moteur de recherche : les données collectées par icoyote sont entièrement anonymisées. Certes, l'application est un peu jeune, et souffre encore de quelques "bugs" mais elle s'améliore en continue.

Un système d'alertes réactif

Les alertes d'icoyote sont très faciles à déclarer et remontent très rapidement vers les autres utilisateurs ; la "communauté" coyote, bien que sans doute moins importante que celle des wazer, me semble après mes premières utilisations assez réactive et digne de confiance. Bref, c'est une application à essayer si vous voulez donner sa chance à un groupe plus proche de chez nous.
La cartographie d'icoyote, basée sur here, est assez claire et précise. Seul manque à ce jour : aucun moyen d'édition de la cartographie par la communauté.

dimanche 14 février 2016

La noyade du phénix


Le contexte

J'ai commencé à lire ce livre car il a été écrit par la fille d'un ami. Ma lecture a donc dans un premier temps été motivée par cette relation, histoire de soutenir une jeune auteure ; mais au fil des pages elle s'est transformée. J'ai commencé ce roman comme un simple curieux, amoureux de la lecture ; puis de plus en plus vite, j'ai été aspiré par l'histoire et comme l'héroïne j'ai été bousculé par les multiples rebondissements du récit. Finalement j'ai oublié qu'entre mes mains se trouvait l'oeuvre de quelqu'un de mon entourage pour ne plus y voir qu'une histoire passionnante qui chaque soir a su me transporter dans un univers différent du mien.

un roman prenant !

Il suffit donc de "tourner" quelques pages pour se sentir aspirer par l'histoire de l'héroïne, jeune romancière à la recherche de son passé familial. Avec une écriture imagée, à la fois réaliste et romantique, l'auteure - Audrey Briere - nous fait visiter les terres d'Ecosse. Ses personnages hauts en couleurs ne m'ont pas lâché pendant les quelques jours qu'il ma fallu pour tout lire. Suspens, amour, histoire, des ingrédients savamment mélangés dans "la noyade du phénix".

Silo

Sur ce blog j'ai toujours tendance à parler positivement des livres que je lis, le respect et l'admiration pour la condition d'écrivain étant très forts chez moi. Mais quand je dis que Silo est véritablement une découverte que j'ai fait, il y a deux mois, avec un grand plaisir. Ce n'est donc pas pour respecter les convenances que je vous invite à croire que Silo réunit de nombreuses qualités !

Roman d'anticipation

Tout d'abord il s'agit d'un bouquin d'anticipation ; l'action se passe en effet dans un futur post-apocalyptique, où l'humanité résiduelle survit dans un silo enchâssé dans le sol pour échapper à l'atmosphère désormais nocive, mortelle. Le "monde" qui est décrit dans cette oeuvre ne ressemble à aucun de ceux que j'ai pu lire auparavant.

Une société originale

Mais ce roman est bien plus qu'un énième livre de SF s'inspirant des sempiternelles "même ficelles" bien connues des amateurs du genre ; Silo est assez unique en son genre. L'auteur Hugh Howey nous dépeint une vision très intéressante des méthodes de survie mises en oeuvre par les survivants.
La société du silo est organisée en caste, chacune étant nécessaire à la survie générale. Pour maintenir la stabilité de ce microcosme des tabous ont été érigés et sont devenus lois ; les enfreindre peut conduire à une condamnation à mort. Les mises à mort elles même participent au bon fonctionnement de la communauté : le condamné doit sortir nettoyer les caméras du silo. Ces caméras sont les seuls fenêtres sur l'extérieur et permettent à ceux qui le veulent de voir dehors grâce à des projections sur un écran géant ; seul problème l'atmosphère souillée salie assez rapidement les caméras. Le condamné, banni du silo, doit donc les nettoyer rapidement, si possible avant que l'atmosphère ne le tue. Le spectacle, macabre, du nettoyage est au peuple du silo ce que le cirque était aux romains : un exutoire et un moyen de contrôle des foules. L'habilité de Hugh Howey tient dans la façon dont il décrit chacun des personnages et les luttes opposants les castes des plus démunies à celles des dirigeants. Chaque caractère est décrit en détail, avec sa part d'ombre et de lumière ; il n'y a pas seulement "les bons et les méchants" mais les intérêts des uns opposés à ceux des autres.

Pour conclure

Ce livre m'aura fait passer de bons moments. Je pense lire un peu plus tard les autres oeuvres de cet auteur, dont les suites de "silo" écrites suite au succès de ce dernier.

mercredi 29 avril 2015

Les listviews

L'objectif de ce billet est de faire un petit résumé riche en exemples des différentes notions que j'ai eu à utiliser en faisant joujou avec les ListView de javafx. J'ai commencé par une utilisation basique (affichage d'une bête liste statique) ; puis mes besoins sont allés crescendo. Cet article suivra la même chronologie que celle qui a été la mienne durant mon apprentissage.

Pour commencer

Tous les exemples de code seront récupérables sur ce dépôt git : git@github.com:beynet/listview.git
Pour exécuter le code démontré, importez le projet dans votre IDE (projet maven) ; la classe à exécuter est "ListViews".

Etape 1 - Une liste toute simple

Positionnement dans le code

Avec javafx, créer une listview et y rajouter/supprimer des éléments est très simple.
C'est ce que nous allons faire durant cette étape.
git checkout step1

Le code

Pour créer la liste :
ListView<Person> persons = new ListView<Person>();
Le code permettant de créer et ajouter des éléments à la liste est celui-ci (lignes 49 et 50 de la classe ListViews).
persons.getItems().add(new Person("John","Doe"));
persons.getItems().add(new Person("MyNameIs","Person"));
Ce qui donne :

Les personnes s'affichent correctement dans la liste car la classe Person surcharge la méthode toString() :
@Override
public String toString() {
    return getFirstName()+" "+getLastName();
};
Par défaut, notre listview a comme modèle de données une liste de type ObservableList<Person> ; les modifications apportées à cette liste (ajout et suppression) sont directement reportées dans la vue graphique. C'est ce qu'illustre notre bouton addPerson : il fait apparaitre une boite de dialogue permettant de rajouter une nouvelle personne (saisissez un prénom et un nom séparés d'un espace) :

Après appuie sur la touche ok la liste est mise à jour. Le code qui met la liste à jour est le suivant ( sur activation du bouton OK ) :
Button addPerson = new Button("aj. person");
addPerson.setOnAction(event -> {
    TextInputDialog askForName = new TextInputDialog();
    askForName.setContentText("new person name");
    Optional<string> result=askForName.showAndWait();
    result.ifPresent((name)->{
        String[] names=name.split(" ");
        if (names.length==2) {
            persons.getItems().add(new Person(names[0],names[1]));
        }
    });
});
Ce qui donne :

Etape 2 - Customiser l'affichage de la liste

Lors de cette étape nous allons voir comment customiser l'affichage des éléments de la liste.

Positionnement à l'étape 2

git checkout step2

Le code

Pour illustrer la customisation nous allons afficher le prénom en rouge et le nom en bleu.
Pour customiser l'affichage il faut implémenter une classe dérivant de ListCell. C'est notre classe PersonCell :
public class PersonCell extends ListCell<person> {
@Override
    protected void updateItem(Person item, boolean empty) {
        super.updateItem(item, empty);
        setText(null);
        setGraphic(null);
        if (item!=null && empty==false) {
            HBox content = new HBox();
            Label firstName = new Label(item.getFirstName()+" ");
            firstName.setTextFill(Color.RED);
            Label name = new Label(item.getLastName());
            name.setTextFill(Color.BLUE);
            content.getChildren().addAll(firstName,name);
            setGraphic(content);
        }
    }
}
Pour utiliser ces "cells" custom il faut associer un cell factory à la listview, c'est ce qui est fait en ligne 25 de la classe ListViews :
this.persons.setCellFactory(param -> {
   return new PersonCell();
});
Ce qui nous donne le résultat attendu :

Etape 3 - Rendre la listview réactive aux modifications des objets Person

Dans cette section nous allons montrer comment rendre la listview réactive aux modifications de son modèle de données sous-jacent ; c'est à dire comment modifier les éléments courant de la listview.

Récupération du code

git checkout step3

Le code

Pour cela nous allons modifier la classe Person pour lui rajouter la méthode permutFirstNameAndLastName(). Comme son nom l'indique cette méthode permettra de permuter le prénom et le nom d'une personne.
Comment informer la listview des modifications effectuées sur une personne ?
On peut imaginer supprimer de la liste la personne à modifier ; puis la rajouter une fois la modification effectuée. Cela marche, il suffit de faire quelque chose de ce style :

//suppression de la personne p1
persons.getItems().remove(p1);
p1.permutFirstNameAndLastName();
// rajout de p1 modifié
persons.getItems().add(p1);

Mais ce n'est pas la meilleur des solutions ; on peut facilement faire que la listview se modifie automatiquement quand son modèle de données est modifié. Pour cela nous allons utiliser les "propriétés" de javafx. Voir cet article (en anglais) pour tous les détails.

Modification de la classe Person

La classe Person est modifiée ainsi : les variables de classe firstName et lastName ne sont plus des instances de String mais des instances de StringProperty. En voici le code :
public class Person {
    public Person(String firstName, String lastName) {
        this.firstName = new SimpleStringProperty();
        this.firstName.set(firstName);
        this.lastName = new SimpleStringProperty();
        this.lastName.set(lastName);
    }

    public StringProperty firstNameProperty() {
        return firstName;
    }

    public StringProperty lastNameProperty() {
        return lastName;
    }

    public String getFirstName() {
        return firstName.get();
    }

    public String getLastName() {
        return lastName.get();
    }

    @Override
    public String toString() {
        return getFirstName()+" "+getLastName();
    }


    /**
     * permut first and last name
     */
    public void permutFirstNameAndLastName() {
        String first = this.firstName.get();
        this.firstName.set(getLastName());
        this.lastName.set(first);
    }

    private StringProperty firstName;
    private StringProperty lastName;
}

Modification de la listview

La classe ListViews est modifiée pour rajouter un bouton permuttant le nom/prénom de la personne sélectionnée :
//this button will permute the selected person name and first name
Button permut = new Button("permut");
permut.setOnAction(event -> {
    Person selected = this.persons.getSelectionModel().getSelectedItem();
    if (selected!=null) {
        selected.permutFirstNameAndLastName();
    }
});
Enfin, la liste observable à laquelle la liste view sera couplée est construite "à la main" de façon à ce que la listview soit informée des changements sur les instances de Person que l'on veut propager. Le code tient en une seule ligne :
// associate the listview with a custom observable list
this.persons.setItems(FXCollections.observableArrayList(param -> new Observable[]{param.firstNameProperty(),param.lastNameProperty()} ) );
En résumé, pour chaque instance de personne on retourne un tableau d'observable qui contiendra la liste des propriétés à observer.

samedi 20 décembre 2014

La maîtresse de guerre

Un livre français

J'ai découvert Gabriel Katz avec la trilogie du puits des mémoires ; trilogie qui m'avait enthousiasmé. Quand j'ai vu qu'il sortait un nouveau livre je me suis précipité dessus et je n'ai pas été déçu.

L'histoire

Le personnage principale est une femme ,Kaelyn, fille d'un maître d'arme qui malgré son sexe rêve de reprendre la succession de son père. Elle va s'engager dans une guerre pour, d'après les recruteurs, combattre contre les esclavagistes d'un lointain pays. Convaincue d'être du bon côté Kaelyn s'engage donc ; mais la réalité de la guerre va très rapidement la rattraper. Ses certitudes seront vite chamboulées : les libérateurs s'avèrent brutaux, la culture du pays des esclavagistes paradoxalement plaisante.

Et alors ?

L'écriture de ce livre est limpide ; sa lecture semble couler de source. Si le style est plaisant, peut-être pourra-t-on reprocher au livre de manquer d'un peu de suspens : le scénario se déroule de manière très plaisante mais sans grandes surprises. Mais bon, je ne suis quand même pas resté sur ma faim ; Gabriel Katz a quand même accouché d'une belle oeuvre.

Ma note : 7/10

Treize

Une histoire originale

Voilà une histoire originale que j'ai découvert avec un grand plaisir. Il parait que cet auteur est connu car certaines de ses histoires ont été reprises sous la forme de séries TV. Je l'ai quant à moi découvert par hasard un jour où la politique éditoriale du bookenstore mettait en avant son livre "treize".

Des morts bien vivant

L'histoire se passe dans un monde où l'humanité a découvert qu'il est possible de communiquer avec les morts. Cette communication peut se réaliser lorsqu'un reviver, homme ou femme doté du pouvoir de communication avec les décédés,  rentre en contact avec le cadavre de la personne à contacter. 
Le personnage principal du livre, l'un des reviver les plus doué, va lors à la fin d'une séance de résurrection complexe rentrer en  contact avec une entité menaçante. S'en suivent alors les doutes, : quelle est cette entité ; les reviver et plus généralement les humains sont ils menacés ?

A lire 

J'ai trouvé cette histoire très intéressante, le scénario m'a agréablement surpris. Pour tout vous dire j'ai du lire le livre en deux ou trois soirées. Je pense qu'il en sera de même pour la plupart des lecteurs !!

Ma note : 8/10.

samedi 29 novembre 2014

Lollipop Nexus 7

Contexte

Je dispose d'une tablette nexus 7 (modèle 2012) qui est devenue soudainement très très lente après la mise à jour vers Lollipop. Je n'avais jusqu'à présent jamais trop cherché à "ouvrir le capot" d'android. Après quelques allez-retour sur certains forums j'ai trouvé quelque chose qui chez moi a parfaitement fonctionné : j'ai formatté la partition cache de la tablette (sans danger aucun, il s'agit du cache). Suite à cette manip le fonctionnement est redevenu correct.

Procédure

  1. Eteindre la tablette
  2. Appuyer simultanément sur "power" et "volume bas" jusqu'à apparition d'une grosse flèche au centre de l'écran
  3. Avec les touches du volume sélectionner l'option "recovery" (sélection avec le boutton power)
  4. Apparaitront la mascotte android et un triangle rouge
  5. Laisser appuyer sur power, appuyer sur "volume haut" et enfin relâcher le boutton power. 
  6. Sélectionner "wipe the cache partition"
  7. laisser la chose se dérouler puis redémarrer la tablette