sironekotoroの日記

Perl で楽をしたい

YAPC::Tokyo 2019 に参加してきた

前回のYAPC::Okinawa 2019 Onnnasonからずっと楽しみにしてた東京での開催。

yapcjapan.org

うちが見たセッションの裏番組も気になるセッションで、毎回自分が分裂するかYoutube録画が欲しいと思います。

エンジニアリング組織論への招待

超よかった。ゲストトークとのことでベストトーク対象には無かったけど、あったら1票入れてたなぁ。
例として上がる「取引コストの高い組織」がまさに今いる自分のところであり、前のめりで聞いておりました。

これはスライド中の

システムは時間を経ると次第に交換できなくなり、コントロールを喪失する

を見てのツイート。
うちのクライアント、うちのいるグループについてのコントロールを喪失しており、うちらの言われるがままにするしかなく・・・しかも、うちらが知見も経験も技術も独占してるよなぁ・・・ってことを思いながらのツイートでした。

広木さんの本もオススメです。 gihyo.jp

YAPC座談会

2016年、札幌でのリブートから大阪、博多、沖縄と開催されてきたYAPC::Japanの実行委員長さんたちの座談会。

同じYAPCでありつつも、各地域ごとに課題や特色や狙いがあり、そんで楽しんでもらおう!的なホスピタリティ精神溢れる話ばっかで、すごいよかったです。

ランチセッション

SBX Technologies 深澤さん

