Per l'esercizio Puzzle dei log, utilizzerai il codice Python per risolvere due rompicapi. Questo esercizio utilizza il modulo urllib, come mostrato nella sezione Utility Python. I file per questo esercizio si trovano nel "logpuzzle" all'interno di google-python-exercises (scarica google-python-exercises.zip se non lo hai già fatto, vedi Configurazione per i dettagli). Aggiungi il codice al file "logpuzzle.py". .
L'immagine di un animale è stata suddivisa in molte immagini strette a strisce verticali. Le immagini a strisce si trovano da qualche parte su Internet, ciascuna con il proprio URL. Gli URL sono nascosti in un file di log del server web. La tua missione è trovare gli URL e scaricare tutte le strisce di immagini per ricreare l'immagine originale.
Gli URL delle sezioni sono nascosti all'interno dei file di log Apache (il server web apache open source è il server più utilizzato su internet). Ogni file di log proviene da un server e gli URL delle sezioni desiderati sono nascosti all'interno dei log. Il file di log codifica il server da cui proviene il server: il file di log zoo_code.google.com proviene dal server code.google.com (formalmente, diremo che il nome del server è quello che segue la prima barra di sottolineatura). Il file di log animale_code.google.com contiene i dati relativi all'animale l'immagine di un rompicapo. Sebbene i dati nei file di registro abbiano la sintassi di un vero server web Apache, i dati che vanno oltre il necessario per il puzzle sono dati randomizzati provenienti da un vero file di registro.
Ecco come appare una singola riga del file di log (questo è esattamente l'aspetto dei file di log di Apache):
10.254.254.28 - - [06/Aug/2007:00:14:08 -0700] "GET /foo/talks/ HTTP/1.1" 200 5910 "-" "Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4"
I primi numeri sono l'indirizzo del browser che effettua la richiesta. La parte più interessante è "GET path HTTP" che mostra il percorso di una richiesta web ricevuta dal server. Il percorso stesso non contiene mai spazi ed è separato da GET e HTTP da spazi (suggerimento regex: \S (S maiuscola) corrisponde a qualsiasi carattere diverso da uno spazio). Trova le righe nel registro in cui la stringa "puzzle" all'interno del percorso, ignorando le numerose altre righe del log.
Parte A - File di log negli URL
Completa la funzione read_urls(filename) che estrae gli URL del puzzle dall'interno di un file di log. Trova tutti i "rompicapo" nel file di log. Combina il percorso di ogni URL con il nome del server del nome file per formare un URL completo, ad esempio "http://www.example.com/path/puzzle/from/inside/file". Escludi gli URL che appaiono più di una volta. La funzione read_urls() dovrebbe restituire l'elenco di URL completi, in ordine alfabetico e senza duplicati. Prendendo gli URL in ordine alfabetico si produrranno le sezioni dell'immagine nell'ordine corretto da sinistra a destra per ricreare l'immagine animale originale. Nel caso più semplice, main() dovrebbe semplicemente stampare gli URL, uno per riga.
$ ./logpuzzle.py animal_code.google.com http://code.google.com/something/puzzle-animal-baaa.jpg http://code.google.com/something/puzzle-animal-baab.jpg ...
Parte B - Scarica il rompicapo delle immagini
Completa la funzione download_images() che accetta un elenco ordinato di URL e una directory. Scarica l'immagine da ciascun URL nella directory data, creando prima la directory se necessario (vedi il modulo "os" per creare una directory e "urllib.urlretrieve()" per scaricare un url). Assegna ai file immagine locali uno schema semplice, ad esempio "img0", "img1", "img2" e così via. Potresti voler stampare un piccolo messaggio di "Recupero in corso..." riga di output dello stato durante il download di ciascuna immagine, perché può essere lenta ed è utile avere qualche indizio del funzionamento del programma. Ogni immagine è una piccola sezione verticale rispetto all'originale. Come unire le sezioni per ricreare l'originale? Può essere risolto facilmente con un po' di HTML (non è richiesta la conoscenza dell'HTML).
La funzione download_images() dovrebbe anche creare un file index.html nella directory con un tag *img* per visualizzare ogni file immagine locale. I tag img devono essere tutti su un'unica riga senza essere separati. In questo modo, il browser visualizza tutte le sezioni insieme senza problemi. Per eseguire questa operazione non è necessaria la conoscenza del codice HTML. crea un file index.html simile al seguente:
<html> <body> <img src="img0"><img src="img1"><img src="img2">... </body> </html>
Ecco come dovrebbe apparire quando riesci a scaricare il rompicapo con animali:
$ ./logpuzzle.py --todir animaldir animal_code.google.com $ ls animaldir img0 img1 img2 img3 img4 img5 img6 img7 img8 img9 index.html
Quando tutto funziona, l'apertura del file index.html in un browser dovrebbe visualizzare l'immagine originale dell'animale. Qual è l'animale nell'immagine?
Parte C - Descrambling delle sezioni di immagine
Il secondo puzzle riguarda l'immagine di un luogo molto famoso, ma dipende da un ordinamento personalizzato. Per il primo rompicapo, gli URL possono essere in ordine alfabetico per ordinare le immagini correttamente. Nell'ordinamento viene utilizzato l'intero URL. Tuttavia, se l'URL termina con il pattern "-wordchars-wordchars.jpg", ad es. "http://example.com/foo/puzzle/bar-abab-baaa.jpg", l'URL deve essere rappresentato dalla seconda parola nell'ordinamento (ad es. "baaa"). Di conseguenza, se ordini un elenco di URL che terminano con il pattern parola-word.jpg, gli URL devono essere ordinati in base alla seconda parola.
Estendi il codice per ordinare correttamente questi URL, quindi dovresti essere in grado di decodificare il secondo puzzle place_code.google.com che mostra un luogo famoso. Quale luogo viene mostrato?
CC Attribution: le immagini utilizzate in questo rompicapo sono state rese disponibili dai rispettivi proprietari ai sensi della licenza Creative Commons Attribution 2.5, che incoraggia generosamente i remix dei contenuti come questo. L'immagine dell'animale è dell'utente zappowbang di flickr, mentre l'immagine del luogo è dell'utente booleansplit su flickr.