2013年11月1日金曜日

angular-jsのng-optionsで謎の空白でvalue="?"なoptionが発生する

しばらくハマったのでメモ

ng-optionsでoptionを設定するselectに外から持ってきたデータをあとで追加するときに、何故か空白の要素が追加されてしまって困っていました。結局ng-modelとng-optionsを両方使うときに、ng-modelで指定されているオブジェクトが追加された要素にない場合に発生することがわかりました。なので元のデータを入れてやるか、データが追加された後にもう一度ng-modelで指定しているオブジェクトを設定して直してやる必要があります。まあ考えれば単純な話なのですが気づくまでに時間がかかってしまいました。


再現HTML
初期時様態のselect
ng-repeatで使うarrayにng-modelで指定されているデータがある場合(load1)
ng-repeatで使うarrayにng-modelで指定されているデータがない場合(load2)

2013年7月31日水曜日

Linux環境メモ

今使っているPCはThinkpad x201sなのですが、Linuxで使うにあたって幾つか設定したのですが、すでに忘れかけているので、忘れる前にメモしておきます。

  • CPU fanの回転数を最大にする echo "level full-speed" > /proc/acpi/ibm/fan
  • batteryの情報は /sys/devices/platform/smapi/BAT[01] にある。{start,stop}_charge_threshを指定すると充電開始・終了残量を指定できる(要smapi)
  • 面倒ならtlpを入れると良い。AURにもパッケージがある。
  • powertopでTunablesにある項目をGoodにするとバッテリーの持ちが少し良くなる気がする
  • AndroidのEmulaterでAtomなイメージを動かすのにKVMを使うには、以前は追加のオプション -qemu -enable-kvm が必要だった気がするけど最近は不要っぽい。-verboseをつけると emulator: KVM mode auto-enabled! と出るし、lsmodで見るとkvm_intelの使用数が増える。
  • Arch LinuxでKVMを使えるようにするにはArchのWikiにあるKVMのエントリに従うだけなので簡単。kernel moduleのloadとKVMを使いたいuserをkvm groupに追加するぐらい。

2013年7月8日月曜日

