OmniAICreator/Qiita-1.07M huggingface dataset:
【CakePHP2】requestActionがSessionに悪さをしている気がする

#ページの共通部分に通知を出したい
## requestActionを使って通知を取得していた
View/ElementsのHeader.ctpからrequestActionを使って通知取得用のメソッドを呼び出していた。よくある使い方だと思うし、特に問題なく動いているように見えた。
## AuthComponentを併用した場合の再ログインで挙動がおかしい
Sessionが切れて自動ログアウトをした後再度ログインすると、requestActionで指定したURLにアクセスしてしまう。（action内では$this->request->params['requested']で判定しているのでエラーが出る。）これは困った。
何回か試してみたが、起こるときと起こらないときの差がわからず、うまく再現できない。
でもrequestActionが悪いに違いないので、使わないことにした。
（もしかすると、AuthComponentの設定が悪いのかもしれないが。）
## どうせヘッダーで読み込むならAppControllerに書いてしまえ
ほとんどのページで通知領域は表示するので、AppControllerに共通処理として埋め込むことにした。
でもログイン用のlayoutで読み込む必要はないので、layoutで条件分岐したい。そうなると、beforeFilterでは各actionの$this->layoutが反映されていないから、beforeRenderあたりに書くことになるのだろうか。
結局以下のように書くことでrequestActionと同様の結果を得た。

```php:AppController.php
<?php
#省略
	public function beforeRender(){
		if($this->layout === 'default'){
			$this->set('notifications', ClassRegistry::init('Notification')->find('all'));
		}
	}
いまさら SoftAP を使用してWindowsノートマシンを無線親機にする

# ほんにいまさらですｗ
ちょいと仕事先でWiFi接続でテストする必要性があったのですが、機器買いにいく時間もなかったので SoftAP を使って Windowsマシンを無線親機にしてみました（超簡単）。で、設定は、とりあえず以前から気になっていた参考サイトさんの記事とおりに進めればokだけど、ちょいとばかり判りにくい点があったのでそこだけを自分メモとしてます。

# Windowsノートマシンがいいんじゃね？でもね
いまどきの Windowsノートマシンなら有線LAN、WiFiがついているものと思ったら、格安ノートPCとかだとWiFiついてないーーってことがあるらしい（ハード的に500円もしないのにねｗ）。あとWiFi付いていても 5Ghz 未対応とかあるので微妙にハマルｗ。

# 備忘録というか参考リンク
> ・[無線LANルータ（Wi-Fiルータ）を使わずにiPhoneをWi-Fiに接続する方法! 【Windows 8 / 8.1 編】 PCを無線親機にする逆テザリング設定](http://nw-knowledge.blogspot.jp/2014/02/win8-8.1-softap-virtualwifi.html)
> ・[あなたはもう使ってる？Windows8/8.1/10 無線LANルータ化の方法！](http://somegoro.hatenablog.com/entry/2016/05/07/075634)

# コマンド
管理者権限で黒い画面(cmd)を開き、以下のコマンドを実行するだけ。注意点は特にないけど ssid, key(パスワード)  をここで設定するので少し頭をひねって決めた方がいいぐらい。

```
> netsh wlan set hostednetwork mode=allow
> netsh wlan set hostednetwork ssid=ssidtest
> netsh wlan set hostednetwork key=password keyusage=persistent
> netsh wlan start hostednetwork
```

# ちょいとはまった点
コントロールパネルを開いて「ネットワークとインターネット - ネットワーク接続」をクリックしていくと、下記のような情報となっているハズ。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/d0df63d5-fb8f-eda8-fdfc-9f5fa8a6bcbb.png)

①は、もともとのLAN線の接続情報。
②は、SoftAP により追加された接続情報。「Microsoft Hosted Network Adapter」ってなっているのが SoftAP なのでこの接続情報名を覚えておく。「ローカル エリア接続*4」の「*4」 は、自動的に採番される値なのであまり気にしない。

①接続情報のプロパティを開き「共有」タブで下記のように全てチェックする。
ホームネットワーク接続は、SoftAP の接続情報を指定する（紐付けする）。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/c56cf7d0-96da-aa54-cf19-2d759656f847.png)

# 接続してみる
こんな感じで Windowsノートマシンが無線親機になったのでスマホとかで設定したアクセスポイントに接続してみる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44540/288136b8-fc25-7b52-db39-ddd791987d4c.png)

# セキュリティ的にどうなのよ
ステルスSSIDできないとか、帯域幅を指定するとか…細かい設定はできません。まあ、あくまで手軽に使いたいってことでのSoftAPを使うのであれば問題ないですが、会社で使うのであればNGでしょうね。ともかくちゃんとしたネットワーク管理者がいるとこでしたら怒らるの必須です。

まあそういう点も理解している前提であれば、いいんじゃね？って思いますがあくまでも「個人の責任の範囲で運用してね」としか言えません。
macでターミナルにgithubのブランチ名を表示させる

どのブランチで作業しているかすぐわかるようにする。

#ターミナルにgitブランチ名を表示させる

##git-completion.bashのインストール
https://github.com/git/git/blob/master/contrib/completion/git-completion.bash

homebrewでgitをインストールした場合はすでにファイルが存在するはずなので
ファイルがあるかどうか検索する
`$mdfind git-completion.bash`

ファイルが存在した場合
.bashrcに
`source /git-completion.bashがあるパス/git-completion.bash`
を記述することでブランチ名が表示される。

ファイルが存在しない場合
DLしたgit-completion.bashをgitがあるフォルダに配置
`/usr/local/Cellar/git/1.X.X.X/etc/bash_completion.d/`あたり

#インストール後は下記のURLを参考に
https://qiita.com/varmil/items/9b0aeafa85975474e9b6

ブランチ名に色をつけたりできて便利
Google App Engine Flexible Environment で初期設定コマンド実行

Google App Engine Flexible Environment で初期設定コマンド実行

Google App Engine Flexible Environment の中身は Docker なので、[DockerfileのCMDおよびdocker-compose.ymlで複数のbashコマンドを実行させる方法](https://qiita.com/kon_yu/items/29e6e7ad1caa28dce498) が使える。

# 前提条件
* 2017年10月時点の Google App Engine Flexible Environment で動作確認。

# 例: Django で `python manage.py migrate` の実行後 gunicorn を起動する。
例として、[Running Django in the App Engine Flexible Environment](https://cloud.google.com/python/django/flexible-environment?hl=en) のソース・ファイルを使用する。
変更箇所は下記になる。

appengine/flexible/django_cloudsql/app.yaml

```yaml
runtime: python
env: flex
entrypoint: bash -c "python manage.py migrate && gunicorn -b :$PORT mysite.wsgi"

beta_settings:
    cloud_sql_instances: <your-cloudsql-connection-string>

runtime_config:
  python_version: 3
```

`entrypoint` で、 `bash -c "コマンドA && コマンドB"` のように指定する。

# やりたかったこと
[Heroku](https://www.heroku.com/) でいう `heroku run python manage.py migrate` を Google App Engine Flexible Environment で実現したかった。

`gcloud app instances ssh` でインスタンスにログイン -> Docker に入って `python manage.py migrate` を検討したが、うまくいかなかった(エラー原因の特定に時間がかかりそうだったので途中で諦め)。


# 懸案事項
上記の方法だと、App Engine のインスタンスが起動するたびに実行されるので、複数インスタンスがあると複数回 `python manage.py migrate` が発行される。
複数インスタンスから同時に `python manage.py migrate` を実行するとどうなるかは未検証。
rubyのpとputsとprintの区別

rubyで、pとputsとprint三つの出力があります。

例：

```
puts "welcome to 'get my number'"# 改行ありで出力
print "What is your name? " # 改行なしで出力

input = gets

