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

27/05/2018

Quand Spoggy utilise Polymer pour s'attaquer à Persée...

Difficulté du tuto ? ça devrait être accessible à toute personne qui a un peu approché le javascript...



Dans ce petit tutoriel, on va voir comment utiliser Polymer ( plus d'infos ) pour effectuer des requêtes vers un endpoint sparql et afficher les résultats, on va ici utiliser :


mais le principe est le même avec d'autres endpoints tels que :


... et bien d'autres  ou encore
C'est quoi un endpoint Sparql ?
et un triplestore ? un triplet ? un  prédicat ? un vocabulaire ?


ETAPE 1 : INSTALLER LA STRUCTURE D'UNE APPLI POLYMER

ETAPE 2 : CREATION DE L'ELEMENT SPOGGY-SPARQL QUI VA EFFECTUER LES REQUETES VERS LE ENDPOINT

ETAPE 3 : LA REQUETE VERS L'ENDPOINT SPARQL.

ETAPE 4 : LANCER LA REQUETE ET RECUPERER LES RESULTATS.

ETAPE 5 : AFFICHAGE DES RESULTATS SOUS FORME DE LISTE.


ETAPE 1 : INSTALLER LA STRUCTUTRE D'UNE APPLI POLYMER



Prérequis :
Ouvrez un terminal / invite de commande et installez en global (-g) Polymer  : 
  • npm install -g polymer-cli

Nous utilisons ici Polymer 2 car à l'heure où l'on écrit ces lignes, Polymer 3 n'est pas encore stabilisé.


Créez un dossier pour votre appli  et un dossier 'public' à l'intérieur de celui-ci et installez l'appli exemple de Polymer: 
  • mkdir tutosparql && cd tutosparql
  • mkdir public && cd public
  • polymer init
  • choisissez '6) polymer-2-starter-kit'


lancez polymer serve



Votre appli 'starter-kit' devrait normalement être accessible à l'adresse http://127.0.0.1:8081 



Utilisez maintenant votre éditeur préféré pour changer le code de cette appli

Le fichier principal de notre application se trouve dans 'public/src' et se nomme 'my-app.html'




Dans le code du fichier 'my-app.html', on constate l'import des modules 'my-view1', 'my-view2' et 'my-view3', on va utiliser et modifier 'my-view1' qui se trouve être la page d'accueil de notre appli.

Commençons par créer un nouvel élément que nous allons ensuite inclure dans la page 'my-view1'.
Arrétez le server (Ctrl+C) ou ouvrez un nouvel invite de commande/ terminal, placez vous dans le dossier 'public/src', créez un dossier pour votre nouvel élément, lancez à nouveau 'polymer init' et choisissez 'polymer-2-element'




Ceci vous créé un élément nommé 'spoggy-sparql' dans 'public/src'. 
Commencez par modifier la première ligne du fichier 'public/src/spoggy-sparql/spoggy-sparql.html' (on utilise un dossier public, qui n'est pas réellement la norme, donc il faut ajouter '../' pour remonter d'un niveau de plus et aller chercher 'polymer' dans le dossier 'bower_components'  ;-) ) : 

<link rel="import" href="../polymer/polymer-element.html">
modifié en :
<link rel="import" href="../../bower_components/polymer/polymer-element.html">



Maintenant que notre élément est créé, on va l'insérer dans la page 'my-view1.html'
Pour importer notre element spoggy-sparql, il faut l'importer en incluant la ligne : 

<link rel="import" href="./spoggy-sparql/spoggy-sparql.html">

et ensuite le positionner entre les balises <template> .... </template>




Ce qui nous donne en consultant la page http://127.0.0.1:8081 (si vous avez arrêté le serveur avec Ctrl+C, relancez-le avec 'polymer serve'




Jusque là, tout va bien, attention, ça se corse...


ETAPE 2 : CREATION DE L'ELEMENT SPOGGY-SPARQL QUI VA EFFECTUER LES REQUETES VERS LE ENDPOINT


Bon passons aux choses sérieuses. Maintenant que notre structure d'appli est prête, on va pouvoir utiliser tout le potentiel de Polymer, et notamment la réutilisation des web-components ou elements...

On va par exemple avoir besoin du composant <iron-ajax> qui nous permettra d'effectuer les requêtes ajax asynchrones...

