OmniAICreator/Qiita-1.07M huggingface dataset:
E2Eテスト(とUIテスト)ってなんなの？

# Motivation

上司に「E2Eテスト(ぽいの)担当して」って言われたけど、うーん、なんにもわからん

というわけで調べた

# E2Eテストとは

https://martinfowler.com/articles/practical-test-pyramid.html#End-to-endTests
を読んでみた。(以下、ほぼ訳)

E2Eテスト = End to end テスト

ユーザーインターフェース(UI)を介して、デプロイされたアプリケーションをテストすること。
ソフトウエアが動作していることを確認する。

(想定: ブラウザを介したアプリケーション) 
ブラウザを開いて、クリックしたり、データを入力したりして、UIを確認する。
後述のUIテストとは違うのは、End to Endで(システム全体を利用して)テストする

## E2Eテストの課題

### (意図せず)壊れやすい

しばしば期待しない予測不可能な理由で失敗する。この多くは実際は失敗ではなく、誤検知である。
それはブラウザの特徴や、タイミング、アニメーション、期待しないポップアップダイアログが原因である。
誤検知ばかりだと、時間がかかったり、テストの信頼性を失うので注意。

### 誰が作るの？

マイクロサービスだと、これらのテストの作成は誰が担当するのか、という問題がある。複数のサービスにまたがるので、E2Eテストを作成する責任を負う単一チームがいない
一元化した品質保証(QA)チームがいるならばぴったりだけど、DevO一元化したQAチームを持つことはアンチパターン。
E2Eテストを誰が持つかはかんたんに答えを出せない。
組織に依存するところなので、組織にあったやり方で。

### コストが高い

しばしばメンテナンスしなくてはならないし、実行に時間がかかる。
いくつかのマイクロサービスで構成されていると、そもそもローカル環境で実行できない。ローカルで実行するには、すべてのマイクロサービスをローカルで実行する必要がある。

E2Eテストの数は最小限にする。
商品の核となる価値部分のユーザージャーニーを考えて、その部分をE2Eテストに変換する

特殊なケースは、ユニットテストなどの下位テストに任せる。

## テストツールなど

* Selenium ブラウザの自動化ツール https://selenium.dev/
* 最近までは HeadlessブラウザとしてPhantomJSが有力だったが、ヘッドレスモードが実装されたので、ユーザーが実際に使うブラウザ(Choromium, Firefox)でテストしたほうが良い
* Nightwatch.js - https://nightwatchjs.org/

# ここまできたけど

多分これ上司に期待されているの、これだけじゃなさそうなんだよな。
記事の上に書かれているUIテストも含まれそう。

# UIテスト

https://martinfowler.com/articles/practical-test-pyramid.html#UiTests

UIテストはアプリケーションのUIが正しく機能することをテストする。ユーザーの入力が正しくアクションをトリガーし、データがユーザーに表示され、UIの状態は期待通りに変わるということ。

UIテストとE2Eテストは同じものだと言われることがあるが、アプリケーションをE2Eでテストするのは、UIを介してテストを実行することであるが、その逆は当てはまらない。
つまり、UIテストはE2Eで実施する必要はない。使用する技術に応じて、バックエンドはスタブアウトして、フロントエンドのjavascriptの単体テストを記述すれば良い。

アプリケーションのレイアウトが損なわれていないことをテストするのは難しい。
これはコンピュータが「見た目の良さ」を判別し難いから。
(ただし、機械学習アルゴリズムが将来それを解決するかも)

ユーザビリティや見栄えの良さをテストするのは自動テストではなく、探索的テストやユーザービリティテストに頼るべき。


## テストツール

react, vue.js, Angular 

* 独自のツールとヘルパーが付属しているはず

vanilla javascript ( = つまりただのjavascript)

* jasmine - https://jasmine.github.io/
* Mocha - https://mochajs.org/index.html

伝統的なサーバサイドレンダリング

* Selenium - https://selenium.dev/

アプリケーションのレイアウト

* Galen - http://galenframework.com/
* Lineup - https://github.com/otto-de-legacy/lineup
* JLineup - https://github.com/otto-de/jlineup

# まとめ

E2Eテストは、システムを用意して、UIを介してアプリケーションが動作していることを確認すること。

ただし、ユーザーのインプットに対して、

* 正しくアクションをトリガーして、データが出て、UIの状態が変わること
* UIのレイアウトが適切であること
* 期待通りの価値が提供できていること (← ここがE2Eテストの範囲)
* ユーザービリティが低下していないこと

を同時にテストするのは難しい...(手法、テストの実行時間やメンテナンスコストなどが異なる)
どれをテストするのかきちんと決めてそれぞれにあったやり方を選んでいくべき

あんまりまとまってないですが、こんなところでこの記事は落とし所にします。

# 参考文献

* https://martinfowler.com/articles/practical-test-pyramid.html
#Rails + #rspec でハッシュに対して一部のkey/valueの型だけを検証する、ゆるいテストをするには include と be_an を組み合わせて使う

```rb
expect(a: 1, b: Time.now, c: 'wow').to include({a: be_a(Integer)})
# => true

expect(a: 1, b: Time.now, c: 'wow').to include({b: be_a(Time)})
# => true

expect(a: 1, b: Time.now, c: 'wow').to include({c: be_a(String)})
# => true

expect(a: 1, b: Time.now, c: 'wow').to include({c: be_a(Integer)})
# => [#<RSpec::Expectations::ExpectationNotMetError: expected {:a => 1, :b => 2019-12-13 02:08:55.283922100 +0000, :c => "wow"} to include {:c => (be a kind of Integer)}
# Diff:
# @@ -1,2 +1,4 @@
# -:c => (be a kind of Integer),
# +:a => 1,
# +:b => 2019-12-13 02:08:55.283922100 +0000,
# +:c => "wow",
# >]

```

# ref

ruby - Testing hash contents using RSpec - Stack Overflow
https://stackoverflow.com/questions/8392884/testing-hash-contents-using-rspec

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2845








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
マンガでわかる Command

![29DD722E-1BED-4C85-8B68-5C330CFE2D22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/fe551146-380b-4164-91a5-c15174627d69.png)

ゆうしゃくるみよ、それではレベルが低すぎるぞ。

Command パターンは、メッセージへの応答としてすぐに処理を実行するのではなく、「その処理を実行すること」を表すモデルです。Command のインスタンスは、実行可能なアルゴリズムと、生成時に決めたパラメーターを持ちます。

通常そのパブリックメソッドは、「主たる実行」を表すものが 1 つあるだけです。メソッドの名前は、execute だったり run だったり invoke だったり、あるいはバトルシステム内のアクションを意味する名前だったり、様々です。

もっと別の言い方をすれば、クロージャーやラムダと呼ばれる言語機能のことです。あるいは、関数型言語の言葉でいうところの、部分適用された関数を束縛する変数です。(C 言語の関数ポインタは、それ単体でパラメーターを持てないので少し違います)

なぜ「実行すること」なんて回りくどいインスタンスを作るのでしょうか。実行するときに呼べばいいんじゃ? それは、Command オブジェクトとして置いてあれば、じっさいに動かすタイミングを、実行計画を担うマネージャーに委ねることができるからです。もしくはキャンセルできるからです。

すばやさで順序が変わるゲームのバトルシステム以外にも、マルチスレッドのマネージャーだったり、複数のリクエストを受けるプリンタのジョブキュー(印刷ヘッドはひとつしかないので)のようなものだったり、逆に、一箇所で作った複数のジョブを分散実行させるシステムだったり... コンピューターシステムには、やることを決めるタイミングと、それを実行するタイミングをずらしたい場合がよくありますね。

Command はひとつのクラスからいくつも生成されます。いちど発行されると、基本的には、すべていつか実行され、実行が済んだらインスタンス破棄です。送ってしまったメールのパケットは、まだ相手に届いていないからといって、訂正することはできませんね。