puts input.inspect
p input
```
- printとputs

printは改行なしで出力
putsは改行ありで出力

<img width="294" alt="スクリーンショット 2017-10-10 17.01.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/197386/42f8c856-d20c-d3f9-b5d4-a905d5a5a089.png">

- putsとp

`puts input.inspect` = `p input`

p.s:inspectメソッドは、オブジェクトを分かりやすい文字列にして返します。

<img width="242" alt="スクリーンショット 2017-10-10 17.03.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/197386/f9295100-104f-c088-88a3-0710b5e66a71.png">
ビットマップスタイルデザイナの使い方

Delphi, C++Builder にはビットマップスタイルデザイナというツールが付属しています。（Starterにも付属しています)
このツールは、Delphi, C++Builder のアプリケーションやアプリケーション内のコントロールの外観（スタイル）を自分で作成・設定できるツールです。

ここでは、Delphi 10.2.1 Tokyo Starter 付属のビットマップスタイルデザイナを使用しています。

この記事は、以前 [EDN](http://edn.embarcadero.com/article/44091) に書いた記事を 10.2.1 Tokyoでリライトしたものです。

##画像イメージを作成
1. Windows のペイントを起動してお絵かき開始。5色の△だけの簡単なものです。ガチなスタイルを作るのであれば、illustratorなどで、それ相当の見栄えの良い画像を作ってください。
![qiita01.png](https://qiita-image-store.s3.amazonaws.com/0/164551/f8a77c43-8e77-f535-046b-aedd1ae60d4c.png)


2. 透過処理を行ないます。メニューの[選択]の▼をクリックして、[すべて選択]⇒[透過の選択]で、透過処理を行ないます。
![qiita02.png](https://qiita-image-store.s3.amazonaws.com/0/164551/a9d577a0-1c99-3484-45de-f02468503840.png)

3. ファイルを保存します(ここでは PNGとして保存)

##スタイルファイルを作成 
1. ビットマップスタイルデザイナを起動します。ここでは FireMonkey アプリケーション用の Windows スタイルを定義します。
画面は Starter エディションのメニュー画面です。
![qiita03.png](https://qiita-image-store.s3.amazonaws.com/0/164551/0410b1a5-cd3c-138e-a20e-9b5d1ddfa01f.png)

2. [ファイル｜新規作成｜Windowsスタイル]で新たにスタイルファイルを作成します。
![qiita04.png](https://qiita-image-store.s3.amazonaws.com/0/164551/c5e4011a-2e3a-cf72-158a-a9ac7d9a3e1d.png)


##画像イメージファイルを追加
新規作成したスタイルファイルに、作成した画像イメージファイルを追加します。
1. 左側のオブジェクトのツリーの中にある Images をマウスで選択します。この Images に使用する画像ファイルを追加して保存し、使用します。
2. [追加]ボタンをクリックして、作った画像ファイルを読み込みます。
![qiita05.png](https://qiita-image-store.s3.amazonaws.com/0/164551/5b8649d0-4d09-3347-87df-d94d91a63484.png)
3. 読み込んだ画像イメージが表示されます。マスク(不要な部分)色を指定して必要な画像イメージのみとしておき、[OK]ボタンをクリックして保存します。
![qiita06.png](https://qiita-image-store.s3.amazonaws.com/0/164551/70b37a94-5154-c07a-de48-bdce7612e919.png)


##コンポーネントに画像を設定する
それぞれのコンポーネントごとに表示するイメージを設定します。ここでは Button コンポーネントの表示イメージに作った画像を設定します。
1. 左側のオブジェクト内の Objects のツリーを展開します。
2. 展開された項目内の Button を展開します。
3. 展開された中にある Faceを選択します。右側の画面がオブジェクトビューアとインスペクタに変わります。
4. インスペクタ上の Bitmapを選択し[...] ボタンを押します。
![qiita07.png](https://qiita-image-store.s3.amazonaws.com/0/164551/773fa7a9-73aa-22a1-7ba0-6d578b4d1367.png)

5. ビットマップのプロパティ画面が開きます。左側の「ビットマップ」の所に読み込んだファイル名が表示されています。そのファイルを選択します。
6. マウスの左クリックで、左上位置、右クリックで右下の位置を指定し、ボタンのイメージとして表示したいイメージを囲い、[適用] ボタンを押します。
![qiita08.png](https://qiita-image-store.s3.amazonaws.com/0/164551/2798e6b3-1314-e5ac-9052-d0a3e33d6b4d.png)

適用した後の画面
![qiita09.png](https://qiita-image-store.s3.amazonaws.com/0/164551/1098e271-f338-fc3f-49d8-43c66580a5b9.png)

Bitmap(通常), BitmapDisabled(無効), BitmapFocused(FireMonkeyフォーカス時), BitmapHot（VCLのフォーカス時), BitmapPressd(押したとき) が設定できます。

##ビューアで確認できるよ
ビットマップスタイルデザイナのツールバーの所にある緑の△ボタン隣にある▼ボタンを押し「VCLスタイルのテスト」「デスクトップスタイルのテスト(FireMonkey)」を選択して実行すると、スタイルビューアが起動して、設定した状態を確認できます。
![qiita11.png](https://qiita-image-store.s3.amazonaws.com/0/164551/4756fa00-fe78-e492-2b1a-5b82f14ce4d8.png)

![qiita10.png](https://qiita-image-store.s3.amazonaws.com/0/164551/3202058f-9f49-5ad6-2336-5413ccdc84fa.png)
ユーザビリティテスト１　目的決めと仮説立て

ユーザビリティテストを実施することになり、準備を始める。
前回の内容はこちら「[サイト公開前にユーザビリティテストをすることに](https://qiita.com/Yoko3/items/d8630ad719586db8f72d)」

#目的決め
はじめに今回のユーザビリティテストの目的を決める。
計画っておろそかにしやすいけど、仕事も遊びも計画が本当に大事。そして、それを関係者間で共有することを忘れちゃいけない。

そもそも今回なぜユーザビリティテストをすることになったのかに戻った。発端は一緒に作業をしているメンバーの上司の「もっと良くならないかなぁ」、「社員が不自由なく使えるのか？」からスタートした。

そこで目的を決めるために、ユーザビリティテストで何を知りたいのか聞いてみた。
「もっとよくできないか」
「使いにくくないか知りたい」
「不自由なく使えるのか？」
「今まで使っていた人が使えるのか知りたい」
「サイト内で迷うことがないようにしたい」
「前ダサかったから、ダサくないか知りたい」
などが上がってきた。

「もっとよくできないか」というのは、「よく」という言葉は定義が難しく、もう少し上流の調査などでアイデア出ししたり、他の方法で考えた方が適切な対策ができそうだ。あとダサいかどうかは操作してもらって聞くより、アンケートなどの量的調査で調べた方が早そうだ。
ユーザビリティ（使えるかどうか）を疑問視する言葉が多く上がったので、使えるサイトにすることが今の状況では目的に適切では？と提案した。「**迷うことなく使えるサイトにする。**」を今回のユーザビリティテストの目的として置くことになった。



#仮説立て

次に現在作成中のサイトをメンバでレビューした。問題ありそうな箇所を書き出していき、仮説立てに使う。
今回、既存のサイトのコンテンツをそのままに、再構成している。なので一番変わったのは、アイコンメニューを使用して目的のコンテンツグループにページ内をジャンプするようにした箇所だ。

サイトの設計段階でアイコンメニューを
・案１：物を中心としたアイコン
・案２：状況に合わせたアイコン
２パターンのプロトタイプを作り、社内の利用者に少人数にアンケートを取っていた。案２の状況に合わせたアイコンの方がわかりやすいだろうと想像していた担当者の期待とは反対に、案１の物を中心としたアイコンが人気だった。

![IMG_0780.jpg](https://qiita-image-store.s3.amazonaws.com/0/55407/4dc22801-fc06-957f-918b-4e3bd06c3221.jpeg)

しかし、アンケートの結果とは反対に、案２の状況に合わせたアイコンをメニューに採用することになった。担当者はそこが使いにくくないだろうかと心配していた。

このアイコンメニューを調査する対象にして、「状況に合わせたアイコンメニューは使いにくい」を仮説に、「**サイトに来た人が迷うことなくアイコンを選択して、自分の利用したいコンテンツにたどり着くことができるのか**」を検証することにした。決めた目的と仮説をメンバ間で共有（再確認）を忘れずに実施。

次に、仮説を検証するためのタスクを決めて、テストシナリオに落とす。
iOS端末のユーザーエージェントの判別コードは多分これが一番短いと思います(35文字)

JavaScriptでiOS端末を判別する際、次のように「iPhone」「iPad」「iPod」のいずれかの文字列が含まれているかどうかを判断することが多いのではないでしょうか。

```js
const ua = navigator.userAgent
const isIOS = ua.indexOf("iPhone") >= 0
  || ua.indexOf("iPad") >= 0
  || navigator.userAgent.indexOf("iPod") >= 0
```

正規表現 ([RegExp\.prototype\.test\(\) \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test)) を使うと、次のように短くできます。

```js
const isIOS = /iP(hone|(o|a)d)/.test(navigator.userAgent)
```

`/iP(hone|(o|a)d)/`が「iPhone、iPod、iPad」を表現します。`test(対象の文字列)`を使うことで、対象の文字列に「iPhone、iPod、iPad」が含まれているかどうかを判定できます。判定部分だけで見ると43文字のコードで充分短いように見えますが、もっと短くすることはできないのでしょうか。

# `/[ \(]iP/`でiOS端末は判定できる
ユーザーエージェントの一覧が記載されている「[歌うキツネ : User\-Agent \(ユーザー エージェント\) 一覧](http://utaukitune.ldblog.jp/archives/65696057.html)」（※1）を見ると、iPhone、iPodは「`(半角スペース)iP`」が含まれているか、iPadは「`(iP`」が含まれているかどうか（※2）で判定できることがわかります。したがって、iOS端末のユーザーエージェント判別は、次のようなコードで実現可能となります。

```js
const isIOS = /[ \(]iP/.test(navigator.userAgent)
```

`[ \(]` : 半角スペースまたは`(`が含まれる
`iP` : `iP`が含まれる
組み合わせることで、「半角スペース、または`(`から始まり、`iP`が続く文字列」という意味です。

判定部分だけで見ると35文字のコード。**多分これが一番短いコードだと思います**。ちなみにIE 11でもエラーになることなく動作するコードです。

※1 ページに記載されているのは2016年12月までの情報
※2 半角スペースなしの`/iP/`だけだと、Huawei系の端末もヒットする。

# 最後に
実際の案件で使うと可読性が著しく下がる上、`(半角スペース)iPomeranian`のようなユーザーエージェントを持つ端末が将来登場する可能性も0ではありません。

よって、`/[ \(]iP/.test(navigator.userAgent)`は使わず、`/iP(hone|(o|a)d)/.test(navigator.userAgent)`くらいを使うのがよいでしょう（※）。

もし`/[ \(]iP/.test(navigator.userAgent)`よりも短いコードがあれば、お知らせください。

※ 同様の理由で` iPhone Chrome Safari Edge Fox Android`のようなユーザーエージェントを持つブラウザが登場する可能性もあるので、「`iPhone`が含まれるかどうか」も完璧な判定式だとは思いませんが。。。 
事例 → 「[Microsoft Edgeのユーザーエージェントがカオスなので注意](https://qiita.com/tonkotsuboy_com/items/7b36bdfc3a9a0970d23b)」
GAS(Google Apps Scripts)でスプレッドシートを利用する


# スクリプトからスプレッドシートを参照する

## Container Bound Script（スプレッドシートに紐づいている） の場合
```javascript
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
```

## スプレッドシートに紐づいていないスクリプトの場合

```javascript
var spreadsheet = SpreadsheetApp.openById('<キー>');
```

# シートを取得する

## シートを名前で指定して取得する
```javascript
var sheet = spreadsheet.getSheetByName('<シート名>');
```
# セルの値を取得する
行、列の番号を指定することで、セルの値を取得できます。

```javascript
sheet.getRange( row, col ).getValue();
```
GAS(Google Apps Script)のUtilitiesに関するTips

# 日付を指定のフォーマット文字列に変換する。

構文
```javascript
Utilities.formatDate(date, timeZone, format)
```
 date: 文字列に変換したいDateオブジェクト
 timeZone: タイムゾーン　(JST, UTC など)
 format: JavaのSimpleDateFormatに準じたフォーマット指定文字列

|指定文字|時刻要素|
|---------|----------|
| y |年 |
| M	| 月|
| d	| 日|
| E	| 曜日|
| H	| 時 (0-23) 24時制|
| h	| 時 (1-12) 12時制|
| a	| AM/PM|
| m	| 分|
| s	| 秒|
| S	| ms|
| z	| タイムゾーン (+nnnn)|

サンプル
```javascript
Utilities.formatDate(new Date(),"JST","yyyy/MM/dd");
```
Jenkins のビルドログを Dropbox に置いて Github から飛びやすくした

## 状況

- 社内ネットワーク内にある mac で動いてる Jenkins
- Jenkins の job のログを社外からも見たい
- できれば Github の Pull Request のページから簡単に飛びたい
- ログには色々な token とかの機密情報が平文で入ってるから限られた人だけが見れるようにしたい
- VPN とかよくわからない

## やったこと

1. 下のようなコメンドで Jenkins のビルドログを Dropbox 内の特定のディレクトリに書き出します
  - `curl $BUILD_URL/consoleFull > path/to/dropbox/logs/log_${BUILD_NUMBER}.html`
2. Dropbox の設定でこのディレクトリ(logs)を共有したいメンバーに共有します
  - `https://www.dropbox.com/home/logs?preview=logs_${BUILD_NUMBER}.html` という URL でブラウザから見れるようになります
3. github の [Statuses API](https://developer.github.com/v3/repos/statuses/) を使って先程の dropbox の URL を Pull Requset の status に書き込みます
  - curl 使って書き込めます

これらを行った結果、下の画像の `Dropbox` という context の Details から dropbox のページが開けるのでどこからでも安全に jenkins のログを見れるようになりました。

<img width="784" alt="スクリーンショット 2017-10-10 16.17.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/17704/961bccd5-ff73-f732-ed49-29b0e8e063d1.png">

## まとめ

Jenkins のログを Dropbox に書き出す処理自体は以前から行っていましたが、今回社内から Dropbox を同期しないでブラウザから簡単に見たいという要望がありました。

共有 URL を発行すると誰でも見れてしまうため不安だったので Dropbox の共有機能を使って必要なユーザーだけが見れるようにしました。

Github の Pull Request の Status の Detail に URL を載せることで簡単にログにアクセスできるようになりました(フォルダをマウントする形式だとビルド番号からファイル名を探すのが結構手間だった)。

ちょっとした改善でとても効率的になった気がします。
WebAPIでバリデーションチェックエラーの際、HTTPステータスは何を返すのが適切か

先日、WebAPIのバリデーションチェックエラー（必須チェック、桁数チェックなど）でレスポンスを返却する際、HTTPステータスとして何を返すのが適切かで議論となりました。
色々と調べて結論が出たので、せっかくなのでまとめて共有しようと思います。

## 議論メモ
### 返却ステータス案

1. 200 OKを返す
1. 400 Bad Requestを返す

### その時出た意見
* エラーだからOKを返すのも気持ち悪いよね
* 400系は404 Not Foundなどと同じ粒度のエラーで使うべきだよね

などいろいろ出たのですが、これだという結論が出なかったため調べてみました。

## Teratail
最初に、Teratailに質問を投稿してみました。
https://teratail.com/questions/95217
> XHR等で結果を取得する場合、ステータスコード200は正常に取得できた（success）と判断して処理をする記述をされる方が多いように感じますので400系を返すのがよいのではないかと考えます。<br>
teratail APIは容赦なく400 Bad Requestになりますね。
他の実装でも、パラメータ不足等はBad Requestになることが多いかと思います。
エンドポイントが異なる場合等で404が返ることもあります。

上記のようなコメントを頂き、他のAPI仕様を確認してみました。(suyamaさん、コメントありがとうございました！)

## GitHub API
https://developer.github.com/v3/
> Sending invalid fields will result in a 422 Unprocessable Entity response.

## Twitter API
https://developer.twitter.com/en/docs/ads/general/guides/response-codes
> 400 INVALID_PARAMETER


## StackOverFlow
StackOverFlowでも同じような質問を見つけました（最初から検索すればよかった、、）
https://stackoverflow.com/questions/6123425/rest-response-code-for-invalid-data
> 400 is the best choice in both cases. If you want to further clarify the error you can either change the Reason Phrase or include a body to explain the error.
412 - Precondition failed is used for conditional requests when using last-modified date and ETags.
403 - Forbidden is used when the server wishes to prevent access to a resource.
The only other choice that is possible is 422 - Unprocessable entity.

## 結論：400(Bad Request)を返却するのがよさそう
上記の通り色々と調べた結果、やはり400(Bad Request)を返却するのが良さそうでした。
より詳細に返却するのであれば、GitHubのように422(Unprocessable Entity)が適切かもしれません。

参考：[HTTPステータスコード - Wikipedia](https://ja.wikipedia.org/wiki/HTTP%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89)
iOSにおけるHTTPリクエストとTEヘッダの落とし穴

# はじめに

私はiOSプログラミングのエンジニアではなく、サーバーサイド（しかも.NET系）のため、解決策は提示せず、こういう問題が起きうるという紹介に留めさせていただきます。

# 経緯

あるiOSのSDKをバージョンアップしたところ、あるCDNからレスポンスが返ってこなくなってしまいました。

詳しく調査していくと、このSDKではバージョンアップに伴い、サードパーティー製のHTTPリクエスト・ライブラリをiOSネイティブの[NSMutableURLRequest](https://developer.apple.com/documentation/foundation/nsmutableurlrequest)に移行したとのこと。

さらに再現する条件を絞り込むと

* HTTPでは再現しないが、HTTPSだと必ず発生する
* リクエストヘッダに「TE: chunked;q=0」を付けたときだけ発生する
* CDN側ではアクセスログが残っていない（レスポンスを返した記録がない）

ということが分かってきました。

# HTTP/2が使われていた

前述の状況から、リクエスト時点での問題である可能性が高くなり、[NSURLSessionTaskMetrics](https://developer.apple.com/documentation/foundation/nsurlsessiontaskmetrics)の[networkProtocolName](https://developer.apple.com/documentation/foundation/nsurlsessiontasktransactionmetrics/1643141-networkprotocolname)を調べたところ、HTTP通信のときはhttp/1.1が使われている一方で **HTTPS通信のときはHTTP/2が自動で選択**されていました。

# HTTP/2ではTEヘッダは基本的に不正なフォーマット

[RFC7540 Section 8.1.2.2]( https://tools.ietf.org/html/rfc7540#section-8.1.2.2)を読むと、
1つの例外を除き、HTTP/2ではconnection-specificヘッダ([RFC7230 Section 6.1](https://tools.ietf.org/html/rfc7230#section-6.1))は不正な形式として扱うと書かれています。
TEヘッダは値が"trailers"の場合のみが許可されています。

つまり、CDN側は実装としては正しい動作をしていたわけです。

# まとめ

単純に言えば、

* TEヘッダを使わない

というのが一番簡単な解決策です。

そうはいっても、アクセス先が常にHTTP/2に対応しているとは限りません。意図せずHTTP/1.1が選択され、レスポンスがチャンク化されると問題が起きる**かもしれません**。

前置きした通り、この記事ではその問題については言及しません。
逆に言うとiOS以外でも同様の問題は起き得ますので、気を付けましょうという記事でした。
Google FireStore を試したけどまだ早かった

# はじめに

弊社の [Game Server Services](https://gs2.io) はゲームサーバのレンタル事業を行っています。
各クラウドプラットフォームのフルマネージドサービスのみを採用し、安定かつスケーラビリティのあるサービスを提供することを目指しています。
GS2 では Cloud DataStore もサービス開発の際に使用しています。
Cloud DataStore の後継サービスとして開発されているといわれている FireStore のβテストが始まったので早速評価を行いました。

# 所感

Firebase Realtime Database 風のインターフェースを Cloud DataStore の上にのせた。という感じです。
あくまで Firebase Realtime Database 風であり、互換性はありません。そのいくつかはスケーラビリティに問題があった箇所を仕様変更した。といえそうです。

というのも、料金体系が Cloud DataStore と全く同じで、これから解説する仕様から
Firebase Realtime Database のバックエンドは Cloud DataStore と推定できるからです。

# Firebase Realtime Database と比較して劣化している点

## ノード削除

Realtime Database ではノードを削除する際に中間ノードを削除すると、再帰的に子ノードを削除してくれていました。
しかし、FireStore では子ノードがある状態で中間ノードを削除しようとしてもエラー応答するようになりました。

当然ですが、子ノードが大量にある場合削除にかかる時間は一定ではなく、また料金体系としてこのようなコストのかかる巨大なリクエストに対して、それに見合う料金請求が出来ていなかったのが Firebase Realtime Database でした。
FireStore では、子ノードを1つずつ削除する必要があるため(batchリクエストは出来ます)削除1リクエストごとに課金も出来ますし、処理時間も Realtime Database と比較して予測可能な状態になっています。

しかし、利用者サイドの立場から見れば使いにくくなった点といえそうです。

## 子ノードの取得

Realtime Database は秒間スループットをどの程度保証するか明示されていませんでした。
実際に、GS2のサービスでの採用を検討しましたが、性能が安定せず、スケーラビリティもあまり良くなかったという経緯があり採用を見送っています。

一方で、 FireStore には保証される秒間スループットが制限という形で公開されました。
書き込みスループットの制限は ドキュメントあたりの書き込みが秒間1回。コレクションへの追記が秒間500回となっています。
書き込みが秒間1回。というのはいかにも Cloud DataStore といった感じです。
コレクションへの追記は秒間500回と多めになっているのは、コレクションは Cloud DataStore におけるエンティティグループに属していない。という状態でしょう。

これを裏付けるように、現在の FireStore は各ノードのもつコレクション（サブコレクション)を取得する手段がありません。

```
users/1/profile
users/1/image
users/1/items/1
users/1/items/2
```

このようなリソースがある状態において、

`users/1` 以下のドキュメント一覧を取得しても `profile` と `image` しか取得できません。
`items` はどうやっても取得できません。 
`profile` と `image` を削除すると `users/1` を削除できるようになりますが `items` 以下のリソースが残ります。

## Cloud DataStore におけるテーブル構成は以下のようなものになっていると推測します。

**Indexes**

|path|
|----|
|Key('Indexes', 'users/1')|

**Documents**

|key|name|age|url|
|----|----|----|----|
|Key(Key('Indexes', 'users/1'), 'Documents', 'profile')| "taro" | 19 | |
|Key(Key('Indexes', 'users/1'), 'Documents', 'image')|  |  | http://example.com/icon.jpeg |

**users/1/items**

|key|name|count|
|----|----|----|
|Key('users/1/items', '1')|やくそう|5|
|Key('users/1/items', '2')|ひのきのぼう|1|

Collection に属するエンティティが単独のテーブルになっているのは、エンティティグループに含めてしまうと Collection への追記も秒間1回に制限されてしまうためです。
その代償として、特定のノードに属するサブコレクションの一覧を取得する手段が無くなっているのだと推測します。

この仕様により、再帰的に全ての子ノードを削除するのが非常に困難です。
コレクションを作成する際には、メタ情報を作成してどんなコレクションが存在するのかを管理するなど、それなりの努力が必要となるでしょう。

# Cloud DataStore と比較して劣化している点

## 安定性

現在はβ期間中だからだと信じたいのですが、現在の FireStore は全然安定していません。

### gRPCエラー

API呼び出しが数パーセントの確率で失敗します。
失敗する理由の多くは Internal Error のgRPCエラーであり、詳細は不明です。

### 一貫性のある読み込み

FireStore は一貫性のある読み込みができません。
DataStore では見たこと無い症状としてはデータを削除後にデータの一覧を取得すると、削除したデータが含まれた結果が一定期間返ってきます。
これがキャッシュなのか、結果整合によるものなのかは定かではありませんが、Cloud DataStore と比較して一貫性のある読み込みが期待できません。

# 注意するべき点

## Cloud DataStore が使用不能になる

FireStore を有効にすると、GCP の Cloud DataStore が利用できなくなります。
FireStore のバックエンドが Cloud DataStore であるということを裏付ける最大の要因はここですが、一度設定してしまうと後戻り出来ませんので、注意する必要があります。

## ネームスペースが使用できない

Cloud DataStore にはネームスペースという機能がありましたが、FireStore ではデータベースという名前で同機能が利用できそうなSDKになっています。
しかし、現状の FireStore のマネージメントコンソールにはデータベースを切り替える手段がありません。
また、SDKもデータベースを指定すると様々なAPIでエラーが発生し、実質使用できない状態でした。
[Unity]特定の階層にオブジェクト生成(ラクな方法)(Unity5.4)

<h1>方法</h1>
方法としては親を指定するだけでいいのだが、生成した後にわざわざ、～transform.parent=
とかしなくてもよかったとさっき知った。

http://kurihara-n.hatenablog.com/entry/2016/08/13/011728
↑この記事を見て便利な書き方を知った。

今までInstantiate(Obj,transform.position,Quaternion.identity);
みたいに書いたあとに、～transform.parent=
ってやってたけど、Instantiate関数の第四引数にオブジェクト生成する際の親を指定できる。

Unityの公式ページ見たら確かに第四引数にも指定できることが書いてあった。(今まで読んできた本には第四引数使ってるの見たことなかったなぁ、、、（笑）)
https://docs.unity3d.com/ja/2018.4/ScriptReference/Object.Instantiate.html

さっきの記事を見て、自分なりにも書いてみた。

```c#:I_am_hentai.cs
    [SerializeField]
    GameObject characterPre;//生成するもの
    GameObject character;
    [SerializeField]
    Transform characterParent;//親

    void Hoge(){
       character=(GameObject)Instantiate(characterPre,transform.position,Quaternion.identity,characterParent);
    }

```
Google Cloud Platform で cURL error 60: SSL certificate problem ……

Google API を使おう！と言う人にとってはアタリマエのことなのかもしれませんが、ワタクシめにはなかなか解決策が見つけられず苦労したので、同じ境遇の人が生まれないようにメモを残します…。

公式のPHP用SDKと使い方はこちら
[Google Vision APIのクライアントライブラリ 各言語](https://cloud.google.com/vision/docs/reference/libraries)


# 何がしたい？

Google Cloud Platform ……の中の、VisionAPIっていうのを、PHPで使おうと思ったんです。サンプルソースコードもあって、Composerでライブラリが組み込めて、楽勝楽勝♪と思っていたのに、このエラーに阻まれました。


<b>Fatal error</b>:  Uncaught Google\Cloud\Core\Exception\ServiceException: <font color="red">cURL error 60: SSL certificate problem</font>: unable to get local issuer certificate (see http://curl.haxx.se/libcurl/c/libcurl-errors.html) in C:\xampp\cloudvision\vendor\google\cloud-core\RequestWrapper.php:245

言いたいことはわかります。SSLをするのにクライアント証明が無いってことですよね。けど、本格的なサービスを作るわけでもなく、試作や開発要サンプルの段階なので、そういうのすっ飛ばしたいんです。

# 結論

サンプルプログラムはこうなっています。

```php
 $vision = new VisionClient([
     'projectId' => $projectId
 ]);
```

まず、こうします。このJSONは [APIとサービス](https://console.cloud.google.com/apis/credentials) というページでキーを作ったときにダウンロードされるJSONファイルで、それをプロジェクトディレクトリにコピーしてきてパスを通しておきます。

```php
 $vision = new VisionClient([
     'projectId' => $projectId,
     'keyFilePath' => __DIR__ . '/myproject-xxxxx.json'
 ]);
```

次に本題。冒頭の cURL error 60 を回避するためにこうします。

```php
 $guzzleClient = new GuzzleHttp\Client(['verify' => false]);
 $vision = new VisionClient([
     'projectId' => $projectId,
     'keyFilePath' => __DIR__ . '/myproject-xxxxx.json',
     'httpHandler' => function ($request, $options = []) use ($guzzleClient) { 
         return $guzzleClient->send($request, $options);
     }
 ]);
```

# 感想

[VisionClientの公式ドキュメント](http://googlecloudplatform.github.io/google-cloud-php/#/docs/cloud-vision/v0.4.1/vision/visionclient?method=__construct) を眺めていて、なんとなくこの httpHandler っていうのがあやしいなぁという雰囲気はありますが、サンプルがまったくなくて困りました。できてしまうとカンタンであっけないものですが。やっぱりアタリマエのことなのでしょうか…(´ε｀ )

というわけで、Google Vision APIが、なんとなく動かせるようになったので、もうちょっといろいろ遊んでみたいと思います。
ImmutableとLodashでDynamoDBから取得した配列をソートする実装例。

# 概要

ImmutableとLodashを使って配列を任意のキーでソートする機能の実装例を紹介します。前提としてAPI Gateway、Lambda、DynamoDBでサーバーレス構成を構築し、エンドポイントを叩けばソート前のデータが取得できる状態です。またModelの概念を取り入れ、ロジックはModelで持ち、Viewは描画のみを行うようにします。

# やりたいこと

- DynamoDBでGETしてきたデータの配列を任意のキーでソートして画面に表示する
- Viewに直接ロジックを書きたくない

# 実装例

Modelの実装例です。Recordはプロパティやメソッドを持たせることができるので、Model実装に便利です。ソートに関してはLodashの`orderBy`を使います。以下の例では`data.sort`のsortで配列をソートしています。`return { Items: newDatas };`の部分でソートした配列をItemsに入れてnewStateを返します。

```models/item.js
import {
  Record,
  List,
} from 'immutable';

import _ from 'lodash';

const DatasRecord = Record({
  Count: '',
  Items: List(),
  ScannedCount: ''
});

const ItemState = Record({
  datas: DatasRecord()
});

class Item extends ItemState {

  sortByNum(state) {
    const newDatas = _.orderBy(state.datas.Items, (data) => {
      return data.sort;
    }, 'asc');


    const newState = state.update('datas',
      () => {
        return { Items: newDatas };
      });

    return newState;
  }
}

export default Item;
```

ソートの反映はボタン押下で実行できるようにします。

```components/Hoge/SortButton/index.jsx
import React from 'react';

import PropTypes from 'prop-types';

import {
  Button,
} from 'semantic-ui-react';

class SortButton extends React.Component {
  static propTypes = {
    sortNum: PropTypes.func,
  }

  constructor(props) {
    super(props);

    this.handleSortBySortNumber = this.handleSortBySortNumber.bind(this);
  }

  handleSortBySortNumber() {
    this.props.sortNum();
  }

  render() {
      return (
        <div className="container">
          <Button
              basic
              color="teal"
              fluid
              onClick={this.handleSortBySortNumber}
            >
              ソート番号順
            </Button>
        </div>
      )
  }
}

export default SortButton;

```

View側は結果を描画するだけです。またkeyの指定が必要です。VirtualDOMのdiffからDOMに変更を反映させる時に最小限の変更に留めるためです。そのため、keyに指定するのは扱うリスト内でユニークなものである必要があります。

```components/Hoge/Result.jsx
import React from 'react';

import PropTypes from 'prop-types';

import SortButton from './SortButton';


// Class Component
class Item extends React.Component {
  static propTypes = {
    hoge: PropTypes.object,
  }

  constructor(props) {
    super(props);
    this.state = {};
  }

  render() {
    return (
      <div>
        
          {
            this.props.hoge.datas.Items.map((data) => {
              return (
                <div
                  key={data.Id}
                >
                  <div>
                    Name: {data.name}
                  </div>
                  <div>
                    SortNum: {data.sort}
                  </div>
                </div>
              );
            })
          }
　　　　　　　　　　　　　　<SortButton
          {...this.props}
        />
      </div>
    );
  }
}

export default Item;
```
ソートをView側に書くことも可能ですが、どこに何が書いてあるのかメンテナンス上、管理が煩雑になることも考えられるので、ロジックなどはModelの概念を用いて管理するのもいいかと思います。

# 参考

公式
[Immutable](https://facebook.github.io/immutable-js/)
[Lodash orderBy](https://lodash.com/docs/4.17.4#orderBy)
[immutableのメリットとImmutable.jsでのModel定義](http://tech.connehito.com/entry/2016/09/07/091428)
Play Framework 2.6.x Scala PDF

# Play Framework 2.6.x / Scala で PDF出力する方法

GitHub にあるオープンソースのライブラリを使う。
https://github.com/benjohnde/play-pdf

mavenでは公開されていないので
ローカルでjarライブラリをビルドする。

```
cd module
sbt clean
activator publish-local
```

`module/target/scala-2.12` に `pdf_2.12-1.1.3.jar` が生成されるので、この jar を導入先プロジェクトの `lib` ディレクトリにコピーする。（libディレクトリがない場合は新規作成する）

build.stb に下記を追記する。

```build.stb
libraryDependencies ++ Seq(
    "de.benjohn.play" %% "pdf" % "1.1.3"
)
```

日本語フォントを使う場合は、conf ディレクトリの下に fonts ディレクトリを作成して、フォントファイル(例 ipag.ttf）をコピーする。

```
conf
  +- fonts
       +-- ipag.ttf

```

読み込むフォントファイル名を application.conf に追記する。

```application.conf

pdf.fonts = ["fonts/ipag.ttf"]
```

PDFのテンプレートとなるHTML

```views/main.scale.html

<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>@title</title>
        <style>
                @@font-face {
                    font-family: "IPAGothic";
                    src: url("/fonts/ipag.ttf");
                    -fs-pdf-font-embed: embed;
                    -fs-pdf-font-encoding: Identity-H;
                }

                body {
                    font-family: "IPAGothic";
                }
        </style>
    </head>
    <body>
        <h1>画面表示</h1>

```
 
コントローラー

```
def index = Action {
    Ok(PDF.toBytes(views.html.index("日本語 にほんご ニホンゴ JAPAN"))).as("application/pdf")
}
```

play-mailer でメールにPDFを添付する場合は　PDF.toBytes で得られたバイト配列を AttachmentData する。（一時ファイルに保存する必要なし）
P値と信頼区間

# P値は本当に万能なのか
大学の研究室・ゼミで、よく使われる「 **P値** 」ですが、P値は欲しい情報を表し切れているのでしょうか？

## P値とは
まず、P値の説明をします。
**まぐれ当たりの確率** をP値と言います。
P値は、005を基準として、上回れば有意差はない、0.05以下だと有意差はあると、一般的にされている。

### 例
```
A：「コインを投げて、表が出たら僕が君に1000円をあげるよ。裏が出たら、君が僕に1000円をちょうだいね。」
B：「いいよ！！」
1回目：裏
A：「約束通り1000円ちょうだい！！まだやる？」
B：「やる！！」
2回目：裏
3回目：裏
4回目裏
A：「やったー！4回連続裏だ！」
B：「イカサマしてないか？？」
A：「いや、してないよ・・・・だって、4回連続で裏が出る確率は、6%なんだから！！」
B：「なら、もう一回やろう。これで裏が出たら、5%を下回るから、インチキをしたとしてもいいよね？」
5回目：裏
B：「5回連続裏が出る確率は、3%だよね。これはインチキをしたと断言してもいいよね？」
```

## P値の落とし穴
0.05を基準として、その事例がまぐれなのかどうかを判断できるので、よく使われて信頼できる指標であるとされているが、落とし穴がある。

それは、データの数で大きくP値が変動するということです。

データの数を増やせば、P値は小さくなり、有意差があると判断される0.05を容易に下回ってしいます。
逆にデータ数が少なければ、P値は大きくなり、 **「科学的に意味のある差」** なのに、 **「統計的には有意差がない」** と結論づけられてしまう可能性が高くなります。

## 信頼区間
そんなP値の落とし穴をカバーできるのが、「 **信頼区間** 」です。
一般的には、P値と同様に統計的有意差の判定に用いられる指標です。

多くは「95%信頼区間」が利用されます。
この意味は、「信頼区間に真の値が95%の確率で存在している」ということです。

P値と異なる部分は、 **データ数を加味した指標** であるという点です。

### 信頼区間の求め方

```
95%信頼区間 = 群間差±1.96 × 群間差のばらつき( **標準誤差** )
```

標準誤差こそが、データ数の影響を加味してくれています。

標準誤差は
標準誤差 = 標準偏差 ÷ $\sqrt{データ数}\\ $
で、求めることがきます。

つまり、データ数が増えれば、信頼区間は狭くなります。

## 信頼区間の広さ
先ほど、データ数が増えれば、信頼区間が狭くなると数式からわかりました。

「信頼区間が狭くなる」ことは、「真の値が存在する可能性がある区間が狭くなった」ということです。

## まとめ
「P値より万能的に使えるのが、データ数の影響を正しく反映した **信頼区間** 」ということを頭の片隅に置いておいてください。
APACHE2.2 + WEBDAV設定(windows 7) + basic認証

1.httpd.conf の mod_dav を有効する
Edit “%APACHE_PATH%/conf/http.conf“, uncomment the following load statements.
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204707/8ab4df30-b451-29f4-8dd4-9624455ca61f.png)
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204707/60aca9f8-a138-26cd-9448-68f6ab8d38fe.png)
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
※dav_fs_moduleをコメントする原因
⇒エラー「Unknown DAV provider: filesystem」を解消するため

2.共有フォルダとして公開するフォルダの指定
Configure WebDAV folder
![image.png](https://qiita-image-store.s3.amazonaws.com/0/204707/a63d78c7-43c2-84e1-6b55-4ecc555bd3fc.png)
※Order allow,deny　Allow from all
⇒エラー「client denied by server configuration」を解消する
※Options Indexes FollowSymLinks
⇒エラー	「Directory index forbidden by Options directive」を解消する
※[パスワードファイル webdavBasic.txtを作る](https://qiita.com/ousiu0730/items/c6a7d69f190ed18d0439)
3.apacheを再起動する
restart Apache server service
C++11のstd::mt19937をコンストラクタ以外でシード値を設定する方法


# 結論

std::mt19937をコンストラクタ以外でシード値を設定する場合はメンバー関数seedを使います。

# ソースコード


```cpp:main.cpp

#include <ctime>
#include <cstdint>
#include <cstdio>
#include <iostream>
#include <random>

int main(void){

    std::mt19937 Get_random;

    uint32_t seed=time(NULL);

    Get_random.seed(seed);

    std::cout << Get_random() << std::endl;

    return 0;
}

```
数学-三角関数-余弦定理の証明

# 余弦定理の証明

[戻る](12efd87e80b55fc0835f)

## 角Ａが鋭角の場合

- 頂点Ｃから辺ＡＢに垂線を下ろし、交点をＨとする。

<img src="https://qiita-image-store.s3.amazonaws.com/0/4641/5a528e7b-3be3-185f-808f-ef6f014d7ca7.jpeg" width="50%">

```math
\\
\begin{array}{l}
直角三角形 \triangle ACH において、\\
CH = b \sin A \\
AH = b \cos A \\
となる。\\
\end{array}
```

```math
\\
直角三角形 \triangle BCH において三平方の定理より、\\
\begin{array}{rl}
BC^2 &= CH^2 + BH^2 = CH^2 + (AB - AH)^2\\
a^2 &= (b \sin A)^2 + (c - b \cos A)^2\\
    &= (b^2 \sin^2 A) + (c^2 -2bc \cos A + b^2 \cos^2 A)\\
    &= b^2(\sin^2 A + \cos^2 A) + c^2 - 2bc \cos A\\
    &= b^2 + c^2 - 2bc \cos A\\
\end{array}
```

[上へ](#余弦定理の証明)


## 角Ａが直角の場合

- $\angle A$ が直角の場合

<img src="https://qiita-image-store.s3.amazonaws.com/0/4641/00ffc6d4-1750-fe29-7c19-f82e519bc59d.png" width="40%">

```math
\\
\begin{array}{l}
&\cos A = \cos \frac{\pi}{2} = 0 \\
\\
&三平方の定理より、\\
&a^2 = b^2 + c^2\\
\\
&a^2  = b^2 + c^2 = b^2 + c^2 -2bc \cos A\\
\end{array}
```

[上へ](#余弦定理の証明)


## 角Ａが鈍角の場合

- 頂点Ｃから辺ＡＢの延長上に垂線を下ろし、交点をＨとする。

<img src="https://qiita-image-store.s3.amazonaws.com/0/4641/786538a4-c938-eca9-a340-7e992884f74b.jpeg" width="50%">

```math
\\
\begin{array}{l}
直角三角形 \triangle ACH において、\\
CH = b \sin(\pi - A) = b \sin A \\
AH = b \cos(\pi - A) = -b \cos A \\
となる。\\
\end{array}
```

```math
\\
直角三角形 \triangle BCH において三平方の定理より、\\
\begin{array}{rl}
BC^2 &= CH^2 + BH^2 = CH^2 + (AB + AH)^2\\
a^2 &= (b \sin A)^2 + (c - b \cos A)^2\\
&= b^2 \sin^2 A + c^2 -2bc \cos A + b^2 \cos^2 A\\
&= b^2(\sin^2 A + \cos^2 A) + c^2 - 2bc \cos A\\
&= b^2 + c^2 - 2bc \cos A\\
\end{array}
```

[上へ](#余弦定理の証明)
JuliaをJupyterで使えるようになるまで（Ubuntu）

JuliaをJupyter使ってやってみたかったので，やってみました
[ここで](https://juliabox.com/)いろいろ試せました

## 環境

 - Ubuntu 14.04

## Julia インストール

[こちらを参考に]
(https://qiita.com/n_kats_/items/bbfea88247cd0daa01f8)やってみました

先人に倣って

```shell-session
sudo add-apt-repository ppa:staticfloat/juliareleases
sudo add-apt-repository ppa:staticfloat/julia-deps
sudo apt-get update
sudo apt-get install julia
```
で難なくJuliaインストール

## Jupyterで扱う

その後は[こちらを参考に](https://qiita.com/kenmatsu4/items/b77ecec75418cbaa2212)

```jl
Pkg.add("IJulia")
Pkg.add("ZMQ")
```

としましたが

```
============================================[ ERROR: ZMQ ]============================================

LoadError: failed process: Process(`sudo apt-get install libzmq3`, ProcessExited(1)) [1]
while loading /home/username/.julia/v0.6/ZMQ/deps/build.jl, in expression starting on line 35

======================================================================================================

===========================================[ BUILD ERRORS ]===========================================

WARNING: ZMQ had build errors.

 - packages with build errors remain installed in /home/username/.julia/v0.6
 - build the package(s) and all dependencies with `Pkg.build("ZMQ")`
 - build a single package by running its `deps/build.jl` script

======================================================================================================
```

と出てきたので

```jl
Pkg.build("ZMQ")
```
とするも失敗

```shell-session
sudo apt-get install libzmq3
```

で入れてあげて，もう一度

```jl
Pkg.add("IJulia")
Pkg.add("IJulia")
```
で通りました

いつのように

```shell-session
jupyter notebook
```
でJupyterを立ち上げると，Juliaが選択できるようになっていました
adbでandroidの無線LANのアドレスを取得する

# コマンド

```
$ adb shell ip addr show wlan0 | grep 'inet ' | cut -d' ' -f6 | cut -d/ -f1
192.168.1.xxx
```

# 参考

https://stackoverflow.com/questions/13169249/adb-command-for-getting-ip-address-assigned-by-operator
pySerialをTornadoを使ってイベント駆動っぽくするメモ

# TL;DR
pySerialを使ってシリアルポートから受信する際に，組込系の受信割り込みめいた処理を行いたいときはTornadoのioloopを使ってポーリングすると似たようなことが出来る．

# なにがしたいか
pySerialを使うとOS非依存でシリアルポートを使えて便利です．
ただ、基本的にはポーリングでの利用がメインになるので[^1]，任意の条件をみたした時にコールバック関数を呼ぶ的な動作は単体だとできません．
そこで，[Tornadoをスケジューラとして使ってマルチタスクっぽいのを実現するメモ](https://qiita.com/Dr10_TakeHiro/items/612c5bed111c7140c0f7)で書いたTornadoでマルチタスクっぽいのを実現する方法を使って，コールバック関数っぽい処理を実現してみました．
（本当はこういうことしない方がそれっぽいのかもしれませんが，組み込み系のUART受信割り込みを処理するのに慣れた身だとこういう書き方が一番楽なんです・・・）

# ソースコード
基本的には，Tornadoのioloopを使ってpySerialを一定周期で読みに行って，条件をみたしたらコールバック関数を呼ぶ形です．
下の例では，終端文字(`'\n'`)を受信したらコールバック関数が呼ばれるようになっています[^2]．

```python
# -*- coding: utf-8 -*-
import time
import tornado.ioloop
import serial


class SerialPolling(object):
    def __init__(self, port, baudrate, delimiter=b'\n'):
        self.serial_port = serial.Serial(port, baudrate)
        self.delimiter = delimiter

        self.ioloop = tornado.ioloop.IOLoop.current()
        self.read_buffer = b""
        self.LOOP_FREQ = 1000

        self.loop()

    def loop(self):
        self.ioloop.add_timeout(time.time()+1/self.LOOP_FREQ, self.loop)
        self.read()

    def read(self):
        self.read_buffer += self.serial_port.read(self.serial_port.inWaiting())
        % 以下条件確認．任意の条件に変更可能
        for segment in self.read_buffer.split(self.delimiter)[:-1]:
            self.callback(segment)
        self.read_buffer = self.read_buffer.split(self.delimiter)[-1]

    def callback(self, recieved_segment):
        print("Receieved: ", recieved_segment)


if __name__ == "__main__":
    serial_porlling = SerialPolling("COM16", 115200)
    tornado.ioloop.IOLoop.current().start()
```

[前回の記事](https://qiita.com/Dr10_TakeHiro/items/612c5bed111c7140c0f7)で書いたように，`ioloop.add_timeout`を使って`loop()`が`LOOP_FREQ` Hzで実行されるようにしてあります．
`loop()`から呼ばれた`read()`は，まずpySerialの受信バッファの内容をすべて`read_buffer`に移したあとで条件確認とコールバック関数の呼び出しを行います．
今回の例では，`split()`関数を用いて終端文字で文字列を分割，分割後の要素ごとにコールバック関数を呼び出すようにしてあります．
（`read_buffer`内が`"abc\ndef\ngh"`であれば，`callback("abc")`，`callback("def")`が呼び出され，`read_buffer`内に`"gh"`が残る．）
この個所の条件を任意に変更することで，様々なプロトコルに対応可能です．

[^1]: どうやら`aync`/`await`が実装されつつあるのでそのうちもっとスマートに実現できるようになるかもしれないですね．
[^2]: それなら`readlines`とか`readline`でいいじゃんって話ではあるんですが，あれだと`"abc\ndef\ngh"`が受信バッファにあるときに`["abc", "def", "gh"]`を返してきて`"gh"`の処理に困るのです．
メタプログラミングRuby  4章 スコープを越える  スコープゲート フラットスコープ その１

メタプログラミングRuby 4章のブロックに関してのアウトプット。

変数のscopeを越える方法（スコープゲートの突破）をまとめます。

## Before

```ruby:scope.rb
var = "scopeを越える瞬間!!"
puts var #=> scopeを越える瞬間!!

class HogeClass# スコープの壁①

  puts "①ここで使えるようにしたい"
  puts var #=> error

  def magic_scope# スコープの壁②
      puts "②メソッドの中でも使いたい"
      puts var
  end
end
```

実行すると....

```
$ ruby scope.rb 

scopeを越える瞬間
ここで使えるようにしたい
scope.rb:11:in `<class:HogeClass>': undefined local variable or method `var' for HogeClass:Class (NameError)
Did you mean?  var
	from scope.rb:8:in `<main>'
```
→ 普通にscopeで落ちる。

これを使えるようにしてしまうのが、**スコープのフラット化** というものです。


## After
まずは①のスコープゲートを超える方法。
classをスコープゲートではない、メソッド呼び出しに置き換える。メソッド呼び出し。
→ブロックをClass.newに渡すと、クラスにインスタンスメソッドを定義することができます。

```ruby:scope.rb
var = "scopeを越える瞬間"
puts var

HogeClass = Class.new do # ブロックをClass.newに渡す

  puts "ここで使えるようにしたい"
  puts "①:#{var}" # ①

  def magic_scope
      puts "メソッドの中でも使いたい"
      puts "②:#{var}" # ②
  end
end
```
実行

```
$ ruby scope.rb
scopeを越える瞬間
ここで使えるようにしたい
①:scopeを越える瞬間 #=> 超えた！！
```

続いて②を超えます。

ここもメソッド呼び出しに置き換えることで実現可能。
define_methodを使用する。

```ruby:scope.rb

var = "scopeを越える瞬間"
puts var

HogeClass = Class.new do

 puts "ここで使えるようにしたい"
 puts "①:#{var}"

 define_method(:magic_scope) do
   puts "メソッドの中でも使いたい"
   puts "②:#{var}"
 end
end

puts HogeClass.new.magic_scope
```

実行

```
$ ruby scope.rb
scopeを越える瞬間
ここで使えるようにしたい
①:scopeを越える瞬間
メソッドの中でも使いたい
②:scopeを越える瞬間
```
以上です。
フラットスコープを駆使すれば、スコープでやりたいことはほとんどできそうです
個人開発の時にはどんどん使用してみます。
AndroidManifestにいきなりroundIconが出てきた時の対処法

AndroidManifest.xmlでいきなり見知らぬroundIconとやらがエラーを出した時の対処法です。

環境
MacBookPro(13-inch, Mid 2012)
MacOS Sierra version10.12.6
Android Studio 2.3.3
JRE 1.8.0_112


参考にしたサイトはこちら（英語です）↓
https://stackoverflow.com/questions/43049734/no-resource-identifier-found-for-attribute-roundicon-in-package-android

自分はとあるLibraryを入れた後Rebuild Projectをしたあと急に出てきました。消してrun,buildしたりしても元に戻ってエラーを吐きました。

Rebuild Projectした後のエラー

```java:error.java
No resource identifier found for attribute 'roundIcon' in package 'android'
Exception failed for task '.app.processDebugResources'.
>com.android.ide.common.process.ProcessException:Feiled to execute aapt
```
と出ました。

どうやらroundIconはSDKversion 25から使用できるようになるものでもちろん24以下では使用ができません。

そのためどうしても24以下のSDKを使用しなければならない場合を除いてSDKversionを25に上げるとcompileが通るようになります。

appのbuild.gradle
![スクリーンショット 2017-10-10 14.40.21.png](https://qiita-image-store.s3.amazonaws.com/0/180370/a9199664-5b20-45ff-e1ab-9cbc2cfff275.png)
上の画像のcompileSdkVersionを25に変更してAndroidStudioに上に出てくるSyncNowを押してください。
Rails + Puma + React のローカル環境で HTTPS 接続してみる

# 概要
Rails + Puma + React のローカル開発環境でどうしても HTTPS 接続したいときがあったので、ローカル環境で HTTPS 接続するための手順を残します。

# 手順
## 1. 自己証明書作成
プロジェクトディレクトリで下記コマンドを実行する。

```bash
$ cd /Users/owner/git/hoge
$ openssl genrsa -out ./localhost.key 2048
$ sudo openssl req -new -x509 -key ./localhost.key -out ./localhost.crt -days 3650 -subj /CN=localhost
```
## 2. Puma 設定ファイル編集

```bach:config/puma.rb
# HTTPS 利用可能設定
if "development" == ENV.fetch("RAILS_ENV") { "development" }
  ssl_bind '0.0.0.0', '3001', {
    key: "/Users/owner/git/hoge/server.key",
    cert: "/Users/owner/git/hoge/server.crt",
    verify_mode: "none"
  }
end
```

## 3. Webpacker 設定ファイル編集
dev_server の ```https: false``` を ```https: true``` に変更する。　

```bash:config/webpacker.yml
development:
  <<: *default

  dev_server:
    host: 0.0.0.0
    port: 8080
    https: true
```

## 4. 動作確認
``` https://localhost:3001/ ``` にアクセスして ```HTTPS``` でアクセスできることを確認する。
ローカル環境でも HTTPS を利用した動作確認ができるようになりました。
IoTシステム技術基礎検定 #0　どういう試験なの？

　| #0 | [#1 1-1 ~ 1-6](https://qiita.com/yamato031033/items/a039f729fd6317554f80)>>
#＜この記事、何？＞
- 12月に実施される、IoTシステム技術基礎検定について書いていこうと思います。
- 今回初めて設けられる試験ですので勝手がわかりにくいですが、以下の[公式サイト](http://www.mcpc-jp.org/iotkentei/index.html)が参考になります。
- 初投稿です。読みにくいかもしれませんがご了承ください。


#＜概要＞
- 試験について
  IoTシステム技術検定は、IoTを用いたシステムを構築・活用するための技術や知識の習得を目指す方を対象としていて、IoTシステム構築・活用に関する技術知識を認定し、そのスキルを基礎、中級、上級の3段階で区分しています。
 その中で、基礎検定は主に大学・短大・専門学校の学生や新社会人をターゲットとしており、試験に合格することで、IoTに関する基礎知識を保持していることを証明できます。
IoT、BD（ビッグデータ）、AI(人工知能）に関する実務に適用（活用）することが期待されます。

- 試験日程
第1回 2017年12月2日（土）
9:50～10:50（1時間）

- 試験会場
東京、横浜、名古屋、大阪、札幌、仙台、さいたま、広島、福岡
具体的な場所は受検票での告知。とりあえず、各駅周辺と考えておきます。。

- 受験料
10,800円（税込）
バウチャー有、MCPCの会員や協力企業の方には割引があるみたいです。

- 問題数
マークシート式60問
単純計算で1問/分のペースで解答。
中級と同じ形式なら4択ですね。
- 出題範囲(対策教材)
以下の公式テキストより出題されるようです。


[ MCPC「IoTシステム技術検定　基礎編」対応 ―（モバイルコンピューティング推進コンソーシアム監修）]
(https://www.amazon.co.jp/IoT%E6%8A%80%E8%A1%93%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-%E5%9F%BA%E7%A4%8E%E7%B7%A8-MCPC-IoT%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E6%8A%80%E8%A1%93%E6%A4%9C%E5%AE%9A%E5%9F%BA%E7%A4%8E%E5%AF%BE%E5%BF%9C-%E5%85%AC%E5%BC%8F%E3%82%AC%E3%82%A4%E3%83%89/dp/4295002461)
![alt](https://images-na.ssl-images-amazon.com/images/I/51UTob8ipCL._SX351_BO1,204,203,200_.jpg)

A5判の200P程度。7章構成で、以下の章に分かれています。

1章　IoTの概要を知る
2章　IoTデバイスを理解する
3章　IoTにおける通信方式を知る
4章　モバイル環境とその活用を知る
5章　IoTでデータを活用する
6章　プロトタイピングを知る
7章　情報セキュリティを知る
8章　IoTのエコシステムを知る

配分は分かりませんが、テキストのページ数だけなら1,2,3,7章が多いですね。

#＜サンプル問題＞
いつの間にか公式が追加していました。こんな感じで出てきます。
[基礎問題](http://www.mcpc-jp.org/iotkentei/pdf/kisosample.pdf)
[基礎解答](http://www.mcpc-jp.org/iotkentei/pdf/kisosampleanswer.pdf)

（参考）以下は中級のサンプル問題ですが、基礎の知識でも解ける範囲です。
[中級問題](http://www.mcpc-jp.org/iotkentei/pdf/sample.pdf)
[中級解答](http://www.mcpc-jp.org/iotkentei/pdf/sampleanswer.pdf)

#＜今後＞
資格取得に向けて、勉強の記録やメモを書いていきたいと思います。参考になれば幸いです。

　| #0 | [#1 1-1~1-6](https://qiita.com/yamato031033/items/a039f729fd6317554f80)>>
jsdoでMK-80 その10

#概要
jsdoでMK-80やってみた。
Mk-80を説明してみる。

#一言で言うと
NECが昭和に発売した。8bitワンボードマイコンTK-80を2012年11月4日にJeansがHTML5によるエミュレートしたもの。

#TK-80とは

https://ja.wikipedia.org/wiki/TK-80

#作者は

http://hp.vector.co.jp/authors/VA016157/mk80web02/mk80web.html

#TK-80との違いは

モニタプログラムが自作。
RAMが、1024バイト。
セーブできる。

以上
技術適合マーク外製品(TBS2910 Matrix ARM)のWi-Fi無効化利用について

#前略
皆さまの録画環境は幸せでしょうか？

私の過去実績は下記URLをご覧ください。
[Chinachu + Mirakurun + TVTest によるリアルタイム視聴&録画機能](https://qiita.com/h-mineta/items/28dddff08d5a52dedffb)
[Chinachu + Mirakurun をdockerに閉じ込めた話](https://qiita.com/h-mineta/items/5b06c43c6d25a0ad23f8)

上記成果により録画については平穏な日々を過ごしています**が**、
安定しすぎて遊びが欲しくなりました

##シングルボードコンピュータ(以下、SBC)
昨今Raspberry Piが安く手軽に手に入るので流行ってるのですが、
如何せんPCI-Expressスロットが無い為
Linux&PT3を利用したい私にとっては選択肢になりませんでした

別の候補としてIntel NUCがmini PCI-Expressを備えていること、
入手性と信頼度について申し分がないのですがちょっとばかし高価(10k over)な事や
急を要する事案でもないので放置しておりました

##TBS2910 Matrix ARMとの出会い
そんな日々を過ごしていた時、下記のSBCがあることを知りました

TBSテクノロジー社のIPTVソリューション向けSBCとのことです
[TBS2910 Matrix ARM mini PC](https://www.tbsdtv.com/launch/tbs-2910-matrix-arm-mini-pc.html)

- Quad Core ARM Cortex-A9 1GHz(Max 1.2GHz) と性能はありそう
- mini PCI-Expressがある
- GPUでハードウェアエンコードできそう
- eMMCが付いているなど機能は十分
- 802.11n/b/g ...

**Wi-Fi ｱｯｰ**

こちらの製品は日本国内販売はされておらず、もちろん**技術適合マーク無し**

しかし、諦めきれずダイアグラムを見てみるとRT8188EUSがUSBで繋がっているだけ
[Schematic Diagram](https://www.tbsdtv.com/download/document/tbs2910/TBS2910-Matrix-ARM-mini-PC-SCH_rev2.1.pdf)
2.4GHzだけのWi-Fiなんて要らないし、これはもしかするとパターンカットだけでWi-Fiを止められるんじゃないか?


## 技術適合マーク(以下 技適マーク)
技適マークについては各々検索していただいた方が詳しい情報があるので、
ここでの詳細は控えますが総務省のHPにもある通り
技適マークが付いてない無線機を使用すると**電波法違反**となります
[総務省 - 技適マーク、無線機の購入・使用に関すること](http://www.tele.soumu.go.jp/j/adm/monitoring/summary/qa/giteki_mark/)

*1年以下の懲役又は100万円以下の罰金
また、公共性の高い無線局に妨害を与えた場合は、5年以下の懲役又は250万円以下の罰金*

## 総務省(東海総合通信局)に聞いてみよう
自己判断で使うのは問題なので実際に電話で問い合わせてみました
なお、住居が東海エリアにつき東海総合通信局に問い合わせをしています

---

### Q. ソフトウェア的に無線機能を無効にすれば利用しても良い?
A. *NG*
技適マークを持たず電波を送信できる状態で製品を利用することは**電波法違反**となる
(ここは事前に知ってた通り)

---

### Q. ハードウェア的に無線を送信できない加工がされていれば利用しても良い?
　　(例: 基盤上のパターンカット or 無線チップの排除)
A. **OK**
法律上は**電波を送信しないのであれば利用可能**
なお、ハード的に無効化する方法までは定義されていないとのこと

---

普段「技適マークが無い機器は使いたいけど、**Wi-Fiは要らない**からハード的に無効化したらOK？」なんて質問は無いらしく
電話に出られた担当者の方も「あ～」と困っておられました(申し訳ありません)

おかげでモヤモヤは無事解決しました
東海総合通信局のご担当者様有難う御座いました

#草々
その後~~ヤフオクで~~ポチりました
届いたら速攻でWi-Fiをヌッコロして電源を入れる予定です
その後、メインの録画環境は上手くいったら続きを書きます

運営さん> 今はプログラミング要素無いのですが、お待ちくださいorz
UILabelを配列に入れてみる

どうも、こんにちはTOSHです!

最近、Swiftでiosアプリ制作にはまっているのですが、その際にたくさんのUILabelに対して、同じ動作をさせる際に、配列に入れられたらなぁと思っていたのですが、それについての記事がなかったので書かせていただきます。

# 方法A

##UILabelを配列にしてみる
まずは、storyboardにlabelを５つほど置いてみます。
![スクリーンショット 2017-10-10 13.10.48.png](https://qiita-image-store.s3.amazonaws.com/0/180994/240b17a8-1893-e5bb-416a-5db4ef3dcac9.png)

ここからは、コードにうつります
通常、UILabelを関連付けする際には、

```Swift:ViewController.swift
@IBOutlet weak var label: UILabel!
```

のように書きますが、UILabelを配列にする際には、weak参照はできないので
下のように書きます。

```Swift:ViewController.swift
@IBOutlet var labelArray: [UILabel] = []
```

このように書くと、UILabelの配列を作成できます。
そして、関連付けをしていく順番に
`UILabelArray[0]` `UILabelArray[1]` `UILabelArray[2]`
と定義されていきます。

##実際にできているのかを確認してみる

```swift:ViewContorller.swift
override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        for i in 0...4{
            labelArray[i].text = "label number \(i)"
        }
    }
```

のようにやってみると、（for文の中身は一行ですが、Swiftでは一行であっても{}を省略はできないので注意してください！)

![スクリーンショット 2017-10-10 13.11.02.png](https://qiita-image-store.s3.amazonaws.com/0/180994/804a2729-8d7a-d5da-86e4-8b87ae25f215.png)

無事、labelを配列に置き換えることができました。

これで完成です。お疲れ様でした。

##サンプルプログラム
参考までに、githubに、サンプルプログラムを載せて置いたので参考にしてください！
[サンプルプログラム](https://github.com/tosh7/sample1)

# 方法B
もう一つ方法があります。
そもそも、UILabelの配列の変数を作ってしまい。一つ一つUILabelを`@IBOutLet`で定義をしてあげ、
その配列の中に入れてしまう方法です。

```swift
@IBOutlet weak var label0: UILabel!
@IBOutlet weak var label1: UILabel!
@IBOutlet weak var label2: UILabel!
@IBOutlet weak var label3: UILabel!

let labelArray: [UILabel] = [label0, label1, label2, label3]
```
方法Aでは、UIパーツの弱参照が切れてしまうので、こちらの方法をとると弱参照を保持したまま、配列にすることができます。
正直どっちがいいのかは一長一短なので、使いやすさに応じて使ってみてくださいー！
Angularで範囲外をクリックしたイベントを取得する

#やりたいこと

「開いているウィンドウの範囲外をクリックしたら、ウィンドウを閉じる」といった動きを実現する際に、範囲外をクリックしたイベントを取得したい。

jQueryで言うところの、
[範囲外クリックでポップアップを閉じる正しい JQuery](https://qiita.com/mabots/items/74c21ebcedf0004f7fb5) 


# 自分で実装

Output、EventEmitterの仕組みを使えば、簡単に実装できました。
イメージ的には、「子コンポーネントでグローバルなクリックイベントを拾って、そのイベントが自分に対するものではなかったら、親コンポーネントにイベントを投げる」と言った感じです。

## 子コンポーネント

Output, EventEmitter, HostListener, ElementRefをインポートし、ElementRefをconstructorでDIします。

```typescript:child.component.ts
import { Output, EventEmitter, HostListener, ElementRef } from '@angular/core';

constructor(
    private elementRef: ElementRef
) {}
```

コンポーネントの範囲外がクリックされたことを親コンポーネントに通知するためのイベントのバインディングを定義します。

```typescript:child.component.ts
@Output() clickOutside = new EventEmitter<MouseEvent>();
```

HostListenerデコレータを宣言した後に、範囲外がクリックされたことを検知するメソッドをバインドします。

```typescript:child.component.ts
  onClickOutsidefDetailSearch(event: MouseEvent, targetElement: HTMLElement) {
    const clickedInside = this.elementRef.nativeElement.contains(targetElement);
    if (!clickedInside) {
      this.clickOutside.emit(event);
    }
  }
```

## 親コンポーネント

clickOutsideイベントを受けるメソッドを定義します。

```typescript:parent.component.ts
  onClickOutside(event: MouseEvent) {
        console.log(event);
        // 何かする
  }
```

```typescript:parent.component.html
<app-child (clickOutside)="onClickOutside($event)"> My element </app-child>
```


# ライブラリを使う

[ng-click-outside](https://www.npmjs.com/package/ng-click-outside) というライブラリがあるようです。

先に紹介した自分で実装する方法では、個々のコンポーネントに一連の実装を行う必要がありましたが、こちらのライブラリでは、ディレクティブとして機能が使えるため、めちゃ楽です。

## 使ってみる

インストール

```
$ npm install --save ng-click-outside
```

インポート

```typescript:app.module.ts
import { ClickOutsideModule } from 'ng-click-outside';

@NgModule({
  ...
  imports: [
    ...
    ClickOutsideModule
    ],
    ...
})
class AppModule {}
```

clickOutsideイベントを受けるメソッドを定義します。

```typescript:parent.component.ts
  onClickOutside(event: MouseEvent) {
        console.log(event);
        // 何かする
  }
```

好きなエレメント、コンポーネントにディレクティブを追加します。

```typescript:parent.component.html
<div (clickOutside)="onClickOutside($event)">My element</div>
```

# 参考

https://qiita.com/mabots/items/74c21ebcedf0004f7fb5
https://github.com/valor-software/ngx-bootstrap/issues/1823

# 終わりに

今回紹介した内容を実装するにあたって、参考に記載したgithubのissueを参考に自分で実装した後に、便利なライブラリがあることに気づきました...
HostListenerをの使い方を再確認するいい機会になったかと思います。
とりあえずng-click-outsideを使いましょう。
AndroidのFlatListでOutOfMemory

## 問題
Androidでクラッシュ。
画像をたくさん読んでいるのでOutOfMemoryっぽい

ListViewはほぼほぼFlatListに置き換えているのに何でだろう

## 調べたこと
android manifestでlargeHeap = trueにする
https://stackoverflow.com/questions/39655791/out-of-memory-application-crash-react-native


下記の3つをやってみる
>1.Make sure FlatList is not a child of ScrollView as scrollview will render all child components, even those not on the screen in FlatList.
>2.Add prop removeClippedSubviews to FlastList so it removes items out of view. (didn't test if this is redundant to #1)
>3.Implement shouldComponentUpdate for the renderItem component or make it a PureComponent.

https://github.com/facebook/react-native/issues/13413

## やってみる
#### largeHeap = true
heapが大きくなるので画像が表示されない、みたいな問題はなくなるが、結局落ちるときには落ちる

#### scroll view と flatlistのネストをやめる
全体の構造を変えないと行けないのでスキップ

#### removeClippedSubviews
多少マシになった感あり。要検証。
※ bugもあるようなので自己責任でとのこと

#### shouldComponentUpdateを組み込む
後回し

#### その他
react-navigation使っているのですが、stack navigatorで重ねた時に下のscreenは残っているので、重いもの重なり過ぎている説は有力

## 結論
ロジックも含めて継続改善中。。
良い方法あれば教えてください、、 <-
aws: both ssh and mysql connection hang

# エラー内容
`ssh -i ~/.ssh/鍵名.pem ec2-user@IP`と`mysql -h エンドポイント -P 3306 -u root -p`の二つのコマンドを打っても何も返答がない状態。少し待っていると`ERROR 2003 (HY000): Can't connect to MySQL server on [endpoint] (60)`というメッセージが。

# 解決策
EC2 -> security groupsにあるinboundに最新のmy IP addressに更新してあげるだけ。