sironekotoroの日記

Perl で楽をしたい

Perl入学式 2018 in東京 秋開講 第2回 お疲れ様でした

受講された方、サポーターの方、お疲れ様でした。
講師をやったジャージの人です。

スライド中の練習問題と復習問題ですが、今年春に書いた解答例をblogに掲載しています。
参考にしてください。
あと、一緒に掲載してるアナグラくんのスライドも超いいので見て!
sironekotoro.hateblo.jp

fizzbuzz

今回は18時ギリギリまで引っ張ったものの、20分くらい足りず、以下の練習問題にたどり着けず、すみませんでした。

fizzbuzzはぜひ自宅で自習してチャレンジしてみてください。
fizzbuzzができれば、「2007年のコンピュータサイエンス学科卒業生の過半数」より出来る・・・と言えるので!

1から100までの数をプリントするプログラムを書け。ただし3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」とプリントし、3と5両方の倍数の場合には「FizzBuzz」とプリントすること。

ちゃんとしたプログラマであれば、これを実行するプログラムを2分とかからずに紙に書き出せるはずだ。怖い事実を聞きたい? コンピュータサイエンス学科卒業生の過半数にはそれができないのだ。自称上級プログラマが答えを書くのに10-15分もかかっているのを見たこともある。

どうしてプログラマに・・・プログラムが書けないのか?

重要開示

なお、うちは2007年当時、dankogaiさん(Perlハッカー)のblogでこのfizzbuzz問題に言及があり、そこで知ったクチです。

当時はプログラムを書けませんでしたが、日常使っているExcelのセル内に書けるIF関数で書けるだろう・・・って思ったものです。
そんで書けませんでした。

これはショックな出来事で、IT業界の片隅にいながらこれが出来なかったこと・・・簡単と思った課題に歯が立たなかったことに超絶危機感を覚え、真面目に勉強するきっかけの一つになりました。

そんな人でも、諦めなければ講師ができるくらいにはなります。みなさんやっていきましょう。

用意していたスライド

解説用のスライドを用意していたのですが、時間に余裕がなく活用できませんでした。
ここに掲載して供養しておきます。

docs.google.com

配列の存在意義

スカラー変数だけではたくさんのデータを扱う時に大変ですが、配列にデータを押し込めることで扱いが楽になります。

もし、スカラー変数しか存在しなかったら・・・?

Q.あるクラスには5人の生徒がいます。この生徒たちの体重の平均を出しなさい。

といった問題が出た場合、スカラー変数しかないと以下のようなスクリプトを書くことになります。

use strict;
use warnings;

my $abe     = 68;
my $inoue   = 58;
my $ueshima = 65;
my $edajima = 87;
my $ono     = 72;

my $sum = $abe + $inoue + $ueshima + $edajima + $ono;
print $sum / 5; # 70

5人くらいであれば、手書きでいいかもしれません。
でも、もしクラスの生徒が30人だったら・・・?
あなたが市の教育委員会の人間で、市の小学5年生1000人の体重を求める必要が出て来たら?
あなたが厚生労働省の役人で全国の小学5年生の体重を・・・(大体100万人くらいみたい)

スカラー変数を100万個用意するのは避けたい事態です。

