2010年11月19日金曜日

WebSocketを試す

WebSocket

最近、WebサーバからWebクライアントにデータをPushする技術としてWebSocketが脚光を浴びています。従来だと、Comet(AJAXの返答を引き延ばす技法=ロングポーリング)を用いて擬似的にPushしていたのですが、(サーバサイドもクライアントサイドも)プログラムが面倒だったり、クロスドメインへの対応がイマイチだったり、リアルタイム性が乏しかったりなどの理由で、だんだんとWebSocketに移ってきています。気づくと、サーバ側ではpywebsocketやnode.websocket.js、Jetty、mojoなどの実装が出てきましたし、クライアント側ではChromeやFirefoxが対応しており、そろそろ手を出してみても良い頃合いになってきました。ruby好きなので、サーバ側にrev-websocketを使ってみたいと思います。

rev-websocketの準備

今回は、OSにDebian Squeezeを使用します。正直、aptの便利さと、Debianのパッケージの多彩さとGUIいらずで軽量なヴァーチャルマシンを多数用意できるポータビリティにメロメロです。

まずはruby関連でインストールするパッケージです。入れたパッケージのメモを取り忘れたので、dpkg -l | grep rubyした結果を示します。不要なモノもありますが、リストに載せておきます。
libruby1.8
libsqlite3-ruby1.8
ruby
ruby-dev
ruby1.8
ruby1.8-dev
rubygems1.8

次に、rubygem関連でインストールするパッケージです。確かこれだけで良かったと思います。
rev
rev-websocket

revを検索したところ「Rev is a high performance event library for Ruby built on top of libev.」「libevのrubyバインディング」「Rubyの高速なイベント駆動IOライブラリ」などと書かれていました。便利そうなので使います。

revのサンプルプログラムを読む

まずは、revのサンプルコードを試してみます。/usr/lib/ruby/gems/1.8/gems/rev-0.3.2/README.textileを覗いてみると、echo serverの例が載ってます。gemを使ってインストールしたので、そのままではrevが無いと言われ、1行目にrubygemsのrequireを追加してあります。
require 'rubygems'
require 'rev'
HOST = 'localhost'
PORT = 4321

class EchoServerConnection < Rev::TCPSocket
  def on_connect
    puts "#{remote_addr}:#{remote_port} connected"
  end

  def on_close
    puts "#{remote_addr}:#{remote_port} disconnected"
  end

  def on_read(data)
    write data
  end
end

server = Rev::TCPServer.new(HOST, PORT, EchoServerConnection)
server.attach(Rev::Loop.default)

puts "Echo server listening on #{HOST}:#{PORT}"
Rev::Loop.default.run
このソースを見ると、(1)Rev::TCPSocketを継承したクラスを作り、(2)接続されたり、接続が切れたりしたら「on_connect」「on_close」が呼び出され、データを受信したら「on_read」が呼び出され、(3)20行目にあるようにRev::TCPServerのオブジェクトを作る際にポート番号や作成したクラスを登録すれば良いことなどが分かります。あと細かいことでは、wirteメソッドを使うとクライアントにデータを送れることも分かります。 実際に「telnet localhost 4321」で接続してみると、確かに入力した文字列がそのまま返されることが分かります。また、最終行の「Rev::Loop.default.run」によりイベントループが回り出すのですが、プログラムの実行してはこれより下には行きません。もっと複雑なプログラムを組もうとしたら、スレッド化が必要かも知れません。

WebSocketのサンプルプログラムを読む

revのソースコードの書き方が分かったところで、WebSocketのサンプルも試してみます。こちらは/usr/lib/ruby/gems/1.8/gems/rev-websocket-0.1.3/README.rdocの中にサンプルがあります。
require 'rubygems'
require 'rev/websocket'

class MyConnection < Rev::WebSocket
  def on_open
    puts "WebSocket opened"
    send_message("Hello, world!")
  end

  def on_message(data)
    puts "WebSocket data received: '#{data}'"
    send_message("echo: #{data}")
  end

  def on_close
    puts "WebSocket closed"
  end
end

host = '0.0.0.0'
port = '8080'

server = Rev::WebSocketServer.new(host, port, MyConnection)
server.attach(Rev::Loop.default)

Rev::Loop.default.run
echoサーバのプログラムと比べても、ほとんど違いがありません。構造的に違うのは、2行目のrequireと、4行目で作成しているクラスのスーパークラスがRev::WebSocketであることと、23行目でRev::WebSocketServer.newとしている箇所です。 サーバができたので試してみましょう。ただし、telnetコマンドではWebSocketサーバと通信できません。いや、正確には可能なのですが、繋がった後に渡すパラメータが複雑なので現実的ではありません。そこで、とりあえずChromeのJavaScriptコンソールから接続してみたいと思います。下記のプログラムを入力してみて下さい。接続先ホスト名は必要に応じて変更して下さい。うまく動作すれば、3行目で送信したメッセージが、アラートウィンドウに表示されます。
var ws = = new WebSocket( 'ws://localhost:8080/' );
ws.onmessage = function(event){ alert( event.data) ; }
ws.send( "This is a test message." );

重要な部分は、WebSocketのオブジェクトを生成すること、データを受信した際にonmessageが実行されること、受信したデータはevent.dataで取得できること、データ送信はsendメソッドであることです。

このように、WebSocketを使うことは難しくありません。皆さんもお試し下さい。 このエントリーをはてなブックマークに追加

2010年10月20日水曜日

メモ: クロージャの書き方

クロージャとは?

JavaScriptに触れていると、クロージャという書き方に突き当たります。それ何?って思って検索しても、難しいことばかりで本質はなかなか分かりません。しかも、他の言語でどう書くかも掲載されないことが多いです。元々慣れない言語(JavaScript)を勉強しているときに、概念もあやふやで、他の言語の例もない・・・ってことで使えるようになるまで苦労しました。確かに、他の言語では書き表しにくい書き方です。

そうは言っても、避けてばかりでは進歩しないので、自己流で解説してみます。サンプルは、node.jsなどを想定して書いています。Debianのsqueeze(2010/10/20時点でtesting)では、すでにnode.jsが標準パッケージに入っているので、敷居はかなり低くなっています。

まずはJavaScriptでクロージャ

