2008年6月30日月曜日

Haskell の畳み込み関数 - foldl, foldr

1. リストを畳み込む foldl と foldr

Haskell のサンプルコードを見ていると、よく見かける foldl と foldr 。名前からして両者は対照的な関数のようだ。

PreludeList Operation の分類において、

として、わざわざ分類されているところを見ると、重要な関数なのだろう。 (@_@)

そういえば、Reduce と言えば、Python の関数 reduce を思い出した。

これと似たものなのかな?

 

2. どのように計算が行われるのか

foldr と foldl の違い - 言語ゲーム」によると、foldr, foldl は、以下のように計算が行われる。

foldr (+) 4 [1, 2, 3] -- 1 + (2 + (3 + 4)) == 10
foldl (+) 1 [2, 3, 4] -- ((1 + 2) + 3) + 4 == 10

なるほど、これは Python の reduce() と同じ役割の関数のようだ。

Python の「2.1 組み込み関数」によると、

reduce(labmda x, y: x+y, [1, 2, 3, 4, 5])((((1+2)+3)+4)+5) を計算します。

Ruby では inject に相当する。

 

3. foldl と foldr の定義を見ながら理解する

動作を理解するために、foldl とfoldr の定義を見ながら、具体的な計算を、定義で置き換えてみる。

 

foldl の計算を、定義で置き換える

まずは、foldl から。定義は、Haskell Code by HsColour より、

foldl        :: (a -> b -> a) -> a -> [b] -> a
foldl f z xs = lgo z xs
      where
  lgo z []     =  z
  lgo z (x:xs) = lgo (f z x) xs

これを見ながら、

foldl (-) 100 [1,2,3]

の計算の過程を追ってみる。

lgo 100 [1,2,3]
lgo ((-) 100 1) [2,3]
lgo ((-) ((-) 100 1) 2) [3]
lgo ((-) ((-) ((-) 100 1) 2) 3) []  -- ここで lgo z [] = z にマッチ
((-) ((-) ((-) 100 1) 2) 3)         
((-) ((-) 99 2) 3)
((-) 97 3)
94

 

foldr の計算を、定義で置き換える

次に foldr。定義は、Haskell Code by HsColour より、

foldr            :: (a -> b -> b) -> b -> [a] -> b
foldr k z xs = go xs
      where
        go []     = z
        go (y:ys) = y `k` go ys

同じように

foldr (-) 100 [1,2,3]

の計算を定義で置き換える。

go [1,2,3]
1 - go [2,3]
1 - (2 - go [3])
1 - (2 - (3 - go []))
1 - (2 - (3 - 100))
1 - (2 - (-97))
1 - 99
-98

よし!これで動作を覚えた。

 

4. 他の言語との比較

最後に、他の言語で、Haskell の map, filter, foldl に相当する関数、メソッドを整理しておく。

  • Haskell : map, filter, foldl
  • Python : map, filter, reduce
  • Ruby    : map, select, inject

 

試してみる

Ruby では、inject。

irb(main):001:0> [1,2,3].inject(100){|x,y| x - y}
=> 94

Python では、reduce。

>>> reduce(lambda x,y: x - y, [1,2,3], 100)
94

Firefox で効率的に Tumblr - Google Reader の活用, 複数のテキスト選択, 全画面モード

Firefox のアドオン tombloo

tombloo 。対象を選択して、右クリック > J

 

Google Reader で Tumblr

Google Reader で気に入ったサイトの RSS を取得。

Tumblr on Google Reader を利用して、気に入った記事がアクティブな状態で Shift + R キー を押す。(要、Greasemonkey)

追記 (2009.1.24) : 一時期 Shift + R が使えなくなってしまったので、 reblog する気がなくなった。2009.1.20 にアップデートされたものをインストールしたら、また使えるようになった。これがなければ多分 Tumblr やってないだろうなぁ...。

記事の先読みが少ないと感じたら、Google Reader Prefetch More を使う。

 

Google Reader におけるタグの活用

Tumblr を利用したサイトは、Tumblr on Google Reader Shift + R キーで素早くタンブれるので、それらをまとめてタグ付けしておく。(ex. tumblr)

それ以外は上記のタグとは別のタグをつけてまとめる。 (ex. tumblr’)

追記(2008.10.26) : RSS を一部しか出力していない Tumblr は見なくなる。(Advanced > Truncate RSS feed) 削ぎ落されてないテキストも読まなくなる気がする。

 

サイトのレスポンスに応じて

タンブる際、対象サイトのレスポンスが良ければ、[Updated] Google Reader Preview Enhanced v1.07g を入れておくことにより、 Google Reader の記事のタイトルをクリックすることによって各記事のフレームの中で元記事にアクセスできる。インラインで開いて tombloo で対象を選択して、右クリック > J 。

対象のサイトのレスポンスが悪い場合は、Easy DragToGo を利用して記事のタイトルをドラッグし、バックグラウンドのタブで開いておく。

 

reblog するテキストが複数の場合

追記 (2008.7.2) :

Firefox 3 なら、 Ctrl で離れた場所にあるテキストを複数選択。(Mozilla Japan - Firefox 3 リリースノート の「テキスト選択の改善」より)

 

全画面モード

追記 (2008.11.2) : F11 で全画面モードにするといいかも。

元に戻すときは再度 F11 を押す。全画面モードになっていても、Ctrl + L でロケーションバーが表示され、他のタブも見えるようになる。 Ctrl + Tab でタブを切り替えることができるし、Ctrl + K で検索もできる。

普通にショートカットを覚えていれば広くて便利かも。


関連記事

2008年6月29日日曜日

親父の自作 PC の検討

ノート PC 修理へ

親父のメイン PC はノート型。いつの間にか親父の視力は結構悪くなっていた。めちゃ老眼。 (@_@;) 遠近両用の眼鏡をはずしては、ノート PC の画面を覗き込むようにして文字を追っている。その様子を傍らから見ていると、昔に比べて画面の情報を探すのが遅くなったなと思う。操作がわからないとき色々と教えることがあるのだが、「ほら、そこのボタンの...」と言ってもなかなか見つけることができない。脳の老化がはじまっていることも勿論だけれど、画面が小さくて見にくいために思うように PC を操作できないということも多分にあると感じた。

ノート PC は小さいと言っても、画面は標準よりも少し大きい。しかし、デスクトップ PC に比べたら雲泥の差がある。ぼくの PC の画面を覗き込んではよく言っていた。

「画面が広くていいな。」

とは言ったものの、自分の PC の画面なんて 17 インチしかないので、今の PC としては小さい方だ。それでもノート型と比べれば圧倒的に見やすい。

今年になってはじめて自作 PC にチャレンジした。組んでみたら動かなかったということもなく、以前に比べたら快適な PC ライフを送っている。ちゃんと動いたものだから、親父にしたり顔で「自作っていいよ」とか言っていた。 ^^; そんな折、たまたま親父のノート PC が修理で一週間ほど手元からなくなることになった。

「一台、デスクトップ PC もあるといいんだけどな ...」

「じゃあ、自作してみる?」

「適当にパーツ決めてくれ。金はあまりケチらなくていいから。」

こんな感じに親父の PC を組むことになった。

ところで、親父にとって自作 PC のメリットは画面の広さだけではない。メーカー製の PC はインストールするといらないソフトもてんこ盛り。これがどうやら気にくわないらしい。なぜか親父はよく再インストールをしていることがある。聞いてみたら、システムにとって必要なファイルまで削除してしまい、PC の動きが悪くなってしまったとのこと。ぼくから見たらインストールマニア。そんな人、他に見たことがなかった。そういった点からしても、自作 PC は親父にとって魅力的に映ったようだ。

 

方向性を考える

PC でどんなことをしたいかと聞いてみた。そうしたら、今一判然としない。動画を編集できたらいいとか、TV を録画したいとか、ブルーレイを使いたいなど。全ての要求を満たそうと思ったら、結構金額がいってしまう。金はケチらなくてもいいと言っていたが、ある程度ケチって次回に回した方がいいような気がする。どうせ 2, 3 年もすれば今作った PC でも不満だらけになる。そこそこの値段で十分安くなっているパーツで満足させ、どうしてもこれだけはゆずれないというものだけにちょっと投資するのがいい。ちなみに自分の PC は最低ラインは確保しつつ、全てを削れるだけ削った。 ^^;

親父といろいろ話した結果、結局一番重要なのは画面の大きさではないかということになった。猫背になって覗きこまなくても読むことのできる文字の大きさを確保すること。そして、複数のアプリケーションを立ち上げたときの視認性を良くすること。当初は 19 インチのモニタで十分だと考えていたが、ここだけははりこんで 24 インチのワイド画面にすることにした。加えて、はりこんでと言うわけではないが、音楽好きであることを考えてサウンドカードも付けることにした。また、うるさい PC はゴメンだということで静穏性にも配慮することに。結局、TV を見るとかブルーレイで録画とか全て今回は見送ることにした。

基本的な要求をまとめておく。

  1. 大きな画面がいい (老人でも見易く)
  2. 静かな PC であること (寝室においても問題のないように)
  3. いい音で音楽を聴きたい

 

具体的な構成を考える

さて、最低限の要求を設定することができたので、次に具体的にパーツを決めていくことにした。とは言っても、自作 2回目なのでそんなにわからない。何が必要なパーツなのかくらいしか知らない。ちょっと前に自作したばかりなので、そのときに買った本が役立った。(パソコンの自作 2008年 04月号 [雑誌], 日経 WinPC (ウィンピーシー) 2008年 05月号 [雑誌]) 前回はケチりにケチって安く仕上げたが、今回は本に載っている定番と言えるパーツを使うことに。パーツを選ぶときは、価格.com でよく売れていて、かつ、口コミの数が多いものを選ぶことにした。

 

マザーボード、CPU

まず最初にマザーボードを決めた。定番中の定番を選んでいくということで ASUS P5K-E を。そして CPU にはインテル Core 2 Duo E8400 BOX。同じくらいの価格である Core 2 Quad Q6600 も考えたが、一度に複数の処理をさせることがないので、クロック周波数の高い E8400 にした。これも老人向けと言えばそうかもしれない。親父の PC の操作を見ていると、一つのことしか処理をさせていないことが多い。同時にあれこれをするという考えがないようだ。

CPU クーラーについては付属のものを使うことにした。 E8400 なら消費電力も少なくそんなに熱い CPU ではないこと、また、ケースが静穏設計されているものを組み合わせれば問題ないと考えたからだ。

 

モニタ、グラフィックボード

今回一番重要なのがモニタ。 24 インチワイドの中から選ぶことにした。液晶モニタ・液晶ディスプレイ 売れ筋ランキング の中から値段が手頃なものを探すことに。見てみたら 10 万近くするものから、4, 5 万のものまで幅が結構ある。しかし、パソコンで動画を鑑賞することがメインではないため、4, 5 万のもので十分。モニタにはいろいろと種類があるようだ。親父がメインで使っている ノート PC はツルピカの液晶だ。昔に比べたら映り込みが少なくなっているが、親父はどちらかと言うと映り込みのしない液晶が欲しいとのことだった。机は部屋の奥の方にあるのだけれど、南向きの部屋に対して北向きに机が配置されているので、どうしても窓からの光が気になるようだ。これは値段にとっては好都合だった。全体的にツルピカの方が液晶の値段が高い。

さて、そんな中で BenQ G2400WD が候補に上がった。値段は手頃。ツルピカ液晶ではない。仕様を見ると、

解像度 1920x1200(WUXGA)

入力信号 アナログRGB / デジタルDVI-D(HDCP対応) / HDMI

