大西ブログ

All your blog are belong to us

Scratchを使った子どもへのプログラミング教育

この記事は、はてなエンジニア Advent Calendar 2017 の19日目の記事です。
昨日の記事は, id:papix の「「雑に文章を書く」活動と, そこから得たもの - Masteries」でした.

僕には今、小6と小4と二人の子どもがいるのですが、2年ほど前から子どもたちに Scratch を使ってプログラミングを教えています。そこから得た知見などを書いてみます。(最近はサボってるのでごめんよ子どもたちよ)

Scratch とは

説明も不要なくらい有名になってますが、Scratchとは、MITメディアラボが開発している子ども向けのビジュアルプログラミング言語です。アラン・ケイのスクイークをベースに開発されています。
ブロックのように命令を組み合わせてマウスでプログラミングでき、マウスだけでも簡単なプログラムは作れるので児童にプログラムの基本概念を教えるのによい(とされている)。
Scratch 2.0 はFlashプレーヤーを搭載したブラウザだけで動くので、今すぐあなたもプログラミングできます。この記事の中にも動くプログラムを幾つか埋め込んでいるので是非試してみてください。

https://scratch.mit.edu/

なぜ子どもにプログラミングを教えるか

義務教育でプログラミングが必須授業だとか、AI社会に向けて、とか色々言われています。が、割とどうでもよくて、僕は子どもと共通言語ができる、自分のやっている仕事を子どもに理解してもらえる、というのが大きいと感じています。

我が家での導入

プログラミングスクールの体験会に参加

Scratch自体はエンジニアなら触れば大体わかると思いますが、子どもにどういうテンション、カリキュラムで教えるのか、を体験するために、無料体験会に参加してみました。
PC触るのも初めての子どもを対象にしていたので、すごくわかりやすいテキストを写経するだけの簡単なものでしたが、子どもが熱中し、できたものを自分で作り上げたものとして誇らしげにしている様が印象的でした。

書籍の購入

子どもが読めるテキストを購入しました。教えるテキストとして、また自分の理解のために。ある程度進んだら、本を与えると自分で勝手にプログラムを作る、本を発展させて自分で作りたいものを考えるようになるといいですね。

小学生からはじめるわくわくプログラミング

小学生からはじめるわくわくプログラミング

阿部先生の本。アラン・ケイのメッセージも載っててグッときます。Scratch1.4ベースですが最初に読ませる本としてはベストでは。

小学生からはじめるわくわくプログラミング2

小学生からはじめるわくわくプログラミング2

2冊目。Scratch2.0ベースになってるし、2冊目として高度化した内容。この2冊は最初に買う本としておすすめです。

その他の書籍の紹介

(我が家では)子ども受けはイマイチだったものの、面白かった本も紹介します

10才からはじめるゲームプログラミング図鑑: スクラッチでたのしくまなぶ

10才からはじめるゲームプログラミング図鑑: スクラッチでたのしくまなぶ

ヴォーダマンの本。前半Scratch、後半Pythonという構成。Scratchで学んで手続き型プログラミングって、Pythonでも一緒だよ、という主旨だけど子どもはタイピングできなくて詰む。

Scratchではじめよう! プログラミング入門

Scratchではじめよう! プログラミング入門

こちらはもう少し高度な内容。一冊かけてシューティングゲームを作る。基本~応用初級くらいまでが学べる。

Scratchで学ぶプログラミングとアルゴリズムの基本

Scratchで学ぶプログラミングとアルゴリズムの基本

Scratch でアルゴリズムを学べる。線形探索とかソートのアルゴリズムをScratchで学べる。自分は面白く読んだけど、子どもに読ませるのは少し先かな。

do it yourself

本で基礎を学んで、なんとなく「何でもできる」感を感じてもらったら、あとは好きに作らせるといいですね。音を鳴らすもいい、カメラを使うもいい、Scratchでできることに限界を感じたら、もっと高級な言語を学ばすなり、ロボティクスにいくなり、どっちに行っても楽しいです!(子どもも親も)プログラミング教育最高。

