OmniAICreator/Qiita-1.07M huggingface dataset:
windowsでSATySFiの環境構築

# はじめに
texに代わる組版システムが開発中と聞いたので使ってみたくなった
公式のREADMEでwindowsへのインストールの仕方がよくわからなかったので(特にopamのインストール)調べてやってみた
だからもっといい方法があるかもしれにあ


# SATySFi
公式より
>SATySFi（英単語の “satisfy” と同様に発音します）は，新しい組版処理システムとその言語です。構文は主にテキスト部分とプログラム部分からなり，前者はLaTeX風の構文で文書を執筆するために，後者はコマンドを定義するために使われます。いわゆる函数型プログラミングの要領でコマンドが定義でき，かつ静的に型がつけられるため，柔軟な記述とわかりやすいエラー報告が実現されています。

# インストール手順
大雑把に書くと以下のようになる
1. opamの入ったCygwin環境の用意
2. Cygwinに必要なパッケージをインストール
3. いくつかのコマンド実行


## 1. opamの入ったCygwin環境の用意
windowsでSATySFiをインストールするためにはopamというものをインストールする必要がある
しかし(調べた範囲では)windowsではCygwin環境上で動かすしかないらしい
そのためタイトルのように「opamの入ったCygwin環境の用意」することとなる
opamの環境構築は別の記事として書いたのでそちらを参照されたし
https://qiita.com/shiba44/items/69a7bfeef82cf27794a3

## 2. Cygwinに必要なパッケージをインストール
ここではすでにopamが入ったCygwin環境が構築できているものとする
ここからは公式のREADMEに従えば良い
Cygwin環境に以下のパッケージをインストールする

* bzip2
* cc
* git
* m4
* make
* unzip
* wget or curl
* ruby

## 3. 公式に従ってコマンドを実行していく
Cygwin環境のターミナルを立ち上げ, 以下のコマンドを実行する

```
[user]$ opam repository add satysfi-external https://github.com/gfngfn/satysfi-external-repo.git
[user]$ opam update
```
このあとはSATySFiのプロジェクトを持ってきてCygwin環境でビルドするだけ

```
# clone
[user]$ git clone https://github.com/gfngfn/SATySFi.git
[user]$ cd SATySFi

# build
[user]$ opam pin add satysfi .
[user]$ opam install satysfi
```

# デモ実行
ちゃんと実行するためにはまだ手順が必要
公式がわかりやすいので参照されたし
https://github.com/gfngfn/SATySFi/blob/master/memo-ja-how-to-use.md


基本的にやることは「ライブラリルート」の構築,フォント設定だけ

## ライブラリルートの構築

サンプルがlib-satysfiという名前で公式のリポジトリに置いてあるので, それをusr/local直下に.satysfiという名前で配置する
つまり以下のようなディレクトリ構造がusr/localにできていればいい

```
~/.satysfi/
    |
    +-- dist/
        |
        +-- fonts/
        |
        +-- hash/
        |   |
        |   +-- default-font.satysfi-hash
        |   +-- fonts.satysfi-hash
        |   +-- mathfonts.satysfi-hash
        |
        +-- hyph/
        |   |
        |   +-- english.satysfi-hyph
        |
        +-- packages/
        |
        +-- unidata/
            |
            +-- EastAsianWidth.txt
            +-- LineBreak.txt
            +-- Scripts.txt
```

## 実行
ここまでやってとりあえず実行してみる
ローカルに持ってきた公式リポジトリのdemoディレクトリ
https://github.com/gfngfn/SATySFi/tree/master/demo
をターミナルで開き以下を実行する

```
[user]$ satysfi demo.saty -o output.pdf
```
するとこんな感じで怒られるはず

```
! [Error] package file not found:
      dist/fonts\Junicode.ttf
```

これは「必要なフォントファイルが入ってないよ!!」ということなので「ないよ！」と言われたフォントファイルをそれぞれネットからインストールしてきて~/.satysfi/dist/fontsフォルダに置いていく

そうすると今度は

```
! [Error] satysfi-logo.jpg: No such file or directory
```
と言われる

これは「demoディレクトリ内にsatysfi-logo.jpgというファイルがないよ!」って言ってる 
なのでdemoディレクトリ内にsatysfi-logo.jpgという名前のjpgファイルを追加すれば良い

これで終わり
エラーの代わりに以下が出力されたら成功

```
  output written on 'output.pdf'.
```

# 参考文献
https://qiita.com/aomidro/items/9b8d66a51e81931f1c98
https://qiita.com/puripuri2100/items/a63e0c48f245dfcb0446
https://qiita.com/pochiMasahiro/items/91f2eecbffaf85c3f2a3

# 最後に
いつかTex-Liveみたいにディストリビューションが公開されるのかな
求むSATySFi-Live
自分でかけた電話を追跡する方法

# この記事について