ところで、マザーボードの P5K-E にはグラフィックボードを乗せなくてはいけない。パソコンの自作 2008年 04月号 には、静音化のためにファンレスのグラボが使われていた。そのため当初ファンレスのグラボを探した。しかし、静音化のために密閉性の高いケースを使おうと思っていたのでファンレスはやめた。熱がこもるといけないからだ。そうすると選択肢が広がった。が、しかし、どれを選べばいいのやらわからず。 ^^; 結局、3D ゲームをやるわけではないので、売れ筋で安いグラボを選ぶことにした。で、GALAXY GALAXY GeForce 8600GT を。

液晶がでかいので、念のため仕様を確認しておいた。GeForce 8600GT << Product Details << GALAXY Technology によると、

ONE dual-link DVI outputs support two 2560x1600 resolution displays (…)

HDCP Capable (Optional)

dual-link とは、デュアルリンクとは 【dual link】 - 意味・解説 : IT用語辞典 によると、

コネクタには24ピンのDVI-Dデュアルリンクもしくは29ピンのDVI-Iデュアルリンクを用いる。UXGA(1600×1200)まではTMDSリンク1本のシングルリンクで対応できるが、これを超える解像度が必要な場合にデュアルリンクを用いる。

ということで、全然余裕だということわかった。

それから HDCP とは、

ブルーレイコンテンツをパソコンで再生する場合、光学ドライブグラフィックスボードディスプレイが HDCP に対応しているかが確認され、 HDCP 対応機器間でのみ、 AACS によって暗号化されたデータのやり取りができる。

(パソコンの自作 2008年 04月号 [雑誌], p107 より、太字は引用者による。)

とあるように、ブルーレイのコンテンツを再生できるかどうかというこに関わってくる。この点、このディスプレイもグラボもクリアしている。

 

ケース、電源

静穏性の高いケースとして定番の ANTEC SOLO にした。このケースには電源が搭載されていない。雑誌を読んでも、どの電源がいいのかよくわからなかった。とりあえず 400W あれば十分という感じで書かれていた。しかし、ネットを読んでいると、わりと電源は大事だよということも見かけるので、高くはないけれど激安ではないものにすることに。静穏性のことも考えて Abee AS Power Silentist S-550EB にしたかったが、注文しようとした店ではすぐに手に入らないため、CORE POWER2 CoRE-500-2007 にした。これだと 500W にしては安い部類だと思ったが、自分の PC が電源付属のケースで 8000円 くらいだったので、とりあえずはいいかと判断した。

 

サウンドカード

価格.com - サウンドカード・ユニット 売れ筋ランキング を見ると、ONKYO のものが定番のようだ。これも値段に差があり、8,000 ~ 22,000 くらいの開きがある。実際のところどうなのかと評価を検索してみると、やはり違いがあるという意見から、それほど素人ではわからないという意見まで幅があった。だから、中間のランクのものにしようと思ったけれど、これまた注文しようとした店ですぐには手に入らず。仕方なく、一番安い ONKYO SE-90PCI にした。親父も耳が徐々に遠くなってきているようなので、まぁ、十分と言えば十分。 ^^;

 

メモリ, 光学ドライブ, HDD

この辺は、どこがいいのか全くわからないので、自分が買ったものと同じのにした。ただし、 HDD は 500G に。

 

キーボード

キーボードは、机を広く使いたいという要求に合わせたものにした。サンワサプライ:SKB-SL09SV は使わないときに机に立てることができる。また、テンキーもついていなくてコンパクトだ。しかも、値段が安い。

 

その他

無線 LAN  も自分が買ったものと同じものを。そして、OS は Vista の Premium に。

Haskell の関数合成

1. 関数合成の例

Haskell では (.) を用いると、2つの関数を合成できる。

例えば、与えられた数値に1加える関数 add1 と、与えられた数値を2倍する mul2 がある。

add1 x = x + 1
mul2 x = x * 2

100を2倍した後、1加えるには、

*Main> add1 $ mul2 100
201

100に1加えた後、2倍するには、

*Main> mul2 $ add1 100
202

上記の関数を(.) を使い、合成したい場合、

add1mul2 = add1 . mul2
mul2add1 = mul2. add1

これを使うには、

main = do print $ add1mul2 100   --- 201
          print $ mul2add1 100   --- 202

(.) を使うと、シンプルな関数を組み合わせて、複雑な関数を定義することができる。

 

2. 関数合成を理解するには、部分適用について先に知るのが良い

ふつうのHaskellプログラミング」で、はじめに戸惑ったのが、この

  • 「8.2 関数合成」 (p198)

の説明。

  • 「8.3 部分適用」 (p202)

の解説の前にあったので、すんなりと理解できなかった。

同書において、「関数合成」について、以下のように述べられている。

(.) 関数は、二つの関数を合成する関数です。「合成する」とは、「2つの関数を順番に適用する新しい関数を作る」ということです。(p198)

関数と関数を合成?

(.) を適用すると関数が返されるというのは、どういう意味だろう?(@_@;)

 

3. 関数合成 (.) も関数の一種

はじめて

.

を見たとき、この記号は、Haskell で「引数を省略して書くための、特別な表記」なのかと思った。

先ほどの例で言えば、(.) を使わずに add1mul2 関数を定義するなら、以下のように書ける。

add1mul2 x = add1 $ mul2 x

この定義と (.) を使った定義を比べると、

add1mul2 = add1 . mul2
add1mul2 の引数が消されてしまったかのように見える。

同書(p199) の説明に、関数 (.) の型が書かれてる。

(.) :: (b –> c) –> (a –> b) –> (a –>c)

つまり (.) は、

「引数として 2 つの関数を与えると、関数が返される関数である」

というように、関数に過ぎない。

ただし、「部分適用」 に関する知識がない状態で、この説明を理解することができなかった。

合成する前にあった、関数の引数が消えてしまっている。これはどういうことだろうか?

という疑問を持った。

 

4. 関数を合成する関数に対して「部分適用」

上記を理解するには、「部分適用」について把握しておく必要がある。

(.) の実装を見てみる。Haskell Code by HsColour によると、

(.)   :: (b -> c) -> (a -> b) -> a -> c
(.) f g x = f (g x)

関数の型宣言における、最後の

a –> c

が括弧で囲まれていない。なぜなら、関数の宣言は右結合であるため、括弧が必要ないから。

4.1.2 型の構文 によると、

関数の型t1 -> t2 という形式で、これは、型 (->) t1 t2 と同等である。関数の矢印は右結合である。

意味は全く同じだけれど、最後の括弧がない方が、(.) 関数を

「3 つの引数を与えると、値が返ってくる関数」

という意識で見ることができる。

部分適用について理解があれば、

(.) に対して、二つの関数を与えると、あと一つ引数を与えれば値が返される関数

となり、部分適用した状態であるということが分かる。

 

5. (.) 関数を使い、型を確認する

例えば、

  1. 適当に関数 f, g を定義し、
  2. 2つの関数を (.) 関数に部分適用し、
  3. 型を確認してみる。
Prelude> let f x = x + 10
Prelude> let g x = x * 2
Prelude> :t (.) f g
(.) f g :: (Num a) => a -> a

関数 f, g を (.) に部分適用した型は、

あと一つ引数として値を与えれば、値が返ってくる関数

であることが示される。つまり、

f . g

という式は、 (.) 関数に対して、引数を 2 つ与え、部分適用した状態である。

(.) 関数の定義に戻り、3 つ目の引数 x を見れば、

(.)   :: (b -> c) -> (a -> b) -> a -> c
(.) f g x = f (g x)

これが先ほど「消えてしまった」と感じた、関数の引数であることが分かる。

 

関連記事

ウェブサイトを Prism for Firefox を使って独立したアプリケーションに変換

GTD を実践するためのツールとして Remember The Milk を使っている。というかちゃんと使いたい。 ^^; 思ったときに素早く RTM に入力するのには、 Google デスクトップのガジェットを使う。しかし、このツールはあくまでも入力のためにあり、入力したものを整理したり編集したりするのには向いていない。

いつでもすぐに使えるようにと Firefox のブックマークツールバーの先頭に RTM を登録した。しかし、これでもボタンを押してRTM のサイトが開くまでには数秒の時間を要するため、 GTD のツールとしてサイトから足が遠のいてしまう。

以前に Prism を利用してブラウザから Web アプリを独立させることをした。今では Firefox のアドオンとしても利用できるようだ。 Prism 自体が Firefox に付属してくれれば、いざサイトを独立化させるときもお手軽でいい。 ^^

 

インストール

Prism for Firefox からインストールする。

 

使い方

独立化させたいサイトを Firefox でアクセスする。

メニューより、ツール > Convert WebSite to Application を選択する。

080627-001

 

Prism のダイアログが表示されるので、 Name フィールドに適当に名前をつける。 Create Shortcuts において Desktop にチェックをつけると、アイコンがデスクトップに作成される。これをクリックして RTM を起動 (アクセス) 。

080627-003

2008年6月28日土曜日

Firefox で英語の辞書を引く

1. 英和辞典を引くためのスクリプト

わからない英単語を、マウスで指すことにより、辞書を引けるように設定した。ただし、この方法は英辞郎のデータがない使えない。

ウェブ上のデータを利用し、辞書を引くには、英語のウエブページで辞書引くのを簡単に. [ firefox greasemonkey] - hiyuzawa.jpn.org で紹介されている、

を使うと良い。Greasemonkey のスクリプトなので、予め Greasemonkey をインストールしておくことが前提となる。

このスクリプトは、わからない単語を選択するだけでポップアップ表示がされる。詳細を見たい場合には、さっと Yahoo 辞書に飛べるので便利。

080628-002

 

Fast Look up Alc

個人的には、アルク の辞書が引ける

を使いたい。しかし、アルクの利用規約に抵触するようでダメらしい。残念 ... (+_+)

※ ソースコードにおいて、表示されるエリアの CSS を設定している style プロパティの配列の要素として、'z-index: 9' を追加しておくとよい。

 

2. 英英辞典を引くためのアドオン

英英辞典には、Answers.com を利用したアドオンを使う。英単語の発音を聞けるので重宝している。

使い方は、調べたい単語の上で

alt キーを押しながら左クリック

この操作はカスタマイズ可能なので、別のキー操作とバッティングする場合は変更するとよい。

080628-003

 

3. その他

[firefox][Greasemonkey][javascript] Fast look up JP and EN - jimo/memo

は、辞書以外にも Wikipedia などの検索ができる。

Haskell でリストの要素を join - List.Data の intersperse, intercalate

Haskell で Python の String#join, Ruby の Array#join に相当するものは何だろう?

Prelude, Data.List を眺めてみるが、どこだろうか ... (@_@;)

 

自分で実装

とりえあえず、自分で書いてみる。 まず使い方を考えた場合、こんな感じ。

join ", " ["aaa", "bbb", "ccc"]

文字列と文字列のリストに join を適用すると、連結された結果の文字が返されると考え、

join :: String -> [String] -> String
join _ [] = []
join sep ss@(x:xs) = x ++ case length ss of {1 -> ""; otherwise -> sep} ++ join sep xs

ワイルドカード(ふつうのHaskellプログラミング, p170)、アズパターン(同, p173)、case 式(同, p177) の練習になったが、なんともぎこちない感じが。 ^^;

少し改良してみた。 case 式を使うのをやめて、リストパターン(同, p172)で。

join :: String -> [String] -> String
join sep [] = []
join sep [x]  = x
join sep (x:xs) = x ++ sep ++ join sep xs

最初、リストパターンについてわかっていなくて、次のように書いていた。

join sep [x]  |  length x == 1 = x

冗長だ ... (@_@;) これにずっと気がつかず、意味のないガードを。 ^^;

