jeudi 29 octobre 2015

Liste des processus - commande ps

la commande ps -ef permet de lister facilement les processus.... mais ce qui serait parfois utile de savoir, c'est l'état du processus.
Pour cela, nous avons la commande ps -aux  qui fourni un résultat similaire à ceci.

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   4464  2512 ?        Ss   sep17   0:02 /sbin/init
root         2  0.0  0.0      0     0 ?        S    sep17   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    sep17   4:49 [ksoftirqd/0]

yyy
La colonne STAT nous indique le statut du processus dont voici les principaux
  • D - Uninterruptible sleep - En sommeil et ne pouvant pas être arrêté (généralement en attente d' IO)
  • R - Running - Exécuté ou processus exécutable (dans la queue d'exécution)
  • S - Sleep - en sommeil et pouvant être interrompu (en attente d'événement)
  • T - Arrêté, soit suite à u signal de contrôle de job/processus ou parce qu'il est en cours de débogage (traced).
  • X - processus mort (dead). Nous ne devrions jamais voir ce statut
  • Z - Zombie, processus terminé et non repris en charge (collecté/libéré) par son processus parent.

dimanche 11 octobre 2015

Activer Google comme moteur de recherche par Defaut dans Firefox

Nous sommes quand même nombreux à vouloir utiliser Google comme moteur de recherche dans Firefox.
Comme c'est un moteur commercial, il n'est pas installé par défaut... et la recherche sur le net est un peu fastidieuse.

Voici donc comment faire:
1) Télécharger le greffons/plug-in "Google Search" sur le site de mozilla.

Cliquer sur le lien suivant et installer le plug-in

https://addons.mozilla.org/en-US/firefox/addon/google-default/

2) Ensuite, allez cliquer sur l'icone en forme de loupe dans la barre de recherche.

Cela affiche un menu et tout en bas, vous pouvez voir "paramètres de recherche".
Cliquez sur le point de menu "Paramètres de recherche"

3) Dans la fenêtre des paramètres de recherche, sélectionnez simplement le moteur de votre choix.... dans notre cas "Google"


Voili, voilou,

mardi 6 octobre 2015

Inférence entre dictionnaire et paramètres nommés

Cas pratique
J'ai un cas pratique où je veux recharger des données depuis un fichier json (une fois chargé, j'ai une liste de dictionnaire) PUIS les injecter dans une DB à l'aide de sqlAlchemy.
In [57]: d[0]
Out[57]: 
{'actif': 'Y',
 'libe': 'Le carbone lorraine',
 'name': '0200',
 'pnet': 50.0,
 'sync_id': 1.0}

In [58]: d[1]
Out[58]: 
{'actif': 'Y',
 'libe': 'BUSELURES',
 'name': '0201',
 'pnet': 50.0,
 'sync_id': 2.0}

Dans sqlAlchemy, j'ai définit un modèle pour mes tables.
En utilisant ce modèle (ici family_table), l'insertion est relativement simple:

q = family_table.insert()
q.execute( actif='Y', libe= 'Le carbone lorraine', name= '0200', pnet= 50.0, sync_id= 1.0 )

Mais ce qui serait vraiment cool, c'est appeler execute() directement avec le dictionnaire d[0], d[1], ...et se passer de la tache fastidieuse décrite ci-dessus. Comme sqlAlchemy utilise **kwargs, nous pouvons faire de l'inférence :-)

q = family_table.insert()
dic = d[0] # récuperer un dictionnaire
# La ligne suivante dit que dic doit être passé directement
# en tant que paramètre **kwargs de la fonction 
q.execute( **dic ) 

**KWargs - comment ça marche?
Définissons la fonction printkw() pour afficher les valeurs disponibles dans le paramètre **kwargs.
En fait, kwargs est un dictionnaire qui contient les paramètres nommés sous forme clé = valeur. Comme kwargs n'est pas un mot clé (mais une convention de nommage), on utilise le signe ** pour identifier kwargs (et ses propriétés extraordinaires) dans la déclaration de la fonction printkw()
Vous pourriez fort bien appeler ce paramètre **dico_des_parametre_nommes , mais il est préférable de respecter les conventions.

def printkw( **kwargs ):
   for k,v in kwargs.items():
      print( '%s = %r' % (k,v) )

Maintenant, si nous appelons la fonction printkw() avec des paramètres nommés, nous avons:

>>>printkw( name='hello', value=12, value2='test me' )
value2 = 'test me'
name = 'hello'
value = 12

Dans notre fonction printkw() nous pourrions facilement récupérer une valeur donnée avec l'instruction le_nom = kwargs['name']
Cela nous fournirait la valeur du paramètre "name".

Mais le plus intéressant, selon moi, réside au passage des paramètres par l'intermédiaire d'un dictionnaire. Il devient alors très facile de:
  • Passer de nombreuses valeurs d'une fonction à l'autre
  • De présenter une interface très flexible (surtout avec des DB) pour transmettre de nombreuses données
  • De faire une persistance des paramètres nommés dans une DB,Fichier, Json, service en ligne, etc
