La 6ème édition du logiciel Google Earth est sortie hier. Parmi les nouveautés, la multinationale de Mountain View a ajouté une option impressionnante qui permet de visualiser les arbres en 3D selon un procédé de détection automatique par satellite (évidemment, c'est une simulation). 80 millions d'arbres virtuels auraient été plantés, représentant environ 40 espèces différentes (voir cet article intéressant à ce sujet).
Ici, une vue de la ville de New York à partir de Central Park.
Jusqu'à maintenant, seules quelques villes américaines et autres endroits spécifiques dans le monde bénéficient de cet nouvelle fonctionnalité (il faut croire que les villes de Montréal et Québec viendront beaucoup, beaucoup plus tard).
Pour activer l'option, rendez-vous dans le panneau Layers et cochez 3D Buildings ainsi que Trees.
Le restaurant qui prépare votre poutine préférée offre la livraison dans un rayon restreint de 3 kilomètres ? Vous voulez illustrer graphiquement la zone sur une carte Google ? Voici comment faire.
Tout d'abord, si c'est votre première expérience avec Google Maps, référez-vous à mon billet qui explique comment intégrer une carte Google à son site (en obtenant une clé d'API gratuite).
Incluez un conteneur HTML pour la carte en indiquant un ID unique qui pourra être utilisé dans la programmation JavaScript :
<div id="map" style="width:800px;height:600px"></div>Ensuite, déclarez la carte, les coordonnées du point central du cercle et indiquez le rayon. À l'aide de votre ami jQuery, appelez la fonction principale au chargement de la page (sinon, faites-le dans l'événement onLoad de la balise body).
Le code JavaScript :
var map;La seule difficulté réside dans le fait qu'on doit utiliser un polygone et calculer avec une formule mathématique chaque point du cercle (1 par degré). Le résultat obtenu est réussi:
var center = new GLatLng(45.563234,-73.65614);
var radius = 3; // km
$(document).ready(loadMap);
function loadMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map"));
map.enableScrollWheelZoom();
map.setCenter(center, 13); // 13 = niveau de zoom
var centerMarker = new GMarker(map.getCenter());
map.addOverlay(centerMarker);
var points = new Array();
// rayon de la Terre = 6378.8 km
var d = radius/6378.8;
// radians
var lat1 = (Math.PI/180)* center.lat();
var lng1 = (Math.PI/180)* center.lng();
var bounds = new GLatLngBounds();
// calculer les 360 points du cercle
for(var i=0 ; i<=360 ; i++ ){
var tc = (Math.PI/180)*i;
var y = Math.asin(Math.sin(lat1)*Math.cos(d)+Math.cos(lat1)*Math.sin(d)*Math.cos(tc));
var dlng = Math.atan2(Math.sin(tc)*Math.sin(d)*Math.cos(lat1),Math.cos(d)-Math.sin(lat1)*Math.sin(y));
var x = ((lng1-dlng+Math.PI) % (2*Math.PI)) - Math.PI ;
var point = new GLatLng(parseFloat(y*(180/Math.PI)),parseFloat(x*(180/Math.PI)));
points.push(point);
bounds.extend(point);
}
if (d < 1.5678565720686044) {
circle = new GPolygon(points, '#ACACAC', 2, 1, '#ACACAC', 0.25);
}
else {
circle = new GPolygon(points, '#ACACAC', 2, 1);
}
map.addOverlay(circle);
map.setZoom(map.getBoundsZoomLevel(bounds));
}
}
Pour en revenir au restaurant que je mentionnais, je ne connais pas vraiment l'étendue de leur zone de livraison. La plupart du temps, je prends mes commandes en take-out. Avec 10% d'escompte au comptoir, essayez la grosse poutine Mistinguette (frites, viande fumée, sauce à la viande, le tout gratiné). Pendant la préparation, allez faire un tour au dépanneur juste à côté et découvrez leur belle sélection de bières de microbrasseries québécoises. Hum... l'heure du lunch approche...
Facebook, c'est comme la prison. Vous y perdez du temps, écrivez sur les murs et vous faites poker par des inconnus.
Dans la catégorie des instruments de musique atypiques, ce gars en a inventé un plutôt original à l'aide de tuyaux en PVC. Il nous offre une performance stupéfiante en interprétant un medley d'extraits connus, de Rondo Alla Turca de Mozart, en passant par Lady Gaga et Ozzy Osbourne, le thème de Mario Bros et The Final Countdown en duo à la fin (et plusieurs autres). Incroyablement original et créatif.
Noël arrive dans exactement un mois. J'ai découvert aujourd'hui LE cadeau par excellence que j'aimerais recevoir en tant que geek assumé : un disque dur en modèle réduit de la DeLorean du film Back To The Future.
Spécifications techniques :
- Disque dur Seagate de 500 GB
- Échelle 1:18
- Réacteur Mr Fusion!
- 250$, payable par PayPal
- Très, très geek (idéal pour faire des jaloux au bureau)
Mais bon, comme je n'ai pas été très sage cette année, je me contenterais d'un kit de modèle à coller ou encore d'un die cast (je sais, je n'ai toujours pas décroché de cette voiture mythique)... Autrement, il y a toujours le modèle de maquette en carton, mais je me vois mal placer mon disque dur dedans.
Demain, nous serons le 25 novembre, à 1 mois du compte à rebours de l'arrivée de la fête de Noël. Pour l'occasion, sur le thème du numéro 25, je vous offre cette petite devinette.
Savez-vous pourquoi les programmeurs ne font pas la différence entre l'Halloween et Noël ? Parce que Oct 31 == Dec 25.
Besoin d'explications ? Vous devez savoir que pour le commun des mortels, l'abréviation "Oct 31" équivaut au 31 octobre alors que "Dec 25" représente la date du 25 décembre. Pour quelqu'un de familier avec la programmation et les mathématiques, la signification est tout autre.
Le programmeur lira Oct 31 en tant que "valeur octale 31" et Dec 25 comme étant la "valeur décimale 25". Alors que le système décimal utilise la base 10, le système octal utilise une base 8.
Base 10 : 2 dizaines (2 x 10) + 5 unités = 25
Base 8 : 3 octets (1 octet = 8 bits, 8 x 3 = 24) + 1 bit = 25
J'ai enfin trouvé un nouveau site inutile pour pouvoir créer mon top 5 des sites les plus inutiles. Je vous les présente donc, pas nécessairement dans l'ordre d'impertinence. Je vous laisserai en juger par vous-même.
Le blogue ultime de la productivité
Pour le meilleur conseil sur la productivité, on vous signale que vous devriez plutôt être en train de travailler.
Devrait-on utiliser des tables pour faire la mise en page HTML ?
Le site shouldiusetablesforlayout.com fournira une réponse claire à quiconque mettrait en doute cette vérité absolue.
Benoit Brunet
Oui, c'est un fait, le commentateur est maladroit dans ses descriptions de matchs de hockey. Un "hater" a pris les choses en main en s'appropriant le nom de domaine benoitbrunet.com pour résumer en quelques mots ce que les fans n'osaient pas dire tout haut.
Je tiens à dire que je ne partage pas nécessairement l'opinion de Habs or Die qui est derrière cette initiative. Comme disait Stéphane Richer : Y a pas juste le hockey dans la vie !
Perdu sur l'Internet ?
Pas de panique, ce site va vous aider à vous y retrouver. Le point concret sur une situation très problématique.
Une mention honorable puisqu'il fût créé en 1996 et obtient un remarquable Page Rank de 5 !
Nom de domaine trop long
Faut vraiment être con pour avoir une adresse internet aussi longue. 58 caractères, excluant le .com. Qui dit mieux ?
Avec tout ça, c'est quand même surprenant que personne n'ait encore acheté le nom de domaine answertolifetheuniverseandeverything.com pour y placer un 42 géant (disponible selon register.com). À qui la chance ?
J'ai visité un vieux blogue à l'abandon et j'y ai trouvé une énigme intéressante que je reprends ici afin que vous tentiez à votre tour de la résoudre.
- Observez l'image ci-dessous et comptez le nombre d'individus
- Attendez qu'elle s'anime et comptez à nouveau
Source : Math à Jakarta
Quel est votre résultat ? 12 ? 13 ? Sauriez-vous expliquer l'astuce ?
Sans vous énerver qu'il disait...
Comment démarrer une vidéo YouTube à un temps spécifique
La documentation de YouTube est claire à ce sujet. On peut utiliser le paramètre start pour indiquer à quelle seconde on souhaite faire démarrer le clip vidéo.
Pour l'intégrer au code HTML, on l'ajoutera comme paramètre GET, par exemple pour se positionner directement à la reprise au ralenti de l'impressionnant but du joueur de hockey Alexander Burmistrov. On indiquera la 38ème seconde comme temps de départ, que le service YouTube nous assure d'être valide avec une précision de +/- 2 secondes. Pour un temps au-delà de 60 secondes, il faudra effectuer le calcul (par exemple, 2 minutes et 5 secondes = 60*2+5 = 125).
<object width="640" height="385">Autrement, on pourra aussi utiliser une ancre pour positionner le début de la lecture au moment voulu en utilisant une notation indiquant l'heure (h), la minute (m) et la seconde (s). Dans le cas d'un long métrage comme The House On Haunted Hill (durée d'une heure et 14 minutes), on pourra référer à un passage précis en indiquant le temps sous cette forme dans le paramètre GET nommé "t" qu'on viendra ajouter à la fin de l'URL. Pour 1 heure, 10 minutes et 5 secondes : t=1h10m5s.
<param name="movie"
value="http://www.youtube.com/v/YxiJRx7F_5I?start=38">
</param>
<embed src="http://www.youtube.com/v/YxiJRx7F_5I?start=38"
type="application/x-shockwave-flash"
width="640"
height="385">
</embed>
</object>
http://www.youtube.com/watch?v=NXPjWk5IZ-g&t=1h10m5s
YouTube Time, un petit outil web est disponible pour vous aider. Contrairement à mon exemple, il ne tient pas compte des heures. Il faut donc les convertir en minutes.
A programmer is a device for turning energy drinks into rants about bad coding.
Vous l'avez probablement vu sur FailQc plus tôt cette semaine. C'est maintenant le temps de vous rappeler que c'est ce matin que vous devez vous rendre chez Bureau en gros pour profiter du spécial "lève-tôt du samedi" pour vous procurer une clé USB Kingston avec un écran de 16 pouces (au lieu de capacité de 16 Go), au prix spécial de 9,99$.
Publié en première page de la circulaire web et papier, il semblerait que cette erreur ait échappé à la personne en charge de la révision. Quelqu'un, quelque part n'a pas fait son boulot correctement.
Si vous êtes employé de Bureau en gros, je serais curieux de savoir combien de clients vous ont fait la remarque et s'il y en a qui ont insisté pour avoir le modèle avec l'écran...
Selon les succursales, les magasins ouvrent à 9h ou 10h le samedi.
Une simple constatation qui plaira sans doute à la gente féminine et qui concerne le chanteur Mike Patton qui nous a donné d'excellents albums avec les formations Faith No more, Mr. Bungle, Fantômas et Tomahawk. Ne trouvez-vous pas qu'il ressemble étrangement à l'acteur Johnny Depp ?
À gauche, Mike Patton, à droite, Johnny Depp.
On dirait même que son sosie suit les mêmes modes au fil du temps.
Il ne faut surtout pas les confondre. L'un fait des films pour Disney, l'autre ne s'adresse surtout pas aux enfants. La preuve, l'excellente prestation de la pièce Urlo Negro (le cri de l'homme noir) de l'album Mondo Cane, sorti plus tôt cette année :
Lo sai che cosa hai fatto ? A me !
Savez-vous ce que vous avez fait ? Pour moi !
Vous trouverez une traduction italien-anglais des paroles de l'album Mondo Cane.
En 1984, Steven Levy (magazine Wired) énonçait les règles d'éthique des hackers dans son livre Hackers: Heroes of the Computer Revolution (chapitre 2, édition 25ème anniversaire).
Veuillez en prendre connaissance si ce n'est pas déjà fait.
- L'accès aux ordinateurs et tout ce qui pourrait vous apprendre quelque chose sur la façon dont le monde fonctionne, devrait être illimité et total. N'hésitez pas à vous retrousser les manches pour surmonter des difficultés
- Toutes les informations doivent être libres
- Méfiez vous de l'autorité. Faites la promotion de la décentralisation
- Les pirates devraient être jugés par leurs piratage, pas par des faux critères tels que les diplômes, l'âge, la race, ou leur position
- Vous pouvez créer de l'art et la beauté sur un ordinateur
- L'informatique peut améliorer votre vie
Voici un piège sur lequel vous risquez de tomber si vous comptez passer un URL comme valeur dans la query string (peu importe le langage de programmation utilisé, ça ne s'applique pas exclusivement au PHP). Considérant un URL comme le suivant :
http://tests.localhost/script.php?active=1&redirect=http://www.google.com/page.php?q=test&limit=10
Vous remarquerez que parmi les paramètres passés dans la query string, il existe plusieurs clés dont "active" et "redirect". On note aussi que la valeur de la clé redirect est elle-même un URL. Donc l'URL complet compte deux "?" en plus des clés supplémentaires "q" et "limit". On pourrait s'attendre à ce que la valeur de la clé redirect soit "http://www.google.com/page.php?q=test&limit=10". Pourtant non.
echo $_GET['redirect']; // http://www.google.com/page.php?q=testAussi, la dernière combinaison de clé/valeur est manquante. Pourquoi ? Simplement parce que c'est une clé additionnelle qui est considérée comme partie intégrante de l'URL principal (pas de la valeur du paramètre redirect) et qui est séparée du reste avec le symbole "&". La paire q=test est complètement ignorée parce qu'elle fait partie de la deuxième combinaison :
?(active=1)&(redirect=http://www.google.com/page.php?q=test)&(limit=10)
echo $_GET['active']; // 1Même la fonction parse_url() n'est pas d'un grand secours pour le décortiquer :
echo $_GET['redirect']; // http://www.google.com/page.php?q=test
echo $_GET['limit']; // 10
$url = 'http://tests.localhost/script.php?active=1&redirect=http://www.google.com/page.php?q=test&limit=10';
$urlParts = parse_url($url);
print_r($urlParts);
ArrayPour contourner ce genre de problème, on devra préalablement transformer la valeur du paramètre redirect avec une fonction comme urlencode(). Le fichier script.php pourra ensuite extraire la valeur de la clé redirect en effectuant quelques manipulations et en décodant la valeur avant de faire la redirection.
(
[scheme] => http
[host] => tests.localhost
[path] => /script.php
[query] => active=1&redirect=http://www.google.com/page.php?q=test&limit=10
)
$urlParam = urlencode('http://www.google.com/page.php?q=test&limit=10');Certaines personnes pourraient avoir tendance à vouloir utiliser base64_encode() et base64_decode() pour encoder la valeur de l'URL passée en paramètre. Je ne vous recommande pas car vous risquez d'avoir un problème au moment de faire le split sur le caractère "=" (une chaîne encodée en base64 peut comprendre le caractère = dans le résultat).
$url = 'http://tests.localhost/script.php?active=1&redirect=' . $urlParam;
$parts = parse_url($url);
$pairs = explode('&', $parts['query']);
$keys = array();
foreach($pairs as $pair){
list($key, $value) = explode('=', $pair);
$keys[$key] = $value;
}
header('Location: ' . urldecode($keys['redirect']) );
exit;
Qui dit déménagement rime généralement avec magasinage de meubles et accessoires. En faisant du lèche-vitrine virtuel sur la version française du site web de Brick, dans la section des tables de cuisine de forme ronde, on nous montre une table carrée. Et pas n'importe laquelle : une table d'amitié !?
En plus, c'est quoi la différence entre trier les items par prix croissant ou par prix de bas en haut ?
Tables carrées, rectangulaires ou rondes, jamais je ne me serais douté qu'il pouvait exister un modèle de table triangulaire (chez Brault et Martineau). Si ce n'est pas une preuve que le monde est remplit de surprises...
Parlant de meubles, on ne peut passer sous silence IKEA. Cette opératrice en ligne ressemble étrangement à Anna, leur personnage virtuel.
Gracieuseté de Totally Looks Like.
Je suis un développeur web ayant plus de 10 ans d'expérience en différents langages de programmation. Depuis son lancement, je suis un utilisateur modéré du framework PHP de Zend. Il m'offre la flexibilité de choisir un par un quels composants peuvent améliorer ma productivité sans toutefois m'imposer de contraintes et me mettre en boîte comme le feraient d'autres framework plus stricts.
Suite à la lecture du billet Pourquoi le framework est synonyme du mal sur le blogue Coding by Head, j'étais plus ou moins d'accord avec l'argumentation de l'auteur parce qu'il ne présente qu'un seul côté de la médaille. Plutôt que d'envoyer un commentaire qui aurait été trop long, je présente ma réplique ici.
Je vais donc me faire l'avocat du diable et représenter le clan qui est en faveur de l'utilisation d'un framework. Vous pourrez ensuite vous faire votre propre opinion car tout est une question de perception.
Un framework suit le principe de pareto (la règle du 80/20) : faire 80% du travail avec 20% des efforts. Si le but premier d'une usine est de sortir un produit fini répondant aux besoins de la clientèle, une firme de conception web a le même mandat. À l'intérieur de la fabrique, le moyen pour y arriver n'est pas un souçi de la clientèle qui utilisera le produit final. Ce qui se passe dans l'usine reste à l'usine. Et ce n'est pas une surprise, le client, l'acheteur, veut payer le moins possible pour en obtenir le plus pour son argent. Vous aussi, en tant que consommateur, devez comparer les prix et magasiner les soldes parce que vous pensez à la santé de votre porte-feuille.
C'est la triste vérité pour l'artisan : on s'industrialise pour être concurrentiel face à la compétition. On utilise différents moyens pour faciliter la création du produit et réduire les coûts pour l'offrir à un plus grand nombre possible. Ce qui fait qu'un artiste offrira un original étiquetté 1000$ à un cercle restreint de connaisseurs alors que la reproduction imprimée trouvera preneur chez des millions de consommateurs heureux de l'obtenir pour une fraction du prix. Produire plus vite en gardant le plus haut niveau de qualité possible au moindre coût. Nos voitures japonaises sont fabriquées au Mexique et le iPhone est mis en production en Chine. Tant pis pour le principe.
Dans notre milieu, le programmeur doit se doter des meilleurs outils pour avoir le rendement le plus efficace. Et il y a des choix à faire. Parfois déchirants et qui vont contre l'idéologie utopique d'un monde idéal et parfait. C'est ce qui rend notre gagne-pain possible. Si les entrepreneurs demandent à leurs employés d'utiliser une méthodologie, un outil ou un framework, c'est qu'il y a des avantages d'ordre logistique, organisationnel et économiques en jeu. Les décisions sont parfois motivées par des erreurs commises dans le passé que vous n'auriez jamais soupçonné. Autrement, libre à vous de tenter votre chance en vous lançant en affaires et de l'apprendre à vos dépens.
Oui, un framework peut être perçu comme contraignant pour la créativité et le mérite. Mais on parle aussi de ne pas réinventer la roue en programmation (voir aussi mon billet sur la performance de Zend Framework). Dans le monde idéal, si on avait du temps illimité pour réaliser un projet, je préférerais aussi tout programmer les composants de A à Z. Pour la même raison que j'aimerais programmer mon propre système d'exploitation, juste pour le plaisir de le faire (quoi que la barre serait haute avec Linux). On est soumis aux lois économiques et bien qu'on puisse choisir d'appliquer les principes qu'on juge les meilleurs dans nos projets personnels, quand on le fait dans le milieu professionnel, il faut prendre des décisions selon ce qui est le plus rentable.
Pour avoir travaillé avec des dizaines de programmeurs, j'ai constaté que plusieurs ont de la difficulté à structurer leurs programmes et que ça peut facilement virer en code spaghetti. Pour eux, le framework devient un avantage car il vient encadrer leur mode de pensée pour donner une ligne directrice commune aux développeurs d'une même équipe. Travail d'équipe + egoless programming = succès.
Il n'y a pas de mal à ne pas tout faire soi-même. Je ne connais personne qui programme "from scratch" en ignorant l'environnement sur lequel il développe (Windows API, applications iPhone, COM objects, libraires commerciales, etc). On construit constamment autout du code que d'autres ont produit. Pourquoi est-ce que ça ne serait pas pareil pour l'utilisation d'un framework ? Après tout, il ne sert que de fondation à la maison qu'on tente de construire.
Dans le cas d'un framework comme celui de Zend, il a l'avantage d'être développé et révisé par une communauté très active, d'être utilisé par des milliers de programmeurs dans le monde (voire plus), ce qui lui confère un avantage considérable sur sa qualité. Pour une même fonction, plus elle sera utilisée et appelée, plus on aura la conviction qu'elle sera fiable ou qu'on détectera un bogue rapidement. Chose que vous aurez beaucoup plus de difficulté à faire avec vos librairies maison.
Un bogue est trouvé dans un framework populaire ? La communauté prendra la responsabilité d'offrir une patch dans les plus brefs délais parce qu'ils sont réactifs. Oui, il existe un risque pour des frameworks moins populaires qui peuvent parfois être à l'abandon et laisser ses utilisateurs sans ressource. C'est à vous de choisir le bon et de ne pas mettre tous vos oeufs dans le même panier (tous vos projets avec le même framework).
Au fil du texte, l'auteur présente aussi plusieurs questions qu'il laisse sans réponse. Tentons d'y trouver écho.
Essayez donc de voir plus loin que le bout de votre nez, pensez comme les gens qui ont fait cet outil incontournable dans votre quotidien, recréez la roue pour innover.
Réinventer la roue n'est pas toujours synonyme d'innovation parce qu'il faut considérer que le temps de faire de la recherche et développement pour trouver une meilleure solution en plus du temps pour l'implémenter creusera le retard sur la solution existance qui poursuivrera son évolution. À moins d'une bonne raison de le faire, tout le temps passé à réinventer la roue est du temps que vous ne facturez pas vos clients et que vous ne remplissez pas les coffres.
Car avant tout, un code est une pensée. C’est un texte possédant tout un sens, une idéologie et une expression.
Faux. Comme j'ai déjà dit, c'est de la technique, pas de la poésie ;-) Le code est la représentation d'un algorithme, la traduction d'un processus d'affaires en langage machine. Un artisan, un artiste, comme un peintre, prend son temps pour réaliser son oeuvre. Il n'est pas autant soumis aux contraintes de productivité que peut l'être un programmeur qui travaille dans un milieu commercial. L'artiste vit aussi sous le seuil de la pauvreté.
Où est le mérite lorsque c’est quelqu’un d’autre qui a pensé la solution pour lui?
Le mérite vient de l'innovation sur la façon d'utiliser les outils mis à notre disposition. Le fait de combiner deux idées ordinaires peut donner naissance à une idée géniale. Il faut se rappeler que l'utilisateur final ne voit pas le code et que c'est bien le dernier de ses soucis! S'il y a du mérite à aller en retirer, ce serait l'impact que peut avoir le projet s'il a été bien réalisé. Mais ça ne dépend en rien du langage de programmation utilisé, c'est l'idée qui fait le succès. Le programmeur travaille dans l'ombre du grand public et les seuls dont il peut espérer faire reconnaître son mérite, ce sont ses pairs. Adoptez une attitude digne du egoless programming.
Sincèrement, allez-vous réellement regarder dans les sources du framework en vous disant “tiens, comment le mec a pensé tel truc” ?
Parfois oui. Et c'est une bonne source d'apprentissage de voir comment ils ont implémenté ce qu'ils croyaient être la meilleure solution. D'autres préféreront apprécier le principe de la boîte noire et faire confiance au fonctionnement interne.
Où est l’intérêt d’utiliser une solution inventée par quelqu’un sans même poser un œil sur cette solution?
Jusqu'à preuve du contraire, s'il y a une seule solution proposée, c'est la meilleure par défaut. On vit dans mon monde d'hyperspécialisation où des milliers de personnes se sont penchées sur un problème et on trouvé une solution acceptable. La nature humaine fait qu'on aime pelleter des nuages. On peut critiquer la solution et proposer des améliorations mais si ça prend quelques centaines d'heures de recherche, d'essais et erreurs et de tests pour obtenir un gain peu significatif ou arriver au même résultat avec une solution différente, la discussion n'a pas lieu d'être. Je ne dis pas que ça ne vaut pas le coup d'essayer mais n'oubliez pas que d'autres ont eu des bonnes idées avant vous et que l'évolution avance à petits pas. SVP, faites confiance à l'intelligence humaine.
Le framework, c’est LA chose qu’il vous faut posséder sinon vous n’êtes pas à la mode, pas à jour, et surtout, vous ne vous faites pas embaucher.
C'est loin d'être une mode. Oui c'est relativement nouveau dans le jeune monde du web mais ça existe depuis la nuit des temps pour d'autres langages. On regroupe les bouts de code utiles en fonctions, en classes, en librairies et ensuite en framework.
Si vous pensez que seul la connaissance d'un framework est déterminant dans une entrevue, remettez vos compétences en question.
Pourquoi une telle dépendance au framework? Pourquoi est-il aussi important qu’un bonbon, une nouvelle technologie, ou bien un nouvel artiste du domaine musical?
Un individu qui se tient à jour dans son domaine d'expertise, voire qui est à l'avant-garde, qui explore ce que le futur lui réserve sont des synonymes de curiosité, d'exploration, d'évaluation des opportunités. Il saura prendre les meilleures décisions et influencer la direction de l'entreprise où il oeuvre plutôt que d'être influencé. En ayant une longueur d'avance sur les autres, il est le premier à profiter des opportunités qui s'offrent à lui. D'un autre côté, il serait bête d'opter pour une nouvelle technologie s'il n'avait pas la conviction que ça lui sera bénéfique.
Le développeur sera-t-il alors un simple mec bon à appeller des fonctions toutes faites et ne pensera plus à rien? S’il n’y a plus de développeur, il n’y aura plus de langage.
Ouf, un peu alarmiste comme propos! Comme le disait un autre programmeur mentionné dans son billet : le framework reste un outil, il ne remplacera jamais un développeur. Je suis d'accord avec lui. Pour moi, le framework ne solutionne aucun problème de logique, sauf si ce n'est de la structure qu'il permet de mettre en place plus facilement et d'offrir un jeu de librairies pour simplifier les actions qu'on fait régulièrement.
On disait il n'y a pas si longtemps que les robots nous feraient perdre nos emplois. Au contraire, ça en a créé! Des emplois de meilleure qualité et de plus haut niveau de complexité qui nécessite une spécialisation toujours plus poussée. Le métier de programmeur ne fera qu'évoluer vers des nouveaux défis.
Le temps n’est pas une excuse valable pour l’utilisation d’un framework. S’il en est une pour vous, alors cela prouve tout l’intérêt que vous portez à votre projet, c’est à dire aucun.
Mon cher ami, tu expliqueras ça à ton patron quand il t'annoncera que tu perds ton poste parce que son entreprise n'est plus assez compétitive sur les coûts et le temps de production. Il y a probablement plusieurs chinois et indiens qui ont tout à gagner à travailler 14 heures par jour pour un salaire dérisoire.
Si on compare le temps utilisé, alors comparons le temps utilisé pour créer un framework ou bien pour recréer la roue.
J'ai une très belle histoire à ce sujet. Deux de mes collègues ont créé, sur les heures normal de bureau, un projet qui aurait nécessité quelques composants du ZF. Parce qu'ils avaient une perception bien négative de l'utilisation du framework, ils ont décidé de développer leurs propres composants spécifiques à ce projet. 600 heures personnes ont été nécessaires pour le réaliser en imitant les fonctionnalités déjà offertes par ZF. Le résultat : mal structuré, limitatif en fonctionnalités, bogué et j'en passe. Le projet initial avait été évalué à 250 heures. Aujourd'hui, les deux programmeurs ne travaillent plus pour l'entreprise.
Je dis ça juste comme ça.
Pourquoi les entreprises focalisent-elles sur ces produits mâchés par des gens aux ambitions de contrôle et de manipulation?
Parce qu'on est victime d'une grande conspiration internationale. Ben non, voyons! Les recruteurs qui cherchent à engager des programmeurs savent que :
- en ayant travaillé avec un framework, le candidat est capable d'être productif dans un cadre de travail défini;
- de façon générale, sa courbe d'apprentissage sera plus aisée et le risque amoindri
- qu'il parlera un langage commun, avec les mêmes termes et patterns avec les autres programmeurs
- il risque moins de déroger des standards de l'industrie pour imposer "ses" standards;
- que la documentation d'un framework connu est disponible : tutoriels, formations, références, livres, etc;
- il y a plus de chances que le candidat connaisse un framework largement utilisé plutôt qu'un framework ou jeu de librairies faits maison. Il sera rentable plus rapidement pour l'entreprise.
Parler contre les frameworks, c'est un peu insulter tous ceux qui en utilisent (Zend, CakePHP, Symphony, Drupal, jQuey, Prototype, YUI, .NET, etc). Si vous avez une critique envers un framework, rien ne vous empêche de vous impliquer dans son développement et de suggérer des améliorations. Ce sont souvent des projets collectifs, à l'écoute des besoins des développeurs. Ce sera gratifiant parce que vous aurez excellé là où d'autres n'avaient jamais pu offrir mieux. Si vous ne le faites pas, là ce sera de la paresse. Trouver LA ligne de code à améliorer est plus exigeant que critiquer et tout réécrire 10000 lignes de code à votre façon (sauf rares exceptions). C'est une question d'efficience. Si vous avez la prétention de pouvoir faire mieux, vous venez de tomber dans le piège. Si vous avez la conviction et que vous savez exactement pourquoi vous devez le faire, faites-le.
Oui, il faut regarder ce que le framework offre et le choisir par rapport au besoin du projet. Le problème est que le temps investi dans l'apprentissage d'un nouveau framework doit être de beaucoup inférieur au temps que vous prendriez pour coder votre propre framework. Sinon, remettez en question celui que vous avez choisi, il n'est peut-être pas approprié à l'application que vous voulez en faire. Le second problème est qu'après avoir investi du temps à le connaître et à le maîtrisez, c'est naturel de vouloir utiliser l'outil connu et de l'adopter pour le projet suivant. Ça demande moins d'efforts mais vous vous casserez peut-être la tête à figurer comment contourner les problèmes et deviendrez amer envers le framework.
Avoir un bon outil est mieux que de ne pas avoir le bon ou ne pas en avoir du tout. Je terminerai avec un passage du livre The Pragmatic Programmer, From Journeyman to Master :
Tools amplify your talent. The better your tools, and the better you know how to use them, the more productive you can be. Start with a basic set of generally applicable tools. As you gain experience, and as you come across special requirements, you'll add to this basic set. Like the craftsman, expect to add to your toolbox regularly. Always be on the lookout for better ways of doing things. If you come across a situation where you feel your current tools can't cut it, make a note to look for something different or more powerful that would have helped. Let need drive your acquisitions.
L'intelligence est la qualité permettant à ceux qui la possèdent de trouver d'excellentes raisons aux bêtises qu'ils font.
Après une courte pause d'analyse des attrapes JavaScript pour éviter d'en faire une indigestion (vous comprendrez que j'ai aussi été très occupé), me revoilà ce matin prêt à examiner la troisième question du test de PerfectionKills qui présente un piège avec l'instruction delete.
Voici l'énoncé :
(function(x){Choix de réponse :
delete x;
return x;
})(1);
- 1
- null
- undefined
- error
En regardant de plus près, ceci nous montre que la variable x n'est pas supprimée :
(function(x){Et que la bonne réponse sera 1 :
delete x;
console.log(typeof x); // number
return x;
})(1);
var result = (function(x){Suite à l'explication trouvée dans cet article du même site (understanding delete, lecture recommandée malgré sa longueur), on comprend qu'il est impossible de supprimer les arguments d'une fonction. Dans le cas qui nous préoccupe, nul besoin de plus amples explications pour répondre à la question. Or, dans les autres cas, l'instruction delete a un comportement particulier qu'il vaut la peine de comprendre.
delete x;
return x;
})(1);
alert(result); // 1
En règle générale, on peut supprimer une propriété d'un objet (ou un élément à un indice spécifique d'un tableau) mais pas une variable. Pour saisir toute la subtilité, notez la différence :
// variable déclaréeMais si le mécanisme d'assignation est utilisé :
var a = 1;
delete a;
alert(typeof a); // number
// assignation de propriété (à l'objet global)
b = 1;
delete b;
alert(typeof b); // undefined
var x = this;Des assignations à des variables non déclarées créent des propriétés supprimables. Autrement, les variables et les fonctions ne le sont pas.
x.test = 10;
alert(typeof x.test); // number
delete x.test;
alert(typeof x.test); // undefined
Ça y est, notre objectif est atteint : nous avons enfin acheté notre maison à Montréal. Après des années de préparation financière et de recherche, on se lance dans l'aventure de devenir propriétaire. Comme disait Louis-José Houde : j'ai payé ça une fortune, ça a été construit en 1914, le plancher est croche, le plafond coule, t'as pas de terrain, pas de place de parking mais à côté de chez vous, t'as une charcuterie que tu peux te rendre à pied. Ça te donne l'impression de mener une bonne vie. Toujours aussi drôle! Non, rassurez-vous, l'inspecteur l'a qualifiée de A1, mis à part quelques défauts mineurs à corriger.
Ça peut peut-être paraître un peu fou de notre part de vouloir vivre à Montréal si on compare les prix avec la banlieue. Mais comme je l'ai déjà expliqué, tout dépend de la façon dont vous économisez. Comme on l'a vu, posséder une seule voiture (ou une combinaison transport en commun / Communauto) permet de faire des économies substantielles qui rend possible l'achat d'une maison plus dispendieuse au coeur de la métropole. Et croyez-moi, malgré les prix élevés, ça se vend comme des petits pains chauds. En novembre 2010, sur l'île de Montréal, la valeur de revente médiane s'est établie à (source) :
- 350000$ pour les unifamiliales
- 250000$ pour les copropriétés
- 397000$ pour les «plex»
Si vous aussi avez l'intention d'acheter une maison à Montréal (ou ailleurs au Québec), voici quelques informations pratiques pour la réalisation de votre projet.
Étape 1 : trouver une maison
Parcourez les rues des quartiers qui vous plaisent et repérez les maisons en vente par le propriétaire. Ça vous permettra d'économiser sur la commission de l'agent immobilier (le vendeur gonfle son prix pour absorber le coût). Sinon, jetez un oeil à DuProprio et sur MLS (regroupe la plupart des propriétés à vendre par les bannières). Vous devez savoir que les agents ont accès aux fiches des nouvelles propriétés quelques jours avant que ça s'affiche sur le système MLS. À quelques reprises, nous avons eu la surprise de constater que c'était déjà vendu dès la première journée d'affichage sur le site web.
Étape 2 : offre d'achat
Si une maison vous intéresse, faites une offre d'achat. Assurez-vous d'inclure une clause conditionnelle au financement et une autre pour l'inspection (suggéré).
Étape 3 : inspection
L'inspection par un professionnel est une bonne façon de connaître l'état d'une maison et d'avoir un aperçu des réparations que vous aurez à faire. Si c'est désastreux, vous pourrez retirer votre offre d'achat.
Selon cet article de La Facture, le coût d'inspection variant entre 240$ à 400$ en 2001. En 2010, le prix moyen était environ 500$ plus taxes chez les inspecteurs que j'ai appelé qui faisaient partis de l'AIBQ (Association des inspecteurs en bâtiment du Québec).
Étape 4 : financement
À moins que vous ayez déjà gagné à la loterie, vous devrez emprunter pour acheter. Vous pouvez aller à la banque ou chez un courtier hypothécaire (par exemple Multi-Prêts ou Hypotheca). De notre côté, nous n'avons eu aucune difficulté à obtenir de notre banque le plus bas taux qu'offrait le courtier. Il suffit de le demander.
Étape 5 : prime d'assurance hypothécaire
Si votre mise de fond (cash down) est inférieur à 20%, vous devrez payer une prime d'assurance sur votre prêt. Sur une maison de 250000$, 20% représente 50000$. Ce n'est pas tout le monde qui peut se permettre ce montant! Même si vous grattez les fonds de tiroirs et que vous réussissez à rassembler 49999$, vous aurez 3500$ de plus à payer (inclus dans le montant du prêt hypothécaire). Pourtant, ajoutez 1$ et votre prime sera de 0$. Autrement dit, plus vous mettez de cash down, plus cette taxe sera faible.
À titre indicatif, sur un prêt de 250000$ (selon les règles en vigueur en novembre 2010) :
Mise de fond | Prime à payer |
0$ | 7750$ |
5000$ | 7595$ |
25000$ | 4500$ |
49999,99$ | 3500$ |
50000$ | 0$ |
Si vous avez des REER (Régime enregistré d'épargne-retraite), vous pouvez les retirer pour un RAP (Régime d'accession à la propriété) qui sera à rembourser à l'intérieur de 15 ans, à raison de 1/15 par année.
Étape 6 : notaire
Pierre Légaré sera heureux que vous alliez voir le notaire pour régler tous les papiers légaux. C'est un coût fixe qui ne dépend pas de la valeur de la maison. Pour nous, c'était 1300$ tout inclus. Consultez le site web de la Chambre des Notaires du Québec pour plus d'informations.
Étape 7 : taxe de bienvenue
Dès que vous devenez officiellement propriétaire, attendez-vous, dans les mois qui suivent, à avoir à payer la fameuse taxe de bienvenue (taxe de mutation). Le calcul se fait toujours à partir du montant le plus élevé entre le prix d'achat et le prix inscrit dans le rôle d'évaluation. Et comme le prix payé est pratiquement toujours le plus élevé...
Pour une propriété de 200000$ : 1750$.
Pour une de 250000$, ce sera 2250$.
Étape 8 : taxes municipales et scolaires
Selon la période de l'année où vous emménagerez dans votre nouvelle demeure, vous devrez rembourser à l'ancien propriétaire le ratio de la taxe municipale et scolaire qu'il aura déjà payé. Dans le pire des cas, ce sera 100% à prévoir dans votre budget.
De toutes les maisons comparables visitées, ces taxes variaient entre 2200$ et 3700$.
Étape 9 : déménagement
N'oubliez pas que le déménagement nécessitera quelques frais : louer un camion ou des déménageurs, briser votre bail si vous louez un appartement, la peinture, réparations, la bière et la pizza aux amis, etc.
Conclusion
Avant d'acheter une maison, même si ne mettez pas de mise de fond, prévoyez toujours d'avoir au minimum 8000$ à 10000$ de côté dans votre bas de laine. Pensez-y à deux fois et faites les calculs comme il faut pour éviter les désagréments.
J'adore fouiller pour trouver des anecdotes de toutes sortes, en particulier dans le domaine de la programmation. Peu importe l'époque, ça démontre bien l'état d'esprit du programmeur et dans quel genre d'environnement il évoluait. Ma plus récente trouvaille nous ramène à la fin des années 50 et le TX-0 (Transistorized Experimental computer zero, "Tixo"), un ordinateur de 16 bits / 64k d'une valeur de 3 millions de dollars reçu au département de recherche en électronique du MIT.
Peter Samson, un des premiers hacker du MIT (dans le sens original du mot) et amateur de musique classique, a utilisé les capacités du TX-0 pour envoyer du "bruit" vers un haut-parleur audio. Comme il n'y avait aucun moyen intégré pour contrôler la hauteur, l'amplitude ou la tonalité, il trouva un moyen de contrôler les sons émis en fonction de l'état du 14ème bit du "18-bit word" que le TX-0 avait dans son accumulateur, à une microseconde donnée. Le son était allumé ou éteint selon si le bit no. 14 avait la valeur de 1 ou 0.
Pour des raisons obscures, Samson refusait toujours d'écrire des commentaires dans son code pour expliquer ce qu'il faisait. Plus tard, dans un programme de plusieurs centaines de lignes d'assembleur, un seul commentaire figurait à côté d'une instruction contenant le chiffre 1750. Le commentaire était RIPJSB.
Beaucoup se sont creusé la tête pour comprendre sa signification jusqu'à ce que quelqu'un figure que 1750 était l'année où Bach était mort. Une abbréviation pour Rest In Peace Johann Sebastien Bach. On doit entre autre à Samson le compilateur de musique Harmony qu'il créa vers 1961 pour le PDP-1 à partir de son programme initial du TX-0.
Tiré du livre Hackers: Heroes of the Computer Revolution, 25th anniversary edition de Steven Levy (magazine Wired) que j'ai reçu la semaine dernière d'Amazon. Avis aux intéressés, les deux premiers chapitres sont disponibles sur Gutenberg Projet.
On n'est vraiment pas à jour sur notre suite bureautique. En effet, là où je travaille, les programmeurs n'utilisent pratiquement jamais Word, sauf pour consulter la documentation envoyée par les clients et à l'occasion rédiger des analyses (on utilise une panoplie d'autres outils comme Balsamiq pour faire des mockups).
Or, Office 2003 est toujours installé sur nos postes et jusqu'à maintenant, on ne voit pas l'intérêt d'acheter des mises à jour (qui sait, peut-être une éventuelle conversion vers une suite libre ?). Chez moi, j'utilise OpenOffice depuis des années et il est 100% compatible avec les fichiers Office 2007.
Le problème, c'est que de plus en plus de clients nous envoient des fichiers .docx et .xlsx. Au début, on demandait à nos supérieurs de nous les convertir (par paresse ou pour mettre de la pression pour inciter à un changement ?), jusqu'à ce qu'on installe le module de compatibilité pour Microsoft Office System 2007 pour les fichiers Word, Excel et PowerPoint (FileFormatConverters.exe, gratuit). Une fois le fichier ouvert, il suffit d'enregistrer le fichier sous un autre format désiré (le format Office 2007 n'est pas possible).
C'est ce qui est dommage en entreprise : nous n'avons pas toujours le choix des outils à notre disposition. Si c'était juste de nous, Exchange prendrait le bord, Outlook aussi au profit de Thunderbird, on abandonnerait la suite Microsoft Office pour OpenOffice ou LibreOffice, nos postes de travail seraient en Linux au lieu de Windows, etc... Heureusement, mon patron n'est pas très avare quand vient le temps d'acheter les meilleurs outils de programmation. On l'excusera de vouloir économiser ailleurs pour investir là où ça compte vraiment.
Je vous ai montré plus tôt cette semaine comment valider la syntaxe d'un lien YouTube et extraire la clé de l'URL. Maintenant, je vais vous montrer comment, à l'aide d'un composant du Zend Framework, obtenir la liste des thumbnails d'une vidéo YouTube.
Pour ce faire, j'ai utilisé la classe Zend_Gdata_YouTube. Si vous comptez récupérer des données en mode lecture seule, vous n'aurez pas besoin de vous authentifier au service.
Liez d'abord la classe principale à votre projet :
require_once('Zend/Gdata/YouTube.php');Si vous n'utilisez pas l'autoloader, vous risquez d'obtenir le message suivant :
Fatal error: Class 'Zend_Uri_Http' not found
Si c'est le cas, vous avez le choix d'utiliser le mécanisme d'autoload ou bien d'inclure la classe Zend_Uri_Http :
require_once('Zend/Uri/Http.php');Vous pouvez alors instancier l'objet et récupérer les informations d'une vidéo en passant la clé extraite de l'URL à la fonction getVideoEntry(). Idéalement, utilisez un try/catch pour attraper les exceptions, par exemple au cas où la clé fournie est érronée ou n'existe plus.
# clé de la vidéo à récupérerSi vous ne réussissez pas à faire fonctionner cet exemple et que le message d'erreur ci-dessous est affiché, vérifiez votre version du ZF. Je n'ai eu qu'à mettre à jour ma vieille version du ZF vers la version 1.10.8 pour qu'il disparaisse.
$key = 'lX1r6fQjBq4';
$youtube = new Zend_Gdata_YouTube();
$youtube->setMajorProtocolVersion(2);
try{
$video = $youtube->getVideoEntry($key);
$thumbnails = $video->getVideoThumbnails();
foreach($thumbnails as $image){
echo $image['url'] . "\n";
echo $image['width'] . "\n";
echo $image['height'] . "\n";
# correspond à quel moment de la vidéo la capture a été prise
# echo $image['time'] . "\n";
}
}
catch(Exception $e){
# Expected response code 200, got 400 GData InvalidRequestUriException Invalid id
echo $e->getMessage();
# throw new Exception($e);
}
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 1 bytes)
Enfin, vous devez savoir qu'il y aura toujours une image nommée default.jpg, que les autres seront numérotées [1-n].jpg et que l'image haute définition est hqdefault.jpg. Autrement dit, si vous connaissez la clé unique, vous pouvez recomposer le lien vers les images en l'insérant dans l'URL :
- http://i.ytimg.com/vi/CLÉ/default.jpg
- http://i.ytimg.com/vi/CLÉ/hqdefault.jpg
I suspect if you had the sixteen year old Shakespeare or Einstein in school with you, they'd seem impressive, but not totally unlike your other friends. Which is an uncomfortable thought. If they were just like us, then they had to work very hard to do what they did. And that's one reason we like to believe in genius. It gives us an excuse for being lazy. [...] Instead of waiting to be taught, go out and learn.
Tiré du billet What you'll wish you'd known publié sur le site de Paul Graham.
À lire aussi :
- What a High School Student Learned from Paul Graham
- L'excellent livre Hackers & Painters: Big Ideas from the Computer Age
L'informatique est un domaine où on a souvent à manipuler les chiffres différemment de la façon dont est habitué monsieur et madame Tout-le-monde (système décimal à base 10). On utilise le binaire (base 2) dans le langage machine, l'octal (base 8) pour les bits et l'hexadécimal (base 16) pour représenter les codes de couleurs en HTML, ce qui nous amène à percevoir les choses avec un peu plus d'abstraction.
Par exemple, la valeur 42 en binaire est représentée ainsi : 101010. En lisant à partir de la droite, la première position est 2 à la puissance 0 (valeur de 1).
Valeur binaire | 1 | 0 | 1 | 0 | 1 | 0 |
Exposant | 2^5 | 2^4 | 2^3 | 2^2 | 2^1 | 2^0 |
Équivaut à | 32 | 16 | 8 | 4 | 2 | 1 |
Total | 32 + 8 + 2 = 42 |
Dans ce système, un grand nombre écrit 15.5.10 vaudrait dans notre système décimal (toujours de droite à gauche) :
Valeur | 15 | 5 | 10 | ||
Exposant | 60^2 | 60^1 | 60^0 | ||
Équivaut à | 3600 | 60 | 1 | ||
Total | (15x3600) + (5x60) + (10x1) = 54310 |
- secondes (60 secondes dans 1 minute)
- minutes (60 minutes dans 1 heure)
- heures (3600 secondes par heure)
- division du cercle (6 x 60 degrés = 360 degrés)
Pour les programmeurs sains d'esprit qui me lisent, si vous souhaitez explorer davantage l'affichage des caractères cunéiforme (je sais, ça n'a probablement aucune valeur pratique, mais c'est juste pour le plaisir de le faire), installez d'abord les polices cuneifont (Old Babylonian). Sachant que les valeurs unicodes réservées à l'écriture cunéiforme vont de U+12000 à U+1236E, on pourra, en PHP, faire afficher le symbole pour la valeur 5 (voir graphique plus haut) :
$five_cuneiform = "0x1240A";Vous serez peut-être obligé de mettre le font-size assez élevé pour bien voir le caractère ou encore, utilisez la fonction de zoom du navigateur.
echo "&#" . hexdec($five_cuneiform) . ";";
Inscrit aux spécifications du cahier de production : le formulaire devra accepter un lien YouTube. Comme je ne vois pas l'intérêt de vous écrire un roman sur le sujet, on va faire ça court. Voici donc l'expression régulière que j'ai écrite pour valider le lien saisi par l'utilisateur.
Validation
# format longExtraction de la clé
$url = 'http://www.youtube.com/watch?v=DF2G6rbzxHc&feature=player_embedded';
$regex = '/^http:\/\/(www\.)?youtube\.com\/watch\?v=([\w-]+).*$/i';
echo preg_match($regex, $url) ? 'valide' : 'invalide';
# format court
$url = 'http://youtu.be/DF2G6rbzxHc';
$regex = '/^http:\/\/youtu\.be\/([\w-]+)$/i';
echo preg_match($regex, $url) ? 'valide' : 'invalide';
Le plus pratique est d'extraire la clé unique de l'URL original pour pouvoir le faire jouer à l'extérieur de sa page YouTube en recomposant l'URL sous la forme http://www.youtube.com/v/CLÉ. Ainsi, on pourra le faire jouer facilement dans un lecteur intégré comme celui de Shadowbox.
# format long
$url = 'http://www.youtube.com/watch?v=DF2G6rbzxHc&feature=player_embedded';
$regex = '/^http:\/\/(www\.)?youtube\.com\/watch\?v=([\w-]+).*$/i';
$key = preg_replace($regex, '$2', $url);
echo 'http://www.youtube.com/v/' . $key;
# format court
$url = 'http://youtu.be/DF2G6rbzxHc';
$regex = '/^http:\/\/youtu\.be\/([\w-]+)$/i';
$key = preg_replace($regex, '$1', $url);
echo 'http://www.youtube.com/v/' . $key;
Pourquoi parler de poutine aujourd'hui ? Parce que ce plaisir coupable par excellence des québécois vient d'être immortalisé par un groupe de punk/gypsy de Vancouver que je viens de découvrir nommé The Dreadnoughts. Sur son plus récent album, Polka's Not Dead, sorti il y a à peine un mois, la chanson "Poutine" met ce mets à l'honneur.
C'est un peu cliché de penser qu'on est accro à ce junk food qui mélange frite, sauce et fromage en grains mais comme c'est offert dans tout bon casse-croute qui se respecte et ce dans tous les coins du Québec, le touriste en visite se souviendra de cette caractéristique propre à nous. Nous avons même le festival de la poutine qui se tient à Drummondville qui présente des spectacles (oh, est-ce qu'on aurait un concept si on invitatait The Dreadnoughts ?).
Il faut croire que les membres du groupe soient tombés sous le charme puisqu'ils en ont fait le sujet d'une chanson, un hymne à la poutine. Sur leur blogue de tournée, ils confirment que c'est une obsession culinaire qu'ils ont : ils auraient commandé au moins 75 poutines en l'espace de deux semaines, ce qui leur aurait donné un look de femme enceinte... Faut croire qu'il y en a qui aiment ça plus que nous.
Voyez cet extrait de spectacle. Malheureusement, la qualité sonore laisse à désirer. Pour bien comprendre les paroles, mieux vaut l'écouter sur iTunes, Amazon ou tout autre service en ligne (introuvable sur Last.fm, Grooveshark et Pitchfork).
Poutine poutine, j'ai tellement faim. Poutine poutine, c'est ça ou rien!
À l'autre extrémité du Canada, dans le Village Historique Acadien situé près de Caraquet au Nouveau-Brunswick, nous avons goûté à de la "poutine râpée". Servie au restaurant la Table des Ancêtres qui se trouve à même le site, tous les clients autour de nous ont passé un commentaire lorsque nous avons placé la commande. Nous étions encore plus intrigués alors quand l'assiette est arrivée, on a constaté que ça ressemblait à une pomme de terre bouillie, avec du lard à l'intérieur. Comme c'était peu goûteux (ou pour changer le goût curieux de la viande), on pouvait y ajouter de la mélasse ou de la cassonade. Et ce n'était pas meilleur! Nous étions contents d'avoir fait l'expérience mais nous n'en recommanderons pas. Rien ne vaut la poutine de chez nous.
Zero Clipboard pour pallier à un manque des fureteurs
La majorité des fureteurs ne donnent pas accès au presse-papier. Sauf Internet Explorer. Aucun client ne m'a demandé ce genre de fonctionnalité dans le passé. Pourtant, c'est quelque chose que je n'avais jamais songé intégrer dans un projet et que pour le peu d'effort que ça demande, je risque de l'offrir plus souvent.
C'est l'interface du raccourcisseur d'URL Bit.ly qui m'y a fait penser. Coller un URL, cliquer dans la case et retrouver immédiatement l'URL court dans mon presse-papier pour le coller dans Facebook, Twitter ou Identi.ca sans avoir à le sélectionner manuellement pour le copier.
Idéal pour faciliter la récupération d'une clé d'API, d'un URL, d'un snippet de code ou de toute autre information qui nécessite le copiage exact pour avoir la certitude qu'il sera collé tel quel sans omettre un caractère important. Ça peut paraître un détail, mais il semble que la notion de copier/coller ne soit pas encore totalement maîtrisée chez certaines personnes. Pour les autres, ça nous permet d'être un peu plus efficace.
Si on fouille dans le code source de Bit.ly (côté client), la librairie JavaScript externe bitly_compressed.js montre que Zero Clipboard est utilisé. En utilisant une combinaison de JavaScript et de Flash, Zero Clipboard peut compenser l'absence de clipboard sur différents browsers.
Essayez les quelques lignes de code ci-dessous. Vous verrez que seul Internet Explorer ne chigne pas sur l'utilisation du presse-papier, malgré qu'il vous demandera une autorisation. Firefox, Safari, Chrome et Opera afficheront plutôt l'alerte "Fonction inexistante".
if( window.clipboardData && clipboardData.setData ){D'abord, téléchargez la dernière version de Zero Clipboard. Décompressez le dans un répertoire à la racine de votre projet et liez le fichier JavaScript principal à votre page.
clipboardData.setData('Text', 'Code 18');
}
else{
alert('Fonction inexistante');
}
<script type="text/javascript" src="/zeroclipboard/ZeroClipboard.js"></script>Comme configuration, indiquez le chemin du movieclip Flash seulement si votre page ne se trouve pas dans le même répertoire que le fichier .swf. Utilisez le fichier ZeroClipboard10.swf si vous comptez copier du contenu riche (nouveauté disponible depuis la version 1.0.7).
ZeroClipboard.setMoviePath('http://localhost/zeroclipboard/ZeroClipboard.swf');Pour le markup HTML, vous devez définir un conteneur principal qui accueillera le Flash (dynamiquement, par programmation) ainsi qu'un élément qui servira de bouton pour lancer la copie au presse-papier (utilisez glue() pour faire le pont entre les deux).
<div id="container"></div>
<a id="btn" href="javascript:;">Copier au presse-papier</a>
Le code JavaScript, que j'ai combiné à jQuery :
var clip = null;Voilà votre interface utilisateur déjà un peu plus user-friendly.
$(document).ready(
function(){
clip = new ZeroClipboard.Client();
clip.glue('btn', 'container');
clip.addEventListener('mouseDown',
function() {
clip.setText( $('#textToCopy').val() );
// effet simpliste pour indiquer textuellement à
// l'utilisateur que le contenu est copié
$('#result').show();
$('#result').html('Contenu copié au presse-papier!').css('color', 'green');
$('#result').fadeOut(2500);
}
);
}
);
Quant au service Bit.ly, on ne sait pas combien de temps il survivra. Le roi de la Libye n'est pas heureux que son extension de domaine soit associée à des URL raccourcis...
Je vous avais déjà parlé de ce gars qui avait créé un répertoire de chansons à jouer sur le clavier du téléphone ? Ce même gars avait aussi comme projet de reproduire l'interface de Windows 3.1 en JavaScript. Ça faisait déjà un bon bout de temps qu'on en avait entendu parler mais pour une raison que j'ignore, plusieurs personnes ont ressorti ce projet des boules à mites et ont fait circuler le lien sur Twitter durant la journée. Je comprends pourquoi parce que c'est un exploit digne de mention.
Essayez par exemple le command prompt MS-DOS :
C:\> cd windows
C:\> dir
Ou tentez votre chance à Minesweeper, entièrement codé en JavaScript. D'ailleurs, si vous jetez un oeil au code source, c'est du JavaScript pur, sans framework. Mais où se trouve le code pour le jeu ? Avec Firebug, sous l'onglet Net, j'ai regardé quelles ressources étaient chargées. Aucune ne correspondait à ce que je cherchais. Au moment de cliquer sur l'icône, le fichier suivant est appelé et charge le fichier externe :
http://michaelv.org/apps/getfile.php?dir=\windows&file=winmine.exe
On voit que c'est la fonction loadExternalFile() qui s'occupe de le récupérer sur le disque. La ligne ref.setAttribute('href','/apps/'+f); montre que les fichiers externes se trouvent à la racine du répertoire app. Du point de vue d'un programmeur, c'est très enrichissant de voir de quelle façon il s'y prend. Sans aucun framework, la totalité du JavaScript dans ce répertoire ne pèse que 64 kb (moins s'il avait été minifié avec YUI compressor).