Le problème
Maintenir la conception du modèle de trace d'une application de la conception de l'application n'a pour moi pas de sens : on perd du temps à passer de l'un à l'autre, on s'embrouille et c'est une approche préhistorique (ou du moins datant du COBOL :)
On pourrait se dire que disposer d'un modèle de l'application ne présente pas nécessairement un intérêt quand on cherche à obtenir une trace des interactions d'un utilisateur, mais pour moi c'est sauter une étape.
En effet, depuis de nombreux mois plusieurs personnes de l'équipe SILEX travaillent sur des modèles d'interactions. Au delà des problèmes concrets lié à l'expression de modèles conformes au métamodèle, il se pourrait qu'une des choses qui nous freine soit de vouloir réaliser tout de suite un grand pas : on ne sait pas décrire le comportement d'une application, alors qu'on veut décrire le comportement de l'utilisateur dans cette application.
La solution (possible ?)
Plus j'y pense, et plus je me dis que la solution passe peut-être par une génération automatique des modèles de l'application. Le principe serait alors de générer le(s) modèle(s) de l'application à la compilation, sur le même principe que la documentation des API tel javadoc ou doxygen.
On peut songer à quelque chose de similaire au javadoc : avec des marqueurs bien placés dans le code, on génère à la compilation des modèles correspondant à des éléments d'interface.
Du coup, on permet au développeur de structurer les modèles de l'application, tout en permettant à l'utilisateur de concevoir des modèles supplémentaire.
Conceptuellement
idée clé : les API sont un modèle de l'application orienté développeur; le modèle de trace d'interactions est un modèle de l'application orienté utilisateur.
Cette approche serait utilisée, a priori, uniquement pour les applications instrumentées directement dans le code. Éventuellement, peut-être aussi pour les enrichissements d'application à base de plugins, mais il faudrait que j'y réfléchisse.
En pratique
Pour réaliser la génération de modèle d'application, ces questions pratiques se posent :
sur quelles fonctions placer les marqueurs de génération d'observés ? Callback/méthode associés aux widgets ? D'une façon générale, très probablement sur les fonctions les plus proches de l'utilisateur, donc au niveau des E/S. L'idée est de ne pas ajouter de code, juste des commentaires contenant les marqueurs.
On commence par définir globalement les propriété communes : références au métamodèle, à l'extension temporelle, etc. On peut songer par exemple à un mécanisme de macro ou de variables (je l'appellerais ici « en-tête 1 »
=define "en-tête 1"
@prefix : <http://liris.cnrs.fr/silex/ns/ktbs/>.
@prefix mod: <>.
@prefix xsd: <TODO> .
<> a :TraceModel ;
:hasTemporalDomain :seconds .
Puis, dans le code de l'application on insère les marqueurs pour la génération du modèle
/*
* =include "en-tête 1"
* =type presseTouche
* =description "décrit la frappe d'une touche dans la zone de saisie"
* =string "versionDeWeeChat"
* =string "monPseudo"
* =string "nomDuCanal"
*/
LaFonctionGérantLesFrappesClavierDeLutilisateur(...) {
...
}
Et là, c'est le drame car il faut exprimer des choses comme comme le fragment ci-dessous.
>:aRange [ a owl:DatatypeRestriction ;
owl:onDatatype xsd:string ;%%%
xsd:pattern "(#|&)[a-zA-Z0-9]{,63}"
]
Mais l'idée reste la même : pour moi, les informations permettant la génération du modèle doivent être notées sous forme réduite, juste à côté du code, et sans gêner les développeurs.
Le modèle généré :
@prefix : <http://liris.cnrs.fr/silex/ns/ktbs/>.
@prefix mod: <>.
@prefix xsd: <TODO> .
<> a :TraceModel ;
:hasTemporalDomain :seconds .
mod:presseTouche a :ObserType .
mod:versionDeWeeChat a :Attribute ;
:aDomain mod:presseTouche ;
:aRange xsd:string ;
.
mod:monPseudo a :Attribute ;
:aDomain mod:presseTouche ;
:aRange xsd:string ;
.
mod:nomDuCanal a :Attribute ;
:aDomain mod:presseTouche ;
:aRange [ a owl:DatatypeRestriction ;
owl:onDatatype xsd:string ;
xsd:pattern "(#|&)[a-zA-Z0-9]{,63}"
]
.
mod:nomDuServeur a :Attribute ;
rdfs:label "Nom du Serveur"@fr ;
:aDomain mod:presseTouche ;
:aRange [ a owl:DatatypeRestriction ;
owl:onDatatype xsd:string ;
xsd:pattern "(IPv4|IPv6|hostname)"
]
.
mod:typeDeTampon a :Attribute ;
rdfs:label "Type de tampon"@fr ;
:aDomain mod:presseTouche ;
:aRange [ a owl:DatatypeRestriction ;
owl:onDatatype xsd:string ;
xsd:pattern "[0-2]"
]
.
mod:caractère a :Attribute ;
rdfs:label "Caractère frappé"@fr ;
:aDomain mod:presseTouche ;
:aRange [ a owl:DatatypeRestriction ;
owl:onDatatype xsd:string ;
xsd:pattern "(\*?|STRING)"
]
.
mod:zoneDeSaisieAvantCaractère a :Attribute ;
rdfs:label "Contenu de la zonne de saisie avant la frappe clavier"@fr ;
:aDomain mod:presseTouche ;
:aRange [ a owl:DatatypeRestriction ;
owl:onDatatype xsd:string ;
xsd:pattern ".*"
]
.
mod:zoneDeSaisieAprèsCaractère a :Attribute ;
rdfs:label "Contenu de la zonne de saisie après la frappe clavier"@fr ;
:aDomain mod:presseTouche ;
:aRange [ a owl:DatatypeRestriction ;
owl:onDatatype xsd:string ;
xsd:pattern ".*"
]
.
mod:drapeauAway a :Attribute ;
rdfs:label "Status de présence"@fr ;
:aDomain mod:presseTouche ;
:aRange [ a owl:DatatypeRestriction ;
owl:onDatatype xsd:string ;
xsd:pattern "(0|1)"
] ## ?? vérifier dans la spec de OWL 2
.
mod:contenuDeLaZoneDeSaisie a :Attribute ;
rdfs:label "Contenu de la zone de saisie"@fr ;
:aDomain mod:presseTouche ;
:aRange [ a owl:DatatypeRestriction ;
owl:onDatatype xsd:string ;
xsd:pattern ".*"
]
.
mod:contenuDuMasqueDeCouleurDeLaZoneDeSaisie a :Attribute ;
rdfs:label "Masque de la zone de saisie"@fr ;
:aDomain mod:presseTouche ;
:aRange [ a owl:DatatypeRestriction ;
owl:onDatatype xsd:string ;
xsd:pattern ".*"
]
.
mod:positionDuCurseurDansLaZoneDeSaisie a :Attribute ;
rdfs:label "Position du curseur dans la zone de saisie"@fr ;
:aDomain mod:presseTouche ;
:aRange [ a owl:DatatypeRestriction ;
owl:onDatatype xsd:string ;
xsd:pattern "[0-9]*"
]
.
aucun rétrolien
mercredi 10 juin 2009
Par Damien Clauzel le mercredi 10 juin 2009, 16:17
Avant propos
Il y a deux abréviations à connaitre.
i18n (internationalization) internationalisation
Les adaptations à faire sur les formats de données, selon les pays. Par exemple, comment on exprime une date (JJ/MM/AA, MM/DD/AA, etc), une monnaie ($123, 123€), un nombre (123.456 ou 123,456), etc. C'est un travail technique qui demande à faire abstraction du contenu pour en décrire sa structure.
CF l18n
l10n (localization) régionalisation
Il s'agit de la traduction à proprement parler.
WP :
La régionalisation de logiciel concerne le processus de traduction de l'interface utilisateur d'un logiciel d'une langue vers une autre et en l'adaptant à la culture locale. On utilise parfois le terme localisation, qui est une transposition du mot anglais localization (faux ami). On écrit parfois l10n car le mot localization est composé de dix lettres encadrées par un l et un n.
Avant qu'un logiciel ne soit régionalisé, il faut au préalable qu'il ait été internationalisé, c’est-à-dire qu'il ait été écrit pour pouvoir être traduit dans différentes langues et cultures.
CF l10n
Discussion sur les modèles
Pour construire l'interface de l'outil générique de visualisation interactive de trace (OGVIT), il faut que chaque attribut ait un nom compréhensible pour l'utilisateur. Ce qui veut dire qu'au couple attribut+valeur (par exemple, ktbs:hasTime et 1244638257), il faut ajouter un 3e élément qui est le « nom humain » (mercredi 10 juin 2009, 14:50:57)
De plus , ce nom humain doit pouvoir être internationalisé (et localisé), car tout le monde n'utilise pas la même langue. Ce qui veut dire qu'un observé, au final, doit autant être compréhensible par la machine que par l'humain. Si l'humain sait vaguement s'adapter, la machine elle a besoin d'un formalisme explicite.
Il existe plusieurs endroits où ajouter ces élément de i18n et de l10n :
Dans l'observé lui-même
- avantage : l'information est immédiatement présente, on peut la traiter directement
- inconvénients :
- ça prend de la place, on répète l'information autant de fois qu'on a d'observés.
- pour gérer plusieurs langues, il faudra ajouter autant d'éléments de traduction; c'est du gaspillage.
Dans le modèle de trace
- avantage : c'est définit une fois pour toute; on économise de la place et du temps
- inconvénients :
- on se retrouve à trimbaler dans le modèles des informations dont on n'a pas besoin. Par exemple, moi je n'ai pas besoin de pouvoir exprimer mes dates en japonais.
- ajouter une langue revient à reprendre le modèle, ce qui n'est pas toujours évident à faire car celui-ci n'est pas forcément modifiable. Par exemple, il peut être intégré dans une application dont on n'a pas les sources.
Dans un document à côté du modèle
- avantages :
- on peut modifier et compléter les traductions et formats sans toucher au modèle.
- le modèle ne contient que la définition de la trace, le reste étant dans un document associé.
- inconvénients :
- quand on veut manipuler un modèle, il faut alors manipuler deux fichiers pour avoir les littéraux. Pas pratique.
- ça complique le schmilblick.
Reste à décider. Vos avis sur la question ?
Exemple concret
Je souhaite visualiser la trace de ma (« Damien_traces ») frappe clavier dans weechat, mon client IRC tracé. La trace correspondant à l'envoi du message « bonjour » sur le canal #LIRIS de Freenode est la suivante :
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix ktbs: <http://liris.cnrs.fr/~ithaca/ns/ktbs/0.1/> .
@prefix : <http://example.com/trace-model/> .
[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*b";
:zoneDeSaisieAvantCaractère "";
:zoneDeSaisieAprèsCaractère "b";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "b";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie " ";
:positionDuCurseurDansLaZoneDeSaisie "1";
ktbs:hasBegin "1244635383";
ktbs:hasEnd "1244635383";
ktbs:hasTrace <> ;
].
[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*o";
:zoneDeSaisieAvantCaractère "b";
:zoneDeSaisieAprèsCaractère "bo";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bo";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie " ";
:positionDuCurseurDansLaZoneDeSaisie "2";
ktbs:hasBegin "1244635383";
ktbs:hasEnd "1244635383";
ktbs:hasTrace <> ;
].
[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*n";
:zoneDeSaisieAvantCaractère "bo";
:zoneDeSaisieAprèsCaractère "bon";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bon";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie " ";
:positionDuCurseurDansLaZoneDeSaisie "3";
ktbs:hasBegin "1244635383";
ktbs:hasEnd "1244635383";
ktbs:hasTrace <> ;
].
[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*j";
:zoneDeSaisieAvantCaractère "bon";
:zoneDeSaisieAprèsCaractère "bonj";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bonj";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie " ";
:positionDuCurseurDansLaZoneDeSaisie "4";
ktbs:hasBegin "1244635384";
ktbs:hasEnd "1244635384";
ktbs:hasTrace <> ;
].
[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*o";
:zoneDeSaisieAvantCaractère "bonj";
:zoneDeSaisieAprèsCaractère "bonjo";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bonjo";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie " ";
:positionDuCurseurDansLaZoneDeSaisie "5";
ktbs:hasBegin "1244635384";
ktbs:hasEnd "1244635384";
ktbs:hasTrace <> ;
].
[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*u";
:zoneDeSaisieAvantCaractère "bonjo";
:zoneDeSaisieAprèsCaractère "bonjou";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bonjou";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie " ";
:positionDuCurseurDansLaZoneDeSaisie "6";
ktbs:hasBegin "1244635385";
ktbs:hasEnd "1244635385";
ktbs:hasTrace <> ;
].
[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "*r";
:zoneDeSaisieAvantCaractère "bonjou";
:zoneDeSaisieAprèsCaractère "bonjour";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "bonjour";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie " ";
:positionDuCurseurDansLaZoneDeSaisie "7";
ktbs:hasBegin "1244635385";
ktbs:hasEnd "1244635385";
ktbs:hasTrace <> ;
].
[ a :presseTouche;
:versionDeWeechat "0.2.6.1";
:monPseudo "Damien_traces";
:nomDuCanal "#LIRIS";
:nomDuServeur "freenode";
:typeDeTampon (0=standard, 1=DCC, 2=données IRC brutes) "0";
:caractère "return";
:zoneDeSaisieAvantCaractère "bonjour";
:zoneDeSaisieAprèsCaractère "";
:drapeauAway "0";
:contenuDeLaZoneDeSaisie "";
:contenuDuMasqueDeCouleurDeLaZoneDeSaisie "";
:positionDuCurseurDansLaZoneDeSaisie "0";
ktbs:hasBegin "1244635386";
ktbs:hasEnd "1244635386";
ktbs:hasTrace <> ;
].
L'OGVIT est supposé construire automatiquement, à partir du modèle de la trace, la visualisation suivante.

