機種変には2段階認証プロセスの罠がっ

Xi に乗り換えのクーポン・チケットが届いていたので galaxy s からgalaxy s 3 へ乗り換えしてきました.
思わぬ躓きがあったのでメモです.

さて機種の初期設定,とショップでGoogle アカウントでログインしようとしたところ... 失敗.
2段階認証プロセス を設定していたため,携帯でコードを発行しろとGoogle 様よりお達しが.
その携帯を今初期設定しているので出来ません...

結局,家でアカウント設定します!と持ち帰って来ました.
PCで2段階認証プロセスの設定を開いて無効にしてやっと携帯初期設定が出来ましたよ.

機種変更に行く前に2段階認証プロセスを無効にするか,その他のタブレットなどを持ち歩くことお勧めします.
ドコモショップの方も知らなかったのでご注意を.

BTW;
iPhone/iPad の認証コード用アプリもあるよ,とGoogleのサイトにあったので検索してみたら見つからず.
どうやら "Google authenticator" という名前なので日本語で「Google 認証」と検索してもアプリが見つからないようです.
これもちょっとした罠だなぁ.


追記:
上記の設定ページにある,「バックアップコードを表示」から確認できる10個のコードをメモしてどこかに忍ばせておくと楽できます :)

HomeBrew でMySQL 5.5.15をインストール

MacBookをLionにアップデートしたついでに
MySQL をインストールしてみたところ
設定や手順でハマって時間をとってしまったのでメモです.

$ brew install mysql

だけでインストールできるとおもいきや
http://downloads.mysql.com/archives/
は反応なし.
参考を元にミラーを参照してみたものの*1

$ mysql_install_db

では動かず,パラメタを指定してあげなければならなかったみたい.

詳しくは参考先を見てください.

*1:この間,ソースのバージョンが違うために失敗を繰り返しました.5.5.16はHomeBrewのそのままの設定ではまだダメ

Array#product を使って配列の操作を楽にする

配列が次のように与えられているときに,

a = %w(a b c d e f g h i j)
b = %w(1 2 3 4 5 6 7 8 9 0)

各要素の総当りでこのような配列を作りたい場合,

["a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "b0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "e0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", "g8", "g9", "g0", "h1", "h2", "h3", "h4", "h5", "h6", "h7", "h8", "h9", "h0", "i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8", "i9", "i0", "j1", "j2", "j3", "j4", "j5", "j6", "j7", "j8", "j9", "j0"]

こんなふうに書いてました.

# Array#map
def cross(a, b)
  a.map{|elem_a| b.map{|elem_b| elem_a.to_s + elem_b.to_s}}.flatten
end

mapのなかでmapは気持ち悪いなーと思い調べていたところ,
Array#productのお手軽さを再発見.

# Array#product
def cross(a,b)
  a.product(b).map{|elem| elem.join()}
end

Array#productを使うと,以下のような総当りの組み合わせの配列が
ネストされて返されるので,個々の配列について処理をしてあげればいいわけです.

[["a", "1"], ["a", "2"], ["a", "3"], ["a", "4"], ["a", "5"], ["a", "6"], ["a", "7"], ["a", "8"], ["a", "9"], ["a", "0"], ["b", "1"], ["b", "2"], ["b", "3"], ["b", "4"], ["b", "5"], ["b", "6"], ["b", "7"], ["b", "8"], ["b", "9"], ["b", "0"], ["c", "1"], ["c", "2"], ["c", "3"], ["c", "4"], ["c", "5"], ["c", "6"], ["c", "7"], ["c", "8"], ["c", "9"], ["c", "0"], ["d", "1"], ["d", "2"], ["d", "3"], ["d", "4"], ["d", "5"], ["d", "6"], ["d", "7"], ["d", "8"], ["d", "9"], ["d", "0"], ["e", "1"], ["e", "2"], ["e", "3"], ["e", "4"], ["e", "5"], ["e", "6"], ["e", "7"], ["e", "8"], ["e", "9"], ["e", "0"], ["f", "1"], ["f", "2"], ["f", "3"], ["f", "4"], ["f", "5"], ["f", "6"], ["f", "7"], ["f", "8"], ["f", "9"], ["f", "0"], ["g", "1"], ["g", "2"], ["g", "3"], ["g", "4"], ["g", "5"], ["g", "6"], ["g", "7"], ["g", "8"], ["g", "9"], ["g", "0"], ["h", "1"], ["h", "2"], ["h", "3"], ["h", "4"], ["h", "5"], ["h", "6"], ["h", "7"], ["h", "8"], ["h", "9"], ["h", "0"], ["i", "1"], ["i", "2"], ["i", "3"], ["i", "4"], ["i", "5"], ["i", "6"], ["i", "7"], ["i", "8"], ["i", "9"], ["i", "0"], ["j", "1"], ["j", "2"], ["j", "3"], ["j", "4"], ["j", "5"], ["j", "6"], ["j", "7"], ["j", "8"], ["j", "9"], ["j", "0"]]

