OmniAICreator/Qiita-1.07M huggingface dataset:
ログアウトができない　No route matches [GET] "/users/sign_out"

#ログアウトができない、、、
Edit Accountのログアウトボタンを押すと、 
<img width="1018" alt="スクリーンショット 2019-06-06 19.55.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432050/2de17f1f-0b1b-faef-2c60-3bad397c69e7.png">
No route matches [GET] "/users/sign_out"とgetに飛んでしまっている、、、
<img width="789" alt="スクリーンショット 2019-06-06 19.41.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432050/9e9ac359-e6c9-983b-fdbf-dd8059e52c45.png">

#やったこと

ルーティングを確認！
<img width="657" alt="スクリーンショット 2019-06-06 20.00.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432050/442f611d-b323-699a-46d7-63d208a01ad3.png">

そうdeleteに飛びたいの、、、

ビューを確認！

<img width="703" alt="スクリーンショット 2019-06-06 20.01.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432050/17d70ffb-482b-b232-c8c0-964c796c7468.png">

あれ、ちゃんと記述できている。。

#解決しました！！（解決策）

下記記述をapplication.jsの１２行目に記述するだけ！

```
＊app　assets　javascripts　application.js＊

//= require jquery
//= require jquery_ujs
```

#jquery-ujsといのが鍵！
link_toで生成されるリンクはGETリクエストだけになってしまう
（make non-GET requests from hyperlinks;　https://github.com/rails/jquery-ujs/blob/master/README.md）
しかしjquery-ujsを使うとGETリクエスト以外も使えるようになる

結果、ログアウトを無事に行うことができました！

<img width="1149" alt="スクリーンショット 2019-06-06 19.47.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432050/36f6393d-02b7-ff7c-7591-2443d7104a9d.png">
JSONと向き合う時にお世話になったブログ・記事

感謝と尊敬の念でいっぱいです。

【Java】JSONデータを標準API、Jackson、JSON in Javaで扱う方法
https://www.sejuku.net/blog/39599

Java 向け JSON ライブラリ Jackson でデータを読み込む
https://blog.kymmt.com/entry/jackson

Java JacksonでJSONとJavaオブジェクトを変換するサンプル
https://itsakura.com/java-jackson

URLConnection(HttpURLConnection)と向き合おう~GETメソッドでデータを取得する~
http://blog.officekoma.co.jp/2016/07/urlconnectionhttpurlconnectionget.html

【Java】YahooAPIの商品検索を実装してみた
https://qiita.com/tosuu/items/b440ad3f3cbf7c4b8396
BOM付きのhtmlをBOM削除させる方法

### BOM削除する方法について調べた結果
色々調べたが、結局たどり着いたのが
`nkf` というbrewでインストールするもの（そこまでbrewは把握していないのでご了承ください）
※昔見ていたら、nkfってなんやねん！！ってきっとなっていたが、自然とbrewだろうな、、、と予測できた自分に感動しています



さて余談はおいておき本題へ
まずbrewでnkfをインストール

`brew install nkf`
`nkf --version` でインストールされているかチェック

## BOMかどうかの判断
`file index.html` とか(基本tabでぽんぽん打てば調べられる)

調べるとこんな風に表示される（例）
`index.html: HTML document text, UTF-8 Unicode (with BOM) text`

`nkf --overwrite --oc=UTF-8 index.html`
とかやると消える

`index.html: HTML document text, UTF-8 Unicode text`


## まとめ
他に多分オプションの設定とかあるんでしょうが、一旦これでできたっぽいのでメモとして保存
text-to-speech の前処理のメモ

自前で text-to-speech したい場合, テキスト(transcript)の前処理が必要になるケースがあります.

英語を想定します.

たとえば `42` -> `forty-two` など(こういうのを全体的に何と呼ぶのかはわかっておりませんが, keithito tacotron では cleaner という呼び方をしていますね)

keithito's tacotron の `text/clearner.py` が参考になります.

https://github.com/keithito/tacotron

既存の tts サービスなどはこのあたりを対応していますね.


## 数字の展開

Python ですと `inflect` ライブラリがあります(keithito tacotron も inflect を呼んでいる)

https://pypi.org/project/inflect/

## 短縮形の展開

`Dr.` -> `doctor` など. いくつかは keithito tacotron で自前でやっています. 

`You've` -> `You have` など. `contractions` ライブラリがあります.

https://stackoverflow.com/questions/19790188/expanding-english-language-contractions-in-python


## その他参考になりそうなもの

spaCy で全部よろしくやってくれるかしら? https://spacy.io/

https://pypi.org/project/lemminflect/

突き詰めると NLP の世界になってきますね.

## TODO

* spelling correction
* 数式を word に展開したい(`1/3` -> `one over three` など)
* C++ で実装されたのほしい
各国のEnsemblサーバーの通信状態を確認

Ensemblはバイオインフォマティクスで利用される代表的なデータベース。
https://bi.biopapyrus.jp/db/ensembl.html

自分の開発したscTensorパッケージも、遺伝子ごとの各種機能アノテーションを取得する際に、内部でbiomaRtパッケージを利用して、Ensemblにアクセスしている。
https://bioconductor.org/packages/release/bioc/html/scTensor.html

Ensemblは世界中で4箇所にサーバーが設置されているが、
https://ensembl.org/info/about/mirrors.html

先日、本部のサーバー（UK）が調子が悪かったらしく、それに伴いscTensorも正常に実行されなかった。
https://support.bioconductor.org/p/121331/

scTensorでは、biomaRtパッケージのuseEnsembl関数を使ってるが、この時に、mirrorでどのサーバーを利用するかを指定できるらしい。

何も指定しないと、本部のサーバーに繋がるらしい。

とりあえず、今現在どのサーバーが遅いのかは、以下で確認できると思う。

```{r}
library("biomaRt")

# UK (Sanger Institute)
system.time(mart <- useEnsembl(biomart = "ensembl", 
	dataset = "hsapiens_gene_ensembl", 
	mirror = "www"))

# US East (Amazon AWS)
system.time(mart <- useEnsembl(biomart = "ensembl", 
	dataset = "hsapiens_gene_ensembl", 
	mirror = "useast"))

# US West (Amazon AWS)
system.time(mart <- useEnsembl(biomart = "ensembl", 
	dataset = "hsapiens_gene_ensembl", 
	mirror = "uswest"))

# Asia (Amazon AWS)
system.time(mart <- useEnsembl(biomart = "ensembl", 
	dataset = "hsapiens_gene_ensembl", 
	mirror = "asia"))
```
ESP32にNode-REDから文字列を送りOLEDへ表示するデモ

# 概要
 
　映画やドラマで、突然パソコン画面にハッカーからのメッセージが表示されるシーンがありますよね。

「お前は狙われている」「Hi, ○○○.」
 
 今回は映画「マトリックス」で、主人公 ネオが自室で寝ているときパソコンに表示されたメッセージを再現してみました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">もくもく会進捗その2。<br>メッセージの追加と、トリガ一回でメッセージを送るように自動化してみました。<a href="https://twitter.com/hashtag/PLY?src=hash&amp;ref_src=twsrc%5Etfw">#PLY</a> <a href="https://twitter.com/hashtag/Arduino?src=hash&amp;ref_src=twsrc%5Etfw">#Arduino</a> <a href="https://t.co/s5fOco3yAN">pic.twitter.com/s5fOco3yAN</a></p>&mdash; まえぷー (@kmaepu) <a href="https://twitter.com/kmaepu/status/1136230561356308480?ref_src=twsrc%5Etfw">2019年6月5日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


※「白うさぎを追え」は実装忘れていました(￣▽￣;) 
 
# 技術的な話 
　構成はこんな感じです。

 ![新規 Microsoft PowerPoint プレゼンテーション.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/d4f0f888-29e5-b8bf-7bf2-e754ea980f5d.jpeg)
　基本的な処理は次の通りです。
・ESP32マイコンにtelnetサーバを立てています。
・telnetで文字列をESP32に送ると、OLEDに表示されます。
・文字表示を遅らせているのは、ESP32側で処理しています。
・受け取った文字列を250ms間隔で１文字ずつ表示しています。
 
　telnetで文字列送信処理にNode-REDを使用しました。
Node-REDについてはこちらを参照して下さい。

　Node-RED日本ユーザ会
　　https://nodered.jp/

　Node-REDで、ボタンを押すと文字列をtelnetで送信するフローを作成しました。
フローは次の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183282/04cd92e7-8dd1-e249-f340-72de09dc7f7b.png) 

# おわりに
　この作品はArduinoファンもくもく会＃034に参加した成果物です。面白い作品を制作している方が多く興味を引くものばかりでした！
　以下の記事に、主催の方がもくもく会の様子をまとめて下さっています。
 
https://l-w-i.net/m/20190605_01.txt?fbclid=IwAR0zaETCWDQwJheMr9cT4O7qbJ99ScndiPbVPRqk1hO4nggLt7XN6yKoyGM
SharePoint OnlineにG Suiteユーザーを招待する

SharePointにはテナント外のユーザーを招待する機能がある。組織外のユーザーとのファイル共有に便利なので、使っている組織も結構あるんじゃないか、と思う。

ただ、招待できるのが「組織ユーザー（Office365か、AzureADのユーザー）」か、「マイクロソフトアカウント」だけ。G Suite使っている組織もあるので、招待できたらいいのにな・・・。