ちなみに、[], (x:xs) はデータコンストラクタによるパターンマッチ。(同上, p173) うーん、ややこしい。(+_+) パターンマッチによるフィールドへのアクセス(同上, p226)で書かれていたこと同じものに分類される。うーむ... CCC

 

Data.List

BBL::Wiki - Haskell::覚え書き によると、

Rubyでよく使うArray#joinはList.intersperse::a->[a]->[a]を利用すれば似たようなのが書ける。

Data.List の intersperse を見てみると、

The intersperse function takes an element and a list and `intersperses' that element between the elements of the list. For example,

 intersperse ',' "abcde" == "a,b,c,d,e"

ところで、この語の意味は Yahoo!辞書 – intersperse には、

1 …を間隔をおいて配置する, ばらまく, ちりばめる, 点在させる
flowers interspersed among the grass
草むらに点々と咲く花.

2 …に(…を)点在させる, …に(…で)変化をもたせる((with ...))
intersperse one's talk with good humor
おもしろいユーモアをはさんで話に変化をつける.

あるものの中に挟み込まさせるというイメージか。 join のように「つなげる」とは対照的な語が使われているところがおもしろい。

 

intersperse の実装を真似る

Haskell Code by HsColour にあるソースコードを見てみると、

intersperse  :: a -> [a] -> [a]
intersperse _   []      = []
intersperse _   [x]     = [x]
intersperse sep (x:xs)  = x : sep : intersperse sep xs

あ~、綺麗。 (@_@) これを真似して先ほど書いたコードを修正してみよう。

join :: [a] -> [[a]] -> [a]
join _ [] = []
join _ [x]  = x
join sep (x:xs) = x ++ sep ++ join sep xs

 

intercalate

intersperse のすぐに下に intercalate なる関数があった。

Yahoo!辞書 – intercalate によると

1 〈余分の日・月などを〉暦に挿入する, 閏(うるう)にする.

2 …を挿入する.

実装を見ると、intersperse を concat している。

intercalate :: [a] -> [[a]] -> [a]
intercalate xs xss = concat (intersperse xs xss)

map に対する concatMap のようなものか。

 

使い方のまとめ

import Data.List
main = do putStrLn $ intersperse ',' "abcd"
          putStrLn $ concat $ intersperse ", " ["aaa", "bbb", "ccc"]
          putStrLn $ intercalate ", " ["aaa", "bbb", "ccc"]

Windows で困ったときの強制ログオフ

あれ?コンピュータの動きがおかしい。 CPU が何かに占有されているわけではないのに、特定のアプリケーションの反応がなくなってしまった。タスクマネジャーでそのアプリを強制終了させようとしても、タスクマネジャーの動きもおかしい。反応してくれない。ログオフしようと思ってもできない。どうしよう ... (@_@;)

 

ブルースクリーンのトラウマ

以前は気軽にリセットスイッチを押していたけれた。しかし、オーバークロックして落ちてブルースクリーン、Windows XP が起動しなくなってクリーンインストールという経験をしてから、何かトラブルがあった場合には、極力 Windows の力で再起動もしくはシャットダウンをさせたいと思うようになった。

さて、現状を確認しよう。画面には反応しないアプリ多数。頼みの綱のタスクマネジャーもダメ。ただ、 先ほどまで使っていた Meadow は生きているようだ。 そこで、 Meadow からシェルを起動、コマンドを入力してログオフさせることにした。

 

shutdown.exe

まず、Meadow から シェルを起動する。

M-x shell

コマンドラインより、help を入力しても該当するコマンドが見つからず。 (@_@;) 適当に shutdown と入力してみる。

d:\meadow\bin>shutdown
shutdown
使用法: shutdown [-i | -l | -s | -r | -a] [-f] [-m \\コンピュータ名] [-t xx] [-c "コメント"] [-d up:xx:yy]

    引数なし        このメッセージを表示します (-? と同じです)
    -i            GUI インターフェイスを表示します。このオプ
                ションは最初に指定する必要があります
    -l            ログオフ (-m オプションとは併用できません)
    -s            コンピュータをシャットダウンします
    -r            コンピュータをシャットダウンして再起動します
    -a            システム シャットダウンを中止します
    -m \\コンピュータ名    シャットダウン/再起動/中止するリモート コン
                ピュータの名前です
    -t xx            シャットダウンのタイムアウトを xx 秒に設定
                します
    -c "コメント"        シャットダウンのコメントです (127 文字まで)
    -f            実行中のアプリケーションを警告なしに閉じます
    -d [u][p]:xx:yy        シャットダウンの理由コードです
                u = ユーザー コード
                p = 計画されたシャットダウンのコード
                xx = 重大な理由コード (255 以下の正の整数)
                yy = 重大ではない理由コード (65535 以下の正の
                整数)

shutdown –l というのがよさそうだ。 Meadow のシェルからコマンドを入力する。しばらくすると、アプリケーションが終了し、無事ログオフできた。

 

コマンドラインから以外には

もし、今回のように Meadow が起動していなかった場合、「スタート > ファイル名を指定して実行」 ( Windows キー + R ) でダイアログを表示させ、 shutdown –l と入力する。タスクマネージャが生きているようであれば、タスクマネージャを起動 ( Alt + Ctrl + DEL ) して、アプリケーションタブ右下の「新しいタスク...」ボタンを押して、同様に shutdown –l と入力する。

 

リモートシャットダウンダイアログ

ちなみに、上記コマンドラインの i オプションを利用すると、次のような GUI が表示された。

080628-001

2008年6月27日金曜日

Windows で MinGW と Meadow を使い C 言語をコンパイル

1. 「プログラミング言語 C」

本棚を整理していたら、なつかしい本が出てきた。

プログラミングをはじめたときはオブジェクト指向真っ盛りで、C 言語は本棚の隅に追いやられていた。

必ず一度は通る定番の言語として、古典と呼ばれる本だけは押さえておきたかった。しかし、購入しただけで、本棚の隅に追いやっていた。 ^^;

訳者まえがきを読むと、隔世の感がある。

郵便だと、アメリカとのやりとりには約 2 週間かかるが、電子メールならすぐ連絡がつく。 1981 年当時と比べると隔世の感がある。(…)

1989年5月

 

2. MinGW を利用する

プログラミング言語C に掲載されているコードを Windows 上で試したい。Windows 上で C ができる環境を整えることにした。

ゴテゴテした IDE を利用せず、なるべくシンプルな環境にしたい。適当に C コンパイラをインストールし、Meadow で C のコードを編集するという方針にする。

タダで始めるC/C++プログラミング for Windows の中で紹介されていた MinGW を試してみることにする。

MinGW は UNIX 用の C/C++ コンパイラの GCC を Windows に移植し,Windows ネイティブなプログラムを作成するためのヘッダファイルなどを整備するプロジェクトです。

サイトから MinGW-5.x.x.exe をダウンロードして下さい。Latest File Releases に無い場合には,SourceForge.net の [View ALL Project Files] から選んでください。

より UNIX 風に使いたい場合には,UNIX に似たコンソールを提供する MSYS (Minimal SYStem) も使うと良いでしょう。

同じく GNU Compiler Collection として Cygwin がある。Cygwin は、UNIX 環境を Windows 上に再現するという感じ。今回はコンパクトな MinGW を利用する。

 

3. MinGW と Cygwin の違い

MinGW – Wikipedia によると、 Cygwin との違いは、

MinGWはCygwin 1.3.3からフォークした。Cygwin、MinGWいずれもUnixソフトウェアのWindowsへの移植に使用されるが、異なる方針を採っている。 CygwinはLinuxや他のUNIXシステムに見られるような、Windows上に完全なPOSIX層を提供することを目標にしており、互換性のために必要であれば性能も犠牲にしている。一方でMinGWはフリーのコンパイラと各種ツールのみを行い、性能を重視している。

ライセンスについては、 Routine-Work:/topics/MinGW/overview.html によると、

cygwin1.dll が GPL であるということは cygwin1.dll をリンクするすべてのプログラムにも GPL が適応されるということです. つまりすべてのソースコードを GPL に従ってと公開する必要があります.

MinGW の基本部分のライセンスはパブリックドメインです.また Win32 API のインポートライブラリとヘッダについても自由に使うことのできるライセンスとなっています.

 

4. MSYS

MinGW プロジェクトには、 MinGW 以外にも MSYS というのがある。

MSYS – Wikipedia によると、

Windows上で動作するシェル(Bash)やテキスト操作ユーティリティ(gawk,sed, findutil)、ソースコードパッチ用ツール(diffutil), アーカイブツール(tar, bzip, zlib)を統合したパッケージである。MinGWを補う目的で作られた。

後で必要になってから、インストールすることにした。

 

5. MinGW のインストール

SourceForge.net: Files から MinGW-5.1.4.exe をダウンロードしてインストール。

環境変数 Path に c:\MinGW\bin を追加し、再ログイン。

 

6. Meadow の設定

インデントスタイルを設定した。スタイルはもちろん K&R 。

字下げスタイル – Wikipedia

K&Rスタイルとは、ブライアン・カーニハンデニス・リッチーの著書『プログラミング言語C』で使われた字下げスタイルであり、C言語で一般に使われている。

CC-mode の簡単な使い方 を参考に .emacs に以下のように記述した。

(add-hook 'c-mode-hook
	  '(lambda()
	     (c-set-style "k&r")))

 

参考サイト

Emacs Lisp は全く知らないので、いつかは一通り目を通そう。^^;

2008年6月26日木曜日

Haskell で リストの n 番目の要素を取得 – PreludeList の (!!)

1. リストの n 番目の要素を取得する関数を定義してみる

Haskell でリストの n 番目の要素を取得するには、どうしたらいいんだろ?

例えば、

["hoge", "piyo", "hoge"]

というリストから、2番目の要素である "piyo" を取り出すことを考える。

 

take, reverse, head 関数を使って

これまで使ったことのある関数で、定義してみる。

Prelude> head $ reverse $ take 2 ["hoge", "piyo", "fuga"] 
"piyo"

  1. 取り出したい要素を、リストの末尾に来るようにして、
  2. リストを反転、
  3. リストの先頭の要素を取得。

というやり方はちょっと面倒 ^^;

 

zip, lookup 関数を使って

モナドのところで出てきた lookup 関数を使って定義してみる。

Prelude> lookup 2 $ zip [1..] ["hoge", "piyo", "fuga"]
Just "piyo"

  1. zip 関数で、リストに対して、インデックスを付け、
  2. lookup 関数で探す。

先ほどよりは、幾分ましになった。しかし、こんな基本的な操作は、違う書き方があるはず。

ふつうのHaskellプログラミング によると、

すべてのモジュールは暗黙のうちに Prelude モジュールをインポートしており、 import 宣言をまったく書かなくとも Prelude モジュールで定義された関数が使えます。(p251)

ということは、Prelude に何か定義してあるだろうか。 (@_@)

 

2. PreludeList の (!!) 演算子

The Haskell 98 Report: Standard Prelude によると、

プレリュードはひとつのルートモジュール Prelude  と 3つのサブモジュール PreludeList、PreludeText お よび PreludeIO で組織されている。

Prelude を見ると List operations のところに、

(!!) :: [a] -> Int -> a

List index (subscript) operator, starting from 0. It is an instance of the more general genericIndex, which takes an index of any integral type.

と書かれている。これだ!

Prelude> ["hoge", "piyo", "fuga"] !! 1
"piyo"

「!」 はふつうのHaskellプログラミング (p181) の二項演算子に使える文字に含まれている。

ちなみに、リストの範囲を超えたインデックスを指定すると、エラーが表示される。

Prelude> ["hoge", "piyo", "fuga"] !! 3
"*** Exception: Prelude.(!!): index too large

定義を見ると、再帰的な定義がされていた。

xs     !! n | n < 0 =  error "Prelude.!!: negative index"
[]     !! _         =  error "Prelude.!!: index too large"
(x:_)  !! 0         =  x
(_:xs) !! n         =  xs !! (n-1)

 

3. ついでに、リスト操作の基本を学ぶ

List operations を見ると、Reducing lists, Building lists ... という分類があり、たくさんの操作が定義されている。とりあえずは List operations の最初に出てきているところだけを押さえておこう。

いつもながら、自分なりに、適当に分類してみる。

  • (++) , (!!) , length, null
  • head , last , init , tail
  • reverse
  • map ,  filter

これらの関数を早速試してみる。

Prelude> [1,2,3] ++ [4,5,6]
[1,2,3,4,5,6]

Prelude> [1,2,3] !! 1
2

Prelude> length [1,2,3]
3

Prelude> null [1,2,3]
False
Prelude> null []
True


Prelude> head [1,2,3]
1
Prelude> last [1,2,3]
3

Prelude> tail [1,2,3]
[2,3]
Prelude> init [1,2,3]
[1,2]


Prelude> reverse [1,2,3]
[3,2,1]


Prelude> map (+1) [1,2,3]
[2,3,4]
Prelude> filter (>1) [1,2,3]
[2,3]

2008年6月25日水曜日

Haskell で日本語表示 - utf8-string を利用して

ghcで日本語を正しく扱うには,いまのところ入出力の際に UTF8 <-> 内部コードという変換をする必要があります.…,今は Hackage DB に登録されています.(...)

(どう書く?org 3513 nobsun: ghcで日本語を正しく扱うには,いまのと...(文字列の反転(括弧の対応を保存)) - 投稿の詳細 より )

 

utf8-string パッケージをインストール

以下、上記のサイトの説明に沿ってインストールを行なった。 (GHC 6.8.3, Windows XP)

HackageDB: utf8-string-0.3.1 にアクセスし、Downloads より utf8-string-0.3.1.tar.gz をダウンロードし、解凍。

コマンドラインより、utf8-string-0.3.1 ディレクトリで以下を実行。

runhaskell Setup.lhs configure
runhaskell Setup.lhs build
runhaskell Setup.lhs install

ghc-pkg list でインストールされたパッケージを確認することができる。(cf. 5.8.1. Using Packages)

追記 (2011.4.23) : コマンドプロンプトから cabal でインストールするには、

cabal install utf8-string

 

試してみる

ソースコードは UTF8 にする。読み込むファイルがある場合は、それも UTF8 に。

追記(2009.4.25) : 改行コードは LF 。Meadow なら C-x RET f で utf-8-unix に。

例えば、 文字列の先頭から 3 文字取って返す場合、

import System.IO.UTF8

main = System.IO.UTF8.putStrLn $ take 3 "ほげpiyo"

上記を test.hs と名前を付けて保存。コマンドラインより、

runghc test.hs > result.txt

結果は result.txt に書き込まれる。 (コマンドラインで chcp 65001 とし、UTF-8 が表示されるようにしたが、コマンドラインに出力させるとエラーが表示された。)

 

ファイルから読み込む場合

今度は、ファイルから読み込んで、3 行分出力するスクリプト。

import qualified System.IO.UTF8 as U

main = do cs <- U.getContents
          U.putStrLn $ unlines $ take 3 $ lines cs

(参考: そんな悲しい目をしないで » Blog Archive » Haskell で日本語(マルチバイト文字)を使う方法 )

上記を test2.hs と名前をつけて保存。読み込む対象のファイル名は data.txt 。コマンドラインから、

runghc test2.hs < data.txt > result.txt

result.txt に結果が表示される。

 

ドキュメント

上記 HackageDB: utf8-string-0.3 によると、

Exposed modules
Codec.Binary.UTF8.String, System.IO.UTF8, Data.ByteString.UTF8

それぞれ利用できる関数が記載されている。


関連記事

2008年6月24日火曜日

Windows で同じキーを押し続けたときに、連続して入力されるスピードを調整する

1. 繰り返し入力される文字のスピードを変更したい

文章を削除するときは、DELETE キーを押し付けて、一気に文字を削除する。カーソルを意見させたいときは、矢印キーを押し続けることによって移動する。

同じキーを押し続けたときに、繰り返し入力される文字のスピードを設定したい。

 

2. キーボードのプロパティ

例えば、DELETE キーを押してから、削除が繰り返されるまでの時間を短くしたい。

  • コントロールパネル > キーボード を開く。

キーボードのプロパティにおいて、「表示までの待ち時間」を「短く」する。

080624-004

  • 「長く」と書かれたスライダーは、「キーが押されてから、繰り返されるまで」の時間。
  • 「遅く」と書かれた方は、押し続けたときの繰り返す速さ

使っているキーボードの特性に合わせて設定するのが良い。黒軸のキーボードを使っている場合、繰り返される速度が早過ぎると逆に打ちにくくなった。

Haskell のセクションと中置記法

1. セクションの特徴は何?

Haskell の2項演算子に対して部分適用したものをセクションと呼ぶ。

ふつうのHaskellプログラミング によると、

部分適用を使い引数を1つだけ渡した二項演算子のことを特にセクション (section) と言い、普通の部分適用とは少し違った特殊な機能が用意されています。 (p205)

「部分適用とは少し違った特殊な機能」とはなんだろう?

部分適用については、以下を参照。

セクションとは、Haskell 98 Report: 式 によると、

セクション( op e ) あるいは ( e op ) のように書く。ここで、op は 二項演算子であり、e は式である。セクションは二項演算子の部分適 用をあらわすのに便利な構文である。

 

2. 二項演算子を関数として用いる

二項演算子とは、演算子 - Wikipedia によると、

二つのオペランドから一つの結果を得る演算を表す演算子を二項演算子という。数学での写像を表現するのに通常は前置記法で書くのに対して、二項演算子は中置記法で書くことが多い。つまり、"k + 3" のように演算子を二つのオペランドの中間に置く。

Haskell では、二項演算子を中置記法で書くことができる。

Haskell 98 Report: 式の「3.4 演算子適用」には、

e1 qop e2 という 形式は二項演算子 qop の式 e1 および e2 への中置適用である。(...)

変換:
以下の同一性が保存される:

e1 op e2 = (op) e1 e2

例えば、

Prelude> 1 + 2
3

Prelude> (+) 1 2
3

Prelude> :t (+)
(+) :: (Num a) => a -> a -> a

 + という二項演算子は、関数 (+) である。この関数に対して、部分適用をしてみる。

Prelude> :t (+) 1
(+) 1 :: (Num t) => t -> t

 

セクションの型を調べる

次に、+ 演算子をセクションとして用い、型を調べてみる。

Prelude> :t (1 +)
(1 +) :: (Num t) => t -> t

Prelude> :t (+ 1)
(+ 1) :: (Num a) => a -> a

 

部分適用する引数によって異なるセクション

二つのセクションの違いは、除算の場合で考えると分かりやすい。

Prelude> (/ 2) 4
2.0

Prelude> (2 /) 4
0.5

前者のセクションは 2 割る計算を表し、後者は 2 割る計算である。2つのセクションの違いは、部分適用するために渡す引数の位置、項が違うということ。

二項演算子の部分適用に対して、特別に「セクション」と名前が付けられているのは、部分適用で渡す引数の位置を指定できるため。

 

3. 関数を中置記法で書く

Haskell では、関数も二項演算子の中置記法のように書くことができる。

識別子を使って関数を定義した場合でも、関数名を「` `」で囲うと二項演算子として使えるようになります。例えば関数f を定義したら、`f` は二項演算子として使えます。

(ふつうのHaskellプログラミング, p181)

例えば、 hoge  x y のように引数を二つとる関数を定義した場合、 x `hoge` y と書ける。

Prelude> let hoge x y = x / y

Prelude> hoge 4 2
2.0
Prelude> 4 `hoge` 2
2.0

 

関数をセクションとして用いる

この関数に対して部分適用をし、セクションと同じ形式で関数を適用してみる。

Prelude> (hoge 2) 4
0.5

Prelude> (`hoge` 2) 4
2.0
Prelude> (2 `hoge`) 4
0.5
関数合成とセクションを組みわせた場合、次にように書くことができる。

Prelude> let piyo x = (+ x) . (/ 2)

-- 普通の関数の適用
Prelude> piyo 100 50
125.0

-- 部分適用を用いて
Prelude> (piyo 100) 50
125.0

-- セクションを用いて
Prelude> (100 `piyo`) 50
125.0
Prelude> (`piyo` 50) 100
125.0

ふぅ~、やっと見慣れてきた。 ^^;

「レジストリが壊れて Windows XP が起動しなくなった」その後 ...

レジストリが壊れて、Windows xp が起動しなくなったの続き。

再び起動せず

Windows Update でいくつかのアップデートができない状態になった。 (@_@;) 各アップデートをダウンロードサイトからダウンロードしてインストールしてみたがダメ。やむなく、再度修復インストールをすることに。そうしたら ...

Windows がまた起動しない。 パタッ(o_ _)o~†

Windows のロゴすら表示されない。 パタッ(o_ _)o~†

 

前回と同じように回復コンソールを利用して、いくつかのレジストリを修復したが、前回のように起動させることができなかった。 chkdsk /R もしたけれどダメ。

 

電源を入れてしばらくすると、次のようなメッセージが表示されるようになった。

「次のファイルが存在しないかまたは壊れているため、Windows を起動できませんでした:\windows\system\vgaoem.fon.
オリジナル セットアップ CD-ROM から Windows セットアップを起動して、このファイルを修復できます。修復するには、最初の画面で 'R' キーを押してください。 」

Windows XP へアップグレード後のエラー メッセージ : 次のファイルが存在しないかまたは壊れているため、Windows を起動できませんでした: Windows\System\Vgaoem.fon」の解決策に従って操作をしたけれど、

7. コマンド プロンプトで map と入力し、Enter キーを押します。
Windows XP CD が挿入されている CD-ROM または DVD-ROM ドライブに割り当てられているドライブ文字を書き留めます。次の形式と同様の形式で表示されます。

D: \Device\CdRom0

の段階で、map によって CD-ROM のドライブが表示されないので断念。

 

またもエラーメッセージ

諦めず、再度修復インストールを試みた。その後、起動すると次のメッセージが表示された。

「STOP:c000021a Unknown Hard Error」

何か嫌な雰囲気のメッセージ。 (@_@;)

同じようなエラーに遭遇した人はいないかと思って、検索してみたら、

『調子の悪い電源を使っていて、ハードディスクの読み書きに何かしらの不具合を生じさせ、起動に重要なファイルorセクタを壊したので立ち上がらなくなった』

と、結論を出しました。

結局、怪しいATX電源を交換して、WinXPを再インストール。
リカバリインストールを試みましたが何故かサウンドのドライバのインストールで固まるので、ハードディスクのフォーマットをかけてからクリーンインストール。

んで、キチンと立ち上がってきました。

電源とハードディスクは、調子が悪いとすぐOSレベルでの影響を出し始めるような気がします。
特に、何かもう48時間とかつけっぱなしなPCなんかは、安物のパーツを使っていると、まず電源が壊れちゃう感覚がします。根拠は無いですけど、自分自身の経験談で。

(【Windows トラブル】 c000021a Unknown Hard Error | www.code-d.org )

やばい、自分の PC、自作でケチって、結構長時間つけっぱなしにしているのにもかかわらず電源はケース付属のを使っている。 ^^; 自作 PC の構成を考えているときに、「電源って結構大事だよ~」という旨をどこかで読んだことがあったけれど、こういうこと?! あ、自分の場合は、オーバークロックしてて、落ちたんだった。 ^^;

 

死のエラー

調べてみると、似たようなエラーメッセージとして、「C0000218エラー(UNKNOWN HARD ERROR)」というのがあるようだ。「C0000218エラー(UNKNOWN HARD ERROR)を考える記事」によると、

このページに来られた時点でおおよその見当はつきます。ひとまずお察し申し上げます。
C0000218はWindows2000がリリースされた当初から発生が確認されているエラーであり、にもかかわらず今にいたるまで完全な解決策が編み出されていないというWindows最凶クラスのエラーです。この原因不明の凶悪なエラー症状から、「死のエラー」という別称で呼ばれています。

パタッ(o_ _)o~†

で、とりあえず、データの救出することを考えろということなので、 次のうちからやれる方法を選択した。

  1. HDDを他のPCにつなぐ
  2. KNOPPIXを用いる
  3. 別パーテーションにWindowsをインストールする
  4. 回復コンソールを用いる

(C0000218エラー(UNKNOWN HARD ERROR)を考える記事 の「データ救出」より)

ダメになった HDD に、はじめて Windows XP をインストールするとき、パーティションを二つに分けておいた。実際問題これが慣習なのか、何かの役に立つのかわからなかったけれど、計らずも役に立つことになった。とりあえず、 D ドライブに Windows をインストールして、 C にあるデータを救出することにした。

 

ドライブレターが逆に

D: ドライブに新たに Windows をインストールした。そして、データを救出しようと思って、ドライブを見たら、あれ???

C と D のドライブが逆になってる!!!しかし、データの救出は無事できた。

 

元 C ドライブは、現在 D と表示されてしまっている。 元 C ドライブに再度 Windows を新規インストールしたいので困った ... (+_+)

Windows のシステム ドライブまたはブート ドライブのドライブ文字の復元方法 に従って、C と D のドライブレターを変更し、再起動。起動はうまくいった。しかし、またも Windows Update が動かなくなってしまった。

いくつかのアップデートは、ファイルをダウンロードしてインストールすることができたが、.NET だけは、アンインストールすら受けつけられなくなってしまった。(参考: [HOW TO] .NET Framework を修復する方法) これは後でわかったことだが、ドライブレターを変更する前に、マザーボードに付属の CD-ROM の中に .NET に関するものが含まれていた。これにより、.NET の修復が不可能になったのではないかと思う。

 

諦めて D にインストール

ここで、このまま作業を続けるのを諦め、再度 Windows をインストールすることを選択した。しかも、インストールするドライブは C ではなく D 。元 C ドライブである。何となくスッキリとした気分ではなかったけれど、後で不具合がでて対処するよりはましだと思い、D に Windows をインストールすることにした。

これで何とか Windows のクリーン インストールの完了 ^^;

疲れ果てた ... パタッ(o_ _)o~†

Windows Live Writer (14.0.3920.528) Technical Preview で良くなった点

いつの間にか Writer ZoneTechnical Preview が出ていたので試してみることに。起動してみると Version が 14.0.3920.528 だった。

Image1

触った感じの印象は全体的に滑らか。

 

SKKIME で落ちない

以前 Windows Live Writer を使うのをやめて、Meadow の html-mode でブログを書こうかと思った。その理由は、次の通り。

SKKIME が「直接入力」になっている状態で Ctrl + l を押してしまうと、「画像の挿入」ダイアログが表示され、その後、落ちてしまう。

(Meadow でブログを書く - html-mode を使って より)

しかし、このバージョンでは同じ動作をさせても落ちることはなかった。 ^^

 

タグ付けでフィルタ

080624-003タグを設定するときに、画面下の set categories を使う。この動作が早くなっている。以前のバージョンでは、たくさんのタグがある場合に表示させるだけでも時間がかかっていた。それがすっと動作してくれる。 ^^ また、文字列を入力することによってフィルタリングされるので、目的のタグを素早く見つけることができる。

目的のタグの文字列を一部入力したら、キーボードの下方向の矢印を押して移動。リターンキーを押せば、チェックをつけることができる。

画像をセンターに

確かこれ以前には設定できなかった気がするけれど、画像を中央に表示するための項目がセレクトボックスに追加された。

 Image2

 

加えて、 Format > align に Center も加えられてようだ。前からあったっけ ? ^^;

Windows XP の休止復帰後にキーボードからの入力がおかしいと思ったら... - 壊れたキーボードにご用心

PC を休止させる前はキーボードの入力が正常に行われていた。しかし、休止後にキーを入力すると、挙動がおかしいことがある。例えば、 D キーを押すと、なぜか 「Windows キー + D」が入力されているようで、これはデスクトップを表示させるためのショートカットだから、表示させていたウィンドウが全て消えてしまう。結果、D を入力することができない。 (+_+)

 

原因

正常に動作するキーボードと、壊れたキーボードをつなげていたため。

PC が二台あるために CPU 切替器を使っている。最近、BIOS を何度も設定する必要があったので、仕方なく直接壊れたキーボードを PC に接続していた。 CPU 切替器経由では、起動時に DEL キーを押して BIOS の設定画面を表示させることができないためだ。 CPU 切替器には正常なキーボードを、 PC には壊れたキーボードを。この壊れたキーボードは Windows キーに相当するメタキーが正常に入力できない状態にあった。時には全く反応せず、時には押してもいないのに連続で押下されてしまったり。

つまり、多分こういうことだろう。正常に入力されている時点では、 CPU 切替器に接続していた正常なキーボードの入力が優勢、もしくは、壊れたキーボードからの入力信号が出ていなかった。この状態で休止状態へ移行する。休止から起こすと、PC に直接接続していた壊れたキーボードもムクリと起き、悪さをすると。

 

マウスの動作もスムーズに

壊れたキーボードをはずしたら、マウスの動作も以前に比べて滑らかになった。以前にマウスの動作がおかしいとき、付属しているドライバが原因かと思っていたけれど、本当はこの壊れたキーボードが直接の原因だったのかも。 (+_+)

壊れたキーボードには気をつけよう。って、当り前か ^^;  てゆうか、なぜこれに気が付かないでいたのだろうか …

パタッ(o_ _)o~†

2008年6月21日土曜日

Firefox 3 のタブ操作をどうしようか - Tab Mix Plus ? Tab Kit ?

Tab Mix Plus 0.3.6 は Firefox 3 に未だ対応してないようだ。これないと困るんだよね (+_+) いなくなってはじめて気がつくその大切さ。 Firefox における操作では必須のものとなってしまっている。 (cf. Firefox で複数のタブを飼い馴らすためのアドオン)  特に機能の中で欠かすことができないのは、マウスオーバーによるタブの選択。これがないとクリックのし過ぎで腱鞘炎になりそう ... ^^; それから、新しく開いたタブを、今見ているすぐ右隣に開いてくれないと、どこに何があるのかわからなくなってしまう。一々、開いたタブを移動させるのも面倒だし ...

 

Dev-Build

Tab Mix Plus 0.3.6 のアドオンのサイトを見たら、

A version for Firefox 3 is found here:http://tmp.garyr.net/forum/viewtopic.php?t=7031

とあったので、ここにある Dev-Build を早速試してみることに。

おぉ ~ 動いたぁ~ ^^

しかし、一つ問題が。Firefox で複数のタブを飼い馴らすためのアドオン の中で使っていた  Tab To Window 1.2.8 が使えなくなってしまった。 (+_+) 複数のタブをたくさん開くときにはウィンドウをいくつか開き、そこへ開いたものをグループごとに振り分けているので、これが使えないと痛い ...

しかし、そこは Firefox 3 。Firefox 2 では良くなかった操作が改善されていた。

 

タブを別のウィンドウへ D&D

メニューより、「オプション > タブ」の「常にタブバーを表示する」にチェックしておく。これで新しいウィンドウを開くと、タブが常に開くようになる。複数のタブを開いていて、別のウィンドウへ移したいときは、移したいタブをつかみ、新しく開いたウィンドウのタブの部分へ向ってドロップする。

080621-1

確か Firefox 2 ではこの操作をすると、元のウィンドウにタブが残ってしまい、それで Tab To Window を探すことになった。こういう細かな点が改善されているのがうれしい ^^

ちなみに、スピードが早くなったことも勿論だけれど、個人的に非常に使い勝手がよくなったと思えるのは、 IME がオンの状態でも、 Space キー でページをスクロールできたり、Ctrl + k で 検索ボックスへフォーカスを移したりできるようになったこと。また、RTM の入力においても、 t を押すと新規に項目を作成できるようになったので、IE 系のブラウザを使う必要がなくなった。 (cf. RTM は IE コンポーネントを使った軽いブラウザで )

 

Tab Kit

当初、 Tab Mix Plus を Firefox 3 では使えないと思っていたので、別のものを探していた。そのとき見つけたのが、Tab Kit 。マウスオーバーによるタブの選択はないようだけれど、 Tab Mix Plus にはない視認性の良さがあった。それはこちらを見れば、まさに一目瞭然。

サイドバーに開くこともできるし、普通の位置に納めることもできる。秀逸なのは、グループ化されたタブをダブルクリックすれば、それを一つにまとめて閉じておくことができる点。 Tab To Window のように、新しくウィンドウを開いてグループごとに振り分けをする必要がほとんどなくなりそうだ。新しく開いたタブをどこに開くかの設定もできるし、グループ化の方法も直観的な操作でできる。もし、これにマウスオーバーによる選択ができるのであれば、こちらに浮気しそう。 ^^;

「マウスオーバーによるタブの選択」をするだけのアドオンってどこかにないのかなぁ ...

xmpfilter で Ruby のコードに実行結果をコメントに表示

1. 自動注釈プログラム xmpfilter とは?

Ruby で、スクリプトに注釈として、実行結果を載せたい場合、xmpfilter を使う。

xmpfilter を知ったきっかけは、Rubyの初心者にたいして「これは読むべき」だと思うコードを教えてください。.. - 人力検索はてな のコメントを読んだこと。

僕の例だとxmpfilterという超強力な自動注釈プログラムに惹かれ、内部を解析しました。

 

2. xmpfilter のインストールと実行

eigenclass - xmpfilter によると、

xmpfilter は rcodetools に含まれている。As of 0.4.0, xmpfilter has been included in rcodetools.

eigenclass - rcodetools に従い、コマンドラインから 、rcodetools をインストール。

gem install rcodetools

これにより、コマンドラインから、xmpfilter を実行できるようになる。

xmpfilter ファイル名

 

3. Code annotation

ブログにソースコードを載せるとき、実行結果や、変数の動きも含めたい場合がある。

例えば、次のようなコードを test.rb というファイル名で保存したとする。

出力させたい変数の右に # => と書く。

10.times do |i|
  i                    # =>
end

a = [1,2,3,4,5]
a.map{|i| i*2}         # =>

puts "ほげ"                    
puts a                         

コマンドラインから、以下を実行すると、

xmpfilter test.rb

次の出力が得られる。

10.times do |i|
  i                    # => 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
end

a = [1,2,3,4,5]
a.map{|i| i*2}         # => [2, 4, 6, 8, 10]

puts "ほげ"                    
puts a                         
# >> ほげ
# >> 1
# >> 2
# >> 3
# >> 4
# >> 5

 

4. Meadow (Emacs) での利用

gem でインストールすると、Ruby をインストールしたディレクトリの中に、

  • C:\ruby\lib\ruby\gems\1.8\gems\rcodetools-0.7.0.0\rcodetools.el

が存在する。これを C:\meadow\site-lisp に入れ、.emacs に

(require 'rcodetools)

を記述した。

これにより、Ruby のスクリプト上で、

M-x xmp

とすると、xmpfilter を適用した結果が表示される。 また、

M-x comment-dwim (M-;)

でコメントを入力することができて便利。

追記 (2009.12.27) : Dropbox に Emacs のライブラリを置いたのに伴い、rcodetools.el も Dropbox に置くことにした。

Meadow でブログを書く - html-mode を使って

1. Windows Live Writer の調子が悪い

普段、ブログを書くのには、Windows Live Writer を使っている。WLWは、SKK-IME と相性が悪い。SKKIME が「直接入力」になっている状態で Ctrl + l を押すと、「画像の挿入」ダイアログが表示され、その後、アプリケーションが落ちる。

最近、頻繁にこの症状が起こり、書きかけの文章が消えてしまった。

プログラムのコードを貼り付けるときは、html の編集用に切り替え、blockquote と pre タグを直接書いている。これが今一使いづらい。

そこで、Windows Live Writer 以外でも、ブログを快適に書けないか試してみることにした。

 

2. Emacs の html-mode を使う

Meadow で HTML ファイルを表示すると、タグが色付けされる。モードは html-mode になる。

html-mode は、機能はシンプル。しかし、ブログを書くとき、タグをそれほど使わないので、必要にして十分。

html-mode のヘルプを表示させ (C-c C-h) 、機能を分類してみた。以下では、C-c を押した後のキーのみを書いている。

一般的なタグの入力、h タグ、段落、アンカー、そして、ブラウザでプレビューを覚えれば十分。

それから、

  • 整形するときは全部を選択 (C-c h) しておいてから M-x indent-region (C-M-\) 。
  • 文字を書いた後にタグで囲みたいときは、対象の文字列を選択した後にコマンドを入力する。

とりあえず、これまで Windows Live Writer で書いた記録が残っているので、

  1. それを Meadow で HTML を編集。
  2. 投稿するときだけ Windows Live Writer を使う

というスタイルにしてみる。

2008年6月19日木曜日

Haskell における関数の型と、部分適用

1. 関数には型がある

ふつうのHaskellプログラミング」には、関数の型について、以下のように記述されている。

引数の型と返り値の型の組み合わせで関数の型を表現します。(p57)

関数に型なんてあるの (@_@?というのが最初の印象。

 

2. 関数の型を調べる

コマンドラインから ghci を起動。同書 (p202) に書かれていた、

「3 つの引数を渡されたら、その合計を返す関数」

を定義し、その型を調べてみる。

 

GHCi で関数を定義し、型の確認する

GHCi で関数を定義するには、

第2回 多相性(ポリモーフィズム)への理解を深める:ITpro によると、

GHCiの対話環境内で関数を定義する場合には, (...)  letの後にスペースを空けて入力する必要があります。

型を調べるには :type を使う。( :type:t と省略できる。)

 

「3 つの引数を合計する関数」を定義して、型を確認する

では、関数の定義から。

Prelude> let addThree a b c = a + b + c

addThree 関数の型を調べる。

Prelude> :type addThree
addThree :: (Num a) => a -> a -> a -> a

`a’ という文字が、関数の型に含まれている。

