Perl初歩の初歩

プログラミング言語Perlの初心者のためのわかりやすい解説ブログ(を目指しています)

print 人間へのメッセージ

2009-05-31 14:53:38 | 命令を覚えよう

Perlでは、print には主に2つの意味があります。
ひとつは画面に表示すること、もうひとつはファイルに書き込むことです。

print "画面に表示します";

open(DAT, ">>test.dat");
print DAT "ファイルに書き込みます";
close(DAT);

いずれの場合も考え方は一緒で、コンピュータの内部で行った結果を、人間が確認できるように、画面上もしくはファイル上へ出力するわけです。

画面に表示するほうの print は、表示したい内容を print の後ろに書きます。

$x = '桜';
$menu{'Aランチ'} = '野菜炒め定食';
print 1 + 2;
print "$xは春に花が咲きます";
print "今日の昼ご飯は$menu{'Aランチ'}です";
print '$xは変数です';
print $x . 'の花は淡いピンクです';

上の例では、「3」「桜は春に花が咲きます」「今日の昼ご飯は野菜炒め定食です」「$xは変数です」「桜の花は淡いピンクです」と表示されます。

print の後ろに計算式があれば、計算した結果を表示します。
" " で囲んだ場合は、変数があればその中身に置き換えて表示します。
' ' で囲んだ場合は、そのまま表示します。
 . で変数とほかの文字とをつなぐことができます。


print <<__HTML__;
<a href="http://www.goo.ne.jp/">goo</a><br>
gooのトップページはこちら<br>
__HTML__

上の例は、print <<__HTML__; の次の行から、 __HTML__ の手前までをそのまま表示します。(ヒアドキュメントという)
__HTML__の部分はアルファベットや数字で自由に変えられます。

print <<goo;
<a href="http://www.goo.ne.jp/">goo</a><br>
gooのトップページはこちら<br>
goo

極端な話、上のようにしても大丈夫です。
print <<goo; のあとに、単独で goo が出てくるところまでを表示してくれるわけです。
ただ、この極端な例ではさすがに紛らわしいので、普通は大文字のアルファベットを用いるのが慣例となっています。
EOF や EOS や _HTML_ などを使う人が多いようです。


ファイルに書き込むほうの print は、また別の機会で。


わかれ道を作ってこそ…条件の話

2009-05-30 12:05:02 | ルールを覚えよう

プログラムが最初から最後まで1本道だったら、いつも同じ答えが出てしまい、応用がききません。
やっぱり、プログラムにはいろいろな場合場合によって、状況を変えるわかれ道が必要で、そうでなくてはなりません。

Perlでわかれ道を作るには次のようにします。

if ($hour == 6) { print "おはようございます"; }

if は もし~なら という英語で、if の後に条件があって、もし条件に合えば、{ } の中を実行し、もし条件に合わなければ、{ } は無視して次に進むようになっています。

上の例では、もし $hour という変数が 6 だった場合のみ、「おはようございます」と表示され、6 以外だった場合は、何も表示されないという意味になります。

== は 数字を比較するときに使う特殊な記号(比較演算子)で、同じかどうかを調べます。

if ($hour != 6) { print "6時ではありません"; }

!= も 数字を比較するときに使う特殊記号で、違うかどうかを調べます。
上の例では、$hour が 6 ではないときに、{ } の中を実行します。

if ($hour < 6) { print "まだ6時になってません"; }
if ($hour > 6) { print "もう6時は過ぎました"; }
if ($hour <= 6) { print "6時か6時前ですね"; }
if ($hour >= 6) { print "6時以降ですね"; }

不等号を使って比較することもできます。


文字を比較するときには別の記号を使います。

if ($shumi eq 'マラソン') { print "何km走れますか?"; }
if ($shumi ne 'マラソン') { print "走るのは嫌いですか?"; }

eq は 文字が同じかどうかを調べます。英語のイコール(equal)を略したんでしょうね。
ne は 文字が違うかどうかを調べます。not equal の略でしょう。


さらに、2つ以上の条件を使うには次のようにします。

if ($hour >= 6 && $hour <= 9) { print "おはようございます"; }
if ($hour <= 4 || $hour >= 18) { print "こんばんは"; }

$hour が 6時から9時の間のときに、「おはようございます」を表示します。
$hour が 4時より前、あるいは 18時以降のときに、「こんばんは」を表示します。