ゴタゴタ書くと、難しいという先入観が形成されてしまうので、まずは下記のソースをお読み下さい。
var test = function() {
  var i = 0;
  return function() {
    i += 1;
    return i;
  }
}

var count = test();
count();  // => 1
count();  // => 2
count();  // => 3
まず、変数countにはtest内の3行目以降で宣言したfunctionが代入されます。堅い言語に慣れている人は、まずこの書き方を許容して下さい。functionは変数に代入できます。
このfunction内で扱っている変数iは、functionの外で宣言されています。ここで、count()が実行されると、iが1増えます(iが1になります)。そして、このiの値は(プログラマから見て)裏側で保持され、再度count()が実行されると、今度はiが2になります。このように、スコープ外で宣言された変数を取り扱うのがクロージャです。

では、iはどこに保持されているかと言うと、概念的にはcountの一部として保持されています。例えば、別の変数も作ってみましょう。8行目までは上記と一緒で、9行目から先を以下のように改造したとします。
var count1 = test();
var count2 = test();
var count3 = test();
count1();  // => 1
count2();  // => 1
count1();  // => 2
count3();  // => 1

このように、count1, count2, count3でのiはそれぞれ別の値を保持しています。もちろん、test内でいくつもの変数を宣言することも可能です。

Rubyでクロージャ

次に、比較のためにRubyでクロージャを扱ってみましょう。例によって、まずは下記のコードをご覧下さい。
def test
  i = 0
  return lambda { i += 1 }
end

count = test
count.call  # => 1
count.call  # => 2
count.call  # => 3
count.callの文字数が多くて嫌いな人は、最新版のRubyならcount[]という書き方も許されます。

Rubyを知らない人のために、じっくりと説明していきます。まず、1行目のdefはメソッドを定義するための構文です。この例ではtestという名前のメソッドを定義しています。2行目で変数iに0を代入しています。変数宣言はRubyでは不要です(と言うか、できません)。3行目でlambdaを使って定義した一連の作業を返しています。lambdaは、「一連の作業をオブジェクト化する」ことが可能です。(Rubyでは、最後に評価された内容がそのまま返り値となるので、returnは省略可能です)

6行目で変数countにtestメソッドの実行結果として先ほど定義したlambdaが代入されます。「test」は「test()」の省略形です。7行目以降のcount.callは、lambdaの実行です。iがどこに保持されているかはともかく、iの値が1ずつ増えているのが分かると思います。もちろん、count1, count2などを定義すると、それぞれのiは独立した変数として保持されます。

ついでにカリー化の手前

上のサンプルでは、クロージャの良いところが伝わりきっていないと思いますが、そのままカリー化の手前まで突っ走りたいと思います。カリー化の手前とは「2つの引数を伴う関数f(x,y)をg(x)(y)のように記述すること」です。真のカリー化は、もう少し複雑なので説明は割愛します。こちらも早速サンプルをご覧下さい。
var test2 = function( x ) {
  return function( y ) { return x * y }
}

mul = test2(3);
mul(2);  // => 6
mul(5);  // => 15

def test2( x )
  lambda { |y| x * y }
end

mul = test 3
mul.call 2  # => 6
mul.call 5  # => 15
2つの引数x, yを受け取って積を返す関数の代わりに、一つ目の引数xを先に受け取りクロージャの要領で保持しておきます。その後、もう一つの引数yを受け取って積を計算し、返すという流れが記述できました。もう一つの引数の受け取り方ですが、Rubyでは2行目の「 |y| 」のように、パイプ記号で囲った変数に代入されます。

この例では、掛け算に使用する数値の一つを先に受け取り、以後はその数値を基準として、もう一つの数値は実際に計算する際に渡す形となっています。これ以外にも、初期値を指定してカウントダウンするような場合とか、出力フォーマットを定めておいて後で数値を渡すと指定したフォーマットで出力するなどの場合に便利ではないでしょうか?

クロージャまとめ

C言語では、スタティック変数を使用することで、一見似た様な記述が行えます。しかし、その場合はcount1とcount2のように二つ以上の状態を保持できません。だからと言ってグローバル変数を使用するのも気が引けます。そのような場合にクロージャのような書き方ができると、グローバル変数を使用することなく実装できます。

一方、「クロージャなんて使わずに、オブジェクト指向(クラスとかインスタンス)でいいんじゃない?」って考えもあると思います。もちろん、オブジェクト指向の記述方法でも同じことができます。しかしその場合、変数の値を裏で保持して欲しいだけなのに、大げさな記述が必要になってしまいます。Rubyでのサンプルを以下に示します。
class Test
  def initialize
    @i = 0
  end
  def count
    @i += 1
  end
end

c1 = Test.new
c1.count  # => 1
c1.count  # => 2
c1.count  # => 3
この程度のプログラムでしたら、クロージャでもクラスでも好きな方で記述して良いと思いますが、クロージャのシンプルさは魅力的です。そうは言ってもクラスを使ってもカリー化と同等の内容も簡単に記述できます。クロージャに慣れていない人は現時点では多いと思いますので、そう言う人に気を遣う場合にはクラスを使った方が良いと思います。 このエントリーをはてなブックマークに追加

2010年5月29日土曜日

JavaScriptで苦悩

苦悩する日々

MeSHのフレームワークには、今のところユーザ管理機能はありません。ユーザ管理などは他のシステムに任せて、コアな部分だけを実装する予定だからです。とは言っても、そろそろ何らかのシステムと連携して実践したいところです。そう思ってたら、棚からぼた餅が落ちてきました。なんと、大学にLMSが(試験的に)導入されました。元々大学にはとあるプロジェクトがあって、当時はLMSが動作していたのですが、現在は停止しております。プロジェクトの中心にいた私が言うので間違いないです。停止しています。

自前でLMSを立ち上げるなど考えていたのですが、ユーザ管理の手間はいかんともしがたいものがあります。どうしたものかと思っていたところに、タイミング良くLMSが導入されたので、さっそく認証情報をもらうことにします。とは言っても、ユーザ情報の入っているデータベースに接続するとか、セッション情報を貰ってくるなんてことは、どう考えても許可が下りるとは思えません。色々考えた結果、LMSにHTMLの教材をアップロードして、そこでスクリプトを動かして強引に外部ページにリンクしてしまえ!と言うことに決め、さっそく慣れないJavaScriptと格闘しました。苦悩の始まりです。