a は型変数(type variable) と言い、どんな型と置き換えてもよいことを表わすために用いられます。また、型変数を含む型のことを多相型 (polymorphic type) と呼びます。

(ふつうのHaskellプログラミング, p58)

よって、 addThree は引数に、型変数をとる多相型。

 

型クラスによる型の制約

(Num a) => の意味は、関数を適用できる型に、制約があることを表す。

型クラスを使うと、多相型に制約を付けれられます。このような制約の付いた多相性のことをアドホック多相(ad hoc polymorphism) と呼びます。 (...) 制約のない多相性のことはパラメータ多相(parameter polymorphism) と呼びます。

(同上, p237)

型変数 a が、Num クラスのインスタンスである必要がある。

 

3. 部分適用の意味

引数を一度にすべて渡さず、一部だけ渡しておくことを部分適用 (partial application) と言います。(同上, p202)

関数型言語を、これまで知らなかったので、「部分適用」は驚きの性質。(@_@;)

カリー化 - Wikipedia によると、

この技法は、Christopher Stracheyにより論理学者ハスケル・カリーに因んで名付けられたが、実際に考案したのはMoses Schönfinkelとゴットロープ・フレーゲである。

関数 ff:(X×Y)→Z の形のとき、f をカリー化したものを g とすると、gf:X→(YZ) の形を取る。非カリー化uncurrying)とは、これの逆の変換である。

