Si je vous offre une tisane Ukiurtatuq, Arpiqutik, Qisiqtutauyak, Paurngaqutik ou Mamaittuqutik, qu'est-ce que ça vous évoque ? Mis à part que ce sont des mots qui valent chers au Scrabble, ce sont principalement des variétés de fines tisanes Inuites qu'on m'a offertes hier.
Je ne suis pas vraiment du type "tisane" mais pour la tasse que j'ai bue, ça avait bon goût. Contrairement à la croyance populaire, ces tisanes ne sont pas aromatisés au goût de babiche. J'ai trouvé la liste des ingrédients sur le site web de Délice Boréal, un projet mené par l’Institut culturel Avataq, un organisme sans but lucratif qui se consacre à la protection et à la promotion de la langue et de la culture des Inuits du Nunavik (Nord du Québec).
Parmi les ingrédients utilisés, on retrouve de la racine de guimauve, des racines de salsepareille, des graines de fenugrec, des fleurs de trèfle rouge, des fleurs d'hibiscus (comme la bière du Dieu-du-Ciel!), des fleurs de coquelicot, des feuilles de raisin d'ours et bien plus.
Sur les sachets, j'avais remarqué des symboles d'écriture, avec la transposition dans notre alphabet, d'où les noms qui sont difficiles à prononcer pour nous. Imaginez, le Nunavik compte à peine 11 000 habitants, ce qui me fait croire que leur langue est probablement moins parlée que l'espéranto!
On peut consulter le site de Délice Boréal en français, en anglais et en Inuktitut. Pour cette dernière, on voit dans le CSS que les polices de caractères utilisées sont :
font-family:AiPaiNuna, AiPaiNunavik, AiNunavik, AiPaiNutaaq, AiNunavi, AiPaiNun;
Vous pouvez télécharger les polices Inuktitut à partir du site d'Avataq si vous êtes curieux de voir ce que ça l'air (il s'agit d'un petit exécutable qui se charge d'installer le support pour la langue dans Windows). J'ai aussi noté au passage que leur site utilise des SIFR, jQuery et l'UTF-8 :-)
Dans le monde de la programmation JavaScript, il y en a qui ne jurent que par le langage dans sa forme la plus pure. D'autres, comme moi, ont appris à aimer ce langage de scripting lorsqu'ils ont découvert Prototype et jQuery qui permettait de faire abstraction des subtilités des fureteurs tout en ajoutant de puissantes fonctionnalités. Et comme moi tout à l'heure, après des années à utiliser ces frameworks au quotidien, j'ai réussi à oublier que le JS de base pouvait s'avérer utile pour nous sortir d'embarras.
J'avais une requête Ajax qui récupérait un array associatif que j'avais converti avec json_encode() de PHP.
$field['input_id_1'] = 'html 1';Ce qui retourne un résultat comme le suivant :
$field['input_id_2'] = 'html 2';
$field['input_id_3'] = 'html 3';
echo json_encode($field);
{Une fois la réponse récupérée par une requête Ajax, je voulais boucler sur chaque propriété pour attribuer la valeur de la clé à l'ID de l'élément du DOM (la clé JSON représente l'ID dans le HTML). Au début, j'ai eu le réflexe de regarder du côté de Enumerable.each dans Prototype, ensuite dans la fonction jQuery.each(). Ni un ni l'autre ne permettent de boucler sur les propriétés d'un objet JSON. Tout ce qui est possible de faire, c'est de boucler sur des éléments d'une liste.
'input_id_1' : 'html 1',
'input_id_2' : 'html 2',
'input_id_3' : 'html 3'
}
C'est là que j'ai allumé qu'on pouvait le faire nativement, sans aucune librairie. À supposer une chaîne de caractère JSON comme celles-ci :
var json = "{ 'input_id_1' : 'value 1', 'input_id_2' : 'value 2', 'input_id_3' : 'value 3' }";On doit d'abord évaluer la chaîne JSON avec eval() en prenant soin de l'entourer de parenthèses (autrement vous pourriez voir le message invalid label apparaître dans la console de Firebug) :
// ou
// var json = "{ 'title':'Code 18', 'url':'http://code18.blogspot.com', 'pagerank':'3' }";
var data = eval( "(" + json + ")");À titre de trace, ça affichera dans la console :
for(var key in data){
console.log(key + ' = ' + data[key]);
// prototype
// $(key).update(data[key]);
// jquery
// $j('#' + key).html(data[key]);
}
input_id_1 = value 1
input_id_2 = value 2
input_id_3 = value 3
Hier soir, j'étais de passage pour la première fois à la bibliothèque de mon quartier et j'ai ramené un exemplaire de la revue gratuite Le Libraire (le bimestriel des librairies indépendantes, vol 13 no 60 Août-Septembre 2010). C'est fou comme on y trouve du contenu pour un truc gratuit (pour ceux qui aiment les livres, bien entendu). C'est vraiment une manie chez moi de lire tout ce qui me tombe sous la main, parfois seulement pour trouver le petit extrait qui deviendra le point de départ vers la découverte de quelque chose de passionnant.
Dans le rack à publications, le Westfalia jaune en couverture a attiré mon attention, de même que la mention du libraire d'un jour : Amir Khadir. Il liste ses choix de lecture (page 8-9) et les explique dans le texte "Frapper l'imagination, nous élever un peu...". Comme le livre de Chams de Tabriz de Mawlâna Djâlâl al-Dîn-Rûmi. Ça sonne exotique vous ne trouvez pas ? Moi c'est le genre de truc qui m'allume, quand j'ai le sentiment de pouvoir explorer un domaine sans avoir trop de points de repères ou lu une critique qui dévoile tout.
Quand on y pense, c'est vrai qu'on a tendance à ne pas lire beaucoup. La lecture entraîne notre cerveau qui est aussi un muscle à développer. Un entraînement à faire au moins trois fois par semaine pour le garder en forme et pas seulement de temps en temps lorsqu'on se sent coupable de ne pas en prendre soin.
Ensuite, on se déplace à la page 43 où une chronique nous attend par la plume de Normand Baillargeon (qu'on connaît pour son Petit cours d'autodéfense intellectuelle et pour un entretien avec Noam Chomsky). Je note la citation au passage : "L'idée de l'avenir est plus féconde que l'avenir lui-même. - Henri Bergson". Coup d'oeil au livre Nanotechnologies et société qu'il présente en introduisant la conférence de 1959 sur le sujet, du physicien Richard Feynman. Un génie qui mérite d'être aussi connu qu'Einstein.
Quelques pages plus loin (p.46), ils ont posé la question à la libraire Johanne Vadeboncoeur : Quelle est votre meilleure anecdote de libraire ? Sa réponse :
Le jour où un client m'a dit avoir entendu parler d'un roman dont l'auteur était David Ciccone... Après plusieurs recherches infructueuses, j'ai réalisé qu'il s'agissait en fait du livre Da Vinci Code!
Enfin, du côté de la littérature jeunesse, on retrouve encore une fois une référence au mythique H2G2 (Guide du voyageur galactique). Cette fois-ci, c'est Eoin Colfer qui reprend le flambeau pour écrire encore une chose sur cette trilogie. Parce qu'il y a toujours quelque chose à dire. Et à lire.
Dans la bibliothèque, il y avait aussi un café Internet et des cours offerts gratuitement sur des sujets comme Word ou Excel. Je crois que c'est quelque chose qui me plairait de donner des formations aux gens de ma communauté. Un genre de cours pour débutant sur le web ou de programmation 101. Juste parce que le contact humain me manque lorsque j'écris sur mon blogue. Il y a tellement de livres et de choses qui m'intéressent, mon plus grand regret dans la vie sera que je n'aurai jamais le temps de tout faire.
Ça c'est particulièrement drôle pour un geek. Un écriteau en milieu urbain indiquant "Reboot universe". En effet, c'est tentant d'appuyer sur le bouton ! Quelqu'un a une idée dans quelle ville se trouve cette pancarte (même si elle semble plus ou moins réelle) ?
Je me rends compte que j'ai accumulé quelques photos de ce type déjà. Dorénavant, je les regrouperai sous la catégorie "Pancartes et écriteaux".
Quand la tablette iPad est arrivée sur le marché, j'étais enthousiaste mais j'ai résisté à la tentation d'acheter. C'est un beau gadget mais le prix m'a convaincu de patienter un peu. Malgré le succès qu'on connaît, il fallait que d'autres joueurs fassent leur apparition afin d'avoir une réelle concurrence et considérer ce que les rivaux d'Apple auraient à offrir.
Plus récemment, j'avais donné un vote de confiance à la tablette québécoise ExoPC slate qui semble prometteuse mais qui tarde à venir. Le prix, similaire à celui de l'iPad (600$), demeure un irritant. Peut-être qu'un essai me fera croire que ç'en vaut le coût.
On a pas eu à attendre longtemps pour voir apparaître des clones asiatiques de la tablette populaire, dont le prix se situe généralement sous la barre des 200$ :
- eKen aPad iRobot (189$)
- l'iPed, une imitation à s'y méprendre du iPad, lancé en Chine en juin 2010 (OS Android 1.6)
- HIApad
- FlatPad (285$)
- Gnomes (107,70$)
- Pandigital Novel (169,99$)
- Voir aussi SlateDroid.com (lien click me / tablet wiki)
À petit prix, on pourrait croire à une liquidation puisqu'on sait que la version courante est 2.2 et que la version 3.0 d'Android devrait voir le jour dans le dernier trimestre de 2010. Peut-être que ça vaut la peine de prendre son mal en patience pour obtenir mieux. Justement, la chaîne de magasin KMart aux États-Unis annonce sur son site une tablette Augen Gentouch 78 roulant sous Android 2.1 à seulement 149$ US (source: Teleread.com et Slashgear.com).
L'alternative à l'iPad devient soudainement très alléchante. Pour moi on approche d'un gagnant ou d'une guerre de prix qui sera à l'avantage des consommateurs. Ma carte de crédit est déjà prête de lui donner sa chance.
Tu te souviens de la fois où il fallait faire une évaluation de temps sur un coin de table et sortir le plus rapidement possible une réponse alors qu'il y avait beaucoup trop de zones grises ? Dans ce cas, donner n'importe quel chiffre au hasard revient à peu près au même que de ne pas faire d'analyse du tout. Pour tourner la situation au ridicule, on pourrait jeter les dés et additionner le pointage obtenu, lancer les darts sur une cible ou mieux, laisser le soin à un coin-coin en papier servir d'oracle. Idéalement, il faut procéder immédiatement devant la personne qui vous fait la demande (sauf s'il s'agit de votre patron, qui risque de la trouver moins drôle).
Vous vous souvenez du coin-coin de notre enfance ? Cette feuille de papier qui, une fois pliée, ressemble à un bec de canard. Les enfants demandent un chiffre, comptent jusqu'à celui demandé en alternant le sens du mouvement et déplient le coin correspondant afin de transmettre la réponse qui est cachée.
En milieu de travail, un coin-coin peut s'avérer utile :
- principalement, pour éviter de prendre une décision responsable
- pour donner un estimé de temps aléatoire à un projet
- pour trouver une excuse de programmeur
- trouver une position au lit (oups, non pas au boulot!)
- etc.
Comment fabriquer un coin-coin en papier ?
Étape 1 : prenez une feuille de papier 8 1/2 par 11.
Étape 2 : pliez le coin de façon à créer un angle droit.
Étape 3 : Coupez l'excédent.
Étape 4 : Vous obtiendrez un carré une fois déplié. Pliez le une seconde fois dans l'autre diagonale.
Étape 5 : Pliez chaque coin vers le centre.
Étape 6 : Retournez la feuille et pliez à nouveau les 4 coins vers le centre
Étape 7 : Pliez la pour former un rectangle.
Étape 8 : la forme est complétée. Inscrivez sous chacun des 8 petits triangles du centre la réponse absurde que vous souhaitez.
Utilisé avec humour, cet outil est excellent contre le stress et est une excellente façon de faire comprendre que la tâche d'analyse est plus complexe qu'elle ne le paraît. Sinon, vous amuserez les enfants ou vos collègues de travail car on sait tous que l'âge mental d'un groupe de personnes est d'environ 6 ans.
P.s. Merci à Mamzelle V pour les photos!
Chaque minute, en Amazonie, on déboise l'équivalent de soixante terrains de football. C'est un peu idiot, il n'y aura jamais assez de joueurs.
J'ai un ami mécanicien qui, chaque fois que je le vois, me raconte ses histoires de chars. À tout coup, c'est très imagé, un peu comme les histoires de pêche. Il reste que c'est comique à écouter et que la façon dont il relate ses anecdotes, on veut y croire.
Je suis allé dîner avec lui et pendant qu'on mangeait, on a rencontré un de ses anciens collègues qui nous en a appris une bonne à propos des lois routières en Ontario. Alors qu'il se rendait là-bas en voiture pour ses vacances, il a eu droit à une contravention d'un peu plus de 400$ pour une infraction de la route.
Un excès de vitesse ? Même pas. Il a simplement dépassé une voiture de police avec ses gyrophares allumés qui était immobilisée dans l'accotement. N'étant pas au courant de ce règlement spécial en Ontario, il s'est fait coller et le policier lui a fait payer la note. Selon le règlement, il aurait dû ralentir et même changer de voie.
La loi ontarienne est très sévère à ce sujet :
- pour la 1ère infraction, l'amende peut varier de 400$ à 2000$ + 3 points d'inaptitude
- pour la 2ème, c'est une amende de 1000$ à 4000$ + possibilité de peine d'emprisonnement de 6 mois + possibilité de suspension du permis de conduire pour une période allant jusqu'à 2 ans
On trouve ce genre de loi étrange dans 5 provinces canadiennes (île-du-Prince-Édouard, Ontario, Manitoba, Saskatchewan et Alberta) mais c'est en Ontario qu'ils sont les plus intolérants. Si vous planifiez des vacances à l'extérieur du Québec ou si vous en connaissez qui iront, soyez vigilant et faites circuler l'information. Tout comme nous, vous préférerez vous gâter avec 400$ plutôt que de les remettre à un service de police. N'en déplaise à Chantal Fontaine et ses publicités pour Tourisme Ontario, j'irai ailleurs (comme le Nouveau-Brunswick) lorsque viendra le temps de choisir une destination vacances.
En terminant, avant de vous affoler et que vous pensiez que ce que je raconte est une légende urbaine basée sur des ouï-dires, visitez le site de la Gendarmerie Royale du Canada qui fait état de la situation sur le dépassement des véhicules prioritaires arrêtés sur la route.
Pourquoi des éléments du DOM ? Le besoin vient généralement du fait que des éléments doivent être classés dans un ordre précis et qu'il n'y a pas mieux que de pouvoir le faire dans l'interface en les faisant glisser à l'aide de la souris. C'est convivial et tellement mieux que d'essayer de maintenir un ordre avec n'importe quelle autre technique.
J'avais expérimenté l'effet sortable avec Prototype et Scriptaculous mais depuis le virage vers jQuery, c'était mon premier essai avec la librairie. Je mets à votre disposition un exemple fonctionnel en guise de snippet de départ qui utilise jQuery UI sortable.
La première chose à faire est de lier à la page les librairies jQuery et jQuery UI :
<script type="text/javascript" src="/js/jquery-1.4.min.js"></script>J'ajoute un peu de CSS pour créer un visuel plus attrayant pour la liste à classer :
<script type="text/javascript" src="/js/jquery-ui-1.8.2.custom.min.js"></script>
<style type="text/css" media="screen">Je génère dynamiquement des éléments de la liste pour le HTML à l'intérieur du formulaire (l'index numérique pourrait correspondre à une clé primaire de la base de données) :
#list{
/* annuler l'indentation */
marign-left: 0;
padding-left: 0;
list-style: none;
}
.item{
/* annuler l'indentation */
marign-left: 0;
padding-left: 0;
padding:5px;
margin:5px;
border:1px solid black;
background-color: #ececec;
width: 300px;
/* curseur de la souris lorsqu'on se trouve sur un item déplaçable */
cursor: move;
}
</style>
<form id="frmList" action="<?php echo $_SERVER['SCRIPT_NAME']; ?>" method="post">Remarquez ici, ce sont les conteneurs LI qui seront réordonnés. Comme ils contiennent des champs de saisie portant le même index, ce sont les noms de ces champs qui seront postés au script PHP.
<ul id="list">
<?php for($i=1; $i<=5; $i++){ ?>
<li class="item" id="li_<?php echo $i; ?>">
<input type="text" id="input_<?php echo $i; ?>" name="input_<?php echo $i; ?>" value="Bloc <?php echo $i; ?>" />
</li>
<?php } ?>
</ul>
<input type="button" id="btnSubmit" name="btnSubmit" value="Enregistrer" />
</form>
Au chargement de la page, j'ajoute le JavaScript d'initialisation. Pour suivre la trace de ce qui se passe dans Firebug, je définis une fonction optionnelle onDrop() qui sera appelée lorsque l'item sera déposé à sa nouvelle position.
var $j = jQuery.noConflict();En appelant toArray sur sortable() on récupérera côté client les ID des LI (li_[1-n])
$j(document).ready(onLoad);
function onLoad(){
$j('#list').sortable({ 'update': onDrop });
$j('#btnSubmit').click( onSubmit );
}
function onDrop(){
console.log('order has changed');
}
function onSubmit(){
$j('#frmList').submit();
}
var arr = $j('#list').sortable('toArray');Dans ce cas, onSubmit pourrait d'abord récupérer les ID des LI selon l'ordre affiché, extraire l'index (la portion numérique) et composer une liste CSV du type "1,3,5,4,2" qui pourrait être stockée dans un champ caché du formulaire :
HTML
<input type="hidden" id="items_order" name="items_order" value="">JavaScript
function onSubmit(){La fonction ci-dessus utilise each() de jQuery pour boucler sur les éléments. On aurait aussi pu l'écrire avec cette fonction équivalente qui utilise map() de jQuery :
var arr = $j('#list').sortable('toArray');
$j(arr).each(
function(i, e){
// arr est utilisé en "closure"
arr[i] = e.replace('li_', '');
}
);
$j('#items_order').val( arr );
$j('#frmList').submit();
}
function onSubmit(){Dans les deux cas, PHP recevra la valeur CSV sous la variable $_POST['items_order']. Vous pourrez convertir la string en array avec explode().
var arr = $j('#list').sortable('toArray');
arr = $j(arr).map(
function(){
return this.replace('li_', '');
}
);
$j('#items_order').val( arr.get().join(',') );
$j('#frmList').submit();
}
Par contre, si ce qui vous intéresse est d'obtenir par PHP les valeurs des champs de saisie selon le classement, les clés reçues seront placées dans l'ordre à l'intérieur de la variable $_POST. Il suffira de boucler sur la liste pour les récupérer dans l'ordre (pour faire simple, vous pourrez par exemple passer les clés une par une et vous assurer que son nom commence par "input_" avant de récupérer la valeur). Peu importe comment vous l'implémenterez, ça ouvre la porte à une panoplie de solutions originales. Laissez aller votre créativité !
Tiens, y'a du curieux par ici ! J'aimerais tellement que Montréal soit aussi original que Vancouver dans ses pancartes.
Je cherchais un moyen d'écrire une requête SQL qui me permettrait d'obtenir, à partir des tables systèmes de Postgres, la liste des champs d'une table et leurs types.
À mon premier essai, j'ai pu les afficher avec cette requête :
SELECT col.attname, t.typnameJusqu'à ce que je me mette à utiliser le information_schema qui me permet d'aller chercher plus de détails :
FROM pg_attribute as col
INNER JOIN pg_class as tbl ON col.attrelid = tbl.oid
INNER JOIN pg_type as t ON t.oid = col.atttypid
WHERE tbl.relname = 'tablename'
AND col.attnum > 0
SELECT column_name, data_type, is_nullable, character_maximum_length, udt_nameBeaucoup plus simple, sans avoir besoin de se casser le bicycle avec la mécanique interne de Postgres.
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'tablename'
ORDER BY ordinal_position
Vous connaissez la section Séparés à la naissance sur Cyberpresse ? Dans le même ordre d'idées, on m'a fait parvenir la photo du joueur de hockey Georges Laraque prise sur un panneau publicitaire de Teksavvy en me faisant remarquer à quel point ses yeux faisaient penser au regard effrayant de Vigo, le vilain dans Ghostbusters 2.
Georges est un gars sympathique qui n'a pas peur du ridicule. Sa publicité vidéo tournée pour l'entreprise qu'il représente montre qu'il ne se prend pas au sérieux. Est-ce un hasard que la publicité imprimée indique aussi "Internet haute vitesse, sans contrat!" ? Comme lui, sans contrat depuis qu'il a été libéré par les Canadiens de Montréal.
À part la ressemblance, j'ai intérêt à me montrer gentil. Je ne souhaite aucunement chercher la bagarre avec l'un ou l'autre.
Parlons sérieusement. Teksavvy offre un service Internet DSL avec la bande passante illimitée pour 24,95$ par mois, sans contrat. Ça semble vraiment pas cher. Je risque de leur passer un coup de fil pour comparer lorsque mon contrat de 42,95$ par mois avec Vidéotron prendra fin.
En ce début de semaine, je vous présente un petit survol sur l'utilisation des variables en PHP à l'attention des débutants. Pour les autres, révision obligatoire pour se rafraîchir la mémoire sur des notions qu'on prend pour acquis.
1. Entre apostrophe
La base, où le texte est entre apostrophes (single quotes).
$var = 'world';2. Concaténation
echo 'Hello $var';
// Erreur. Imprimera le texte en littéral: Hello $var
Pour venir juxtaposer la valeur d'une variable, on peut utiliser la concaténation avec le caractère . (point).
$var = 'world';3. Entre guillemets
echo 'Hello ' . $var;
// Imprimera: Hello World
Pour pouvoir insérer la variable à même la chaîne de caractères, on utilisera les guillemets (double quotes).
$var = 'world';4. Tableau indexé (array)
echo "Hello $var";
// Imprimera: "Hello World"
Lorsque la valeur se trouve dans un tableau, on peut l'imprimer normalement en utilisant l'index indiqué entre crochets.
$arr = array('Gibson', 'Fender', 'Godin');5. Tableau associatif
// imprimera en littéral le texte Guitare $arr[2]
echo 'Guitare $arr[2]';
// imprimera la valeur Godin (excellentes guitares québécoises en passant)
echo "Guitare $arr[2]";
C'est ici que ça se complique un peu. Supposons le tableau suivant :
$arr = array('a' => 'Gibson', 'b' => 'Fender', 'c' => 'Godin');Les deux causent des erreurs. Comment résoudre ce problème ? Avec les accolades :
// on peut ni utiliser cette syntaxe :
echo "Guitare $arr['c']";
// ni celle-ci :
echo "Guitare $arr["c"]";
echo "Guitare {$arr['c']}";Utilisées dans ce contexte, les accolades permettent l'interprétation du code PHP. Autrement dit, on dit à PHP d'évaluer ce qu'il y a à l'intérieur avant de faire le reste.
6. Propriété d'un objet
Si on ne connaît pas le truc des accolades, on peut contourner cette difficulté en attribuant d'abord la valeur à une variable.
$age = $oPerson->getAge();7. Composer le nom de la variable
echo 'Son âge est: ' . $age;
// ou
echo "Son âge est: $age";
// mais comme nous le connaissons :
echo "Son âge est: {$oPerson->getAge()}";
Disons deux variables où les noms possèdent le même préfixe mais qui se terminent par le code de langue (fr ou en). Une troisième variable qui contient la valeur de langue utilisée pourrait permettre de déterminer la variable à afficher.
$default_fr = 'Bonjour';8. Stocker le nom de la variable dans une variable avec $$
$default_en = 'Hello';
$lang = 'fr';
echo ${"default_" . $lang};
// ou
echo ${"default_$lang"};
// Imprimera "Bonjour"
Moins populaire et plus difficile à lire, cette méthode permet de stocker le nom d'une variable dans une variable. Pour faire simple, la valeur de la première variable devient le nom de la variable. Peut-être que l'exemple ci-dessous illustrera mieux ce qui se passe :
$variable = 'code18';Personnellement, je vois mal dans quel contexte je l'utiliserais.
$$variable = "une valeur";
echo $code18;
// Imprimera "une valeur"
Conclusion
J'ai connu certains programmeurs qui ont découvert toute la portée des utilisations possibles et qui se sont mis à en faire un exercice de style dans leurs projets. Ce n'est pas parce que le feature existe qu'il faut nécessairement l'utiliser. Le mot d'ordre : Keep it simple.
Une Corona glacée instantanément ? Buveurs de bière, faites l'expérience :
- placez une bouteille dans votre congélateur
- sortez-la et frappez la bouteille d'un petit coup
- observez l'effet, tout semble se solidifier
C'est toujours une expérience enrichissante lorsqu'un administrateur réseau nous assiste pour faire des manipulations sur un serveur Linux. J'apprends quelque chose de nouveau à tout coup. Enthousiaste de Linux, je suis loin d'être un expert. Lentement, je découvre le système d'exploitation et j'apprends à maîtriser mon environnement, une étape à la fois. Comme on dit qu'il n'y a pas de question stupide, j'en profite pour les poser à ces experts pour qui Linux n'a plus de secrets.
À partir de Windows, j'étais connecté à un serveur Linux avec Putty et il m'a demandé de chercher un fichier par son nom. Intuitivement, j'ai entré quelque chose comme ceci (recherche à partir de la racine /) :
find / -name 'php.ini'
C'est là qu'il m'a arrêté pour me suggérer l'utilisation de la commande locate, qui est plus rapide. Ok, mais pourquoi ? Je ne veux pas l'utiliser sans avoir compris en quoi locate est mieux que find dans cette situation.
Il m'explique que locate utilise un index maintenu à l'interne. Si un fichier est nouvellement ajouté, il ne sera peut-être pas répertorité immédiatement (un cron permet de réindexer les fichiers de façon périodique, par exemple quotidiennement). Mais pour un fichier plus vieux, il le trouvera plus rapidement. Dans le pire des cas, si le fichier n'est pas trouvé avec locate, on pourra se rabattre sur la commande find qui le trouvera. Cette dernière est plus puissante et possède plus d'options mais demeure plus lente.
Donc je me suis réessayé en entrant :
locate php.ini
Le résultat est apparu instantanément. Le soir même, chez moi, j'ai cherché à en savoir plus sur locate et son indexation. Sur le bureau d'Ubuntu, j'ai créé un fichier nommé "youppi". Immédiatement après, j'ai tenté de le chercher par locate : aucun résultat.
À quel moment l'indexation a lieu ? Comment repartir manuellement le processus d'indexation en cas de besoin ?
En fouillant un peu, j'ai trouvé que le processus s'appelle updatedb et se trouve dans /usr/bin/updatedb. Si je l'exécute, le nouveau fichier sera indexé pour les recherches ultérieures :
sudo updatedb
Ensuite :
locate youppi
Résultat:
/home/code18/Desktop/youppi
Autrement, je peux patienter lors de la prochaine indexation automatique. Ceci se fait à partir d'un cron job où on peut voir l'appel dans /etc/cron.daily/mlocate. Selon ce que j'en lis, mlocate est la nouvelle implémentation de locate (où "m" est pour merging, qui utilise la même base de données d'updatedb). En jetant un coup d'oeil à l'aide (locate -h), j'ai été étonné de voir que les implémentations de locate et mlocate sur Ubuntu avaient été développées par RedHat ou du moins un contributeur qui y travaille.
Si votre femme a envie d'habiter un appartement plus cher, inutile de déménager. Allez voir votre propriétaire et demandez-lui d'augmenter son loyer.
Autres références à Hitchhiker's Guide to the Galaxy
J'ai lu sur le tard le réputé The Hitchhiker's Guide to the Galaxy de Douglas Adams et je me demandais quel héritage cet ouvrage avait laissé dans la culture geek. On en parle, on y fait constamment référence, jusqu'à temps que je me rende compte que personne dans mon entourage avait lu ce livre, y compris moi.
Je suis sur le point de compléter la lecture du premier tome et uniquement dans celui-ci, on note certaines références reprises par la culture populaire :
- Chapitre 6 : le Babel Fish qui fût repris comme nom par l'outil de traduction de Yahoo! (page 55).
- Chapitre 19 : le robot Marvin se fait surnommer le Paranoid Android (page 119). Sur son album OK Computer (1997), Radiohead a intitulé Paranoid Android une pièce qui est rapidement devenue un succès. Thom Yorke disait que le titre était supposé être une blague en référence à Marvin, alors qu'il se sentait trop déprimé.
- Chapitre 25 : Googleplex Star Thinker in the Seventh Galaxy of Light and Ingenuity, un ordinateur superpuissant, repris pour le nom du siège social de Google (page 145).
Je peux maintenant rayer ce point sur ma liste des choses à faire.
Pour poursuivre dans la même lignée que deux billets que j'ai publié cette semaine (Origine du Babel Fish et Quand j'étais petit, j'étais con), j'aimerais présenter le cas comique de ma mère qui déforme constamment les mots. Tellement que c'est devenu un "running gag" dans ma famille depuis un bout de temps. On a même commencé à les noter, question de lui ressortir un jour lors d'un bien cuit. Disons qu'elle a le lapsus facile.
Voici donc un extrait du dictionnaire de traduction, un outil qui pourra s'avérer utile à l'humanité afin de comprendre adéquatement toute conversation qui pourrait avoir lieu avec elle dans un avenir rapproché.
- En faisant référence à la liqueur alcoolisée aux fraises Fragoli, elle l'a rebaptisé "Froglia" (un mélange avec le journaliste Pierre Foglia ?).
- Lors d'un séjour à Paris, nous avions l'intention de visiter les Catacombes. Elle nous a demandé de lui rapporter un souvenir des "hétacombes" (en fait, c'est très ressemblant avec le mot hécatombe qui aurait été plus proche des catacombes puisqu'il s'agit d'un massacre d'un grand nombre de personnes).
- Adorant faire des sautés de légumes à l'asiatique, elle met de temps à autre du "Boy Choy" plutôt que du Bok Choy (le lien vient peut-être du baby boy choy)...
- Elle n'a jamais voulu essayer les sushis. Sûrement que le truc vert, le "wasaski" (wasabi), ne lui inspire pas confiance.
- Je lui ai prêté le DVD de Slumdog Millionnaire. Quand elle a vu le Taj Mahal, elle s'est exclamée : hey, c'est le "Taj Mahoul" !
- Elle semble avoir quelques difficultés avec les lieux exotiques. Du coup, le Machu Picchu au Pérou est soudainement devenu le très québécois "Mitsou Pichou".
- Je ne te crois pas! Va voir sur Google Maps avec ton "Light Top" ou "Lite Top" est l'autre variante désignée pour parler d'un lap top.
Elle n'est pas la seule à trébucher dans les mots. Une de ses amies lui a confié avoir des problèmes au "nerf asiatique" (nerf sciatique).
Avec tout ça, vous allez croire que ma mère est folle. Rassurez-vous, ce n'est pas le cas. J'espère qu'elle ne m'en tiendra pas rancune. Seulement, peut-être que ça vient avec l'âge ? Malheureusement pour moi, je crois que c'est héréditaire.
Quelques signes
Lorsque j'étais petit, ma mère fumait des cigarettes Rothman's. Elle m'envoyait en mission au dépanneur pour lui acheter un paquet (c'était légalement et socialement accepté dans les années 80). Avec la monnaie, j'avais le droit d'acheter des avions en styrofoam, des friandises ou des autocollants Panini... En posant ma récolte sur le comptoir, je demandais au commis un paquet de Walkman... Quelqu'un, quelque part sur l'île de Montréal, doit se souvenir de ça...
Si on ne vaut pas une risée, on ne vaut pas grand chose...
Un ami, adepte de jeux de rôles, faisait la même chose lorsqu'il jouait à Donjons & Dragons. À chaque semaine, si un joueur ou le maître de jeu faisait un lapsus ou une description douteuse, il répertoriait tous les termes cocasses entendus. Je crois qu'il en a un cahier plein aujourd'hui. Comme la fois où les personnages se trouvaient dans une pièce carrée mais ronde avec une forme de cylindre inversé...
Suite à la suggestion de Matt O'Phinney, j'ai fait des tests de benchmark avec XDebug sur le composant Zend_ACL (Access Control List) qui permet de gérer des droits d'accès sous forme de rôles, ressources et privilèges. J'avais promis de publier les résultats alors les voici.
Pour réaliser mes tests, j'ai réutilisé un vieil exemple que j'avais publié en novembre 2008 alors que j'expliqueais le fonctionnement de Zend_ACL. Ce test n'a pas été mesuré sur un serveur mais sur mon vieux PC laboratoire Windows XP Home Edition SP3 avec processeur AMD Athlon 64 X2 Dual Core 4200+ avec 3 Gb de RAM (en d'autres mots, il date d'environ 4 ans).
Vous remarquerez dans l'exemple que je déclare :
- 1 instance de Zend_ACL
- 3 rôles sous forme d'objects Zend_Acl_Role (Programmeurs, Designers et Administrateurs Systèmes)
- 7 ressources distinctes avec Zend_Acl_Resource
- Plusieurs types de privilèges par ressource sont initialisés avec la méthode allow() (j'ai fait exprès de ne pas réutiliser les exemples classiques de CRUD et je me suis rendu compte en me relisant que j'avais réussi à placer une bonne joke dans le code. Même si vous n'êtes pas programmeur, vous serez en mesure de la trouver)
Selon la configuration exacte présentée dans l'exemple, si j'isole uniquement les composants ACL, le temps d'exécution final avec une seule vérification est de 0,0021 seconde. En effet, très rapide.
Comme l'initialisation se fait une fois pour la page, c'est le nombre de requêtes à isAllowed() qui fera varier le temps. Si je l'appelle en boucle :
Itérations SecondesÀ 1000 vérifications, on parle d'un peu moins que 1/3 de seconde. C'est assez rapide même si ça commence à paraître un peu plus à mesure qu'on augmente le volume (tout à fait normal). Mais soyons honnête : dans la plupart des cas d'applications web, 10 vérifications ou moins seront nécessaires. Dans le pire des cas, moins de 100 par page. À moins d'une utilisation abusive du composant, le coût de temps versus le gain de performance ne justifie pas le temps qui serait nécessaire pour tenter de faire mieux.
1 0,0021
10 0,0048
100 0,0324
1000 0,2965
Rarement j'ai vu une implémentation des droits aussi facile à lire et à maintenir. ACL offre une granularité qui permet de changer complètement les droits, les rôles et les ressources pour faire une toute nouvelle combinaison. Les possibilités sont quasi infinies. J'insiste sur le fait qu'on peut indiquer textuellement par un verbe toute forme d'action possible sur une ressource et pas seulement le droit de Read, Insert, Update, Delete.
La plupart du temps, les autres systèmes de gestion de droits se contentent de gérer la relation entre un module et son droit d'accès binaire (accès à tout ou rien). Rien n'est clairement défini au niveau du rôle (niveau d'utilisateur), l'héritage de droits et les privilèges. C'est clair que si vous développez un système qui offre moins de possibilités, vous gagnerez légèrement en performance (c'est fort probable que le gain en PHP se transformera en perte à un autre niveau, comme la base de données par exemple). C'est quand même un beau défi à relever. Mais avant de commencer, posez-vous les questions suivantes :
- Est-ce que ma solution sera aussi flexible ?
- Sera-t-elle aussi performante ?
- Est-ce que je ferai mieux en terme d'implémentation et de lisibilité ?
- Combien de temps cela me prendra pour satisfaire mon ego ?
Avant le souper, je suis allé faire un tour sur Twitter pour voir ce qui se passait. J'ai vu que Jean-François Gagné Bérubé (@FailQC) a écrit un tweet assez comique :
Quand j'étais enfant je pensais qu'on disait "Perdre ses os" et non ses eaux. J'trouvais ça weird perdre ses os!
Sur le coup, j'ai vraiment ri. J'aurais voulu lui répondre sur Twitter mais 140 caractères n'étaient pas suffisants. Après, je me suis rappelé que quand j'étais petit, j'ai longtemps pensé que Jean Coutu était un ami de mon père ("je m'en vais chez Jean Coutu") et je confondais Fabricville avec le quartier Fabreville de la ville de Laval. Bon, chacun son truc.
Oui, j'étais con quand j'étais petit. Heureusement, ça s'est un peu amélioré avec le temps :-)
J'espère ici que vous avec bien lu "l'âne" de Sam Loyd dans le titre et non pas "l'ame"! C'est que je viens de tomber sur un vieux catalogue numérisé comptant 5000 casse-têtes inventés et/ou répertoriés par M.Loyd de son vivant, il y a plus de 100 ans (1841-1911).
J'avais tenté de résoudre quelques puzzles qui étaient présentés dans le livre The Geeks' Guide to World Domination: Be Afraid, Beautiful People et je cherchais à en savoir plus sur ces trucs, question de mettre mon esprit à l'épreuve.
C'est là que j'ai aperçu ce problème classique de l'âne que je me rappelle avoir vu dans un coffret de tours de magie lorsque j'étais enfant. À cet âge, j'ignorais que Loyd en était l'inventeur et le voir tantôt m'a rappelé ce souvenir depuis longtemps oublié. Si ma mémoire est bonne, le kit s'appelait Hocus Pocus et j'en ai retrouvé un exemplaire sur eBay qui date de 1983 (mise de départ à 9,99$). Au même titre que les blocs Lego, la magie est quelque chose de stimulant pour l'imaginaire d'un enfant (quoi que ça n'a plus rien à voir les tours que fait Luc Langevin).
Dans cette boîte se trouvait un des casse-têtes de Sam Loyd reproduit sur trois cartons séparés représentant deux ânes et deux cavaliers en selle. J'ai trouvé une image couleur de ce puzzle. Imprimez-la, découpez les 3 parties et essayez de le résoudre en les plaçant de façon à ce que les cavaliers soient assis correctement sur le dos de l'animal.
Maintenant, creusez-vous la tête un peu. La solution est ridiculement simple. Si vous n'êtes pas capable de la résoudre, écrivez-moi, je vous donnerai la réponse. Comme dirait le groupe We Are Wolves : si c'est magique, c'est que c'est sûrement des magiciens!
Je suis certain que vous adorerez cette vidéo qui met en scène le premier jeu de Mario sur la console NES. L'effet sur le muret et le sol est impressionnant.
Source: Techi.com
On parle souvent du livre The Hitchhiker's Guide to Galaxy de Douglas Adams pour sa fameuse réponse à la question ultime (42). Mais il y a une autre référence geek qu'on doit lui attribuer que j'ignorais : le poisson de Babel (Babel fish ).
Quand j'ai commencé à le lire, ça m'a immédiatement fait penser au moteur de traduction utilisé par Yahoo! et Altavista (développé par Systran). En fait, ce n'est pas un hasard s'il porte le même nom : c'est sans aucun doute un clin d'oeil à ce classique de la littérature geek que je suis en train de découvrir.
Dans l'édition que je me suis procuré (The trilogy of four, 768 pages, publié chez Picador, acheté usagé au coût de 0,10$ sur Amazon + 6,49$ de frais de livraison), le personnage s'insère dans l'oreille un petit poisson jaune qui a la capacité de traduire n'importe quel type de communication.
On en entend parler pour la première fois à la page 55 du chapitre 6 (premier livre) dans cet extrait :
The Babel fish, said The Hitch Hiker's Guide to the Galaxy quietly, is small, yellow and leech-like, and probably the oddest thing in the Universe. It feeds on brainwave energy received not from its own carrier but from those around it. It absorbs all unconscious mental frequencies from this brainwave energy to nourish itself with. It then excretes into the brain of its carrier a telepathic matrix formed by combining the conscious thought frequencies with nerve signals picked up from the speech centres of the brain which has supplied them. The practical upshot of all this is that if you stick a Babel fish in your ear you can instantly understand anything said to you in any form of language. The speech patterns you actually hear decode the brainwave matrix which has been fed into your mind by your Babel fish.
En plus, le livre dans lequel il consulte la définition est une sorte de livre électronique qui pourrait s'apparenter à ce qu'on connait aujourd'hui (comme le Kindle) :
"Le Guide du voyageur galactique". C'est une sorte de livre électronique. Il vous dit tout ce que vous devez savoir sur quoi que ce soit. C'est son travail. [...] Tu appuies ce bouton et l'écran s'allume et te montre l'index. L'écran, environ 3 pouces par 4 pouces, s'éclaire et les caractères commencent à scintiller à la surface...
Il possède aussi une fonctionnalité du type "text-to-speech". J'avoue qu'à l'époque où le scénario a été rédigé (1978 pour la radio, 1979 pour la version imprimée), c'était assez avant-gardiste.
Si on te met un coup de pied au cul, serres les fesses et tu auras gagné une chaussure !
Pour un projet personnel, je suis en train de développer un prototype d'application qui permettra d'indexer le contenu texte d'une large collection de documentation enregistrée au format PDF. À l'aide d'une interface, on pourra lancer une recherche et chaque résultat de la liste pointera à la page exacte où le terme a été trouvé.
Pour ce faire, je dois être en mesure de savoir comment ouvrir un PDF à la bonne page, à partir d'une commande avec le shell.
Sous Windows, Adobe Acrobat Reader permet de définir des arguments de lancement lors de l'ouverture d'un PDF par le shell. Par exemple, l'exécutable AcroRd32.exe suivi de /A permettra de fournir une liste de clé/valeur, dont le numéro de page d'un document spécifique.
C:\Program Files\Adobe\Reader 9.0\Reader>AcroRd32.exe /A page=10 "c:\document.pdf"
Ce que je suis en train de développer pourrait aussi être portable sous Linux puisqu'Adobe développe aussi une version pour ce système d'exploitation. Cependant, le produit propriétaire n'est généralement pas la solution retenue par les distributions Linux et n'est pas le lecteur par défaut installé sur Ubuntu. En cas de besoin, on peut forcer l'installation en modifiant les sources acceptées du repository et en lançant la commande : sudo apt-get install acroread.
Sous Ubuntu (environnement Gnome), c'est le programme Evince (document viewer) qui se charge d'ouvrir les PDF. Par le shell, on pourra ouvrir un PDF à la bonne page avec une commande comme celle-ci :
evince document.pdf -p 10
Dans mes recherches, j'ai découvert qu'on peut ouvrir un PDF en spécifiant la page par l'URL. Si j'opte de faire une interface web, je n'aurai qu'à afficher les résultats en faisant suivre le nom du PDF par le symbole dièse (#), la clé "page" et son numéro. Comme dans l'exemple HTML suivant :
<a href="/static/document.pdf#page=10">Page 10</a>La beauté ici, c'est que ça fonctionne aussi bien si la visionneuse est Evince ou Acrobat Reader.
Pour la suite et la liste complète des paramètres pris en charge au moment de l'ouverture par Acrobat, je mets à votre disposition le lien exact vers la documentation Parameters for Opening PDF Files (remarquez l'URL).
Avez-vous remarqué que le fureteur IE ne se nomme pas du nom du fabricant ? On ne lit pas Microsoft Internet Explorer 8 mais bien Windows Internet Explorer 8 ? C'est subtil comme stratégie marketing de faire croire que c'est un composant vital au système d'exploitation plutôt que de laisser le choix à l'utilisateur de le remplacer par une application concurrente. Oui on peut utiliser un logiciel alternatif mais il ne semble pas possible de le remplacer proprement. Les deux fureteurs coexistent sur la machine pendant que IE attend patiemment l'heure glorieuse de sa résurrection.
Chez moi, si je suis sur Windows XP Home Edition (quand je ne suis pas sur Ubuntu), je n'ai même pas l'option de le retirer dans Add or Remove Programs (le bouton à droite est carrément absent).
Au travail, si j'essaie de le désinstaller, il ne m'assure plus que les autres programmes fonctionneront bien (DLL partagés ?). Un vrai boulet au pied du prisonnier. Tout pour qu'on soit pris avec ce fureteur de malheur qui, même si on lui en préfère un autre, refait surface une fois de temps en temps avec un popup de sollicitation désespéré et demande si on est certain de ne pas le préférer comme fureteur par défaut.
Désolé buddy, tu as eu ta chance. Être méchant, je dirais que tu serais le dernier joueur que je voudrais avoir dans mon équipe. Avec IE 9, tu seras en liberté conditionnelle pour une mise à l'essai. Peut-être que tu regagneras un peu de mon respect si tu te conduis bien. Autrement, qui sait si, comme un chat, tu t'éteindras après ta 9ème vie ?
Dans la catégorie découvertes, un autre artiste dont le talent mérite plus de visibilité est le guitariste montréalais Erik Mongrain. J'appréciais déjà la musique d'Andy McKee, les premiers albums instrumentals de Kaki King, Rodrigo y Gabriela, toutes les sonorités particulières et la rythmique pouvant sortir d'une guitare sèche.
Sur cette vidéo (malheureusement pas de la meilleure qualité mais qui reflète bien l'énergie de la performance live), remarquez la dextérité de ses doigts et les sons qu'il réussit à faire ressortir avec sa technique.
AirTap d'Erik Mongrain, à l'émission Belle et Bum.
Ne manquez pas ses autres vidéos sur son canal YouTube. Si le coeur vous en dit, vous pouvez essayer de l'imiter en téléchargeant des tablatures de ses pièces sur Ultimate-Guitar.com.
Si vous voulez relever un autre défi, achetez le CD éponyme de Rodrigo y Gabriela. Si vous obtenez une copie comme la mienne, le digipak contient un DVD qui présente un tutoriel sur la façon de jouer avec ses doigts et en tappant sur la caisse de résonance de la guitare. J'en suis encore au stade de débutant tellement la vitesse rend l'exécution compliquée.
Et si vous êtes vraiment mauvais à la guitare, vous pouvez toujours rabattre vos doigts sur Guitar Hero ou le jeu pour iPhone / iPod touch Tap Tap Revolution / Tap Tap Revenge.
Bon, quoi faire comme introduction à ce billet ? Quand on ne sait pas quoi dire, il faut parler de la pluie et du beau temps. Vous avez remarqué la canicule qui sévit au Québec ces derniers jours ? Jamais on a sué à si grosses gouttes.
Parlant de sensations fortes, j'ai eu l'immense joie de convertir un site web ASP 3.0 vers PHP (avouez que vous ne l'aviez pas vu venir). J'avoue que ce n'est pas ce qui est le plus trippant mais ça fait un projet de plus utilisant un langage douteux d'éliminé sur la planète (comme dans l'origine des espèces de Darwin, seuls les plus forts survivent). Je vais renchérir avec mon côté écolo en disant qu'il faut combattre la pollution, même dans le monde numérique. Enfin, le méchant est sorti.
Cela dit, j'ai pris quelques précautions dans le fichier .htaccess pour conserver le plus possible l'indexation dans les moteurs de recherche et rediriger les anciennes pages vers les nouvelles (il ne faudrait pas que le client perde son Page Rank de 1...).
D'abord, la page principale d'un projet ASP roulant sur IIS est généralement default.asp. En PHP, son équivalent est index.php. J'ai fait une redirection 301 (permanente) vers la racine en conservant les paramètres GET de la query string :
RewriteRule ^(.*)default\.asp$ /index.php [R=301,L,QSA]
Ensuite, il suffit de faire correspondre chaque page se terminant par l'extension .asp vers la page du même nom en .php :
RewriteRule ^(.*)\.asp$ /$1.php [R=301,L,QSA]
Voilà pour la partie de plaisir. À partir de maintenant, si vous me cherchez, je serai dans un centre d'achat près de chez vous à profiter du système d'air climatisé. Encore mieux, si vous avez de la place dans votre piscine, n'hésitez pas à me passer un coup de fil.
Si un collègue de travail commence à inventer un terme inspiré de votre nom, c'est peut-être que vous avez mauvaise réputation. Ou une mauvaise odeur.
Je jetais un oeil à l'édition 25ème anniversaire du livre Hackers de Steven Levy et une des anecdotes racontées fait référence au programmeur Richard Greenblatt.
Reconnu comme le hacker des hackers, il se serait faire expulser du dortoir du YMCA de Cambridge parce qu'il ne gardait pas sa chambre propre. Si on se fie aux rumeurs (et à la légende), la propreté n'était apparemment pas sa plus grande priorité.
Certains hackers se souviennent qu'il ne se lavait pas souvent et qu'ils en ressentaient une forte odeur. La plaisanterie s'est même répandue jusqu'au laboratoire d'intelligence artificielle où une nouvelle mesure scientifique olfactive se faisait appeler le milliblatt. Un ou deux milliblatts était extrêmement puissant et un Blatt complet était totalement inconcevable.
Pour contrer le milliblatts, l'histoire raconte que des hackers l'auraient amené de force au building 20 pour le placer dans la douche d'urgence destinée aux explosions chimiques accidentelles.
Greenblatts a toujours insisté pour dire que son hygiène n'était pas pire que celle des autres.
Dommage qu'on se souvienne de lui pour la mauvaise raison.
Vous vous plaignez d'avoir des fins de mois difficiles ? Chaque fois que vous recevez votre compte de carte de crédit, vous payez le montant minimum plutôt que de régler la somme en totalité ? Vous avez consolidé vos dettes dans le but de payer moins d'intérêts ? Votre style de vie fait que l'argent vous brûle entre les doigts ? Vous ne possédez pas un arbre qui fait pousser de l'argent ?
Eh bien j'ai des p'tites nouvelles pour vous, il n'y a pas de recette miracle pour vous en sortir. À vrai dire, vous avez deux choix : hausser vos revenus ou diminuer vos dépenses. Le problème lorsqu'on réussit à avoir une entrée d'argent supplémentaire, c'est qu'on risque de vouloir s'offrir du luxe plutôt que de rembourser partiellement une dette. L'autre option est de se serrer la ceinture quelques temps ou de changer ses habitudes à long terme. Ce n'est pas une question d'être gratteux mais plutôt une remise en question de nos habitudes au quotidien. Est-ce vraiment nécessaire ? En tout cas, je me pose la question chaque fois que j'entends des gens se plaindre qu'ils sont serrés financièrement. Il est peut-être temps d'éliminer le superflu...
Voici quelques options à considérer si vous cherchez à faire des économies.
Cas # 1 : la voiture
Vous êtes un petit couple jeune et fringant et vous avez la coquetterie de posséder chacun une voiture. Si on considère le prix d'achat, du gaz, des assurances, de la maintenance et des réparations, voici combien coûte concrètement l'achat d'une seconde voiture (pour une minoune, vous débourserez un peu moins).
Mensualité
Prêt : 300$ (une voiture de base d'environ 20000$, taxes incluses)
Assurances : 75$
Gaz : 100$
Maintenance : 100$
Total : 575$ par mois
Si vous payez votre voiture sur un terme de 5 ans, vous direz adieu à 34500$.
En revanche, le coût d'une passe CAM mensuelle pour le transport en commun à Montréal est de 70$. Si l'un de vous se sacrifiait à utiliser le transport en commun, vous payeriez seulement 4200$ sur 5 ans. On peut donc conclure que vous feriez des économies de 30000$. Définitivement, optez pour un moyen alternatif : covoiturage, Communauto, transport en commun, vélo, marche, etc.
Cas # 2 : le téléphone cellulaire
Qui n'a pas de téléphone cellulaire en 2010 ? Moi. Oui, c'est pratique, mais traîner 50 cennes dans le fond de ses poches pour faire un appel dans une cabine publique en cas de besoin, c'est aussi valable. C'est juste une question de mieux s'organiser. De plus, j'apprécie le fait de ne pas toujours être rejoignable. Ça me procure une tranquillité d'esprit et beaucoup moins de stress.
La plupart des couples possèdent un téléphone chacun. À un coût mensuel moyen de 30$ par appareil, c'est 3600$ qu'on peut mettre de côté pour une période de temps équivalente.
Cas # 3 : cigarettes
Déjà que c'est une mauvaise habitude pour la santé, le coût du paquet a grimpé en flèche ces dernières années. Actuellement 9$ le paquet qu'on m'a dit. Pour ceux qui en fument un par jour, c'est environ 16000$ qui se sont envolées en fumée lors des 5 dernières années. Et ce n'est rien si vous êtes un habitué de substances illicites.
Si vous êtes un fumeur de longue date, aller vous mordre les doigts sur le calculateur du site de Nicorette pour savoir combien vous auriez pu sauver depuis que vous êtes fumeur.
Cas # 4 : café et déjeuner
Votre routine du matin inclut un détour par le premier Starbucks ou Tim Hortons sur votre chemin ? À raison de 5$ par jour (ouvrable), c'est environ 6500$ que vous flambrez sur 5 ans pour consommer des breuvages caféinés et des trous-de-beignes graisseux. Et vous vous enrichissez de calories.
Cas # 5 : cinéma et DVD
Si vous êtes cinéphiles, vous allez probablement au cinéma sur une base régulière. Lorsque les films sortent au club vidéo, vous les louez peut-être et si vous les avez vraiment aimé, vous les achetez et ils accumulent la poussière sur vos tablettes (juste pour avoir le sentiment de les posséder). Soyons franc, les chances sont minces pour que vous les revisionnez tous à nouveau. C'est le genre de produit qui dévalue rapidement et qui n'est certainement pas un investissement (voyez le renaissance constante sous forme de VHS, DVD, Blu-Ray et le 3D...).
En partant de cette hypothèse, si votre couple se rend au cinéma chaque semaine, vous payerez 10$ le billet d'entrée (20$), 6$ pour le popcorn et 4$ pour la liqueur géante (à partager tellement le format est inhumain). Donc une sortie de 30$ par semaine équivaut à 7800$ pour une tranche de 5 ans. Si vous achetez le film, dépendamment du moment où vous vous le procurez, vous payerez 15 à 20$ à sa sortie ou 5 à 10$ en pré-visionné chez Blockbuster lors d'une vente de débarras. Alors qu'une simple location se détaille 4$ en moyenne (1 film par semaine pendant 5 ans revient à 1000$).
Conclusion
Juste pour vous faire réaliser à quel point on dépense pour rien dans notre société nord-américaine, la combinaison de ces 5 facteurs échelonnés sur une durée de 5 ans représente...
Roulement de tambour...
des économies totales de près de 60000$ !
Allons, célébrons la société de consommation.
Pour effectuer le test de performance comparatif entre le composant provenant du Zend Framework et l'alternative programmée maison dont je parlais hier, Matt O'Phinney n'avait pas de benchmark sous la main mais me suggérait d'utiliser XDebug pour mesurer le temps d'exécution.
Selon lui, je ne devrais pas avoir de mauvaise surprise dans la plupart des cas d'utilisation normale avec le composant ZF car la mécanique interne utilise un "di-cyclic graph" (graphique dicyclique ? Ça dépasse mes connaissances mathématiques, je devrai me le faire expliquer)...
En effet, j'ai réalisé le premier test de 1000 appels mesuré à 0,29 secondes d'exécution. Pour obtenir le résultat, j'ai dû installer l'extension XDebug sur mon environnement de tests à la maison (EasyPHP 3.0, Windows).
Sur Windows, c'est un jeu d'enfant :
- Déterminez la version de PHP utilisée (5.2 dans mon cas)
- Téléchargez le bon DLL (j'ai pris php_xdebug-2.1.0-5.2-vc6.dll) et déposez le dans le répertoire d'extensions de PHP. Par défaut : C:\Program Files\EasyPHP 3.0\php\ext
- Vous pouvez optionnellement faire analyser le contenu de phpinfo() avec ce parser. Il vous indiquera la procédure à suivre et vous pourrez analyser le tout à nouveau pour voir si c'est installé correctement
- Dans php.ini, ajoutez la ligne suivante :
zend_extension_ts = "C:\PROGRA~1\EASYPH~1.0\\php\ext\php_xdebug-2.1.0-5.2-vc6.dll" - Il faut s'assurer que l'extension est chargée avec le Zend Engine (zend_extension_ts = valeur) et pas sous la forme "extension = valeur". Contrairement à ce que le parser me proposait comme configuration, j'ai ajouté les guillemets pour entourer le chemin du DLL.
- Rédémarrer le serveur Apache
Dans cet exemple de code PHP qui lance un warning de division par zéro ($var = 1/0;), une erreur qui est affichée normalement à l'écran (display_errors de php.ini) :
Warning: Division by zero in D:\Programmation\Web\Projets\tests\xdebug.php on line 2
Sera plutôt affichée avec de l'information bonifiée avec XDebug :
Pour calculer le temps d'exécution dans le script principal qui utilise ZF, j'ai pris la méthode simple qui consiste à obtenir un timestamp au début du script et de le soustraire à un autre qui se trouve à la fin.
$start = xdebug_time_index();En fait, ça me donne exactement le même temps que si j'avais utilisé cette technique pour mesurer le temps d'exécution d'un script mais XDebug offre des fonctionnalités avancées qui permettent de suivre la trace complète, le profilage, la performance, les paramètres des fonctions, etc, et montrer concrètement à quel endroit se trouve le "bottleneck" lorsqu'il y a une perte de performance importante à une des étapes. XDebug est à privilégier pour parfaire vos techniques de débogage.
/* le script à mesurer ici */
$end = xdebug_time_index();
echo $end - $start;
Les fonctionnaires, c'est comme les livres d'une bibliothèque : ce sont les plus haut placés qui servent le moins.
On dit que la nuit porte conseil alors j'ai dormi sur mes deux oreilles et je suis prêt à faire suite à ma réflexion amorcée hier quant à réinventer la roue en programmation.
Tout a commencé quand un programmeur récemment embauché s'est mis à remettre en question les façons de faire adoptées par l'entreprise. Pas qu'il manque d'expérience : il a tout simplement une expérience différente. C'est correct car ça apporte un point de vue nouveau qui peut nous éclairer face à certaines décisions. Comme n'importe quoi, on en prend et on en laisse. Or, pour rester objectif, je n'aime pas quand ça fonctionne sur des ouï-dire ou quand ça tourne à la loi de celui qui parle le plus fort. C'est important d'appuyer nos arguments avec des faits concrets, d'être en mesure de les justifier.
Je l'avoue, j'ai reçu des coups bas (cheap shots) de sa part et je n'ai pas été mieux car j'ai répondu à ses attaques. Je suis un type de personne assez "low-profile", généralement assez discret mais quand j'entends dire une niaiserie, je suis toujours prêt à défendre mon point et d'assumer mes opinions et prouver ce que j'avance.
Un des points qui m'a dérangé est une accusation visant la qualité de Zend Framework (ZF). Selon lui, parce qu'il a trouvé une limitation d'un composant et un bogue dans un autre, c'est suffisant pour conclure que c'est de la merde dans son ensemble. À ses yeux, mieux vaut développer nos propres composants, ça serait plus fiable. De plus, il prétendait que le framework était trop lourd, que la performance était atroce et qu'il fallait bannir ZF de nos projets à tout prix.
Hum, ça sonne mal à mes oreilles. Malgré toute ma bonne volonté, je n'ai pas la prétention d'être meilleur que les développeurs de Zend. Vous savez Zend, les mêmes qui développent le Zend Engine, le moteur de PHP ? C'est un peu comme si on accusait Sun de bâcler le travail effectué dans le développement de Java. C'est facile de chialer sur le travail accompli par les autres. Et avouez que ça donne le goût de lancer un défi aux détracteurs pour voir s'ils feraient mieux! À tord, notre ego de programmeur est souvent trop confiant de pouvoir surpasser les éléments en place pour apporter une amélioration réellement significative. Parfois on réussit, mais à quel prix ?
D'un côté, c'est vrai qu'en utilisant ZF, on est dépendant du développement externe pour les "bug fixes". Au rythme où les mises à jour sortent (1 fois par mois je crois), les chances sont bonnes pour que le bogue risque d'être corrigé rapidement si on leur rapporte.
Du point de vue de la performance, il n'a pas été en mesure de quantifier l'amélioration qu'a apporté le développement interne effectué pour remplacer le composant de Zend qui avait largement fait ses preuves. À l'écouter parler, le gain était tel que c'était le jour et la nuit. J'étais sceptique face à ce qu'il avançait car jamais je n'ai remarqué de lenteur en utilisant ce composant en trois années d'utilisation. Quand je lui ai demandé de préciser, il s'est contenté de répondre que c'était trop technique pour en parler devant les patrons et qu'on en discuterait à un moment plus opportun.
En vérité, on ne l'utilise pas sous forme de framework MVC proprement dit justement pour ne pas qu'il soit trop limitatif (nous avons développé une grosse base de code réutilisable au fil des ans). Le terme "framework" n'est pas tout à fait exact dans le cas de ZF (contrairement à Symphony, CakePHP, etc) car il s'agit plutôt d'une librairie de composants indépendants (on choisit ceux qu'on a besoin) qualifié de "lightweight, loosely-coupled component library".
Mais lentement, on se rend compte des avantages liés à l'utilisation d'une architecture MVC et on s'en va dans cette direction. Utiliserons-nous les composants ZF pour arriver à nos fins ? Eh bien non. Il semblerait qu'on soit en train de développer une autre solution maison.
Développeriez-vous une équivalent "home-made" pour remplacer jQuery ou faire votre propre éditeur RTE plutôt que de préférer TinyMCE ? Si la librairie ZF offre une classe qui permet de faire le travail, par exemple Zend_Service_Twitter, est-ce que ce n'est pas un choix logique que de le mettre à l'essai en premier avant de réinventer la roue ? Est-ce que la loi du 80/20 (Pareto) serait de mise ?
Il y a aussi un autre avantage de taille à utiliser des composants connus et supportés par la communauté : lorsque des nouveaux programmeurs sont engagés, ils peuvent apprendre rapidement les composants qui sont largement documentés et testés par des milliers de développeurs, plutôt que de tenter de patauger dans du code maison que seuls ceux qui travaillent (encore) entre les 4 murs de l'entreprises peuvent supporter.
C'est une attitude qui me déplait chez certains programmeurs. Au lieu de se concentrer sur "getting the job done", ils ont la prétention de pouvoir révolutionner le monde avec des solutions obscures. En même temps, créer un système maison les rend indispensables à l'entreprise puisque la vision et la documentation se trouvent dans leurs têtes. S'ils quittent, quelles ressources pourront reprendre le flambeau ? On est loin des standards que l'autre parlait.
En tant que programmeur, qu'est-ce qui fait qu'on a une fâcheuse tendance à vouloir remplacer une solution qui marche bien par une autre ? Est-ce par recherche du défi ? Avoir le mérite d'avoir codé toutes les lignes du projet ? L'atteinte de la perfection ? Le monde qui nous entoure n'est pas parfait alors réinventons en un numérique qui le sera ? Est-ce une façon de jouer à Dieu et d'avoir le contrôle total sur notre création ? (bien entendu, j'exagère, mais c'est pas faux)
Cela dit, je ne remets pas en question la compétence de ces individus, seulement les décisions liées au développement durable dans une entreprise. Dans notre cas, je sens qu'on est à la croisée des chemins et que j'ai mon mot à dire sur ce qui touchera mon travail dans les années à venir.
Revenons-en à la performance du composant de ZF. Rappelons-nous que l'argument qui était au coeur de la discussion était que ce composant précis était peu performant. Pour m'en assurer, je suis allé chercher conseil auprès de Matthew Weier O'Phinney, le "project lead" du ZF. Tant qu'à aller à la source, autant choisir quelqu'un qui ne parlera pas à travers son chapeau. Je lui ai expliqué la problématique et voici un extrait de sa réponse :
I haven't done any benchmarking of the component, but knowing its design, I suspect it will not suffer. It uses a di-cyclic graph in order to perform permission lookups, which tends to be very fast, and comparable to tree traversal when it comes to zeroing in on an individual permission.
Of course, it will take some amount of time -- just like calling any operation in PHP. If you're doing 100s or 1000s of lookups in a single request, it may be possible that you'll see a slowdown -- but then, that will be true for any operation you perform that many times in your request.
If you're uncertain, use XDebug or Zend Debugger to do some targetted profiling of your application to see how much time is being spent.
Merci Matt, je vais suivre ton conseil, juste pour avoir des chiffres à l'appui. Qui sait si ce n'est pas moi qui a tord ? Je laisse le bénéfice du doute tant que je n'ai pas de preuve. J'ai installé XDebug et j'ai effectué un test de performance où 1000 appels ont été faits sur le composant ZF. Le résultat est étonnant : 0,29 seconde. Je ferai des tests de performance comparatifs la semaine prochaine en soumettant la classe maison dans le collimateur et voir si ça valait le coût de remplacer ce composant. À date, avec ce que j'ai vu, ce sera difficile à battre...
Stay tuned!
Quand on a des patrons qui manquent de connaissances techniques, il y a un risque pour que les programmeurs leur racontent un peu n'importe quoi. Qui pourra prouver le contraire ? C'est un peu la situation que j'ai vécu cette semaine et qui m'a causé un brin de frustration et la réflexion qui s'en suit.
Je vote pour ça
Lors des réunions, des décisions sont à prendre, les idées sont lancées et débattues et c'est la nature humaine de tirer sur son bord de couverture pour faire adopter sa proposition, même si ce n'est pas la meilleure. Il y a une réelle auto-satisfaction pour l'ego de savoir que sa proposition est retenue. Les gens sont généralement prêts à suivre les gens qui ont l'air sûrs d'eux. Et c'est ainsi que les efforts collectifs sont mis dans une direction qui n'est pas nécessairement bénéfique pour l'entreprise. Dans le monde idéal, il faut demeurer objectif et savoir apporter des arguments qui prouvent ce qu'on avance.
Dans la salle de conférence
Durant une de ces réunions, ce que j'ai entendu sortant de la bouche d'un programmeur aussi expérimenté que moi m'a fait faire le saut. Il proposait d'instaurer une standardisation dans notre façon de programmer alors qu'il a lui-même refusé de suivre les standards de l'entreprise dès son arrivée. Il a ensuite convaincu un autre employé qu'il valait mieux tout balancer par-dessus bord et recommencer à leur façon sans en parler aux supérieurs. Pour moi, c'est une source de problème sur l'efficacité qui instaure un rapport de cause à effet direct sur le bon fonctionnement de l'entreprise et sa rentabilité (les chiffres parlent : les projets qui leur sont assignés dépassent régulièrement les temps estimés, donc les coûts de production et les profits générés). Il y a plusieurs causes mais le temps passé dans l'ombre à réinventer la roue n'est pas étranger à ce phénomène.
Le problème est un peu ça : au lieu de pousser collectivement dans la même direction, de se concerter et de faire le mieux dans l'intérêt de tous, des clans se forment selon les écoles de pensées. D'un côté ceux en faveur d'une solution, de l'autre, ceux qui se rangent derrière l'alternative. Chacun va chercher l'approbation de ses pairs avec qui il s'entend bien et ça devient politique (et on sait que quand c'est politique, c'est contre l'évolution, ça fait du sur place). Ce qui fait que les standards changent selon qui réalise le projet, et ce même si l'entreprise est claire face aux technologies à favoriser. De toute façon, personne n'ira vérifier si c'est conforme et une fois le fait accompli, c'est souvent difficile de reculer.
Ce que dicte l'entreprise devrait avoir préséance sur tout le reste. Les patrons, qui signent notre chèque de paye, ont tranché. À moins d'une justification assez forte pour remettre en question la technologie en place, on devrait respecter le choix des investisseurs. En revanche, ce sont nous les spécialistes qui peuvent suggérer des pistes technologiques mieux adaptées à nos besoins. Les patrons sont ouverts à écouter les arguments mais manquent parfois de connaissances techniques pour faire un choix éclairé. Ils s'en remettent donc à nos bons conseils. Et alors apparaîssent les abus de confiance.
Gare aux sophistes!
Ceci ouvre la voie à celui qui parle le plus fort, qui se montrera le plus persuasif. Je racontais la situation à un ami et il qualifiait cette attitude de sophiste (vous vous souvenez, les cours de philosophie au Cegep ?). C'est un peu vrai. Certains sont passés maître du discours en utilisant une série de buzzwords pour se montrer convainquants en présence de la direction. Voyez ce qu'en dit Wikipedia :
Les sophistes développent des raisonnements dont le but est uniquement l'efficacité persuasive, et non la vérité. Des raisonnements ou des arguments apparemment solides mais contenant en réalité un vice ou une perversion volontaire visant à manipuler ou à tromper l'auditeur .
Dès que je reconnais ce profil chez quelqu'un, je me méfie immédiatement, qu'il soit vendeur d'auto ou programmeur. Je me refuse de jouer le même jeu mais je sens au fond de moi que je dois réagir, faire quelque chose.
Programmation sans ego
Il est vrai que certains développeurs voient un idéal d'être indépendant face à des outils populaires qui ont fait leur preuves. Ils veulent à tout prix essayer quelque chose de nouveau même si l'ancienne méthode fonctionne bien. Ils ressentent un besoin d'enrichir leurs connaissances personnelles plutôt que de répondre au besoin immédiat du client. C'est bien de vouloir se perfectionner, mais il faut aussi choisir le bon moment. Adopter une attitude saine comme "l'egoless programming" est de mise.
Personnellement, je ne suis pas réfractaire au changement, au contraire. Mais l'histoire m'a prouvé que des décisions stupides sont prises ou imposées par des employés de passage et que ce sera la base d'employés stable (core team) qui sera prise avec les problèmes causés par des mauvaises décisions, à éteindre des feux et à rétablir un certain équilibre. Croyez-moi, j'ai déjà donné plus souvent qu'à mon tour.
Habituellement, le roulement d'employés fait qu'ils restent en poste 1 an ou 2 et quittent pour offrir leurs services ailleurs. Moi, ça fait déjà 8 ans que je suis au sein de la même entreprise. D'autres se poussent dès qu'ils sentent la soupe chaude, qu'ils devront faire face à la responsabilité qui viennent avec leurs choix et à se justifier. Combien de fois ai-je eu à réparer les pots cassés d'anciens programmeurs ? Souvent et je ne compte pas le nombre de fois que j'ai sacré...
Pour un patron, qui croire ? Un employé de longue date fidèle à l'entreprise ou le petit nouveau qui, même s'il compte autant d'expérience, prétend autre chose ?
Carriériste ?
Pas tout à fait. Développer une relation de confiance et équitable entre employé-employeur, c'est ce qui est payant à long terme. Un peu comme un mariage, autrement c'est un divorce assuré. Et d'un côté comme de l'autre, il ne faut pas abuser de cette confiance. Pierre Péladeau père disait à ses employés : si tu me fais faire de l'argent, tu vas en faire toi aussi. Ça résume bien mon état d'esprit professionnel. Avec ce mode de pensée, on finit par prendre des décisions éclairées pour l'entreprise plutôt que des décisions basées sur des préférences personnelles. On sait qu'on devra vivre avec notre choix à long terme. Pour moi, c'est aussi ça une attitude professionnelle. J'aime mieux réparer mes gaffes involontaires que réparer les pots cassés causés par des programmeurs insouciants.
Méritocratie
Et pourtant, face à certains choix, je suis découragé. Je me demande si je ne suis pas le seul à pouvoir me projeter à long terme dans une entreprise alors qu'on vit dans une culture d'instantanéité. Notre génération veut tout, tout de suite et on leur doit tout. Des enfants-rois. Merci à mes parents, je n'ai pas été élevé selon ces valeurs. Chez moi, on nous a inculqué le mérite. On met nos efforts à la bonne place pour mériter ce qu'on a. Et ne jamais s'assoir sur ses lauriers (prendre pour acquis). Le mérite est biodégradable et doit être renouvelable.
Passer à autre chose
Remarquez, j'ai peut-être un peu une écoeurantite. Malgré toute ma bonne volonté, j'ai parfois l'impression de nager à contre-courant et de ne pas être en mesure de renverser la situation. Peut-être ai-je besoin d'un nouveau départ ?
À la lumière de ce que me disent quelques personnes de mon entourage, j'ai le profil d'un travailleur autonome. Serais-je prêt à faire le saut en affaires ou dois-je chercher à prendre plus de responsabilités (dans cette entreprise ou une autre) ? Chose certaine, j'ai besoin de défis stimulants.
Peut-être est-il temps de me lever et de combattre de front cette attitude néfaste ? Est-ce que je prends mon rôle trop à coeur ? Est-ce une assez noble cause pour y mettre des efforts ou est-ce que je gaspillerais mon temps ? Suis-je assez mûr passer à un niveau supérieur ? Définitivement, un changement s'impose.
La suite demain... Sur la performance de Zend Framework.