OmniAICreator/Qiita-1.07M huggingface dataset:
NLP for Java (NLP4J) (2)


以下のような感じで簡単なJavaプログラムを書くとテキストマイニングが楽しめるというコードを作りましたので、近々オープンソースとして公開しようと考えています。
「自然言語処理をやってみたい」「テキストマイニングをしてみたい」という方をターゲットに考えています。

形態素解析エンジンにはYahoo JapanのWebサービスを利用しています。
形態素解析の結果を利用して、文書に特徴的なキーワードを出力します

処理とInput

```java
		List<Document> docs = new ArrayList<Document>();
		{
			docs.add(createDocument("Toyota", "ハイブリッドカーを作っています。"));
			docs.add(createDocument("Toyota", "ハイブリッドカーを売っています。"));
			docs.add(createDocument("Toyota", "自動車を作っています。"));
			docs.add(createDocument("Toyota", "自動車を売っています。"));
			docs.add(createDocument("Nissan", "EVを作っています。"));
			docs.add(createDocument("Nissan", "EVを売っています。"));
			docs.add(createDocument("Nissan", "自動車を売っています。"));
			docs.add(createDocument("Nissan", "ルノーと提携しています。"));
			docs.add(createDocument("Nissan", "軽自動車を売っています。"));
			docs.add(createDocument("Honda", "自動車を作っています。"));
			docs.add(createDocument("Honda", "自動車を売っています。"));
			docs.add(createDocument("Honda", "バイクを作っています。"));
			docs.add(createDocument("Honda", "バイクを売っています。"));
			docs.add(createDocument("Honda", "軽自動車を売っています。"));
			docs.add(createDocument("Honda", "軽自動車を作っています。"));
		}
		Annotator annotator = new YJpMaAnnotator();{
			// 形態素解析処理
			annotator.annotate(docs);
		}
		Index index = new SimpleDocumentIndex();{
			// キーワードインデックス作成処理
			index.addDocuments(docs);
		}
		{
			// 共起性の高いキーワードの取得
			List<Keyword> kwds = index.getKeywords("名詞", "item=Nissan");
			System.out.println("Keywords(名詞) for Nissan");
			for (Keyword kwd : kwds) {
				System.out.println(String.format("%.1f,%s", kwd.getCorrelation(), kwd.getLex()));
			}
		}
		{
			// 共起性の高いキーワードの取得
			List<Keyword> kwds = index.getKeywords("名詞", "item=Toyota");
			System.out.println("Keywords(名詞) for Toyota");
			for (Keyword kwd : kwds) {
				System.out.println(String.format("%.1f,%s", kwd.getCorrelation(), kwd.getLex()));
			}
		}
		{
			// 共起性の高いキーワードの取得
			List<Keyword> kwds = index.getKeywords("名詞", "item=Honda");
			System.out.println("Keywords(名詞) for Honda");
			for (Keyword kwd : kwds) {
				System.out.println(String.format("%.1f,%s", kwd.getCorrelation(), kwd.getLex()));
			}
		}
	}
```

Output: Nissanに特徴的なキーワードを係数の大きい順に表示する

```
Keywords for Nissan
3.0,EV
3.0,ルノー
3.0,提携
1.0,軽自動車
0.6,自動車
```

Toyota と Honda はこちら

```
Keywords(名詞) for Toyota
3.8,ハイブリッド
3.8,カー
1.5,自動車
Keywords(名詞) for Honda
2.5,バイク
1.7,軽自動車
1.0,自動車
```
PHP関係まとめ 

## デバッグ

