このエントリーをはてなブックマークに追加

はじめに

こんにちは。CTOの 金本 です。

Nagoya.php とは、名古屋で隔月を目処に開催しているPHPの勉強会です。

もともと有志の個人によって運営されていた勉強会でしたが、立ち上げメンバーが次々にカルテットに入社した結果、ここ数年はなんとなくカルテット主催のイベントという感じになっています(笑)

2019/02/13(水)に 通算14回目のNagoya.php を弊社セミナールームにて開催しましたので、その様子を簡単にレポートしたいと思います :elephant: :sparkles:

Nagoya.phpの特徴

Nagoya.phpは、よくあるLT中心の勉強会ではなく、「実際に手を動かしてプログラミング問題を解いてみる」 という取り組み(通称「どう書く」)を中心にした内容になっています。

問題は主に、@Nabetani 氏が開催されている 横浜へなちょこプログラミング勉強会 という勉強会で出題されたものを拝借しています :pray:

多くの方が独力で問題にチャレンジされますが、手ほどきが必要な初心者の方や、自分では解かずに他の人の解答を見るだけでいいやという人のために、スタッフ(私)が説明を交えながらライブコーディングを行いますので、お酒を飲みながらそれを見ていただくだけというスタイルでの参加もOKです。

実はこのライブコーディングスタイルは、今回初めての取り組みでした :sweat_smile:

乾杯&自己紹介タイム

19:00のオープニングとともに、早速全員で乾杯 :beers: :sparkles:

時間も限られているので一人30秒制限で全員に簡単な自己紹介をしていただきました。

自己紹介の題材としてPHP歴を発表していただいたのですが、始めたばかりという初心者の方もいれば、PHP歴15年以上といった大ベテランの方もいて、いつもながら非常にバラエティに富んだ参加者層でした :+1:

プログラミング問題タイム

自己紹介が済んだら、早速プログラミング問題タイムです。(制限時間は40分ほど)

今回使わせていただいた問題は、回文数の数というものでした。

今回も「早い人なら40分程度でなんとか解ける」ぐらいの問題を選ぶのに苦労したのですが、はてさて結果やいかに…。

答え合わせ&交流タイム

20:00からは、ピザ :pizza: を片手にプログラミング問題の答え合わせをしつつ、交流タイムです。

の、予定だったのですが、なんと私がライブコーディングに夢中で ピザを発注するのを忘れる という事態に :scream:

