OmniAICreator/Qiita-1.07M huggingface dataset:
conoha-cliをgoで作った

僕はよくconohaのvpsを利用しています
理由は

- 安い(aws)とくらべて
- かつ時間課金
- 課金すればスペック上げられる

です。

節約のために使うときだけマシンをbootしてたりしてましたが
ログインするのめんどくさいし、結構管理画面が重い。

なのでターミナルから指定マシンを`ON / OFF`できるCLIを作りました。

https://github.com/smith-30/conoha-cli

### できること

__boot(起動)__

```bash
$ ./build/bin/conoha-cli boot
2017-12-09T16:17:11.468+0900	INFO	client/boot.go:40	StatusCode 202
```

__halt(シャットダウン)__

```bash
$ ./build/bin/conoha-cli halt
2017-12-09T16:21:23.050+0900	INFO	client/halt.go:41	StatusCode 202
```

### 使い方

1. build

```
$ go get github.com/smith-30/conoha-cli
$ cd $GOPATH/src/github.com/smith-30/conoha-cli
$ dep ensure -v
$ make build-cli
```

2. 設定ファイル編集

```
$ vi .env.example
```

```
TenantID=
SERVER_ID=
API_USER=
API_PASSWORD=
```

__SERVER_ID__

サーバーの詳細からUUIDを設定


__TenantID& API_USER & API_PASSWORD__