カリー化とは直感的には「引数を幾つか固定すると、残った引数の関数が得られる」ということである。たとえば、除算の関数 div(x, y) = x / y をカリー化したものをcdivとし、inv=cdiv(1) とすると、inv は新しい関数となり、inv(y) = 1 / y 、つまり引数の逆数を返す関数になる。

部分適用は、クラスとインスタンスの関係を連想させる。メタ的な関数として、複数の引数を与える関数がある。そこから、部分適用により、具体的な関数を導出する、といった流れ。

 

定義した関数に対して部分適用

先ほどの addThree 関数に対して、部分適用をし、その型を調べてみる。

Prelude> :type addThree 1
addThree 1 :: (Num t) => t -> t -> t

Prelude> :type addThree 1 2
addThree 1 2 :: (Num t) => t -> t

Prelude> :type addThree 1 2 3
addThree 1 2 3 :: (Num t) => t

上記の結果を見ると、それぞれ

  • 「あと 2 つ引数を与えると、t 型の値が返ってくるよ。」
  • 「あと 1 つ引数を与えると、t 型の値が返ってくるよ。」
  • 「返ってきたのは t 型です!」

ということ。

 

部分適用した場合に決まる型

Maybe モナド (p263) の説明に出てきた、lookup 関数を調べてみる。

