Je me suis mis depuis quelques mois à Python. Il y a énormément de choses très appréciables dans le langage et sa logique. À vrai dire, plus le temps passe, et moins je lui trouve de points faibles. Sûrement le début d’une longue série d’articles, de tous niveaux.

Mais en attendant, je vais ici relater mon premier bout de code un petit peu « tricky ». Python propose un lot de méthodes pour accéder aux répertoires/fichiers : os.listdir, walk… Mais ces méthodes ont le défaut de retourner une liste construite des éléments. Du coup, lorsque le temps de traitement devient critique, on aimerait bien pouvoir itérer directement sur les descripteurs de fichiers sans attendre une liste de potentiellement 10 000 éléments. Bref, la possibilité d’accéder aux fonctions Posix opendir() et readdir().

Le soucis ? Python ne propose pas ces fonctions. Mais il y a la possibilité d’accéder à des API du langage C, et dans un environnement Unix, on y retrouve nos chères fonctions si convoitées ! Après avoir étudié cette piste, voilà un snippet fort utile :

#!/usr/bin/python
from ctypes import CDLL, c_char_p, c_int, c_long, c_ushort, c_byte, c_char
from ctypes import Structure, POINTER
from ctypes.util import find_library

class c_dir(Structure):
    """ Defined C struct DIR """
    pass

class c_dirent(Structure):
    """ Directory entry structure equivalent """
    _fields_ = (
        ('d_ino', c_long),  # inode number
        ('d_off', c_long),  # offset to the next dirent
        ('d_reclen', c_ushort), # length of this record
        ('d_type', c_byte),  # type of files; os specific
        ('d_name', c_char * 4096) # filename
        )

c_dirent_p = POINTER(c_dirent)
c_dir_p = POINTER(c_dir)
c_lib = CDLL(find_library("c"))

opendir = c_lib.opendir
opendir.argtypes = [c_char_p]
opendir.restype = c_dir_p

readdir = c_lib.readdir_r
readdir.argtypes = [c_dir_p]
readdir.restype = c_dirent_p

closedir = c_lib.closedir
closedir.argtypes = [c_dir_p]
closedir.restype = c_int

def listdir(path):
    """
    A generator to return the names of files in the directory passed in
    """
    dir_p = opendir(".")
    try:
        while True:
            p = readdir(dir_p)
            if not p:
                break
            yield p.contents.d_name
    finally:
        closedir(dir_p)

Attention, listdir() retournera les répertoires « . » et « .. » ! Notez l’utilisation du yield pour définir ici un générateur (sujet d’un autre article). De ce fait, notre fonction s’utilise comme cela :

if __name__ == "__main__":
    for name in listdir("."):
        print name

En espérant que ça puisse servir à quelqu’un d’autre…

fk_breaker

Aux débuts de Piwam, les relations décrites dans le fichier schema.yml n’étaient pas nommées explicitement. Du coup, lors de la génération du schmilblick par Propel (Model + SQL), c’est InnoDB qui s’occupait de trouver un nom à ces relations.

Aujourd’hui, j’écris le script permettant de migrer de Piwam 1.1.2 vers Piwam 1.2, script qui nécessite d’effectuer des opérations sur des foreign keys, en l’occurence les supprimer… Comment diable alors faire référence à une clé étrangère dont on ne connait pas le nom ? Après avoir farfouillé partout sur la toile, il apparaît qu’il n’y a pas moult solutions pour arriver à mes fins. On se retrouve ainsi soit à écrire des procédures, soit à faire appel à l’information_schema. Enfin, certains proposent une utilisation de SHOW TABLE avec les arguments qui vont bien, puis parser la sortie pour récupérer les noms des contraintes. J’ai pu par ailleurs découvrir la version Firebird :

SELECT RDB$CONSTRAINT_NAME
FROM RDB$RELATION_CONSTRAINTS
WHERE RDB$CONSTRAINT_NAME LIKE 'FK%' AND
RDB$RELATION_NAME='MATABLEAMOI'
ORDER BY RDB$CONSTRAINT_NAME

Ne pouvant exécuter de requêtes propres à Firebird, ni même de procédures (Piwam tourne sous trop de types de serveurs différents aux configurations et autorisations bien différentes), j’ai finalement opté pour une solution ma foi fort simple. Accrochez-vous, c’est du SQL de très haut niveau (hum…).

CREATE TABLE ma_table_copy AS SELECT * FROM ma_table;