Sans plus tarder, entrons dans le vif du sujet : 
Placez-vous dans le dossier 'public' et installez le composant 'iron-ajax' : ( si vous n'avez pas encore installé bower, installez-le maintenant en global avec la commande 'npm install -g bower' ) 


 Vous pouvez retrouver les composants installés dans le dossier 'public/bower_components'
Maintenant que le composant iron-ajax est installé, on va pouvoir l'inclure dans notre composant 'spoggy-sparql'... C'est bon ? vous suivez toujours ???

De la même façon que tout à l'heure, il faut importer le composant avec la ligne : 

<link rel="import" href="../../bower_components/iron-ajax/iron-ajax.html">

et le placer entre les balises <templates></templates>

Ici, rien n’apparaît car le composant <iron-ajax> ne sert qu'à faire des requêtes, il n'a pas de 'visuel', mais on s'occupera de ça plus tard.



Tout va bien ? 
On attaque maintenant la requête

ETAPE 3 : LA REQUETE VERS L'ENDPOINT SPARQL.

Donc, ce qui nous intéresse, Thérèse, c'est d'aller chercher des data à l'adresse http://data.persee.fr/sparql . Ne soyons pas plus royalistes que ceux qui le sont déjà, sur cette page, il y a déjà un exemple de reqûete que voici : 

select distinct ?p where {?p a foaf:Person} LIMIT 100

On va pas aller chercher plus loin pour l'instant...
Mais il va falloir paramétrer notre élement <iron-ajax>.
le composant iron-ajax a en effet besoin de quelques paramètres : 
  • id : un identifiant, ça ne fait pas de mal, et on en aura besoin plus tard pour lancer la requête
  • url : une url, pour savoir à quelle adresse effectuer la requête
  • param : des options qui vont contenir le corps de la requête
  • handle-as : on défini le format dans lequel on souhaite recevoir le résultat de la requête
  • on-response : la fonction à exécuter lorsque un résultat est disponible (Attention au 's' dans _handleResponse, avec un 's' comme en anglais, je me suis fait avoir plus d'une fois...
  • on-error : la fonction à exécuter en cas d'erreur de la requête (ça peut être utile)

On peut donc remplacer <iron-ajax></iron-ajax> par :

<iron-ajax
id="sparqlRequest"
url="{{url}}"
params="{{options}}"
handle-as="application/sparql-results+json"
on-response="_handleResponse"
on-error="_handleError"></iron-ajax>



En fait, ici, nous n'avons pas défini 'url' et 'params', mais nous avons mis en face des variables Polymer ( reconnaissables avec les doubles accolades {{...}}), cela nous permet de les modifier plus facilement, donc allons y, c'est un peu plus bas, toujours dans le fichier spoggy-sparql.html, dans la fonction 'properties (){...}'

Et on va remplir les variables pour accéder à l'endpoint de Persée : 
 url avec 'http://data.persee.fr/sparql'
 et options avec la requête :  'select distinct ?p where {?p a foaf:Person} LIMIT 100 '
... voici ce qu'il faut ajouter : 


  url: {
          type: String,
          value: 'http://data.persee.fr/sparql'
        },
        options: {
          type: Object,
          value: {
            query:  'select distinct ?p where {?p a foaf:Person} LIMIT 100',
            format: 'application/sparql-results+json',
          }
        }





ETAPE 4 : LANCER LA REQUETE ET RECUPERER LES RESULTATS.


Commençons par créer un bouton pour lancer la requête : 
Comme d'habitude, on va inclure un element <paper-button> et lui mettre une fonction quand on clique dessus : 
installer le composant paper-button : 
dans 'public' executez la commande :  bower install paper-button



Puis importez-le dans notre module spoggy-sparql... 
Comme d'habitude : 
import : 

 <link rel="import" href="../../bower_components/paper-button/paper-button.html">

placement entre les balises <template>...</templates> avec le code : 

  <paper-button on-tap="executeRequete" raised> Executer la requête</paper-button>




Et ça donne quoi ??? Ben y'a qu'à aller voir sur http://127.0.0.1:8081, et actualiser la page via la touche F5, ou le bouton de rafraîchissement de page pour qu'elle se recharge



On a bien notre bouton (1) mais quand on clique dessus, on a une erreur dans la console (2): 
 listener method `executeRequete` not defined

Ah bah oui, mince, on n'a pas défini la méthode 'executeRequete' qu'on souhaite utiliser lors de l'evenement 'on-tap' du bouton (quand on clique sur le bouton)... Et bien allons-y, définissons cette méthode... son rôle ??? on a dit que quand on clique sur le bouton, on l'application devait executer la requête, non? Ok, c'est parti, attention c'est trop hard : 

Cette fois, c'est après la fonction 'properties', et il faut ajouter (voir n°3 dans l'image qui suit): 

    executeRequete(){
      this.$.sparqlRequest.generateRequest()
    }

ici, on utilise l'identifiant de notre requete 'sparqlRequest' et on lui applique la fonction 'generateRequest()' .... Tu vois... trop dur ...

Et tant qu'on y est, maintenant, je te sens chaud, allez, on se lâche, on écrit la fonction qu'on avait définie pour récupérer les résultats, rappelle-toi, c'est la fonction '_handleResponse' dans la requete <iron-ajax> (voir n°4 dans l'image qui suit)


    _handleResponse(data){
      console.log("Reponse Sparql");
      //  console.log(data);
      //  console.log(data.detail);
      //  console.log(data.detail.error);
      //  console.log(data.detail.error.message);
      //  console.log(data.detail.request);
      console.log(data.detail.response);
      let response = JSON.parse(data.detail.response);
      let link = response.head.link;
      let vars = response.head.vars;
      let results = response.results.bindings;
      console.log(results);
    }