Prelude> :t lookup
lookup :: (Eq a) => a -> [(a, b)] -> Maybe b

Prelude> :t lookup "hoge"
lookup "hoge" :: [([Char], b)] -> Maybe b

Prelude> :t lookup "hoge" [("a",100),("b",200)]
lookup "hoge" [("a",100),("b",200)] :: (Num t) => Maybe t

第一引数を、文字列ではなくて数値にすると、

Prelude> :t lookup 1
lookup 1 :: (Num t) => [(t, b)] -> Maybe b

Prelude> :t lookup 1 [(1,100),(1,200)]
lookup 1 [(1,100),(1,200)] :: (Num t) => Maybe t

部分適用により、具体的な制約や型が付けられるのが分かる。

 

4. プログラムの中で型を調べる (GHCi を使わない場合)

Data.Typeable の typeOf を使うと、プログラムの中で型を調べることができる。

import Data.Typeable

addThree :: Int -> Int -> Int -> Int
addThree a b c = a + b + c

main = print $ typeOf $ addThree 1

追記(2008.6.20) : ファイルに保存した関数を、GHCi に読み込ませる場合には、 GHCi において

:l ファイル名

と書く。例えば、上記のコードを partial.hs として保存したとする。このfファイルを読み込み、型を調べるには、

Prelude> :l partial.hs
[1 of 1] Compiling Main             ( partial.hs, interpreted )
Ok, modules loaded: Main.
*Main> :t addThree
addThree :: Int -> Int -> Int -> Int
*Main> :t addThree 1 2
addThree 1 2 :: Int -> Int

関連記事

PyScripter でモジュールを変更した場合、手動でインポート

次の二つのファイルがあるとする。

  • hoge.py
  • piyo.py

hoge.py では、piyo.py の hello() を呼び出す。

from piyo import *
hello()

ここで piyo.py で hello() を定義して、hoge.py を実行すると、 PyScripter (1.9.9.2) ではエラーが表示される。

def hello():
    print "piyo: hello()"

ただし、コマンドラインからの実行はエラーが表示されず問題ない。もちろん、Meadow のシェルコマンドからの実行も OK.

 

対処

080619-1この場合、PyScripter において piyo.py を変更後に、メニューより「Run > import Module」を選択する。これにより piyo モジュールがインポートされ、 hoge.py の実行がうまくいく。

Run > External Run」 ならば、 piyo.py におけるモジュールのインポート操作をしなくても問題ないようだ。

たくさんのモジュールを PyScripter で変更した場合、PyScripter の再起動が早いかな? ^^;

 

参考

Meadow の シェルコマンドで Python を実行

  1. ユーザー環境変数 PATH に Python.exe があるディレクトリ (C:\Python25) を追加する。
  2. 再起動

これで、M-! python ファイル名 を実行できる。

ユーザー環境変数を変更したら、Meadow を再起動するだけで変更が反映されると思ったけれど、ダメだった。 (+_+) 再起動じゃなくて、再ログインだけでもよかったのかな?

Meadow (Emacs) で指定範囲にあるコードを実行して結果で置き換える

  1. 実行したいコードを選択
  2. C-u M-|
  3. ミニバッファで、実行するためのプログラム名を入力

そもそも C-u とは、GNU Emacs Manual - Arguments によると、
引数を設定するには,C-u(universal-argument)コマンドの後ろに数字を入力する方法もあります.
なので、上記の方法は、選択した文字列を引数として、シェルコマンドに渡しているというイメージか。

参考

http://www.argv.org/bep/common/refcard/refcard.txt

関連記事

2008年6月18日水曜日

Firefox の Easy DragToGo - Drag de Go の代替

追記(2013/10/29): 現在、Easy DragToGo+ を利用している。


Drag de Go は、リンクや検索したい単語を、バックグラウンド開くアドオン。

Firefox 3 にアップグレードしたら、このアドオンを使えなくなった。

この操作方法にすっかり馴染んでいるので、使えないと困る。 (+_+)

は、名前がそっくりで、機能もそっくりのアドオン。利点は、Firefox 3 でも利用できるところ。

デフォルトの設定も同じ。

080618-2

Drag de Go から Easy DragToGo へ乗り換えることにした。

 

関連記事

レジストリが壊れて、Windows xp が起動しなくなった

対象

  • Widnows XP sp3 を使用
  • キーボードは USB 接続
  • Windows のインストール CD は XP sp2

 

症状

Windows 上でアプリケーションを使用中 (EasyTune5 Pro でオーバークロック) にシステムがダウンし、その後、再起動がかかった。セーフモードで起動するかどうかの選択画面が表示されたとき、キーボードの操作ができず、「Windows を通常起動する」が自動的に選択される。しかし、その後、 Windows の起動画面が現われる前に、ビープ音と供に再び再起動が行われる。これが延々と繰り返された。

 

対処

USB 接続のキーボードの操作を受けつけるようにする

PC に電源を入れた後、 DEL キーを押して、 BIOS の設定画面を表示させる。

Integrated Peripherals > USB Keyboard Support がデフォルトで Disabled になっているので、これを Enabled に変更。

 

Windows のインストール CD から起動

BIOS の設定画面で、 Advanced BIOS Features > First Boot Device をCDROM に変更する。

Windows のインストール CD を挿入しておく。

Save & Exit Setup で BIOS の設定は終了。

 

回復コンソール

Windows のインストール CD が起動したら、 R キーを押して、回復コンソールを表示させる。 (参考 : Windows XP 回復コンソールについて )

C:\Windows にログオンしたら、次のように表示された。

SYSTEM レジストリはアクティブな ControlSet キーがないようです。

SYSTEM レジストリが壊れている可能性があります。

ここで試しに chkdsk /p でディスクの修復を行い再起動させたが、 Windows の起動画面は表示されなかった。

※ この後、一度 Windows のインストール CD を使って修復を試みたが、作業の途中で中断してしまい、修復を完了できなかった。

 

レジストリの復元

