「ほっ」と。キャンペーン

<   2008年 09月 ( 27 )   > この月の画像一覧

下線の引き方

本を読むときに、段落の論理構造によって下線の引き方を考えたほうが良いと以前に書いた。論理構造は大まかに、推論を直列につなげていくものと、一つの概念をその下位概念に分割して述べる並列型の記述がある。以前のエントリーでは、キーワードがそのどれに相当しているかで、下線の種類を変えてみた。

しかし、実際にやってみると、論理構造を考えながら、下線を引くのは煩わしかった。それよりも、読み進めるときは、単に一本線の下線をひき、あとで、その種類によって、下線の始点や終点のそばに記号を書くというやり方のほうが、自然に実行できる。

たとえば、次のような文章の構成はよく見かける。

この主題については、A と B と C が関係している。 A というのは、.... 。Bは、...。そして、Cは、.... 。

こういう構成では最初に概要を述べて、次の部分で詳しく説明するという構成をとっている。このような場合に、最初のA, B, C にも後の A, B, C にも同じ下線を引いておくと、同じキーワードに2回も下線を引くことになり紛らわしい。

このような場合には、最初のキーワードには下線の頭に i (index) をつけておくと、それが後の内容の目次のようになっていることが分かる。イメージとしては、

 キーワードA
i ----------

というような感じだ、後半のキーワードはそれぞれのキーワードの定義が述べてあることが多い。そこでキーワードの下線の頭に D (definition) を書いておくと、そのキーワードの定義はそのあたりを読めばよいことが分かる。

 キーワードA
D ---------

のようにする。

そのほか、論理的な推論が次々に行われているときは > -------- 、並列の項目が並んでいるときは o --------- 、問題提起の形で説明を始めてある時は -------- ? など、そのときの思いつきでいろいろと書き加えていけばいい。

キーワードに下線を引く目的は、そのキーワードをきっかけにして意味のネットワークを連想することだ。下線に特徴を持たせるようにして読み返した時にその文章の構造が分かるようにしておくことが大切だ。
[PR]
by tnomura9 | 2008-09-30 12:51 | 考えるということ | Comments(0)

多様性

サブプライムに端を発した金融機関の危機が世界を揺さぶっている。経済のことはよくわからないが、ほとんど世界中の金融機関がサブプライムに手を出していたという事実に驚かされた。あらゆる機関が同じ投資方法を採用して、その方法が失敗した場合の危険性をまったく考えなかったのだろうか。

また、販売競争の激化で市場の占有の選択が起きて、勝ち組と負け組ができて参入する業者の巨大化と寡占化が起きてくるというのはよく分かる。しかし、勝ったはずの巨大企業が自己崩壊して消滅していくというのはどういう訳なのだろうか。

大体失敗というのは思いもかけない事態が生じたときに発生するものだ。予測が当たっていれば失敗するはずがない。予測が当たらなかったのだ。落ち着いて考えても、ずっと予測が当たり続けるという確率は非常に少ないのではないだろうか。

危機管理というのは予測がはずれた場合を考えてとられる対策だが、危機管理の予測の範囲を超える変化というものも起こりえる。変化を未来永劫にわたって予測することは不可能なのだ。

それでは、予測不能な変化に対応する方法は全くないのだろうか。その答えは多様性ではないかと思う。企業ごとに予測の方向性や方法が異なっていて、そのような企業がたくさんあれば、一つの企業の予測の失敗は、別の企業の予測の成功となって、社会全体の大きな破綻は避けることができる。多様性を内部に持っているシステムは、変化に対して強いのではないだろうか。

金融機関の破たんも、意思統一が整備された大企業の破綻も、多様性が足りなかったからだ。現代の企業経営の中で、最重要視されているのが効率化だ。人員や資源の効率化によって最大限の利益や価格競争力を発揮していこうという考え方だ。しかし、その中でシステム内部の多様性が損なわれ、環境の急激な変化に対応できず破綻していく危険性を内包していくのではないだろうか。