条件と条件の間に && を入れることで、両方の条件を満たすかどうかを、
同様に間に || を入れることで、どちらかの条件を満たすかどうかを調べます。

これらを使って複雑な条件を作ることができます。

if ($hour >= 6 && $hour <= 8 && ($shumi eq 'マラソン' || $shumi eq 'ジョギング')) { print "さあ、朝のランニングに行きましょう"; }

6時から8時の間で、かつ、趣味がマラソンかジョギングのときに表示されます。

このとき、優先度に注意してください。
>= や <= や eq が最優先で、次に && 最後に || という順番があります
上の場合、2番目の && よりも マラソンとジョギングをつなぐ || を優先したいので、( ) でくくっています。

もし、カッコがなかった場合は、
 6時から8時の間でかつ趣味がマラソン、あるいは、趣味がジョギング
という条件になってしまいます。

 


小数の四捨五入と丸め誤差の話

2009-05-29 15:43:59 | テクニックを身につけよう

print int((0.1 + 0.7) * 10);

上の答えはいくつになるでしょうか?
int( ) は カッコ内の数値の整数部分だけを取り出す命令です。

0.1 + 0.7 = 0.8 ですから、それを10倍して 8 となり、その整数部分といっても小数はありませんから、答えは 8 となりそうです。

ところが実際計算してみると、7 と表示されてしまいます。おかしな話です。

これはコンピュータの内部ではデータを2進数で扱っている、ということに原因があります。2進数とは 0 と 1 の2つの数字だけを使って表現する方法。われわれ人間は普通は 0 から 9 までの数字を使いますから 10進数 です。

1 は 2進数では 1 のままですが、2 は 2進数では 10 となります。
3 は 2進数では 11 となり、4 は 2進数では 100 となります。

では、小数はどうなるでしょう。

0.5 が 2進数では 0.1 です。0.25 が 2進数では 0.01 となります。
0.125 は 2進数では 0.001 となり、0.0625 が 2進数では 0.0001 となります。

計算過程は省きますが、10進数の 0.1 は 2進数では 0.0001100110011…という循環小数となってしまいます。0.7 は 2進数では 0.101100110011…という循環小数です。

この2つを足すということは、10進数でいうところの 0.3333… + 0.6666… に似ています。極限まで計算すれば正しい答えが得られますが、コンピュータはある程度の桁数で計算をやめてしまいます。
0.3333… + 0.6666… が 0.9999… となって 1 にならないように、0.1 + 0.7 は 2進数で計算すると、わずかに 0.8 に足りない数字となってしまうのです。
これを「丸め誤差」といいます。

では、どうすればいいのでしょうか。

sprintf(  ) を使って 数値を文字にしてしまう方法があります。

$x = sprintf("%.0f", 1.001);
$y = sprintf("%.0f", 0.999);

上の式は、両方とも 1 という文字になります。

$x = sprintf("%.1f", 1.001);
$y = sprintf("%.1f", 0.999);

上の式は、両方とも 1.0 という文字になります。

したがって、最初の式 int((0.1 + 0.7) * 10) を正しく計算するには、

$x = sprintf("%.0f", (0.1 + 0.7) * 10);
print $x;

とすれば 正しく 8 という答えが出ます。


四捨五入の場合も、この丸め誤差を考慮にいれておく必要があります。

Perlには round関数がありませんので、通常は次のようになります。

$y = int($x * 10 + 0.5) / 10;

小数点以下第2位を四捨五入して、小数点以下1桁に丸めているわけですが、ここでさきほどの「丸め誤差」が出る場合があります。

そこで次のようにします。

$x = 0.34999;
$y = int(sprintf("%.1f", $x * 10 + 0.5)) / 10;

$x の値が実際は 0.35 であるはずなのに、わずかに誤差が出ていると仮定します。
$x * 10 + 0.5 は 3.9999 になります。
それを sprintf( ) で 4.0 にしてその整数部分 4 を 10で割ると、答えは 0.4 になります。

ただし、$x が 0.349 という数値で、それが誤差ではなく正しいものだった場合、上の例ですとうまくいきません。
その場合は、$y = int(sprintf("%.2f", $x * 10 + 0.5)) / 10; と sprintf での桁数を変えます("%.2f" の 2)。
$x に正しい数値 0.3499 がある場合は %.3f にするわけです。


