Ghi nhật ký bài tập Python Puzzle

Đối với bài tập Log Puzzle, bạn sẽ sử dụng mã Python để giải 2 câu đố. Bài tập này sử dụng mô-đun urllib, như hiển thị trong mục Tiện ích Python. Các tệp của bài tập này nằm trong thư mục "logpuzzle" bên trong google-python-exercises (tải tệp google-python-exercises.zip xuống nếu bạn chưa tải, xem phần Thiết lập để biết thông tin chi tiết). Thêm mã của bạn vào tệp "logpuzzle.py".

Một hình ảnh động vật bị chia thành nhiều hình ảnh sọc dọc và hẹp. Các hình ảnh sọc xuất hiện trên Internet ở đâu đó, mỗi hình ảnh có URL riêng. Các URL này bị ẩn trong tệp nhật ký máy chủ web. Nhiệm vụ của bạn là tìm URL và tải tất cả sọc hình ảnh xuống để tạo lại hình ảnh gốc.

URL lát cắt bị ẩn trong tệp nhật ký apache (máy chủ web apache nguồn mở là máy chủ được sử dụng rộng rãi nhất trên Internet). Mỗi tệp nhật ký đều đến từ một số máy chủ và các URL lát cắt mong muốn sẽ bị ẩn trong nhật ký. Tệp nhật ký mã hoá máy chủ đến từ đâu như sau: tệp nhật ký Hãy nhập vai trò người dùng vào mã máy chủ code.google.com (chính thức, chúng ta sẽ nói rằng tên máy chủ là tên bất kỳ nằm sau thanh gạch dưới đầu tiên). Tệp nhật ký animation_code.google.com chứa dữ liệu về hình ảnh ghép hình "động vật". Mặc dù dữ liệu trong các tệp nhật ký có cú pháp của một máy chủ web apache thực, nhưng dữ liệu ngoài những gì cần thiết cho câu đố là dữ liệu ngẫu nhiên từ một tệp nhật ký thực.

Một dòng đơn từ tệp nhật ký trông sẽ như sau (đây thực sự là giao diện của tệp nhật ký 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"

Một vài số đầu tiên là địa chỉ của trình duyệt yêu cầu. Phần thú vị nhất là "GET path HTTP" cho thấy đường dẫn của một yêu cầu web mà máy chủ nhận được. Bản thân đường dẫn không bao giờ chứa dấu cách và được phân tách với GET và HTTP bằng dấu cách (đề xuất biểu thức chính quy: \S (chữ hoa S) khớp với bất kỳ ký tự nào không có dấu cách). Tìm các dòng trong nhật ký nơi chuỗi "câu đố" xuất hiện bên trong đường dẫn, bỏ qua nhiều dòng khác trong nhật ký.

Phần A – Tệp nhật ký vào URL

Hoàn tất hàm read_urls(filename) để trích xuất các URL của câu đố từ bên trong một tệp nhật ký. Tìm tất cả các URL đường dẫn "giải đố" trong tệp nhật ký. Kết hợp đường dẫn của mỗi url với tên máy chủ trong tên tệp để tạo thành một url đầy đủ, ví dụ: "http://www.example.com/path/puzzle/from/bên trong/file". Lọc ra các URL xuất hiện nhiều lần. Hàm read_url() phải trả về danh sách URL đầy đủ, được sắp xếp theo thứ tự bảng chữ cái và không có các URL trùng lặp. Việc lấy URL theo thứ tự bảng chữ cái sẽ tạo ra các lát hình ảnh theo đúng thứ tự từ trái sang phải để tạo lại hình ảnh động vật ban đầu. Trong trường hợp đơn giản nhất, main() chỉ nên in các URL, mỗi URL trên một dòng.

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

Phần B – Tải câu đố hình ảnh

Hoàn tất hàm download_images(). Hàm này sẽ lấy danh sách các URL được sắp xếp và một thư mục. Tải hình ảnh từ mỗi url xuống thư mục cho sẵn, tạo thư mục trước nếu cần (xem mô-đun "os" để tạo thư mục và "urllib.urlRetrieve()" để tải url xuống). Đặt tên cho tệp hình ảnh cục bộ bằng một lược đồ đơn giản như "img0", "img1", "img2", v.v. Bạn có thể muốn in một chút dòng đầu ra trạng thái "Truy xuất..." trong khi tải xuống từng hình ảnh vì hình ảnh có thể chậm và rất tốt khi có dấu hiệu cho biết chương trình đang hoạt động. Mỗi hình ảnh là một lát dọc nhỏ so với hình ảnh gốc. Làm cách nào để ghép các lát với nhau để tạo lại bản gốc? Có thể giải quyết tốt bằng một chút html (không bắt buộc phải có kiến thức về HTML).

Hàm tải xuống_images() cũng phải tạo một tệp index.html trong thư mục có thẻ *img* để hiển thị từng tệp hình ảnh cục bộ. Tất cả các thẻ img phải nằm trên một dòng với nhau mà không có phân tách. Bằng cách này, trình duyệt hiển thị tất cả các lát cắt cùng nhau một cách liền mạch. Bạn không cần phải biết về HTML để thực hiện việc này; chỉ cần tạo một tệp index.html giống như sau:

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

Sau đây là ví dụ minh hoạ thời điểm bạn có thể tải câu đố về động vật xuống:

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

Khi mọi thứ đều hoạt động, việc mở index.html trong trình duyệt sẽ hiển thị hình ảnh động vật ban đầu. Con vật trong hình ảnh là gì?

Phần C – Lát cắt hình ảnh giảm dần

Câu đố thứ hai liên quan đến hình ảnh của một địa điểm rất nổi tiếng, nhưng phụ thuộc vào cách sắp xếp tuỳ chỉnh. Đối với câu đố đầu tiên, bạn có thể sắp xếp các URL theo thứ tự bảng chữ cái để sắp xếp các hình ảnh một cách chính xác. Trong kiểu sắp xếp này, toàn bộ URL sẽ được sử dụng. Tuy nhiên, chúng tôi sẽ nói rằng nếu url kết thúc bằng mẫu "-chữ ký tự-chữ cái.jpg", ví dụ: "http://example.com/foo/puzzle/bar-abab-baaa.jpg", thì url phải được đại diện bằng từ thứ hai trong sắp xếp (ví dụ: "baaa"). Vì vậy, việc sắp xếp danh sách các URL, mỗi URL kết thúc bằng mẫu word-word.jpg phải sắp xếp các URL theo từ thứ hai.

Hãy mở rộng mã của bạn để sắp xếp thứ tự các URL đó đúng cách, sau đó bạn sẽ có thể giải mã câu đố place_code.google.com thứ hai cho thấy một địa điểm nổi tiếng. Nó hiển thị địa điểm nào?

Ghi công CC: những hình ảnh sử dụng trong câu đố này do chủ sở hữu cung cấp theo giấy phép Creative Commons Attribution 2.5, khuyến khích một cách hào phóng các bản phối lại nội dung như tác phẩm này. Hình ảnh con vật là từ zappowbang của người dùng trên Flickr và hình ảnh địa điểm là từ phần phân tách boolean của người dùng trên Flickr.