簡単・・・じゃ無い

まずはLMSにHTML教材もどきをアップロードして、何ができて何ができないか確認します。その結果、LMSが作成したページ内にiframeで表示されることが分かりました。面倒なので、LMSが作成したページを「親」、iframe内のページを「子」と呼びます。親にはユーザ名が表示されているので、この情報を取ってきて、Formに入れて、MeSHのサーバにSubmitすれば、少なくともユーザ名を取得できます。本当は学生番号のようなユニークな情報があれば良いのですが、親のソースをいくら探してもそのような情報はありません。邪道なことをおこなうので仕方ないと考えつつ、氏名がliタグに囲われているのが救いでした。とりあえず、同姓同名がいたらそのときに悩むことにして、まずは技術確認を行います。

子では、割と自由がききました。JavaScriptも使えますし、JQueryを読み込むこともできます。とりあえず、ブラウザ(Google Chrome)のJavaScriptコンソールで一行一行実行しながら試そうとしたとき・・・「ん?iframeの親の情報ってどうやって取得するんだ?」と言うJavaScript初心者の検索の旅が始まりました。結局、金曜日の23:00~翌3:00、土曜日の21:00~翌3:00までやって、なんとか親のliタグの情報を取得することができましたが、ページに埋め込むとエラーで止まってしまいました。仕方ないのでJavaScriptが得意な学生にメールでデバッグの要請をしたら、ものすごい初心者的なバグ(と言うか考え違い)を指摘されました。我ながら「おぃおぃ、こんなのが分からなかったのかい?」と問いかけたくなるレベルでした。

やっとプログラムの話

そんなこんなで、やっとこさ完成したのが以下のソースコードです。生のJavaScriptとJQueryのコードが混在しているあたりが初心者丸出しです。はい、JavaScriptは初心者です。やってることは、parent.document.getElementsByTagNameを使って、親のフレームの特定のタグ(ここではli)に書かれた内容を取得し、その内容をid="username"の入力欄に入れ、新しいウィンドウを開いて、formをsubmitするだけです。まぁ、ちゃんと使うためには、textタグじゃなくてhiddenタグを使うとか、画面デザインを考えるなど、やることは沢山あります。また、Webサーバxxx.xxx.xxxでは、HTTP_REFERERをチェックすることもセキュリティ上必要だと思ってます。でも、とりあえず動作確認のためなので、これで良しとします。



以下、上のソース内のJavaScript部分の抜粋です。
var name1=parent.document.getElementsByTagName('li')[0].firstChild.nodeValue;
$('#username').val(name1);
window.open('about:blank', 'starting');
var f=document.starting; f.action='http://xxx.xxx.xxx/';
f.method='post'; f.target='starting';
f.submit()
このエントリーをはてなブックマークに追加

2010年5月13日木曜日

メソッド一覧を得る方法

前回の日記から、だいぶ日数が空いてしまいました。久しぶりに投稿しようと思います。今回は、技術的なメモで、あるクラスの持つメソッドの一覧を表示するやり方です。

Javaでメソッド一覧

Javaを使っていると、ふと「このクラスのメソッドって何があったっけ?」と思うことがあります。ドキュメントなどを漁るのが正道ですが、メソッド一覧が欲しいだけなら、このような方法があります。
この例では、Stringクラスのメソッド一覧を表示しています。5行目の「String」を別のクラス名にすれば、好きなクラスのメソッド一覧を得ることができます。

import java.lang.reflect.Method;

public class ClientMethod {
    public static void main(String[] args) {
        Method[] methods = String.class.getMethods();
        for(int i = 0; i < methods.length; i++){
            System.out.println(methods[i].getName());
        }
    }
}

Rubyでメソッド一覧

参考までにRuby版も掲載しておきます。2行目の「String」を好きなクラスに変更すればメソッド一覧を得ることができます。sortメソッドを組み込んでいるので、メソッド名をabc順に並べ替えてから表示します。
#!/usr/bin/ruby
String.methods.sort.each do | method |
  print method + "\n"
end

ふとしたときにご活用下さい。 このエントリーをはてなブックマークに追加

2010年3月28日日曜日

MeSHの対象

MeSHを使う人たちとして、1.学習者、2.教育者、3.コンテンツ開発者、4.翻訳者が挙げられます。この中で、2.と3.(と4.)が共通であることが多いと思いますが、教育者以外がコンテンツ開発を行う状況も考慮して分けております。システム的には、コンテンツ開発者が開発したコンテンツをテストすることが必要であることから、共通となります。

確認:利用場面別のMeSHの利用体系

マルチメディア教材を利用した授業体系

「見せる」教材としてのマルチメディア教材
 工学系で扱われる多くの不可視現象を、インタラクティブな教材を利用して説明する。すでに10年以上前から、板書を用いない授業体系を取り入れて、板書を一切行わずに授業を行っています。このような授業体系を取り入れることにより、期末試験での論述問題の正答率が向上した。学生が、教員の話をイメージしやすくなったものと分析している。

自己学習環境としてのマルチメディア教材

「見せる」授業体系だけでは、論述問題の正答率のみ向上した。しかし、学習者の理解度を向上させることを考えると、学習者が授業で使用したシミュレータ教材を利用して学習することが望ましい。
しかし、単にシミュレータ教材を配布したのみでは使い方が分からないなどの問題が発生する。そこで、授業または授業と同等の説明を行った説明を記録(録画)して、全部または一部を伴った教材として提供することで解決できる。

演習室などでのマルチメディア授業

少々特殊な環境ではありますが、演習室を利用する授業について説明します。これにより、考えられる利用パターンとして、「教員が説明してシミュレータの利用手順を見せた後に学習者が実験を行う」があげられます。また、学習者のシミュレータ操作情報を記録しておくことにより、「ある学習者がきちんと学習を行えているか教員側で判断できる」「模範的な学生の操作情報を取得して、全体に提示することができる」などがあります。

教材は国境を越える

これまで、シミュレータ教材は日本語だけでなく、英語、フランス語、中国語、韓国語、アラビア語版の開発が進められています。Wikipediaによれば、国連の公用語は、英語、ロシア語、中国語、フランス語、アラビア語、スペイン語の6カ国語らしいので、後はスペイン語とロシア語版を開発すれば世界制覇だ、という冗談はともかくとして、やはり使われない教材を開発するのはモチベーション維持の面で難しいです。そこで、翻訳成果をみんなで共有できればモチベーションも維持できると思います。

利用者のメリット

1.学習者にとってのメリット

 学習者のメリットは、これまでに述べているように、シミュレータ教材を含む統合されたマルチメディア教材を利用できることです。特に演習室などでの授業により、学習効率の向上が期待されます。

2.教育者にとってのメリット

 学習者の理解度向上が期待できることが最大のメリットです。また、自己学習環境を提供することにより、学習者が聞き逃したなどの場合に対応できる。さらに、シミュレータ教材を操作することで現象を理解した上で、踏み込んだ質疑応答が展開されることが期待できます。

3.教材作成者にとってのメリット

 シミュレータ教材の開発は、時間・手間などの人的コストが大きいものです。これまでの枠組みだと、開発したシミュレータ教材が、開発者に近い位置にいるごく少数の教員にしか使われないことが多かったです。

4.翻訳者にとってのメリット

 先に述べたように、翻訳しても誰も使わないようであればやる気が失せてきます。そこで、みんなで共有できる環境を提供します。これはシステムとしてはMeSHとして規定しなくても良いのですが、せっかくなのでMeSHを取り巻く開発環境の一環として開発する予定です。
 また、翻訳のために特別なプログラムが必要だとすると、翻訳作業が嫌になってしまう可能性が高いです。なぜならば、翻訳者が必ずしもコンピュータに詳しい者とは限りません。むしろ、世間一般を見回すと翻訳を生業としている方は、コンピュータ業界とは異なる分野に身を置くことが多いと思われます。
 以上のことから、特別なソフトウェア無しに翻訳成果を共有することが求められ、そのような仕組みを開発することで翻訳作業が進むと考えております。

全体としては、「シミュレータ間の通信の仕組み統一されている」→「シミュレータを開発して授業に使いたい」→「開発したシミュレータを使いたい」+「翻訳が容易」→「コンテンツの充実」というスパイラルがうまく回れば良いな・・・と思ってます。

ついでに言うと、ある科目に使うために開発したシミュレータが、関連する他の科目で活用されることもあると思います。活用も、関連科目でピッタリ使えるものもあれば、ちょっと違うけど何とか使えるレベルまで様々だと思います。教育を受ける側に立てば、同じシミュレータが出てくれば、何らかの関連があることを学習する効果が期待できるとも思ってます。
よって、学習者から見てバラバラに見えていた科目達が、シミュレータという指標によって結びつけられると学習効果が向上するのではないかとも思ってます。
この辺は、まだ私も実現できるかどうか分かりません。まずはシミュレータ教材開発者を増やすことと、MeSHに対応した教材を増やすことが第一だと思ってます。 このエントリーをはてなブックマークに追加

2010年2月9日火曜日

JavaScriptとjQueryのメモ

検索すれば済む話ですが、あまりに何回も同じことを検索するのに疲れたので、メモとしてまとめておきます。

生のJavaScriptとjQuery

すでに有名な話ですが、JavaScriptの実装はブラウザによって若干の誤差があります。特に有名なのがInternetExplorerですが、Microsoft社が実験的に先行して拡張したにも関わらず後続が異なる書式を採用したものもあるので、一概に責めることはできません。もしかしたら、他のブラウザで同様の技術が実装されなかった可能性もあります。

とは言っても、いわゆるWeb屋さんから見ると、IEとそれ以外で(実際にはもっと細かく)処理を分けるのは、やりたくないけどやらなければならない仕事であることは、想像に難くないです。そう言うことが嫌いな人たちが、関数化(またはクラス化)された処理内でブラウザ毎に処理を分けるノウハウを蓄積してきました。ブラウザ毎に処理を分ける必要がなくなり、プログラム効率が向上したのを良いことに、さらに便利な処理を関数化(またはクラス化)して、より複雑な処理の記述に耐えるべく進化してきました。

ありがたいことに、このような関数(またはクラス)がライブラリとして公開されています。有名なところでは、jQueryや、prototype.js、YUI、Dojoなどが存在します。これらのライブラリを活用することによって、生のJavaScriptでは難しい、またはブラウザ毎に処理を分けなければならない部分のプログラムを省略し、高度なプログラムを作成することができます。

JQueryを使う

上に挙げたように、いくつものライブラリが存在します。その中で、ここではjQueryを取り上げます。まずは、jQueryを使うための宣言を行います。通常はjQueryをダウンロードして、htmlファイルと同じディレクトリに置くのですが、楽な方法としてGoogleがホストしているものを使います。headタグの中に以下のように記述します。google.loadメソッドの引数は、順にライブラリ名、バージョンです。他にも様々なライブラリがホストされているので、興味のある方はこちらをご覧ください。



次に、JavaScriptのプログラムを置く場所ですが、上記の1行目のような記述方法で、外部ファイルを読み込むのが良いとされています。ですが、ちょっとお試しの場合は、わざわざ別ファイルを作成するのも面倒なので、htmlファイルの中に記述できます。もっと言えば、FireBugやChromeのJavaScriptコンソールを使ってもお試しできますが、後に残るようにすると、何かの時に役立ちます。それでは、jQueryを使って、JavaScriptのコードを書いてみましょう。



2行目は

と同じ意味です。

DOMの取得

さて、jQueryによって、まずプログラマが楽をできるのがDOM要素の取得です。DOMをいい加減に解説すると、「HTMLで書かれた文章から特定の内容を取り出したり、内容を変更する際に場所を指定する方法」です。例えば、「htmlの中のbodyの中のformの中の3番目のinput」のように階層化された構造を辿ることで、内容を取得できます。さすがにこれは面倒なので、通常は「id」や「class」などを目印に指定することになります。

以下のようなhtmlがあるとします。

このとき、「No.1」と書かれている箇所の指定方法には、以下のようなやり方があります。


上記の例は全てidによる指定でしたが、タグによる指定も行えます。この場合、結果は配列で返されます。


このようにすると、jQueryオブジェクトからDOM要素を取り出すことができます。DOM要素をjQueryオブジェクトに変換するためには、$( )で括れば良いです。以下の例では、No.1と書かれている箇所をjQueryを使って赤くします。

