Le cyberblog du coyote

 

Extra
Langues :

Editorial

Ce blog a pour objectif principal d'augmenter la culture informatique de mes élèves. Il a aussi pour ambition de refléter l'actualité technologique dans ce domaine.

vendredi 15 mai 2009

Initiation au traitement d'image avec Numpy

A la fin de ce tutoriel vous saurez récupérer les données brutes d'une image, les mettre en forme afin de les traiter et de reconstruire l'image résultat. Tout cela sera fait avec l'aide des librairies PIL et NumPy. Côté traitement d'images, nous traiterons la segmentation à deux seuils, la dilatation et l'érosion.

mercredi 6 mai 2009

Codes sources

Tout bon ingénieur vous le dira : plutôt que de réinventer la roue, regardons d'abord si quelqu'un n'a pas déjà fait quelque chose qui ressemble à notre projet. PythonFrance.com met à disposition des codes sources en Python proposés par des internautes. Il y en a pour tous les goûts.

dimanche 3 mai 2009

Plus Court Solveur de Sudoku

Voici un programme en Python de 173 caractères seulement qui serait le plus court solveur de sudoku connu actuellement :

def r(a): i=a.find('0') if i<0:print a [m in[(i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3)or a[j]for j in range(81)]or r(a[:i]+m+a[i+1:])for m in`14**7*9`]r(raw_input())

Ce programme est extrêmement compact et condensé, voire cryptique. Ce n’est pas la meilleure façon de programmer, mais ça révèle souvent la puissance cachée de certains langages. Ce programme est décrit en anglais et en détail ici, mais voici son principe en gros et en français:

def r(a): ... r(raw_input()) // définit la fonction “r” qui résout le sudoku, puis on l’appelle en passant en paramètre ce que l’utilisateur a entré au clavier. Ca doit être une chaine de 81 caractères contenant ligne par ligne les chiffres de 1 à 9 donnés, et des 0 aux emplacements vides.

i=a.find('0') if i<0:print a // au début de la fonction, on cherche le premier emplacement vide. Si on ne le trouve pas, on imprime le sudoku résolu
la partie principale de la fonction utilise deux concepts puissants de Python:

  • la “lazy evaluation” qui fait que l’expression “a or b” est équivalente à “if not(a):b”
  • la “compréhension de liste” qui permet de créer une liste en écrivant une boucle à l’intérieur de [crochets]. Par exemple “l = [x**2 for x in range(10)]” crée la liste des carrés des 10 premiers nombres entiers
ainsi cette expression [(i-j)%9*(i/9^j/9)*(i/27^j/27|i%9/3^j%9/3)or a[j]for j in range(81)] fournit la “liste d’exclusion” contenant les chiffres qui ne peuvent pas figurer dans le trou à la position i. On l’obtient en parcourant toutes les celllules et en ajoutant à la liste la valeur des cases a[j] situées sur la même ligne, la même colonne ou dans le même bloc que i. Le grand test compliqué détermine ces conditions en utilisant les opérateurs modulo (%), ou binaire (|) et ou exclusif (^).

Finalement, le [m in [...] or r(a[:i]+m+a[i+1:])for m in`14**7*9`] remplit successivement la grille avec les chiffres possibles en utilisant la ‘lazy evaluation’ une fois de plus : ce n’est que si le chiffre m n’est pas dans la liste d’exclusion qu’on execute la partie droite du or, laquelle appelle récursivement la fonction r en lui passant la grille en paramètre la grille a[:i]+m+a[i+1:]. Ici , l’opérateur + sert à concaténer des listes : d’abord les i-èmes premières cases, puis le chiffre m proposé pour la case vide, puis les cases à partir de la i+1 ème.

Ce programme utilise donc une approche “force brute” loin d’être optimale en temps de calcul : on essaie les chiffres possibles dans chaque case vide jusqu’à ce que ça marche.

Reste à découvrir une astuce de geek que je ne connaissais pas : 14**7*9 vaut 948721536, un nombre qui contient les chiffres 123456789, dans le désordre, mais ça va aussi pour notre application. Les backquotes ´…´ servent à former une chaine, comme d’ailleurs la fonction str(). L’avantage de ´14**7*9´sur “123456789″ ? ben c’est évident : il faut deux bytes de moins …

Source : Dr Goulu