103

Perl入学式in東京vol.3の復習問題(★5段階評価のやつ)

本来であれば第3回(前々回)が終わってから取り組むたぐいのこの復習問題集。
https://github.com/perl-entrance-org/workshop-2013-03/blob/master/practice.md

かなり歯ごたえがあって何度でもぶつかってみてる。
直近の入学式(in東京#4)の冒頭では、そのうち「score.pl」というのをpapixさんが解いてくれたんだけど、その場ではほとんどついていけず、とりあえずその時のpapixさんのエディタどっかに貼り付けてもらうだけでもいいので解答例UPしてもらおうかな・・と思っていたんだけど、いやちょっと待て、まずは自分でできるだけやってみよう、ということで、5問あるのだけど一旦やってみたら、なんとか全部終わった。
そのすべての回答をどこかにまとめて置いておきたいが、とりあえずその直近の解答タイムでは時間の都合で触れなかった問題がひとつだけあったので、それをここに掲載しておきたい。
対象は「score.pl」の第3問で、
https://github.com/perl-entrance-org/workshop-2013-03/blob/master/practice.md#3-%E4%BA%94%E6%AE%B5%E9%9A%8E%E8%A9%95%E4%BE%A1

ようは以下のようなハッシュリファレンスによる素材データを5人分用いて、

my $papix = {
    name => 'papix',
    affiliation => 'namba.pm',
    perl => 60,
    python => 50,
    ruby => 50,
    php => 80,
    binary => 30,
};
#これで1人分。

言語分野の点数を対象に、それぞれこんなルール&書式で5段階表示せよ、というもの。

0 - 19 =>
20 - 39 => ★
40 - 59 => ★★
60 - 79 => ★★★
80 - 99 => ★★★★
100     => ★★★★★
----
boolfool:
perl: ★★
python:
ruby: ★
php:
binary:

んで、回答ファイルはこんな感じに作った。

#!/usr/bin/env perl

use strict;
use warnings;

#ここからしばらく素材データ。
my $papix = {
    name => 'papix',
    affiliation => 'namba.pm',
    perl => 60,
    python => 50,
    ruby => 50,
    php => 80,
    binary => 30,
};
my $boolfool = {
    name => 'boolfool',
    affiliation => 'namba.pm',
    perl => 40,
    python => 10,
    ruby => 20,
    php => 30,
    binary => 10,
};
my $moznion = {
    name => 'moznion',
    affiliation => 'hachioji.pm',
    perl => 100,
    python => 70,
    ruby => 80,
    php => 50,
    binary => 50,
};
my $binarian = {
    name => 'binarian',
    affiliation => 'hachioji.pm',
    perl => 10,
    python => 11,
    ruby => 1,
    php => 100,
    binary => 100,
};
my $uzulla = {
    name => 'uzulla',
    affiliation => 'hachioji.pm',
    perl => 1,
    python => 0.01,
    ruby => 0.5,
    php => 4,
    binary => 0.01,
};

#ここから回答。
my @people = ($papix, $boolfool, $moznion, $binarian, $uzulla);
my @lang = qw(perl python ruby php binary);

for my $people(@people) {
    print "$people->{name}: \n";
    for my $lang (@lang) {
        my $num = $people->{$lang};
        my $rate;
        if ($num == 100) {
            $rate = "★★★★★\n";
        } elsif ($num <= 99 && $num >= 80) {
            $rate = "★★★★\n";
        } elsif ($num <= 79 && $num >= 60) {
            $rate = "★★★\n";
        } elsif ($num <= 59 && $num >= 40) {
            $rate = "★★\n";
        } elsif ($num <= 39 && $num >= 20) {
            $rate = "★\n";
        } else {
            $rate = "\n";
        }
    print "    $lang: $rate";
    }
}

実行結果はこんな。

papix:
    perl: ★★★
    python: ★★
    ruby: ★★
    php: ★★★★
    binary:boolfool:
    perl: ★★
    python:
    ruby:    php:    binary:
moznion:
    perl: ★★★★★
    python: ★★★
    ruby: ★★★★
    php: ★★
    binary: ★★
binarian:
    perl:
    python:
    ruby:
    php: ★★★★★
    binary: ★★★★★
uzulla:
    perl:
    python:
    ruby:
    php:
    binary:

どうでしょうか・・
じつは最初、全然わからなくてこれ、サブルーチン使わないとできないじゃん・・でもサブルーチン習う前の問題だしなあ・・でもサブルーチン使えばできそう・・って意識の流れを経てサブルーチン使ったので作ったんだけど(それはそれでメチャクチャながら何とかできた)、その辺のgdgdな経緯は別途でまた。

追記: Gistというのに上げてみた。
https://gist.github.com/note103/7241971

追記2: つづく第4問、第5問の回答もUPした。
https://gist.github.com/note103/7253246
https://gist.github.com/note103/7253611

追記3: 5問まとめて回答をGitHubに上げた。
https://github.com/note103/perl_entrance/tree/master/2013_3