On constate plusieurs choses :
- c'est vide : ben oui, car je n'ai pas le modèle de cette trace, et d'une façon plus générale le format d'un modèle
- il manque des informations pour construire la représentation de la trace : les noms (humains) des colonnes doivent provenir du modèle, ou du fichier de l10n associé.
Comme quoi, c'est vraiment là un problème technique et non pas scientifique. Il faut qu'on se force à prendre des décisions pour avancer.
aucun rétrolien
mardi 26 mai 2009
Par Damien Clauzel le mardi 26 mai 2009, 09:46
Annonce de débat : Les grands débats du CNRS : Sécurité ou vie privée, a-t-on le choix ? :
Les téléphones portables, les cartes de paiement ou de déplacement, les technologies numériques de la reconnaissance et de la localisation (biométrie, puces RFID) envahissent notre quotidien. Ces techniques sont censées nous faciliter la vie et assurer notre sécurité. Peuvent-elles porter atteinte à notre vie privée ? Sommes-nous constamment sous surveillance ?
Au niveau de SILEX, nous discutons depuis longtemps sur le caractère privé des traces : censure d'observés, partage sélectif de traces, stockage, etc.
Mais je ne crois pas qu'il existe un document dans lequel nous avons mis cela par écrit. Ça pourrait être l'occasion de s'y mettre, en commençant par les grandes lignes.
Un utilisateur doit pouvoir :
- connaître toutes les traces qu'il possède
- consulter de façon compréhensible ses traces et leur contenu
- supprimer une trace
- supprimer un observé dans une trace
- ...
Pour ce faire, la page Traces et vie privée du wiki a été mise en place avec les éléments existant.
aucun rétrolien
♻ Ils parlent