60%の人間はプログラミングの素質がない…
個人的には、なかなか、的を得た数字のように思うな…
「ふたこぶラクダ」という名前の有名な論文に書かれているんだってさ。
引用:プログラミングの素質は、構築したメンタルモデルを、 ブレずに一貫して適用できるかどうかにかかっているようだ。
それぞれのプログラミング言語の都合に合わせて、動くようにプログラムを書くのだから、 わけのわからない言語のルールに、ブレずにしたがって頭の中で動く様をシミュレートできるか…って感じかな。
引用:一貫したグループにプログラミングを教育するのは、はるかに簡単である。 このグループは、観測的に、さらにふたつに分かれるようだ。 ひとつは、プログラミングを非常に簡単に感じ、プログラミングを楽しみ、 その後も成長してソフトウェアを書く良いプログラマーになるグループ。 もうひとつのグループは、プログラミングはできるものの、 それ自体には楽しみを見出さず、管理職になってUML図に溺れるグループ(やれやれ)。
爆笑….
ハノイの塔とマージソートの分析
再帰呼び出しを含む処理の、速度分析の説明として、ハノイの塔とマージソートを 説明する。
ハノイの塔
ハノイの塔は、3本の塔にN枚のディスクを積み、ディスクの上により大きいディスクを積まずに、移動させるパズル。 ハノイの塔の移動回数を とした場合、 少ない枚数での回数の考察から、
ということが予想される。
この予想が常に正しいことを証明するために、ハノイの塔の処理を、 最も下のディスク1枚と、その上の(N-1)枚のディスクに分けて考える。 これより、
ということが言える。 ディスクが 枚で、予想が正しいと仮定すると、
枚では、
となり、 枚でも、予想が正しいことが証明された。 よって数学的帰納法により、1枚以上で予想が常に成り立つことが証明できた。
マージソートの処理速度分析
最も高速なソートアルゴリズムとして、クイックソートがあげられる。 しかし、説明が分かり難いので、同じ処理速度のオーダとなる、 マージソートの分析で説明する。
マージソートのアルゴリズムは、
- データが1件の時は、そのまま。
- それ以上の件数では、
- データを中央で2分割して、それぞれをマージソートを行う。
- 出来上がった2つのデータ列を、先頭から2つを比較し小さい方から移し替える。
この方式であれば、再帰方程式として、以下の式が示される。
N=1,2,4,8,…と、代入を繰り返すと、処理時間は、 であることがわかる。
創造工学の導入実験でPerlと正規表現
4年の前期実験では、2週分を創造工学でのシステム作りの導入とするための、 基礎実験を行っている。クラスを3グループに分け、私の担当は初回にPHPによる、 Webプログラミングの説明。これにより簡単な掲示板やアンケートを作ってもらった。
2回目の今日は、1日実験でPerlと正規表現の実験を行った。 最初に、超単純英語によるBot作りをネタに、Perlの基本文法と、正規表現を体験してもらう。 理解度が速い人向けに、後半はメールデータを題材にしながら、 Jcode.pmを用いた文字コード変換、headerのmime_decodeを説明し、 このメールデータの中から、From,Toの部分を抽出するプログラムを作ってもらう。
#!/usr/bin/perl # 超基本英語によるBot while( <> ) { $line = $_ ; if ( $line =~ /like/ ) { if ( $line =~ /^(.*)\s+like(|s)\s+(.*)\.$/ ) { print "$1 は $3 が好きです。\n" ; } } }
#!/usr/bin/perl # メールデータの文字コード変換 use Jcode ; my $head = 1 ; while( <> ) { $line = $_ ; if ( $head ) { print Jcode->new( $line )->mime_decode->utf8 ; if ( $line =~ /^$/ ) { $head = 0 ; } } else { print Jcode->new( $line )->utf8 ; } }
Perlを初めて使ってもらうので、 暗黙変数$_とのマッチングや、 「式 if ( 条件 ) ;」といった Perl らしい節操のない書き方は、説明を避けた。
OB特別講演
プログラミングに興味を持ってもらうためにも、 情報系の企業の方の知識で語ってもらう特別講演にて、 OBの中西さんに来てもらい話していただきました。