最近のアジャイルな開発にしても、ブラジルの経営者がはじめたセムラーイズムにしても、小規模な組織で変化に大胆に対応していくという姿勢がみられる。これらが万能だと主張する気もないし、巨大企業の力を無視することは無理だ。しかし、現代が今までにない変化の速い時代であり、それに対応するのに多様性というキーワードは重要な意味を持っているのではないかという気がする。
[PR]
by tnomura9 | 2008-09-28 09:21 | 考えるということ | Comments(0)

集中と不安定化

リーマンブラザーズの突然の倒産から世界中が大変な騒ぎになりそうだが、同じような危険は経済のどの分野でも起こりそうな気がする。

すなわち、資金や市場支配の集中化による、経済システムの不安定化だ。資金や市場支配が集中することによって、それを担う企業の肥大化が起こり、それにともなう企業の内部崩壊によって全体の経済システムが簡単に破綻してしまうというシナリオだ。

多数の企業が乱立している状況では、一つの企業が破綻しても、すぐに別の企業がそれを補ってくれる。しかし、一つの企業が市場の大半を支配している状態でその企業に異変が起きると、全体の経済システムに破壊的な影響を与えてしまう。

経済のグローバル化の本質は、情報と物の移動の速度の増加だ。一地方で起きた異変が簡単に世界全体に波及してしまう。また、企業間競争の勝敗へのプロセスも加速され、その結果としての寡占状態が、同時に勝者であるはずの企業の組織の硬直化と内部崩壊を引き起こしてしまう。これに、対抗する勢力があれば問題ないが、寡占状態ではそのような担い手は存在せず、ステークホルダーの崩壊はそのまま全システムの崩壊へつながっていく。

移動速度の増加と、支配力の集中化、集中化した権力の内部崩壊による破綻という図式は簡単なセル・オートマトンでもシミュレーションできるのではないだろうか。

医療崩壊が止まりそうにない。地方の基幹病院が次々に縮小、廃業する流れは止まりそうにもない。医師数を増やすとか、勤務医の手当てを上げるとかいろいろ対策が議論されている。しかし、このような事態が発生した根本が、ユーザの良質の医療を求める行動と、医師の側の良質の経験と自己の診療能力の開発を願う行動や、業務の集中やユーザからの訴訟による医療従事者の疲弊による脱落などの行動と、それが情報伝達の高度化によって一部の施設へ医療機能が集中しそうして崩壊していくことを理解しなければならない。そうして、個々のユーザや医療従事者のセル・オートマトンの行動が、どのように全体のシステムに影響を与えていくのかということについてのシステム論的な考察が必要なのではないだろうか。
[PR]
by tnomura9 | 2008-09-27 00:12 | 話のネタ | Comments(0)

Ruby をシェルとして使う snrb

srb で入力行ごとにインスペクトが表示されるのが煩わしかったので、表示させない snrb を作った。

snrb で遊んでいたら、シェルのコマンドが `.... ` (backquote) で動かせるのに気がついた。snrb 上で a = `ls foo` のようにすると、 ls の出力を変数に取り込むことができる。取り込んだ変数は正規表現で検索したり、配列に変更したり、Rubyの機能で自由に加工できる。

自分が何をやりたかったのかがやっとわかった。Rubyでデータが加工できるシェルが欲しかったのだ。

ファイル名: snrb (open, eval は全角英数に変換して使用)

require 'readline'
include Readline

module Srb
  def Srb.edit(prog = nil)
    if prog != nil
      File.open('temp.txt','w') {|f| f.write(prog)}
    end
    system "vi temp.txt"
    prog = IO.read('temp.txt')
    system "rm temp.txt"
    prog
  end
  
  def Srb.save(path, var)
    File.open(path, 'w') {|f| f.write(var)}
  end

  def Srb.load(path)
    IO.read(path)
  end
end

def _ml
  prog = ""
  while true
    line = readline('ml*> ', true)
    break if line == ";"
    prog << line + "\n"
  end
  return prog
end

loop do
  begin
    _line = readline('srb> ', true)
    if _line == ";"
      then _line = _ml
    end
    eval(_line, TOPLEVEL_BINDING)
  rescue SyntaxError, LoadError, StandardError
    STDERR.puts "Warning: #$!"
  end
end

実行例

Ruby$ ruby snrb
srb> a = `locate open-uri`
srb> a = a.chomp
srb> prog = IO.read(a).split(/\n/)
srb> ;
lines*> for i in 1..5
lines*> puts prog[i]
lines*> end
lines*> ;
require 'stringio'
require 'time'

