OmniAICreator/Qiita-1.07M huggingface dataset:
クロスプラットフォームの話を社内でLTした話

##はじめに

エンジニアの皆さん、おつかれさまです。
(。・ω・）ノ

年末に投稿した[クロスプラットフォームについての記事](https://qiita.com/zaki_zaki/items/7fcd0fffef29e751e6e8)をもとに、
社内LTをやらせていただきましたので、その際の話をします。

## スライド

Windows歴が長いので、いつも通りパワポにしようかなと思いましたが、
勉強の意味も込めて、Keynoteで作成しました。

デザインは[Azusa](http://sanographix.github.io/azusa-keynote/)といういい感じのテンプレートがありましたので、
そちらを元に作成しました。

スライドはQiitaにリンクさせたLinkedIn→SlideShareで公開しようと思いましたが、
.keyファイル、pptxファイルに変換してもアップロードに失敗してしまうため、
[speakerdeckの方](https://speakerdeck.com/zucky_zakizaki/kurosupuratutohuomukai-fa-huan-jing-falsesu-me)にアップロードしました。

~~後ほど、原因とか調べて、可能ならSlideShareの方に公開を試みます。~~

slideshareへのアップロードができました！
URLはこちらです。
#### [クロスプラットフォームのすヽめ](https://www.slideshare.net/ssuser5ee824/ss-92392075/ssuser5ee824/ss-92392075)

同じく現象が発生していた方が解決方法を見つけ、
ツイートしてくれてたので助かりました。。。
ほんと感謝です。。。

[ツイートはこちらです。](https://twitter.com/nakasho_dev/status/971386904737300480)

##感想

15分の尺をいただいていたのですが・・・内容を詰め込み過ぎてしまって、
Xamarinあたり（24スライド目）のところで15分過ぎてしまい、最後駆け足となってしまいました。

内容が単純に多いというのもありますが、質疑応答とかも踏まえると、
10分程度の内容に抑えるべきだったなと反省しました。

でも、LTをやらせていただいたことで、以下のことが収穫できました。
次回＆社外の勉強会のLTにむけて、改善していこうかと思います。

- 収穫できたこと
    - 知識の定着化
    - 発表に対しての尺の考え方
    - クロスプラットフォーム開発環境の種類　→　11個もあるとは知らなかった！


##その他

スライドに関して、間違いなどありましたら、コメントいただけると助かります！
GitHubメモ


公開鍵作成

`ssh-keygen -t rsa`


確認

`ls ~/.ssh/`

任意のフォルダ初期化

`git init`

変更ファイルをaddする`git add --all`

コミットする`git commit -m "first commit"`


リモート先を確認`git remote -v`

プッシュ`git push origin master:master`

-----------
github設定確認
---------------

///////////////
# GitHubへのSSH接続を確認する

`$ ssh github`


/////////////////////

# 設定を確認するには、-lオプション
`git config --list`
`git config -l --global`

# コミット時のAuthorを変更
`git config --global user.name ddddd`
`git config --global user.email assss@gmail.com`

# 出力を色付けしてくれる設定
`git config --global ui.color auto`

# あとは安全対策
`git config --global push.default current`



/////////////////////////////


# ブランチ作成
`git branch ブランチ名`

# ブランチ確認 
`git branch`

# ブランチ切り替え
`git checkout ブランチ名`

# 変更（ブランチ先にコミット）
`git status`
`git diff`
`git add .`
`git status`
`git commit -m "コメント"`

# リモートにPush
`git push origin ブランチ名`

# さっき作成したブランチをマージ先にマージ
`git merge ブランチ名`

# ログ確認
`git log`
世の中のビジネスモデルにいろんな会社を当てはめてみた。

# 本を読んでの感想とアウトプットの記事です。
自分がエンジニアリングやデザインを仕事にしているので、あえてQiitaに書いてみます。
ザ・プロフィットという本を読んだアウトプットとして記事にしてみました。本で世の中のビジネスモデルを23の分類に分けています。
それぞれのビジネスモデルが現実の会社のどのビジネスに当てはまるのか自分なりに考えてみたいと思います。本を読んでの記録ということもあり、折々で自分の中から出るつぶやきのようなものも書いています。
違うよ〜とか、なんでもお気軽にご意見をコメントしてもらえると嬉しいです。

# ザ・プロフィット
この記事を書く上で読んだ本です。エイドリアン・スライウォッキーさんが書いており、世の中のビジネスを23個のモデルに分類しています。
本はこちらから。https://goo.gl/NoUy3g


# 本で語られている世の中のビジネスモデル
- 顧客ソリューション利益モデル
- 製品ピラミッド利益モデル
- マルチコンポーネント利益モデル
- スイッチボード利益モデル
- 時間利益モデル
- ブロックバスター利益モデル
- 利益増殖モデル
- 起業家利益モデル
- スペシャリスト利益モデル
- インストール・ベース利益モデル
- デファクト・スタンダード利益モデル
- ブランド利益モデル
- 専門品利益モデル
- ローカル・リーダーシップ利益モデル
- 取引規模利益モデル
- 価値連鎖ポジション利益モデル
- 景気循環利益モデル
- 販売後利益モデル
- 新製品利益モデル
- 相対的市場シェア利益モデル
- 経験曲線利益モデル
- 低コスト・ビジネスデザイン利益モデル
- デジタル利益モデル


# 実際の会社とビジネスモデル

## 1. 顧客ソリューション利益モデル
### ビジネスモデルの説明
顧客が抱えている問題を解決するモデル。世の中のほぼ全てのビジネスがそうであるといえるかもしれませんが、ここでは顧客の問題を解決する事に特に集中しているビジネスモデルのこと。顧客の問題を顕在化させるために数人のスタッフが顧客のオフィスで一緒に働いたりします。
概念的には、
- 1.顧客の問題を解決するために、自社の商品にカスタマイズを行い、顧客に提供する。
- 2.顧客の問題を解決するために、ゼロから商品を組み上げ、顧客に提供する。
- 共通して、提供するまでの過程で顧客とのコミュニケーションを連続的に行う。

### つぶやき
1つ目を考える時から、なかなか難しいなと思いました。まずは、自分がそんなに世の中の会社の事を知らないこと。ネットで会社を調べても会社が行っているサービスには詳しく書かれていない企業も多いです。企業はパブリックにされている情報をベースに考えて、同時に概念的なものも書いて行くほうが良いと思いました。関係無いですが、自分の文章力のなさにもショックを受けたので、こちらはこちらで勉強して行くことにします。


### 該当する会社
IT業界はこのモデルに良く当てはまるのでは無いかと思いました。最初は全てのサービスがそうなのではと思ったいたのですが、分類する上で気にかけたのが、顧客の問題のヒアリングを先に行ってから商品提供するかどうかです。

次の企業が提供するサービスは、IT業界で顧客ソルーション利益モデルに当てはまるのではと思いました。


#### SAP, IBM, HITACHI, Fujitsu (や類似する体系を取るシステムベンダー)
導入前にはコンサルタントが顧客とコミュニケーションを行いカスタマイズされたサービスを提供するという事でリストアップしました。コンサルタントに試験を用意していたりします。その分ヒアリングに重きを置いているのかと。逆に、同じ会社のサービスだとしてもカスタマイズ無しで導入するサービスは顧客ソルーションモデルには当てはまらないと思います。

### 該当しない会社
多くのSaasサービスの場合、まずは無料で始めてみるというケースが多いです。この場合、顧客の問題のヒアリングをサービス提供側から行っていません。サービス導入後でもカスタマイズ性が高いSaasサービスも多くありますが、顧客が自分でカスタマイズしているとそれは当てはまらないと思います。　最近導入前にチャットで質問に答えてくれるサービスがありますが、そのサービス提供側が問題をヒアリングしてくれて事前にカスタマイズしてくれたサービスを提供してくれたらモデルに当てはまるでしょう。


### つぶやき2
前に、ガイアの夜明け的な番組で見たのですが。ある町工場は製品製造過程で必要になるプロトタイプの制作(一点もの)を高精度、短納期で実現するのだそうです。これもこのモデルに当てはまるのではと思ったのですが、なんかハッキリしないので、読み進めた上で判断する事にします。




・・・続く
pix2pixの出現で「DLで大量データが必要」は伝説になった～検証編～

前回、ちょっと言いすぎかな。。でも検証してみても、やはり１データで学習してしまう。。。

いやいや、言い方がちょっと違うかもしれません。
汎用性は全くない。。Trainデータをしっかり覚えてくれます。
つまり、普通の意味で言うと、完全に過学習！

いくつか改変したコードを以下に置きました
[MuAuan/pix2pix](https://github.com/MuAuan/pix2pix)

#pix2pixの原理
pix2pixは、普通のGANと異なり、二つの画像の関連性の真偽から学習して、習得した関連に関しては再現よく表現するというものです。したがって、利用は２つの画像ペア（画像に表せれば何でもOKだし、二つである必要も無いらしい）間の変換や途中の補完などに利用するものであるようです。

pix2pixは原理として以下の工夫をしています。
（１）pix2pixは、cGANである
条件付きという意味は、今回はもともとの画像と加工先の画像等が必要で、どっちがどっちでもいいですが、この二つの画像ペアの一致度をDiscriminatorが判断しつつ学習します。
（２）Generatorにu-netを使っている
u-netは、encoder-decoderにおいて、対象的な構造としており、対応する（相似な）中間層のパラメーターをencoderから直接decoderに渡す構造を採用しています。
※一応、普通のencoder-decoderでもよさそうですが、論文中ではよい結果は得られていないようです
（３）patchGANを利用して、L1相関を強化
論文見るとL1相関強くして、全体的な変化を均一化してDiscriminatorを欺く戦略とのこと。確かに効果が表れている根拠図が示されています。

因みに、Generatorは、例えばGray画像や輪郭画像のみで目的の図を出力しています。
#とにかく１dataChallengeを継続
今回、やってみたこと
###準備として
TestとTrainのコンタミが怖いのと、どの画像がTestに採用されているのかがわかりにくいので、完全に分離して読み込むように改めました。
###①１Train１Testで収束するのか
やってみました。
Trainはほんとに1個でも１０分もかからず収束する。
けど、TestはCannyとGrayで試しましたが、どちらもいい結果は出ません。
###②９０％Train１０％TestでTestはきれいな絵になるのか
###③Grayの場合、顔でtrainして、ファッション絵に適用
汎用性の検証としてやってみました。
###おまけ～出力専用AP作成
モデルの構造を見る意味でも、検証用に利用する意味でも、学習済のパラメータで出力専用アプリを作成しました。
※入力対応はhdf5ファイルです

#結果
###①各カテゴリ１Train１Testの結果
データは同じデータの右向きと左向きをTrainとTestに使っています。
Trainデータ
![current_batch_training1000.png](https://qiita-image-store.s3.amazonaws.com/0/233744/3fae931f-b1f7-efe9-44a0-dbcc7fae71f1.png)
Testデータ
（ひどいので掲載しません）
Grayの場合
Testデータは綺麗に塗れました
![current_batch_validation200.png](https://qiita-image-store.s3.amazonaws.com/0/233744/ba46abeb-bec3-ab48-d98c-61eb9cd1d9ad.png)

###②９０％Train１０％TestでTestはきれいな絵になるのか
これも、Cannyは汚れてしまって、何がなんだか
![current_batch_validation390.png](https://qiita-image-store.s3.amazonaws.com/0/233744/e87448eb-0f32-0112-9cb5-2ad66ad562a7.png)
Grayは一応、見られる程度の色を塗ってくれますが、以下の通りです
![current_batch_validation170.png](https://qiita-image-store.s3.amazonaws.com/0/233744/ab463909-1313-04b6-de48-d1c72c458a3c.png)
でも、色合いとか完成度低い。。ということで不満足

この結果は、かなり危険です。汎用的な変換器を作ろうという目論見だと、破綻する兆候です。
###③Grayの場合、顔でtrainして、ファッション絵に適用
これは、それなり。。。塗れてます
Testデータ
![current_batch_validation160.png](https://qiita-image-store.s3.amazonaws.com/0/233744/a29fd631-41d0-61aa-f13c-b1b629bbda09.png)
まあ、植物も背景も学習していなから、塗れないのは当然ですが、ファッションのデータで学習しても上のレベルなので、ほぼ似たような感じです。

もちろん、どれもTrainデータの再現性はほぼ完ぺきです。

#まとめ
・１データでも簡単に学習する
・過学習である
#課題
・Generatorの過学習を回避するにはどうすればいいか
・過学習であることを利用すること
Pandas データフレーム検索 isin メソッド

データフレームの列に値が含まれているかどうかをチェックする方法を毎度忘れる。
isin メソッドがシンプルで使いやすいと思うが、日本語の記事はなかなか検索でヒットしないため、メモ。

１、df[X].isin([Y])
isin内の値を単独のスカラー量Yのようにするとエラーとなる。
このメソッドは引数にList like objectしか受け付けないとのこと。
スカラー量Yを[Y]としてリストにすると実行される。

２、df[X].isin([Y]).any()
any()をつけるとその列全体で存在するかどうかをBool型で返してくれる。便利。


参考リンク
https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.isin.html
JavaScript undefined値の判定

#javaSciprt　undefined値の判定

javaScriptでは初期化していない変数にはundefinedがセットされている
※undefinedはプリミティブ値を示す

```html:javascirpt
var tmp;
console.log(tmp); //->undefined
```


###当然文字列ではないので文字判定ではNG

```html:javascirpt
var tmp;
if( tmp == "undefined"){
    console.log("true");
}else{
    console.log("false");
}
//->false
```

###typeof 演算子を利用する

```html:javascirpt
var tmp;
if( typeof tmp === 'undefined'){
    console.log("true");
}else{
    console.log("false");
}
//->true
```
[MDN参考](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/typeof)






###厳格な等価評価

```html:javascirpt
var tmp;
if( tmp === undefined){
    console.log("true");
}else{
    console.log("false");
}
//->true
```

undefined と厳格を行う事で評価することが出来るが、この方法は推奨されていない
[MDN参考](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/undefined)





###void 0と比較

```html:javascirpt
var tmp;
if( tmp === void 0){
    console.log("true");
}else{
    console.log("false");
}
//->true
```
voidはあらゆる値に作用し、常にundefinedを返す演算子でそれを利用する
[MDN参考](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/void)
【cpuminer】最適化メモ

内容的には古いが、下書きのまま放置するのもアレなので公開

ビルド環境的にはあとはClang/LLVMかIntelCompilerにするくらいしか無さそうなので。
https://software.intel.com/en-us/qualify-for-free-software/opensourcecontributor
申し込んでみたけど、反応が無い。
主な処理のSIMD化とかやっているのでコンパイラを変えても性能向上の幅はどれほどあるのか。
それよりは分岐予測ミスの原因になりそうなところに手を入れたり、ミスキャッシュしないようにするべきかと。
⇒iccは遅い。最適化コードは非Intel CPUだと動かないようなのでそのせいかも
⇒aocc(AMD Optimized C/C++ Compiler)を試したが、WSL上では好成績だったが、Windows用のクロスコンパイルでは振るわず。

##参考文献
http://jp.xlsoft.com/documents/intel/seminar/2_Sofrware%20Optimize.pdf
https://ja.wikipedia.org/wiki/Zen_(%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3)
＞ L1キャッシュは1コアごとに命令用に64KiB、データ用に32KiB、L2キャッシュは512KiB、L3キャッシュはコアあたり2MiB
https://en.wikichip.org/wiki/amd/microarchitectures/zen
https://password-hashing.net/submissions/specs/yescrypt-v2.pdf

##PREFETCH
AArch64でプリフェッチを実装して高速化する記事を読んだので。
SSE2の_mm_prefetchを効率化する。
prefetchのデータサイズは64Bなので__mm_prefetch()とサイズは合っている。
しかし、アクセスするアドレスが連続アクセスではなく、ランダムアクセスになっている。
→使う順にPREFECHしている。
→１回のPREFETCHは１～２KiB
→データ格納に2MiB、一時的な計算領域に1+2KiB
　→計算に必要なメモリは全てキャッシュに収まっている。
　→L3を使わず、できるだけL1,L2を使うようにする。
https://stackoverflow.com/questions/7327994/prefetching-examples
SIMD部分以外もPREFETCH出来る。
__builtin_prefetch
-fprefetch-loop-arrays
-fstrength-reduce *-O2
-frerun-cse-after-loop  *-O2
⇒下手にPrefetchを行うと、CPUのハードウェアプリフェッチを阻害して遅くなる結果に。
JavaScript 文字列の中に特定の文字列が含まれるかの判定

#特定の文字列の中に文字列が存在するかの判定

##indexOfを利用

指定した値が初めて出現したインデックス。見つからなかった場合は、-1を返却することを利用

```javaScript
tmpString = "ABCDEFG";

if( tmpString.indexOf('BCD') != -1 ){
   console.log("存在する");
}else{
   console.log("存在しない");
}

//->存在する
```

※indexOf()は最初に見つかったインデックス値を返却
※tmpString.indexOf(searchValue[, fromIndex])　第２引数で検索開始位置を指定可能
※indexOf()は大文字小文字を区別
golang　文字列→数値、数値→文字列変換



```golang:import
import("strconv")
```
#文字列→数値変換

```golang:型変換
var i int
var s string="123"
i, _ = strconv.Atoi(s)
fmt.Println(i) // -> 123

```

#数値→文字列変換
```golang:型変換
var i int=321
var s string
s = strconv.Itoa(i)
fmt.Println(s) // -> "321"

```
golang　配列を特定の文字で連結し１つの文字列にする

#PHPでimplodeのようなことが出来ないか？
```php:implode
$arr[0] = "A"; 
$arr[1] = "B";
$arr[2] = "C";

echo( implode(",", $arr) ); // -> A,B,C
```

↓↓↓

```golang:Join
import "strings"

strings.Join(arr, ",")

fmt.Println(arr) // -> A,B,C

```
VC++デバッガーで、ライブラリコードにステップインすることなくデバッグする

Visual C++ Team Blogにてstd::functionのデバッグを改善したとの記事が上がりました。
F11でステップインする時にstlの内部実装に入る事無くデバッグしたい箇所にステップイン出来ています（ライセンスとか知らないので記事参照
Visual Studioバージョン15.5から使えるようです

[Improving the debugging experience for std::function](https://blogs.msdn.microsoft.com/vcblog/2017/11/16/improving-the-debugging-experience-for-stdfunction/)  

下記のユーザーの声を反映したとの事
[Make StepInto a std::function go directly to the implementation without stepping into std library code.](https://visualstudio.uservoice.com/forums/121579/suggestions/4078610)  


# 自分のライブラリで試してみる

本題です。
自作ライブラリでもこんな便利機能使いたい！って事でstd::functionの実装を見て見ました。
見てみると飛ばしたい箇所と止めたい箇所にマクロを入れているのが分かります
自分のライブラリでも試してみます

※ Visual Studioバージョン15.5.6での実装です。公式ドキュメントも無いので今後使えなくなる可能性はあります

# 実装

```cpp:ステップイン機能未実装
namespace test
{
	class function
	{
		using func_type = void(*)();
		func_type _pred;
	public:
		function(func_type _f) noexcept
			: _pred(_f)
		{}

		void operator() () const noexcept
		{
			_pred();
		}
	};
}
```

![function1.gif](https://qiita-image-store.s3.amazonaws.com/0/66029/9be07175-a329-c877-f9d8-87bd91705f58.gif)


```cpp:ステップイン機能実装後
namespace test
{
	class function
	{
		using func_type = void(*)();
		func_type _pred;
	public:
		function(func_type _f) noexcept
			: _pred(_f)
		{}
		void operator() () const noexcept
// 飛ばしたい箇所
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
		{
// 内部実装を見たい
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_INTO
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
			_pred();
// 飛ばしたい箇所
#ifndef _DEBUG_FUNCTIONAL_MACHINERY
#line _DEBUGGER_STEP_OVER
#endif /* _DEBUG_FUNCTIONAL_MACHINERY */
		}
	};
}
```

![function2.gif](https://qiita-image-store.s3.amazonaws.com/0/66029/308d5e85-38e2-c384-b91d-37b6f48c1933.gif)
[WKWebView][RxSwift] 規約ページの一番下にスクロールした時にネイティブ側の同意ボタンを有効にする

## 概要

　webで公開されている規約ページをWKWebViewで読み込み、ページの一番下までスクロールされたことをアプリでキャッチして同意ボタンを有効にします。
（特に受諾開発の案件でよくあるのかなーと思います）

　この仕様を振られてちょっと困ったのですが、WkWebViewのプロパティでUIScrollViewが公開されているので`didEndDecelerating()`でスクロール位置を判定できるのでした。
https://developer.apple.com/documentation/webkit/wkwebview/1614784-scrollview

　更に、読み込み途中のページでスクロール位置を判定されてはいけないので、`estimatedProgress`をKVOで監視してロードの判定も行います（無理矢理感あります。他に何かいい方法がありそうです）。

　「ロード完了」かつ「スクロール位置が底」ならば同意ボタンを有効・そうでなければ無効とします。

## 実装

```Swift

import UIKit
import RxSwift
import WebKit

class ViewController: UIViewController {

    
    @IBOutlet weak var webView: WKWebView!
    @IBOutlet weak var agreeButton: UIButton!
    
    let agreementUrl = URL(string: "https://qiita.com/terms")
    
    let disposeBag = DisposeBag()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        agreeButton.isEnabled = false
        bindScrollAgreement()
        
        let urlRequest = URLRequest(url: self.agreementUrl!)
        self.webView.load(urlRequest)
    }
    
    private func bindScrollAgreement() {
        
        let margin: CGFloat = 5 // 底かどうかのマージン
        
        Observable.combineLatest(self.webView.rx.isLoadCompleted,
                                 self.webView.scrollView.rx.didEndDecelerating) {(isLoadCompleted, _) -> Bool in
                                    
                                    let bottomEdge = self.webView.scrollView.contentOffset.y
                                                        + self.webView.scrollView.frame.size.height
                                                        + margin
                                    
                                    let position = bottomEdge - self.webView.scrollView.contentSize.height
                                    let isBottom = position > 0
                                    
                                    return isLoadCompleted && isBottom
            }
            .bind(to: self.agreeButton.rx.isEnabled)
            .disposed(by: disposeBag)
    }
}

extension Reactive where Base: WKWebView {
    
    /// ロード完了かどうか
    public var isLoadCompleted: Observable<Bool> {
        return self.observe(Double.self, "estimatedProgress")
            .throttle(0.1, scheduler: MainScheduler.instance)
            .map { $0 == 1.0 }
    }
}

```

## 動画

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">WKWebViewで規約ページの一番下に達したかどうかを判定（動画のページはqiita） <a href="https://t.co/0tHKtx4PG7">pic.twitter.com/0tHKtx4PG7</a></p>&mdash; takkei (@takkei9) <a href="https://twitter.com/takkei9/status/965275311536455680?ref_src=twsrc%5Etfw">2018年2月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 補足

1回一番下まで行ったら後でまた上にスクロールしてもずっと有効したい場合、以下のようにオペレータを追加しましょう。

```Swift
    .filter { $0 }
    .take(1)
    .bind(to: self.agreeButton.rx.isEnabled)
```
[iOS]フェードするポップアップビューを作成する！

##つくったもの

![ポップアップ動作.mov.gif](https://qiita-image-store.s3.amazonaws.com/0/138735/bfd73d78-82e9-2c9e-b632-0e55361597b5.gif)

・swift4使用

##コード

```PopupView.swift

import Foundation
import UIKit

public class PopupView {
    
    private var popupView: UIView!
    static let sharedManager = PopupView()
    
    private func setup() {
        popupView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
        popupView.backgroundColor = UIColor.gray
        popupView.alpha = 0.8
        popupView.layer.cornerRadius = 8
        
        // ポップアップ内のコンテンツを設定
        let labelWidth: CGFloat = 100
        let labelHeight: CGFloat = 100
        let labelItem = UILabel(frame: CGRect(x: popupView.frame.width/2.0 - labelWidth/2, y: popupView.frame.height/2.0 - labelHeight/2, width: labelWidth, height: labelHeight))
        labelItem.text = "✅"
        labelItem.font = UIFont(name:"Helvetica", size: 70.0)
        labelItem.textAlignment = NSTextAlignment.center
        popupView.addSubview(labelItem)
    }
    
    public func show() {
        if popupView == nil {
            self.setup()
        }
        
        if let window = UIApplication.shared.delegate?.window {
            window!.addSubview(popupView)
            popupView.center = window!.center
        }
    }
    
    public func hide() {
        UIView.animate(withDuration: 1, delay: 1, options: .curveEaseIn, animations: {
            self.popupView.alpha = 0
        }) { _ in
            self.popupView.removeFromSuperview()
            self.popupView.alpha = 1
        }
    }
}

```

##使い方

表示したいタイミングで

```
PopupView.sharedManager.show()
```
隠すタイミングで

```
PopupView.sharedManager.hide()
```

以上😆！！
AutoLayout + SnapKit でアスペクト比固定のViewを作る

最近、iOS の View は InterfaceBuilder を利用せずにコードで生成しています。
その際に SnapKit という OSS を利用しているのですが、 アスペクト比固定の View の生成方法にちょっと悩んだので、Tipsとして残しておきます。

## InterfaceBuilderの場合

Add New Constraints から Aspect Ratio にチェックを入れればOKですよね。

![スクリーンショット 2018-02-19 1.13.45.png](https://qiita-image-store.s3.amazonaws.com/0/46792/424960db-2352-d580-83a9-57821e9f3a28.png)

## SnapKitの場合

```Swift:横幅基準でアスペクト比固定する
aView.snp.makeConstraints { make in
    let width = 100
    let ratio = 0.5
    make.width.equalTo(width)
    make.height.equalTo(aView.snp.width).multipliedBy(ratio)
}
```

とまぁ、こんな感じに View の固定する方（今回は横幅）は普段通り設定し、依存する方（今回は縦幅）へ equalTo で固定する方と同じであると宣言した後に、multipliedByでその比率を入れることで実現可能でした。


## ImageViewを画像にFitさせる

この考えを用いることで、画像の比率を保ったまま ImageView を AutoLayout　で画像のアスペクト比を保ったままいい感じに設定することができます。

```Swift:ImageViewを画像にFitさせる
imageView.snp.makeConstraints { make in
    let ratio: CGFloat = {
        let size = imageView.image!.size
        return size.height / size.width
    }()
    make.width.equalToSuperview().multipliedBy(0.8)
    make.height.equalTo(imageView.snp.width).multipliedBy(ratio)
}
```

これでImageViewの横幅を親Viewの0.8倍した横幅に設定し、画像のアスペクト比にImageViewをFitさせることができました。
GitHubのissueを移行したい・API操作したい

実現するCLI兼Node.jsクライアントライブラリを作りました(PR/projectsの操作も実装中)
https://www.npmjs.com/package/issue-ctl

# 使い方

https://github.com/darai0512/issue-ctl をご覧ください

## CLI

```
$issue-ctl migrate
posted old issue#1 to new issue#4
posted old issue#2 to new issue#5
posted old issue#3 to new issue#6
```

## in Node.js

slackやjiraなどとbot経由で連携するのに便利かと

```javascript

const {issue} = require('issue-ctl');

const main = async () => {
  const issues = await issue.get('api.github.com', 'org/repo', 'username:passwd');
  // ex, issues.title = prefix + issues.title + postfix;
  await issue.post('your.enterprise.url', 'org/repo', 'oauth2token', issues);
};

// 申し訳ありませんがUnhandledPromiseRejectionWarningが発生します（後述）
// 現在リファクタリング中ですが、エラーハンドリングされたい方は下記を記述ください
process.on('unhandledRejection', (reason, pos) => {
  console.log('at:', pos, 'reason:', reason);
});

main().catch((err) => console.error(err));
```

# できること

- 特定のリポジトリからissue(PRを除く)を全て取得する
  - 紐付くコメント、ラベル、マイルストーン、アサイン者情報も取得
- 特定のリポジトリへissueを全てPOSTする
  - 紐付くコメント（順番保持）、ラベル、マイルストーン、アサイン者情報も登録
  - closeしたissueなら登録後closeされる
  - 新規POSTのため、移行前後でissue番号は異なる

# やりたかったこと

- GitHub Enterprise(v2.11)からGitHubへ、コードの公開にあたりissueを移行したい
- その際、一般に公開できない部分のコードはラップするため、直書きされていた過去のcommit情報は移行させたくない
- 移行先は既に運用中で、新しいissueなどが作られ続けている
- リポジトリのマイグレーションはGitHubにAPIで用意されているが、commit履歴も移行されてしまうし、移行先が初期化されるので使えない
- 移行時に、従来のissueを指定フォーマット（スクラムのユーザーストーリー）に置換したい
  - ex, `FEチームとして、${old_title}したい。なぜなら、業務効率化に繋がるから。`
  - Get時にファイルにJSONで落とすので、必要に応じて置換し、Postできるよう実装

## 調査

- https://gist.github.com/agarny/5541773
  - コピー先のラベルとマイルストーンは全削除されるため、運用中のリポジトリには使用できない
- https://qiita.com/koic/items/800bbc03281558ab93db
  - 公式のマイグレーションだと、移行先のデータが全て消え、commit履歴も残ってしまう
- https://www.npmjs.com/package/gh-issues-cli
  - 認証しないとAPI叩ける回数に制限食らうよ、というのは大事な気づき
- https://github.com/github/hub
  - おそらくやりたい機能はないはず

# Tips
## 内部実装

- Node.jsのcore APIのみで実装。ブラウザJSでは動作しません。
- getではリポジトリ内のissueとcommentを100件ずつpagingしながら全件取得します。commentの取得はissue単位ではなくリポジトリ単位で、後から紐付けています。API実行回数は最小のはずですが、利用回数制限がかかっている場合は注意ください。
- postは１秒ごとに1 issueずつ
  - 紐付くコメント・closedの場合はその操作も含めて

## Promise のエラーハンドリング漏れ

上述の通り、一部async/awaitでcatch漏れがあり、下記エラーが発生することがあります。

```
(node:111) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: ***
(node:111) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
```

このエラーログだけではコードのどの部分でハンドリングが漏れているのかわかりません。
発生箇所特定のためには、上述のように`unhandledRejection`イベントを登録ください。
これでPromiseの包括的なエラーハンドリングが可能ですが、公式ではこれに頼ってエラーハンドリングを放棄することは推奨していません。
（理由は内部実装を見てみるとわかります、機会があれば記事化します）

これでいつも通りのスタックトレースが見れるので、原因のPromiseでcatch処理を入れれば特定可能です。よければPRお待ちしております。
dockerのmysqlでUTF8が文字化けしたらやること

# はじめに

dockerでローカル開発環境を作る時、大概お世話になるのがmysqlイメージですよね〜
``/docker-entrypoint-initdb.d``に初期化のsqlを入れたフォルダをマウントするとdocker起動時に実行してくれるのでほんと便利ですね！
だけど、えー・・文字化けしてるやん！ってことで悩んでるかたはこちらを試してみてください。

# やること
dockerを起動する時のコマンドに``character-set``と``collation-server``を指定しときましょう

```yaml:docker-compose.yml
version: '3'
services:
  mysql:
    image: mysql
    command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
    volumes:
      - ./docker/mysql:/docker-entrypoint-initdb.d
    ...
```

起動時に実行されるsqlでは、先頭で``CHARACTER_SET_CLIENT``と``CHARACTER_SET_CONNECTION``をしときましょう。

```sql:./docker/mysql/create.sql
SET CHARSET UTF8;
CREATE DATABASE IF NOT EXISTS sample_database DEFAULT CHARACTER SET utf8;

USE sample_database;
CREATE TABLE IF NOT EXISTS sample_table(
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(255),
  updated_at TIMESTAMP
);

```

```sql:./docker/mysql/insert.sql
USE sample_database;

SET CHARACTER_SET_CLIENT = utf8;
SET CHARACTER_SET_CONNECTION = utf8;

INSERT INTO sample_table 
  (name) 
VALUES 
  ('テスト１'),
  ('テスト２');
```
これで大丈夫なはず！？
nimのunittestを使ってテストコードを書く

# 概要

* nimbleで作成したパッケージのテストコードを書く
* nimは標準で[unittest](https://nim-lang.org/docs/unittest.html)モジュールがあるのでそれを使用する

# 環境

* nim 0.17.2
* nimble 0.8.8

## nimbleプロジェクトを作成

* プロジェクトを作成してインポートできるようにしておく、手順は[ここ](https://qiita.com/honeytrap15/items/9daa648efe373fbcb1fe#自作のパッケージを作成する)
* 作ったのはこんな感じ

```
% tree
.
├── example.nim
└── example.nimble
```

```example.nimble
# Package

version       = "0.1.0"
author        = "honeytrap15"
description   = "example nimble package"
license       = "MIT"

# Dependencies

requires "nim >= 0.17.2"
```

```example.nim
proc sum(a: int; b: int): int = 
  result = a + b


export sum
```

## テストコードを書く

* `tests`ディレクトリを作成する
* `tests`以下にテストコードを配置
* `nimble test`を実行

```tests/tester.nim
import example
import unittest


test "test case 1":
  let r = sum(1, 2)
  check(r == 1 + 2)

test "test case 2":
  let r = sum(-1, 2)
  check(r == 2)
```

```zsh
% tree
.
├── example.nim
├── example.nimble
└── tests
    └── tester.nim
```

```zsh
% nimble test
...
[OK] test case 1
tester.nim(11, 10): Check failed: r == 2
r was 1
[FAILED] test case 2
...
```

* こんな感じで実行される
ontouchxxxxxは存在しない

`ontouchstart, ontouchmove, ontouchend`は存在しない。

```js
console.log(onmousedown); // => null
console.log(ontouchstart); // => Uncaught Error: 'ontouchstart' is not defined
```

当然、代入してもタッチイベントは取れない。

```js
// マウスで左クリックする時のイベント
addEventListener('mousedown', function() { console.log('new mouse'); });

// 古いやり方（非推奨だが、可能）
onmousedown = function() { console.log('old mouse'); };


// スマホなどでタップする時のイベント
addEventListener('touchstart', function() { console.log('new touch'); });

// 古いやり方も可能かと思いきや、不　可　能
ontouchstart = function() { console.log('old touch'); };
```

ちなみにこの例では一貫してグローバルオブジェクト(window)だったが、
documentでも個別のHTML要素でも同様に無効である。

たとえ書き捨て目的でもサボらずaddEventListenerを使おう。
Azure MLメモ

###Accuracy（正解率）
100%に近いほどよい

###TPR:True Positive Rate（真陽性率）
100%に近いほどよい

###FPR:False Positive Rate（偽陽性率）
0%に近いほどよい

###Precision（適合率）
100%に近いほどよい

###Recall（再現率）
100%に近いほどよい
	
###F1 score, F-score（F値）
1.0に近いほどよい
	
###AUC
1.0に近いほどよい

###ROC曲線
左上に張り付くほど良い

#活性化関数
##代表的なもの
###ReLU関数（ランプ関数） rlinear
###シグモイド関数 sigmoid
###ハイパボリック・タンジェント tanh
##その他
###絶対値 abs
【Unity】Unityがクラッシュした時にザオリクで復旧する

◆要点
・Unity初心者向け
・Unityがクラッシュや永久ループで強制終了した時の復旧方法
・編集中のデータを失わず復旧できます（まさにザオリク！）

◆手順
①強制終了後、エディタのトップ画面を開きます
**この時、いつもの癖でプロジェクトを選択して開かないこと！！**
<img width="1112" alt="スクリーンショット 2018-02-19 00.07.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/237014/e24b6f20-8033-51a5-09ab-bbcb7f0e65e3.png">

②右上の「OPEN」をクリック

③Unityプロジェクトのフォルダを開いて
Temp>__Buckupscenes を選択してOPEN
<img width="642" alt="スクリーンショット 2018-02-19 00.08.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/237014/3fc74eec-9b7e-dee2-d4bf-d19dcf40b98a.png">

④ザオリクして復活します

◆捕捉
ちなみに手順①でいつもの癖でプロジェクトを選択して開いてしまうとTempフォルダは消えてなくなります。すると復旧が不可能になるのでご注意ください。


参考になった方という方はいいねお願いします。
Ubuntu 16.04 で MinGW を使い C++11 プログラムの Windows バイナリをクロスコンパイルする

漢なら Ubuntu で C++11 プログラムをクロスコンパイルし, Windows バイナリを作りたいですね!

やりましょう!

## 目的

* Unix 系と Windows で動く C++11 プログラムを作りたい.
* Windows を起動せずとも windows バイナリをビルドしたい.
* Wine で動かし Linux 上で動作確認したい(継続ビルド&テストとかで Windows インスタンス立てるのめんどい).

## MinGW のインストール

64bit 版を仮定します.

https://kakurasan.blogspot.jp/2015/07/debianubuntu-mingw-crosscompile.html

を参考に apt でインストールできます. Ubuntu 16.04 ではバージョン 5.3 が最新でした.

## C++11 スレッド実装

MinGW で C++11 プログラムをコンパイルするときは, `std::thread` 周りに注意が必要です.

STL(runtime?)実装まわりの関係で C++11 スレッド周りの実装は posix 実装と win32 実装の二種類があります.
(MinGW コンパイラのサフィックスで `-posix`, `-win32` があります)

win32 実装が理想な気がしますが, 現状の C++11 プログラムを改変せずそのまま使いたい場合(サードパーティ OSS ライブラリを使うなど)は `-posix` でコンパイルする必要があります. 

`-win32`(デフォルト) だと `mutex` が定義されていないなどとコンパイルエラーが出ます.

ソースコードを修正することができる場合, 以下の `mingw-std-threads` を使うことで, `win32` ネイティブスレッドが使えると思われます.

https://github.com/meganz/mingw-std-threads
 
MinGW ですと `__MINGW32__`, `__MINGW64__` マクロが定義されますので, これで判別して C++11 ヘッダを読むのか, mingw std threads ヘッダを読むのかの切り分けをするとよさそうです.

## CMake

toolchain ファイルを作ると便利です.

https://cmake.org/Wiki/CMake_Cross_Compiling

```
SET(CMAKE_SYSTEM_NAME Windows)

SET(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc-posix)
SET(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++-posix)
SET(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)

SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)

SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
```

Win7 以降で導入された Win32 API を使うときなどは, `_WIN32_WINNT` バージョンを指定する必要があります.

```
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WIN32_WINNT=0x601")
```

のようにして `CMAKE_CXX_FLAGS` に追加しておきましょう.

あとは, cmake bootstrap 時, 以下のように `CMAKE_TOOLCHAIN_FILE` でファイルを指定します.

```
$ cmake -DCMAKE_TOOLCHAIN_FILE=mingw-cross.cmake ...
```

## TODO

* 静的リンクを試す.
* [ ] clang で cross-compile を極める.(より msvc に近いバイナリ生成とか)
  * [ ] llvm-mingw(clang)
クラウドIDE 3選 Cloud9 v.s Codeanywhere v.s PaizaCloud Cloud IDE

# クラウドIDE比較
現在の主要３クラウドIDEを紹介します。オススメは日本語対応で使いやすい[PaizaCloud Cloud IDE](https://paiza.cloud/ja/)。

# [AWS Cloud9](https://aws.amazon.com/jp/cloud9/)おすすめ度★★
もともと単独のクラウドIDEでしたが、AWSが買収後、AWSのサービスの一部となりました。
AWSアカウントがそのまま使えます。また、AWSのインスタンスを利用して動作します。
AWS統合後は、定額課金から従量になるなど、かなり使い勝手が変わっています。

# [Codeanywhere](https://codeanywhere.com/)おすすめ度★
対応フレームワークがいろいろ選べるクラウドIDEです。設定が少し難しいですが、設定できる項目は多いです。

# [PaizaCloud Cloud IDE](https://paiza.cloud/ja/) おすすめ度★★★
最近リリースされたクラウドIDEです。3秒で起動してウェブ開発が行えます。日本語対応で使いやすく、おすすめです。
環境設定不要なので、すぐに開発ができます。
ウェブ開発等に対応しており、その場でサービスを公開することもできます。Ruby on Rails, Node.js, Django, LAMP(PHP), Laravel
などの主要フレームワークにはほぼ全て対応しており、自分でパッケージを追加インストールすることもできます。
Vagrant : バージョンを指定してboxを削除

`vagrant box update`などをすると、バージョンだけが異なる同じboxが同時に存在することになる。

```
$ vagrant box list
bento/centos-7.4 (virtualbox, 201801.02.0)
bento/centos-7.4 (virtualbox, 201802.02.0)
```

上の例ではv201801.02.0が古いバージョンになるので、これを削除したいときには次のコマンドでできる。

```
$ vagrant box remove bento/centos-7.4 --box-version 201710.25.0
```

さらにプロバイダも指定したい場合は

```
$ vagrant box remove bento/centos-7.4 --box-version 201710.25.0 --provider virtualbox
```

のようにオプションを追加する。
データベース管理システム(DBMS)のアーキテクチャの解説

この記事はミック[著][SQL実践入門](https://www.amazon.co.jp/SQL%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80%E2%94%80%E2%94%80%E9%AB%98%E9%80%9F%E3%81%A7%E3%82%8F%E3%81%8B%E3%82%8A%E3%82%84%E3%81%99%E3%81%84%E3%82%AF%E3%82%A8%E3%83%AA%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-WEB-DB-PRESS-plus/dp/4774173010/ref=cm_cr_arp_d_product_top?ie=UTF8)の第一章を要約した記事になります。
#記憶装置（ストレージ）の階層分類
記憶装置はシステムがデータを保存するための装置ですが、記憶装置は装置の値段あるいはアクセスの速さによって３つに分けることができます。
例えば、メモリは他の記憶装置に比べてかなり高価ですが、HDDはメモリより断然安い上にかなりの容量があります。
価格ドットコムを見てみると、[CT2K8G4DFS824A](http://kakaku.com/item/K0000995492/) というメモリ(一枚当たり8GB)は2枚セットで18,999円するのにたいして、[WD40EZRZ-RT2](http://kakaku.com/item/K0000927098/)というＨＤＤは4TBで9389円です。
価格と容量だけみるとＨＤＤの方が良さそうにみえますが、その分アクセスのスピードは遅くなってしまいます。
逆にメモリは高価な分、アクセスのスピードはＨＤＤに比べて断然速いです。
従って、**容量や価格、保管性を取れば速度が犠牲になる**と押さえておけば大丈夫です。
またデータベースではデータを保存する媒体として**HDD**が圧倒的に使われています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/224195/a3b84d52-4d57-c6b8-9ba2-10c9f4916800.png)

---
#賢くメモリを使い、アクセス速度を向上させる
メモリはとても高価なため、HDDに比べて収容できる容量が限られます。
データベースシステムでは**よくアクセスされるデータをうまくメモリ上に保持しておく**ことで、保持されたデータはメモリのアクセスだけで処理を返すことができるので、**圧倒的にアクセスが速い**です。
このようなアクセス速度の向上のために、データを保持するメモリを**バッファ**あるいは**キャッシュ**と呼びます。
また、データをどのくらいの期間載せておくかということを管理する機能を、**バッファマネージャ**といいます。
#データキャッシュとログバッファ
データベースシステムが使用するメモリは大きく分けて、**データキャッシュ**と**ログバッファ**の2種類あります。
**データキャッシュ**はＨＤＤ上にあるデータの一部を保管する領域になります。
そして、頻繁にアクセスされるデータが保管されます。
**ログバッファ**はデータベースを更新(INSERT、DELETE等)した時にバッファ上に更新情報が保管される場所になります。
なぜ直接ＨＤＤに更新の書き込みを行わないのかというと、ＨＤＤへの更新の書き込みはとても時間がかかるので結果的に、ユーザーを長時間待たせてしまいます。
したがってデータベースでは利便性向上のため、**ＨＤＤに更新の書き込みが行われていないにも関わらず、ログバッファ上に書き込みが行われた時点でユーザに更新完了を知らせる仕組み**をとっています。
また、メモリは**揮発性**をもっており、つまるところ**電源を落とした瞬間メモリ上のデータは全て消える**ので、データベースシステムでは必ずコミットのタイミングで更新情報をログファイルに書き込んでいます。
###データキャッシュとログバッファのサイズ
データキャッシュとログバッファのデフォルトサイズを比較してみると、ＭＹＳＱＬではデータキャッシュの初期値が128Mバイトに対して、ログバッファの初期値は8Mバイトしかありません。
その理由は**データベースは基本的に検索処理がよく使われるだろうと想定されている**からです。
データキャッシュは頻繁にアクセスされるデータの一部を保管することでスピードを速めるためのメモリ領域でした。
ただし、更新を頻繁に大量に行うデータベース([バッチ処理](http://www.oracle.com/technetwork/jp/database/articles/tsushima/tsm15-1598273-ja.html)等)に関してはこの限りではありません。そのときはログバッファに多くのメモリを割り当てる場合もあります。
#クエリ評価エンジン
DBMSにおいて、クエリ評価エンジンはユーザーから受け取ったクエリを最初に受け取る部分であり、4つのモジュール(部品)から構成されています。
##①パーサー
パーサー(Parser)とは構文解析という意味です。パーサーの役割は**受け取ったクエリが正しいかどうか確認すること**と**クエリを定型的な形式に変換して後の処理を効率化する役割**を担っています。
プログラミング言語のコンパイル時に実行されるのと同じです。
##②オプティマイザ
オプティマイザは英語のoptimizeから由来していて、最適化という意味です。
ここでの最適化とは最適にデータをアクセスするための**実行計画**という意味です。
オプティマイザは**インデックスがあるかどうか・データの分散や偏りの具合**などの条件を考慮して、いくつかの**実行計画**を作成してそれらのプランのコストを計算した後、最も低いコストの実行計画一つを選出します。
##③カタログマネージャ
カタログマネージャは**テーブルやインデックスなどの統計情報**が格納されていて、その統計情報をオプティマイザに提供しています。
**統計情報には
・各テーブルのレコード数
・各テーブルの列数と列のサイズ
・列値のカーディナリティ(カーディナリティについては[カーディナリティについてまとめてみた](https://qiita.com/soyanchu/items/034be19a2e3cb87b2efb))
・列値のヒストグラム
・列値のNULL数
・インデックス情報**
　が格納されています。
注意してほしいのは**テーブルの値が大きく更新されたら、カタログの統計情報も更新して(analyze table等)**あげないといけません。
**統計情報を更新しないとカタログマネージャがオプティマイザに更新する前の統計情報を渡してしまうから**です。
SQLによって統計情報を自動で更新する機能があるのかどうかは不明です。
##④プラン評価
よくわかりませんでしたがとりあえず**Explain**をつかうとどのように実行計画が選択されているか分かるので、補正案を考えることができます。

#次回
結合辺りをまとめたいと思います。
MySQLのGROUP_CONCAT関数が結構使える

MySQLの`GROUP BY`はみなさんよく使っていると思います。
何かしらのグループごとに`SUM`とか`COUNT`とかでSELECTするときです。

例えば、以下のようなデータをもつ`user_group`というテーブルがあったとき、

|group_id|name|age|
|:---|:---|:---|
|A|John|24|
|B|Bob|22|
|A|Tom|31|
|A|Adam|19|
|B|Mike|25|
|A|Bill|33|

例えば、こういうクエリを書くと、

```sql
SELECT group_id, COUNT(name) AS user_count
FROM user_group
GROUP BY group_id
```
以下のような結果がかえってきます。

|group_id|user_count|        
|:---|:---|
|A|4|
|B|2|

この4とか2とかの中身を知りたい！というときに役に立つのが、`GROUP_CONCAT`です。
使い方はこんな感じ。

```sql
SELECT group_id, GROUP_CONCAT(name) AS user_list
FROM user_group
GROUP BY group_id
```
GROUP BYされている中身をカンマ区切りでリスト化してくれます。


|group_id|user_list|        
|:---|:---|
|A|John, Tom, Adam, Bill|
|B|Bob, Mike|

セパレーターや、並び順も変更することが可能。

```sql
SELECT group_id, GROUP_CONCAT(name ORDER BY age DESC SEPARATOR '|') AS user_list
FROM user_group
GROUP BY group_id
```

指定したセパレーターでsplitして、arrayで持つとかなり便利に持ち回れます。
Gitlab CEでLet's Encryptの証明書を使ってHTTPS通信を有効にする

#前提
`/etc/letsencrypt/live/`の下にLet's Encryptで生成した証明書が存在すること。

#方法

```bash:bash
sudo vi /etc/gitlab/gitlab.rb
```

```rb:/etc/gitlab/gitlab.rb
external_url 'https://<your FQDN>'

nginx['redirect_http_to_https']      = true
nginx['ssl_certificate']             = "/etc/letsencrypt/live/<your FQDN>/fullchain.pem"
nginx['ssl_certificate_key']         = "/etc/letsencrypt/live/<your FQDN>/privkey.pem"

```

```bash:bash
sudo gitlab-ctl reconfigure
```
__注：__ 少し時間を置くか、２回reconfigureを実行しないと証明書が有効にならなかった

#参考
* [Amazon Linux上にインストールしたGitLab CEにLet's Encryptを適用する方法 \- Qiita](https://qiita.com/morisuke/items/a772fc45242e418bf40b)
flexbox系あれこれ

flexbox系のやつ、display:flex;くらいしか日常使いしてなかったので
この機会に...




#　flexboxコンテナ

### flexboxコンテナ: flex-direction
「flex-direction」プロパティは、flexコンテナの主軸の方向を設定することにより、
flexアイテムがflexコンテナでどのように配置されるか明示します。方向は2種類で、横列の水平、縦列の垂直に配置できます。

### flexboxコンテナ: flex-wrap
flexboxの初期のコンセプトは、1行に複数のアイテムをコンテナにセットすることです。
そこから進化し、「flex-wrap」プロパティは、flexコンテナが複数のアイテムを一行、または複数行に配置することをコントロールします。

### flexboxコンテナ: flex-flow
「flex-flow」プロパティは、「flex-direction」と「flex-wrap」を設定するショートハンドです。

#### flexboxコンテナ: justify-content
「justify-content」プロパティは、flexコンテナの主軸に沿ってflexアイテムを一行に配置します。

### flexboxコンテナ: align-items
flexアイテムはflexコンテナのクロス軸に垂直方向で配置することができます。「align-items」プロパティは、デフォルトで全てのflexアイテムを含めます。

### flexboxコンテナ: align-content
「align-content」プロパティは「justify-content」と似ていますが、「align-content」プロパティはクロス軸の垂直方向に揃えて配置します。




#　flexboxアイテム

### flexプロパティ

flexプロパティのショートハンドが、flex-grow、flex-shrink、flex-basisという３つのプロパティ。
flex-grow、flex-shrink、flex-basisを一括指定したい場合は『flexプロパティ』を使う。

### flexboxアイテム: flex-grow

flex-growプロパティはflexアイテムの伸長係数（伸びる倍率）を設定するものです。
数字で指定します。

### flexboxアイテム: flex-shrink

flex-shrinkプロパティはflexアイテムの縮短係数（縮む倍率）を設定するものです。
数字で指定します。


### flexboxアイテム: flex-basis
flex-basisの基本的な使い方は、widthプロパティやheightプロパティと同じです。


各flexアイテムの幅をwidthで指定しても、別のプロパティで比率を指定している場合、widthの値が無視されます。
そういうときに幅を固定してくれるのが、このflex-basisプロパティです。
『flex-direction』が、row、row-reverseのときは『flex-basis』は横幅を指定します。
『flex-direction』でcolumnやcolumn-reverseのときは『flex-basis』は縦の長さを指定することになります。
値に指定できるのは単位を含めた数値と、初期値である『auto』です。
なお、負の値は指定できません。


### flex: 1;の場合

上記の内容を踏まえて、以下の記述が省略されたもの

```css
flex-grow: 1
flex-shrink: 1
flex-basis: 0
```


### flexboxアイテム: align-self
「align-self」プロパティは、flexアイテムの整列を前述の「align-items」での指定より優先します。
nginx.confを書きながら内容を理解する

## この記事は何？
- 自分のnginxの勉強のためのアウトプットです。

## 前提
- nginxが最小構成で動くような設定だけを対象として読んでいます。


---
# server.confの内容
## user
- プロセスを起動するユーザ
- master processはrootで起動する

## worker_processes
- workerの数
- autoだとコア数に設定してくれる

## pid
- プロセスIDを格納するファイル

## events
### worker_connections
- 1ワーカーの接続数

### multi_accept
- 複数のリクエストを同時に受け付けるか

### use
- 複数アクセスをさばくためにI/O多重化に使うシステムコールを指定する
- select/poll/epoll
- epollはselect/pollに比べて計算量が少なく、また監視対象のファイルディスクリプタの数が無制限

## http
### charset
- HTTPレスポンスヘッダの`Content_Type`に付与する文字コード

### server_tokens
- HTTPレスポンスヘッダの`Server`にnginxのバージョンを入れるか

### MIMEタイプの指定
- `/etc/nginx/mime.types;`にnginxが用意したMIMEタイプと拡張子のマッピングがある
- マッピングに無いものは`default_type`で指定したMIMEタイプとなる

### access_log
- アクセスログの出力先PATHを指定する

### error_log
- エラーログの出力先

## server
- バーチャルホスト毎の設定を行う

### listen
- LISTENするポート

### server_name
- HTTPリクエストヘッダのHostに該当する

### root
- Documentルートを指定する

### index
- HTTPリクエストのURLが「/」で終わっている時にインデックスとして使うファイルを指定する

### charset
- HTTPレスポンスヘッダのContent_Typeに付与する文字コード

### location
- URIのパスごとの設定を書く

---

## こんな感じで動いた
```
# プロセスを起動するユーザ
user nginx;

# workerの数
# auto: コア数に合わせて設定
worker_processes auto;

# プロセスIDを格納するファイル
pid /var/run/nginx.pid;

# イベント処理に関するモジュール
events {
  # 1ワーカーあたりの接続数
  worker_connections 2048;

  # 複数リクエストを同時に受け付けるか
  multi_accept on;

  # I/O多重化に使うシステムコールを選択する
  # epollはselect/pollに比べて計算量が少なく、また監視対象のファイルディスクリプタの数が無制限
  use epoll;
}

# httpに関するモジュール
# httpサーバ全体の設定
http {
  # HTTPレスポンスヘッダのContent_Typeに付与する文字コード
  charset UTF-8;

  # HTTPレスポンスヘッダのServerにnginxのバージョンを入れるか(開発時以外は入れないほうが吉)
  server_tokens off;

  # MIMEタイプの指定
  ## nginxがデフォルトで用意するMIMEタイプと拡張子のマッピングファイル
  include /etc/nginx/mime.types;

  ## マッピングにない拡張子のdefault
  default_type text/plain;

  # アクセスログの出力先
  access_log /var/log/nginx/access.log;

  # エラーログの出力先
  error_log /var/log/nginx/error.log;

  # バーチャルホスト毎の設定
  server {
    # LISTENするポート
    listen 80;

    # HTTPリクエストヘッダのHostに該当する
    server_name localhost;

    # ルートディレクトリを指定する
    root /var/www/html;

    # HTTPリクエストのURLが「/」で終わっている時にインデックスとして使うファイル
    index index.html;

    # HTTPレスポンスヘッダのContent_Typeに付与する文字コード
    charset utf-8;

    # アクセスログの出力先
    access_log /var/log/nginx/access.log;

    # エラーログの出力先
    error_log /var/log/nginx/error.log;

    # URIのパスごとの設定
    location / {
      # ルートディレクトリを指定する
      root /var/www/html;
    }
  }
}

```
アジャイルライクな振り返りで恋愛を改善 girl's side

初めまして！

オリンピックが大好きなウェイウェイです！

私たちの「アジャイルライクな振り返りで恋愛を改善」について、
すでに彼氏のかずさが書いてくれました。

第２回は、女子（恋愛？）目線でこれまでの
経緯や気づきを書いてみます！


#付き合い１ヵ月目でキャパオーバー

付き合う前から、
彼のファッションなど見た目へのこだわりと、私の方向性との違いには悩んでいた。

（バンドを組む前から、早くも解散に向かってしまう気分...)

本人にも伝えていたため、お互い折り合いをつけていこうということで一旦収まり、
付き合い始めた。

ただ、いざ付き合ってみると、やはりお出かけの時に人目が気になるなど、
心の負担になっていた。

また、付き合ったからと言って、
相手のパーソナルな部分の話がしやすい
という訳でもない。

それにより、その他の取るに足りないようなことも、いつもならスルーできるネガティブ感情も、すべて積み重なってきて、
１か月目で早くもキャパオーバー！！

（情けない話です...）

後々話を聞いて分かったのが、私のこの頃の葛藤を彼は何も分からなかったと！

（まぁ、分からないよね！笑）


#スクラムを恋愛に適用できる？
先日、スクラム研修を受けた。

とても分かりやすい研修内容で、理解も少しは深めたが、やはり実践経験が無いため、「何か身近な経験」に置き換えて考えないと、
なかなかイメージが付かないことも多かった。

その時、「恋愛や夫婦生活」に
置き換えたらどうだろうと、
頭の片隅で一つのキーワードが残った。

ただ、どう置き換えられるかはあまり考えついてなかった。


#彼の提案

スクラム研修の後、
私の恋愛のキャパオーバーがやってきた...

とりあえず涙が溢れる。

これでは何も解決しないと頭で分かっているだけに、さらに情けなくなり、余計涙が出る。


その時、彼が「アジャイルライクな振り返り」
をしようと提案してくれた！！


このシリアスな場面で、
なかなかの賭けに出たなぁと思って、
面白くて爆笑してしまった。


頭にアジャイル・恋愛のキーワードが
あったので、すんなり受け入れられ、
お互いの考えを書き出すために
付箋を取り出したら、
逆にびっくりされたみたい！笑



※男性からすれば、泣かれるのはズルい、面倒
 なんて思うこともあるかもしれないが、
 泣きたくて泣いてる訳ではないことを
 ご理解頂きたい！笑
 でも、結果的に泣いてスッキリして、
 落ち着いて話せるようになって良かった。
 私が落ち着くまで待ってくれた上で、
 提案をしてくれた彼には感謝。


#気づき
###★初めから完璧な関係なんて無い！
話し合いができる相手と一緒に、
二人で関係を作り上げていくのも良いかも。

###★思っていることを書き出すことの効果

１．相手の顏を見ながら、直してほしいところを話すと、どうしても相手を否定しているような気分になる。相手もそう感じているのでは？と思うことで、言いたいことが言えなかったりする。

　その時、紙に書き出して、それを見ながら二人で話すと、相手を「否定」しているのではなく、「お互いの違い」として話せるので、言いにくいことも言える！！


２．書き出してから話すと、話し忘れを防ぐ

###★次に向けてのActionを決めることの効果（予想）

１．明確なActionを決めることでその後の行動に迷いがない。また、お互いに納得したことをActionとして決めることで、やらされ感もない。
　
２．決めたことに効果があるかどうか分からなくても、アジャイルは短期間のSprintを繰り返すため、とりあえずやってみて次回の振り返りでまた考えれば良い。
　　
　　失敗したとしても、実施した時間は短いため、それほど無駄には感じない。
　　
３．お互いのその後の努力も、決めたActionと照らし合わせて評価できる。

４．二人の関係を良くするためのActionであるため、ある種の「共同目標」ができ、一体感が生まれる。良いActionが取れた時に喜びが２倍になる。


###★「付箋」を取り出すと、相手がびっくりするらしい！笑


#まだまだアジャイルをそれほど分かってないけど
恋愛を通して学ぶこともなかなか面白いなぁと思っています＾＾

Sprint２の振り返りも楽しみです！！
nimbleでパッケージ管理

# 概要

* nimbleでパッケージを作成するときのメモ
* nimbleで作成したパッケージで色々する

# 環境

* OSX
* nim 0.17.2
* nimble 0.8.8

# 外部のパッケージを操作する

## パッケージリストを取得する

```zsh
% nimble update
```

* ~/.nimble 以下にパッケージリストが配置される

## パッケージを検索

```zsh
% nimble search [キーワード]
```

* キーワードで関連するパッケージ一覧を表示

## パッケージをインストール

```zsh
% nimble install [パッケージ名]
```

* ~/.nimble/pkgs 以下にパッケージが配置される

## パッケージをアンインストール

```zsh
% nimble uninstall [パッケージ名]
```

* ~/.nimble/pkgs 以下の対応するパッケージを削除

# 自作のパッケージを作成する

## パッケージ作成

```zsh
% mkdir example.nim
% cd example.nim
% nimble init
      Info: In order to initialise a new Nimble package, I will need to ask you
        ... some questions. Default values are shown in square brackets, press
        ... enter to use them.
    Prompt: Package name? [examplenim]
    Answer: example
    Prompt: Initial version of package? [0.1.0]
    Answer: 
    Prompt: Your name? [honeytrap15]
    Answer: 
    Prompt: Package description?
    Answer: example nimble package
    Prompt: Package license? [MIT]
    Answer: 
    Prompt: Lowest supported Nim version? [0.17.2]
    Answer: 
   Success: Nimble file created successfully
```

* ベースとなるnimbleファイルが生成される

## ビルド設定

* nimble buildでプロジェクトをビルドできる

* 以下のような構成にした

```zsh
% tree      
.
├── example.nimble
└── src
    └── example.nim
```

```example.nim
echo "example package"
```

* ソースディレクトリと生成するバイナリをnimbleファイルに設定する

```example.nimble
# Package

version       = "0.1.0"
author        = "honeytrap15"
description   = "example nimble package"
license       = "MIT"

bin = @["example"]
srcDir = "src"

# Dependencies

requires "nim >= 0.17.2"
```

* ビルド

```zsh
% nimble build
  Verifying dependencies for example@0.1.0
   Building example/example using c backend
% ls
example        example.nimble src
% ./example
example package
```

## タスクを追加

* nimbleファイルに定義することでサブコマンドを追加できる

```example.nimble
...
task clean, "clean build files":
  exec "rm -rf example"
  exec "rm -rf src/nimcache"
  echo "remove build files"
```

## ローカルのパッケージをインストール

* ローカルにあるパッケージのリンクする

```
% nimble develop
   Warning: This package's binaries will not be compiled nor symlinked for development.
  Verifying dependencies for example@#head
   Success: example linked successfully to '/Users/hiro/Desktop/example.nim'.
% ls ~/.nimble/pkgs 
example-#head
```

* これをやっておくとテストコードを書いたり、他のパッケージからimportすることができるようになる
AzureをAnsibleから弄ってみる

どうも。
AnsibleでVMの構成管理をしたいことってありますよね。
ただ、公式ドキュメントが散らばっていてわかりにくいので、自分なりにまとめてみました。

## Azure cliツールを導入する

brewとかで入ります。環境により方法が違うので割愛。

## Azure cliから自分のアカウントにログインする

```bash
$ az login
```

すると、デフォルトブラウザでログイン画面が開きます。ログインが終わると、ブラウザでコードの入力を求められるので、az loginした後に表示されているコードを入力します。

## サービスプリシンパルの作成

いわゆるアプリケーション登録らしいです。

```bash
$ az ad sp create-for-rbac --query [appId,password,tenant]

[
    "aaaaa-aaaaa-aaaaaa",
    "bbbbb-bbbbb-bbbbbb",
    "ccccc-ccccc-cccccc"
]
```

実行すると、キーが３つ入ったjsonが帰ってきます。
上から順に、アプリケーションID、アプリケーションパスワード、テナント、らしいです。

TwittterのOAuthでいうアプリケーションキーとアプリケーションシークレットみたいな感じですかね。

また、自分のサブスクリプションIDも必要らしいので、取得します。

```bash
$ az account show --query [id] --output tsv

ddddd-ddddd-ddddd
```

## 認証情報の追加

`~/.azure/credentials`というファイルを作り編集します。
サブスクリプションIDには先程取得したもの、クライアントIDからテナントまでは、先程のjsonの順番のとおりで大丈夫です。

```ini
[default]
subscription_id=ddddd-ddddd-ddddd
client_id=aaaaa-aaaaa-aaaaaa
secret=bbbbb-bbbbb-bbbbbb
tenant=ccccc-ccccc-cccccc
```

# cli（コマンドライン）から試す

## 場所を選ぶ。

```bash
$ az account list-locations | grep -B1 -A6 Japan
```

をすると、データセンターの場所が選べる。日本は西日本か東日本の２つしか無い。
今回は`japaneast`を選ぶ。

## リソースグループを選ぶ

```bash
$ az group list
```

をすると、今どんなリソースグループがあるか確認できる。
以下で新しく作成もできる。

```bash
$ az group create --name test-by-ansible --location japaneast
```

## サーバーのサイズを選ぶ

```bash
$ az vm list-sizes --location japaneast
```

を実行すると、japaneastで使えるVMの種類リストが出てきます。
たとえば`Standard_B1ms`は、1CPU、メモリ2G、SSDが4GBのプランになっています。

## ネットワークを選ぶ

```
$ az network vnet list
```

みたいに実行すると、今Azureにある仮想ネットワークが表示される。
仮想ネットワークは、単純にVM同士をつなげたりするのに使う。
以下のようにして、新しく作ることもできる。

```bash
$ az network vnet create --name test-network --resource-group test-by-ansible
```

## OSを選ぶ

```bash
$ az vm image list
```

を実行すると、UbuntuやらCentOSやら色々出てくる。
今回はUbuntu 16.04 LTSを選んだ。
`offer`, `sku`, `publisher`, `version`を覚えておく。


## VMを作成する

```bash
$ az vm create --name test-vm --resource-group test-by-ansible --image UbuntuLTS --size Standard_B1ms --vnet-name test-network --admin-username onokatio  --ssh-key-value ~/.ssh/azure.pub
```

みたいに実行する。

# 実際にAnsibleのplaybookで動かしてみる

## ライブラリなどのインストール

```
$ sudo pip install ansible
$ sudo pip install ansible[azure]
```

自分はpyenvを常用しているが、どうやらansibleはライブラリを読み込むのはデフォルトのパス（`/usr/lin/python2.7`）らしいので、一旦`pyenv global system`した。本当はvirtualenvとか使ったほうがいいのかもしれない。

## playbookの作成

# 参考

- https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/ansible-install-configure#create-azure-credentials
- http://otiai10.hatenablog.com/entry/2017/12/17/185605
- https://docs.ansible.com/ansible/latest/guide_azure.html
【Chrome Developer Tools】webサイトのレスポンスが重い・遅い原因を調べる【Networkタブ】

webページの読み込みが遅い、表示に時間がかかる・・・。
だけど原因がわからない・・・。
そんなときに使用するのが、Chromeをはじめとするブラウザに備わっているDeveloper Tools（開発者ツール）のNetworkタブです:star:

QiitaのAdvent Calender 2017のページを利用して、Chrome Developer Tools（開発者ツール）のNetworkタブの使い方を見てみましょう。

# Networkタブの場所と使い方
下の図で示しているように、左から４つ目にあります。
![000_100.png](https://qiita-image-store.s3.amazonaws.com/0/188980/bea69295-165b-9bef-9a5a-bf35262acf99.png)

F12でDeveloper Toolsを起動したら、調査対象のwebページをF5でリロードして、読み込みの記録を開始します。
で、記録が終わったら、この:arrow_down:丸いボタンを押して、ストップさせます。
押さないと、ずーっと記録してしまうんです:exclamation:
ちなみに、記録中は赤く光ってます:red_circle:
![001_e2_100.png](https://qiita-image-store.s3.amazonaws.com/0/188980/e84105a5-53fc-e42b-b327-9e89e9b1d95a.png)

# 何がわかるのか
HTMLやCSS、画像データなどを、

- どのファイルを
- どの順番で
- どのくらいの時間をかけて読み込んでいるか

がわかります。

具体的には、こんな:arrow_down:感じ。
この図の中で５つ示した部分を、以下１つずつ見ていきます。
![001_e1_100.png](https://qiita-image-store.s3.amazonaws.com/0/188980/9e143b6c-4d25-02e9-f950-d65edb80dd19.png)

## １．フィルター機能
CSSだけ、画像だけ・・・など、記録結果をある程度絞り込んで表示することが出来ます。
ファイル名での部分一致検索も可:white_flower:

## ２．ファイル一覧
一番上が、一番最初に読み込まれたファイルです。
処理された順に表示されます。

## ３．ファイルタイプ
JSとかCSSとか表示されます。ここの表示が、「１．フィルター機能」で絞り込むときのファイルタイプでもあります。

## ４．タイムライン
処理スレッドごとにラインが引かれ、ラインの長さが処理時間を表します。
また、処理内容によって、黄色や紫、緑などの色がつきます。
そして、タイムライン上をドラッグすると :arrow_down:その部分だけ抜き出したファイル一覧を見ることが出来ます。
![004_075.png](https://qiita-image-store.s3.amazonaws.com/0/188980/c22235e3-14f3-f37d-72e3-1b3f2d09da8b.png)

## ５．処理時間
ここが一番見てほしい場所:exclamation:
ファイルごとの読み込み時間が数値で表示されるとともに、処理内容がカラーバーで表示されています。
カラーバーの上にマウスカーソルを当てると、処理の詳細がポップアップで表示されます。

# まとめ
Networkタブを起動して、webページをリロードすることで簡単に読み込み処理を記録することが出来ます。
そして、処理時間の長いファイルを特定することが出来れば、対応方法もおのずとわかってきます。
ex）画像サイズを小さくする、js処理を改善する・・・など
逆に、どの処理も同じくらいの処理時間であれば、ブラウザ側ではなくサーバー側を疑ってみることも必要になってきます。

さくっと見てみましたが、これだけでも十分な数値が取得できるかと。
「レスポンス遅いな～」と思ったら、ぜひNetworkタブを開いてパフォーマンス計測してみてください:alarm_clock:
【UE4】AIPerceptionのDetect by Affiliationがブループリントのみで機能しない理由

#はじめに
この記事は以下の記事に自分なりの補足を加えたものになります。

>AI Perception in Unreal Engine 4 – How to Setup Written by Denis Rizov
https://denisrizov.com/2017/05/08/ai-perception-in-unreal-engine-4-how-to-setup/

リンク先の記事にはDetect by Affiliationを機能させるための手順が解説されていますので興味のある方は是非読んでいただければと思います。


#Blueprintのみではチーム設定を行えない
現状（4.18.3）ではIGenericTeamAgentInterfaceが備える関数はBP側に公開されておらず、チーム設定を行うにはC++を避けられません。
ここではブループリントでチーム設定を行えない理由を説明します。

##GenericTeamIdにメンバを設定ってノードあるよ？
ブループリントエディタで「GenericTeam」と検索すると以下のような候補が出ます。

![2018-02-18_20h12_10.png](https://qiita-image-store.s3.amazonaws.com/0/104467/c90b17ca-fd79-3f90-a63a-21db2041c72c.png)

**GenericTeamIdにメンバを設定**というノードがあり、これを使えば問題なくTeamIDを設定できそうですが残念ながら実際には設定されません。

AIPerceptionがTeamIDを取得するための関数GetTeamIdentifierを呼び出すタイミングはBPのConstruction ScriptやBegin Playよりも前なのでBP側でノードが呼ばれるのは、TeamIDが取得された後なので意味を成しません。ですので、クラスのコンストラクタでTeamIDを設定する必要があります。
>AIPerceptionがTeamIDを取得するまでの実行順
UAIPerceptionComponent::OnRegister 
↓
 UAIPerceptionSystem::UpdateListener
↓
FPerceptionListener::UpdateListenerProperties
↓
UAIPerceptionComponent::GetTeamIdentifier

##プレイヤーBPのインターフェースにGenericTeamAgentInterfaceってのが選べるけど？
BPのクラス設定を開くと「インターフェース」という項目があり追加ボタンから各種インターフェースを備える事が出来ます。
追加候補の中に**GenericTeamAgentInterface**というインターフェースがありますが、残念ながらこれを選択しても意味はありません。

恐らくですが、ここで候補として表示されるGenericTeamAgentInterfaceは関数GetGenericTeamIdとかが定義されているインターフェースクラスでは無い気がします。

GenericTeamAgentInterface.hには以下のようにインターフェースが２つあります。

```cpp
UINTERFACE()
class AIMODULE_API UGenericTeamAgentInterface : public UInterface
{
	GENERATED_UINTERFACE_BODY()
};

class AIMODULE_API IGenericTeamAgentInterface
{
	GENERATED_IINTERFACE_BODY()
        // 省略
};

```

候補として挙げられたGenericTeamAgentInterfaceは**UInterfaceを継承したUGenericTeamAgentInterface**ではないかと思います。

本命の**I**GenericTeamAgentInterfaceにはAIPerceptionの刺激対象がどのチームに属するかを判定する関数GetTeamAttitudeTowardsがあります。
プレイヤーBPにGenericTeamAgentInterfaceを追加しても以下の矢印部分で失敗します。

```cpp
	virtual ETeamAttitude::Type GetTeamAttitudeTowards(const AActor& Other) const
	{ 
        // ↓ NULLが返される（キャスト失敗）
		const IGenericTeamAgentInterface* OtherTeamAgent = Cast<const IGenericTeamAgentInterface>(&Other);
		以下省略
	}

```

#まとめ
FGenericTeamIdはUSTRUCTでブループリント側で触れるようになっていますが**GenericTeamIdにメンバを設定ノード**を呼び出しても実行順の関係で特に意味を成しませんし、BP側でGenericTeamAgentInterfaceを追加したとしても恐らく**I**GenericTeamAgentInterfaceでは無いのでキャストに失敗します。
これらの理由によりDetect by Affiliationをブループリントのみで機能させる事は出来ないと考えられます。

正直面倒ではありますがDetect by Affiliationで敵味方の判別をさせる際にはC++が必須です。幸いな事にC++での実装方法は記事上部にあるリンク先の記事にまとめられていますので、実装される方は是非読んでいただきたいと思います。