>>> d = { 'name':'hello', 'value':12, 'value2':'test me' }
>>> printkw( **d )
value2 = 'test me'
name = 'hello'
value = 12

La première ligne crée un dictionnaire avec les paramètre nommés (qui auraient pu provenir d'un fichier json comme dans l'intro de l'article).
La deuxième ligne appel printkw() en passant le dictionnaire d en tant que paramètres nommés (c'est à cela que sert ** )

Recharger un fichier json
Juste pour le fun, voici comment j'ai rechargé le fichier json dans la liste d.

import json
# retourne le nom de fichier pour les données famille
#    'c:\\python\\catflask-alpha\\toolbox\\family.json'
filename = json_filename( 'family' )
with open( filename ) as json_data:
    d = json.load( json_data )
    json_data.close()

vendredi 18 septembre 2015

Inspection des propriétés - petite technique pratique

Voici une petite technique intéressante que vous pouvez utiliser dans un python Interactif (comme IEP par exemple).

Cela fonctionne avec tous les objets... mais dans mon cas, c'est avec un module que j'ai utilisé cette technique. Dans l'article précédent, je voulais recharger le module model.py ... mais je voulais aussi m'assurer que mes objets user_table, group_table, permission_table, etc étaient maintenant disponible!

Les petits trucs à retenir de cet article seront
  [ attr for attr in dir(m) if '_table' in attr]
  [ '%s : %s' % (attr.ljust(25), getattr(m,attr)) for attr in dir(m) if '_table' in attr ]

Mais pour les plus curieux, je vous propose de lire les différentes étapes.

1) Récupérer la référence vers module
import sys
m = sys.modules['model']

2) Faire un dir() --> inefficace
Faire un dir() sur un module (ou un objet) peut retourner un contenu fastidieux à parcourir suivant la taille de l'objet. Dans le cas ci-présent, il n'y a pas moins de 193 entrées! Gloups!

dir( m )
Out[67]: 
['AliasOption',
 'AttributeExtension',
 'BIGINT',
 'BINARY',
 'BLOB',
 ...
 'with_parent',
 'with_polymorphic']

In [68]: len( dir(m) )
Out[68]: 193

3) Utilisons une compréhension list
Avec une simple compréhension liste basé sur dir(), nous allons pouvoir filtrer le contenu retourné à l'aide de l'instruction if.
Comme dir() liste les attribut, il suffit de tester si la chaine de caractère '_table' apparaît dans le nom de l'attribut.
C'est magique :-)

[ attr for attr in dir(m) if '_table' in attr]
Out[69]: 
['group_permission_table',
 'group_table',
 'permission_table',
 'user_group_table',
 'user_table']

4) Avec les valeurs svp
Avoir les noms des attributs c'est bien, avec leur valeur c'est encore mieux!
Cette fois-ci, nous utilisons getattr() pour obtenir la valeur et nous justifions avec ljust() pour le confort de lecture.

In [72]: [ '%s : %s' % (attr.ljust(25), getattr(m,attr)) for attr in dir(m) if '_table' in attr ]
Out[72]: 
['group_permission_table    : tf_group_permission',
 'group_table               : tf_group',
 'permission_table          : tf_permission',
 'user_group_table          : tf_user_group',
 'user_table                : tf_user']

Attention, c'est uniquement pour faire de l'investigation en live!!!

5) Avec le représentation des valeurs
Si vous jouez avec python depuis un moment, vous avez certainement déjà rencontré la fonction __repr()__. Cette dernière est utilisée par l'interpréteur pour afficher plus de détails  sur les objets (et pas uniquement leur adresse).
Si cela est pratique, cela peut aussi fournir du contenu très... touffu selon les circonstances.