Une copie réalisée de la sorte a pour effet de ne copier que la structure et la table, en omettant indexes et contraintes. Lent, mais portable (je ne sais pas si l’adjectif est vraiment adapté) et pratique. Tout ça pour dire, bordel, une bonne fois pour toutes, n’oubliez pas de nommer vos contraintes explicitement, ça facilite grandement la maintenance !

QuicklookPetite astuce trouvée récemment, certainement pas vitale mais toujours pratique, pour les utilisateurs de MacOSX >= 10.5. Pour avoir un affichage un peu plus classe des répertoires par Quick Look, ouvrez un terminal et tapez les 2 commandes suivantes :
> defaults write com.apple.finder QLEnableXRayFolders 1
> killall Finder

Voilà de quoi s’affranchir du simpliste affichage par défaut !

Chase Jarvis a eu la bonne idée de présenter des outils adapté à la correction d’un phénomène bien trop visible lorsque des enregistrement de vidéos sur les appareils munis de capteurs CMOS.

Ce phénomène est dû au fonctionnement de l’enregistrement, qui se fait verticalement, ligne par ligne. De ce fait, filmer un objet ou une scène en mouvement donne un rendu étrange, comme si le vidéaste en herbe filmait après avoir descendu une bonne bouteille.

Le Rolling Shutter en action

La solution présentée ici permet, vous allez le voir, de corriger cet effet sur une scène globale, ou d’appliquer cette correction à seulement un objet, déterminé comme un mouvement par rapport à une scène globale.

Source

VBoxManage clonevdi

Si vous utilisez VirtualBox, et que vous avez besoin de plus d’espace pour votre système émulé puisse évoluer correctement, vous avez sans doute constater que non, il n’y a pas de resizer automagique permettant d’augmenter la taille du disque virtuel VDI.

Il existe néanmoins une petite astuce qui sert de solution, et qui se résume en 2 étapes :

  1. Créez un nouveau disque virtuel, plus grand
  2. Clonez l’ancien disque VDI dans le nouveau, grâce à l’outil « VBoxManage ». Concrêtement, la commande ressemble à cela :
  3. VBoxManage clonevdi /path/to/firstDisk.vdi --existing /path/to/bigDisk.vdi

Et voilà, il ne vous reste plus qu’à virtualo-brancher votre nouveau grand disque ! N’oubliez pas cependant que pour le système virtualisé, la taille de la partition (et non du disque) est toujours la même, il vous faudra donc sûrement agrandir la dite partition.

Propriétaire d’un téléviseur LCD de marque Philips, je constate que ce dernier possède un port USB sur le côté. « Chouette ! », je dis-je, « je vais pouvoir aisément regarder mes vidéos sans brancher le PC« .  Sauf que…

Sauf qu’une fois le disque dur branché, le menu propose seulement « pictures » et « music« . Pas de menu « videos » ou « movies« . Curieux… Après quelques recherches, il apparaît qu’il existe une astuce…  La plupart des récents modèles de TV LCD de la marque sont en effet capables de lire des vidéos au format MPEG-1 et MPEG-2, mais Philips a semble-t-il décidé que ce n’était pas bon d’en faire profiter les utilisateurs.

Comment diable contourner cette restriction ? Customiser le firmware ? Peut être. Mais il existe une astuce beaucoup plus simple. Plus qu’une astuce, c’est un véritable easter-egg. Un de ces trucs cachés qui vous rendent fou. Il suffit en effet de nommer le fichier vidéo à lire (encodé en MPEG) avec le nom de fichier SuperShopDemo.mpg (respectez les majuscules). Une fois le périphérique USB branché sur le téléviseur, la magie opère… la vidéo se lance automatiquement. Une fonctionnalité sûrement laissée à l’intention des vendeurs, dont on ne souhaiterait pas faire profiter les acheteurs…

Et oui… il existe maintenant une version light du lecteur de flux RSS de Google. Ce dernier se résume à une chose : lire les news. Pour tester cette version, un petit tour sur google.com/reader/lite/

Ça y’est, vous êtes en train d’écrire vos tests fonctionnels pour votre application symfony. MAIS votre application – ou une partie – nécessite une identification de la part de l’utilisateur. Il y a bien sûr la solution qui consiste à systématiquement remplir le formulaire dans chaque fichier de test.

Je vous présente ici une solution pour palier à cela. La solution consiste à étendre la classe sfTestFunctional du framework. Ce qui donne, par exemple :

class sfGuardTestFunctional extends sfTestFunctional
{
 public function __construct($browser, $lime = null, $testers = array())
 {
   parent::__construct($browser, $lime, $testers);
   $this->signin(array('username' => 'foo', 'password' => 'bar'));
 }