話の途中で、学生さんの実態を確認したくなって、途中で色々とアンケートっぽく 挙手形式で聞いてみた。 インターネット花盛りで情報系なんだし、インターネットビジネスの入口をどこまで体験しているか ということで、Google検索使ってる?GMail使ってる?Mixi使ってる?Twitter使ってる? GREE使ってる?モバゲー使ってる? 的に聞いてみた。 ただ、結果としては、予想外にネットを使っていないことが解った。 GMail当たりは使っている人も3割程度だったけど、Google検索・Gmail以外のGoogleサービス 使ってる?と聞いても、反応は薄かった。 Twitter,Mixi,GREE,モバゲーと聞いてみたけど、かぶっている利用者ばかりで、 2割を切っていたかなぁ… ヘビーに活用しているひとは使ってるけど、それ以外の人が多すぎるってことか。
ということで、4年の創造工学でアイデア出しとかしても、ネタに窮するのは、 やっぱり電子情報工学科といいながら学生さん自身がインターネットを深く活用していないというのが 根本だと感じたなぁ…
# ヘビーにネット依存されるのも困るんだけどね…2極化?
file-scope(static)とextern文
プロコンの競技部門の学生さんたちが、最後の追い込み。 各パーツに分かれて動作確認が取れてきたし、 1つのプログラムに合成する最後の段階になっている様子。 しかしながら、合成した後プログラムが動かないとの相談。 1度目の処理は動くけど、2回目で動かないという状態なので、 不完全な初期化データを使って動かなくなっているのではと想像する。 といっても、そう簡単に間違いが見つかる訳もないけど、 ひとまずコードを見せてもらう。 すると、覚えたての分割コンパイルで、ヘッダファイルの中に、 static int array[…] ; といった記載が見つかる。
このままでは、array[] が、各C言語ファイル毎に、file-scope の別な実体を持つため、 大域変数渡しの副作用が伝わらなかったり、その結果として未初期化が発生したり。
ファイルスコープ
C言語では、静的変数の局所変数を作りたい場合、関数ブロック内で "static"キーワードを指定すればよい。 しかしながら、関数ブロック外で static キーワードをつけると、 分割コンパイルした場合、file-scope を持つようにコンパイルされる。 つまり、各ファイル毎の大域変数は、たとえ同じ名前の大域変数が別ファイルに あったとしても、別な記憶領域を確保してくれる。
(( aaa.c )) int x1 ; // 静的変数・大域変数 static int x2 ; // 静的変数・大域変数・ファイルスコープを持つ void foo() { static int x3 ; // 静的変数で局所変数 : } (( bbb.c )) extern int x1 ; // aaa.c の x1と同じ実体を参照できる。 static int x2 ; // aaa.cのx2とは大域変数だけど別の実体をもつ
分割コンパイルして、各ファイルで共通の変数や関数を定義する場合は、 以下のように行う。 ポイントは、extern によって宣言すると、実体は別のところにある変数となる。
(( common.h )) int foo() ; // プロトタイプ宣言 extern int bar ; // 実体はどこかで確保される変数として宣言 (( aaa.c )) #include "common.h" int bar = 123 ; // 変数barの実体 int foo() { // 関数foo()の実体 } (( bbb.c )) #include "common.h" void main() { bar = 234 ; // aaa.c の大域変数barに代入 printf( "%d" , foo() ) ; // aaa.c の関数foo()を呼び出し }
構造体ポインタ渡し&オブジェクト指向
先週の構造体の基本の説明を受け、構造体の実際的な使い方の紹介を行う。 後半では、構造体をうまく使えば、データ隠蔽、手続き隠蔽ができて、 手続き・データ設計者と、それを利用する人に分かれて大きいプログラムが書ける… といった説明を行う。 また、この発展形としてのオブジェクト指向の導入部分を説明する。 ただし、オブジェクト指向のネタは、本来の授業範囲外でテストには出さない。
構造体のポインタ渡し
構造体を使っていると、そのデータを使った処理の記述が増えてくる。 この場合は、以下のように関数に構造体へのポインタを渡して操作を行う。
struct Person { char name[ 10 ] ; int age ; } ; // ポインタ渡しに慣れるまではアロー演算子は使わない。 void set( struct Person*p , char s[] , int a ) { // 質問:なぜ (*p).name = s ; ではいけないのか? strcpy( (*p).name , s ) ; (*p).age = a ; } // 慣れたら、アロー演算子。 void print( struct Person*p ) { printf( "%sさんは%dさいです\n" , p->name , p->age ) ; } void main() { struct Person saitoh ; set( &saitoh , "saitoh" , 45 ) ; print( &saitoh ) ; }
このようなスタイルに慣れると、呼び出し側(この例ではmain()の中)には、 データ構造の中身、手続きの中身を知らなくても、プログラムが書ける。 このようにデータ構造をブラックボックスでとらえられることをデータの隠蔽化、 処理の中身をブラックボックス化することを手続きの隠蔽化という。
そのまんまオブジェクト指向に…
この辺に慣れてくると、オブジェクト指向も理解しやすくなってくる。 オブジェクト指向では、データ構造⇒オブジェクト、データに対する手続き⇒メソッドと呼び、 この2つを合わせてクラスと呼ぶ。
class Person { char name[ 10 ] ; int age ; void set( char s[] , int a ) { strcpy( name , s ) ; age = a ; } void print() { printf( "%s%d" , name , age ) ; } } ; void main() { Person saitoh ; saitoh.set( "saitoh" , 45 ) ; saitoh.print() ; }
授業で眠そうにしている学生さんがいたので、ちょいとイヤミきつめで注意。 緊迫感がなさそうだし、3年だと「あと2年しかない」、「不景気で就職も進学も大変」 というネタでやる気をださないと苦労するのは自分…と雑談を交えた授業となった。
学力強化週間で補講
今週は、福井高専では『学力強化週間』ということで、前期授業で理解が浅い学生さんのために、 補講を行うことになっている。 ということで、3年のプログラミング応用、4年の情報構造論について補講を行った。
4年情報構造論
前期では、リスト構造のプログラミングが中心であったので、以下のような課題を、 実際に黒板に書いてもらいながら、説明をしたり、穴埋めや処理の目的を聞きながら、 補講となった。補講は2コマ分しかないので、必要最小限でかつ自分で考えることを目標に行った。
- 昇順の配列の途中にデータを挿入。(挿入場所を探して、後続のデータを1件分後ろにずらして挿入)
- 配列中のデタラメな順序の配列と、昇順になるように次のデータの配列添え字の配列で、 リストもどき。(配列添え字をたどりながら全データ表示)
- リスト処理の宣言の後、リストのデータを1件づつ表示。
やはり成績不振の学生さんは、2年レベルの配列処理でさえもコードが書けない。 すこしづつ経験と、処理を追いかけることができるようになることが重要。 ということで、ループの処理順序と値の変化を追う練習ということで、 上記課題の処理順序と値の変化を処理終了まで記載する課題をだして終了。
3EIプログラミング応用
前期では、2年の復習およびファイル処理とポインタの基礎だったので、 これを踏まえ処理の順序を追いかける練習を中心に補講を行った。
- forループ途中でbreakのプログラムの処理トレース、およびフローチャートを記述
- forの2重ループで、処理のトレース、およびフローチャートの記述
- 配列中の最大値・最小値の差を表示プログラムを作成
- ファイルからのデータ入力の基礎プログラムを説明。(fopen,fclose,fscanf)
- ファイルに記載されているデータを読み込み、最大最小値の差を表示
高専プロコンの講評結果
先日、5チームの応募の中らか、全国高専プロコンの予選に、自由部門1チーム通過、 競技部門1チーム参戦の結果が来ていたが、その書類審査の講評が送付されてきた。
興味深いのは、思考過程を『旅』と捉え、マインドマップのネットワーク共有型エディタの作品の 講評がどういった結果か、興味があった。 思考過程を旅ととらえる部分が趣旨よりはずれていると見られたかどうかであるが、 講評を見ると、「面白い着眼点」とみているひとと「趣旨はずれ」とみなしている人と、 両意見であった。でも予選を通過できなかったのは、どちらかというと「具体性」だったようだ。 もう少し、プロトコルやらデータの管理方法を明言すべきであったようだ。
これに比べ、応募資料的には不安であった、砂で遊ぼうのチームは予選通過となった。 やはり「オリジナルのハードウェア」を含む作品は、「独自性」が高いと評価されやすい傾向がある。 一方で、ソフトウェア単体で動くアイデアの物は、「既存」と判断されやすい。 以前から、創造工学で取り組んでいるのだが「もっとハードに絡むもの」を増やさないとダメだな…
課題レポート採点
今日は寮の日直ということで、 その間にプログラミング応用と情報構造論の課題レポートの採点。
プログラミング応用のレポートは、がんばって書いている人もいるけど、 すでにテスト生点でそれなりの点数が取れた人は、 ちょっと手抜きの様子。 成績は、max(テスト生点,テスト*60%+レポート40%)という計算方法なので、 レポートの加点を入れても、成績が上がらない人がほとんど。 まあ、プログラムがそれなりに書ければ、こんなものかな…. レポートの説明で、変数表とか処理の説明してくれているけど、 どちらかというとイメージ図を交えたりといった説明が欲しかった。 といっても、簡単な課題だし説明を丁寧にといっても、 変数表ぐらいしか丁寧に書けないか….
LEDメッセンジャーを行き先表示板に
自宅で試作していたLEDメッセンジャーのプログラムを職場の行き先表示板にしてみました。PICNICのカタカナ表示よりは便利になりました。 PICNIC版と同じように、携帯からメッセージを書き込めるようにしたし、 表示でもスクロール機能があるので、256byteまでのメッセージであれば、 分かりやすく表示できます。