Perl入学式#3に参加してみた

Perl入学式 プログラミング初心者のためのPerl入門講座の第3回目に参加してみたので、その感想やらを書きなぐるエントリー。

内容については、きっと上記のサイトにレポートが上がると思うのでそちらを参照すればよいでしょう。
Perlの基礎の基礎から勉強しましょう、という勉強会でした。

12月くらいまで1年間という長期にわたって行われるらしいです。結果として長らく続いている勉強会はいっぱいあると思いますが、期間を明確にしているものは珍しいのではないでしょうか。

今日やった演習は恐らく少してもプログラミングを経験したことのある人なら易しいものだったと思います。
今後、回が進むにつれて、途中から参加する初心者の人をどうフォローするのかが課題になってくるのでしょうが、補講までも用意されているので、主催者の本気度がすごいです。

やった課題とその感想

1.半径を入力して、面積を表示する

my $PI : Constant(3.14);
print "半径: ";
my $radius = <STDIN>;
chomp($radius);

print "面積は " . ($radius ** 2) * $PI . "です\n";

話を聞き流しながら、定数をどうやって定義するのかググると、constant とか、Readonly とか色々ヒット。どれがよく使われるのか聞くの忘れた。

2.所持金に応じて、何を食うか決める

print "所持金: ";
chomp(my $money = <STDIN>);

print "場所: ";
chomp(my $place = <STDIN>);

if ( $place eq "梅田" && $money >= 2000 ) {
    print "そうだ、居酒屋に行こう\n";
} elsif ( $money >= 1000 ) {
    print "しかたない、吉野家で我慢するか\n";
} else {
    print "ハラへった\n";
}

まあ、if 文の説明。論理演算子で && と and の両方が使える。違いは優先順位の差とのこと。Rubyと同じだな、というかきっと逆にRubyPerlの影響を受けたのでしょう、elsif も含めて。

3.キーボードから文字を2つ入力して、== や eq の結果を見る
コードは略

数値として比較したい時と文字列として比較したい時をプログラマが意識して == と eq を使い分ける必要がある。面倒。変数にタイプがないので仕方ないか、逆にタイプがあるとRubyみたいに to_i したりしないといけないので、一長一短か?

4.キーボードから数字を入力して合計を求める

print "数値を入力: ";
chomp(my $input_nums = <STDIN>);

my @input_nums = split(/, */, $input_nums);
my @error_inputs;
my @good_inputs;
my $sum = 0;

for my $num (@input_nums) {
    if ( looks_like_number($num) ) {
        $sum += $num;
        push(@good_inputs, $num);
    } else {
        push(@error_inputs, $num);
    }
}

print "@good_inputs の合計は $sum です\n";
if (@error_inputs) {
    print "@error_inputs は数値でないので無視しました\n";
}

split で文字列を分解できるので使ってみた。数値かどうかはモジュールがある、というのでググると looks_like_number() というのがあったので使用。
if(@error_inputs) とすると配列が空かどうか判断できるらしい。Perlで式が「真」と判断されるのがどのような場合かも聞くのわすれた。

5.文字当てゲーム

my $answer = "Perl";
my $len = length $answer;
print $len . "文字の文字: ";

my $win = 'false';
my @words;

for (1..10) {
    chomp(my $word = <STDIN>);
    push(@words, $word);
    if ( $word eq $answer ) {
        print "正解です!\n";
        $win = 'true';
        last;
    } else {
        print "違います\n";
        if ( $answer lt $word ) {
            print "辞書順でもっと小さいです\n";
        } else {
            print "辞書順でもっと大きいです\n";
        }
        print $len . "文字の文字: ";
    }
}
my $count = @words;
if ($win eq 'true') {
    print "あなたの勝ち\n";
    print "$count 回の入力の後に正解\n";
} else {
    print "あなたの負け\n";
    print "10回も挑戦したのに間違えましたね\n"
}
print "入力したのは" . join(', ', @words) . "でした。\n"

勝ち負けを $win フラグに持たせているのがダサいけど、まあいいや。こういうのは間違えた時のヒントの出し方を変えたり、もう少し時間をかけてもいい課題だと思う。

6.FizzBuzz

my $input;
do {
    print "いくつまで?: ";
    chomp($input = <STDIN>);
    if ( $input < 1 ) {
        print "1以上の数値を指定して下さい\n";
    }
} while ( $input < 1 );

print join(', ',
           map {
               ($_ % 15 == 0) ? "Fizz Buzz" :
                   ($_ % 5 == 0) ? "Buzz" :
                   ($_ % 3 == 0) ? "Fizz" :
                   $_ } (1..$input) ) . "\n";

定番。今回 if 文や while 文の説明だったのでやると思った。普通に if 文を使ったコードはつまんないので、map を見よう見真似で使用。

雑感

最初にも書いたけど、続き物で勉強会をするのは途中参加のハードルを上げてしまうので、結構難しいと思う。今後に期待ですね。

講義は若干駆け足。質問を考えている内に次に進んでいくので、止めるのもアレなのでそのままにしてしまった。

資料が事前に公開されていなかったので、各参加者が手元で資料を読み返したりすことができず不自由な思いをした人もいたのではないでしょうか。やっつけ&直前でいいので公開されていると安心。