※ もしかしたら 最後にさらに $y = sprintf("%.1f", $y); を加える必要があるかも…?(10で割った数値に誤差が出るから?)


以上の場合は、小数点以下1桁に丸めたわけですが、小数点以下2桁にする場合はこうです。

$y = int(sprintf("%.1f", $x * 100 + 0.5)) / 100;

* 10 や / 10 の部分を * 100 と / 100 にすればいいわけです。


おまけ: モジュール Math::Round というものもあるそうなので、使用できる環境のかたは、これを使ったほうが手っ取り早いかも。


呼べば応える名前付き配列…連想配列の話

2009-05-25 21:40:52 | ルールを覚えよう

スカラー変数($)と配列(@)について説明してきましたが、今度は名前付きの配列とも言うべき、「連想配列」の話です。別名「ハッシュ」とも言います。

連想配列は、名前(キー)と値の組み合わせを覚えてくれる入れ物です。

%menu = ('今日のオススメ' => 'サバのミソ煮', 'Aランチ' => '野菜炒め定食');
$menu{'Bランチ'} = '豚のしょうが焼定食';
$menu{'スペシャル'} = '幕の内定食';

上の例では、まず、%menu という連想配列に、今日のオススメ という名前の サバのミソ煮 と、Aランチ という名前の 野菜炒め定食 を入れています。
次に、Bランチ という名前の 豚のしょうが焼定食 と、スペシャル という名前の 幕の内定食 を %menu に追加しています。

連想配列の全体をあらわす時は、頭に % をつけます。
また、連想配列に入っている1つ1つのデータをあらわす時は、$ と { } を使います。

$x = '今日のオススメ';
$y = 'Aランチ';
print $menu{$x};
print $menu{$y};

上記のように、$x に 今日のオススメ、$y に Aランチ が入っている場合、
$menu{$x} は、サバのミソ煮 になりますし、$menu{$y} は、野菜炒め定食 です。

%youbi = ('Sun' => '日曜日', 'Mon' => '月曜日', 'Tue' => '火曜日');
%youbi = ('Sun', '日曜日', 'Mon', '月曜日', 'Tue', '火曜日');
%youbi = qw(Sun 日曜日 Mon 月曜日 Tue 火曜日);

上の3つはすべて同じです。
データを連想配列にまとめて入れる時には、通常見やすいように => で、名前と値の組み合わせを表現しますが、単に , カンマ で区切るだけでも構いません。
カッコの前に qw をつけて、 ' や , を省略することもできちゃいます。


データを並べて入れておく箱…配列の話

2009-05-18 14:36:22 | ルールを覚えよう

Perlの変数には3種類ある、というのは以前のページで説明しました。
ここでは、そのうちのひとつ「配列」についてのお話です。

配列は、数値や文字などを順番に並べて置いておく入れ物です。

@kamoku = ('国語', '算数', '理科', '社会');
@channel = (1, 3, 4, 6, 8, 10, 12);
@list = ($x, $y, $z);
@iroiro = ('国語', 3, $x, "$y点です");
@month = (1..12);
@kara = ();

上の例では、
@kamoku には、国語、算数、理科、社会の順に文字が入ります。
@channel には、1 3 4 6 8 10 12 の順に数字が入ります。
@list には、$x と $y と $z の中に入ってるデータが順に入ります。
@iroiro のようにデータを入れることができます。
@month には、1 から 12 までの12個の整数が順に入ります。
@kara は 配列の中身を空っぽにしています。

配列にデータを入れる時には、( )で囲み、それぞれを , で区切ります。
@month の .. は特殊な表現で、数字が1つずつ増えていくことを表します。

@kamoku = ('国語', '算数', '理科', '社会');
$n = @kamoku;
$x = $kamoku[0];
$y = $kamoku[2];
push(@kamoku, '英語');
$n = @kamoku;

上の例では、最初に @kamoku に4教科を入れます。
次に、$n に @kamoku の中に入っているデータの個数(要素数)を入れます。この場合は $n には 4 が入ります。
$x には @kamoku の中の 0 番目のデータが入ります。この場合は「国語」。
$y には @kamoku の中の 2 番目のデータが入ります。この場合は「理科」。
配列の順番は 0 から始まります。
$配列名[番号] の形で、配列の中の1つを取り出すことができます。

push(配列, データ) は 配列の最後にデータを加える命令です。
@kamoku の「社会」の後ろに「英語」を加えています。

最後にもう一度要素数を数えます。
ひとつ前に「英語」が加わっていますので、$n には 5 が入ります。

@month = (1..12);
@tuki = ();
foreach my $m (@month) {
  push(@tuki, "$m月");
}

配列 と foreach とは、切っても切り離せない関係です。
上の例では、1 から 12 の数字を、ひとつずつ順番に $m に入れ、それぞれに「月」を加えた文字を、@tuki に入れています。
@tuki には、「1月」から「12月」までの文字が入ります。


おまけ:
配列にデータを入れるときに、カンマで区切ったり ' をつけるのが面倒なことがあります。そんなときに重宝するのが qw( ) です。

@kamoku = ('国語', '算数', '理科', '社会');
@kamoku = qw(国語 算数 理科 社会);

上の2行ともまったく同じ意味です。
qw を カッコの前につけると、カッコ内の文字は スペース で区切っていることになるのです。すっきりするでしょ?


数字や文字などを1つだけ入れる器…スカラー変数

2009-05-04 14:07:14 | ルールを覚えよう

Perlの変数には3種類ある、というのは前のページで説明しました。
ここでは、そのうちのひとつ「スカラー変数」についてのお話です。

スカラー変数は $a $x $abc $osara $date など、頭に $ をつけてあらわして、数字や文字などの情報を入れておく入れ物です。

スカラー変数に情報を入れるには、スカラー変数に続いて = を書き、そのあとに入れたい数字や数式や文字などを書きます。

$a = 1;
$y = $x * 10;
$abc = 'ABCDEFG';
$osara = '肉じゃが';
$date = "$year年$month月$day日";

上の例では、

$a に 1 を入れる
$y に $x を 10倍したものを入れる
$abc に ABCDEFG という文字を入れる
$osara に 肉じゃが という文字を入れる
$date に $year $month $day の中に入っているものを 年月日の文字とともに入れる

という意味になります。

文字を入れる場合には、' または " で囲む必要があります。
' で囲んだ場合にはそのまま、" で囲んだ場合は変数の中身が入ります。

たとえば

$nedan = 980;
$price1 = '$nedan';
$price2 = "$nedan";

とした場合、$price1 と $price2 には別のものが入ります。
$price1 は ' で囲んでありますので、そのまま $nedan という文字が入ります。
$price2 は " で囲んでありますので、980 という文字が入ります。

スカラー変数では、数字と文字を区別しません。

$x = '001234';
$y = $x * 10;
print $y;

上の例では、最初に $x に 001234 という文字を入れています。
しかし、次の行でその文字を10倍にしています。
$y には 12340 が入ります。
$x に入っている 001234 を 1234 という数字とみなして計算しているわけです。
ただし、 $x 自体は変化せずに 001234 のままです。

では、次の場合はどうなるでしょうか。

$x = 'abc';
$y = $x * 10;
print $y;

$x には abc という文字が入ります。
しかし、次の行でその文字を10倍にしています。
abc を無理やり数字とみなした場合 0 となります。
したがって、$y は 0 です。

スカラー変数には、文字や数字のほかに、他の変数やサブルーチンも入れることができます。
しかし、ここは初心者のためのページなので、そのことについては別の機会で。


プログラムはテキストエディタに書く

2009-05-03 14:23:23 | 目次・はじめに

 Perlに限らず多くのプログラムは、アルファベットを中心とした文字で書きます。
 パソコンで文字を打ってそれを保存する方法は、Windowsの場合は標準で「メモ帳」や「ワードパッド」などが付属していますし(スタート→プログラム→アクセサリ)、仕事などで書類を作る時には Microsoft Office の Word(ワード)を使う人もいるでしょう。
 とはいえ、プログラムを書くときには、文字を太くしたり色をつけたり、あるいは、罫線を書いたり画像を挿入したりする機能はまったくの不必要ですから、Word や ワードパッドでは無駄な機能が多すぎて使いずらいですし、メモ帳では逆にシンプルすぎて使い物になりません。

 そこでプログラマーは、プログラム作成に向いているテキストエディタを使うことになります。
 Windows用のソフトとして以下のようなものがあります。