* [xdebugメモ](https://qiita.com/k_hoso/items/142c7b155e75e54b9079)
* [PhpStormとxdebugがどういう関係なのかのまとめ](https://qiita.com/k_hoso/items/a35a52e481b12f238c0f)

## Dockerコンテナ

* [PHP+xmlrpcのDockerfile](https://qiita.com/k_hoso/items/7353292730807012ca88)
macでvisual studio codeのgit機能を使う流れ


# visual studio Codeを起動

<img width="1440" alt="スクリーンショット 2019-08-28 21.58.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9370/4f332b2c-3a50-cefe-b35a-4d8cd54b8bf3.png">

<img width="57" alt="スクリーンショット 2019-08-28 22.00.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9370/fc193c14-3d4f-31e5-b0e6-49f9a2f0aa34.png">を押す。（このアイコンがバージョン管理システムの管理ツール）

変更したファイルが↓画像の赤枠部分に表示されます。
<img width="647" alt="スクリーンショット 2019-08-28 22.01.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9370/2f43515e-a4da-23f1-5eb8-8433f3858c8a.png">

管理対象フォルダにファイルを追加した例
<img width="426" alt="スクリーンショット 2019-08-28 22.04.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9370/f46ff7e2-1c6d-b1f6-40a5-cebf8002320f.png">


＋を押して、ステージに乗せる
<img width="436" alt="スクリーンショット 2019-08-28 22.06.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9370/0452b379-4180-174b-593a-cd248759e80c.png">

＋で追加したtest.htmlがSTAGED CHANGESに入った。
<img width="451" alt="スクリーンショット 2019-08-28 22.07.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9370/37b6e631-93c2-f893-c294-92b28c5b9b82.png">

チェックマークをクリックしてコミット。
<img width="465" alt="スクリーンショット 2019-08-28 22.08.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9370/71b997f2-8b4a-babe-82b3-3b44f3433e2d.png">

テキスト入力粋が表示されるので、コミットメッセージを記述してエンターキーを押す。
<img width="1174" alt="スクリーンショット 2019-08-28 22.10.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9370/3f0927d6-ae45-d2bf-1b28-beec90edce02.png">

「・・・」を押すと、メニューが出てきます。PullとPushを行います。
<img width="645" alt="スクリーンショット 2019-08-28 22.11.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9370/776646d1-f72b-77df-624b-8672ca386b10.png">
Macのショートカット覚えてる？

# この記事について
　先日今使っているMacを購入したのですが、キーボードのキーの位置が違くて困っていました。
今まで生きてきてWindowsしか触ったことがなかったので打ちたい、出したいものがすぐに出せなかったのでここに備忘録かけて残しておきます。
（ショートカット見つかり次第アップデートします）
# 入力補助
## ひらがな変換する
control　➕　ｊ
（WindowsだとF6）
## 全角カタカナ変換する
control　➕　ｋ
（WindowsだとF7）
## 半角英数変換する
control　➕　：
（WindowsだとF8）
## 全角英数変換する
control　➕　ｌ
（WindowsだとF9）
## 文字入力の確定をする
control　➕　ｍ
（WindowsだとF9）

# 画面表示
## メニューバーを表示する
control　➕　F2

## Dockを表示する（デスクトップ下部に表示されるアプリ一覧）
control　➕　F3

## spotlightを表示する
command⌘　➕　スペース

##シークレットモードを表示する
control　➕shift ➕　N

# 終わりに
ここはキー1つで変換できるWindowsの勝ち。
また更新します。
GooglePlayConsoleの時間指定公開が思っていたのと違った件

#前書き
GooglePlayで最近[人力での審査が入るようになったり](https://www.t3a.jp/blog/android/android-open-time/)、[８月にポリシーが更新された](https://play.google.com/intl/ja/about/updates-resources/)ことなどからか、
アプリの公開に数時間かかったり、気づいたらリジェクトされていたりという話をちらほら聞きます。
「アプリの公開はなるべく早くしてほしい！」
「公開日に突然リジェクトされるのは困る！」
そんな時は**時間指定公開を利用しましょう**
ただこの機能、利用するには非常に戸惑うポイントが何箇所かありまして、
~~難解な~~公式ドキュメントを読み漁り、試行錯誤した結果を同じように戸惑っている方の一助になればと思いここに記します。

#時間指定公開を有効にするには
「ストアの掲載情報」のページ下部にある時間指定公開をオンにすることで有効化されます。
　時間指定公開が有効な場合、GooglePlayConsoleの各画面上部に「時間指定公開」の表示が出ます。
<img width="972" alt="画面上部.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/660f24d3-0d92-1942-c252-c73bcc0db2ff.png">
ストア掲載情報の変更などを行うと、ページ下部にある「アップロードを送信」ボタンが有効になります。
アップロード送信完了後、ページ上部の**公開ボタンが有効になりこのボタンを押下するとストアに反映されます。**

アップデートの送信後、公開可能になるまで多少時間がかかる様ですが
「アプリ内サービス」の管理対象のアイテムの更新などは即時更新となっています。
「管理対象のアイテム」画面上部にこの様な表示がでます。
<img width="965" alt="管理対象アイテム.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/80af5d2c-1e50-e68c-8d79-f7c763ec43ef.png">

#時間指定公開というネーミングの罠
時間指定公開設定は「時間」を「指定」して「公開」できる機能**ではありません。**
通常の公開はアップロード→公開が一連の流れで行われ、このアップロードの段階で審査が行われているようです。
なので、標準公開では公開までに時間がかかったり、リジェクトされたりするわけですね。
一方、時間指定公開は**アップロードだけを事前に行い公開は任意のタイミングで行えるようにする**機能です。
感覚的にはAppStoreへの申請のイメージに近いかと思います。

[アプリの公開(PlayConsoleヘルプ)](https://support.google.com/googleplay/android-developer/answer/6334282?hl=ja&ref_topic=7072031)
<img width="788" alt="スクリーンショット 2019-08-28 21.52.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/bc74b433-27e1-ccf1-8d18-d7ae955a6ad8.png">


#変更ログの罠(2019/11/27更新)
~~内部テストの作成、内部テストからクローズテスト、クローズテストから製品版への移行など**リリースに関わる操作は一切変更ログには残りません。**
リリースページの上部にはしっかりと「時間指定公開」の状態になっているのに、
変更ログには一切残らない為とても不安になりますが**ページ上部にある公開ボタンを押さない限り公開される事はありません。**~~
リリースの作成や移行などが**変更ログに記載されるようになっていました！**
安心してリリースを作成してください。

#怖すぎる文言の罠
製品版リリースを作成した際、最終確認のボタンがの文言が通常通り**「確認して公開」のままになっています。(とても怖い)**
が、**ページ上部にある公開ボタンを押さない限り公開されません。**
安心して確認と公開を行ってください（公開されません）

余談ですが、「これは日本語訳がおかしいのだろう🤔」と思い
英語版のGppglePlayConsoleを確認してみたら「Production rollout(製品版の展開)」でした😇

#アップデートの送信が押せない罠
リリースの公開を行った場合はページ下部の**「アップデートを送信」ボタンは特に有効にならないようです。**
リリースの公開=アップデートの送信ということでしょうか。

試しに「ストアの掲載情報」からアプリの説明文を変更した場合は「アップデートを送信」ボタンが有効化されていました。
時間指定設定をオンにした状態で何らかの変更を行うと、**時間指定公開をOFFできないので注意が必要です**
<img width="698" alt="スクリーンショット_2019-08-28_22_14_44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203331/cf9bef37-438e-7f76-f897-9cdf7af12c72.png">


リリース公開後、~~アップデートを送信が押せないことに戸惑っていたら~~15分程してから公開ボタンが有効になり押せるようになっていました。
通常のアプリ公開でもGooglePlayの反映は大体5分〜15分程(当社調べ)なので
今回は審査の対象にならなかったのかもしれません(謎)

#まとめ
文言など戸惑うポイントはあるかと思いますが基本的に
**ページ上部に「時間指定公開」と表示されている。(時間指定公開が有効になっている)**
**「公開」ボタンを押さない限り公開されない。(他のボタンに公開と書いてあっても)**
以上のことを頭に入れておけば問題ないかと思います。

今回のアプリはそもそも公開で何日も待たさせるという事がなかったので、
アップロードから公開可能になるまでの時間がかかるパターンが検証できませんでしたが
上のドキュメントのスクショにもある通り3日以上の余裕を持ってアップロードの送信を行ってくださいとのことです。

今後はAndroid向けアプリも余裕を持ったリリーススケジュールで行っていきましょう！(3敗)

#ちょっとした不安点
　変更ログのダイアログの右下も公開なのは怖いからやめてほしい(間違えて押しそう)
　一度時間指定公開にした場合は次回も時間指定公開をデフォルトにしてほしい(時間指定公開にしてると勘違いして通常公開にしてしまいそう)
AWS 認定試験勉強の後半戦は Whizlabs で問題を解きまくるといいぞ

## はじめに
最近 AWS 認定ソリューリョンアーキテクトアソシエイト(SAA)の資格を取得しました。取得スコアは867、合格に必要なスコアは720だったので、悪くない点数が取れたかと思います。

勉強法については、Qiitaやブログなどを参考にしました。
例えば [AWS認定11冠制覇したのでオススメの勉強法などをまとめてみる](https://qiita.com/nakazax/items/20458e146d3d9f2aa615) など参考になる記事はたくさんあり、おすすめ通りの勉強を1ヶ月ほど行いました。具体的には [合格対策 AWS認定ソリューションアーキテクト －アソシエイト](https://amzn.to/3cIq38h) を読みつつ、知識が足りない部分に関しては BlackBelt、ドキュメントを読み込みました。

ある程度知識がついたので模擬試験を受けましたが問題数は25問のみだったので、間違えた問題を復習しても本番には少し不安が残っていました。

そこで、ネット上でSAAの問題がたくさん解けるサービスがないかと探していたところ、[Whizlabs](https://www.whizlabs.com/) という実践テストのコースがたくさんある海外のサイトを見つけたので簡単に紹介します。

## [Whizlabs](https://www.whizlabs.com/) とは?
Online Certification Training サービスで、様々な資格試験のためのトレーニングを受講することができます。AWS認定試験のコースについては、全ての種類の試験のトレーニングが存在するようです。また、GCP や Azure などの資格試験コースもあります。
<img width="1424" alt="スクリーンショット 2019-08-28 21.58.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184983/9a551c07-1ad9-a743-5419-16df19379a64.png">

## SAAのサンプル問題を解いてみる
では、実際に SAA のサンプル問題を Whizlabs で解いてみましょう。 [AWS Certified Solutions Architect Associate (SAA-C01)](https://www.whizlabs.com/aws-solutions-architect-associate/) のページの Free Test を選択し会員登録します。(ここまで無料)
<img width="1419" alt="スクリーンショット 2019-08-28 22.12.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184983/6dcd6aaa-30bf-8f17-4763-0242b90ef3c7.png">
画面としてはこんな感じで、問題と右側には何問中何問まで解いたか、あとでレビューするためのチェックボックスなど、とても使いやすい設計となっています。
<img width="1419" alt="スクリーンショット 2019-08-28 22.04.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184983/910e4e7d-0636-3b33-fae9-2867bf772303.png">
公式の模擬試験ではスコアはでましたが解答はありませんが Whizlabs では、１問１問解答を確認できるため、すぐに復習をできる点がとても良いです。
<img width="1423" alt="スクリーンショット 2019-08-28 22.09.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184983/3faeb38c-179c-57ac-5a73-05d24c3c0d90.png">

## 問題を解きまくる
Free Test を解いて使えそうだなと思ったら $19.95(2000円弱)を支払って Practice Tests で問題を解きまくりましょう。定期的にセールが行われているので、セール時を狙って購入するのもありです。

トータルでは620問ほどあり、これを全て解いたら確実に合格に近くと思います。自分の場合は65問ほど解いて、不明点は [BlackBelt](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/) を読んで納得するというのを行なって合格できました。資格のための勉強という側面だけでなく、業務でも普通に使える知識が幅広くついたので受験してよかったなと思っています。

## まとめ
ある程度の知識がついたらあとは本番の試験を想定した問題をたくさん解くというのは資格試験においては定石であるため、それができる Whizlabs は合格に近づくサービスだと思います。また英語の勉強にも繋がるので一石二鳥です。

## 最後に
[Twitterアカウント](https://twitter.com/taigokuriyama) でクラウドサービスや機械学習に関する情報を発信していますので興味のある方はフォローをお願いします。また [Hello, Data Science](https://www.hellodatascience.work/) というデータサイエンスに関するブログも書いているのでぜひこちらも。
PhpStormとxdebugがどういう関係なのかのまとめ

## 最初にまず見るべき

いきなり人様の記事のリンク張るのもあれだけど、まずは↓を見る。
[[PHP] Xdebug のリモートデバッグ、理解していますか？](https://qiita.com/castaneai/items/d5fdf577a348012ed8af)

## PhpStorm側の話

デバッグを開始する際に受話器のアイコン↓をオンにするが、xdebugがデバッグ情報を送ってくる受け口を立てている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299475/573ac48b-85a5-d498-8a2e-f019a4a3abba.png)


PhpStormの設定（`settings > Languages&Frameworks > PHP > Debug > xdebugの欄`）にあるのも、"自分自身が何番ポートでデバッグ情報を受けるのか" という設定となる。

ちなみに、xdebugからの初回アクセスがあった際に、`Incoming connection`のダイアログがでて、`Accept` する必要があるが、`Accept`すると、`settings > Languages&Frameworks > PHP > Servers` に設定が勝手に作られる。

## xdebug側の話

php.iniのxdebugセクションに設定する↓はどこにデバッグ情報を送るかという設定になる。

```
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
```

[xdebugの公式](https://xdebug.org/docs/all) 内の↓も要参照。

* "With a static IP/single developer"
* "HTTP Debug Sessions"

xdebugのパラメータの話は [ココ](https://qiita.com/k_hoso/items/142c7b155e75e54b9079) も参照。
プログラミング学習（4日目）ITパスポート

今日は家でプログラミングをする時間が一切無かったのですが、Qiitaにも何かしら投稿しないと三日坊主になるかと思ったので投稿します。
#ITパスポート
ITパスポートの中でも出題頻度が多く、プログラミングする上でも必要になりそうな「ネットワーク」の箇所についてアウトプットしていきます。

##ネットワーク
LANは、ローカルエリアネットワーク。狭い範囲のコンピュータ同士のネットワーク
WANは、ワイドエリアネットワーク。電気通信事業者が設置した通信回線を使った通信をWANという。

Wi-Fiは、無線LANの規格のひとつ。

ESSIDは、無線LANを識別する名前。

回線交換方式とは、通信回線を独占して行う通信。通信速度は早いが、利用効率が低い。

パケット交換方式とは、データをパケットという単位に分解して複数の回線で通信する方式。
利用効率は良いが、通信速度は遅くなりがち。

通信プロトコルとは、通信する際のルールのようなもの。

###電子メールのプロトコル
SMTPは、メールサーバにメールを送るプロトコル。
POPは、メールサーバからメールをダウンロードするプロトコル。ダウンロードしたメールはメールサーバに残らないので、複数のPCでは見れない。
IMAPは、メールサーバのメールをダウンロードせずに閲覧するためのプロトコル。複数のPCで見れる。

##インターネットの仕組み
IPアドレスとは、ネットワークに接続しているコンピュータの識別番号。
IPv4は、32桁の2進数。IPv6は、128桁の2進数で表されてる。

このIPアドレスを人間が読みやすい文字列にしたのがドメイン。
そしてIPアドレスとドメインを相互に結びつけるのがDNS（Domain Name System）

そしてこのIPアドレスと似てるのが、ポート番号とMACアドレス。

ポート番号とは、アプリケーション事に割り当てられる値。

MACアドレスとはネットワーク機器ごとの固有の宛先。

また、IPアドレスにはグローバルIPアドレスとプライベートIPアドレスがある。

グローバルIPアドレスとは、直接インターネットに接続する機器に割りあけられる世界でただ1つの値。

プライベートIPアドレスとは、直接ネットに繋げない機器に割り当てられる値。

そして、このグローバルIPアドレスを各コンピュータに割り当てるのがDHCP。

プライベートIPアドレスとグローバルIPアドレスを結びつけるのが、NAT。
GitHub+2段階認証+SourceTreeの環境で毎回パスワードを聞かれないようにする方法

## 前置き
新しい環境でSourceTreeを使うとき、毎回パスワードを聞かれるのを止めるのどうやるんだっけ・・・となるので、それを解決するためのまとめになります。

## やりたいこと
SourceTreeでクローンやフェッチをすると毎回パスワードを聞かれるのを止めたい。

## 前提条件
* SourceTreeでGitHubを使う
* GitHubの2段階認証を有効にしている
* GitHubが推奨しているHttpsを使いたい
* GitHubのアクセストークンは発行済み状態

## 環境
* macOS Mojave 10.14.4
* SourceTree 3.2.1

## 手順
基本的な手順はGitHub公式に載っています。
https://help.github.com/en/articles/caching-your-github-password-in-git

ざっくり言えば、キーチェーンにパスワードを保存する設定に変えれば良いとのことです。

#### 「Xcode Command Line Tools」のインストール 
「Xcode Command Line Tools」が入ってない場合はインストールします。
ダウンロードは https://developer.apple.com/download/more/ からできます。AppleIDが必要です。

```
$ git credential-osxkeychain
```
のコマンドが通ることを確認します。

#### キーチェーンに保存する設定
以下のコマンドを叩きます。成功しても特に何か表示されることはありません。

```
git config --global credential.helper osxkeychain
```

#### SourceTreeでクローンする
##### アカウントの環境設定
SourceTreeの環境設定を開き、アカウントタブを選択します。
以下の設定内容でアカウントを追加します。

ホスト：GitHub
認証タイプ：Basic
ユーザー名：適当でもいいみたい（？）
パスワード：GitHubのアクセストークンを入力
プロトコル：HTTPS

##### クローンする
初回クローンするときに、キーチェーンにアクセスするためのログインパスワードを聞かれるので入力します。（パスワード無しなら聞かれないと思います）
これでパスワードがキーチェーンに保存されるので、クローンやフェッチをしてもパスワードは聞かれなくなります。

## …それでもまだパスワードを聞かれる場合
キーチェーンやSourceTreeに正しくないパスワードが保存されている場合があるようです。
この場合、正しいパスワードを入力しても変更されないみたいです。
そのため、キーチェーンアクセスから "github" を削除したり、SourceTreeのアカウントを一度削除してから、↑の手順を行えば解決しました。

## 参考URL
https://stackoverflow.com/questions/38489022/sourcetree-keeps-asking-for-github-password
https://stackoverflow.com/questions/11067818/how-do-you-reset-the-stored-credentials-in-git-credential-osxkeychain
DockerToolboxから見たホストOSのIPアドレスの調べ方

Docker Tookboxで起動したコンテナから見たホストOSのIPアドレスは`192.168.99.1`になる。

toolbox用のVirtualboxの設定に紐づいているネットワークアダプタを、windowsの"ネットワーク状態"の同名アダプタのプロパティからIPアドレス見れる。
Leetcode #1165: Single-Row Keyboard

```swift
func calculateTime(_ keyboard: String, _ word: String) -> Int {
    var ar = Array(repeating: 0, count: 26)
    for (i, char) in keyboard.enumerated() {
        ar[Int(char.asciiValue!) - 97] = i
    }
    var previous = 0
    var time = 0
    for char in word {
        let index = ar[Int(char.asciiValue!) - 97]
        time += abs(index - previous)
        previous = index
    }
    return time
}
```
Textareaで未確定文字がvalueに勝手にinsertされてしまう現象を修正した

# 概要
社内アプリケーションにていつからか、Windowsユーザの方から
「未確定文字がtextareaに勝手にはいって、かつ、未確定文字は残っている」
という不思議な現象が起きるようになった。

## 結論
input eventを使えばいい

## 解消した方法
Vue.jsを使っており、textareaにて、様々なイベントをつけていた。
その一部で keyup eventを使っていたが、それを input event に変更した。

```
<template>
    <textarea
            v-focus
            rows="8"
            cols="40"
            accesskey="g"
            :value="value"
            @keyup.esc="anything"
            @keypress.enter.exact="something"
            @keyup="update"></textarea>
</template>
```
↓

```
<template>
    <textarea
            v-focus
            rows="8"
            cols="40"
            accesskey="g"
            :value="value"
            @keyup.esc="anything"
            @keypress.enter.exact="something"
            @input="update"></textarea>
</template>
```

## 原因
正直わからない。(調べ方がわからない)
あるkeyによって起きるということではなく、たまに起きる。ということ、おそらくIMEの問題ではないかと思っている。
詳しい人がいれば教えて下さい。
Ardino IDEで見つけた最近出るエラー？

###  8/21 人生初のハンズオンに参加してきました。
[【増枠】M5StickC + LINE Things + Amazon Connect連携ハンズオン](https://ldgk.connpass.com/event/140572/)
---------------

その時、主催者の方でも初見だと言われたエラーを叩き出したのでその原因を調べてみました。
エラー文をそのまま検索にかけても全然ヒットしない（そもそもこんなエラー出ない....笑）


その時出たエラー文がこちら（micro：bitになっていますが当日はここがm5Stickcになってました）
------



<img width="836" alt="スクリーンショット 2019-08-28 20.35.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488939/c19d89e4-2128-76e2-4a5b-850fa2c32eca.png">



<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">人生初のハンズオン！<br>なかなか楽しいですが謎のエラー出ちゃったよ^_^<a href="https://twitter.com/hashtag/ldgk?src=hash&amp;ref_src=twsrc%5Etfw">#ldgk</a> <a href="https://t.co/S8SSBYWTL2">pic.twitter.com/S8SSBYWTL2</a></p>&mdash; ようかん (@inoue2002) <a href="https://twitter.com/inoue2002/status/1164142294208929794?ref_src=twsrc%5Etfw">August 21, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>








































# bad cpu type ってなんなんだよ

そんなエラーが出た時の原因を見つけました。





[ArdinoのQ&A]
(https://forum.arduino.cc/index.php?topic=620175.0)



ここで皆さん共通しているのが　
## mac os のベータ版を導入している事。

mac os 10.15 は32bitアプリに対応しておらず、Arduino IDEは32bitアプリの為動かないとの事でした。

OSをバックアップ復元して戻して動かす方法が賢そうですね....


こちらも参考にしてみてはどうでしょうか。

https://github.com/arduino/Arduino/issues/8626



##### 人生初のQiita記事です！笑　これからも色々記事にしていけたらなぁ〜と考えております。





# まとめ
パブリックベータ版を入れている人しか出会わないエラーだったのでもし同じような方がおられたら役に立てば幸いです！
高階オイラーの方程式にチャレンジ

#オイラーの方程式を解く
ごくごく単純なオイラーの方程式を解いて見ます。
かんたんすぎるので知っている人にはすごく退屈だと思います。

##オイラーの方程式とは
オイラーの方程式とは次のような同次微分方程式のことを言います。

```math
x^n y^{(n)} + a_1x^{n-1}y^{(n-1)}+・・・+a_{n-1}xy^{(1)}+a_ny=0
```

ここでyの右肩添字は微分回数を示しています。
具体的にはこんな微分方程式と今日出会いました。

```math
f^{(4)}+\frac{2}{r}\cdot f^{(3)}-\frac{9}{r^2}\cdot f^{(2)}+\frac{9}{r^3}f^{(1)}=0
```

ここで両辺にr^4をかけるとオイラーの方程式になることに気づければ勝ちです。


```math
r^4f^{(4)}+2r^3 f^{(3)}-9r^2\cdot f^{(2)}+9rf^{(1)}=0
```

ここまでできれば


```math
f=r^\lambda
```

を上式に代入することで以下を得る。

```math
r^4\lambda(\lambda-1)(\lambda-2)(\lambda-3)r^{\lambda-4}+2r^3 \lambda(\lambda-1)(\lambda-2)f^{(3)}r^{\lambda-3}-9r^2\lambda(\lambda-1) f^{(2)}r^{\lambda-2}+9r\lambda f^{(1)}r^{\lambda-1}=0
```

すべての項にr^λが共通しているので、両辺をr^λで割り、λを整理すると以下の式が得られます。

```math
\lambda(\lambda+2)(\lambda-2)(\lambda-4)=0
```

よってλは0,-2,2,4となります。
これでfの一般解は次のようになります。

```math
f=C_1r^2+C_2r^4+\frac{C_3}{r^2}+C_4
```

以上です。
自分用メモですが誰かの役に立てたなら光栄です。
今後も勉強を継続し、皆様に有益な情報を発信できるエンジニアになりたいですね。
個人的にwebスクレイピングでよく使うメソッド(Javascript)

備忘録としてNode.jsでWebスクレイピングをする際に個人的によく使うメソッドをまとめておく。

## 前処理編
### filter
配列にフィルターを施す。
任意の条件に対して返り値が`true`であった値のみ出力される。
**外部ファイルからデータを読み込むようにしていたため、不正なURLやパラメータが記載されていた場合は排除するようにしていた**。

```example.js
var urlList= ["https://example.co.jp/item", "https://example.co.jp/list", "https://exmple.co.jp/user"];
var filteredUrlList = urlList.filter(url => url.includes("https://example.co.jp"));
console.log(filteredUrlList ) // Array ["https://example.co.jp/item", "https://example.co.jp/list"]
```

### splice
配列から指定した値を削除したり追加したりする。
filterと似たような使い方をしていたため、どちらかというと配列内のデータを削除したいときに使う。

### toLowerCase & toUpperCase
対象の文字を大文字もしくは小文字に変換する。
**外部ファイルから読み込んだデータをURLのパラメーターとして使う際によく置換していた**。

## データ加工編

### replace
対象の文字を指定した文字に変更できる。
**正規表現と組み合わせて余分な空白を削除したり日付を任意のフォーマットに変更する**ときによく使う。

```example.js
var date = "2018/02/21";
var modifiedDate = date.replace(/\/,-g/, "-");
console.log(modifiedDate) // "2018-02-21"
```

### substring & substr
対象の文字列から指定したインデックスの文字を取得する。
`substring`は 第二引数は終了地点であるのに対し、`substr`は取得文字数を意味している。
**

```example.js
var date = "2018/02/21 12:32";
var modifiedDate = date.substring(0, 10);
console.log(modifiedDate) // "2018/02/21"
```

【追記】
確認すると、どうやら`substr`は非推奨とまではいかないものの、できるだけ使用は避けるべきと[公式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring)に記載がされている。


## 出力編

### push & contat
指定したデータを配列の一番後ろに追加することができる。
`push` を使うとpushされる前のデータはなくなる(破壊的結合)が、`contat` を使うとその前のデータは保持される(非破壊的結合)という違いがある。
**Webスクレイピングで取得したデータを出力対象に追加する**際に使う。

```example.js
var items = ["a", "b", "c", "d"]; // So Many Data
var newItem= "e";
items.push(newItem);
console.log(items); // Array ["a", "b", "c", "d", "e"]
```

### slice
配列もしくは文字列から指定した範囲を抜き取る。
`splice`とは異なり、以前のデータは破壊されない。
**取得したデータを分割して出力する**際に使う

```example.js
var items = ["a", "b", "c", "d", "more"]; // So Many Data
for (i=0, i*50 >item.length, i++) {
    var list= date.slice(i*50, (i+1)*50);
    console.log(list) // "50件ずつ出力"
};
```
git初心者　あれこれ

## PullRequestとMergeの話
  登場人物A, B。

  Aが適当なフォルダをGitで管理し、GitHubへ公開。
  Bがclone。
  AはBへのpush権限を振る。ただ、mergeはAしか出来ない様にする。
  Bがmasterブランチのままファイルを変更。コミットする。
  もちろん、Bはmasterへpushできない。(※1)
  ただ、この状態でdevelopブランチをBが作って、移動する。
  そのdevelopブランチでもファイル変更・コミットをする。
  Bはmaster以外のブランチは作れるし、push出来るので、pushは成功した。
  Bは続けて、develop->masterのmergeをPullRequestとして申請。
  Aが受諾。
  
  この時、面白いのが、Bの※1のコミットは、pushできなかったが、
  PullRequestの受諾によって、developブランチ経由で、masterにも、※1のコミットが記録される。
Leetcode #1170: Compare Strings by Frequency of the Smallest Character

```swift
func numSmallerByFrequency(_ queries: [String], _ words: [String]) -> [Int] {
    var ar = Array(repeating: 0, count: words.count)
    for (i, word) in words.enumerated() {
        ar[i] = frequency(Array(word))
    }
    ar = ar.sorted()
    var answer = Array(repeating: 0, count: queries.count)
    for (i, query) in queries.enumerated() {
        let num = frequency(Array(query))
        answer[i] = binarySearch(ar, num)
    }
    return answer
}

private func frequency(_ str: [Character]) -> Int {
    var smallest = str[0]
    var count = 1
    for i in stride(from: 1, to: str.count, by: 1) {
        if str[i] > smallest {
            continue
        } else if str[i] < smallest {
            smallest = str[i]
            count = 1
        } else {
            count += 1
        }
    }
    return count
}

private func binarySearch(_ ar: [Int], _ num: Int) -> Int {
    var start = 0
    var end = ar.count - 1
    while start <= end {
        let mid = start + (end - start) / 2
        if ar[mid] > num {
            end = mid - 1
        } else {
            start = mid + 1
        }
    }
    return ar.count - start
}
```
ReactのComponentの中での条件分岐

子要素を分岐させたい時のメモ。
基本的に、子要素はReact.createElementの第3引数になるので、
JSXのタグの間に挟まるものは式ではなくてはならない。
が、javascriptのifは式ではなくて文なので少し面倒。

# 対応策1:三項演算子を使う
三項演算子を使えば文ではなく式になるのでOK

``` jsx
<div>
 {someCondition ? <Hoge/> :<PIYO/>}
</div>
```

# 対応策2
無名関数中でif+returnを書き即実行する。

``` jsx
<div>
  {(() => {
      if(someCondition){
         return <HOGE/>;
      }
      return <PIYO/>;
    })()}
</div>
```

# 対応策3
対応策2の応用で関数部分を関数コンポーネント化する

``` jsx
const HogePiyo = (props) => {
      if(props.someCondition){
         return <HOGE/>;
      }
      return <PIYO/>;
    };


//中略
render () {
  return ( <div>
             <HogePiyo someCondition={someCondition}/>
           </div>);
}


```
与えられた木が二分探索木か判定するアルゴリズム by 幅優先探索

[前回](/ataham/items/0f617d13f01b175f74d8)につづいて、「与えられた木が二分探索木か判定するアルゴリズム」について。

二分木が二分探索木であると判定するには、すべての節が制約を満足しているか調べればよいと前回の記事に書いた。これは幅優先探索でも実現できる。

次のコードは幅優先探索ですべての節が制約を満足しているか調べるものである。

```python
import collections


def is_binary_tree_bst_bfs(tree: BstNode) -> bool:
    QueueEntry = collections.namedtuple('QueueEntry', ('node', 'lower', 'upper'))
    bfs_queue = collections.deque([QueueEntry(tree, float('-inf'), float('inf'))])

    while bfs_queue:
        entry = bfs_queue.popleft()
        if entry.node:
            if not (entry.lower <= entry.node.data <= entry.upper):
                return False
            bfs_queue.append(QueueEntry(entry.node.left, entry.lower, entry.node.data))
            bfs_queue.append(QueueEntry(entry.node.right, entry.node.data, entry.upper))

    return True
```

`is_binary_tree_bst_bfs` は根の節を受け取り `QueueEntry` オブジェクトにしてキュー (`bfs_queue`) につめる。 `QueueEntry` オブジェクトは `BstNode` オブジェクトと、その節を二分探索木として成立させるための下限値 (`lower`) と上限値 (`upper`) を含む `namedtuple` である。

ループの中でデキューして節を取得し、その値が `lower` 以上かつ `upper` 以下であるかチェックする。この条件を満足しなければ `False` を返す。満足していれば、「左の子」「右の子」とキューに詰めて、ループを継続する。ループを最後まで回せたら `True` を返す。

この方法では木を最後まで巡回せずとも `False` を返せる。このことから前回のコードより実行効率が高いと期待したが、サンプルデータに対してこのコードを走らせると前回のコードより遅かった (約30倍くらいの実行時間になる)。
【Rails】dotenvで管理していた環境変数が反映されなくなった時やってみること

##dotenvで管理していた環境変数が反映されなくなって大変こまった
環境変数をカンタンに管理できる便利gem、dotenvを利用していましたがプルリクやマージやら重ねてるうちに環境変数が反映されなくなって大変困った

##この記事を必要としていた人に教えられること
ない、結論から言うと**bundle update**で直った。原因わからないから教えて欲しい。

##私が使っていた環境

```
$ rails -v
Rails 5.2.3

dotenv 2.7.5
dotenv-rails 2.7.5

```
ちなみに次のようにGemfileに書き込み、dotenvを利用した。

```rb:Gemfile
gem 'dotenv-rails'
```


####.envはルートディレクトリに置いてあった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339446/05f83951-14b4-3e3b-cea7-2e1d1e66700c.png)


##参考
spring stopしたらいいらしいです、私はやってませんが...
https://qiita.com/metafalse/items/7294afa3d1be3315e999
UnityのVR SamplesのMazeでキャラクターを変更する

# はじめに
前回記事 [UnityのVR SamplesのMazeでカメラの位置をキャラクターに追従する]
(https://qiita.com/Satoshi_Takahama/items/e0f4e0e07543c0d60f84) の続きです。
今回は、キャラクターを変更してみたいと思います。
変更するキャラクターとしては、VRM形式の「ニコニ立体ちゃん」を使用します。

#開発環境
Unity 2019.2.0f1
VR Samples - 1.4
Oculus Integration for Unity - 1.39
UniVRM v0.53.0
「ニコニ立体ちゃん」(VRM版)


#ビルド手順
前回記事で作成したプロジェクトで引き続き作業します。

1. 今回もThe Mazeを改造するので、サンプルのシーンMazeを開きます。
2. まずはVRM形式のモデルのファイルを読み込むためのアセットUniVRMを[vrm-c/UniVRM](https://github.com/vrm-c/UniVRM/blob/master/README.ja.md) からダウンロードします。自分がダウンロードしたファイルは"UniVRM-0.53.0_6b07.unitypackage"ですが、数字の部分はバージョンにより変わります。
3. Assets -> Import Package -> Custom Packageからファイル"UniVRM-0.53.0_6b07.unitypackage"を指定してインポートします。
4. 次に、キャラクターのファイルを[ニコニ立体ちゃん (VRM)](https://3d.nicovideo.jp/works/td32797) からダウンロードします。
5. Projectウインドウで、Assetsフォルダの下にキャラクターを配置するフォルダ(今回はModelsとします)を作成し、ダウンロードしたファイル"AliciaSolid.vrm"エクスプローラーからドラッグアンドドロップすると、プレファブができます。
6. できたプレファブをHierarchyウインドウのCharactersの下にドラッグアンドドロップします。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/bbfff27a-c0b7-77cc-c9fc-347ce46926ee.png)
7. CharactersのMazeCharacterからAliciaSolidに赤枠で囲んだコンポーネントをコピーします。Inspectorウインドウ上で1個ずつ右クリックで"Copy Component"して"Paste Component As New"でコピーします。TransformとAnimatorの設定も合わせます。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/b617345a-1592-09a2-cbaa-ca4895c28e26.png)
8. Third Person Charactorコンポーネントの設定も元の値と変わっていた場合、元の値にあわせておきます(AI Charactor ControlでRequireComponentされているため、コピーする順番によりデフォルトの値になるようです)。Ground Check Distanceの値が0.1になっていると、キャラクターの動作が不自然になります。
9. MazeCharacter側のチェックを外して無効にします。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/ab68f61a-88d5-1a5f-bd3e-a6dcf8345711.png)
9. あとは、あちこちで設定されているMazeCharacterへの参照をAliciaSolidに直していきます。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/a56d8a69-2f5f-eba6-4690-4689d1677aca.png)
10. すべて変更したら、ビルド設定からビルドします。

![com.oculus.vrshell-20190828-203156_Trim_300x300_fps10.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/1fd2c387-2b84-94c5-bc5b-e36605302fcc.gif)

#さいごに
今回キャラクターを変更することができたのですが、変更する箇所が多く、結構手間がかかりました。
VRMのファイルを配置するだけで簡単に変更できるようにする方法がないか、引き続き検討してみたいと思います。
=>記事を追加しました [UnityのVR SamplesのMazeでキャラクターの変更を自動化する]
(https://qiita.com/Satoshi_Takahama/items/d3010d26495e69a3bc56)
LINE Platform Meetup vol.3 ECに参加してきた

# はじめに
[こちら](https://line.connpass.com/event/141788/)に参加してきたのでメモ書きを残します。

# 【セッション1】LINEプラットフォームの機能と可能性/LINEプラットフォームにおけるLINE Pay APIを利用したトークルームECについて　LINE 立花/LINE Pay藤平
前半の話はLINEサービスの基礎的なものだったので省略します。後半はLINE Payについての話です。過去に[記事](https://qiita.com/ufoo68/items/a6d036d143fe4950aea3)を書いたことあります。このサービスは手軽に試すことができます。
LINE Payサービスの登録ユーザーは3600万人(2019/7調べ)に登るとのこと。今回は[トークルームEC](https://ecfanatic.com/blog/wazzupkeyword/)についての紹介でした。実際にサントリーホールディングスの導入事例があるそうです。

# 【セッション2】Webサービスや通販サイトでのMessaging APIの利用について LINE API Expert 西本様
[WazzUp!](https://wazzup.me/)の紹介でした。ここではMessaging API・LIFF・リッチメニュー・フラックスメッセージなどの例でのECの紹介がありましたが、LINE Loginを使ったECサイトへの埋め込みについても紹介されました。LINE Loginは唯一試したことないAPIなので今度個人的に試してみようかなと思いました。
また、EC関係のBotでは以下の３つがかなり熱いとのこと。

- 人材系
- 在宅系
- 保険系


# 【セッション3】従量課金対策の決め手はセグメント配信！6つの従量課金対策と成果が上がる LINE 活用術	WazzUp！野田様
６つのLINE通数課金対策についてはメモしきれませんでしたが、今後重要となるのは全体ではなく特定の個人に向けた配信にフォーカスすることということを学びました。成果としても個別配信のほうが圧倒的に上がるそうです！！いちばん大事なのはアカウントの設計であるとのこと。例として、ブランド・性別で分けるなど。。
後はWazzUp!の紹介だったので省略します。

# 【セッション4】「企業は”目的”でアカウントを使い分けろ！公式、APIの使い分け実践方法​」 株式会社メガネスーパー 川添様
LINEサービスの課金体制の変更という背景から、アカウントの設計を考えることが重要になる。積極的に活用する企業ほど配信数に注意する必要がある。

課金体制などLINEサービスには危険な要素もあるが、位置情報を使ったサービスはLINEを活用するほうが便利である。

あとはオフレコの話がほとんどだったので省略します。後日上がる資料をご期待ください。

# 【セッション5】LINE活用で家を購入！？LINE活用して大変革したハウスメーカーのLiny活用事例
ECではなく、実店舗経営者のLINE活用についての話でした。[Liny](https://line-sm.com/)について紹介されました。このサービスはLINEの特性を生かして顧客をセグメント化させたサービスが実現可能とのこと。

# おわりに
LTで参加してきました。資料は[こちら](https://docs.google.com/presentation/d/181HMJolk0J1o1ohZyY2R0hrh9AHYPY-1dgzbL7LDXJU/edit?usp=sharing)です。
毎度のことですが、各セッションの詳しい内容を知りたい方は後日上がる資料を見てください。
PhpStormプラグイン「RainbawBrackets」の紹介

## RainbawBracketsとは？
カッコの対応関係を色でわかりやすくしてくれるプラグイン。
JavaScriptなどカッコが多すぎてコードが読みづらいときにとても便利。

><img width="530" alt="with-material-theme-ui.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109300/870a5016-ca3e-13f7-d8b1-a24b80a7ef24.png">
出典: [izhangzhihao/intellij-rainbow-brackets](https://github.com/izhangzhihao/intellij-rainbow-brackets)

## ハイライト機能
Ctrl + 右クリックでカッコを選択すると、カッコの中がハイライトされる。

>![rainbow1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109300/4af81eb5-2aa5-dc68-45cd-51f403c1799e.gif)

出典: [izhangzhihao/intellij-rainbow-brackets](https://github.com/izhangzhihao/intellij-rainbow-brackets)

Alt + 右クリックでカッコを選択すると、ほかのコードが暗くなり、選択したカッコの中のみがハイライトされる。

>![rainbow2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109300/f7dfa64f-c877-487e-29a9-c9dab99b76cd.gif)

出典: [izhangzhihao/intellij-rainbow-brackets](https://github.com/izhangzhihao/intellij-rainbow-brackets)

## 色を変える

色を変えたい場合はSetting > Editor > Color Scheme > RainbawBracketsから変更可能

>![customize-colors.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109300/b09c446d-5976-cbda-0db4-10899500ca69.png)

出典: [izhangzhihao/intellij-rainbow-brackets](https://github.com/izhangzhihao/intellij-rainbow-brackets)

# 引用元

 [izhangzhihao/intellij-rainbow-brackets](https://github.com/izhangzhihao/intellij-rainbow-brackets)
雨の日なので CSS だけで雨のアニメーションを実装する

定番ですが雨の日の気晴らしに。
JavaScript は使わずに CSS （ SCSS ）だけで雨が降るアニメーションを実装してみました。

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="mimonelu" data-slug-hash="XWrRPyG" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="SCSS Rain (No JS)">
  <span>See the Pen <a href="https://codepen.io/mimonelu/pen/XWrRPyG/">
  SCSS Rain (No JS)</a> by mimonelu (<a href="https://codepen.io/mimonelu">@mimonelu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## コード（ SCSS ）

```scss
.rain {

  $rain_drop_height: 20vh;

  background-color: #102030;
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;

  & > div {
    animation: rain 500ms linear infinite;
    background-color: rgba(#ffffff, 0.25);
    position: absolute;
    left: 0;
    top: -$rain_drop_height;
    width: 1px;
    height: $rain_drop_height;
    transform-origin: center center;
  }
  @for $i from 1 through 25 {
    & > div:nth-child(#{$i}) {
      animation-delay: #{$i * 100}ms;
      animation-duration: random(250) + 375ms;
      left: random(100) + vw;
    }
  }

  @keyframes rain {
    from {
      transform: rotate(-5deg) translateY(-$rain_drop_height);
    }
    to {
      transform: rotate(-5deg) translateY(100vh + $rain_drop_height);
    }
  }

}
```

## ミソ
### 乱数どうするの問題
雨粒の x 座標やアニメーションの再生時間などはランダムな値にしたいところですが、 CSS に乱数を生成する仕様はないため、 SCSS の `random()` 関数で生成しています。つまり、コンパイルした時に乱数が定数として埋め込まれるだけなので、何度リロードしても同じアニメーションが再生されますが、そこは妥協しました。だって他に方法ないし(´・ω・｀)
### transform の順番
雨粒を斜めに降らせるにはどうすれば良いでしょう？ここでは `transform: rotate(...) translateY(...);` とすることで、雨粒が「回転した方向へ移動」するようにしました。これを入れ替えると「角度は無視して移動」することになり、要するに行列計算の順番を制御することで、あ、ご存知で？あ、はい。

## おわりに
紙吹雪が瞬きながら舞うアニメーションなんかも実装できますが、無茶せずに JavaScript を、できれば Canvas も使って実装した方が良いでしょうね。
TypeScript: オブジェクトたちを任意のキーでグルーピングする関数

TypeScriptで、オブジェクトの配列を、そのオブジェクトのフィールド名でグルーピングする方法を説明する。

## やりたいこと

次の変形をする。

```js:Before
[
	{ make: 'audi', model: 'r8', year: '2012' },
	{ make: 'audi', model: 'rs5', year: '2013' },
	{ make: 'ford', model: 'mustang', year: '2012' },
	{ make: 'ford', model: 'fusion', year: '2015' },
	{ make: 'kia', model: 'optima', year: '2012' },
]
```

↓ `'make'`でグルーピング！

```js:After
{ audi:
   [ { make: 'audi', model: 'r8', year: '2012' },
     { make: 'audi', model: 'rs5', year: '2013' } ],

  ford:
   [ { make: 'ford', model: 'mustang', year: '2012' },
     { make: 'ford', model: 'fusion', year: '2015' } ],

  kia: [ { make: 'kia', model: 'optima', year: '2012' } ] 
}
```

簡単にできそうだが、こういったことを叶えてくれるビルトイン関数はいま(ES2019現在)のところない。

そこで、次のような関数を自作することになる。

```ts
const groupBy = <T extends { [key: string]: any }>(
	objects: T[],
	key: keyof T,
): { [key: string]: T[] } =>
	objects.reduce(
		(map, obj) => {
			map[obj[key]] = map[obj[key]] || []
			map[obj[key]].push(obj)
			return map
		},
		{} as { [key: string]: T[] },
	)
```

使い方:

```ts
const cars = [
	{ make: 'audi', model: 'r8', year: '2012' },
	{ make: 'audi', model: 'rs5', year: '2013' },
	{ make: 'ford', model: 'mustang', year: '2012' },
	{ make: 'ford', model: 'fusion', year: '2015' },
	{ make: 'kia', model: 'optima', year: '2012' },
]
console.log(groupBy(cars, 'year'))
```

実行結果:

```js
{ '2012':
   [ { make: 'audi', model: 'r8', year: '2012' },
     { make: 'ford', model: 'mustang', year: '2012' },
     { make: 'kia', model: 'optima', year: '2012' } ],
  '2013': [ { make: 'audi', model: 'rs5', year: '2013' } ],
  '2015': [ { make: 'ford', model: 'fusion', year: '2015' } ] }
```


## 参考文献

* [javascript - How to group an array of objects by key - Stack Overflow](https://stackoverflow.com/questions/40774697/how-to-group-an-array-of-objects-by-key)
IoT@Loft #3 2019年8月28日　参加メモ

# はじめに
Amazonが開催しているIoT@Loft#3に参加して参りましたので、そのメモです。すいません自分向けメモです。
https://iot-loft.connpass.com/event/142216/

# LT1 - センサを使った見守りサービスはどう作っているのか
高橋 一貴 氏 株式会社チカク シニアエンジニアリングマネージャー

* まごチャンネルを提供している。https://www.mago-ch.com/
* まごチャンネルは始まって3年ぐらい。
* まごチャンネルはスマートフォンで取った写真を遠くのおじいちゃん・おばあちゃんのテレビに写す。
* おじいちゃん・おばあちゃんが写真を見るとスマートフォンに通知がいく。
* 新規機能の開発
    * 温度・振動情報をクラウドに5秒に1回アップロード。しきい値を超えた場合に通知をする。 
    * リアルタイム処理、数千台がターゲット。
    * 重要なポイント
        * スケーラビリティ -> Lambda, Dynamo DB
        * 高可用性 -> Lambda, Dynamo DB
* システム構成
![DSC_0221.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85182/45da1593-3bee-bafd-b530-d2ee7eb61726.jpeg)


* 設計はDDD、　デプロイはTeraform
* センサーデータ保存Lambda Functionがタイムアウトする場合がある。

# LT2 - 1日でプロトタイプを作る技術と働き方
佐野 友則 氏 KDDI株式会社　経営戦略本部 KDDI DIGITAL GATE マネジャー

* KDDI DIGITAL GATEのミッション
    * 企業のデジタル変革を実現する場所。
    * アジャイル、デザイン思考を使う。
    * 1日スプリントを無料で実施して、そのアウトプットのイメージから発注して頂く。
* AWSの機能進化のスピードは非常に早く、絶えずキャッチアップするのは難しい。
* しかし顧客価値の最大化のためにはAWSの便利なサービスを学び続けないといけない。
* Podとユニットを作っている。Podは様々な職種の集まり、ユニットは同じ職種の集まり。
* 1日の決められた時間で最大のアプトプットを出すのが重要な点。
* OST - Open Space Technology
    * weekly 振り返り (課題を出し合う) - 長期的に解決したい事を話をする
    * OSTを実施
* 短い周期に慣れておく。学習は立ち止まる時間も必要。

# LT3 - 水産養殖スタートアップによる洋上で動くIoTプロダクト開発
岡本 拓磨 氏　 ウミトロン株式会社　共同創業者 / CTO

* IoTの技術を使った自動エサやり機械
* ソーラー電源で稼働、ネットワークはSORACOM、リアルタイムデータストリーミング、動画保存
* デバイスのOSはLinuxを採用していて、Go言語で開発している。Go言語は1バイナリで動作するのでアップデートなど対応しやすい。
* 最悪リモートでSSHを使った装置の不具合を確認する。
* AWS IoTはビジネスロジックとは関連のない部分で利用をしている。
* ウミトロンのシステムの監視としては、エサを正しく上げれているかの監視が最重要。魚が出荷されて、装置が撤去されていたり、細い運用が必要。
* AWS IoT ジョブでオンラインになったらアップデートを実現している。https://docs.aws.amazon.com/ja_jp/iot/latest/developerguide/iot-jobs.html

![DSC_0222.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85182/6bd4aabb-62b4-7f88-61fb-bafade289cbc.jpeg)

![DSC_0225.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85182/7ef7de00-e812-9470-16bc-8353d38cf15b.jpeg)


# LT4 - 大きな組織と一緒にはじめるスタートアップ
岡田 貴裕 氏 BCG Digital Ventures　Lead Engineer

* 資源運輸船を対象にした事業立ち上げ
* 一緒に仕事をする・観察する事で様々な課題が見つかる
* IoTのアーキテクチャがわかっているエンジニアが現場に入る事で解決策を考える事ができる。
* 制約条件を最初に確認しておく事が必要。スマフォが使えない、ウェラブルデバイスが使えないなど後工程で確認できた。
* MVPを実現してから、実際に運用フェーズに落とすまでが大変であり、重要。
* 最初はエンジニアが船に乗ってイーサを引くなどやっていたが、それではスケールしない。作業手順に落とすや、調達の安定化など様々な業務が必要であり、重要。

![DSC_0229.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85182/af965a36-b67e-e97c-4d10-72066285ac6f.jpeg)


# LT5 - IoTスタートアップを加速させるAWSの使い方
針原 佳貴 アマゾンウェブサービスジャパン株式会社 Startup Solutions Architect

* AWS Deeplens
* AWSのスタートアップ支援
    * AWS Activate スタートアップ企業がAWSが開始するための必要なリソースをオールインワンで無性提供するスタートアップ支援プログラム。
    * 最大$10万クレジットや技術サポート、研修等
    * AWSエンジニアによる技術支援
* Ask An Expertカウンター
    * 主な質問をブログで公開している。様々なヒントが含まれている可能性がある。
* ML@Loft, Blockchain@Loftなどイベントをやっている。
* AWS Deeplensの構成はかなり参考になりそう。エッジでDeepLearningを使った処理の結果をAWS IoTのTopic経由で情報が取れる。

![DSC_0231.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85182/820f1729-015a-bed1-4eb3-5648d888fd71.jpeg)
![DSC_0236.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85182/33db10b9-7c22-4c92-f3c8-2c09ebd322ab.jpeg)
github からユーザを検索する javascript と、それをテストする mocha (コンソール版)

# github からユーザを検索する

元ネタは[現代の JavaScript チュートリアル](https://ja.javascript.info/task/rewrite-async-2)。

```rethrow.js
'use strict';

const fetch = require('node-fetch');

const rl =
  require('readline')
    .createInterface({ input: process.stdin, output: process.stdout });

class HttpError extends Error {
  constructor(response) {
    super(`${response.status} for ${response.url}`);
    this.name = 'HttpError';
    this.response = response;
  }
}

function loadJson(url) {
  return fetch(url)
    .then(response => {
      if (response.status == 200) return response.json();
      else                        throw new HttpError(response);
    });
}

function demoGithubUser() {
  rl.question('Enter a name? : ', name => {
    return loadJson(`https://api.github.com/users/${name}`)
      .then(user => {
        console.log(`Full name: ${user.name}.`);
        rl.close();
        return user;
      })
      .catch(err => {
        if (err instanceof HttpError && err.response.status == 404) {
          console.log('No such user, please reenter.');
          return demoGithubUser();
        } else {
          throw err;
        }
      });
  });
}

demoGithubUser();
```

## 実行結果

![rethrow.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28376/22183c5f-9896-40c4-55dc-7cbc64ca128d.jpeg)

# mocha でテスト

３つテストがあります。それぞれ `node` を立ち上げます。

```test.js
'use strict';

const assert = require('assert');
const child_process = require('child_process');

let proc;

describe("rethrow", () => {
  beforeEach(() =>
    proc = child_process.spawn('node', ['./rethrow.js'], { stdio: 'pipe' })
  )

  it('should output a prompt.', done => {
    proc.stdout.once('data', output => {
      assert.equal(output, 'Enter a name? : ');
      proc.stdin.end();
      done();
    });
  });

  it('should accept a name', done => {
    proc.stdout.once('data', output => {
      proc.stdin.write('matz\n');
      proc.stdout.once('data', output => {
        assert.equal(output, 'Full name: Yukihiro "Matz" Matsumoto.\n');
        done();
      });
    });
  })

  it('should answer for user who is none', done => {
    proc.stdout.once('data', output => {
      proc.stdin.write('no-such-user\n');
      proc.stdout.once('data', function (output) {
        assert.equal(output, 'No such user, please reenter.\n');
        proc.stdin.end();
        done();
      });
    });
  })
});
```

## 実行結果

![test.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28376/d794d7e8-b966-0018-e347-5b1de26e4dca.jpeg)

# 参考にしたページ

- [Async/await](https://ja.javascript.info/async-await)
- [Mocking STDIN STDOUT in node](http://robawilkinson.github.io/2015/06/20/mocking-stdin-stdout-in-node/)
- [Mocha - the fun, simple, flexible JavaScript test framework](https://mochajs.org/)


# 追記

[readline-sync](https://www.npmjs.com/package/readline-sync) 使ったほうが楽ジャマイカ？
AIに自分の顔を判定させたら失敗した話（番外編）

#概要
本記事は、こちらの記事の番外編になります。
[○○に似てると言われ困ったので、AIに判定させてみた](https://qiita.com/sksk_go/items/fe9d050c09c001a46e49)

AzureのCustom Visionを使って、自分の顔が有名人に似ているかどうか判定させたところ、
学習させるデータが間違っていて失敗したというお話です。　

#学習データの用意
[本編](https://qiita.com/sksk_go/items/fe9d050c09c001a46e49)と同様にスクレイピングで画像を集めます。

```
python scraping.py -s hoshinogen  -n 70
```

まずは通常の星◯源さんの画像を集めて、そこから精度の悪そうな画像は手動で省いていきます。

この時に、星◯源さんといえばメガネが特徴的なので、
メガネありなしのデータで学習させればメガネありなしVerで自分の顔判定できるのではと思い、
メガネありの画像をスクレイピングしました。

```
python scraping.py -s hoshinogenmegane  -n 70
```
ここから失敗へと向かいます。

![スクリーンショット 2019-08-27 21.25.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/fc536100-33dd-a2c5-10c2-ed9dd3fea796.png)

#Custom Visionで学習させる
まずはCustom Vision上で「星野源」「メガネあり」「メガネなし」でタグを作り、
それぞれに紐付けて画像をアップし、学習させていきます。
![スクリーンショット 2019-08-27 21.51.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/b5091aba-eb9f-8406-b72d-438055984e24.png)

準備ができたので、テストしていきます。

#結果判定
自分もメガネありなしで自撮りを済ませ
AIに判定させてみると、非常に高い数字が出ました。
・メガネありの評価
![スクリーンショット 2019-08-27 22.21.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/619253ee-65c6-39ed-da07-cb7e6cb19ae0.png)

・メガネなしの評価
![スクリーンショット 2019-08-27 22.21.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/4e93cc4d-fc98-2e60-9a4f-35f48ae7747c.png)

おお、こんな似てたんだと思うわけです。
他の人も判定してみようと思い、ムロツヨシやイチローなど、
幅広い人で試してみました。
![スクリーンショット 2019-08-28 20.09.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/b7000011-49fc-105d-22af-b10206854bd8.png)

あまり似てないであろう人たちもみんな似てるという結果が返ってきました。
ここでようやく気が付きました。

これ、**ただのメガネかけてるかどうか判定させてるだけだ……**

学習させたデータが1人だけで、かつメガネありなしだけだったために、
全てメガネで判定されてしまうという結果に


以上、失敗した話でした。
メガネの有無を判定させるAIの使い道を考えましたが、
特に思いつかなかったのでアイディアあればこっそり教えてください。

#まとめ
今回失敗してみて、失敗が早い段階でわかるのもプロトタイピングの良さかなと思いました。
上極限と下極限

# 上極限と下極限

覚え書き。正しさは不明。

## 定義

$$
上極限：\quad \limsup_{ n \to \infty } A_n = \bigcap_{n=1}^{\infty}\bigcup_{k=n}^{\infty} A_k
$$
$$
下極限：\quad \liminf_{ n \to \infty } A_n = \bigcup_{n=1}^{\infty}\bigcap_{k=n}^{\infty} A_k
$$

## 具体例1

$[0, 1]$を下記のような区間$A_n$に分割する。

$$
A_n = \Big(\Big(\frac{1}{2}\Big)^n, \Big(\frac{1}{2}\Big)^{n-1}\Big] \quad(n = 1, 2, 3,...)
$$
とする。例えば
$$
A_1 = \Big(\frac{1}{2}, 1\Big],\; A_2 = \Big(\frac{1}{4}, \frac{1}{2}\Big],\; A_3 = \Big(\frac{1}{8}, \frac{1}{4}\Big],\; ...
$$


となる。  
このとき、$k=n$から$\infty$までの和と共通部分はそれぞれ下記のようになる。  

$$
\bigcup_{k=n}^{\infty}A_k = \Big(\Big(\frac{1}{2}\Big)^\infty, \Big(\frac{1}{2}\Big)^n\Big) = \Big[0, \Big(\frac{1}{2}\Big)^n\Big)
$$
$$
\bigcap_{k=n}^{\infty}A_k = \varnothing\quad(※A_nは互いに素な集合なので共通部分は無い。)
$$
よって
$$
\limsup_{n \to \infty} A_n = \{0\}
$$
$$
\liminf_{n \to \infty} A_n = \varnothing
$$
である。

## 具体例2

$A_n$を下記とする。

$$
A_n = \Big[-\frac{1}{n},\; \frac{1}{n} \Big] \quad (n = 1, 2, ...)
$$
例えば
$$
A_1 = \Big[-1,\, 1\Big],\; A_2 = \Big[-\frac{1}{2},\, \frac{1}{2}\Big],\; A_3 = \Big[-\frac{1}{3},\, \frac{1}{3}\Big],\; ...
$$
となる。  
このとき、$k = n$から$\infty$までの和と共通部分はそれぞれ下記のようになる。
$$
\bigcup_{k=n}^\infty A_k = \Big[-\frac{1}{n},\, \frac{1}{n}\Big]
$$
$$
\bigcap_{k=n}^\infty A_k = \Big[-\frac{1}{\infty},\,\frac{1}{\infty}\Big] = \{0\}
$$
よって
$$
\limsup_{n \to \infty} A_n = \bigcap_{n=1}^{\infty}\;\bigcup_{k=n}^{\infty}A_k
= \bigcap_{n=1}^\infty \Big[-\frac{1}{n},\,\frac{1}{n}\Big]= \{0\}
$$
$$
\liminf_{n \to \infty} A_n= \bigcup_{n=1}^{\infty}\bigcap_{k=n}^{\infty} A_k
= \bigcup_{n=1}^{\infty}\{0\} = \{0\}
$$
である。
【Flutter】タブを移動するとListViewのスクロール位置がリセットされる

# 事象

1. タブ内のリストを特定位置までスクロールする。
2. 表示しているタブから別のタブへ変更する。
3. 前のタブに戻る。
4. ★スクロール位置がリセットされている。

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136368/0588436f-6cfe-11c5-f7e8-e766cc623e87.gif)

```dart
class SamplePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultTabController(
      length: 2,
      child: Scaffold(
        appBar: AppBar(),
        body: Column(
          children: <Widget>[
            TabBar(
              tabs: [
                Tab(child: Text("タブ1", style: TextStyle(color: Colors.black))),
                Tab(child: Text("タブ2", style: TextStyle(color: Colors.black))),
              ],
            ),
            Expanded(
              child: TabBarView(children: [
                ListView.separated(
                  itemCount: 50,
                  itemBuilder: (context, index) {
                    return ListTile(title: Text("アイテム${index.toString()}"));
                  },
                  separatorBuilder: (context, index) {
                    return Divider();
                  },
                ),
                ListView.separated(
                  itemCount: 50,
                  itemBuilder: (context, index) {
                    return ListTile(title: Text("アイテム${index.toString()}"));
                  },
                  separatorBuilder: (context, index) {
                    return Divider();
                  },
                ),
              ]),
            ),
          ],
        ),
      ),
    );
  }
}
```

# 対応
ListViewのkeyに`PageStorageKey`を追加します。

```dart:一部抜粋
child: TabBarView(children: [
  ListView.separated(
    // ***ここです！***
    key: PageStorageKey(0),
    itemCount: 50,
    itemBuilder: (context, index) {
      return ListTile(title: Text("アイテム${index.toString()}"));
    },
    separatorBuilder: (context, index) {
      return Divider();
    },
  ),
  ListView.separated(
    // ***ここです！***
    key: PageStorageKey(1),
    itemCount: 50,
    itemBuilder: (context, index) {
      return ListTile(title: Text("アイテム${index.toString()}"));
    },
    separatorBuilder: (context, index) {
      return Divider();
    },
  ),
]),
```

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136368/cf6876f1-9f43-bc3a-d22e-409a8d4c5f35.gif)

PageStorageKeyの説明にはこう記載されています。

>A [ValueKey] that defines where [PageStorage] values will be saved.

>[Scrollable]s ([ScrollPosition]s really) use [PageStorage] to save their
scroll offset. Each time a scroll completes, the scrollable's page
storage is updated.

つまり、スクロール位置は`PageStorage`に保存されており、その保存場所を指定するのが`PageStorageKey`である、ということになります。
スクロール位置の保存場所を指定することで、引き出すこともできるようになったということですね。

# 参考
https://codeday.me/jp/qa/20190504/770454.html
こちらの記事でPageStorageKeyの存在を知りました。
minikubeにimage registryをインストールする

```
minikube addons enable registry
```

これでクラスタ内部から`registry:80`でアクセスできる。

## 参考

* [minikube/deploy/addons/registry at master · kubernetes/minikube](https://github.com/kubernetes/minikube/tree/master/deploy/addons/registry)
* [Addons | minikube](https://minikube.sigs.k8s.io/docs/tasks/addons/)
DHCPで毎度切り替わるminikubeのIPアドレスを固定する

## 環境
- VirtualBox
- minikube v1.3.1
- macOS 10.14

## IPを固定

`/.minikube/machines/minikube/config.json` の `IPAddress` へ直接定義してあげてもだめだった。

## sshで直接変更

```
minikube ssh sudo ifconfig eth1 192.168.99.102
```

## 変更を反映

```
minikube update-context
```

## 変更されてる！

```
minikube status
host: Running
kubelet: Running
apiserver: Running
kubectl: Correctly Configured: pointing to minikube-vm at 192.168.99.102
```

## が、kubectlなどが通らなくなっていた
```
❯ kubectl get pod
Unable to connect to the server: x509: certificate is valid for 192.168.99.102, 10.96.0.1, 10.0.0.1, not 192.168.99.135
```

# 対処方法

## VirtualBoxのDHCPリース情報を削除する関数を作成
```
function minikube_reset_vbox_dhcp_leases() {
  # # Reset Virtualbox DHCP Lease Info
  common_message_print "Resetting Virtualbox DHCP Lease Info..."
  kill -9 $(ps aux |grep -i "vboxsvc\|vboxnetdhcp" | awk '{print $2}') 2>/dev/null

  if [[ -f ~/Library/VirtualBox/HostInterfaceNetworking-vboxnet0-Dhcpd.leases ]] ; then
    rm  ~/Library/VirtualBox/HostInterfaceNetworking-vboxnet0-Dhcpd.leases
  fi
}
```

## 関数実行
```
minikube_reset_vbox_dhcp_leases
```

で、強制的ですが、Delete時などに実行することで、毎度`192.168.99.100`で起動してくるはず
レビューで自分が気をつけていること

# 背景・動機

ソースコードレビューをする（受ける）際に、コメントに困る（困らせてしまう）事があります。
自分なりに原因を考え、レビューで気をつけていることをまとめることで、他の人の参考になればと思い投稿します。

# レビューするときに気をつけていること

1. 具体的に書く
2. 理由を書く
3. 代案を提示する

## 1. 具体的に書く

```
// Bad
もっと良くできるはずなので、頑張りましょう。

// Good
if-elseの階層が深くなっているので、早期returnしましょう。
```

具体的でないコメントはレビューイを混乱させてしまいます。
そういった意図がなくても批判と受け止められることもあり、レビューに対する意欲の低下にもつながります。

## 2. 理由を書く

```
// Bad
変数 user_data の定義を L199 に移動しましょう。

// Good
変数 user_data は利用する直前の L199 で定義しましょう。変数のスコープが広くなると、バグが混入する原因となってしまう可能性があります。
```

レビュアーは完璧ではないので、間違った指摘をすることもあります。
上記の例で、もしかしたら他の行で user_data が利用されているかもしれません。
コメントに理由が書かれていると、レビューイは指摘の意図を汲んで、変数のスコープをなるべく狭くするよう修正するでしょう。
さらに、次から同様の指摘を受けないよう、学習し改善してくれるかもしれません。

## 3. 代案を提示する

```
// Bad
User.checkStatus というメソッド名では、何をチェックしているのか分かりません。

// Good
User.checkStatus というメソッド名では、何をチェックしているのか分からないので User.isActiveState というメソッド名にしましょう。
```

代案が提示されていないと、レビューイはどう修正すれば分からずコメントを返すか、間違った理解をして修正をしてしまい、コメントのやり取りの回数が増えます。
スケジュールが差し迫っている場合（時間が余っている事などないと思いますが）は、レビュアー、レビューイ共に負担となってしまいます。
上記の例で、レビューイは User.checkUserStatus と修正するかもしれません。
実は checkStatus は Active 以外も判定している可能性もあります。
コメントに代案が提示されていると、レビューイは意図を汲んで説明的なメソッド名を付けるでしょう。

# レビューを受けるときに気をつけていること

1. 感謝する
2. まず最初に自分がレビューする
3. 何をレビューしてもらいたいのか書く


## 1. 感謝する

レビューしてくれたことに感謝します。
例えレビュアーから痛烈なコメントを受けたとしても、時間を割いて自分の書いたコードを読んでくれたことに感謝しましょう。

## 2. まず最初に自分がレビューする

自分が書いたコードの最初のレビュアーになりましょう。
一旦冷静になって、自分の書いたコードを読み返してみると、良くない部分が見つかることもあります。

## 3. 何をレビューしてもらいたいのか書く

どういった部分に対して重点的にレビューしてもらいたいのか、自分の意見で良いので Pull Request に記載します。
レビュアーが忙しく時間がない場合（多分そういった人がレビュアーである事が多いと思います）重要な情報源となります。

# 終わりに

過去レビューにおいて、相手への配慮を欠き失敗したことがあります。
本記事は自分の経験に基づき作成しているものですので、万人に共通するものではないかもしれませんが、レビューで建設的なコミュニケーションがされると、非常に気持ち良いですので、ご参考いただければと思います。