再度、回復コンソールにて、レジストリの復元を試みた。方法は、「Windows XP が起動できない場合のレジストリの復元方法 電子頭脳の実験室/ウェブリブログ」に従った。(こちらのサイトのおかげで、データを失わずに済みました。ありがとうございます。(_0_) )

手順は、

  1. 現在のレジストリのバックアップ
  2. バックアップされているレジストリを復元

具体的には上記のサイトでは、現在のレジストリのバックアップ先として、 c:\WINDOWS\tmp ディレクトリを作成。

c:\WINDOWS\system32\config\ 以下にある system, software, SAM, SECURITY, default を copy コマンドによりバックアップ。

5 つの同ファイルを delete コマンドにより削除。

次に、システムがバックアップしていたレジストリを名前を変えてコピーし、元のレジストリの位置に起く。 このとき、念のため起動しなくなった前日のレジストリを復元することにした。

C:\System Volume Information\_restore{[ランダムな文字列]}\RP[番号]\snapshot\
_REGISTRY_MACHINE_SYSTEM
_REGISTRY_MACHINE_SOFTWARE
_REGISTRY_MACHINE_SAM
_REGISTRY_MACHINE_SECURITY
_REGISTRY_USER_.DEFAULT

(同上より)

空白のあるディレクトリ名をコマンドに伝えるときは、" " で囲むこと。また、上記の 5 つのファイルのうち、最後のファイル名 _REGISTRY_USER_.DEFAULT は他の名前が少し違うので、打ち間違えないように。

 

Windows の修復

再度、 Windows のインストール CD を起動し、今度は回復コンソールを表示させずインストール作業へ。  ENTER キーを押して、セットアップを開始する。 (参考 : ITmedia エンタープライズ:Windows Tips「起動しなくなったWindowsXPを修復する」 )

ライセンス契約に同意する。(F8)

次に、新規インストールは選ばずに、修復(R) を選択する。(修復なので、マイドキュメント内などの自分で作成したファイルは残すことができる。)

後は、インストーラの指示に従う。

 

IE7 の削除

これで Windows xp sp2 で修復された状態となった。しかし、 Windows Update をしようとしたら、次のメッセージが表示され、IE7 が起動できなかった。

「'(null)'が見つかりません。名前を正しく入力したかどうかを確認してから、やり直してください。ファイルを検索するには、[スタート]ボタンをクリックしてから、[検索]をクリックしてください。」

( Sleipnir より、ツール > Windows Update をしたら、Windows Update を表示されることができたが、途中でエラーが表示され、sp3 にすることはできなかった。)

CTX113807 - Internet Explorer 7をエクスプローラモードで起動すると「'(null)'が見つかりません」というエラーメッセージが表示される - Citrix Knowledge Center」によると、 IE7 が壊れているようなだ。この回避策として、次のように書かれていた。

Internet Explorer 7をアンインストールしてInternet Explorer 6に戻します。

Internet Explorer 7 を削除する方法」には、IE7 を削除するための二つの方法が書かれている。「プログラムの追加と削除」にはIE7 がなかったので、「方法 2 : フォルダからアンインストーラを実行する」によって削除した。上記サイトによると、

1.[スタート] ボタンをクリックし、[ファイル名を指定して実行] をクリックします。

2.%windir%\ie7\spuninst\spuninst.exe と入力し、[OK] をクリックします。

その後 IE6 から Windows Update をし、 sp3 にすることができた。

最近、頻繁に エクスプローラが落ちるようになったのは、IE7 が壊れていたからだったようだ。^^;

 

関連記事

2008年6月17日火曜日

Firefox のブックマークツールバーが消えた

何だろう? アドオンのアップデートで消えちゃったんだろうか?ブックマークツールバーがない!というか、空っぽ。 (@_@;) ブックマークツールバーのある位置に favicon を乗せようと思っても、乗せることができず。

メニューの「表示 > ツールバー」 の各項目のチェックをつけたりはずしたり試してみると、対応付けがおかしくなってしまっているような感じが ...

古い PC も新しい PC も同様の症状がでている。

 

対処

  1. アドオンを全て無効にして、Firefox を再起動。
  2. 空のブックマークツールバーに、試しに一つブックマーク。
  3. ブックマーク > ブックマークの管理」を選択。
  4. 以前のブックマークツールバー以外に新しくブックマークツールバーが作成されているので、以前のブックマークをすべて選択して、移動。

新しい PC の方はこれで元に戻ったが、古い方はダメだった。 (+_+)

そこで、「Mozilla Re-Mix: ブックマークツールバーが消えたときは。」 の説明に従って、の上記の (1) の後に、「表示 > ツールバー > カスタマイズ 」でツールバーのカスタマイズのダイアログを表示させ、「ブックマーク」の項目を、ブックマークツールバーがあった位置に置いた。そうしたら、favicon をつかんでブックマークを登録できるようになった。後は、(3) 以降の手順と同じ。 ^^

2008年6月16日月曜日

お灸でリフレッシュ

お灸の思い出

最近、お灸にハマっている。灸と言えば、じぃちゃん、ばぁちゃんがやるもの。そういうイメージだった。母の話によると、今は亡き祖母は、もぐさを直接背中に乗せ、バチバチとやったためにケロイド状になっていたとか。(@_@;) それやり方間違ってんじゃねぇ~のと思ったけれど。 ^^;

そんなハードボイルドなお灸ではなく、ぼくの記憶にあるおばぁちゃんのお灸は、せんねん灸。それでも子どもの頃は、火を背中に乗せていることに、相当の恐怖を感じた。ばぁちゃんすげぇと畏怖すら。そんな感覚は今でも続いていた。

 

母の五十肩

母が五十肩になってしまった。実際 六十台なのだけれど、五十肩。 ^^; 痛みどめのシップや飲み薬、整体やカイロプラクティックに行っても一時的に症状が軽くなるだけで、肩を使うとまたすぐに痛くなるようだ。鍼も試してみたが、これも一時的。原因不明で、肩が痛くなる。しかも、特定の年代に集中している。そして、なぜわからないけれど、いつの間にか治ってしまう。そんな症状だそうだ。なんとも不思議な現象だ。

結局、対症療法しかない。一時的に痛みを抑える。家庭で何かできることはないかと考えたら、鍼から連想してお灸に思い至った。 (鍼灸) 昔、ばぁちゃんがよくやっていたなと。お灸なんて効果があるのだろうかと、はじめ思いつつも、ここ 2、3 週間ほど続けている。痛みが完全にとれるわけではないけれど、ちょっと緩和されるようだ。少しでも楽になるなら儲けもの。そんな気持ちでやっている。

 

お灸にチャレンジ!

試しに自分もやってみた。めちゃドキドキ。 (@_@;) 親父などは、昔、腰が痛いときに試したことがあるそうなのだけれど、火もつけないうちから、「熱い!熱い!」と言っていたらしく、母、爆笑。いや、しかし、その気持ちよくわかる。いくら土台があるとは言え、火を使うんだよ。しかも、ジリジリと下へ降りてくるその恐怖。 (@_@;) 何の拷問かと。しかし、試してみたいという興味が勝り、恐る恐るやってた。このときまでに、既に母の肩に相当の数のお灸をしていたので、抵抗感が大分なくなっていたのも事実である。

せんねん灸.オフ竹生島230点
せんねん灸.オフ竹生島230点
せんねん灸 2003-01-14
売り上げランキング : 321

おすすめ平均 star
starレギュラーと併用

Amazonで詳しく見る
by G-Tools

お灸は、もちろん一番熱さの緩いやつを。緩いと言っても、火が土台の方まで来たとき、土台の部分を触ると結構熱い。「こんなものが肌の上に乗っているのか!」と信じられないくらいに。火を使っているという恐怖が余計に指先を敏感にさせ、熱さに対する感覚を鋭敏にしているようにも思う。

まぁ、ともかくお灸をしてみた。攻めるポイントは、腕の内側。最近、キーボードが壊れてしまい、昔のキーボードを使ているせいか、腕が疲れてしょうがない。

はじめ、お灸を乗せたときは熱くもなんともなかった。ぼわぁ~と暖かさが伝わってくるだけ。それが、徐々に肌に向って火が侵攻してくる。 (@_@;) やばい、火が土台に近づくにつれて徐々に熱くなってきた。熱いというよりも、チクッとした感じだ。移動させよう!しかし、土台が結構熱い。母の場合は、途中で移動させるということがあまりないので、こういった場面に慣れていない。しかし、ひぃひぃ言いながら、なんとかお灸をはがし、隣に移動されることができた。

 

結果

08-06-15_21-32やっぱりお灸は怖いと思いながら、はじめてのお灸体験を終えた。しかし、気がつくと、なんか腕がす~っとしている。灸を乗せたところを中心にして、10 cm くらの範囲がポカポカとしている。やばい、結構気持ちいいかも ^^ 。恐る恐る2回目の灸をしてみることに。今度は、指で押したときに気持ちがいい場所に灸を置いてみることにした。

お灸に火をつけて、いざトライ! ... あれ?熱さを感じない ... なんで?火が土台の方まで達っしているにも関わらず、ほとんど熱さを感じなかった。ただ、気持ちいいだけ。実に不思議だ。熱さに対する感覚なんて、どこも均等だと思っていた。それがどうやら違うようだ。 (@_@;) なぜだろう???

再度、別の場所にお灸を据えてみた。あれ?今度は熱い!全然下まで達っしていないのに熱いよ。乗せてからわずかの時間で別の場所に移した。やはり、場所によって温度の感じ方に極端な差があるようだ。

 

温覚

ビジュアル生理学-感覚 によると、

古典的には下記の様な分類があります。

触覚(何かが触れている感覚): ...
圧覚(押されている感覚): ...
温覚(暖かいという感覚): ...
冷覚(冷たいという感覚): ...
痛覚(痛いという感覚): ...

実際には、これらの感覚は単一種の受容器で受容されるのではなく、複数種の受容器で認識されると考えられています(複特異性)。
感覚受容器に入った感覚シグナルは感覚繊維を通って中枢へ伝達されます。

受容器の数については、生体情報論 (SFC-GC)痛覚・温覚・冷覚 によると、

というように、温覚は痛覚に比べて非常に少ないことがわかる。皮膚 1cm2にしてみたら、

模式図を見ると、その差がわかりやすい。温点が黄色で表わされているが、非常に少ない。先ほど書かれていたように、冷たさを感じる冷点との数が違うのも興味深い。この非対称性はなんだろう???熱さと冷たさが別の受容器で感じるというのもおもしろい。心理的には、熱い冷たいという感覚は一次元上なのに。

 

熱いという感覚の差

ところで、お灸の土台は丸く、その直径は約 1.5 cm。温点の分布がどのようになっているのかはわからないけれど、お灸を置いたときに、その下に受容器が全くないという状態もあるのかもしれない。つまり場所によって、熱さを感じるのが違うというのは、灸の熱が一番伝わる灸の中心点からの距離に比例しているだけなのかもしれない。

一つの温点の受容器の守備範囲というのはどのくらいなのだろうか?熱いものが近くにあった場合、それを関知して、「熱いぞ!」と伝えることが、どの程度可能なのだろうか?もし、温点の守備範囲が広く、その範囲内の感度がそれほど変わらないとしたら、場所によって熱さが違うのはなぜだろう。皮膚の厚さか?それとも別の要因があるのだろうか。

 

ところで、はじめてお灸をしたときのチクッとした感覚は、素朴な疑問 QA243 によると、

温度が45℃を越えたとき、10℃を下回ったときに、その情報は「危険信号」と判断され「痛み」として脳が情報を受け取ります。

 

消臭にお灸

