Feeds:
Articles
Commentaires

Je viens de lire la série de twitts de morgan_it, qui commence ici sur le repli communautaire de la génération Y (soit les gens qui sont nés entre 1977 et 1995). Et j’y ai un peu réfléchi.

Chaque génération crée ses communautés

Premièrement, pour qu’il y ai un repli communautaire, il faut déjà qu’il y ait eu une phase d’ouverture vers l’extérieur. Cette phase, si elle existe, aurait eu lieu durant les deux générations précédentes (génération X, 1959-1977, et génération baby-boom, 1943-1959). Or pour moi, cette phase, plus qu’une phase d’ouverture, est plutôt une phase de destruction des anciennes communautés. Durant cette période, le village est détruit pour laisser place à la ville : par l’exode rural, des gens qui ont vécu dans de petits villages se retrouvent dans des grandes villes. Cela entraîne la disparition de certains rituels communautaires, par exemple la messe le dimanche (ce qui provoque le recul de l’église, qui perds l’une de ses raisons premières : rassembler une communauté).

Mais l’homme est un animal de meute (oui, je pousse un peu plus loin l’expression d’Aristote « l’homme est un animal social »). La perte de la communauté villageoise détruit la meute. La génération du baby-boom se doit de retrouver, sinon une meute, au moins un groupe. Et c’est dans l’engagement politique que cette génération va reconstruire des communautés. On aura les libertaires, les féministes, les gauchistes (de toutes les mouvances possibles et inimaginables…), les hippies… Néanmoins, ces engagements politiques vont se heurter à la réalité (et oui, tout n’est ni tout blanc, ni tout noir) : mouvements violents d’extrême gauche, crimes des régimes soi-disant communistes, SIDA, plafond de verre…

La génération suivante (la génération X) rejette alors l’action politique strictement politique, et va tenter de se fédérer par des grandes actions associatives : marche des beurs, concert Band Aid, resto du coeur… Là encore, de nouvelles communautés se forment. On peut noter que cette génération est également la génération de la « crise », ce qui peut également la pousser non pas à réclamer (ce que faisait la génération précédente) mais à sauvegarder (d’où un élan vers des actions solidaires). Mais au final, l’effet est le même, des communautés se forment.

Enfin on arrive à la génération Y (la mienne ^_^). Là encore, cette génération va voir l’échec (relatif) de la génération précédente : émeutes en banlieue (1991), associations débordées par la demande (les restos du coeur), dirigeants de ces mêmes associations qui ne sont pas des saints (Bernard Kouchner, Julien Dray…). Et cette génération forme alors de nouvelles communautés.

Ce qui est intéressant avec ces nouvelles communautés, c’est que d’une part, et contrairement aux communautés des deux générations précédentes, ces communautés ne se fondent plus sur une vision de la société ou sur un rêve commun mais sur des passions communes. Et que d’autre part, et en continuité avec les grands mouvements des année 1970 et 1980, ces communautés sont mondiales.

En fait ces nouvelles communautés sont très étranges à décrire car elles sont à la fois locales (le groupe d’amis/de passionnés proche) et mondiales (grâce à internet). Par exemple je suis un passionné de skateboard. D’une part j’ai mon petit groupe d’amis avec qui je fais du skate. Et d’autre part je regarde des vidéos de skate tournées aux États-Unis, je discute sur des réseaux sociaux avec des gens qui aiment le skate…

Au final, en trois générations, on est passé de communautés qui se définissaient par le territoire (le village, et on n’aime pas le village d’à coté) à des communautés qui se définissent par leur passion (par exemple les skateurs, et on n’aime pas les rappeurs –> oui, c’est un peu caricatural).

Les conséquence des communautés de la génération Y

D’une part, mais c’est dans la nature des relations entre générations, ces communautés sont méprisés par la génération précédentes « ces jeunes sont renfermés sur eux même et ne s’intéressent pas aux problèmes du monde ». On a eu la même chose sur la génération X « ces jeunes ne s’intéressent pas à la politique » et sur la génération du baby-boom « ces jeunes ne connaissent pas la dureté de la vie, et ils font les malins en faisant de grands discours politiques ». Et inversement. La nouvelle génération Y dit à l’ancienne « tes associations c’est bien joli mais ça n’a pas été très efficace ». Comme la génération X a dit aux baby-boomers « le rêve politique c’est bien joli mais cela a provoqué beaucoup de massacres et d’attentats ». Et comme les baby-boomers ont dit à la génération d’avant « pouvoir consommer c’est bien joli mais c’est un peu vide non ? »

À noter, on peut voir cette lutte entre générations dans le domaine des logiciels libres et de l’open source dans l’opposition entre la vision de Richard Stallman (génération baby-boom), plus politique, et la vision de Linus Torvalds (génération X), que nous dirons plus pragmatique.

D’autre part, les communautés de la génération Y vont bientôt atteindre leurs limites. C’est à dire que c’est bien joli d’avoir son petit groupe de passionnés de musique électronique des années 1978-1981, de faire des festivals, de participer à des conférences, mais pendant ce temps, on a un gouvernement qui vote des choses en notre nom. Cette conscience a commencé à se réveiller chez la jeune génération notamment avec le débat sur Hadopi. Mais ce n’est pas gagné : la catégorie de population qui s’est le plus abstenue aux élections européennes de 2009, ce sont les 18-35 ans, soit… La génération Y.

Conclusion

