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の内容と一致 | |
| \W | Wなどによって決まった文字集合と一致 | |
| \{ | 特殊記号との一致 |
()でくくわれたパターンは、それぞれ、$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 までメールを出すこと。