Hatena::Grouprubyist

bongoleのRubyを楽しむ日記 このページをアンテナに追加 RSSフィード

Rubyを楽しむ日記

2006-07-19

[]Pathname 23:53 Pathname - bongoleのRubyを楽しむ日記 を含むブックマーク

いまさらながらPathnameクラスの出来のよさに感動する。

まじあり得ないくらい便利。

mkpathとかrmtreeとかすげーよ。バッチテストするときすごい役にたちました。

ありがとう。

2006-06-30

[]iTunesライブラリ存在するのにファイルがない曲を探すスクリプト 00:29 iTunesのライブラリに存在するのにファイルがない曲を探すスクリプト - bongoleのRubyを楽しむ日記 を含むブックマーク

iTunesに登録してるフォルダがあるHDDが逝かれて大変だった。

なんとか復旧したものの200曲近く失うことになってしまった。。。。orz

で、どうやって失った曲を調べたかというと以下のスクリプトを"iTunes Music Library.xml"がある場所で実行して調べました。

実行結果としてCSV形式で失った曲のリスト標準入力に出力されます。

("iTunes Music Library.xml"は通常"マイドキュメント/iTunes"の下にあります)

require 'open-uri'
require 'kconv'
require 'csv'

$KCODE='u'

class Mp3
	attr_accessor :name, :album, :artist, :location
end

records = []

tmp_record = nil;
open('iTunes Music Library.xml', 'r').each_line do |line|
	line.strip!
	line =~ %r!<string>(.*)</string>!
	next unless $1
	str = $1
	case line
	when %r!^<key>Name</key>!
		tmp_record = Mp3.new
		tmp_record.name = str.tosjis
	when %r!^<key>Artist</key>!
		tmp_record.artist = str.tosjis
	when %r!^<key>Album</key>!
		tmp_record.album = str.tosjis
	when %r!^<key>Location</key>!
		tmp_record.location = URI.decode(str.sub('file://localhost/','')).tosjis
		records << tmp_record
	end
end

buf = ""
CSV::Writer.generate(buf) do |csv|
	records.each do |r|
		unless test(?e, r.location)
			csv << [r.artist, r.album, r.name, r.location]
		end
	end
end

print buf

CSVアーティスト名, アルバム名, 曲名, ファイルの場所 の順番で出力されます。

もうね、200行近く出力された瞬間泣きそうになったというか泣いてた。。。。。。。。。。。。OTZ

2006-06-24

[][]C++Ruby拡張ライブラリを書く 11:47 C++でRuby拡張ライブラリを書く - bongoleのRubyを楽しむ日記 を含むブックマーク

最近C++Ruby拡張ライブラリを書いてる。

んで、結構はまったとこがあったのでそれを書こうと思った。

でも、これからお出かけなんで後で書く。

2006-06-05

[][][]GEDCOM Parser 00:04 GEDCOM Parser - bongoleのRubyを楽しむ日記 を含むブックマーク

今日は調子がいいので、さぼっていたRuby Quizの続きを書こう。

3問目。

GEDCOM(GEnealogical Data COMmunication)フォーマットという構造化されたテキストXMLに変換しようという問題。

GEDCOMフォーマットサンプルは下のような感じ

0 @I1@ INDI
1 NAME Jamis Gordon /Buck/
2 SURN Buck
2 GIVN Jamis Gordon
1 SEX M
...

各行は

LEVEL TAG-OR-ID [DATA]

という構成になっていて、LEVELは注目してる行の階層の深さを表している。

TAG-OR-IDはそのままでタグIDが入る。タグとは英大文字3文字から4文字から成りその後に続くデータの型を表す。

IDは@で囲まれた文字列でファイル内でかぶらないユニークな文字列が入り、その後に続くデータがサブツリーの型を表す。

まぁ、毎度のことながら言葉で説明してもわからんのでXMLで上のGEDCOMを変換すると下のような感じになる。

<gedcom>
    <indi id="@I1@">
        <name>
            Jamis Gordon /Buck/
            <surn>Buck</surn>
            <givn>Jamis Gordon</givn>
        </name>
        <sex>M</sex>
        ...
    </indi>
    ...
</gedcom>

まぁ一目瞭然ですな。

ようするにこんな感じになるように変換しろってことです。

了解。把握した。

ちなみに、でかいGEDCOMフォーマットファイルここにあるらしいのでテストするのに使おう。

続く

2006-05-30

[][][]続・解答 00:57 続・解答 - bongoleのRubyを楽しむ日記 を含むブックマーク

昨日の続き。

3つめの解答。コードはcode/lcd_number/states.rb。

この解答はちょっと変わっていて、縦棒のある行と横棒のある行にそれぞれ以下のような状態をもたせる。

縦棒のある行

  • 0 縦棒なし
  • 1 右側にだけ縦棒がある
  • 2 左側にだけ縦棒がある
  • 3 両側に縦棒がある

横棒のある行

  • 0 横棒なし
  • 1 横棒あり

でこれらの状態を使って図形を配列で表すと

LCD_DISPLAY_DATA = {
#0だけわかりやすく書いてみる
"0" => [1, #  -  横棒がある
         3, # | | 縦棒が両側にある
         0, #     横棒がない
         3, # | | 縦棒が両側にある
         1  #  -  横棒がある
        ],
"1" => [ 0, 1, 0, 1, 0 ],
"2" => [ 1, 1, 1, 2, 1 ],
"3" => [ 1, 1, 1, 1, 1 ],
"4" => [ 0, 3, 1, 1, 0 ],
"5" => [ 1, 2, 1, 1, 1 ],
"6" => [ 1, 2, 1, 3, 1 ],
"7" => [ 1, 1, 0, 1, 0 ],
"8" => [ 1, 3, 1, 3, 1 ],
"9" => [ 1, 3, 1, 1, 1 ]
}

であとは以下のコードのように

横棒のある行、縦棒のある行の状態に対する処理を書き

横棒のある行→縦棒のある行→横棒のある行→縦棒のある行→横棒のある行の順番に処理をしていけば最終的な結果を得られる。

  LCD_STATES = [
    "HORIZONTAL",
    "VERTICAL",
    "HORIZONTAL",
    "VERTICAL",
    "HORIZONTAL",
    "DONE"
  ]

  def display( digits )
    states = LCD_STATES.reverse
    0.upto(LCD_STATES.length) do |i|
      case states.pop
      when "HORIZONTAL" #横棒のある行に対する処理
        line = ""
        digits.each_byte do |b|
          line += horizontal_segment( LCD_DISPLAY_DATA[b.chr][i] )
        end
        print line + "\n"
      when "VERTICAL" #縦棒のある行にたいする処理
        1.upto(@size) do |j|
          line = ""
          digits.each_byte do |b|
            line += vertical_segment( LCD_DISPLAY_DATA[b.chr][i] )
          end
          print line + "\n"
        end
      when "DONE"
        break
      end
    end
  end

この解答のすごいところは、行列を入れ替えたり配列を結合したりしなくても画面で見える1行分の結果が1度に作れるのでメモリを食わないということみたい。

かに、前2つの解答では入力が多くなればなるだけ巨大な配列の確保と操作をしなければならないがこの解答では繰り返しの回数が多くなるだけで消費するメモリは少なくて済む。

いやいや、今回の問題はrubyというよりも考え方が勉強になりました。

明日は、いよいよ次の問題をやろうと思う。

つづく