また、合計を間違いなく求めたとして、何人の平均であるか?を求める必要もあります。
「何人で割るか」、正確に出せるでしょうか。
5人くらいであれば・・・(以下ループ

そこで配列の出番です

この課題の場合、「誰が何キロ」である、という情報は実は重要ではありません。 単に平均のみを知りたいので、体重の値そのものだけで良いのです。

Perl入学式第2回の内容にあるものだけで書いてみるとこんな感じです。

先頭部で宣言されている@weightに数値をスペース区切りで追加していくだけで、平均を求めることができます。
楽ですね!
しかも、平均を出すために必要な「何人で割るか」についてもmy $count = scalar @weight;で自動的に算出してくれます。
超楽ですね!

use strict;
use warnings;

# 配列@weightに体重を入れる。
# qwショートカットを利用
my @weight = qw( 68 58 65 87 72 );

# 配列の中にいくつの要素が入っているかを求める
my $count = scalar @weight;

# 合計値を保存するスカラー変数を用意する
# 数字を加算していくので、初期値として0を代入しておく
my $sum = 0;

# for文を利用して、配列@weightの要素を先頭から
# 順に取り出し、$sumに加えていく
for my $w (@weight) {
    # $sum = $sum + $w と同じ意味になる書き方
    $sum += $w;
}

# 平均を求める
my $average = $sum / $count;
print $average;    # 70

世の中はデータと制御構造だらけ

プログラムの勉強を始めると、世の中にたくさんのデータと制御構造が溢れていることに気づくようになります。
例えば銀行で考えてみます。

  • 銀行の口座残高は増えたり減ったりします。変数の増減です。

  • 残高が0未満になる引き下ろしをしようとすると、エラーを出します。これはIF文で実現できます。

  • いつ、いくらの金額を預けたり引き落としした、というデータは時系列で順番に格納されていると思うので(通帳をイメージ)配列のような構造でしょうか。

  • 銀行の口座残高に応じて、ダイレクトメールを発送する、なんとこともあるかもしれません。
    それぞれのレベルの顧客リストを得る時には IF〜elsif〜else 文で数値を比較してるでしょう

    • 預金残高が1億円以上であれば・・・(貧乏なので想像がつかない、外貨預金とか?)
    • 預金残高が1000万円以上であれば、マンション購入の住宅ローンのお知らせを発送するリストに載せる
    • 預金残高が100万円以上であれば、自動車ローンのお知らせを発送するリストに載せる
    • 預金残高が100万円未満であれば、宝くじ発売のお知らせを発送するリストに載せる

身の回りで他の例もいろいろと出てくると思います。

Perl入学式 2018 in東京 秋開講 第2回 ピザ会の課題

恒例となりつつある、ピザ会でのお題です。

時限パスワード貼り付けツールを作ろう!

このピザ回でのお題なのですが、普段自分が書かないプログラムを書くことになり、とても楽しいです。

今回はOSの機能を使うため、PerlからOSの機能を呼び出すsystem関数を使うのですが、これを実用で使ったのは2回目くらいです。
system関数は「初めてのPerl」にも掲載されているので、知ってはいたのですが、知っていることと使えることはまた違うわけです。

なお、「初めてのPerl 第7版」では15章・プロセス管理のところで出てきます。うむ、見た覚えある。

macOSでしか動かない版ですが、自分の作例です。

一定時間だけパスワードをクリップボードに貼り付け、時間が経過すると元の内容に書き戻す君(OSコマンドインジェクション対応) — Bitbucket

注:OSコマンドインジェクションの脆弱性の指摘があったので、12月24日にその部分を修正してます。勉強になる!

Perl入学式 2018 in東京 秋開講 第3回

ピザ会中にも発表がありましたが、2019年1月19日(土)を予定しています。twitter/web/connpassでの開講のお知らせをお待ちください。

次回は以下の3本立てです

  • 配列に要素を加えたり抜いたりする配列操作
  • 配列と似ているけども違うデータ構造「ハッシュ」
  • 初心者殺しのリファレンス

うちもリファレンスに3回くらい殺されてますが、諦めなければ講師ができるくらいにはなりますので、やっていきましょう!

YAPC::Tokyo 1月26日開催!チケットは今日まで!

そして、2019年1月26日は、あの!YAPC::Tokyo 2019が!開催されます!チケット買えるのは本日12月16日いっぱいです!!
なんと年明け2019年1月6日まで伸びてる!やった!

yapcjapan.org

現役のプログラマー/エンジニア達の取り組みを「生の声」で聞ける貴重な機会です。
うちも毎年楽しみで、2013年から参加しています。
当時はまだリファレンスも理解できない状態でしたが、それでも参加して様々な取り組みや技術のことを聞くことができ、とても楽しかったです。
Perlでこんなことができるかも!って可能性の幅が広がる瞬間がたくさんあります。ぜひ参加ください!