Maintenant quand on clique sur le bouton, les résultats s'affichent dans la console, mais c'est déjà pas mal....

ETAPE 5 : AFFICHAGE DES RESULTATS SOUS FORME DE LISTE.

Mouais dans la console, ça fait pas une appli, ça, donc, on vas récupérer ces résultats, les mettre dans une variable de l'appli (this.results) et utiliser un nouveau composant Polymer (dom-repeat) pour boucler sur les resultats, agrémenté d'un autre composant, paper-item, qui est tout approprié pour afficher des listes...

Ajoutez à la fin de la fonction _handleResponse la ligne 'this.results = results'

ce qui nous donne : 
_handleResponse(data){
      console.log("Reponse Sparql");
      //  console.log(data);
      //  console.log(data.detail);
      //  console.log(data.detail.error);
      //  console.log(data.detail.error.message);
      //  console.log(data.detail.request);
      console.log(data.detail.response);
      let response = JSON.parse(data.detail.response);
      let link = response.head.link;
      let vars = response.head.vars;
      let results = response.results.bindings;
      console.log(results);
this.results = results;
    }



 Maintenant que nous avons sorti nos 'results' de la fonction et l'avons affecté à une variable du composant spoggy-sparql, 


on peut boucler dessus en ayant pris soin : 
  • d'avoir installé le composant 'paper-item'  avec la commande 'bower install paper-item' 

  • d'avoir importé les composants 'dom-repeat' et 'paper-item' (voir n°5)
<!-- import template repeater -->
<link rel="import" href="../../bower_components/polymer/lib/elements/dom-repeat.html">
<link rel="import" href="../../bower_components/paper-item/paper-item.html">


  • d'insérer le code pour boucler (voir n°6)
  <template is="dom-repeat" items="[[results]]">
      <paper-item >[[item.p.value]]</paper-item>
    </template>



Et le résultat ? 

Une liste des résultats issus de Persée....





A vous maintenant de nettoyer les résultats, les mettre en forme, changer la requête...
pourquoi pas une requête du style :
'SELECT DISTINCT ?s ?t ?sub
WHERE {
?s ?p bibo:Document.
?s dcterms:title ?t.
?s dcterms:subject ?sub.
filter (lang(?sub) = "" || langMatches(lang(?sub), "fr"))
} LIMIT 300'

???


Pour récupérer le code de ce tutoriel c'est https://github.com/scenaristeur/tutosparql


Un truc sympa, à mon humble avis, c'est de coupler avec VisJs,
Pour voir ce que ça donne, utilisez Spoggy pour vous brancher sur Persée ou DbPedia: http://spoggy.herokuapp.com/