 /**
  * Perform user authentication
  *
  * @param   array of String         $user_data
  * @return  sfGuardTestFunctional   $this
  */
 public function signin($user_data)
 {
   return $this->info(sprintf('Login as "%s"', $user_data['username']))->
          get('/admin/login')->
          click("S'identifier", array('login' => $user_data))->

          with('form')->begin()->
            hasErrors(false)->
          end()->

          with('user')->begin()->
            isCulture('fr_FR')->
            isAuthenticated(true)->
          end()->

          with('request')->begin()->
            isParameter('module', 'admin')->
            isParameter('action', 'login')->
          end()->

         isRedirected()->
         followRedirect();
 }
}

De cette manière, dans votre fichier de test il vous suffira d’instancier votre browser avec votre nouvelle classe :

$browser = new sfGuardTestFunctional(new sfBrowser('my_vhost'));

Et voilà, vous pouvez vous considérer comme identifié et écrire directement vos tests fonctionnels ! La solution présentée ici est minimale, la mise en forme du code PHP avec Blogspot n’étant pas des meilleure et votre motivation étant sans doute plus grande à déchiffrer 20 lignes de code plutôt que 42.

Une petite mise en oeuvre de ce cette classe, mise en place au sein de Piwam. L’exemple est destiné à la version 1.2 du framework..

C’est un point très mal explicité dans la documentation de symfony. Lorsque vous être en train de concevoir votre schéma au sein du fichier eponyme – schema.yml -, vous aimeriez bien avoir le contrôle de vos champs de type DECIMAL, non ?

La documentation n’étant pas très bavarde, peut être comme moi vous contentiez vous d’indiquer :

amount:   { type: decimal }

Pour exécuter ensuite des requêtes SQL bien placées pour modifier ce ce champ et lui affecter par exemple un stockage de 3 chiffres après la virgule. Je n’avais pas trouvé la réponse immédiatement, mais après un petit tour On Ze Ouaib, j’ai enfin déniché ce qui me manquait :

amount:  { type : decimal, size: 8, scale: 2 }

Pour un champ de type DECIMAL(8,2). Reste plus qu’à compléter la documentation symfony

Eclipse est un outil fabuleux. Complet. Rapide. Puissant. Ne faîtes pas attention au mot rayé. Bien utililsé, cet IDE libre peut rapidement montrer une puissance décuplée. Je ne pense pas utiliser Eclipse à 100%, ni même à 75%, néanmoins j’utilise un certain nombre de raccourcis, et je suis surpris de voir que bon nombre de personnes ne s’en servent pas – sûrement par méconnaissance.

Une petite compilation de mes combinaisons de touches préférées :

  • Ctrl (ou Pomme) + Shift + R : Ouvrir une ressource
    C’est la combinaison que j’utilise toutes les 30 secondes. Un panneau s’ouvre, et vous pouvez accéder à vos différents fichiers, plutôt que d’aller chercher une souris, de cliquer partout pour ouvrir le bon répertoire puis enfin de double cliquer sur un nom de fichier (avec un peu de chance, pas le bon).

  • Ctrl + Shift + F : Formatter le code source
    Quoi ? Vous ne connaissiez pas ? Impossible… Un petit coup de formatter magique, et hop, un code tout propre ! Dans la pratique, je trouve le formattage HTML un peu étrange, même une fois personnalisé. Mais pour ce qui est des autres langages, c’est du bonheur. Si vous n’aimez pas le formatter par défaut, il est bien sûr configurable !

  • Alt + Entrée : Afficher les propriétés
    À effectuer sur une ressource (dans l’onglet explorer typiquement). Vous permet d’afficher le volet de propriétés de la ressource sélectionnée. Fini les clics droits qui mènent à un menu contextuel infiniment long.

  • Ctrl + M : Maximiser / Réduire
    Un raccourci surtout utile pour ceux qui utilisent un petit Netbook, ou pour ceux qui travaillent sur des fichiers larges, dépassant allègrement disons les 120 colonnes. Une combinaison assez simple qui peut rendre le développement plus agréable.

  • Ctrl + H : Le super chercheur de la mort
    Sûrement le plus connu de tous… (?) Une sorte de Ctrl + F magique, un mega-chercheur-trouveur. Vous permet d’effectuer une recherche sur une ressource complète (projet, repertoire, seulement certains fichiers, etc…)

J’espère que cette courte liste sera à même de vous servir au quotidien. Si vous utilisez vous même d’autres raccourcis non mentionnés faîtes le savoir !