<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Claude au pays des 4J</title>
	<atom:link href="http://cfalguiere.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://cfalguiere.wordpress.com</link>
	<description>Java/JEE (outils, langage) et mesure des performances, et d&#039;autres choses utiles.</description>
	<lastBuildDate>Mon, 16 Jan 2012 13:29:23 +0000</lastBuildDate>
	<language>fr</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='cfalguiere.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/f7f1292b946d3fa5665ecd637b19d046?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Claude au pays des 4J</title>
		<link>http://cfalguiere.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://cfalguiere.wordpress.com/osd.xml" title="Claude au pays des 4J" />
	<atom:link rel='hub' href='http://cfalguiere.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Alohomora Incanter-4</title>
		<link>http://cfalguiere.wordpress.com/2012/01/14/alohomora-incanter-4/</link>
		<comments>http://cfalguiere.wordpress.com/2012/01/14/alohomora-incanter-4/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 20:01:21 +0000</pubDate>
		<dc:creator>cfalguiere</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Duchess]]></category>
		<category><![CDATA[French]]></category>
		<category><![CDATA[Incanter]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Valtech]]></category>

		<guid isPermaLink="false">http://cfalguiere.wordpress.com/?p=1185</guid>
		<description><![CDATA[Quand on ne sait plus trop où trouver des formules magiques, il reste Harry Potter, Alohomora l&#8217;incantation qui ouvre les portes, les portes de la voie des statistiques. Allez au boulot, on a du rangement à faire. Cet article fait partie d&#8217;une suite qui commence avec cet article épisode 1. Recharger les données First things [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=1185&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div style="margin-top:30px;height:205px;">
<div style="float:left;"><a href="http://incanter.org/"><img class="alignleft" style="margin:0 35px 20px 25px;" title="Incanter logo" src="http://incanter.org/incanter-i-logo-holo.png" alt="Incanter logo" width="173" height="175" /></a></div>
<p>Quand on ne sait plus trop où trouver des formules magiques, il reste Harry Potter, Alohomora l&#8217;incantation qui ouvre les portes, les portes de la voie des statistiques.</p>
<p>Allez au boulot, on a du rangement à faire.</p>
<p>Cet article fait partie d&#8217;une suite qui commence avec cet article <a href="http://cfalguiere.wordpress.com/2011/12/17/abracadabra-incanter/">épisode 1</a>.</p>
</div>
<h3 style="margin-top:40px;">Recharger les données</h3>
<p>First things first, charger nos librairies et nos données et on reprend où on en était dans l&#8217;épisode 3.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (use '(incanter core io datasets stats))</strong><br />
nil<br />
<strong>user=&gt; (def data (read-dataset<br />
"/Users/cfalguiere/Workspaces/Diapason/report-data/20111217-ETALON_WSW_TPS2011.csv" :header true))</strong><br />
#'user/data </code></div>
<p>Il est grandement temps de faire une fonction qui charge les résultats. On peut être sorcier et fainéant.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (defn read-results []<br />
&nbsp;&nbsp;(read-dataset "/Users/cfalguiere/Documents/2012-01/RD-Clojure/Workspace/incanter/resources/sample-results.csv" :header true))</span><br />
#'user/read-results </code></div>
<p>N&#8217;oubliez pas les parenthèses, sinon au lieu du prince charmant vous auriez une jolie mangouste, jolie mais bon ça n&#8217;est pas ce que vous vouliez. En l&#8217;occurrence, vous ne voulez pas que data représente la fonction mais son résultat.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt;(def data read-results)</strong><br />
#'user/data<br />
<strong>user=&gt; data</strong><br />
#&lt;user$read_results user$read_results@6bd46c20&gt; </code></div>
<p>Donc voilà, le tour exécuté correctement et quelques donnnées présentes.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt;(def data (read-results))</strong><br />
#'user/data </code></div>
<p>Pour le moment j&#8217;expérimente interactivement, donc peu importe l&#8217;IDE. Lançons un éditeur de texte pour copier ce code et chargeons le dans le REPL.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>(use '(incanter core io datasets stats))<br />
<br />
(def result-file-name "/Users/cfalguiere/Documents/2012-01/RD-Clojure/Workspace/incanter/resources/sample-results.csv")<br />
<br />
(defn read-results []<br />
&nbsp;&nbsp;(read-dataset result-file-name :header true))<br />
<br />
(def data (read-results)) </code></div>
<p>J&#8217;aimerais bien indiquer le répertoire courant pour éviter tout ces chemins mais à la différence de R on ne peut pas changer le répertoire courant, parce que la JVM ne permet pas de le faire. Mais au fait quel serait mon répertoire courant ? Une rapide recherche sur Google indique ça :</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (. (java.io.File. ".") getCanonicalPath) </span><br />
"/Applications"</code></div>
<p>Un peu ésotérique. C&#8217;est plus clair avec un exemple plus évident comme la méthode <code>toUpperCase</code> de la classe String. Le . applique la méthode à l&#8217;objet.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt;(. "aaa" toUpperCase)</span><br />
"AAA"</code></div>
<p>Il ne reste plus qu&#8217;à charger le programme et data est disponibles pour d&#8217;autres tours.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt;(load-file "/Users/cfalguiere/Documents/2012-01/RD-Clojure/workspace/incanter/tuto1.clj")<br />
</strong>#'user/data<br />
<strong>user=&gt; (nrow data)</strong><br />
209</code></div>
<h3 style="margin-top:40px;">Agrégeons, agrégeons, ils en restera toujours quelque chose</h3>
<p>En général, j&#8217;aime bien avoir une vue d&#8217;ensemble de mes données : temps max, temps moyen, taux d&#8217;erreur &#8230;</p>
<p>Qu&#8217;est ce que j&#8217;ai là dedans ?</p>
<p>Le dataset est une map qui contient un vecteur de labels et une liste de lignes de données. La fonction col-names retourne les labels des colonnes (c&#8217;est équivalent <code>(:column-names data))</code></p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (col-names data) </span><br />
[:lb :t :lt :ts :s :rc :rm :by :na]<br />
<span style="font-weight:bold;">user=&gt; (:column-names data) </span><br />
[:lb :t :lt :ts :s :rc :rm :by :na] </code></div>
<p>Les labels JMeter ne sont pas des plus parlants pour des raisons de compacité du résultat.</p>
<p>Pour chaque relevé nous disposons des informations suivantes :</p>
<ul>
<li><span style="font-weight:bold;">:t </span>le temps de réponse,</li>
<li><span style="font-weight:bold;">:lt</span> le &#8216;latency time&#8217; c&#8217;est à dire le temps qui s&#8217;est écoulé jusqu&#8217;à la réception du premier octet de la réponse,</li>
<li><span style="font-weight:bold;">:by</span> le nombre d&#8217;octets de la réponse,</li>
<li><span style="font-weight:bold;">:na</span> : le nombre d&#8217;utilisateurs simulés au moment de cette requête,</li>
<li>:rc le code retour de la requête HTTP, habituellement 200 ou 302,</li>
<li>:s le résultat des assertions sur les contenus reçus (true ou false),</li>
<li>:rm : un message,</li>
<li>:lb le label soit le nom donné au sample dans le script JMeter soit une url,</li>
<li>:ts  le timestamp du relevé.</li>
</ul>
<p>Les 4 premières lignes sont des séries numériques. Les autres sont des catégories (l&#8217;équivalent des factors pour R). Elles vont servir à filtrer (pour les statuts) ou à regrouper les données.</p>
<p>Le module <a href="http://clojuredocs.org/incanter/incanter.stats">stats</a> fourni les statistiques habituelles. Pour faire quelques expériementations, on va générer une série de nombres dont la moyenne est connue. <code>sample-normal</code> construit une liste de 1000 nombres distribués selon une loi normale centrée sur 10 avec un écart-type de 1. Sans surprise, la moyenne est autour de 10 et l&#8217;écart type est autour de 1.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code style="font-weight:bold;">user=&gt; <span style="font-weight:bold;">(def mysample (sample-normal 1000 :mean 10 :std 1))</span><br />
(10.099828740537856 9.903470850168006 9.52228847634955 9.003518490739022 9.171579274811812 ...<br />
<span style="font-weight:bold;">user=&gt; (mean mysample) </span><br />
9.941436842660105<br />
<span style="font-weight:bold;">user=&gt; (sd mysample) </span><br />
1.0007997747452984 </code></div>
<p>Et min et max ?</p>
<div style="float:right;margin-left:30px;"><a href="http://cfalguiere.files.wordpress.com/2011/12/histogram-mysample-colors.png"><img class="alignright size-medium wp-image-1191" title="histogram-mysample-colors" src="http://cfalguiere.files.wordpress.com/2011/12/histogram-mysample-colors.png?w=300&#038;h=226" alt="présentation des 4 quartiles" width="300" height="226" /></a></div>
<p>Un magicien ne voit pas les choses aussi simplement. Le min est la valeur qui est inférieure à tous les autres relevés. Et symétriquement le max est la valeur qui est supérieure à tous les autres relevés.</p>
<p>Mais les magiciens aiment bien découper les données en tranches. Donc ils veulent aussi savoir quelle est la valeur qui sépare les relevés en deux groupes, inférieurs et supérieurs à une valeur qui s&#8217;appelle la médiane.</p>
<p>Pour améliorer le spectacle, les données sont découpées en quatre tranches par pas de 25% comme le montre le schéma de droite, ce sont des quartiles. On voit sur le schéma que la surface rouge qui représente les 25% les plus bas se termine vers 9, la surface bleu qui représente les 25% suivants se termine vers 10 etc.</p>
<p>Les valeurs de 25% sont arbitraires. La forme générale de cet agrégat est le quantile. La fonction <code>quantile </code>retourne le min, la valeur maximale pour 25% des relevés, 50% (la médiane) et 75%, et le max (le quantile 100%).</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (quantile mysample) </span><br />
(6.078738192126153 9.284660278736457 9.9269193454763 10.609659921191085 12.899443382831647) </code></div>
<p>Le monde étant ce qu&#8217;il est les sorciers qui font du test de charge ne s&#8217;intéressent pas aux quantiles des magiciens. En fait la seule chose qui les intéressent, c&#8217;est l&#8217;impact des 5% ou 10% de temps les plus longs. Donc ils calculent la valeurs maximale pour 90% ou 95% des relevés.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (quantile mysample :probs 0.95) </span><br />
11.591767882673627<br />
<span style="font-weight:bold;">user=&gt; (quantile mysample :probs [0.9 0.95]) </span><br />
(11.278966306153395 11.591767882673627) </code></div>
<p>Qu&#8217;est ce que ça donne sur nos données de test ?</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (mean ($ :t data)) </span><br />
1429.579831932773<br />
<span style="font-weight:bold;">user=&gt; (sd ($ :t data)) </span><br />
2237.25502018713<br />
</code></div>
<p>On peut faire toutes ces opérations sur la même série de données en utilisant la fonction associée au dataset <code>with-data</code>. Elle  factorise le dataset et permet de définir l&#8217;expression à utiliser, ici construire un tableau contenant les différentes métriques. $data représente la série à l&#8217;intérieur du <code>with-data</code>.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (with-data ($ :t data)<br />
&nbsp;&nbsp;[(mean $data)(sd $data)]) </span><br />
[1429.579831932773 2237.25502018713] </code></div>
<p>Si on rajoute le quantile ça nous donne ce qui suit. Un bon début, mais on a un tableau des différents indicateurs plus une liste avec les quantiles.<code></code></p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (with-data ($ :t data)<br />
&nbsp;&nbsp;[(count $data)(mean $data)(sd $data)(quantile $data :probs[0 0.5 0.9 0.95 1])]) </span><br />
[119 1429.579831932773 2237.25502018713 (10.0 708.0 3393.4 4130.999999999982 13007.0)]<br />
</code></div>
<p>Mmm &#8230; un coup de baguette magique <code>flatten</code> et les données se retrouvent bien alignées dans le tableau.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (with-data ($ :t data)<br />
&nbsp;&nbsp;(flatten [(count $data)(mean $data)(sd $data)(quantile $data :probs[0 0.5 0.9 0.95 1])]) ) </span><br />
(119 1429.579831932773 2237.25502018713 10.0 708.0 3393.4 4130.999999999982 13007.0) </code></div>
<p>Une variable pour stocker le résultat et on sauve</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (def stats<br />
&nbsp;&nbsp;(with-data ($ :t data)<br />
&nbsp;&nbsp;&nbsp;&nbsp;(flatten [(count $data)(mean $data)(sd $data)(quantile $data :probs[0 0.5 0.9 0.95 1])]) ) ) </span><br />
#'user/stats<br />
<span style="font-weight:bold;">user=&gt; stats</span><br />
(119 1429.579831932773 2237.25502018713 10.0 708.0 3393.4 4130.999999999982 13007.0) </code></div>
<p>Quoique, pas tout de suite apparemment.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (save 'stats "stats.csv")</span><br />
java.lang.IllegalArgumentException: No method in multimethod 'save' for dispatch value: class clojure.lang.Symbol (NO_SOURCE_FILE:0) </code>
</div>
<h3 style="margin-top:40px;">En quête d&#8217;une multiméthode &#8230;</h3>
<p>Que peut bien être une multiméthode ?</p>
<p>Vous trouverez une réponse complète dans cet article sur le <a href="http://clojure.org/runtime_polymorphism">polymorphisme</a> en Clojure. En quelques mots, c&#8217;est le mécanisme qui permet à une fonction de se comporter différement en fonction des paremètres qu&#8217;on lui passe (des nombres ou des chaînes par exemple).</p>
<p>Vous avez probablement déjà noté que les fonctions en clojure sont souvent définies pour plusieurs nombres d&#8217;arguments (l&#8217;<a href="http://en.wikipedia.org/wiki/Arity">arité</a> de la fonction si vous voulez briller la nuit au prochain ParisJUG). Clojure permet qu&#8217;une fonction soit <a href="http://clojure.org/special_forms#fn">surchargée</a> (overloaded en anglais) et elle peut ainsi avoir une définition différente selon le nombre d&#8217;arguments.</p>
<p>Ci-après un exemple très simple de surcharge qui crée une map rectangle avec 1 ou 2 paramètres. La forme a un seul paramètre utilise la forme a 2 paramètres pour construire un carré.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (defn make-rectangle<br />
&nbsp;&nbsp;([width] (make-rectangle width width))<br />
&nbsp;&nbsp;([width height] {:width width :height height}))</span><br />
#'user/make-rectangle<br />
<span style="font-weight:bold;">user=&gt; (make-rectangle 20)</span><br />
{:width 20, :height 20}<br />
<span style="font-weight:bold;">user=&gt; (make-rectangle 10 20)</span><br />
{:width 10, :height 20} </code></div>
<p>Autre exemple plus compliqué, la multiplication implémentée de manière récursive en utilisant 4 formes :</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>(def mult<br />
&nbsp;&nbsp;(fn this<br />
&nbsp;&nbsp;&nbsp;&nbsp;([] 1)<br />
&nbsp;&nbsp;&nbsp;&nbsp;([x] x)<br />
&nbsp;&nbsp;&nbsp;&nbsp;([x y] (* x y))<br />
&nbsp;&nbsp;&nbsp;&nbsp;([x y &amp; more]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(apply this (this x y) more)))) </code></div>
<p>La fonction est définie pour 0, 1, 2 arguments et un nombre quelconque d&#8217;arguments. Le &amp; indique que ce qui se trouve à droite contient une liste d&#8217;arguments, et c&#8217;est par ce moyen qu&#8217;on définie une <a href="http://en.wikipedia.org/wiki/Varargs">fonction variadique</a> (pour quand vous ne brillerez plus assez avec arité).</p>
<p>Décryptons un peu cette multiplication. Tout d&#8217;abord, cet exemple n&#8217;utilise pas la macro <code>defn</code>, on a donc deux les étapes, décrire la fonction (<code>fn</code>) et la nommer (<code>def</code>). La multiplication utilise 4 variantes. Dans le cas général (4) je prend les 2 paramètres les plus à gauche, je leur applique &#8220;moi-même&#8221; <code>(this x y) </code>et j&#8217;applique ensuite &#8220;moi-même&#8221; en utilisant ce résultat et tous les paramètres qui restent à droite (<code>more</code>). Si je n&#8217;ai que 2 paramètres (3), je les multiple. Si je n&#8217;en ai plus qu&#8217;un (2), je le renvoie. Si je n&#8217;en ai plus (1) je renvoie 1.</p>
<p>Et pourquoi <code>apply</code> ? <code>apply</code> est utilisé dans les contextes où le nombre d&#8217;élements n&#8217;est pas connu à la compilation et donc typiquement lorsque l&#8217;on déconstruit une séquence. Par exemple</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (+ 1 2 3 4 5)</span><br />
15<br />
<span style="font-weight:bold;">user=&gt; (+ [1 2 3 4 5])</span><br />
java.lang.ClassCastException (NO_SOURCE_FILE:0)<br />
<span style="font-weight:bold;">user=&gt; (apply + [1 2 3 4 5])</span><br />
15<br />
</code></div>
<p>L&#8217;addition du contenu de la séquence n&#8217;est pas possible directement. L&#8217;utilisation d&#8217;<code>apply</code> permet de déconstruire le tableau pour en lister les éléments et d&#8217;effectuer l&#8217;opération. Dans le cas de la fonction <code>mult</code>, <code>apply</code> permet de traiter <code>more</code> qui est une séquence.</p>
<p>Et ma multiméthode ?</p>
<p>La multiméthode est un mécanisme plus puissant qui permet de gérer le polymorphisme. La syntaxe est un peu différente et basée sur les verbes <code>defmulti</code> et <code>defmethod</code>.</p>
<p>L&#8217;exemple suivant montre une multiméthode &#8220;rencontre&#8221; entre différentes espèces. Si le paramètre 1 est un lapin et le paramètre 2 un lion, le comportement de &#8220;rencontre&#8221; est équivalent à la fonction &#8220;s&#8217;enfuit&#8221;. Dans le cas inverse, elle est équivalente à &#8220;mange&#8221;</p>
<pre class="text" style="font-family:Inconsolata, Monaco, Consolas, 'Lucida Console', 'Courier New', Courier, monospace!important;font-size:12px;line-height:18px;background-color:#ffffff;color:#272727;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;orphans:2;text-align:0;text-indent:0;text-transform:none;widows:2;word-spacing:0;border-color:#cccccc;border-style:solid;border-width:1px;margin:2em 0 3em!important;padding:10px;"><span class="parens" style="color:#000000;">(</span><span class="macro" style="color:#6600cc;">defmulti</span> encounter <span class="parens" style="color:#000000;">(</span><span class="macro" style="color:#6600cc;">fn</span> <span class="brackets" style="color:#000066;">[</span>x y<span class="brackets" style="color:#000066;">]</span> <span class="brackets" style="color:#000066;">[</span><span class="parens" style="color:#000000;">(</span><span class="keyword" style="color:#cc0099;">:Species</span> x<span class="parens" style="color:#000000;">)</span> <span class="parens" style="color:#000000;">(</span><span class="keyword" style="color:#cc0099;">:Species</span> y<span class="parens" style="color:#000000;">)</span><span class="brackets" style="color:#000066;">]</span><span class="parens" style="color:#000000;">)</span><span class="parens" style="color:#000000;">)</span>
<span class="parens" style="color:#000000;">(</span><span class="macro" style="color:#6600cc;">defmethod</span> encounter <span class="brackets" style="color:#000066;">[</span><span class="keyword" style="color:#cc0099;">:Bunny</span> <span class="keyword" style="color:#cc0099;">:Lion</span><span class="brackets" style="color:#000066;">]</span> <span class="brackets" style="color:#000066;">[</span>b l<span class="brackets" style="color:#000066;">]</span> <span class="keyword" style="color:#cc0099;">:run-away</span><span class="parens" style="color:#000000;">)</span>
<span class="parens" style="color:#000000;">(</span><span class="macro" style="color:#6600cc;">defmethod</span> encounter <span class="brackets" style="color:#000066;">[</span><span class="keyword" style="color:#cc0099;">:Lion</span> <span class="keyword" style="color:#cc0099;">:Bunny</span><span class="brackets" style="color:#000066;">]</span> <span class="brackets" style="color:#000066;">[</span>l b<span class="brackets" style="color:#000066;">]</span> <span class="keyword" style="color:#cc0099;">:eat</span><span class="parens" style="color:#000000;">)</span></pre>
<p>L&#8217;exemple complet se trouve dans cet article sur le <a href="http://clojure.org/runtime_polymorphism">polymorphisme</a> en Clojure.</p>
<p>Les multimethodes peuvent dispatcher en fonction des types des paramètres mais également sur des valeurs des arguments, leur nombre ou des méta-données selon la syntaxe.</p>
<p>Bref,  &#8220;<code>No method in multimethod 'save' for dispatch value: class clojure.lang.Symbol (NO_SOURCE_FILE:0)" </code>signifie seulement &#8220;je n&#8217;ai pas d&#8217;implémentation de save pour le type que tu m&#8217;envoie&#8221;. Oui, je sais &#8230;, mais les magiciens ne vont pas dévoiler tous leurs tours si facilement.</p>
<h3 style="margin-top:40px;">Enfin sauvé</h3>
<p><code> stats </code>est une liste et <code> save </code> est une fonction Incanter qui fonctionnera que sur une matrice ou un dataset.<br />
Qu&#8217;à celà ne tienne, on va construire un dataset avec ces données. Il faut lui indiquer les noms de colonnes et les valeurs.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; stats </span><br />
(119 1429.579831932773 2237.25502018713 10.0 708.0 3393.4<br />
4130.999999999982 13007.0)<br />
<span style="font-weight:bold;">user=&gt; (def statsds<br />
&nbsp;(dataset ["count", "mean", "sd", "min", "median", "q90", "q95", "max"] stats) )</span><br />
#'user/statsds<br />
<span style="font-weight:bold;">user=&gt; statsds </span><br />
#:incanter.core.Dataset{:column-names ["count" "mean" "sd" "min" "median" "q90" "q95" "max"],<br />
:rows ({"count" 119} {"count" 1429.579831932773} {"count" 2237.25502018713} {"count" 10.0} {"count" 708.0} {"count" 3393.4} {"count" 4130.99999</code><code>9999982} {"count" 13007.0})}<br />
<span style="font-weight:bold;">user=&gt; (view statsds)</span><br />
</code></div>
<div style="float:right;margin-left:30px;"><a href="http://cfalguiere.files.wordpress.com/2011/12/capture-d_c3a9cran-2011-12-30-c3a0-23-25-38.png"><img class="alignright size-medium wp-image-1201" title="Capture           d’écran 2011-12-30 à 23.25.38" src="http://cfalguiere.files.wordpress.com/2011/12/capture-d_c3a9cran-2011-12-30-c3a0-23-25-38.png?w=300&#038;h=172" alt="" width="300" height="172" /></a></div>
<p>Mmm, est ce bien ce que l&#8217;on veut ? Non, en fait le dataset n&#8217;est pas dans le bon sens. Il devrait avoir 1 ligne avec une colonne par indicateur.</p>
<p>Si vous allez sur la fonction <a href="http://liebke.github.com/incanter/core-api.html#incanter.core/dataset?">dataset</a> vous pouvez voir le source sous github. La fonction <code>dataset</code> attend une séquence de séquences ou une séquence de maps. Avec une simple liste, <code>dataset</code> a considéré que l&#8217;on voulait une liste de plusieurs lignes de 1 colonne.</p>
<div style="width:500px;">
<p>La façon la plus simple de résoudre le problème est de transformer la liste en dataset en la transposant pour qu&#8217;elle constitue 1 ligne de plusieurs colonnes. Ensuite on lui ajoute des noms de colonnes.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (def statsds (col-names<br />
&nbsp;&nbsp;(to-dataset stats :transpose true) ["count", "mean", "sd", "min", "median", "q90", "q95", "max"]) ) </span><br />
#'user/statsds<br />
<span style="font-weight:bold;">user=&gt; statsds </span><br />
#:incanter.core.Dataset{:column-names ["count" "mean" "sd" "min" "median" "q90" "q95" "max"],<br />
:rows ({"max" 13007.0, "q95" 4130.999999999982, "q90" 3393.4, "median" 708.0, "min" 10.0, "sd" 2237.25502018713, "mean" 1429.579831932773, "count" 119})}<br />
<span style="font-weight:bold;">user=&gt; (view statsds)</span><br />
</code></div>
</div>
<div style="float:right;"><a href="http://cfalguiere.files.wordpress.com/2011/12/capture-d_c3a9cran-2011-12-30-c3a0-23-29-321.png"><img class="alignright size-medium wp-image-1203" title="Capture           d’écran 2011-12-30 à 23.29.32" src="http://cfalguiere.files.wordpress.com/2011/12/capture-d_c3a9cran-2011-12-30-c3a0-23-29-321.png?w=300&#038;h=52" alt="" width="300" height="52" /></a></div>
<div style="width:200px;height:100px;">
Le dataset est bien dans le bon sens et on peut le sauver
</div>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (save statsds "/Users/cfalguiere/Documents/stats.csv")</span><br />
nil </code></div>
<p>Il manque juste une dernière info utile le taux d&#8217;erreurs et le top n.<br />
Pour le taux d&#8221;erreurs, on verra plus tard (surtout qu&#8217;il n&#8217;y en a pas dans le jeu de données) mais pour le top 5 des pires temps voici l&#8217;incantation trier-les-lignes-renverser-l-ordre-et-prendre-les-5-premiers</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><span style="font-weight:bold;">user=&gt; (take 5 (reverse (sort-by :t (:rows data)))) </span><br />
({:na 1, :by 172777, :rm "OK", :rc 200, :s "true", :ts 1.324109405557E12, :lt 1398, :t 13007, :lb "/CategoryDisplay"}<br />
{:na 1, :by 33235, :rm "OK", :rc 200, :s "true", :ts 1.324109282891E12, :lt 8967, :t 8981, :lb "/--product--.html"} ...<br />
</code></div>
<p>Et voilà d&#8217;autres tours de sorciers inscrits dans le grimoire. Dans l&#8217;épisode 5 on regroupera ces données pour avoir des résultats plus détaillés, par label par exemple et on fera des graphes de ces données.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cfalguiere.wordpress.com/1185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cfalguiere.wordpress.com/1185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cfalguiere.wordpress.com/1185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cfalguiere.wordpress.com/1185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cfalguiere.wordpress.com/1185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cfalguiere.wordpress.com/1185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cfalguiere.wordpress.com/1185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cfalguiere.wordpress.com/1185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cfalguiere.wordpress.com/1185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cfalguiere.wordpress.com/1185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cfalguiere.wordpress.com/1185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cfalguiere.wordpress.com/1185/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cfalguiere.wordpress.com/1185/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cfalguiere.wordpress.com/1185/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=1185&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cfalguiere.wordpress.com/2012/01/14/alohomora-incanter-4/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7fecc53133b5620858e75dc10d1d1a6a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cfalguiere</media:title>
		</media:content>

		<media:content url="http://incanter.org/incanter-i-logo-holo.png" medium="image">
			<media:title type="html">Incanter logo</media:title>
		</media:content>

		<media:content url="http://cfalguiere.files.wordpress.com/2011/12/histogram-mysample-colors.png?w=300" medium="image">
			<media:title type="html">histogram-mysample-colors</media:title>
		</media:content>

		<media:content url="http://cfalguiere.files.wordpress.com/2011/12/capture-d_c3a9cran-2011-12-30-c3a0-23-25-38.png?w=300" medium="image">
			<media:title type="html">Capture           d’écran 2011-12-30 à 23.25.38</media:title>
		</media:content>

		<media:content url="http://cfalguiere.files.wordpress.com/2011/12/capture-d_c3a9cran-2011-12-30-c3a0-23-29-321.png?w=300" medium="image">
			<media:title type="html">Capture           d’écran 2011-12-30 à 23.29.32</media:title>
		</media:content>
	</item>
		<item>
		<title>Présentation Performances à Toulouse et Bordeaux</title>
		<link>http://cfalguiere.wordpress.com/2012/01/08/presentation-performances-a-toulouse-et-bordeaux/</link>
		<comments>http://cfalguiere.wordpress.com/2012/01/08/presentation-performances-a-toulouse-et-bordeaux/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 16:40:46 +0000</pubDate>
		<dc:creator>cfalguiere</dc:creator>
				<category><![CDATA[Duchess]]></category>
		<category><![CDATA[French]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Valtech]]></category>
		<category><![CDATA[présentation]]></category>

		<guid isPermaLink="false">http://cfalguiere.wordpress.com/?p=1260</guid>
		<description><![CDATA[Les slides et les comptes-rendus de ma présentation performance à Toutlouse et Bordeaux.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=1260&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Voici les slides de la présentation que j&#8217;ai faite aux JUGs de Toulouse et Bordeaux le 7 et 8 décembre.</p>
<iframe src='http://www.slideshare.net/slideshow/embed_code/10572923' width='614' height='503'></iframe>
<p>&nbsp;</p>
<p>Je voudrais remercier ces JUGs ainsi que les deux genigraph.fr qui a publié un <a href="http://www.google.fr/url?sa=t&amp;rct=j&amp;q=genigraph%20cfalguiere&amp;source=web&amp;cd=1&amp;ved=0CCUQFjAA&amp;url=http%3A%2F%2Fblog.genigraph.fr%2F2011%2F12%2F13%2Ftests-de-performance-au-jug-toulouse%2F&amp;ei=zsUJT57RBYzT8QOSprjAAQ&amp;usg=AFQjCNE3IU-9S_uDOIrFxu9fUKvVEdAHyg&amp;sig2=Mc0Sz0b7n0wJrtRAQtoQdg">compte rendu</a> sur son blog. Le JUG de Toulouse a également fait un <a href="http://toulousejug.org/2011/12/13/retour-sur-la-soiree-performances/">compte-rendu de la soirée</a>.</p>
<p>Une session similaire a été <a href="http://cfalguiere.wordpress.com/2011/10/16/presentation-performance-pour-le-geneva-jug-et-le-jugl/">enregistrée par le JUG de Lausanne</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cfalguiere.wordpress.com/1260/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cfalguiere.wordpress.com/1260/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cfalguiere.wordpress.com/1260/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cfalguiere.wordpress.com/1260/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cfalguiere.wordpress.com/1260/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cfalguiere.wordpress.com/1260/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cfalguiere.wordpress.com/1260/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cfalguiere.wordpress.com/1260/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cfalguiere.wordpress.com/1260/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cfalguiere.wordpress.com/1260/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cfalguiere.wordpress.com/1260/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cfalguiere.wordpress.com/1260/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cfalguiere.wordpress.com/1260/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cfalguiere.wordpress.com/1260/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=1260&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cfalguiere.wordpress.com/2012/01/08/presentation-performances-a-toulouse-et-bordeaux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7fecc53133b5620858e75dc10d1d1a6a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cfalguiere</media:title>
		</media:content>
	</item>
		<item>
		<title>2012</title>
		<link>http://cfalguiere.wordpress.com/2012/01/08/2012/</link>
		<comments>http://cfalguiere.wordpress.com/2012/01/08/2012/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 16:30:41 +0000</pubDate>
		<dc:creator>cfalguiere</dc:creator>
				<category><![CDATA[French]]></category>

		<guid isPermaLink="false">http://cfalguiere.wordpress.com/?p=1245</guid>
		<description><![CDATA[Et voilà ! Encore une nouvelle année, pleine de bonnes choses espérons le. La fin d&#8217;année est aussi une occasion de faire le point sur l&#8217;année précédente. En 2011, j&#8217;ai appris Objective-C, utilisé 3 IDE différents (Eclipse, XCode, IDEA Intellij), dompté MacOSX, apprivoisé Git, fait mon premier projet Grails et MongoDB. Une année riche en [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=1245&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://cfalguiere.files.wordpress.com/2012/01/claude_cfalguiere_puzzle.png"><img class="alignright size-medium wp-image-1253" title="claude_cfalguiere_puzzle" src="http://cfalguiere.files.wordpress.com/2012/01/claude_cfalguiere_puzzle.png?w=300&#038;h=297" alt="ma photo en puzzle" width="300" height="297" /></a>Et voilà ! Encore une nouvelle année, pleine de bonnes choses espérons le.</p>
<p>La fin d&#8217;année est aussi une occasion de faire le point sur l&#8217;année précédente. En 2011, j&#8217;ai appris Objective-C, utilisé 3 IDE différents (Eclipse, XCode, IDEA Intellij), dompté MacOSX, apprivoisé Git, fait mon premier projet Grails et MongoDB. Une année riche en nouveautés.</p>
<p>Mais un regret, je n&#8217;ai pas vraiment eu le temps de capitaliser sur ces sujets et 2012 m&#8217;amènera probablement sur d&#8217;autres thèmes. Et plein d&#8217;autres choses que j&#8217;aurai voulu expérimenter qui encombrent une très longue liste de choses à faire un jour.</p>
<p>Donc (comme chaque année je pense) je prend la bonne résolution de ne pas trop m&#8217;éparpiller.</p>
<p>Pas simple quand on est curieuse de tout dans un univers qui fourmille en nouveautés.</p>
<p>Le drame quand on a peu de temps disponible, c&#8217;est le &#8220;à quoi bon commencer quelque chose&#8221;. Donc on fini par utiliser ce temps de manière un peu aléatoire. On reste à la surface de tous les sujets. Mais j&#8217;apprend beaucoup plus en essayant de développer quelque chose en Clojure ou en préparant une présentation sur les performances, même si ça m&#8217;amène parfois sur d&#8217;autres sujets.</p>
<p>Donc voilà, en 2012, j&#8217;ai pris la résolution de me concentrer sur quelques sujets et de produire quelque chose sur ces sujets avant de zapper sur autre chose.</p>
<p>Rendez-vous début 2013 pour faire le point <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cfalguiere.wordpress.com/1245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cfalguiere.wordpress.com/1245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cfalguiere.wordpress.com/1245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cfalguiere.wordpress.com/1245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cfalguiere.wordpress.com/1245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cfalguiere.wordpress.com/1245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cfalguiere.wordpress.com/1245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cfalguiere.wordpress.com/1245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cfalguiere.wordpress.com/1245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cfalguiere.wordpress.com/1245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cfalguiere.wordpress.com/1245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cfalguiere.wordpress.com/1245/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cfalguiere.wordpress.com/1245/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cfalguiere.wordpress.com/1245/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=1245&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cfalguiere.wordpress.com/2012/01/08/2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7fecc53133b5620858e75dc10d1d1a6a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cfalguiere</media:title>
		</media:content>

		<media:content url="http://cfalguiere.files.wordpress.com/2012/01/claude_cfalguiere_puzzle.png?w=300" medium="image">
			<media:title type="html">claude_cfalguiere_puzzle</media:title>
		</media:content>
	</item>
		<item>
		<title>supercalifragilisticexpialidocious Incanter-3</title>
		<link>http://cfalguiere.wordpress.com/2011/12/28/supercalifragilisticexpialidocious-incanter-3/</link>
		<comments>http://cfalguiere.wordpress.com/2011/12/28/supercalifragilisticexpialidocious-incanter-3/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 14:14:22 +0000</pubDate>
		<dc:creator>cfalguiere</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Duchess]]></category>
		<category><![CDATA[Incanter]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Valtech]]></category>

		<guid isPermaLink="false">http://cfalguiere.wordpress.com/?p=1110</guid>
		<description><![CDATA[Continuons notre voyage dans les sortilèges d&#8217;Incanter avec l&#8217;incantation de Mary Poppins, supercalifragilisticexpialidocious Le balai arrive. En route pour le monde où nos tableaux de nombres vont se ranger tout seuls ! Cet article fait partie d&#8217;une suite. L&#8221;épisode 1 présentait quelques bases de Clojure et Incanter.  L&#8217;épisode 2 présentait les types. Où trouver des grimoires ? [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=1110&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<div style="margin-top:30px;height:225px;">
<div style="float:left;"><a href="http://incanter.org/"><img class="alignleft" style="margin:0 35px 20px 25px;" title="Incanter logo" src="http://incanter.org/incanter-i-logo-holo.png" alt="Incanter logo" width="173" height="175" /></a></div>
<p>Continuons notre voyage dans les sortilèges d&#8217;Incanter avec l&#8217;incantation de Mary Poppins,</p>
<p><span style="font-size:large;color:#3366ff;">supercalifragilisticexpialidocious</span></p>
<p>Le balai arrive. En route pour le monde où nos tableaux de nombres vont se ranger tout seuls !</p>
<p>Cet article fait partie d&#8217;une suite. L&#8221;<a href="http://cfalguiere.wordpress.com/2011/12/17/abracadabra-incanter/">épisode 1</a> présentait quelques bases de <a href="http://clojure.org/">Clojure</a> et <a href="http://incanter.org/">Incanter</a>.  L&#8217;<a href="http://cfalguiere.wordpress.com/2011/12/18/1-2-3-incanter/">épisode 2</a> présentait les types.</p>
</div>
<h3 style="margin-top:20px;">Où trouver des grimoires ?</h3>
<p>Nous allons manipuler un peu plus d&#8217;API et quelques documents vont être bien utiles.</p>
<p>Clojure ainsi que la librairie présentent l&#8217;API complète ainsi que des cheat sheets pour regrouper les commandes les plus fréquentes.</p>
<ul>
<li><a href="http://clojure.github.com/clojure/api-index.html">API Clojure</a></li>
<li><a href="http://clojure.org/cheatsheet">Cheat Sheet Clojure</a></li>
<li><a href="http://clojuredocs.org/incanter">API Incanter</a></li>
<li><a href="http://incanter.org/docs/incanter-cheat-sheet.pdf">Cheat Sheet Incanter</a></li>
</ul>
<h3 style="margin-top:20px;">To use or not to use ?</h3>
<p>Les librairies sont organisées en modules. Pour utiliser une des formules magiques vous devez d&#8217;abord charger les librairies correspondantes.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (use 'incanter.core)</strong><br />
nil<br />
<strong>user=&gt; (use 'incanter.io)</strong><br />
nil<br />
<strong>user=&gt; (use 'incanter.datasets)</strong><br />
nil<br />
</code></div>
<p>Un peu laborieux au bout d&#8217;un moment, non ?</p>
<p><a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/use">use</a> ou <a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/require">require</a> sont des fonctions du package <a href="http://clojure.github.com/clojure/clojure.core-api.html">clojure.core</a> qui chargent des librairies, c&#8217;est à dire un ensemble de ressources qui se trouvent dans un package Java. Un fichier Clojure à la racine de cette librairie sert de descripteur.</p>
<p>On a souvent à charger différentes librairies avec le même préfixe (par exemple incanter.core incanter.io &#8230;)<br />
On peut réécrire ces lignes en plus compact en utilisant la forme suivante (prefix list).</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (use '(incanter core io datasets))</strong><br />
nil<br />
</code></div>
<p>Vous noterez que les librairies sont maintenant passées dans une liste. Le premier élément est le préfixe, les autres sont les librairies sans le prefixe. Attention, les noms passés dans la liste ne doivent pas contenir de . .</p>
<p>Et bien sûr une  &#8217; pour empêcher l&#8217;évaluation de la liste.</p>
<h3 style="margin-top:20px;">Convoquer les données</h3>
<p>Pour commencer, il vous faut quelques tableaux de nombres.</p>
<p>Incanter propose un moyen rapide de créer un dataset à partir d&#8217;un fichier CSV. Si vous n&#8217;avez pas de données sous la main, Incanter est livré avec quelques jeux de données (<a href="http://liebke.github.com/incanter/datasets-api.html">http://liebke.github.com/incanter/datasets-api.html</a>) que l&#8217;on peur charger en utilisant la fonction get-dataset.</p>
<p>Commençons avec un résultat de test JMeter transformé en CSV. Un tir étalon pour ne pas avoir trop de données pour le moment.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (def data (read-dataset "/Users/cfalguiere/Workspaces/Diapason/report-data/20111217-ETALON_WSW_TPS2011.csv" :header true))</strong><br />
#'user/data<br />
</code></div>
<p>Petite vérification, avons nous bien des données ? <a href="http://cfalguiere.files.wordpress.com/2011/12/capture-d_c3a9cran-2011-12-19-c3a0-23-34-53.png"><img class="alignright size-medium wp-image-1118" title="Capture d’écran view Incanter" src="http://cfalguiere.files.wordpress.com/2011/12/capture-d_c3a9cran-2011-12-19-c3a0-23-34-53.png?w=300&#038;h=254" alt="capture d'écran du résultat de view" width="300" height="254" /></a></p>
<div style="background:white;margin-bottom:20px;margin-right:320px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code style="word-wrap:break-word;"><strong>user=&gt; (view data)</strong><br />
#&lt;JFrame javax.swing.JFrame[frame1,0,22,400x600,invalid,layout=java.awt.BorderLayout,title=Incanter Dataset,resizable,normal,defaultCloseOperation=HIDE_ON_CLOSE,rootPane=javax.swing.JRootPane[,0,22,400x578,invalid,layout=javax.swing.JRootPane$RootLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777673,maximumSize=,minimumSize=,preferredSize=],rootPaneCheckingEnabled=true]&gt;<br />
user=&gt;<br />
</code></div>
<p>La fonction <code>view</code> permet de visualiser ce dataset.</p>
<h3 style="margin-top:20px;">Combien êtes vous ?</h3>
<p>La fonction de dénombrement Clojure est <code>count</code>.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (count [1 2 3])</strong><br />
3<br />
<strong>user=&gt; (count "Incanter")</strong><br />
8<br />
</code></div>
<p>Donc voilà</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (count data)</strong><br />
2<br />
</code></div>
<p>Mmmmm &#8230; 2 &#8230; ???</p>
<p>Regardons de plus près à quoi ressemble ce dataset.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; data</strong><br />
#:incanter.core.Dataset{<br />
</code>  <code>:column-names [:lb :t :lt :ts :s :rc :rm :by :na],<br />
</code>  <code>:rows (<br />
</code>    <code>{:na 1, :by 27985, :rm "OK", :rc 200, :s "false", :ts 1.324109256665E12, :lt 794, :t 808, :lb "/"}<br />
</code>    <code>{:na 1, :by 28383, :rm "OK", :rc 200, :s "false", :ts 1.324109266396E12, :lt 8511, :t 8523, :lb "/CategoryDisplay"}<br />
</code>    <code>;...<br />
</code>    <code>{:na 1, :by 861, :rm "OK", :rc 200, :s "true", :ts 1.324109908066E12, :lt 21, :t 21, :lb "/AjaxLastViewedDisplay"}<br />
</code>  <code>)}<br />
</code></div>
<p>Le dataset est une map composée de 2 éléments <code>:column-names</code> qui contient tous les labels de colonnes dans un vector et <code>:rows</code> qui est une liste comportant une map par ligne de données.</p>
<p>On obtient un résultat plus pertinent en comptant les entrées de la liste. Incanter fournit aussi une fonction <code>nrow</code> qui compte correctement les lignes d&#8217;un dataset (n&#8217;oubliez pas que le dataset n&#8217;est pas une structure de données Clojure)</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (count (:rows data))</strong><br />
119<br />
<strong>user=&gt; (nrow data)</strong><br />
119</code></div>
<p>Le <code>count</code> de l&#8217;élément <code>:rows</code> de data nous donne bien le même compte que le <code>nrow</code> du dataset.</p>
<h3 style="margin-top:20px;">Découper en tranches</h3>
<p>Quelques incantations Clojure pour se faire la main. Affectons les lignes du dataset a une variable pour les manipuler plus facilement.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (def datarows (:rows data))</strong><br />
#'user/datarows</code></div>
<h6>La Clojure way</h6>
<p><strong>Donne moi les deux premières lignes !</strong></p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (take 2 datarows)</strong><br />
({:na 1, :by 27985, :rm "OK", :rc 200, :s "false", :ts 1.324109256665E12, :lt 794, :t 808, :lb "/"} {:na 1, :by 28383, :rm "OK", :rc 200, :s "false", :ts 1.324109266396E12, :lt 8511, :t 8523, :lb "/CategoryDisplay"})</code></div>
<p><strong>Donne moi tous les labels !</strong></p>
<p>On va utiliser la fonction <code>map</code> pour appliquer à chaque ligne une fonction qui renvoie le label.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (map :lb datarows)</strong><br />
("/" "/CategoryDisplay" "/--product--.html" ...</code></div>
<p>Et tout à la fois !</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (take 2 (map :lb datarows))</strong><br />
("/" "/CategoryDisplay")<br />
</code></div>
<h6>L&#8217;Incanter way</h6>
<p>Incanter propose des fonctions de manipulation de dataset. La fonction utilisée pour extraire des données est <code>sel</code> plus souvent utiilisée via son alias <a href="http://liebke.github.com/incanter/core-api.html#incanter.core/$">$</a>.</p>
<p>L&#8217;alias <code>$</code> a plusieurs formes. Il peut être utilisé avec la colonne seule (identifié par sa position, son nom, ou une collection de ces indications), ou bien la ligne et la colonne. Le dernier paramètre est le dataset.</p>
<p>La fonction <code>sel</code> place le dataset en premier argument et spécifie l&#8217;axe par des keywords.</p>
<p><strong>Donne moi tous les labels !</strong></p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; ($ :lb data)</strong><br />
("/" "/CategoryDisplay" "/--product--.html" ...<br />
<strong>user=&gt; (sel data :cols 0)</strong><br />
("/" "/CategoryDisplay" "/--product--.html" ...<br />
</code></div>
<p>Un usage typique est celui-ci, extraire une série, ici le temps de réponse et calculer un agrégat tel que la moyenne :</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (mean ($ :t data) )</strong><br />
1429.579831932773</code></div>
<p>Vous avez testé et ça ne marche pas, jeune sorcier ? C&#8217;est normal, il faut le package <code>incanter.stats</code> qui n&#8217;a pas été chargé pour le moment.</p>
<p><strong>Donne moi les deux premières lignes !</strong></p>
<p>Pour la fonction <code>sel</code> le paramètre qui suit :rows indique soit un numéro particulier de ligne, soit une liste de numéros de lignes, soit un range qui va générer cette liste de numéros de lignes.</p>
<p>Lorqu&#8217;on utilise <code>$</code> le premier paramètre représente la ligne (ou les lignes) et le second la colonne.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (sel data :rows (range 2) )</strong><br />
#:incanter.core.Dataset{:column-names [:lb :t :lt :ts :s :rc :rm :by :na], :rows ({:na 1, :by 27985, :rm "OK", :rc 200, :s "false", :ts 1.324109256665E12, :lt 794, :t 808, :lb "/"} {:na 1, :by 28383, :rm "OK", :rc 200, :s "false", :ts 1.324109266396E12, :lt 8511, :t 8523, :lb "/CategoryDisplay"})}<br />
user=&gt; (sel data :rows '(0 1))<br />
</code></div>
<p>Ce qui est équivalent à :</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; ($ (range 2) :all data)</strong><br />
#:incanter.core.Dataset{:column-names [:lb :t :lt :ts :s :rc :rm :by :na], :rows ({:na 1, :by 27985, :rm "OK", :rc 200, :s "false", :ts 1.324109256665E12, :lt 794, :t 808, :lb "/"} {:na 1, :by 28383, :rm "OK", :rc 200, :s "false", :ts 1.324109266396E12, :lt 8511, :t 8523, :lb "/CategoryDisplay"})}<br />
</code></div>
<p>Vous noterez le <code>:all</code>. La syntaxe oblige à spécifier deux paramètres si l&#8217;on veut indiquer des lignes, les lignes puis les colonnes. :all indique que toutes les colonnes doivent être conservées.</p>
<p><strong>Donne moi les labels des cinq premières lignes !</strong></p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; user=&gt; ($ (range 5) :lb data)</strong><br />
("/" "/CategoryDisplay" "/--product--.html" ...<br />
user=&gt; (sel data :rows (range 5) :cols :lb)<br />
("/" "/CategoryDisplay" "/--product--.html" ...<br />
</code></div>
<p>Toutes sortes de combinaisons sont possibles. L&#8217;expression suivante retourne un dataset ne comportant plus que les colonnes sélectionnées et les deux premières lignes.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; ($ (range 2) [:lb :t] data)</strong><br />
#:incanter.core.Dataset{:column-names [:lb :t], :rows ({:t 808, :lb "/"} {:t 8523, :lb "/CategoryDisplay"})}<br />
</code></div>
<p>S&#8217;il y a plusieurs colonnes, le résultat est un dataset, mais s&#8217;il n&#8217;y a qu&#8217;une ligne la structure de données est également différente. Le résultat est une liste et non un map. Les éléments sont ordonnés conformément aux colonnes du dataset.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (sel data :rows 0)</strong><br />
("/" 808 794 1.324109256665E12 "false" 200 "OK" 27985 1)<br />
<strong>user=&gt; (:column-names data)</strong><br />
[:lb :t :lt :ts :s :rc :rm :by :na]<br />
</code></div>
<p>Pour finir, il existe un mot clé <code>:not</code> qui permet d&#8217;exprimer des listes par exclusion. Dans l&#8217;exemple suivant, l&#8217;expression conserve toutes les colonnes sauf <code>:by</code> et <code>:na</code> pour les deux premières lignes.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; ($ (range 2) [:not :by :na] data)</strong><br />
#:incanter.core.Dataset{:column-names [:lb :t :lt :ts :s :rc :rm], :rows ({:rm "OK", :rc 200, :s "false", :ts 1.324109256665E12, :lt 794, :t 808, :lb "/"} {:rm "OK", :rc 200, :s "false", :ts 1.324109266396E12, :lt 8511, :t 8523, :lb "/CategoryDisplay"})}<br />
</code></div>
<h3 style="margin-top:20px;">Trouver l&#8217;élu</h3>
<p><em>Attention jeune sorcier ça se complique.</em></p>
<p>Pour analyser les résultats on aura souvent besoin de retrouver des sous ensemble sur des critères particuliers, tous les relevés pour une url données (:lb), les relevés avec des temps très élevés (:t), ou les relevés en erreur (statut :s, return code :rc, message :rm).</p>
<h6>La Clojure way</h6>
<p>Les collections Clojure ont une fonction filter <a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/filter">filter</a>. La ligne suivante donne tous les nombres pairs du vecteur [1 2 3 4 5 6].</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (filter even? [1 2 3 4 5 6])</strong><br />
(2 4 6)</code></div>
<p>Dans le cas plus général on ne pourra pas utiliser une fonction existante et il faudra écrire sa propre fonction filtre.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (defn filterAlice [name] (= name "Alice"))</strong><br />
#'user/filterAlice<br />
<strong>user=&gt; (filter filterAlice ["Alice", "Bob", "Charles"])</strong><br />
("Alice")<br />
</code></div>
<p>D&#8217;une manière générale on utilisera plutôt une fonction anonyme. Ce qui nous donne :</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (filter (fn[name](= name "Alice")) ["Alice", "Bob", "Charles"])</strong><br />
("Alice")<br />
</code></div>
<p>C&#8217;est un peu verbeux et vous trouverez plus souvent une forme abrégée utilisant <code>#</code>.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (filter #(= % "Alice" ) ["Alice", "Bob", "Charles"])</strong><br />
("Alice")</code></div>
<p><code>#</code> est appelé la macro dispatch et a plusieurs effets décrits <a href="http://clojure.org/reader">ici</a>. Celui qui nous intéresse ici est <code>#(...)</code> qui est un équivalent de <code>(fn [args] (...))</code>.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; ( #(+ 1 %) 2 )</strong><br />
3<br />
<strong>user=&gt; ( #(+ 1 %1 %2) 2 3 )</strong><br />
6<br />
</code></div>
<p><code>%</code> représente  l&#8217;argument, ou les arguments, de la fonction anonyme, ici le paramètre <code>:name</code> implicite.</p>
<p>Cette fonction anonyme appliquée sur la liste de prénom donne bien le même résultat.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (filter #(= % "Alice") ["Alice", "Bob", "Charles"])</strong><br />
("Alice")<br />
</code></div>
<p>Et sur mes données maintenant ?<br />
<strong>Donne moi toutes les lignes dont le label est &#8220;/&#8221; !</strong></p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (filter #(= % "/") datarows)</strong><br />
()<br />
</code></div>
<p>C&#8217;est vide ? Normal, chaque ligne de la liste est une map. Il faut donc récupérer le <code>:lb</code>.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (filter #(= (:lb %) "/") datarows)</strong><br />
({:na 1, :by 27985, :rm "OK", :rc 200, :s "false", :ts 1.324109256665E12, :lt 794, :t 808, :lb "/"} {:na 1, :by 27974, :rm "OK", :rc 200, :s "false", :ts 1.324109395646E12, :lt 209, :t 213, :lb "/"} {:na 1, :by 27994, :rm "OK", :rc 200, :s "false", :ts 1.324109537182E12, :lt 247, :t 252, :lb "/"} {:na 1, :by 27983, :rm "OK", :rc 200, :s "false", :ts 1.324109682199E12, :lt 344, :t 349, :lb "/"} {:na 1, :by 27980, :rm "OK", :rc 200, :s "false", :ts 1.32410980267E12, :lt 212, :t 217, :lb "/"})<br />
</code></div>
<p>Autre critère, les temps supérieurs à 10s ? Changeons simplement de fonction pour <code> #(&gt; (:t %) 10000)</code>.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (filter #(&gt; (:t %) 10000) datarows)</strong><br />
({:na 1, :by 172777, :rm "OK", :rc 200, :s "true", :ts 1.324109405557E12, :lt 1398, :t 13007, :lb "/CategoryDisplay-REF"} {:na 0, :by 33268, :rm "OK", :rc 200, :s "true", :ts 1.324109406957E12, :lt 11602, :t 11607, :lb "http://www.witre.se/spannare_85915M.html?leafcode=85919&amp;fromSearch=true"})<br />
</code></div>
<p>Et pour finir comment exprimer la négation ? Par exemple, trouver tous les relevés dont le statut n&#8217;est pas OK.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (count (filter #(= (:rm %) "OK") datarows))</strong><br />
97<br />
<strong>user=&gt; (count (filter #(not= (:rm %) "OK") datarows))</strong><br />
22<br />
<strong>user=&gt; (count (remove #(= (:rm %) "OK") datarows))</strong><br />
22<br />
</code></div>
<p>Le total fait bien 119. Deux solutions sont possibles, <code>remove</code> ou <code>filter</code> avec l&#8217;expression complémentaire. La fonction <code>remove</code> n&#8217;altère pas la liste initiale.</p>
<h6>L&#8217;incanter Way</h6>
<p>Incanter propose la fonction <a href="http://liebke.github.com/incanter/core-api.html#incanter.core/query-dataset">query-dataset</a>. Cette fonction a elle aussi un alias <code>$where</code>.</p>
<p>Les prédicats de <code>query-dataset</code> peuvent être exprimés dans un langage voisin du langage de requête de <a href="http://www.mongodb.org/">MongoDB</a>.</p>
<p><strong>Donne moi tous les relevés de la home page !</strong></p>
<p>Ces relevés sont ceux dont la colonne <code>:lb</code> vaut &#8220;/&#8221;.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (query-dataset data {:lb "/"} )</strong><br />
#:incanter.core.Dataset{:column-names [:lb :t :lt :ts :s :rc :rm :by :na], :rows ({:na 1, :by 27985, :rm "OK", :rc 200, :s "false", :ts 1.324109256665E12, :lt 794, :t 808, :lb "/"} {:na 1, :by 27974, :rm "OK", :rc 200, :s "false", :ts 1.324109395646E12, :lt 209, :t 213, :lb "/"} {:na 1, :by 27994, :rm "OK", :rc 200, :s "false", :ts 1.324109537182E12, :lt 247, :t 252, :lb "/"} {:na 1, :by 27983, :rm "OK", :rc 200, :s "false", :ts 1.324109682199E12, :lt 344, :t 349, :lb "/"} {:na 1, :by 27980, :rm "OK", :rc 200, :s "false", :ts 1.32410980267E12, :lt 212, :t 217, :lb "/"})}<br />
</code></div>
<p>La même chose exprimée avec l&#8217;alias <code>$where</code></p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; ($where {:lb "/"} data)</strong><br />
#:incanter.core.Dataset{:column-names [:lb :t :lt :ts :s :rc :rm :by :na], :rows ({:na 1, :by 27985, :rm "OK", :rc 200, :s "false", :ts 1.324109256665E12, :lt 794, :t 808, :lb "/"} {:na 1, :by 27974, :rm "OK", :rc 200, :s "false", :ts 1.324109395646E12, :lt 209, :t 213, :lb "/"} {:na 1, :by 27994, :rm "OK", :rc 200, :s "false", :ts 1.324109537182E12, :lt 247, :t 252, :lb "/"} {:na 1, :by 27983, :rm "OK", :rc 200, :s "false", :ts 1.324109682199E12, :lt 344, :t 349, :lb "/"} {:na 1, :by 27980, :rm "OK", :rc 200, :s "false", :ts 1.32410980267E12, :lt 212, :t 217, :lb "/"})}<br />
</code></div>
<p>On peut aussi exprimer plusieurs critères. Ci-dessous, les temps entre 8s et 10s.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (query-dataset data {:t {:$gt 8000 :$lt 10000} } )</strong><br />
#:incanter.core.Dataset{:column-names [:lb :t :lt :ts :s :rc :rm :by :na], :rows ({:na 1, :by 28383, :rm "OK", :rc 200, :s "false", :ts 1.324109266396E12, :lt 8511, :t 8523, :lb "/CategoryDisplay"} {:na 1, :by 33235, :rm "OK", :rc 200, :s "true", :ts 1.324109282891E12, :lt 8967, :t 8981, :lb "/--product--.html"} {:na 1, :by 30959, :rm "OK", :rc 200, :s "false", :ts 1.324109547672E12, :lt 8787, :t 8792, :lb "/CategoryDisplay"})}<br />
</code></div>
<p>Ou bien les code retours qui ne font pas partie de la liste acceptée, 200 (OK) ni 302 (redirect).</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (query-dataset data {:rc {:$nin #{200 302} } } )</strong><br />
#:incanter.core.Dataset{:column-names [:lb :t :lt :ts :s :rc :rm :by :na], :rows ()}<br />
<strong>user=&gt; (query-dataset data {:rm {:$nin #{"OK" "Found"} } } )</strong><br />
#:incanter.core.Dataset{:column-names [:lb :t :lt :ts :s :rc :rm :by :na], :rows ()}<br />
</code></div>
<p>Les opérateurs disponibles dans les requêtes sont :$gt, :$lt, :$gte, :$lte, :$eq, :$ne, :$in, :$nin, $fn.</p>
<p>Les prédicats peuvent également être définis de manière classique par une fonction anonyme. La fonction s&#8217;applique à la ligne.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (query-dataset data #(= (:lb %) "/" ) )</strong><br />
#:incanter.core.Dataset{:column-names [:lb :t :lt :ts :s :rc :rm :by :na], :rows ({:na 1, :by 27985, :rm "OK", :rc 200, :s "false", :ts 1.324109256665E12, :lt 794, :t 808, :lb "/"} {:na 1, :by 27974, :rm "OK", :rc 200, :s "false", :ts 1.324109395646E12, :lt 209, :t 213, :lb "/"} {:na 1, :by 27994, :rm "OK", :rc 200, :s "false", :ts 1.324109537182E12, :lt 247, :t 252, :lb "/"} {:na 1, :by 27983, :rm "OK", :rc 200, :s "false", :ts 1.324109682199E12, :lt 344, :t 349, :lb "/"} {:na 1, :by 27980, :rm "OK", :rc 200, :s "false", :ts 1.32410980267E12, :lt 212, :t 217, :lb "/"})}<br />
</code></div>
<p>Si vous avez déjà des fonctions dans vos grimoires, vous pouvez bien sûr les utiliser directement.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code><strong>user=&gt; (defn isHomePage [row] (= (:lb row) "/"))</strong><br />
#'user/isHomePage<br />
<strong>user=&gt; (query-dataset data isHomePage )</strong><br />
#:incanter.core.Dataset{:column-names [:lb :t :lt :ts :s :rc :rm :by :na], :rows ({:na 1, :by 27985, :rm "OK", :rc 200, :s "false", :ts 1.324109256665E12, :lt 794, :t 808, :lb "/"} {:na 1, :by 27974, :rm "OK", :rc 200, :s "false", :ts 1.324109395646E12, :lt 209, :t 213, :lb "/"} {:na 1, :by 27994, :rm "OK", :rc 200, :s "false", :ts 1.324109537182E12, :lt 247, :t 252, :lb "/"} {:na 1, :by 27983, :rm "OK", :rc 200, :s "false", :ts 1.324109682199E12, :lt 344, :t 349, :lb "/"} {:na 1, :by 27980, :rm "OK", :rc 200, :s "false", :ts 1.32410980267E12, :lt 212, :t 217, :lb "/"})}<br />
</code></div>
<p>Voilà, beaucoup de sortilèges a expérimenter en attendant l&#8217;<a href="http://cfalguiere.wordpress.com/2012/01/14/alohomora-incanter-4/">épisode 4</a>. Attention à ne pas faire trop de dégâts !</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cfalguiere.wordpress.com/1110/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cfalguiere.wordpress.com/1110/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cfalguiere.wordpress.com/1110/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cfalguiere.wordpress.com/1110/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cfalguiere.wordpress.com/1110/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cfalguiere.wordpress.com/1110/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cfalguiere.wordpress.com/1110/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cfalguiere.wordpress.com/1110/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cfalguiere.wordpress.com/1110/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cfalguiere.wordpress.com/1110/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cfalguiere.wordpress.com/1110/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cfalguiere.wordpress.com/1110/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cfalguiere.wordpress.com/1110/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cfalguiere.wordpress.com/1110/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=1110&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cfalguiere.wordpress.com/2011/12/28/supercalifragilisticexpialidocious-incanter-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7fecc53133b5620858e75dc10d1d1a6a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cfalguiere</media:title>
		</media:content>

		<media:content url="http://incanter.org/incanter-i-logo-holo.png" medium="image">
			<media:title type="html">Incanter logo</media:title>
		</media:content>

		<media:content url="http://cfalguiere.files.wordpress.com/2011/12/capture-d_c3a9cran-2011-12-19-c3a0-23-34-53.png?w=300" medium="image">
			<media:title type="html">Capture d’écran view Incanter</media:title>
		</media:content>
	</item>
		<item>
		<title>1, 2, 3 . . . Incanter</title>
		<link>http://cfalguiere.wordpress.com/2011/12/18/1-2-3-incanter/</link>
		<comments>http://cfalguiere.wordpress.com/2011/12/18/1-2-3-incanter/#comments</comments>
		<pubDate>Sun, 18 Dec 2011 20:23:29 +0000</pubDate>
		<dc:creator>cfalguiere</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Duchess]]></category>
		<category><![CDATA[French]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Valtech]]></category>
		<category><![CDATA[Incanter]]></category>

		<guid isPermaLink="false">http://cfalguiere.wordpress.com/?p=999</guid>
		<description><![CDATA[Cet article est la suite de cet article abracadabra ! Incanter. Pour traiter des données statistiques, les structures de données qui nous intéressent principalement sont les nombres et les tableaux de nombres. Clojure utilise les types de données classiques pour représenter des textes String, Character, des Boolean (true/false), des nombres, plusieurs types de collections et deux [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=999&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://incanter.org/"><img class="alignleft" style="margin:15px 35px 20px 25px;" title="Incanter logo" src="http://incanter.org/incanter-i-logo-holo.png" alt="Incanter logo" width="173" height="175" /></a>Cet article est la suite de cet article <a href="http://cfalguiere.wordpress.com/2011/12/17/abracadabra-incanter/">abracadabra ! Incanter</a>.</p>
<h3></h3>
<p>Pour traiter des données statistiques, les structures de données qui nous intéressent principalement sont les nombres et les tableaux de nombres.</p>
<p>Clojure utilise les types de données classiques pour représenter des textes String, Character, des Boolean (true/false), des nombres, plusieurs types de collections et deux types d&#8217;identifiants.</p>
<p>La documentation de l&#8217;interpréteur décrit de manière assez rapide les différents types de données <a href="http://clojure.org/reader">http://clojure.org/reader</a>.  Ce document <a href="http://clojure.org/data_structures">http://clojure.org/data_structures</a> décrit les structures de données disponibles de manière un peu plus approfondie. J&#8217;ai aussi trouvé ce document utile <a href="http://en.wikibooks.org/wiki/Learning_Clojure/Data_Types">http://en.wikibooks.org/wiki/Learning_Clojure/Data_Types</a>.</p>
<h3>Les textes</h3>
<p>Clojure repose sur les types Java. Donc java.lang.String et la manipulation des chaînes n&#8217;est pas très différente. Quelques opérations utiles :</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (type "A")<br />
java.lang.String<br />
user=&gt; (str 144 " éléments") ; concatène les deux termes<br />
144 éléments<br />
nil<br />
</code></div>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (count "Incanter") ; compte le nombre de caractères de la chaîne<br />
8<br />
</code></div>
<p>La quote &#8216; a une signification particulière dans la syntaxe Clojure (on le verra plus loin). Il ne peut pas être utilisé pour les caractères. Les caractères sont définis par \. Il existe aussi des caractères spéciaux comme <code>\tab \newline \space</code></p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (type 'A')<br />
java.lang.Exception: Unmatched delimiter: )<br />
user=&gt; (type \A)<br />
java.lang.Character<br />
</code></div>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (println \A \tab \B)<br />
A</code>        <code>B<br />
nil<br />
</code></div>
<h3>Les identifiants</h3>
<p>Clojure a 2 types d&#8217;identifiants, <code>symbol</code> et <code>keyword</code>.</p>
<p>Les  <code>symbol</code> sont des identifiants qui référencent quelque chose d&#8217;autre. Ce sont en général des noms de variable, de fonction, de classe.</p>
<p>Les <code>keyword</code> sont des identifiants qui référencent leur nom. Ce sont des sortes de chaînes constantes donc plus rapides à comparer. Elles sont principalement utilisées comme clés dans les hash-maps ou les méta-données des <code>symbol</code>. Un : est placé devant les <code>keyword</code>, mais il ne fait pas partie de son nom.</p>
<p>Ci-dessous la déclaration d&#8217;une variable avec un <code>symbol</code> x . On ne peut pas faire la même chose avec un <code>keyword</code>.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def y 1)<br />
#'user/y<br />
user=&gt; y<br />
1<br />
</code></div>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def :y 1)<br />
java.lang.Exception: First argument to def must be a Symbol (NO_SOURCE_FILE:221)<br />
&lt;/code </code></div>
<p>Les <code>keyword</code> sont utilisés comme label dans les hash-maps. On voit que le <code>keyword</code> Alice retourne son nom.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def scores {:Alice 1, :Bob 2} )<br />
#'user/scores<br />
user=&gt; (get scores :Alice)<br />
1<br />
user=&gt; :Alice<br />
"Alice"<br />
</code></div>
<p>Les  <code>keyword</code> sont aussi utilisés dans la définition des méta-données. Le nom de fonction hello est <code>symbol</code>. Un <code>keyword</code> :doc est utilisé pour ajouter une description. Les  <code>keyword </code>ne peuvent pas avoir de méta-données.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (defn<br />
</code>  <code>^{:doc "pas très utile"}<br />
</code>  <code>hello ([name] (println "Hello" name)))<br />
#'user/hello<br />
</code></div>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (doc hello)<br />
-------------------------<br />
user/hello<br />
([name])<br />
</code>  <code>pas très utile<br />
nil<br />
</code></div>
<p>Les <code>symbol</code> peuvent être utilisés là où des <code>keyword</code> seraient utilisés (même si c&#8217;est sans grand intérêt).<br />
Essayons pour voir.<br />
On ne peut pas utiliser le  <code>symbol</code> directement.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def scores {Alice 1, Bob 2})<br />
java.lang.Exception: Unable to resolve symbol: Alice in this context (NO_SOURCE_FILE:375)<br />
</code></div>
<p>Contrairement aux <code>keyword</code> qui se résolvent sur eux même, les <code>symbol</code> tentent d&#8217;évaluer ce qu&#8217;ils référencent dès qu&#8217;on les utilise. Le <code>keyword</code> :Alice renvoie &#8220;Alice&#8221;. Le <code>symbol</code> Alice ne peut pas être évalué car il n&#8217;existe pas encore, et si on prend un <code>symbol</code> existant dans le contexte tel que y, il renvoie 1 dès qu&#8217;on utilise ce nom.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; :Alice<br />
"Alice"<br />
user=&gt; (name y)<br />
java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.Named (NO_SOURCE_FILE:0)<br />
user=&gt; y<br />
1<br />
user=&gt; (name :Alice)<br />
"Alice"<br />
</code></div>
<p>Le &#8216; permet d&#8217;empêcher l&#8217;évaluation de l&#8217;expression et d&#8217;utiliser le <code>symbol</code> non évalué comme label.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; 'y<br />
y<br />
user=&gt; (name 'y)<br />
"y"user=&gt; (def scores {'Alice 1, 'Bob 2}) ; pour démo, on utiliserait normalement :Alice :Bob<br />
#'user/scores<br />
user=&gt; (get scores 'Bob)<br />
2<br />
</code></div>
<h3>Les nombres</h3>
<p>Les nombres sont toujours &#8220;boxés&#8221; c&#8217;est à dire contenus dans un objet comme Integer pour le type int. Ces types sont dérivés de java.lang.Number.</p>
<p>Quelques différences avec Java. Pour les entiers, Clojure gère automatiquement la conversion vers des BigNum et ajoute un type Ratio. Pour les décimaux, ce sont par défaut des Doubles et Clojure préserve la précision lors des opérations numériques qui impliquent un Double.</p>
<p>La représentation de la constante influence le type. M indique un BigNumber et le . un décimal comme en Java.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (type 1)<br />
java.lang.Integer<br />
user=&gt; (type 1.0)<br />
java.lang.Double<br />
user=&gt; (type 1M)<br />
java.math.BigDecimal<br />
</code></div>
<p>Quelque soit le type de départ, le type est adapté pour contenir la valeur sans la tronquer lors des opérations arithmétiques. Un souci de moins.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (type 123456789)<br />
java.lang.Integer<br />
user=&gt; (type (* 123456789 123456789))<br />
java.lang.Long<br />
user=&gt; (type (* 123456789 123456789 123456789))<br />
java.math.BigInteger<br />
</code></div>
<p>Quelque soit le type utilisé les opérations de comparaison entre des types différents restent cohérentes.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (== 1 1.0)<br />
true<br />
user=&gt; (== 1.0 1M)<br />
true<br />
</code></div>
<h6>Ratio et divisions</h6>
<p>Une spécificité de Clojure, le type Ratio permet de représenter les fractions d&#8217;entiers sans perte de précision. Il ne s&#8217;applique qu&#8217;aux entiers. La même opération retourne un décimal dès qu&#8217;une des valeurs est décimale.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (/ 2 3)<br />
2/3<br />
user=&gt; (type (/ 2 3)) ;; opération sur entiers<br />
clojure.lang.Ratio</code></div>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (/ 2 3.0)<br />
0.6666666666666666<br />
user=&gt; (type (/ 2 3.0)) ;; opération sur un entier et un décimal<br />
java.lang.Double</code></div>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (/ 4 2) ;; opération sur entiers<br />
2<br />
user=&gt; (type (/ 4 2) )<br />
java.lang.Integer<br />
</code></div>
<p>Si on veut faire une division sur entiers, il faut coercer une des valeurs en float ou en double.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (type (float 2))<br />
java.lang.Float<br />
user=&gt; ( / (float 2) 3 )<br />
0.6666667<br />
user=&gt; (type ( / (float 2) 3 ))<br />
java.lang.Float<br />
</code></div>
<p>Même si les nombre sont par défaut traités en Double, la conversion n&#8217;est pas systématique si elle n&#8217;est pas nécessaire. Une conversion en double aurait donné un Double.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; ( / (double 2) 3)<br />
0.6666666666666666<br />
user=&gt; ( type ( / (double 2) 3) )<br />
java.lang.Double<br />
</code></div>
<h6>Les opérations</h6>
<p>Maintenant qu&#8217;est ce que je peux faire avec mes nombres ?</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (pos? -2) ;; is positive ?<br />
false<br />
user=&gt; (min 3 1 5) ;; min<br />
1<br />
user=&gt; (max 4 8 2) ;; max<br />
8<br />
user=&gt; (int 1.2) ;; coercion en entier<br />
1<br />
user=&gt; (inc 2) ;; incrémente de 1<br />
3<br />
user=&gt; (dec 5) ;; décrémente de 1<br />
4<br />
</code></div>
<p>La plupart des fonctions acceptent n valeurs. Qu&#8217;est ce qui se passe si j&#8217;ai plusieurs paramètres ?</p>
<p>Le résultat est à assez évident sur min ou max. Moins sur d&#8217;autres opérateurs. Le résultat est spécifié dans la documentation. Par exemple pour<a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core//"> /</a>, le premier terme est divisé par tous les suivants.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (/ 12 2 3)<br />
2<br />
</code></div>
<p>Pour <a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/%3C">&lt;</a>, la documentation indique &#8220;Returns non-nil if nums are in monotonically increasing order, otherwise false.&#8221; La suite doit être strictement croissante ? Mmm? testons &#8230;</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (&lt; 1 2)<br />
true<br />
user=&gt; (&lt; 1 2 4)<br />
true<br />
user=&gt; (&lt; 1 5 4)<br />
false<br />
</code></div>
<h3>Encore plus de nombres</h3>
<p>En général, lorsque l&#8217;on fait des statistiques on a de longs tableaux de nombres. Il nous faut donc des collections.</p>
<p>A quoi ça ressemble en Clojure ?</p>
<h6>Les maps</h6>
<p>Les maps sont représentées par {}. On en a vu un exemple plus haut. Les , sont facultatives mais améliorent la lisibilité. On peut utiliser tout type de valeurs comme clé (tout type de form dans la terminologie Clojure).</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def scores { "Alice" 1, "Bob" 2} )<br />
#'user/scores<br />
user=&gt; (type scores)<br />
clojure.lang.PersistentArrayMap<br />
user=&gt; (get scores "Bob")<br />
2</code></div>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def scores { 15 "A", 22 "B"} )<br />
#'user/scores<br />
user=&gt; (get scores 15)<br />
"A"<br />
</code></div>
<h6>Les listes</h6>
<p>Les listes sont représentées entre (). C&#8217;est ce qu&#8217;on manipule depuis le début.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; user=&gt; (def readings (1 2 3))<br />
java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:398)<br />
</code></div>
<p>Diantre ! La magie ne marche pas sur les listes ?<br />
Si, mais l&#8217;interpréteur évalue toutes les listes comme si c&#8217;est c&#8217;était des programmes.</p>
<p>Mais si on veut que la liste ne soit pas évaluées et restent des listes ??? Mmm J&#8217;ai déjà vu ça quelque part &#8230;</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def readings '(1 2 3))<br />
#'user/readings<br />
user=&gt; (type readings)<br />
clojure.lang.PersistentList<br />
user=&gt; readings<br />
(1 2 3)<br />
</code></div>
<p>La fonction range est un moyen rapide de générer une liste de nombres.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (range -2 6)<br />
(-2 -1 0 1 2 3 4 5)<br />
</code></div>
<h6>Les vecteurs</h6>
<p>Le vecteur est représenté entre [].</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def persons [ "Alice" "Bob" "Charles"] )<br />
#'user/persons<br />
user=&gt; (type persons)<br />
clojure.lang.PersistentVector<br />
user=&gt; (persons 1)<br />
"Bob"</code></div>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; ([ "Alice", 2, :name ] 2)<br />
:name<br />
</code></div>
<p>La liste et le vecteur  conservent l&#8217;ordre. La liste est à privilégier pour les accès séquentiels. Le vecteur permet un accès direct (par index) efficace.</p>
<h6>Les sets</h6>
<p>Il reste un dernier type de collection dans Clojure, le set qui maintient l&#8217;unicité. Il est représenté par #{}.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; #{1 3 1 4}<br />
java.lang.IllegalArgumentException: Duplicate key: 1<br />
user=&gt; #{1 3 5 4}<br />
#{1 3 4 5}<br />
user=&gt; (type #{1 3 5 4})<br />
clojure.lang.PersistentHashSet<br />
</code></div>
<h6>Quelques opérations sur les collections</h6>
<p>La fonction <code>doseq</code> permet de parcourir l&#8217;itérateur de la collection.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt;(def persons '( "Alice" "Bob" "Charles") )<br />
user=&gt; (doseq [p persons] (println p))<br />
Alice<br />
Bob<br />
Charles<br />
nil<br />
</code></div>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (count persons)<br />
3<br />
</code></div>
<p>Toutes les callections sont modifiables.  <code>conj p</code>ermet d&#8217;ajouter des éléments. Attention l&#8217;effet de <code>conj</code> depend du type de collection.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (conj '(1 2 3) 5)<br />
(5 1 2 3)<br />
user=&gt; (conj [1 2 3] 5)<br />
[1 2 3 5]<br />
</code></div>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (pop [1 2 3])<br />
[1 2]<br />
</code></div>
<h3>Un peu d&#8217;Incanter</h3>
<p><em>Ah ! Quand même !</em></p>
<p>Incanter rajoute un type de donnée, la <a href="https://github.com/liebke/incanter/wiki/matrices">matrice</a>. Une matrice ne peut contenir que des données numériques et n&#8217;a pas de nom de colonnes (même définition que dans R).</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def A (matrix [[1 2 3] [4 5 6] [7 8 9]]))<br />
java.lang.Exception: Unable to resolve symbol: matrix in this context (NO_SOURCE_FILE:450)<br />
</code></div>
<p>Whoops ! Jusqu&#8217;à présent tous les types étaient du Clojure. Ce type de données étant spécifique à Incanter, il faut charger la librairie en utilisant use. Et voilà ! matrix génère une matrice. Comme dans R, la matrice est un Vector replié.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (use 'incanter.core)<br />
nil<br />
user=&gt; (def A (matrix [[1 2 3] [4 5 6] [7 8 9]]))<br />
#'user/A<br />
user=&gt; A<br />
[1,0000 2,0000 3,0000<br />
4,0000 5,0000 6,0000<br />
7,0000 8,0000 9,0000]<br />
</code></div>
<p>Il existe différentes syntaxes pour créer des matrices à partir de vectors ou de listes. La syntaxe précédente concaténait des vecteurs lignes. Celle-ci découpe un vecteur en fonction du nombre de colonnes souhaitées.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def A2 (matrix [1 2 3 4 5 6 7 8] 2))<br />
#'user/A2<br />
user=&gt; A2<br />
[1,0000 2,0000<br />
3,0000 4,0000<br />
5,0000 6,0000<br />
7,0000 8,0000]<br />
</code></div>
<p>Incanter ajoute également le type <a href="https://github.com/liebke/incanter/wiki/datasets">Dataset</a>, qui est l&#8217;équivalent d&#8217;un tableau Excel ou d&#8217;une table en base de données. Le dataset comporte des noms de colonnes. Les colonnes peuvent être de tout type.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (use 'incanter.datasets)<br />
nil<br />
user=&gt; (dataset ["x1" "x2" "x3"]<br />
[[1 2 3]<br />
[4 5 6]<br />
[7 8 9]])<br />
#:incanter.core.Dataset{:column-names ["x1" "x2" "x3"], :rows ({"x3" 3, "x2" 2, "x1" 1} {"x3" 6, "x2" 5, "x1" 4} {"x3" 9, "x2" 8, "x1" 7})}<br />
</code></div>
<p>Ces structures de données sont généralement lues à partir de fichiers CSV ou d&#8217;une base de données.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (use 'incanter.io)<br />
nil<br />
user=&gt; (def data (read-dataset "datafile.csv" :header true))<br />
nil </code></div>
<p>Et quelques statistiques pour finir et vous montrer qu&#8217;on n&#8217;a pas manipulé toutes ces collections pour rien aujourd&#8217;hui :</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;">user=&gt; (use &#8216;(incanter core stats) )<br />
nil<br />
user=&gt; (mean &#8216;(20 10 30) )  ; médiane<br />
20.0<br />
user=&gt; (sum &#8216;(20 10 30) )  ; somme<br />
60.0</div>
<p>On reviendra en détail sur tout ça dans l&#8217;<a href="http://cfalguiere.wordpress.com/2011/12/28/supercalifragilisticexpialidocious-incanter-3/">épisode 3</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cfalguiere.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cfalguiere.wordpress.com/999/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cfalguiere.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cfalguiere.wordpress.com/999/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cfalguiere.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cfalguiere.wordpress.com/999/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cfalguiere.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cfalguiere.wordpress.com/999/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cfalguiere.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cfalguiere.wordpress.com/999/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cfalguiere.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cfalguiere.wordpress.com/999/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cfalguiere.wordpress.com/999/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cfalguiere.wordpress.com/999/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=999&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cfalguiere.wordpress.com/2011/12/18/1-2-3-incanter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7fecc53133b5620858e75dc10d1d1a6a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cfalguiere</media:title>
		</media:content>

		<media:content url="http://incanter.org/incanter-i-logo-holo.png" medium="image">
			<media:title type="html">Incanter logo</media:title>
		</media:content>
	</item>
		<item>
		<title>abracadabra ! Incanter</title>
		<link>http://cfalguiere.wordpress.com/2011/12/17/abracadabra-incanter/</link>
		<comments>http://cfalguiere.wordpress.com/2011/12/17/abracadabra-incanter/#comments</comments>
		<pubDate>Sat, 17 Dec 2011 22:13:56 +0000</pubDate>
		<dc:creator>cfalguiere</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Duchess]]></category>
		<category><![CDATA[French]]></category>
		<category><![CDATA[Language]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Valtech]]></category>
		<category><![CDATA[Incanter]]></category>

		<guid isPermaLink="false">http://cfalguiere.wordpress.com/?p=972</guid>
		<description><![CDATA[Et voilà, j&#8217;ai a nouveau un paquet de résultats de test à analyser. Une bonne occasion d&#8217;évaluer Incanter. Incanter se définit comme &#8220;a Clojure-based, R-like platform for statistical computing and graphics.&#8221;. Un R-like ? R est une plate-forme et un langage dérivé de Scheme (lui même dérivé de LISP) qui permet de manipuler facilement des données statistiques [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=972&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://incanter.org/"><img class="alignleft" style="margin:15px 35px 20px 25px;" title="Incanter logo" src="http://incanter.org/incanter-i-logo-holo.png" alt="Incanter logo" width="173" height="175" /></a><br />
Et voilà, j&#8217;ai a nouveau un paquet de résultats de test à analyser. Une bonne occasion d&#8217;évaluer <a href="http://incanter.org/">Incanter</a>.<br />
Incanter se définit comme &#8220;a <span style="text-decoration:underline;"><a href="http://clojure.org/">Clojure</a></span>-based, <span style="text-decoration:underline;"><a href="http://www.r-project.org/">R</a></span>-like platform for statistical computing and graphics.&#8221;.</p>
<p>Un R-like ? R est une plate-forme et un langage dérivé de <a href="http://fr.wikipedia.org/wiki/Scheme">Scheme</a> (lui même dérivé de <a href="http://fr.wikipedia.org/wiki/Lisp">LISP</a>) qui permet de manipuler facilement des données statistiques (les lire depuis une source, les filtrer, calculer des moyennes, afficher ces valeurs sous forme de courbe ou d&#8217;histogramme, et bien d&#8217;autres fonctions pour statisticiens). Ok, mais ça fait à peu près ce que fait Excel. Oui, mais sous forme de langage ce qui permet de scripter bien plus facilement et surtout permet de traiter de grosses masses de données sans devoir les afficher.</p>
<p>Quel est le problème avec R ? C&#8217;est un outil génial mais qui existe dans un éco-système différent de Java et ne permet pas de réutiliser tout ce que l&#8217;on connait. Il est un peu lent et c&#8217;est un mix entre programmation fonctionnelle et C parfois un peu déroutant. Mais il bénéficie d&#8217;une communauté beaucoup plus grande et de beaucoup plus de fonctions que son challenger. Et puis quand même Incanter : Data Sorcery c&#8217;est indispensable d&#8217;aller voir.</p>
<p>Et c&#8217;est une bonne occasion de se mettre à <a href="http://clojure.org/">Clojure</a> aussi. Pour ceux et celles qui n&#8217;auraient pas fait de veille depuis 2 ans, Clojure est un dialecte de LISP (avec des (parenthèses) partout) qui tourne dans la JVM.</p>
<h3>On s&#8217;y met</h3>
<p>Assez tourné autour du sujet. Maintenant il faut regrouper quelques épices et mettre les mains dans le chaudron.</p>
<p>Pour commencer, il faut un environnement Clojure. Vu que le but c&#8217;est d&#8217;utiliser Incanter, autant utiliser la solution de fainéant avec un kit de magicien.</p>
<p><a href="http://incanter.org/downloads/">http://incanter.org/downloads/</a></p>
<p>Et une incantation ! (enfin un clic sur l&#8217;icône)<br />
Mmm &#8230; non c&#8217;est bien ça.<br />
Certes &#8230;<br />
Effectivement, un R-like (encore que dans l&#8217;environnement R il y a deux ou trois trucs dans le menu).</p>
<p><a href="http://cfalguiere.files.wordpress.com/2011/12/incanter.png"><img class="aligncenter size-medium wp-image-989" title="incanter" src="http://cfalguiere.files.wordpress.com/2011/12/incanter.png?w=300&#038;h=200" alt="incanter shell" width="300" height="200" /></a></p>
<p>J&#8217;ai bien réussi à faire une copie d&#8217;écran sur un Mac. Pas de soucis (encore que WordPress s&#8217;obstine a formater le code préformaté).</p>
<p>Le shell Clojure est un environnement interactif qui lit, evalue et affiche le résultat des expressions qu&#8217;on lui soumet. Il est souvent désigné  sous le nom REPL.</p>
<p>Tentons quelques trucs.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>Clojure 1.2.0-master-SNAPSHOT<br />
user=&gt; (1+1)<br />
java.lang.NumberFormatException: Invalid number: 1+1 java.lang.Exception: Unmatched delimiter: )<br />
user=&gt; ()<br />
()<br />
user=&gt;<br />
</code></div>
<p>Soyons positifs, () marche &#8230; même si ça n&#8217;est pas très utile.</p>
<h3>B-A-BA Clojure</h3>
<p>Bon, commençons par le commencement, lire la doc. Vous trouverez des ressources sur <a title="http://data-sorcery.org" href="http://data-sorcery.org/contents/">http://data-sorcery.org/</a> qui est en fait le blog de incanter.org. Un peu trop compliqué de prime abord. J&#8217;ai trouvé là <a href="http://www.chicoree.fr/w/Premiers_pas_avec_Clojure">http://www.chicoree.fr/w/Premiers_pas_avec_Clojure</a> un tutorial très progressif même si c&#8217;est appliqué à un sujet différent. J&#8217;en ai repris quelques éléments.</p>
<p>On veut manipuler des données. Donc on va faire des opérations sur des nombres. Comment on fait une opération ?</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (+ 1 2)<br />
3</code></div>
<p>Et oui, en Clojure, les opérateurs sont préfixés.</p>
<p>Clojure est un langage <a href="http://en.wikipedia.org/wiki/Homoiconicity">homoiconique</a>, il représente les programmes comme des structures de données. Le programme est donc représenté par une liste d&#8217;éléments. D&#8217;un point de vue plus technique, c&#8217;est une S-expression, c&#8217;est à dire une séquence de termes entre parenthèses. Le premier terme est la fonction à appliquer et les termes suivants sont des arguments. N&#8217;importe quel terme peut être une sous-expression. L&#8217;opérateur + est une fonction comme une autre.</p>
<p>Ce qui  permet d&#8217;écrire un suite d&#8217;additions en passant la liste des valeurs ou d&#8217;appliquer une méthode à un objet (vous noterez le . et le fait que la méthode précède la chaîne à laquelle elle s&#8217;applique).</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (+ 1 2 3)<br />
6<br />
user=&gt; (.toUpperCase "Hello")<br />
"HELLO"</code></div>
<p>Conséquence de ce principe, il n&#8217;y pas de règles de précédence des opérateurs en Clojure, l&#8217;opérateur ne peut se trouver qu&#8217;au début de la séquence.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (+ 1 (* 2 3))<br />
7<br />
user=&gt; ; 1 + 2*3</code></div>
<p>Le symbole qui marque le début d&#8217;un commentaire est ;</p>
<p>Il existe aussi des fonctions prédéfinies telles que print ou println similaires au méthodes Java. Vous noterez que les , entre les termes sont facultatives.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (print "Hello")<br />
Hellonil<br />
user=&gt; (println "Hello", "Claude")<br />
Hello Claude<br />
nil<br />
user=&gt; (println "Hello" "Claude")<br />
Hello Claude<br />
nil</code></div>
<p>Mais d&#8217;ou sort ce nil ?</p>
<p>Les fonctions print n&#8217;ont pas de valeur de retour à la différence de +. L&#8217;affichage du texte est un effet de bord de la fonction. nil sert à plusieurs choses en Clojure, mais en particulier à exprimer la fin de séquence et le rien.</p>
<p>Encore quelques détails et nous voilà prêts à écrire Hello World.</p>
<h3>Hello World !</h3>
<p>Une fonction se définit en utilisant la fonction <code>fn</code> suivi des paramètres entre crochets et d&#8217;une expression qui définit le résultat à produire. Et le nom ? Est ce bien nécessaire d&#8217;avoir un nom ?</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (fn [name] (println "Hello" name))<br />
#&lt;user$eval61$fn__62 user$eval61$fn__62@10e9df&gt;<br />
user=&gt; ( (fn [name] (println "Hello" name)) "Claude" )<br />
Hello Claude<br />
nil</code></div>
<p>Cette fonction anonyme est utilisable (enfin, pour peu qu&#8217;on mettre les parenthèses au bon endroit). Finalement, un nom c&#8217;est pratique. On va associer cette fonction à un nom en utilisant la même syntaxe que pour déclarer toute variable, la fonction <code>def</code>.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def moi "Claude")<br />
#'user/moi<br />
user=&gt; (type moi)<br />
java.lang.String<br />
user=&gt; (println moi)<br />
Claude<br />
nil<br />
</code></div>
<p>Et maintenant la fonction hello :</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (def hello (fn [name] (println "Hello" name)) )<br />
#'user/hello</code></div>
<p>La fonction <code>doc</code> retourne des informations sur la fonction. A noter aussi plus haut, la fonction <code>type</code>.</p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (doc hello)<br />
-------------------------<br />
user/hello<br />
nil<br />
</code>  <code> nil<br />
nil<br />
user=&gt; (doc println)<br />
-------------------------<br />
clojure.core/println<br />
([&amp; more])<br />
</code>  <code> Same as print followed by (newline)<br />
nil</code></div>
<p>En pratique, les fonctions sont plutôt déclarées de la manière suivante, grace à la macro <code>defn</code> qui regroupe les deux étapes.</p>
<p><strong>Hello world en Clojure.</strong></p>
<div style="background:white;margin-bottom:20px;border-color:gray;border-style:solid;border-width:1px;padding:5px;"><code>user=&gt; (defn hello [name] (println "Hello", name))<br />
user=&gt; (hello "Claude")<br />
Hello Claude<br />
nil</code></div>
<p>Et Incanter ?<br />
Houlà !!! vous êtes bien pressé jeune sorcier. Il nous reste à voir les collections et quelques concepts secrets. Mais à chaque jour suffit sa peine. C&#8217;est tout pour aujourd&#8217;hui. La suite dans l&#8217;<a href="http://cfalguiere.wordpress.com/2011/12/18/1-2-3-incanter/">épisode 2</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cfalguiere.wordpress.com/972/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cfalguiere.wordpress.com/972/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cfalguiere.wordpress.com/972/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cfalguiere.wordpress.com/972/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cfalguiere.wordpress.com/972/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cfalguiere.wordpress.com/972/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cfalguiere.wordpress.com/972/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cfalguiere.wordpress.com/972/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cfalguiere.wordpress.com/972/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cfalguiere.wordpress.com/972/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cfalguiere.wordpress.com/972/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cfalguiere.wordpress.com/972/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cfalguiere.wordpress.com/972/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cfalguiere.wordpress.com/972/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=972&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cfalguiere.wordpress.com/2011/12/17/abracadabra-incanter/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7fecc53133b5620858e75dc10d1d1a6a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cfalguiere</media:title>
		</media:content>

		<media:content url="http://incanter.org/incanter-i-logo-holo.png" medium="image">
			<media:title type="html">Incanter logo</media:title>
		</media:content>

		<media:content url="http://cfalguiere.files.wordpress.com/2011/12/incanter.png?w=300" medium="image">
			<media:title type="html">incanter</media:title>
		</media:content>
	</item>
		<item>
		<title>Devoxx 2011 et les femmes</title>
		<link>http://cfalguiere.wordpress.com/2011/11/27/devoxx-2011-et-les-femmes/</link>
		<comments>http://cfalguiere.wordpress.com/2011/11/27/devoxx-2011-et-les-femmes/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 18:21:09 +0000</pubDate>
		<dc:creator>cfalguiere</dc:creator>
				<category><![CDATA[Duchess]]></category>
		<category><![CDATA[French]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Devoxx]]></category>
		<category><![CDATA[Women]]></category>

		<guid isPermaLink="false">http://cfalguiere.wordpress.com/?p=910</guid>
		<description><![CDATA[&#8220;The absence of women in tech is the elephant in the living room, it must be discussed&#8221; &#8211; Tim Bray &#8211; Conference Day 2 Keynote &#8211; Devoxx 2011 Tim Bray a commencé sa keynote par ce constat et annoncé la session &#8220;Why we shouldn&#8217;t target women&#8221;. La salle 3 était pleine alors que nous attendions [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=910&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p class="c0"><img class="alignleft" style="margin-right:10pt;" src="http://images.fanpop.com/images/image_uploads/red-elephant-banksy-338521_800_501.jpg" alt="" width="336" height="211" />&#8220;The absence of women in tech is the elephant in the living room, it must be discussed&#8221; &#8211; Tim Bray &#8211; Conference Day 2 Keynote &#8211; Devoxx 2011</p>
<p class="c0">Tim Bray a commencé sa keynote par ce constat et annoncé la session &#8220;Why we shouldn&#8217;t target women&#8221;. La salle 3 était pleine alors que nous attendions 20 personnes. Merci encore à Tim Bray pour sa keynote passionnante et pour nous avoir soutenu aussi efficacement.</p>
<h6 style="margin-bottom:10pt;margin-top:30pt;">Combien de femmes à Devoxx cette année ?</h6>
<p class="c0">Pas des masses. 1% des participanta à Devoxx 2010 étaient des femmes. Le nombre n&#8217;est pas encore disponible pour cette année, mais il semble similaire.</p>
<p class="c0">Plus de femmes speakers en proportion cette année. Parmi les 167 speakers, 9 sont des femmes bien que 4 seulement aient donné des conférences ou des BOF techniques (<span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Patrycja+Wegrzynowicz">Patrycja Wegrzynowicz</a></span> Performance Anti-pattern in Hibernate, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Lilli+Thompson">Lilli Thompson</a></span> Cross platform game programming with PlayN, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Birgitta+Boeckeler">Birgitta Boeckeler</a></span> Code generation at large, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Sonya+Barry">Sonya Barry</a></span> BOF lessons from the <span class="c2"><a class="c3" href="http://java.net/">java.net</a></span> migration ) et 5 ont parlé lors du panel et du BOF sur les femmes dans l&#8217;IT ( <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Regina+ten+Bruggencate">Regina ten Bruggencate</a></span>, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Trisha+Gee">Trisha Gee</a></span>,<span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Anna+Gos">Anna Gos</a></span>, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Kim+Ross">Kim Ross</a></span>, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Claude+Falguiere">Claude Falguiere</a></span> )</p>
<p class="c0">Quatre speakers c&#8217;est plus que l&#8217;an dernier de toute manière. Inutile de blamer l&#8217;organisation Devoxx : peu de femmes dans l&#8217;IT conduit a peu de speakers feminins.</p>
<p class="c0">Les femmes sont de moins en moins nombreuses dans l&#8217;IT et les écoles d&#8217;informatique. Ce nombre a diminué de 40% dans les années 90 à  20% de nos jours. Pourquoi ? Quelqu&#8217;un a posé la question au panel. Malheureusement nous sommes les personnes les moins susceptibles de répondre à cette question et nous ne voulons pas faire d&#8217;hypothèses pour les autres. Vous trouverez plusieurs tentatives d&#8217;explication dans cet article  <span class="c2"><a class="c3" href="http://en.wikipedia.org/wiki/Women_in_computing">http://en.wikipedia.org/wiki/Women_in_computing</a>.</span></p>
<p class="c0">Cette chute affecte aussi d&#8217;autres métiers scientifiques dans une moindre mesure mais à l&#8217;inverse le nombre de femmes dans le BTP augmente en dépit d&#8217;une image très masculine de ces métiers. Il est intéressant de noter que le nombre de femmes dans l&#8217;IT est de l&#8217;ordre de 50% dans les pays émergents en Asie, en Inde et au Brésil.</p>
<h6 style="margin-bottom:10pt;">Un changement semble possible. Alors pourquoi nous ne devons pas cibler les femmes ?</h6>
<p class="c0">Premièrement, est ce un problème de femmes ? L&#8217;absence de femmes est très visible. Mais d&#8217;autres minorités ne sont pas représentées non plus. Combien de speakers noirs ? 1. Combien de speakers agés &#8230;</p>
<p class="c0">Le secteur IT connait un problème de diversité. Il tend à cloner des hommes blancs jeunes avec le même type d&#8217;aptitudes.</p>
<p class="c0">Ce n&#8217;est pas seulement un problème d&#8217;équité. La diversité est nécessaire aux projets. Les projets IT nécessitent un mélange d&#8217;exploration de nouvelles technologie et de prudence, un mélange de rationalisation, d&#8217;imagination de communication, d&#8217;être en contact avec des utilisateurs aussi bien que des ops. L&#8217;IT a besoin de gens qui ont différents profils psychologiques et des trajectoires diverses.</p>
<h6 style="margin-bottom:10pt;">Diversité des gens, diversité des emplois</h6>
<p class="c0">Et si nous présentions l&#8217;IT comme une industrie avec un grand nombre d&#8217;activités qui vont du design à la programmation hard core, pour produire une grande variété d&#8217;applications, des sites webs, des applications pour smartphones aux systèmes de contrôle aérien ? Si nous présentions différents types d&#8217;informaticiens ?</p>
<p class="c0">! image-de-Geek : C&#8217;est fait</p>
<p class="c0">Quoi d&#8217;autre ?</p>
<p class="c0">Pourquoi pas une femme dans l&#8217;équipe parce que les femmes sont douées pour la communication, la conception d&#8217;IHM, ou quoi ce que ce soit d&#8217;autre ? Ce sont juste d&#8217;autres stéréotypes. Dans le panel, Kim aime être la maman de l&#8217;équipe, les autres non. Toutes les femmes n&#8217;aiment pas nourrir et soigner une équipe et à l&#8217;inverse certains hommes font cela très bien. Nous devons prendre en compte l&#8217;être humain pas la catégorie à laquelle il appartient.</p>
<p class="c0">OK mais alors comment pouvons nous accroître la diversité ?</p>
<h6 style="margin-bottom:10pt;">Accueillir les nouveaux venus</h6>
<p class="c0">Avez vous déjà essayé de vous joindre à un groupe de geeks débattant à propos du meilleur framework ? C&#8217;est intimidant, ils semblent si compétents. Les JUGs sont de bons endroits pour rencontrer des équipes de développement et découvrir des opportunités de postes intéressants. Mais les JUGs, particulièrement le ParisJUG parce qu&#8217;il est si grand, sont intimidants pour les nouveaux venus.</p>
<p class="c0">Accueillez les nouveaux venus. Aidez les à rentrer dans les discussions, préparez les sessions comme Duchess France le fait avant le ParisJUG, faites passer les informations que vous avez apprises dans les sessions précédentes, faites connaître les projets Open Source et aidez les à rejoindre ces communautés via des hackerspaces.</p>
<p class="c0">Le nouveau venu est une femme ? Génial ! Mais n&#8217;oubliez pas que les hommes aussi se sentent isolés et nouveaux.</p>
<h6 style="margin-bottom:10pt;">Favorisez la confiance en soi</h6>
<p class="c0">Les femmes manquent souvent de confiance en elles. Elles ne se sentent pas expertes, elles craignent d&#8217;être un mauvais speaker, elles ont peur de se surévaluer. Que pouvons nous faire  ?  Parrainer, travailler en paire sont des moyens de mettre le pied à l&#8217;étrier et d&#8217;améliorer la confiance en soi.</p>
<p class="c0">Et les filles, armez vous de courage et allez y. Parler à 50 personnes, apprendre de nouvelles technologies est inconfortable pour les hommes aussi. Mais ils n&#8217;en parlent pas  ;-)</p>
<p class="c0">De temps en temps vous échouerez. Vous réfléchirez aux raisons, vous vous améliorerez et vous recommencerez.</p>
<p class="c0">Vous tomberez sur des gars qui affirmeront fièrement que le cerveau des femmes n&#8217;est pas cablé pour faire de l&#8217;informatique. Vous avez choisi de travaillez dans l&#8217;IT parce que vous aimez ce job. Rappelez vous vos projets réussis. Même si c&#8217;est vrai (je ne suis pas neurologue) et que c&#8217;est plus dur, et alors ?  Certaines y sont arrivées et vous y arriverez aussi.</p>
<p class="c0">Vous tomberez sur des speakers qui montreront des images blessantes comme dans le &#8220;Duct Tape talk&#8221; à Devoxx 2011 ( <span class="c2"><a class="c3" href="http://www.slideshare.net/ertmanb/devoxx-building-nextgeneration-enterprise-applications-in-java">http://www.slideshare.net/ertmanb/devoxx-building-nextgeneration-enterprise-applications-in-java</a></span> ). Ne vous sentez pas rejetées. Tout le monde pense que montrer des femmes dénudées dans un talk technique est inapproprié. Les plaisanteries sont amusantes autour d&#8217;une bière mais pas quand la cible ne peut pas répondre.</p>
<p class="c0">Les monde est rempli de stéréotypes. Préparez vous à expliquer encore et encore qu&#8217;il y a des femmes dans l&#8217;IT et à montrer ce que vous savez faire jusqu&#8217;à ce qu&#8217;il y ait suffisamment de femmes pour casser ce stéréotype.</p>
<h6 style="margin-bottom:10pt;">Etre parent</h6>
<p class="c0">Une des choses que les femmes doivent gérer est la maternité et le fait d&#8217;élever des enfants.</p>
<p class="c0">Au lieu de rejeter les femmes parce qu&#8217;elles ont des enfants, nous devrions adapter cette industrie aux parents, en particulier les heures de travail. Antonio nous a montré que même les hommes veulent passer du temps avec leurs enfants.</p>
<h6 style="margin-bottom:10pt;">Proaction pour la prochaine génération</h6>
<p class="c0">Les auditeurs ont posé beaucoup de questions sur la pro-action. Doit on être pro-actifs sur l&#8217;emploi des femmes ? Doit on donner des tickets gratuits à toutes les femmes à Devoxx ?</p>
<p class="c0">Les actions positives sont souvent de mauvaises idées. Elles créent des inégalités. Certains hommes se sont plaint des files d&#8217;attente aux toilettes côté hommes alors que côté femme la file était vide. Qu&#8217;auraient ils dit si la fille à côté d&#8217;eux n&#8217;avait pas payé sa place ?</p>
<p class="c0">De plus les quotas peuvent amener à promouvoir des personnes qui ne sont pas qualifiées pour atteindre le quotas. Quelqu&#8217;un a posé une question sur comment se comporter avec un boss femme et plus jeune que soi. Est qu&#8217;elle était jeune et une femme, ou simplement pas encore préparée à ce job ?</p>
<p class="c0">Les gens apprennent par l&#8217;expérience. Les femmes doivent avoir des carrières normales, apprendre, devenir la personne la plus qualifiée et promues parce qu&#8217;elles méritent le poste. C&#8217;est la même chose pour les conférences. Ce serait une mauvaise idée de propulser des femmes qui n&#8217;ont jamais fait de présentations directement à Devoxx. Des tas de présentations données par des hommes sont mauvaises, mais une mauvaise présentation faite par une femme sera plus visible.</p>
<p class="c0">Vous voulez toujours être proactifs ? Préparez le futur.</p>
<p class="c0">Nous voulons tous voir de nouveaux visages dans les conférences, que ce soit des femmes ou des hommes. J&#8217;ai parlé à de nombreux JUG Leaders qui veulent amener plus de femmes dans leurs JUGs. Et bien vous les JUG Leaders avez la difficile tâche de promouvoir de nouveaux speakers et les faire connaître. Demandez aux femmes que vous connaissez de faire des présentations.</p>
<p class="c0">Les JUGs sont des lieux où il est facile de commencer comme speaker car l&#8217;audience est réduite et que l&#8217;enjeu est faible. La présentation peut être donnée plusieurs fois dans divers lieux, ce qui permet de peaufiner les slides, d&#8217;améliorer ses capacités de speaker, contrôler la durée de la session &#8230;</p>
<p class="c0">Si vous êtes un speaker expérimenté, faites un duo ou parrainez de nouveaux speakers. Vous voulez être speaker ? Etudiez les talks de bons speakers et cherchez un mentor pour vous accompagner. Vous êtes dans une équipe, accueillez les nouveaux, amenez les à votre JUG, parlez aux étudiants.</p>
<p class="c0">Malheureusement le nombre de femmes dans l&#8217;IT est limité par les nombre de femmes qui ont choisi d&#8217;étudier l&#8217;informatique.</p>
<p class="c0">Les raisons peuvent être profondes et remonter à l&#8217;enfance. Apprenez aux enfants, filles et garçons, à être curieux, apprenez leur l&#8217;informatique via des jeux, à construire des objets. Inculquez leur l&#8217;intérêt pour les sciences et les choses merveilleuses quelle permet de produire</p>
<p><img class="alignright" src="http://www.tbray.org/ongoing/When/201x/2011/11/21/RUNE3723.png" alt="" width="331" height="264" /></p>
<div style="margin-bottom:10pt;">&nbsp;</div>
<p class="c0">Ce sont quelques réflexions sur les sessions women in IT à Devoxx 2011. N&#8217;hésitez à me faire part de vos retours via les commentaires.</p>
<p>Trisha Gee a aussi écrit un post sur ces sessions <a href="http://mechanitis.blogspot.com/2011/11/why-we-shouldnt-target-women.html">Why We Shouldn&#8217;t Target Women</a>. Merci à Trisha pour la relecture de mon article en anglais.</p>
<p>Le post de Tim Bray&#8217;s surDevoxx 2011 <a href="http://www.tbray.org/ongoing/When/201x/2011/11/21/Devoxx">Geeks Gather in Belgium</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cfalguiere.wordpress.com/910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cfalguiere.wordpress.com/910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cfalguiere.wordpress.com/910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cfalguiere.wordpress.com/910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cfalguiere.wordpress.com/910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cfalguiere.wordpress.com/910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cfalguiere.wordpress.com/910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cfalguiere.wordpress.com/910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cfalguiere.wordpress.com/910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cfalguiere.wordpress.com/910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cfalguiere.wordpress.com/910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cfalguiere.wordpress.com/910/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cfalguiere.wordpress.com/910/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cfalguiere.wordpress.com/910/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=910&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cfalguiere.wordpress.com/2011/11/27/devoxx-2011-et-les-femmes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7fecc53133b5620858e75dc10d1d1a6a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cfalguiere</media:title>
		</media:content>

		<media:content url="http://images.fanpop.com/images/image_uploads/red-elephant-banksy-338521_800_501.jpg" medium="image" />

		<media:content url="http://www.tbray.org/ongoing/When/201x/2011/11/21/RUNE3723.png" medium="image" />
	</item>
		<item>
		<title>Devoxx 2011 and Women</title>
		<link>http://cfalguiere.wordpress.com/2011/11/27/devoxx-2011-and-women/</link>
		<comments>http://cfalguiere.wordpress.com/2011/11/27/devoxx-2011-and-women/#comments</comments>
		<pubDate>Sun, 27 Nov 2011 15:10:40 +0000</pubDate>
		<dc:creator>cfalguiere</dc:creator>
				<category><![CDATA[Duchess]]></category>
		<category><![CDATA[English]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Devoxx]]></category>
		<category><![CDATA[Women]]></category>

		<guid isPermaLink="false">http://cfalguiere.wordpress.com/?p=907</guid>
		<description><![CDATA[&#8220;The absence of women in tech is the elephant in the living room, it must be discussed&#8221; &#8211; Tim Bray &#8211; Conference Day 2 Keynote &#8211; Devoxx 2011 Tim Bray started the keynote with this statement and announced the session &#8220;Why we shouldn&#8217;t target women&#8221;. Room 3 was full, whereas we had been expecting 20 [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=907&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p class="c0"><img class="alignleft" style="margin-right:10pt;" src="http://images.fanpop.com/images/image_uploads/red-elephant-banksy-338521_800_501.jpg" alt="" width="336" height="211" /> &#8220;The absence of women in tech is the elephant in the living room, it must be discussed&#8221; &#8211; Tim Bray &#8211; Conference Day 2 Keynote &#8211; Devoxx 2011</p>
<p>Tim Bray started the keynote with this statement and announced the session &#8220;Why we shouldn&#8217;t target women&#8221;. Room 3 was full, whereas we had been expecting 20 people. Thanks again to Tim Bray for his vibrant keynote and supporting us so brilliantly.</p>
<h6 style="margin-top:30pt;margin-bottom:10pt;">How many women at Devoxx this year ?</h6>
<p>Not many. 1% of Devoxx 2010&#8242;s attendees were women. Figure is unavailable at the moment but it seems similar.</p>
<p>More female speakers in proportion this year. Amongst 167 speakers, 9 are female speakers though only 4 gave a technical talk or BOF (<span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Patrycja+Wegrzynowicz">Patrycja Wegrzynowicz</a></span> Performance Anti-pattern in Hibernate, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Lilli+Thompson">Lilli Thompson</a></span> Cross platform game programming with PlayN, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Birgitta+Boeckeler">Birgitta Boeckeler</a></span> Code generation at large, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Sonya+Barry">Sonya Barry</a></span> BOF lessons from the <span class="c2"><a class="c3" href="http://java.net/">java.net</a></span> migration ) and 5 talked at the women BOF and panel ( <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Regina+ten+Bruggencate">Regina ten Bruggencate</a></span>, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Trisha+Gee">Trisha Gee</a></span>,<span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Anna+Gos">Anna Gos</a></span>, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Kim+Ross">Kim Ross</a></span>, <span class="c2"><a class="c3" href="http://www.devoxx.com/display/DV11/Claude+Falguiere">Claude Falguiere</a></span> )</p>
<p>Four speakers is more than last year anyway. Don&#8217;t blame the Devoxx organization: few women in IT means few female speakers.</p>
<p>Women are fewer and fewer in IT and Computer Sciences schools. The number decreased from 40% in the 90&#8242;s to 20% nowadays. Why? Someone posed the question to the panel. Unfortunately we&#8217;re the people who are the least likely to answer this question and we don&#8217;t want to make assumptions for others. You may find a lot of theories there <span class="c2"><a class="c3" href="http://en.wikipedia.org/wiki/Women_in_computing">http://en.wikipedia.org/wiki/Women_in_computing</a>.</span></p>
<p>The slope down also affects other scientific jobs to a lesser extent but conversely the number of women in the building industry increases despite the male image of these jobs. Interestingly the number of women in IT is about 50% in emerging countries in Asia, India and Brazil.</p>
<h6 style="margin-bottom:10pt;">Apparently a change is possible. So why we shouldn&#8217;t target women ?</h6>
<p>First, is it a women issue ? The lack of women is very visible. But other minorities are not there either. How many black speakers ? 1. How many old speakers &#8230;</p>
<p>IT experiences a diversity issue. It tends to clone white young men with the same kind of aptitudes.</p>
<p>It&#8217;s not only a fairness issue. Diversity is a must for projects. IT projects requires a mix of exploration of new technologies and prudence, a mix of rationalisation, imagination and communication, being in touch with users and ops. IT requires people with different mindsets and career path.</p>
<h6 style="margin-bottom:10pt;">Diversity of people, diversity of jobs</h6>
<p>Let&#8217;s introduce IT as an industry with a large number of activities ranging from design to hard core programming, to produce a large variety of applications from web site, smartphone application to plane control system. Let&#8217;s show different kind of people.</p>
<p>!Geeky image: DONE</p>
<p>What else ?</p>
<p>What about a women in the team because women are good at communicating, visual design or whatever ? These are stereotypes as well. Amongst the panel Kim liked being a mom of the team, others don&#8217;t. Not all women like nurturing and caring team members and conversely some men are very good at that. We must consider the human being not the category</p>
<p>So how can we increase diversity ?</p>
<h6 style="margin-bottom:10pt;">Welcome newcomers</h6>
<p>Have you ever try to join a group of geeks arguing about the better framework ? It&#8217;s intimidating, they all seem so clever. JUGs are good places to get in touch with teams and be aware of interesting jobs. But JUGs, especially the ParisJUG because it&#8217;s so large, may be intimidating to new comers.</p>
<p>Welcome newcomers. Help them get into discussions, prepare the meeting with them like the Duchess France does before the ParisJUG, pass information you&#8217;ve learnt in previous sessions, promote open-source projects and help them join the community though hackerspace.</p>
<p>Newcomer is a woman ? Great! But don&#8217;t forget men also feel new and alone.</p>
<h6 style="margin-bottom:10pt;">Increase confidence</h6>
<p>Women often lack of self-confidence. They don&#8217;t feel expert enough, they fear they’re bad speakers, they worry about rating themselves too highly. What can we do ? Mentoring, pairing are ways to get started and improve self confidence.</p>
<p>And girls, pluck up your courage and move forward. Talking to 50 people, learning new technologies is uncomfortable for men too. But they never mention it <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Sometime you will fail. You will think about it and improve yourself. And retry.</p>
<p>You will come across guys that proudly state that the female brain is not wired to do Computer Science. You&#8217;ve chosen to go for IT because you like this job. Recall all your successful projects. Even if it&#8217;s true (I&#8217;m not a neurologist) and it&#8217;s harder ? So what ! Some of us made it, you will as well.</p>
<p>You will also come across speakers that show offending images like the &#8220;Duct Tape talk&#8221; at Devoxx 2011 ( <span class="c2"><a class="c3" href="http://www.slideshare.net/ertmanb/devoxx-building-nextgeneration-enterprise-applications-in-java">http://www.slideshare.net/ertmanb/devoxx-building-nextgeneration-enterprise-applications-in-java</a></span> ). Don&#8217;t feel rejected. Everyone feel it&#8217;s inappropriate to show almost naked women in a technical talk. Humor is great around a beer, but not when the target can&#8217;t reply.</p>
<p>There are stereotypes around. Be prepared to explain again and again that there are women in IT and show what you can do until there are enough women to break this stereotype.</p>
<h6 style="margin-bottom:10pt;">Parenting</h6>
<p>One the things women have to deal with is maternity leave and parenting.</p>
<p>Instead of rejecting women because of maternity, we may adapt this industry to parenting, especially working hours. Antonio explained that men also want to spend more time with their children.</p>
<h6 style="margin-bottom:10pt;">Proactivity for the next generation</h6>
<p>The attendees had a lot of questions about proactivity. Should we be proactive when hiring women ? Would there be more women if we gave away free tickets for Devoxx to women ?</p>
<p>Proactivity is often a bad idea. It creates imbalance. Some guys complained about long lines at the men&#8217;s room while the women&#8217;s were empty. What would they say if the women besides them had a free ticket ?</p>
<p>Moreover quotas may promote unqualified persons in order to reach the quota. Someone posed a question about how to behave with a boss that is a woman and younger than you are. Was she young and a woman or unprepared for this job ?</p>
<p>People learn by experience. Women should have normal career path, learn, become the most qualified person and be promoted because they deserve the job. Same goes for talks. It would be a very bad idea to promote women that never did any talk straight to Devoxx. Lots of talks given by men are bad, but a bad talk given by a women will be more noticeable.</p>
<p>Still want to be proactive ? Prepare the future.</p>
<p>We all want to see new faces in conferences, whether they are women or men. I&#8217;ve talked to a lot of JUG Leaders that want to bring more women to their JUGs. JUG Leaders, you have the hard task to promote new speakers and let them know. Ask women around you and men too for talks.</p>
<p>JUGs are a nice place to begin as a speaker because of limited audience and low stake. The talk can be given many time in different areas, giving the opportunity to tweak slides, improve speech capacities, calibrate the talk length &#8230;</p>
<p>If you&#8217;re an experienced speaker, pair or mentor new speakers. Want to be a speaker ? Look to all the talks you can from good speakers and look for mentoring. You&#8217;re a team member, welcome newcomers, bring them to your  JUG, talk to students.</p>
<p>Unfortunately the number of women in IT is limited by the number of women that went for computer sciences.</p>
<p>It takes root in childhood. Teach children, girls and boys, to be curious, to learn programming through games, to build things. Teach them interest in sciences and all the beautiful things science produces.</p>
<p><img class="alignright" src="http://www.tbray.org/ongoing/When/201x/2011/11/21/RUNE3723.png" alt="" width="331" height="264" /></p>
<div style="margin-bottom:10pt;">&nbsp;</div>
<p class="c0">These are reflections about Devoxx 2011&#8242;s women in IT sessions. Please feel free to give me your feedback via the comments form.</p>
<p>Trisha Gee also wrote a post about these sessions <a href="http://mechanitis.blogspot.com/2011/11/why-we-shouldnt-target-women.html">Why We Shouldn&#8217;t Target Women</a>. Thanks Trisha for proofreading my post.</p>
<p>Tim Bray&#8217;s post about Devoxx 2011 <a href="http://www.tbray.org/ongoing/When/201x/2011/11/21/Devoxx">Geeks Gather in Belgium</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cfalguiere.wordpress.com/907/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cfalguiere.wordpress.com/907/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cfalguiere.wordpress.com/907/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cfalguiere.wordpress.com/907/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cfalguiere.wordpress.com/907/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cfalguiere.wordpress.com/907/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cfalguiere.wordpress.com/907/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cfalguiere.wordpress.com/907/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cfalguiere.wordpress.com/907/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cfalguiere.wordpress.com/907/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cfalguiere.wordpress.com/907/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cfalguiere.wordpress.com/907/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cfalguiere.wordpress.com/907/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cfalguiere.wordpress.com/907/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=907&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cfalguiere.wordpress.com/2011/11/27/devoxx-2011-and-women/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7fecc53133b5620858e75dc10d1d1a6a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cfalguiere</media:title>
		</media:content>

		<media:content url="http://images.fanpop.com/images/image_uploads/red-elephant-banksy-338521_800_501.jpg" medium="image" />

		<media:content url="http://www.tbray.org/ongoing/When/201x/2011/11/21/RUNE3723.png" medium="image" />
	</item>
		<item>
		<title>Des images en 8-bits pour iOS</title>
		<link>http://cfalguiere.wordpress.com/2011/10/30/des-images-en-8-bits-pour-ios/</link>
		<comments>http://cfalguiere.wordpress.com/2011/10/30/des-images-en-8-bits-pour-ios/#comments</comments>
		<pubDate>Sun, 30 Oct 2011 17:44:07 +0000</pubDate>
		<dc:creator>cfalguiere</dc:creator>
				<category><![CDATA[Duchess]]></category>
		<category><![CDATA[French]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Valtech]]></category>
		<category><![CDATA[ImageMagick]]></category>
		<category><![CDATA[PNG]]></category>

		<guid isPermaLink="false">http://cfalguiere.wordpress.com/?p=806</guid>
		<description><![CDATA[Warning: Input PNG does not have an 8 bit input depth Lors du packaging d&#8217;une application, XCode vérifie les caractéristiques des images embarquées avec l&#8217;application. En interactif on ne voit rien, mais lorsque l&#8217;on scripte les opérations de fabrication, ce type de messages apparaît : CopyPNGFile build/Release-iphoneos/Ipad.app/interview-frP05-100-2.png Ipad/Images/Interview/Portrait/100/interview-frP05-100-2.png  libpng warning: Warning: Input PNG does not [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=806&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<h4 style="margin-bottom:20px;">Warning: Input PNG does not have an 8 bit input depth</h4>
<p>Lors du packaging d&#8217;une application, XCode vérifie les caractéristiques des images embarquées avec l&#8217;application. En interactif on ne voit rien, mais lorsque l&#8217;on scripte les opérations de fabrication, ce type de messages apparaît :</p>
<pre style="margin-bottom:20px;"><strong>CopyPNGFile build/Release-iphoneos/Ipad.app/interview-frP05-100-2.png Ipad/Images/Interview/Portrait/100/interview-frP05-100-2.png </strong>
libpng warning: Warning: Input PNG does not have an 8 bit input depth. Please convert your PNG to 8-bit for optimal performance on iPhone OS</pre>
<p>Si on regarde d&#8217;un peu plus près on se rend compte que les images concernées sont toutes du même type.</p>
<table style="border:dotted 1px #888888;margin-bottom:20px;">
<tbody>
<tr>
<td><img class="alignleft size-thumbnail wp-image-825" title="interview-frP01-100-1" src="http://cfalguiere.files.wordpress.com/2011/10/interview-frp01-100-1.png?w=150&#038;h=150" alt="" width="150" height="150" /></td>
<td><img class="aligncenter size-thumbnail wp-image-826" title="interview-frP01-100-10" src="http://cfalguiere.files.wordpress.com/2011/10/interview-frp01-100-10.png?w=150&#038;h=150" alt="" width="150" height="150" /></td>
<td><img class="alignright size-thumbnail wp-image-827" title="interview-frP01-100-11" src="http://cfalguiere.files.wordpress.com/2011/10/interview-frp01-100-11.png?w=150&#038;h=150" alt="" width="150" height="150" /></td>
</tr>
</tbody>
</table>
<p>L&#8217;application contient un entretien &#8220;PDF&#8221; zoomable stocké sous forme d&#8217;images 2048&#215;1538. Pour améliorer les performances à l&#8217;affichage ces images ont été découpées en tuiles. Au zoom maximal, certaines zones sont assez vides ou monochromes, en particulier les bords d&#8217;images.</p>
<p>Les images sont découpées avec <a href="http://www.imagemagick.org/script/index.php">ImageMagick</a>. Un examen des images avec warning montre qu&#8217;elles n&#8217;ont pas les mêmes caractériques que les images qui ne causent pas d&#8217;erreur.</p>
<p>Une image sans erreur</p>
<pre style="margin-bottom:20px;"><strong>identify -verbose Ipad/Images/Interview/Landscape/100/interview-frL02-100-13.png </strong>Image: IpadCorporate/Images/Essentiel/Interview/Landscape/100/interview-frL02-100-13.png
  Format: PNG (Portable Network Graphics)
  Class: DirectClass
  Geometry: 256x256+0+0
  Resolution: 72x72
  Print size: 3.55556x3.55556
  Units: Undefined
  <strong>Type: TrueColor</strong>
  Endianess: Undefined
  <strong>Colorspace: RGB</strong>
  <strong>Depth: 8-bit</strong>
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit</pre>
<p>L&#8217;image la plus à gauche, qui ne contient quasiment que tu texte en gris est en GrayScale<span class="Apple-style-span" style="font-family:Consolas, Monaco, monospace;font-size:12px;white-space:pre;"> </span></p>
<pre style="margin-bottom:20px;"><strong>identify -verbose Ipad/Images/Interview/Portrait/100/interview-frP01-100-1.png </strong>Image: IpadCorporate/Images/Essentiel/Interview/Portrait/100/interview-frP01-100-1.png
  Format: PNG (Portable Network Graphics)
  Class: PseudoClass
  Geometry: 256x256+0+0
  Resolution: 72x72
  Print size: 3.55556x3.55556
  Units: Undefined
  <strong>Type: Grayscale</strong>
  Base type: Grayscale
  Endianess: Undefined
  <strong>Colorspace: Gray</strong>
  <strong>Depth: 8-bit</strong>
  Channel depth:
    gray: 8-bit</pre>
<p>Certaines autres images sont en Bilevel (Black &amp; White)<span class="Apple-style-span" style="font-family:Consolas, Monaco, monospace;font-size:12px;white-space:pre;"> </span></p>
<pre style="margin-bottom:20px;"><strong>identify -verbose Ipad/Images/Interview/Landscape/100/interview-frL02-100-32.png </strong>Image: IpadCorporate/Images/Essentiel/Interview/Landscape/100/interview-frL02-100-32.png
  Format: PNG (Portable Network Graphics)
  Class: PseudoClass
  Geometry: 256x256+0+0
  Resolution: 72x72
  Print size: 3.55556x3.55556
  Units: Undefined
  <strong>Type: Bilevel</strong>
  Base type: Bilevel
  Endianess: Undefined
  <strong>Colorspace: Gray</strong>
  <strong>Depth: 8/1-bit</strong>
  Channel depth:
    gray: 1-bit</pre>
<p>ImageMagick cherche le format le plus adapté ce qui revient parfois à transformer l&#8217;image en niveaux de gris voir en Noir et Blanc si elle n&#8217;a pas de contenu.</p>
<h4 style="margin-bottom:20px;">Une première solution</h4>
<p>J&#8217;ai d&#8217;abord tenté de forcer la profondeur à 8-bits avec la syntaxe <strong>png8:nom-fichier</strong></p>
<pre style="margin-bottom:20px;">convert interview-frP01-100.png -crop 256x256 +repage +adjoin <strong>png8:</strong>interview-frP01-100-%d.png</pre>
<p>Cette option supprime bien les warnings mais ne rend pas un très bon résultat. Sur l&#8217;image réassemblée, le dégradé sur le fond est remplacé par un effet psychédélique assez laid.</p>
<table style="margin-bottom:20px;border-style:none;">
<tbody>
<tr>
<td><a href="http://cfalguiere.files.wordpress.com/2011/10/interview-frp01-100-113.png"><img class="alignright size-thumbnail wp-image-833" title="interview-frP01-100-11" src="http://cfalguiere.files.wordpress.com/2011/10/interview-frp01-100-113.png?w=150&#038;h=150" alt="" width="150" height="150" /></a></td>
<td><a href="http://cfalguiere.files.wordpress.com/2011/10/image-degradc3a9e1.png"><img class="alignright size-full wp-image-834" title="image-degradée" src="http://cfalguiere.files.wordpress.com/2011/10/image-degradc3a9e1.png?w=614" alt=""   /></a></td>
</tr>
</tbody>
</table>
<p>L&#8217;image est postérisée car le nombre de couleurs est réduit.</p>
<pre style="margin-bottom:20px;"><strong>identify -verbose generated_images/Interview/Portrait/100/interview-frP01-100-10.png </strong>Image: generated_images/Interview/Portrait/100/interview-frP01-100-10.png
  Format: PNG (Portable Network Graphics)
  Class: PseudoClass
  Geometry: 256x256+0+0
  Resolution: 72x72
  Print size: 3.55556x3.55556
  Units: Undefined
  Type: Palette
  Endianess: Undefined
  Colorspace: RGB
 <strong> Depth: 8/4-bit</strong>
  Channel depth:
    red: 4-bit
    green: 4-bit
    blue: 4-bit</pre>
<p>Ceci dit cette option marche bien sur un autre jeu de tuiles qui ne contient que des images monochromes.</p>
<h4 style="margin-bottom:20px;">La solution correcte</h4>
<p>J&#8217;ai ensuite tenté diverses options (-depth, -colorspace, -type, -define png:bit-depth). En fait, CopyPNGFile semble rejeter le colorscale Gray mais je n&#8217;ai pas réussi à convaincre ImageMagick de ne pas changer le colorscale des tuiles très simples.</p>
<p>L&#8217;issue est dans le pngN: mais il faut lui donner les bonnes valeurs.</p>
<p>Le build veut 8 bits par canal de couleur.</p>
<div style="margin-bottom:0;">Les images en RGB (Red Green Bleu le color scale le plus courant) comportent 3 canaux :</div>
<ul style="margin-bottom:20px;margin-top:0;">
<li>un qui contient la valeur du rouge,</li>
<li>un qui contient la valeur du vert (Green)</li>
<li>et un qui contient la valeur du bleu.</li>
</ul>
<p>Chaque pixel est codé sur 8 bits soit une valeur entre 0 et 255. La combinaison de la valeur de chaque canal produit la couleur souhaitée parmi 16 millions de couleurs (256x256x256).</p>
<p>Pour les images transparentes, elles comportent un quatrième canal, le canal alpha, qui indique la transparence du pixel.</p>
<p>Si on veut <strong>8 bits par canal</strong> il faut indiquer <strong>png24</strong> (3&#215;8) pour une image sans transparence, ou <strong>png32</strong> (4&#215;8) pour une image avec un canal alpha.</p>
<pre>convert interview-frP01-100.png -crop 256x256 +repage +adjoin <strong>png24:</strong>interview-frP01-100-%d.png</pre>
<p>Cette option supprime les warnings et ne dégrade pas l&#8217;image.</p>
<p>L&#8217;image de gauche en niveau de gris devient</p>
<pre style="margin-bottom:20px;"><strong>identify -verbose Ipad/Images/Interview/Portrait/100/interview-frP01-100-1.png </strong>Image: IpadCorporate/Images/Essentiel/Interview/Portrait/100/interview-frP01-100-1.png
  Format: PNG (Portable Network Graphics)
  Class: DirectClass
  Geometry: 256x256+0+0
  Resolution: 72x72
  Print size: 3.55556x3.55556
  Units: Undefined
  <strong>Type: Grayscale</strong>
  Base type: Grayscale
  Endianess: Undefined
  <strong>Colorspace: RGB</strong>
 <strong> Depth: 8-bit</strong>
  Channel depth:
    gray: 8-bit</pre>
<p>et la plupart des images ressemblent à ce qui suit</p>
<pre style="margin-bottom:20px;"><strong>identify -verbose Ipad/Images/Interview/Portrait/100/interview-frP01-100-10.png </strong>Image: IpadCorporate/Images/Essentiel/Interview/Portrait/100/interview-frP01-100-10.png
  Format: PNG (Portable Network Graphics)
  Class: DirectClass
  Geometry: 256x256+0+0
  Resolution: 72x72
  Print size: 3.55556x3.55556
  Units: Undefined
  <strong>Type: TrueColor</strong>
  Endianess: Undefined
  <strong>Colorspace: RGB</strong>
  <strong>Depth: 8-bit</strong>
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit</pre>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cfalguiere.wordpress.com/806/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cfalguiere.wordpress.com/806/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cfalguiere.wordpress.com/806/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cfalguiere.wordpress.com/806/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cfalguiere.wordpress.com/806/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cfalguiere.wordpress.com/806/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cfalguiere.wordpress.com/806/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cfalguiere.wordpress.com/806/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cfalguiere.wordpress.com/806/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cfalguiere.wordpress.com/806/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cfalguiere.wordpress.com/806/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cfalguiere.wordpress.com/806/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cfalguiere.wordpress.com/806/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cfalguiere.wordpress.com/806/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=806&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cfalguiere.wordpress.com/2011/10/30/des-images-en-8-bits-pour-ios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7fecc53133b5620858e75dc10d1d1a6a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cfalguiere</media:title>
		</media:content>

		<media:content url="http://cfalguiere.files.wordpress.com/2011/10/interview-frp01-100-1.png?w=150" medium="image">
			<media:title type="html">interview-frP01-100-1</media:title>
		</media:content>

		<media:content url="http://cfalguiere.files.wordpress.com/2011/10/interview-frp01-100-10.png?w=150" medium="image">
			<media:title type="html">interview-frP01-100-10</media:title>
		</media:content>

		<media:content url="http://cfalguiere.files.wordpress.com/2011/10/interview-frp01-100-11.png?w=150" medium="image">
			<media:title type="html">interview-frP01-100-11</media:title>
		</media:content>

		<media:content url="http://cfalguiere.files.wordpress.com/2011/10/interview-frp01-100-113.png?w=150" medium="image">
			<media:title type="html">interview-frP01-100-11</media:title>
		</media:content>

		<media:content url="http://cfalguiere.files.wordpress.com/2011/10/image-degradc3a9e1.png" medium="image">
			<media:title type="html">image-degradée</media:title>
		</media:content>
	</item>
		<item>
		<title>Présentation performance pour le Geneva JUG et le JUGL</title>
		<link>http://cfalguiere.wordpress.com/2011/10/16/presentation-performance-pour-le-geneva-jug-et-le-jugl/</link>
		<comments>http://cfalguiere.wordpress.com/2011/10/16/presentation-performance-pour-le-geneva-jug-et-le-jugl/#comments</comments>
		<pubDate>Sun, 16 Oct 2011 12:14:56 +0000</pubDate>
		<dc:creator>cfalguiere</dc:creator>
				<category><![CDATA[Duchess]]></category>
		<category><![CDATA[French]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Valtech]]></category>

		<guid isPermaLink="false">http://cfalguiere.wordpress.com/?p=789</guid>
		<description><![CDATA[Voici les slides de la présentation que j&#8217;ai faite au Geneva JUG à Genève et au JUGL à Lausanne. L&#8217;enregistrement fait au JUGL est en ligne sur parleys http://www.parleys.com/#st=5&#38;id=2695&#38;sl=3<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=789&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Voici les slides de la présentation que j&#8217;ai faite au Geneva JUG à Genève et au JUGL à Lausanne.</p>
<iframe src='http://www.slideshare.net/slideshow/embed_code/9719835' width='614' height='503'></iframe>
<p>L&#8217;enregistrement fait au JUGL est en ligne sur parleys http://www.parleys.com/#st=5&amp;id=2695&amp;sl=3</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/cfalguiere.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/cfalguiere.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/cfalguiere.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/cfalguiere.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/cfalguiere.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/cfalguiere.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/cfalguiere.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/cfalguiere.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/cfalguiere.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/cfalguiere.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/cfalguiere.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/cfalguiere.wordpress.com/789/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/cfalguiere.wordpress.com/789/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/cfalguiere.wordpress.com/789/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=cfalguiere.wordpress.com&amp;blog=7986623&amp;post=789&amp;subd=cfalguiere&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://cfalguiere.wordpress.com/2011/10/16/presentation-performance-pour-le-geneva-jug-et-le-jugl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/7fecc53133b5620858e75dc10d1d1a6a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">cfalguiere</media:title>
		</media:content>
	</item>
	</channel>
</rss>