![スクリーンショット 2017-12-09 19.57.45.png](https://qiita-image-store.s3.amazonaws.com/0/47896/ddc3ea14-e8b1-cc82-51f1-205f5899f6e9.png)






__設定ファイルをバイナリパスに移動__
```
$ cp .env.example build/bin/.env
```

__test__

```
$ ./build/bin/conoha-cli boot
```

### VPS側でやっといたほうがいいこと

ubuntuであれば
`/etc/rc.local` にスクリプトを書くことで
起動時にそのコマンドが実行されます

僕は、bootしたときにdockerを動かしたいので下記のようにしています

```shell:/etc/rc.local
# <your-project-root> にMakefileがある
cd <your-project-root> && make start-app
```

### 反省

人に使ってもらうなら設定ファイル形式でなくて
パラメータ渡して使えるようにしたほうが良かった。
次回から気をつける
初めてのAWSのEC2でwebサーバー構築→nginx導入（後編）

前回の続きです。

今回は仮装サーバーを構築してnginxを導入してみたいと思います。

#　**サーバーを構築する**
前回までで、物理的な世界でいうとインターネット接続の契約が済み、ルーターなどの機器の配線や設定が終わった状態。これからそのネットワーク上に仮装サーバーを作成する。

## 仮想サーバー構築

![ec2.png](https://qiita-image-store.s3.amazonaws.com/0/212851/938725c2-47e9-7887-2621-64c9779f67e3.png)

仮想サーバーは、Amazon EC2を用いて作成する。インスタンスと呼ばれ、このインスタンスにwebサーバーソフト（今回はnginx）をインストールしてwebサーバーとして機能させる。インスタンスには、パブリックサブネット内で利用可能な「プライベートIPアドレス」を割り当てる。前回、パブリックサブネットは「172.30.1.0/24」のCIDRブロックにしたので、「172.30.1.0 ~ 172.30.1.255」のいずれかの値を割り当てることになる。だが、プライベートIPアドレスは、インターネットとの接続には利用できないので、インスタンスを起動する時は、もう一つ「パブリックIPアドレス」を設定するようにする。作成したインスタンスは「VPC内で通信するためのプライベートIPアドレス」と「インターネットで通信するためのパブリックIPアドレス」の二つを持つ。


**インスタンス作成**

インスタンスを作成してみる。

[EC2]

1.リージョンを確認する（VPCと同じところに、今回は東京）
2.[インスタンス]>[インスタンスの作成]
3. AMIを選択(Amazon Machine Image)OSがインストールされて初期のアカウントの設定まで済んだもの。今回はAmazon Linux AMIを選択。
（AMIとは→http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instances-and-amis.html）
4.インスタンスタイプ(仮想マシンのスペック。インスタンスのタイプによって、インスタンスの CPU 能力、メモリ、およびストレージが決まる)を選択。（今回はt2.micro）
5.インスタンスの詳細情報を設定
  1.VPCとサブネット インスタンスを配置するサブネットを選択。[ネットワーク]で配置したいVPC領域を選択し、[サブネット]で配置したいサブネット(先ほどパブリックに設定したもの)を選択する。
  2.パブリックIPアドレス インターネットからこのインスタンスにアクセスできるようにするため、パブリックIPアドレスを付与。[サブネット設定を使用（有効）]を選択。   
  3.プライベートIPアドレス このインスタンスには、プライベートIPアドレスも設定。「プライベートサブネット」に、先ほど「172.30.1.0/24」を定義しているので、「172.30.1.0~172.30.1.255」のいずれかのIPアドレスを指定できる。 ここでは、「172.30.2.166」を割り当てる。
6.ストレージの設定
デフォルトで設定した。
（ボリュームタイプの説明についてはこちら→http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/EBSVolumeTypes.html）
7.インスタンスに名前を付ける。何でも良いが今回はtakahashi-ec2とした。
8.セキュリティグループ設定する。
セキュリティグループはインスタンスに対して、セキュリティを設定する機能。後述。
9.インスタンスの起動、[確認と作成]をクリック。
10.キーペアを作成してダウンロード。インスタンスにログインする際に必要になる鍵。
11.インスタンスの起動。キーペアをダウンロードしたら、[接続]ボタンをクリックして、インスタンスを起動。

一息入れましょう。


**SSHで接続する**

起動したインスタンスに、インターネットからログインして操作するため「SSH」というプロトコルを使う。
(SSHとは→http://wa3.i-3-i.info/word11722.html)

**パブリックIPアドレスを確認する**
EC2インスタンスの、Public IPを見れば確認することができる。

**いざ、接続**

1.ターミナル起動
2.`ssh -i keyペアファイル名 ec2-user@パブリックIPアドレス`

**ファイアウォールで接続制限する**

IPアドレスや、ポート番号を元にサーバーやネットワークのセキュリティを高めるようにする。

**パケットフィルタリング**

パケットフィルタリングは、流れるパケットを見て、通過の可否を決める仕組み。IPアドレスを判定して、「特定のIPアドレスを送信元とするパケット以外を除外するようにする」ように構成すれば、接続元を制限できる、またポート番号を制限すれば、特定のアプリケーションを外部から接続できないように構成できる。

**インスタンスのセキュリティグループ**

実世界ではパケットフィルタリングはルーターやサーバー、もしくは専用のダイアウォール機器で構成されるが、AWSでは、インスタンスにたいして、構成する「セキュリティグループ」がこの機能を担う。作成したインスタンスに対するセキュリティグループはデフォルトの構成でインバウンドを見ると、ポート22にたいして全ての通信(0.0.0.0/0)を許可する、という設定があり、それ以外の設定はない。デフォルトのこの設定では、webサーバーソフトなどをインスタンスに入れたとしても、阻まれて通信できないので、ソフトウェアのインストールとともに、セキュリティグループの構成も変更する必要がある。

#　**nginxを入れる**

webサーバーといえば有名なものにapacheがあるが今回はnginxを導入してみた。

（理由についてはおもに→https://academy.gmocloud.com/qa/20160616/2761）

前提
　・EC2のインスタンスを作成している
　・インスタンスのセキュリティーグループでsshとhttpを許可している
　・インスタンスにSSHに繋げる
　・Macでターミナルを使用

### **1.インスタンスにsshで入る**
`ssh -i keyペアファイル名 ec2-user@パブリックIPアドレス`

### **2.yumのupdate**
(yumとは→http://uxmilk.jp/9715)
`sudo yum update`

### **3.nginxのインストール**
`sudo yum install nginx`

その後バージョンの確認
`nginx -v`

### **4.nginxのデフォルトページを表示**
nginxの始動！
`sudo service nginx start`

IPアドレスでブラウザから接続し、デフォルトページが表示されれば成功:relaxed:

自動起動にしてしまう。
`　sudo chkconfig nginx on`

以上

nginxはまだまだわからないことが多いのでDjangoと絡めながら今後勉強していこうと思います。
Drupal8 Webformモジュールの紹介

# はじめに
Qiita Advent Calendar 2017 10日目、Drupal8限定記事です。
フォーム作成モジュール、Webformの機能の一部をご紹介します。

Drupal8はインストールした時点でContactモジュールがあるので、
管理ページから操作してフォームページを作ることが可能です。

簡単なフォームであればこれで十分ですが、
Webformというモジュールを導入するとそれ単体でフォームページのカスタマイズ幅がぐーんと上がります。
あまりにも機能が多いので、簡単なフォーム作成方法とざっくりとした機能紹介だけします。

# モジュールのインストール
他のコントリビューションモジュールと同様、composerや公式サイトからダウンロードして有効化してください。

[Drupal.orgのWebformページ](https://www.drupal.org/project/webform)

# フォームを作る

## 新規作成

1.フォーム一覧を表示
管理メニューからサイト構成 > Webforms (/admin/structure/webform) から表示。

2.タイトル設定
「Add webform」ボタンをクリックして、タイトルを入力、保存するとページが完成します。

<img width="321" alt="webform02.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/41498/50a9e1f3-6ded-0822-8a6b-177cee6182af.jpeg">

## 項目追加
コンテンツタイプにフィールドを追加する要領で項目追加していきます。

1.追加する項目タイプ選択
フォーム編集のBuildタブのページにて、「Add element」ボタンをクリックして、追加したい項目を選択します。
テキストエリア、チェックボクス、セレクトリスト、マークアップ表示用など様々な項目が選択できます。
例では単純なテキスト入力欄を追加します。
<img width="450" alt="webform05.png" src="https://qiita-image-store.s3.amazonaws.com/0/41498/a251fcaa-7f1a-c835-8e72-4dea312c83d5.png">
<img width="411" alt="webform03.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/41498/0b6e30e6-901f-c03f-420a-fe45d2b2182c.jpeg">


2.項目の詳細設定
タイトルの設定のほか、ラベルの表示方法、説明の追記、バリデーションの設定など行います。
保存したら項目追加完了です。
他にもタブごとに以下のようなことができます。

* 条件・・・他項目の状態によって項目の表示・非表示・非活性などの条件を付与できます
* 高度・・・デフォルト値の設定、CSSのクラスの付与ができます
* アクセス・・・ロールごとに項目の表示・非表示の設定ができます

<img width="411" alt="webform04.png" src="https://qiita-image-store.s3.amazonaws.com/0/41498/0e87fdba-ab2e-d9d4-a12e-ff787b8e8c97.png">

ビュータブから見ると追加した項目 + Submitボタンが表示できています。
あとは表示したい項目分だけAdd elementするだけ・・・！
<img width="980" alt="webform06.png" src="https://qiita-image-store.s3.amazonaws.com/0/41498/da38d3c1-bc62-8ca8-5201-133911dd8c0d.png">


## 機能紹介 やりたいこと別リスト
設定できることが多いので、やりたいことがどこで設定できるかのリストです。
<img width="960" alt="webform07.png" src="https://qiita-image-store.s3.amazonaws.com/0/41498/7bbf4ea4-db84-19fd-31e4-114eacea9b7f.png">

### フォーム投稿内容を見たい
結果タブのページで一覧表示できます。CSVダウンロード、投稿内容の編集、削除、一括クリアなどもできます。

### 投稿後にメールで通知したい
設定 > Emails / Handlersタブで複数設定できます。フォーム内容から宛先、本文内容も可変に設定できます。

### 確認画面を表示したい
設定 > フォームで有効化できます。

### スケジュール公開したい
設定 > フォームで公開日・終了日を設定できます。

### URLを自由に決めたい
設定 > General でエイリアスが設定できます。

### プログレスを表示したい
設定 > フォームのWIZARD SETTINGSで表示できます。

### フォーム内容を一時保存したい
設定 > Submissions のDRAFT SETTINGSでできます。
保存できる単位はセッション毎です。

### フォーム投稿後は別ページに遷移したい
設定 > Confirmationで設定できます。
フォーム送信直後にTOPページを表示しつつ、ページ上部に「投稿完了しました」のメッセージを表示することもできます。

### ログインしている人のみ表示したい
設定 > アクセス でロール毎に表示設定ができます。

# おしまい
Webformモジュールはフォームが欲しいときの機能は概ね揃っていると思います。
2017年12月現在、Drupal8版は絶賛開発中のステータスです。
ただ短いスパンでバージョンアップしているのでバグがあってもフィックスは早いと思います。

またソースコードを見るとサードパーティーモジュールが作られることを想定した実装になっていて、機能追加がしやすいです。
現在、絶賛機能追加中の身なので、もっと知識がついたら新記事を書いてみたいと思います。

以上になります。ありがとうございました。
nginx で SSLアクセラレータ+リバースプロキシでサブドメイン運用

# TL;DR
- Azure VM にインストールされているDockerで複数台のサーバーを立てている
- これまで同一ホスト名＋別ポート番号で接続していた
- ホストが増えてきたのとポート番号運用はいけてないので nginx のリバプロでサブドメイン運用したい

# nginx の設定
- HTTP は 強制的にHTTPS 接続に
- proxy_pass は、Docker ホストを指定(もっといい方法ないのかな。。。)

```nginx:/etc/nginx/conf.d/default.conf
ssl_certificate     /etc/nginx/conf.d/nomupro.com.crt;
ssl_certificate_key         /etc/nginx/conf.d/nomupro.com.key;
ssl_prefer_server_ciphers on;
ssl_session_cache    shared:SSL:10m;
ssl_session_timeout  5m;
ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128:AES256:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK';


proxy_next_upstream error timeout;
proxy_set_header Host              $host;
proxy_set_header X-Real-IP         $remote_addr;
proxy_set_header X-Forwarded-For   $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port  $remote_port;
proxy_set_header X-Forwarded-User $remote_user;
port_in_redirect                   off;
add_header      Front-End-Https    on;
server_tokens off;

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://$host$request_uri;
}
# default
server {
    listen    443 ssl default_server;
    server_name _;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}
# zabbix
server {
    listen    443 ssl;
    server_name zabbix.nomupro.com;
    location / {
        proxy_pass http://172.17.0.1:8080;
    }
}
# phpmyadmin
server {
    listen    443 ssl;
    server_name pma.nomupro.com;
    location / {
        proxy_pass http://172.17.0.1:8081;
        allow 192.168.0.0/16;
        deny all;
    }
}
```

## Docker コマンド
```
docker run -d -it -p 80:80 -p 443:443 --restart=always -h nginx --name nginx -v $(pwd)/nginx-conf/:/etc/nginx/conf.d/ -v $(pwd)/html/:/usr/share/nginx/html nginx
```

# 参考サイト
Nginx で 「SSL Accelerator(SSLアクセラレータ)」を作りました！ (SSLリバースプロキシ)
https://snickerjp.blogspot.jp/2015/03/nginx-ssl-accelerator.html
NginxでのSSL設定の細かい意味
https://gist.github.com/koudaiii/735ef14b83ee31ac0967
REDIRECT ALL HTTP REQUESTS TO HTTPS WITH NGINX
https://www.bjornjohansen.no/redirect-to-https-with-nginx
nginx の設定で気をつける事（個人用メモ）
https://qiita.com/white_aspara25/items/bc9d9b9b2dc0a673169a
DockerfileでNginxの起動とログのローテーションまで
https://qiita.com/k7tak29/items/993ba3af8b0ac62a02c5
Google Homeにアドベントカレンダーの更新状況を喋らせてみた

12月ですね。この記事はオールアバウトアドベントカレンダー9日目の記事です。
投稿当日（2017/12/9）に焦って書かれています。

# はじめに
この時期、アドベントカレンダーのおかげで技術系の記事が多く更新されるのでとても楽しみな季節です。
そのため、毎日アドベントカレンダーの更新が気になり、何度も何度も見にいってしまう僕がいます。
早朝に公開されていれば問題ないのですが、僕みたいにギリギリの時間帯に更新してしまう人もいると思います。
そんな気になって何度も確認してしまう手間を軽減するために、
Google Homeに更新状況を喋らせるということをやってみました。

# やっていること
- QiitaアドベントカレンダーのRSSを読み込む
- なんかいい感じにパースする
- クリスマスまでの残日数をお知らせする
- 当日の投稿がある場合は、その投稿のタイトルをお知らせする
- 当日の投稿がない場合は、そうお知らせする

## 使っている技術
- Google Home
- node.js（v8.1.4）
- npm(5.0.3）

## 使っているnpmライブラリ
- [google-home-notifier](https://github.com/noelportugal/google-home-notifier)
- [feedparser](https://github.com/danmactough/node-feedparser)
- request

## 実際のjavascriptコード

```js:notifier.js
const googlehome = require('google-home-notifier');
const FeedParser = require('feedparser');
const request = require('request');

// Qiitaのアドベントカレンダーフィード
const qiita_feed = 'https://qiita.com/advent-calendar/2017/allabout/feed';
const language = 'ja';
// クリスマスの日付
var xmas_day = new Date(2017, 11, 25, 0, 0);

var req = request(qiita_feed);
var feedparser = new FeedParser({});
req.on('response', function(res) {
  var stream = this;

  if (res.statusCode !== 200) {
    this.emit('error', new Error('Bad status code'));
  } else {
    stream.pipe(feedparser);
  }
});

var blog_titles = [];
var updated_date;  // 最終更新日

feedparser.on('meta', function(meta) {
  updated_date = meta.date;
});

feedparser.on('readable', function() {
  var stream = this;
  var item;

  while (item = stream.read()) {
    // Qiita内と外部でタイトル保持部分が違うみたいなので条件分岐
    if (item.link.indexOf('https://qiita.com/') === 0) {
      blog_titles.push(item.title);
    } else {
      blog_titles.push(item.description);
    }
  }
});

feedparser.on('end', function() {
  var today = new Date();
  var month = today.getMonth() + 1;
  var day = today.getDate();

  // クリスマスまでの残日数
  var day_to_xmas = Math.ceil((xmas_day.getTime() - today.getTime()) / (1000 * 60 * 60 * 24));

  var updated_day = new Date(updated_date).getDate();

  var comment = "クリスマスまで、" + day_to_xmas + "日だよ。";
  if (day >= updated_day) {
    comment += "しかし残念ながら、本日のアドベントカレンダーの投稿はまだのようです！"
  } else {
    comment += "本日、" + month + "月" + day + "日は、" + blog_titles[0] + "が投稿されました。読んでくださいね！";
  }

  // GoogleHomeに送信
  googlehome.device('Google-Home', language);
  googlehome.notify(comment, function(res) {
    console.log(res);
  });
  
});

```


Google Homeと同じネットワークで以下を実行

```bash
$ node notifier.js
```

### 実行結果

#### 当日の更新がある場合

- Google Home  
「クリスマスまで、16日だよ。本日12月9日は"Google Homeにアドベントカレンダーの更新状況を喋らせてみた"が投稿されました。読んでみてね！」

#### 当日の更新がない場合
- Google Home  
「クリスマスまで、16日だよ。しかし残念ながら、本日のアドベントカレンダーの投稿はまだのようです！」

## 難点
現状の実装だとGoogle Homeのネットワーク内でしか実行できないので、
毎回スクリプトを叩く必要がある。できたら自動化したかった・・・。

# さいごに
アドベントカレンダーのおかげで、すでにGoogle Homeに色々やらせてみた実装は多く公開されていたので、組み合わせて割と簡単に実装ができました。
クリスマスまで、まだまだ日にちもあるので、これからも多くの情報が出てくると思うと楽しみです！


## 気になっているアドベントカレンダー
- スマートスピーカー Advent Calendar 2017
https://qiita.com/advent-calendar/2017/smart-speaker

- おうちハック Advent Calendar 2017
https://qiita.com/advent-calendar/2017/ouch-hack
Scalaのvar, valとmutable, immutableについてのまとめ

## この記事は?
Scalaを勉強していて、var,val,mutable,immutableの組み合わせで理解に苦しんでいたところ、
@takc923さんの
[scalaのvar, valとmutable, immutableについて
](https://qiita.com/takc923/items/f62c173beacee280c369)
を読み、こちらの記事がとても参考になったのですが、最終的なまとめがなかったので、var,valとmutable,immutableの組み合わせのまとめを書こうと思った次第です。

## 前提
上の記事にもありますが、この前提を理解する必要があります。

```
var: 参照を変えることができる
val: 参照を変えることはできない
mutable: 要素変更後も参照が変わらない
immutable: 要素変更後は新しい参照を返す
```

## 組み合わせのまとめ
```
var & mutable:   参照を変えられるし要素変更後の参照は変わらないのでエラーにならない
var & immutable: 参照を変えられるので、要素変更後に新しい参照が返ってきてもエラーにならない
val & mutable:   参照は変えられないが、要素変更後の参照は変わらないのでエラーにならない
val & immutable: 参照は変えられないが、要素変更後に新しい参照が返そうとするのでエラーになる
```
Ruby on RailsでモデルをCSV出力させる


Railsで社内システム系のWEBアプリケーションを作りました。コマンドを扱えない利用者でもデータをいつでも可視化できるようにExcelなどのおなじみのUIで閲覧できたら良いなと思い、CSV出力を試みたので、方法をを紹介します。

##①CSVの出力は結構簡単
私も実は「Gemとか、configとか色々大変なんだろうな」と考えていました。しかしコントローラーで特別な処理を書く必要はありません。普段HTMLでしているように、csvはビューとして扱います。Formatが.csvに変わっただけです。Railsおそるべし。


####**コントローラ**
まず、コントローラーではHTMLに出力するのと同じように記載すれば基本的にOKです。

```ruby:app/controllers/admin_controller.rb
def users_to_csv
  @users = User.all
end
```
####**ルーティング**
```ruby:config/routes.rb
'admin/users.csv' => 'submit#users_to_csv'
```
ここまでは、DBをサーバーからビューで閲覧・操作させるときと変わりません。
特別な操作（それほど特別でもありませんが）はビューにやらせればOKです。
####**ビュー**
拡張子は`.csv.rb`ではなく`.csv.ruby`でファイルを記述してください。
(リテラルを使うとより効率的にコードが書けます。)
**[リテラルまとめ](https://docs.ruby-lang.org/ja/latest/doc/spec=2fliteral.html)**

```ruby:users_to_csv.csv.ruby
require 'csv'

CSV.generate do |csv|
  csv_column_names = %w(氏名 アドレス 番号 ステータス)
     #%w(氏名 アドレス)はrubyのリテラルの一つで、["氏名","アドレス"]と同値になります。

  csv << csv_column_names
  @users.each do |mic|
    csv_column_values = [
      user.name
      user.email
      user.tel
      user.status
    ]
    csv << csv_column_values
  end
end
```
##②ハマりやすい点
linkを指定する際に、`format: :csv`の指定が必要です！ネットに乗っているドキュメントをみる限り、かなり詳細に記載してくれているので、エラーが出る場合ここが最多なんじゃないかなと。

CSV出力のためのリンクは以下のように指定しましょう。

```html
<%= link_to('CSVをダウンロード','/admin/users.csv',{format: :csv}) %>
```

これで、PC用のブラウザでCSVファイルがダウンロードができます。UTF-8を指定している場合Excelで表示すると文字化けすることがあります。その対処方法に関しては次のリンクを参照してください。
http://global-wing.com/activity/csv_character_code.html
Unityコライダーまとめ

Unityのコライダーまわりについて少しまとめました

#主なコライダーの種類
##Static Collider(静的コライダー)

###コンポーネント
TriggerがオフのColliderのみ．Rigidbodyはつけない．

###仕様
**動かしてはならない**．Unityは動かすことをサポートしていない．
他のRigidbodyオブジェクトと衝突するが，自身は動かない．

###主な用途
床，壁など動かないオブジェクト．

##(非Kinematic) Rigidbody Collider
###コンポーネント
- TriggerがオフのCollider
- KinematicがオフのRigidbody

###仕様
物理演算が行われ，ほかのRigidbodyオブジェクトや静的コライダーと衝突することができる．移動は衝突や力によって動かす．**transformの変更で動かしてはならない**．

###主な用途
物理演算によって動かすオブジェクト．

##Kinematic Rigidbody Collider
###コンポーネント
- TriggerがオフのCollider
- KinematicがオンのRigidbody

###仕様
物理エンジンによる制御を受けない．よって，ほかのRigidbodyオブジェクトと衝突することができるが，自身はそのはね返りによる衝突後の回転や移動の影響を受けない．移動は**transformの変更で動かしてよい**．
IsKinematicをオンにすれば即座に物理挙動ができるため，爆発等で吹き飛ばされるキャラクターの手足にもデフォルトで用いられる．ただし，IsKinematicの切り替えはパフォーマンスコストがかかるため頻繁に行ってはならない．
また，**他の静的コライダー，Kinematic Rigidbody Colliderとは衝突しない**ことに注意．

###主な用途
スライドドアのように基本静的コライダーとして振る舞い，時々動かすものに用いる．


#IsTrigger
IsTriggerがオンになっていると，物理エンジンから無視されて衝突はできず，衝突の検出のみがOnTrigger~()でできる．

#IsKinematic
IsKinematicがオンになっていると，物理エンジンによる制御を受けない．

#衝突アクションマトリクス
Unityマニュアルには衝突の検出が行われるかどうかの組み合わせ表がある．つまり，OnCollision~()，OnTrigger~()のコールバック関数が呼ばれるかどうかの表がそれぞれ存在する．
[衝突アクションマトリクス（下のほう）](https://docs.unity3d.com/jp/540/Manual/CollidersOverview.html)

#CharacterController
###仕様
CharacterControllerを使った場合はColliderやRigidbodyは用いない．よってRigidbodyは呼ばれず，現実的な力による制御はされず，衝突のみができる．移動はCharacterController.Move()やSimpleMove()で行う．
衝突のコールバック関数は**OnControllerColliderHit()**であることに注意．

###主な用途
非現実的な挙動をするキャラクター等

#参考
- [Unityマニュアル-コライダー]
(https://docs.unity3d.com/jp/540/Manual/CollidersOverview.html)
- [Unityマニュアル-Rigidbody 概要]
(https://docs.unity3d.com/jp/540/Manual/RigidbodiesOverview.html)
- [Unityマニュアル-CharacterController]
(https://docs.unity3d.com/ja/540/Manual/class-CharacterController.html)
組合せ最適化でクリークを解く

Advent Calendar 9日目の記事 [組合せ最適化でチョコナを解く](https://qiita.com/SaitoTsutomu/items/6185510f01a615ba9ca5)
Advent Calendar 11日目の記事 [組合せ最適化でスターバトルを解く](https://qiita.com/SaitoTsutomu/items/8bc6342225a63fb68888)

## これなに

**クリーク**を、Pythonで[組合せ最適化](https://qiita.com/SaitoTsutomu/items/bfbf4c185ed7004b5721)モデルを作って解きます。
解く楽しみは、モデル化を工夫することになります。

自分でも試してみたい人は、下記を参考にしてください。

- [数独を通して組合せ最適化を学ぼう](https://qiita.com/SaitoTsutomu/items/bd09190d8a02432b3f16)

## 問題

- いくつかのマスを黒くぬります。
- 数字は、数字が隣接するマス中の黒マスの数を表します。
- すべての白マスは連結すること。

左が問題で、右が答えです。

![](https://raw.githubusercontent.com/SaitoTsutomu/opt4puzzle/master/pic/kuriku.png)

Pythonでは、`data`（数字ならばヒント）を使うことにします。

```py3:python
import pandas as pd, matplotlib.pyplot as plt
from pulp import LpProblem, lpSum, value
from ortoolpy import addbinvars, unionfind
data = """\
....1.
0.....
..3.4.
.2.12.
...1.1
......""".splitlines()
```

## 変数表

下記のような変数表を作成します。各行の変数(Var)は0または1をとります。
変数の値が1ならば、該当行 該当列のマスが該当の数になります。

<table><tr><th></th><th>行</th><th>列</th><th>Var</th></tr>
<tr><th>0</th><td>0</td><td>0</td><td>v000001</td></tr>
<tr><th>1</th><td>0</td><td>1</td><td>v000002</td></tr>
<tr><th>...</th><td>...</td><td>...</td><td>...</td></tr>
</table>

```py3:python
ni, nj = len(data)-1, len(data[0])-1
a = pd.DataFrame([(i,j) for i in range(ni)
    for j in range(nj)], columns=['行','列'])
a['Var'] = addbinvars(len(a))
a[:2]
```


## 数理モデルを作り解く

変数表ができたので、クリークの解になるように、制約条件を追加し数理モデルを作成し、解きましょう。

- 数字のヒントは、周りの黒の数。
- 白が連結していること。
    - 制約条件として書くこともできますが、大変なので、ここでは一旦無視して解きます。
    - 答えが連結していないときに、その答えを禁止して解き直します。
    - 連結しているかどうかは、`unionfind.isconnected`でできます。

```py3:python
m = LpProblem()
m += lpSum(a.Var)
for i in range(ni+1):
    for j in range(nj+1):
        if data[i][j].isdigit():
            q = f'{i-1}<=行<={i}&{j-1}<=列<={j}'
            m += lpSum(a.query(q).Var) == int(data[i][j])
while True:
    m.solve()
    r = a.Var.apply(value)
    if unionfind.isconnected((r!=1).values.reshape(ni,nj)):
        break
    m += lpSum(a[r==1].Var) <= (r==1).sum()-1
```

### 結果の表示

```py3:python
plt.imshow((1-r).values.reshape(ni,nj), cmap='gray', interpolation='none')
plt.show()
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/13955/4c8dc3ac-4e20-b552-058f-c95f6daa2c4a.png)

解けていることが確認できます。

以上
タートルグラフィックスでネコを描く

弊社のオフィスには7匹のネコがおり、その為かネコ好き社員が多く在籍している変わった会社となっております。斯く言う私もネコ好きなのですが、同じくらい亀も好きで、家にはクサガメとホシガメ(リクガメ)を飼っております。
今回はネコとカメをテーマにタートルグラフィックスでネコを描いてみます！

# タートルグラフィックスとは
画面上に表示されているカメに命令を与えて動きの指示を出します。カメが移動をすると軌跡が線となって描画されます。簡単な命令を組み合わせることで複雑な図形の描画ができるため、プログラミング学習の現場で使用されているそうです。
WindowsではPythonをインストールすればタートルグラフィクスが標準で使えます。

# まずはカメを動かしてみる
まずはカメを前進させてみます。タートルグラフィックスでは描画エリアの中央が(0 , 0)となっており、カメは0度(東)を向いています。この状態でforward(前進)の命令を与えてみます。

```py:forward.py
# coding: UTF-8

import turtle

wn = turtle.Screen()
tur = turtle.Turtle()
tur.shape("turtle")

# カメを100前進させる
tur.forward(100)

wn.exitonclick()
```

|![forward.png](https://qiita-image-store.s3.amazonaws.com/0/150944/d84c60eb-7082-6829-72b1-906dbf93a4d7.png)|
|:-:|

# カメの向きを変える
カメの向きを変える場合はsetheadingで指定します。引数は角度になりますが、少し癖があるので注意が必要です。【東(0度)、北(90)、西(180)、南(270)】
向きを変更して五芒星の描画を行います。

```py:star.py
# coding: UTF-8

import turtle

wn = turtle.Screen()
tur = turtle.Turtle()
tur.shape("turtle")

for i in range(5):

    # カメの向きを変える
    tur.setheading(i * 216)
    tur.forward(100)

wn.exitonclick()
```

|![star.png](https://qiita-image-store.s3.amazonaws.com/0/150944/0466887f-69ee-c2dc-6ff5-f2a6f2523124.png)|
|:-:|

# ネコを描画してみる
タートルグラフィックスでは上記で説明した命令以外にもたくさん用意されております（参考https://docs.python.jp/3/library/turtle.html#turtle.forward）
では実際にいろいろな命令を使ってネコを描画してみたいと思います。

```py:cat.py
# coding: UTF-8

import turtle

wn = turtle.Screen()
tur = turtle.Turtle()
tur.pensize(3)
tur.shape("turtle")

#　まるかいてちょん
def maru_chon(kame, i):
    kame.penup()
    kame.goto(50 * i, 100)
    kame.down()
    kame.circle(50)
    kame.penup()
    kame.goto(30 * i, 140)
    kame.dot(20)


# お豆に芽が出てて―
def omame(kame):
    kame.penup()
    kame.goto(0, 80)
    kame.down()
    kame.circle(20)
    kame.goto(0, 50)


# お空に三日月のぼってた
def osora_mikaduki(kame):
    kame.penup()
    kame.goto(0, 50)
    kame.down()
    kame.goto(80, 50)
    kame.setheading(90)
    kame.circle(80, -180)
    kame.setheading(90)
    kame.goto(0, 50)


# 植木鉢1
def uekibachi_1(kame):
    kame.penup()
    kame.goto(-100, 140)
    kame.down()
    kame.setheading(210)
    kame.circle(100, 120)
    kame.setheading(90)
    kame.setx(100)
    kame.setheading(30)
    kame.circle(100, 120)


# 植木鉢2
def uekibachi_2(kame):
    kame.penup()
    kame.goto(0, -70)
    kame.setheading(0)
    kame.circle(170, 50)
    kame.down()
    kame.circle(170, 260)


# ひげを付けたら
def hige(kame, i):
    kame.penup()
    kame.goto(90 * i, 80)
    kame.down()
    kame.goto(130 * i, 90)
    kame.penup()
    kame.goto(90 * i, 60)
    kame.down()
    kame.goto(130 * i, 60)
    kame.penup()
    kame.goto(90 * i, 40)
    kame.down()
    kame.goto(130 * i, 30)


maru_chon(tur, -1)
maru_chon(tur, 1)
omame(tur)
osora_mikaduki(tur)
uekibachi_1(tur)
uekibachi_2(tur)
hige(tur, -1)
hige(tur, 1)

tur.hideturtle()
wn.exitonclick()
```
|![neko.png](https://qiita-image-store.s3.amazonaws.com/0/150944/8b5e023d-b06c-b141-756b-c33182bddfe3.png)|
|:-:|

# 最後に
いかがでしょうか。とてもかわいいネコが書けたと思います。
タートルグラフィックは気軽に線画などが描画できるため、気分転換などにオリジナルの数式で幾何学模様を作ってみるのも楽しいかもしれませんね。
エンジニアがプレゼンテーションするときに気をつけること

これは、[「プレゼン研究会 Advent Calender 2017」](https://qiita.com/advent-calendar/2017/infrapre) 12/9分の投稿です。
（本投稿は個人の見解であり、所属企業とは関係がありません）

# 効果的なプレゼンテーションに必要なもの
効果的なプレゼンテーションに必要なのは、生来の性格や慣れではありません。**パッション（情熱）**と後から学習可能な**テクニック**です。
ここではテクニカルなトレーニングを実施してきた私の経験から、プレゼンテーションにおけるポイントをお伝えします。みなさんご自身のプレゼンテーションに取り入れていただき、技術を伝える人の輪がより広まると嬉しいです。

書いていたら長くなってしまったので、2回に分けたいと思います。今回は**プレゼンテーションの目的**と**効果的なプレゼンのための3つのポイント**について書きます。次回は6つの話し方テクニックと7つの話し方以外のテクニックについて書きます。

# 聞いた人にどんな行動を起こしてほしいのか明確にする
私たちはなぜプレゼンテーションをするのでしょうか？
それは **聞き手が新しい行動を起こしたくなるようにするため** です。
たとえばこういう行動を期待します。

- 自社に帰ってから新しく聞いたプロダクトを自分で動かしてみる
- プレゼンで聞いた内容を他の人にも広める

では人を動かすために必要なものは何でしょうか？
それは、まず **パッション（情熱）**。次に **プレゼンテーションテクニック** です。

以前、英会話の先生（カナダでTV通販をやってた）から「People buy People, not Products」という言葉を聞きました。人は製品そのものではなくセールスパーソンを見て製品を買うそうです。そこに必要なのは製品のスペックそのものではない。セールスパーソンが持つ「この製品はこんなに素晴らしい、これはあなたの人生を豊かにするのだ」という熱意なのだと。私も熱意のあるプレゼンには人を惹き込み、動かす力があると思います。

技術を人に伝えたい、と思った段階でパッションは十分にお持ちだと思います。そこで、プレゼンテーションの作成、実施においては、**そのパッションが相手に伝わったときに、どんな行動を起こしてほしいのか？を常に念頭においてください**。そうすることでプレゼンテーションは主旨が明確になります。テクニックは必要ですが、あくまでパッションを他の人が理解しやすくするためのツールにすぎません。

# 効果的なプレゼンのための3つのポイント
プレゼンを行う際に全体的に押さえておく3つのポイントがあります。
この内容はストーリーとして資料に入れる場合もありますが、慣れてくると口頭でもコントロールできるため、他人の資料で話す場合にも使えて便利です。

## なぜそのプレゼンテーションを聞く必要があるのか伝える
子供は与えられる情報を素直に学びますが、**経験と知識のある大人は自分が必要と思うもの以外は学習しない**傾向があります（成人学習の原則、でググってみてください）。
そこで、**プレゼンテーションの最初で、なぜ聴衆がこのプレゼンテーションを聞く必要があるのか、これを聞くことで何ができるようになるのか、何については話さないのか明確に伝えましょう**。聴衆が提示された題材に問題意識を持つようになり、話に乗ってきてくれるようになります。
これにはもう一つ効果があります。発表には一般的にタイトルが付きますが、聴衆にとって実際に何が話されるのかは始まってみないとわかりません。異なる期待値を持つ人に話すのは難しいものですが、最初に内容を伝えることで期待値を合わせ、プレゼンテーションの納得感を高めることができます。
複数トラックのあるカンファレンスではこれを徹底したほうが良いと思います。最初の導入を聞いて期待と合わなければ違うセッションに移っていただくよう誘導できます。

## 絶対に持ち帰って欲しい一言を選ぶ
プレゼンテーションは大量の情報を伝えるために適した方式です。一方で**人間は大量の情報を持ち帰ることは得意ではありません**。例えば60分のプレゼンを聞くことを考えてください。これを一言一句漏らさず聴き続けるのはかなりしんどい作業です。ふとした隙に大事な言葉を話されると思うと気も抜けません。**プレゼンには重要なところとそうでないところが必要**なのです。
そこで、**絶対に持ち帰って欲しい一言を決める**ことが効果的です。これにより自分がプレゼン中に脇道にそれてしまう可能性も減り、聴衆はプレゼンの主旨を明確に理解することができます。その一言はプレゼンの間、繰り返し伝えることになるため、聴衆がキーワードを聞き落とす可能性を下げることもできます。

プレゼンで情報を伝える際は、次のように人間の情報の受け取り方に合わせた方式を使うのが効果的です。

- **Whole-Part-Whole** （全体像が分からない情報は理解できない。 常に ①全体像を示し②個別の内容を説明し③再度全体をまとめる　の形で情報を提供する）
- **学習-体験-応用** （インプットだけによる情報は頭に定着しない。自ら手や口を使ってアウトプットし、自分で考えることによって情報を定着させる）
- **既知の情報と連携させる** （全く新しい概念は人の頭に残らない。身近な何かとの関連を示し、地続きになるよう情報を提供する）

## 受け手の目線に合わせて伝える
**既存の知識から離れた全く新しい概念は人の頭に残りません**。オンプレの硬めの運用経験しかない人にクラウド上の自動化されたデプロイの話をしても、現実味がなく「へー」で終わりです。新しい話をする場合は聴衆の既存の知識から地続きになるよう解説すると理解が進みます。私の場合プレゼンの最初に質問をして、聴衆のバックグラウンドを確認します。それに合わせて具体例を変えるといったことをしています。
聴衆の一人に経験を話してもらうことも効果的です。成人に対するプレゼンテーションでは、机上の抽象論ではなく、経験を元にした具体的な事例に対するケーススタディを行うことで、他人事ではない自分ごととして知識を得ることができます。

# まとめ
本エントリでは以下の内容について書きました。

- 聞いた人にどんな行動を起こしてほしいのか明確にする
- 効果的なプレゼンのための3つのポイント
  - なぜそのプレゼンを聞く必要があるのか伝える
  - 絶対に持ち帰って欲しい一言を選ぶ
  - 受け手の目線に合わせて伝える

次回はより具体的に、以下の内容について書きます。

- 話し方に関する6つのテクニック
- 話し方以外に関する7つのテクニック

# 参考資料
- [プレゼンは話術だけ磨いても絶対上手くならない](http://diamond.jp/articles/-/96928) MSのエバンジェリスト澤さんの記事。プレゼンを人の行動に繋げることについて詳しく書かれています。
- [WikiPedia - 学習学](https://ja.wikipedia.org/wiki/%E5%AD%A6%E7%BF%92%E5%AD%A6) 成人学習の原則について簡単な説明があります
Git運用体制について考察

## Outline
* まえがき
* masterは開発ブランチではない！！
* プロジェクトマネージャーがmasterを管理しろ！！
* コメントはソースではなく、プルリク内に書け！！
* 最終的なGit管理構成

## まえがき
仕事で利用していたGit運用体制に納得いかず、どんな運用方法が良いのかを考察したので、Qiitaにまとめようと思いました。

## masterは開発ブランチではない！！
自分のところの開発環境がmasterブランチのみで開発を行なっています。いや、それじゃ、SVNと変わらんやん。ブランチの概念理解してます？

* Gitのmasterブランチの位置付け
    * リリース可能な状態だけを管理する
    * 特定のブランチからマージすることによってしか更新されない
    * 直接コミットしてはならないという制約をもつ
    * バージョンごとのtagはここから生まれる

> 当たり前のようにmasterブランチは基本ですが、このブランチモデルにおけるmasterは、開発の主軸ではありません。このmasterは、今顧客に提供している価値そのものを表すブランチです。

**masterは主軸のソースであって、開発するソースではないんです！！**

## プロジェクトマネージャーがmasterを管理しろ！！
masterのみで管理していると、developerの方がmasterをいじれます。
先ほども言いましたが、Gitの概念を理解していない。
基本的にはPMの方がソースレビューを行い、git mergeを行います。
PMの方頑張ってください。

## コメントはソースではなく、プルリク内に書け！！
GitHub/GitLab/GitBucketには、プルリク(pull request)の機能があります。
プルリクでは、変更した箇所が色分けされており、そこに対しコメントを記述することができます。
色分け、UIによる差分を見ても可読性が向上します。

GitLabのリポジトリをブラウザで開いた[例](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/15821/diffs)です。
![GitLabのプルリク](https://qiita-image-store.s3.amazonaws.com/0/168051/c1208c52-4a6c-1290-130e-c9aaec54bca9.png "GitLabのプルリク")

## 最終的なGit管理構成
* PM
    * master管理
    * git merge
    * ソースレビュー
* PG
    * developer使用
    * git push
    * pull request

ざっとこんな感じですかね。
PMとPGは分けて考えないとGitの意味も権限の意味も理解していない。

## 参考
* [Gitブランチについての基本まとめ](https://qiita.com/katsunory/items/252c5fd2f70480af9bbb)
Deviseでusernameカラム追加時に，Rails4以降の正規表現でのバリデーションで気をつけたこと


Deviseに，usernameカラムを追加した時に，公式のwikiを見ててまずいな，と思ったポイントです．

[公式](https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address)では，追加したusernameのバリデーションに，次の正規表現を使っていました．

```ruby
# app/models/user.rb

# Only allow letter, number, underscore and punctuation.
validates_format_of :username, with: /^[a-zA-Z0-9_\.]*$/, :multiline => true
```

しかし，`:multiline => true`がセキュリティー的に問題です．なしだと，こうなります．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/83242/357458c3-4928-ed66-1829-7e34ef308210.png)

[Rails Guide (6.6)](http://guides.rubyonrails.org/security.html#regular-expressions)によると，Rails 4以降では，^,$ではなく代わりに\A, \zを使うことが推奨されています．なので，こう変えましょう．


```ruby
  validates_format_of :name, with: /\A[a-zA-Z0-9_\.]*\z/

```

参考:
http://jumperson.hatenablog.com/entry/2013/06/27/062237
http://guides.rubyonrails.org/security.html#regular-expressions
https://stackoverflow.com/questions/577653/difference-between-a-z-and-in-ruby-regular-expressions
chocolateyでruby on rails環境を構築

windowsでrails環境を整えようとした際にchocolateyという便利なパッケージ管理ツールを見つけたので、chocolateyでrails環境を構築するためのコマンドを書き置きします。
msys2まわりがネットで引っかかりにくかったので今回投稿しましたが、マニュアルにはちゃんと載っているので大したことはしてないです。

## コマンド
chocolatey導入済みから

```powershell
# ruby v2.4.2.2
cinst ruby

# msys2
cinst msys2 --params "/NoUpdate" # 非アップデート状態でインストール
refreshenv                       # or cmd/powershellの再起動
ridk install 2 3                 # ruby installer2 の 2 3 項目を実行

# rails関連
gem install bundle
gem install rails
```

## 参考サイト
[Chocolateyを使った環境構築の時のメモ](https://qiita.com/konta220/items/95b40b4647a737cb51aa)
[RubyInstaller2でRuby2.4 with Rails5の環境を作る～Nokogiriでエラー～](https://qiita.com/KTakata/items/1f30b8571764f7801708)
[chocolatey - MSYS2](https://chocolatey.org/packages/msys2)
【Spring Boot】受け付けたリクエストの後処理を実装する方法について調べた

外部サービスとの API ⇔ API な連携処理を実現する案件を担当することになりまして、
タイトルについて、いろいろと調査/実装したことをメモしておきます。

## 環境
* Spring Framework 4.2.4.RELEASE
* Spring Boot 1.3.2.RELEASE

## 要件
外部サービス側の担当者に以下のことを言われました。

* 必ず 200 OK を返して欲しい。  
200 OK 以外を受け取ると、監視に引っかかって運用コストが生じるのでヤダ

上記を受けて、こちら側の API を設計していたときに考えたのは以下です。

* リクエストを受け取ったらさっさと 200 OK を返す
* こちらが実装したい内部処理は 200 OK を返した後の処理として実装する

上記のようにしてしまえば、まず外部サービス側の要求には合うかなと。
こちらとしても、先に返すもの返してしまった方が気楽なので。
コードイメージは以下です。

```java:SampleController.java
@RestController
public class SampleController() {
    // 外部サービスからのリクエスト受付
    @RequestMapping(value = "/sample")
    public String sample(@Validated SampleForm form) {
        // レスポンスを返すための最低限の処理
        return "";
    }

    // 後処理(あくまでイメージ：この記事を読んでいくとこんな実装にはならない)
    private void after() {
        // レスポンスを返す以外に必要な処理
    }
}
```


## 実現方法

調査したところ、`HandlerInterceptor#afterCompletion()` によって実現できそうです。
以下の記事を参考にしました。
[Spring MVC(+Spring Boot)上でのリクエスト共通処理の実装方法を理解する](https://qiita.com/kazuki43zoo/items/757b557c05f548c6c5db)

`HandlerInterceptor` は後処理以外の用途に向けたメソッドも持つインタフェースですが、
今回は後処理のみ個別に実装したいため、
`HandlerInterceptor` の実装クラスである `HandlerInterceptorAdapter` を継承したクラスを用意します。
また、後処理という観点であれば `HandlerInterceptor#postHandle()` も候補に入りますが、
こちらは例外発生時には呼び出されないため、我々の要件に合わないことから、除外しました。
`HandlerInterceptor#afterCompletion()` は正常終了しようが例外が発生しようが呼び出されます。

```java:SampleInterceptor.java
public class SampleInterceptor extends HandlerInterceptorAdapter {
    // 正常終了時/異常終了時を問わず後処理のみ実装したいため afterCompletion() のみオーバーライド
    @override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler, Exception ex) throws Exception {
      // 後処理の実装
    }
}
```

次に、我々の要件では、上記コードイメージの `/sample` に対するリクエストだけに後処理を適用したいです。
これについては、上記の記事にもあります以下の実装で対応できました。


```java:WebMvcConfig.java
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
    // どうも Bean 登録しないといけない
    @Bean
    public SampleInterceptor sampleInterceptor() {
        return new SampleInterceptor();
    }
    @Bean
    public HogeInterceptor hogeInterceptor() {
        return new HogeInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(sampleInterceptor())
                .addPathPatterns("/sample"); // ここで対象を指定している
        // 複数の Interceptor を指定したければ並べて書く。チェインして複数パスの指定も OK
        registry.addInterceptor(hogeInterceptor())
                .addPathPatterns("/hoge").addPathPatterns("/huga")
        // 異なる Interceptor で同じパスを指定すると、両方の afterCompletion() が実行される
        // 実行順序がどう決められるかは未調査
                .addPathPatterns("/sample");
                
    }
}
```

以上で求める処理を実現できました。
`addPathPatterns` で対象を指定しない場合は、すべての Controller が後処理の対象になるようです。

実際のコードは上記のサンプルコードだけではなく、もう少しいろいろあるのですが、
書き留めておきたいことはこれぐらいで。
メッセージ指向、クラス指向、インターフェイス指向

# is 何
**オブジェクト指向の一種です。実装方針のひとつと言い換えることもできます**。
オブジェクト指向 (OO) は知っていてもこれらは知らないって人が多かったので、ざっくりとまとめてみることにします。

# メッセージ指向
アラン・ケイの「オブジェクト指向」。
……なんですが、これを説明するのは難しいです。
というのも、かなり**間違って広まった部分が多い**概念らしく、どれが正解なのかを掴むのが難しいので……

少なくとも重要なのはこのあたりでしょうか。

* 「オブジェクト」が「メッセージ」を送りあう。
* 「オブジェクト」は「メッセージ」を受けた時、その内容を解読して動作する。
* 「メッセージ」という形で「要求」あるいは「結果」を表現することで、それ以外のどうでもいい部分は二次的に決定する。

ある意味では、マイクロサービスはメッセージ指向に近いのかもしれません。
いやまあ、本来メッセージ指向上の「オブジェクト」というのはサーバやら何やらのメタファーらしいので、むしろそれそのものなんでしょうか？

Smalltalkあたりが有名ですが、これも"誤った"メッセージ指向の下に進化してしまっている、という声も聞いたことがあります。

参考:
https://ubiteku.oinker.me/2016/05/09/what-is-oo-all-about/

# クラス指向
ビャーネ・ストラウストラップ氏の「オブジェクト指向」。バートランド・メイヤー氏でもいいです。
(※前者はC++開発した人、後者は"契約による設計"を提唱した人)

「カプセル化」「継承」「多態性」という (今となっては古式ゆかしい) 三要素が必須とされています。
ストラウストラップ氏の本来の定義によると、これにコンパイル時型チェック機構、多重継承機構、アクセス制限（情報隠蔽）機構が続くとのことです。
……と、この時点で気づいたかもしれません。**これってまさにC++のことなんです**。
(なので、本当ならこの三要素も「抽象データ型」「派生」「仮想関数」と呼ぶべきかもしれないですね)

良くも悪くも今最も知られている「クラスと継承」モデルで、大多数のロースキルプログラマの知るOOはこれでしょう。「車」クラスから「カローラ」だの「ハイエース」だのを派生させるってアレです。
実際のところ、Cをベースに、オーバーヘッドを起こさないようにOOを導入するのであればどうしたってこういう風になるんだろうなあ、という意味で納得感のあるタイプです。
実際、クラス指向は静的に解決するのが非常に得意です。**だって定義にコンパイル時型チェック含んでるし**。
なお念のために言っておきますが、**Javaはクラス指向ではなく後述するインターフェイス指向に分類される言語です**。ジェネリクスとか型チェックろくなもんじゃないですし……

ちなみに、本来「クラス」なるものは**オブジェクト指向とは無関係です**。SIMULA (ALGOL系言語の一つ) に存在した言語機能だったとか。
そんな事情もあってかなくてか、オブジェクト指向を謳う言語やそれらに"使われる"ような者を「クラス指向」と揶揄することも少なくありません。

# インターフェイス指向
(これの提唱者って誰なんだろう？)
有名所では、クラス指向で紹介したバートランド・メイヤー氏の"契約による設計"に代表される、高凝集・疎結合を目指す設計思想です。**とりあえずJavaやC#はこれ**。

インターフェイス指向最大の特徴は**特性を示すことができる**点です。
例えば、

* Listインターフェイスを実装している。こいつはListとして扱えるはずだ。
* Comparableインターフェイスを実装している。ということはこの手順なら比較できるだろう。
* Runnable？なるほど、とりあえず実行できるんだな？

中身も見ていないのに「なるほどお前はそういうやつなんだな」となっているのがおわかりでしょうか。
中身を気にすることなく、「お前はこういう動作をしてくれるんだな」という「契約」のもとに話を進められるというのは、非常に大事なことなのです。**いちいち中身気にしないといけないとかやってらんないじゃないですか**。

なお、これが守られないと「**お前これポンドじゃねえか！キログラムで計算しろよ！**」なんて恐ろしい事態も起こります。
(なお、これは割と有名な航空事故の原因です。ギムリー・グライダーでググってみてください)

ところで、「これクラス指向でもよくね？」と思ったそこのアナタ。
鋭いですが、ちょっと惜しい。インターフェイス指向はクラス指向よりも**後付けしやすい**のが長所です。継承と違って、あくまで「私はこれができます！」というだけなのです。
「親子関係」なんてややこしいもの、気にしたくないでしょう？

# おまけ: プロトタイプ指向
スクリプト言語にたまーに見るやつです。Selfとかioとか。
「**なんでもかんでもクラスだなんだってやったらめんどくせえだろ！！**」
……と思ったかどうかはわかりませんが、あらゆるオブジェクトを「汎用変数の塊でできた可変な構造体」として捉えるのが特徴です。乱暴ですが、要するに「**オブジェクト=連想配列**(Mapとかテーブルとか)」と捉える形式です。
クラスのような「静的な設計図」は全て廃止され、オブジェクトの生成は「空っぽのオブジェクトを作る」または「今あるオブジェクトをコピーする」のどちらかで行われます。

なお、JavaScriptはprototypeという属性を持ち、世の中ではプロトタイプ指向と称されることがよくありますが**なんか微妙に違います**。
……ほんとにめんどくさい立場だなあこいつ。

参考: http://blog.anatoo.jp/entry/2015/05/05/163225
Ansibleでリモート上のJSONを読ませてwith_itemsで色々とする方法

# 概要
クローンしてきたリポジトリ内のpackage.jsonとかを読んで色々させるみたいな事をしたくなったら、思ったよりめんどくさかったので書き残しておく。

# catして結果をfrom_jsonに食わせる
実は公式ドキュメントにちらっと書いてあった。

```yaml
tasks:
  - shell: cat /some/path/to/file.json
    register: result

  - set_fact: myvar="{{ result.stdout | from_json }}"
```

[Filters#Filters For Formatting Data — Ansible Documentation](http://docs.ansible.com/ansible/latest/playbooks_filters.html#filters-for-formatting-data)

無理矢理だなって感じが否めないけど、まぁ読めるレベルなコマンド芸なので許容するかーって気分。

# 例: `files` という項目に記載されたファイルを移動する

`input.json`

```json
{
  "files": [
    "hoge.js",
    "fuga.html"
  ]
}
```

Ansible

```yaml
- name: read json
  command: "cat /tmp/hoge/input.json"
  register: json_string

- name: parse json
  set_fact:
    json_parsed: "{{ json_string.stdout | from_json }}"

- name: move object file
  command: "mv -f /tmp/hoge/{{ item }} /etc/deployed/{{ item }}"
  ignore_errors: true
  with_items: "{{ json_parsed['files'] }}"
```



# 余談: ローカル上のJSONを読ませたい
ローカル上のJSONを読ませたい場合は `lookup('file', 'var.json') | from_json` みたいに書くと良いらしい。
 
[reading json like variable in ansible - Stack Overflow](https://stackoverflow.com/questions/36728760/reading-json-like-variable-in-ansible)
ESLint v4.13.0

前 [v4.12.0] | 次 [v4.14.0]

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">ESLint v4.13.0 has been released: <a href="https://t.co/dNyRjqIUQw">https://t.co/dNyRjqIUQw</a></p>&mdash; ESLint (@geteslint) <a href="https://twitter.com/geteslint/status/939254950126936067?ref_src=twsrc%5Etfw">December 8, 2017</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ESLint 4.13.0 がリリースされました。
今回はバグ修正だけです。ただし、バグ修正によって ESLint の警告が増える可能性があるため、[私たちの Semantic Versioning Policy](https://github.com/eslint/eslint#semantic-versioning-policy) に則りマイナーバージョンが上がっています。

質問やバグ報告等ありましたら、お気軽にこちらまでお寄せください。

> 🏢 [日本語 Issue 管理リポジトリ](https://github.com/eslint/eslint-jp)
> 👫 [日本語サポート チャット](https://gitter.im/eslint/eslint-jp)
> 🏢 [本家リポジトリ](https://github.com/eslint/eslint)
> 👫 [本家サポート チャット](https://gitter.im/eslint/eslint)

# 🚀 本体への機能追加

特になし。

# 💡 新しいルール

特になし。

# 🔧 オプションが追加されたルール

特になし。

# ✒️ `eslint --fix` をサポートしたルール

特になし。

----

[v4.12.0]: http://qiita.com/mysticatea/items/149f48ac8483a8571197
[v4.14.0]: http://qiita.com/mysticatea/items/5a1ea63f71e51e334853
[#9999]: https://github.com/eslint/eslint/issues/9999
[xxxx]: http://eslint.org/docs/rules/xxxx

<!-- 
![JSCS Icon](http://jscs.info/favicon.ico) JSCS 互換ルールです。
-->
p5.jsで作ったダメなソリティア

[クソアプリ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/kuso-app2017) 10日目の記事です.


#成果物
ブラウザ上で表示するソリティアです。

[詰みティア](https://de-teiu.github.io/washed-up-klondike/)

<img width="638" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/173272/7c6413cb-297f-103c-745e-12bcaa4b0f33.png">

##遊び方
(ソリティアのルールについては割愛します。)

画面左上の山札をクリックすると、カードが３枚ずつめくれます。

最初に配置される７枚の札と、山札をめくった際に表示される３枚の内の先頭にあるカードは、
**ルール上一切動かせないカードになっています。**

##要するに
**最初から詰んでます。**

#何故こんなものを
ちゃんとしたソリティアを遊んでいる時に、「このゲーム、最初から詰んでるようなカードの配置ってあり得るんだろうか」と思ったのがきっかけです。

#実装
このクソアプリは[p5.js](https://p5js.org/)を使用して作りました。

ソースは[こちら(GitHub)](https://github.com/de-teiu/washed-up-klondike)にあります。

###(補足)p5.jsとは
processingという言語をjavascriptに移植したものです。わりとシンプルなコードでキャンバスに図形を描画したりアニメーションさせたりなどができます。

ブラウザ上で動くちょっとしたアプリを作りたいときなどにおすすめです。
Railsでuuidを取り扱う時のTips

Railsでidを `uuid` を取り扱う時に苦労したので、Tipsとして残しておきます。
そもそもuuidってなんなの！？というのは、適度にググってください。

## 開発環境

- Ruby: `2.3.1`
- Rails: `4.2.6`
- MySQL: `5.7.16`

Rails4系でuuidを使いたい場合は `activeuuid` というGemを入れると便利です。

```ruby
gem 'activeuuid'
```

Rails5からは、データベースマイグレーションの生成時にuuidをデフォルトの主キーに設定できる機能が追加されたので、そちらを利用してください。
https://railsguides.jp/5_0_release_notes.html

## 問題点

上記の方法でuuidを使っていると、実際のDB内にはバイナリ形式で保存されており、データベースからデータを取得したい場合にちょっと面倒な部分があります。

## モデル検索

こんなモデルがあったとします。

```app/models/book.rb
# == Schema Information
#
# Table name: books
#
#  id              :uuid(16)         not null, primary key
#  created_at      :datetime
#  updated_at      :datetime
#

class Book < ApplicationRecord
end
```

### find

何も意識しなくても、発行されたSQLを見ると、ActiveRecordがいい感じにしてくれる事に気がつきます。

```ruby
Book.find('d84e1955-b5c5-4b0f-b75f-1ab2db7359e2')
# Book Load (1.5ms)  SELECT  `books`.* FROM `books` WHERE `books`.`id` = x'd84e1955b5c54b0fb75f1ab2db7359e2' LIMIT 1
=> #<Book:0x007ff372ed5b30>
```

### where

`find` で上手く行ったからといって、whereではそうは行きません。

```ruby
Book.where('id = ?', 'd84e1955-b5c5-4b0f-b75f-1ab2db7359e2')
# Book Load (1.6ms)  SELECT `books`.* FROM `books` WHERE (id = 'd84e1955-b5c5-4b0f-b75f-1ab2db7359e2')
=> []
```

これは、こうする必要があります。

```ruby
Book.where('id = x?', 'd84e1955b5c54b0fb75f1ab2db7359e2')
# Book Load (0.5ms)  SELECT `books`.* FROM `books` WHERE (id = x'd84e1955b5c54b0fb75f1ab2db7359e2')
=> [#<Book:0x007ff36d15d480>]
```

MySQLでは `x` をつけることで16進数として検索をかける事ができます。

### ユースケースドリブン

さて、uuidを文字列として扱っていると、`-` が入った形式で取り扱う事になります。しかしながら、上記でもあるように、whereで検索したい場合 (primaryなのにそんなことあるのかというのは置いといて) 、エンドユーザーに対して、ハイフンは消してから検索してくださいというのはちょっと不便かも知れません。
その場合、次のように検索します。

```ruby
uuid = 'd84e1955-b5c5-4b0f-b75f-1ab2db7359e2'
condition = "
  CONCAT(
    SUBSTR(HEX(books.id), 1, 8),
    '-',
    SUBSTR(HEX(books.id), 9, 4),
    '-',
    SUBSTR(HEX(books.id), 13, 4),
    '-',
    SUBSTR(HEX(books.id), 17, 4),
    '-',
    SUBSTR(HEX(books.id), 21)
  ) = ?
"
Book.where(condition, uuid)
=> [#<Book:0x007ff36ecc32b0>]
```

なぜ、こんな面倒な事が起きたかというと、サービス運用をしているとカスタマーサポートでユーザー情報を取り扱う事が多々あり、お問い合わせメールにそのユーザーの識別子を付与したいというケースがあります。識別子というと、primary keyであるuuidをそのまま渡せば楽ですが、安全性の観点からMD5でハッシュ化した文字列を付与するケースがあります。
その場合、MD5でハッシュ化されてしまった文字列を使って、ユーザー情報を引っ張ってくるのはどうしたものかと四苦八苦しました。
その解決策が以下の通りです。

```ruby
uuid = 'd84e1955-b5c5-4b0f-b75f-1ab2db7359e2'
hashed_uuid == Digest::MD5.hexdigest(uuid)
condition = "
  MD5(
    CONCAT(
      SUBSTR(HEX(books.id), 1, 8),
      '-',
      SUBSTR(HEX(books.id), 9, 4),
      '-',
      SUBSTR(HEX(books.id), 13, 4),
      '-',
      SUBSTR(HEX(books.id), 17, 4),
      '-',
      SUBSTR(HEX(books.id), 21)
    )
  ) = ?
"
Book.where(condition, hashed_uuid)
=> [#<Book:0x007ff36e218068>]
```

MySQLでは、`MD5` という関数があるので、これを利用します。
これで、データベース内に存在するバイナリ形式のuuidを16進数に直して、ハイフンがある形に連結し、それをMD5で検索をかけるという事が実現できます。

他にもいい方法ありましたら、是非教えてください！
布製LEDリボンとNefryBTを連携するメモ

この記事は[Nefry Advent Calendar 2017](https://qiita.com/advent-calendar/2017/nefry)の12日目の記事です。

昨日は @minwinmin さんの「[研究室のみんなとNefry BTを使ってはじめIotデバイスをつくってみた \- Qiita](https://qiita.com/minwinmin/items/d1f296b8a9cd1a2c22f6)」でした、手軽に作れる試せるというNefryBTのメリットが、つくるということをチームづくりにマッチしてて、気持ちのよい記事でした！

さて今回お伝えするのは、布製LEDリボンとNefryBTを連携するメモです。

## 布製LEDリボンとは

布製LEDリボンとはスイッチサイエンスで発売されているものです。ATL SHOWCASEの<a href="https://atl-hiroo.recruit-tech.co.jp/showcase/archives/742" target="_blank">HoloTakibi</a>のIoT部分の検討中に購入しました。

布製LEDリボン - LED50個搭載 1m（赤色） - スイッチサイエンス
https://www.switch-science.com/catalog/3356/

テープLEDのようにカラー変更はできませんが、単色をすぐに使えるのが良いかなと思って買ってみました。

![cloth-led-nefrybt-qiita_01.jpg](https://qiita-image-store.s3.amazonaws.com/0/56170/1335e9af-64e8-5252-3164-b3ff138e08a0.jpeg)

炎になったらいいなと言う思いを込めて、赤色のを買いまして、届きました。

## 工作してみる

ということで、NefryBTのピンに刺さるように改造していきます。

![cloth-led-nefrybt-qiita_02.jpg](https://qiita-image-store.s3.amazonaws.com/0/56170/8e3c026e-5c1e-04c8-645a-dbf187c4c46c.jpeg)

末端のところに注目して剥いていきます。

![cloth-led-nefrybt-qiita_03.jpg](https://qiita-image-store.s3.amazonaws.com/0/56170/3accffa5-3048-a57c-bfd4-6ea27f558892.jpeg)

はんだ付けします。

![cloth-led-nefrybt-qiita_04.jpg](https://qiita-image-store.s3.amazonaws.com/0/56170/ae76210f-ae0e-39ea-50fd-7bb55142a78f.jpeg)

心もとないのでグルーガンします。安心。

![cloth-led-nefrybt-qiita_05.jpg](https://qiita-image-store.s3.amazonaws.com/0/56170/ee94f8f1-103d-436b-ca4b-3b53663fc28c.jpeg)

出来上がったので、まず基礎的な、Arduino UNO + Grove シールドで点灯してみます。きれい。

ここですでに、**VOUT（＋）とGND（ー）を逆にして配線をつけていた事がわかり、後述しますが、マスキングテープで残念な旗をつける羽目**になります。

## ソースコード

2本線で出来ているLEDなのでシンプルです。

```c
#include <Nefry.h>
int OUTPUT_PIN = D2;  // 出力ピン D2

void setup() {
  pinMode(OUTPUT_PIN, OUTPUT);
}

void loop() {
  digitalWrite(OUTPUT_PIN, HIGH);
  delay(1000);
  digitalWrite(OUTPUT_PIN, LOW);
  delay(1000);
}
```

## ということでNefryBTに布製LEDリボンをつけてみます

NefryBTに装着しました。

![cloth-led-nefrybt-qiita_06.jpg](https://qiita-image-store.s3.amazonaws.com/0/56170/7a7f17e1-e4e3-36b7-956b-47a74f9c953d.jpeg)

はい。大変残念なことに、赤と黒を逆のカラーでつけてしまったので、マスキングテープで残念な旗をつけました。

そのため、幸いにも、ピンにつける際は間違えずつけることが出来ました :laughing:  

## 実際に動かしてみます

上記のソースコードを書き込んで動かしてみます！

![cloth-led-nefrybt-qiita_07.gif](https://qiita-image-store.s3.amazonaws.com/0/56170/ae565c26-0d51-38a3-7cc3-51727d22f76d.gif)

無事点灯しました！

## まとめ

実は、これを試した際に「2本線の機材ってどう動かすんだろ？」という疑問があって、なんか追加機材とか回路が必要だったらやだな～と思ったのですが、特に苦労なく、単体のLEDを光らすような形で動かすことができました。

![cloth-led-nefrybt-qiita_08.jpg](https://qiita-image-store.s3.amazonaws.com/0/56170/634ec785-f145-699d-329b-2691a618fda1.jpeg)

明るいところで点灯するとNefryBT自体のLEDの光量に負けちゃってますが、暗いところなら良い感じに使えると思います！
実験スクリプトにLuigiを使う


論文を書くとき、実験が必ず必要になる。この実験にworkflowフレームワークのLuigiを使い始めたが、いい感じなので、布教しようかと思い記事を書いてみた。

# ほしかった要件
個人的に、実験スクリプトで求める要件としては以下のようなもの。

- デバッグ容易さ
- 処理の依存関係の制御
- 処理が完了しているスクリプトは再実行しない
- 処理ごとにIDの自動割り当て

今まで論文の実験はシェルスクリプト等を使っていたが、実験を追加していくとどんどんスパゲッティーになっていくし、上記の機能を全部自前で作るのは面倒。
ということで、Luigiを使って始めた。

Luigiの基本的な使い方は本家のチュートリアルを見るのがわかりやすい。
http://luigi.readthedocs.io/en/stable/example_top_artists.html

また、練習に私がいつも書いているような配列相同性検索の実験スクリプトを書いてみた。
https://github.com/shu65/sequence_alinger_evaluation


# 実際にLuigiを実験スクリプトに使った際に感じた良い点
ほしかった機能以外に感じた良かった点は以下の通り。

## Pythonのパッケージを活用できる
テンプレートエンジンであるJinjaやパラメータの列挙が簡単にできるsklearnなどのPythonのパッケージをそのままワークフローで活用できる。このため、特殊なconfigファイルを生成や、パラメータのグリッドサーチなども簡単にできる。

## 実行に特殊なサーバーがいらない
Pythonがあれば、基本的には実行できるので、特殊なサーバーを立てる必要がないので、ローカルでもぱっと実行できる。このため、試行錯誤が非常にしやすい


# Luigiを使った際に気を付けないといけないこと
あとから探索するパラメータを追加したい場合、コードを改良して、新しいパラメータを入力として加えるという変更を加えると思われるが、これをすると、すでに実行済みの処理も別ものとされ再度実行される。今回のサンプルでは特に対処しなかったが、この辺りを少し工夫しないと、実験に余計な時間がかかるので、実験スクリプトの作成には注意が必要。

# まとめ
Luigiを使った実験スクリプトのサンプルと、Luigiを使った良かった点等を紹介した。
是非、シェルスクリプトで疲れている人はLuigiを使って見るのを勧める。
もし、Luigiで合わなければ、Luigi以外のworkflowフレームワークもあるので、状況によってはそれも検討してみても良いかもしれない。
ネイティブアプリ と Progressive Web Apps ( PWA ) のどちらを選択するか

# はじめに
いずれ選択する際の指標として使うために書き出しました。
ぼちぼち追記するかも。

# ネイティブアプリ
Android や iphone などの端末自体で処理するアプリ。
大まかに分けてOS依存するタイプとWeb技術を用いるタイプの二つがある。
## OS依存するタイプ
Swift や Objective-C　など。

**メリット**

* ハードウェアの機能が使用できる
 
**デメリット**

* 違うOSに対応するのが辛い
 
## Web技術を用いるタイプ
React native や Weex など
**メリット**

* 広く使われているWeb技術(厳密には違う)を使える
* 必要に応じてハードウェアの機能も使える

**デメリット**

* Web技術で完結しない。
* Weexをちょっとだけ使ってみたが情報が少なくググるのが難しい

# Progressive Web Apps ( PWA )
最近巷で流行りの PWA 。Web技術だけを使ってスマホアプリっぽい動きを実現する。

* プッシュ通知
* オフラインで作業する
* ホーム画面にアイコンを追加する
* フルスクリーンで起動する
* クリップボードへのアクセス

など

### **メリット**
* 検索エンジンで見つかる
* リンクがあるので簡単に共有できる
* web技術で完結する

### **デメリット**
* ハードウェアアクセスに限界がある
* ~~safariの対応がまだ (2017/12/7時点)~~ ios11.3で対応するらしい

### PWA対応するのにみておきたいサイト

Google が pwa チェックリストを用意してくれているのでこれを満たすとよい。
[pwa checklist](https://developers.google.com/web/progressive-web-apps/checklist)
簡単に pwa を作りたい場合、Google がスターターキットを用意してくれている。
[web-starter-kit](https://github.com/google/web-starter-kit)
今日、web 技術でどこまでハードウェアアクセスできるのかがわかる。これをみるとあらゆるケースで PWA を選択できることがわかる。
[what web cando](https://whatwebcando.today/)

# おわりに
個人的にはPWAが流行って欲しい。
kotlinとかdart2とかもありなのかな？と思うけどその辺の界隈はまだよくわかりません。
Google HomeでChatworkにメッセージを投稿した

# 前置き
半額だったのでビックカメラで Google Home Mini を買いました。
Google Homeが一台あると、Google Assistantと[IFTTT](https://ifttt.com/)を連携してたくさんのことができます。
無駄にTwitterに投稿したり今日の予定を聞いたりできて、なんだか色々操ってる感じがして楽しいです。

そして購入してから一週間、しばらく遊んでいたのですが、ふと「思いついたことをよく見るところに残しておきたいな」と思ったわけです。
#前提
私はLINEでもSlackでもなく、Chatworkを日常的に使用しています。
またChatworkの「マイチャット」は簡単なメモやタスクをまとめるために常用しています。
LINEやSlackだったらIFTTTを使うだけですぐにGoogle Homeからの投稿ができるわけですが、
Chatworkはそれが無理なので、Google AssistantとIFTTTに加えて、「[Zapier](https://zapier.com/)」を使うことにしました。

IFTTTとZapierの連携には、Webhooksを使用します。
# Zapier側の準備1/2
まずはZapierでWebhookを受信する準備を行います。
Zapierでのアカウント作成が終わったら、「Make a Zap!」をクリックして新しいZapを作成しましょう。

![Zapier1.PNG](https://qiita-image-store.s3.amazonaws.com/0/220448/9e36f808-1c95-36f8-2f82-0dc200578556.png)
Choose Appでは、Webhookと検索して、「Webhooks by Zapier」を選択します。

![Zapier2.PNG](https://qiita-image-store.s3.amazonaws.com/0/220448/687a3ec9-b0c3-0cf5-9ad9-97b2874f77ee.png)
今回ZapierはWebhookを受信する側なので、「Catch Hook」を選択します。
次の「Set Up Options」は今回スキップします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/220448/d97844de-21a2-0236-4423-a2c3fbff6cc5.png)
設定が終わると、Webhookで使用するURLが表示されます。
IFTTTの準備で使用するのでメモを取りましょう。
Zapier側の準備1/2はここまでです。この設定中の画面は**閉じずに**次のIFTTT側準備を行いましょう。

# IFTTT側の準備
次はIFTTTの準備を行います。
アカウントの取得・Google AssistantとIFTTTの連携を行ったら、早速Appletの作成を行います。
下を参考にしてください。
thisにはGoogle Assistantを、thenにはWebhookを選択します。
![FireShot Capture 7 - If You say _マイチャットに $ を投稿_, then make _ - https___ifttt.com_applets_67212761d.png](https://qiita-image-store.s3.amazonaws.com/0/220448/b2f3f0fc-72b5-eab2-4585-bab46fa41eb7.png)
「Make a web request」の「URL」にはZapier側の準備でメモしたURLを記述します。
「Body」には今回、メッセージだけを送るので画像のようにmessageだけのJSONを書きます。
準備ができたら有効化してSaveしましょう。

# Zapier側の準備2/2
IFTTTの準備ができたら、ZapierでWebhookの受信テストを行います。
「Test Webhooks by Zapier」の画面に戻って、「OK, I did this」をクリックします。
そうすると、Webhook受信待ちになるので、このタイミングで
「**OK Google,マイチャットに テスト を投稿**」と発声しましょう。
自動的にZapierの画面が切り替わります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/220448/565a9477-2111-ce65-c8cf-1f608e840dfa.png)
Testが終わり、受信項目の選択を終えたらChatworkへの連携設定を行います。
「Choose an Action App」でChatworkを検索し、選択しましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/220448/f9070310-b85b-eb3e-5c82-354c8655222d.png)
今回はメッセージの送信を行いたいため、「Send Message」を選択します。

次の画面で、Chatworkとの連携設定を行います。
事前にChatworkのAPI設定からAPIキーを取得し、入力すると完了です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/220448/69750403-d012-e3db-7855-9cbe049bec68.png)
次にRoomを選択します。
連携したChatworkアカウントで使用しているルームが一覧表示されるため、
今回は目的の「**マイチャット**」を選択します。
Textには、WebhookのTestで使用したMessageを追加します。
またこのフィールドには定型文を設定することができるため、
Google Homeから送信したことがわかるよう、末尾に「[Send via Google Home]」を追加しました。

ここまで実施したら、あとはChatworkへの投稿テストを行って連携は終了となります。

IFTTTとZapierの連携方法がわかったら、もっとできることが増えそうですね！