Lecture on Programming I 5/18

Menu Menu


先週の復習

   typing の練習
   課題の提出について
   インデントについて
   Mule の漢字のcut&pasteについて
   subroutine
   Turtle Graphics
   Perl のオブジェクト
   Turtle Graphics の課題
   ドラゴン曲線

来週、5/25 は学会のために自習とします。


Typing の練習

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

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

整形した結果を、

    Subject: Report on Programming I   5/18-typist

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


Turtle Graphics の復習

以下のような渦巻型を引数で指定された大きさで、表示するプログラムを作成せよ。

引数は、

	$count = $ARGV[0]

という形でとることができる。


渦巻型のプログラムの作り方の例

まず、渦巻の最初の座標を手で計算してみる。この時に、紙ではなく、エディタを使うとそれをそのままプログラムのコメントに使用できる。

       +----20+10-------+
       |
      20 
       |     ---10-+
       |           |
       |          10
       +----20-----+

これを書くための Turtle の動きを考えよう。
           
 forward 10             
 right                 
 forward 10           
 right               
 forward 20
 right 
 forward 20
  .....

毎回、右に曲がるのは良いとして、同じ距離だけ2回動いて、10 だけ進む距離を増やすのが良いらしい。(ちょっと考えれば理由はすぐにわかる)

これを、for 文で書いてみよう。

    $length = 10;
    for($i=0;$i<$count;$i++) {
	&forward($length);
	&right();
	&forward($length);
	&right();
	$length += 10;
    }

こんな感じか? ここで $count は、進む数。ただし、二つずつになっている。
	$i++              $i を一つ増やす
	$length += 10     $length を 10増やす

という慣用句に注意しよう。

Turtle.pm には、(まだ) forward と right がないので自分で作る。いきなり、Turtle を呼ばないで、座標を計算して表示させるものを作ろう。

    sub forward {
	my ($length) = @_;
	if ($dir == 0) {
	    $x += $length;
	    print "forwad $legnth (X = $x,Y = $y)\n";
	} elsif ($dir==90) {
	    $y += $length;
	    print "forwad $legnth (X = $x,Y = $y)\n";
         ...
	}
    }

方向を曲げるのは簡単で、
    sub right {
	$dir += 90;
	$dir %= 360;
    }

とすれば、良い。%= は、割算の余りを計算している。(本当は、これらのものは、Turtle graphics のlibraryのなかに入っているべきだ)

これを動かして、座標を確認する。正しい座標が表示されなかったら、プログラムを見直そう。

正しく動いたら、Turtle graphics に関するさまざまなものや、$count を引数から受け取る部分を記述する。

さっき書いた絵も、コメントとしていれておくのが良い。このようにして、作られたのが、 です。


問題 (追加分)

二重の渦巻を書くプログラムを作成せよ。

四角い渦巻ではなく、丸い渦巻を作成するにはどうすれば良いか? 円をずらして実現する方法も考えられる。自己相似な渦巻も考えられる。


ドラゴン曲線について

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

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

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

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

top

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


Unix プログラミングスタイル

なるべくいろいろなツールを組み合わせる

Henon アトラクタを計算してみよう。

    #!/usr/local/bin/perl5
    $x = 0.2; 
    $y = 0.3;
    for($i=0;$i<10000;$i++) {
	   printf("%1.3g %1.3g\n",$x,$y);
	   ($x,$y) = (1.0+$y-1.4*$x*$x,0.3 * $x);
    }

これを、henon.pl として、

    perl5 henon.pl > output.henon
    gnuplot
    gnuplot> plot "output.henon"

としてみよう。


Perl の構文について

正しい文の作り方

式とは何か?

文とは何か?

文法構造とはなにか?

    if-statement 
	: if ( condition ) { statement }
	| if ( condition ) { statement } else { statement }
	| if ( condition ) { statement } else-if-statement
	;
    else-if-statement
	: elsif ( condition ) { statement }
	| elsif ( condition ) { statement } else { statement }
	| elsif ( condition ) else-if-statement
	;

このことについてはコンパイラの授業で詳しく習う。


Perlのデータ型について

文字列と数字

配列と連想配列

スカラ (scalar)


配列

配列は、数字から値への対応を提供する。順序のあるデータの集まりの表現に便利である。

      DB<2> @a = (a,b,c,d,e)
      DB<3> p $a[1]
    b
      DB<4> @b = (1,2,3,4)
      DB<5> @c = (@a,@b)
      DB<6> p "@c"
    a b c d e 1 2 3 4
      DB<7> 

for文で配列を処理するのが一般的。
    for $i ( @a ) {
	print "$i\n";
    }
    for($i=0;$i<$#a; $i++) {
	print "$i $a[$i]\n";
    }

要素を削除するには? splice というのがあるけど、今のところはcopyが簡単。

Perl のプログラムに与えられる引数は配列の形で与えられる。


問題

Perl のプログラムに与えられた引数を逆順に表示するプログラムを作成せよ。

Perl のプログラムに与えられた引数で指定された数だけ四角を書くプログラムを作成せよ。

   ex.  perl5 squares.pl 1 2 5
   □
   □□
   □□□□□


連想配列

連想配列は、文字列から値への対応を提供する。集合などの表現に便利である。

      DB<7> $a{'kono'} = kono
      DB<8> $a{'key'} = value
      DB<9> p "%a"
    %a
      DB<10> p %a
    keyvaluekonokono
      DB<11> p join(" ",%a)
    key value kono kono
      DB<12> 

のように定義する。 削除する時には delete を使う。

      DB<13> delete $a{'kono'}
      DB<14> p join(" ",%a)
    key value
      DB<15> 

key は、keys という関数で取り出すことができる。連想配列全体を処理するには、
    for $i ( keys %a ) {
	print "$i -> $a{$i}\n";
    }

などとする。


正規表現によるパターンと置換</h2><p>

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 のプログラムを書き、それを配列と連想配列に格納してから、表示するプログラムを作成せよ。


宿題

カオスの例を WWW などから検索し、それを Perlで計算して gnuplot で表示するプログラムを作成せよ。

以上の課題を

  Subject: Report on Programming I   5/18

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


Shinji KONO / Fri May 19 23:48:53 2000