module Kernel
private
srb> prog.each{|l| puts l if l =~ /class|module/}
module Kernel
module_function :open
module OpenURI
raise ArgumentError.new("invalid access mode #{mode} (#{uri.class} resource is read only.)")
raise "Non-HTTP proxy URI: #{proxy}" if proxy.class != URI::HTTP
if target.class == URI::HTTPS
class HTTPError < StandardError
class Buffer # :nodoc:
module Meta
module OpenRead
module URI
class Generic
class HTTP
class FTP
[PR]
by tnomura9 | 2008-09-26 07:51 | Ruby | Comments(0)

Ruby 標準ライブラリの歩き方 English.rb

English.rb の歩き方

Ruby$ grep alias /usr/lib/ruby/1.8/English.rb > English.txt
Ruby$ cat English.txt
alias $ERROR_INFO              $!
alias $ERROR_POSITION          $@
alias $FS                      $;
alias $FIELD_SEPARATOR         $;
alias $OFS                     $,
alias $OUTPUT_FIELD_SEPARATOR  $,
alias $RS                      $/
alias $INPUT_RECORD_SEPARATOR  $/
alias $ORS                     $\
alias $OUTPUT_RECORD_SEPARATOR $\
alias $INPUT_LINE_NUMBER       $.
alias $NR                      $.
alias $LAST_READ_LINE          $_
alias $DEFAULT_OUTPUT          $>
alias $DEFAULT_INPUT           $<
alias $PID                     $$
alias $PROCESS_ID              $$
alias $CHILD_STATUS            $?
alias $LAST_MATCH_INFO         $~
alias $IGNORECASE              $=
alias $ARGV                    $*
alias $MATCH                   $&
alias $PREMATCH                $`
alias $POSTMATCH               $'
alias $LAST_PAREN_MATCH        $+
[PR]
by tnomura9 | 2008-09-25 00:19 | Ruby | Comments(0)

スニペット活用環境 srb

スニペットを活用するための、対話型 Ruby 環境のスニペット srb を作った。

edb や minirb などの機能を集めて贅肉を落としただけのもの。使い方はほぼ以前の記事と同じ。コードサイズが小さいので邪魔にならない。

使用例

Ruby$ ruby srb.rb
srb> a = SRB.edit
"puts \"hello, world\"\n"
srb> puts a
puts "hello, world"
nil
srb> eval a
hello, world
nil
srb> a = SRB.edit( a )
"total = 0\nfor i in 1..10\n total += i\nend\nputs total\n"
srb> puts a
total = 0
for i in 1..10
  total += i
end
puts total
nil
srb> eval a
55
nil
srb> SRB.save('total.rb', a)
53
srb> b = SRB.load('total.rb')
"total = 0\nfor i in 1..10\n total += i\nend\nputs total\n"
srb> eval b
55
nil

ファイル名: srb.rb (eval,open は半角英数に変換して使用)

require 'readline'
include Readline

module SRB
  def SRB.edit(prog = nil)
    if prog != nil
      File.open('temp.txt','w') {|f| f.write(prog)}
    end
    system "vi temp.txt"
    prog = IO.read('temp.txt')
    system "rm temp.txt"
    prog
  end
  
  def SRB.save(path, var)
    File.open(path, 'w') {|f| f.write(var)}
  end

  def SRB.load(path)
    IO.read(path)
  end
end

loop do
  begin
    _line = readline('srb> ', true)
    p eval(_line, TOPLEVEL_BINDING)
  rescue SyntaxError, LoadError, StandardError
    STDERR.puts "Warning: #$!"
  end
end

入力行の値を表示させたくない場合は、p eval(line, TOPLEVEL_BINDING) の p を消す。Windows で使う場合は、SRB.edit の vi を適当なエディタに、また、rm を del に置き換える。
[PR]
by tnomura9 | 2008-09-24 01:44 | Ruby | Comments(0)

車輪を二度発明しないためには

「車輪を二度発明してはいけない」とよく言われる。

動作のテストが済んだプログラムが既にある場合はそちらを利用したほうが効率がいいはずだからだ。しかし、それはそのプログラムを使用できるようになるためのコストを除外しているような気がする。ちょっとした用途に使うのに分厚いマニュアルを読まないといけなくなるようでは、費用対効果がいいとはいえないのではないだろうか。

また、自分が作ったプログラムもしばらくすると使い方すら忘れてしまう。そういえば利用できそうなプログラムを以前作っていたなと思いだしても、使い方すら忘れているので、結局ソースを読み直すことになる。スニペットのような短いものなら、それも簡単だが、長いものだとうんざりするし、ロジックを読み取ることすら困難な場合もある。

単機能のスニペットをたくさん作っておくというのはいいアイディアだ。しかし、あるスニペットと別のスニペットのデータ構造が違うため、このふたつを単につなぎ合わせても動かないことがある。二つを一つのプログラムに統合すればよいかもしれないが、思いもかけないデバッグの作業が発生し、泥沼に陥ることも多い。

便利なスクリプトを作ったのに案外使わないのは、再利用の手間が馬鹿にならないからだ。

これらの問題を解決する方法として考えてみたのが、対話的にRubyを実行できる環境で、必要になったらそのつどスニペットを呼び出しながら使っていくというやり方だ。データ構造の整合性がない場合は、そのつどデータ変換の小さなプログラムを作りながら既存のスニペットを利用するのだ。

このブログで掲載した、edb.rb を使ってその辺の事情を実験してみた。

edb.rb はテキストベースのフラットファイルのデータを並べ変えたり、検索したりするために作ったプログラムだ。また、stat.rb は一次元配列のデータの統計処理をするためのスニペットだ。

もくろみは、データ構造の違う edb.rb と stat.rb をつなげて、テストの成績の統計的な分析をしてみようというものだ。この際、edb.rb と stat.rb の変更はせず、コマンドプロンプト上でデータの変換を行って、両者の機能をつなげてしまいたい。

実行例は次のようになる。

まずフラットファイルデータベースの edb.rb を立ち上げる。下の例では、生徒の数学、国語、英語のデータ表を読み込んで、数学の成績順に並べ替えている。

C:\Users\********\Ruby>ruby edb.rb
easydb> seiseki = Edb.new('seiseki.txt')
easydb> seiseki.dump
name sugaku kokugo eigo
A 90 65 55
B 46 50 50
C 63 63 58
D 50 40 48
E 55 32 40
easydb> seiseki.sort(:sugaku).reverse.dump
name sugaku kokugo eigo
A 90 65 55
C 63 63 58
E 55 32 40
D 50 40 48
B 46 50 50

今度は各教科のデータを、配列の統計処理のスニペット stat.rb で処理したいのだが、次の例のように、edb 備え付けの表から配列をとりだすメソッド to_array ではデータが列方向の2次元配列になってしまう。sugaku の点数を取り出してみると、縦方向の二次元配列になっているのがわかる。

easydb> p sugaku = seiseki.to_array('sugaku')
[[90], [46], [63], [50], [55]]

一方、stat.rb が処理するのは一次元配列なので、縦方向の配列を横方向に変換することが必要になってくる。必要なものは作ればいいので、mk_c2r 変数に edb.rb の edit コマンドでプログラムを作成する。

easydb> mk_c2r = edit

mk_c2r プログラムは下のようになる。

easydb> puts mk_c2r
class Array
  def c2r
   &bsp;self.collect{|x| x[0]}
  end
end

このプログラムを eval で実行すると、Array クラスに対し、縦方向の配列を横方向の配列に変換するメソッドを追加することができる。

easydb> eval mk_c2r

このメソッドを先ほど作った sugaku 配列に適用してみるとうまくいっているのが分かる。

easydb> p sugaku = sugaku.c2r
[90, 46, 63, 50, 55]

そこで、国語や英語の点数も一次元配列にして取り出すことにする。

easydb> kokugo = seiseki.to_array('kokugo').c2r
easydb> eigo = seiseki.to_array('eigo').c2r

準備ができたのでいよいよ、stat.rb を require して統計処理を行う。

easydb> load 'stat.rb'

まず、各教科の生徒数、得点の合計、平均、標準偏差を計算する。

easydb> p sugaku.stat
[5, 304, 60.8, 17.5128524232919]
easydb> p kokugo.stat
[5, 250, 50.0, 14.3003496460751]
easydb> p eigo.stat
[5, 251, 50.2, 6.94262198308391]

次に各教科の間の相関係数をとってみる。

easydb> p sugaku.cor(kokugo)
0.517884396596487
easydb> p sugaku.cor(eigo)
0.25276578505604
easydb> p kokugo.cor(eigo)
0.953858389080128

これを見ると、数学と英語の点数の相関が低く、英語と国語の得点の相関が高いことがわかる。

ここで、まにあわせで作った c2r メソッドは、いろいろな場合に使えそうなので、ファイルにして保存しておくことにする。

easydb> save('c2r.rb', mk_c2r)

この例の場合は、Rubyを対話的に使う環境として、このブログの edb.rb を使ったが、もちろん irb や、このブログの minirb も使うことができる。

もっといいやり方はもちろんあるだろうが、Ruby を対話的に使える環境で、使いたいデータやスニペットを呼び出しながら、ミニプログラムで繋げていくというやり方は、車輪を二度発明しないようにするためには便利な方法ではないかと思う。
[PR]
by tnomura9 | 2008-09-23 09:31 | Ruby | Comments(0)

統計計算スニペット

配列に統計計算をするスニペットをつくった。

使い方

C:\Users\******\Ruby>irb
irb(main):001:0> require 'stat.rb'
=> true
irb(main):002:0> [1,2,3].stat ........ 個数、総和、平均、標準偏差
=> [3, 6, 2.0, 1.0]
irb(main):003:0> [1,2,3].sum ........ 総和
=> 6
irb(main):004:0> [1,2,3].mean ........ 平均
=> 2.0
irb(main):005:0> [1,2,3].sd ........ 標準偏差
=> 1.0
irb(main):006:0> [1,2,3].cor([4,5,6]) ........ 相関係数
=> 0.262612865719445

ファイル名: stat.rb

class Array
  def stat
    sum = 0
    ss = 0
    n = self.size
    self.each do |x|
      sum += x
    end
    mean = sum / n.to_f
    self.each do |x|
      ss += (x - mean) ** 2
    end
    ss = ss / (n - 1).to_f
    sd = Math.sqrt(ss)
    return n, sum, mean, sd
  end

  def sum
    return self.stat[1]
  end

  def mean
    return self.stat[2]
  end

  def sd
    return self.stat[3]
  end

  def cor(other)
    sum_x = 0
    sum_y = 0
    n = self.size
    for i in 0...n
      sum_x += self[i]
      sum_y += self[i]
    end
    mean_x = sum_x / n.to_f
    mean_y = sum_y / n.to_f
    ss_x = 0
    ss_y = 0
    ss_xy = 0
    for i in 0...n
      ss_x += (self[i] - mean_x) ** 2
      ss_y += (other[i] - mean_y) ** 2
      ss_xy += (self[i] - mean_x) * (other[i] - mean_y)
    end
    r = ss_xy / Math.sqrt(ss_x) / Math.sqrt(ss_y)
    return r
  end
end
[PR]
by tnomura9 | 2008-09-23 07:53 | Ruby | Comments(0)

edit.rb で snippet 管理

プログラムをするとき、snippet は便利だ。動作テストの済んだ snippet をたくさん持っていると、コピペでプログラムを書くことができる。しかし、意外に snippet の管理は難しい。snippet の内容を忘れていることが多いし。cat でファイルの中身を見て、ruby foo.rb で実行して、vi の :r コマンドで取り込んでという手順が面倒だ。

このブログで掲載した、edit.rb を利用するとそんな snippet の管理が楽にできる。irb に require 'edit.rb' しておくと、snippet の作成が、foo = edit でワンタッチでできる。eval foo で動作確認ができるし、動作にエラーが出たときは、foo = edit(foo) で編集ができる。動作確認のできたプログラムは、save('foo.rb', foo) でファイルへの書き出しが、hoge = IO.read('foo.rb') でファイルからの読み込みができる。

ディスクの snippet のリストは、irb から system 'ls snippets/' のようにすれば取得できる。

また、変数へプログラムを読み込む利点は、irb から出ることなしに、複数の snippet の動作を確認することができることだ。foo と bar に別の snippet が入っていても eval foo、eval bar で実行できる。また、それぞれの内容は、puts foo、puts bar とすれば、すぐに確認できる。

irb に edit.rb を require すると、snippet を作りたくてたまらなくなる。

実行例は下のようになる。

Ruby$ irb
irb(main):001:0> require 'edit'
=> true
irb(main):002:0> hello = edit
=> "puts 'hello, world'\n"
irb(main):003:0> puts hello
puts 'hello, world'
=> nil
irb(main):004:0> eval hello
hello, world
=> nil
irb(main):005:0> triangle = edit
=> "for i in 1..5\n for j in 1..i\n print '*'\n end\n puts\nend\n"
irb(main):006:0> puts triangle
for i in 1..5
  for j in 1..i
    print '*'
  end
  puts
end
=> nil
irb(main):007:0> eval triangle
*
**
***
****
*****
=> 1..5
irb(main):008:0> save('hello.rb', hello)
=> 20
irb(main):009:0> save('triangle.rb', triangle)
=> 61
irb(main):010:0> foo = IO.read('triangle.rb')
=> "for i in 1..5\n for j in 1..i\n print '*'\n end\n puts\nend\n"
irb(main):011:0> eval foo
*
**
***
****
*****
=> 1..5
[PR]
by tnomura9 | 2008-09-21 07:48 | Ruby | Comments(0)

edb.rb で簡単プログラム開発 その2

irb は便利だが、複数行のプログラムを開発するようには作られていない。edb を使うと、edb から出ずに複数行にわたる Ruby プログラムを開発することができる。

edb ではプログラムを開発する前にデータを取り込むことができる。まず、サンプルの seiseki.txt を読み込んでみる。

Ruby$ ruby edb.rb
easydb> table = Edb.new('seiseki.txt')
easydb> table.dump
name sugaku kokugo eigo
A 90.0 65.0 55.0
B 46.0 50.0 50.0
C 63.0 63.0 58.0
D 50.0 40.0 48.0
E 55.0 32.0 40.0

このデータの成績の部分を処理したいので、成績の部分だけを取り出して二次元配列を作る。

easydb> array = table.to_array('sugaku kokugo eigo')
easydb> p array[0]
[90.0, 65.0, 55.0]

各列の総和を計算するプログラム sum を作りたいので、変数 sum にプログラムを入れるメソッド edit を呼び出す。

easydb> sum = edit

すると、vi を呼び出すので、vi で次のプログラムを作成する。

array.each do |x|
  p x
end

vi を終了すると、edb のコンソールに戻ってくるので、sum にプログラムが入っているか確認する。

easydb> puts sum
array.each do |x|
  p x
end

sum を実行してみる。

easydb> eval sum
[90.0, 65.0, 55.0]
[46.0, 50.0, 50.0]
[63.0, 63.0, 58.0]
[50.0, 40.0, 48.0]
[55.0, 32.0, 40.0]

これで、上のループが動くのが確認できたので、sum を再度編集して合計を出すように変更する.

easydb> sum = edit(sum)
easydb> puts sum
total = [0,0,0]
array.each do |x|
  for i in 0..2
  total[i] += x[i]
  end
end
p total

実行してみる。

easydb> eval sum
[304.0, 250.0, 251.0]

sum をテキストファイルに保存する。

easydb> File.open('sum.rb','w'){|f| f.write(sum)}

ファイルが作成できているかどうか確認する。

easydb> system 'cat sum.rb'
total = [0,0,0]
array.each do |x|
  for i in 0..2
    total[i] += x[i]
  end
end
p total

外部プログラムを変数に読み込むには IO.read メソッドを使う

easydb> sum2 = IO.read('sum.rb')
easydb> puts sum2
total = [0,0,0]
array.each do |x|
  for i in 0..2
    total[i] += x[i]
  end
end
p total

edb を終了するには exit と入力する。

easydb> exit

この様に、データをまず取り込んでおいて、それを処理するプログラムを動作を確認しながら開発していけるので、プログラム開発の負担感がずいぶん減る。
[PR]
by tnomura9 | 2008-09-20 07:05 | Ruby | Comments(0)