ログパズル Python の演習

ログパズルの演習では、Python コードを使用して 2 つのパズルを解きます。この演習では、Python ユーティリティ セクションに示されている urllib モジュールを使用します。この演習のファイルは、google-python-exercises 内の「logpuzzle」ディレクトリにあります(まだダウンロードしていない場合は、google-python-exercises.zip をダウンロードします。詳細については、セットアップをご覧ください)。コードを「logpuzzle.py」ファイルに追加します。

動物の画像が縦長の細い画像に分割され、ストライプの画像はインターネット上のどこかで公開されており、それぞれ独自の URL を持っています。ウェブサーバーのログファイルでは、URL は非表示になっています。あなたのミッションは、URL を見つけ、すべての画像ストライプをダウンロードして、元の画像を再現することです。

スライスの URL は Apache ログファイル内では隠されます(オープンソースの apache ウェブサーバーは、インターネットで最も広く使用されているサーバーです)。各ログファイルはなんらかのサーバーからのもので、目的のスライス URL がログ内で非表示になっている。ログファイルは、作成されたサーバーが次のようにエンコードされています。ログファイル動物コード.google.com は code.google.com サーバーのものです(正式には、サーバー名は最初のアンダーバーの後に表示されます)。artist_code.google.com ログファイルには、「animal」パズル画像のデータが含まれています。ログファイル内のデータは実際の Apache ウェブサーバーの構文を備えていますが、パズルに必要なもの以外のデータは、実際のログファイルのランダム化されたデータです。

ログファイルの 1 行は次のようになります(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"

最初の数桁は、リクエスト元のブラウザのアドレスです。特に興味深い部分は、サーバーが受信したウェブ リクエストのパスを示す「GET path HTTP」です。パス自体にスペースは含まれず、GET や HTTP とはスペースで区切られています(正規表現の候補: \S(大文字の S)はスペース以外の文字と一致します)。ログ内のパスの中に文字列「puzzle」が表示されている行を見つけます。ログ内の他の多くの行は無視します。

パート A - URL へのログファイル

ログファイル内からパズルの URL を抽出する read_urls(filename) 関数を完成させます。ログファイルで「パズル」パスの URL をすべて見つけます。各 URL のパスとファイル名のサーバー名を組み合わせて完全な URL にします(例: http://www.example.com/path/puzzle/from/inside/file)。複数回表示される URL を除外します。read_urls() 関数は、完全な URL のリストを、重複のないアルファベット順に並べ替えて返します。URL をアルファベット順にすると、画像スライスが左から右に正しい順序で出力され、元の動物の画像を再現できます。最も単純なケースでは main() は URL を 1 行に 1 つずつ出力するだけです。

$ ./logpuzzle.py animal_code.google.com
http://code.google.com/something/puzzle-animal-baaa.jpg
http://code.google.com/something/puzzle-animal-baab.jpg
...

パート B - 画像をダウンロードするパズル

並べ替えられた URL とディレクトリのリストを受け取る download_images() 関数を完成させます。各 URL の画像をダウンロードし、必要に応じて最初にディレクトリを作成します(ディレクトリを作成するには「os」モジュールを、URL のダウンロードについては「urllib.urlretrieve()」をご覧ください)。ローカル画像ファイルには、「img0」、「img1」、「img2」などの単純なスキームの名前を付けます。各画像をダウンロードする際に、ステータス出力の小さな行を出力することをおすすめします。これは、処理に時間がかかり、プログラムが動作していることがわかると便利な場合があるためです。各画像は、元の画像を縦に少し分割した画像です。スライスを組み合わせてオリジナルをどのように再現すればよいでしょうか。ちょっとした HTML を使うとうまく解決できます(HTML の知識は必要ありません)。

また、download_images() 関数は、各ローカル画像ファイルを表示するために *img* タグの付いた index.html ファイルをディレクトリに作成する必要もあります。img タグはすべて 1 行にまとめて、区切りで配置しないでください。このようにして、ブラウザはすべてのスライスをシームレスに表示します。HTML の知識がなくても、次のような index.html ファイルを作成します。

<html>
<body>
<img src="img0"><img src="img1"><img src="img2">...
</body>
</html>

動物のパズルをダウンロードすると、次のように表示されます。

$ ./logpuzzle.py --todir animaldir animal_code.google.com
$ ls animaldir
img0  img1  img2  img3  img4  img5  img6  img7  img8  img9  index.html

すべて問題なく動作したら、ブラウザで index.html を開くと、元の動物の画像が表示されます。画像に写っている動物は何ですか?

パート C - 画像スライスのスクランブル処理

2 つ目のパズルは非常に有名な場所の画像を使用しますが、カスタムの並べ替えに依存します。最初のパズルでは、URL をアルファベット順に並べ替え、画像が正しい順序で並べられるようにします。並べ替えでは URL 全体が使用されます。ただし、URL が「-wordchars-wordchars.jpg」というパターンで終わる場合(例: 「http://example.com/foo/puzzle/bar-abab-baaa.jpg」)、URL は並べ替えの 2 番目の単語で表す必要があります(例: 「baaa」)。したがって、それぞれが word-word.jpg パターンで終わる URL のリストを並べ替えると、URL が 2 番目の単語順に並べ替えられます。

コードを拡張して、このような URL を適切に並べ替えると、有名な場所を示す 2 つ目の place_code.google.com パズルをデコードできるようになります。表示される場所

CC 表示: このパズルで使用されている画像は、所有者からクリエイティブ・コモンズ表示 2.5 ライセンスに基づいて提供されたものです。このライセンスでは、このようなコンテンツのリミックスを大いに推奨しています。動物の画像は Flickr の Zappowbang から、場所の画像は flickr のブールスプリットから取得されたものです。