ここが、基本 1 クラス 1 インスタンスでアルゴリズムを準備しておいて (Singleton っぽい)、選択したり入れ替えたりする [Strategy](https://qiita.com/tanakahisateru/items/398676a754ea1fe4cb80) パターンとの決定的な違いです。

クラスを単品で見てしまうと、Command は Strategy と区別がつきません。その実行可能なアルゴリズムをどうしたいのか、オブジェクトの使われ方から意味を読んで判断することがたいせつです。
サボらせないクソアプリを作った

## どういうアプリか
デフォルトで5分、あるいは起動時に指定した分数キータイプが無い場合、サボりの可能性ありとみなして以下画面を表示させます。

<img width="512" alt="スクリーンショット 2019-12-11 16.21.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224108/76835d63-b799-559e-3dee-d9e20b1269d9.png">

この画面を×ボタンを押して消すと、再度監視が走り出します。

exe化、app化はしてないので、Python3.7を入れたPCでコマンドラインから実行してください。

MTGやプレゼンなど、キータイプの無い仕事を始める時にはオフにしてください。

## 操作方法
以下からソースをDLしてきてください。

https://github.com/anchor-cable/stupidapp

### 起動
```
sudo python3 main/watch_keyboard.py 1
```
keyboardライブラリでキーボードを監視する都合上、管理者権限が必要でした...
(自分の認識する範囲で何も悪さはしていませんが、**何かあっても責任は持てません**)

引数の1は監視時間（分）です。省略するとデフォルトの5分監視になります。
引数に小数点以下を与える事はできません。

### 普通に仕事する
普通に仕事するためのアプリなので普通に仕事してください。
監視時間の間キータイプが1回もない場合、冒頭の画面が表示されます。

## 技術の話
### 監視用のループ

再帰で以下のように書きました。

```python
    def watch(self,timeout_count):
        typed_pool = []
        keyboard.start_recording()
        time.sleep(60)
        typed_pool = keyboard.stop_recording()
        if len(typed_pool) == 0:
            timeout_count += 1
        else:
            timeout_count = 0
        if timeout_count <= self.watch_minutes:
            self.watch(timeout_count)
```

ループを抜けたらポップアップウィンドウを表示するようにしています。

### ポップアップウィンドウの一工夫

```python
root.protocol("WM_DELETE_WINDOW", self.main())
```

×ボタンを押した後に再度コマンドラインで起動するとか面倒の極み。サボりを指摘されて仕事に戻る前に、最初から処理が走るようにしました。

## 感想
簡単な画面作るだけならtkinter良いですね。
もうちょい頑張ればデスクトップアプリにできると思います。

## クソどうでもいい余談1 誕生秘話
「あー、クソアプリアドカレの締切が近い」
「元々考えてたアプリ、去年上位互換のアプリ出てたからお蔵入り決定や...」
「何作ろうかな...」

(40分後)

「ハッ！」
「俺ずっと**Twitter**見てただけやんけ」
「このままやとアドカレ落としてしまう......でもGUI書ける言語分からんし、機械学習みたいな高度な事もできん」
「...CLIツールでええか」
「サボり禁止のCLIツールやったら作れるんちゃうかな」

## クソどうでもいい余談2 開発苦労話
これの動作確認のため、何回も1分間キーボードを入力せず放置する必要があり、その度に「サボってねえし...！」という気分にさせられました。
Mac Pro 指定するWifiのパスワードをもう一度設定する方法

Mac Pro 指定するWifiのパスワードをもう一度設定する方法

”Wifiのネットワーク”環境設定を開く

<img width="323" alt="スクリーンショット 2019-12-14 12.14.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550974/492acd1a-d182-6c5c-10ba-40d8ab697d1d.png">

詳細をクリックする
<img width="671" alt="スクリーンショット 2019-12-14 12.15.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550974/35da15b8-4a45-5488-84a7-af3cbbf435bf.png">

指定のWifiを削除する（※Wifiの名前を覚えておいてください）
① → ② → ③
<img width="666" alt="スクリーンショット 2019-12-14 12.19.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550974/0a38d81c-2962-1943-e2b8-e3947d7fb2f5.png">

もう一度Wifiを連携すると、パスワードを聞いてくるようになる。
我が家のSlack活用法

こんにちは！私は IoTやAIを活用して空席情報を配信するサービスを提供する [株式会社VACAN](https://www.vacancorp.com) の事業開発部で、PMをしています。
この記事は、[バカン (Vacan) Advent Calendar 2019](https://qiita.com/advent-calendar/2019/vacan)の14日目(12/14)の投稿です🍸

## 初めのあいさつ

普段はPMとして、お客様と打ち合わせをしたり、エンジニアやデザイナーと色々相談したりして、サービスを無事リリースするために日々駆け巡っております。

社内でのコミュニケーションにSlackを使っているのですが[（詳しくは12/6の記事へ✏️）](https://www.wantedly.com/companies/vacancorp/post_articles/198426)、色々と便利そうだし同居中のパートナー（エンジニア）とのコミュニケーションに使えないかと考え、我が家でもSlackを導入！！（いきなりプライベートな話...！）

非エンジニアの自分ですが、Slackのカスタマイズは結構簡単にできるものが多く、プライベートで使うのにもオススメだなと思ったので、どう使っているかを簡単に紹介していきます🥂

## Googleカレンダー連携
わざわざカレンダーを見なくても、予定が分かるようにSlackに通知しています📅

まずGoogleカレンダーの共通アカウント作り、共通のGoogleカレンダーアカウントをSlackに通知できるように設定。
そして以下の手順で予定が通知されます。
>手順①お互いが各々のアカウントのカレンダーに予定を入れる
手順②共通アカウントもゲスト招待する
手順③共通アカウントがinviteされる度にSlackに通知が飛んでくる
※ちなみに上記①は、仕事のカレンダーとは別の自分のプライベートアカウントを使用します。（仕事に関わる予定を共有している訳ではない）


（こんな感じで予定が飛んできます）
<img width="290" alt="スクリーンショット 2019-12-14 10.23.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541230/5d18bfd6-05e3-d141-31ab-d62716d129f1.png">

前日にリマインド通知も来るので、お互い家に居ない日が漏れなく分かるようになります。
これで当日に「今日飲み会で帰り遅くなるから、ご飯は各自で！」的なバタバタしたやり取りが不要に！

参考：https://se.miyabikno-jobs.com/slack-calender/

## RSS連携
好きなニュースをSlackでも見れるように連携しています📰
RSSをSlackと連携させると、わざわざ各Webサイトを開かなくても、気になる記事やブログが更新されるたびSlackに通知が来るので便利です。

（こんな感じでニュースが飛んできます）
<img width="777" alt="スクリーンショット 2019-12-14 10.35.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541230/93bceadd-dfd2-ab61-f829-ac78b7e01936.png">

参考：https://businesschatmaster.com/slack/rss-johoshushu


## スプレッドシート連携
行きたい所とかやりたい事をメモするスプレッドシートを作っているのですが、更新した事が分からないのでSlackに通知をしています🎉

（こんな感じで更新通知が飛んできます）
<img width="282" alt="スクリーンショット 2019-12-14 11.30.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541230/577bb717-c732-c285-e6f4-0caa1bc22bd2.png">


参考：https://qiita.com/matsukazu1112/items/d47e81d4c4d08d2147d3

## チャットボット連携

これはお遊び程度ですが、Dialogflowを使って、天気やよく使うリンクを教えてくれるBotを作成しています🤖

（こんな感じでBotと会話できます）
<img width="419" alt="スクリーンショット 2019-12-14 10.53.26 1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541230/4a52d760-c340-1556-cead-9af1ce98ed27.png">


参考：https://qiita.com/ume1126/items/1fa38c430fc0e6248be8


## IFTTT連携
SlackにMemoしたい内容を、スマートスピーカーに話しかけるとMemoしてくれるようにしています✍️
（これが一番便利かもしれない）

例えば我が家では、料理中に卵がなくなった際に、スマートスピーカーに
「Slackの買い物リストに卵を追加して！」
と言うと、Slackの買い物チャンネルに投稿されるようにしています。
買い物行った時にチャンネルをチェックすれば、買い忘れ防止に👜🥕

（こんな感じで投稿されます）
<img width="306" alt="スクリーンショット 2019-12-14 11.10.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541230/836b17b5-af14-4a80-f07b-08075b1f93bf.png">


参考：https://qiita.com/KSxRDevelop/items/4aff0f1856c0c200c1a0


## 終わりのあいさつ

以上、我が家でのSlack活用についてご紹介してみました💐
仕事以外にも応用できる便利機能が色々とあるため、ぜひ試してみてはいかがでしょうか？


そして！バカンでは一緒に働く仲間を募集しています🎉
個性溢れる素敵なメンバーがお待ちしていますので、気になった方は[こちら](
https://www.wantedly.com/companies/vacancorp)をチェックしてみてください！

株式会社バカン
https://www.vacancorp.com/
株式会社バカン　サービスサイト
https://product.vacancorp.com/
Pythonで任意の確率密度関数からサンプリングを行う方法

~~MCMCすればいいじゃん！というツッコミはなしでオネガイシャス~~

ご存知の通り、scipyには多くの確率密度関数があらかじめ定義されており、それらを使うことで、サンプリングや、確率密度関数のプロットなどを容易に行うことができます。

例えば、

``` python3
stats.norm.rvs(loc=50, scale=20, size=1000)
``` 

とすれば、平均50, 標準偏差20の正規分布から1000個のサンプルを得ることができますし、

``` python3
x = np.linspace(0, 100, 100)
px = stats.norm.pdf(x, loc=50, scale=20)
plt.plot(x, px)
``` 

とすれば、$0<x<100$での正規分布を図示することもできます。

では、scipyにあらかじめ定義されていない自前の確率密度関数からサンプリングを行うにはどうしたらよいでしょうか。離散分布の場合は@yk-tanigawaさんの[記事](https://qiita.com/yk-tanigawa/items/0e4bd9480216c7a84106)で紹介されているので、ここでは連続分布の場合を扱います。

例として、scipy.statsに正規分布が定義されていないとして（本当は定義されてます）、自前でこれを定義して、サンプリングする例を下に書いておきます。rv_continousから継承して、_pdf 関数の中で定義したい関数を書くだけですね。

``` python3
from scipy import stats
import math

class gaussian(stats.rv_continuous):

    def _pdf(self, x, mu, sigma):
        normalize_factor = 1.0/(2.0*math.pi*sigma**2)**(1/2)
        px = normalize_factor * math.exp(-(x-mu)**2/(2*sigma**2))

        return px

gaussian = gaussian(name="gaussian", a=0.0)    
sample_from_gaussian = gaussian.rvs(size=1, mu=10.0, sigma=1.0) 
``` 

なお、自前で定義する確率密度関数は規格化されている必要があるので注意してください。規格化できていない場合は、[棄却サンプリング](https://www.iwanttobeacat.com/entry/2018/03/24/225348)を使うとよいっぽいです。

(しかし、[ドキュメント](https://docs.scipy.org/doc/scipy-1.2.1/reference/generated/scipy.stats.rv_continuous.html)をみても、a=0が必要な理由がよく分からないな…。)
FACTFULNESS(ファクトフルネス) ～ ビジネスチャンスに気付くには？

データをじっくり見ていくと、そこには今まで誰も気付かなかった見込み客が眠っているのでは？と思わされる本を読みました。少し前に流行っていた[FACTFULNESS(ファクトフルネス) 10の思い込みを乗り越え、データを基に世界を正しく見る習慣](https://www.amazon.co.jp/FACTFULNESS-%E3%83%95%E3%82%A1%E3%82%AF%E3%83%88%E3%83%95%E3%83%AB%E3%83%8D%E3%82%B9-10%E3%81%AE%E6%80%9D%E3%81%84%E8%BE%BC%E3%81%BF%E3%82%92%E4%B9%97%E3%82%8A%E8%B6%8A%E3%81%88%E3%80%81%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%9F%BA%E3%81%AB%E4%B8%96%E7%95%8C%E3%82%92%E6%AD%A3%E3%81%97%E3%81%8F%E8%A6%8B%E3%82%8B%E7%BF%92%E6%85%A3-%E3%83%8F%E3%83%B3%E3%82%B9%E3%83%BB%E3%83%AD%E3%82%B9%E3%83%AA%E3%83%B3%E3%82%B0/dp/4822289605)という本です。副題の通りですが、本書では人間の〇〇本能と書かれている世界を見るときの10の思い込みと、データを基に世界を正しくみるとはどのようなことかが書かれています。

私が最も魅かれたのは「***世界には50億人の見込み客がいる。***」という一文です。例えば、世界を高所得者層／先進国と低所得者層／後進国という2クラスだけで認識している人には、欧米の人々のみ（せいぜい10億人）しか見込み客に見えていない。しかも、きっと、欧米以外の人々は貧しくてその日の食事にも困る可哀そうな人たちであろうという誤った見方しかできない。でも、実際にデータを見れば、本当の貧困層という人は世界に9%しかいなくて、残りの91%は高所得者層と中所得者層であることが分かる。生活水準が上がっている中所得者層の人はスマートフォンなどの購買意欲も高まっている。そういう人たちをデータも見ずに貧困者と見ている限りは、***ビジネスチャンスに気付けない***だろう、というのです。この話は「1章　分断本能」の中で述べられています。

現在の私自身は全世界の50億人を相手にするようなビジネスをしていないものの、参考になる部分は大きいと思いました。例えば、私は大企業相手にビジネスをしているIT業者です。しかし、[経済産業省の資料](https://www.chusho.meti.go.jp/koukai/chousa/chushoKigyouZentai9wari.pdf)を見てみると、大企業の社数は全体の0.3%で、従業者数は31%でしかないようであるものの、普段はそれ以外をターゲットとは見ていません。では、実際、大企業じゃない人たちはIT化が進んでいないかというと、そうともいいきれなくて、大企業では考えられないくらいG-SuiteやOffice365やSalesforceを先進的に活用している企業も多くあります。大企業とそれ以外という分断で見たときに、見落としているビジネスチャンスがあるかもしれないな。

上記で述べてた分断本能だけでなく全部で10の〇〇本能が書かれていて、どれも参考になります。ときどき見返してみると、そのときそのときの気づきがありそうだなと思わされる本でした。ですので、数年後の自分のためのメモとしてQIITAに掲載させて頂きます。

ファクトフルネスに書かれている10の思い込み
---

1. 分断本能　「世界は分断されている」という思い込み
2. ネガティブ本能　「世界はどんどん悪くなっている」という思い込み
3. 直線本能　「世界の人口はひたすら増え続ける」という思い込み
4. 恐怖本能　危険でないことを、恐ろしいと考えてしまう思い込み
5. 過大視本脳　「目の前の数字が一番重要だ」という思い込み
6. パターン化本能　「ひとつの例がすべてに当てはまる」という思い込み
7. 宿命本能　「すべてはあらかじめ決まっている」という思い込み
8. 単純化本能　「世界はひとつの切り口で理解できる」という思い込み
9. 犯人捜し本能　「誰かを責めれば物事は解決する」という思い込み
10. 焦り本能　「いますぐ手を打たないと大変なことになる」という思い込み
Blazorでドラクエウォークのお土産近いところ調べるサイト作った話

Qiita Advent Calendar 2019　C# の記事です。C#でWEBアプリケーションが作成できるBlazorの良いところとか、ロードマップとか記載しようと思いましたが、ドラクエウォークでお土産近いところ調べたいなと思って、気づいたらコード書いてました！今は反省している。。。

[Demo](https://blazordqw.firebaseapp.com/)
<img width="375" alt="iOS の画像.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110304/1d8e9260-dfc3-4c9f-5b1a-90a8550aad4a.png">


何県人かばれてしまう。。

# 概要

現在地から、ドラクエウォークのお土産に近い順に表示します。 PCのブラウザはほとんど大丈夫だと思うのですが、**ブラウザによっては、動かないかもです。** GeoLocation情報はブラウザから取得しており、`JavaScript`を使用しています。デバイスによってはGPSの精度にばらつきがありますので、必ずしも正確な距離が出ない場合があります。
Blazorは`JavaScriptレス`をウリにしている感じですが、現状は`JavaScript`とは切っても切れない関係ですね。

# Blazorの説明。HTMLにインラインでC#コーディング
Razor構文に慣れると非常に楽です。C#を使って、要素に対し直感的に扱うことができるので、この辺はすんなりと書けるようになると思います。また、`LINQ`もバシバシ使うことができます。

```javascript:Index.Razor
@page "/"
@inject HttpClient Http

@using AspNetMonsters.Blazor.Geolocation
@inject LocationService  LocationService
<h3>ドラクエウォーク　現在地から近いところTop20</h3>

@*データがある場合、表示*@
@if(Datas.Any())
{
    @foreach (var d in Datas)
    {
        <SurveyPrompt Title="@(Pres.Where(p=>p.Id==d.Pre).First().Name)" Data="@d"/>
    }
}

@functions
{
    Location location;

    private Omiyage[] Datas = new Omiyage[0];

    private Pre[] Pres = new Pre[0];


    protected async override Task OnInitializedAsync()
    {
        // 現在地取得
        location = await LocationService.GetLocationAsync();

        // お土産データ取得
        Datas = await Http.GetJsonAsync<Omiyage[]>("data.json");

        // 県名取得
        Pres = await Http.GetJsonAsync<Pre[]>("pre.json");

        //データのセット
        SetData();
    }

    //データのセット
    void SetData()
    {
        // 現在地の取得
        var lat1 = (double)location?.Latitude;
        var lon1 = (double)location?.Longitude;

        // 現在地との距離を計算
        foreach(var data in Datas)
        {
            data.SetKyori(lat1, lon1);
        }

        // 近い順に20個まで取得
        Datas = Datas.OrderBy(p => p.Kyori).Take(20).ToArray();
    }

}
```

# Blazorの説明。.Netのライブラリが豊富！
Blazor Client-Sideアプリケーションは、`WebAssembly` によりブラウザ上で実行されます。現時点ではプレビュー版ではあるのですが、ほぼ実用レベルに近いところまで行っているのではないでしょうか。もちろんブラウザでできること以外のことはできませんが、nugetパッケージは適用できるパッケージが多く、既存のノウハウを活かした開発ができるようになっています。

2点間距離の計算も、一発。。これ、ブラウザ上で動いているわけですから、違和感さえ覚えます。

```c#:Model.cs
/// <summary>
/// 現在地との距離
/// </summary>
public double Kyori { get; set; }

/// <summary>
/// 距離を算出する
/// </summary>
/// <param name="lat2">現在の緯度</param>
/// <param name="lon2">現在の経度</param>
public void SetKyori(double lat2,double lon2)
{
    Kyori = new System.Device.Location.GeoCoordinate(Lat, Lon).GetDistanceTo(new System.Device.Location.GeoCoordinate(lat2, lon2));
}
```

# Blazorに興味を持ったら。。。
このアプリケーションの作成には、それほど時間をかけてません（位置情報の収集には時間がかかりましたが。。）Blazorに興味を持ったら、Blazorの[Qiita Advent Calendar](https://qiita.com/advent-calendar/2019/blazor)にアクセスしてみてください。
Numpy操作いろいろ(修正）

# このページについて
　いくつか自分で調べた機能を記述していきます。

<br><br>
### 特定条件の部分を抜き出す
　Trueのみを抜き出す。Falseは否定で対応する。

```python
array[a == b,:]
array[a != b,:]
```
その他評価式が使えます。

参考サイト
[python の配列。要素をまとめて論理演算。not、and、or、xor](http://ailaby.com/logical_and/)
[NumPy配列ndarrayから条件を満たす要素・行・列を抽出、削除](https://note.nkmk.me/python-numpy-condition/)
<br><br>
### numpyの配列の大きさだけForを回す

```python
for i in range(array.shape[0]):
```
参考サイト
[Pythonでリストとタプルを相互に変換するlist(), tuple()](https://note.nkmk.me/python-numpy-condition/)
Goのhtml/templateでifする方法

[参考](https://off.tokyo/blog/go%e3%81%aehtml-template%e3%81%a7if%e3%81%a7%e6%9d%a1%e4%bb%b6%e5%88%86%e5%b2%90%e3%81%99%e3%82%8b%e6%96%b9%e6%b3%95/)
ETL(ELT)処理用フレームワークcliboaとは何か

# ETL処理とは
ETLはextract, transform, loadの頭文字を取って繋げた用語である。extract, transform, loadは日本語に直訳すると抽出、加工、読み込みになる。
ETL処理とは、何らかのデータ(テキストファイル、csvファイル、etc...)に対してETLが示す処理を行うことである。

# ELT処理とは
ELT処理はETL処理とは順番が異なるのみである。E,L,Tが示す処理の内容はETLと変わらない。

# cliboaとは
<a href="https://www.brainpad.co.jp/">BrainPad</a>社内で開発・運用が行われていたETL処理機能の共通基盤部分をアプリケーションフレームワークとして設計・実装し直したものがcliboa(クリボア)である。

GitHub
https://github.com/BrainPad/cliboa

PyPI
https://pypi.org/project/cliboa/

## cliboaに置けるETL処理の定義
cliboaではextract(抽出)は何らかの箱からデータをダウンロードすること、transform(加工)はダウンロードしたデータを加工すること、load(読み込み)は抽出、加工したデータをいずれかの箱にアップロードすることとして定義している。下記に概念図を示す。
![cliboa_brief.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55214/7bbe68aa-c7ae-8b3d-edf9-5d92f31e84ad.png)



## cliboaの特徴
- Pythonで実装されている。
- Yamlファイルを書くだけで簡易なETL処理を稼働させることが可能である。
- PythonでETL処理を拡張実装することが可能である。

# クイックスタート
## 必要な環境
Debian, Ubuntu, CentOSなどのLinuxOS上で動作する。

## インストール方法
version3.0以上のpythonを用意した後、pipコマンドでインストール。

```
sudo pip3 install cliboa
```
インストール完了後、cliboadminというコマンドが実行可能になる。cliboadminを任意のディレクトリで実行する。

```
$ cd /usr/local
$ cliboadmin init sample
$ cd sample
$ cliboadmin create simple-etl
```
## ファイル・ディレクトリ構成
cliboadminによって初期化されたプログラム構成は下記の通り。

```
├── Pipfile
├── bin
│   └── clibomanager.py
├── common
│   ├── environment.py
│   ├── __init__.py
│   └── scenario
├── conf
├── logs
└── project
│    └── simple-etl
│            ├── scenario
│                    └── scenario.yml
└── requirements.txt
```

## PyPIパッケージのインストール
requirements.txtにcliboaを動かすのに必要なpythonパッケージ一式が定義されているので、pipコマンドで指定してインストールする。

```
$ cd sample
$ pip3 install -r requirements.txt
```

## ETL処理のシナリオを書く
project/simple-etl/scenario.ymlに例として下記の処理を書く。

処理内容
sftpサーバーからtest.csv.gzをダウンロード、ダウンロードしたファイルを解凍、解凍したtest.csvをsftpサーバーにアップロード

```
scenario:
- step:
  class: SftpDownload
  arguments:
    host: localhost
    user: root
    password: pass
    src_dir: /usr/local
    src_pattern: test.csv.gz
    dest_dir: /tmp
- step: FileDecompress
  arguments:
    src_dir: /tmp
    src_pattern: test.*\.csv.*\.gz
- step:
  class: SftpUpload
  arguments:
    host: localhost
    user: root
    password: pass
    src_dir: /tmp
    src_pattern: test.*\.csv
    dest_dir: /usr/local
```
## 実行

実行前に下記を整えておく
- localhostをsftpサーバー化
- id=root, password=passでsftpサーバーにログイン可能
- /usr/local以下にtest.csv.gzを用意

下記のコマンドで実行

```
cd sample
pipenv run python3 bin/clibomanager.py simple-etl
もしくは
python3 bin/clibomanager.py simple-etl
```

実行後、下記のようになっていれば成功である。
- /usr/local以下に置いたtest.csv.gzが/tmp以下に展開されtest.csvになっている。
- /usr/local以下にtest.csvが存在する
yahoo路線の運行情報を取得したい

# 背景
とあるTwitterのBot作成で、どーしても、電車の運行情報が必要となった。
どこからか、**無料で特定の路線のみ**の運行情報を引っ張って来れないかな〜と色々考えた結果、
yahoo路線からスクレイピングするのが最適解だと分かった。
# 運行状況を配信しているapiやらサイトやら
色々調べて、現在、路線の運行情報を配信しているのは
1. [鉄道遅延情報のjson] (https://rti-giken.jp/fhc/api/train_tetsudo/) (json形式で、遅延などが生じている路線を集計して、返してくれる)
2. [駅すぱあとのapi](http://docs.ekispert.com/v1/) (優秀そう！でも有料有料)
3. [yahoo路線の運行状況] (https://transit.yahoo.co.jp/traininfo/top) (一番馴染みのあるやつ、でもapiない!!!)

結局の話、無料でやるならば、[鉄道遅延情報のjson] (https://rti-giken.jp/fhc/api/train_tetsudo/)か[yahoo路線の運行状況] (https://transit.yahoo.co.jp/traininfo/top)になってくる。
前者の場合、全国の遅延している路線情報が返ってくる。あとは情報の更新が10分ごと...朝の通勤ラッシュでは10分でさえも命とり。

後者のyahoo路線、**実は中身が駅すぱあとだったりする**....笑（意外と知られていない）
路線ごとに運行情報もあるし、正確かつリアルタイムで早い！じゃあ
***apiがないんだったらスクレイピングしてしまえ！***
#yahoo路線の運行情報をスクレイピング
スクレイピングの「す」もやったことのない筆者がスクレイピングをやってみる。
どうやら**「BeautifulSoup」**ってのを使うらしい...
すばっらしいスープを見せてもらおうじゃないかっ！
##BeautifulSoupってなーに？？
BeautifulSoupはHTMLやXMLファイルからデータを取得するPythonのライブラリ。
どうやら、**取ってきたHTMLから、パーサーってものを使ってHTMLの要素を検索**できたりする。
細かいことは分からないから、早速やってみよう！
#レッツ！スクレイピング！
今回スクレイピングしたいサイトはこちら！
[yahoo路線　東海道線の運行状況] (https://transit.yahoo.co.jp/traininfo/detail/27/0/)
まずは、ページのhtmlを覗いてみよう
![スクリーンショット 2019-12-14 11.46.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309863/3704cc48-567f-ada8-c00d-16f852d19f34.png)
遅延時のHTMLを見てみると、ddタグのtroubleクラスがある

```html
<div id="mdServiceStatus">
　　<dl>
　　<dt>
　　<span class="icnAlertLarge">[!]</span>列車遅延</dt>
　　<dd class="trouble">
　　　<p>宇都宮線内で線路内点検を行った影響で、下り線(熱海方面行)の一部列車に遅れが出ています。　<span>（12月14日 09時25分掲載）</span></p>
　</dd>
　</dl>
</div><!--/#mdServiceStatus-->
```

一方で、通常時のHTMLを覗いてみるとddタグのnormalクラスがある

```html
<div class="elmServiceStatus">
    <dl>
    <dt><span class="icnNormalLarge">[○]</span>平常運転</dt>
    <dd class="normal">
        <p>現在、事故・遅延に関する情報はありません。</p>
    </dd>
    </dl>
</div>
```

つまり
遅延時：　**troubleクラスのddタグ**
通常時：　**normalクラスのddタグ**

**このddタグを元に、遅延か、通常運転かを判別ができそう!**
さっそくやってみよう！

##インストール
まずはpipでBeautifulSoupを入れる

```
$ pip install beautifulsoup4 
```

##コード

```python
import requests
from bs4 import BeautifulSoup

#東海道線の運行状況のURL
ToukaidouLine_URL = 'https://transit.yahoo.co.jp/traininfo/detail/27/0/'

#Requestsを利用してWebページを取得する
ToukaidouLine_Requests = requests.get(ToukaidouLine_URL)

# BeautifulSoupを利用してWebページを解析する
ToukaidouLine_Soup = BeautifulSoup(ToukaidouLine_Requests.text, 'html.parser')

#.findでtroubleクラスのddタグを探す
if ToukaidouLine_Soup.find('dd',class_='trouble'):
    message = '東海道線は遅延しています'
else:
    message = '東海道線は通常運転です'

print(message)
```

実行結果

```
東海道線は遅延しています
```

##感想
めっちゃ簡単じゃない？？webページから情報を持ってこれるのは夢広がる！
後日談：yahooの人に見せたら、「グレーゾーンだね」と言われたのは内緒
AWS QuickSightの導入検討と使ってみた所感


カレンダーに登録するの忘れてました…
エキサイトのデータテクノロジーグループ新卒1年目の藤井です。

弊社では、全社員が数値を確認し、数値に基づいた定量的な意思決定をすることが重要だと考えています。
そのため、データチームとして各主要サービスの現在の状況（PV数や売上など）を可視化することが第一にやるべきことだとしてデータテクノロジーグループではダッシュボード作成から取り組んでいます。

BIツールの選定から始めていましたが、QuickSightを導入していくことに決定しました。
そこでQuickSightを使っていて感じたメリットを紹介したいと思います。

以下では、チームの活動についてや、スライドではもうちょっと詳しく書いていますが、コンフィデンシャルな内容を扱っていたので内容は薄めです。
[AWS QuickSightの導入検討と使ってみた所感とデータチームの活動について : エキサイト公式　エンジニアブログ](https://exdev.exblog.jp/30965350/)
スライドは以下にもありますが、実演を抜いています。
[Amazon QuickSightを使ってみた 〜QS導入に至った経緯と活用例〜 - Speaker Deck](https://speakerdeck.com/fj_ex/amazon-quicksightwoshi-tutemita-qsdao-ru-nizhi-tutajing-wei-tohuo-yong-li)





## QuickSightについて
今回社内に導入することを検討いるのがAWSの提供するBIサービス「QuickSight」です。
ざっくりと感じたメリットを上げると以下の通りです。

* **全社員にアカウントを配布してもスケールする料金設定**

閲覧者モード（月額最大5ドル）と作成者モード（年契約で月額18ドル）があり、基本エンジニアやマネージャークラスは作成者モードでダッシュボードを好きにイジれるように、というように設定することも可能です。閲覧者アカウントが200人いても最大1000ドル！安い…
詳しくは[公式](https://aws.amazon.com/jp/quicksight/pricing/?nc=sn&loc=4)を。

* **AWSサービスとの連携、エクセルなどこれまで使用してきたものを可視化できる**

* **アプリやメールレポートによる共有のしやすさ**

ダッシュボードでよくあるのが、誰も見てくれないパターン…。（載せる内容も重要ですが）Google Analyticsも動作が重い、ブラウザを開くのが面倒くさいという意見も聞きます。
QuickSightは公式アプリがiOS、Androidから配布されていたり、メールでダッシュボードの内容を送れたりできるので手が空いたほんの数分でどこでも確認ができます。

* **ML Insightや機能アップデートの速さ**

ML Insightという機能があり、これは予測や異常検知ができます。
今後施策を打たない場合や施策を行なった結果、今後どうなるのかなど予測値を出してくれます。（単純移動平均などで。詳しく見れてません。）
例えば以下のように、自動ナラティブ機能を使うと、文章で成長率の予測などを計算してくれます。
<img width="420" alt="スクリーンショット 2019-12-14 11.05.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528149/2842f341-c928-3b35-efdd-bf83798ab649.png">
そしてこの文章は以下のようにカスタマイズできるので、期間の変更や日本語文章の作成もできます。
レポーティングの時間も短縮できるとても便利な機能だと思います。
<img width="750" alt="スクリーンショット 2019-12-14 11.05.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528149/df8a31a9-8bb3-a765-dfec-9b0f613fbc84.png">

また、アップデートが非常に早く、最近のアップデートではsdkやcliからのAPI機能追加や[SageMakerとの連携も可能になりました](https://docs.aws.amazon.com/ja_jp/quicksight/latest/user/sagemaker-integration.html)！東京リージョンではまだですが…

今後、異常検知や予測モデルがカスタマイズできたり、実験中の学習モデル精度や実際にサービスで運用している機械学習モデルの監視などもQuickSightで簡単に可視化できてしまいそうです。


などなど私達の目標を達成するために便利な点が多いです。
今後ドンドン全社導入を進めていきたいと思います。
VSCodeのREST ClientでCognitoを利用するためのツールを作ってみた

# はじめに

皆さんはVisual Studio Codeの拡張機能の一つの[REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client)は利用していますか？
VSCode上でREST APIを呼び出すツールとして人気があると思います。
しかし、このツールではOAuth2.0がサポートされおらず、Cognitoで認証し、APIをコールすることが現時点ではできません。(2019年12月14日時点)
また、似たツールとしてPostmanが有名ですが、あちらはCognitoで認証してAPIをコールすることができますが、私は次の点でPostmanを利用せずにREST Clientを利用しています。

- テキストベースでAPIを定義することができるので、Gitで管理することができる。

Gitで管理することで、APIも変更があった場合もそのバージョンでコールするための情報が残っているので、APIのバージョンごとの呼び出しデータを管理する必要がなくなるのは大きかったです。

## 実装方法

ローカルにCognitoで認証を行いアクセストークンを取得してきてくれる認証サーバをローカルに立ててるだけです。

## インストール方法

必要としているディレクトリで`npm i -D rest-client-cognito`でインストールすることができます。
Nodeの開発環境でななければ、グローバルインストールしていただければ利用できると思います。（未検証）

## 使い方

プロジェクトディレクトリに`.env`ファイルを作成してください。
次の４つの項目を追加してください。

``` ..env
RCC_USER_POOL_ID={CognitoのユーザープールID}
RCC_CLIENT_ID={アプリクライアントID}
RCC_USER_NAME={ログインするユーザー名}
RCC_PASSWORD={ログインするユーザーのパスワード}
```

次にコンソールで`rcc`コマンドを実行することで、Cognitoの認証サーバをローカルに立ち上げることができます。
`rcc`で立ち上がる認証サーバはデフォルトで3000番ポートで起動するようになっています。
`localhost:3000/login`をGETすることでアクセストークンを取得することができます。
(普通ログインといったらPOSTですが、深夜テンションで作成したのですっかりそんなことも忘れて作ってしまいました。。。指摘しないでもらえると助かります。。。)

このAPIで返却されるデータの構造は次の形になります。

``` ..json
{
  "token": "アクセストーン"
}
```

なので、これをREST Clientで利用する場合は次のように記述することで利用できるようになります。

``` RestClient.rest
@rccPort = 3000

###

# @name login

GET http://localhost:{{rccPort}}/login

@authToken = {{login.response.body.token}}
```

あとは`authToken`を色々なAPIで利用してもらえれば、Cognitoからもらった認証情報を用いてAPIをコールできるようになります。

## オプション

デフォルトで3000番ポートで起動しますが、だいたいの方は3000番ポートは使っていると思います。
なので、`-p`か`--port`オプションを利用することで、ポート番号を変更することができるようになっています、
例：`rcc -p 4000`、`rcc --port 4000`

## 最後に

簡単な動作確認程度のことしかしていないので、何かありましたらGitの方でコメントお願いします。
#Github での master / production / develop などベースブランチ同士の merge で、どんな conflict 解消をしたかがわかりにくいけど、どうすれば良い？

-  一度conflictした状態のコミットを積んでおいてから、修正コミットを積んだら差分が分かりやすいのでは
-  commitは少し荒れるのと、綺麗なやり方ではないと思うけれど
-  手元でパッチファイルを作成しておくなど、他の提示方法もあるかもしれない

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2844








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
[Laravel] スプレッドシート → マイグレーション

ExcelやGoogle Spreadsheetなんかに記述したテーブル定義からマイグレーションファイルを作成する際に使っている式をシェアします。
必要に応じてカスタマイズして使ってください。

こんなレイアウトの表を想定しています。

|A|B|C|D|E|F|G|H|
|---|---|---|---|---|---|---|---|
|フィールド名(英語)|型|フィールド名(日本語)|備考|桁1|桁2|デフォルト？|Null許可？|
|name|string|名称||256|||o|

```
=IF($A5="created_at", "$table->timestamps()",
 IF($A5="updated_at", "//",
 IF($A5="deleted_at", "$table->softDeletes()",(
   IF($A5="id", "$table->bigIncrements('id')",
   IF($B5="long", "$table->bigInteger('" & $A5 & "')",
   IF($B5="boolean", "$table->boolean('" & $A5 & "')",
   IF($B5="datetime", "$table->dateTime('" & $A5 & "')",
   IF($B5="double", "$table->double('" & $A5 & "', " & $E5 & ", " & $F5 & ")",
   IF($B5="float", "$table->float('" & $A5 & "', " & $E5 & ", " & $F5 & ")",
   IF($B5="int", "$table->integer('" & $A5 & "')",
   IF($B5="string", "$table->string('" & $A5 & "', " & $E5 & ")",
   IF($B5="text", "$table->text('" & $A5 & "')",
   IF($B5="timestamp", "$table->timestamp('" & $A5 & "')",
   "// NO MATCH"))))))))))
   & IF(ISTEXT($G5), "->default('" & $G5 & "')",
     IF(ISNUMBER($G5), "->default(" & $G5 & ")",
     ""))
   & IF(ISTEXT($H5), "->nullable()", "")
   & "->comment('" & $C5 & "')"
 ))))
 & ";"
```

こんな感じのテキストが生成されるので、これをマイグレーションファイルにぺたり！

```
$table->string('name', 256)->nullable()->comment('名称');
```
強化学習３５　pythonローカル開発で、myModuleにリンクを貼ってimportする。

中学生から大学生のAI初学者を対象にしています。

chokozainerRLで強化学習の学習環境開発をしていますが、ローカルのgitで変更して、リモートに送って、colaboratoryでチェックするという流れは、結構面倒です。

簡単なモジュール変更のチェックをする場合、ローカルにもpython環境があるのならば、そちらでチェックするのが速い。
そのときに、gitで変更して、リモートに送って、再度　pip　installするのもなあということです。

直接、
anaconda3/envs/chainer/lib/python3.7/site-packages/chokozainerrl
を変更すると、、gitで上げるときにコピーしたりするので、、、。

そこで、シンボリックリンクを貼ってみました。

```bash
ln -s /home/{user name}/chainerrl/chainerrl anaconda3/envs/chainer/lib/python3.7/site-packages/chainerrl
ln -s /home/{user name}/chokozainerrl/chokozainerrl anaconda3/envs/chainer/lib/python3.7/site-packages/chokozainerrl
```

{user name}はそれぞれ変更してください。
これで、簡単なチェックはできます。
ローカルのjupyter notebookで簡単なチェックをしてから、Colaboratoryに上げてチェックすると楽ですね。
chainerRLもgitで更新されてから、PyPIにアップロードするまで時間がかかるみたいなので、新しいものを試すときは、このようにしておくと便利です。
ローカルリポジトリをGitHubにpushする方法

ローカルで作業リポジトリをリモートリポジトリにpushする際の手順
いつも忘れてしまうので、忘備録として書き留めておきます

```
// 作業ディレクトリに移動(今回の作業ブランチはstudy-laravelと想定)
$ cd workspace/SampleProject

// gitを初期化
$ git init

// ステージングにあげる
$ git add .

// メッセージを付けてコミット
$ git commit -m "Initial Commit"

// リモートディレクトリを追加
$ git remote add origin <リモートリポジトリのURL>

// リモートリポジトリにPush
$ git push origin master
```

以上！！
これでリモートリポジトリにプロジェクトをpushすることができました！！
VSCodeでGoのDebugにちょっとハマった話 ~firebase絡み~

VSCodeで[Firebase Admin SDK](https://firebase.google.com/docs/admin/setup?hl=ja)を用いたGoのDebugをしようとしてちょっとハマりました。

[SDK初期化](https://firebase.google.com/docs/admin/setup?hl=ja#initialize_the_sdk)でいきなりfirebase-adminsdk.jsonを読み込めなくて怒られる。。

```golang
	// SDK初期化
	app, err := firebase.NewApp(ctx, nil, opt)
	// err: "cannot read credentials file: open firebase-adminsdk.json: no such file or directory"
```

普通にgo runで起動した時はエラー出ないので、`launch.json`の設定で現在のディレクトリを明示する必要があるのではないかとアタリをつけてみる。
自分のプロジェクトの場合、`{root}/cmd/api`の下にmain.go、プロジェクト直下にfirebase-adminsdk.jsonを置いています。

```
├── cmd
│   └── api
│       └── main.go
├── ***
└── firebase-adminsdk.json
```

```launch.json
{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Launch",
      "type": "go",
      "request": "launch",
      "mode": "auto",
      "program": "${workspaceFolder}/cmd/api",
      "env": {},
      "args": []
    }
  ]
}
```

[公式ドキュメント](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations)で設定の詳細を見たら、明らかにそれっぽいのがあった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71113/ebe9cbbc-5666-7f75-ecbf-ba94ff652d2e.png)

というわけでlaunch.jsonに`cwd`を追加します。

```launch.json
{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Launch",
      "type": "go",
      "request": "launch",
      "mode": "auto",
      "program": "${workspaceFolder}/cmd/api",
      "cwd": "${workspaceFolder}",
      "env": {},
      "args": []
    }
  ]
}
```

デバッグ再起動したら無事成功した！

そもそもGoでFirebase Admin SDK使ってる人どれぐらいいるんだろ・・
仲間が増えると良いなー
Vim プラグインのヘルプのフォーマットについて調べた

## はじめに

Vim プラグインを使う際、ヘルプを見ることがあると思いますが、フォーマットが整っていますよね。

その中で、自分でヘルプを書くときにはどのようにフォーマットに則ればいいのかがわからなかったので、調べてみました。

## フォーマットサンプル

`:help write-local-help` に、フォーマットサンプルが載っています。
以下、引用します。こちらを参考に説明します。

```vim
  1     *typecorr.txt*  Plugin for correcting typing mistakes
  2
  3     If you make typing mistakes, this plugin will have them corrected
  4     automatically.
  5
  6     There are currently only a few corrections.  Add your own if you like.
  7
  8     Mappings:
  9     <Leader>a   or   <Plug>TypecorrAdd
 10             Add a correction for the word under the cursor.
 11
 12     Commands:
 13     :Correct {word}
 14             Add a correction for {word}.
 15
 16                                                     *typecorr-settings*
 17     This plugin doesn't have any settings.
```

## ヘルプの書き方

`:help help-writing` に説明がありましたので、かいつまんで紹介します。

### 1行目にヘルプファイル名を記載する

1行目の行頭に、 `*typecorr.txt*` というヘルプファイル名へのリンクを記載します。
これで、`:help typecorr.txt` というふうに検索したら、準備したヘルプにジャンプしてくれます。

### 行末に Vim モードラインを書く

ファイルの見た目を制御するVim モードラインを定義することで、ヘルプファイルの体裁を整えます。
[vim-go のドキュメントファイル](https://github.com/fatih/vim-go/blob/8e6fcae371918fa8ebae088ce8e71de7df8cdbca/doc/vim-go.txt#L2550)には以下のように記載されていました。

`vim: ft=help tw=78 et ts=2 sw=2 sts=2 norl`

* `ft=help`: `filetype` を `help` に
* `tw=78`: `textwidth`、テキスト最大幅を 78 に
* `et`: `expandtab`、タブを指定数の空白文字に
* `ts=2`: `tabstop`、2文字分の空白文字をタブとして認識させる
* `sw=2`: `shiftwidth`、インデント時に使用される空白文字の数を2文字に
* `sts=2`: `softtabstop`、タブを押下したときに使用する空白の数
* `norl`: `norightleft`: 画面表示の方向を左から右に

### 適切にヘルプタグを付ける

アスタリスク `*` を指定することで、ヘルプタグをつけることができます。プラグイン名から始めるのが理想的とのこと。`<plugin-name>-hogehoge` みたいな感じですね。
また既存のヘルプタグにリンクするときは`|`で囲みます。

### 適切にシンタックスハイライトを使う

よりヘルプを読みやすくするために、シンタックスハイライトを適用します。いくつか紹介します。

* コマンドブロック：`>` をブロック直前に、`<` をブロック直後に
* 列見出し：`~` を行末に
* セクション区切り：`=` をテキスト最大幅まで使う

## おわりに

今回調べたことでヘルプの書き方の概要はざっくりつかめました。あとは他の Vim プラグインのヘルプファイルを参考に書いていこうと思います。

## 参考

* [helphelp - Vim日本語ドキュメント](https://vim-jp.org/vimdoc-ja/helphelp.html#help-writing)
* [Documentation for vim help file markup - Stack Overflow](https://stackoverflow.com/questions/3847224/documentation-for-vim-help-file-markup)
* [Documentation / Learn Vimscript the Hard Way](http://learnvimscriptthehardway.stevelosh.com/chapters/54.html)
* [モードラインを使って、ファイルごとにvimエディタのオプションを指定する。 — 名無しのvim使い](https://nanasi.jp/articles/howto/file/modeline.html)
* [Vim の 5 つのタブとスペース関連のややややこしいオプションをできるだけ簡単に解説するよ - yu8mada](https://yu8mada.com/2018/08/26/i-ll-explain-vim-s-5-tab-and-space-related-somewhat-complicated-options-as-simply-as-possible/)
[GAE] Cloud Buildからcron.yamlをデプロイする

Google App Engine(GAE)でスケジュール実行したい場合、cron.yamlを書いてデプロイするわけですが、それをCloud Buildを使ってやりたい場合に軽くハマったことなど。

## 問題

まず、大前提として、Cloud Buildにてアプリケーションをデプロイできているものとします。
となると、すでにcloud_build.yamlファイルがあるはずなので、そこに

```yaml
- name: 'gcr.io/cloud-builders/gcloud'
  args: ['app', 'deploy', 'cron.yaml']
```

というステップを追加します。
これだけで完了！と思うじゃないですか？
ところが、実際にやってみるとこんなエラーが出てしまいました。

```
Already have image (with digest): gcr.io/cloud-builders/gcloud
Configurations to update:

descriptor: [/workspace/cron.yaml]
type: [cron jobs]
target project: [XXXXXX]


Do you want to continue (Y/n)?
Updating config [cron]...
.failed.
ERROR: (gcloud.beta.app.deploy) Server responded with code [403]:
Forbidden Unexpected HTTP status 403.
You do not have permission to modify this app (app_id=u'b~ XXXXXX').
```

## 解決方法

CloudBuildのサービスアカウント(例:999999999999@cloudbuild.gserviceaccount.com)に「Cloud Scheduler 管理者」の役割を追加します。
axiosのヘッダーのconfigでちょっとハマった


某APIを試しててaxiosのconfig指定をミスってたので、自戒の意味を込めて残しておきます。

完全に自分用メモっぽいやつです。

## ミスったコードなど

```js

//省略

class Hoge {
    constructor() {
    	//省略
    }
    
    //ミスった方
    methodA(IMAGE_PATH){
        const file = fs.createReadStream(IMAGE_PATH);
        const form = new FormData();
        form.append('image', file);
        form.append('entrance', 'detection');
        
        const config = {
            'X-ClovaOCR-Service-ID': this.SERVICE_ID,
            ...form.getHeaders()
        };

        return axios.post(this.URL.RECOGNITION, form, config)
   }
   
   
   //うまくいった方
   methodB(IMAGE_PATH){
        const file = fs.createReadStream(IMAGE_PATH);
        const form = new FormData();
        form.append('image', file);
        form.append('entrance', 'detection');

        const config = {
            headers: {
                'X-ClovaOCR-Service-ID': this.SERVICE_ID,
                ...form.getHeaders(),
            }
        }

        return axios.post(this.URL.RECOGNITION, form, config)
   }
}

const hoge = new Hoge();
hoge.methodA(); // エラー
hoge.methodB(); // 成功
```

## axiosのconfigミス

慣れてつかってるうちにconfig=headersっぽいイメージで使ってたみたい。
通常configの中には他にもmethod指定やbodyデータなども入ってくるので`config.headers`な指定にしないとですね。

```js
const config = {
	'X-ClovaOCR-Service-ID': this.SERVICE_ID,
    ...form.getHeaders()
};
```

```js
const config = {
    headers: {
        'X-ClovaOCR-Service-ID': this.SERVICE_ID,
        ...form.getHeaders(),
    }
}
```
[勉強用](随時更新)Vueを勉強しようとおもったら久々にWebにてお出すことになった話(応援歓迎)

開発に合わせたGithubはこちら
https://github.com/KeiMae/vue-study

# 何をやってみようかと
普段データサイエンスをしていているだけど、簡単なレポートはBIツールではなくWebでも見せられるようにしてみようかなぁと思い立って。
データサイエンスらしく普段はpythonしか描かないのですが、さすがにモノスキルは良くないと思い、Golangに~~いまさら~~着手しようと。
詳しいコンテンツはPageTopのgithubを見てください

このポスト自体は初心者・初学者（主に大学から情報工学に触り始めた学生さん・新社会人）にむけた記事になれば良いと思っています。

初学者の方は下の方主なトラブルまとめを見ると安心できるかもしれません

## さて 
普通のpythonだと、インフラは大体こんな感じじゃないかと

- パッケージマネージャ
 - pyenv
- 仮想環境
 - virualenv

サイエンスならcondaなのでしょうけど。
確かにこれでパッケージのバージョン管理とかもできるし、（今回はやらないけど）検証・本番環境へのリリースもある程度簡単にできる。しかし、いま(2019年)はコンテナ全盛期。 ちょっとコンテナ開発を試みます。

# 自分の思うコンテナ
きっと仮想環境を作ってくれる、、、つまり、ミドル層でのバージョン管理なんかは扶養。。コンテナ内にGlobal installして構わないはず！

間違ってたら教えてください・・・

# 開発環境
とりあえず、自分用Macのローカルに構築

* OS
 * macOS Catalina 10.15
* Docker
 * 2.1.0.5

# GOAのコンテナの用意
GolangでAPIを作るときWebServerをどうするか。フレームワークはどうするか。が早速ハマる（Golangマジでおっかけなかった）。
調べたらgoaが結構ヒットするので、とりあえず、日本語文献が多そうなgoaからスタート
https://qiita.com/loftkun/items/1a9951d1864bebdc51e1
を見るとgoaよりgo-kitとかの方がグローバルスタンダードっぽいけど、、

# トラブル(情けないものかきっとあるあるまで)
## やべ、Dockerの使い方忘れたｗｗ
2年近くWebの業界を離れていました。そして2020年2月現在在籍しているところは外注の嵐。。。
ということで、Dockerの基本すら忘却の彼方。正直焦りました。
## Linuxも色々やらんきゃあかんかったけん
DockerのImageで引っ張ってきたLinuxはほんと何も入ってません(Amazon Linux2 が以下に助かることか。。。)。ってことで下記を参考にvimとNeoBundleのインストールを進めます。
「vimで文字化けした時の対応」 view at 2020/02/25
https://qiita.com/meio/items/08143eacd174ac0f7bd5
「vim-goをインストールしてみた（所要時間：15分）」
https://qiita.com/lucy/items/e4f21c507d3fd2c0ffe9
「【ざっくりまとめ】Linuxパッケージのインストール方法を一通り」
https://eng-entrance.com/linux-package-install
## vim-goが使えない・・・？
vim-goでvimをSyntaxハイライトしようとしたところ、vim8出なければならないよう。
下記のサイトを参考に更新
https://genzouw.com/entry/2019/02/27/075021

# 参考文献
「Go言語Webフレームワークランキング」 view at 2019/12/07
https://qiita.com/loftkun/items/1a9951d1864bebdc51e1
「docker run(コンテナ作成)する時のオプションあれこれ」
https://qiita.com/shimo_yama/items/d0c42394689132fcb4b6
「vimで文字化けした時の対応」 view at 2020/02/25
https://qiita.com/meio/items/08143eacd174ac0f7bd5
「vim-goをインストールしてみた（所要時間：15分）」
https://qiita.com/lucy/items/e4f21c507d3fd2c0ffe9
「【ざっくりまとめ】Linuxパッケージのインストール方法を一通り」
use-reducer-asyncの紹介

## はじめに

[先日の記事](https://qiita.com/daishi/items/72e5ef3a46c83897af06)で[react-tracked](https://react-tracked.js.org)の紹介をしました。react-trackedはreactのcontextとhooksを使ったglobal stateのライブラリです。プリミティブな機能を提供しており、必要に応じて拡張(custom hooks化など)して使えます。非同期処理も可能なのですが、ドキュメントサイトでチュートリアルを作成する際には、オススメの非同期処理なども記述する必要があると思いました。react-trackedはreduxなどと違って外部にstoreを持たないため、非同期処理もReactの範囲でやることになります。custom hooksで非同期処理用のcallbackを作る方法もありますが、今回は、useReducerを拡張して非同期処理を記述するライブラリを紹介します。

react-trackedと合わせて使うことを想定して説明しましたが、特にreact-tracked専用のライブラリではなく、普通のReact stateでも使うことができます。

## use-reducer-async

リポジトリはこちらです。

https://github.com/dai-shi/use-reducer-async

コードはとても小さいです。ライブラリにしなくても自分でcustom hooksを書いても同じことができます。このライブラリは、その機能より、コーディングパターンを提案することに意味があります。

## 使い方

一例として、データ取得を行うケースを実装してみたいと思います。

ライブラリをインポートします。一つのhookだけです。

```javascript
import { useReducerAsync } from 'use-reducer-async';
```

初期ステートを定義します。personというデータを取得するケースを想定しています。

```javascript
const initialState = {
  loading: false,
  person: null,
};
```

reducerを定義します。

```javascript
const reducer = (state, action) => {
  switch (action.type) {
    case 'FETCH_STARTED': return { ...state, loading: true };
    case 'FETCH_FINISHED': return { ...state, loading: false, person: action.person };
    default: throw new Error('no such action type');
  }
};
```

非同期処理を行うハンドラーを定義します。今回は一つだけです。

```javascript
const asyncActionHandlers = {
  START_FETCH: (dispatch, getState) => async (action) => {
    dispatch({ type: 'FETCH_STARTED' });
    const data = await fetchData();
    dispatch({ type: 'FETCH_FINISEHD', person: data });
  },
};
```

最後にコンポーネントでhookを使います。

```jsx
const Component = () => {
  const [state, dispatch] = useReducerAsync(reducer, initialState, asyncActionHandlers);
  return (
    <div>
      <button type="button" onClick={() => dispatch({ type: 'START_FETCH' })}>Fetch Person</button>
      {state.loading && 'Loading...'}
      {state.person && <Person person={state.person} />}
    </div>
  );
};
```

これにより非同期処理が実行されて、ステートが更新されます。

## ポイント

今回の例では使いませんでしたが、本ライブラリはTypeScriptの型定義があるため、それを使うとより便利です。

ところで、Reduxでは公式ドキュメントでredux-thunkを推奨していますが、型付けが難しいことが課題です。use-reducer-asyncやcustom hooksで非同期処理をする場合は、その課題が軽減されます。ちなみに、本ライブラリのハンドラー定義はredux-thunkのAPIとそっくりです。

また、Reduxの場合はexternal storeを使うため、Concurrent Modeの対応が限定的になる部分があります。use-reducer-asyncはReactのstateを使うだけなので、Concurrent Modeに素直に対応できます。

## おわりに

このライブラリを作ろうと思ったきっかけは、[use-saga-reducer](https://github.com/azmenak/use-saga-reducer)を見つけたからです。redux-sagaにExternal APIというものがあることを知らず、Redux以外で使えることは驚きでした。redux-sagaはとても強力でいいとは思うのですが[^1]、ドキュメントサイトのチュートリアルで紹介するには向かず、シンプルな非同期処理のみを対象にした本ライブラリを開発しました。

[^1]: Reduxの公式ドキュメントでも、redux-sagaは標準採用ではなく、redux-thunkが標準になっています。
ReactNativeでDropdownメニューを模索する


Fomを作成するときDropdownメニューが必要になるときがあります。
RactNativeやExpoにはPickerの機能がありますが、Dropdownメニューの方が慣れてる人が多くのでいいかなと思い、軽く調査してみたのですが、意外としんどかったのでメモしておきます。

## Dropdownメニューのコンポーネントなんていくらでもあるだろう

そう思って軽く調べて見たところ以外としっくりくるものがありませんでした。
また、一見良さそうに見えても最新環境では動かないなどの問題がありました（これ多かった）。

## 試してみたもの

ググってみつかったいくつかのものを試してみましたが、WarningやErrorによりほとんど動きませんでした。
随分前にissueは上がってますがメンテされてない感じです。

* react-native-picker-select（動くけどスタイルの設定面倒）
* react-native-material-doropdown（componentWillUpdate has been renamedのWarning出る）
* react-native-modal-dropdown（componentWillReceiveProps has been renamedのWarning出る）
* react-native-dropdown（Super expression must either be null or a functionってエラーでる）

これいいよ！ってのがあればぜひ教えて欲しいです。。。

## React-native-picker-select


唯一動いたreact-native-picker-selectを試してみます。
本モジュールは、結局の所iOS, Androidのネイティブコンポーネントにマップする系のものですが、いきなりPickerとかが出てるより、とりあえずデザインとかを他のFormコンポーネントと統一化できるので、まあ、ギリ要件は満たすかな。。。

最終的には下記のような感じにしました。左iOS, 右Androidです。

![スクリーンショット 2019-12-14 10.12.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/2ffd9b56-8c4f-2b68-5f46-868220650d08.png "スクリーンショット 2019-12-14 10.12.01.png")

先にiOSでスタイル作ってAndroidに同じ記述してみましたがborderとか反映されないです。。。（なのでbackgroundColor付けてます）。
アイコンとか、自分で位置調整必要です。。。

以下、サンプル。

```
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import RNPickerSelect from 'react-native-picker-select';

export default class App extends React.Component {
  render() {
    return (
      <View style={{ marginTop: 60 }}>
        <Text style={{ marginVertical: 20, marginLeft: 30 }}>お住まいのエリア</Text>
        <RNPickerSelect
          onValueChange={(value) => console.log(value)}
          items={[
            { label: '関西', value: '関西' },
            { label: '関東', value: '関東' }
          ]}
          style={pickerSelectStyles}
          placeholder={{ label: '選択してください', value: '' }}
          Icon={() => (<Text style={{ position: 'absolute', right: 95, top: 10, fontSize: 18, color: '#789' }}>▼</Text>)}
        />
      </View>
    );
  }
}

const pickerSelectStyles = StyleSheet.create({
  inputIOS: {
    fontSize: 16,
    paddingVertical: 12,
    paddingHorizontal: 10,
    borderWidth: 1,
    borderColor: '#789',
    borderRadius: 4,
    color: '#789',
    paddingRight: 30, // to ensure the text is never behind the icon
    width: 300,
    marginLeft: 30
  },
  inputAndroid: {
    fontSize: 16,
    paddingHorizontal: 10,
    paddingVertical: 8,
    borderWidth: 0.5,
    borderColor: '#789',
    borderRadius: 8,
    color: 'black',
    paddingRight: 30, // to ensure the text is never behind the icon
    width: 280,
    marginLeft: 30,
    backgroundColor:'#eee'
  },
});
```

うーん。
C# - マルチディスプレイ（マルチスクリーン）における座標の取得について調べてみた - Windows10

# 調査内容

ウィンドウ（C#の`Form`）をスクリーンをまたぐ位置に置いてみて、クリックしたときに得られる座標を調べた。

# 調査結果

実験してみたところ、`Form`はどちらか一方のScreenに所属する扱いのようである。
「左端をクリックしたらPrimaryスクリーン、右端をクリックしたらSecondaryスクリーン」というわけ<b>ではない</b>。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/8180c47d-b4cb-e970-d23c-f8f8a14c047c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/efe8ec15-317f-edd1-f9f8-beec9f0f341a.png)

座標については、スクリーンをまたいで連続しているようである。

# 調査に使ったプログラムのコード

```cs

using System;
using System.Drawing;
using System.Windows.Forms;

class MultiScreenTest : Form
{
    Button btn;

    MultiScreenTest()
    {
        Text = "Multi Screen Test";
        ClientSize = new Size(500,400);

        btn = new Button();
        btn.Text = "Show X,Y";
        btn.Size = new Size(500,200);
        btn.MouseClick += Btn_MouseClick;
        Controls.Add(btn);
    }

    void Btn_MouseClick(object sender, MouseEventArgs e)
    {
        Point screenP = btn.PointToScreen(e.Location);

        Console.Write("Click: ");
        Console.Write(screenP.X);
        Console.Write(", ");
        Console.Write(screenP.Y);
        Screen screen = Screen.FromPoint(screenP);
        Console.Write("  Primary:");
        Console.WriteLine(screen.Primary);
    }
    
    [STAThread]
    static void Main(string[] args)
    {
        Application.Run(new MultiScreenTest());
    }
}
```


# プログラムの実行結果

```

Click: 457, 251  Primary:True
Click: 119, 122  Primary:True
Click: 114, 114  Primary:True
Click: 31, 49  Primary:True
Click: 1878, 387  Primary:False
Click: 1921, 390  Primary:False
Click: 1958, 391  Primary:False
Click: 1916, 410  Primary:False
Click: 1881, 413  Primary:False
Click: 1838, 401  Primary:False
Click: 1153, 283  Primary:True
Click: 1800, 378  Primary:False
Click: 1730, 382  Primary:False
Click: 1074, 237  Primary:True
Click: 1099, 242  Primary:True
Click: 1529, 341  Primary:True
Click: 2239, 274  Primary:False
Click: 2231, 322  Primary:False
```

# 参考サイト

1. [.NET TIPS  スクリーン座標←→クライアント座標の変換を行うには？](https://www.atmarkit.co.jp/fdotnet/dotnettips/377screentoclient/screentoclient.html)
2. [Screenクラス - Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.forms.screen?view=netframework-4.8)


# おまけ

2つ目のスクリーンのタスクバーのWindowClass名は`Shell_SecondaryTrayWnd`になるようである。

下記は https://qiita.com/kob58im/items/3587d8e595e655e9391d で作ったツールを使用して確認した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/1fe5c62c-1daa-0d2d-c5db-2f8e3b6caec6.png)