OmniAICreator/Qiita-1.07M huggingface dataset:
PlayFab 2019年1月～3月アップデートのお知らせ☆

PlayFabのアップデートロードマップが出たので日本語訳してみました
原文は[こちら](https://blog.playfab.com/blog/upcoming-roadmap-2019-q1-jan-march-edition)

## Q4(2018年10月～12月)のアップデートのおさらい

**・古いCloudSciptの削除**
削除したい古いバージョンのCloudScriptを選択すると削除することが可能
![PlayFab2019Q1_01.png](https://qiita-image-store.s3.amazonaws.com/0/313446/377cff50-f4b4-8bb9-7ebf-781eb689c68e.png)

**・ランキングのアップデート**
ランキングのカスタマイズオプションの追加やパフォーマンスの向上など大幅にアップデートされました。
元々プライベートプレビューとして実装されていたので2019年Q1中には正式リリースされる予定。

**・User Generated Content (UGC)のプレビューリリース**
マインクラフトなどで実装されているユーザが作ったコンテンツを販売できる仕組みがプレビューリリースされました
まだプライベートプレビューなので利用にはPlayFabチームに連絡が必要そうです。

**・ベンチマーク**
これは2018年10月にすでにプレビューリリースされた機能で、PlayFabを使ってリリースされている他のタイトルとの比較をしながらリリースのタイミングを計ったりすることができるものです。
タイトルを登録するときに設定するタイトル情報が正確であればあるほど、同様のタイトルとの比較が可能になります。
データ自体は匿名なので、どのゲームの情報かや自分のデータの漏洩の心配はありません。
![PlayFab2019Q1_02.png](https://qiita-image-store.s3.amazonaws.com/0/313446/1d3f5073-caae-b9cb-3c61-c88655f37f28.png)


**・FaceBookのインスタントGamesとの連携**
2018年12月にFaceBookのインスタントゲームスとの連携が可能になりました
![PlayFab2019Q1_03.png](https://qiita-image-store.s3.amazonaws.com/0/313446/33d3a4df-d68b-4e4f-b713-46c9ae1f172d.png)


**・ゲームマネージャのローカライズ**
新たに ドイツ語, 日本語, 韓国語, 中国語がゲームマネージャ(PlayFabの管理サイト)で使えるようになりました
利用しているブラウザの言語から利用可能な言語が自動的に設定されますが、手動で設定することも可能です。
手動で変更する際はマイプロフィールから変更可能です。
  ![PlayFab2019Q1_04.png](https://qiita-image-store.s3.amazonaws.com/0/313446/5e94f168-bb87-a8b3-eeaf-a9b4defc8b66.png)

**・マルチプレイサーバのプレビューリリース**
もともとXBoxで実装されていた「Thunderhead」がPlayFabでも利用できるようになりました。
すでに昨年末パブリックプレビューされており、PlayFabチームに依頼すると実装することが可能
このあたりの仕組みは[こちら](https://qiita.com/ume67026265/items/317a308c6772dabdf625)にもちょっと書きましたのでご参考までに

2018年Q4アップデート予定だったけど実装できなかった項目に関しては、引き続き2019年Q1実装に向けて改善中です
・iOS GameCenter認証
・ギルドの名前検索
・VisualStudioAppCenter との連携

## 2019年Q1のアップデート
前置きが長くなりましたが、アップデート予定の項目です

**・ゲームマネージャの認証にAzure Active Directoryが利用可能に！！**
ゲームマネージャ(PlayFabの管理サイト)のアカウントをAzure Active Direcrotyで管理できるようになります。
個別のアカウントを登録して権限管理をしなくても、企業で利用しているAzureADを連携させて一元管理することができるようになります

**・CloudScriptにC#が利用可能に！！**
今までJavaScriptでしか書けなかったCloudScriptがAzure Functionsで動くようになることでC#にも対応できるようになります。それにより開発者が好きな言語を選んでVSCodeと連携したりデバックしたりできるようになります
今回はC#のみのリリースのようですが、おそらく今後段階的にAzure Functionに対応するほかの言語でも利用できるようになると思われます。

**・ギルドシステムの強化！！**
昨年実装したギルドシステムにより、さらにPlayFabとして柔軟にいろいろなことができるようになりました
このギルドシステムを利用して今後下記のことを実装します。
・ギルドの経済用API(いい訳がわからない・・・)
・ギルドのPlayStream
・ギルド検索
・ギルドのポリシー設定
・ギルドのSDKサポート

**・SDKの機能強化！！**
マルチユーザをサポートしたクライアントSDK、マルチインスタンスをサポートしたサーバSDK、PlayFabを使ったゲームクライアントの認証のベストプラクティスワークフォローなど機能強化を行っています。
まずはUnityのSDKから対応し、それ以外も今後追加されます

追加で
**・音声チャットシステムの実装**
GDC2019で詳細は発表されるようです
内容がわかったらまた書きたいと思います
Google Cloud Certified - Professional Cloud Architect を取得するために（６／６）

#概要
Google Cloudの認定資格の一つであるProfessional Cloud Architectを取得するまでの軌跡をリアルタイムで記事として記録していく。

#試験受験日
2019年2月5日（火）

#過去の記事
[第１回](https://qiita.com/shuichiro/items/a87f021f05fb8d558756)
[第２回](https://qiita.com/shuichiro/items/97e11704c46b10831cca)
[第３回](https://qiita.com/shuichiro/items/fe243a3e00a0965991a4)
[第４回](https://qiita.com/shuichiro/items/992fe9396e30967d5d17)
[第５回](https://qiita.com/shuichiro/items/9b7427fe82127166be60)

#やったこと
##書籍によるトレーニング
読破済

###タグによる通信制御のトレーニング
前回理解不足を感じた通信制御のためのタグだが、これは実際にCompute Engineにインスタンスを立てて実際に試すことでトレーニングを行った。VPCで設定したファイアウォールルールをどのインスタンスに適応するかというもので、タグでまとめることで「MySQL用のファイアウォール」というように便利に使えるようになる。VPCで設定するルールのターゲットをタグではなくサービスアカウントにすることもできる。

###Cloud Functionsのトレーニング
触ったことのないサービスを試す意味でCloud Functionsに実際にデプロイを行ってみた。Cloud shellを使って簡単にデプロイができ（かつ素早い！）サーバレスのメリットの実感ができた。ログの出力をすることでStackdriver Loggingへのログの出力のしかたもトレーニング出来た。


##公式ドキュメントによるトレーニング
書籍にないサービスは読破済

##公式模擬試験の受験
実施済、正答率50%

#GCPの理解度確認
総合的な理解度確認のために[GCP活用事例](https://cloud.google.com/customers/?hl=ja)をいくつかピックアップして読んでみて、課題に対する解決策としてのGCPサービスが頭に浮かぶかどうかを試していく。アーキテクチャ図が載っていないようなものはなるべく自分なりの理解でアーキテクチャ図を書いてみる。事例ピックアップの際はG-SuiteやGoogle Maps等の事例を除くため、画像通りのフィルタをかけて検索を行った。
![フィルタ](https://qiita-image-store.s3.amazonaws.com/0/168941/64c1f241-9224-77ca-7451-da1cae0e9820.png)


##ピックアップ事例１
[株式会社ナビタイムジャパン様の導入事例](https://cloudplatform-jp.googleblog.com/2018/01/Google-Cloud-Platform-navitime-kubernetes.html)
###課題
1. システム構築に時間がかかる
2. 更新が頻繁にあり容量の大きいデータがあり、データを各サーバに配布するのに時間がかかる

###GCPでの解決方法
1. Kubernetes Engineを採用し、システム構築にかかる期間を短縮した。予めアプリケーションはコンテナ化済だった。
2. Compute Engineに永続ディスクを利用することで複数インスタンスから参照可能になった。

##ピックアップ事例２
[株式会社バンダイナムコスタジオ様の導入事例](https://cloudplatform-jp.googleblog.com/2018/07/google-app-engine-bandainamcostudios.html)
###課題
1. スマホアプリのため突然の高負荷が発生し、WEBサーバのスケーリング・DBサーバのスケーリングを素早く行う必要がある
2. スケールアップ後の平常時の運用へ戻すために運用工数がかかる

###GCPでの解決方法
1. App Engine上にWEBサーバと同等の機能を開発して自動スケーリング、Datastoreを使用しDBサーバと同等の機能を自動スケーリングした。
2. 自動スケーリングのため、平常時へ戻す運用工数が削減された。

###予想アーキテクチャ図
（この図は筆者が導入事例を元に予想で書いた物で、実際の構成とは異なります。）
![予想アーキテクチャ図](https://qiita-image-store.s3.amazonaws.com/0/168941/12202542-0616-75b3-6387-892118b3d165.png)


#感想
いくつか事例を読んでも「なんだっけ、このサービス？」といったものは無かった。App Engineを使っての運用工数削減する事例が多かったように思える。そういった事例ではStackdriverでログが一元的に見やすくなったといった副次的な効果を活用していることが多かった。
一通りやれることはやったと思う。あとは来週の本番に向けて、トレーニングしたことが頭から抜けていないか記事を振り返り読んで思い返していきたい。
templateの数値引数に制約をかける

整数管理クラスを作る時、最大値と最小値をtemplate引数に持ってきて、その最大値と最小値の大小関係の制約をかけたかったんですが、templateの開きカッコと閉じカッコ扱いされてできなかったのでこれ作りました

```cpp:Compassion.hpp
#ifndef __COMPASSION_HPP__
#define __COMPASSION_HPP__
#include <type_traits>

namespace standard {
	namespace compassion {
		namespace {
			template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
			constexpr bool large_impl(const T a, const T b) { return a > b; }
			template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
			constexpr bool small_impl(const T a, const T b) { return a < b; }
			template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
			constexpr bool e_large_impl(const T a, const T b) { return a >= b; }
			template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
			constexpr bool e_small_impl(const T a, const T b) { return a <= b; }
			template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
			constexpr bool eq_impl(const T a, const T b) { return a == b; }
			template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
			constexpr bool ne_impl(const T a, const T b) { return a != b; }
		}
		template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
		constexpr bool large = large_impl<T>(a, b);
		template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
		constexpr bool small = small_impl<T>(a, b);
		template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
		constexpr bool e_large = e_large_impl<T>(a, b);
		template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
		constexpr bool e_small = e_small_impl<T>(a, b);
		template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
		constexpr bool eq = eq_impl<T>(a, b);
		template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
		constexpr bool ne = ne_impl<T>(a, b);
	}
}
#endif
```
これを作るのに参考にしたのは、std::is_arithmetic_v等の実装です

使い方はこんな感じですね

```cpp:sample.cpp
template<typename T, T max, T min, std::enable_if_t<std::is_arithmetic_v<T> && standard::compassion::e_large<T, max, min>, std::nullptr_t> = nullptr>
class Integer {
	// 実装を記述する
};
```
compassionの変数たちのtemplate引数の片方を数字にしても使えます。ただし、floatとdoubleは使えません
Swiftでカスタムエラー実装するときはLocalizedErrorプロトコルに準拠させると良い

Swiftでカスタムエラーを実装ときたら、何も考えず`Error`プロトコルに準拠させたEnum型として実装してましたが、ある時想定したエラーメッセージが表示できてないことに気づきました。

以下はRxSwiftで実装したコードです。
ViewModel.errorsは`Signal<Error>`型のプロパティで、様々なエラーイベントが流れてきます。
そしてUIAlertControllerでエラーメッセージを表示させています。

```swift
viewModel.errors
    .emit(onNext: { [unowned self] in
        let alert = UIAlertController.makeErrorAlertController(error: $0)
        self.present(alert, animated: true)
    })
    .disposed(by: disposeBag)
```

流すエラーは例えばこんな感じで、`Error`プロトコルに準拠させたEnumです。

```swift
enum AppError: Error {
    case unknown

    var localizedDescription: String {
        switch self {
        case .unknown: return "unknown error happened"
        }
    }
}
```

このエラーがViewModelから流れてきて画面にエラーメッセージを表示させる（`localizedDescription`プロパティを参照する）と、、

```
The operation couldn’t be completed. (Example.AppError error 0.)
```

`unknown error happened`になってない。
まあよく考えれば当たり前で、このメッセージは`AppError`型の`localizedDescription`で実装されているのであって、ViewModelから流れてくるのは`Error`型なので`localizedDescription`のデフォルト実装によってメッセージが生成されてこの形になっています。

表示ロジックは変えずに`localizedDescription`で自分が定義したメッセージを表示できるようにするには、`LocalizedError`プロトコルに準拠させると良いです。

```swift
enum AppError: Error {
    case unknown
}

extension AppError: LocalizedError {
    var errorDescription: String? {
        switch self {
        case .unknown: return "unknown error happened"
        }
    }
}
```

`errorDescription`プロパティを実装すると、`Error.localizedDescription`はこのプロパティを参照してくれます。

これで画面に`unknown error happened`というメッセージが表示されるようになります。
PyCharmでjupyter notebookを使用する方法（Windows10）

私を含めた超初心者向けの備忘録です。
PyCharmの補完機能・文字色に慣れている方や、.ipynbと.pyを同時に編集するときに便利かもしれません。

###環境
python 3.6.8および3.7.2
PyCharm 2019.1 EAP Community Edition（日本語化済み）
jupyter 1.0.0


###要約
プロジェクトインタープリターを設定
↓
jupyter notebookをインストール
↓
ターミナルからjupyter notebookを起動し、ノートブックサーバーのアドレスをコピー
↓
ipynbファイルを開いて実行すると、サーバーアドレスを要求されるので貼り付け


以下は、Python3.7とPyCharmをインストールした直後の場合です。
#プロジェクトインタープリターの設定
ファイル→設定→プロジェクト:（プロジェクト名）→プロジェクト・インタープリター→右上の![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/352531/8d59659d-e721-a2f0-da4c-bc7e935f3ce6.jpeg)ボタン→追加。
ベースインタープリターに使用するPython.exeを選択。

#jupyter notebookのインストール
ファイル→設定→プロジェクト:（プロジェクト名）→プロジェクト・インタープリター→右端の「+」ボタン→「jupyter」を検索・選択し「パッケージをインストール」。

#jupyter notebookの起動
左下のターミナルを開き、「jupyter notebook」と入力すると、以下のように表示されます。
同時にブラウザが起動しダッシュボードが開きます（現在のPyCharmプロジェクトのフォルダがルートディレクトリになります）。
![キャプチャ2.JPG](https://qiita-image-store.s3.amazonaws.com/0/352531/cfa65eed-c54f-b85e-17e6-b9bdf881f3cc.jpeg)
上の画像で青字で表示されているjupyterサーバーのアドレスをコピーしておく。
ipynbファイルを実行（Shift+Enterや緑の▶ボタン）すると開くポップアップにアドレスを貼り付け。
Deployerのssh接続設定

## イントロダクション
DeployerはPHP製のデプロイツールです。これを使うことでFTPでの手動公開でありがちな公開時のファイル漏れや、部分的なファイルアップロードによる公開途中の不具合などをかなり減らすことができます。また、過去バージョンを保存する機能により、公開後のロールバックにも対応します。
この設定において、ssh接続設定のところで少し複雑な部分があったため、忘れないようにメモしておきます。

## Deployerの仕組み
公開はローカルPCからのコマンドにより実行しますが、サイトへの公開はローカル環境からではなく**Git上のデータを公開**します。
そのため、Gitの利用は必須となります。（ただしGithubではなくても、BitbucketやオンプレミスのGitなどでも問題ありません。）

## 設定
Deployerの基本設定はいろいろなサイトに記載がありますので、ここでは省略して、ssh周りの設定に絞ります。
DeployerにはローカルPC、Git、公開サーバーの各接続にsshを利用します。

具体的には以下の2点を設定します。

* deployを実行するローカルPCの公開鍵を公開サーバーに登録
* 公開サーバーの公開鍵をGitに登録

### ローカルPC - 公開サーバー
ローカルPCでRSA暗号の鍵を生成します。

```ローカルPC.
$ ssh-keygen -t rsa
```

生成が完了したら、下記コマンドで確認します。

```ローカルPC.
$ ls ~/.ssh
id_rsa id_rsa.pub
```
相手先(公開サーバー)のauthorized_keysに自身(ローカルPC)の公開鍵(id_rsa.pub)を登録します。
SCPコマンドを使って、サーバー間転送を行います。こんな感じで記述します。

```ローカルPC.
// scp [公開サーバーのユーザ名]@[公開サーバーのホスト名]:~/.ssh/id_rsa.pub .
$ scp public@public-server.com:~/.ssh/id_rsa.pub .
```

転送が完了したら、公開サーバー側でauthorized_keysにキーを追加します。（その後id_rsa.pubを削除）

```公開サーバー.
$ cd ~/.ssh
$ cat id_rsa.pub >> authorized_keys
$ rm id_rsa.pub
```

パーミッションを600に変更します。

```公開サーバー.
$ chmod 600 authorized_keys
```

以上の設定が完了したら、ローカルPC - 公開サーバーの設定は完了です。
以下コマンドで接続テストを行います。

```ローカルPC.
// ssh -l [公開サーバーのユーザ名] -i [秘密鍵のパス] [公開サーバーのホスト名] -p [sshのポート番号]
$ ssh -l public -i ~/.ssh/id_rsa public-server.com -p 22
```

### 公開サーバー - Git
こちらも同様にキーを設定します。
キーの生成は先の手順と同様に、今度は公開サーバーにて公開鍵、秘密鍵を生成します。

```公開サーバー.
$ ssh-keygen -t rsa
```

Gitへの登録はファイル転送ではなくブラウザからコピペで登録します。

```公開サーバー.
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0zaFz1R4V27....

↑これを丸々コピペ
```

Gitをブラウザから開いて、ユーザーのプロフィール設定からSSH鍵登録を行います。
(**プロジェクトのSSH鍵登録ではないので注意！**)
登録が完了したら接続テストを行います。

```公開サーバー.
GitHubなら
$ ssh -vT git@github.com

BitBucketなら
$ ssh -T git@bitbucket.org

```
logged in as …の表示が出ればOK。
知識ゼロから簡単なWebページを作成できるようになるまでのHTML/CSSの勉強方法について

今回は、僕が全くの知識ゼロの状態から、簡単なWebページを作成できるようになるまでにどのようにHTML/CSSを勉強したのかについて書いていきたいと思います。

まず、
僕がHTML/CSSや、Javascript、jQueryなどといった、フロントエンドの言語の存在を知ったのが、現在作成中の学内施設のWebページを作ると決まってからでした。
僕は情報系の学科で、講義の中でバックエンド(Java,C)については勉強をしていたのですが、当初は、フロントエンドについての知識は全くなく、そもそも、JavaやCがバックエンドの言語であり、HTML/CSSとは役割や動作が変わるということも全く知りませんでした。


そこで、まず、一緒にWebページを作成している先輩に前提知識として、

○フロントエンドとバックエンドについて
・フロントエンド：ユーザーなどと直接やり取りをする要素
→見た目を決定する。開発するときは、変化が直接見れるので、比較的容易。
ex)HTML,CSS,Javascript,jQuery,React.js
・バックエンド：フロントエンドの入力データや指示をもとに、処理を行って結果を出力したり、記録媒体に保存したりする処理
→ユーザーが入力したデータを裏でこっそり処理して、出力する。裏で処理をするため、変化が見えづらいため、比較的難しい。
ex)Java,C,Python,Ruby,Perl

○フロントエンドの言語について
・HTML: 記事のテキストを書く→”What”の部分
・CSS: テキストに加工を入れる→”How”の部分
・Javascript: テキストに動きをつける→"How"の部分
・jQuery,React.js: Javascriptの動きをいくつかまとめて簡単に動きをつけられるようにした辞書(ライブラリという)。他にもいろいろあり、それぞれエフェクトを付けるのが得意だったり、処理が速かったりするので、用途によって使い分ける。jsはJavascriptの略。
・Vue.js,Angular:　フレームワーク。枠組み。開発を簡単にできるんだと思う。他にもいろいろあると思う。この記事を書く上で初めてライブラリと別物だと知ったので、説明は省く。

これを覚えておきましょう。


そして、ここからは僕が実際にした勉強について、

僕がしたのは、
・『作りながら学ぶ HTML/CSSデザインの教科書』を読む→実際にコードを書く。
⇒王道のWebページの作り方や注意点について学ぶ
・Progate有料版を登録(月額980円で学び放題)→HTML/CSSのコースを修了
⇒より実践的な練習で基本をおさらいしながら、仕様書を元にWebページを作成し、細かい部分の注意点について学ぶ

以上、2点です！！！
この2つをしたらある程度のものは作れるようになると思います。というか、HTML/CSSについて概要がわかるので、あとはわからないところは開発過程でググれれば大丈夫です。
そもそも、フロントエンドの言語は見た目で変化がわかりやすいことから、参考コードがネットに上がっているので、それらをコピー＆ペーストするだけである程度のものが作れるので、自分で書けなくても、コードを読めたらWebページ作成を始めちゃってもいいと僕は思います。
そのほうがモチベも保てますし◎

そして、今は、
・ProgateでJavascriptのコースを受講中
です。

今後は、学内施設のWebページを作成しながら、Webページの作成案件を受注していきたいと思っています。

そのために、勉強、開発、アウトプットの日々ですね◎
Python環境をDockerを用いて整えてみた

環境：MacOS 10.12.6

###前準備
公式サイトからDockerをインストール


きちんとインストールされたか確認します。


```
$ docker --version
Docker version 18.03.1-ce, build 9ee9f40
$ which docker
/usr/local/bin/docker
```

入ってますね。

次にimageをpullします。

```
$ docker pull python:3.7
```

```
Status: Downloaded newer image for python:3.7
```
この表示が出たらsuccessです。場合に応じてコマンドの頭にsudoをつけてください。


###コンテナを起動する

```
$ docker run -it --name pydock python:3.7 /bin/bash
```

環境が整ったことを確認します。

```
＄　python --version
Python 3.7.0
```
##SUCCCESS!!

```
# apt-get update
# apt-get install -y vim
```
headlessをつけると要素が取れないとき

# 私がしたかったこと
 * `driver.find_element_by_link_text('メニュー').click()`といった感じで、
  リンクテキストを用いて要素をクリックしたい
 * headlessをつけたい

# ところがどっこいエラーが発生
エラー内容は、
リンクテキストをクリックするところでの、`NoSuchElementException`

でもheadlessをつけないとエラーは出ず。

# 解決法
言語設定してあげることで１発で解決。

```
options = ChromeOptions()
options.add_argument('--headless')
options.add_argument('--lang=ja-JP')

driver = Chrome(options=options)
```

`options.add_argument('--lang=ja-JP')`の言語設定をしてあげることで、
headlessをつけても無事動くようになりました。
puppeteer でスクレイピングするサーバを Now を使って作る方法

Now(ver 2)で Doker を使わずに puppeteer が動くようになりました。
[Serverless Chrome via Puppeteer with Now 2.0](https://zeit.co/blog/serverless-chrome)

この記事では puppeteer を使ってスクレイピングした結果を返す API を作りました

## 注意

2019 年 1 月 29 日現在、`yarn`だとデプロイに失敗します。(issue はまだないかも)
使うときは`npm`を使って`package-lock.json`がある状態でデプロイしてみてください。

## 全体のソース

ざっくりとしたソースを載せておきます

### package.json

`puppeteer`の代わりに`puppeteer-core`と`chrome-aws-lambda`を使います

```json
{
  "name": "",
  "version": "1.0.0",
  "main": "server.js",
  "license": "MIT",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "body-parser": "^1.18.3",
    "chrome-aws-lambda": "^1.11.2",
    "express": "^4.16.4",
    "express-validator": "^5.3.1",
    "puppeteer-core": "^1.11.0"
  }
}
```

### now.json

`builds`の`config`で`maxLambdaSize`を指定しておきます

```json
{
  "version": 2,
  "name": "<アプリ名>",
  "alias": "<必要であれば>",
  "builds": [
    {
      "src": "server.js",
      "use": "@now/node-server",
      "config": { "maxLambdaSize": "40mb" }
    }
  ],
  "routes": [{ "src": "/(.+)", "dest": "/server.js" }]
}
```

### server.js

```JavaScript
// Express
const express = require('express');
const bodyParser = require('body-parser');
const app = express();

// Express-validator
const { check, validationResult } = require('express-validator/check');
const { matchedData } = require('express-validator/filter');

const { getNewBooksList } = require('./chromium');

// Support parsing of application/x-www-form-urlencoded post data
app.use(bodyParser.urlencoded({ extended: true }));

app.get(
  '/',
  [check('type').exists(), check('ndc').exists()],
  async (req, res) => {
    const errors = validationResult(req);
    if (!errors.isEmpty())
      return res.status(422).json({ errors: errors.mapped() });

    const valid = matchedData(req);
    const type = valid.type;
    const ndc = valid.ndc;

    const booksList = await getNewBooksList(type, ndc);

    res.json(booksList);
  }
);

app.listen(3000, () => console.log('App listening on port 3000!'));

module.exports.app = app;

```

### chromium.js

`puppeteer.launch`のオプションの指定が異なるので注意

```JavaScript
const chrome = require('chrome-aws-lambda');
const puppeteer = require('puppeteer-core');

async function getNewBooksList(bookType, bookNdc) {
  const browser = await puppeteer.launch({
    args: chrome.args,
    executablePath: await chrome.executablePath,
    headless: chrome.headless
  });

  const page = await browser.newPage();
  await page.setViewport({ width: 1280, height: 800 });

  //各自の処理を入れてください

  await browser.close();

  return booksList;
}

module.exports = { getNewBooksList };

```

## あとがき

公式のサンプルはこちら
[now-examples/puppeteer-screenshot/](https://github.com/zeit/now-examples/tree/master/puppeteer-screenshot)

Now を使うと無料で動かせるので、簡単なスクレイピング API をデプロイするなら選択肢の一つになるかと思います。
ActiveRecordの属性を変えずにupdateしてもupdated_atは更新せず、余計なSQLを発行しないので便利

## 概要
ActiveRecordを継承したモデルで属性値を変えずにupdateメソッドを実行しても、更新するSQL自体実行しない。
更新日付のupdate_atも更新されない。

`モデルの値を変えない`というのは明示的に属性値を`変える前と同じ値を代入`しても同様に更新するSQL自体実行しない。

### 前提条件

Rails: 5.2
Ruby: 2.5.1

# 本題
サンプルのユーザテーブルの定義

```
create_table :users do |t|
  t.string :name
  t.timestamps
end
```

ユーザモデルの定義

```
class User < ApplicationRecord
end
```

サンプル用に適当なUserモデルを作成しupdated_atを表示する

```
User.first.updated_at
=> Tue, 29 Jan 2019 03:56:08 UTC +00:00
User.first.updated_at.to_i
=> 1548734168
```

name属性を、Userモデルに元々入っていた値でupdateする。
後述する変更した場合と比べると、UPDATE文のSQLが実行されないことがわかる
実行結果のupdated_atが、updateメソッド実行前のupdate_atと同じ1548734168で有ることがわかる

```
> User.first.update!(name: User.first.name)
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
   (0.1ms)  begin transaction
   (0.0ms)  commit transaction
=> true
irb(main):008:0> User.first.updated_at.to_i
=> 1548734168
```

検証ついでにname属性の値を変更すると、UPDATE文のSQLが実行され、updated_atの値が更新されることがわかる

```
> User.first.update!(name: User.first.name + "1")
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
  User Load (0.2ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
   (0.1ms)  begin transaction
  User Update (1.3ms)  UPDATE "users" SET "name" = ?, "updated_at" = ? WHERE "users"."id" = ?  [["name", "テスト1"], ["updated_at", "2019-02-01 08:27:12.468565"], ["id", 2]]
   (2.9ms)  commit transaction
=> true

> User.first.updated_at.to_i
  User Load (0.3ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
=> 1549009632
```
Intel Parallel Studio XE Composer EditionをoFで使うまでの覚書

環境
* MacBook Pro (15-inch, 2016)
* macOS High Sierra 10.13.6
* Xcode 9.4.1
* Intel Parallel Studio XE Composer Edition for C++ macOS [2019.1.034]
* openFrameworks 0.10.1 osx release

## インストール

* Xcode10.1は対応してないっぽいので共存させてたXcode9.4.1を指定した
    * 10.0なら対応してるようなので10.0にした方が良かったかも...？

## ビルド設定

Build OptionsのCompilerでICC Intel C++が選べるようになってるので選んで

<img width="649" alt="スクリーンショット 2019-02-01 17.12.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/4206/99f5949a-1867-7a53-02ea-38cfaa2e22bf.png">

ICC Intel C++の設定項目でC++11を選択. C11は取り敢えず選んでみた.

<img width="729" alt="スクリーンショット 2019-02-01 17.11.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/4206/6835ab78-9b31-37df-d702-00e67dec54ec.png">

これで普通にビルド出来た. 想像以上に簡単過ぎて拍子抜け.

ただ, これだとXcode 9.4.1でしか使えない.
そのうちオフィシャルで対応されるんだろうけど, 設定ファイル弄れば10.1でも使えそうなので調べてみる.
fuzzy finderのイディオム(?) : Self list-select-do

# fuzzy finderの便利な使い方

...だと思う定型をメモしますが、イディオムというほどのものじゃない(本来用途なだけ)気はします。

同一コマンドのリスト出力を入力引数に転用するパターン、と言えるかなと。

## 例
### getignore
```sh:getignore-select.sh
#!/bin/sh
# need backslash escape? ... currently not use backslash
if which fzf >/dev/null 2>&1; then
  getignore list | fzf -m --prompt="gitignore\\> " | xargs -r getignore get
elif which peco >/dev/null 2>&1; then
  getignore list | peco   --prompt="gitignore\\> " | xargs -r getignore get
else
  echo "selector not found"
fi
```

`getignore` はオンラインの定義を呼んできてリスト出力でき、それを指定するとgitignoreファイルの定義を出力してくれます。

### gopass
```sh:gopass-select.sh
#!/bin/sh
if which fzf >/dev/null 2>&1; then
  # # use null sep
  # gopass ls --flat | fzf  --prompt="password-store > " --print0 | xargs -0 -n 1 -r gopass --clip --yes show

  # use sed escape backslash
  gopass ls --flat | fzf  --prompt="password-store\\> " | sed -e 's/\\/\\\\/' | xargs -n 1 -r gopass show -c
elif which peco >/dev/null 2>&1; then
  # use sed escape backslash
  gopass ls --flat | peco --prompt="password-store\\> " | sed -e 's/\\/\\\\/' | xargs -n 1 -r gopass show -c
else
  echo "selector not found"
fi
```

`gopass` は [Pass: The Standard Unix Password Manager](https://www.passwordstore.org/) のgo実装で、Windowsでも動くもので、秘密鍵をサブフォルダに格納できるためバックスラッシュ対策しています。

## 要点
- フラットなリストを出力する
    - サブコマンドリストも可
- pecoやfzfに食わせる
    - ファイルなどなら複数選択できる場合もあるが、逆にサブコマンドは不可なのでmulti選択はoffにするand/or`xargs -n 1`で抑制
- 必要な途中処理をしてから、コマンドの引数として与える
- キャンセル時動作として 「`xargs -r`で引数0個で実行しない」にして、例外的な挙動を抑制
- ファイルパスごと渡すものは、Windowsでのバックスラッシュに注意する、できればnullターミネートを`xargs -0`で処理するのがいいが、`fzf --print0`や[findとxargsコマンドで\-print0オプションを使う理由\(改\) \- Qiita](https://qiita.com/maskedw/items/2dfdf6fa7eee991ddc45)にあるようにfindコマンドとくらいしか連携できる例はしらないのがツラい所...
    - 挙動については[xargsのオプション無し、\-Iオプション、\-0オプションの挙動に関する勘違い \- Qiita](https://qiita.com/takc923/items/da1c32f3a622dc1c5489)を参照
Gradle5で依存jarをコピーする

# Gradle5にしたら動かなくなっちゃった
パパから貰ったクラリネット、とっても大事にしてたのに。ドとレとミとファとソとラとシがでないってさ。オーケー分かった落ち着くんだ少年。**君がくわえているそれはちくわだ。**

さて[何もしてないのに壊れました](https://togetter.com/li/1122462)というのは良くある話で、大体そいつが何かやらかしてるのだが、さておき一番良くあるパターンが**「○○しただけなのに壊れちゃった」**って奴だ。

今回俺の場合はGradleを5にした上に、build.gradleまで書き換えたのだから何もしてないと言い張るのは難しそうである。

どこが動かなくなったのか？
外部依存jarのコピータスクである。

## 元のソースコード
```build.gradle
task copyDependencies(type:Copy) {
    new File('libs').mkdirs()
    copy {
        from configurations.runtime
        into 'libs'
    }
}
```
普通に依存jarをlibsフォルダにコピーするタスクである。
これがいきなりなんのjarも吐き出してくれなくなった。

## 何を編集したのか？
`dependencies`の`compile`が非推奨になったってんで、ぽいーんと`implementatin`置き換えたのである。EmEditorでファイル全置換。やることが男らしいね俺は。男じゃなく漢とは俺の事なんだろうね。

```build.gradle
dependencies {
	implementation project (':hoge')
	implementation project (':fuga')
	implementation project (':piyo')

	implementation(
		  'commons-io:commons-io:2.5'
		, 'org.apache.commons:commons-lang3:3.5'
		, 'ch.qos.logback:logback-core:1.2.3'
		, 'ch.qos.logback:logback-classic:1.2.3'
```

さて原因はというと、勿論`implementation`に書き換えたからである。
依存の伝播範囲が変わってんだから当たり前と言えば当たり前なのかな。

で、勿論困る。リリースする時困るじゃん。
解決方法を探ってたら、意外と時間かかったので、ちゃんとQiitaにでも書いておけば誰かの無駄な工数が俺のおかげで削減できるかもね、そうなったら素敵だね。

駄文が多すぎるって？　**うるせえ、俺は息抜きでQiitaに書いてんだ。何が嫌いかじゃなく何が好きかで自分を語れよ！（意味不明）**

## コピータスクの方を書き換えましたとさ

**configurations.implementation**なんてないしなあ、と探してたら、**runtimeClasspath**ってあるじゃん。

```build.gradle
task copyDependencies(type:Copy) {
    new File('libs').mkdirs()
    copy {
        from configurations.runtimeClasspath
        into 'libs'
    }
}
```

これだけの話でしたとさ、と。
Swift nil 強制アンラップをしない！

#超基礎？　nill の合体演算子について。（１分程度で読めます。）
<br>
##optional って難しい！って感じません？
swift初心者にとって一番最初につまずくのは optional 型　のところではないでしょうか？
私自身、　optional型ってなんやねん！！とりあえず　! つけたらいいんか。。。っと思っていました。
例えば以下の例
###あるoptional型の値がnilの時に0を代入する作業を行なったとします。
***
私は以前以下のようにコードを書いていました。

```swift:optional.swift
//nはoptional型とします。
var a = n!
if n == nil{
           //nill の時の処理
           a = 0
}
```
<br>

***
### 強制アンラップ（!を）せずに上記と同じコードを書いてみる

```swift:optional2
//もしn がnilの時aには０を入れる
//nil出ないときはそのままnを入れる
var a = n ?? "0"

```
***
##後者のように書く利点！
- コードの量が少なくなる！
- 一回一回nilかどうか確認しなくてもよくなる！
<br>

***
もし中身がnilで強制アンラップしてしまった場合、プログラムが落ちるということがあります。（私は度々経験してきました。）
だから私は、後者の方をお勧めします！
***
###最後に
今回あまり時間がなかったので詳しく丁寧に説明することができませんでした！
ちょこちょこ編集していきたいと思います。
[Swift]カスタムセルを用いて、UserDefaultsの中にあるものを表示する

# はじめに
Udemyにある[【iOS12対応】未経験者が有名アプリ開発者になるiOS 12の全て 20個以上アプリをつくりプロになる](https://www.udemy.com/ios12_swift5_iphonex/)という講座のTodoアプリに1つ新しい機能を加えました。
カスタムセルを加えてtodoだけでなく何時までにそのTodoを行うかも確認できるようにしてみました。
# やりたいこと
- CostomCellを用いて1つのセルにつき2つの情報を表示する
- UserDefaultsに保存されているものを表示する

# 完成図
<img width="373" alt="スクリーンショット 2019-02-01 16.58.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/198475/ebbe519a-0719-482a-80a5-f4944a2f73f9.png">


# Cellを表示する側
### viewDidLoadに使用するカスタムセルのクラスを登録する
デリゲートメソッドを宣言とカスタムセルのクラスを登録する

```swift:ViewController
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UINavigationControllerDelegate {
    
    @IBOutlet var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        tableView.register(UINib(nibName:"CostomCellClass",bundle:nil), forCellReuseIdentifier: "Cell")
    }
```
- カスタムセルのクラスを登録する
<img width="837" alt="スクリーンショット 2019-02-01 16.35.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/198475/c7961a6c-f8a8-c32b-28f3-58c245321a61.png">



### cellの中身はカスタムセル側のコードを見てねってことを書く
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{}は、セルに表示するものを記載するデリケートメソッド。
今回はカスタムセルに具体的に記載するので、ここにはカスタムセルを見てねってことを書く

```swift:ViewController
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
　　　let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CostomCellClass
　　　cell.cellDisplay(indexNum: indexPath)
　　　return cell
        
    }
```
- 使用するセルがどれなのか
<img width="845" alt="スクリーンショット 2019-02-01 16.41.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/198475/42e0bc3b-7ca2-3e4a-4c78-2e33262ab2d2.png">



# カスタムセル側
### StoryBordで表示するラベルを用意し関連付けを行う
<img width="1106" alt="スクリーンショット 2019-02-01 16.12.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/198475/5eaee3a8-f376-1de8-df26-bbc3fd9d0c5d.png">

### 必要な変数を宣言する
セルの中にあるテキストラベル２つと、UserDefaultsに保存されているデータを入れる変数を宣言する

```swift:UITableViewCell
    @IBOutlet var todoLabel:UILabel!
    @IBOutlet var timeLabel:UILabel!
    var cellArray = [String]()
    var cellTimeArray = [String]()
```

### UserDefaultsの中身を取り出し配列に入れる
```swift:UITableViewCell
override func awakeFromNib() {
        super.awakeFromNib()
        cellArray = UserDefaults.standard.object(forKey: "todo") as! [String]
        cellTimeArray = UserDefaults.standard.object(forKey: "time") as! [String]
    }
```

### セルの中身を記述するコードを書く
ViewControllerからこのメソッドは呼ばれる。
メソッド"cellDisplay"は具体的にカスタムセルの中にあるラベルに表示するものを書く

```swift:UITableViewCell
 func cellDisplay(indexNum:IndexPath){

        self.todoLabel?.text = cellArray[indexNum.row]

        self.timeLabel?.text = cellTimeArray[indexNum.row]
    }
```

# 最後に
かなりざっくり書いています。
また追記します。
間違っているところ,詳しく書いて欲しいところございましたらコメントお願いします。
Windows 10 Pro x64 + SQL Server2016 Express で SQL CLR を試してみる

#目的
以前から気になっていた SQL CLR を試した時のメモ
AdventureWorks2016.bak を取り込んで行う
修正や追記は色々あるんだろうけどな
##ストアドのコード
サンプルをそのままコピペ(SQLは修正)
新規作成 -> プロジェクト ->Visual C\# -> クラスライブラリ で適当に作成

```c#
using System;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server; 

public class StoredProcedures 
{
   [Microsoft.SqlServer.Server.SqlProcedure]
   public static void PriceSum(out SqlInt32 value)
   {
      using(SqlConnection connection = new SqlConnection("context connection=true")) 
      {
         value = 0;
         connection.Open();
         SqlCommand command = new SqlCommand("SELECT AddressID FROM Person.Address", connection);
         SqlDataReader reader = command.ExecuteReader();
         
         using (reader)
         {
            while( reader.Read() )
            {
               value += reader.GetSqlInt32(0);
            }
         }         
      }
   }
}
```
##コードのコンパイル
スタート -> Visual Studio 2017 -> Developer Command Prompt for VS 2017 を起動する
<pre>
\> cd /path/to/tsql\PriceSum\PriceSum
\> csc /target:library PriceSum.cs
</pre>
##CLR 統合を有効化/無効化する
これ以降の操作はSSMSを起動後、AdventureWorks2016を選択して行う

```sql
#CLR 統合を有効化
sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO

#CLR 統合を無効化
sp_configure 'clr enabled', 0
GO
RECONFIGURE
GO
```
##Transact-SQL をクエリに追加することにより、サーバーにアセンブリを作成する
<pre>
CREATE ASSEMBLY PriceSum from '/path/to/tsql\PriceSum\PriceSum\PriceSum.dll' WITH PERMISSION_SET = SAFE;
</pre>
##プロシージャクラスをクエリに追加する
```sql
CREATE PROCEDURE PriceSum (@sum int OUTPUT)
AS EXTERNAL NAME PriceSum.StoredProcedures.PriceSum
```
AdventureWorks2016 -> プログラミング -> アセンブリ-> PriceSum
    が追加されていることを確認する

##動作の確認
```sql
DECLARE @sumout int;
EXECUTE PriceSum @sumout OUTPUT;
PRINT @sumout;
GO
```
##削除の手順
SSMSにて以下を実行する

```sql
DROP PROCEDURE  PriceSum 
GO

DROP ASSEMBLY PriceSum
GO
```
デバック時は削除＆登録をきれいにまとめてスクリプト化するのが良いのだろうな
※CREATE OR REPLACE は偉大だ・・・

```sql
sp_configure 'clr enabled', 1
GO
RECONFIGURE
GO

DROP PROCEDURE  PriceSum 
GO

DROP ASSEMBLY PriceSum
GO

CREATE ASSEMBLY PriceSum from '/path/to/tsql\PriceSum\PriceSum\PriceSum.dll' WITH PERMISSION_SET = SAFE;
GO

CREATE PROCEDURE PriceSum (@sum int OUTPUT)
AS EXTERNAL NAME PriceSum.StoredProcedures.PriceSum
GO
```
##参考にしたのは以下のサイト
[SQL Server の CLR 統合の概要](https://docs.microsoft.com/ja-jp/dotnet/framework/data/adonet/sql/introduction-to-sql-server-clr-integration)
[CLR ストアド プロシージャ](https://docs.microsoft.com/ja-jp/previous-versions/sql/sql-server-2008/ms131094(v=sql.100))
[CLR データベース オブジェクトの配置](https://docs.microsoft.com/ja-jp/sql/relational-databases/clr-integration/deploying-clr-database-objects?view=sql-server-2017)
[ストアド プロシージャからデータを返す](https://docs.microsoft.com/ja-jp/sql/relational-databases/stored-procedures/return-data-from-a-stored-procedure?view=sql-server-2017)
[データベースを新しい場所に復元する (SQL Server)](https://docs.microsoft.com/ja-jp/sql/relational-databases/backup-restore/restore-a-database-to-a-new-location-sql-server?view=sql-server-2017)
NPCMJ (Kainoki) & tregex :「〜化する」の用例を集める

「〜化」の例を検索

``/.化$/`` （320例）

「〜化する」に類する例（「〜化し（ます）」「〜化できる」など）の「〜化」の品詞は VB とされている。

``/.化$/ >>: VB`` （125例）
``/.化$/ !>>: VB`` （195例）

ちなみにVB でない「〜化」は名詞類（N か NPR）
[Heroku]app crashedってなった時にチェックすること


```
 heroku[router]:at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" （以下略）
```

みたいなのが出て、相当困ったのでメモ。

#チェックすること
##その1　host確かめた？
例えば

```app.run(host="localhost", port=port)```

みたいなコードがあると、「ローカルではうまくいくのに、なぜかapp crashedする」みたいな状況になります。
自分の場合はデータベース接続先がそれでした。


##その2
（以後新しい解決策を発見次第書きます）
HerokuのQuotaGuard Staticアドオン

参考 - https://devcenter.heroku.com/articles/quotaguardstatic

まずは無料プランをProvisionしてみる

```
C:\>heroku addons:create quotaguardstatic:starter
Creating quotaguardstatic:starter on ⬢ ＜アプリ名＞... free
Your static IPs are [＜IPアドレスその1＞, ＜IPアドレスその2＞]
Created quotaguardstatic-XXX as QUOTAGUARDSTATIC_URL
Use heroku addons:docs quotaguardstatic to view documentation

C:\>heroku config | find "QUOTAGUARDSTATIC_URL"
QUOTAGUARDSTATIC_URL:         http://＜ユーザ名＞:＜パスワード＞@＜リージョン？＞-static-XXX.quotaguard.com:＜ポート番号＞
```

上記のQUOTAGUARDSTATIC_URLにブラウザでアクセスすると`This is a proxy server. Does not respond to non-proxy requests.`と表示された
ということはOutbound通信時に通すProxyかな(そうであればProximoから乗り換えできるかな)

Herokuのアプリ画面のアドオン一覧からQuotaGuard Staticの管理画面(※1)に進むとPrivacy Agreementへの同意を求められる
(管理画面には heroku addons:open quotaguardstatic でも行ける)
AgreeにチェックしてSave押下するとDashboard画面が表示される

＜IPアドレスその1＞＜IPアドレスその2＞にブラウザでアクセスすると「アプリが見えると思った？もうちょっと設定が必要だよ」的なメッセージが表示される
以後、`heroku addons:docs quotaguardstatic`でドキュメントを読みながら作業

先日ProximoでOutbound通信はできるようになっていた( https://qiita.com/pilot/items/35675c6a50ba9cc364ee )し、URLの形式も末尾にポート番号がつく以外は同じなので、参照する環境変数をPROXIMO_URLからQUOTAGUARDSTATIC_URLに変えてアプリを動かしてOutbound通信(Salesforce API呼出)をしてみたところ、Salesforce側のログイン履歴に＜IPアドレスその1＞または＜IPアドレスその2＞からのアクセスが表示されたのでうまく行った模様

QuotaGuard StaticのInbound ProxyはMicro以上のプランでないと使えないのでまた後日試す

---

以下、MicroプランでのInbound Proxy確認結果

https://dashboard.heroku.com/apps/＜アプリ名＞/resources にて、QuotaGuard StaticのModify PlanでMicroを選択してアップグレード実行

QuotaGuard Staticの管理画面(※1)にて右上のSettingsドロップダウンからSetupに進んで左側のInboundを押下、Create Inbound Proxyを押下(※2)、
Forwarding URL欄に現在のHerokuアプリのURL(※3)を入力( https://＜アプリ名＞.herokuapp.com ) してSaveを押下すると、Inbound ProxyのURL(※4)とそれをHerokuに伝えるためのheroku domains:addコマンド(※5)と「That Works For Me」ボタン(※6)が表示される

Windowsのコマンドプロンプトにてheroku domains:addコマンド(※5)を実行、
表示されたheroku domains:waitコマンドを実行 ※Windowsなのでシングルクォートをダブルクォートに書き換えた上で
しかし何故か「ACM is failing for 1 domain name (Incorrect DNS Settings)」とのエラーになるので、結局heroku domains:removeコマンドで削除してしまったが、動作に問題なし

ブラウザでInbound ProxyのURL(※4)にアクセスするとアプリの画面(※7)が見える
ただし、Create Inbound Proxyを押下(※2)してすぐだとまだ駄目なので、ちょっと時間をおいてから(最大10分)アクセスすればアプリの画面が見える
既存のURL(※3)でもアクセス可能
nslookupコマンドでInbound ProxyのURL(※4)内のドメインのIPアドレスを調べると、無料プランで発行されたアドレス2個と一致した

アプリ画面が見えたので「That Works For Me」ボタン(※6)を押しておく

以上

＜追加1＞
実はこの時点で見えたアプリの画面(※7)は https://qiita.com/pilot/items/11efce99be33f17f5bc3 による接続元IPアドレスチェックに引っかかったことによるエラー画面

QuotaGuard StaticのInbound Proxyを経由した場合、
request.getRemoteAddr()ではQuotaGuard Staticのアドレスが取得できるだけ
本当の接続元IPはX-Forwarded-Forヘッダで取得する

なので、接続元IPアドレスチェックを「X-Forwarded-ForヘッダがあればそのIPをチェック」と変更した

＜追加2＞
QuotaGuard StaticのInbound ProxyはSession Affinityと一緒に使用できない！
(Session Affinity用のSet-CookieヘッダにDomainとしてXXX.herokuapp.comが指定されているため。Domainの書き換えには対応できないとのこと。こねくり回してなんとなく動かしたがいまひとつ)

＜追加3＞
iPadで写真(2MBほど)を撮ってアプリにアップロードしようとするとエラー
https://qiita.com/pilot/items/9badd3e94fe48af1adb5 で調べるとどうもQuotaGuard Static Inbound Proxyのnginxから413 Request Entity Too Largeが返っている
nginxのリクエストサイズ制限はデフォルトで1MB
Herokuサポートにチケットで制限緩和を依頼したら512MBに設定変更してくれてエラーは解消した
並行処理の基本とgoroutine（スライド）

## まずは簡単な用語整理

---
## マルチタスクとは
**複数のタスクを切り替えて実行できるシステム**のこと

- タスクがプロセスの場合、→　マルチプロセス
- タスクがスレッドの場合、→　マルチスレッド

---
## プロセスとスレッドのおさらい

---
### プロセス
プロセスはプログラムの実行単位のこと。
プロセスの中身は「実行プログラム」や「変数の値」がある。

OS（Linuxカーネルなど）がこのプロセスを切り替えながら実行する。

---
### スレッド
スレッドにはカーネルスレッドとユーザースレッドの2種がある。

---
#### カーネルスレッド
カーネルスレッドの実体はプロセス。軽量プロセスとも呼ばれる。

他スレッド（つまり他プロセス）と変数の値などを共有している。

---
#### ユーザースレッド
ユーザースレッドは、1つのプロセスの中にある擬似的なスレッド。軽量スレッドとも呼ばれる。

あくまで1つのプロセスの中で複数の擬似スレッドがあるだけ。
つまりマルチコアの恩恵を受けられない。

---
## goroutine

---
### goroutine
Goではgoroutineを使って、簡単に並行処理プログラミングが行える。
（詳しい説明は後で）

---
### 並行と並列の違い

---
### 並行処理と並列処理

- Concurrent（並行）は「複数の動作が、論理的に、順不同もしくは同時に起こりうる」こと
- Parallel（並列）は、「複数の動作が、物理的に、同時に起こること」

並列は並行の部分集合である。（並列⊂並行）

---
#### 並列性はランタイムの性質
プログラムが並列実行されるかどうかは完全にCPUの論理コア数に依存している。
（1つの論理コアでは同時に1つのプロセスしか実行できない）

私たちはあくまで**並列に走って欲しいと思う、並行性のあるコード**を書いているだけである。

---
### goroutineの説明に戻ります

---
### goroutine is ユーザースレッド
goroutineはユーザースレッドである。

```main.go
func main() {
  go myFunction() // myFunctionがgoroutine化される
}
```

---
### ユーザースレッドであるgoroutineの並列実行

---
#### goroutineはカーネルスレッドに紐づけられる
goはgoroutineをキューで管理し、キューから取り出してカーネルスレッドに割り当てる。

そのカーネルスレッドがCPUコアで実行される。

---
### まとめ:goroutineによる並行処理のメリット

- カーネルスレッドの数が膨れ上がることはない（C10K問題を回避）
- goroutineはカーネルスレッドよりタスク切り替えが高速
- goroutineはカーネルスレッドよりも省メモリ
アプリで表示している画面のUIImageを作成する

## 画面全体から作成
表示している画面をそのままimage化したいということ偶にあるでしょう。

下記は表示しているUIViewControllerをimage化下処理の流れです。
ユーザが見たままの形でimage化できます。

```swift
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, false, 0.0)
let context = UIGraphicsGetCurrentContext()
self.view.layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
```

## UIScrollView内の画面から作成
画面によってはUIScrollViewを使用しており、scrollした先のviewもimageに含めたい場合があります。

下記は、UIScrollViewのchildViewであるcontentViewをimage化した処理の流れです。
画面全体から作成する場合と大差はなく、指定するsizeとviewが異なるだけです。

```swift
UIGraphicsBeginImageContextWithOptions(scrollView.contentSize, false, 0.0)
let context = UIGraphicsGetCurrentContext()
contentView.layer.render(in: context)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
```

試していませんが、UITableViewやUICollectionViewのようなcellを再利用して表示する場合には、cellから解放されている箇所は真っ白になると思われます。
その場合には、意図的にscroll positionを変更して複数枚のimageを作成後、合成することになるかと思います。

## 必要な画面のみから作成
画面によっては、image化すると情報量が多すぎる場合があります。
その場合、必要な画面だけ1枚のimageにしたいこともあると思います

下記では、3枚のimageを1枚のimageに縦並びで作成した処理の流れです。
3枚のimageは、上述した処理でview毎に用意してやります。

imageの配置を横並びや4等分等にしたい場合は、`draw(in: CGRect)`のCGRect部分で座標を適宜調整してください。

```swift
let images: [UIImage] = [image1, image2, image3]
let width = images.max(by: { $0.size.width > $1.size.width })?.size.width ?? 0
let height = images.reduce(0.0, { $0 + $1.size.height })
let canvasSize = CGSize(width: width, height: height)

UIGraphicsBeginImageContext(canvasSize)

var offset: CGPoint = .zero
images.forEach { image in
    let rect = CGRect(origin: offset, size: image.size)
    image.draw(in: rect)
    offset.y += image.size.height
}

let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
```

## 上述3パターンを含んだsample
下記にXcode10.1で開けるsample projectを用意しています。
https://github.com/aryzae/ScreenShotImage
環境変数の値を別の環境変数から動的に組み立てて設定する

## やりたいこと

タイトルがややこしいですが、モチベーションは Travis とかで環境毎の環境変数を簡単に設定したいという所です。
Travis で dev, stg, prod のデプロイを行っており、Travis の環境変数設定で
`SECRET_dev`, `SECRET_stg`, `SECRET_prod` のような環境変数が設定されている。
アプリケーションとしては `SECRET` という環境変数を読み取っているので、デプロイする環境のサフィックスがついた環境変数を `SECRET` として設定したい。

## やりかた

デプロイするスクリプトで以下の関数を定義して使う

```shell
ENV_SUFFIX=${TRAVIS_BRANCH}

set_env () {
    local ENV_NAME=$(echo ${1}_${ENV_SUFFIX})
    eval $(echo "export ${1}=${!ENV_NAME}")
}

set_env "SECRET"
```

今はサフィックスの値を `TRAVIS_BRANCH` から持ってきているので、dev, stg, prod のブランチでデプロイをすると `SECRET` という環境変数に `SECRET_dev` などの環境変数の値が設定される。
ERROR: cannot launch node of type [controller_manager/spawner]: controller_manager

ubuntuを新しく入れなおしてgazebo上でモデルを出そうとしたら入れる前は出なかったエラーが出た

ERROR: cannot launch node of type [controller_manager/spawner]: controller_manager

調べるとパッケージが足りないらしい
以下の２つのコマンドを入れることで解決した

$ sudo apt-get install ros-kinetic-ros-control ros-kinetic-ros-controllers
$ sudo apt-get install ros-kinetic-gazebo-ros-control
AWS 料金アラートを設定しよう

AWSアカウントを作成したらまずやっておきたいことの1つ。



##1.IAMでも請求の設定をできるようにする##

IAMユーザでも請求ダッシュボードを開くとこんな感じになります。
![スクリーンショット 2019-01-31 21.45.00.png](https://qiita-image-store.s3.amazonaws.com/0/280929/f86b76b7-5acd-270c-8e33-bdc081b6fbc3.png)

最初ルートユーザで以下の設定をしておきます。

「アカウント」を開きます。
![スクリーンショット 2019-01-31 20.52.33.png](https://qiita-image-store.s3.amazonaws.com/0/280929/e9beb0d7-1bba-a1a8-3ce9-9c7bf37fb001.png)

「IAM ユーザー/ロールによる請求情報へのアクセス」から「IAM アクセスのアクティブ化」を「有効」にします。
![スクリーンショット 2019-01-31 20.49.48.png](https://qiita-image-store.s3.amazonaws.com/0/280929/fd6dae94-256d-be6b-d06f-dd0184752b5a.png)

これで、IAMユーザーでも、請求ダッシュボードを確認できるようになります。



##2.請求アラートを受け取る##

IAMユーザでログインし、「請求ダッシュボード」をクリック。
![スクリーンショット 2019-01-31 21.45.00.png](https://qiita-image-store.s3.amazonaws.com/0/280929/118da477-65d2-49be-4d47-e8dc90d5cef2.png)

「設定」の「請求アラートを受け取る」にチェック。
＊請求アラートは一度オンにするとオフに戻す事はできません。
![スクリーンショット 2019-01-31 22.32.49.png](https://qiita-image-store.s3.amazonaws.com/0/280929/360ae1fa-9b2d-afde-b61e-206c39403702.png)



##3.CloudWatchから請求アラームを作成する##

CloudWatchを開き「請求」から「アラームの作成」
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/16befe2d-61a9-5d12-a1b2-bdc8ab9bd5b1.png)

5 USDを超過したら、任意のメールアドレスに届くように設定し、「アラームの作成」。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/ea9e81cd-d9e3-2e7d-42d5-a2409911615b.png)

登録したメールアドレスに承認のメールが届くので承認すれば完了です。
eccube4を下層ディレクトリへリバースプロキシ

# はじめに

表題の件での対応メモです。
リバースプロキシの設定は初めてだったので、ちょっとハマりました。

# やりたいこと

(1)webサイト(wordpress) : https://hoge.com
(2)ecサイト(eccube4) : https://shop.hoge.com

リバースプロキシで別サーバにあるecサイトを本家サイトのサブフォルダ配下にあるように見せたい。
https://hoge.com/shop -> reserve proxy - > https://shop.hoge.com

# 設定(1) - webサイト側

confに以下を設定。.htaccessでは設定できないので注意。

```vhosts.conf
SSLProxyEngine On
ProxyPass /shop https://shop.hoge.com
ProxyPassReverse /shop https://shop.hoge.com
```

# 問題点

css/js/imageなどが読み込めない！
eccube4では、url生成にsymfony/twigの以下の関数を利用しています。

(1)asset('style.css')
=> /html/template/default/style.css =>  https://hoge.com/html/template/default/style.css => エラー
↓本当はこうしたい
https://hoge.com/shop/html/template/default/style.css

(2)url('homepage')
=> https://shop.hoge.com/ => エラーではないが、このドメインは見せたくない
↓本当はこうしたい
https://hoge.com/shop

上記関数のソースを直すことはやりたくないし、symfonyの設定等で変更できそうな気がするが、ググってもわからず。
ちょっと力業になるが、以下のように対応した。

# 設定(1)・改 - webサイト側

```vhosts.conf
SSLProxyEngine On
ProxyPass /shop https://shop.hoge.com/shop
ProxyPassReverse /shop https://shop.hoge.com/shop
```

# 設定(2) - ecサイト側

(1)サブフォルダ(shop)配下で動作するように構成を変更。これによってasset()の問題を回避
(2)HTTP_HOSTの書き換え。これによってurl()の問題を回避

```index.php
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
```
ただし、Requestクラスを生成する前に実行する必要あり。

# 最後に

もっとスマートな対応方法があれば教えてください。
DNA解析3 - マッピング memo

###フロー
リファレンスGenome配列取得 ⇨ Short Read Array配列取得 ⇨ Qualityチェック ⇨ **マッピング ⇨ 可視化**

---
###マッピング
####インデックス作成
Genome配列情報から、遺伝子のインデックスを作成しておく。
.bt2 拡張子が6種生成される。

```
> bowtie2-build -f pombe.fa pombe
```


####マッピング
Fastq形式のSRA配列を、Genome配列にマッピング。

```
> bowtie2 -x pombe -U SRR8512918.fastq -S SRR8512918.sam
```


####SAM->BAM変換
```
> samtools view -Sb SRR8512918.sam > SRR8512918.bam
```
or

```
> samtools view -b -o SRR8512918.bam SRR8512918.sam
```


####ソート
```
> samtools sort SRR8512918.bam -o SRR8512918_sorted.bam
```


####インデックスファイル .bai 作成
```
> samtools index SRR8512918_sorted.bam
```


####IGV

```
> igv.sh
```
Genome -> Load Genome from File、でFastaファイルを指定。
File -> Load from File...、でソート・インデックスした.bamファイルを指定。
読み込みフォルダに.baiファイル。
MySQLメモ： INSERT時に最大値＋1を使いたいけど、auto_incrementは使いたくない

テーブルにデータ入れる時、「既存データの最大値＋1」を使いたいことはよくある。
けど諸般の事情で `auto_increment` は使いたくない、ということも、ままある。（ないですか？）

その時の定番フレーズを良く忘れるのでメモ。

```sql
INSERT INTO テーブル名 ( id, name, とかなんとか )
  SELECT last_insert_id( ifnull(max(id), 0) + 1  ), '何かデータ', とかなんとか
  FROM テーブル名
```

既存データが1件も無い場合は、`max()` は `null` を返すので、`ifnull()` で 0 扱いしてる。

いま追加した id の取得は以下の通り。

```sql
SELECT last_insert_id() FROM テーブル名
```

# last_insert_id()、便利かも

`auto_increment`された値をもらう関数だと思ってた。
マニュアルよく読んでみたら、もちろんその用途にも使えるけど、それだけじゃなかった。

* 引数あり `last_insert_id(何かしら)` で、何かしらが保存され、その場では何かしらをそのまんま返す関数。
* 引数なしの `last_insert_id()` で、直近に保存された値が受け取れる。
* 他のステートメント発行しても、`last_insert_id(何かしら)` を使わない限り、値は変わらない。
* 接続ごとにサーバに保存される。別の接続で**同時にほかの人が触っていても、値は変わらない**。

## 情報元
[MySQLリファレンス / 12.14 情報関数 LAST_INSERT_ID()](https://dev.mysql.com/doc/refman/5.6/ja/information-functions.html#function_last-insert-id)
DNA解析1 - インストール memo

個人的なメモ。
###参考例
+ NBDCハンズオン講習会: https://biosciencedbc.jp/human/human-resources/workshop/h27


---
###インストール
####各種ツール
Sratoolkit (prefetch, fastq-dump), fastx_toolkit (fastq_quality_trimmer)等。

```
> brew install wget
> brew install sratoolkit
> brew install fastx_toolkit
> brew install bowtie2
> brew install samtools
```


#####FastQC(クオリティチェック)
+ GUI版: 下記から。JDK要。
https://www.bioinformatics.babraham.ac.uk/projects/fastqc/

+ コマンドライン版: /usr/local/src にて

```
> wget "http://www.bioinformatics.babraham.ac.uk/projects/fastqc/fastqc_v0.11.8.zip"
> unzip fastqc_v0.11.8.zip
> chmod a+x FastQC/fastqc
> ln -s FastQC/fastqc /usr/local/bin
```


####IGV(可視化)
+ コマンドライン版
http://software.broadinstitute.org/software/igv/

---
PATHの設定例
~/.bashrc

```
export PATH=/usr/local/src/FastQC/fastqc:$PATH
```
ARCore (Unity)で平面検知のモードを実行中に切り替える

# この記事は古いです
**UnityARCoreSDKは開発終了しています**
現在はARFoundationを用いた開発が主流なためこの記事は参考にならないです。


# 概要
ARCoreでアプリ開発してる際に「このメッセージ表示している時は平面の検知してほしくないなぁ」というタイミングや垂直面の検知はしてほしくないタイミングが発生してきたので切り替えれる関数を作ることにしました。
ARCoreUnitySDKの1.6で実装してます。

# 実装
今回はめんどくさかったのでARCoreSessionクラスの中に追加でメソッドを定義しました

```csharp:ARCoreSession.cs
 public void ChangeDetectedPlaneFindingMode(DetectedPlaneFindingMode mode)
        {
            this.SessionConfig.PlaneFindingMode = mode;
            this.OnEnable();
        }
```
とてもシンプルな話でセッションを作成するときに使っているSessionConfigの中のPlaneFindingModeを書き換えてやってからOnEnableを呼びます。

OnEnabnleの中では

```
LifecycleManager.Instance.EnableSession();
```
という処理がありこの中でセッション情報の更新をやってくれてるみたいです。

あとはこの関数を好きなところから呼んでやれば平面検知のモードを切り替えることができます。
なお、InstantPreviewではこの関数は実行できません。警告が出ます。
InstantPreview中は平面検知のモード変更はできない模様。
#　まとめ
ARCoreは良いぞ。
yarn run generateをしたら動かなかった

# 概要

Nuxtを利用していて以下のエラーに遭遇した。ただ、`yarn run build`を利用した際は問題ないのに、`yarn run generate`をしたら、これが起こる。

```
[nuxt] Error while initializing app DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.
```

# 本題

実は開発環境でも、上記のエラーが発生する兆候は表れている。開発者ツールのエラーメッセージを眺めていると、以下のようなメッセージが表示される。生成された html と component を利用してレンダリングをする html が異なる場合、このエラーが発生するらしい([楽勝すぎるはずの netlify form を nuxt generate で頑張って使う](https://qiita.com/yahsan2/items/a70c4c8f617ee9b1f9ff))。

```
[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
```

確かにレンダリングされるDOMの不一致が発生しているとのこと。

この問題の原因は、`v-if`による表示制御をしていることが問題であり、解決策の一つとして、`v-show`に置き換えることで解決することができる。この理由は、`v-show`を利用した場合、`v-show="false"`の値について注目すると、生成されたDOMは`display:none`で見えなくされており、`v-if`の場合はそうではなく、サーバ側では`v-if="false"`でもDOM自体は生成されており、クライアント側では`v-if="false"`のDOMはレンダリングされないため、レンダリング結果に差異があるため、エラーが発生するものと考察した。
ただ、`v-show`では`display:none`のスタイルがあたっているだけなので、開発者ツールで見ようと思えば見えてしまう。
あまり、こうしたくない場合は、`<no-ssr></no-ssr>`で囲うことで、DOMの差分も発生せず、かつ、`yarn run generate`をしても、エラーが発生することはない。
JVMに数独を解いてもらう

# 前書き

このページは、[JavaFXとか使って手探り開発した時のメモ](https://qiita.com/UFOnian/items/67cd4f6f8c71e178f06b)の続編のようなもので、あちらを表示に寄った記事にし、こちらを内容に寄った記事にしようというものである。
正直、クラスの設計とかでかなり無駄が多かったので、`NumberPlaceSolver 2.0`を始動するにあたって記事を新しくした、というくらいの話。
表示についてはガッツリ排除した。
以前の仕様はこちらには書かないので、元記事を読んでいただきたい。

# 作ろうとしてるもの
数独解いてくれるモノ。学校の自由課題にて。

## 環境その他

Java(8) ...はある程度学習済み（使用経験は浅い）
IDEとして、講師オヌヌメのintelliJIDEA(ver.3.2)最近アプデが入って若干UIとか変わった模様。リファクタ機能が強すぎて、こないだeclipse使ったらいろんなところかゆかった。

# いくつかの簡単な対応について

 - FXMLで指定した`fx:id`はControllerでは`@FXML`を直前で指定しないと怒られる。delimiter単位でつけないとやっぱり怒られる。
 - 配列xに、配列yを`x=y`みたいにして渡すと(仮称)参照値渡し（後述）となる。xとyは同じオブジェクトを指す名前となる。
  - 新しい別のオブジェクトとして扱いたい場合はcloneメソッドを使用して、`x=y.clone()`とする。
  - この問題はString型の同一の文字列を格納した別のオブジェクトを条件演算子`==`で結ぶ(すなわち、`str==new String(str)`)と、オブジェクトの参照値を比較するために、`false`が返されることを連想させる。ただしString型自体が若干特殊な仕様を含んでいるようなので、取り扱いに注意すべきか。
 - 数独では行と列のほかに、3x3のsubRegionでも重複を禁じている。この3x3のグループを順番に追う式を書いた。

```java
for (int i = 0; i < 9; i++) for (int j = 0; j < 9; j++) {
  int idev3= i/3 , jdev3= j/3 ;

  int x= idev3 * 3 + jdev3 ,
      y= i % 3 * 3 + j % 3 ;

  subRegion[x][y] = cell[i][j]
//  逆関数が同様の式になる（名前忘れた）ので、[i][j]と[x][y]は逆にしても目的を果たす。
//  subRegion[i][j] = cell[x][y];
}
```

 - 二次元配列`x = new Object[i][j]の`length`について。
  - `x.length`は`i`
  - `x[0].length`は`j`。ただしもし`i==0`ならば、`ArrayIndexOutOfBoundsException`を吐く。



## 共有データを操作させるにあたって

Javaでは、C言語でいうところのポインタを、「参照変数」とか「参照値」とか呼ぶっぽい。

各リージョンに参照値を納めさせて、テーブル一個分のセルのデータ群だけで処理ができるようにしたい。
つまり、リージョンからの操作で、テーブルに存在するセルのデータも変更されるようにしたい。

以下はつたないイメージ図

![Cell Region image](https://qiita-image-store.s3.amazonaws.com/0/226001/7ec1272f-0b68-6ca0-1570-2b1fc9228829.png)


# 各クラスの設計説明の前書き

冒頭でも書いたし、内容読めばわかる人にはわかるでしょうし、プロフにも書いたはずなのでわかるとは思いますが、

わたくし、バリバリの初心者にござる。
何やるにしても拙いものになると思いますので、どうかご容赦を。（批判とか改善策とかのコメントは歓迎いたします。）
同輩の初学者様がたも、こんなの参考にしちゃダメです。参考にするにしても、教育者の意見をもらってからにしましょう。

----
[元記事の同じ場所](https://qiita.com/UFOnian/items/67cd4f6f8c71e178f06b#%E5%90%84%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AE%E8%A8%AD%E8%A8%88%E8%AA%AC%E6%98%8E%E3%81%AE%E5%89%8D%E6%9B%B8%E3%81%8D)から後ろは、できれば失敗談として、あるいは比較対象として、
読んでほしくない（読まなくてもわかるように書いていきたい（願望））


ここまで、元記事と同じとはいえ必須と思われる部分。

# これからの方針
既に書いた設計を基に、改善したものを作成する。

盛り込みたいこと

 - クラス設計見直し **:** 無駄と思われるメソッドの削除等。
 - 複数スレッドで仮置き **:** 仮置き処理を複数スレッドですることで、処理スピードを底上げ
 - 全体のデータを管理するstatic Boardを用意 **:**「denyされた」情報を全スレッドで共有化
AdonisJs でレスポンスタイムを計測する

## 環境

- Node.js v10
- AdonisJs v4.1

## 計測する

計測用のミドルウェアを作成する。

```sh
$ adonis make:middleware LogRequest
```

ミドルウェアを登録しておく。

```start/kernel.js
const serverMiddleware = [
  'App/Middleware/LogRequest'
]
```

以下のモジュールが必要なのでインストールしておく。

```sh
$ npm i on-finished
```

ミドルウェアの中身を書く。

```App/Middleware/LogRequest.js
const onFinished = require('on-finished')

class LogRequest {
  async handle ({ request, response }) {
    const start = process.hrtime()
    onFinished(response.response, function () {
      const end = process.hrtime(start)
      const diff = ((end[0] * 1e9) + end[1]) / 1e6
      console.log(diff)
    })
  }
}
```

実行する。

## 参考

[Measuring request time - Help / Http Lifecycle - Forum - AdonisJS Framework](https://forum.adonisjs.com/t/measuring-request-time/2340)