第24回 Ruby/Rails勉強会@関西に参加
日本Rubyの会 公式Wiki - 第24回 Ruby/Rails勉強会@関西
http://jp.rubyist.net/?KansaiWorkshop24
行ってきました神戸。とりあえず、神戸大の正門付近から見える街と海の景色が素晴らしかった。早めに着いたのでプラプラ歩き回っていたのだ。晴れてて良かった。あのキャンパスは六甲山の麓というロケーションのみで最早最高ですね。思えば僕の母校周辺の景観は割と酷かったな(とても大昔)。設備はNeXTとかnews使い放題で最高だったけど(年がばれる)。完全に猫に小判で、Mathematicaで適当なグラフとか描いて遊んでた。そういえば今日の演習室はiMacだったな。スティーブ・ジョブズ恐るべし。
さて、ともかくは、またRuby初級者向けレッスン第18回 by okkezさんの演習の回答から。ブログに書くとokkezさんが添削して下さるということだ。素晴らしい。
- 演習1 テキスト解析
- まず、「単語」とは、\wな文字か、\wな文字でも空白類でも無い文字の連続したものとした。例えば、"(7:00:00 PM)"は"(", "7", ":", "00", ":", "00", "PM", ")"に区切られる。最初、"(7:00:00"を単語とするような区切り方をしていたのだが、気持ち悪いのでやめた。
- 行数は空行もカウントする。
- 文字は空白類もカウントする。
char_count = 0; word_count = 0; line_count = 0; chars = Hash.new(0) words = Hash.new(0) File.open("text.txt") do |f| f.each do |l| char_count += l.size l.scan(/./m) {|c| chars[c] += 1 } l.strip.scan(/\w+|[^\s\w]+/) do |w| words[w] += 1 word_count += 1 end end line_count = f.lineno end printf("文字数 %d\n", char_count) printf("単語数 %d\n", word_count) printf("行数 %d\n", line_count) puts "文字出現頻度(文字 頻度(%) 回数)" chars.sort_by {|c, n| -n }.each {|c, n| printf("%-10s %4.2f%% %5d\n", c.dump, 100 * n/char_count.to_f, n) } puts "単語出現頻度(単語 頻度(%) 回数)" words.sort_by {|w, n| -n }.each {|w, n| printf("%-10s %4.2f%% %5d\n", w, 100 * n/word_count.to_f, n) }
- 出力結果
文字数 6096 単語数 1238 行数 43 文字出現頻度(文字 頻度(%) 回数) " " 16.44% 1002 "t" 8.76% 534 "e" 8.40% 512 "o" 7.10% 433 "n" 5.51% 336 "i" 5.38% 328 ...(省略) 単語出現頻度(単語 頻度(%) 回数) , 5.82% 72 . 5.09% 63 the 3.88% 48 and 2.34% 29 for 1.62% 20 a 1.62% 20 to 1.53% 19 in 1.45% 18 of 1.45% 18 it 1.45% 18 as 1.37% 17 you 1.21% 15 ' 1.21% 15 Chkrootkit 1.13% 14 is 1.05% 13 that 0.89% 11 -- 0.89% 11 ...(以下省略)
ファイルをeachで回すと、linenoがインクリメントされていくということを知った。また、scanする時の区切りの正規表現にmオプションを付けないと、行末の改行にマッチせず結果が変わってきてしまう。あと今回ファイルが小さいし1行毎に処理する必要は無いのだが、readして処理するのはやめておいた。
- 演習2 ログ解析
require "Time" index_count = 0 first_access_from_mac = nil google_access_count = 0 days = Hash.new(0) agents = Hash.new(0) File.open("access.log") do |f| f.each do |l| time, request, referer, agent = /[\d+.]+[^\[]+\[([^\]]*)\][^"]*"([^"]*)"[^"]*"([^"]*)"[^"]*"([^"]*)"/.match(l).to_a.values_at(1, 2, 3, 4) index_count += 1 if request =~ /\/index.php/ first_access_from_mac = time if first_access_from_mac.nil? && agent =~ /Macintosh/ google_access_count += 1 if referer =~ /http:\/\/[\w.]+google/ days[Time.parse(/(\w+)\/(\w+)\/(\w+)/.match(time).to_a.values_at(1, 2, 3).join(" ")).to_s.gsub(/\s.+/, "")] += 1 agents[agent] += 1 end end printf("/index.phpへのアクセス回数 %d\n", index_count) printf("最初のMacユーザのアクセス日時 %s\n", first_access_from_mac) printf("Google経由のアクセス回数 %d\n", google_access_count) printf("最もアクセスの多い曜日 %s\n", days.sort_by {|d, n| -n }[0][0]) puts "ブラウザ毎のアクセスランキング" agents.sort_by {|a, n| -n }.each {|a, n| printf("%5d %s\n", n, a) }
- 出力結果
/index.phpへのアクセス回数 2652 最初のMacユーザのアクセス日時 10/Mar/2008:12:17:22 +0900 Google経由のアクセス回数 74 最もアクセスの多い曜日 Mon ブラウザ毎のアクセスランキング 1212 Mozilla/5.0 (Twiceler-0.9 http://www.cuill.com/twiceler/robot.html) 908 Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12 829 e-SocietyRobot(http://www.yama.info.waseda.ac.jp/~yamana/es/) 672 Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) 379 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727) Sleipnir/2.6.2 231 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 1.1.4322) Sleipnir/2.6.2 159 Bloglines/3.1 (http://www.bloglines.com; 2 subscribers) 155 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648) 149 Mozilla/5.0 (Windows; U; Windows NT 6.0; ja; rv:1.8.1.12) Gecko/20080201 Firefox/2.0.0.12 149 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; SLCC1; .NET CLR 2.0.50727; .NET CLR 3.0.04506; InfoPath.1; Tablet PC 2.0) 135 Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322) 131 Apache/2.2.3 (Debian) DAV/2 SVN/1.4.2 PHP/5.2.0-8+etch10 (internal dummy connection) ...(以下省略)
その他の感想などは、疲れたので明日続きを書くことにする。