やってみる

前置きが長くなりましたが、Scratchプログラミングの例として fizzbazz を書いてみましょう。

f:id:onishi:20151021190649p:plain:w400

https://scratch.mit.edu/projects/194480042/#editor


Perl ならこんな感じですね

my $i = 1;
my $serif = '';

while (1) {
    $serif = $i . '! ';
    if ($i % 15 == 0) {
        $serif = $serif . 'fizzbuzz';
    } elsif ($i % 3 == 0) {
        $serif = $serif . 'fizz';
    } elsif ($i % 5 == 0) {
        $serif = $serif . 'buzz';
    }
    print $serif . "\n";
    sleep(1);
    $i++;
}

一緒じゃん、ということで、子どもに手続き型プログラミングを教えるのに Scratch は最初の一歩に良いなと思っています。
とにかく、マウス(トラックパッド)の操作さえ教えれば、キーボードをほぼ触らずにプログラミングが組めるのは画期的で、参入障壁が低いです。

メッセージング

Scratch の基本は手続き型プログラミングですが、スプライトのクローンでオブジェクトも作れるぞ!(ちょっと違う)
そして複数のスプライトとその間のメッセージ通信ができるぞ!(ただしブロードキャストのみ)

f:id:onishi:20151021180930p:plain


リミックス

GitHubのソーシャルコーディング、素晴らしいですね!Scratchでもソーシャルコーディングできる!
クリエイティブ・コモンズの継承ライセンスで公開、リミックスができます。リミックスツリーというビューがあり、ビジュアライズされます。他の人の作ったプログラムに自由に改変を加えて発表でき、それがさらにという循環が生まれます。
自分の作ったプログラミングが公開できて、コメントがもらえたり、forkして新しいプログラムが生まれるという体験をローティーンでできるのはすごい!僕も実際コメントをもらったりforkされたことがありましたが、ちょっと感動がありました。

いろいろやってみた

というわけで、Scratch が楽しいので、勉強がてら自分でも Scratch ブログを始めてみました。
まだ記事数は少ないですし最近更新も滞っていますが、興味ある方は是非読んでいただければと思います。
oniscratch.hatenablog.com

おすすめ記事

その他いろいろやってます!見てください!&アドバイスください!

Scratch の発展・今後

Scratch2MCPI

みんな大好きマインクラフトでプログラミングを勉強しよう!ラズパイで Mincraft Pi を動かして、Scratch でプログラミングできます!子どもの興味を引く「自作PC(ラズパイ)」「マイクラ」「Scratch」で完全勝利ですね

Scratch 3.0

Flashで動作していた Scratch が HTML5, WebGL といった標準化技術で使えるようになるぞ!

Appendix

教育

最後に

駆け足になりましたが、プログラミングは楽しいですよね、それを子どもに教えるのもまた楽しい。未来の日本のために、我が子の未来のために、自己満足のために、子どもとの対話のために、プログラミングを教えましょう!
あなたの知見も教えてください!

編集チーフになってやったこと

はてなでサービス・システム開発本部長をやっている id:onishi です。
この記事は「はてなディレクターアドベントカレンダー」の5日目の記事として書かれました。前の記事は id:AirReader の「サポートからディレクターになって - 日直地獄」でした。
さて、僕の本業は本部長なのですが、この半年ほど暫定的に編集チーフという仕事をやっていて、12/1付で後任者に引継ぎをしました。その引継ぎのために、自分がやってきたことをまとめたものをアドベントカレンダーにしたら安上がり知見をオープンにできて良いと思ったので書いてみます。

以下は、この半年ちょっとで考えたことややったことを時系列ではなく構造的に整理したものです。また僕自身は編集職としてのキャリアは無かったので、これまでの他職種でのチーフなどの経験を活かしてやってきました。一人で考えたものではなく、シニアエディターやその他いろいろな人と相談しながら作ってきたものです。後任のチーフや、組織をマネジメントする人のお役に立てれば幸いです。



チーフとは

はてなのサービス開発は「ブックマークチーム」とか「ブログチーム」のようなサービスを軸にしたチームで構成されています。それとマトリクスを描くように「技術グループ」「デザイングループ」「編集グループ」といった専門職種によるまとまりも存在します。チーフはその専門職グループのリーダーです。

専門職グループの存在意義

はてなは技術の会社です。はてなで働く人に大事にしてもらいたい価値観「はてなバリューズ」の中でもこのように言っています。

技術が好き

  • ひとりひとりが持っている技術にこだわりをもとう
  • 自分の専門領域を常に貪欲に学習しトッププレイヤーを目指そう
  • 技術を使って生まれる価値を大切にしよう

チームとしてサービスを開発し、会社の業績に貢献することは大切ですが、それと同時に自分の専門領域を向上させるというのを大切にしています。
専門職グループを置いてマトリクス組織にしているのは、その技術の研鑽についての責任をもつという現れです。
専門技術を向上させるための、専門職グループの活動は主に以下のものに集約されます。

  • 採用
    • そもそも専門技術を有する、あるいは向上を望めるメンバーを採用する、その選考に責任を持つ
  • 教育
    • 採用したメンバーの技術向上のための研修の仕組みづくり、個人の目標立案の補助、メンタリング、コーチング、ティーチング
  • 評価
    • 半期に一度行われる評価のタイミングで、専門スキル評価を行う
  • 対外プレゼンス向上
    • 対外発表することによる専門技術の向上、ブランディング、社会への貢献
    • 対外アウトプットについては、はてなのエンジニアに期待する「アウトプット」というエントリがありますが、これはエンジニアに限らず、専門職種全般に言えることだと考えています

編集グループのミッション

グループの存在意義がわかったところで、あらためて「編集グループが目指す方向」を考えました。判断に迷ったとき、ミッションに照らして、我々が目指す方向に合致しているかを考える基準になるものになるといいですね。僕が考えた編集グループのミッションは具体的に以下のものです。

編集グループのミッション

「インターネット上における表現活動を編集の力で最大化する」

かみ砕いて言うと

  1. はてなから発する表現(自社メディア、告知、ヘルプ、規約、自社サイト、サービス上の文言など)を正確でわかりやすいものにする
  2. ユーザーから発する表現(ブログなどはてなのサービスを利用した表現活動)を後押しし、はてなから良質なコンテンツが生まれる土壌を育てる
  3. インターネット上の表現活動を編成・編集などによって後押しし、インターネットにおいて良いコンテンツが正当に評価され、より多くのクリエイターにより優良なコンテンツであふれる状態とする

はてなのビジョン」に書かれているこの部分

当社は、インターネットにおいて良いコンテンツが正当に評価され、より多くのクリエイターにより優良なコンテンツで溢れる状態となることを望みます。

これはまさに、編集グループが目標におくべきことなので、ほぼそのまま活用しています。「文章」という言葉を使わず「表現」としたのは、インターネット上の表現手段やメディアは多様化しており、テキストだけでなくあらゆる表現活動をよりよくしていくことが編集の仕事だと考えたからです。

シニアエディター

もともとシニアエディターという役職はあって、編集職の中で指導的な立場をとってもらっていたのですが、その業務範囲を明確にし、チーフ(僕)との役割分担をしました。

チーフの役割

  • グループの方向性/ミッション
  • 編集シニア会を開催する
  • 編集会を開催する

シニアの役割

(複数のメンバーがいるので実際は具体的な分担も決めています)

  • 採用
    • 書類選考
    • その後の面接、可否判断に参加
  • 教育
    • 研修ドキュメント整理
  • 評価
    • 目標設定面談
    • 定期面談
    • 期末評価
  • ブランディング向上
    • 編む庭(ブログ・イベント)
  • その他
    • 社内編集タスクの巻き取り
    • チーフ不在時の代理

専門職スキルを有しないチーフ(僕)と有するシニアで、僕は型を作ってシニアに執行してもらうという体制をとりました。

メンタリング、コーチング、ティーチング

シニアとそれ以外のメンバーでメンター・メンティーの関係を設定しました。
月一回、月報提出とメンター面談を実施し、専門目標の達成状況や業務、キャリアに関する相談の場としています。

活動場所

編集メンバーの活動のための場所を作りました。

  • はてなグループ
    • 自社製グループウェアです。はてなでは、チーム毎、専門職グループ毎に一つずつはてなグループを作るのが一般的です
    • トラックバックで業務上のやりとりをする他、編集技術に関する知見も積極的に投稿するように呼びかけています
  • Slackチャンネル
    • 社内Slackに編集メンバー全員参加するチャンネルを作りました。編集メンバーだけでなく、編集や文章についての相談もできるように Public チャンネルにしています。 #editors 社内の方はお気軽に join してください

会議体の組織

編集シニア会

上記編集シニアとチーフ(僕)が話す会です。目的は「編集グループ」をちゃんと組織化すること。
GitHub Enterprise の issue でやることを管理して、この記事に書いているような決めごとをしたり、個別のメンバーについての相談をしたり。
そんなに話す事もないだろうと油断していて、当初は毎週だけど徐々に頻度は減らしていこうって言ってたのですが、結局任期の間ずっと毎週やっていました。

編集会

編集グループ所属メンバーが全員集まる会です。目的はメンバーの情報共有です。
はてなは東京・京都と二つの拠点があり、編集メンバーは地理的にも離れているほか、自社メディアの運営と、他社オウンドメディアの運営補助、記事広告など編集といっても様々な業務があるので、チームやオフィスを跨がった情報共有を大事にしています。
こちらは参加メンバーも多くコストがかかるので基本は隔週開催。アジェンダは以下のようにしています。

  • 近況報告(全員)
    • 3行で今やっている仕事の内容を共有、職務上の悩みがあったらそれも話します。その場で軽くディスカッションになることも
  • 知見共有
    • はてなグループ上に投稿されたエントリを確認し、知見を共有します
  • はてな編集部ブログ「編む庭」企画会議
    • 編集メンバー持ち回りで「編集」に関するさまざまな記事をお届けするブログです
    • 次の記事の企画、書かれた記事の振り返りなど
  • 新しい登場人物
    • 自社メディアでも他社オウンドメディアでも、ブロガーさんに寄稿をお願いすることがあります。「こんどこのブロガーさんに記事執筆をお願いする」という情報を共有しておくことで、各媒体の運営がスムーズになります
  • この人にあれを聞きたい
    • 編集、とくにウェブ編集者は、たとえばHTML/CSSに造詣が深い、画像処理ができる、動画が作れる、ソーシャルメディアに詳しい、などなど必要なスキルが多岐にわたってきています。この人に具体的にこのスキルについて聞いてみたい、というスプレッドシートを全員で共有し、情報交換の促進を促しています

専門目標

はてなにおける評価項目(転じて目標軸)は3軸あり、「成果」「行動スキル」「専門スキル」の3つです。専門職グループは、「専門スキル評価」とそのための「専門スキル目標」にコミットします。
成果目標に対して専門スキル目標は、個別具体的な技術向上の目標になったりしがちですが、会社やチームの方向性は不変ではないので、ともすれば業務と専門スキル目標を両立することが難しかったりします。
そのため、専門スキル目標の位置づけは以下のように定義し、目標立案をお願いしています。

  • 専門スキル目標は、達成・未達成が評価に直結するものではなく、専門スキル向上のための「成長目標」と捉えてください
    • 「今期はこれを頑張ります・伸ばします」というマニフェストと考えるとわかりやすいと思います
  • 目標達成のために努力した結果が専門スキル評価向上というかたちで反映されるはずです
  • メンターと相談しながら、職種専門スキルを伸ばすための目標を「必ず1つ以上」立ててください

専門スキルを伸ばすことは本人にとってプラスである、個々人が専門スキルを高めることが会社に還元される、という正の循環を作っていきたいですね。

編集チーフをやってよかったこと

という感じでいろいろやってみて、なんとなく形になってきたかなというところです。編集職スキルを有しないチーフとしては型を作るまでが仕事で、実際にこれに則ったりもっと良くしていったりして、実際的に編集職のメンバーを伸ばしていくのは後任にお任せしたいと思います。後任のチーフは編集畑の方なので、大いに力を発揮してもらえると期待しています。
編集職を育てていく環境もより整備されていくと思いますので、ウェブ編集の仕事に興味のある方は是非ご応募ください!

もともとエンジニアとしてやってきて、チーフエンジニア、ディレクター、プロデューサー、本部長、編集チーフ、と職種を変えたり増やしたりしてきたのですが、変えるたびに何をやっていいかわからず、ゼロから積み上げる不安な気持ちになってきたものでした。
しかし、最近は特に業務の変化が多く発生するなかで、培ってきた経験やスキルが他職種でも生きるという気づきをたくさんしています。エンジニアのチーフから編集のチーフは、同じチーフなのでそれがわかりやすく感じられたのがよかったです。

先日、デブサミ関西でも発表したのですが、エンジニアがマネージャになることって地続きの部分もあるなと思っています。サービスを作るのも組織を作るのも、結局は問題を発見して仮説を立てて改善し…というPDCAサイクルを回すのは一緒ですし。
専門職種の人間が一人で上げられる成果、に上限は無いと思います。1つのライブラリが世界中で便利に使われることもあります。そういう追求もあるし、専門職種やチーム全体の向上に力を割くこともまた面白いな、と感じています。自分の考えた仕組みでうまくいってなかったチームがうまく回り出した、自分一人で到底なし得ないような大きな成果をチームがなし得た、と感じた時にチーフやディレクターをやってよかったと思ってきました。

おわりに

というわけで、編集チーフとしてやってきたことをまとめつつ、チーフやディレクターというマネージャ職について僕が考えていることを書かせて貰いました。なんとなくディレクターアドベントカレンダーの体はなしたのではないでしょうか。
はてなディレクターアドベントカレンダー、次回は id:riko さんです!

好きなものについて語る難しさ

はてなスタッフアドベントカレンダー2016 を始めます!

advent.hatenablog.com

今年のテーマは「好きなもの」ということで、これは書きやすいテーマだなと思って決めたものの、改めて自分の好きなものって何だっけ…と考えると意外と何も無い気もしてきました。

好きなもの、を聞かれると控えめに「アニメ、マンガ、ゲーム、映画、SF、ミステリ」と言っているのですが、年々声が小さくなっている気がします。何でかというと、これらのジャンルはそれぞれ深く精通している人がいるので、生半可な知識で好きとか言えないという意識が働くからです。さらに家庭を持ち趣味に使う時間も減っていくので尚更です。

アニメ好きと言っても最近のアニメは毎期数本見てるくらいで、会社のアニメ好きと会話してもついていけない事が多いです。はたしてアニメ好きと言えるのか…と自問自答してしまう。
一番最近見たアニメの話をすると、先週末に家族で金沢に車で旅行した往復に、子どもたちに未来少年コナンのDVDを見せました。

コナンといえば『未来少年コナン』の愛称として定着していたが、日本テレビ系アニメ『名探偵コナン』の登場により事情は変わった。今やコナンといえぱ『名探偵コナン』の愛称として定着しており、『未来少年コナン』をイメージするのは若くない証拠なので要注意。

(はてなキーワード未来少年コナンより)


この通りで、「今日はコナンのDVDだよ」って言って再生したら「これ違う」とびっくりしてたのですが、数話見せたら完全にハマってしまい、上の子が何話か見た後「最初の頃より最近のほうが1話の時間が短くなってない?」とまさに狙い通りのコメントをしてくれて嬉しかったです。良いものは年月を超えて愛されると思って(おっさんくさいですが)、車の長距離移動の際は「世界名作劇場」とか古い名作をよく見ています。


好きなものについて人力検索で質問したことがあったなーと思い出して質問履歴を紐解いてみたところ、10年も前にありました。
q.hatena.ne.jp
沢山回答いただけて嬉しかったし、読んだことの無かった面白い本を沢山紹介してもらえました。

思い返すと、「SF小説が好きだ」と思ったのは高校生の時、インターネットも無く、専門誌を読むでもなかった当時に本屋でたまたま手に取った小説がベイリーの「時間衝突」で、それがものすごく面白くて、「たまたま手に取った本がこんなに面白いSFすげー」と思って、SF小説のことを好きになり、大学に進学したとき「もっとSFのことを詳しい人に聞きたい」と思ってSF研究会というサークルの門を叩いたのでした。
単なる知識だけでなく「好き」が伴った情報は圧倒的に面白いというのはブログサービスを運営していてもすごく思うところです。
好きなものについて語るのは気恥ずかしさを伴いますが、勇気をもって声を出してみると同好の士から有益な情報が得られて嬉しい、という体験を何度かしてきたので、好きなものについて話すのも聞くのも大好きです。今回のアドベントカレンダーで同僚が「好きなもの」について熱く語るのを読むのが楽しみです。

アドベントカレンダー次回は id:daiksy さんです。よろしくお願いします!

エンジニアの働きやすい職場を求めていろいろ回ってきました

最近の私は、5ヵ月に渡り、ITスタッフィングさんのITスタッフィング エンジニアスタイルで「エンジニアの働きやすい職場って?」を聞いて回る連載をしていました!先日公開された第5回で一旦連載終了です。

  1. リクルートマーケティングパートナーズさん
  2. クックパッドさん
  3. スマートニュースさん
  4. ヤフーさん
  5. ソニーさん

「エンジニアの働きやすい職場とは」ということで、オフィス環境に留まらず、仕事の進め方、評価とキャリアパスなど、突っ込んだ質問をしていく記事となり、自分の関心分野とも合致していたので非常に興味深い話を毎回聞けて楽しい連載でした。
毎回一緒にオフィス取材に行ってくださった池澤あやかさんとはこの連載が初対面でした。可愛らしいのは記事をご覧の通りですが、エンジニアとしても活躍されているだけあり、質問パートも鋭い質問をしていただき盛り上がりました。実際この連載僕要らなかったんじゃ、と何度も思いました…。

取材を引き受けていただいた皆さんも、エンジニアとして尖った方ばかりでしたし、自分と同じような、開発のマネージャーだったりエンジニアのキャリアパスを考える立場だったり、という方の話を聞くことができて、同じような悩みに共感したり、問題を解決するための仕組みに感心したり、学びのある話ばかりでした。同じような問題意識を持っていらっしゃる方に読んでいただければ幸いです。

各社を回り、「エンジニアの働きやすい職場」のやり方はたくさんあるけれども、成長機会がある、ということが非常に重要だと改めて感じました。エンジニアの成長と事業の成長をきちんとリンクさせられるのが一番だと思います。エンジニアが(それ以外の職種もですが)楽しく働けてかつ成長実感があり、それが事業の成功や会社の成長につながっている、そんな会社に弊社もしていきたいですね。

私は普段は京都に引っ込んでいるので、こういう機会があるのは本当にありがたいです。経営、マネジメント、エンジニアの評価・キャリアパス・採用などについてお話しする機会があれば飛びつきますのでご一報ください。

喰らえ10年鍛えた俺の test.pl !!

こんにちは、2011年くらいにディレクターになってめっきりPerl書かなくなった id:onishi です。

この記事は Perl5 Advent Calendar 2015 18日目です!

書き捨てのコードを test.pl という単一ファイルに __END__ と共に上に追加し続けて10年。3万行超に成長した俺の test.pl から厳選したコード群を喰らえ、という主旨の記事です。

今日のお品書きはこんな感じです。

( [PR]この目次ははてなブログの目次機能で自動生成しています )

ちなみに、書き捨てのコードから良いものは、プロジェクトのリポジトリに入れたり、~/bin/ に置いたりしています。今日は ~/bin/ に移った厳選処理も紹介しますね。
とにかく test.pl にいろんな処理が書かれているので、日付処理したい、とかメール送りたい、とか思ったらそれっぽい単語でファイル内を検索すると適切なコードスニペットが見つかるので業務効率に繋がっています。

list()

ORM使うほどでもないけどさくっとDB引きたい時の簡易DBIラッパーです。

use DBI;

my $host = {
    user => ['host1', 'user', 'pass'],
    blog => ['host2', 'user', 'pass'],
};

sub dbh {
    my $dbname = shift;
    DBI->connect_cached(
        sprintf(
            'dbi:mysql:database=%s;host=%s',
            $dbname,
            $host->{$dbname}->[0],
        ),
	$host->{$dbname}->[1],
        $host->{$dbname}->[2],
    )
}

sub item {
    my $list = list(@_) or return;
    $list->[0];
}

sub list {
    my ($dbname, $sql, @bind) = @_;
    my $dbh = dbh($dbname);
    my $sth = $dbh->prepare_cached($sql);
    $sth->execute(@bind);
    return $sth->fetchall_arrayref({});
}


こんだけ書いておけば list() と item() で以下みたいなコードが書けます。

my $user = item(
    user => 'SELECT * FROM user WHERE name = ?',
    'onishi'
);

my $entries = list(
    blog => 'SELECT * FROM entry WHERE user_id = ?',
    $user->{user_id},
);

print map { $_->{title} . "\n" } @$entries;

数クエリで済みそうな集計を雑にしたい時に使ってます。

fotolife

フォトストレージサービスはてなフォトライフに簡単にファイルをアップロードするコマンドです。Config::Pit で username, apikey, folder を指定しておきましょう。

$ fotolife ファイル
$ fotolife URL

第一引数にファイルパスかURLを受け取り、自分のフォトライフにアップロードし、アップロード結果を出力します。
結果はこのように、はてなブログ用記法、はてなダイアリー用記法、フォトライフpermalink、画像permlinkをまとめて出力する親切設計です。

$ fotolife some-file.jpg
[f:id:onishi:00000000000000p:plain]
[f:id:onishi:00000000000000p:image]
http://f.hatena.ne.jp/onishi/00000000000000
http://cdn-ak.f.st-hatena.com/images/fotolife/o/onishi/000000/00000000000000.png
#!/usr/bin/env perl
use strict;
use warnings;

use Config::Pit;
use FileHandle;
use LWP::Simple 'get';
use XML::Atom::Entry;
use XML::Atom::Client;

my $file = shift;

my $type = $file =~ /(png|gif|bmp)$/i ? lc($1) : 'jpeg';
my $t    = substr($type, 0, 1);
my $ext  = $type eq 'jpeg' ? 'jpg' : $type;
   $type = "image/$type";

my $image;
if ($file =~ m{https?://}) {
    $image = get($file);
} else {
    local $/; # slurp mode
    my $fh = FileHandle->new($file) 
        or die "cannnot open $file: $!";
    $image = $fh->getline;
}

my $config = pit_get("hatena.ne.jp", require => {
    username => 'username',
    apikey   => 'apikey',
    folder   => 'folder',
});
my $username = $config->{username};
my $apikey   = $config->{apikey};
my $folder   = $config->{folder};

my $PostURI = 'http://f.hatena.ne.jp/atom/post';

my $api = XML::Atom::Client->new;
$api->username($username);
$api->password($apikey);

my $entry = XML::Atom::Entry->new;
$entry->content($image);
$entry->content->type($type);
$entry->title('');
my $dc = XML::Atom::Namespace->new(dc => 'http://purl.org/dc/elements/1.1/');
$entry->set($dc, 'subject', $folder) if $folder;
my $EditURI = $api->createEntry($PostURI, $entry) or
  die $api->errstr;

$EditURI =~ /(\d+)/ or die $EditURI;
my $fototime = $1;
my $initial  = substr($username, 0, 1);
my $date     = substr($fototime, 0, 8);
print "[f:id:$username:$fototime$t:plain]\n";
print "[f:id:$username:$fototime$t:image]\n";
print "http://f.hatena.ne.jp/$username/$fototime\n";
print "http://cdn-ak.f.st-hatena.com/images/fotolife/$initial/$username/$date/$fototime.$ext\n";

長い。あと、WSSE認証使ってますけど最近はOAuthでも書けます。
はてなフォトライフAtomAPI

wq

みんな大好き、Web::QueryjQuery ライクに scraping できます。

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

binmode STDOUT, ':utf8';

use Web::Query;

my $url      = shift or die;
my $selector = shift or die;
my $limit    = shift || 0;

my $i;
wq($url)->find($selector)->each(
    sub {
        printf("%s\n", $_->text);
        $limit && ++$i >= $limit and exit;
    }
);

こんな雑なスクリプトを wq という名前でPATHが通ったところに用意しておくと、URLとセレクタを引数にこんな感じで簡易スクレイピングコマンドとして使えます。

$ wq http://www.hatena.ne.jp 'ul#servicelist li' 5
    ブックマーク ネット上にお気に入りを保存できるサービス。ネット上の旬な話題がすぐわかる
    ブログ 書き残そう、あなたの人生の物語。だれでも使いやすく簡単に書ける、はてなの新しいブログ
    B!KUMA “がんばる私”に、ちょっと一息。恋愛、レシピ、おしゃれ、育児など女性が気になる話題をお届け
    ニュース ネットで旬な話題を分かりやすく紹介。地元発の京都情報、ひとこまマンガも楽しめるニュースサイト
    人力検索 調べたいことを誰かが自分の代わりになって調べてくれる人力検索サービス

(はてなトップページから「はてなのサービス」を5件取得する例)

セレクタ指定して取得した数字を別のサービスに投げたりすると便利なんじゃないでしょうか。

punycode

日本語ドメインでイラッとすることが多いので punycode の自動変換をします。

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

use IDNA::Punycode;
use Encode;

binmode STDOUT, ':utf8';

idn_prefix('xn-');

my $word = shift;

if ($word =~ /^xn-/) {
    print join('.', map { decode_punycode(Encode::decode('utf-8', $_)) } split(/[.]/, $word)) . "\n";
} else {
    print join('.', map { encode_punycode(Encode::decode('utf-8', $_)) } split(/[.]/, $word)) . "\n";
}

こんな感じ。

$ punycode xn--wgv71a119e.jp
日本語.jp

$ punycode 日本語.jp
xn--wgv71a119e.jp

イラッとしなくなりました。

statuscode

任意のステータスコードを返すサーバーをさっと建てたいこと、ありますよね!(無い)

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

use HTTP::Daemon;
use HTTP::Status;
use HTTP::Response;

my $d = HTTP::Daemon->new(LocalPort => shift || undef) || die;
print "Please contact me at: ", $d->url, "\n";
while (my $c = $d->accept) {
    while (my $r = $c->get_request) {
        if ($r->method eq 'GET' and $r->url->path =~ m{/(\d+)}) {
            my $code    = $1;
            my $header  = HTTP::Headers->new( 'Content-Type' => 'text/html' );
            my $message = status_message($code) || '';
            my $res     = HTTP::Response->new(
                $code,
                $message,
                $header,
                "<title>$code $message</title><h1>$code $message</h1>"
            );
            $c->send_response($res);
            warn "$code $message\n";
        } else {
            $c->send_error(RC_FORBIDDEN)
        }
    }
    $c->close;
    undef($c);
}
$ statuscode
Please contact me at: http://localhost:53812/

サーバーが立ちます。
http://localhost:port/200 のように任意の数字をパスに指定するとその数字のステータスコードを返します。なんか便利ですね!

結びの言葉

10選くらい挙げたかったのですが、意外と仕事のコードと密なコードが多すぎて紹介できなくて飽きてきたのでここらへんで終わります。
1ファイルを眺めるだけで10年の歴史が眺められて面白かったです。