Lecture on Programming I 5/24

Menu Menu


先週の復習

    エラーの読み方
    Perlの参照
    Turtle Graphics
    Package / Module
    Object


Typing の練習

今日も typing の練習をすること (20分)

結果をscript でメールすること。

整形した結果を、

    Subject: Report on Programming I   5/24-typist

というサブジェクトで、kono@ie.u-ryukyu.ac.jp までメールを出すこと。

    % rsh pw006 "Mail -s 'Report on Programming I   5/24-typist' kono@ie.u-ryukyu.ac.jp" < typescript


Perl の名前の付け方

大文字や特殊な文字は、変数や関数名には使わない。

モジュール名は、大文字で始める。:: を使って、階層的なモジュールを作成する。


Perl のデバッグの方法

   print 文
   実行状態のモニタ
   動作のおかしな地点の特定
   テストプログラム


Perl のmy について

    $i = 4;
    print "1: $i\n";
    &test();
    print "2: $i\n";
    sub test {
	my $i;
	print "3: $i\n";
	$i = 3;
	print "4: $i\n";
	&test2();
    }
    sub test2 {
	print "5: $i\n";
    }

以上のプログラムを実行し、my の役割と、$i の意味について、自分の言葉で100文字程度で、 説明せよ。

test を以下のものに置き換えたらどうなるか?

    sub test {
	my $i;
	print "3: $i\n";
	$i = 3;
	$j = \$i;
	print "4: $i\n";
	&test2();
    }
    print "6: $j\n";
    print "7: $$j\n";


Turtle Graphics の復習

Turtle.pm


追いかけ

亀を追い掛ける亀を作ろう。

これを四角に並べて動かして見る。

square 四角でなくて、三角だったら? N角形だったら? N角形をシミュレーションするプログラムを作って見よ。


Turtle の拡張

拡張された亀として、追い掛けるプログラムを作って見よう。

それを使って、N角形の場合を記述して見よう。


Turtle の継承

@ISA を使って、Turtle.pm を直接モディファイ(modify)しないで、FollowTurtle.pm
 を作ろう。


酔っ払いシミュレーション

    前に進む $turtle->forward($length)
    方向を変える $turtle->turn($degree)

を使って、酔っ払いの動きをシミュレーションしてみよう。

drunken.pl Turtle.pm 2次元配列 $visit[$x][$y] を使って、酔っ払いがどこにどれだけいたかを積算してみる。Perl の配列にはマイナスの添字が使えないので、ちょっとオフセットを足すのが良い。

    亀の位置  $turtle->{-x},$turtle->{-y}

亀の位置は、浮動小数点の数値なので、int()を使って整数に直す。

2次元配列の内容を、gnuplot で表示できるように以下の形式で出力する。

    X Y Count

このためには、Turtle.pm から、表示ルーチンを変更したものを作ると良い。STurtle.pm

gnuplot の splot コマンドで表示してみよう


Perlの参照の復習


2次元配列

  DB<2> $a[0][0]=1
  DB<3> $a[0][1]=2
  DB<4> $a[1][0]=3
  DB<5> $a[1][1]=4
  DB<6> p $a[0]
  ARRAY(0x813ba94)

Perl の2次元配列は、配列の配列になっている。この、
  ARRAY(0x813ba94)

とななんだろうか?

  ARRAY(0x813ba94)

は、Perl の参照と呼ばれるスカラの値である。スカラなので、普通の変数に代入することができる。

      DB<8> $b = $a[1]
      DB<9> p $b
    ARRAY(0x813b43c)
      DB<10> p $b[1]
      DB<11> p $b->[1]
    4

$b[1] は、配列@b の2番目の値であって、$b の値とは違う。$b に入った配列への参照は、-> を使ってアクセスすることができる。

      ->    参照へのアクセス

Perl のデータ構造は、\ を使って参照に変えることができる。

      DB<12> @c=(1,2,3,4,5)
      DB<13> $b->[3] = \@c
      DB<14> p $b->[3]
    ARRAY(0x813be4c)
      DB<15> p $b->[3]->[2]
    3


問題