タバコの臭いは大嫌いだ。しかし、お灸で使われている「もぐさ」の煙は気にならない。何と言えばいいのだろうか、、、夏の匂いがする。なつかしい感じだ。部屋が臭いとき、そこでお灸をするのも効果的。 ^^;

 

せんねん灸のホームページを見ていたら、こんなお灸もあった。

香りがえらべるはじめてのお灸 moxaシリーズ SENNENQ 

天然の香り成分を配合。お灸と同時に香りも楽しめます。
選べる香りは、Fruits(くだもの)、Bouquet(はな)、Thé vert(緑茶)、Encens(香木)の4種類。

ブログもあるのには驚いた。 ^^; :: はじめてのお灸 moxa BLOG ::

それにしても、「くだもの」の香りってどんなのだろう。今度試してみたい。

2008年6月15日日曜日

Meadow (Emacs) で shell-command の補完

プログラムの実行

Meadow を使ってスクリプトを書いていると、頻繁に行うのが書いたスクリプトの実行。

M-! スクリプト名

右手の親指で Alt , 小指で Shift キーを押し、左手の薬指で 1 のキーを押す。これが習慣になると、 M-! を頭の中で言うのではなくて、「コマンドの実行」と心で思うと、自然に手が動くようになってくる。しまいには、 M-! であることを忘れ、手の動きから「コマンドの実行は何のキーだっけ?」と推測するようになる。 ^^;

 

履歴から実行

一度、実行したスクリプトなら、M-! の後に、すぐ上矢印キーに手がのびる。 M-p でヒストリーを辿るという手の動きは習慣化されていない。 HHKB なので、M-! のアクションから、 Fn + [ という手の移動が最小でやりやすい。

 

選択範囲を実行

さすがに「すぐに忘れる脳みそ」だけあって、範囲を選択して実行 なんて、すっかり頭から抜けていた。復習。復習。手になじませる。 ^^;

!

と形が似ている

|

で、! とは対照的な場所に位置している。よって、手の動きも対照的。

 

コマンドの入力時に補完

shell-command で不満なのは、M-x で実行するコマンドのように TAB キーを押したら補完してくれるのかと思いきや、そうではないこと。頻繁に行う操作なので補完されるようにしたい。

shell-command.el を導入するとこれが可能となる。 「shell-command のコマンド入力に補完が効くようにする」 の説明に従い shell-command.el をダウンロードして c:\meadow\site-lisp\ に置き、 .emacs に以下を設定。

(require 'shell-command)
(shell-command-completion-mode)

追記 (2009.12.27)Dropbox に Emacs のライブラリを置いたのに伴い、shell-command も Dropbox に置くことに。

 

M-x load-file ~/.emacs で .emacs を再読み込み後に M-! を入力すると、以前とは違って現在編集しているファイルが存在するディレクトリが表示されている。ここで例えば ruby を実行したいなら、 r と入力後に TAB キーを押すと、 r で始まる .exe の候補が表示される。

ruby.exe を選択した後、動かしたいファイル名の先頭の文字を入力し、 TAB を押せばさっとファイル名が補完されるようになる。 ^^

2008年6月14日土曜日

Python の シーケンス型に慣れる

1. 配列の操作

プログラミングは、習うより慣れろ。

そう、避けるべきは黙読で、すべきは朗読です。文書は声に出して読まなければ身につきません。とはいっても、ソースコードまで音読していたらそれはそれで間抜けです。ソースコードは音読ではなく書き写す、すなわち写経するのがいいでしょう。

(本気でやるなら黙読は避けて朗読すべき: Days on the Moon  より)

新しく言語をはじめる場合、最初に確認する書き方の一つに「配列」がある。

配列操作の比較表: Ruby, Python, JavaScript, Perl, C++ - bkブログによると、

プログラムを書いていると、他のプログラミング言語の記憶とごっちゃになって、「配列の後ろに要素を追加するのは push だっけ、 append だっけ」などと混乱することがあります。

これを見ながら、写経することにした。 ( ̄人 ̄)ナムナム

a = [3,2,1]
b = [10,200,30]

# 大きさ
print "len(a) :", len(a)

# 空か?
if len(a) == 0: print "empty"
else:           print "not empty"
# 末尾に追加
a.append(4)
print a

# 挿入
a.insert(2, 100)
print a

# 末尾の要素を取り出す
print a.pop()
print a

# 先頭の要素を取り出す ※
print a.pop(0)
print a

# 別の配列を足す
a.extend(b)
print a

# 特定の値を削除する
a.remove(100)
print a

# 特定の位置にある要素を削除する
del(a[2])
print a
# 特定の値の数をカウントする
print a.count(3)
print a.count(0)

# 特定の要素を含んでいるか調べる
print 3 in a
print 4 in a
# 先頭の要素
print a[0]
# 末尾の要素
print a[-1]

# 特定の区間の要素
print a[1:3]    # 1 ~ 2 まで
# sorted は要素自体を並び換えない
print "sorted(a) :", sorted(a)
print a

# sort は配列自体を並び換える
print a
a.sort()
print a

# 要素を末尾から辿る
for elem  in reversed(a):
    print elem

# reversed は要素自体を操作しない
for x in reversed(a):
    print x
print a

# reverse は要素を自体を逆順にする
a.reverse()
print a
# 配列の要素を、特定の文字列でつなげる
print ', '.join("abc")
print ', '.join(str(x) for x in a)

# 要素を全てクリアする
b = a
a[:] = []
print a
print b

 

uniq

Python で、Ruby の Array#uniq に相当するものは、組み込み関数の set(), list() を使い、 list(set(リスト)) とする。

set([iterable])

集合を表現するset 型オブジェクトを返します。

list([sequence])

sequence の要素と同じ要素をもち、かつ順番も同じなリストを返します。

 

join

Python と Ruby の違うところは、 join が 文字列のメソッドとして定義されていること。

Python はなぜ String#join か - TokuLog 改めChumbyとどきました日記 によると

これ、理由は明解で、「join メソッドは文字列の処理だから」です。

それ以下でもそれ以上でもない。

文字列の処理をするメソッドを、どんなものでも入る Array Class のメソッドとしてはやすなんてとんでもない!

そう考えるのが Pythonista クオリティ

(via Python の join が str のメソッドになっている理由 - odz buffer)

 

2. Python は配列クラスに定義されているメソッドが少ない

こうやって見ると、Ruby は語彙が豊富で何でもありの言語だとすると、Python は正当な表記しか許さない律儀な言語。

「今の若者の言葉の乱れは...」

とでも言いそうな雰囲気を感じる。

認知的経済性から考えると、Python の方が言語としてシンプルで良い。独特の言い回しも許容する、言語の豊かさという視点から見たら、Ruby は使いやすい。

Python には、

「要素をリストの先頭に入れる」関数

に特別な名前がない。insert() による表現の一部になっている。これに対して、Ruby では unshift() という特別な名前が与えられている。

同様に Python では

「リストの先頭の要素を取り出す」関数

は pop() メソッドで代替する。Ruby では shift() という名称が与えられている。

「要素の取得」

においても、Ruby では .first, .last という特別な名前が与えられている。

Ruby は人が使う言葉に沿うようなメソッド名が付けられる傾向があるようように感じる。Python は、「あるもので間に合わせろ」ということか。

String クラスで定義されているメソッドの数を比較からも、そういう雰囲気が伝わってくる。

 

3. 文字列とリスト

Python では、文字列を for ループに投入すると、一文字ずつ処理が行われる。

for c in "hoge":
    print c

for c in u"ほげほげ":
    print c

これに対して、 Ruby では、hoge という一つの文字列として処理される。

for c in "hoge"
  puts c
end

一文字ずつ処理を行いたい場合は、split や scan を使って文字列を分割しなくてはならない。

"hoge".split(//).each do |c|
  puts c
end

"hoge".scan(/./).each do |c|
  puts c
end

# 文字コードが Shift_JIS の場合
"ほげほげ".split(//s).each do |c|
  puts c
end

 

3. シーケンス型

list() 関数に、次のような説明がある。

例えば、list('abc')['a', 'b', 'c'] および list(1, 2, 3)[1, 2, 3] を返します。

これを見て、 Haskell を思い出した。

ふつうのHaskellプログラミング によると、

実は、 Haskell では文字列もリストなのです。文字列は文字のリストとして表現されていて、特別な文字列は存在しません。ですから、リストの処理を覚えてしまえば文字列処理も身についたことになります。 (p36)

Haskell では、 "abc" は、['a', 'b', 'c'] と同じ。なぜなら、String 型は [Char] 型の別名に過ぎないため。

Python のライブラリリファレンスに、組み込み型の説明がされている。

ここに、リスト文字列の上位にある

「シーケンス型」

というものが定義されている。

上記で写経した sorted, reversed メソッドの位置付けも、これを見ると理解できる。

結構、イテレータ型が重要。

2008年6月13日金曜日

Ruby の Hpricot でスクレイピング

1. scRUBYt! を使えない

Python で、スクレイピングをするのに Beautiful Soup を使った。

スクレイピングの対象は、気象庁の過去のデータ。具体的には、

「2008 年 1 月の東京の日ごと」の気象データが掲載されているページから、特定の観測対象のデータのみを抽出したい。ただし、抽出するとき、抽出データを後で表計算に貼り付けるため、「タブ区切り」にすること。対象の項目は、「現地の気圧」と「平均気温」とする。

同じ課題に対して、Ruby を使いたい。

Scrubyt は、

スクレイピング

という言葉を知ったきっかけとなった。

RubyGemsScrubyt をインストールはできた。しかし、Scrubyt を使うと、エラーが表示されてダメだった。

 

2. Hpricot でスクレイピング

Scrubyt を使うことは諦め、代わりに

を使ってみる。使い方は、以下を参考にした。

 

/ は search の別名

サンプルのコードには、普通のメソッドとは違った書き方がされている。

(doc/:a).each do |link|

これは、HTML の a タグを取得しているところ。

pylori*style wiki - HTMLパーサ Hpricot によると、

Hpricot::Doc#searchメソッドを使って、要素を検索できます。 searchの引数には、XPathあるいは CSS のセレクタを指定することができます。

以下の例では class="section" な div 要素を抜き出しています。

doc.search("div.section")

返ってくる値は Hpricot::Elementsオブジェクトです。

search の alias として '/' も使えます。

doc/"div.section"

/ は search の別名として定義されている。

lib/hpricot/elements.rb at master from hpricot/hpricot - GitHub

alias_method :/, :search

よって、

(doc/:a)

と書いているコードは、以下と同じ。

(doc./(:a))

これは、

1 + 2

が、以下と同じであることと同じ。

1.+(2)

 

ソースコード

早速書いてみる。

require 'hpricot'
require 'open-uri'

doc = Hpricot(open("http://www.data.jma.go.jp/obd/stats/etrn/view/daily_s1.php?prec_no=44&prec_ch=%93%8C%8B%9E%93s&block_no=47662&block_ch=%93%8C%8B%9E&year=2008&month=01&day=12&view=p1"))

DATE_FROM = 1
DATE_TO = 5

records = []
(doc/"tr.mtx").each do |tr|
  rec = []
  (tr/"div#a_print").each do |div|
    rec << (div/:a).inner_html.strip
  end
  (tr/"td.data_0_0").each do |td|
    rec << td.inner_html.strip
  end
  records << rec if not rec.empty?
end

records.each do |rec|
  next unless (DATE_FROM..DATE_TO).include?(rec[0].to_i)
  rec.each_with_index do |d,i|
    print d ,"\t" if [1,6].include?(i)
  end
  puts
end

/ を search の別名として使えるので、コードが書きやすいし、読みやすい。 ^^