L’homme est un animal qui se sent bien dans une communauté relativement restreinte (« meute ») et tout homme finit par se retrouver dans une communauté restreinte. C’est pourquoi il n’y a pas de repli communautaire d’une génération par rapport à une autre, juste la création de nouvelles communautés, différentes de celles de la génération précédente. Chaque génération crée ses propres communautés, avec leurs avancées et avantages, et leurs limites. Limites que la génération suivante tente de dépasser en créant de nouvelles communautés.

Aujourd’hui j’ai du générer un package PEAR pour un plugin Symfony de ma composition. Ce plugin est en fait un admin-generator amélioré. Pour créer un package PEAR, il faut d’abord créer un fichier package.xml à la racine du plugin. Cela est bien expliqué dans le chapitre 17 du Definitive Guide To Symfony (désolé, c’est en anglais).

Le problème, c’est que dans ce fichier package.xml il faut taper toute l’architecture du plugin. Et pour un admin generator modifié, cela commence à faire beaucoup (une vingtaine de fichiers). C’est pourquoi, au lieu de tout taper bêtement à la main, nous allons utiliser un logiciel pour générer le fichier package.xml

On va donc :

  • récupérer le générateur automatique du fichier package.xml
  • générer le fichier package.xml et le rendre conforme à Symfony
  • générer le package

Récupération du générateur automatique du fichier package.xml