深澤さんが勤める「SBX Tech」のプロダクト、Garuda(ガルーダ)の紹介。
入力された情報に応じて最適なsolverを提案し、その解をさらに別のsolverに渡して望む解を求めて行く、というようなシステム(うちの理解力ではこの辺りが限界
あとのそのsolverはPerlはじめ、様々な言語で記述が可能(Garudaで利用する形式のラッパーで包む必要はある)。

デモでは細胞の情報をインプットし、細胞内の酵素の構成図(オブジェクト図みたいだった)、その酵素に薬物を投与した時の反応をグラフで表示、というのをポンポンポンと進めていく様を実演。
大学・企業での導入もされており、あぁ、こうやって研究が進められていってるんだなぁってのを垣間見ることができました。

mixi 萩原さん

speakerdeck.com

お若いのに堂々とした話ぶりと落ち着きぶり。相当練習したんか、学生時代通してそういう経験積んできたのか、立派でした。
萩原さんが関わっているminimoはmojoliciousで動いているってことで、Perl入学式でもそのことは伝えていきます。
自分たちが学んでいるフレームワークが実世界で稼働してるよ!ってのはモチベーション高くなると思うんですよね。

LTで紹介される

id:xtetsujiさんの「2018年のPerl入学式報告」で紹介していただきました。

というわけで、2月から新しい会社に勤めます。

懇親会・二次会

深澤さんに改めて「すぐわかるオブジェクト指向Perl」についてのお礼(出版してくれてありがとうございます!的な)を伝えました。
この本は「自分が欲しかったけど無かったから書いた」というようなことを話していて、あ、さっきtokuhiromさんのキーノートでも同じことを言っていたなぁ、と思うなどしました。

他、ここしばらく姿を見せてない、精神的なPerl恩師の方の消息を聞いて回るなどしておりました。

報恩謝徳・恩送りしていく

Perlという言語からもPerlコミュニティからもたくさん色々なもの(環境や知識とか)をいただいているという実感はあるので、次の世代や他の人にもそういうものを伝えていきます。

次回

次回は未定とのことですが、懇親会中にどっからから「京都!」って声が聞こえてきた気もするんですが気のせいかもしれない。

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

Perl入学式 in 東京では各回の講義終了後にピザ会(ピザ&ジュース代は参加者負担)を開催しており、そこで受講者さんと雑談などをしております。
その中で、id:xtetsuji さんから課題が出てそれをコードで解決する、という試みを行っています。

今回のお題:Googleトレンドを非公式APIから取得し、各日のランキングをとり、前日と順位の変動があればそれが分かるようにする

というもの・・・だった気がします(曖昧
しかし、うちの実力不足で当日できたのは

  • 非公式APIから特定の日のデータを取得する
  • JSON形式のデータをPerlのデータ構造(リファレンス)に変換する
  • 関連する記事のタイトルを表示する(!?)

まででした。

最後の「関連する記事のタイトルを表示する(!?)」なんですが、当時は完全に勘違いしており、検索語を取ることができませんでした。
結果、無念のタイムアップとなったのでした。

作ってみたが・・・

2019年01月01日〜18日までで、連続した日に現れる検索ワードは「純烈」が2019年01月10日と翌2019年01月11日・・・のみ!

これは、完全に同じ単語が連続した日に現れた場合、という条件でしか抽出できなかったのが原因。 例えば、正月なので箱根駅伝についての話題は当然出てきていますが、

と、検索ワードとしては同一ではないので、別の検索語と判断してしまったわけです。

これらの語を「同じ意味をもつ語」として、「箱根駅伝」が3日連続して検索語に登場した、と判断するには文字列を分解して他の検索語とのマッチ率を見て同一の話題の単語か?を判断する
・・・って工程が必要になるんかなぁ?
ちょっと今の自分にはハードル高そうです・・・

Googleトレンドを非公式APIから取得し、各日のランキングをとり、以前に出現してたらその日と順位も表示する

このままでは悔しいので、同じ検索ワードが過去にランキング入りした場合、前回登場した日付と順位を表示する、ということにしてみます。

例えば同じ検索ワードが連続していない日に出てくることがあります。

  • 錦織圭
    • 2019年01月05日 5位
    • 2019年01月15日 5位
    • 2019年01月17日 5位
  • 地震
    • 2019年01月03日 1位
    • 2019年01月08日 4位
    • 2019年01月14日 4位
    • 2019年01月18日 3位

こういったデータの場合、例えば 01月08日に

04 地震 [前回出現:2019年01月03日 1位]

といったような表示が出るようにしてみました。

bitbucket.org

一応、プログラム本文にコメントをいっぱい書いてみたんですが、これ、うち自身も3ヶ月後に見て「何言ってるんだこの人・・・」ってなるパターンな気がします。
うわ、わたしのコメント力低すぎ・・・?

ちょっとだけ解説

時系列順に表示するだけであれば、日付をkeyとして、valueには順位順に検索ワードを格納した配列リファレンスを入れるデータ構造でいけます。
my %date_query; # date をkeyとするデータ構造 です。

20181231 => [ '紅白歌合戦 2018' ,  'メイウェザー' , '米津玄師' ,  '紅白' ... ];
20190101 => [ '箱根駅伝' ,  'MHPS' , 'マリウス' ,  '2019年運勢' ... ];

しかし、このデータ構造だけでは、検索ワードが過去のいつ出現したかを調べるときに大変です。

  • 1日前のハッシュkeyを把握する
  • valueデリファレンスし、検索ワードが配列リファレンスに格納されているかを調べる
  • 1日前で見つからなければ、さらに前日に遡り調べる

これを繰り返すのは厳しいです。100日とか計算するとして、100日目の検索ワードが1日目に出現していた場合、過去99日遡って探すことになります。
すぐ見つかれば良いですが、見つからなかったら・・・?
計算量も多そう。

ということで、検索語そのものをkeyとするデータ構造を作ります。
valueには2つのリファレンスを入れます。

  • 日付をkey、その日付の順位(ranking)と何回目の出現か(count)を格納したハッシュリファレンス
  • 文字列 history をkey、検索ワードが登場した日時を格納した配列リファレンス

さらに、history という文字列をkeyとしてvalueに配列リファレンスを格納。
この配列リファレンスに1つ以上の要素がある場合には、過去複数回出現している判断。
末尾から2番目にある要素を直前の出現日付として last_time に記録します。

my %query_date; # query をkeyとするデータ構造

"純烈" => {
           'history' => [
                          20190110,
                          20190111
                        ],
           '20190110' => {
                           'ranking' => 0,
                           'count' => 1
                         },
           '20190111' => {
                           'count' => 2,
                           'last_time' => 20190110,
                           'ranking' => 1
                         },

これにより、検索ワードと日付をkeyとして last_time があればそれが前回の出現日という処理をしています。

1つのデータ構造では難しいなぁ、と思ったら同じデータが入っていてもkeyを変えた構造のデータを作ってみるという感じです。
うちが最近勉強しているSQLだと同じレコードに別名をつけて副問い合わせをする、みたいな感じですかね。

もっと実装力やデータ構造力が高ければ、もっと簡単になりそうな気がするんですが、気がするだけでその具体的な道筋が見えない・・・ってのが今のうちの現在地です。
頑張ろう。

※第4回でやる「サブルーチン」を導入すると、コードの見栄えがもう少しスッキリするはず。

おまけ

このゲーム、1回遊ぶのに500円かかり、もらえる額はサイコロの目の数 × 100 なので、5 か 6 を出さないとペイしない。
サイコロを振って 5 か 6 が出る確率は 1/3なので、ボーナス抜きでは普通に負ける。

で、ボーナスが出る確率は

  • 1が3回連続で出る: 1/6 × 1/6 × 1/6 = 1/216
  • 4,5,6のいずれかが3回連続で出る: 3/6 × 3/6 × 3/6 = 27/216 = 1/8

うーん、具体的な計算してないけど、負け(2/3)を覆せるだけの確率ではなさそうだなぁ

bitbucket.org

試行回数: 10000
ボーナス回数: 440
最終損益: -700700

追記

サイコロの6の目がでないよー、との指摘をいただき、修正したら勝率が変わった!
(bitbucketにあげたコードは修正済みです)

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

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

スライド中の練習問題と復習問題ですが、昨年夏に書いた解答例をblogに掲載しています。
参考にしてください。
sironekotoro.hateblo.jp

あと、時々つかったスライドも置いておきます。

docs.google.com

リファレンスは難しい

リファレンス、自分も苦労した覚えがあります。というか、リファレンスがあると何が便利になるのか?何が良くなるのか?が、まずわからなかった。
自分が複雑なデータ構造を扱うことはないと思ってました。
「すっぱいブドウ」の話ではないですが、リファレンス使わなくてもいいもんね!と思っていたものです。
その時は斜に構えたままでしたが、Perlに慣れ、自分がしたいことを実現するためにはリファレンス使えばいけそう!となってから一気に理解が進みました。

リファレンスは教えるのも難しい

リファレンス、Perl入学式の現在のテキストでは、「リファレンスじゃないとできないことがある」「便利だから使う」ってな感じで進めています。

そんな中、毎回試行錯誤、苦労しながら捻り出しているのがリファレンスの「たとえ」です。
「変数が格納されているメモリのアドレス」という説明でわかる人はそれで良いのですが、「メモリのアドレス」でわかる初心者さんがどれほどいるのか。
C言語のポインタのようなもの」といっても、C言語もポインタも知らなければ伝えられません。

※ そもそも、うち自身がC言語は名前だけ、ポインタも「Perlのリファレンスみたいなやつ?」って程度の理解です。

ということで、今回は「雑多な人間の属性と値(ハッシュ)が GPS を通すことで1つの座標(緯度経度)に定まるように、配列やハッシュをリファレンスにすることで一つのスカラーとして扱うことができる」という言い方とスライドを用意しました。

f:id:sironekotoro:20190124123242p:plain
雑多な人間の属性と値(ハッシュ)がGPSを通すことで1つの座標(スカラー)になる

f:id:sironekotoro:20190124123241p:plain
ハッシュをリファレンス化することで1つのスカラーになる

もし、リファレンスについて良い言い回しや、こういう例えはどうだろう?ってのがあれば是非教えてください。

オススメ参考書

以前のエントリでも書きましたが、深澤千尋さんの「すぐわかるオブジェクト指向Perl」これがいいです。

gihyo.jp

タイトルにはないですが、この本の半分程度がPerlのリファレンスについての説明に当てられています。
これは、Perlオブジェクト指向はハッシュリファレンスを利用するためなのですが、微に入り細に入り、噛み砕いて説明してくれている良い本です。

そして、なんとその著者の深澤さんがくるPerlのイベント「YAPC::Tokyo 2019」が今週末に開催です。
様々なPerlやシステムについてのセッションが多数行われるイベントです。是非参加ください!

yapcjapan.org

yukicoder

yukicoder.me

講義の後のピザ会で紹介したyukicoderです。うちもサポーターのmotiさんから教えてもらいました。

競技プログラミングアルゴリズムを 練習する目的で運営されています。

とのことですが、★1つのレベルの問題であれば、Perl入学式第1回〜第3回の内容で解けるものもあります。
例えば

No.56 消費税

この問題は

  • 標準入力
  • スカラー変数
  • 改行の削除
  • 文字列の分割
  • 配列(リスト)
  • 四則演算
  • 標準出力

で解くことが可能です。

まずは下記の初心者向けチュートリアルから始めてみてください。

yukicoder.me

Perl入学式の課題で物足りない、とか、プログラムで問題を解くことを習慣にしたい、という方にもオススメです。

Googleトレンドの非公式APIから情報を取ってきていい感じにする

恒例、ピザ回のお題です。別エントリであげます。

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でこんなことができるかも!って可能性の幅が広がる瞬間がたくさんあります。ぜひ参加ください!

吉祥寺pm #16 で登壇して来た

初登壇でした。

docs.google.com

5分の時間をいただいたんですが、オーバーしてしまいました・・・すみません
Googleスライドのツールでちゃんと発表者側に経過時間が表示されていたのですが、緊張して全く時間を見ることができなかったですね・・・

補足

Linuxの勉強はどうやったの?

  • 基本的なところはLPIC
    • なにから始めればいいか分からなかったので、とりあえず体系的な知識を得るため
    • 当時は会社の補助なかった
  • 各自で初心者本買ったりVPS借りて色々やる
  • 検証機を提供してもらい、素人が存分に実験

CSがシステム(Linux)触って問題はなかったか?

  • たくさんあった
    • 箇条書きで書きだしたものの、表に出して良いネタかどうかわからないので消す

問題はどうやって回避したの?

  • ターミナルソフトのマクロ機能を使い、定型処理を簡易化した
  • エンジニアさんに頼み、フールプルーフな仕組みを作ってもらった
  • ファイル編集時のフローを整備した

主にどんなコマンド使うの?

  • ping, traceroute, dig
  • wget
  • tcpdump
  • top, sar
  • cat, tail, grep
  • vi(で設定ファイルの編集
  • 複雑なコマンドはマクロとして登録

発表

マミーさんのお話、登壇へのハードルを下げてくれる内容で良かった。
カラオケボックス借りて一人登壇発表練習」ってのはいいなぁ、と。

speakerdeck.com

あと、エンジニアさんが古代の会社に行ったという話が良かった・・・。

speakerdeck.com

SIerが旅館に勤めてその旅館がすごくなった、ってな話を思い出しました。

www.itmedia.co.jp

まさかのRPGツクールを使っての起業プロセスの発表、ああいう方法もあるのか!と

つっちーさんのプロキシサーバをPerlで作るというお話。
うちだったら、Squid立てて設定して、それでおしまいにするところを、Perlでやってみるという方法があるのか!と当たり前のことに衝撃

github.com

ほんと、吉祥寺pm面白かったです。

Perl入学式 2018 in東京 秋開講 第1回 落穂ひろい

msys2・ターミナル(黒い画面)編

スライドの入力例の先頭にある $ マーク

この $ は一般ユーザー権限でコマンド入力待ちになっていることを示すものです。
UNIXLinuxには権限といった考え方があり、一般ユーザーとスーパーユーザー(管理者,root)とで実行できるコマンドに差があります。
書籍やスライドにある先頭の $ は入力する必要はないです(というか、手元のターミナルに既に表示されているはず

スーパーユーザーの場合には、先頭に # と表示されます。

whoamiはユーザー名を表示するコマンド、su -は一般ユーザーから管理者ユーザーになる時のコマンドです。
先頭の $# に変わっています。

f:id:sironekotoro:20181104141155g:plain

以前に入力したコマンドをもう一度使いたい

キーボードの キーを押すことで、過去に入力したコマンドが出てきます。

長いファイル名を入力するのが大変

キーボードの TAB キーを押すことで、ファイル名が補完されます。

長いファイル名のファイルを作成し、それを削除する時に先頭のファイル名先頭の a のみを入力してTABキーでそれ以降を保管しています。

f:id:sironekotoro:20181104135513g:plain

ターミナルの画面が入力した文字や、実行結果で埋まってきた・・・

clear コマンドで画面がきれいになります。

CUIは寡黙

コマンドが成功した場合には特に応答を返さないことが多いです。
エラー時にはエラーメッセージを表示します。

OSの歴史編

プログラミング言語の系統図

www.levenez.com

Plotter ってのをクリックすると一枚のPDFで表示されます。重いので注意。
Perlは1987年に誕生しています。

書籍だと、この本が簡潔にまとまってて良いです。もちろんPerlも載ってます!

www.socym.co.jp

詳説! Hello world

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

print "Hello world!";

1行目:#!/usr/bin/env perl

いきなりわかんないですよね・・・ということで定番書籍にご登場願います。

#!/usr/bin/perl
(中略)

Unixシステムでは、テキストファイルの最初の2文字が #!shebang:シバンまたはシェバンと発音します)だったら、その後ろに続くものが、ファイルの残りの部分を実際に実行するプログラムの名前になります。このケースでは、そのプログラムは usr/bin/perl に格納されています。

はじめてのPerl 第7版 電子版 14p

この上記の例だと、「このファイルは /usr/bin/perl で実行してくださいねー」とシステム(Unix)に伝える行、と思ってください。

ですので、この行を適当に書き換えると、Unixはどのプログラムで実行して良いか分からず、エラーになったり異なる応答をします。
macOSで実行してみました。

  • 1行目を存在しないプログラム名(SuperDuperMiracleLanguage)にした場合
    #!/usr/bin/SuperDuperMiracleLanguage
  $ perl hello.pl  
  Can't exec SuperDuperMiracleLanguage at hello.pl line 1.

そんなプログラム無いから実行できないよ、とエラーが出ます。

  • 1行目を別のプログラム言語にした場合 #!/usr/bin/ruby
  $ perl hello.pl  
  hello.pl:2:in `<main>': undefined local variable or method `strict' for main:Object   (NameError)

rubyとしてファイルを実行したけど、rubyが2行目の use strict の解釈でエラー、と出ます。

では/usr/bin/env perl って?

再度定番書籍にご登場願います。

Unixシステムの中には、 #! 行に次のように書くと、perlを探してくれるものもあります。

#! /usr/bin/env perl

はじめてのPerl 第7版 電子版 14p

ということで、Unix環境の中からPerlを探してくれることを期待して書く行なのでした。

2行目:use strict;

厳密な書式を定めたり, 未定義の変数を警告するといった効果があります

変数については第2回でやるので、そこで説明します。

3行目:use warnings;

望ましくない記述を警告してくれる効果があります。

例えば、use warnings の無い、このようなプログラムで実験してみます。

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

print;

実行します。

$ perl hello.pl
$ 

エラーは出ません。
print 文ですが、なにをprint、表示するのかの指定が無いプログラムです。

しかし、これは正しいprint文でしょうか?何も表示しないなら、不要な行なのでは?

こういったあやしい記述を警告してくれるのが use warnings です。

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

print;

実行します。

$ perl hello.pl
Use of uninitialized value $_ in print at hello.pl line 5.

エラーが出ます。
エラーの内容は「未定義の暗黙の変数使ったな!」ってやつなのですが、「エラーが出たんでどっか直さないとダメなんだな」くらいでokです。

4行目:(空白行)

Perlでは空白文字であるスペースやタブは無視されます。
そのため、これらの空白文字を使ってプログラムを読みやすくすることができます。

5行目:print "Hello world"

・・・古来、というか1989年の「プログラミング言語C 第2版(訳書訂正版)によるとこうです。

https://pbs.twimg.com/media/DrID3ibUcAAWXbK.jpg

ちなみに、すごい驚いたんですが、Perlちょっとやってると、Cのプログラムが読めます。書けないけど。びっくり。

練習問題(1), 練習問題(2)

TMTOWTDIのモットー通り、いろいろな書き方があります。

  • 普通の書き方
print "Perl-Entrance\n";
print "2018/10/27\n";
print "Gotanda\n";
print "Tokyo\n";
  • 1行で書いてみる
print "Perl-Entrance\n2018/10/27\nGotanda\nTokyo\n";
  • 偏屈な書き方
print "Per";
print "l-Entrance\n20";
print "18/10/27\nGot";
print "anda\nTokyo\n";

上記3つとも同じ出力になります。

  • 練習問題(2)の引き算
print 2018 - 1987;
  • 練習問題(1)と練習問題(2)の引き算も含めて1行で・・・ってのは第1回の範囲では無理かなー?
    第2回でやる文字列連結演算子 . (ドット) と計算部分をカッコで囲む方法を使います。
print "Perl-Entrance\n2018/10/27\nGotanda\nTokyo\n" . (2018 - 1987) . "\n";

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

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

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

今期からの新要素は以下となります。

  • Windowsユーザ向けにmsys2でUNIX環境を構築し、その上でPerlを実行
  • スライド共有

不慣れなところが多く、お手数をおかけしました。

今回ですが、Perlの学習内容としては print "Hello! World"; のみなので特に復習問題はないです。
また来月お会いしましょう!

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

Perl入学式 in東京 では講義終了後、希望者で集まりピザ会と称した懇親会を行っています。
(ジュース・ピザ代は実費)
昨年からそこで余興として xtetsuji さんが課題を出し、そこにチャレンジャーが回答して公開する、というようなことをやってます。

今回の出題は、シミュレーションでした。
過去の出題傾向からてっきりWebからスクレイピングってネタが来ると思ってたので完全に不意打ち。

ルール

  • プレイヤーA、プレイヤーBに手札が3枚配られる
    • 今回は配られる手札は固定
    • プレイヤーA:1, 5, 10
    • プレイヤーB:2, 2, 2
  • 1 〜 40 の目がランダムに出るルーレットを3回まわし、手札と同じ数字が出たら手札を捨てる
  • プレイヤーBのように同じ手札が複数枚ある場合には、同じ目が出ても捨てられるカードは1枚だけ
  • 先にカードがなくなった方が勝ち

ヒント

  • 1 〜 40 のランダムな数字を出すには int( rand(40) + 1 ) を使う

うちの予想

  • 3枚のカードが来て、ルーレットも3回まわすんだから、プレイヤーAもプレイヤーBも勝率は同じなのではないか?

コード

ピザ会で書いたものを少し改変して、コメントを入れてアップしています。

Perl入学式でやる範囲の内容のみ、かつリファレンスを使わない、という縛りで書いてみました。
結果、めっちゃ煩雑になりましたわ・・・

Perl入学式 2018 in東京 秋開講 第1回 ピザ会でのお題 — Bitbucket

なお、コードを実行すると勝利回数は6〜7倍プレイヤー1の方が高いですが、これは確率的に正しいとのこと。
うちはサイコロに置き換えて考えて納得した気になってるけど、正しいかどうか不安・・・

サイコロに置き換えると

  • プレイヤーAの手札(1, 3, 5)
    • 出た目が 1, 3, 5 どれかに合致すれば札を捨てられる
      • 最初に 1 が来ても 3 が来ても 5 が来ても手札を捨てることができる
    • 3/6 * 2/6 * 1/6 = 6/216
  • プレイヤーBの手札(2, 2, 2)
    • 3回とも同じ目が出なくてはいけない
    • 1/6 * 1/6 * 1/6 = 1/216

これで約6倍の差、って言ってたのもわかる気がする・・・合ってるかな?

そういえば

確率の面白問題として「モンティホール問題」ってのがあるんですが、それをPerlで解いたことあったなぁ、ってことで。

sironekotoro.hateblo.jp