C’est la séance [[1B5]] de la formation 2012-2013. Ce TP met en œuvre la notion de parcours dans un arbre. L’arbre en question est celui du système de fichiers : c’est donc l’occasion d’introduire un peu de programmation système en Python 3. == Tâche 1 : recherche de fichier == On va écrire un programme : * qui prend en entrée un `dossier` et un `nom` de fichier, * qui recherche si un fichier `nom` apparait dans le `dossier` ou dans ses sous-dossiers, * qui affiche le chemin complet vers ce fichier. === Préliminaires === Pour obtenir la liste des éléments d’un dossier, on utilise la fonction `os.listdir` : {{{#!highlight python import os os.listdir() }}} affichera le contenu du dossier courant (sous Windows, c’est probablement celui où se trouve l’interpréteur python). Testez. {{{#!wiki tip Il est possible de changer le dossier courant avec la fonction `os.chdir`. Pour construire un chemin, on peut utiliser la fonction `os.path.join` qui s'occupe d'ajouter les séparateurs de dossier (`\` sous Windows, `/` dans le reste du monde). }}} Par exemple, sous Windows: {{{#!highlight python os.chdir(os.path.join('/','Documents and Settings','Utilisateur','Mes documents','ISN','1B5')) }}} vous amènera dans `\Documents and Settings\Utilisateur\Mes documents\ISN\1B5`. Pour savoir si un chemin mène vers un dossier ou un fichier, on utilise la fonction `os.path.isdir`. {{{#!highlight python >>> os.path.isdir(os.path.join('/','Documents and Settings')) True >>> os.path.isdir(os.path.join('/','Python32','README.txt')) False }}} Testez. === Au travail === Mettez d’abord au point un algorithme de parcours dans le système de fichier : de quelle structure s’agit-il (un arbre, oui, mais de quel genre) ? quel parcours faire ? Écrivez alors une fonction : {{{#!highlight python def cherche_fichier(dossier,nom): ... }}} qui renvoie la liste des chemins des fichiers `nom` accessibles à partir de `dossier`. === Extensions possibles === Si vous êtes à l’aise, vous pouvez considérer les extensions suivantes. Si vous avez déjà passé beaucoup de temps sur ce qui précède, mieux vaut passer à la tâche 2. ==== Permettre de rechercher un sous-mot ==== Si on cherche tous les fichiers python, la fonction précédente ne sert pas à grand chose. On voudrait utiliser des motifs du genre `*.py`. Ça tombe bien, il y a aussi une bibliothèque python pour ça : `fnmatch`. {{{#!highlight python >>> import fnmatch >>> fnmatch.fnmatch('toto.py', '*.py') True >>> fnmatch.fnmatch('totopy', '*.py') False }}} Étendez la fonction de recherche en : {{{#!highlight python def cherche_motif(dossier,motif): ... }}} ==== Recherche multicritère: nom, taille, date, ... ==== On peut connaître la taille d’un fichier avec la fonction `os.path.getsize`. La date de dernière modification est obtenue avec `os.getmtime`. Genéralisez la fonction de recherche en : {{{#!highlight python def cherche_test(dossier,test): ... }}} où `test` spécifie des critères à vérifier pour qu’un fichier soit retenu. On discutera ensemble des solutions possibles pour donner ces critères (c’est la seule vraie difficulté ici). == Tâche 2 : calcul de l’occupation du disque == On cherche maintenant à estimer l’espace disque occupé par le contenu d’un dossier (et de ses sous-dossiers). Rappelons (?) que la taille d’un fichier est donnée par la fonction `os.path.getsize` : {{{#!highlight python import os for fichier in os.listdir(): print('{nom:20s}\t{taille:10d}'.format( nom=fichier, taille=os.path.getsize(fichier), )) }}} affichera la liste des fichiers du dossier courant ainsi que leur taille (en octets). === Au travail === Écrivez une fonction : {{{#!highlight python def utilisation_disque(dossier): ... }}} qui renvoie la quantité d’espace disque (en octets) occupée par le contenu du `dossier`. === Extensions possibles === Écrivez une fonction : {{{#!highlight python def affiche_utilisation_disque(dossier,profondeur): ... }}} qui affiche récursivement la taille occupée par les sous-dossiers, jusqu’à une `profondeur` fixée. L’affichage devrait reproduire l’arborescence. Ajoutez des arguments optionnels pour : * trier les résultats par taille, ou par nom ; * spécifier une unité autre que l’octet ; * afficher des barres proportionnelles à la taille occupée par les sous-dossiers ; * générer (avec PIL) une représentation graphique de l’utilisation du disque dur (barres ou camembert). == Si ce qui précède n’a été qu’une promenade pour vous == Créez une interface graphique pour l’un des programmes précédents.