.NET(C#)でMS Office(Excel)のバージョンに依存しないアプリを作る

以前作ったツール(C#からExcelを使う)が別の環境で動かないと言われ、調べたらMS Officeのバージョン違いだった(2007→2010)。最初にその話を聞いたとき、詳しい情報を聞いていなかったので、とりあえず自分のところ(MS Office 2013)でビルドしなおしたのを送ってもダメだったいうので、エラーメッセージ聞いたらわかった。

私が知っていたこの依存を無くす方法は、遅延バインディングを使うかCreateObject使うとか型情報が使えなくて面倒なやつばっかりだったので、このツール以降に作ったExcelを使うやつはどうせ型情報使えないのならとIronPythonを使っていました。とはいえ、C#で書いてあるのを書き直すのも面倒なので、他に方法が無いか調べたところ、MSのサイトにチュートリアル: Microsoft Office アセンブリからの型情報の埋め込み (C# および Visual Basic)というのがあり、同じこと(Embed interop types)をSharp developでやってみたところ、2点ほどはまりどころがあったものの動くようになりました。

問題があったところ

  1. Microsoft.CSharpを参照に追加しないとコンパイルエラーになる
  2. ビルド環境が.NET 4.5で、実行環境が.NET 4.0だと実行時エラー。エラー情報で検索してStackOverflowでExcel interop MissingMethodExceptionを見つけたので、.NET 4.5を消して4.0にしたら解決した。

後者はWindows 8(.NET 4.5)環境では解決できないので、対象環境を4.5にするのが良いのだろうか。ターゲットを3.5にしたらコンパイルできなかった(Embed interop typesがC#4.0からだから)。

今後は.NET 4.0以降を対象にOfficeのバージョンに依存しないアプリを作る場合は、この方法が使えそうです。事前バインディングだと補完が出来るし、実際かなり楽なのでもう戻したくありません。

(追記)
4.5の環境に4.0のリファレンスアセンブリをインストールしてビルドしたものは、4.0がインストールされているところで動かなかったので、4.5環境で4.0環境用にビルドするのは多分無理なんだろう…。しばらく4.0の環境をとっておくしかなさそう…。

2013年7月6日土曜日

Igo-python 0.9.3リリースしました

igo-python 0.9.3をリリースしました。前のエントリのとおり拡張領域にある文字を扱えるようにしたものです。この対応で、Unicode文字列として持っていたデータをunsigned shortのarrayとして持つようになりました。そのせいか少しだけ高速化されたようです。このような対応を行った理由は前のエントリにあるとおり、辞書内の文字列がUTF-16(Javaのchar)であるためです。

timeitで簡単に測ってみました。青空文庫の夏目漱石、吾輩は猫であるを解析するのにかかった秒数です。

この後の予定は、パッケージングなどの見直し、その後にmmap対応を考えています。

2013年7月5日金曜日

ipadic以外をigo-pythonで使う

igoはMeCab用の辞書が使えるはずなので、ipadic以外の辞書を試してみました。naist-jdic, UniDicを試しましたが、どちらもバイナリ辞書を作って、そっちを指定するというだけでは行きませんでした…。

naist-jdicはバイナリ辞書の作成が失敗しますが、回避可能です。失敗する原因は、辞書にある,を含んだエントリなので、パースしているところを直すのが一番いいのですが、delimiterが指定できるので、とりあえず元ネタのCSVの方をTSVに書き換えることで回避しました。
以下のスクリプトでできます(gist埋め込みが消えてたので追加しなおしました)。
CSVからTSVにする
python csv2tsv.py mecab-naist-jdic-0.6.3b-20111013/naist-jdic.csv EUC-JP > naist-jdic.csv && mv naist-jdic.csv mecab-naist-jdic-0.6.3b-20111013
バイナリ辞書を作る
java -cp igo-0.4.5.jar net.reduls.igo.bin.BuildDic naist-jdic mecab-naist-jdic-0.6.3b-20111013 UTF-8 ' '  # 最後のシングルクォートはタブ
生成されたバイナリ辞書は少し使ってみただけですが、問題無さそうでした。問題としては、解析結果の素性もタブ区切りになってしまうことでしょうか。


UniDicの方は特に問題なくバイナリ辞書の作成が可能です。但し、igo-pythonの方に問題があり、そもそも辞書がロードできません。とりあえず対応したものはコミットしてあります。
辞書のロードでエラーが起きる原因は、辞書内の文字データ(UTF-16)をPythonの(Unicode)文字列に変換するときに、サロゲートペアの片方だけがあった場合にUnicode文字に変換できずエラーになるためです。なので、上記の対応では文字列にせず2byteの整数配列として保持することでこの問題を回避しています。

また、サロゲートペアで表現する文字を含んだ文字列を形態素解析しようとすると、例外が発生してしまいます。こちらは修正中です(修正した0.9.3をリリースしました)。


配布物は大きくなってしまいますが、コンパイル済みの辞書も入れようか考えています。

2013年7月4日木曜日

Python 3.4のEnumを使ってみた

Python 3.4で導入される予定のEnumを使ってみました。PEP 435 -- Adding an Enum type to the Python standard libraryは見ていたのですが、実装もドキュメントもすでにあります。enum.pyだけ持ってくればPython 3.3でもとりあえず動くようです。

EnumといえばEnumのSwitch/Caseかなと思い、全パターン網羅しているかチェックするの程度なら簡単そうなので適当に実装してみました。

Enumにメンバーを追加しなければ継承できるので、switchを持ったクラスを作るのもいいと思ったけど、すでに存在しているEnumに対して使えないのは微妙なのでやめた。

キーワード引数でEnumの名前とその要素だった時に呼ぶ関数を渡す形でswitch関数を実装してみました。キーワード引数の名前とswitchする値が属するEnumの名前をチェックして、全てのパターンが網羅されていないと例外を投げます。デフォルトは _ にしました。

Weather terms / 天気予報の用語

Sunny/Clear, Cloudy, fogとかは知ってたけど、良く違いがわからないのがあったのメモ。天気予報のサービスによって表現が違うので、同じようなのがあるけど。
  • Drizzle - とても弱い雨/霧雨
  • Mist - Drizzleより少し粒が大きい
  • Sprinkles - 小雨
  • Rain - 雨
  • Showers - 通り雨(局所的な大雨)
  • Smoke - 煙ってる(天気予報とは別な感じがするけど)
修飾語として、Mostly, Partly, Few, Isolated, Scatteredあたり。
  • Isolated Thunderstorm - 局所的な雷雨
  • Scattered Thunderstorm - 広範囲の雷雨
  • Few showers - 小雨
  • Mostly cloudy - 殆ど曇り
  • Partly cloudy- 雲が半分以下
  • Partly sunny- 雲が半分以上
  • Mostly sunny- 殆ど晴れ
同じ天気予報で全部見ることは無いけど、快晴から曇りまで並べると多分
Sunny > Mostly sunny> Partly cloudy > Partly sunny> Mostly cloudy > Cloudy

2013年6月18日火曜日

Feedeen使い始めた(けどまだインポートだけしかしてない)

申し込んでおいたFeedeenの招待が来たので、早速Google Readerからフィードをインポートしてみたところ、インポート結果のメールを見ると、そこそこの数の失敗があった。

メールにはタイトルが書いてあるので、そのタイトルをもとにOPMLからURLを探して、
存在しているかどうか・移動先があるかなどをチェックしながら、失敗したのを追加していたら、3件目ぐらいで面倒くさくなったので自動化したくなったので、とりあえず手始めにメールとOPMLからフィードのURLだけ取り出すのを作ってみた。

結局それではいろいろ面倒なので、インポートするのに使ったOPMLから、インポート結果のメールでエラーがあったと言われたフィード以外は削除、さらにurllib.request.openでアクセスしてみてアクセスできなければ削除して、取り込めそうなフィードだけ残すようにしてみた。

Gistに貼ったスクリプト

2013年6月16日日曜日

Emacs環境を久しぶりに見なおした

dual bootにした結果Linuxを使う時間が増えて、Emacsを使う時間も増えたので、ちょっと環境を整理してみた。

まずフォントの設定。9ptだとちょっと小さく感じることがあるので大きくしたいが、half width:full width=1:2にならないと気になるので、ptではなくpxで指定して
(set-default-font "VL Gothic:pixelsize=16")
とした。pixelsizeが偶数なら1:2になるはず。

野良で.emacs.dに突っ込んでいた幾つかのelispをMELPAのパッケージで置き換えた。

次にPythonのauto-completionをJedi.elにした。設定は簡単だし軽いと思う。これはMELPAのパッケージリストを見ていた時に思い出した。以前見かけて使ってみようと思っていたのにすっかり忘れていた。

ついでにhelmも使ってみたけど、なれるまで大変そうなのでやめておいた。
C-x bにhelm(anything)-for-files割り当ててるのを見たので試しに、やってみたら遅くてなかなかつらい。一個前(previous-bufferではなく)に戻るのにC-x b(switch buffer)使うのが悪いのかもしれないけど、C-x b RETみたいに入力するとbuffer作成中に切り替え先を確定してしまうので期待通りに動かないことが多かった。

C-x b周りをいじってる時に、前から使っているiswitchbとidoで迷ったものの、idoにしてみた。ただ、idoはido-find-fileが素のfind-file+session(+minibuf-isearch)みたいに過去に開いたファイルを開けないのが辛いので、find-fileはそのままにした。最近開いたファイルだけを開くのであればrecentf+idoでやってる例が幾つか見つかったけど、ファイルを開くという操作に対して別のキーを割り当てるのは厳しい。ido-find-file自体は使いやすいんだけど…。

2013年6月8日土曜日

Linux環境をVMからdual bootに移行した

しばらくWindows上でArch LinuxのVMを動かしていましたが、メモリ使う処理をするのに不便なので、dual boot化しました。Thinkpad x201sのUltra Baseに増設した1TBのHDDにWindows 8と一緒に入れてWindows 7,8, Arch Linuxを起動できる状態です。Windows 7/8は普通に起動するだけですが、Arch Linuxは手を抜いて起動デバイス選択メニューから起動させるようにしました(grubを増設ディスクのMBRに入れられるので)

VMに物理ディスクをマウントできるようにしてrsyncでコピー、あとはgrub2を設定しなおしぐらいでできたので特に書くことはない感じだった。
しばらくはVMからも起動できるようにしておいたけど、必要性がない感じがしてきたのでVMware関係(open-vm-toolsとかxf86-video-vmware/xf86-input-vmmouse)は削除。

dual boot化で入れたのは無線LAN、電源管理、Bluetooth関係のパッケージくらい。無線LANはnetctl(wifi-menu)ですませることにしました。
Windows 8だとやり方がわからないバッテリ充電レベルの調整(40%まで減ったら充電開始、80%で充電止めるとか)もできて満足です。

KVMとかが遊びやすくなりました。

btrfs send/receive

いつの間にかbtrfs send/receiveができるようになっていたらしい。zfsのやつと使い方は基本的に同じ。

自分の環境(Arch Linux)で試しにbackupをとる手順をやってみた。
[root@archbox ~]# uname -a
Linux archbox 3.9.4-1-ARCH #1 SMP PREEMPT Sat May 25 16:14:55 CEST 2013 x86_64 GNU/Linux
[root@archbox ~]# btrfs --version
Btrfs v0.20-rc1-253-g7854c8b
 手順は簡単
  1. snapshotをとる(readonlyじゃないとsendできないので-rをつける)
    btrfs subvol snapshot -r /home/ /home/backup (/homeがsubvolume)
  2. snapshotをbackup
    btrfs send /home/backup/ | btrfs receive /backup
だけ

sendしたstreamをとっておくだけでもいいし、基準のsnapshotと新しいsnapshotを使ってincremental backupもできる

incremental backupは、前の手順の続きで
  1. 新しいsnapshotをとる
    btrfs subvol snapshot -r /home/ /home/backup2
  2. 親(基準)を指定してsend
    btrfs send -p /home/backup/ /home/backup2 | btrfs receive /backup

しばらくブラウザで遊んだあと試してみた結果
[root@archbox ~]# btrfs send  /home/backup | wc -c
At subvol /home/backup
4609013921
[root@archbox ~]# btrfs send  /home/backup2 | wc -c
At subvol /home/backup2
4610672892
[root@archbox ~]# btrfs send -p /home/backup /home/backup2 | wc -c
At subvol /home/backup2
59143976