で,2つ以上の配列を組み合わせたいときには

def cross(a,*b)
  p a.product(*b)
  a.product(*b).map{|elem| elem.join()}
end

と,第2引数で複数の配列を受け取ってそのままArray#productに渡しちゃえばいいんですね.

配列内の重複する値を抽出する方法を測ってみた

Rubyで配列内の重複する値を抽出する方法

というエントリを見て触発されてベンチマークを取ってみました.
紹介されている方法は下記のようなコード

a = [1, 2, 3, 4, 5, 6, 5, 4]
a.uniq.map{|v| v if a.inject(Hash.new(0)) {|h, key| h[key] += 1; h}[v] >= 2}.compact

mapのブロック内でのイテレートはコストが高く,
下記のエントリのようにArray#indexとArray#rindex を使う方法が簡潔で早いと思います.
Rubyで配列から重複したモノ(要素)を抜き出す(Uniqの逆)

a.uniq.select{|i| a.index(i) != a.rindex(i)}

ついでに,上記エントリにある方法に追加して「Hashに集計して重複しないものを削除」

a.inject(Hash.new 0){|h, k| h[k] += 0; h}.delete_if{|k,v| v < 2}.keys

も測定してみました.
# delete_if の条件を変えて取り出す値を変更することを想定.

ベンチマーク用のコード

#! /usr/bin/env ruby
#-*- coding: utf-8 -*-

require 'benchmark'

class Array
  # (1) map内で集計
  def inject_in_map
    self.uniq.map{|v| v if self.inject(Hash.new(0)) {|h, k| h[k] += 1; h}[v] >= 2}.compact
  end

  # (2) Hashに集計して重複しないものを削除
  # Hash#select だとruby 1.8系では配列で返ってくるのでHash#delete_ifを採用
  def inject_delete_if
    self.inject(Hash.new 0){|h, k| h[k] += 0; h}.delete_if{|k,v| v < 2}.keys
  end

  # (3) Array#index Array#rindex を使う方法
  def index_rindex
    self.uniq.select{|e| self.index(e) != self.rindex(e)}.uniq
  end
end

# 1000回の反復ベンチマーク
n = 1000

# 配列サイズを4種
[10, 100, 1000, 10000].each {|size|
        # 対象となる配列は一桁の数値をランダムで
	a = size.times.collect{rand(10)}

	p "array size: #{a.size}"
	Benchmark.bm(16) do |x|
	  x.report("inject in map") {n.times do; a.inject_in_map; end}
	  x.report("inject delete_if") {n.times do; a.inject_delete_if; end}
	  x.report("index rindex") {n.times do; a.index_rindex; end}
	end
}

ベンチマーク結果

ベンチマークには,

を使いました.

予想していたように,反復が多いmap内でのinjectは処理が遅いようです.
追加してみたinject -> delete_if はHashを生成する分配列が大きくなると遅くなりますね.
単に重複だけ見る場合はArray#index とArray#rindexを使う方法が早いようです.
# Rubyらしくてもっといい書き方があれば知りたいです :-)

ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin10.8.0]
"array size: 10"
                      user     system      total        real
inject in map     0.060000   0.010000   0.070000 (  0.057868)
inject delete_if  0.010000   0.000000   0.010000 (  0.011259)
index rindex      0.010000   0.000000   0.010000 (  0.010686)

"array size: 100"
                      user     system      total        real
inject in map     0.370000   0.000000   0.370000 (  0.365121)
inject delete_if  0.030000   0.000000   0.030000 (  0.036980)
index rindex      0.030000   0.000000   0.030000 (  0.029389)

"array size: 1000"
                      user     system      total        real
inject in map     3.020000   0.010000   3.030000 (  3.056347)
inject delete_if  0.300000   0.000000   0.300000 (  0.298579)
index rindex      0.110000   0.000000   0.110000 (  0.107295)

"array size: 10000"
                      user     system      total        real
inject in map    29.840000   0.090000  29.930000 ( 30.700796)
inject delete_if  2.900000   0.010000   2.910000 (  2.910935)
index rindex      0.870000   0.000000   0.870000 (  0.921698)