参照を使って、-> が4つ以上続くデータアクセスの例を作成せよ。正しく動くことを perl5 -de 0 のデバッガで確認すること。

      DB<9> p $b
    ARRAY(0x813b43c)

であるときに、
    $b = 0;

とすると、どうなるか? $b から参照されていた配列はどうなるのか考察せよ。
    $c = $b;
    $b = 0;

ならばどうか?


1次元配列を使って2次元配列を表す

2次元配列は、以下のように1次元配列を使って表すこともできる。

    $col_size = 10;
    $a[$x * $col_size + $y]


問題

酔っ払いの位置を積算する場合について、この1次元配列による2次元配列を実装する方法と、配列の配列で2次元配列を実装する方法を比較し、双方の良い点と悪い点をそれぞれ2つづつあげよ。


再帰呼び出し

渦巻の形に注目する。外側を一つ書くと、内側は、まったく同じ形になっている。

これを利用して、渦を外側から書いてみよう。

自分自身を呼び出すサブルーチンを再帰呼び出しという。


プログラムの停止条件って何?

再帰的に呼び出して停止するためには?


ループか再帰呼び出しか?

ループや再帰呼び出しからの脱出

eval と die


再帰呼び出しとオブジェクト

uzu.pl を、Turtle.pm を拡張する形で作ってみよう。

Turtle.pm には変更を加えずに、新しい機能を持つオブジェクトを定義する。


ドラゴン曲線を書こう

例 dragon.pl を適当な所で、色かえて再帰的な動さを理解してみよう。

どのようなタイミングで色を変えるときれいに表示できるか考えて、実装しよう。

次数nの時に直線の個数はいくつ?

指数オーダということはどういうことか?

一つの直線について、メモリはどれくらい消費されるのか?

プログラムが要求したメモリが実装メモリを越えたらどうなのるのか?

top

人に迷惑をかけないように実験しよう


正規表現によるパターンと置換

Perl でパターンを取り出すには正規表現と言うのを使う。

defined($var)変数$varが定義されているかどうか
$var$varが定義されていて、0でなく""でもない。
$a == $b数値的に等しい
$a != $b数値的に等しくない
$a > $b数値的に大きい
$a eq $b文字列的に等しい
$a ne $b文字列的に等しくない
$a =~ /pattern/パターンマッチ
$a =~ s/pattern/replace/置換

Perlの強力な機能の一つは、パターンである。正規表現により、さまざまなパターンを処理し、必要なデータを抜き出したり、置き換えたりすることができる。

      $var =~ /pattern/;
      $var =~ s/pattern/replace/;

などの形で使う。$var を省略するとdefaultの変数 $_ が使われる。これは、while(<>) {} の形で、行毎に代入される。したがって、
      while(<>) {
         if (/pattern/) {
              print;
         }
      }

あるいは、
      /pattern/ && print while (<>);

で、grep pattern と同じ動作をする。

pattern には以下のような種類がある。

ABCDそのまま文字列ごとの一致
[a-z]aからzの文字に一致
[a-z]*aからzの文字の0個以上の一致
[a-z]+aからzの文字の1個以上の一致
.任意の一文字(改行以外)
(ABCD)+ABCDの文字列の1個以上の一致
$var$varの内容と一致
\WWなどによって決まった文字集合と一致
\{特殊記号との一致

()でくくわれたパターンは、それぞれ、$1,$2... に格納される。これらは、置換パターンの中で使うこともできる。

      s/j000(\d\d)/& = $1/;


問題

typist の script から、38.00 (語/分) 誤入力率 0.00% などの数値を抜き出す Perl のプログラムを書き、それを配列と連想配列に格納してから、表示するプログラムを作成せよ。

データ 解答例 これから、gnuplot 向きのデータを作成するプログラムを生成し、表示させて、データについて分析せよ。

自分の時系列データをグラフにする。

速度のみを表示する。

エラー率のみを表示する。


宿題

以上の課題を

  Subject: Report on Programming I   5/24

というサブジェクトで、kono@ie.u-ryukyu.ac.jp までメールを出すこと。


Shinji KONO / Thu May 31 15:06:31 2001