cssメソッドは、CSSに相当する操作を行います。色を変えたり、サイズを変えたり、非表示にしたりと、CSSで指定できるパラメータは(たぶん)全て記述できます。 このエントリーをはてなブックマークに追加

MeSHのコンセプト(3)

MeSHの目指したもの

元々は自学自習用のe-Learningのために、様々な技術を経てたどり着いたのが、Webブラウザ上で授業を行うという仕組みです。これにより、授業で使用するコンテンツと自学自習で使用するコンテンツを統一できます。また、教員の行った操作を逐一サーバに転送することにより、教員の動画像と同期して自学自習用コンテンツを動作させるための操作情報の取得が可能となります。

さらに、教員の操作情報をサーバに転送する機能を応用すると、演習室のような環境で、学生の使用しているコンピュータ上に、プレゼンデータやシミュレータを提示することが可能となります。単に提示するだけならば良くある(映像を使った)授業支援システムと同じです。しかし、MeSHで取り入れた操作情報のみをやり取りする方法では、学生の使用しているコンピュータ上でも実際にシミュレータが動作することになります。そのため、教員がシミュレータを操作しながら一通り説明した後に、「それでは、各自操作してみてください」と、即座に学生に実験環境を提供することが可能です。

実験の補助としてのMeSH

コンセプトの説明の冒頭でも述べましたが、理工系大学の教育には、実験・実習が欠かせません。しかし、実際に実験器具に触れる機会というのは、それほど多くありません。学生数に対して実験機材が少ない場合や、管理の都合上利用できる時間が限られることなどが原因です。

もちろん、実際に実験装置に触れることは重要です。しかし、実験装置の前に立ち、いきなり操作しろと言われても戸惑うのは当然です。そんなときに、模擬的とは言え経験があれば、操作に対する熟練に要する時間は節約できます。その分、実験に費やす時間が増えることでしょう。また、MeSHであれば、シミュレータの提供にとどまらず、教員の解説や模範操作まで提供可能です。

理論確認のためのMeSH

複雑な実験器具だけではありません。書籍などで解説されている理論を、その場で確かめてみたい、とか、何らかの理論から導かれたグラフを、パラメータを変えて変化を見たい、などの願望に対して、これまでなら自分で計算して確認することしかできませんでした。もちろん自分で計算することは重要です。しかし、全ての理論について計算を行っていたら、とてもじゃないですが時間が足りません。そのような場合にシミュレータを用いることで、体験的に理論を確認できます。単純な疑問をその場で解消することで、理論の深い部分に目を向けることが可能となります。このように、深い部分に到達するマイルストーンとして、分からない箇所を気づかせるということが重要だと考えます。ここで少々脱線して、経験を踏まえた与太話をします。

実は、授業で教えた内容を学生に確認すると、「分かりません。」「どこが分からない?」「全部分かりません」と言った会話が繰り返されます。全部分からない学生に深く話を聞くと、その授業を履修する前提となっている知識が不足していることに気づかされます。しかし、さらに深く話を聞くと、実は前提となっている知識が身についているにも関わらず、対象としている内容に結び付けることができていないことが多いです。

つまり、こう言うことです。
理論A: その授業で教えたい理論
理論B: 理論Aの基になっている理論
理論C: 理論Bの基になっている、ものすごく基本的なことので説明しない理論

説明内容:
「Cを基にしてBが成り立ちます。その条件・式の展開・応用範囲はこれこれこう言うことです。さらにBを深く見ていくと、これこれこう言う場合にはAということになります。」

授業終了後:
私:「今日の所は簡単だったから分かったでしょ?」
学生:「分かりません。」
私:「Bは分かる?」
学生:「分かりません。」
私:「Cは分かる?」
学生:「分かりません。」
私:「Cって、○○の授業でやったと思うけど、××ってことだよ。(などと数分にわたって説明)」
学生:「あぁ、それなら分かります。」
私:「そうそう、それを応用するとBなんだよ。さらに応用するとAなんだよ。(などと数分にわたって説明)」
学生:「なぁんだ。最初からそうやって説明してくださいよ。」

もちろん、こんな簡単に話が進みませんが、雰囲気だけは伝わったと思います。教員側・学生側問わず、誰でも一度ぐらいはこのような経験があるのではないでしょうか?ここで、「ゆとり世代」などと一言で片付けては、教育界に未来はないと思います。この学生に何が不足していたのか?と考えた結果、教えられたことに関してイメージをふくらませて「把握」することができなかったのだと思います。しかし、試験やレポート課題になっているため、とにかく丸暗記してやり過ごし、頭の片隅には残っているけど、同じ聞き方をしないとその記憶がよみがえらない、という状態です。例えが合っているか分かりませんが、歴史の授業で試験に出るからと言って、年号と起こったことを丸暗記するのと同じ状態です。

本来なら、授業で教わったことが、より広く・深く結びついて、やっと楽しくなるのに、その可能性を自ら閉じている状態です。これでは学生だけでなく教員も不幸です。そんなときにシミュレータを使って、基礎理論の段階から把握していれば、その先の講義でも興味を持って聞くことができるのではないでしょうか?もちろん、シミュレータを自分で操作することによって、好奇心が満たされるモノと考えています。

そのような場を提供するのがMeSHです。このように書くと、「e-Learningがあれば授業が不要になるの?」と勘違いされるので書いておきますが、MeSHの主体はあくまで対面式の授業です。授業を主軸に据えて、その内容を体験的に学習する場、授業内容を繰り返し学習する場がMeSHの目指す所です。

いわゆる学習サイクルは、以下のように定義されています。
  • 対面授業
  • 自学自習
  • 質疑応答
ここにMeSHを取り込むことにより、対面授業を補助し、心ゆくまで授業内容を確認しながらシミュレータで仮想実験でき、それでも分からない箇所は(分からない箇所がはっきりしているので)質問をしやすい、という形でサイクルがうまく回ります。

長くなりましたので、本日はここまでにしておきます。 このエントリーをはてなブックマークに追加

2010年2月5日金曜日

MeSHのコンセプト(2)

マルチメディア教材の配布

授業にマルチメディア教材を取り入れることで教育効果が上がることは、前回の記事で説明しました。当然、学生からは「授業で使っている教材を使って勉強したい」などの要望が寄せられてきます。それならば、と、さしあたってシミュレータ教材をWebサーバに置いてみました。ところが、寄せられる声は
  • 知らない拡張子で、使い方が分からない → 圧縮ファイルです
  • 展開はできたけど、エラーで実行できない → Runtime Libraryがないのでインストールしてください
  • Runtime Libraryってどこにありますか?どれを入れればよいですか? → このURLからダウンロードしてください
  • プログラムは動いたけど、これ何? → .....
などなど、情報系の大学生らしからぬ声が多数寄せられました。

圧縮ファイルの展開とかRuntime Libraryについて、マニュアルやFAQを充実させてもラチがあかないので、その辺は割り切って、教材の説明が必要だと感じました。また、当初はプレゼンテーションのデータも配布していなかったので、第2弾として、シミュレータ教材+プレゼンテーションデータ+講義映像を配布しました。と言っても、それらのデータを別々に置いて、「第○週」というリンクを掛けただけです。予想通り、「プレゼンのデータが開けません」との声が寄せられました。もちろん、「要PowerPoint」と明記したり、PowerPointViewerの配布ページへのリンクも付けておいたのですが。

ここまで来たら、とにかく使ってもらおうと本腰を入れて研究を始めました。まずは、Webブラウザ上で動かせば、ライブラリとかViewerの問題は解決するだろうと思い、JavaとかFlashに注目しました。とは言っても、シミュレータ教材を含むマルチメディア教材をWebコンテンツとして成立させるなんて、夢のまた夢です。今でこそ、HTML5の旗の下に、何でもHTML+JavaScript+CSSで片付きそうな勢いですが、当時はJavaScriptを本気で実用化させることすら無理と言われていた時代です。

そしてFlashへ

第3弾として、プレゼンデータの集まりをFlash上で成立させることを行いました。プレゼンデータはアニメーションを多用し、1ページ内の文字数を多くしつつ、今説明している箇所を分かりやすくしていました。ですので、まずはFlash上でそれらのアニメーションを再現し、「次」ボタンにより学習者が手動で読み進めるような形式にしました。実際にこの作業を担当した学生は、Flashならではのアニメーションを多用して、「かっこよく」したかったようですが、あまり派手にすると視認性が落ちるのは目に見えていたので、とにかく元データを再現して貰うように話し合いました。ですが、派手なアニメーションが多数残っていたのは彼の意地だったものと思います。参考までに、使用したFlashはFlash MXかその前だったと記憶しています。アニメーションは、図形の変形を使ってタイムラインに従って高さがほぼ0の状態からすーっと大きくなるように手作業で付けていました。作業自体は地味です。地味ですが延々と続きます。だいたい一科目のスライド数が150枚程度だったと記憶しています。

プレゼンデータが何とかなりそうだったので、第3弾の続きとして、シミュレータ教材をJavaに移植する作業に取りかかりました。とは言っても、VB6でお世話になった仮想座標やTimerなどがJavaには存在しません。この辺は、実際に担当した学生達が意地になって移植しました。移植したソースプログラムはJava Applet特有のpaintやinitなどのせいで処理が散乱している上、仮想座標を物理座標に変換するための式が所々に散らばり、かつ、Timerの代わりに使ったThreadのせいで、その後のメンテナンスが絶望的な状態でした。現に、VB6版のシミュレータは、たいていバージョンアップしていますが、Java版のバージョンアップは見送られた状態です。とは言え、これらを配布したところ、ライブラリなどに関する質問は激減しました。だいたい一科目のシミュレータ数が30程度だったと記憶しています。

さらに第3弾の続きとして、マルチメディア教材の説明を配布することになりました。これについては、教員の空き時間の関係で授業そのものを録画することと、圧縮にはMPEG-1を用いることが決まりました。MPEG-1を選択した理由ですが、当時は様々な動画圧縮技術が出てきた時代ですが、そのなかでもプラットフォームを問わず、編集・圧縮・再生環境が安定していて、当時の貧弱な家庭ネットワークにも対応できるように選びました。学生がダウンロードするにしても、ネットワーク帯域を考えるとちょっと大きなサイズだったと思います。とは言え、シミュレータ+プレゼン+説明が揃いました。学生からの声は、案の定、「手で動かすのが面倒」「動画データがでかい」「ウィンドウが重なりすぎて混乱する」などでした。ウィンドウの件については、確かに当時の狭い画面で、講義映像とFlash、Javaを開くのは無謀でした。肯定的な意見としては、概ね「このような教材が無いよりは良い」という程度でした。

プレゼンデータと講義映像の統合

そこで第4弾として、ブラウザ上でシミュレータとプレゼンと講義映像を統合することに挑戦しました。さらに欲張って、プレゼンが講義映像に同期して進むとか、先生の説明している場所が分かるようにレーザーポインタを再現するとか、今思えば無謀きわまりない仕様で作成することになりました。作業手順はこんな感じです。
  1. PowerPointのデータを、グループ毎にまとめてコピーし
  2. Flash側でタイムラインを考慮しながらペースト。
  3. それぞれのアニメーションが終わるところで一時停止するようActionScriptを記述
  4. 授業を撮影(教員+スクリーン)→編集(スライド1枚ごとに動画像を切り分ける)→それぞれ圧縮。
  5. タイムラインに講義映像をペースト
  6. 講義映像に合わせてプレゼンデータのタイムラインを引き延ばす
  7. プレゼンのアニメーションタイミングを調整
  8. スクリーンを撮影したビデオを見ながら手作業でレーザーポインタの光をコンテンツ上に再現
  9. 目次を作成してリンクを掛ける
うーん、やはり手間が掛かりすぎる。とは言え、学習者からは概ね良い評価を貰いました。ただし、このやり方ではシミュレータを統合することはできません。当時の標準的なe-Learningシステムでは、プレゼンが単なる静止画になっているものが多かったので、それと比べてアニメーションが付いていることとレーザポインタが再現されていることが利点でしたが、さらなる発展が必要です。

統合型教材誕生

第5弾は、いよいよシミュレータの統合です。第4弾の開発手法では、とにかく表示内容全てをFlashの支配下に置いていましたが、HTMLをベースとするようコンテンツ全体を見直しました。開発担当の学生が、「HTML内の別々のFlash同士で変数を共有できる(ように見せかける)技術」を発見し、この機能を軸に開発を進めました。具体的には、全体を一つのFlashにするのを辞め、講義映像再生用のFlashコンテンツとプレゼンテーションデータ表示用のFlashコンテンツに分けました。細かいことを言えば、それらの他に目次が付きます。そして、講義映像Flashが再生時間を通知し、それを受けてプレゼンFlashがアニメーションやレーザーポインタを進めていく方式です。ついでに講義映像も別ファイルに置いて、メンテナンス性を向上させました(後になって講義映像の編集ミスが見つかることが多い)。

肝心のシミュレータはと言うと、プレゼンFlashの代わりにシミュレータを読み込むようHTMLに記述しています。今でこそ、JavaScriptなどを介してFlash→Javaにデータを送ることができますが、当時はそんなことは夢のまた夢。そのため、シミュレータの動作は、学習者が手作業で進めることになりますし、レーザポインタも再現されません。その代わり、プレゼン時に教員を再生している箇所を、シミュレータ時にはスクリーンの映像に切り替えることにしました。とりあえず、マルチメディア教材を統合することができなので、統合型教材と名付けました。

このように苦労した甲斐あって、ほとんどの学生から「このようなコンテンツが必要」との意見を貰いました。実際にシミュレータを自分で操作する(=手を動かす)ことによって、理解度が向上したようです。おそらく心ゆくまでシミュレータの操作を楽しんだものと思われます。

利用者にとって、いささか問題は残るものの、シミュレータ教材を提供するための技術が確立しました。次に確立しなければならないのが、統合型教材の開発コストを下げることです。どこにコストが掛かっているかというと、
  • プレゼンデータのFlashへの移植(タイミングは考慮せずに、単純にデータをコピー&ペーストするのみ)
  • 講義映像の編集(ページ毎の切り出し)
  • シミュレータの移植(VB6→Java)
  • プレゼンデータのタイミング設定
  • レーザーポインタの再現
などです。さらに、シミュレータ教材についても、教員の操作を再現する仕組みが必要です。動画像データとしてしまうことも検討しましたが、データサイズが膨大になることと、学習者が操作する際の切り替えに時間が掛かること、細かい点ではシミュレータ教材を撮影した動画像データが見づらいことも改善の必要有りです。もっと言えば、シミュレータ教材の開発効率も向上させる必要があります。

そしてMeSHへ

それらを加味した第6弾がMeSHです。一番肝心な点は、プレゼンテーションツールとしてPowerPointを捨て、Webブラウザを選択しました。また、シミュレータもWebブラウザ上で動作させるようにし、Flash、Java、Silverlightなどの技術を用いて開発します。これによって、教員の操作データを逐次サーバに送り、保存することが可能となりました。さらに、演習室のようにパソコンが並んでいる環境では、サーバに送られた操作データを学生用パソコンにリダイレクトすることで、目前のスクリーンで講義を受けることができます。もちろん、インターネットを通じた別の場所でも受講できるでしょう。さらに、サーバに蓄積された操作データを元に、自学自習用コンテンツに転用することも容易になります。演習室などでの利用形態を下図に示します。

このエントリーをはてなブックマークに追加

MeSHのコンセプト(1)

MeSHのコンセプトを一言で言うと、「高等教育のための、シミュレータをベースとしたマルチメディアe-Learning」です。
それって何だ?と思われた方は、ちょっと話が長くなりますがおつきあいください。

MeSHは、e-Learningと言う単語を使っています。e-Learningと言うと、通常はコンピュータベースの自学自習システムを指しますが、MeSHでは対面授業もサポートします。

e-Learningと言う単語の守備範囲は広いです。元々は学習状況(いつ、誰が、何を学習したか?その講義を受けた後の確認試験で何点だったか?)を記録し、教育者が学習者全体の理解度を管理することが目的となっていました。その後、ある学習者がつまづいた箇所を調べたり、授業中にリアルタイムで意見を求めたり、iPdoなどで講義動画像を見せるだけだったり・・・とありとあらゆることがe-Learningの範疇に入ってきました。一方、授業の様子は?と言うと、コンピュータを活用する授業が少しだけ出てきた以外は、何ら全く変わっていません。

前述のiPodへの講義動画配信などは、単純に黒板を背にして講義している姿が手元のiPodで見られますが、講義そのものは全く変わっていません。そのようなスタイルであらゆる学問領域をカバーできるか?と聞かれると、「文系科目ならできるかもね」と答えています。何故かと言うと、理工系科目の多くは、学習者が自分で手を動かさないと理解できないことが多いからです。数式の展開とか、構造の図式化とかが相当します。最も分かりやすい例は演習とか実験科目です。

授業スタイルの話に戻すと、理工系の科目で取り扱う題材は、教育者は深く理解していても、学習者にとっては未知の領域であることが多いです。さらに、教員は授業のやり方などを一切勉強していません。そのため、教員の説明は、得てして飛び飛びになったり、前提となるはずだが説明が抜けていた箇所を後の方で説明したり、学習者の理解レベルが分からなくて説明を飛ばした箇所が重要なポイントになっていたり、教員の頭の中では図・式・対応する現象が溢れていても学習者の頭の中にはクエスチョンマークが飛び交うなんてことが展開されています。もちろん、全ての先生がこのような授業をやっていると言うつもりはありません。説明の上手な方もいらっしゃいます。しかし、私のように説明の下手な教員がうまく説明するために、何かできることはあるでしょうか?

ポイントをまとめると、理工系では
  • ただでさえ、理解に時間が掛かる
  • その上、先生の説明していることがよく分からない
  • 話していることを見てみたい
と考えている学生がいます。学習者に図式化して提示するために黒板があるのですが、直線や円を描くのが難しかったり、動きを見せられなかったり、見えない現象の説明には限界があるし、パっと描くには複雑すぎたり、パラメータの変化による現象の変化を示すには描くのに必要な時間も場所も不足するなどの問題があります。

そこで、
  • 写真やビデオ
  • 音声
  • パソコン上でリアルタイムに演算した結果
などを用意して、まず学習者に提示することで、理解を促進させることができます。

