大雨後の濁流の動画(卒研用)
今年の卒業研究では、型落ちしたスマホなどが出た時の活用として、 川の氾濫警報のための監視システムを作ることをテーマにしている。
そこで、平常時の川の写真よりも、濁流となった状態がどういったものなのか、 サンプルが欲しいということで、今朝の川の動画を撮影してみた。
これより解かることとして、濁流状態では水しぶきで霞んだ状態になっている。 このため、時間軸の差分法では、明確な「濁流」を検出することは難しいと思われる。
2013年7月28日(第331回)
学生さんがテスト期間中につき、教員による収録でお送りしました。
- 新任先生紹介 物質工学科 後反先生
- まるよし Train Pops ~ 国語と遊ぼう! 第17回 「新幹線の名前」
- 金田先生の恋愛相談室
ゲスト:物質工学科 後反先生
担当:長水先生、金田先生、丸山先生、西
コンテナクラスとテンプレート(C++),Generics(Java)
オブジェクト指向で、純粋仮想基底クラスと、仮想関数を使った応用では、 コンテナクラスと呼ばれる方法が使われる。 コンテナクラスでは、空っぽの純粋仮想基底クラスを使って、データを便利に扱える 処理(アルゴリズム)を記述しておく。 自分でデータを扱うプログラムを作成する場合には、その空っぽクラスから派生させた クラスを定義し、仮想関数のメカニズムを使ってそのアルゴリズムが動くようにしておく。 こうすれば、面倒なアルゴリズムを、違う型でもそのアルゴリズムを使える。 このようなクラスは、コンテナクラスなどと呼ばれたり、Generic クラスなどと呼ばれる。
過去の記事では純粋仮想クラスの説明で、Object という純粋仮想基底クラスで、 データ並び替えなどのアルゴリズムが、使える例を示した。
しかし、この過去の記事では、配列には、Object から派生させた Integer や、CString が 入っている例で、便利に使える例として説明しているが、 一つの配列の中に、Integer や CString が混在したら、実は cmp() 関数で、 異なる型のことを考えていないため、実行時に動かなくなる。
こういった問題の解決として、色々なテクニックが考案されているが、この例が、 C++ のテンプレート機能と、Java の Generics 機能である。 ただ、この2つの機能は、文法の字面では似ているが、考え方はまるっきり違う。 以下に、固定長スタックを例に使い方を中心に説明する。
C++ テンプレート
C++のテンプレート機能の基本原理は、実はあんまりオブジェクト指向と関係はない。 例えば、整数データを記憶するスタックのプログラムは以下のようになる。
class Stack { private: int data[ 100 ] ; int sp ; public: Stack() { sp = 0 ; } void push( int x ) { data[ sp++ ] = x ; } int pop() { return data[ --sp ]; } } ; void main() { Stack s ; s.push( 1 ) ; s.push( 2 ) ; printf( "%d" , s.pop() ) ; printf( "%d" , s.pop() ) ; }
しかし、整数を覚えるスタックは記述できたが、実数を覚えるスタックや文字列を覚えるスタックは、改めて記述する必要がある。 この不便さを解消するのがテンプレート機能である。
template<class T> class Stack { private: T data[ 100 ] ; int sp ; public: Stack() { sp = 0 ; } void push( T x ) { data[ sp++ ] = x ; } T pop() { return data[ --sp ] ; } } ; void main() { Stack<int> si ; // 型Tにintを割り当てた、処理が生成される。 si.push( 1 ) ; printf( "%d" , si.pop() ) ; Stack<double> sd ; // 型Tにdoubleを割り当てた、処理が生成される。 sd.push( 1.23 ) ; printf( "%lf" , sd.pop() ) ; }
テンプレートの基本は、型情報を<class T>として雛形プログラムを記述しておき、 具体的に型を明記して使われた時点で、その型に応じた機械語を生成してくれる。
JavaのGenerics
JavaのGenericsは、字面や使い勝手では、C++のテンプレートと同じように使う。 しかし、実際は、Java の全データの純粋仮想基底クラスの Object 型を使っている。
public class Stack<T> { private T[] data ; private int sp ; public Stack() { sp = 0 ; data = (T[]) new Object[10] ; } public void push( T x ) { data[ sp++ ] = x ; } public T pop() { return data[ --sp ] ; } public static void main() { Stack<Integer> si ; // Integerはintのラッパークラス si.push( 1 ) ; System.out.println( si.pop() ) ; Stack<Double> sd ; // Doubleはdoubleのラッパークラス sd.push( 1.23 ) ; System.out.println( sd.pop() ) ; } }
2013年7月21日(第330回)
学生さんがテスト期間中につき、教員による収録でお送りしました。
- 五味が答える!~かかってこいや~
- まるよし Train Pops ~ 国語と遊ぼう! 第16回 「新幹線の名前」
- テストの話
担当:青木先生、五味先生、丸山先生、西
2013年7月14日(第329回)
- まるよし Train Pops ~ 国語と遊ぼう! 第15便 「質問コーナー」
- 五味が答える!~かかってこいや~
担当:前田勝(4EI)、松島(2C)、山野(2C)、五味(教員)
自宅で監視カメラを動かしてみた
今度の週末は、家族旅行の予定。 だけど、子どもがその間、最近病院に連れて行った婆ちゃん猫を 心配している。
そこで、使っていなかったWebカメラで、急遽、監視カメラを動かしてみた。 奥さんからは、解像度低いじゃんとツッコミを受けるが、 もともとのWebカメラの性能だと思うし…
余りにも他愛もないコードだけど、 この手のお遊びプログラムは、 学生さんに「こんなこと簡単にできるよ」と見せることも多いので、 PHPコードに改良&コメント付けをしておく。
監視カメラを動かすまで
fswebcamが一番簡単に使えそうだったので…
(( fswebcamをインストール)) $ sudo aptitude install fswebcam
fswebcamの出力をそのまま画像形式で返すプログラム。
(( webcam.php )) <?php // 画像形式、キャッシュさせない header( "Content-Type: image/jpg" ) ; header( "Cache-Control: no-store, no-cache, must-revalidate" ); // 連続読み出し用にファイルロック $flock = fopen( "/var/www-support/.webcam.lock" , (file_exists( "/var/www-support/.webcam.lock" ) ? "rb+" : "wb+" )) ; if ( flock( $flock , LOCK_EX ) ) { system( "/usr/bin/fswebcam -q -d /dev/video1" ." -p YUYV" // 画像形式 ." -D 0" // delay ." -S 3" // skip frame ." -r 320x240" // 解像度 //." -r 640x480" ." --title \"tsaitoh.net's webcam\"" ." --jpeg 75 -" ) ; fclose( $flock ) ; } ?>
webcam.php の出力画像を、連続で読み出すように、 JavaScriptで設定を書き加える。 <meta http-equiv=”refresh” content=”5″> みたいな方法だと、reload の度に画像がちらつくので、JavaScriptで reload させることになった。
(( index.php )) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" id="sixapart-standard"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="viewport" content="width=320,height=320,initial-scale=1"/> <title>自宅監視カメラ</title> <script type="text/javascript"> <!-- var count = 0 ; function reload() { count = (count + 1) % 100 ; // 画像を更新(キャッシュ画像を使わないように番号付) var img = document.getElementById( "image" ) ; img.src = "webcam.php?"+String(count) ; img.id = "image" ; // 動きの少ない相手用に確認表示 var txt = document.getElementById( "text" ) ; txt.innerText = "自宅監視カメラ: "+String( count ) ; } // --> </script> </head> <body> <p align="center"> <img id="image" src="webcam.php" onload="reload()" /> <div id="text"></div> </p>
オブジェクト指向とGUIプログラミング
オブジェクト指向のプログラミングの基礎の話も終わり、 UMLによるプログラム設計の記述方法や、最後にソフトウェアの作成の流れ などを説明できたので、テストまでの今日を含めあと3回。 オブジェクト指向で分かりやすくなったGUIプログラミングについて解説を行う。
オブジェクト指向がないGUIプログラミング
技術の比較として、オブジェクト指向を使わないGUIプログラミングの例として、 unix の GUI 環境でもある X11 における Xlib を使ったプログラミングを最初に紹介。
なお、以下のプログラム例では、概念を示すために初期化や関数の引数は省略されており、 実際にはもう少し記述量が必要。
void main() { Display* display = ディスプレィの初期化 ; Window w1 = ウィンドウの初期化 ; Window w2 = ウィンドウの初期化 ; while(1) { // イベントが発生するまで待つ XNextEvent( display , &event ) ; // 発生したイベントを分類するswitch文 switch( event.type ) { case Expose: // ウィンドウの露出イベント // 対象となるウィンドウを調べて各種処理 if ( event.xany.window == w1 ) { w1の描画処理 ; } else if ( event.xany.window == w2 ) { w2の描画処理 ; } break ; case ButtonPress : // マウスが押されたイベント if ( event.xany.window == w1 ) { マウス処理 ; } break ; //------------------------ // ここが延々と巨大化 //------------------------ } } }
この方式では、XNextEvent() の後の何をすべきかの イベントの分岐命令が巨大化するし、対応するウィンドウを 探す if 文なども煩雑。
これではプログラムが大変なので、Xt(Xlib toolkit)では、コールバック関数を 用いて分岐までをスムーズに記載できるようになる。 コールバック関数とは、そのイベントが発生した時の処理関数を、 関数ポインタで登録しておき、イベント時に呼び出してもらう関数。
void w1_expose_callback( ... ) { w1の描画処理 ; } void w2_expose_callback( ... ) { w2の描画処理 } void w1_button_press_callback( ... ) { マウス処理 ; } //-------------------- // ここが延々と巨大化 //-------------------- void main() { Xtの初期化 ; // ウィジェットは、ウィンドウ上の部品を管理するデータ構造 Widget w1 = ウィンドウを初期化 ; Widget w2 = ウィンドウを初期化 ; // Xtにコールバック関数を登録する // (引数に関数名だけが書いてあることに注目) XtAddCallback( w1 , ExposureMask , w1_expose_callback , ... ) ; XtAddCallback( w2 , ExposureMask , w2_expose_callback , ... ) ; XtAddCallback( w1 , XtNcallback , w1_button_press_callback , ... ) ; // Xtに処理を完全に任せる... XtAppMainLoop( ... ) ; }
Xt では、ウィンドウの管理を行う toolkit に、自分の作ったウィンドウで、 必要なイベントが発生した時に実行してほしい処理を、 関数ポインタで登録しておく方法をとる。 この後、XtAppMainLoop() を呼び出して、この関数の中から必要な ウィンドウのイベントが発生する度に、コールバック関数を呼び出してくれる。
JavaアプレットのGUIプログラミング例
基本的には、ウィンドウ処理を記載する場合には、ウィンドウ画面を管理するための Applet と呼ばれる基底クラスを用いる。 自分で作るウィンドウの処理を記載する場合には、Applet クラスから 自分の処理のクラスを派生させ、その中で 描画処理を行う paint() や、 マウス処理を行う mousePressed() 等を記述すればいい。 そうすると、 Applet クラスが、仮想関数のメカニズムで、ユーザのクラスの paint() や mousePressed() などを、必要なタイミングで呼び出してくれる。 自分にとって特に記述の必要がなければ、イベント関係のメソッドを記述しなければ良い。 そうすれば親クラスのメソッド等が呼び出され、必要な処理を行なってくれる。
public class MyApplet extends Applet { // ウィンドウの露出に合わせて呼び出される。 public void paint( Graphics g ) { 描画処理 ; } // マウスが押された時に呼び出される。 public void mousePressed( MouseEvent e ) { マウス処理 ; } // 他にも、init , start , stop , destroy , // paint , repaint , update 等のメソッドなどを // 必要に応じて定義すればいい */ }
画面にボタンや、別の部品が必要な時は、ActionListener というインタフェース(interface)を実装(implement)する。 インタフェースとは、純粋仮想基底クラスのような物で、 Javaには多重継承の概念が無いため、インタフェースを実装するという形で、 プログラムを記述する。 特に、ActionListener インタフェースは、ウィンドウのイベントを処理する仮想関数を 記述するために使われる。
public class MyApplet extends Applet implements ActionListener { // クラス変数(Applet内のボタン等を記述する) Button b1 = new Button( "ボタン1" ) ; Button b2 = new Button( "ボタン2" ) ; // Appletの初期化関数 public void init() { b1.ボタンの配置を設定() ; b2.ボタンの配置を設定() ; // ボタンが押された時に呼び出してほしい事を、 // ActionListenerに登録する。 b1.actionListener( this ) ; b2.actionListener( this ) ; } // ウィンドウが露出した時に呼び出される。 public void paint( Graphics g ) { 描画処理 ; } // ボタンが押されるなどのタイミングで呼び出される。 public void actionPerformed( ActionEvent e ) { if ( e.getSource() == b1 ) { ボタン1の処理 ; } else if ( e.getSource() == b2 ) { ボタン2の処理 ; } } }
これらの方式は、基本的な考え方であり、最近の Java では、 さらに進んだイベント処理の考え方が取り入れられていたりするので、 あくまで、このプログラムの例は参考です。
電子情報でPC学生購入で簡単アンケート
今日は校長裁量経費のプレゼンテーションであった。 この中で、電子情報の実験環境として、**の実験設備が希望といった プレゼンを行った。 ただ、電子情報では実験用をサポートするためのPC購入を 希望しても、国への補正予算要求なども含め、 最近はなかなかPC購入にOKが出ない場合が多い。
この対応として、パソコンをバリバリに使うんなら、 学生が個人購入してもらい、それを使うという方法もある。 実際、他の高専の情報系の学科では、入学時購入や 3年で購入といった所もある。
個人的にも、1年購入であれば 4,5年でパソコンが 陳腐化するかもしれないので、なかなか賛成はしづらい。
情報系でPC購入のアンケート
ということで、授業の最後の5分で実際にパソコンをバリバリに 使っている4年を相手に挙手形式で簡単アンケートをしてみた。
1年でノートパソコン購入だと、高いと思う人...約90%
うーん、やっぱり入学時だと他にも購入するものも多いし、難しいかな。 関数電卓とか、TIのグラフ電卓の絡みもあるし、悩みどころ。
授業用パソコン購入をするのなら、何年がいい? 入学時...約20% 3年.....約50%
この辺は意見が分かれる所で、こんな結果であった。
パソコン購入は、高いというイメージがありそうなので、
皆さんがイメージするパソコンっていくら? 5万円... 20% 7万円... 30% 10万以上... 50%
うーむ、高い機種を考え過ぎだと思うんだけどな….
また、3年購入だとパソコンの使い方も色々なので、機種とかを 完全同一というのも難しいとも思うので、
3年でパソコン購入なら、機種は自分で選びたいと思う? ... 約90%
やっぱり3年購入だと、共通環境で購入してもらうのは、極めて難しそう。
んで、この質問タイムの間の意見で次のような意見もあった。 入学時購入ならOfficeなどのインストールはどうするの? (同一環境PCなら業者に事前に対応してもらうことになるだろうな…)
Office入れるぐらいなら、Google Document でいいんじゃ? といった意見もあった。これについては、私もクラウド利用もあると 思っていて、「Microsoft 包括協定」もあることだし、Office 365 を使う手もあるとは思っている。
また、自転車通学の学生からは、「ノートパソコンあっても学校に持っていくのは 大変。落として壊す心配もあるし、自転車だと *お*も*い* !!」とのことであった。 そーだよなぁ…. かといってタブレットじゃ、プログラミング系の課題はできんしなぁ…