Si vous comptez démarrer un groupe de musique et que vous êtes à la recherche d'un peu d'originalité, peut-être serez-vous tenté d'intégrer des instruments de musique originaux à vos compositions.
"Out" sont les instruments classiques comme les guitares, la basse, le synthétiseur et la batterie ! Choisissez un instrument moderne issu du 21ème siècle comme le "Hang", un instrument de percussion créé en Suisse il y a 10 ans. Vous aurez l'avantage de faire parti du club très sélect des artistes qui performent de cet instrument et vous vous démarquerez par son originalité (tout comme pour le Chapman Stick, le Warr Guitar, etc).
Regardez la technique et écoutez le son, c'est assez particulier.
OK, j'admets que vous devrez mettre de côté votre âme de rocker si vous désirez vous consacrer à cet instrument. À Montréal, ne comptez pas sur Steve's Music ou Italmélodie pour vous en procurer un. Le prix d'un hang se détaille entre 500$ et 1500$ et ça semble être disponible que par commande spéciale.
En temps normal, quand j'ai à intégrer un champ autocomplete, j'utilise le composant autocomplete de YUI qui est parfaitement configurable. Cette fois-ci, ayant remarqué que jQuery était dans le projet, je me suis dit qu'il serait avantageux de chercher un plugin jQuery qui allégerait le chargement plutôt que d'intégrer les multiples scripts nécessaires à YUI.
J'en ai trouvé un dans jQuery UI mais comme je ne souhaitais pas un thème particulier, j'ai trouvé ce plugin autocomplete simplifié créé par Jörn Zaefferer. Bien sûr, la version 1.1 possède beaucoup moins d'options et de flexibilité que ce qu'offre les autres, mais j'ai jugé bon de le mettre au banc d'essai. Parfois la simplicité est suffisante pour faire le travail. Et ça a été le cas ici pour une intégration éclair.
D'abord, il faut télécharger jquery.autocomplete.zip et le décompresser. À l'intérieur se trouve plusieurs fichiers mais je n'ai besoin que de ceux-ci :
- jquery.autocomplete.min.js
- jquery.autocomplete.css
- indicator.gif
<script type="text/javascript" src="/js/jquery-1.4.min.js"></script>Il semble y avoir une petite erreur dans la feuille de style car indicator.gif ne se trouve pas à la racine mais plutôt dans le répertoire demo. Vous pouvez soit copier l'image à la racine (ce que j'ai fait), soit changer l'URL de la classe CSS pour ceci si vous souhaitez déposer le répertoire demo en ligne :
<script type="text/javascript" src="/js/jquery-autocomplete/jquery.autocomplete.min.js"></script>
<link rel="stylesheet" type="text/css" href="/js/jquery-autocomplete/jquery.autocomplete.css" />
.ac_loading {
background: white url('demo/indicator.gif') right center no-repeat;
}Créez une page dynamique (exemple: get-data-autocomplete.php) qui fournira la source de données. Ici, ça peut provenir de n'importe où tant que chaque ligne en sortie correspond à un enregistrement (j'aurais préféré une source JSON). Par exemple, chaque ligne devra prendre la forme étiquette|valeur :Marc|1Dans le fichier principal, ajoutez le champ de formulaire HTML qui servira de point d'entrée au champ d'auto-complétion. À l'affichage, la largeur du champ définira la largeur du panneau de suggestions.
Marc-André|2
Martin|3
Martine|4
Mathieu|5
Matthieu|6
Mathias|7
Mathis|8
<input id="ac_field" name="ac_field" value="" type="text">Et enfin le JavaScript :
<input id="ac_value" name="ac_value" value="" type="hidden">
$j = jQuery.noConflict();Le plugin effectue automatiquement la requête Ajax avec la méthode GET et envoie au fichier PHP des paramètres utiles qui sont automatiquement nommés q et limit.
$j(document).ready(function(){
$j('#ac_field').autocomplete(
'/ajax/get-data-autocomplete.php',
{
'minChars': 1,
'max': 10,
'mustMatch': true
}
).result(
function(e, i){
if(i != undefined){
$j('#ac_value').val(i[1]);
}
else{
$j('#ac_value').val('');
}
}
).blur(
function(){
$j('#ac_value').val();
// réinitialiser le formulaire si nécessaire
// avec des valeurs par défaut
}
);
});
$_GET['q'] // pour filtrer la source de donnéesAinsi, vous pouvez adapter votre requête SQL pour filtrer les résultats d'une table.
$_GET['limit'] // pour limiter le nombre de résultats retournés
Comme je voulais forcer l'utilisateur à faire un choix dans la liste de suggestions et ne pas accepter de nouvelles entrées, j'ai trouvé une suggestion sur Stack Overflow où quelqu'un proposait d'enchaîner les fonctions result() et blur() pour contrôler la manipulation.
Il suffira ensuite de valider côté serveur que le champ ac_value (hidden) n'est pas vide et d'afficher un message d'erreur si c'est le cas.
J'aimerais attirer votre attention sur un très bon article paru dans le journal Les Affaires que je suggère à tous de lire, ne serait-ce que pour les reconnaître si vous avez le malheur d'être dans une situation similaire : manipulateurs et cie.
Dans ma (jeune) vie, j'ai eu affaire à deux reprises à ce genre d'individu. Une fois dans ma vie professionnelle et l'autre au niveau personnel. On s'entend, tout le monde pourrait à l'occasion être tenté de déformer la réalité pour servir ses intérêts. Je ne fais pas référence à des erreurs de parcours ou des cas isolés mais bien à des circonstances où le comportement est chronique et qui nous pollue l'existence au point de nous rendre malade. Vous verrez que le texte est orienté sur le milieu du travail mais c'est un jeu d'enfant que de faire le parallèle avec d'autres sphères sociales. Peut-être reconnaîtrez-vous quelqu'un dans votre entourage ?
On apprend de nos erreurs et on finit par se convaincre que plus jamais on ne voudra vivre ce genre de situation. J'ai le sentiment qu'avoir lu cet article avant m'aurait ouvert les yeux et que j'aurais pu franchir les obstacles plus facilement. On grandit et on prend de la maturité, même dans les pires épreuves.
Distribuez cet article à votre entourage, c'est leur rendre service. Et fuyez les manipulateurs comme si la peste était à vos trousses. Vous méritez du respect et ces gens n'en valent tout simplement pas la peine.
Boire du café empêche de dormir. Par contre, dormir empêche de boire du café.
Un petit conseil à la volée concernant la fonction clone() de PHP : si vous écrivez le code d'une classe dont vous souhaitez restreindre la possibilité de clone son objet pour avoir plus d'une instance, ça peut être une bonne idée de définir dans la classe la méthode magique __clone() et de lancer une exception si la fonction clone() est appelée.
En reprenant l'exemple de l'objet Singleton PHP :
classe Singleton{
// constructeur et méthodes
public function __clone(){
throw new Exception('Cet objet ne peut pas être cloné');
}
}L'appel à clone sur l'objet provoquera une erreur à l'attention du programmeur :$singleton1 = Singleton::getInstance();Fatal error: Uncaught exception 'Exception' with message 'Cet objet ne peut pas être cloné' in fichier...
$singleton2 = clone($singleton1);
Hier, comme beaucoup d'autres, j'ai téléchargé Ubuntu 10.04 LTS (Lucid Lynx) pour mettre à jour mon système. J'ai pris l'ISO plutôt que de faire la mise à jour réseau proposée par le gestionnaire d'updates du système d'exploitation. Comme la dernière fois quand je suis passé de Jaunty Jackalope à Karmic Koala, je me suis trompé et j'ai téléchargé l'image ISO du disque standard plutôt que l'alternate install CD.
J'ai suivi les instructions dans la section Upgrading Using the Alternate CD/DVD pour faire la mise à jour directement à partir de l'ISO téléchargé plutôt que de le graver sur un CD. En premier lieu, il faut monter le fichier comme si c'était un drive (à partir d'un terminal) :
sudo mount -o loop ~/Desktop/ubuntu-10.04-alternate-i386.iso /media/cdrom0
Ensuite, on lance la commande suivante pour démarrer le processus de mise à jour.
gksu "sh /cdrom/cdromupgrade"
Pour un novice, quand on regarde la documentation, on peut généralement transcrire les commandes telles quelles et ça fonctionne. Mais pourquoi ne pas les décortiquer pour mieux comprendre ce qu'on fait ?
Charger l'ISO
- sudo pour exécuter la commande en se substituant à l'utilisateur
- mount pour monter un système de fichiers
- -o pour spécifier la liste des options
- loop permet de faire en sorte que les fichiers du système de fichiers contenus à l'intérieur de l'image soient accessibles
- ~ est un alias pour indiquer le répertoire utilisateur (si votre utilisateur courant est code18, ce sera traduit par /home/code18
- le fichier ISO téléchargé
- /media/cdrom0 représente le point de montage où les fichiers pourront être accessibles
- gksu est un programme qui permet d'accéder aux droits administrateurs en mode graphique
- sh pour lancer l'appel à un script Bourne Shell
- le script à exécuter qui se trouve dans le point de montage
Quand on programme un script ou une routine, il est généralement d'usage d'avoir une idée sur le temps nécessaire à son exécution. Dans certains cas, on pourra apporter des modifications pour améliorer significativement la performance.
Plusieurs outils existent pour mesurer le temps d'exécution d'un script. Cependant, avec peu de moyens, on peut se tourner vers la bonne vieille méthode de calcul en effectuant deux lectures successives du temps courant.
L'idée est de noter une première fois l'heure au début du script et une seconde fois à la fin. Comme la durée d'exécution peut varier de quelques millisecondes à quelques minutes, nous avons intérêt à utiliser la plus petite unité de mesure du temps pour s'assurer de la meilleure précision.
Voici deux exemples :
JavaScript
var startTime = new Date().getTime();PHP
var elapsedTime = 0;
// votre code à mesurer ici
elapsedTime = new Date().getTime() - startTime;
console.log(elapsedTime);
$startTime = microtime(true);Pour les autres langages, le principe est le même. Trouvez la fonction ou l'objet qui permet d'obtenir le temps réel courant, faites deux lectures et soustrayez les pour obtenir le temps du script ou d'une portion du script. Vous pouvez même les conserver dans un fichier de log pour créer un jeu de statistiques et découvrir où est le bottleneck dans votre processus.
$arr = range(1, 1000000);
foreach($arr as $a){
// votre code ici
}
$endTime = microtime(true);
$elapsed = $endTime - $startTime;
echo "Temps d'exécution : $elapsed secondes";