Python – Buscando a Wally.txt

Objetivo: mostrar cómo recorrer recursivamente el sistema de archivos en Python.

Wally.txt es un fichero juguetón, caprichoso y escurridizo. A la primera de cambio, en cuanto le das la espalda, se esconde en el sistema de ficheros y ¡ponte entonces a buscarlo!

Lo que Wally.txt ignora es que somos programadores en Python, de modo que un simple juego como el escondite puede resultarnos incluso aburrido de lo trivial que es. Pero, si lo que quiere es jugar, adelante: contemos hasta 30 y que se esconda donde quiera.

Dentro del virtualmente infinito maletín de herramientas de que dispone Python hay un módulo que tenemos la obligación de dominar y que hoy presentaremos con una demostración básica. Nos referimos al módulo os, que proporciona una serie de utilidades para acceder a la funcionalidad del sistema operativo subyacente. Y lo elegante de Python es que lo hace de un modo portable, es decir, facilitando una interfaz común tanto si lo que hay por debajo es un Linux, Mac o Windows, pudiendo ejecutar, sin ninguna (o poca) modificación, el mismo código en cualquier plataforma.

Abrimos la caja de herramientas con una sencilla línea:

import os

Para recorrer el arbol de ficheros invocaremos al generador os.walk(). A grandes rasgos, un generador no es más que una función especial que nos va a devolver una serie de valores sobre los que podremos iterar. En esencia, os.walk() funciona del siguiente modo:

La función recorre, paso a paso, como un incansable turista, todo el sistema de archivos recursivamente, a la par que va tomando fotos cada vez que se detiene en un directorio.

Cada foto que toma consiste en una tupla compuesta de tres elementos:

– la ruta del directorio en el que se halla (un string)
– los subdirectorios que cuelgan de ahí (una lista de strings)
– los ficheros que ve en ese nivel (otra lista de strings)

Una vez tomada esa foto, se sumerge en un nuevo subdirectorio, tomando una nueva instantánea de lo que ve. Y así sucesivamente hasta haber recorrido exhaustivamente el sistema de archivos a partir de donde comenzó su trabajo.

De modo que ya podemos esbozar una solución a nuestro problema: por cada tupla devuelta, consultemos el último elemento (el tercero, que tiene por índice 2) y comprobemos si en esa lista está Wally.txt. En caso afirmativo devolvemos el directorio desde el que se tomó la foto, contenido en el primer elemento de la tupla (de índice 0).

La iteración a lo largo y ancho del generador es simple:

for foto in os.walk('c:\\'):

Como argumento, facilitamos el directorio desde el que comenzará la búsqueda. Hemos necesitado escapar la barra inclinada hacia atrás (el backslash) precediéndola de otra igual, pues ese símbolo tiene un significado especial para Python. Si estás en un Linux o Mac, con la barra hacia delante, /, no necesitas tomar esa precación, obviamente.

Una vez hemos tomado cada foto, echamos un vistazo a ver si en ella está Wally. En foto[2] se almacena una lista con cada uno de los ficheros que hay en ese nivel. Buscar a Wally.txt es inmediato:

if 'Wally.txt' in foto[2]:

Si encontramos a Wally.txt el programa debe devolver el directorio en el que se encuentra, que es donde ha sido tomada la foto, es decir, el string almacenado en foto[0]:

print(foto[0])
break

Con el break interrumpimos la iteración para que no siga buscando más una vez el no tan huidizo, como quería hacernos creer, Wally.txt ha sido localizado.

El código hasta el momento:

import os

for foto in os.walk('c:\\'):
     if 'Wally.txt' in foto[2]:
          print(foto[0])
          break

Como remate, podemos unir la ruta donde ha sido localizado con el nombre del fichero. Para esto bastaría una simple concatenación:

print(foto[0] + '\\' + 'Wally.txt')

Pero no sería una solución elegante, pues presupone que estamos ante un Windows. En aras de la portabilidad, dejemos entonces que Python decida cuál es el símbolo apropiado según en qué plataforma se ejecute:

print(os.path.join(foto[0], 'Wally.txt'))

La función join() del módulo os.path se encarga de unir inteligentemente ambos términos.

Contamos: 1, 2, 3, …, 30.

import os

for foto in os.walk('c:\\'):
     if 'Wally.txt' in foto[2]:
          print(os.path.join(foto[0], 'Wally.txt'))
          break

Que, en mi caso particular, devuelve:

>>>
c:\aqui\nadie\me\encontrara\Wally.txt

(Que te creías tú eso…)

Asómate a la documentación oficial de Python y echa un vistazo a la funcionalidad del módulo os. Esta solo ha sido una visita de cortesía, aunque prometo repetirla de cuando en cuando.

Javier Montero Gabarró


http://elclubdelautodidacta.es/wp/2016/02/python-buscando-a-wally-txt/


El texto de este artículo se encuentra sometido a una licencia Creative Commons del tipo CC-BY-NC-ND (reconocimiento, no comercial, sin obra derivada, 3.0 unported)


El Club del Autodidacta


Consulta el índice completo de artículos relacionados con Python.

Safe Creative #1602036431538

Protegiendo la escritura de código

Los programadores que utilizamos WordPress para mostrar código nos las vemos y deseamos para que nuestras líneas de programa queden medio decentes a la hora de ser presentadas en el blog.

Un lenguaje de programación como Python utiliza las indentaciones para establecer correctamente los límites de los bloques. Si pegamos el código directamente en el editor HTML de WordPress y previsualizamos el resultado observaremos que todo el espaciado extra ha sido eliminado. Podemos recurrir a etiquetas como <pre> … </pre>, que harán su mejor esfuerzo por mantenernos el formato, pero aún así no tenemos la certeza de que WordPress o algún plugin que tengamos instalado modifique su contenido.

Publicar los artículos del curso de HTML también ha sido truculento. No podía recurrir al editor HTML porque interpretaría las etiquetas. Pegando el código en el editor visual conseguía respetarlas, pero debía ser muy cuidadoso cada vez que conmutaba editores y asegurarme de que no se obtenían resultados imprevistos después de haber enmarcado el texto en un bloque <code> para visualizarlo con una fuente de espaciado fijo.

Finalmente, opté por deshabilitar el editor visual (algo que debía haber hecho desde el primer momento) y escribir los códigos especiales HTML directamente recurriendo a su código de entidad, lo cual convertía el trabajo en una labor de chinos, pero así me aseguraba de que no iban a producirse sorpresas después.

En resumen, la presentación de código fuente en un blog era toda una odisea chapucera.

Afortunadamente existen soluciones inteligentes en forma de plugin que nos ayudan a que nuestro código aparezca inmaculado. Voy a hablaros de una que he adoptado yo y en breve activaré en el blog: el plugin Preserve Code Formatting, de Scott Reilly (alias coffee2code).

Su funcionamiento es muy sencillo: todo lo que escribamos dentro de <code> y de <pre> ( o en otras etiquetas que también podemos especificar) quedará protegido y no será transformado ni por WordPress ni por otros plugins.

El lugar perfecto para nuestros bloques de código.

Tengo el plugin instalado pendiente de activación. En cuanto lo haga, todos los trucos que he tenido que hacer para mostrar el código en series como la de Python o HTML se volverán contra mí y los programas aparecerán descabalados.

Uno a uno deberé corregir cada artículo teniendo en cuenta las nuevas normas de preservación de código. Pero es algo que debo hacer ya y cuanto más tarde en demorarlo más trabajo me supondrá después.

Javier Montero

Uso de cookies

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies