omohayui blog

おも‐はゆ・い【面映ゆい】[形][文]おもはゆ・し[ク]《顔を合わせるとまばゆく感じられる意》きまりが悪い。てれくさい。

Chrome Extension gcp-status-timezone-localize を作りました

What?

GCP でインシデントが起きたときに確認する Google Cloud Status Dashboard は、
時系列が全て PST (Pacific Standard Time) で表示される為、毎回 JST に変換して確認するのが面倒だったので、
ブラウザの Local Timezone に変換してくれる Chrome 拡張機能を作りました。
(丁度、GCPUG の Slack でそのようなご意見を見かけたのがきっかけ)

before

f:id:omohayui:20191211003723p:plain
before

after

f:id:omohayui:20191211004116p:plain
gcp-status-timezone-localize

How to install

Chrome Web Store

Chrome Web Store からインストールできます。
gcp-status-timezone-local

Summary

  • Google Cloud Status Dashboard で使う為の超シンプルな Chrome Extension を作りました
  • まだ時系列部分しか Localize できてないので、他の箇所も対応するようにしようかなと思ってます

Life in Christchurch

早いもので、私がクライストチャーチの学校へ通うのもラスト1日となってしまいました。まだまだ勉強足りてないし、もっとここにいたいなぁという思いを綴ります…

Weekends

the crater rim walk

クライストチャーチの南に位置する巨大な火口跡の縁がクレイターリム。
個人でツアーガイドをしている Nicole さんに連れて行って貰いました。
幸いなことにものすごく良いお天気で、ハイキングする人、トレイルランニングする人、マウンテンバイクで登る人たちで賑わってました。
普段はそんなに混んでないらしいです。あと羊も人間以上にたくさんおりました。 f:id:omohayui:20191024175042j:plain 途中でランチ食べたり休憩も挟みながら約3時間ほど海辺から頂上までぐるっと歩き周りました。
素晴らしい景色だったのですが、多分写真だけでは伝わらないです…

C1 Espresso

チューブスライダーでフライドポテトやバーガーが運ばれてくるので有名な何とも不思議なカフェです。 f:id:omohayui:20191024180425j:plain f:id:omohayui:20191024180223j:plain クライストチャーチにはたくさんカフェがあり、地元の人たちもコーヒー好きが多いのですが、スタバは1店舗しかありません。
皆それぞれお気に入りのカフェがあってシアトル系にはあまり興味がないのかもしれないです。
私がたまたまスタバに通りかかった時は謎の Happy Hour でフラペチーノが半額でした。

The Botanic Gardens

クライストチャーチには広大な公園がたくさんあるのですが、中でも Hagley Park は巨大で、その中心に Christchurch Botanic Gardens があります。
f:id:omohayui:20191024181447j:plain 昼間表に出ているのは珍しいという野生のハリネズミを見かけました。めっちゃ可愛かったです。 あとニュージーランドきてから予想以上にジーランスが捕まらないのですが、ここには水辺があるので1匹だけ捕獲しました。

Christchurch Art Gallery

ニュージランドで活躍する現代アーティストの作品が多かったのですが、中でもマウイのアートが面白かったですね。
独特の文化とスピリチュアルな表現に惹かれました。 christchurchartgallery.org.nz

Weekdays

School

New Zealand への短期留学 - omohayui blog の「授業について」に大体のことは書いたのですが、毎週のように生徒や先生が変わっていくので結構目まぐるしい学校生活だなぁと感じる今日この頃です。
先週まではコロンビアやブラジルからきたクラスメイトがいたのですが、授業が自分と合わないとか希望を出すと次の週から他のクラスに移籍できたりして、今週はチリやアルゼンチンから来たクラスメイトが増え、といった感じでなかなか面白いです。
最初は先生の話が聞き取れなくて辛いこともあったのですが、慣れでそこは大分改善しました。
が、相変わらず話すのは苦手です(汗) 私がいつも一緒にランチしたりしている友達は台湾からきた姉妹で、私より英語レベルが上なんですが、拙い英語でも暖かい眼差しで聞いてくれます。
明日は車を出してくれて、ずっと私が行きたかった New Brighton Library に連れてってくれる予定です(涙)

Pokemon Go

びっくりするほどポケゴーやってる人がいなくて全然レイドできてないです。
って話を日本人のクラスメイトにしたら、Facebookのグループに Pokemon Go Canterbury なるものがあってそこに入るとたまにレイドの集まりとかあるらしいです。
もっと早く知りたかったと思いながら参加申請しました…

Next

今週末には日本に帰らなければなりません・・・新たな会社で仕事が待っております。
ですが本当にクライストチャーチが良いところすぎて、また戻ってくることを真剣に考えてしまう今日この頃です。
No Snake, No Mosquito が嬉しいし、町中が綺麗で環境意識高いし、治安もいいし、地元の人たちもフレンドリーだし。
日本で働きながら英語の勉強はもちろん続けるつもりだし、また成長したところを見せに戻りたいなぁ。

New Zealand への短期留学

何しにニュージーランドへ?

今年の4月ぐらいから英語話せる&聞き取れるようになりたい…!
と思ってオンライン英会話を(1日25分のやつ)を毎日続けてはいたのですが、
本当に簡単な会話ぐらいしかできていなくて、どうしたらもっと上達するだろうかということを考えた結果、 英語を使う会社に転職して強制的に話す環境に身を置くことだ!という結論に至り、
5年弱務めた某D社を退社することにしました。
で、11月からは半分以上が foreigners という環境で働くことになったのですが、
有休消化1カ月というロングバケーションを手に入れた私は真っ先にニュージーランドへの短期留学を決意しました。

なぜニュージランド?

私がポケモントレーナーだと言うことをご存知の方はもうお気づきだろう。
ご存知ない方は、 フロリダでヘラクロスとケンタロスとサニーゴを捕まえたときの話 - omohayui blog を一読してほしい。(※しなくていいです)
選定時まだ私が手に入れていない地域限定はパチリスジーランス
カナダという選択肢もありましたが、良さげな学校があるバンクーバートロントモントリオールは緯度的にパチリスが出ないという独自の調査結果が出たので、ジーランス狙いで候補地はニュージランドになりました。
(ニュージランドで働きたいが為に職を捨てて同じ学校に来てる人たちもいるので、この話は学校では絶対にできません。)

f:id:omohayui:20191011192102j:plain

現在10月ですが、ニュージーランドは丁度桜の季節です。
朝と夜は結構肌寒いです。

なぜクライストチャーチ

ニュージランドと言えばオークランドの方が都会でたくさん語学学校があるのですが、
クライストチャーチは自然に溢れたとても綺麗な街で、
私が通っている語学スクールは広大な敷地を持つカンタベリー大学の構内にあり、 大学内の図書館やカフェテリアが使えちゃうんです。

f:id:omohayui:20191011192306j:plain

カンタベリー大学の敷地内には広大なラグビー場があります。
(筑波大にいたときと雰囲気似てるんだけど、なんか一緒にしてはいけないぐらい洗練された感じ…笑)

授業について

まず初日にオリエンテーションとペーパーテストと interview を受けます。
それで、その人のレベルに応じてクラス分けがされて、翌日から10~14人程度のクラスに入って授業を受けます。
私のクラスメイトは日本・中国・タイ・韓国といったほぼアジア系で和気あいあいとした雰囲気。
グループワークかペア作業が多めで、先生の人柄のおかげだと思うけどとても楽しいし面白いです。
明らかに私が最年長な訳ですが、案外若者たちと一緒に混じってやれてしまうものです。
クラス替えのテストは5週間に一度行われます。

また、授業とは別に毎週3時間分の e-Learning が課せられます。
これは Google Docs で writing したものや Canvas Student というアプリを使って録音したものを提出するホームワークです。
期日内に提出すれば先生からレビューが貰えます。

放課後はクラスとは別に Conversation Club や Movie 鑑賞、スポーツのアクティビティに任意参加します。
ちなみに今日は Movie の日で、みんなでスナックつまみながら Bridget Jones を英語字幕付きで観ました。

ホームステイについて

homestay か flatting (シェアハウスの寮版みたいな?) を選びました。
家でも英語を使うようにする為に homestay がおすすめです。
私のホストファミリーはめちゃくちゃ優しくて、すぐスーパーマーケットに行くのに車を出してくれたり、
kiwi が見たいと話してたら、Willowbank という野生保護区の動物園連れて行ってくれました。
f:id:omohayui:20191011200330j:plain host mother はタイ出身で彼女の作ってくれたマッサマンカレーパッタイはめちゃくちゃ美味しかった…
host father はNZの方でビーフハンバーガーとかスパゲティを作ってくれるんだけどそれもとても美味しいのです…
しかも家は学校から徒歩10分。School Assistant には You're very lucky! って言われました。

週末の予定

明日はまだ行ってないクライストチャーチの City Central (市街地の方) に行ってみる予定です。
オススメのカフェをクラスメイトに聞いたら C1 って言ってたので、そこと、修復中の大聖堂とカードボード・カセドラルかな。
続きはまた来週…

Code Jam to I/O for Women 2019

なにそれ?

codingcompetitions.withgoogle.com

Google が毎年開催している、女性向けの online coding contest です。
スコアがTOP150位内にランクインすると Google I/O へのチケットと旅費が賞品として授与されます。

2019 は?

今年は2月に開催されたのですが、Google I/O の話題で盛り上がりつつある昨今、
ふと思い出して今更ながらまとめておこうと思います。
去年はスケジュールの都合で参加できず、今年初めて参加したのですが、 結果としては散々で、世界の壁の厚さを思い知ることに・・・
ランキングを見るとロシアや中国の方が強かったですね、日本人の方も1人ぐらい150以内に入っていた気がするけど先進国の中ではワーストなのでは...ってぐらい少なかったです。

参加方法は?

毎年、開催の1ヶ月程度前から公式サイトで事前登録が始まります。
Google アカウントがあれば誰でも登録できます。
(特に女性であることの証明みたいのはなかった)

事前準備は?

過去問を解く

とりあえず、チュートリアルだけでも絶対やっておいたほうがよいです。
Code Jam のサイトでは、自分で書いたコードがテストケースをクリアするかどうかオンライン上で即時に判定されます。
毎回問題の内容自体は異なりますが、テストケースの入力形式とテスト結果の出力形式は一緒です。
このテストケースを読み込み、テスト結果を出力する部分は予め準備しておけるわけです。

テストケースとテスト結果の input / output 形式

テストケースは標準入力(STDIN)としてテストコードに渡ってきます。

  • 1行目がテストケースの数(1 ≤ T ≤ 100.)
  • 2行目以降が検証する要素の数と検証する要素の値

(例)

3                # テストケースの数
5                # Case1 の要素数
0 2 1 1 2        # Case1 の値
1                # Case2 の要素数
0                # Case2 の値
6                # Case3 の要素数
2 2 2 2 2 2      # Case3 の値

テスト結果は標準出力(STDOUT)としてアウトプットする必要があります。
そしてこれも出力形式が決まっています。

(例)

Case #1: 2              # Case1 のテスト結果
Case #2: 0              # Case2 のテスト結果
Case #3: 10              # Case3 のテスト結果

実際に解いてみる

2018年のハンバーガーの具材を最適化しようという課題を試しに解いてみましょう。
Burger Optimization

プログラミング言語はプルダウンから自分の好きな言語を選べます。

f:id:omohayui:20190503183330p:plain
select programming language at Code Jam

※ 参加した時は、プルダウンに Perl がなかったのですが、今見ると対応言語が増えているようで...

Go で書いてみる

つっこみどころ満載のコードですが晒します。
ローカルで実装しながら検証するときはテストケースを外部ファイルとして作っておくと便利です。
あとは go run コマンドで実行するだけ。
(限られた時間で競うときこそコンパイルが速い go にすべきじゃない?)

$ go run main.go < input_file.txt
package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
    "sort"
    "strconv"
)

var s = bufio.NewScanner(os.Stdin)

func main() {
    s.Split(bufio.ScanWords)
    t := nextInt() // test case 数

    for i := 1; i <= t; i++ {
        k := nextInt()       // burger の中の要素数
        ds := make([]int, k) // バンズまでの距離のslice
        bs := make([]int, k) // 最適なバンズまでの距離のslice
        for j := 0; j < k; j++ {
            ds[j] = distance(k, j) // バンズまでの距離
            bs[j] = nextInt()      // 最適なバンズまでの距離
        }

        // 最小誤差を出すために並び替える
        sort.Sort(sort.IntSlice(ds))
        sort.Sort(sort.IntSlice(bs))

        es := 0 // 誤差合計
        for j := 0; j < k; j++ {
            d := square(ds[j] - bs[j]) // 誤差
            log.Print(d)
            es += d
        }
        fmt.Printf("Case #%d: %d\n", i, es)
    }

    if err := s.Err(); err != nil {
        log.Fatal(err)
    }
}

func nextInt() int {
    s.Scan()
    i, e := strconv.Atoi(s.Text())
    if e != nil {
        panic(e)
    }
    return i
}

// 次乗
func square(x int) int {
    return x * x
}

// バンズからの距離
func distance(k, j int) int {
    d := k - 1
    if (d - j) < j {
        return d - j
    }
    return j
}

標準入力の取得は os パッケージ(当たり前だけど)、 os.Stdin から io.Reader を一行ずつ読み込むのには、bufio.NewScanner を使いました。
※ bufio.NewScanner はスキャンできる一行のサイズに上限があるので、テストケースによっては使えないことがあるかもしれませんが、
Code Jam の課題ではここを超えてくるテストケースには出会いませんでした。

あとよく使うであろう、nextInt() や square() も予め用意しておいたほうがよさげです。

Perl で書いてみる

この記事を書こうとして Perl がサポートされていることに気づき Perl版も作ってみました。
(書いて気づいたけど、Perl の方がコード量半分で済むし、そもそもコンパイル要らないよ...って)

use strict;
use warnings;
use utf8;

my $t = <STDIN>; # test case 数

for (my $i = 1; $i <= $t; $i++) {
    my $k = <STDIN>; # burger の中の要素数
    my @bs = split(/ /, <STDIN>); # 最適なバンズまでの距離の配列
    my @ds;                        # バンズまでの距離の配列
    for (my $j = 0; $j < $k; $j++) {
        push @ds, distance($k, $j); # バンズまでの距離
    }

    # 最小誤差を出すために並び替える
    @ds = sort { $a <=> $b } @ds;
    @bs = sort { $a <=> $b } @bs;

    my $es = 0; # 誤差合計
    for (my $j = 0; $j < $k; $j++) {
        my $d = ($ds[$j] - $bs[$j]) ** 2; # 誤差
        $es += $d;
    }
    printf("Case #%d: %d\n", $i, $es);
}

# バンズからの距離
sub distance {
    my ($k, $j) = @_;
    my $d = $k - 1;
    return $d - $j if ($d - $j) < $j;
    return $j;
}

当日のハプニング

2019年の競技開始は何やらトラブルがあったようで何度も遅れました・・・ 日本時間 AM0:00 開始予定だったのが直前に 30min 遅れになり、さらにまた 30min 延長、さらに... といった感じで眠気との戦いが大変でした。

感想

来年こそはチケットと旅費を手に入れるぞ!(※会社に出してもらうのではなく)

How to upload a module to CPAN

Why?

とある既存の CPAN module に修正を加える必要あり、PullReq を作成して送ったところ、
自分でアップロードしてみたらと言われ、アップロードを試み、結果たくさんの反省点があったので、
一から自分で作った module をアップロードすることにしました。

Process

Step1: What should I make as a module?

perlnewmod - 新しいモジュールを配布するには - perldoc.jp

とりあえず、CPANアップロードのリベンジをしたいという思いで、以前実装したコードを module に切り出してしまったので、
ここに記載あるように「必要性の議論」はできていないです。(ごめんなさい)
作成したのは、FCM の API v1 向け Client です。
必要だったのは FCM の API Client というより OAuth 2.0 アクセストークンを使った Google API Client でした。
ServiceAccount の json ファイルをそのまま使ってやりたいことをできるものが当時見つからず。
Go で書かれている google api client のソースコードを読んで perl に置き換えることにしたのです。

github.com

Step2: Create a module

今回、 Minilla というオーサリングツールを使いました。

% minil new WWW-FCM-HTTP-V1

するだけで、アップロードまでに必要なものは勝手に作ってくれます。

% ls -l WWW-FCM-HTTP-V1
 Build.PL
 Changes
 LICENSE
 META.json
 README.md
 cpanfile
 lib/
 minil.toml
 t/

lib/ と t/ ディレクトリにそれぞれソースコードを置いて minil test を行うと、
META.json や README.md も更新してくれます。

Step3: Create PAUSE ID

まず、 module ができても、 PAUSE のアカウントがないと CPAN にはアップロードできません。

PAUSE: The CPAN back stage entrance から登録を行います。

そしてここから申請してもすぐアカウントが自動作成されるわけではなく、
手動で作成される (!) ので、1週間ぐらいはかかりました。

おそらく、 "A short description of why you would like a PAUSE ID:" の内容を人の手でちゃんとチェックしているのかなと・・・

アカウントが作成されると「Welcome new user OMOHAYUI」というメールが届きます。
別のメールで仮パスワードが送られてくるので、そちらでログインし、パスワードを変更します。

ここで、 metacpan.org のアカウントと PAUSE ID の連携を試みるのですが、
現在ここで問題が起きていて、連携用コードが PAUSE アカウントに設定しているメールに届きません。。。
これができなくても CPAN にはアップロードできるのですが、
アイコンが設定できなかったり、いいねができなかったりちょっと寂しいものがあります。

Can't associate with PAUSE · Issue #2048 · metacpan/metacpan-web · GitHub この issue が resolve されれば・・・

Step4: Setting pause_config

Minilla でリリースする際には cpan-upload を利用する為、
.pause ファイルを home directory に配置しておく必要があります。
pause にログインする際の user名とパスワードを記載します。

user OMOHAYUI
password *********

Step5: Release

Minilla でリリースする場合は、

minil release

とコマンドを打つだけです。

test と Changes の更新、 Github への commit & push CPAN アップロード までやってくれます。 アップロード後、しばらくすると upload と indexer report のメールが届いて完了です。

補足として、Changeログの更新時は、version と更新日時は自動で追加されるので追記不要です。

{{$NEXT}}
    - next version

0.01 2019-03-31T16:07:40Z

    - original version

Step6: Update modules

自分の場合は、翌日ぐらいに CPAN Testers から Daily Summary Report が届きました。
テスト結果としては、 MSWin32-x86 環境で send test が失敗しているよ!という内容でした。

win環境でテストするのめん..困難なので、 MSWin32 はサポート外としてテストを修正し、再度アップロードを試みました。

初回移行も minil release だけで、いけます。
version もデフォルト 0.02 で更新してくれます。

Next

CPANアップロードの方法は覚えたけれども、
やっぱり Go の方で何か package 作りたいな...