Je suppose que vous avez déjà installé PEAR (# apt-get install php-pear). Comme la version de PEAR fournie par Squeeze (ah oui, je suis passé à Squeeze récemment) et donc à fortiori celle fournie par Lenny n’est pas suffisante, il nous faut d’abord mettre à jour PEAR par la commande suivante :

# pear upgrade pear

Et après on installe le générateur automatique du fichier package.xml :

# pear install PEAR_PackageFileManager
# pear install PEAR_PackageFileManager_cli

Ensuite, vous taper pfm dans une ligne de commande. S’il vous renvoie bash: pfm: command not found, il va falloir encore souffrir un peu pour installer le générateur…

Note : Les instructions en italique sont à suivre seulement si la commande pfm ne marche pas.

On récupère d’abord le générateur pfm et on le met dans le dossier d’installation de PHP, ce qui donne les commandes suivantes. On se place d’abord dans le répertoire d’installation de PHP :

# cd /usr/share/php

On récupère la dernière version du fichier pfm (à vérifier dans les sources de PEAR, au moment où j’écris, c’est la version 1.21) :

# wget http://cvs.php.net/viewvc.cgi/pear/PEAR_PackageFileManager_Cli/scripts/pfm?revision=1.21&view=co

Et on change le nom du fichier en pfm :

# mv pfm\?revision\=1.21 pfm

Note : le fichier pfm doit obligatoirement se placer dans le dossier PHP dans lequel est installé PEAR.

Après on rend le fichier pfm exécutable en ligne de commande. Pour cela on modifie d’abord la première ligne du fichier pfm pour que script s’execute avec l’executable PHP. Ainsi chez moi :

#!@php_bin@

devient :

#!/usr/bin/php

Ensuite on crée un lien dans le dossier /usr/bin pour rendre le fichier pfm exécutable en ligne de commande :

# ln -s /usr/share/php/pfm /usr/bin/pfm

Voilà, vous pouvez désormais utiliser le logiciel pfm

génération du package.xml

Nous allons maintenant générer le fichier package.xml. Pour cela, on se place d'abord dans le dossier du plugin puis on lance pfm :

$ cd repertoire_racine_du_futur_package
$ pfm

Après il suffit de répondre aux questions que pose le programme (on sens la flemme du mec qui n'a pas envie de détailler toutes les questions... Bon, comme je suis gentil, et pour vous préparer psychologiquement, voici un lien vers le détail des questions posées). Vous terminez le questionnaire en répondant 14 (save & quit) à la dernière question et c'est bon, votre fichier package.xml est généré.

Néanmoins, il nous reste encore un petit détail à régler pour que le fichier package.xml devienne le fichier package.xml d'un plugin Symfony. Pour cela, il suffit de changer, pour toutes les balises <file>, l'attribut role="php" en role="data" (un recherche et remplacer devrait faire l'affaire :))

Votre fichier package.xml est prêt !!!

génération du package

Une simple commande, à effectuer dans le dossier racine de votre plugin (là où est votre fichier package.xml) et votre package est généré :

$ pear package

Conclusion

Ouf, on y est arrivé. Peut-être qu'en tapant tout à la main cela aurait été plus rapide 😉 ?

Dans une ancienne publication, je vous expliquais comment écrire Chinois (et/ou Japonais) sous Debian. Et bien aujourd’hui allons plus loin et donnons-nous la possibilité d’écrire Chinois dans des documents Latex.

Note : cet article a pour pré-requis l’installation d’une méthode d’écriture du Chinois (voir ecrire Chinois et/ou Japonais sous Debian)

Installation de CJK

Tout d’abord, il nous faut installer quelques packages pour que Latex puisse comprendre les caractères Chinois :

# apt-get install latex-cjk latex-cjk-chinese

Note : CJK est un acronyme signifiant Chinese, Japanese, Korean. Ainsi, semblable à latex-cjk-chinese, il existe des packages latex-cjk-japanese et latex-cjk-korean.

Charger les packages dans votre document Latex

Note : partie inspirée par le site des tuteurs de l’ENS, qui est une mine d’or en ce qui concerne Latex.

Ensuite, pour pouvoir écrire chinois, il suffit de rajouter les lignes suivantes en tête de votre document Latex :

\usepackage[cjkgb]{ucs}
\usepackage[utf8x]{inputenc}
\usepackage[C10,T1]{fontenc}
\DeclareFontSubstitution{C10}{gbsn}{m}{n}

Vous pouvez désormais taper vos textes en Chinois avec SCIM et les compiler avec Latex.

EDIT Note : Faite attention, vous ne pouvez taper que des caractères simplifiés. Taper un caractère non simplifié provoquera une erreur à la compilation.

Astuce et Bonus Style

Voir les cours de Kidtonik pour comprendre le titre de cette partie

Pour écrire en pinyin en latex, il faut charger le package pinyin en ajoutant la ligne suivante en tête de votre document .tex :

\usepackage{pinyin}

Après, il suffit de taper, par exemple pour wàn, \wan4. Ainsi pour taper la phrase 我很高兴 (je suis content) en pinyin dans un document latex, il faut taper :

\wo3 \hen3 \gao1\xing4

Conclusion

Voilà, vous pouvez désormais utiliser Latex pour écrire vos documents en Chinois, avec le pinyin.

Toujours Symfony, toujours… Comme dit dans la précédente publication, je travaille en ce moment sur plusieurs applications web. Chacun de ces applications me (nous) ont fait faire du symfony propel:init-admin de manière industrielle.

Pour tous ces init-admin, un fichier de configuration global unique de type generator.yml pour l’application que l’on puisse surcharger avec les fichiers generator.yml des modules est un plus. Cela permet par exemple de faire en sorte que la forme de tous les champs « created_at » de nos tables soit stockée à un unique endroit.

Nous allons donc intégrer un fichier globalgenerator.yml dans les fichiers de configuration de symfony, qui sera chargé avant le generator.yml.

Cela se fera en deux étapes :

  • 1° étape, surcharger la classe sfGeneratorConfigHandler par une classe monGeneratorConfigHandler
  • 2° étape, modifier la classe monGeneratorConfigHandler pour prendre en compte un nouveau fichier de configuration

1° étape, surcharger la classe sfGeneratorConfigHandler par une classe monGeneratorConfigHandler

Tout d’abord, il faut savoir que les fichiers de configuration sont lus par des Handlers, qui sont des classes PHP situées dans vendor/symfony/lib/config en partant du vendor. Chaque fichier de configuration a son propre Handlers, les liens entre les fichiers de configuration et leurs Handlers étant fait dans le fichier config_handlers.yml situé dans vendor/symfony/lib/config/config.

L’idée va être dans un premier temps de surcharger, et le Handler du fichier generator.yml, le bien nommé sfGeneratorConfigHandler, et le config_handlers.yml.

On commence par copier le fichier sfGeneratorConfigHandler.class.php (situé dans vendor/symfony/lib/config) dans le répertoire lib de votre projet (ou à toute autre endroit où vous êtes sur qu’il sera chargé par Symfony).

Renommez ensuite ce fichier en, par exemple monGeneratorConfigHandler.class.php et éditez le pour que l’entête du fichier ressemble à cela :

<?php

class monGeneratorConfigHandler extends sfYamlConfigHandler
{

Note : pour les puristes on pourrait faire en sorte que la classe monGeneratorConfigHandler étende la classe sfGeneratorConfigHandler.

Bon, après, on va faire en sorte que ce soit ce Handler qui soit appelé pour traiter les fichiers generator.yml. Pour cela, on crée un fichier config_handlers.yml dans le dossier config de l’application concernée (soit apps/monApplication/config) et on le remplit avec les lignes suivantes :

modules/*/config/generator.yml:
  class:    monGeneratorConfigHandler

Voilà, désormais, lorsque vous chargez un module avec un generator, c’est notre Handler qui est appelé. Nous allons maintenant éditer ce Handler pour qu’il puisse prendre en compte un fichier de configuration supplémentaire.

2° étape, modifier la classe monGeneratorConfigHandler pour prendre en compte un nouveau fichier de configuration

On va faire en sorte que le Handler prenne en compte le fichier globalgenerator.yml situé dans le dossier config de notre application (si ce fichier existe).

EDIT Note : n’appelez pas le fichier global generator.yml. En effet, placer un fichier generator.yml dans le dossier config de l’application fait crasher la dite application.

Pour cela, on rajoute quelques lignes à la méthode execute de notre classe monGeneratorConfigHandler, ainsi cela :

  ...
  public function execute($configFiles)
  {
    // parse the yaml
    $config = self::getConfiguration($configFiles);
    if (!$config)
    ...

devient cela :

  ...
  public function execute($configFiles)
  {
    
    $advancedConfigFiles = $configFiles;
    if (file_exists(sfConfig::get('sf_app_config_dir').'/globalgenerator.yml')) {
      $advancedConfigFiles = array_merge(
             array(sfConfig::get('sf_app_config_dir').'/globalgenerator.yml'), 
             $configFiles);
    }
    // parse the yaml
    $config = self::getConfiguration($advancedConfigFiles);
    if (!$config)
    ...

Note : la méthode sfConfig::get(‘sf_app_config_dir’) nous permet de récupérer le chemin du dossier config de l’application. D’autres variables peuvent être récupérées par cette manière. On peut notamment les voir dans le menu config/settings de la barre symfony apparaissant dans le navigateur web lorsque l’on charge une page de l’application.

Voilà, désormais, si le fichier globalgenerator.yml existe dans le dossier config de l’application, le Handler ira d’abord le rechercher puis le surchargera avec le generator.yml du module.

Conclusion

Nous avons donc vu comment créer un fichier de configuration global pour tous les generators de notre application. On peut bien entendu penser à surcharger de cette manière d’autres fichiers de configuration (par exemple view.yml)

Un mois sans publications, que le temps passe vite !!! En effet, ces dernières semaines ont été assez… Chargées. J’ai notamment trois développements d’application web en cours, ce qui ne laisse pas beaucoup de temps pour écrire.

D’ailleurs, cette publication leur est consacrée (oui, le boulot, toujours le boulot…). Pour ces projets, je, enfin nous (je ne suis pas tout seul à développer) utilisons le cadriciel Symfony.

Et récemment, j’ai dû rajouter des méthodes aux classes du model (alias Machin et MachinPeer). C’est ce que je vais vous expliquer maintenant.

Nous allons voir trois méthodes (trois « voies ») pour ajouter des méthodes aux classes du model (classes situées dans lib/model).

  • la voie facile : ajout de méthodes à l’aide des Behaviors
  • la voie des damnés : ajout de méthodes en modifiant le model-generator
  • EDIT la voie du sage : contournement de l’ajout de méthodes par création d’une nouvelle classe

Note : Les deuxième et troisième voies permettent notamment de rajouter des méthodes statiques. La deuxième méthode est fortement déconseillée car elle modifie le coeur même de symfony.

la voie facile : ajouter des methodes à une classe du model à l’aide de Behaviors


Cette possibilité d’ajouter des méthodes à une classe machin du model a en effet déjà été prise en compte dans Symfony, cela s’appelle les Behaviors. Un behavior permet d’ajouter des méthodes d’une classe à une autre classe. Nous allons donc coder un Behavior pour notre classe machin

Il nous faut d’abord créer un plugin ce qui se traduit dans les faits par créer le dossier plugins/monPlugin à la racine de votre projet Symfony

Ensuite, on crée dans ce plugin les dossiers config et lib. Et dans ces dossiers on crée respectivement les fichiers config.php et monBehavior.class.php. On a donc l’architecture suivante :

racine du projet
    ...
    plugins
        monPlugin
            config
                config.php
            lib
                monBehavior.class.php

Bon, ensuite, dans le fichier monBehavior.class.php, on crée une classe monBehavior et dans cette classe on y met les méthodes que l’on souhaite appeler dans la classe Machin, par exemple une méthode getIdAndString() :

<?php

class monBehavior {

  public function getIdAndString($object, $con = null) {
    $id = 'get'.get_class($object).'Id';
    return $object->$id()." -  oh yeah";
  }
}

Après, on va dans le fichier config.php et on ajoute le code suivant afin de charger les méthodes de la classe monBehavior pour qu’elles soient accessibles à d’autres classes :

<?php

sfPropelBehavior::registerMethods('monBehavior', array(
  ':getIdAndString'            => array('monBehavior', 'getIdAndString'),
));

note On constate que la méthode sfPropelBehavior::registerMethods prend deux arguments, le premier le nom sous lequel le behavior sera appelé (voir ci-dessous), le deuxième est un tableau avec comme index le nom des méthodes dans la classe qui appelle le behavior, et en valeur un tableau à deux éléments contenant la classe appelée et la méthode de la classe appelée.

Bon, une fois ceci effectué, il nous faut encore charger le behavior dans la classe Machin. Cela se fait en ajoutant la ligne suivante en dessous de la classe comme ceci :

<?php

class Machin extends BaseMachin
{
}

sfPropelBehavior::add('Machin', array('monBehavior'));

Voilà, il ne reste plus qu’à activer les behaviors en remplaçant false par true à la fin de la ligne suivante du fichier config/propel.ini :

propel.builder.addBehaviors = true

Et à régénerer le model (symfony propel:build-model pour les ignares…). Vous pouvez désormais appeler la methode getIdAndString() à partir d’un objet de classe Machin.

Avantages et limites des behaviors

Le gros avantage, c’est que l’on peut ainsi faire un pseudo multi-héritage (qui n’existe pas en PHP). Une classe peut utiliser à la fois les méthodes de la classe dont elle hérite et d’une autre classe myBehavior.

La grosse limite, c’est que cela ne marche pas pour les méthodes statiques, à cause d’une limitation du language PHP.

En effet, et sans rentrer dans les détails, lors de la sortie de PHP 5, les codeurs avait pensé à une fonction __call() qui permettait de récupérer les appels à des méthodes non définies mais malheureusement cette fonction ne marche pas avec les méthodes statiques. Cela sera possible dans PHP 5.3 avec la méthode __callStatic(). Cette fonction __call() permettant aux behaviors d’être appelés, on ne peut donc pas utiliser les behaviors pour des méthodes statiques.

C’est ce qui va nous pousser, pour pouvoir ajouter facilement des méthodes à toutes les classes Peer, à plonger dans les tréfonds du model-generator…

la voie des damnés : ajouter des méthodes statiques à la classe MachinPeer du model en modifiant le model-generator


ATTENTION : cette méthode est totalement déconseillée. Elle risque notamment de vous empêcher de mettre à jour Symfony. En effet, cette méthode implique de modifier des fichiers au coeur même de Symfony. Donc si vous pouvez vous en passer…

EDIT : Préférez largement la troisième voie (voir fin de la publication) à cette méthode

En gros, cette méthode consiste à rajouter directement les méthodes dans les fichiers de chargement des méthodes prédéfinies des classes peers afin qu’elles soient générées en même temps que le model. Pour cela, deux fichiers nous intéressent, et ce sont en partant du vendor de Symfony, les fichiers (respirez un bon coup) :

symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel
/engine/builder/om/php5/PHP5PeerBuilder.php

et

symfony/lib/plugins/sfPropelPlugin/lib/vendor/propel-generator/classes/propel/
engine/builder/om/PeerBuilder.php

Ce qu’on va faire, c’est mettre les méthodes que l’on veut ajouter dans PHP5PeerBuilder.php et les insérer dans la classe générée dans PeerBuilder.php.

Pour cela, il faut comprendre un peu comment fonctionne la génération des classes du model. Le générateur crée d’abord une chaine de caractères vide qu’il va remplir au fur et à mesure des headers puis des methodes de la classes. Le remplissage s’effectue donc par étapes et sous-étapes, chaque étape étant représentée par une méthode add du générateur.

Nous allons donc coder nos propres méthodes add puis nous allons les ajouter dans la méthode de création du corps de la classe générée afin de générer nos méthodes automatiquement.

Tout d’abord, on ajoute une méthode add à la classe PHP5PeerBuilder du fichier… PHP5PeerBuilder.php !!! Cela ressemble à cela :

	protected function addRetrieveByString(&$script)
	{
		$script .= "
	public static function retrieveByString(\$string = null, PropelPDO \$con = null)
	{
            return null;
	}
";
	}

Vous pouvez constater que cette methode addRetrieveByString prend en argument une chaine de caractères et lui rajoute une autre chaine de caractères contenant la méthode que nous aimerions voir généré automatiquement dans les classes peers.

Après, il nous faut faire en sorte que cette méthode add soit appelé lorsque le générateur contruit la classe peer. Il faut donc ajouter la ligne suivante à la fin de la méthode addClassBody de la classe PeerBuilder dans le fichier PeerBuilder.php :

$this->addRetrieveByString(&$script);

Et voilà, on régénère le model et la fonction « retrieveByString » est ajoutée à toutes les classes Peers… Elle n’est pas belle la vie ?

Conclusion


On a donc vu deux méthodes pour ajouter des méthodes à une classe du modèle, une facile pour les méthodes non statiques, l’autre plus expérimentale et à utiliser en ultime recourt pour les méthodes statiques des classes peers.

Un dernier conseil, si vous utilisez la deuxième méthode : copier les fichiers originaux quelque part, modifier vos fichiers, générez le model puis remettez les fichiers originaux (quitte à copier vos fichiers modifiés autrepart). Cela vous permettra de garder votre Symfony « propre ».

EDIT : la troisième voie : la voie du sage, contourner l’ajout de méthodes


En fait, il existe une troisième voie (merci Jon). La solution pour rajouter des méthodes dans une classe peer sans modifier symfony (avec toutes les conséquences que cela implique), c’est de ne pas essayer de rajouter des méthodes dans la classe peer.

Bon, normalement, là, vous vous dites : il est bien gentil mais moi je veux ma méthode MachinPeer::retrieveByString() qui retourne null et que l’on puisse surcharger. Patience, cela arrive.

L’idée c’est de créer une classe à un endroit qui sera lu par symfony, par exemple dans le dossier lib à la racine de symfony. Créons donc la classe MorePeerMethods dans le fichier MorePeerMethods.class.php dans le dossier lib de symfony.

Et après, pour chaque méthode créée dans cette classe, on fait en sorte que la dite méthode vérifie d’abord qu’une méthode du même nom n’existe pas dans, par exemple, MachinPeer (ceci pour permettre la surcharge). Pour cela, on introduit un choix « if ». Ainsi en reprenant l’exemple de la méthode retrieveByString décrite au dessus, cette méthode devient dans la classe MorePeerMethods :

<?php

class MorePeerMethods {

  public static function retrieveByString($object, $string = null, $con = null) {
    if(method_exists($object.'Peer', 'retrieveByString')) {
      return call_user_func_array($object.'Peer::retrieveByString', array($string, $con));
    } else {
      return null;
    }
}

Ensuite, pour appeler cette méthode dans un action.class.php quelconque, il suffit de taper :

 MorePeerMethods::retrieveByString('Machin', $monArgument1,$monArgument2);

Au lieu de :

 MachinPeer::retrieveByString($monArgument1, $monArgument2);

Le tour est joué, tout le monde est content, et personne n’a eu à tuer Symfony

Conclusion n°2


Jon a toujours raison.

Un tout petit mémoire (14 pages) sur la machine Enigma que j’ai eu à faire pour un cours de cryptanalyse.

Vous y trouverez un bref historique de la machine Enigma, une présentation de la technique de cryptographie d’une machine Enigma simplifiée et enfin un listing de code en Python permettant de modéliser cette machine Enigma simplifiée.

Lien ver le mémoire :

Mémoire sur Enigma

Sommaire du mémoire :

  • 1. Introduction
  • 2. Historique
  • 3. Fonctionnement
    3.1 Théorie
    3.2 Mécanisme

  • 4. Modélisation d’une machine Enigma en Python
    4.1 Modélisation
    4.2 Tests

  • 5. Conclusion
  • A. Bibliographie
  • B. Diagramme de classe
    B.1 Rotor
    B.2 Reflecteur
    B.3 Enigma

  • C. Codes
    C.1 rotor.py
    C.2 reflecteur.py
    C.3 enigma.py
    C.4 test.py

EDIT : Suite au commentaire de desfrenes, j’ai corrigé la boulette qui faisait dire que le Python ne supportait pas la surchage des opérateurs dans la conclusion de l’article.

Pour un devoir à la maison que je dois rendre, j’ai programmé une machine Enigma. J’ai décidé de faire ce travail en Python, d’une part parce que c’est un langage assez simple à écrire (pas de « #include stdio », pas de « private int monEntier »…) et d’autre part parce que cela faisait un an que je n’avais pas programmé dans ce langage et qu’il fallait que je me dérouille un peu.

Préliminaires

Avant de parler plus en détail de mon expérience, je vais commencer par relater une discussion que j’ai eu récemment avec un professeur de mon école. Ce professeur avait dû apprendre le Python dans le cadre de son travail, et n’avait pas du tout apprécié ce langage. Il était en effet choqué par plusieurs choses, par exemple l’absence de typage, ou par l’impossibilité de surcharger les méthodes.

Toutes ces choses le confortaient dans l’idée de ne jamais enseigner le Python dans le cadre de ses cours. Sur le coup je n’ai pas très bien compris, parce que pour moi le Python est vraiment le language idéal pour les débutants. Cela les force à indenter, le code est clair, il n’y a rien de superflu… Surtout que dans un hors-série récent de GNU Linux Magazine j’avais lu un plaidoyer pour l’enseignement du Python à la place du C ou du Java comme premier langage.

La (dure) reprise

Et j’ai commencé à programmer. Et j’ai compris mon professeur. Première réaction : « eeuuh, ils sont où les types ??? ». Ah ben oui, en Python, tout peut être tout et n’importe quoi. Après 6 mois de Java ça fait tout drôle. Et rien ne vous dira que vous vous plantez, en tout cas pas Pydev, le greffon Python d’Eclipse.

Bon, je programme pépère… Arrive le moment de tester mon programme. Et là l’interpréteur me signale une erreur de manque d’arguments. Après recherche sur internet, je constate qu’en effet, le Python et la surcharge, cela fait deux. Là je me dis « Mais c’est quoi cette blague !!! »

Bref, j’ai eu un peu du mal à m’y remettre, et quand je pense à mon professeur, je le comprends. Cela fait plus de 10 ans qu’il programme en C, en Java. Qu’il a l’habitude de surcharger ses fonctions. Qu’il a l’habitude de déclarer ses types. Moi, après 6 mois de Java, j’ai déjà du mal alors lui…

La dernière fois que j’ai fait du Python, je venais de faire du C++ non objet (hérésie quand tu nous tiens…), le Python m’était alors apparu comme une révélation. Mais là, après 6 mois sur Java avec Eclipse (IDE grâce auquel, il faut le dire, programmer en Java se fait les yeux fermés), ce fut un tout autre son de cloche.

Ce bon vieux Python

Néanmoins, après ces désagréables surprises et un petit temps d’adaptation, quel plaisir. Parce que taper trois lignes de code pour une fonction, regarder le code, se poser la question : elle est finie là ma fonction ?, reregarder le code, et voir qu’en effet la fonction est bien terminée, c’est une sensation agréable que je ne connais qu’en Python.

Et que dire de la gestion des listes… On passe d’une chaine de caractères à une liste, on supprime, on ajoute, on permute avec bonheur. Ce qui, pour programmer une machine Enigma, est assez utile. Quand je me rappelle l’année dernière comment j’avais galéré pour écrire une sorte de parseur en C++…

Conclusion

Deux conclusions s’imposent. D’une part, en informatique, il faut toujours essayer de coder dans tous les languages que l’on a appris, et ne pas se limiter à un seul language ou deux. En effet, on prend vite des habitudes qui peuvent nous jouer des tours. Et l’on finit par rejeter des languages forts intéressants, comme mon professeur avec le Python. Et en plus on perd son sens critique vis à vis de certains langages. D’où l’apparition des débats du genre Emacs/Vi…

D’autre part, le Python, malgré ce qu’il prétend, n’est pas un language objet. Il lui manque trop de choses qui font un language objet (surcharges de toutes les méthodes et non simplement surcharge des opérateurs…). Par contre, ce language est parfait pour apprendre l’algorithmique voir la programmation objet basique. Sa simplicité permet aux débutants de se concentrer sur le code et non pas sur « est ce que je dois mettre un point-virgule ou pas ».

Mais il n’est pas suffisant en programmation objet. Je pense qu’un enseignement Python + Java serait parfait pour une école généraliste. Le seul point génant est que l’on laisse le C/C++ de coté. Mais cela permettrait d’avoir un enseignement progressif incluant toutes les notions de la programmation impérative et objet.

Mon premier ordinateur portable vient de mourir, dans la fleur de l’age. Voici son oraison funèbre.

Au commencement

Joseph5, je t’ai acheté en janvier 2005, pour mes dix-huit ans. J’avais avant un PC fixe, Pentium III 600 Mhz, que j’avais acheté en 2000. Il commençait à se faire vieux, et, avant qu’il ne meurre comme toi, j’avais décidé de le mettre à la retraite. L’avenir s’ouvrait alors à moi, j’allais entrer en classes préparatoires, et il me fallait un nouveau PC.

Mon choix, après avoir hésité à prendre un ordinateur fixe, s’est porté sur un portable. Je risquais d’être en internat l’année prochaine, il me fallait donc un peu de mobilité. C’est ainsi que je t’ai acquis, toi, ACER TRAVELMATE 3202.

Ton nom a été trouvé durant un TP de biologie, dans une salle informatique. Avec une copine, nous avions décidé de renommer tous les ordinateurs avec le prénom de notre professeur de mathématiques, Joseph. Joseph1 était le PC sur lequel j’étais en TP, Joseph2 fut celui d’à coté, joseph3 celui de l’autre coté, Joseph4 fut ma TI83. Tu arrivais donc en cinquième, d’où ton nom : joseph5

Expérience de Linux (janvier 2005 – novembre 2005)

On en a vécu des choses ensemble. Notamment les installations de distributions linux. Dès que je t’ai reçu, j’ai installé une Mandriva. A l’époque, cela s’appelait encore Mandrake. Une Mandrake 10.0. Je ne fut pas très satisfait de cette distribution, hélas, je ne me rappelle plus pourquoi.

Toujours est-il qu’après un plantage totale (je crois me souvenir que ce n’était pas un kernel panic) dû au module ACPI (aaah, la gestion de l’énergie…), j’installais une Aurox. Aurox, c’est une distribution polonaise européenne basée sur Fedora. Je n’utilisais alors pas beaucoup Linux, restant la majorité du temps sous Windows. Du coup, bien que j’ai gardé cette distribution 8 mois, je n’ai pas de souvenirs concernant son utilisation.

Tout ce dont je me souviens, c’est que c’est la première distribution sur laquelle j’ai installé mes pilotes wifi. A l’époque, les pilotes wifi centrino n’étaient pas encore intégré dans le noyau, il fallait donc les installer à la main. J’étais assez fière de réussir cette opération, jeune débutant que j’étais. Mais une semaine plus tard, ce fut mon premier kernel panic.

Je décidais donc (oui, à l’époque j’étais assez radical) de changer de distribution pour essayer la nouvelle Ubuntu qui venait de sortir, Breezy Badger (5.10). Là ce fut un bonheur. Fort de mes expériences précédentes (un peu) et grâce à la simplicité de cette distribution (beaucoup), j’eu un système fonctionnel rapidement.

Il faut aussi savoir que c’est vers cette époque que je passais du coté de Linux, ne me servant de Windows que pour les jeux (jamais réussi à me servir de Wine…). En effet, notre connection internet était instable à la maison. Et Windows avait tendance à se bloquer en cas de perte de connection, contrairement à Linux. C’est d’ailleurs à cette occasion que tu as perdu ta touche « Z », un jour où je m’étais trop énervé( oui, je suis violent aussi…).

La classe préparatoire (novembre 2005 – mai 2007)

Là, ce fut l’époque de Camllight, d’Emacs et de Tuareg. Chose rigolote, à chaque fois que je mettais à niveau Ubuntu (c’est à dire que j’installais la nouvelle version en écrasant l’ancienne), je devais recréer les packages .deb à partir des packages .rpm en utilisant Alien. Finalement, je suis retourné à Vi en rentrant en école.

Mais la prépa, ce fut aussi les parties de Counter Strike et de Worms Armaggedon, la découverte des animes grâce à la diffusion de GTO sur Europe2TV, devenu Virgin 17. Chaine télé que je regardais avec ma carte TV achetée fin 2006.

Durant cette période, j’ai aussi amélioré mon PC. Rachat de mémoire RAM (pour faire tourner Civilization 4) fin 2006 et d’un disque dur au beau milieu du concours des Mines.

Civilization 4, pendant que j’y pense, ce fut assez grandiose. Ah ! passer une nuit entière, avec un ami, à refaire le monde dans ma chambre d’internat. Se rendre compte au petit matin que c’est le petit matin. Et passer une colle après une nuit blanche… Que du bonheur…

La fin (mai 2007 – mars 2009)

C’est alors que tu as commencé à vieillir. Cela s’est de plus en plus remarqué après mon entrée à l’école. Petit à petit, des morceaux de toi se sont détachés. Cela a commencé par la protection de la baie PCMCIA. Puis les pieds en caoutchouc. Puis ce fut un coup dans l’écran.

La déchéance n’était pas seulement externe. Ainsi, les distributions Ubuntu ont commencé à moins bien fonctionner que les précédentes. La dernière qui fut potable était la 7.10 Gutsy Gibbon. Et cela empirait. Ainsi, pour la 8.10 Intrepid Ibex, tu ne démarrais pas si la souris et le secteur n’étaient pas branchés.

Malgré cela, ce fut encore une période prolixe. J’appris le PHP, la gestion de bases de données, les frameworks MVC. Mais je sentais que le moment de la retraite avait sonné… J’achetais donc un PC fixe en avril 2008, dans le but de te soulager un peu. Puis un netbook début mars 2009. Et je commençais à regarder pour acheter un nouveau portable de ton calibre…

Malheureusement, en ce fatal début d’après-midi du 31 mars, harassé par tant d’efforts, tu t’enfonças dans un coma profond. Coma dont je sens bien que tu ne te relèveras jamais.

Conclusion : vers l’avenir

Aujourd’hui j’ai perdu un ordinateur. Mais j’espère, joseph5, de la où tu es, que tu verras l’avenir radieux auquel tu as contribué. Que tu verras tes successeurs. Tu connais déjà minijoseph et joseph-server. Mais bientôt ton remplaçant, ton petit frère sera là !!!

Joseph5, tu peux être fier de ce que tu as accompli. Tu fûs un fidèle compagnon de route. Il ne me reste plus qu’à te souhaiter bon repos au paradis des ordis.

Chebitchov, en mode craquage.

J’étudie le Chinois et je regarde beaucoup d’animes japonais, j’ai donc « besoin » de pouvoir écrire en Chinois (surtout) et en Japonais sur mon ordinateur. Il existe une méthode simple sous Linux pour pouvoir écrire dans diverses langues asiatiques, c’est d’utiliser le logiciel scim. Nous allons voir comment l’installer.

Configuration

L’installation s’est faite sur une Debian Lenny Stable avec comme environnement graphique gnome (installation de base de Debian).

Installation

On commence tout d’abord par installer scim avec un gestionnaire de paquet. Pour le Chinois, j’utilise scim-pinyin et pour le Japonais, j’utilise anthy, ce qui donne comme ligne de commande :

# apt-get install scim scim-pinyin scim-anthy

Bien sur, la ligne précédente est à adapter en fonction de vos besoins. Une fois les paquets (et leurs dépendances) installés, il nous faut installer les polices de caractères Chinois et Japonaise. La première ligne correspond à l’installation des polices Chinoises, la deuxièmes à celle des polices Japonaises :

# apt-get install ttf-arphic-bkai00mp ttf-arphic-bsmi00lp ttf-arphic-gbsn00lp
# apt-get install ttf-kochi-gothic ttf-kochi-mincho

EDIT : Tout ce qui suit et qui est en italique est superflu pour écrire chinois ou japonais.

Bon, après, j’ai installé des paquets supplémentaires dont le rôle m’est flou, mais comme je ne sais pas s’il sont vraiment inutiles, je préfère le signaler :

# apt-get install xfonts-intl-japanese xfonts-intl-chinese

Encore une chose que je pense être optionnel (mais dont je ne suis pas sur hélas), c’est de reconfigurer les [langues] locales du système. Pour cela on tape la commande suivante :

# dpkg-reconfigure locales

On arrive alors dans une interface graphique ncurses. Donc, espace pour sélectionner, tab pour changer de fenêtre, flèche haut et flèche bas pour naviguer dans une fenêtre. On sélectionne alors les langues suivantes :

    fr_FR.UTF-8 UTF-8
    ja_JP.EUC-JP EUC-JP
    ja_JP.UTF-8 UTF-8
    zh_CN GB2312
    zh_CN.GBK GBK
    zh_CN.UTF-8 UTF-8
    zh_TW BIG5
    zh_TW.UTF-8 UTF-8

Enfin, il ne nous reste plus qu’à faire en sorte que scim se lance à chaque démarrage du serveur X. Pour cela, on modifie (ou on crée) le fichier /etc/X11/Xsession.d/95xinput en y ajoutant ces lignes :

/usr/bin/scim -d
XMODIFIERS="@im=SCIM"
export GTK_IM_MODULE="scim"
export XIM_IM_MODULE="scim -d"
export QT_IM_MODULE="scim"
export XMODIFIERS

Voilà, il ne reste plus qu’à redémarrer le serveur X pour que scim soit opérationnel.

Conclusion

Par défaut, il faut taper controle-espace pour activer le passage à l’écriture asiatique et majuscule-controle pour changer de langues asiatiques.

Michiko e Hatchin

Michiko e Hatchin est un anime qui est diffusé depuis le printemps 2008 sur Fuji TV et que j’apprécie beaucoup (j’en suis à l’épisode 14 sur 22). Cette anime raconte l’histoire d’une femme et d’un fillette de 10 ans partant ensemble à la recherche du père de la fillette.

Synopsis

L’histoire se passe en Amérique du Sud, dans un pays imaginaire (qui ressemble fortement au Brésil). Michiko, la femme, est une prisonnière évadée d’une prison de haute sécurité. Hatchin, la fillette, une orpheline élevée par une famille qui ne l’aime pas. La première enlèvera la seconde, et les deux partiront à la recherche d’un homme, grand amour de la première et père de la seconde.

Le scénario : un peu fouillis mais très bien

On est alors en présence d’une grande histoire, parfois assez fouillis. Tout au long de leur périple sera révélé le passé de Michiko, marqué notamment par les guerres de gangs dans les favelas, qui sont parfois assez difficiles à comprendre. On pourra noter de temps en temps des pirouettes scénaristiques que je n’ai pas très bien comprises. On découvrira aussi une galerie de personnages (l’ancienne amie devenu policière, le chef de gang sadique, …) ayant chacun une histoire et une personnalité assez fouillées, avec une mention spéciale pour la policière qui aura le droit à son épisode spécial.

L’ambiance : soignée

Le dessin et l’ambiance générale collent parfaitement avec le scénario. La musique est de tonalité espagnole, elle n’est pas exceptionnelle mais encore une fois cela va bien avec l’ambiance générale.

On n’est pas spécialement frappé par la beauté des graphismes (quoique) mais ils sont propres et efficaces et c’est tout ce qu’on leur demande.

El Cazador de la Bruja ?

En regardant Michiko e Hatchin, je n’ai pas pu m’empêcher de penser à El Cazador De La Bruja. En effet, la ressemblance entre les deux animes est stupéfiante d’un certain coté. On aura tôt fait de trouver des similitudes entre Hatchin et Ellis, et surtout entre Michiko et Nadie.

Heureusement la ressemblance s’arrête là. Michiko e Hatchin se concentrant plus sur une histoire développée plutôt que sur la mise en scène (mise en scène raté dans El Cazador). Malgré tout, j’ai parfois vu en Michiko e Hatchin un El Cazador réussi.

Conclusion

Un bon anime, porté par une histoire complexe voir fouillis présentant une galerie de personnages travaillés, avec des graphismes simplement beaux et une musique assez quelconque mais qui colle bien avec une ambiance générale réussie. À regarder si vous aimez les galeries de personnages, les road-movies et l’ambiance sud-américaine.