ここで、多くの現象はコンピュータによる解析が進んできています。さらに、コンピュータの計算速度はものすごい勢いで向上してきています。現行品として売られている最も低性能のパソコンでも、一昔前のスパコン並みの計算速度を持っています。実際にパソコンに自作のプログラムを入れて、複雑な演算を行わせても、ほぼ一瞬で計算が終了します。このように、理論に従って計算し、図(静止画・動画)、音声として学習者に提示するプログラムをシミュレータ教材として定義しています。さらに、上に挙げた「図」「写真やビデオ」「音声」「シミュレータ教材」をプレゼンテーションソフト(具体的にはPowerPoint)で統合した教材をマルチメディア教材として定義しています。

マルチメディア教材を授業に取り入れることにより、学習者は説明内容をイメージングできます。なおかつ、教科書や参考書などではページ数の都合で、現象の条件すべてについて図示することができませんが、シミュレータ教材であればパラメータを変えることで、いくらでも図示することができます。

「そんなの、Mathematicaを使えばいいんじゃない?」って意見もあるかと思います。Mathematicaを頭から否定することはしませんが、以下の点を問題視しています。(私自身はMathematicaを知らないので、間違いがあればご指摘ください)
  • Mathematicaをコマンドラインで扱えないと何もできない
  • パラメータの変更に時間が掛かる
  • ちょっとしたパラメータ変更時などで入力ミスをすると、その後に影響が大きい
  • 音を合成できない
  • 実行時にMathematicaが必要
  • グラフ化して見栄えが悪い場合に線の色などを変更できない

グラフィックに強い(手間が掛からない)言語を使うべく、シミュレータ教材は主にVisualBasic6.0(以下VB6)で書いてきました。VB6は、グラフィックを手軽に扱え、グラフ描画に必要な仮想座標も扱える等の点で良い言語でした。「Fortranは?」って人もいるかもしれませんが、虚数は実数部と虚数部に分けて計算することで回避できますし、行列演算などはループを使えば良いので、演算部分はどんな言語でも大差ないです。演算速度を問題にする人もいるかもしれませんので少し説明すると、例えば演算速度が100倍違ったとします。でも、最近のパソコンはすでに高速なので0.0001[sec]と0.1[sec]の違いしかないかもしれません。授業で扱うような題材は、わかりやすさを優先して理論単純化することが多いので、その程度の計算時間のものが大多数を占めますので、概ね問題ありません。

マルチメディア教材を授業に取り入れたのは、1997年からでした。当時のパソコンの性能はと言いますと、CPUが200MHz、RAMが64MB、HDDが数GBぐらいの時期です。VisualBasicも5.0だったかもしれません。ノートパソコンのスペックは、それよりも数段劣りますし、プロジェクタも部屋を真っ暗にしなければならない時代でした。パソコン、プロジェクタ、スピーカを担いで授業を行いました。その甲斐あって、学生からは分かりやすいとの意見を貰いました。期末試験の結果も、特に論述問題に関して大幅に向上しました。ただ、計算問題については、学生自ら手を動かして確認することの重要性を確認しました。

マルチメディア教材は、以下の特徴を持ちます。
  • 分かりにくい理論の説明に役に立つ
  • シミュレータ教材や他のメディアを統合したマルチメディア教材
  • 見せてあげることで現象を把握できる
  • 学習者が手を動かすことは重要

長くなりましたので、今回はここまでにしておきます。 このエントリーをはてなブックマークに追加

2010年2月4日木曜日

JavaScriptとC#の連携方法(1)

シミュレータ教材の操作情報をサーバに送ったり、送られてきた操作情報に従ってシミュレータ教材の動作を制御することが必要となります。その方法を簡単なサンプルを使って紹介します。まずはC#を使って、HTMLのDOM要素にアクセスしましょう。

以下のようなHTMLを想定してください。



C#からDOMの取得

まず、C#からのDOM制御のやり方です。HTMLの中の特定の箇所の内容を取得します。id="test1"で指定された「シルバーライトのテスト」を取得し、変数strに代入します。


後は、strを表示するなり加工するなり、好きに使ってください。

C#からDOMを制御

次の例では、DOMを制御して文字列をセットします。上のプログラムで取得したstrをid="test2"に納めます。
このエントリーをはてなブックマークに追加

2010年2月3日水曜日

ソースコード表示機能のテスト

最近、ソースコードがきれいに掲載されているサイトが多いです。それらに刺激されて、どうやったらきれいになるのか、試してみます。

ソースコードを整形するツール(と言うかJavaScriptとCSS)を見つけようとしても、数が多すぎてよく分からないのが実態です。そんな中、SyntaxHighlighterに辿り着きました。(URL

まずは、私のよく使う(または使うであろう)言語・フォーマット達が含まれているかチェックです。割と沢山対応していて、Ruby, VisualBasic, JavaScript, C#, Java, PlainText, HTML, CSSなどたいがいのものはオッケーです。GoogleのGoogle-Code-Prettifyというツールもあるのですが、Rubyのサポートがないのと、表示がイマイチなので使いません。

使い方も、headタグでJavaScriptを読み込んで、表示したい箇所でちょっとだけJavaScriptを書くだけです。嬉しいことに、作者のWebページでホスティング(って言葉で正しいのかな?)してくれてます。

まずはheadタグの中に以下の内容を書きます。


その後、ソースコードを埋め込みたい箇所に以下のように書きます。


別の書き方はこちら
<pre class="brush: html">
ソースコード
</pre>

いずれも、brush: htmlの箇所を書き換えると様々な言語に対応できます。ただし!HTMLのタグが入っていると、(少なくともBloggerでは)エラーになってしまうので、この際ですから&gt;や&lt;に書き換えてしまいましょう。これらの対応を施しても、ソースコードの右上付近に出てくるコピーツールでコピーすると、きちんとした括弧に直してくれます。

その変換は、クリボウさんのこちらの記事をご覧ください。このような便利なツールを公開していただき、ありがとうございます。 このエントリーをはてなブックマークに追加

MeSH日記始めました

現在、MeSHフレームワークを開発しています。
MeSHとは、Multimedia e-Learning based on Simulator for Higher educationの略です。
簡単に言うと,シミュレータ教材を活用するためのe-Learningフレームワークです。

このブログでは、
・MeSHとは何か?
・開発の方向性
・使えそうな技術のピックアップおよび簡単なコード
などを掲載していきます。 このエントリーをはてなブックマークに追加