急遽、参加者さんのアイデアで、Uber Eatsでケンタッキーフライドチキンを購入して何とか事なきを得ました。(届いたのが20:40ぐらいだったので皆さん空腹がマックスでしたが :dash:

Uber Eatsの到着を待つ間に、今回はLTの申し出が2本あったので、それらを行いました。

発表者 内容
@ttskch 今日の”どう書く”問題のアルゴリズム例
@longkey1 生活をハックしよう

私の 今日の”どう書く”問題のアルゴリズム例 というLTは、プログラミング問題コーナーの延長的な内容でした。

実は今回のプログラミング問題、私は当然ながら問題選定の段階で実際に解いてみていたのですが、多くの方が真っ先に思い浮かぶであろう総当たりによる解法だと、計算量が大きすぎて普通のマシンでは現実的な時間でテストが完了しないということが分かっていました :bulb:

案の定、20:00の時点で割と多くの方が一旦の実装は終えられていたのですが、用意されたテストケースをすべてパスできたという方はいらっしゃいませんでした。(私自身も事前に解いた際にまったく同じ轍を踏んでいるので、完全に想定どおりではありましたが :sweat_smile:

LTでは、総当たり方式と比べて計算量を大きくカットできるアルゴリズムの一例を紹介させていただきました。

@longkey1 さんの 生活をハックしよう は本編とはまったく関係のない、ザ・LTといった内容で興味深いものでした :+1: 何より、Uber Eatsを待つ時間を埋めていただいて大変ありがたかったです(笑)

その後、無事にケンタッキーが届きまして、参加者の皆さんで食事をしながら :meat_on_bone: 好き好きに交流していただき、予定よりも30分オーバーの21:30頃に解散という流れでした :pray:

おわりに

前回は9ヶ月ぶりの開催だったのですが、今回は隔月開催という約束を守って2ヶ月ぶりで開催することができました :raised_hands:

なお、参加者の皆さんの解答例がTwitterのハッシュタグ #nagoyaphp で見られたりもしますので、興味のある方は覗いてみてください :smile:

引き続き隔月開催を目標に頑張って運営していこうと思っています(次回は2019年4月開催予定)ので、名古屋近郊にお住まいのPHPerさんはぜひ気軽に遊びに来ていただけると嬉しいです!


このエントリーをはてなブックマークに追加

明けましておめでとうございます!永井です!
本年も「カルテットコミュニケーションズ開発部ブログ」を、宜しくお願い致します。

はじめに

弊社では会社の公休日というのをGoogleカレンダーを利用して全社員に公開されています。
2019年1月現在、2020年末ごろまで登録されていますが、年初の時点で今年中の予定が公開されているというのは、一社員としてはとても助かりますよね。
折角、Googleカレンダーというアクセスしやすい形で公開されているので、プログラムで「特定の日が休みかどうか」を判定できると、いろいろ便利かなと思い、実際に検証してみました。

検証

前提

弊社は完全週休2日制で、祝日も休みとなりますので、

  • 土日
  • 祝日
  • 会社が定める公休日

という条件で、その日が休みかどうかを判定することができそうです。
ちなみに会社の公休日は主に年末年始とお盆休みが定められており、年間休日120日以上は確保されています。詳細はこちらをごらんください → 募集要項

土日の判定

これは結構簡単に判定できますよね。
例えばこんな感じ。

<?php

function isWeekend(\DateTimeInterface $target): boolean
{
    return in_array($target->format('w'), ['0', '6'], true);
}

祝日と会社の公休日の判定

祝日の判定は、77web/Japanese.Holidayという素敵なライブラリがあるのですが、今回はGoogleカレンダーをつかうことになりますので、祝日も日本の祝日というGoogleカレンダーで判定することにします。
Googleカレンダーの情報を取得するには、APIを利用したいと思いますが、G Suite配下のプライベートなカレンダーへアクセスする場合には、 サービスアカウントを利用する方がお手軽なので、今回はこちらを利用して進めていきます。

GCPのプロジェクトを作成する

GCPのWebコンソールへアクセスして、プロジェクトを作成してください。

gcp1

GCPのWEBコンソールで、Google Calendar APIを有効にする

API とサービス ページから、Google Calendar API を有効にしてください。

gcp2

サービスアカウントの作成

  • 役割は特に指定しなくてもOK
  • キーのタイプは特にこだわりがなければJSON

というで進めていきます。

service account

会社の公休日カレンダーのサービスアカウントへの共有とIDの確認

カレンダーの詳細ページにいくと、特定のユーザーとの共有で先程追加したサービスアカウントが選べるようになっていますので、閲覧権限(すべての予定の詳細)で共有します。
ちなみに 予定の時間枠のみ表示(詳細は非表示) でも大丈夫かなと試してみましたが、権限が不足しているみたいでした。

また、カレンダーIDも確認してください。

calendar id

日本の祝日カレンダーのIDの確認

日本の祝日 は既に全ユーザーに共有されていますので、何もしなくても利用できます。
IDは ja.japanese#holiday@group.v.calendar.google.com になります。

利用するライブラリ

Googleが用意してくれているgoogleapis/google-api-php-clientを利用します。
composerで簡単にインストールできます。

$ composer require google/apiclient:"^2.0"

特定の日付に予定があるか判定するコード

以下のような関数を用意してみました。

<?php

function hasItems($calendarId, \DateTimeInterface $date)
{
    $credentialsPath = 'service-account-key.json';
    putenv('GOOGLE_APPLICATION_CREDENTIALS='.$credentialsPath);

    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();

    $client->addScope(Google_Service_Calendar::CALENDAR_EVENTS_READONLY);
    $service = new Google_Service_Calendar($client);

    $optParams = [
        'orderBy' => 'startTime',
        'singleEvents' => TRUE,
        'timeMin' => (new \DateTime($date->format('Y-m-d 00:00:00')))->format(DATE_RFC3339),
        'timeMax' => (new \DateTime($date->format('Y-m-d 23:59:59')))->format(DATE_RFC3339),
        'timeZone' => 'Asia/Tokyo',
    ];
    $results = $service->events->listEvents($calendarId, $optParams);

    return \count($results->getItems()) > 0;
}

見ていただければわかると思いますが、

特定の日付に1件以上予定があるかどうか

というロジックになります。

気をつける点はタイムゾーンの設定です。
PHPのタイムゾーン、カレンダーのタイムゾーンなど色々ありますので、それぞれ適切に設定する必要があります。

また、Googleクライアントにはスコープを指定する必要があります。
Google_Service_Calendar::CALENDAR_EVENTS_READONLY または Google_Service_Calendar::CALENDAR_READONLY を指定する事でカレンダーおよびそのイベントにアクセスする事ができます。

最終的なコード

<?php

date_default_timezone_set('Asia/Tokyo');
require_once 'vendor/autoload.php';

$japaneseHolidayCalendarId = 'ja.japanese#holiday@group.v.calendar.google.com';
$quartetDayOffCalendarId = '会社の公休日のカレンダーID';

// 2019年の1月1日から31日を判定して出力する
foreach (range(1, 31) as $day) {
    $target = (new \DateTime())->setDate(2019, 01, $day)->setTime(0,0,0);
    if (
        isWeekend($target) ||
        hasItems($japaneseHolidayCalendarId, $target) ||
        hasItems($quartetDayOffCalendarId, $target)
    ) {
        printf('%s is day off.'.PHP_EOL, $target->format('Y-m-d'));
    } else {
        printf('%s is work day.'.PHP_EOL, $target->format('Y-m-d'));
    }
}

function isWeekend(\DateTimeInterface $date)
{
    return in_array($date->format('w'), [0,6], false);
}

function hasItems($calendarId, \DateTimeInterface $date)
{
    $credentialsPath = 'service-account-key.json';
    putenv('GOOGLE_APPLICATION_CREDENTIALS='.$credentialsPath);

    $client = new Google_Client();
    $client->useApplicationDefaultCredentials();

    $client->addScope(Google_Service_Calendar::CALENDAR_EVENTS_READONLY);
    $service = new Google_Service_Calendar($client);

    $optParams = [
        'orderBy' => 'startTime',
        'singleEvents' => TRUE,
        'timeMin' => (new \DateTime($date->format('Y-m-d 00:00:00')))->format(DATE_RFC3339),
        'timeMax' => (new \DateTime($date->format('Y-m-d 23:59:59')))->format(DATE_RFC3339),
        'timeZone' => 'Asia/Tokyo',
    ];
    $results = $service->events->listEvents($calendarId, $optParams);

    return \count($results->getItems()) > 0;
}

実行した結果は以下の通り。

2019-01-01 is day off.
2019-01-02 is day off.
2019-01-03 is day off.
2019-01-04 is work day.
2019-01-05 is day off.
2019-01-06 is day off.
2019-01-07 is work day.
2019-01-08 is work day.
2019-01-09 is work day.
2019-01-10 is work day.
2019-01-11 is work day.
2019-01-12 is day off.
2019-01-13 is day off.
2019-01-14 is day off.
2019-01-15 is work day.
2019-01-16 is work day.
2019-01-17 is work day.
2019-01-18 is work day.
2019-01-19 is day off.
2019-01-20 is day off.
2019-01-21 is work day.
2019-01-22 is work day.
2019-01-23 is work day.
2019-01-24 is work day.
2019-01-25 is work day.
2019-01-26 is day off.
2019-01-27 is day off.
2019-01-28 is work day.
2019-01-29 is work day.
2019-01-30 is work day.
2019-01-31 is work day.

意図したとおり実行されました!

さいごに

いかがでしたでしょうか。
簡単ではありますが、いろんなところで活躍する場面がありそうですよね。
とても小さい機能ですが、色んな所で使い所がありそうなので、ライブラリ化して社内で公開できると良いかなと思っています!


このエントリーをはてなブックマークに追加

はじめに

Nagoya.phpとは、名古屋で不定期に開催しているPHPの勉強会です。

もともと有志の個人によって運営されていた勉強会でしたが、立ち上げメンバーが次々にカルテットに入社した結果、ここ数年はなんとなくカルテット主催のイベントという感じになっています(笑)

去る2018/12/26(水)、通算13回目(9ヶ月振り)のNagoya.phpを弊社セミナールームにて開催しました :elephant: :sparkles:

本記事では、Nagoya.php #13 の様子を簡単にレポートしたいと思います :muscle:

Nagoya.phpの特徴

Nagoya.phpは、よくあるLT中心の勉強会ではなく、「プログラミング問題を解いてみよう」というコーナーを中心にした内容になっています。

これは、ちょっとしたプログラミング問題を用意して、参加者それぞれで実際にコードを書いて解いてみるというものです。

問題は主に、@Nabetani氏が開催されている横浜へなちょこプログラミング勉強会という勉強会で出題されたものを拝借しています :pray:

乾杯&自己紹介タイム

19:00のオープニングとともに、早速全員で乾杯 :beers: :sparkles:

時間も限られていたので一人30秒制限で全員に簡単な自己紹介をしていただきました。

自己紹介の題材としてPHP歴を発表していただいたのですが、始めたばかりという初心者の方もいれば、PHP歴15年以上といった大ベテランの方もいて、いつもながら非常にバラエティに富んだ参加者層でした :+1:

プログラミング問題タイム

自己紹介が済んだら、早速プログラミング問題タイムです。(制限時間は40分ほど)

今回使わせていただいた問題は、縦横ローテーションというものでした。

過去のNagoya.phpは基本的に週末のお昼で開催していたので、プログラミング問題を解く時間として贅沢に2時間ぐらい使っていたのですが、今回は初めての平日開催ということでかなり時間が限られていたため、比較的簡単そうな問題を選びました。

が、皆さん仕事終わりで頭が疲れていた様子で、想定していたよりやや苦戦されていました :sweat_smile:

答え合わせ&交流タイム

20:00からは、ピザ :pizza: を片手にプログラミング問題の答え合わせをしつつ、交流タイムです。

まずは参考までに私の解答例を発表させていただきました。

ここから先は、参加者の皆さんの中で時間内に解けた方や、最後までは終わらなかったけど大枠は作れたという方による、「私はこんな感じで解きました」の発表タイム(通称「自慢タイム」)です :sparkles:

こんな感じで、何名かの方に、前に出て自分のコードの設計や実装の工夫点、苦労したポイントなどを簡単に解説していただきました。

なお、参加者の皆さんの解答例がTwitterのハッシュタグ #nagoyaphp で見られたりもしますので、興味のある方は覗いてみてください :smile:

おわりに

今回は実に9ヶ月ぶりの開催になってしまいましたが、2019年は隔月開催を目標に頑張って運営していこうと思っています(次回は2019年2月開催予定)ので、名古屋近郊にお住いのPHPerさんはぜひ気軽に遊びに来ていただけると嬉しいです。

今回、クロージングの前に参加者の皆さんに「今日楽しかった人ー!?」という問いを投げかけてみたのですが、ほぼ全員が手を挙げてくださいました :flushed:

この調子で皆さんに楽しんでいただける場にしつつ、プログラミング問題のレベル設定やスムーズな進行など、運営側として改善できるところは頑張って改善していきますので、引き続きよろしくお願いします! :raised_hands: