<?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/"
	>

<channel>
	<title>Coder-Studio &#187; Non classé</title>
	<atom:link href="http://www.coder-studio.com/blog/category/non-classe/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.coder-studio.com/blog</link>
	<description></description>
	<lastBuildDate>Wed, 02 Mar 2011 22:17:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>CipherSaber - Chiffrement en kit</title>
		<link>http://www.coder-studio.com/blog/ciphersaber-chiffrement-en-kit/</link>
		<comments>http://www.coder-studio.com/blog/ciphersaber-chiffrement-en-kit/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 22:07:59 +0000</pubDate>
		<dc:creator>Wett</dc:creator>
				<category><![CDATA[Non classé]]></category>
		<category><![CDATA[ARC4]]></category>
		<category><![CDATA[ARCFOUR]]></category>
		<category><![CDATA[Chiffrement]]></category>
		<category><![CDATA[CipherSaber]]></category>
		<category><![CDATA[Cryptage]]></category>
		<category><![CDATA[RC4]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=404</guid>
		<description><![CDATA[CipherSaber, c'est la reprise du concept selon lequel il faut en savoir faire un minimum, tout seul, comme un grand. A l'instar des Jedis dans l'univers Star Wars qui vont réaliser eux-même leur sabre laser (vous comprenez maintenant le nom du projet), on nous propose de réaliser nous-même notre petit logiciel de chiffrement. ]]></description>
			<content:encoded><![CDATA[<h2>Sabre <span style="text-decoration: line-through;">laser</span> de chiffrement</h2>
<p>Au détour d'une naviguation web fortuite mais bienheureuse, je suis tombé sur <a title="CipherSaber" href="http://ciphersaber.gurus.org/">CipherSaber</a>. Vous savez, c'est ce genre de moment où on tombe sur une initiative sympa, facile à suivre et qui fait sens. Bref, j'ai accroché tout de suite, alors j'ai laissé tomber ce que j'étais en train de faire et y ai consacré mes heures suivantes.<br />
CipherSaber, c'est la reprise du concept selon lequel il faut en savoir faire un minimum, tout seul, comme un grand. A l'instar des Jedis dans l'univers Star Wars qui vont réaliser eux-même leur sabre laser (vous comprenez maintenant le nom du projet), on nous propose de réaliser nous-même notre petit logiciel de chiffrement.<span id="more-404"></span> Je vous laisse parcourir le site pour une explication plus en détail de la philosophie derrière ce petit combat pour la cryptographie, mais l'idée est là : A n'importe quel moment, nous devrions être capable de produire un logiciel de chiffrement suffisamment solide pour être utilisé sans risque, afin de s'affranchir des éventuelles lois contre l'exportation et garantir notre liberté de parole, autant que faire se peut. Joli programme !<br />
Voici les instructions que l'on nous fournit pour réaliser cet outil (directement traduites depuis le lien du début de l'article) :</p>
<ol>
<li> Utiliser l'algorithme de chiffrement ARCFOUR (ou RC4), tel que décrit par exemple <a title="ici" href="http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt">ici</a>.</li>
<li>Chaque fichier chiffré se compose d'un Vecteur d'Initialisation (IV) de 10 octets, puis du contenu chiffré. Un nouveau vecteur aléatoire devra être généré à chaque chiffrement de fichier.</li>
<li>La clé de chiffrement se compose elle de la clé que l'utilisateur nous fournit suivie de ce même Vecteur d'Initialisation.</li>
</ol>
<p>Et effectivement, ce sont les seules indications dont nous aurons besoin. Une fois le programme réalisé, nous aurons la possibilité de déchiffrer un certificat en gif, preuve de notre petite réussite. Si l'idée vous plait et que vous souhaitez vous contenter de ces informations pour vous-même construire votre CipherSaber, alors ne revenez lire la suite de cet article que quand vous aurez votre certificat !</p>
<h2>ARCFOUR ?</h2>
<p>ARCFOUR, c'est l'algorithme libre identique au RC4 qui lui est une propriété de RSA Security. Ici, pas de clé publique/privée, pas d'algorithme alambiqué, mais une solution implémentable "de tête", pour peu qu'on fasse l'effort de la comprendre et d'en retenir les fondements.</p>
<p>Bon, ok, c'est gentil, mais le ARCFOUR moi, je ne le connais pas. Qu'à cela ne tienne, il suffira de suivre le lien donné ou de rechercher RC4 sur le web pour que l'algorithme nous tombe tout cru, ou presque. Mais j'insiste, le but ici est de pouvoir à tout moment réécrire ce logiciel de mémoire, donc on apportera un soin tout particulier à en retenir les principes de fonctionnement.</p>
<p>C'est un algorithme de chiffrement à flot, il repose sur deux phases :</p>
<ol>
<li>A partir de la clé K que nous donne l'utilisateur, on va générer un tableau d'état S que l'on va mélanger de nombreuses fois afin d'obtenir une suite de chiffres pseudo-aléatoires.</li>
<li>On va ensuite chiffrer le contenu sensible par un simple XOR entre ses octets et ceux du tableau d'état. Si c'est votre tout premier pas dans le monde de la cryptographie, sachez que l'opération XOR est "réversible" (il y a sûrement un terme mathématique approprié à cette propriété, pardon à eux pour mon ignorance), c'est à dire que si A xor B = C, alors A xor C = B. On utilise donc exactement la même procédure et la même clé pour chiffrer et déchiffrer.</li>
</ol>
<p>Maintenant qu'on saisit la généralité de la méthode, voyons comment la réaliser plus en détail :</p>
<ol>
<li>Créons notre tableau d'état :
<ol>
<li>Soit la clé K d'une taille de 256 octets (si elle fait moins, on la répète à la suite jusqu'à obtenir 256 octets pile)</li>
<li>Construisons un tableau S de 256 valeurs, chacune contenant son index basé à 0 : S[0] = 0, S[255]=255.</li>
<li>Mélangeons S, avec i allant de 0 à 255 et j démarrant à 0:
<ol>
<li>Inverser l'élément i de S <em>avec celui de rang</em> (S[i]+K[i])+j, j étant le rang du "mélangé" précédent. Autrement dit, ajouter S[i]+K[i] à j et inverser S[i] et S[j]</li>
</ol>
</li>
</ol>
</li>
<li>Chiffrons :
<ol>
<li>Boucler sur chaque octet du fichier à chiffrer, et avec i et j démarrant à 0 :
<ol>
<li>incrémenter i</li>
<li>Un peu comme précédemment, inverser l'élément i de S avec celui de rang (S[i]+j), j étant le rang du mélangé précédent. Autrement dit, ajouter S[i] à j et inverser S[i] et S[j]</li>
<li>Combiner l'octet à chiffrer avec la valeur de l'élément S[i]+S[j] par un XOR.</li>
</ol>
</li>
</ol>
</li>
</ol>
<p>J'ai conscience que ce n'est sûrement pas clair au premier abord, mais j'ai essayé ici de résumer l'algorithme par ses opérations logiques, afin que ce soit appréhendable pour l'esprit et donc plus aisé à retenir. Pour une version plus proche de l'implémentation, il vous reste votre moteur de recherche préféré. Retenez par contre un détail important : Chaque éléments de chaque tableau est un octet, il en va de même pour i et j. Par conséquent, <strong>chaque addition se fait modulo 256</strong>.</p>
<p>Une fois votre implémentation écrite, n'hésitez pas à la tester. Un petit chiffrement/dechiffrement pour s'assurer que tout va bien ne sera pas de trop, croyez-moi.</p>
<h2>IVs et tests</h2>
<p>Maintenant que votre ARC4 est implémenté et testé, reste à en faire quelque chose. Oui car utilisé tel quel, c'est un algorithme tout à fait prévisible, or nous recherchons un chiffrement suffisament fort. La règle qui semble être celle de base, c'est qu'un même chiffrement appliqué à un même fichier ne doit pas donner le même résultat. L'idée est donc d'ajouter un IV, l'Initialisation Vector dont on parlait plus haut.  Ainsi, lors du chiffrement, on va générer un IV <em>aléatoire</em> de 10 octets, qu'on va :</p>
<ul>
<li>Mettre à la suite de la clé que nous a fourni l'utilisateur pour produire une clé <em>unique</em> à fournir à l'argorithme de chiffrement</li>
<li>Ajouter en clair au début du fichier crypté, afin quand même que l'on puisse connaitre la clé à utiliser pour déchiffrer.</li>
</ul>
<p>L'IV est donc une donnée "publique" puisqu'en clair, mais cela suffit à notre besoin de non-répétition. Par contre son choix est important, crucial même, alors attention à la méthode de génération pseudo aléatoire que vous allez utiliser.</p>
<p>Et voilà ! Une fois ce dernier détail implémenté, il ne vous reste plus qu'à tester votre programme sur les fichiers chiffrés fournis sur le site. Si vos tests ne fonctionnent pas, vous trouverez dans la FAQ quelques points à vérifier dans votre code pour trouver le bug. Voici ceux qui m'ont servi :</p>
<ul>
<li> Si vous programmez en C/C++, ouvrez vos fichiers en binaire... On aurait tendance à l'oublier.</li>
<li>Double, triple-vérifiez vos index et les combinaisons de tailles, ajout, suppression, décalages.</li>
</ul>
<h2>Aller un peu plus loin</h2>
<p>Ainsi que vous avez peut-être lu quelque part, certaines faiblesses ont été décelées dans l'ARC4. Elles sont notamment à la base des attaques contre le protocole WEP maintenant si rapides qu'on peut faire tomber un réseau Wifi en 15 minutes. L'auteur recommande donc de passer à... CipherSaber 2 ! &lt;Musique épique, et là avouez, ça picote !&gt;</p>
<p>En fait ce n'est qu'une petite évolution de votre programme actuel : le moyen le plus simple de sécuriser son CipherSaber est de démultiplier le nombre de mélanges de S. Ainsi, à l'étape 3 de la création de notre tableau d'état décrite ci-dessus, on va non pas effectuer ce mélange complet de S une fois mais N fois, N étant une donnée qu'il faudra bien évidemment connaitre lors du déchiffrement. Pour être tranquille, utilisez un N de 15 ou 20.</p>
<h2>Aller vraiment au bout de son sabre</h2>
<p>Mais toute bonne votre méthode de chiffrement soit-elle, si vous utilisez une passphrase de 3 lettres ou votre date d'anniversaire, tout cela n'aura servi à rien. Ce n'est pas le but de l'article que de décrire un moyen efficace d'en générer une, mais sachez qu'il existe des méthodes comme celle décrite sur <a title="Diceware" href="http://world.std.com/~reinhold/diceware.html">Diceware</a> (c'est depuis ce site que j'ai découvert CipherSabre, ce n'est donc pas par hasard que je met ce lien ici). Retenez tout de même qu'un mot de passe n'est pas une.. hm, et bien phrase de passe. Le premier est adapté à un contexte local, lorsque vous avez besoin d'un mot court à entropie forte. La passphrase, de ce que j'en comprend, permet de s'affranchir plus ou moins du coté "impossible à retenir" d'un vrai de mot de passe fort, en augmentant la taille de la clé à 15 ou 20 caractères avec des mots courants, tout en fournissant pour peu qu'elle soit bien choisie (aléatoire) un entropie plus que satisfaisante.</p>
<h2>Et alors ?</h2>
<p>Et bien voilà, maintenant vous savez écrire un logiciel de chiffrement. Gardez bien-sûr conscience qu'il ne remplacera jamais une vraie solution comme OpenPGP, qui malgré sa puissance est deja suffisament mal diffusée pour qu'on n'en rajoute pas à vouloir utiliser notre solution personnelle moins pratique et moins sûre. Mais enfin, à votre niveau vous savez reproduire tout seul un outil basique mais potentiellement utile en situation réelle, vous avez limité votre dépendance à ceux qui savent, ceux qui dirigent, ceux en qui on vous demande d'avoir une confiance presque aveugle. Et enfin, vous en aurez un peu appris sur les fondements de la cryptographie, peut-être plus qu'en jouant avec AirCrack sur votre propre réseau ou celui du voisin...</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/ciphersaber-chiffrement-en-kit/feed/</wfw:commentRss>
		<slash:comments>3854</slash:comments>
		</item>
		<item>
		<title>La programmation fonctionnelle n&#039;est pas un jouet pour académiciens</title>
		<link>http://www.coder-studio.com/blog/la-programmation-fonctionnelle-nest-pas-un-jouet-pour-academiciens/</link>
		<comments>http://www.coder-studio.com/blog/la-programmation-fonctionnelle-nest-pas-un-jouet-pour-academiciens/#comments</comments>
		<pubDate>Sun, 26 Apr 2009 18:30:26 +0000</pubDate>
		<dc:creator>Alp Mestan</dc:creator>
				<category><![CDATA[Langages fonctionnels]]></category>
		<category><![CDATA[Non classé]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[lambda]]></category>
		<category><![CDATA[lisp]]></category>
		<category><![CDATA[ocaml]]></category>
		<category><![CDATA[programmation fonctionnelle]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=267</guid>
		<description><![CDATA[Bonjour, Cela fait maintenant un moment que j'apprends et pratique la programmation fonctionnelle, aussi bien sur le point de vue théorique en m'intéressant à ses relations avec la théorie des catégories (mathématiques) entre autres, que sur le point de vue pratique, c'est à dire que j'ai mené quelques projets (de petite envergure... oui, c'est proportionnel [...]]]></description>
			<content:encoded><![CDATA[<p>Bonjour,</p>
<p>Cela fait maintenant un moment que j'apprends et pratique la programmation fonctionnelle, aussi bien sur le point de vue théorique en m'intéressant à ses relations avec la théorie des catégories (mathématiques) entre autres, que sur le point de vue pratique, c'est à dire que j'ai mené quelques projets (de petite envergure... oui, c'est proportionnel au temps que je peux passer dessus) à bien.</p>
<p>Quand on dit "langage fonctionnel" ou "programmation fonctionnelle", les gens s'imaginent (pour ceux qui ne connaissent pas) des programmes avec tout un tas de fonctions, c'est tout. Ce n'est pas ça la programmation fonctionnelle. Enfin biensûr il y a des fonctions, mais la programmation fonctionnelle ne s'arrête pas là.</p>
<p>Déjà, la programmation fonctionnelle, c'est une toute autre façon de concevoir des programmes. Détailler toutes les différences avec la programmation impérative serait pire que les 12 travaux d'Hercules et c'est pourquoi je ne le ferai pas. Je vais toutefois vous parler des points qui font que je suis désormais adepte de ce style de programmation.</p>
<p><center><img src="http://www.geocities.com/EnchantedForest/1110/images/lambda.gif" alt="" title="La programmation fonctionnelle tire ses racines du lambda-calcul" /></center><br />
<span id="more-267"></span></p>
<p>Tout d'abord, étant assez orienté mathématiques, il y a une première chose qui me plaît. Dans les langages de programmation fonctionnelle (du moins la plupart), on définit des types, des opérations sur ces types, le tout très simplement et de manière on ne peut plus cohérente.</p>
<p>Ensuite, pour les langages fonctionnels compilés et typés statiquement, on est généralement accompagné d'un compilateur très strict, qui tentera d'éliminer un maximum d'incohérences (comprendre "erreurs") en nous envoyant des erreurs très précises en rapport avec le fait que nous n'avons pas bien typé des parties de notre programme. De plus, les 3 langages majeurs pour une utilisation "real world", Haskell, OCaml et F#, ont vu leur compilateur se doter de l'inférence de type ; il s'agit de la capacité qu'a un compilateur a donner lui-même un type à vos valeurs dans le programme (fonctions, expressions, ...). Entre ceci et la vérification des types, la compilation possède une part de travail autour des types en action dans votre code.</p>
<p>De plus, en programmation fonctionnelle, il s'agit de ne pas avoir ce que l'on appelle des effets de bords ; on parle de programmation fonctionnelle pure ; dans un tel cadre, une fonction à qui l'on donne les mêmes entrées renverra toujours la même sortie. Les programmeurs fonctionnels font en sorte d'isoler les parties pour lesquelles ce n'est pas vrai (lecture d'un fichier, intéraction réseau, ...) : monades en Haskell, on laisse la possibilité de faire de l'impératif pour OCaml et F#, ... </p>
<p>Continuons sur la curryfication. Cette dernière consiste à faire par exemple d'une fonction de 2 arguments 2 fonctions à 1 argument, qui pourront s'appliquer partiellement. Si l'on définit une fonction "add" pour ajouter 2 nombres x et y, alors on pourra appliquer add à son premier argument, x, en lui donnant par exemple la valeur 12, pour obtenir une fonction à UN SEUL argument qui additionnera son argument à 12.</p>
<p>Les fonctions sont capitales en programmation fonctionnelle. Contrairement à dans un certain nombre de langages (beaucoup), les fonctions peuvent être stockées, passées en argument, construites à la volée, retournées par d'autres fonctions, etc. Elles deviennent des valeurs de première classe. </p>
<p>A propos du passage en argument, une chose très importante en programmation fonctionnelle est la possibilité d'abstraire une partie des algorithmes et d'en confier la responsabilité à une fonction donnée en argument par exemple. Une fonction qui prend une autre fonction en argument est appelée "fonction d'ordre supérieur". Cela permet de factoriser un maximum de code tout en laissant la variabilité possible grâce au passage de fonction en argument. Le compilateur fera les vérifications nécessaires pour voir si les types concordent, ne vous inquiétez pas.</p>
<p>La paresse est également quelque chose qui s'avère bien sympathique parfois. Il s'agit de n'évaluer une expression qu'au moment où l'on en aura besoin (affichage du résultat de l'évaluation de l'expression -- comme une addition -- par exemple). Elle est mise en oeuvre différemment selon les langages (implicitement en Haskell, c'est le compilateur qui gère cela, alors que c'est explicit en OCaml -- module Lazy).</p>
<p>Tout cela, rajouté aux syntaxes assez simples, donne une très grande expressivité aux langages fonctionnels, proche de l'expressivité que l'on a en mathématiques. Qui plus est, rappelons-le, les langages fonctionnels sont des langages dits "déclaratifs". On exprime le problème, on obtient la solution, contrairement à ce que l'on fait dans un langage impératif où l'on doit donner toutes les étapes à la main nous-mêmes.</p>
<p>Bref, beaucoup d'avantages, un tout nouveau style de programmation, cela ne vaut-il pas le détour ? Allez, si vous voulez en savoir plus, voici quelques liens essentiels pour terminer ce billet sur la programmation fonctionnelle.<br />
<a href="http://damien-guichard.developpez.com/tutoriels/ocaml/">Cours d'introduction à OCaml de Damien Guichard</a> -- dont je me suis beaucoup servi et que j'apprécie beaucoup<br />
<a href="http://gorgonite.developpez.com/livres/traductions/haskell/gentle-haskell/">Traduction de "A gentle introduction to Haskell"</a> -- un peu rude pour débuter, mais vous fera comprendre pas mal de choses. </p>
<p>N'hésitez pas à utiliser le forum pour donner vos avis et retours d'expérience ou pour des questions, bien évidemment !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/la-programmation-fonctionnelle-nest-pas-un-jouet-pour-academiciens/feed/</wfw:commentRss>
		<slash:comments>1026</slash:comments>
		</item>
		<item>
		<title>Les sujets en rapport avec OCaml qui vous intéresseraient</title>
		<link>http://www.coder-studio.com/blog/les-sujets-en-rapport-avec-ocaml-qui-vous-interesseraient/</link>
		<comments>http://www.coder-studio.com/blog/les-sujets-en-rapport-avec-ocaml-qui-vous-interesseraient/#comments</comments>
		<pubDate>Sun, 26 Apr 2009 18:18:18 +0000</pubDate>
		<dc:creator>Alp Mestan</dc:creator>
				<category><![CDATA[Langages fonctionnels]]></category>
		<category><![CDATA[Non classé]]></category>
		<category><![CDATA[maths]]></category>
		<category><![CDATA[ocaml]]></category>
		<category><![CDATA[OpenGL]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=262</guid>
		<description><![CDATA[Salut, Étant tombé amoureux du langage OCaml, et comptant propulser cette activité de blog sur Coder-Studio, j'aimerais savoir ce que vous, amateur du langage OCaml, de la programmation fonctionnelle en général ou tout simplement curieux, vous souhaiteriez lire en rapport avec OCaml sur notre site préféré Alors ? Quelques grandes lignes qui pourraient intéresser : [...]]]></description>
			<content:encoded><![CDATA[<p><center>Salut,</center></p>
<p><center><img src="http://lampwww.epfl.ch/%7Emichelou/images/ocaml.gif" alt="" /></center></p>
<p>Étant tombé amoureux du langage OCaml, et comptant propulser cette activité de blog sur Coder-Studio, j'aimerais savoir ce que vous, amateur du langage OCaml, de la programmation fonctionnelle en général ou tout simplement curieux, vous souhaiteriez lire en rapport avec OCaml sur notre site préféré <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Alors ?<br />
Quelques grandes lignes qui pourraient intéresser :<br />
- OCaml et les maths (comme <a href="http://www.coder-studio.com/blog/construction-de-lensemble-de-cantor-en-ocaml/">mon billet précédent</a>)<br />
- OCaml et les GUIs<br />
- OCaml et le multimédia (OCamlSDL, OCaml/OpenGL, ...)<br />
- OCaml et la conception de compilateurs/interpréteurs (lexing, parsing, etc)<br />
- ...</p>
<p>Merci de donner votre avis !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/les-sujets-en-rapport-avec-ocaml-qui-vous-interesseraient/feed/</wfw:commentRss>
		<slash:comments>1759</slash:comments>
		</item>
		<item>
		<title>Simerion – Retour de développement</title>
		<link>http://www.coder-studio.com/blog/simerion-%e2%80%93-retour-de-developpement/</link>
		<comments>http://www.coder-studio.com/blog/simerion-%e2%80%93-retour-de-developpement/#comments</comments>
		<pubDate>Sun, 19 Apr 2009 00:32:04 +0000</pubDate>
		<dc:creator>Aquanum</dc:creator>
				<category><![CDATA[Non classé]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[Jeu en ligne alternatif]]></category>
		<category><![CDATA[Jeu web]]></category>
		<category><![CDATA[Nainwak]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Simerion]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=242</guid>
		<description><![CDATA[Je me suis lancé en 2005 avec Wett dans le développement d’un jeu par navigateur web: Simerion pour les gens qui ne connaissent pas. Il s’agit d’un jeu mélangeant à la fois le genre RPG et gestion. L’idée étant d’endosser le rôle d’un colon fraichement envoyé sur de nouvelles planètes. Chaque joueur choisit un métier, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a title="Simerion" href="http://www.simerion.fr" target="_blank"><img class="size-full wp-image-247 alignleft" title="simerion" src="http://www.coder-studio.com/blog/wp-content/uploads/2009/04/simerion.jpg" alt="simerion" width="200" height="117" /></a>Je me suis lancé en 2005 avec Wett dans le développement d’un jeu par navigateur web: <a title="Simerion" href="http://www.simerion.fr" target="_blank">Simerion</a> pour les gens qui ne connaissent pas. Il s’agit d’un jeu mélangeant à la fois le genre RPG et gestion. L’idée étant d’endosser le rôle d’un colon fraichement envoyé sur de nouvelles planètes. Chaque joueur choisit un métier, et le principe est simple : du RolePlay, tout le monde fait ce qu’il veut, tout est possible. Bref, dans le principe, le jeu idéal, mais hélas pas forcément en pratique.</p>
<p style="text-align: justify;">J’ai quitté l’équipe de Simerion, après 5 ans de conception et développement, il y a un peu plus d’un mois pour différentes raisons que j’aborderai plus loin. Mais je profite de ce billet pour faire une sorte de bilan du projet, de mon point de vue. L’idée étant de faire un retour d’expérience afin de pointer du doigt ce que nous avons pu apprendre mais aussi afin de mettre en évidence les erreurs que nous avons commises. Le tout dans l’espoir de pouvoir aider des personnes s’engageant dans un projet similaire.<br />
Tout d’abord, je précise que le jeu n’est pas arrêté. Il est toujours en développement, je n’ai fait que quitter l’équipe. Donc si mon article vous donne envie d’en savoir plus ou de rejoindre l’équipe de développement, n’hésitez pas à vous rendre sur <a title="Simerion" href="http://www.simerion.fr" target="_blank">www.simerion.fr</a></p>
<p style="text-align: justify;"><a title="Simerion" href="http://www.simerion.fr" target="_blank"><span id="more-242"></span></a></p>
<p style="text-align: justify;">Tout d’abord, un rapide historique :</p>
<p><strong>2005</strong> : Wett et moi-même avons ressorti du fond d’un tiroir les bases d’un projet que j’avais esquissé 2 ans plus tôt. Durant 5 mois nous mettons ainsi à plat toutes nos idées sur un forum et wiki. Mais très rapidement nos études respectives (classes prépa) nous ont poussées à mettre en pause le projet.<br />
<strong>Juillet 2006</strong> : Un an plus tard nous reprenons notre projet en main et continuons à travailler sur la conception durant un mois de manière soutenue.<br />
<strong>Août 2006</strong> : Nous commençons enfin le développement et devenons membre de l’association <a title="Nainwak" href="http://www.nainwak.org" target="_blank">Nainwak </a>qui nous hébergera par la suite.<br />
<strong>Août 2007</strong> : Un an plus tard, avec l’aide d’Altheran qui nous a rejoint en mars, nous sortons notre première version alpha avec une cinquantaine de joueurs.<br />
<strong>Mars 2009</strong> : Plus d’un an et demi plus tard, la beta alors que je quitte l’équipe.</p>
<p>Voici donc une suite de points, qui maintenant avec le recul me semblent importants à souligner.</p>
<h3>Travailler en équipe</h3>
<p>A travers ce projet j’ai pu découvrir la nécessité de travailler à plusieurs. Et cela pour plusieurs raisons. Tout d’abord afin de s’entre-motiver lorsque certains d’entre nous sont démotivés. Voir d’autres personnes travailler sur le projet peut très facilement nous remonter à bloc. Le développement d’un jeu web comme Simerion ne doit pas se faire en comité réduit. Attention l’effet inverse n’est pas pour autant une bonne idée. S’entourer de trop de monde peut être néfaste pour le projet. Il faut prendre le juste nombre de programmeurs, en prenant en compte leurs disponibilités et leurs compétences.</p>
<h3>Bien choisir son langage</h3>
<p>Notre choix s’est porté initialement sur le PHP couplé à de l’Ajax afin de bénéficier d’un jeu accessible partout depuis Internet avec une grande interaction avec les joueurs. Pourquoi le PHP ? Parce que ce langage m’était déjà familier et était simple à prendre  en main. Cependant avec le recul, nous n’aurions sans doute pas dû employer celui-ci préférant sans doute le JAVA ou le C++ afin de réaliser un véritable MMORPG. A maintes reprises nous nous sommes mordus les doigts quant à notre choix de technologie. Nous avons très rapidement atteint les limites du PHP et de l’Ajax. Nous avons été bridés par nos choix initiaux qui nous ne ont pas permis pleinement de faire ce que nous souhaitions réaliser. Mais il était trop tard pour changer.<br />
Je conseille vraiment au départ de faire le tour de toutes les technologies lorsque l’on s’aventure dans un projet web d’ampleur. Chaque langage possède ses avantages et inconvénients qu’il faut comparer. Nous ne l’avons pas fait, et cela nous a desservis.</p>
<h3>Ne pas réinventer la roue</h3>
<p style="text-align: justify;">Une autre erreur que nous avons commise a été de ne pas faire le tour des Frameworks PHP et Ajax existants. En jeunes fous que nous étions, nous avons créé notre propre moteur de jeu de A à Z et notre propre Framework Ajax. Nous avons réinventé la roue et avons perdu un temps fou. D’un autre côté, nous ne savions pas forcément que des outils tout fait existaient, cela nous a toutefois permis de comprendre le fonctionnement d’un certain nombre de techniques et technologies. Mais si c’était à refaire j’utiliserais au maximum des outils déjà disponibles.<br />
Avant de commencer un projet conséquent. Je pense qu’il faut vraiment regarder, comparer les outils à sa disposition et ne pas fonce dans le tas tête baissée. Utiliser des outils déjà faits peut faire réellement gagner un temps précieux.</p>
<h3>Utiliser des schémas et diagrammes UML</h3>
<p style="text-align: justify;">L’utilisation de diagrammes UML est assez primordiale. Il est difficile d’être rigoureux sur la durée  afin de mettre sur papier les idées avant de coder. Mais c’est un mal pour un bien au final, car c’est un gain de temps non négligeable. Toutefois les diagrammes UML ne sont utiles que si l’on ne change pas d’idée en permanence. Auquel cas, les diagrammes sont en permanence remis en cause, ce qui est pour ce coup-ci une grosse perte de temps.</p>
<h3>Eviter l’approche du « tout objet »</h3>
<p style="text-align: justify;">L’approche objet d’un jeu web est assez complexe. A première vue, le « tout objets » peut sembler être une bonne chose, mais les objets ne sont pas les amis des bases de données. Qui dit objets, dit attributs, et qui dit attributs dit base de données derrière chargée et mise à jour en permanence. Travailler avec les objets et leurs instances implique d’optimiser en permanence le code afin que  le serveur ne s’écroule pas sous les requêtes SQL. Par exemple, si je veux charger une instance d’appartement d’un joueur dans Simerion, nous devons charger un objet qui va définir son type (classe), puis un objet qui va définir son instance de conteneur (bâtiment) ainsi que la classe de celui-ci. Vu que nous avons besoin parfois de localiser cet appartement, nous avons besoin de charger la région dans laquelle se trouve notre bâtiment (une table supplémentaire). Comme il y a plusieurs planètes il faut également charger sur quelle planète se trouve cette région (une table de plus). Au final la création d’un objet devient pharamineuse en terme de ressources, nécessitant une flopée de requêtes SQL. Imaginez comment charger des collections entières d’appartements... De quoi mettre à terre le serveur. Nous sommes alors obligés d’optimiser en nous éloignant peu à peu du système classique d’objets. Travailler en objet est intéressant, mais dès que l’on se met à travailler sur des pages qui vont recevoir énormément de visites, l’intérêt en prend un sérieux coup.<br />
Je pense qu’il n’y a pas de solution absolue et  qu’il faut privilégier les objets pour la maintenabilité du code. Par contre, en ce qui concerne le lien avec les BDD, il faut trouver un compromis et essayer de s’éloigner  du schéma classique qui consiste à tout charger lors de la création de l’objet. Je pense qu’il suffirait de regarder du côté des gros Frameworks ce qu’il se fait en la matière. La liaison avec la BDD est une chose assez pointilleuse et complexe, je pense que même au bout de 5 ans, le code n’est pas optimisé au maximum de ce côté-là. Par conséquent, aller voir les outils qui existent déjà peut être d’une très grande aide.</p>
<h3>Ne pas remettre en question son code en permanence</h3>
<p style="text-align: justify;">Une des choses qui nous a fait le plus perdre de temps a été la permanente remise en question de notre code. C’est bien plus facile à dire qu’à faire, mais il faut à tout pris se contenter au plus tôt de son travail pour avancer de l’avant. De la même façon, il faut éviter d’optimiser à mort tout et tout de suite, il faut le faire au fur et à mesure en trouvant un juste milieu. J’aborderai plus loin la question du travail étape par étape, mais il est très très important, d’après l’expérience que j’ai tirée de Simerion, de se contenter de ce qui fonctionne et aller de l’avant pour avoir du concret et non pas du code en permanence remanié. Une fois que le code fonctionne il est alors possible de l’optimiser, mais il faut viser à mon sens le fonctionnel avant de foncer tête baissée sur la sécurité et l’optimisation du jeu.</p>
<h3>Bien choisir son cycle de développement</h3>
<p style="text-align: justify;">Le choix de notre cycle de développement n’a définitivement pas été le bon. Et ce dernier est à mon sens la raison de notre (mon) échec. 5 ans ! Nous avons passé 5 ans sur ce projet et toujours pas de jeu jouable en version publique à mon départ … C’est entre autres une des raisons de mon arrêt. C’est même un exploit d’avoir tenu aussi longtemps. Nous avons choisi en effet de n’ouvrir le jeu que lorsqu’une version du jeu serait suffisamment jouable pour retenir le joueur. Or, le principe de Simerion est de pouvoir tout faire. Tout est interdépendant, et tout s’équilibre. Il est alors impossible de sortir une version jouable tant que TOUT le jeu n’a pas été programmé. Quelle erreur nous avons faite ici !<br />
Dès que le concept est posé sur papier un jeu amateur doit, selon moi, sortir au plus vite en production. A la fois pour avoir des retours des joueurs, mais aussi afin de se motiver dans son travail de développement. C’est extrêmement déprimant de ne pas avoir de retour de joueurs avant des mois, voir des années dans notre cas. La motivation est naturellement en constante baisse, et pas un joueur pour vous rebooster. Il ne faut compter que sur les membres de l’équipe qui eux aussi sont en manque de motivation.<br />
Donc vraiment je conseille vivement de développer les jeux web sur des versions fréquentés par les joueurs (tout du moins pour les jeux amateurs). Il faut sortir régulièrement les versions de développement et surtout ne pas attendre aussi longtemps que nous entre chaque version. En faisant cela on entretient la communauté de joueurs qui nous supporte et nous est très utile, et on entretient notre motivation dans le projet. Sans cela, tout s’effondre au bout de X mois ou années. Et tout l’investissement aura été vain.</p>
<h3>Créer une communauté autour de son jeu</h3>
<p style="text-align: justify;">Comme je le disais précédemment, il est nécessaire de s’entourer dès le début d’une communauté de joueurs. Ces derniers pourront tester votre jeu, donner leur avis, proposer leurs idées d’améliorations etc. N’ayant pas lancé de version jouable durable de Simerion, nous n’avons pas eu de communauté derrière nous pour nous soutenir dans notre développement. Et c’est une conséquence très négative, qui va avec notre mauvais choix de cycle de développement.<br />
Je conseille donc vraiment de travailler dès le début à la création d’une communauté entourant le projet à la fois pour y puiser de la motivation, mais aussi afin de se faire aider. Car bien souvent, la communauté gravitant autour de votre jeu est source de nouveaux membres pour votre équipe de développement.</p>
<h3>Les amateurs ne peuvent pas rivaliser avec les pros</h3>
<p style="text-align: justify;">Cela fait mal à dire, mais la création d’un jeu RPG complexe n’est pas à la portée d’une équipe d’amateurs. Qu’on me montre le contraire et j’en serais ravis ! Mais le fait est que la création d’images, de décors, d’histoires, de scénarios, de quêtes et de missions nécessite un travail pharaonique. J’ai les 95% du temps endossé le rôle du développeur, du scénariste et de l’illustrateur à la fois. Ceci est quasiment impossible à gérer dans un tel projet. Idéalement il faudrait avoir dans son équipe au moins un graphiste / illustrateur et plusieurs scénaristes pour remplir le jeu. Mais il s’agit d’atouts rares, et il faut bien souvent ne compter que sur soi même. Sur cet aspect je suis assez pessimiste hélas, je pense qu’un jeu de l’envergure de type Fallout, Baldur’s gate, Final Fantasy, ou même Zelda n’auraient pas pu être réalisés par des amateurs. Cela demande trop de travail en dehors de la partie programmation. Le jeu ultime est à mon sens impossible à développer par des amateurs, hélas… A mon sens, un jeu amateur ne doit pas voir trop gros dès le départ. Il faut y aller au fur et à mesure, en se faisant plaisir et tout en gardant à l’esprit que nous ne pouvons pas rivaliser avec les grands. Le jeu ultime amateur n’est pas réalisable, cela demande beaucoup trop de travail. Avec Simerion nous sommes partis sur un concept trop complexe, trop utopique … La clé de la réussite est un cadrage dès le départ qui trouve un compromis entre un concept novateur et le minium de code possible.</p>
<h3>Tenir un cahier des charges et une documentation à jour</h3>
<p style="text-align: justify;">Un point important dans le cycle de développement réside dans la tenue d’un cahier des charges et d’une documentation à jour. En effet, il n’est pas rare de mettre en pause le projet pendant X mois. Et reprendre le code après une période d’inactivité est vraiment très difficile (même pour du code tapé soi même).  Le cahier des charges permet de garder une vue globale sur le projet avec un certain recul, il vous permet de poser au clair toutes les idées et mieux structurer ses  idées. La documentation permet, elle de son côté d’expliquer le fonctionnement du jeu (aspect technique) mais aussi d’expliquer pourquoi tel ou tel choix d’algorithme. La documentation peut vous faire gagner un temps fou pour vous remettre dans votre code, ou pour comprendre le code d’un autre programmeur. Ces deux outils permettent également l’intégration de nouveaux membres à l’équipe de développement (chose à laquelle on ne pense pas forcément). Le fait est que Simerion est devenu une véritable usine à gaz et que plusieurs personnes se sont cassées les dents à essayer de comprendre notre code pas toujours commenté ni expliqué. Le manque d’explication peut alors être un frein au recrutement de nouveaux développeurs.</p>
<h3>Se faire soutenir</h3>
<p style="text-align: justify;">Nous avons rejoint dès le départ l’association <a title="Nainwak" href="http://www.nainwak.org" target="_blank">Nainwak</a>, qui nous a hébergés, soutenus et conseillés. Nous n’aurions sans doute pas tenu autant de temps sans elle. Nous avons même eu la chance grâce à elle d’être exposant à 2 reprises au festival du jeu vidéo. Nous avons pu rencontrer des professionnels qui ont été intéressés par notre jeu. Cela fut une expérience très enrichissante.<br />
Je conseille vivement à toute personne se lançant dans un jeu web sérieux de contacter Nainwak. La mission de cette association est d’aider les amateurs, et elle y travaille à merveille.</p>
<h3>Bilan</h3>
<p style="text-align: justify;">J’ai complètement arrêté Simerion tout d’abord parce que je ne prenais plus aucun plaisir à travailler dessus. Le développement était devenu interminable et j’avais besoin de passer à autre chose. A cela se sont ajoutés des problèmes de santés plus une saturation du web en général. Abandonner Simerion alors que ce projet me tenait tellement à cœur a été une chose très difficile, mais je pense qu’au bout de 5 ans, il fallait simplement passer à autre chose.<br />
Simerion a été une expérience vraiment très enrichissante. J’ai pu apprendre énormément et rencontrer beaucoup de monde. Mais je pense que si nous nous étions pris autrement dès le départ nous aurions sans doute bien mieux réussi, et je serais encore sur le projet. Mais tout cela fait partie de l’apprentissage. C’est chuter pour mieux se relever et mieux démarrer mes prochains projets.<br />
Toutefois, nous nous sommes lancés dans un concept dément, où tout devait être possible. Le jeu ultime en quelques sortes. Un tel jeu n’est tout bonnement pas réalisable et complètement utopique (A moins d’être un studio de jeu vidéo avec de la monnaie sonnante et trébuchante pour assurer le coup). Mauvais choix de départ, concept trop ambitieux, mauvaise démarche de développement, réinvention de la roue ont été autant d’erreurs qui ont amenés Simerion à ne pas arriver au point escompté. On apprend de ses erreurs et j’espère que les nôtres pourront vous êtes bénéfiques également.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/simerion-%e2%80%93-retour-de-developpement/feed/</wfw:commentRss>
		<slash:comments>1729</slash:comments>
		</item>
		<item>
		<title>Construction de l&#039;Ensemble de Cantor en OCaml</title>
		<link>http://www.coder-studio.com/blog/construction-de-lensemble-de-cantor-en-ocaml/</link>
		<comments>http://www.coder-studio.com/blog/construction-de-lensemble-de-cantor-en-ocaml/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 23:12:36 +0000</pubDate>
		<dc:creator>Alp Mestan</dc:creator>
				<category><![CDATA[Langages fonctionnels]]></category>
		<category><![CDATA[Non classé]]></category>
		<category><![CDATA[batteries]]></category>
		<category><![CDATA[cantor]]></category>
		<category><![CDATA[included]]></category>
		<category><![CDATA[maths]]></category>
		<category><![CDATA[ocaml]]></category>

		<guid isPermaLink="false">http://www.coder-studio.com/blog/?p=235</guid>
		<description><![CDATA[Bonsoir, Un billet à propos d'OCaml, encore. Je me suis amusé à implémenter la construction de l'Ensemble de Cantor (version anglaise un peu plus complète). Vous voulez en savoir plus ? Première étape, il me fallait une fonction qui à partir d'une liste et d'un couple (a,b) de nombre réels, représentant l'intervalle [a,b], rajoute les [...]]]></description>
			<content:encoded><![CDATA[<p>Bonsoir,</p>
<p>Un billet à propos d'OCaml, encore. Je me suis amusé à implémenter la construction de <a href="http://fr.wikipedia.org/wiki/Ensemble_de_Cantor">l'Ensemble de Cantor</a> (<a href="http://en.wikipedia.org/wiki/Cantor_set">version anglaise un peu plus complète</a>). Vous voulez en savoir plus ?</p>
<p><center><a href="http://www.coder-studio.com/blog/construction-de-lensemble-de-cantor-en-ocaml/#more-235"><img src="http://www.developpez.net/forums/u67052-a100-i323.png" alt="Construction de l'Ensemble de Cantor" /></a><br />
<span id="more-235"></span></center></p>
<p>Première étape, il me fallait une fonction qui à partir d'une liste et d'un couple (a,b) de nombre réels, représentant l'intervalle [a,b], rajoute les deux intervalles qui en sont générés par une itéraction de la construction de l'ensemble de Cantor, c'est à dire les intervalles [a, (2a+b)/3] et [(a+2b)/3, b], à la liste. Voici la fonction en question, appelée cantor_step ici :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code7'); return false;">View Code</a> OCAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2357"><td class="code" id="p235code7"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">let</span> cantor_step l <span style="color: #6c6;">&#40;</span>a,b<span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">=</span>
 <span style="color: #6c6;">&#40;</span>a, <span style="color: #6c6;">&#40;</span>a <span style="color: #a52a2a;">+.</span> <span style="color: #060;">a</span> <span style="color: #a52a2a;">+.</span> <span style="color: #060;">b</span><span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">/.</span> <span style="color: #c6c;">3</span><span style="color: #a52a2a;">.</span><span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">::</span> <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#40;</span>a <span style="color: #a52a2a;">+.</span> <span style="color: #060;">b</span> <span style="color: #a52a2a;">+.</span> <span style="color: #060;">b</span><span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">/.</span> <span style="color: #c6c;">3</span><span style="color: #a52a2a;">.</span>, b<span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">::</span> l</pre></td></tr></table></div>

<p>Ensuite, il fallait une fonction qui permettre d'appliquer cette fonction sur une liste de couples (a,b) pour passer d'une liste d'intervalles à une autre, c'est à dire passer à l'étape suivante de la génération de l'Ensemble de Cantor. J'ai par la même occasion profité pour rajouté un paramètre n permettant de réaliser cela n fois. J'ai appelé cette fonction map_n.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code8'); return false;">View Code</a> OCAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2358"><td class="code" id="p235code8"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">let</span> map_n f l n <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">match</span> l <span style="color: #06c; font-weight: bold;">with</span>
  <span style="color: #a52a2a;">|</span> <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#93;</span> <span style="color: #a52a2a;">-&gt;</span> <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#93;</span>
  <span style="color: #a52a2a;">|</span> l <span style="color: #a52a2a;">-&gt;</span> aux l n 
      where
	<span style="color: #06c; font-weight: bold;">rec</span> aux l <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">function</span> 
	  <span style="color: #a52a2a;">|</span> <span style="color: #c6c;">0</span> <span style="color: #a52a2a;">-&gt;</span> l
	  <span style="color: #a52a2a;">|</span> k <span style="color: #a52a2a;">-&gt;</span> aux <span style="color: #6c6;">&#40;</span><a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html"><span style="color: #06c; font-weight: bold;">List</span></a><span style="color: #a52a2a;">.</span><span style="color: #060;">fold_left</span> f <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#93;</span> l<span style="color: #6c6;">&#41;</span> <span style="color: #6c6;">&#40;</span>k<span style="color: #a52a2a;">-</span><span style="color: #c6c;">1</span><span style="color: #6c6;">&#41;</span></pre></td></tr></table></div>

<p>List.fold_left est ce que l'on appelle un "pliage" (<em>fold</em> en Anglais). Pour vous familiariser avec ces derniers, une recherche sur "functional programming fold" devrait vous apporter le nécessaire <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ). Il permet de parcourir la liste d'une certaine façon en appliquant une certaine fonction sur l'élément courant et le résultat de ce qui a été fait jusque là de la même façon, et ainsi de suite. </p>
<p>Enfin, définissons une fonction nth_cantor qui permet d'obtenir la liste des intervalles qui constituent la n-ème itéraction de la construction de l'Ensemble de Cantor.</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code9'); return false;">View Code</a> OCAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2359"><td class="code" id="p235code9"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">let</span> nth_cantor <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">function</span>
  <span style="color: #a52a2a;">|</span> <span style="color: #c6c;">0</span> <span style="color: #a52a2a;">-&gt;</span> <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#40;</span><span style="color: #c6c;">0</span><span style="color: #a52a2a;">.</span>,<span style="color: #c6c;">1</span><span style="color: #a52a2a;">.</span><span style="color: #6c6;">&#41;</span><span style="color: #6c6;">&#93;</span>
  <span style="color: #a52a2a;">|</span> k <span style="color: #a52a2a;">-&gt;</span> map_n cantor_step <span style="color: #6c6;">&#91;</span><span style="color: #6c6;">&#40;</span><span style="color: #c6c;">0</span><span style="color: #a52a2a;">.</span>,<span style="color: #c6c;">1</span><span style="color: #a52a2a;">.</span><span style="color: #6c6;">&#41;</span><span style="color: #6c6;">&#93;</span> k</pre></td></tr></table></div>

<p>On voit donc que l'on part de l'intervalle [0,1], et que l'on va répéter k fois l'itéraction. </p>
<p>Deux fonctions utilitaires, dont une qui utilise non pas le module List standard mais le module List de OCaml Batteries Included, pour la fonction print. (en fait, List.fold_left ci-dessus est également celui de OCaml Batteries Included, étant donné que le programme sera compilé avec OCaml Batteries Included).</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code10'); return false;">View Code</a> OCAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p23510"><td class="code" id="p235code10"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">let</span> couple_printer <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#VALoutput"><span style="color: #06c; font-weight: bold;">output</span></a> <span style="color: #6c6;">&#40;</span>a,b<span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">=</span> <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.html"><span style="color: #06c; font-weight: bold;">Printf</span></a><span style="color: #a52a2a;">.</span><span style="color: #060;">printf</span> <span style="color: #3cb371;">&quot;(%f,%f)\n&quot;</span> a b
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> list_printer l <span style="color: #a52a2a;">=</span>  <span style="color: #5d478b; font-style: italic;">(* List.print couple_printer stdout l ;*)</span>  <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Printf.html"><span style="color: #06c; font-weight: bold;">Printf</span></a><span style="color: #a52a2a;">.</span><span style="color: #060;">printf</span> <span style="color: #3cb371;">&quot;\n%d intervals in list\n&quot;</span> <span style="color: #6c6;">&#40;</span><a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html"><span style="color: #06c; font-weight: bold;">List</span></a><span style="color: #a52a2a;">.</span><span style="color: #060;">length</span> l<span style="color: #6c6;">&#41;</span></pre></td></tr></table></div>

<p>La première permet d'afficher un couple de réels depuis ... un couple de réels.<br />
La seconde permet d'afficher une liste en précisant quelle fonction utiliser pour afficher chaque élément. Elle affiche ensuite la taille. Ici, le passage d'affichage des éléments est commenté (entre (* ... *)) car ayant testé mon code avec notamment 25 itérations, on se retrouve avec beaucoup trop de choses à afficher pour que ça soit supportable pour un être humain normal.</p>
<p>Enfin, le code qui est exécuté :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code11'); return false;">View Code</a> OCAML</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p23511"><td class="code" id="p235code11"><pre class="ocaml" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">let</span> main <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#41;</span> <span style="color: #a52a2a;">=</span> 
  <span style="color: #06c; font-weight: bold;">try</span> 
    <span style="color: #06c; font-weight: bold;">let</span> n <span style="color: #a52a2a;">=</span> <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#VALint_of_string"><span style="color: #06c; font-weight: bold;">int_of_string</span></a> <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Sys.html"><span style="color: #06c; font-weight: bold;">Sys</span></a><span style="color: #a52a2a;">.</span><span style="color: #060;">argv</span><span style="color: #a52a2a;">.</span><span style="color: #6c6;">&#40;</span><span style="color: #c6c;">1</span><span style="color: #6c6;">&#41;</span> <span style="color: #06c; font-weight: bold;">in</span>
    <span style="color: #06c; font-weight: bold;">let</span> cn <span style="color: #a52a2a;">=</span> nth_cantor n <span style="color: #06c; font-weight: bold;">in</span>
      list_printer cn
  <span style="color: #06c; font-weight: bold;">with</span> _ <span style="color: #a52a2a;">-&gt;</span> <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#VALprint_endline"><span style="color: #06c; font-weight: bold;">print_endline</span></a> <span style="color: #3cb371;">&quot;Use : ./cantor n, where n is an integer&quot;</span> <span style="color: #a52a2a;">;</span> <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html#VALexit"><span style="color: #06c; font-weight: bold;">exit</span></a> <span style="color: #c6c;">0</span>
&nbsp;
<span style="color: #06c; font-weight: bold;">let</span> _ <span style="color: #a52a2a;">=</span> main <span style="color: #6c6;">&#40;</span><span style="color: #6c6;">&#41;</span></pre></td></tr></table></div>

<p>Pour  terminer, la compilation :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p235code12'); return false;">View Code</a> SHELL</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p23512"><td class="code" id="p235code12"><pre class="shell" style="font-family:monospace;">$ ocamlfind batteries/ocamlopt -o cantor cantor.ml</pre></td></tr></table></div>

<p>(pas d'optimisation ici, si vous les voulez, rajouter -cc -O<em>n</em> après ocamlopt)</p>
<p>Et on exécute :</p>
<blockquote><p>$ time ./cantor 25<br />
33554432 intervals in list</p>
<p>real    0m25.553s<br />
user    0m23.481s<br />
sys     0m2.060s
</p></blockquote>
<p>En activant l'affichage des éléments, sur un petit nombre d'itérations :</p>
<blockquote><p>$ time ./cantor 4<br />
[(0.740741,0.753086)<br />
; (0.765432,0.777778)<br />
; (0.666667,0.679012)<br />
; (0.691358,0.703704)<br />
; (0.962963,0.975309)<br />
; (0.987654,1.000000)<br />
; (0.888889,0.901235)<br />
; (0.913580,0.925926)<br />
; (0.074074,0.086420)<br />
; (0.098765,0.111111)<br />
; (0.000000,0.012346)<br />
; (0.024691,0.037037)<br />
; (0.296296,0.308642)<br />
; (0.320988,0.333333)<br />
; (0.222222,0.234568)<br />
; (0.246914,0.259259)<br />
]<br />
16 intervals in list</p>
<p>real    0m0.013s<br />
user    0m0.000s<br />
sys     0m0.016s
</p></blockquote>
<p>Vous avez surement remarqué que cette méthode ne préserve pas l'ordre des intervalles... Ce n'a pas vraiment été mon soucis premier, et ce serait arrangé avec la méthode décrite ci-dessous.</p>
<p>Au passage, si j'utilisais des arbres binaires pour toutes les étapes intermédiaires et que je produisais une liste depuis cet arbre, je gagnerais pas mal en efficacité, disons que je vous le laisse à titre d'exercice <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Enjoy !</p>
<p>PS : la capture d'écran ci-dessus provient d'un programme que j'avais réalisé il y a quelques mois et qui faisait une construction itérative représentée graphiquement, mais la méthode de génération était moins efficace, et j'ai la flemme de refaire la même chose maintenant...</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/construction-de-lensemble-de-cantor-en-ocaml/feed/</wfw:commentRss>
		<slash:comments>1382</slash:comments>
		</item>
		<item>
		<title>Coder-Studio V3 est né !</title>
		<link>http://www.coder-studio.com/blog/coder-studio-v3-est-ne/</link>
		<comments>http://www.coder-studio.com/blog/coder-studio-v3-est-ne/#comments</comments>
		<pubDate>Mon, 23 Feb 2009 21:31:58 +0000</pubDate>
		<dc:creator>Aquanum</dc:creator>
				<category><![CDATA[Non classé]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=3</guid>
		<description><![CDATA[Après des années d'attente, voici enfin la sortie de la nouvelle version de Coder-Studio. Plus conforme à nos utilisations, le format blog a été choisi à l'unanimité par les membres. L'idée est de se regrouper autour de ce blog afin de proposer articles, notes et tutoriaux. Et cela pour discuter, comme à notre habitude, de [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Après des années d'attente, voici enfin la sortie de la nouvelle version de Coder-Studio. Plus conforme à nos utilisations, le format blog a été choisi à l'unanimité par les membres. L'idée est de se regrouper autour de ce blog afin de proposer articles, notes et tutoriaux. Et cela pour discuter, comme à notre habitude, de tout ce qui touche à l'informatique de près ou de loin. Chacun, de part son cheminement personnel et professionnel, bénéficie d'une expérience qui lui est propre ainsi que de connaissances qui peuvent être profitables à tous. Cette V3 de Coder-Studio s'inscrit donc toujours dans cette volonté de partage qui nous est chère. J'espère que cette nouvelle version sera un succès et que nous prendrons du plaisir à écrire ensemble sur ce blog.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/coder-studio-v3-est-ne/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Complément du tuto sur la classe Factory</title>
		<link>http://www.coder-studio.com/blog/complement-du-tuto-sur-la-classe-factory/</link>
		<comments>http://www.coder-studio.com/blog/complement-du-tuto-sur-la-classe-factory/#comments</comments>
		<pubDate>Tue, 08 Feb 2005 17:58:05 +0000</pubDate>
		<dc:creator>twxs</dc:creator>
				<category><![CDATA[Non classé]]></category>
		<category><![CDATA[design pattern]]></category>
		<category><![CDATA[factory]]></category>

		<guid isPermaLink="false">http://r19649.ovh.net/cs/blog/?p=181</guid>
		<description><![CDATA[J'avais laissé en exercice à la fin du dernier tutorial sur les factories un petit exercice... face au nombreux mail de votre par je publie la réponse. Donc pour rappel, nous avons a notre disposition une classe Factory qui nous permet de créer des instances d'objets héritant tous d'une interface de base. i.e. Shape était [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">J'avais laissé en exercice à la fin du dernier tutorial sur les factories un petit exercice... face au nombreux mail de votre par je publie la réponse.</p>
<p><span id="more-181"></span></p>
<p>Donc pour rappel, nous avons a notre disposition une classe Factory qui nous permet de créer des instances d'objets héritant tous d'une interface de base.<br />
i.e. Shape était notre interface Cylinder, Sphere nos instance a créer.</p>
<p>Le désavantage principal de l'implémentation était l'obligation d'écrire dans chaque classe une méthode statique créant l'instance :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p181code19'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18119"><td class="code" id="p181code19"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">static</span> Shape <span style="color: #000040;">*</span>Sphere<span style="color: #008080;">::</span><span style="color: #007788;">create</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>Heureusement, les template vont encore une fois nous aider a nous abstraire de cette contrainte.</p>
<p style="text-align: justify;">La factory retourne des objets de type Object (paramètre de la classe templatée) elle stocke pour chaque clef une fonction dont le prototype est :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p181code20'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18120"><td class="code" id="p181code20"><pre class="cpp" style="font-family:monospace;">Object <span style="color: #000040;">*</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">L'idée va être de ne plus stocker une fonction mais un objet au sens C++ jouant le rôle de cette fonction.</p>
<p style="text-align: justify;">Dans notre cas, le foncteur a donc une méthode CreateInstance(void) retournant un Object</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p181code21'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18121"><td class="code" id="p181code21"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span>  <span style="color: #0000ff;">struct</span> InterfaceCreator<span style="color: #008000;">&#123;</span>
   <span style="color: #0000ff;">virtual</span> Object <span style="color: #000040;">*</span>CreateInstance<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span> <span style="color: #000080;">=</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>on modifie en conséquence la classe Factory :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p181code22'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18122"><td class="code" id="p181code22"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span>  <span style="color: #0000ff;">class</span> Factory<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
&nbsp;
<span style="color: #666666;">// on redéfinit notre nouveau type comme</span>
<span style="color: #666666;">// etant un InterfaceCreator&lt;object width=&quot;100&quot; height=&quot;100&quot; type=&quot;application/x-shockwave-flash&quot;&gt;&lt;/object&gt;</span></pre></td></tr></table></div>

<p>Maintenant, il nous faut specialiser des Creator pour notre Sphere, Shape, etc...</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p181code23'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18123"><td class="code" id="p181code23"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span>
<span style="color: #0000ff;">class</span> Creator <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> InterfaceCreator
<span style="color: #008000;">&#123;</span>
<span style="color: #0000ff;">public</span><span style="color: #008080;">:</span>
  BaseClass <span style="color: #000040;">*</span>CreateInstance<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">void</span><span style="color: #008000;">&#41;</span><span style="color: #008000;">&#123;</span>
     RealClass instance <span style="color: #000080;">=</span> <span style="color: #0000dd;">new</span> RealClass<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
     <span style="color: #0000ff;">return</span> <span style="color: #0000ff;">static_cast</span><span style="color: #008000;">&#40;</span>instance<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
  <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Petite explication de cette double paramétrisation. Nous avons besoin du type réel de l'objet (Sphere) pour le créer et le type abstrait(Shape) pour pouvoir heriter de InterfaceCreator</p>
<p>Passons a l'utilisation :</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p181code24'); return false;">View Code</a> CPP</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p18124"><td class="code" id="p181code24"><pre class="cpp" style="font-family:monospace;">Factory shapeFactory<span style="color: #008080;">;</span>
...
&nbsp;
<span style="color: #0000ff;">class</span> Sphere <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> Shape<span style="color: #008000;">&#123;</span>
  ....
  <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">bool</span> registered<span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">bool</span> Sphere<span style="color: #008080;">::</span><span style="color: #007788;">registered</span> <span style="color: #000080;">=</span> shapeFactory.<span style="color: #0000ff;">register</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Sphere&quot;</span>, <span style="color: #0000dd;">new</span> Creator <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
<span style="color: #0000ff;">bool</span> Cylinder<span style="color: #008080;">::</span><span style="color: #007788;">registered</span> <span style="color: #000080;">=</span> shapeFactory.<span style="color: #0000ff;">register</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;Cylinder&quot;</span>, <span style="color: #0000dd;">new</span> Creator <span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span></pre></td></tr></table></div>

<p>j'espère que ca vous aura plu un minimum <img src='http://www.coder-studio.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
a+<br />
Twxs</p>
]]></content:encoded>
			<wfw:commentRss>http://www.coder-studio.com/blog/complement-du-tuto-sur-la-classe-factory/feed/</wfw:commentRss>
		<slash:comments>1486</slash:comments>
		</item>
	</channel>
</rss>