EmEditor(有料)
http://jp.emeditor.com/

秀丸エディタ(有料)
http://hide.maruo.co.jp/software/hidemaru.html

TeraPad(無料)
http://www5f.biglobe.ne.jp/~t-susumu/library/tpad.html

 このほかにもさまざまなテキストエディタがありますので、自分の好みのものに出会えるといいですね。
 ちなみに、筆者は秀丸エディタを使っています。


foreach コツコツとしらみつぶしに

2009-05-02 12:09:40 | 命令を覚えよう

foreach は 配列に入っているデータを順番に1個ずつ取り出したいときに使います。

@obento = ("ご飯", "タコさんウインナー", "お漬け物");
foreach my $ryouri (@obento) {
  print "$ryori\n";
}

まず、@obento の中に 「ご飯」と「タコさんウインナー」と「お漬け物」を入れます。
次に foreach (フォーイーチ) を使って、@obento の中から一品ずつ料理を取り出して、表示させています。

表示結果は、

ご飯
タコさんウインナー
お漬け物

となります。

foreach my $ryouri (@obento) の部分で、@obento から順番にひとつずつ取り出して、$ryori に入れています。

my は変数の前につけて、「この変数はここでしか使わない変数です」ということを主張しています。この場合は、「$ryori という変数は、このforeachの中だけでしか使わない変数」という意味で、もしここ以外の場所で $ryori を使っていた場合は、別の変数として扱われます。
考えだすと難しいので、foreach my $~~ (@~~) {  } をセットで覚えてしまいましょう。

 


Perlを自分のパソコンにインストールしてみよう

2009-05-01 17:40:51 | 目次・はじめに

 これからPerlを覚えようとしている人の多くは、WindowsやMacのパソコンを使っていると思います。今のままではPerlのコードを書いても、実行することができませんので、あなたのお使いのパソコンにPerlをインストールする必要があります。
 Perlはありがたいことに無料のソフトですから、気軽にインストールしてプログラミング体験してみてください。

 ここでは、Windowsパソコンにインストールして実行する方法を書きます。
 というのは、筆者がWindowsパソコンしか使ったことがないからです。

 Windows用のPerlは ActivePerl (アクティブパール) という名前がついています。
 http://www.activestate.com/activeperl/

  1. 「DOWNLOAD NOW」をクリック
  2. ファイルのダウンロード:「実行」をクリック
  3. セットアップ:「Next」をクリック
  4. 規約への合意:「I accept the terms in the License Agreement」を選択して「Next」をクリック
  5. インストール先:「Next」をクリック
  6. オプション:「Next」をクリック
  7. インストール:「Install」をクリック
  8. インストールの完了: Display the release notes のチェックを外して「Finish」をクリック

 以上でインストールは終了です。

 ちゃんとインストールできているかどうかを確認するには、
「スタート」→「すべてのプログラム」→「アクセサリ」→「コマンドプロンプト」を起動して、「perl -v」と打ってEnterキーを押して、バージョン情報が表示されれば成功です。

 ためしに、「perl -e "print 1+2"」と打ってみましょう。
 3 と表示されましたか? Perlが 1+2 を計算して表示してくれました。
  → 1+2 の部分をいろいろ変えて、Perlに計算させてみよう。

 今後のために、Perl専用のフォルダを1個作っておきましょう。
  →フォルダ名は漢字やひらがなやカタカナはやめて、アルファベットにしておいたほうがいいでしょう。

 Perlが実行しやすいように、デスクトップにコマンドプロンプトのショートカットを作っておきましょう。
 「スタート」→「すべてのプログラム」→「アクセサリ」で コマンドプロンプト を右クリックして、「送る」→「デスクトップ」でショートカットを作成後、デスクトップにできたコマンドプロンプトのアイコンを右クリックしてプロパティを表示し、作業フォルダの欄を、さっき作ったフォルダへのパスをいれておきます。
  例) C:\Users\HANAKO\perl\

 これで、Perlを使うときには、デスクトップにできたアイコンをダブルクリックして、コマンドプロンプトを表示させます。そしてその画面で、「perl」+半角スペース+ファイル名 と入力しEnterキーを押すことで、自分で作ったperlのプログラムを実行できるようになります。