MacBookのバッテリーを交換してもらってきた.

きっかけ

MacBook の座りが悪くてがたがたするなーと思って
ふとひっくり返してみてみたらバッテリー部分がこんもり膨らんでいたので
Genius Barに駆け込んできました.

バッテリーが膨らんだのはMacbook 2008 early の中位モデル.
3年以上前に買って,クラムシェルモード*1 で毎日のように使ってました.
電源アダプタを繋いでいないと動かせないので電源はつなぎっぱなし.

Genius Barにて

Genius Barの方が言うには,
(1)バッテリーの暴発や火災を防ぐために膨らむようになっている
(2)月に一度くらいは最低でもバッテリーを使いきって再び充電したほうが良い
とのこと.
なぜ?どうして?と思ったのですが,
とその仕組みを確かめられないのでお約束として守っていたほうが良さそうです.

Apple Careが切れているし,
バッテリーはその保証対象外だけれども,
という前置きで,無償で交換してもらってきました.

Genius Bar に来たから特別だよ,と,
信者を増やせそうな 素敵な取り計らいをしてもらいました.
# 他の人に聞いてみたところ,Genius Barに駆け込んだ人はバッテリーを無償交換できているらしい.

放置するときは電源アダプタを抜きつつスリープさせて様子見したいと思います.

ついでに

もう一つついでに聞いてきたところ,
最近のMacBookは電源なしでクラムシェルモードが動くそうです.
電源を落とすよりもスリープを推奨するAppleらしい設計ですね.

Genius Bar の脇ではMacBook Air の最新版が売られていて
これは新調したほうが良いだろうかーと思いながら帰ってきました.

*1:外部ディスプレイやキーボードを接続して閉じて使う方法 http://support.apple.com/kb/HT3131?viewlocale=ja_JP

「集合知プログラミング」をRubyで書いてみよう

集合知プログラミング

集合知プログラミング

何年か前に買って斜め読みしたまま放置していた
集合知プログラミング」をRubyで書いてみようとふと思い立ったので
とりあえず決意表明のエントリ*1

github

https://github.com/hrstt/collective_intelligence

内容は...

  • コメントは殆ど書いていない
  • git のコメントは似非英語
  • Snow Leopard に付いてきたruby 1.8.7*2 で確認
  • del.­icio.­us などウェブサービスからデータを取る部分は割愛
  • サンプルデータは lib/PCIData にまとめる
  • Array など標準クラスに追加するメソッドは lib/Misc にまとめる

としています.

  • グラフ画像どうするんだ?
  • SVMのライブラリ依存をどうするんだ?
  • ruby 1.9.2 に合わせなくてよいだろか?

といった課題は書いていく中で理解していこうと思ってます.

*1:週末ごとにゆるゆると進めるペースで続けようと思ってます.

*2: ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin 10.0]

RVM 関連のエントリまとめ

rvmをネタにずいぶんエントリがたまってたんだなぁと気づいたので
自エントリのまとめをしておこうと思います.
# 同じようなことばっかり書いている気もする.

Snow Leopard

新しめのエントリ.Xcode 4 を買うと,rvm周りに関しては
MacPortsのお世話にならなくて良いのがいいですね.

関連ライブラリ

readlineやopensslはrvmから入れたほうが他の環境を汚さずにいいかも.
# ライブラリなくてインストールし直しとか面倒です :-(

Ubuntu

Railsの2系を使うので,Redmineを動かすなら専用に環境作ったほうが幸せ.
そう思って試してみた内容です.

  1. Ubuntu 10.4 でredmine その1 - rails導入編 - - たぐってつづる はてなブックマーク - Ubuntu 10.4 でredmine その1 - rails導入編 - - たぐってつづる
  2. Ubuntu 10.4 でredmine その2 - git編 - - たぐってつづる はてなブックマーク - Ubuntu 10.4 でredmine その2 - git編 - - たぐってつづる
  3. Ubuntu 10.4 でredmine その3 - nginx編 - - たぐってつづる はてなブックマーク - Ubuntu 10.4 でredmine その3 - nginx編 - - たぐってつづる

以下は真似しちゃダメよ,なエントリ.
rubygemsUbuntuのパッケージから入れると
バージョンアップ等でつまずきやすいのでやめたほうがいいです.
root権限でrvm導入も,せっかくの手軽さを失ってしまうので勧められません.
晒し上げのようにこの一覧にも載せときます.