Cette version du script remplace uniquement un des %s par %r (pour demander l'affichage de la "représentation").

In [73]: [ '%s : %r' % (attr.ljust(25), getattr(m,attr)) for attr in dir(m) if '_table' in attr ]
Out[73]: 
["group_permission_table    : Table('tf_group_permission', MetaData(bind=Engine(postgresql://dom:***@hp-minty/dom)), Column('id_permission', Integer(), ForeignKey('tf_permission.id'), table=), Column('id_group', Integer(), ForeignKey('tf_group.id'), table=), schema=None)",
 "group_table               : Table('tf_group', MetaData(bind=Engine(postgresql://dom:***@hp-minty/dom)), Column('id', Integer(), table=, primary_key=True, nullable=False), Column('group_name', Unicode(length=16), table=, nullable=False), schema=None)",
 "permission_table          : Table('tf_permission', MetaData(bind=Engine(postgresql://dom:***@hp-minty/dom)), Column('id', Integer(), table=, primary_key=True, nullable=False), Column('permission_name', Unicode(length=16), table=, nullable=False), schema=None)",
 "user_group_table          : Table('tf_user_group', MetaData(bind=Engine(postgresql://dom:***@hp-minty/dom)), Column('user_id', Integer(), ForeignKey('tf_user.id'), table=, primary_key=True, nullable=False), Column('group_id', Integer(), ForeignKey('tf_group.id'), table=, primary_key=True, nullable=False), schema=None)",
 "user_table                : Table('tf_user', MetaData(bind=Engine(postgresql://dom:***@hp-minty/dom)), Column('id', Integer(), table=, primary_key=True, nullable=False), Column('user_name', Unicode(length=16), table=, nullable=False), Column('password', Unicode(length=40), table=, nullable=False), Column('display_name', Unicode(length=255), table=, default=ColumnDefault('')), Column('created', DateTime(), table=, default=ColumnDefault(. at 0x04560B70>)), schema=None)"]
Comme vous pouvez le constaté, c'est nettement plus chargé... et avec le retour à la ligne, c'est franchement illisible)
Comme quoi "le mieux est parfois l'ennemi du bien".

Voila, Happy Python Hacking ;-)

Recharger un module Python à la volée

Il y a peu, je vous parlais d'IEP dans ce billet "IEP: un éditeur Python interactif convivial (Windows, Mac, Linux)".

Environnement bien pratique pour faire des tests et je découvre justement SqlAlchemy.
J'étais justement entrain de coder un petit module de test model.py lorsque je me suis demandé comment recharger mon module!
IEP - édition d'un module "model.py"

J'avais déjà fait un import model ... mais ayant modifié le code, je voulais savoir comment le recharger.
Voici donc comment faire...

Option 1 - à la dure
import sys
del( sys.modules['model'] ) # virer le module "model.py"
from model import *         # ré-importer le module "model.py"

Option 2 - importlib.reload()
import importlib
import sys
a = sys.modules['model'] # Référence vers le module
importlib.reload( a )    # Demander à Python de recharge le module

jeudi 17 septembre 2015

Entête pour fichier Python

Voici une proposition d'entête de fichier Python à partir d'information collectées ici et là.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Foobar.py: Description of what foobar does."""

__author__ = "Rob xxxx, Gavin xxxx, and Peter xxxx"
__copyright__ = "Copyright 2007, The xxxx Project"
__credits__ = ["Rob xxx", "Peter xxx", "Gavin xxxx",
                    "Matthew xxxx"]
__license__ = "GPL"
__version__ = "1.0.1"
__maintainer__ = "Rob xxx"
__email__ = "rob@spot.xxx.edu"
__status__ = "Production"


from sqlalchemy import *
from sqlalchemy.orm import *
from datetime import datetime
....

vendredi 4 septembre 2015

IEP: un éditeur Python interactif convivial (Windows, Mac, Linux)

IEP est un outil vraiment très pratique et agréable permettant de faire du prototypage en Python dans un milieu ergonomique.
Nous ne parlons pas de développement (qui est un autre domaine) mais de Python Interactif (et même IPython).
IEP - Un python interactif vraiment convivial.
J'aime employer Python en mode interactif... c'est vraiment pratique pour faire du prototypage ou essayer des nouvelles fonctions. Il y a aussi son grand frère IPython que je ne connais pas encore très bien.

Limite de Python Interactif en mode console
Par contre, si ces environnements consoles sont plus que pratique du fait de leur mode console, ils deviennent également pénibles lorsqu'il faut faire un "fix" dans une fonction mal définie.
Il faut recommencer la saisie ligne a ligne... ce n'est pas gênant si c'est une fois mais autrement plus ennuyant en usage intensif.

Je voulais charger dynamiquement le contenu d'une table postgresql dans un objet SqlAlchemy (via l'ORM)... puis sauver les objets dans un fichier JSON. Le but est d'exporter les données sur un serveur FTP pour rechargement dans une DB en ligne. Alors oui, vu le nombre de manipulation, j'étais un peu à l'étroit dans la version console.

IEP... KASEKO?!?

J'ai donc cherché un environnement Python Interactif plus convivial - aussi sous Windows - et je suis tombé sur Interactive Editor for Python (IEP)

C'est toujours un Python interactif (IPython) auquel est associé une gestion de fichier, quelques outils, un logger et des fonctionnalités vraiment efficaces.
Une combinaison idéale pour une utilisation en mode Interactif:
  • Exécution du texte sélectionné à la volée (dans l'interpréteur)
  • Exécution du script ou du contenu du fichier
  • Explorateur de fichier
  • Explorateur de classe
  • Auto complétion
  • Python Interactif fonctionnant dans un thread séparé
    Autorise donc la poursuite du coding pendant une phase d'éxécution.
  • Excellent support de raccourcis clavier!
    Capital pour allez vite.
  • etc
L'installer Windows ne fait que 10Mb... tout à fait raisonnable pour les services rendus.

Ressources