ちょうどそんなときに、国井さんの[GoogleアカウントでAzure ADにサインイン](
http://azuread.net/2019/05/09/google-signin/)という記事をTwitterで見かけた。Azure AD B2Bで、GoogleアカウントやG Suiteアカウントでログインできるようになる。これ使えば、SharePointのゲストとして招待できるんじゃないか、ってことで試してみた。


流れは、こんな感じ。
Azure AD B2Bでgoogleアカウントに招待できるよう設定
Azure ADのゲストユーザーとして招待
SharePointのサイトに招待

#Azure AD B2Bでgoogleアカウントに招待できるよう設定

詳しい手順は上記の記事がとても分かりやすいので、そちらをみてほしいです。この手順通り私も実施しました。


#Azure ADのゲストユーザーとして招待

いきなりSharePointに招待するのではなく、いったんAzure ADのゲストユーザーとして招待します。Azure AD管理センターで新規作成→ゲストユーザーでメールアドレスを入れて、招待します。
この時点では、ソースは招待中になっています。

ユーザー宛に招待メールが届いているので、リンクを開いて承諾してもらいます。
Azure AD上のソースが、「外部のAzure Active Directory」になっています。

#SharePointのサイトに招待

そうしたら、対象のSharePointサイトから、招待しましょう。これで完了です。

ゲストユーザーを初めて招待する際は、招待メールが届き、ユーザーが承諾することが必須です。しかし、先の手順ですでにAzure AD上にアカウントが作成されているので、即時アクセス権が付与されます。

#まとめ

ゲストユーザー管理には、フリーで作成できるコンシューマー向けのアカウントである、マイクロソフトアカウントよりも、Office365やG Suiteのように組織で管理しているアカウントのほうが何かと安全で、かつ利便性も高いです。

AzureADでの招待が先に必要とはいえ、G Suiteユーザーが招待できるのは使える機能と思います。
コーディングする上で気を付けていること

##はじめに
新卒でSIerに入社し、現場に配属されてから2年弱。
チームメンバーからのソースレビューなどで養ってきた観点をメモとして残しておきます。
『こんなとこも意識したほうがいいよ』とかあれば教えてください。

##コーディング
- 運用面を意識した実装となっていることを確認する。
 - 必要なログが出力されているか（アクセス開始ログ、アクセス終了ログ、トランザクションIDとか）
 - 画面の表示文言など、頻繁に変わることが想定されるものが影響範囲少なく変更が容易にできるか<br>
 ⇒マスタで管理する 等
 - 適切なエラーハンドリングとなっているか<br>
 ⇒ユーザー目線で何をすれば良いのかわかるエラーメッセージが表示されていること
 ⇨いつ、どの処理でエラーが発生した場合に、誰に知らせるか決めていること（アラートメールを飛ばしたり）
- コメントが適切か
 - 半年後の自分が読んでも理解できること
- コピペするときには以下を注意
 - コピペ元とコピペ先で環境面の違いによる影響はないか
-命名が適切か
 -処理内容とメソッド名が剥離していることがないように。 
-責務配置を意識できているか
 -Modelでは業務ロジックを、DAOではDBアクセス部分を　というようにチームで合意した責務配置を意識してコーディングを行う

##DB周り
- 適切なインデックスが貼られているか
  - 検索対象キー項目に対して貼る<br>
  ※但し、インデックスを貼るのは性能が向上することが期待できる時のみ（むやみやたらに貼らない）

##その他
- 外部に開発依頼をする必要がある場合に、外部の開発手法を確認する。<br>
  特に外部がウォーターフォール開発の場合は、結構期間がかかる場合があるので注意する。<br>
例）
A社は、アジャイル開発。<br>
　　 B社は、ウォーターフォール開発。<br>
　 　ある日A社が、○○という情報を参照する機能を作ることになった。<br>
　　 そこで、今までも使っている既存APIに○○という情報の追加をB社へ依頼することになり、<br>
　　 スケジュール感を確認した。<br>
　　 「今からだと3か月作成かかりますね。」<br>
　　 ん・・・？3か月とは想定外。<br>
　　 スプリント内に終わらなさそう。他のストーリーやろっと。
 
-思い込みを捨てる。
rails s エラー #自分メモ

Githubからクローン後､
$rails sでエラー｡

【エラーメッセージ】
Could not find concurrent-ruby-1.1.5 in any of the sources
Run ｀bundle install｀ to install missing gems.

$bundle install を実行

【エラーメッセージ】
An error occurred while installing pg (1.1.4), and Bundler cannot continue.
Make sure that ｀gem install pg -v '1.1.4' --source 'https://rubygems.org/'｀ succeeds before bundling.

$brew install postgresql を実行

【ブラウザ エラーメッセージ】
Migrations are pending. To resolve this issue, run: bin/rails db:migrate RAILS_ENV=development

$bundle install --without production を実行 (サーバー立ち上がりました！)

$rails db:migrate を実行

これでエラー解消できました｡
jQueryのhtml()でコードを書き換えたあとにコードが変わっている？

#概要
HTMLが同一かを判断するのに、以下のようなコードを書いていたら、うまく判定できなかったので、検証したメモ。

```javascript
var str = 'something html code';
if($('#target').html == str){
  // same code??
}

```

CODEPENで検証用のコードをざっと書きました。
テキストエリアにHTMLをかいて「CHANGE」ボタンをクリックすると適用され、アラートで同一か違うか表示されます。
違う場合は、取得されたHTMLコードがアラート表示されます。
<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="tsunet111" data-slug-hash="RmmJyZ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Is the HTML code changed after jQuery html() ?">
  <span>See the Pen <a href="https://codepen.io/tsunet111/pen/RmmJyZ/">
  Is the HTML code changed after jQuery html() ?</a> by Tsuneaki Hasekura (<a href="https://codepen.io/tsunet111">@tsunet111</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

##検証結果
入力テキスト
一致したか（same or not same）
一致していない場合に取得されたコード
の順で記載しています。

```
テキストTEXT
//same

テキスト<br>TEXT
//same

テキスト<br/>TEXT
//not same
//テキスト<br>TEXT

<p class='sample'>あああ</p>
//not same
//<p class="sample">あああ</p>

<h1>サンプル</h1>
//same

<h1>サンプル<h1>
//not same
//<h1>サンプル</h1><h1></h1>

サンプル<>
//not same
//サンプル&lt;&gt;

```

##さいごに
ブラウザによってコードの解釈が異なり、動作の差異があるようです。
[Vue.js]Vue.jsでLocalStrageを使う

### src/plugins/VueLocalStrage.js

```javascript

export default {
  install(vue) {
    vue.prototype.$storage = {
      get(key) {
        // localstrageからとる
        return localStorage.getItem(key)
      },
      set(key, value) {
        // localstrageへ保存
        localStorage.setItem(key, value)
      },
    }
  },
}

```

### 使うところ

```html

<script>

/////////////// 省略 ///////////////

methods: {
  setLocalStrage(){
        // ローカルストレージに値を保存する
        this.$storage.set('email', this.email)
  },
  sgtLocalStrage(){
        // ローカルストレージに値を取得する
        this.$storage.get('email', this.email)
  },
}

</script>

```
ELBを利用したEC2インスタンスに、Djangoをデプロイする際のHOST問題

# ホスト名を記述しておかないと、アクセスできない件
この場合、下記２点を予めsettings.pyの`ALLOWED_HOSTS`に記載しないとアクセスが拒否される現象が発生します。

- ELBの`DNS name`
- EC2の`Private IPs`

ちなみに、ELBのDNSを独自ドメインで利用する場合(CNAMEを使用）、そのドメイン名を`DNS name`の代わりに記入する必要があります。（例：お名前ドットコムのドメイン名を使用したい）

```python:settings.py
ALLOWED_HOSTS = ['ELBのDNS', 'EC2のprivateIP']
```
Ubuntu18.04 + bitnami Redmineで楽して作るお手軽Redmine環境


「今日から新しいプロジェクトが始まりますね、よろしくお願いします」
「はい」
「私はよくわからないのですが上からRedmineで管理しろと言われました。
　**プログラマのあなたなら環境構築出来ると思う**のでよろしくお願いします」
「」

という状況に遭遇しても死なない為のサバイバルガイドです。

# この記事の対象者

* なるべく楽に環境構築したい人
* 最低明日にはRedmineの環境が出来てないと色々とアレな人
* Redmine入れるOSがたまたまUbuntu18.04だった人

# 前提条件

* Ubuntu 18.04 LTS構築済み

# 構築手順

楽に構築する事を主眼に置いてますので、[bitnami](https://bitnami.com/stack/redmine/installer)を用いてRedmineを構築します。

※本記事ではbitnami-redmineのバージョンは3.4.3-1を使っています。
別のバージョンが必要な人はそれぞれ読み替えて下さい。

### 1. インストーラーの取得

```bash
sudo wget https://bitnami.com/redirect/to/164047/bitnami-redmine-3.4.3-1-linux-x64-installer.run
```
### 2. 取得したインストーラーの権限変更

```bash
sudo chmod 0755 ./bitnami-redmine-3.4.3-1-linux-x64-installer.run
```

### 3. インストールを実行

```bash
sudo ./bitnami-redmine-3.4.3-1-linux-x64-installer.run
```


・・・お手軽ですね。

実際これだけですが、一応インストーラーをコマンドラインで実行した際の流れを以下に記します。

#### Please select the installation languge
![Image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324639/e83d3de2-5c91-5a4c-2a16-89bca734fc42.png)

言語が9個から選べますが3を選択。

#### ソフト選択

Subversion
→n
PhpMyAdmin
→n
Git 
→n


今回はRedmineのみインストールするので全てNで。
環境によっては既にインストールされている場合もあるので、その辺りは柔軟に対応して下さい。

#### Bitname Redmine Stack をインストールするフォルダ
→/opt/redmine-3.4.3-1(デフォルト)

どうしてもこだわりがある人は別の場所で。

そのままインストールまでは必要な情報（アカウント等）を入力してインストールを続行します。

![install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324639/0415c348-c86b-ef62-4be0-efc10aa8c3ba.png)


最後にアプリケーションの起動でYを選択してRedmineの起動を行います。

![redmine_login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324639/7a575091-5da3-a2ff-9b3f-93447f695d25.png)


インストールが成功していれば、上記画面が表示されるはずです。
簡単ですね。
MacでUSキーボードの左右Cmdを英/かな設定した際のことえりバグを回避する

##### 環境：
MacBookPro（10.13.6｜US） + 外付けWinUSキーボード
MacBookPro（10.13.6｜JIS） + 外付けWinUSキーボード
MacBookPro（10.13.6｜JIS） + 外付けMacUSキーボード
##### 問題：
USキーの左右Commandキーを英数/かなに変更して文字入力していると、不可視文字が入力されていることがある。これを回避する。
##### 原因：
Command/Control/Option/Shift + EISSU もしくは、Command/Control/Option/Shift + KANA の入力で、不可視の0x08（バックスペース）の制御コードが挿入される。
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85559/c860b117-8708-6c8e-c1fc-17ba2eb214dd.png)
これはMacOSと、ことえり（日本語IM）のバグでかなり前からあるけどずっと解消されていない。とのこと。
https://blog.right-apps.com/develop/2018/post-62/
http://kawaken.hateblo.jp/entry/2018/04/02/234339
##### 解決法：
Karabiner-Elements の complex_modifications で調整する。

---

Karabiner-Elements をインストールし、一旦キー配列のみ変更。
https://pqrs.org/osx/karabiner/ （記事時点では、v12.4.0）
##### ▼ キーリマップ
キーボードDIPスイッチ： 左Alt ←→ 左Command （入れ替え）
Karabiner-Elements： 右Alt → 右Command　
![スクリーンショット 2019-06-06 19.16.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85559/e30795f2-325f-e2bb-8cbe-93f034458e6d.png)

##### ▼ complex_modifications での調整
https://pqrs.org/osx/karabiner/complex_modifications/
↑ここから、 For Japanese （日本語環境向けの設定） (rev 4) をダウンロードしてインストールして使っていたのですが、デフォルトの設定だと、 Control/Option/Shift + Command の一度押しで、0x08（バックスペース）の制御コードが入力されてしまう。
![スクリーンショット 2019-06-06 19.19.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85559/9bf783ed-5268-9112-7574-35c46bd3913a.png)


設定をよく見ると、modifiers でほかのキーを押している状態でも、コマンドの1回押しで数・かなキーが送られるようになっていた。modifiers を丸っと削除したところ、不可視文字の入力を回避することに成功。


<b>デフォルト<b>

```
          "from": {
            "key_code": "left_command",
            "modifiers": {
              "optional": [
                "any"
              ]
            }
          },
```

<b>調整後</b>

```
          "from": {
            "key_code": "left_command"
          },
```

以上。同じ状況で困っている人の参考になれば幸いです。


メモ

##### ▼ 自分の環境でのMacUSキーの左右Commandキーを英数/かなに変更する方法の変遷。

1. KeyRemap4MacBook（~10.8）
2. Karabiner（~10.11） [このKarabinerにはこのバグをFixするアセットがデフォルトで入っていたのですが、Elementsだと無い。]
3. ⌘英かなApp[https://ei-kana.appspot.com/] （~10.12）
4. Karabiner-Elements（~10.13）

参考リンク
https://qiita.com/s-show/items/40ad22c4ee4a0465fad5
https://qiita.com/nekoneko_mon/items/4450646fe1dbb052bd6c

##### ▼ しかしながら、option+control+記号以外の文字 で DEL が入力される問題は解消できず…。
https://qiita.com/usagimaru/items/2002e85c2f874ec682fd

##### ▼ 追記
MacBookPro側のキーボードが JISキーの場合、Karabiner-Elements が立ち上がっていると、USキーとして認識されてちょっとパニクる。
→ Karabiner-Elementでコントロールしたい外部キーボード以外を、Devicesから外してあげるとうまくいく。
![karabiner_E_LEO98_4_Devices.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/85559/beafdbbe-bd7f-179e-199a-023ac3b9cef8.png)
データベースの基本1(MySQL)

##CREATEでテーブルを作る
基本式：`CREATE TABLE テーブル名 (カラム1 型, カラム2 型, ...);`
###例

```sql
CREATE TABLE my_items (id INT, item_name TEXT, price INT);
```
##INSERTでデータを挿入する
`SET`を使った書き方と`VALUES`を使った書き方がある
基本式：
`INSERT INTO テーブル名 SET カラム名1=値, カラム名2=値, ...;`
`INSERT INTO テーブル名(カラム名1, カラム名2, ...) VALUES (値1, 値2, ...);`
###例

```sql
INSERT INTO my_items SET id=1, item_name='レモン', price=500;
INSERT INTO my_items(id, item_name, price) VALUES (1, 'レモン', 500);
```

##UPDATEでデータを変更する
条件文がでてきます。ここが最も難しく、しかしパワフルな部分です。とりあえず基礎を。
基本式：`UPDATE テーブル名 SET カラム名1=値, カラム名2=値, ... WHERE 条件文;`
###例

```sql
UPDATE my_items SET price=200 WHERE id=1;
```
`UPDATE`の`SET`以降は変更するカラムだけ書けばいい。`WHERE`以下の構文が条件で、ここでは`id=1`のデータを指定する。

##DELETEでデータを削除する
基本式：`DELET FROM テーブル名 WHERE 条件文;`
###例

```sql
/* my_itmesテーブルからidが1のデータを削除するなら */
DELETE FROM my_items WHERE id=1;
```
`UPDATE`の`SET`以降は変更するカラムだけ書けばいい。`WHERE`以下の構文が条件で、ここでは`id=1`のデータを指定する。

##SELECTでデータを検索する
基本式：`SELECT カラム名1, カラム名2, ... FROM テーブル名 WHERE 条件文;`
###例

```sql
SELECT id, item_name FROM my_items WHERE id=1;
SELECT * FROM my_items WHERE id=1;
```
`*`は全てという意味を持つ。これを指定するとわざわざカラム名指定しなくていい。

##WHEREで条件指定する
`SELECT`,`UPDATE`,`DELETE`では`WHERE`に続けて条件文を書いた。複雑な条件はたくさんあるが、よく使うものをいくつかピックアップ。

| id     |item_name |price    |keyword|
|:-----------------|:------------------|:------------------|:---------|
| 1             | いちご |        180        |赤い、甘い、ケーキ|
| 2           |りんご       |       90       |丸い、赤い、パイ|
| 3             |バナナ              |120 |     パック、甘い、黄色        |
| 4             |ベリー              |200 |     袋入り、青い、眼精疲労        |
データベースに上記のデータが入っていることを前提に。テーブル名は`my_items`

###不等号を使う
```sql
SELECT * FROM  my_items WHERE id<>1;
/* idが1以外の商品 */
```
###文章の部分検索LIKE
キーワード検索によく使われる。入力したキーワードを含んだ文章を検索できる。
####前後を曖昧にした部分検索
keywordカラムに甘いというキーワードが含まれた商品だけを抜き出す

```sql
SELECT * FROM my_items WHERE keyword LIKE '%甘い%';
```
いちご、バナナをヒットさせた。`LIKE`は半角空白に続けて検索したい文字を追加する。前後に`%`をつけます。

####後ろのみを曖昧にした検索（前方一致）
`%`が部分検索の記号で、この部分にはどんな文字があってもいいということになる。

```sql
SELECT * FROM my_items WHERE keyword LIKE '赤い%';
```
これは**いちご**だけがヒットする。りんごにもキーワード「赤い」があるが、`%`が後にしかついてないので、先頭にキーワード「赤い」があるやつを検索する。このように、`%`の位置によって条件が変化する。

###数の検索を組み合わせて使うAND, OR
####複数の条件を全て満たすデータの検索
例えば、50円以上150円未満のものを探したいというとき

```sql
SELECT * FROM my_items WHERE price>=50 AND price<150;
```
`AND`は「且つ」という条件になる

####複数の条件のどれかを満たすデータの検索
idが1と3の商品を探したいというとき

```sql
SELECT * FROM my_items WHERE id=1 OR id=3;
```
`OR`は「または」という条件になる。

####複雑な条件での検索
```sql
SELECT * FROM my_items WHERE (id=1 OR id=3) AND price<150 AND keyword LIKE '%甘い%';
```
バナナがヒットします。

####ORを使うときの注意
正確に条件を`()`で囲わないと、正常に動作しなくなる。例えば

```sql
SELECT * FROM my_items WHERE id=1 OR id=3 AND price<150 AND keyword LIKE `%甘い%`;
```
これでは180円のいちごがヒットしてしまう。

>[データベースの基本2(MySQL)](https://qiita.com/Take_jpn/items/c647421a90070ebf0b93)
【参考】
[よくわかるPHPの教科書](https://www.amazon.co.jp/%E3%82%88%E3%81%8F%E3%82%8F%E3%81%8B%E3%82%8BPHP%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E3%80%90PHP7%E5%AF%BE%E5%BF%9C%E7%89%88%E3%80%91-%E3%81%9F%E3%81%AB%E3%81%90%E3%81%A1%E3%81%BE%E3%81%93%E3%81%A8/dp/4839964688/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=&sr=)
Windows 10 > **トラブル** > 設定 > ストレージ > 今すぐ空き容量を増やす > 「Windows Modules Installer Worker」がCPUを高負荷にする

```txt:動作環境
Windows 10 Pro (64bit) バージョン 1809
Windows Update適用済み
```

### 症状

設定において、「ストレージ > 今すぐ空き容量を増やす」を実施。

CPU使用率が97%を維持するようになる。

処理の途中で「ストレージ > 今すぐ空き容量を増やす」のウィンドウが消えた。

タスクマネージャで確認したところ「Windows Modules Installer Worker」がCPUを高負荷にしている。

シャットダウンをしたが、20分経過してもシャットダウン処理が終わらない。

### 関連

- [Windows10が重い、CPU使用率が高い、HDDのアクセスが100%になる原因(新版)](https://freesoft.tvbok.com/win10/general/windows10_cpu_hdd_100_ex.html) @ ぼくんちのTV別館

> 有効な対処方法はありません。
PCをしばらく放置するのが一番簡単かつ有効な対処方法です。

情報感謝です。


放置するしかないようです。

### 放置後

**シャットダウンは40分後に完了した。**


### 教訓

- A. 「ストレージ > 今すぐ空き容量を増やす」はトラブル覚悟の上で実施すること
- B. 「ストレージ > 今すぐ空き容量を増やす」は作業途中でしないこと
    - 今回のように作業ができなくなる
capistrano-sidekiq でデプロイ時に古い sidekiq のプロセスが kill されずに残る問題について

## 前提

* capistrano で rails のアプリケーション (sidekiq) をデプロイしている
* 外部拡張として [capistrano-sidekiq](https://github.com/seuros/capistrano-sidekiq) を使っている

## 問題点

デプロイ時に古い sidekiq のプロセスが kill されずに残る。
（1インスタンスあたり2つの sidekiq プロセスが起動した状態になる）

## 原因

cap でデプロイする場合、capistrano-sidekiq の仕様により、 `/tmp/pids/sidekiq-0.pid` にPIDファイルが作られる。
一方、 rake タスクから sidekiq を起動する場合、 `config/sidekiq.yml` の `:pidfile` にで定義したパスのファイル（現行だと `/tmp/pids/sidekiq.pid`）にPIDファイルが作られる。
したがって、合計で2つのPIDファイルが作られる。
これらは別々のプロセスとみなされるので、1つのインスタンス内に2つの sidekiq プロセスが存在することになる。

## この問題が再現する条件

以下のいずれもを満たす場合:

1. rake タスクから sidekiq を起動／再起動する
2. 1が1回以上発生した状態で cap deploy を実行する

## 対処

暫定的な対処だが、 
`config/sidekiq.yml` の `:pidfile` にで定義してある PID ファイルのパスを capistrano-sidekiq の仕様に合わせて変更する。

## 本来あるべき対処

本来デプロイツールの仕様に合わせてミドルウェアの設定を変更することはすべきでない。
あるべき姿としては、capistrano-sidekiq が sidekiq の設定ファイルの仕様に合わせるべきである。
capistrano-sidekiq に相当する処理を自前で実装する、capistrano-sidekiq を fork して改良して使う、などの対応が望ましい。

## 参考

1. https://github.com/seuros/capistrano-sidekiq/pull/116

問題となったPR。 0.5.4 からデフォルトで `sidekiq-0.pid` といったPIDファイルを生成するようになった。

2. https://github.com/seuros/capistrano-sidekiq/issues/44

「pidファイルのパスを勝手に書き換えるのはやめるべき」とコメントしているユーザもいるが、長期間この問題は放置されている。現在も Open な Issue.
Atomic Designについて今更学んだ

## Atomic Design

業務でAtomic Designについて学ぶ機会があったので理解度の確認程度に書いてみる
間違っている箇所があれば指摘してください

## Atomic Designとは
* サービスが大きくなるにつれて複雑になっていくファイルを部品ごとに分けて開発しやすくするためのデザインパターン(component指向という)
* 開発しやすくすると言ったが元々はデザインの考え方の一つ
* ちなみにcomponent指向で作るのに適しているフレームワークはReact.js,Vue.js,Riot.jsなどがある

## 使われている理由

* 今までやってきた一つのHTMLファイルに記述していく形式だと、一部を変更するだけでも手間がかかる
* そこでHTML内の要素をcomponent化することによって一部を変えたいときはそのcomponentをいじるだけで良くなる
* レイアウトもcomponentを入れ替えるだけで簡単にレイアウトを変えられる

## Javascriptは一つのファイルしか読み込んでくれない 
* component指向だとjsファイルは分けられている
* じゃあどうやって読み込むのか
* 例えばwebpackというものを使えば、モジュール化(部品で分けられているもの)されたjsを一つのjsにまとめてくれる
* cssとかもうまくまとめてくれる
* Webpackについて詳しく知りたいのならこの記事がオススメ
[Webpackってどんなもの？ - Qiita](https://qiita.com/kamykn/items/45fb4690ace32216ca25)

#### とにかくバンドルするツールが必要！！

## Atomic Designの粒度(分け方)

Atomic Designには決まりがあってcomponentをどの程度で分けるのかというのが定義されている
1. Atoms 原子
    * 一番細かく分ける部品、ボタンだったらとりあえずボタンを押された時に関数を実行するだけな部品
    * 例 : button,textinputなど
2. Molecules 分子
    * componentをまとめたもの、Organismsの一部として使われたりする部品
    * 例 : 検索フォームなど
3. Organisms 有機体
    * こちらもcomponentをまとめたもの、Moleculesと違うのはこれ一つで何をしているかがわかる(成り立つ)部品
    * 例 : ニュース記事の一つ分の記事など
4. Templates テンプレート
    * componentを当てはめていくための枠組みを作る部品
    * 例 : ページのレイアウト
5. Pages　ページ
    * 実際に作成したcomponentをはめ込んで行って実際のページを作る部品
* componentで分ける時に結構2と3で悩むが、2はサポート役 3はメインみたいな感じで覚えておけば分けやすいかも？

## まとめ
* Atomic Designを学んでいる中で、これを知っているか知っていないかでかなり開発のしやすさに差が出るなと思った。
* component指向を知らない人が作り方を学ぶのならとりあえず簡単な部品を合わせた何か一つを作るだけで理解できそう

## 用語
* component : 一つの部品
* Webpack : node.jsで動くjsたちをまとめるツール
EC2インスタンスにgit,docker,docker-composeを導入、公開鍵の登録(CircleCI用)

EC2インスタンス作成後、SSHに接続し、下記コマンドを実行します。
なお、インスタンスは`Amazon Linux`で作成してあります。

# git

```
# yumを最新状態にしたうえで、gitのインストール実行
sudo yum update -y
sudo yum install git
```

# docker
dockerグループへの登録は、後の`docker-compose`をsudo権限無しで実行する際に必要です。

```
sudo yum install -y docker
# docker サービスの起動
sudo service docker start
# ec2-user を docker グループに追加する
sudo usermod -a -G docker ec2-user
```

# docker-compose

```
# suに変更
sudo -i

curl -L "https://github.com/docker/compose/releases/download/1.11.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 実行権限付与
chmod +x /usr/local/bin/docker-compose

# su解除
$ exit

# docker-compose バージョン確認
docker-compose --version
docker-compose version 1.11.2, build dfed245
```

# 公開鍵

`CircleCI`等で、自動デプロイを実施する際、SSH接続のために予め公開鍵をインスタンス内に登録しておく必要があります。
ちなみに、`CircleCI`で使用できる鍵は`ssh-keygen -m pem`で作成した形式しか使用できません。
参照：[Adding an SSH Key to CircleCI](https://circleci.com/docs/2.0/add-ssh-key/)
vimで、公開鍵の中身を追加しておきます。

```
vi .ssh/authorized_keys
```

# 参照元
[AWS EC2 Amazon LinuxでDocker, Docker Composeをインストールする](https://qiita.com/shinespark/items/a8019b7ca99e4a30d286)
CircleCIでLaravelの.envファイルを環境変数を使って参照する

CircleCIに入門したときに､ちょっと思いついたので備忘録です｡

[CircleCI2.0でMySQLを使ったLaravelのテストを実行する](https://qiita.com/kazuhei/items/29ee2c3cbd5960814959)
こちらの記事を参考に､ `config.yml` を設定していたのですが､ふと疑問に思いました｡

これって他のAPIキーとか設定する場合､べた書きだとまずいよな......

単純にCircleCIの環境変数を使えばいいのでは?と思ったのですが､せっかくなので`.env.testing`をそのまま使いたいところです｡
ですが､APIキーが書かれた`.env.testing`を`Git`で管理はしたくないです｡(するべきではないです)
そこで､`.env.testing`の中身をすべて環境変数につっこんでしまおう､と考えました｡

# .envの中身を出力する
例えばこんな`.env`ファイルがあったとします｡

```text:.env.testing
APP_ENV=testing
APP_KEY=base64:tekitounamojiretsu
APP_DEBUG=true

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=circle_test
DB_USERNAME=root

EXAMPLE_API_KEY=qwerty
EXAMPLE_API_SECRET=ytrewq
```
それを`base64`にエンコードして出力します｡

```bash
$ cat .env.testing | base64
QVBQX0VOVj10ZXN0aW5nCkFQUF9LRVk9YmFzZTY0OnRla2l0b3VuYW1vamlyZXRzdQpBUFBfREVC
VUc9dHJ1ZQoKREJfQ09OTkVDVElPTj1teXNxbApEQl9IT1NUPTEyNy4wLjAuMQpEQl9QT1JUPTMz
MDYKREJfREFUQUJBU0U9Y2lyY2xlX3Rlc3QKREJfVVNFUk5BTUU9cm9vdAoKRVhBTVBMRV9BUElf
S0VZPXF3ZXJ0eQpFWEFNUExFX0FQSV9TRUNSRVQ9eXRyZXdxCg==
```
出力された文字列をコピーします｡

# CircleCIの環境変数に設定する
CircleCIにログインし､対象のリポジトリの`Settings > BUILD SETTINGS > Environment Variables`を開き､`Add Variable`から環境変数を設定します｡
`Name`は`ENV_FILE`とします｡

![2019-06-06_17h59_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74711/de98d083-fe66-e848-4250-221eeb3b6097.png)

# config.ymlを設定する
`.circleci/config.yml`に`.env.testing`ファイル作成コマンドを記述します｡
※詳細は､[CircleCI2.0でMySQLを使ったLaravelのテストを実行する](https://qiita.com/kazuhei/items/29ee2c3cbd5960814959)のものを参考にしてください｡

```.circleci/config.yml
# steps 配下
- run:
    name: base64 decode env file
    # ファイルに改行が含まれているので`-i`オプションを付ける
    command: echo $ENV_FILE | base64 -di > .env.testing
```


これでローカルなどと同じように`.env.testing`ファイルが利用できます｡
とはいえ､あまり使いどころはないかもしれませんが......
FOSS4G 2019 Bucharest でのベクトルタイル関連発表を調べた

FOSS4G 2019 Bucharest について sneak peek at the accepted papers できるようになったので、ベクトルタイル関係の発表がどのくらいあるか調べてみました。

# [General Track](https://2019.foss4g.org/schedule/general-track/)
- YeonHwa Jeong: VectorTile for SeaWind
- Pirmin Kalberer et al.: Vector tile benchmark
- Jerome St-Louis: GNOSIS Map Tiles: Open specifications for tiles of vector, imagery, coverages, point clouds, referenced and embedded 3D models
- Steven Ottens: Building a national vector tile set for the Netherlands
- Niene Boeijen: How to make a crafty Vector Tile map: Custom tiles, the perfect sprite, animating stuff and random hot air balloons!
- Enrique Soriano: Struggle with WebGL to render vector data
- Enrique Soriano: Serverless infrastructure to manage vector and tiff data: pbf and COGs

# [Academic Papers](https://2019.foss4g.org/schedule/academic-track/)
- Fujimura et al.: Design and development of the UN Vector Tile Toolkit

# 但し書き
sneak peek サイトを検索語 vector で調べているだけなので、調べ漏れはあるかもしれません。
Javaのメソッドにおけるstaticやpublicの挙動を確認する

#経緯
- クラス自身が持つ？ 公開範囲？
- オブジェクト？　インスタンス？　コンストラクタ？
    - わかりにくい
    - 順を追って確認しよう
    

#注意
- 「いつ使うべきか」はさておきます
- classは全部publicで固定します
    - 雑


#ただのメソッド
これが一番シンプルな形
Javaはmainメソッドに修飾子がゴテゴテついていて取っ掛かりにくい気がする

```java:Calculator.java
package jbasic;

public class Calculator {
	 int add(int number1, int number2) {
		int result = number1 + number2;
		return result;
	}
}
```


###ただのメソッドが使えるタイミング
||メソッドが書かれたクラスのインスタンスが生成済み|メソッドが書かれたクラスのインスタンスが生成されていない|
|:--------:|:---------:|:---------:|
|**パッケージが同じ**|○|×|
|**パッケージが違う**|×|×|

```java:Seller.java
package jbasic; //同じパッケージ

public class Seller {
	public static void main(String[] args) {
		Calculator calc = new Calculator();  //インスタンス生成
		System.out.println(calc.add(10,5));  //OK!
	}
}
```

```java:Seller2.java
package jbasic; //同じパッケージ

public class Seller2 {
	public static void main(String[] args) {
        //インスタンス生成なし
	    System.out.println(Calculator.add(10,5));  //非staticメソッドをstatic参照するなと怒られる
	}
}
```


#staticメソッド
これをつけるとインスタンス化しなくてもメソッドが叩けるようになります

```java:Calculator.java
package jbasic;

public class Calculator {
	 static int add(int number1, int number2) {
		int result = number1 + number2;
		return result;
	}
}
```

###staticメソッドが使えるタイミング
||メソッドが書かれたクラスのインスタンスが生成済み|メソッドが書かれたクラスのインスタンスが生成されていない|
|:--------:|:---------:|:---------:|
|**パッケージが同じ**|○|○|
|**パッケージが違う**|×|×|

```java:Seller2.java
package jbasic; //同じパッケージ

public class Seller2 {
	public static void main(String[] args) {
        //インスタンス生成なし
		System.out.println(Calculator.add(10,5));  //OK!
	}
}
```

```java:Robot.java
package jmaster; //違うパッケージ

public class Robot {
	public static void main(String[] args) {
		System.out.println(Calculator.add(10,5));  //クラスをpublicにしろと怒られる
	}
}
```
#public staticメソッド
publicをつけると他のパッケージのクラスからメソッドが使えるようになります。

```java:Calculator.java
package jbasic;

public class Calculator {
	 public static int add(int number1, int number2) {
		int result = number1 + number2;
		return result;
	}
}
```

###public staticメソッドが使えるタイミング
||メソッドが書かれたクラスのインスタンスが生成済み|メソッドが書かれたクラスのインスタンスが生成されていない|
|:--------:|:---------:|:---------:|
|**パッケージが同じ**|○|○|
|**パッケージが違う**|○|○|

```java:Robot.java
package jmaster; //違うパッケージ

import jbasic.Calculator; //クラスのインポートは必要

public class Robot {
	public static void main(String[] args) {
		System.out.println(Calculator.add(10,5));  //OK!
	}
}
```

#全部public staticでよくない？
- staticメソッドはインスタンスフィールドが使えない
- publicだと変な使われ方をして困る時がある(という理解だけど実際の弊害が分からん)
Laravelでcreated_atの日付を範囲指定してデータを取得する（自分用）

##メモ程度に書く

###bladeファイルに検索フォームを設置
選択された20xx/xx/xx ~ 20xx/xx/xxを取得する

```blade:date.blade.php
<form action="hashtag" method="GET">
    <input type="date" name="from" placeholder="from_date">
        <span class="mx-3 text-grey">~</span>
    <input type="date" name="until" placeholder="until_date">
    <button type="submit">検索</button>
</form>
```

###Controllerで条件分岐してクラスを呼び出す
とりあえず`$request`を取得して`$request['from']`と`$request['until']`があれば関数を呼び出す。っていう簡単な作りです。

```php:DatesController.php
<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Date;


class DatesController extends Controller
{
    public function index(Request $request)
    {
        //日付が選択されたら
        if (!empty($request['from']) && !empty($request['until'])) {
            //ハッシュタグの選択された20xx/xx/xx ~ 20xx/xx/xxのレポート情報を取得
            $date = Date::getDate($request['from'], $request['until']);
        } else {
            //リクエストデータがなければそのままで表示
            $date = Date::get();
        }

        //取得したデータをviewに渡す
        return view('date', [
            "date" => $date
        ]);
    }
}
```

###Modelにクラスを書く
ささっと書いただけなので色々と抜けてるけど許して

```php:Date.php
    //ハッシュタグレポートを取得
    public static function getDate($from, $until)
    {
        //created_atが20xx/xx/xx ~ 20xx/xx/xxのデータを取得
        $date = Date::whereBetween("created_at", [$from, $until])->get();

        return $date;
    }
```

こんな感じで取得できる~~はず~~
Macbook Pro と Raspberry Pi の接続をワイヤ一本で維持する

Raspberry Pi と Macbook Pro を持っていくつかの WiFi ネットワークを渡り歩くような状況で、とりあえずワイヤ一本を持っておいて接続を維持する方法のメモです。

# Raspberry Pi と電源だけ持ち歩きたい
## キーボードやマウス、モニタは持ち運びたくない
ソフトウェアのデモやトレーニングの環境として Raspberry Pi を考え、普段はいつも使っている端末から ssh 接続で扱うことにしたい場合、いつもマウスやキーボード、さらには HDMI 対応モニタ対応を持ち歩くのは大変です。また、案外、エンタープライズ環境では HDMI 端子を備えたモニタが見つからなかったりすることもままあります。

## いつも前回と同じ IP アドレスで WiFi に繋がるとは限らない
いったん情報を覚えこませた WiFi 環境にいれば、Raspberry Pi は自動的にネットワークに接続してくれるようです。しかし、もちろん IP アドレスのリースが満了して IP アドレスが変わる場合もあります。また、まだ情報を覚えこませていない WiFi 環境では、そもそも Raspberry Pi は WiFi ネットワークには接続しません。

# ケーブルで接続する
たまたま私は、Macbook Pro から Ethernet ポートを生やしてくれるものを持っていました。この Ethernet ポートと Raspberry Pi の Ethernet ポートをつなぐと、繋がります。その時の IP アドレスは、リブートしても変わらない場合があります。（そもそも IP アドレスを決定する手順を未確認なのですが、多分、こういうときのための自動割り当てなのでしょうね。手順がわかれば、IP アドレスがどういう頻度やきっかけで変わるのかもわかるのでしょう。）

## 私の手順
ということで、私は次のようなやりかたを今のところしています。

1. Raspberry Pi のケースに紙を貼っておき、それぞれのネットワークで当座使っている IP アドレスを鉛筆で書いておく。
2. WiFi あるいはケーブル直接接続のいずれかのネットワークで繋いだら、もしもわかっていなければもう一方のネットワークへの接続のために Raspberry Pi が使っている IP アドレスも確認しておき、ケースに貼った紙の上の IP アドレスも、鉛筆で書き換えておく。

## 正しい手順！
```
ssh pi@raspberrypi.local
```
で接続できるようですね。
slackでbotをつくる。（slack APIからApp Installまで）

# まずslack api にアクセス
[slack API](https://api.slack.com/)
<img width="512" alt="スクリーンショット 2019-06-06 16.57.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178483/c5d4d0b0-6b04-7529-04e5-c1657d768994.png">
右上の　Your Apps　をクリックします。

# Create New App　で設定
<img width="512" alt="スクリーンショット 2019-06-06 17.04.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178483/1d1838f8-8666-3d29-68c7-9adbde96b10b.png">
Create New Appをクリックします。
すると下の画面になるので、App Nameを入力して、Development Slack Workspaceでワークスペースを選択。Create Appをクリックします。
<img width="512" alt="スクリーンショット 2019-06-06 17.11.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178483/5dbe0531-1dea-7742-70af-58524b0cc4d0.png">

# できたAppの設定をする
<img width="512" alt="スクリーンショット 2019-06-06 17.23.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178483/d0c7f6ab-a332-1000-9e13-a2a95e4aca63.png">

1.このような画面になるので、左の下のほうにあるBot Usersをクリックして、Display nameとDefault usernameを入力し、Add Bot Userをクリック。

2.次にInstall AppからInsatall Appして、AppのInstallができました。

OAuth Tikens for Your TeamのTokenは後で必要になります。

Slackをみてみると、AppのところにつくったApp名が出ているはずです。ただまだ、起動していないです。bot機能を設定して、起動させるまではまだ次回に。
Automation AnywhereのBefore-Afterを使用したWebページのデータ抽出

勉強がてらやってみたので備忘録として残しておこうと思います。

例えば、対象のWebページに以下のようなテーブルがあるとします。

|    名前     |       年齢|      性別|
|-------------|-----------|----------|
|    田中     |         20|        男|
|    鈴木     |         22|        男|
|    高橋     |         24|        女|

Automation AnywhereのBefore-Afterコマンドでは
抽出対象の文字列から、Beforeに設定された文字列とAfterに設定された文字列を探し
その間にある文字列を取得することができます。

###・Before-Afterコマンドの設定画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/430538/b1070ca6-c2a8-8760-1287-b9d68cb635da.png)

- Source String
    - 抽出したい文字列（今回であればテーブルのソースコード）
- Before
    - 抽出条件の開始文字
- After
    - 抽出条件の終了文字
- Assign The Output To Varidate
    - 抽出した結果を代入する変数

抽出したいテーブルのソースが以下のようになっているとした場合。

```html
<tr class="rankingTabledata">
<td class="txtcenter">田中</td>
<td class="txtleft">20</td>
<td class="txtleft">男</td>
</tr>
<tr class="rankingTabledata">
<td class="txtcenter">鈴木</td>
<td class="txtleft">22</td>
<td class="txtleft">男</td>
</tr>
<tr class="rankingTabledata">
<td class="txtcenter">高橋</td>
<td class="txtleft">24</td>
<td class="txtleft">女</td>
</tr>
```
名前
Before
```<td class="txtcenter">```
After
```</td">```

年齢
Before
```<td class="txtleft>```
After
```</td">```

性別
Before
```<td class="txtleft>```
After
```</td">```

と設定することで抽出できます。

- Occurrence
    - ここで指定した回数分抽出条件文字が見つかった個所から文字列抽出を行うための設定値になります。

例えば、名前を抽出する際
Occurrenceを1に設定していると「田中」が
Occurrenceを2に設定していると「鈴木」が抽出されます。

さて、ここで一つ問題があります。
年齢と性別のクラス名が同じためこのままでは、うまく思った通りの値をとることができません。

そこで、Occurrenceをうまく使います。
年齢抽出時には、1を。
性別抽出時には、2を。
こうすることで、1回目にマッチした個所と2回目にマッチした箇所からそれぞれ取ってくることができます。

Occurrenceにループカウンタを使うことで続けてのデータ取得も可能です。
ただし今回のケースだと年齢と性別のカウンタは別々に管理しないといけない点に注意です。
【Unity】AwakeとStart

#AwakeとStart
Unityのイベント関数でよく使うものの中に、AwakeとStartがあります。
どちらも初期化関数なのですが、次のような違いがあったりします。

## Awake
- 最初のシーンのロード
 - この関数は常に Start 関数の前およびプレハブのインスタンス化直後に呼び出されます。(もしゲームオブジェクトがスタートアップ時に無効である場合、有効になるまで Awake は呼び出されません。)

（Unity公式ページより引用）

## Start
- 最初のフレームのアップデート前
 - スクリプトのインスタンスが有効な場合にのみ、最初のフレームのアップデート前に Start が呼び出されます。

（Unity公式ページより引用）

## ことの発端

初期化っぽいイベント関数が二つあるのは知ってた。
StartよりもAwakeの方が先に呼ばれるであろうことも知ってた。
てことで、なんとなくAwakeばっかり使っていたのですが
プログラムをちょっと変更したら、UnityEditor上では動いていたプログラムが
実機（Android）では動かなくなってしまいました。

### プログラムの作り（変更前）
- GameDirectorオブジェクト
 - Scene上にインスタンスとして配置
 - Playerの走行ルートや、Enemyの発生を管理する
 - UIの管理
 - Awake内でPlayerの走行ルートをセット。Startなし。

- Playerオブジェクト
 - Scene上にインスタンスとして配置
 - 設定された走行ルート上を自走する
 - Awake内で初期化を行う。Startなし。

### プログラムの作り（変更後）
- GameDirectorオブジェクト
 - 変更なし

- Playerオブジェクト
 - Prefab化した後、Scene上にインスタンスとして配置
 - そのほか、変更なし

## UnityEditor上と実機上での動きの違い
PlayerのAwakeでは、各種初期化を行っています。
GameDirectorのAwakeで行う走行ルートセットは、
Playerの初期化後に呼ばれる前提でした。

修正前のプログラムでは、UnityEditorとAndroid共に
GameDirectorのAwakeより先にPlayerのAwakeが呼ばれていたようです。

それが、PlayerオブジェクトをPrefabしたことで
Awakeの呼ばれる順番（＝インスタンス化の順番？）が変わってしまったようです。
しかも、UnityEditorとAndroidとで異なる。
※処理速度の問題？？

## 結論
- Awakeは、自分の初期化のみ
- Startは、他者も関係する初期化を行って良い

こんな感じのルールを作っておけば、問題ないのではないかと思います。

いや～、実機でしかエラーが起きないから
テストのたびにビルドしなきゃいけなくて、時間がかかりました(^^;
エビをDetectionして遊ぶ

![anim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227432/26a19ea5-1056-a857-d5c6-4804fb14282d.gif)

[EBI: Estimate Boundingbox of shrImp (GitHub)](https://github.com/kuboyoo/EBI)
研究室の仲間とYOLOを使って，研究室で飼育しているレッドチェリーシュリンプの検出をして遊んだ．

## 学習方法
- 自前で56枚のデータを用意し，YOLOv3で学習．

## 結果
- 温度計の赤色に反応して誤検出されることが問題．
- 少ない枚数でも1ラベルかつ対象が分かりやすい色なら，ある程度の精度が出せる．

## 展望
- 個体識別 & 個体数カウント．
- データセットの枚数を増やす．
JSAI2019 3日目まとめ

おはようございます、ということでJSAI2019の３日目です.
今日は寿司ですよ寿司.下手したら学会よりも重要です.
![image0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431433/d7c9bbcd-e2d8-5d1e-e215-73a5eb7bf101.jpeg)
![image0 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431433/cd205ef2-134a-1445-eef3-b2a288fa93c7.jpeg)
新潟といえばスルメイカの名産地です.南は富山のホタルイカ、北は新潟スルメイカと呼ばれるほど.
そしてさらに６月は水揚げ量年間１位という旬でもあって食べざるを得ない.食べないという選択肢はない.
さらにアジも旬です.夏の青物は脂が乗って最高です.
もし新潟に行かれる際は是非お寿司を食べましょう.

まだまだお魚さんについて話したいところですが,話を人工知能学会に戻したいと思います。
##自動交渉エージェントのための制約緩和を用いた説明可能な妥協アルゴリズム
増田 淳基1、松平 正樹1 (1. 沖電気工業株式会社)
https://confit.atlas.jp/guide/event/jsai2019/subject/3Q4-J-13-01/tables?cryptoId=

課題として「二次災害を防ぐために交通異常（事故）の発見・位置の特定」を人工知能を使い発見しようというのが今回の発表.
手法としてETC2.0はトラカンというものがあり、一定箇所ごとにスキャンすることができる.
ETC2.0には各車両のGPSによって取得した位置情報・速度・加速度が記録されて居ます.
データのグラフを観察してみると渋滞には常に
「渋滞開始場所は時間関わらず常に一定」
「しかし渋滞の末端は時間とともに変わっていく」
という構造が見られた.
そして渋滞には「自然渋滞」、「事故渋滞」の２種類があり,それぞれが
自然渋滞は「速度低下が自分でもわからないぐらい自然」
事故渋滞は「事故発生場所から突然速度低下が発生する」
といった特性を持っている.
この特性を利用して閾値学習を用いた交通異常（場所・時間）の検知を行う.
今回の発表では自然渋滞のみを使った.渋滞を抜ける際の速度の上昇をモデル化.
渋滞発生を感知した際,モデルを適用して同時生起確率を測定,一定確率以下の場合に事故渋滞と推論する.
面白いのがこの手法により適合率94%で検知を行えたそうです.かなり高い数値です.
今後は自然渋滞の発生原因等も考慮に入れたモデル化を行うそうで,また聞きたい発表でした.


##高効率なドローンハイウェイ網の設計手法
浜中 雅俊1 (1. 理化学研究所)
https://confit.atlas.jp/guide/event/jsai2019/subject/3Q4-J-13-02/tables?cryptoId=

ドローンは次世代の交通網として期待されています。無人の運搬ドローンの他に少人数を載せた無人タクシードローンなんかもUberが2020年での実用化を目指しているそうで.近未来どころか来年です.

##人狼ゲームにおける明示的役職・陣営推定理由の抽出
小村 友希1、坂本 航1、〇尾崎 知伸1 (1. 日本大学)
https://confit.atlas.jp/guide/event/jsai2019/subject/3F4-OS-14b-04/tables?cryptoId=
####我らがSir.Ozakiの発表です.
と言っても内容は去年の学部生４年の卒論なので聞くのは２回目.
人間が理解できるように役職推定をモデル化しようといった研究です.
大学で講義を受けて居た時も思いましたが尾崎先生,話すのが上手いですよね.
以前も卒論で欠席者が出た時に尾崎先生の発表が聞けたのですが,学会で聞いていても尾崎先生の発表は聞きやすくて聞きに来ました.
尚,尾崎先生には嫌がられました.

####[四日目に続く!](https://qiita.com/MrMoto/items/663b577a3f434975d700)
ubuntu18.04。キー入力ができなくなった。マウスのみ動く。

症状）
すべてのキーボードのキーが入力できなくなった。
マウスのみ
端末でDockerをつかっていて、TABキーを押して入力候補を使ったらなった。

環境)
ubuntu18.04
OSインストールしてわずか数日。


対処）
端末を開く。（ALT+CTRL+T)
＄　sudo ubuntu-drivers list
＄　sudo ubuntu-drivers autoinstall
＄　sudo reboot

振り返り）
NVIDEAのドライバー関係のようだ。


現状）
正常作動している

参考になったURL）
http://chamiz.hateblo.jp/entry/2018/01/04/200000
Python assertの簡単な利用シーン

assert の利用シーンで最近お手軽だな、と思う利用シーンがあったので備忘録として書いておきます。

assertは結果がFalseの場合、AssertionErrorを起こしますがその際に、 "," で繋いで文字列をおくと、その文字列と一緒にAssertionErrorが起こります。つまり、以下の様になります。

```python
>>> assert False, "hoge"
AssertionError: hoge
```

例えば、以下の様な関数を書く場合に、assertで引き数のチェックを簡易にできます。

```python
def do_something(mode="train"):
    assert mode in ['train', 'test'], "modeは train か test のみだよ."
```
こうすることで引き数のチェックは簡易になります。

```python
>>> do_something(mode='本番')
AssertionError: modeは train か test のみだよ.
```

便利ですね。
Cloud FunctionsにGoのコードをdeployしようとしたら嵌ったこと


# CloudFunctionsにデプロイする

以下のようなディレクトリ構成下において、`operate`で`gcloud functions deploy --runtime go111`を実行するとエラーが吐かれる。

```
C:.
│  go.mod
│  go.sum
│  main.go
│
└─ operator
         operate.go
         utils.go
```

以下がエラー内容。どうやらパッケージが見つからないらしい。

>
Deploying function (may take a while - up to 2 minutes)...failed.
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Build failed: /tmp/sgb/gopath/src/serverlessapp/vendor/o
perator/main.go:5:2  cannot find package "github.com/deckarep/golang-set" in any of:
   /tmp/sgb/gopath/src/serverlessapp/vendor/github.com/deckarep/golang-set (vendor tree)
   /go/src/github.com/deckarep/golang-set (from $GOROOT)
   /tmp/sgb/gopath/src/github.com/deckarep/golang-set (from $GOPATH)
/tmp/sgb/gopath/src/serverlessapp/vendor/operator/utils.go:4:2: cannot find package "golang.org/x/net/context" in any
 of:/tmp/sgb/gopath/src/serverlessapp/vendor/golang.org/x/net/context (vendor tree)
   /go/src/golang.org/x/net/context (from $GOROOT)
   /tmp/sgb/gopath/src/golang.org/x/net/context (from $GOPATH)
...（以下略）


# 対応策
`go.mod`のあるディレクトリで`gcloud functions deploy`を実行する。
カレントディレクトリからでないとデフォルトでは見つけてくれない。

### デプロイする関数のあるコードだけ指定
`--source`でソースコードの場所を指定してあげると、ソースコードと`go.mod`が別の場所にあってもデプロイできそう。

公式ドキュメントでも指摘されていた。
> 
* Note that if you do not specify the `--source` flag:
  - Current directory will be used for new function deployments.
>

# 参考
* [Cloud SDK : gcloud functions deploy](https://cloud.google.com/sdk/gcloud/reference/functions/deploy)
DockerイメージのENTRYPOITとCMDを上書きした場合の挙動について

## 背景

あるDockerイメージのENTRYPOINTに指定されたシェルの前にちょっとした処理を入れたくて、ENTRYPOINTを上書き定義したら想定外の挙動をしたのでその結果の記録です。

## 実験に使ったもの

```Docker:Dockerfile
FROM busybox

ENTRYPOINT [ "echo" ]

CMD [ "param1", "param2", "param3"]
```

```yaml:docker-compose.yml
version: '3.5'
services:
  non-override:
    container_name: non-override
    image: test
    build: .

  entrypoint-override:
    container_name: entrypoint-override
    image: test
    entrypoint: echo "overwride entrypoint. parameters =>"

  command-override:
    container_name: command-override
    image: test
    command: foo bar baz

  both-override:
    container_name: both-override
    image: test
    entrypoint: echo "overwride entrypoint. parameters => "
    command: foo bar baz
```

## 結果

```shell-session
[docker@docker-host test]$ docker-compose up --build
Building non-override
Step 1/3 : FROM busybox
 ---> 64f5d945efcc
Step 2/3 : ENTRYPOINT [ "echo" ]
 ---> Running in 98a926f84654
Removing intermediate container 98a926f84654
 ---> 29d72f5786f0
Step 3/3 : CMD [ "param1", "param2", "param3"]
 ---> Running in 4c3fff18bbfe
Removing intermediate container 4c3fff18bbfe
 ---> 214995d47fad

Successfully built 214995d47fad
Successfully tagged test:latest
Creating entrypoint-override ... done
Creating non-override        ... done
Creating both-override       ... done
Creating command-override    ... done
Attaching to both-override, command-override, entrypoint-override, non-override
both-override          | overwride entrypoint. parameters =>  foo bar baz
command-override       | foo bar baz
entrypoint-override    | overwride entrypoint. parameters =>
non-override           | param1 param2 param3
both-override exited with code 0
command-override exited with code 0
entrypoint-override exited with code 0
non-override exited with code 0
[docker@docker-host test]$
```

# 結論

## ENTRYPOINTを上書きするとDockerイメージのCMDがNULLになる

`entrypoint-override    | overwride entrypoint. parameters =>`の結果からイメージのCMDがnullに上書きされていると思われるのでdocker inspectで確認。

```shell-session
[docker@docker-host test]$ docker inspect entrypoint-override | jq '.[].Config | .Entrypoint,.Cmd'
[
  "echo",
  "overwride entrypoint. parameters =>"
]
null
[docker@docker-host test]$
```

というわけで、以下のような独自のEntryPointシェルとかを作ってイメージのENTRYPOINTを上書きした場合は元のイメージのCMDを調べたうえで、Shell自体にCMDの内容を書くか、dockerコマンドの最後の引数、docker-composeのcommandに同じものを指定しないとダメでした。。

```shell:docker-entrypoint.sh
#!/bin/bash
set -euo 

# 何かの処理

# 元のイメージをCMDは引数にならないよ！！
exec "$@"
```
Slate: 美しいWeb APIドキュメント生成ツール


![screenshot-slate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/581ae4fa-3084-b1da-9c9e-19ea2a999ebb.png)

## 概要

* SlateはWeb APIのドキュメントを生成するツール
* 静的HTMLを出力する
* UIがきれい
* APIドキュメントはMarkdownで書く
* GitHub: [lord/slate: Beautiful static documentation for your API](https://github.com/lord/slate)
* デモサイト: [Introduction – API Reference](https://lord.github.io/slate/#introduction)
* APIドキュメントの書き方: [Markdown Syntax · lord/slate Wiki](https://github.com/lord/slate/wiki/Markdown-Syntax)
* APIドキュメントの公開方法: [Deploying Slate · lord/slate Wiki](https://github.com/lord/slate/wiki/Deploying-Slate)

## 所感

* RESTful APIなどのドキュメントをAWS S3などにて公開するのに良さそう。
【MovableType】カスタムフィールドでhtmlファイルの出力有無を設定する

今後も使いそうですので、備忘録としてメモ。

##やりたいこと
再構築時にhtmlファイルを出力させないようにする。

##背景
自分はトップページのあれこれをカスタムフィールドで切り替えるために、 親サイトのウェブページに「トップページ更新用」というページを作成しているのですが、再構築時にhtmlファイルとして出力されるのは気持ち悪かったのでチャレンジしてみました。

##解決方法

1.カスタムフィールドの作成
2.実行するための記述を「アーカイブマッピング」追加
3.対象ウェブページのチェックボックスにチェックを入れる。
4.動作確認

###1.カスタムフィールドの作成

例として「cf_page_nofile」というチェックボックスのカスタムフィールドを作成します。

■内容
・システムオブジェクト：ウェブページ
・名前：任意で入力
・説明：任意で入力
・種類： チェックボックス
・ベースネーム： cf_page_nofile
・テンプレートタグ： cf_page_nofile

###2.実行するための記述を「アーカイブマッピング」追加

実行するための記述は「テンプレートの編集」内の対象ウェブページアーカイブテンプレートの「アーカイブマッピング」に行います。

例： テンプレートタグが「cf_page_nofile」の場合

```mt:ウェブページアーカイブテンプレート
<mt:If tag="cf_page_nofile"><mt:Else>%-c/%-f</mt:If>
```

「 %-c/%-f 」は、htmlファイルをどのような構造で出力したいかを指定しています。
※任意で変更してください。

###3.対象ウェブページのチェックボックスにチェックを入れる。

対象のウェブページ内で、用意したカスタムフィールドのチェックボックスにチェックを入れて、作成or更新します。

###4.動作確認

作成or更新後にサーバー上にファイルが出力されていなければ成功です。

##まとめ

蓋を開けてしまえば、通常のカスタムフィールドの運用で解決するという・・・。
まさか、アーカイブマッピングにカスタムフィールドの記述が使えるとは思ってもみませんでした。

「思いついたら試してみる」って大切ですね。
AI開発基盤KAMONOHASHIの構築ツールの中身

OSSのAI開発基盤KAMONOHASHIのデプロイツールの解説記事です。

# インフラ部分
[kubespray](https://github.com/kubernetes-sigs/kubespray) + ansibleを使用

## kubesprayとは
* ansibleベースのKubernetes自動構築ツール
* kubeadmの構築に加え、手動で行う必要のあるカスタマイズをいろいろやってくれる
  * masterをinventoryにマシン名複数台書いておけば勝手に冗長化設定もろもろやってくれる
  * ipvsロードバランス構築
  * ...etc
* ansibleのgroup_varsやextra_varsで構築内容をカスタマイズできる
  * DNSの設定
  * dockerのオプション
  * insecure-registry
  * http proxy
  * ...etc 

## kubesprayにansibleで独自処理を追加
* kubesprayをimportして自分のansible playbookから呼び出す
* デフォルトで書き換えたい内容はあらかじめ[group_vars](https://github.com/KAMONOHASHI/kamonohashi/blob/master/deploy-tools/infra/conf/group_vars/all.yml)に書いておく
* 自分のansible playbookでは主に次のことを行っている
  * Minio・NFSの構築
  * nvidia-dockerのインストール 

# アプリ部分
[Helm](https://github.com/helm/helm)を使用

## Helmとは
* k8sのyaml群をテンプレート化
  * 設定箇所を変数化しておいて、構築時には変数のみ指定すればKAMONOHASHIが構築できるようにする
  * 複数のyamlをまとめて置ける。バージョン管理できる
* デプロイしたyaml群のバージョン管理・切り戻し
  * 複数のyamlをまとめたバージョン管理ができる   
  * デプロイの履歴が取れる
  * デプロイの切り戻しができる

上記だけだとk8sなどの知識がない人にデプロイのハードルが高いため、
決め打ちの構成で設定してkubespray, helm実行するbashスクリプトを提供している[deploy-basic-cluster.sh](https://github.com/KAMONOHASHI/kamonohashi/blob/master/deploy-tools/deploy-basic-cluster.sh)
このスクリプトを使わずにansible,Helmの設定ファイルを手で書けば自由にカスタマイズできる。
たぶんHelmだけを使えばGKEなどを利用することもできるが試したことはない。

# ツールを使う理由
* 構築・移行が頻繁のため自動化したい
  * マシン変更、IP変更、新規構築で動くかのテスト、客先、・・・
* kubespray: 当時オンプレはkubeadmかkubesprayぐらい。nvidia-dockerの対応も必要なので、kubespray+ansibleとした。
  * 今ではkubesprayでnvidia-dockerも入れられそうだが未検証
* Helm: 当時kustomizeがなかったため、一番メジャーなHelmにした
 
# 使ってみた感想
* kubespray+ansibleは変数の上書きや変数中で別の変数の参照ができるので挙動をカスタマイズしやすい。変数を変数を使って組み立てられる。
  * 例えば、dockerのセグメント変更を可能にするために自作のdocker_bipの変数を追加している。それをkubesprayに組み込むのには、kubesprayのdocker_optionsh変数を次のようにgroup_varsで上書きしている。ユーザーは設定ファイル(extra_vars)にdocker_bipだけ定義すればよい。
  
```yaml:デプロイツール側
docker_options: >-
  {%- if docker_bip is defined %}
  --bip={{ docker_bip }}
  {%- endif -%}
  {%- if docker_insecure_registries is defined %}
  {{ docker_insecure_registries | map('regex_replace', '^(.*)$', '--insecure-registry=\1' ) | list | join(' ') }}
  {%- endif %}
  --live-restore --graph={{ docker_daemon_graph }} {{ docker_log_opts }}
```
```yaml:設定ファイルに書く内容
docker_bip: 192.168.1.1
```

* 一方Helmは変数を変数を使って組み立てるということができない(変数中で変数を参照できない)。変数の上書き自体はできるが、yamlのネストが深い場合にそのyamlのオブジェクト構造ごと上書きしないといけない.
kubespray+ansibleでやっているようなデプロイツールで組み立て処理を書いておき、ユーザーの設定項目を簡単にするということができない

```yaml:ingressのHelmチャートの変数上書き。ユーザーの設定ファイルでネスト構造を丸ごとコピーしないと上書きできない
ingress:
  controller:
    nodeSelector:
      kubernetes.io/hostname: "${INGRESS_NODE}"
    service:
      externalIPs:
       - "${INGRESS_NODE_IP}"
```

* kubesprayは最新のk8sの機能をいろいろ取り込んでいてかつ勝手にやってくれる。ありがたい反面、デフォルトの構築内容が変わるので、kubesprayのバージョンアップでkamonohashiが動かないことも(k8sの新機能のバグ？)。バージョンアップの際に明示的に古いバージョンと同じ構成にするオプションをkubesprayに入れたりしている。
* Helmは書き方の学習コストが高いかつかゆいところに手が届かない（変数の組み立てなど）のであまり気に入っていない
【R言語】Rでゲンシジンになってみた

###動機

[オレ プログラム ウゴカス オマエ ゲンシジン ナル - Qiita](https://qiita.com/Harusugi/items/f499e8707b36d0f570c4)

R　ゲンシジン　ナリタイ!ってなった。
や、データ加工のテクニックを身につけたいという気持ちもあるのですよ？

###実装

悩んだところもありましたが、総じて意外と簡単にできました。

```R:genshijin.r

# ライブラリ -------------------------------------------------------------------

library(RMeCab)
library(pipeR)
library(dplyr)

# ソース本文 -----------------------------------------------------------------------

txt <- "ソースコードは嘘をつかない"

#ファイル保存
write.table(txt,file="txt.txt",col.names = F,row.names = F)

#キーワードの抽出
txt <- RMeCabText("txt.txt")%>>%
  as.data.frame() %>>%        #データフレーム化
  t()                         #転置

#助詞を除いたキーワードを抽出
txt <- txt[txt[, 2] != "助詞",] 


txt <- txt[,9]
txt <- paste(txt,collapse = "")


```

txt変数の中身を見てみると以下のような結果になります。

```実行結果
[1] "ソースコードウソツカナイ"
```

別の文言に置き換えて試してみます。

```実行結果
入力：最高の力を発揮して書いたコードにあるバグは、自分では解決できない

[1] "サイコウチカラハッキシカイタコードアルバグ、ジブンカイケツデキナイ"
```

出来たようです。アルファベットに対応していないのが残念な点なので、今後の課題とします。



アリガトウ。R ゲンシジン　ナッタ！
トモダチ。