[Twilio Advent Calendar 2018 - Qiita](https://qiita.com/advent-calendar/2018/twilio) の 18日目 の記事です。
※遅刻してすみません。

Twilioの架電周りについては、架電することはよく書かれていますが、架電のトレーサビリティについてはあまり語られていないようなので、この機会に残しておきます。

Twilioの架電実装の容易性は素晴らしいのですが、トレーサビリティについても簡単に行えて素晴らしいので、是非参考にしていただきたいです。

文中のコードはLaravel 5.5で書かれたものです。

# どうやるのか
## 概略
1. 架電して架電IDを取る
2. 取った架電IDを保存しておく
3. Twilioからのコールバックを受けてステータスに応じた処理をする

## 詳細

Twilioの架電には、架電ごとに割り振られるcallSidというものがあるので、これで以ってトレースします。

```php
/** @var Twilio\Rest\Client twilio_cli */
$call_obj = $twilio_cli->calls->create(
    $to, $from,
    [
        'url' => $markup_url,
        'method' => 'POST',
        'StatusCallback' => 'https://hoge.com/callback',
        'statusCallbackMethod' => 'POST',
        'statusCallbackEvent' => ['initiated', 'ringing', 'answered', 'completed'],
    ]
);
```

このコードを実行すると、$call_objの属性にsidというのが入ってくるので、
これをデータベースやKVSに登録しておき、アプリで拾えるようにします。

statusCallbackEventに、トレースしたい架電ステータスを放り込んでおくと、その状態に変わったときに、
TwilioのサーバからwebhookがStatusCallbackで指定したURL宛てに届くので、それに応じた処理をします。

例を置いておきます。

```php
public function modify(TwilioTelRequest $request)
{
    $input = $request->only(['CallSid', 'CallStatus']);

    if ($input['CallStatus'] === 'in-progress') {
        // なんか実装
    }
    $this->updateCallStatus($input);

    // Twilioに何かしたいわけではないので、Twimlを生成して返しておけばOK。
    return new Twiml();
}
```

TwilioTelRequestの中でTwilioサーバーからのリクエストかをチェックするようにしています。
Twilioからのリクエストかチェックする方法については、[こちら](https://qiita.com/sh-ogawa/items/ab1794bb271b2392c83c)を見ていただければと思います。

### statusCallbackEventでの注意事項
私も最初勘違いしていましたが、
ここに設定できる設定値に、in-progressやbusyなどはありません。
これらのステータスは詳細のステータスであり、
statusCallbackEventというのは、概形的なイベントを設定するにすぎません。

うろ覚えですが、例えばin-progressだとstatusCallbackEventで指定したところのansweredの詳細ステータスにあたったはずです。

[ここ](https://jp.twilio.com/docs/voice/make-calls#get-call-status-events-during-a-call)みてもらうのが一番手っ取り早いです。

ちなみに、上記にはqueuedも取れそうな感じで書いてありますが、

> $twilio_cli->calls->create

して取った$call_objのステータスを見るとqueuedになっているので、私がやるときは無意味だと思ってstatusCallbackEventには含めていないです。
（含めてもコールバックは飛んでこないし、たとえ飛んできてもタイミングなどの問題を埋め込むことになる）

# その他注意事項
CSPを独自にいぢってたりすると、そもそもTwilioからの要求を受け付けなかったりします。
その場合はCSPに以下を追加してください。

> script-src 'self' *.twiliocdn.com 'unsafe-inline';

# おわりに
自分からかけた架電のトレースについてざっくり書いてみました。
iPhone の新アプリ「押したときだけ動画撮影」Clips で、サーバー構成図・ドメイン理解・プログラミング全体像を把握するのがやばそうな件





# これ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/d3b955b0-0524-e375-0e9c-6e882ee2eae7.png)

最近流行りのMAD的動画的な?言い方がよくわからないけど。

とにかくやばい。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/403bf4c4-00f8-fc68-5883-866df995f100.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/403bf4c4-00f8-fc68-5883-866df995f100.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/403bf4c4-00f8-fc68-5883-866df995f100.png)
# 普通の動画撮影に比べて、編集や撮影の多くの問題を根本的に解決している

- 本当にやばい。
- シャアザクの3倍速どころじゃない。300倍だ。
- エンジニアのライフチェンジング!革命レベル!

# 「ボタン押してる間だけ撮影」が出来る

- たとえば人と話ながらホワイトボードに図を描く
- 同時にホワイトボードを撮影
- 理解しながら地図を描ける

# 「撮影のコマ」ごとに削除ができる

- NGテイクがなくなる
- 最初から撮り直し不要
- あとからの面倒くさい動画編集も不要

# 「撮影のコマ」ごとに入れ替えが出来る

- 使えそう

# 

# 静止画を作る

- スクリーンショットでも撮れば。

# 1本の動画に最後に変換

- 「コマ3からコマ12までで一本!」とか出来る
- コマをずらしてなんどでも動画が作れそう
- ハイブリッド!

# 実演

したい‥! 次の記事で書くかも。

---

Signed [yumainaura iphone - Google Search](https://www.google.com/search?q=yumainaura+iphone&oq=yumainaura+iphone&aqs=chrome..69i57.3543j0j7&sourceid=chrome&ie=UTF-8)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
いろいろ書いてみた

※2024/03/06 この記事は移動しました。
[いろいろ書いてみた](https://qiita.com/moonWalf/items/38bc13f796d69a944ae6)

あくまで私の経験から。
ちがうケースもあると思う。

##Web系とSIer系の違い

Web系はお客様がユーザーそのもの(ユーザー企業と呼ばれる)。
なので、コーディングの前提があくまで対ユーザーになる。
だから仕様書は少なくていいし、エビデンスも不要だったりする。
いわゆる「憧れのエンジニア」は多分こっち。

SIer系はお客様がユーザー企業になる。
なので、コーディングの前提はユーザーというよりは企業の担当者向けみたいになる。
ユーザー企業(非エンジニア)に対して仕事をするので、
詳細な仕様書を求められることが多く、
ちゃんと動くことを証明するための画面エビデンス(全機能・全操作分)を
求められることも多い。
いわゆる「IT土方/ブラック企業」は多分こっち。

Web系はとかくコードを書く。
SIer系はとかくドキュメントを書く。

Web系は育成をある程度してくれる。
SIer系は育成とかしない(メンターとかいないので、現場で自分でもがくしかない)。

Web系は服装自由が多い。
SIer系はスーツが多い(エンジニアというより会社員という感じ)。

Web系はリリースが多い(週1回とか)。
SIer系はリリースが少ない
(バグがない前提だから複数リリースしない事が多い、Webシステムの場合は月1回とかはあった)。

Web系は自動テストが多い。
SIer系は打鍵テストが多い
(エンジニアのレベルにばらつきがあるからだと思う)。

Web系はエビデンスが最小限。
SIer系はエビデンスが最大限
(押す、スクショとる、エクセルに貼り付ける、をひたすら繰り返す)。

Web系はエンジニアの最低レベルが高い
(ある程度はできる人が多い)。
SIer系はエンジニアの最低レベルが低い
(if文がギリわかる新人からペーパープログラミングしてた超ベテランまで幅が広い)。

Web系は人の入れ替わりが少ない
(もちろん転職や引き抜きもあるだろうけど)。
SIer系は人の入れ替わりが多い
(契約終われば終了だし、突然他のプロジェクトに持っていかれたりする)。

Web系はWeb系。
SIer系はオンプレミス(ローカル環境で動くアプリ)が多い。

Web系はスキルが身につく。
SIer系は上手く行けばスキルが身につくが、ヘタなところにいくと何も身につかない。

Web系はある言語や環境に専門的になれる(受託開発ではない場合)。
SIer系は幅広く学ぶことができる
(C#,Python,RPG(ゲームではなくてIBMの言語),DBもOracle,DB2,MySQLなど)。

##個人的にいいなぁと思った環境

やり方は任せてくれるところで、人間関係が良好なところ。
心理的安全性とまでいかなくとも、思いやりがある人が多いところ。
デュアル以上のモニタをくれるところ。
※追記 MacでRetinaとかならデュアル出なくても良い。
あと、不可能な納期を押し付けて来ないところ。

##Web系にSIerの人が来たらすぐに馴染めるか？

もはや人によるとしか言えない。
自由な雰囲気に馴染めるかどうか。
戸惑う人のほうが多そう。
ただ、スキル的にはSIerは知らないスキルの習得が得意な人が
多い印象があるので、スキルの問題はないと思う。
あと、Macは珍しくて操作を知らない人のほうが多いと思う。

##プログラミングに飽きる？

飽きる。
そりゃ飽きる。
人間だもの。
飽きたらちょっと離れて、やりたくなるのを待ったりする。
エンジニアリングに完全に興味がなくなったら、
本屋さんとかで働きたい。

##アルゴリズムは役立つか？

直接役に立つ場面は多くないのかな。
詳しくないから多分だけど、
処理速度がすごく求められる場面では逆に知らないと太刀打ち出来ないイメージ。
デザインパターンも合わせて学ぶといいと思う。

##プログラム上達の最短ルート

王道なし。

体系的に学んだことがないから、むしろ教えてほしい。
体感的に言うと、
入門書読んで、なにか簡単なものを作ってみて、いじってみる。
小さく初めて、ちょっとずつ学ぶ感じ。
入門書100回読んだりProgate100周するよりも、
入門が終わったら何か作ってみたほうがいいと思う。
自分の頭を回してみる必要がある。

あとは、言葉を覚えること。
クラスとか、メソッドとか、正規化とか。
そういう意味で、基本情報技術者試験はオススメ。
実務に役立たないと言われるけども、
学ぶ上での基礎にはなる。

##他言語を学ぶコツ

王道なし。

これもまた教えてほしい。
多分、まずは言語の思想を知ること。
オブジェクト指向なのか、関数型なのか、
動的型付けなのか、静的型付けなのか。
思想を知った上で、最低限を学ぶ。
変数・if文・for文等はほぼすべての言語にあるから、
その書き方を学べばいいと思う。

##コードレビューのコツ

わからん。
場面によりけりだと思う。
処理速度より読みやすさが必要な場面なら、読みやすいかどうかだし。
時と場合によるのでは。
ただ、どうしてそういう書き方をしたのか、
理由が説明できないコードはNGだと思う。
理由は論理的以外にも、
「時間がなくて」とか「思いつかなくて」でも良い。
そして、責めないこと。
責めても得られるものはない。

##便利ツール

Visual Studio Codeがすごくいい。
AtomもSublimeもBracketsもいいが、
今はVSCodeがひとつ抜けている感じがする。
プラグインが豊富で、あらゆる環境に対応してくれる。

DBクライアントは
OracleのSQLDeveloperがいい。無料で、会員登録は必要。
特別優れたところは無いけど、見た目がわかりやすい。
Windowsにもあるというのが強み。

AdobeXDは素敵なツール。
UIを考えるのに便利。制限付き無料、会員登録必要。

Todo管理は
Microsoft To-Doが好き。
チェックリストを階層化できるし、
チェック項目ごとにメモを書ける。

Trelloも便利。
カード一覧で見れて把握しやすい。

MarkdownのメモにはVSCode。

Slackも使う。
最近はMicrosoft Teamsに注目してる。

あとは...無いものは作ればいいので作る。

##フォント

フォント好きなのでコーディング用フォントも使ってたりする。
最低限、ゼロとオーの区別が付きやすいフォントがいい。
あと等幅がいい。

Fira Code
リガチャという見せ方がついてるフォント。
https://qiita.com/tonkotsuboy_com/items/e512bfa5db7593b87d74
なれるとわかりやすくて便利。

Myrica
シャープでかわいくて読みやすい。

##最近気になっていること

Vue.jsがすごくいい。
これからも伸びそう。

Microsoftの勢いがすごい。
Appleの株価を抜いたし。

機械学習は面白そう。

インフラ・プログラマ・デザイナーの垣根が
どんどん下がっていってる気がする。

味噌ラーメン屋。北海道絶対うまい。
https://r.gnavi.co.jp/dhe1jmek0000/
Gitでよく使うワンライナー

## 現在のmasterを最新のものにした上でマージされたブランチは削除する
有用度: ★★★★★


```sh
sync = !git checkout master && git pull origin master && git fetch -p origin && git branch -d $(git branch --merged | grep -v master | grep -v '*')
```

## 現在の変更点をHEADのコミットに追加
有用度: ★★★★★

```sh 
amend = commit --amend -C HEAD
```

## .gitignoreに追加(なかったら作成)
有用度: ★★★★☆

```sh
ignore = "!f() { echo $1 >> \"${GIT_PREFIX}.gitignore\"; }; f"
```

#### 使い方

```sh
git ignore [ignoreするファイル名]
```

## 簡易ステータスを表示
有用度: ★★★★☆

```sh
s = status --short --branch
```

## 全てのファイルをaddして簡易statusを表示
有用度: ★★★★☆

```sh
aa = !git add -A && git s
```

## グラフログを表示
有用度: ★★★☆☆

```sh
lg = log --graph --date=short --decorate=short --pretty=format:'%C(yellow)%h %Cgreen%cd %Cblue%cn%Cred%d %Creset%s'
```

## 参考記事
https://qiita.com/awakia/items/4c599ebe29a8b2b6ca27
状況で使い分けるGit術　後編

この記事は JSL (日本システム技研) Advent Calendar 2018 - Qiita 25日目の記事です。(オオトリですなあ。。。)

---

[状況で使い分けるGit術　前編](https://qiita.com/moonwalkerpoday/items/c19d0a31b9897a45f162)
*前半の記事からーー早6ヶ月*
(前回の設定で記載されてたP上司一切でてきてなくて吹いた）

---

Advent Calendarという理由にかこつけて後編です。

前編では

* コンフリクト時にMergeとRebaseで対応
* コミットをrebaseでまとめる

について記述しました。
今回は「月君のやらかし事例とその対処」です。 

### 設定
* 月君 ... 最近調子に乗っており、ミスを犯すのは秒読み。SouceTree崇拝者。
* A先輩 ... 開発チームメンバーの先輩。すぐ調子に乗る月君を見はさなず見守ってくれるデキる意識高い系。

#### 前提
  * GitFlowを使用している
  * Macでvimを使用している

Mergeでコンフリクト時に、軽率なresetを行い・・・
---

月君は相変わらず慎重さにかけた実装を行っていました。

**月君**「さて、じゃあPush前に・・・moon_dev2の内容をMergeしておくか」
<img width="530" alt="スクリーンショット 2018-12-25 10.59.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/129996/4bc83b44-3811-39ec-a4a7-9c4948c3008f.png">
**Tips**
*SouceTreeからのMergeやRebaseは、対象ブランチの副ボタンクリックで出てくるコンテキストメニューから行えます*
<img width="413" alt="スクリーンショット 2018-12-25 10.59.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/129996/0175a2db-1789-93d4-a091-04da01d9c888.png">

しかし

<img width="730" alt="スクリーンショット 2018-12-25 10.59.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/129996/c36ac2f0-c1da-5d02-70ae-0ecabb43ece1.png">

**月君**「まじかあ。。。」

*〜数十分後〜*

**月君**「あーもうコンフリクト地獄でよくわからん。`origin/moon_dev`のコミットにresetしよう。そうすればもう大丈夫。なかったことにしよう」

<img width="1039" alt="スクリーンショット 2018-12-25 11.00.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/129996/06de6214-06d5-48ff-5df6-982be819083d.png">

月君は気づきませんでした。
moon_devブランチのHEADはPushしていなかったことに。
そしてPushしていなかったコミットはかなり重要な変更だったということに。

**月君**「よし。一旦なかったことにしたぞ。これでコンフリクトとかもきれいさっｐ・・・」

<img width="589" alt="スクリーンショット 2018-12-25 11.01.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/129996/eea907ec-e3ae-ae97-2970-a78f1ebec472.png">

**月君**「重 要 な 変 更 の コ ミ ッ ト が 消 え て し ま っ た」

*〜conflictを、軽率になかったことにしてはいけない〜*

月君は焦るあまり、resetの--hardで嫌な記憶を抹消してしまったのです。
そして抹消したのは嫌な記憶のみならず、重要な記憶すらも…

*〜そしてA先輩のもとへ〜*

**月君**「かくかくしかじかで、やらかしてしまいました:scream:」

**A先輩**「そろそろやらかすと思っていたよ:sweat:」

**A先輩**「そういうときはreflogでリカバリしよう」

**月君**「それはいったい！？」

reflogとは個人の環境に保存されている参照ログです。

```zsh
$ (moon_dev) git reflog
```

![スクリーンショット 2018-12-25 11.38.12.png](https://qiita-image-store.s3.amazonaws.com/0/129996/93eb5e6c-e93e-44e6-15dc-ca6fae42a123.png)

参照ログがつらつら出てきました。
なくなってしまった重要な変更コミットも存在しています。

**月君**「む、重要なコミットは７４１７ｃｄ２だな。」

復元にはresetでHEADを指定します

```zsh
$ (moon_dev) git reset --hard HEAD@{1}
```

<img width="530" alt="スクリーンショット 2018-12-25 10.59.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/129996/4bc83b44-3811-39ec-a4a7-9c4948c3008f.png">

**月君**「戻ったーーーーーーー！！！」

こうして肝を冷やした月君は、この反省を生かして今後も実力を延ばしていくのでした。

---

前編後編の事例は実体験だったり。。。
本番masterにpush -fしてCI走ってデプロイされた話も書こうかと思いましたが、
書いてる最中に胃が痛くなったので断念。

ちなみに私は現在の職場でGitを知りました。
それまではエクセルに差分記録して手動Mergeというレガシー通り越して化石な運用でしたね。

今回はストーリー仕立てにしましたが、Gitに関して一番参考にしたQiitaの記事は⇣だと思います
[Gitでやらかした時に使える19個の奥義](https://qiita.com/muran001/items/dea2bbbaea1260098051)

そんなこんなで2018年アドベントカレンダー終了。
来年もよろしくおねがいします！
失敗から学ぶ、ReactNative

#はじめに
この記事は[Android 初心者 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/android-beginner)の２５日目の記事です。
Qiitaへの投稿は初めてとなります。

ReactNativeを触り始めて累計約６ヶ月、**その時失敗した経験を伝え、
みなさんが同じ過ちを繰り返さないように、この記事を書かせていただきます。**
~~Android初心者やけどKotlin Javaの記事じゃないのかよ！ってツッコまないでね~~

#親子関係はシンプルにしよう。


###私の失敗
親子孫ひ孫、玄孫、、、、
みたいなコードを爆誕させ、そのページ担当時は自分でもギリギリ理解していた。
しかし一旦別担当に取り組んだ後、再びそのカオスコードを見ると、
わけがわからない、コメントも書いていたがそれを読んでも意味不明。
全てを一旦白紙に戻し、再始動。

###改善点
コンポーネント同士で値を受け渡しするには、必ず親子関係をシンプルに構築しよう。
**最大でも、親・子・孫の３関係程度でデータの受け渡しをしましょう。**
それ以上子を増やすと自分で理解するのが難しくなりますし、コードが煩雑になります。

#iOS、Android両方の機器で動作確認をしよう。
iOS、Androidそれぞれレイアウトや、動作が異なることがあります。

例えばTextInput
iOSはこうですが、
![iospict.png](https://qiita-image-store.s3.amazonaws.com/0/235364/b62d73cd-6ab0-a083-f162-90a80f00dea5.png)
Androidだとデフォルトではアンダーラインがひかれます。
<img width="300" alt="androidpict.png" src="https://qiita-image-store.s3.amazonaws.com/0/235364/c836e461-2328-7e68-7bdc-376b5077428d.png">



###私の失敗
iOSエミュレーターで動作を確認して、慢心していた私はAndroidで確認を取らず、
そして、β版発表前日に、Androidでは動作しない、
ましてや、メイン機能のレイアウトがそもそも表示してない事に気付き、
その日はほぼ寝ずに修正する事に

###改善点
**一つ機能を実装したら、両端末で確認を。**
経験上、iOSは割とガバガバ設計でも通ってしまう
そしてAndroidは厳密に設計しないといけない感じです。
じゃぁ確認全部Androidでしてたらよくね？って思うかもしれませんが、
逆もまた然りなので、ご注意を。

#正解は１つじゃない。
よくプログラミングの教科書で言われる言葉ですね。
本当にそう思います。１つの機能を実装するにも方法はたくさんあります。

###私の失敗
プロフィール画面とプロフィール編集画面を実装時。
無知だった私はまず、親子関係を無視して、
次にグローバル変数を自作ヘッダーに持たせて、
ニックネーム、自己紹介文などの値書き換えたらいいやんっって思って実装してたら、
グローバル変数危なスギィぃぃ！ってチームメンバーに注意され、
例によって例のごとく、担当部分、白紙化、再始動。
<img width="975" alt="スクリーンショット 2018-12-24 13.44.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/235364/51d35e8e-67f6-0dd9-935e-1f4fee1e9a5e.png">



###改善点
Profileという親に対して、
MyPrifile(プロフィール画面)・Edit_Profile(編集画面)の２つの子を持つようにした。
これによって編集画面で書き換えた値を親が保持し、プロフィール画面では親の値を表示する
<img width="744" alt="スクリーンショット 2018-12-24 14.26.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/235364/4511c744-9c3a-e6a5-80e2-2c8e66e1eb12.png">

**「こういう実装しよう」とアイデアが出たとしても
一度立ち止まり、「別の方法もないかな？」という自分に問いかけてみよう。**
またチームで製作している場合なら、
チームメンバーに相談するともっといいアイデアがもらえるかも！

#最後に
まだまだReactNativeの開発は続くので、また気づきがあればこの記事を更新していきます。
これにてQiita書込童貞卒業です。最後まで読んで頂き、ありがとうございました。
MonacaのPWAアプリをAmazon S3&CloudFrontで公開する

[Monaca Advent Calendar 2018 - Adventar](https://adventar.org/calendars/3073) & [PWA Advent Calendar 2018](https://qiita.com/advent-calendar/2018/pwa) の25日目です！

[Monaca](https://ja.monaca.io)でPWAアプリが開発できるようになりました。Service Workerなどがあらかじめ組み込まれたアプリケーションテンプレートがあるので、開発をすぐにはじめられます。

<img width="1513" alt="ScreenShot_ 2018-12-25 11.50.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/197026/3afa727f-9707-43c9-a80a-346380a096f8.png">

PWAとしてビルドした際、その内容はZipまたはFirebaseにデプロイできます。Firebase Hostingを使う場合にはこれで十分ですが、別なサービスを使うことも多いはずです。以前[GitHub Pagesへデプロイする方法は書きましたが](https://press.monaca.io/atsushi/3371)が、今回はAmazon S3とCloudFrontへのデプロイ方法を紹介します。

## 必要なAWSのサービス

AWSは一つのサービスで完結してくれないのが辛い…。ということで今回は以下のサービスを組み合わせています。

- **S3**  
HTML/JavaScript/CSS/画像などのリソース保存用
- **CloudFront**  
S3コンテンツをCDN配信するため。独自ドメインのHTTPS化
- **IAM**  
ターミナルからS3へアップロードするためのキーを生成
- **Route53**  
ドメイン管理
- **Certificate Manager**  
ドメインの証明書管理

S3のバケット、CloudFrontの設定、Route53でのドメイン設定、Certificate Managerでの証明書取得が終わっていることとします。一連の手順は[CloudFront で S3 静的ウェブサイトホスティングを SSL/TLS に対応させる ｜ DevelopersIO](https://dev.classmethod.jp/cloud/aws/tls-for-s3-web-hosting-with-cloudfront/)などが詳しいかと思います。

## Monaca IDEのターミナルで設定

Monaca IDEにはデフォルトでPythonが入っていますが、pipは入っていません。そこでインストールします（ターミナル機能はProプラン以上でないと使えないので注意して下さい）。

```
$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python get-pip.py --user
```

そしてコマンドのPATHを通します。

```
$ echo 'export PATH=/home/terminaluser/.local/bin:$PATH' >> ~/.bashrc
$ . ~/.bashrc
```

これで pip コマンドが使えるようになります。

### AWSコマンドのインストール

AWSをCLIで扱えるようにする awscli をインストールします。

```
$ pip install awscli --user
```

## AWS CLIの設定

IAMで生成したAWSキーを設定します。S3へのフルアクセスが必要です。

```
aws configure --profile=monaca
```

対話型のプロンプトが出ますので、AWSのキーを指定してください。

## コンテンツをアップロードする

ここまで準備ができれば、後はコマンドを打つだけです。syncコマンドで Monacaアプリの www ディレクトリとS3のバケットを同期してくれます。

```
aws s3 sync www s3://monaca.com2.io/ --acl public-read --profile=monaca
```

<img width="723" alt="ScreenShot_ 2018-12-25 11.52.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/197026/2ad69636-0d1a-0ad4-75ed-7eadce8429f5.png">

## まとめ

PWAの技術的必須要素にHTTPSが挙げられています。HTTPSでないとService WorkerやWebプッシュ通知は利用できません。また、キャッシュを使う際には基本的には静的サイトで開発されている方がお勧めです。そうした点からS3 + CloudFrontの組み合わせはありでしょう。

MonacaアプリをPWA化する際の配信先として、FirebaseだけではくS3 + CloudFrontやGitHub Pagesも検討してください！

# 追記

PWAに関するコミュニティを立ち上げました！第一回目のイベントは2月20日です、PWAが気になる方はぜひご参加ください！

https://pwanight.connpass.com/event/116944/
[論文メモ] Factorization Machines


# はじめに
* 他の論文を読むために読むので、まとめは雑です。
* [Factorization Machines](https://www.csie.ntu.edu.tw/~b97053/paper/Rendle2010FM.pdf)

# Introduction
* SVMがsparseなデータに対して上手くいかない理由を示す。
* tensor factorization modelの欠点として、
  * 標準的な予測問題に使えない。(予測値が実数など)
  * 個々のタスクに対して学習アルゴリズム等を設計する必要がある。
* この論文では新しい"Factorization Machine(FM)"という新しいモデルを提案する。
  * SVMのようにジェネラルな予測モデルであるがスパースなデータにも活用できる。
  * このモデルは線形の時間とパラメータで学習することができる。



# Factorization machine

## Factorization machine model
### Model Equation
* defree $d=2$ のFMのモデルは下記の数式で表すことができる。
  * 式(1) $\hat{y}(x) := w_0 + \sum_{i=1}^n w_i x_i + \sum_{i=1}^n \sum_{j=i+1}^n <v_i, v_j> x_i x_j$
* ここで学習対象となるモデルパラメータは
  * $w_0 \in R$
  * $w \in R^n$
  * $V \in R^{n \times k}$
* また$k$はハイパーパラメータ。
* $d=2$のFMは変数の単体とペアを捉えている。
  * $w_0$はバイアス
  * $w_i$ は $i$ 番目の変数の寄与度
  * $\hat{w}_{i,j}:=<v_i, v_j>$ は $i$, $j$ 番目の交差項の寄与度。
      * ここで $\hat{w_{i,j}}$ を直接学習させるのではなく、$v_i$ と $v_j$ を介して計算している。次元が大きくなると組み合わせ数が膨大になり $\hat{w}_{i,j}$ を直接計算するのは難しい。特にスパースなデータでは精度が下がる。

### Expressiveness
* 正定値行列 $W$ に対して$k$が十分に大きいとき、$W=V \cdot V^t$ となる$V$が存在する。
* つまり、$k$ が十分大きときにFMは任意の $W$ を表現することができる。
* しかし、スパースな状況ではデータが十分ではなく$k$を十分大きく取ることは難しい。

### Parameter Estimation Under Sparsity

### Computation
* 式(1)のまま計算しようとすると $O(k n^2)$ となるが、式変形することで線形の時間で計算することができる。
![スクリーンショット 2018-12-25 11.47.58.png](https://qiita-image-store.s3.amazonaws.com/0/199247/b1f98afe-0490-a0ed-7172-77c142612349.png)



## Factorization machine as predictor
* FMは様々な問題に適用することができる。
  * 回帰
     * 最小事情誤差を使って最適化する。
  * 2値分類
     * hinge loss や logit lossを使って最適化する。
  * ランキング
     * pairwise classification lossを使う
     * 詳しくは T. Joachims "Optimizing search engines using clickthrough data"
* どの問題でもオーバーフィッティングを防ぐためにL2正則化を行う。


## Learning Factorization Machines
* $\hat{y}$の微分は$O(1)$で計算することができる。
* 全て変数の更新は$O(kn)$、またはスパースのときは$O(k m(x))$。
* 実装は [LIBFM](http://www.libfm.org) で公開されている。


## d-way Factorization Machine
* ここまで紹介してきたFMは2次元だったが、簡単に$d$次元に拡張することができる。
Nyagos & GitBash でWindowsでも呼吸できる環境を作る

ドーモ、gakkiです。

ほとんどのエンジニアがWindowsでは呼吸ができない事は有名ですが､
それでもWindowsを使わないと行けない人向けの酸素ボンベです｡

# Nyagos
[Github zetamatta/nyagos](https://github.com/zetamatta/nyagos)

Go言語で書かれたLuaで拡張できるシェル

## 特徴
- UNIX風
- Luaで拡張できる
- Unicodeサポート

## UNIX風
- UNIX系の幾つかのコマンドが使える
- ヒストリが使える
  - `![ヒストリ番号]`で再実行など
- エイリアスを設定できる
- ファイル名/コマンド名保管
- パイプが使える
  - `$ pwd | clip`とすればカレントディレクトリのパスをクリップボードにコピーできる

## Luaで拡張
- LuaでBashの.bashrcや、スクリプトが記述できる

# GitBashのbinにPathを通すとどうなるの?
GitBashで使えるコマンドがそのまま使えるので実質ネイティブなBashになる

# Nyagosの設定ファイルでPathを通す
- ~/.nyagos にこんな感じのを書く (Winのホームディレクトリ配下)

```lua
function setSemicoron()
  local p = nyagos.env.PATH
  if p:sub(p:len()) ~= ";" then
    nyagos.env.PATH = p .. ";"
  end
end

function setPath(path)
  setSemicoron()
  local p = nyagos.env.PATH
  if not p:find(path .. ";") then
    nyagos.env.PATH = p .. path .. ";"
  end
end

setPath([[C:\Program Files\Git\usr\bin]])
-- [[]]で囲む文字列はエスケープされる
```

- 直接環境変数にPATHを通しても良いがPowerShellとか使うときに邪魔かもしれない

# まとめ
- これだけでかなりネイティブなBashっぽい環境を作ることができる
- WSLが結構進歩してきたので基本はそっちでよさそう
IntelliJ系列のIDEをしばらく使ってみた感想

ドーモ､gakkiです｡
珍しくJetBrainsがセールをしていてIntelliJの全部乗せパックを買いましたので､しばらく使った使用感をまとめてみます｡

# TL;DR
**最 & 高★💯💪**

# よく使ったツール
- WebStorm
- PyCharm
- IDEA
- ToolBox 

# 全体的に
- Eclipse等と比べると補完が軽量かつ想定通りの保管がでてきます
- ユニットテストの手助けも強く､ユニットテストファイルが自動で認識されて気軽にテストできる
    - テストが成功したメソッドにチェックマークが付くので修正箇所がわかりやすい
- Docker対応が強く､エディタ上GUIでビルドやComposeが操作できる
    - WinでもDocker for Windowsに対応できる
- GitのGUIクライアントになる
    - Diffが見やすくて結構高機能｡ブランチ変えるのとかワンクリック
- 個人的にはMaterial Theme UIを入れるといい感じ


# [ToolBox](https://www.jetbrains.com/toolbox/app/)
**必須｡今すぐインストールしなさい｡**
しばらくそれぞれのIDEを一つ一つ管理していたが､こんなものがあったのを知らなかった｡
愚行であった･･･

IntelliJツールすべてをこれ一つで管理できます｡
インストールからアップデートまでこれひとつ｡
全プロジェクトもまとめてくれてIDEを選ばずにプロジェクトを選択すると自動でそのIDEで開いてくれる｡
1分以内でインストールできるのでIntelliJツールを使うときは最初にインストールすること｡

# WebStorm
Node.jsが好きなのでよく使いました｡

- TypeScriptの型対応がすごい
    - 自動トランスパイル機能もある
- NodeだけじゃなくてHTML,CSS,Pug,Sass等も当然書きやすい
- package.jsonが扱いやすい
    - scriptsのコマンドに実行ボタンが付く
    - 使われるkeyが補完される
- `npm install`とかもコマンドライン開かずにやってくれる
- WinならWSL上のNodeを使うことができる
- moduleをGUI上でインストールできる
    - (内蔵ターミナルでインストールするほうが早いのかもしれないが)

# IDEA
競プロでKotlinを使ったり､MinecraftのMODやプラグインを作るのに使いました｡

- Gradleビルドを自動でやってくれたりGUIが見やすい
- ライブラリのインポートがGUI上でできる

# PyCharm
機械学習関係で使いました

- Pythonなのに型補完が効いていて書きやすい
- pipインストールがGUIでできる
- WSL上のインタプリタを利用できる
- numpy対応している

# まとめ
- 非常に高機能なのにそれなりに軽量
- まだ半年しか触っていないので機能を全然把握できていない
- C/C++/C#/Java/Kotlin/Go/Python/Javascript/Ruby/PHPなど主要な環境殆どが揃っている

# 購入 / インストール
- [サムライズムで購入](https://samuraism.com/jetbrains)
- [JetBrains](https://www.jetbrains.com/)
年の変わり目には気をつけよう

# はじめに
こんにちは。みんなのウェディングのインフラエンジニア[横山](https://twitter.com/tatsuo4848)です。
この記事は[くふうカンパニーアドベントカレンダー](https://qiita.com/advent-calendar/2018/kufu)23日目になります。
今回はDB連携ジョブフローの管理を[bricolage](https://github.com/bricolages/bricolage)から[digdag](https://www.digdag.io/)に移行するにあたり、週番号について考える必要があったのでそこで得た知見を共有します。

# 週番号
週番号では、その年の初めての週を第1週として、1週ごとに数えていきます。
52週または53週で1年となります。

# 2020年12月27日は第何週？？
この質問の答えは地域によって変わってきます。
例えば米国での数え方だとこれは2021年の第1週となります。

```javascript
moment.locale('en');
"en"
moment('2020-12-27').weekYear();
2021
moment('2020-12-27').week();
1
```

逆にフランスでの数え方だと以下のように2020年の52週となります。

```javascript
moment.locale('fr');
"fr"
moment('2020-12-27').weekYear();
2020
moment('2020-12-27').week();
52
```

さらにイスラエルなどのヘブライ語圏での数え方だと、2021年の第1週となります。

```javascript
moment.locale('he');
"he"
moment('2020-12-27').weekYear();
2021
moment('2020-12-27').week();
1
```

このような違いはその年の第1週をどのようなルールに則って定めているかによって生まれています。
ルールは以下の通りとなります。

| 米国 | フランス | イスラエル(ヘブライ語圏) |
|:---:|:-------:|:------------------:|
| 1月1日が含まれる週を第1週 | その年の最初の木曜日が含まれる週を第1週 | その年の最初の金曜日が含まれる週 |
※参考資料 https://www.toishi.info/email/week_calendar_2018.html

地域によってバラバラですね。
このようにバラバラだと国際取引において不都合が多いということでISO8601で標準化されています。
こちらのルールだと、フランスのように`その年の最初の木曜日が含まれる週を第1週`としています。

| 米国 | フランス | イスラエル(ヘブライ語圏) | ISO8601 |
|:---:|:-------:|:------------------:|:-------:| 
| 1月1日が含まれる週を第1週 | その年の最初の木曜日が含まれる週を第1週 | その年の最初の金曜日が含まれる週 | その年の最初の木曜日が含まれる週を第1週 |

特に理由がなければISO8601に規定された通り`その年の最初の木曜日が含まれる週を第1週`とするのが良いかと思います。
moment.jsには[isoWeekYear](https://momentjs.com/docs/#/get-set/iso-week-year/)、[isoWeek](https://momentjs.com/docs/#/get-set/iso-week/)があるのでこれを使うと良さそうです。
以下の通り`locale`が米国でも2020年の52週となります。

```javascript
moment.locale('en');
"en"
moment('2020-12-27').isoWeekYear();
2020
moment('2020-12-27').isoWeek();
52
```
私が考えるエンジニアリングマネージャー

自己紹介

この記事は[Engineering Manager vol.2 Advent Calendar 2018 ](https://qiita.com/advent-calendar/2018/em2)25日目の記事です。


株式会社レアジョブ　でエンジニアリングマネージャーをしていました。
去年の11月に1年のフィリピン出張を経て帰国し、今年春から新プロダクト開発のエンジニアチームのリーダーとして奮闘してきました。@yashioです。[チームギーク](https://www.amazon.co.jp/Team-Geek-%E2%80%95Google%E3%81%AE%E3%82%AE%E3%83%BC%E3%82%AF%E3%81%9F%E3%81%A1%E3%81%AF%E3%81%84%E3%81%8B%E3%81%AB%E3%81%97%E3%81%A6%E3%83%81%E3%83%BC%E3%83%A0%E3%82%92%E4%BD%9C%E3%82%8B%E3%81%AE%E3%81%8B-Brian-Fitzpatrick/dp/4873116309/ref=sr_1_1/357-0678899-3509625?ie=UTF8&qid=1543989851&sr=8-1&keywords=%E3%83%81%E3%83%BC%E3%83%A0%E3%82%AE%E3%83%BC%E3%82%AF)が好きです。

今年の締めくくりとしてマネージャーの役割ってこういうことかなあ、ということを書いてみたいと思います。簡単に概要を紹介します。

## チームとプロジェクトの背景

- 5-6名程度のチーム（多少の変動あり）
- サーバーサイドのAPI開発 サービス連携を伴う
- 新規プロダクト開発
- メンバー編成は過去にお仕事をしたことがあったりなかったり
- 連携調整する部署やチームが多いのが特徴（基盤、フロント、運用、協力会社、フィリピン子会社　などなど）
- プロダクトのゴールはあるが、仕様的なものはプロジェクト開始時に詰めていくスタイル

## その１調整し、俯瞰するひと
<img src="https://qiita-image-store.s3.amazonaws.com/0/12103/2b2a6883-ff8a-d05b-0956-1faedb1d50a3.png" width=50%>

つまり、、**「調整（おば/おじ）さん」！**
エンジニアリングマネージャーとは
チーム内に発生する「障害となる、なり得るもの」を見つけ解消していく、そこに尽きるのではないかと思います。具体的には以下のような役割の人かなと思います。:relaxed:ちょっとお節介？なニュアンスなのかもしれません。

- 人と人とで連絡をとりキャッチボールしないといけない問題を拾い停滞している問題を率先して消化
- 技術要件で手をさしのべる、あるいは助けてくれる（人/糸口/技術）を知っており解決策を教えてくれ
- （エンジニア的には生産的だと思えない）一部のタスクを率先して消化
- 「あれ、どしたの元気ないね」と声をかける

もう少し見栄えを良くすると・・・

1.チーム内の課題/相談に対して解決手段を講じる
2.チーム内で収束しない議論や方針で答えが見出せない時の先導
3.やるべきことを見える化
4.関係部署と連携・調整していく（粒度が荒いフェーズの仕様詰め、実装/テスト/本番構築のスケジュール、テストデータ/テスト仕様書整備/実施など）

    
## その2「意思決定」を早める
<img src="https://qiita-image-store.s3.amazonaws.com/0/12103/b418e09b-a806-5279-642f-d21925c5abc9.png" width=50%>

不確定要素が高い課題についてを相談された場合はできるだけ早めの判断をします。誰がきめてもいいのだけど、決めかねてる時には自分が決断する。「メンバーを迷わせない」というのは重要な役割です。それと・・・信頼関係がチーム内に醸造されていないフェーズでマネージャーがいつまでもその課題を抱えているとメンバーは何度も状況を確認しにくいです。
    
## その3「心理的安全」の維持
<img src="https://qiita-image-store.s3.amazonaws.com/0/12103/af1c8b1d-3da1-10a9-f634-c1f02245dc04.png" width=50%>


チーム内ではメンバーそれぞれ得意な領域がありアウトプットが出やすいところや挑戦してみたいところを尋ねてそれらをお任せするようにしていました。
正直にいうとこの規模でも開発の初期段階だと決めないといけない事が多く、この方法しか取れなかったという事実もあります。ただ結果的にチームの中でも「これを聞くのはXX さんだね」ということでお互いを尊敬する文化が醸造できたなと感じてます。対リーダーや対メンバーに限らずお互いを尊重し、意見を聞くという姿勢がチーム内にあることで「こんなこといってもいいのかな」という心理的要素をできるだけ排除することができたと感じられるようになりました。
  
## あとがき

昨今エンジニアリングマネージャーというワードがホットですが本当に役割の一つだと感じています。
が、一点。「調整さん」の役割は一部エンジニアにむいてないところもあると感じています。私自身もサーバサイドエンジニアである経験から、開発業務とやプロダクト開発と、調整業務というのは全く別の能力であるからと考えるからです。
自身の書くコードで戦える「開発業務」とチーム全体を一つの生き物ととしてとらえ、価値を最大化させることを常に念頭において立ち回る調整や「連携業務」は視点や注ぐ能力が異なるからです。

## 最後に

マネージャーをしていた、と過去形になってしまいましたが、年内でレアジョブを卒業し新しいチャレンジにむかいたいと思います！最後までよんでいただきありがとうございました。
チームのみんな！わたしは今でも一緒にお仕事できたことをとっても嬉しく思ってるし、いつかまた一緒に仕事ができるとおもっているよー！！またチャーハンたべよう！
Rational Performance TesterをMac OSに入れてみた



#前提
Rational Performance Tester 9.1.0をmacOS 10.12(Sierra)導入にする

#インストールメディア
Windowsと同じインストールイメージを用意する

#参考にした情報
インストール手順についてマニュアルの内容
https://www.ibm.com/support/knowledgecenter/ja/SSMMM5_9.1.0/com.ibm.rational.test.lt.install.doc/topics/t_start_install_launchpad.html

>.zip や ISO などの圧縮ファイルからインストールする場合は、ファイルを共通ディレクトリーに解凍します。 Common_Directory/RPT/disk1/Platform_Directory にナビゲートし、install.exe をダブルクリックします。

#途中困ったこと
- disk1の下にはプラットフォーム別のディレクトリがない。
- RPT_SETUP/InstallerImage_macosx_cocoa_x86_64/Install.app/Contents/MacOS/install　をダブルクリックしたら、ターミナルが起動したけど、「CRIMC1018E 管理者特権が必要です。」と怒られた。
root権限にsuしようとしたけど、sorryと返ってきてsuできなかった。

#最終的にやったこと

1. 管理者権限が必要なので、以下のリンク先を参考に、管理者を有効にする。
Mac でルートユーザを有効にする方法やルートパスワードを変更する方法
https://support.apple.com/ja-jp/HT204012
rootにsuできたことを確認。

2. GUIではroot権限で実行できなかったので、ターミナルに表示された以下のコマンドを実行した。
`RPT_SETUP/InstallerImage_macosx_cocoa_x86_64/install ; exit;`
【AWS】 ALB構成で動画配信

## はじめに

動画配信基盤は要件によって、様々な構成で環境構築しています。

今回は、ELBを使って配信動画ごとにインスタンスを分ける場合を考えてみます。
弊社では、下記のAWSリソースを使用して環境を構築していました。

・ **EC2（nginx + apache） - CLB - CloudFront**

ただ、これだとEC2台数分のCLBが必要になり、手間とコストがかかってしまうデメリットがありました。
調べてみると、CLBの代わりに**ALBの構成**が可能だと分かったので、試してみました。

## おさらい

ELB（Elastic Load Balancing）には、現在3種類あり、
それぞれ**ALB**, **NLB**, **CLB**と略されています。

**ロードバランサーの種類**

- Application Load Balancer
- Network Load Balancer
- Classic Load Balancer

[Load Balancer Types](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/load-balancer-types.html)
## 構成図

構成のイメージは下記のようになります。

ELBの数が少ない方が構築やメンテナンス時の設定変更の手間が減らせるので、
CLBからALBの構成に変更したいと考えています。

### ＜CLB構成＞

<img width="761" alt="スクリーンショット 2018-12-20 14.00.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/277934/67984e0d-6f13-9c42-ce84-36daf7b7d018.png">


### ＜ALB構成＞

<img width="833" alt="スクリーンショット 2018-12-13 17.46.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/277934/6acd7bab-d36a-f91d-5047-9b6b0e140dee.png">

## 振り分け

CLBからALBへの構成変更によって、パスを振り分ける場所が変わります。
これまではCloudFrontでしたが、ALBで振り分ける形になります。

### ＜CLB構成＞

CloudFrontのBehavior設定でURLの振り分けを行い、
オリジンである各ELBに流します。（最終的にはELBにアタッチしている各EC2へ）

### ＜ALB構成＞

CloudFrontでは、共通のALB（1台）をオリジンに設定し、
Target Groupで各EC2に振り分けを行います。

## Target Group

今回の場合で考えると、Target GroupはEC2の数だけ作成します。

上の構成図では大きな枠で表現していますが、
実際には、Target GroupとEC2は**１対1**で紐付きます。
<img width="103" alt="スクリーンショット 2018-12-25 10.42.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/277934/1726b482-9561-843d-f9a1-d97b6ce5634a.png">
ちなみに、Target GroupにEC2インスタンスを登録する際は、
ELBとは違って、**起動中のEC2インスタンス**しか画面に表示されないので注意が必要です。
<img width="1049" alt="スクリーンショット 2018-12-25 10.50.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/277934/0a72b921-6a50-a0da-e58a-9a831e2176b6.png">

## ALBリスナー

下記のような経路となるように設定します。

＜URL＞ ➡︎ ＜Target Group＞ ➡︎ ＜EC2＞

（例）

```
・　＜/testA/*＞　 ➡︎ ＜targetgroup-A＞ ➡︎ ＜EC2instance-A＞
・　＜/testB/*＞　 ➡︎ ＜targetgroup-B＞ ➡︎ ＜EC2instance-B＞
・　＜/testC/*＞　 ➡︎ ＜targetgroup-C＞ ➡︎ ＜EC2instance-C＞
```

（※振り分けURLは例ですので、各々のパスに読み替えてください。）
<img width="1086" alt="スクリーンショット 2018-12-25 10.57.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/277934/23e2af62-62bc-211d-848d-8fc49e17d6be.png">

※Application Load Balancerの細かな設定は、
「**ALB パスベースルーティング**」「**ALB URL 振り分け**」などで検索してみてください。

## CloudFront

OriginにALB（1台）を設定します。
![スクリーンショット 2018-12-25 11.13.29_m.png](https://qiita-image-store.s3.amazonaws.com/0/277934/81a57676-2795-efbc-64a0-0d91f48cc999.png)
## おわりに

元々のCLB構成の場合では、配信動画に対して1インスタンスの構成で割り当てていたため、
仮に3つの場合を想定しても、必要な設定を比較すると下記の表になります。

|  　　　　　　　　|CLB構成|ALB構成|
|:-----|-----:|------:|
| ELB数 | 3個 |1個|
| Target Group数 | ー |3個|
| CF Origin登録 | 3個 |　1個 |
| CF Behavior作成 | 3個 |　1個 |

ALB構成の場合だと、さらにインスタンスが増えた場合でも、
Target Groupを追加して、ALBリスナーに設定追加するだけでよいため、メンテナンスが楽になります。

ELBの使い方一つで、構成がシンプルになるので、
ELBを使った、動画配信基盤では**ALB構成**をお勧めします。
0xプロトコルと接続するためにGanacheのセットアップを行う

# モチベーション
0x.jsでganache-cliとやり取りを行うためのセットアップを行う。間違い、ご意見あれば[Twitter経由](https://twitter.com/WatanabeSota?lang=en)でご連絡ください。

# Ganacheを使ってセットアップを行う。
0x.jsを使ってEthereumネットワークと接続するためには、EthereumのノードでWeb3 Providerを指定する必要がある。開発環境では、Ethereum RPCクライアントとしてGanache Cliを使うのが良い。

<img width="1140" alt="Screen Shot 2018-12-25 at 11.14.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/327904/a7f1fc95-0502-186e-3e6d-3ca28238a03c.png">

**Ganache-cli**

<img width="710" alt="Screen Shot 2018-12-25 at 11.18.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/327904/6e7ba611-aeda-c7f5-3aae-ef6838cb5a5e.png">

Ganache-cliをロー間環境でダウンロードする。
`npm install -g ganache-cli@6.1.6`

0x v2のアップデートを使用するためには、Ganache-cliのsnapshotをダウンロードする必要がある。ダウンロードは[こちら](https://0x.org/wiki#Ganache-Setup-Guide)から。ダウンロード後、Zipファイルを解凍する。

ファイルを解凍したデヒレクトリー内で以下のコマンドを打つ。

```
ganache-cli \
--networkId 50 \
-p 8545 \
--db ./0x_ganache_snapshot \
-m "concert load couple harbor equip island argue ramp clarify fence smart topic"
```
ここで実行結果は以下のようになる。
<img width="1182" alt="Screen Shot 2018-12-25 at 11.26.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/327904/040c13f5-61d5-aa0e-211a-c61ed59d619d.png">

10個の新規アカウントと各アカウントに100ETHがあることがわかる。もちろんテストネットなので価値はない。

portを8545に設定したので、0x-starter-kitなどでZeroExにパスを通す際のWeb3 Providerとして`localhost:8545`を指定することができるようになった。

```javascript
const provider = new Web3.providers.HttpProvider('http://localhost:8545');
```

このパスを指定することによってHTTP通信を通して0x.jsでGanache-cliと通信を行うことができる。
elm-canvasでCanvas APIを使おう！

どうも

今日はクリスマスですね。いかがお過ごしでしょうか？
僕はこのアドベントカレンダーを急いで書いています。

突然ですが、elmでcanvas使いたくなるときありますよね。
ぼくはあります。

そこで、[elm-canvas](https://package.elm-lang.org/packages/joakin/elm-canvas/latest/)を紹介したいと思います。

# 導入方法
```
$ npm i elm-canvas
$ elm install joakin/elm-canvas
```

```js
// main.js
import 'elm-canvas';
```

or

```html
<!-- index.html -->
<head>
    <script src="https://unpkg.com/elm-canvas/elm-canvas.js"></script>
</head>
```

[ellie](https://ellie-app.com)で使いたい人はCDNからimportする方法でやりましょう。

# 使い方
`ImageData`を弄る系のAPI以外は提供されているので普通のcanvasのように扱うことができます。

## 矩形の描画
基本的なところからいきましょう。
矩形の描画は

```elm
rectRender : Renderable
rectRender =
    shapes
        [ fill Color.red ]
        [ rect (100, 100) 50 50 ]
```

こんな感じで書くと`座標(100, 100)`のところに`50 x 50`の矩形を`赤で塗りつぶし`て描画できます。

詳しく見ていきましょう。

基本となる関数は`shapes : List Setting -> List Shape -> Renderable`です。
`Setting`は主に塗りつぶし縁取りの色、移動・回転・拡大など見た目に関係する部分を扱います。`Html.Attribute`みたいな感じですね。
`Shape`は矩形や円、pathといった形の情報です。

これらを`shapes`関数に入れることで描画してくれます。同じ見た目になる形は1つの`shapes`関数で描画するといいようです。

## 円の描画
それでは、`座標(100, 100)`のところに`半径50`の円を`緑で縁取り`描画してみましょう。

上記の説明から考えると`List Setting`のところに`緑で縁取り`を`List Shape`のところに`座標(100, 100)のところに半径50の円`を入れたらよさそうです。

したがって、正解はこんな感じです。

```elm
circleRender : Renderable
circleRender =
    shapes
        [ stroke Color.green ]
        [ circle (100, 100) 50 ]
```

縁取りは普通のcanvasのように`stroke`でできます。
円は`circle`関数を使うことで表現できます。簡単ですね？

## ブラウザに描画
これだけでは描画はできません。htmlにしましょう。`toHtml`関数を使います。
`toHtml : Point -> List (Html.Attribute msg) -> List Renderable -> Html msg`となっているのでview関数の任意の位置に入れて上げましょう。

```elm
view : Model -> Html msg
view model =
    div []
        [ toHtml (model.width, model.height)
            []
            [ clear
            , render
            ]
        ]
```

みたいな感じ

# 注意点
このpackageはあくまでelm用にCanvasAPIを使えるようにしたものなので自分で画面の更新をしなければなりません。
画面の更新とは、前のフレームで描画しているものを消すことです。canvasには`clearRect`がありますがこのpackageにはありません。canvasの領域を任意の色で塗りつぶす関数を作って置くと便利でしょう。

さらに、`shapes`や`toHtml`の`Renderable`の順番は**描画の順番**です。
なので、上の例の`clear`と`render`を逆に書いてしまうと望んでいる結果にはならないでしょう。そこを考えてコーディングしましょう。

最後に、座標の指定が`(Float, Float)`のタプルです。この部分に関しては特に言いません。がんばりましょう。

# まとめ
この他にも`path`を用いた複雑な図形やテキストなどを描画することができます。
僕自身もこの記事のためにクリスマスっぽいものを作ろうと思ったのですが、記事を書こうとした8日前にこのpackageが更新されて仕様がまるっきり変わっていました。。。
混乱の元になるのでソースコードは載せませんが、できてあるものは載せたいと思います。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">雪降った <a href="https://t.co/T96cAgJ3zU">pic.twitter.com/T96cAgJ3zU</a></p>&mdash; うじまる🐣 (@uzimaru0601) <a href="https://twitter.com/uzimaru0601/status/1069520669178683392?ref_src=twsrc%5Etfw">December 3, 2018</a></blockquote>

まだすべての機能を触りきれていないので随時更新していきたいと思います。

更新前と更新後の変更としては、宣言的に書けるようになりました。おそらく、更新頻度が高いライブラリなので使うときはしっかりとドキュメントを読みましょう。

それでは、良いお年を:hand:
Change Mac Google IME keyboard japanese inputs setting FULLWIDTH to HALFWIDTH

# LEts Happy Hacking !

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/17060fa7-4276-9706-3132-be2c359d58b5.png)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【Django】DjangoJSONEncoderを使おう

## はじめに
nana musicでサーバサイドエンジニアをやっている@xKxAxKxです
この記事は[nana music Advent Calendar 2018](https://qiita.com/advent-calendar/2018/nana-music)の25日目の記事です
最終日だけど、時間無いので小ネタです

## DjangoJSONEncoderを使おう
Django REST frameworkでAPIを作るとき、レスポンスは大抵JSON形式でクライアントに返していると思う
その場合、基本的にSerializerを使って、レスポンスデータを返していることが多いと思うので、あんまり意識することがないと思うが、実はdatetimeなどは `json.dumps()` でjson形式にエンコードすることができない

```python:
import json
import datetime

data = { 'datetime': datetime.datetime.now() } 
json.dumps(data)
```
このようにやってしまうと、 `TypeError: Object of type 'datetime' is not JSON serializable` といったエラーが発生する
しかし、 `DjangoJSONEncoder` を使用すると、datetimeなども含めてエンコードしてくれる

```python:
import json
import datetime
from django.core.serializers.json import DjangoJSONEncoder

data = { 'datetime': datetime.datetime.now()} 
json.dumps(data, cls=DjangoJSONEncoder)
```
このようにすると、返り値として `'{"datetime": "2018-12-25T07:02:06.223"}'` といったJSONにエンコードされた形で取得することができる

## 参考リンク
[Serializing Django objects | Django documentation | Django](https://docs.djangoproject.com/en/2.1/topics/serialization/)
PWAを体験できるハンズオンコンテンツを公開しています

[PWA Advent Calendar 2018 - Qiita](https://qiita.com/advent-calendar/2018/pwa)の16日目です。

PWAの主な技術要素として、以下がよく知られています。

- Service Worker
- Webプッシュ
- CACHE API
- アプリ化

これらを自分で作りながら体験するのも良いですが、ハンズオンとして体験できるコンテンツを作成しました。こちらであればドキュメントを読みながら、徐々に理解度を深められるはずです。なお資料のライセンスはMIT Licenseになります。

[hifivemania/pwa_handson_docs](https://github.com/hifivemania/pwa_handson_docs)

以下、ハンズオンコンテンツの紹介です。

## 内容について

資料は大きく分けて3部構成になります。[第1章 アプリの説明](https://github.com/hifivemania/pwa_handson_docs/blob/master/1.md)は共通です。

### 第1部 アプリ化を体験する

マニフェストファイルを用いたアプリ化を体験します。

- [第2章 マニフェストファイルを作る](https://github.com/hifivemania/pwa_handson_docs/blob/master/2.md)
- [第3章 Service Workerのインストールと有効化](https://github.com/hifivemania/pwa_handson_docs/blob/master/3.md)
- [第4章 Service Workerを使った表示高速化、オフライン対応について](https://github.com/hifivemania/pwa_handson_docs/blob/master/4.md)

### 第2部　Todoアプリのオフライン化

あらかじめ作ってあるTodoアプリをオフライン化させます。

- [第5章 Todoの表示処理をオフライン対応させる](https://github.com/hifivemania/pwa_handson_docs/blob/master/5.md)
- [第6章 Todoの投稿処理をオフライン対応](https://github.com/hifivemania/pwa_handson_docs/blob/master/6.md)

### 第3部 WebPush通知を体験する

VAPIDプッシュ通知を用いてWebリモートプッシュを開発します。

- [第7章 Webリモートプッシュ通知を実装する](https://github.com/hifivemania/pwa_handson_docs/blob/master/7.md)

各部は独立していますので、途中（第2部など）から体験も可能です。

## ハンズオンについて

各ドキュメントは読めるように作ってあるので、自宅や仕事場で体験もできます。とはいえ仕事中に時間を確保して実施などは難しいかと思います。hifiveチームでは定期的にハンズオンイベントを開催していこうと考えていますので、ぜひご参加ください。案内は[hifive - connpass](https://hifive.connpass.com/)で行っていきます。

また、イベントスペースを確保いただければ私たちがハンズオン講師として参加することも可能です（無料）。条件としては以下のようになります。

- 10〜30名程度
- イベントスペース、電源必須（PCは各自用意）
- 誰でも参加可能（社内限定などは不可）

## 質問など

ハンズオン資料を体験してみて不明点があれば[Issues · hifivemania/pwa_handson_docs](https://github.com/hifivemania/pwa_handson_docs/issues)にて質問してください。

では良いPWAライフを！

# 追記

PWAに関するコミュニティを立ち上げました！第一回目のイベントは2月20日です、PWAが気になる方はぜひご参加ください！

https://pwanight.connpass.com/event/116944/
iOS Avoid duplicate view controllers with custom NavigationController

It is possible that duplicate view controllers may be accidently instantiated by the user. This is particularly a risk if the segue to a new view controller follows the response and processing of a REST request. 

If the view controllers are managed by a UINavigationController, we can modify its behaviour to avoid duplicate view controllers. This method assumes that only one instance of each View Controller class is allowed at one time.

First, we provide a identifier for each Object (and therefore View Controller) based on its class.

```swift
extension NSObject {
    var className: String {
        get {
            return NSStringFromClass(type(of: self))
        }
    }
}
```

Then we subclass UINavigationController and override pushViewController; this method will now permit a new view controller to be added to the stack if 
1. a view controller of this type does not already exist, and
2. another view controller is not already being added

```swift
class CustomNavigationController: UINavigationController {
    
    var isNewViewControllerBeingAdded: Bool = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }
    
    func contains(viewController: UIViewController) -> Bool {
        return self.viewControllers.map{ $0.className }.contains(viewController.className)
    }
    
    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        if(!self.isNewViewControllerBeingAdded && !self.contains(viewController: viewController)) {
            self.isNewViewControllerBeingAdded = true
            super.pushViewController(viewController, animated: animated)
        }
    }
}
```

We also extend this subclass with a delegate handler, which modifies the "isNewViewControllerBeingAdded" flag upon successful addition of a view controller.

```swift
extension CustomNavigationController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        self.isNewViewControllerBeingAdded = false
    }
}
```
[R]ggplot2で散布図を作成

散布図を書いてみたので、超基本的なところのまとめ

#環境
- Windows10 
- R：3.5.2
- Rstudio

#データセット（2018.txt）の一部

|順位|チーム|試合|打率|打点|平均|安打|
|:-----------|:------------|:------------|:------------|:------------|:------------|:------------|
|1|レッドソックス|162|0.268|876|5.41|1509|
|2|カブス|162|0.259|760|4.69|1450|
|3|インディアンズ|162|0.259|818|5.05|1448|

用いたデータセットは2018年のMLBのチーム打撃成績です。実際は30チーム分のデータセットがあります。

#データセットの読み込み

```r
table = read.table("2018.txt", sep="\t", header=T,encoding="utf-8")
```
タブ区切りなので今回は「sep="\t"」としました。

#パッケージのインストールと呼び出し
```r
install.packages("ggplot2")
library(ggplot2)
```

#散布図を書く
実際のコードの前にサクッと説明すると

```r
g <- ggplot(データフレーム, aes(x=x軸のカラム名,y=y軸のカラム名))
g <- g + geom_point()　#geom_pointは「散布図で書いてね」と指定するため
plot <- g
```
これに、データフレーム、xとy軸のカラム名を当てはめていく。
今回データフレームは「table」、x軸のカラム名は「順位」、y軸のカラム名は「安打」。

実際のコードはこんな感じ

```r
g <- ggplot(table, aes(x=順位 ,y=安打))
g <- g + geom_point()
plot(g)
```

###実行結果
![plot1.png](https://qiita-image-store.s3.amazonaws.com/0/326771/da991f05-a82b-de07-2198-19db3b14c633.png)

#ラベルを付けてみた
「ggrepel」というパッケージを利用することで、ラベルを付けることができる。
ラベルを付ける方法として「geom_text_repel」と「geom_label_repel」の2つがある。

##geom_text_repel

```r
library(ggplot2)
library(ggrepel)
g <- ggplot(table, aes(x=順位 ,y=安打, label=チーム))
g <- g + geom_point() + geom_text_repel()
plot(g)
```

追加したのは「library(ggrepel)」と 「label = チーム」と「geom_text_repel()」の3ヵ所

###実行結果
![plot1_label.png](https://qiita-image-store.s3.amazonaws.com/0/326771/f98a3ff1-c08b-c5ae-293e-95ce45c2fa3c.png)

##geom_label_repel

「geom_text_repel()」の部分を「geom_label_repel()」に置き換える

```r
library(ggplot2)
library(ggrepel)
g <- ggplot(table, aes(x=順位, y=安打, label=チーム))
g <- g + geom_point() + geom_label_repel()
plot(g)
```

###実行結果
![plot1_label2.png](https://qiita-image-store.s3.amazonaws.com/0/326771/ae2e2b5b-16a9-c947-8ad9-5d215dfaaa27.png)

###png形式として保存
pngとして保存する場合はpng関数を利用します。ざっくり説明すると、「タイトルとサイズを決める」→「グラフを描く」→「描いたものを閉じる」といった流れです。ちなみに、画像のサイズは決めなくてもできます。


```r
library(ggplot2)
library(ggrepel)
png("plot1_label2.png", width=1000, height=700)
g <- ggplot(table, aes(x=順位, y=安打, label=チーム))
g <- g + geom_point() + geom_label_repel()
plot(g)
dev.off()
```
【悲報】Twitterのパスワードリセットフローが緩くて複数垢の一致疑惑に使われてしまう＆対策

おはようございます。ritou です。

この記事はどっかのアドベントカレンダーではありません。

いわゆるお仕事中に真面目に Twitter をみている時に、こんな記事を目にしました。

[【速報】百田尚樹＝船木朱音説！？【電話番号下2ケタが一致】](https://rondan.net/9597)

気になるのは百田なんとか氏ではなく、この画像の方です。

## Twitterのパスワードリカバリーフロー

今回は Web のパスワードリカバリーフローを見ていきます。

![リカバリーフロー画面その1.png](https://qiita-image-store.s3.amazonaws.com/0/10192/1fc46c7a-1fa3-fd88-6bee-c5c097c2111b.png)

この画面で、**Twitterアカウント** 入れて進めてみます。今回は自分のアカウントで体はります。

![リカバリーフロー画面その2.png](https://qiita-image-store.s3.amazonaws.com/0/10192/7c6e3ad5-160b-1be5-d10a-f07421d11644.png)

これですね。
電話番号とメアドが登録されていたら、最後の2桁とかマスクされたメアドがすぐに表示されます。

今回はこの仕様により、電話番号一致？同一人物か？となっています。

一応回数制限はあるみたいですがIP変えたら行けるとかその辺でなんとでもなりそうです。

個人的には、登録済みの電話番号かメアドと一致するかを確認した上でリセットさせるべきじゃないかと思ったら、設定でできます。

![リカバリーフロー画面その3.png](https://qiita-image-store.s3.amazonaws.com/0/10192/f147a343-5a3d-097e-a5f6-d6aaf8dc68af.png)

定番ネタみたいになってる「ログイン認証」が気になりますが、今回はそこの下ですね。

![リカバリーフロー画面その4.png](https://qiita-image-store.s3.amazonaws.com/0/10192/ff103118-f149-6b95-08f9-09574d3b0806.png)

チェック入れて保存しましょう。

で、最初から同じことやると今度は

![リカバリーフロー画面その5.png](https://qiita-image-store.s3.amazonaws.com/0/10192/5e60f0b7-307a-c6b9-fecd-bcc5d458591e.png)

これならまぁ大丈夫かと思います。

気になった方は設定しましょう。

## まとめ

![まとめ.png](https://qiita-image-store.s3.amazonaws.com/0/10192/f888c65b-73f7-b2ac-f845-8cd00eab0f6b.png)

スクリーンショット含めた Tweet そのものじゃなくて文言だけ切り出して貼り付けるところが大人じゃない？
vmihailenco/msgpackの非互換に対応する

# [vmihailenco/msgpack](https://github.com/vmihailenco/msgpack)の非互換に対応する
Goで使ってる[MessagePack](https://msgpack.org/)のライブラリで非互換な更新があってそれに対応したメモです。

## そもそもの非互換
従来の挙動: 数値型を可能な限り小さい数値型表現で格納していた。
現在の挙動: [#198](https://github.com/vmihailenco/msgpack/pull/198)でデフォルトではGoの型に対応する数値型表現で格納されるようになった。

例で示すと:

```Go
var v int64 = 10
b, err := msgpack.Marshal(v)
// 従来: `b` は埋め込み整数型
// 現在: `b` はint64_t表現型
```

のような感じになっています。
テストで一応確認してたので、どうゆうわけかテストが失敗していて気づきました。

## 対処方法
```Go
var buf bytes.Buffer
var v int64 = 10
enc := msgpack.NewEncoder(&buf).UseCompactEncoding(true)
err := enc.Encode(v)
b := buf.Bytes()
// 従来どおりの `b` が生成されている
```

といった、 `msgpack.Encoder` を使った方法に切り替えます。
3行くらい増えるので若干めんどうになります。

## 総評とか
Goでの `Encode` / `Decode` 操作はストリーム型を使った方が効率的になることもあるので、たまには使ってみるのもよいかと思います。
長くなるのでめんどうですが。
kubectl で操作対象の Master を変える

小ネタ。
複数の k8s のマスターを kubectl で操作する場合にどのように操作対象のマスターを変えるという点について確認したのでメモ。

# まとめ

+ `~/.kube/config`の current-context を変えることで操作対象のマスターを変えている
+ context の変更は`kubectl config use-context`によって可能

# 環境

```bash
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.3", GitCommit:"2bba0127d85d5a46ab4b778548be28623b32d0b0", GitTreeState:"clean", BuildDate:"2018-05-28T20:03:09Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"11+", GitVersion:"v1.11.5-eks-6bad6d", GitCommit:"6bad6d9c768dc0864dab48a11653aa53b5a47043", GitTreeState:"clean", BuildDate:"2018-12-06T23:13:14Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
```

k8s のマスターは EKS を利用する。


マスターとの通信には認証が必要だが、この情報はデフォルトでは`~/.kube/config`を利用する。(環境変数`KUBECONFIG`で変えれる模様)

現状 kubectl を実行するとこんな感じ。

```bash
# 現在の context は eks-first-cluster
$kubectl config current-context
arn:aws:eks:ap-northeast-1:xxxx:cluster/eks-first-cluster

# ファイル上も同じ
$cat ~/.kube/config |grep current-context
current-context: arn:aws:eks:ap-northeast-1:323817733012:cluster/eks-first-cluster


# worker node が存在する
$kubectl get nodes
NAME                                              STATUS    ROLES     AGE       VERSION
ip-172-31-0-56.ap-northeast-1.compute.internal    Ready     <none>    4d        v1.11.5
ip-172-31-19-51.ap-northeast-1.compute.internal   Ready     <none>    4d        v1.11.5
ip-172-31-23-75.ap-northeast-1.compute.internal   Ready     <none>    4d        v1.11.5

```

# マスター情報を追加して context を変える

上記状態でマスター(eks-second-cluster)を別途作成し、kubectl で操作する。
`~/.kube/config`への設定追加は`aws eks update-kubeconfig --name cluster_name`で実施。
これによって`~/.kube/config` に追記が実施され、kubectl　によって操作するマスターが変わった。
より具体的には current-context が新規に作成したマスターになっていた。

```bash
# context が変わっている
$kubectl config current-context
arn:aws:eks:ap-northeast-1:xxx:cluster/eks-second-cluster

# config ファイルも変わっている
$cat ~/.kube/config |grep current-context
current-context: arn:aws:eks:ap-northeast-1:xxx:cluster/eks-second-cluster


# eks-second-cluster には worker node がない
$kubectl get nodes
No resources found.
```

操作したいクラスターを変えたい場合、`kubectl config use-context`で変更出来る。

```bash
# context を変える
$kubectl config use-context arn:aws:eks:ap-northeast-1:xxx:cluster/eks-first-cluster
Switched to context "arn:aws:eks:ap-northeast-1:xxxx:cluster/eks-first-cluster".


$kubectl get nodes
NAME                                              STATUS    ROLES     AGE       VERSION
ip-172-31-0-56.ap-northeast-1.compute.internal    Ready     <none>    4d        v1.11.5
ip-172-31-19-51.ap-northeast-1.compute.internal   Ready     <none>    4d        v1.11.5
ip-172-31-23-75.ap-northeast-1.compute.internal   Ready     <none>    4d        v1.11.5
```

なお、shell autocompletionを入れておくと `kubectl config use-context`実行時に tab で設定変更可能な context が分かるので便利。

[Enabling shell autocompletion](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion)

公式ドキュメントとしては以下辺りが参考になりそうなのであとで見ておく

[Configure Access to Multiple Clusters](Configure Access to Multiple Clusters)