読者です 読者をやめる 読者になる 読者になる

Perl入学式2013年度第5回補講(2014/01/11)・参加レポート vol.1

この数日は公私が立てこんで毎日かなりグロッキー(ってどういう意味)ですが、だからこそというか、私事にも仕事にも関係ないプログラミングのペースを保ちたいところです。イングヴェイ・マルムスティーン先生も「調子が悪いときほど練習を休んではいけない(ギターの)」と言っておられましたし。

ということで自分を盛り上げるためにも、久しぶりにルーティンなメモではない記事を。
ネタ自体はいくつかありますが、やっぱり一番グッとくるのは「Perl入学式」のことなのでそれについて、でもちょっと時間も環境も十分じゃないので今日は助走的なネタからスタートします。

最新第5回の本講の方は昨年12/8だったのですが、その前後に超体調崩して、せっかくその直前に大仕事終わらせたのに、あえなく欠席して1/11の補講に行きましたが、でもおかげでかなり予習できたので結果オーライだったでしょうかね。

当日の資料はこちら。
https://github.com/perl-entrance-org/workshop-2013-05/blob/master/slide.md

この日はなんだっけ、京王線と中央線がダブル遅延で、13時からの予定だったのが14時から、とかになったんですよね。
でも生徒さんはすごい出席率よくて、けっして小さな会場ではなかったんですが、ピッタシぐらいに埋まってPerlPerl入学式も生徒さんもすごいな、と思ったものでした。

会場のガイアックスさんも素敵な会社で、長時間でしたがゆったり落ち着いて内容に取り組むことができました。関係各位、ありがとうございました。

calc.pl-1

ではさっそく(でもないが)最初の案件。まずは前回の復習ということで、この問題を解きました。

  • 1. calc.pl

2つの数値を引数として, add (+), sub (-), mul (*), div (/), mod (%) といった key に演算結果を代入し, そのハッシュリファレンスを返り値とするような関数 calc を作成してください.

https://github.com/perl-entrance-org/workshop-2013-04/blob/master/practice.md#1-calcpl

これはねえ、これは結構サクッと解けた気がしますね。
自分の回答をマシンから探すのが面倒なのでこのまま考えます・・ポクポクポク・・(古い)
ええ、こんなで!*1

#!/usr/bin/env perl
use strict;
use warnings;
use DDP;

sub calc {
    my ($l, $r) = @_;
    my $result = {
        add => $l + $r,
        sub => $l - $r,
        mul => $l * $r,
        div => $l / $r,
        mod => $l % $r,
    };
}
p calc(3, 5);

実行結果はこのようでした。

\ {
    add   8,
    div   0.6,
    mod   3,
    mul   15,
    sub   -2
}

ちなみに最初、Data::Dumperで出したのですがちょっと見づらかったので@papixさん御用達のDDPを使ってみました。ターミナルで見ると綺麗ですね。

calc.pl-2

続いてこれです。

  • 2. calc.pl

上記で作成した関数における引数が数字であるかどうか正規表現を使って判定するように改良してください.
数値以外が引数であった場合は undef を返すようにしてください.

https://github.com/perl-entrance-org/workshop-2013-04/blob/master/practice.md#2-calcpl

んー、なるほど。この後者の、「undefを返す」というのが今ひとついまだにわかれてないのですが、とりあえず「ERROR!!」とか返すようにする感じにしましょうか。
これも即興で考えます・・ポクポク・・
こんなで!!

#!/usr/bin/env perl
use strict;
use warnings;
use DDP;

sub calc {
    my ($l, $r) = @_;
    unless ($l =~ /-?\d+/ && $r =~ /-?\d+/) {
	print "ERROR!!\n";
    } else {
	my $result = {
            add => $l + $r,
            sub => $l - $r,
            mul => $l * $r,
            div => $l / $r,
            mod => $l % $r,
	};
    }
}
p calc(3, 5);
p calc('z', 5);
p calc(3, 's');
p calc('t', 'i');

はい。*2 で、実行結果!!

\ {
    add   8,
    div   0.6,
    mod   3,
    mul   15,
    sub   -2
}
ERROR!!
1
ERROR!!
1
ERROR!!
1

ん〜〜、なんか、いちおう動いてはいるようですが、後半三つの「ERROR!!」の後の「1」は何なんでしょうかね・・(笑)。また1に悩まされつつありますが・・
ああ、そういえば今回は結構頑張って、papixさんの模範解答をガッツリ記録してきたので、明日はこの続きでpapixさんの模範解答と突き合わせてみる、ということをやりましょう。
たぶんこの「1」はなかったはずだよな・・

food.pl

一旦そのまま、復習問題の最後まで行きます。
というかこの流れでは最後ですが。これ!

  • 3. food.pl
my $data = q{
papix : sushi
moznion : soba
boolfool : sushi
macopy : sushi
};

food.pl では, 上記のように, $data に人物名と好きな食べ物を (スペース):(スペース) 区切りで与えています.
この変数から食べ物が何回出現したかカウントして表示させてください.

  • はじめに $data を改行ごとに split するとよいでしょう
  • 分割後, 正規表現により必要な文字列を抽出してください

https://github.com/perl-entrance-org/workshop-2013-04/blob/master/practice.md#3-foodpl

ああ、これか・・これ結構大変だったんだよな・・余力で出来るかな。
ええと、最初はこれ、ぼく単に「食べ物が何回出現したか」っていうから「4回!」とか出ればいいんだと思って、コロン(:)の数だけ数えるように作ったりしていたんですが、よく考えたらそれはあり得なかったので、ソバが何回、スシが何回、という風に出るように考えたいと思いますが・・

・・あ、思ったよりサクっとできたかも。こんなで?

#!/usr/bin/env perl
use strict;
use warnings;
use DDP;

my $data = q{
papix : sushi
moznion : soba
boolfool : sushi
macopy : sushi
};

my @data = split /\n/, $data;
my %food;
for my $data2 (@data) {
    if ($data2 =~ /^(\w+) : (\w+)$/) {
        $food{$2}++;
    }
}
p %food;

実行結果。

{
    soba    1,
    sushi   3
}

ふむ・・まあ、会場でpapixさんがやったのを見て、なんだハッシュ使うのか・・超意外だ、と思った記憶がまだ残っていたから、かな・・
せっかくなので、ちょっと条件変えてみましょう。
素材データをこのようにしてみます。

my $data = q{
papix : sushi
moznion : soba
boolfool : sushi
macopy : sushi
xtetsuji : curry
ytnobody : ramen
tsucchi : soba
uzulla : sushi
yusukebe : ramen
};

オールスターにしてみました。(すみません)
同じ内容で実行すると・・

{
    curry   1,
    ramen   2,
    soba    2,
    sushi   4
}

ふむ。よさそうですね。

ええと、こうなると何となく、それぞれのフードを選んだ人の名前も格納してみたくなりますね・・どうやればいいんだろ。
・・と、この後しばらく考えたんですが、分からなかったのでマイ宿題にします。

次回は上記設問に対して、Perl入学式内での解答例はどうだったか、ということについて触れたい予定です。
今日はここまで!

*1:ハッシュリファレンス後のセミコロンが抜けていたので、後からちょっと直しました。

*2:上記同様、ハッシュリファレンス後のセミコロンが抜けていたので足しました。挙動にはなぜか関係なかったようですが・・