Python Log Puzzle Exercise in Japanese

Google による Python の授業 (日本語訳)/ Google's Python Class (英語原文)

資料
日本語訳: 設定/ 入門/ 文字列/ リスト/ 整列/ 辞書とファイル/ 正規表現/ ユーティリティ
英語原文: Set Up/ Introduction/ Strings/ Lists/ Sorting/ Dict and Files/ Reg. Exp./ Utilities

練習問題
日本語訳: 基本問題/ 新生児名/ 特殊なコピー/ アクセス履歴のパズル
英語原文: Basic Exercises/ Baby Names Exercise/ Copy Special Exercise/ Log Puzzle Exercise

講義映像
英語
1日目: Introduction, Strings/ Lists and Sorting/ Dicts and Files
2日目: Regular Expression/ Utilities/ Utilities urllib/ Conclusions

サーバの履歴を使ったパズルの練習問題


サーバの履歴を使ったパズルの練習問題に対して, 2つのパズルを解く Python のコードを使います. この練習問題は Python Utilities (英語原文), Python ユーティリティ (日本語訳) で説明されている urllib モジュールを使います. この練習問題に対するファイルは, google-python-exercises の中の "logpuzzle" ディレクトリにあります. (google-python-exercises.zip をまだダウンロードしていないなら, ダウンロードし, 詳細について Set Up (英語原文), 設定 (日本語訳) を見ること). コードを "logpuzzle.py" のファイルに追加すること.
動物の画像が細い縦長の縞模様の画像に分解されています. その縞模様の画像はインターネットのどこかにあり, それぞれが固有の URL を持っています. その URL は web サーバの履歴ファイルに隠されています. あなたの使命は, その URL を見つけ, 原画像を再構成するためにすべての画像をダウンロードすることです.
画像片の URL は apache の履歴ファイルの中に 隠されています (オープンソースの apache ウェブサーバはインターネット上で最も広く使われています). それぞれの履歴ファイルはあるサーバから取得したもので, 探している画像片の URL はその履歴の中に入っています. その履歴ファイルは どのサーバからその履歴が 来たかを次のように符号化しています. 履歴ファイル animal_code.google.com は code.google.com サーバから 来ています (形式的に, 初めの下線記号に続くものをサーバ名とします). animal_code.google.com という履歴ファイルは, "animal" のパズル画像に対するデータを含んでいます. 履歴ファイルの中のデータは実際の apache ウェブサーバ の文法に従っていますが, パズルに必要なもの以外のデータは 実際の履歴ファイルから乱数化したデータになっています.
履歴ファイルの単一行はこうなっています (これは実際の 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"

最初のいくつかの数字は, データを要求したブラウザのアドレスです. 最も気になる部分は, サーバが受け取ったウェブの要求のパス (path) を表す "GET path HTTP" です. パスそのものは空白を決して含まず, GET と HTTP は空白で分けられています (正規表現に関する助言: \S (大文字の S) は任意の空白でない記号に一致します). "puzzle" という文字列がパス内にあるログの行を見つけ, ログのそれ以外の行は無視すること.
Part A - 履歴ファイルから URL を作る
履歴ファイルの内部にある puzzle の URL を抜き出す read_urls(filename) 関数を完成させること. 履歴ファイル中のすべての "puzzle" パスの URL を見つけること. "http://www.example.com/path/puzzle/from/inside/file" のような 完全な URL を作るために, ファイル名から決まったサーバ名と それぞれの URL のパスをつなげること. 重複している URL は 1つにまとめること. 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
...
Part B - 画像パズルのダウンロード
整列された URL のリストとディレクトリを引数に取る download_images() 関数を完成させること. 指定されたディレクトリにそれぞれの URL の 画像をダウンロードします. ただし, そのディレクトリがないときは新たに作ること (ディレクトリを作るには "os" モジュールを, URL に指定されたファイルをダウンロードするには "urllib.urlretrieve()" を それぞれ参照). 手元にある画像ファイル名を, "img0", "img1", "img2", といった 簡単な決め方で名づけること. ダウンロードに時間が掛かるのに加えて, プログラムが動作していることがわかると安心できるので, それぞれの画像をダウンロードしているときに "Retrieving..." (取得中...) といった状態を表示するのも 良いかもしれません. それぞれの画像は, 元画像より少し縦長な 切れ端になっています. 元の画像に戻すために画像片をまとめるには, どうしたら良いでしょうか? ちょっとした 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 を開くと, 元の動物の画像が出てくるはずです. その画像の動物は何ですか?
Part C - 画像片の復元
2つ目のパズルはとても有名な場所の画像に 関するものですが, 特別仕様の整列に依存します. 1つ目のパズルでは, 画像を正しく並べるために URL をアルファベット順に 並べました. その整列では全体の URL を使いました. しかし URL が例えば, "http://example.com/foo/puzzle/bar-abab-baaa.jpg" といった "-単語-単語.jpg" の形で終わっているなら, その URL は 2番目の単語 (例では, "baaa") を基準に整列させること. 単語-単語.jpg の形で終わるそれぞれの URL のリストを 整列させるときは, 2番目の単語で URL を並べること.
そのような URL を正しく並べるように, あなたのコードを拡張することで, 有名な場所を表す 2つ目の place_code.google.com パズルを解読できるでしょう. その場所はどこですか?
クリエイティブコモンズの属性: このパズルに使った画像は, その所有者の Creative Commons Attribution 2.5 という, このような内容の改変を奨励している許可の下で利用しています. 動物の画像は flicker の zappowbang 氏のもので, 場所の画像は flicker の booleansplit 氏のものです.
この資料は Google の Nick Parlante によって作成されたものの翻訳です. Google による Python の授業の文章と映像は Creative Commons Attribution 2.5 ライセンスの下で利用できます.