ATTENTION utilisez l'adresse http://spoggy.herokuapp.com/ et non httpS://spoggy.herokuapp.com/  --> sans le 's' de https, car http://data.persee.fr/sparql n'est pas accessible en mode sécurisé

Voir la vidéo Quand Spoggy utilise Polymer pour s'attaquer à Persée...

Pour participer au projet Spoggy : https://github.com/scenaristeur/heroku-spoggy

Ps : tu auras peut-être remarqué que parfois que vous ai tutoyé... Normal,... dans les moments difficiles, il faut savoir être soudé...





  


















24/01/2018

Apprendre à coder, Par où commencer quand on n'y connait rien ?

Ce qui est sympa quand on apprend à coder, c'est de voir les changement rapidement.
Le logiciel avec lequel je me suis le plus éclaté, c'est Processing, conçu à la fois pour l'éducation et les performances artistiques...

J'ai commencé avec "Learning Processing" (et ses exemples) et "The Nature Of Code" écrits par Daniel Shiffman, qui sévi maintenant en vidéos :  http://shiffman.net/videos/ .

Le logiciel Arduino  pour ceux qui s'intéressent aux objets connectés ou à la robotique est également basé sur Processing (avec quelques exemples).
Il existe même une version Android pour ceux qui souhaiteraient pouvoir coder sur leur smartphone en attendant leur bus ( rigolez pas, ça m'est arrivé), il suffit de télécharger l'appli APDE sur le PlayStore.

Processing permet de créer des programmes sur votre ordi (Windows / Linux ou MAC), APDE des applis Android, mais celui qui me parait le plus intéressant actuellement c'est P5JS.

Vous pouvez soit télécharger le fichier ZIP (P5JS COMPLETE), et modifier l'exemple, soit utiliser directement l'éditeur en ligne  https://alpha.editor.p5js.org/.
 (on doit pouvoir enregistrer son travail en s'abonnant, sinon copiez votre code avec Ctrl+c et collez le dans un fichier texte sur votre ordi avec Ctrl+v ).
Pour retrouver facilement l'éditeur en ligne, recherchez "p5js online" sur Google .

Commencez par P5js online, (allez voir notamment les exemples dans 'Files/Example').

On va commencer par faire quelques tests, mais pour aller plus loin (image, video, gestion de plusieurs fichiers, utilisation de librairies, il faudra téléchargez 'P5JS Complete' pour travailler sur votre ordi.
On y reviendra, mais sous son allure très simple, P5js permet de faire des choses monstrueuses. Vous ne me croyez pas ? Allez donc jeter un oeil sur Open Processing, cliquez sur l'un des exemples, au hasard, son code est accessible en cliquant sur l'icône '</>' et pour executer le code, c'est sur le triangle 'play' (ça sera toujours le même que ce soit sur Processing, APDE, P5JS)...

Ce qui peut vous être utile, si vous bloquez, ou pour avoir des exemples d'utilisation des fonctions,  c'est d'aller voir les "REFERENCES" ou "EXEMPLES" de chacun des logiciels :

P5JS : REFERENCE & EXEMPLES
PROCESSING : REFERENCE & EXEMPLES
APDE : https://github.com/Calsign/APDE/wiki


Les librairies sont des extensions du logiciel.


Programmer , c'est quoi ? A la base, c'est écrire du code pour créer une application, automatiser une tâche, transformer des données, mais avec Processing et toute la série ( je parlerais de Processing de manière générale), ça va un peut plus loin, et on peut pousser le côté créatif / artistique assez facilement, enfin ça ça dépend de chacun... Fonctionnel / Visuel...


Pour une première approche, on va se concentrer sur l'éditeur online de P5js que vous pouvez ouvrir en cliquant ici  : https://alpha.editor.p5js.org/

Par défaut, dans chacun de ses logiciels, on trouve deux fonctions :
- une fonction 'setup' qui permet de mettre en place l'environnement
- un fonction 'draw' (ou 'loop' dans le logiciel Arduino) qui boucle à l'infini tant qu'on ne l'arrête pas expressément.

Quelques notions essentielles sont nécessaires :
- une variable est un espace de stockage en mémoire dans laquelle on va pouvoir stocker une chaine de caractères, un nombre, un objet;
- une fonction est une action que l'on va pouvoir appeler à plusieurs endroits sans être obligé de la réécrire.

Une fonction commence par le mot 'function' , suivi du nom de la fonction, suivi d'un couple de parenthèse, suivi d'un couple d'accolades. Les parenthèses seront utilisées pour envoyer des paramètres à la fonction, et les accolades contiendront le corps de la fonction, ce qu'elle fera réellement.


Bien maintenant, nous avons tout pour commencer.
En ouvrant l'editeur P5js online, vous pouvez cliquer sur le 'triangle PLAY' pour lancer le programme présent, et le carré 'STOP' pour arrêter.

function setup() { 
  createCanvas(400, 400);
} 

function draw() { 
  background(220);
}


En fait on a déjà, ici 4 fonctions : setup et draw, les deux fonctions que nous venons de voir et
- la fonction 'createCanvas(400,400);' qui créé notre espace de travail de 400 pixels de largeur par 400 pixels de hauteur. le premier pixel, de coordonnées (0,0) se situant en haut à gauche, et le dernier pixel, de coordonnées (400,400) si situant en bas à droite, et vers le milieu de notre espace de travail, on aura le pixel (200,200) jusque là, tout va bien ????

[vous pouvez remplacer les 400 par d'autres valeurs, pour modifier la taille de votre espace de travail.]

Ok, on continue...
Noter que chaque commande se termine par un point-virgule, vous risquez d'en oublier parfois, mais vous vous en rendrez vite compte : votre programme ne se lancera pas, et vous aurez un message d'erreur, dans la console (cadre gris, en bas à gauche) vous indiquant un truc du style :


Uncaught SyntaxError: missing ; after argument list (sketch: line 2)

la fonction 'backgound (220);'
est la seule action exécutée actuellement, et elle remplit le fond (et oui, background = fond, on est obligé de comprendre un peu l'anglais quand on veut programmer !)
On remplit ici le fond avec la couleur (220);

Pour les couleurs, une seule valeur, indique un niveau de gris : 0 = noir, 255 = blanc.
Pour un peu plus de fun, les couleurs peuvent aussi s'écrire comme un triplet de valeurs (rouge, vert, bleu) allant de 0 à 255.
ainsi la couleur (255, 0, 0) vous donnera du rouge.

Pour vérifiez, modifiez le code ainsi :

function setup() { 
  createCanvas(400, 400);
} 

function draw() { 
  background(255, 0, 0);
}

Votre fond devrait devenir rouge. Pour trouver vos couleurs favorites allez voir ici et noter les valeurs RVB de vos couleurs.

STROKE & FILL


Deux autres fonctions qui vous seront très utiles, et qui se placent avant les éléments que l'on veut dessiner:
- 'stroke()' détermina la couleur de votre trait,
- et 'fill()' la couleur de remplissage.

J'en ajoute deux tant qu'on est là, mais ces deux-ci ne devraient pas vous pposer de problèmes :
- rect() permet de dessiner un rectangle, et
- ellipse() permet de dessiner une ellipse.... Wahou, trop dur....

Vous pouvez tester le code suivant qui vous dessinera, sur fond rouge, un rectangle vert dont le contour est jaune et une ellipse jaune dont le contour est vert :

function setup() { 
  createCanvas(400, 400);
function draw() { 
  background(255, 0, 0);
stroke(255,255,0); 
fill(42,156,23);
rect(50, 50, 75, 100);
stroke(42,156,23);
fill(255,255,0); 
ellipse(250, 350, 75, 100);
}

Pour 'rect' et 'ellipse', on utilise 4 paramètres : les deux premiers, sont les coordonnées, l'endroit où l'on va dessiner les éléments, le troisième correspond à la largeur, et le quatrième à la hauteur.

On a déjà bien avancé, non ? Profitez-en pour faire une pause, vous pouvez ajouter des cercles, des rectangles et pourquoi pas un triangle ???

Vous pouvez aussi vous inspirer de ZOOG, le personnage de  "Learning Processing"



notez la notation des commenatires par la double barre oblique // et les commentaires sur plusieurs lignes entourés par /*......*/

// un commentaire sur une ligne
function setup() { 
/* ici 
un 
commentaire
sur
plusieurs
lignes */
  createCanvas(400, 400);
function draw() { 
  background(121, 248, 248);
ellipseMode(CENTER);
rectMode(CENTER); 
// Corps
stroke(0);
fill(247,255, 56);
rect(240, 145, 20, 100);
// Tête
fill(0, 255, 0);
ellipse(240, 115, 60, 60); 
// Yeux
fill(0); 
ellipse(221, 115, 16, 32); 
ellipse(259, 115, 16, 32);
// Jambes
stroke(0);
line(230, 195, 220, 205);
line(250, 195, 260, 205); 
}

Pas la peine que je vous explique à quoi servent les deux fonctions, je vous laisse découvrir par vous même leur utilité ou allez voir la "référence" :

ellipseMode(CENTER);  --> https://p5js.org/reference/#/p5/ellipseMode
rectMode(CENTER); --> https://p5js.org/reference/#/p5/rectMode

Interaction
Un peu plus de fun ? Ajoutons de l'interaction, en utilisant la position de la souris, elle est définie par deux variables prédéfinies : 'mouseX' et 'mouseY', et poussons le bouchon, en utilisant la position précédente de la souris 'pmouseX' et 'pmouseY', ajoutons une action lors du clic 

function setup() { 
  createCanvas(400, 400);
// La vitesse est réglée 30 images par seconde.
  frameRate(30);
function draw() { 
  background(121, 248, 248);
ellipseMode(CENTER);
rectMode(CENTER); 
// Corps
stroke(0);
fill(247,255, 56);
rect(mouseX, mouseY, 20, 100);
// Tête
fill(0, 255, 0);
ellipse(mouseX, mouseY-30, 60, 60);
// La couleur des yeux est déterminée en fonction de la position de la souris.
  fill(mouseX/2, 0, mouseY/2); 
  ellipse(mouseX-19, mouseY-30, 16, 32); 
  ellipse(mouseX+19, mouseY-30, 16, 32); 
// Jambes
stroke(0);
// Les jambes sont dessinées en fonction de la position de la souris et de sa position précédente.
  line(mouseX-10, mouseY+50, pmouseX-10, pmouseY+60);
  line(mouseX+10, mouseY+50, pmouseX+10, pmouseY+60);
}
function mousePressed() {
  console.log("Mets moi dans ta poche!");
}

référence : http://learningprocessing.com/examples/chp03/example-03-06-interactive-zoog


Les yeux de ZOOG changent de couleur en fonction de la position de la souris, les jambes semblent trainer, et quand on clique ( function moussePressed )  un message est écrit dans la console ( cadre gris en bas à gauche).


Jetez aussi un oeil sur cette page pour voir quelques interactions avec le clavier .

Notez au passage l'utilisation des conditions:
- si (condition) alors faire {...} sinon faire {...}

function setup(){

 createCanvas(480, 270);

}



function draw() {

  background(255);

  stroke(0);

  line(240, 0, 240, 360);

  line(0, 135, 640, 135);



  // Fill a black color

  noStroke();

  fill(0);



  // Depending on the mouse location, a different rectangle is displayed.    

  if (mouseX < 240 && mouseY < 135) {

    rect(0, 0, 240, 135);

  } else if (mouseX > 240 && mouseY < 135) {

    rect(240, 0, 240, 135);

  } else if (mouseX < 240 && mouseY > 135) {

    rect(0, 135, 240, 135);

  } else if (mouseX > 240 && mouseY > 135) {

    rect(240, 135, 240, 135);

  }

}


et des boucles :
Pour 'i' de 0 à la moitié de la largeur (width/2) , avec un pas de 10, dessiner un rectangle commencant à la position (i,10), de largeur 3 et de hauteur 200+i.

function setup(){

createCanvas(500,500);

}



function draw(){

fill(255,115,143);



for(var i=0; i<width/2 ; i+=10){

    rect(i, 10, 3, 200+i);

  }

}

[ 'width' correspond à la largeur de l'environnement de travail, ou canvas, 'height' correspond à la hauteur ]

On a encore plein de trucs à voir comme les Objets/ Classes, les tableaux d'objets, ou comment utiliser des librairies externes, mais vous devriez maintenant être armé pour aller triturer
quelques démos sur Open Processing ou modifier le code du jeu basé sur  slither.io

En cas de doute, consultez la REFERENCE P5JS