Rubyで平日20時から翌日9時までの間と、土日祝の終日のアラート件数を集計するスクリプトを作成したいです。下記のようなファイルがある場合、そこから上記条件で月ごとの件数を抽出するのが目的です。右端の回数はすべて一回となりますので、単純に「平日20時から翌日9時までの間と、土日祝の終日」の行数がわかればアラート件数となります。


考えてみて、1~4のような手順で作ればよいものかと思うのですが、他に何かよい方法等があればご教示ください。

1.正規表現である月だけ抽出
2.そこから平日の9-19時を除外
3.その行数を出す

ファイル:
日付     時間(hh) 曜日  回数
20080922    5    月   1
20080922    3    月   1
20080922    17    月   1
20080922    1    月   1
20080921    17    日   1
20080921    14    日   1
20080921    5    日   1
20080920    5    土   1
20080916    15    火   1
20080916    5    火   1
20080915    3    月   1
20080915    2    月   1
20080914    10    日   1

回答の条件
  • 1人10回まで
  • 登録:2008/10/23 17:33:57
  • 終了:2008/10/28 15:34:23

回答(2件)

id:rubikitch No.1

るびきち回答回数120ベストアンサー獲得回数222008/10/23 18:23:59

ポイント60pt

まず、ファイルの構造に問題があると思います。

年月日がわかれば同時に曜日がわかるので曜日は不要です。

回数が常に1だったら回数というフィールドも不要です。

2以上になるかもしれないので一応加算しておきました。

日付判定はdateライブラリを使いました。

なお、レコードは構造体に落としておくと便利です。

require 'date'
Alerts = Struct.new(:date, :hour, :week, :count)
records = <<EOR
20080922    5    月   1
20080922    3    月   1
20080922    17   月   1
20080922    1    月   1
20080921    17   日   1
20080921    14   日   1
20080921    5    日   1
20080920    5    土   1
20080916    15   火   1
20080916    5    火   1
20080915    3    月   1
20080915    2    月   1
20080914    10   日   1
EOR

class Date
  def holiday?
    false                       # 面倒なので仮実装
  end
end

puts records.split(/\n/).map {|str|
  date, hour, week, count = str.split
  Alerts.new Date.parse(date), hour.to_i, week, count.to_i
}.select {|a|
  a.date.year == 2008 and a.date.month == 9 and # 2008/9/xx
  [0,6].include?(a.date.wday) or                # 土日
  a.date.holiday? or                            # 祭日
  # 平日の0~9時か20~23時
  ((1..5).include?(a.date.wday) and ((0..9).include? a.hour or (20..23).include? a.hour))
}.inject(0) {|s, a| s + a.count } # 加算
# >> 11

なお、祝日判定は面倒なのでここではやっていません。

id:ikazuo

ありがとうございます。

試してみたところ、きちんと欲しい件数が出ました。

業務に役立ちそうです。

コードを読んで理解するところから始めます。

本当にありがとうございます!

2008/10/24 00:18:03
id:pahoo No.2

pahoo回答回数5960ベストアンサー獲得回数6332008/10/23 18:46:01

ポイント20pt

ご質問の手順だと祝日の判定が抜けているようです。


最近はハッピーマンデーなどがあり、ロジックで算出するのは面倒なのですが、「Ruby でカレンダー」の方法がよくできています。

しかし、春分の日・秋分の日については、計算で求めることができません。その前年の2月の閣議で決まるからです。このあたりの事情については「秋分の日と敬老の日の微妙な関係」をご覧ください。

個人的には、祝日は判定テーブルを用意するのが確実だと思います。

id:ikazuo

ご指摘ありがとうございます。

それと、春分の日・秋分の日ついても知りませんでした。

教えていただいてありがとうございます。

>祝日は判定テーブルを用意するのが確実だと思います。

調べて試してみます。

2008/10/24 00:34:57
  • id:kn1967
    Ruby使いじゃないのでコメント欄で・・・。

    絞り込む条件式としては
    (該当月であれば真) and (土日祝/9時以前/22時以降のいずれかであれば真)
    といったような形で済むのでは?

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません