OmniAICreator/Qiita-1.07M huggingface dataset:
react-bootstrap-tableで日本語(漢字)ソートを実装してみた。

# 前書き
管理画面などで、データテーブルはよく使われますね。
今回は、[react-bootstrap-table](http://allenfang.github.io/react-bootstrap-table/index.html)という、ReactでBootstrapのテーブルを良い感じに使いやすくしてくれるライブラリで日本語ソートを実装してみたのでまとめます。
用途とすれば、漢字名をソートしたときに文字コード順になってしまうのでそれをフリガナ順にしたいときです。

# 前提

* 人物名や商品名のテーブルで利用する
* 漢字名とフリガナがある

上記２点を前提に、実装しようと思います。

# 実装
大まかなreact-bootstrap-tableの利用方法は今回は割愛します。

実装は以下の通りです。

## ソート関数を作成する。

実装的には漢字名の部分でソートした際に、別のフリガナの値を利用してソートする形になります。
内部で利用している、katakanaToHiraganaに関しては以下のサイトをご参考ください。

https://goma.pw/article/2015-11-18-0/

文字列をひらがなにする必要があるので利用しています。

```js
 jpSort(a, b, sortOrder, sortField) {
   const main = katakanaToHiragana((a.kana).toString());
   const sub = katakanaToHiragana((b.kana).toString());
   if (sortOrder === 'asc') {
     if (main < sub) {
       return -1;
     } else if (main > sub) {
       return 1;
     }
   }
   if (main < sub) {
     return 1;
   } else if (main > sub) {
     return -1;
   }
   return 0;
 }
```

引数aとbには、ソート検査対象の２列のオプジェクトが来ます。
この関数自体は、漢字名をソートした際のみ実行されるので、ソート対象をkanaにしてひらがなに変換
その後でソートの処理を実装します。
作成する関数はこれだけです。
あとはこれをBootstrapTable側で指定してあげます。

## BootstrapTableのソートに作成した関数を指定する。

TableHeaderColumnのsortFuncというpropsに作成した関数を渡します。

```html
<BootstrapTable
   data={this.state.filterResult}
   options={options}
   version="4"
>
  <TableHeaderColumn
    sortFunc={this.jpSort}
    dataField="kanji"
  >
    漢字名
  </TableHeaderColumn>
  <TableHeaderColumn
    dataField="kana"
  >
    フリガナ
  </TableHeaderColumn>
</BootstrapTable>
```

以上で終わりです。
動作を見ていただければ、きっちり漢字でもフリガナ順で並ぶと思います。

# 後書き
処理的には細かな部分ですが、利用するユーザから見れば、文字コードなんてわからないことが多いので
きちんとフリガナ順で並んでくれれば嬉しいですね。
react-bootstrap-tableはなかなかクセのある部分もありますが、callBackが取りやすく独自が組みやすいので、色々使って行きたいです。
jupyter notebookで画像を表示させたいだけならば、`IPython.display`モジュールのメソッドを使うべし

# 本題

google検索にて、`jupyter notebook 画像表示`とすると、`pillow`(PIL)を用いて画像表示するとか、matplotlibで画像表示するとか言う方法がトップに来ます。

それよりも、notebookで(出力)画像を表示するだけならば`IPython.display`モジュールの`display_*`関数がおすすめです。

```python
from IPython.display import Image, display_png
# png_file: str
display_png(Image(png_file))
```

とするだけ！[^jupyter] もちろんmatplotlib使わないので、`%matplotlib inline`も不要ですよ:ok_hand_tone1:

`jpeg`とか、`pdf`も扱えるようです。詳しくは、APIを見てください。 https://ipython.org/ipython-doc/3/api/generated/IPython.display.html

[^jupyter]: と言うより最近はもっぱら、画像やtableを表示するためだけしかnotebook使ってないですね。。
プログラミングをよく知らない初心者がシステム開発をしてみて気付いた話

# はじめに
先に言っておくと技術的に何か伝えられるかどうかは曖昧です。プログラミングすらよくわかってない自分が仕事でシステム開発をしてみた備忘録として何か残せればと思います。
##大学までのバックグラウンド
- 田舎に生まれる。ごく一般的な子供だった
- 運動は得意でいわゆる体育会系だった
- 高校は工業系で電気電子や金属加工、土木建築など学んでいた(ちゃっかり成績トップクラス)
- 大学はメディア学科という抽象的な学部でUIやUX中心にサービスデザインなどを経験
- 卒論は就職面接を動画から自動評価するシステムの提案(学会発表もしたが表彰にはかすりもしなかった)

##現在の経験とか
- PHP3か月分くらい。
- Laravel1か月分くらい。
- 上流:WF作成、画面遷移図作成くらい。
- テスト項目書作成ちょいちょい。

##入社前後に感じていたこと
- PHPって何…HTMLより強いの？
- echoって何???えちょーって読んでた。アホ。
- フレームワークとか知らない。ボタンポチポチしてればシステムできるの？
- DBって何？データベース？なにやら大規模そう…
- 3画面遷移とかつらそう…hiddenってかっこいい

#それでは本題
上を見ていただければわかると思いますが完全にポンコツです。Laravelのフレームワークを用いた開発を行ってみて感じたことなどつらつら書いていきます。

##よくわからん中システム開発をしてみて…感じたこと
- シンプルに、難しいよね。でも楽しい！
- テストって序盤にやらせてもらったから雑用かと思ってたけど、かなり大事。
- 急に要求変更とかってあるんだほんとに。笑
- MVC＋Sってするだけでもソースが見やすくなった！
- Larabel楽しい！
- ファイル操作関連がまだちょっとわからない…

##褒められた事
**分からない事はわからんって言う。**
→どこから説明すれば良いのかが分かったりクライアント様と調整がしやすかったりするらしい

**○○機能を3人日で作ってくれと言われたときにその機能をさらに細分化した**
どちらかというと自分にとって良かった。○○機能って言われてもよくわからんし一つずつ進んでいこうと思えた

**とりあえず20分くらい悩んで詰まったら聞いてみる**
→一人で悩んでいてもしょうがない！周りには優秀な方がいるのだからたくさん聞いて吸収しよう。もちろんある程度は自分で考えるように。


##こんなメンバーがいるとやりやすい
- 勉強熱心な人
- 進捗どうですかとたまに気にかけてくれる人
- テンションが普通以上の人
- 怒るだけじゃなく今後のフォローなどもしっかりしている人
- 育てようとする意志が見える人

やりやすいかは別としてPM的な立場の人がちょいちょい管理してくれるとスムーズに業務が進んだ。
##ここが上手くいかなかった

- **工数を余分に見積もってしまう。**間に合わない恐れとか不安から多めに見積もって伝えてしまう。癖になるとマズイです。
- なりたい目標や今後の目標があいまいで何を勉強したらよいかわからない
- **FatController**になりがち。オブジェクト指向とかLaravelの強みとか活かしきれていない。


#まとめ
プログラミングの経験がなくても、実践経験がなくとも頑張れば結構なんとかなります。(保証しているわけではありません)
もちろん周りの方々の協力であったり会社の方針であったり様々な影響はあるものの楽しくやらせてもらっている事には感謝しております。
勉強するにあたって参考になった本を紹介します。
[現場で役立つシステム設計の原則](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E5%BD%B9%E7%AB%8B%E3%81%A4%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E8%A8%AD%E8%A8%88%E3%81%AE%E5%8E%9F%E5%89%87-%E5%A4%89%E6%9B%B4%E3%82%92%E6%A5%BD%E3%81%A7%E5%AE%89%E5%85%A8%E3%81%AB%E3%81%99%E3%82%8B%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%AE%E5%AE%9F%E8%B7%B5%E6%8A%80%E6%B3%95-%E5%A2%97%E7%94%B0-%E4%BA%A8/dp/477419087X)　という本です。初心者にもわかりやすく読みやすい本です。
皆さんもぜひみてみてください。
jQueryのセレクタにご用心

jQueryを使うには`$(セレクタ)`のような書き方がよく出てきますが、このセレクタにもいくつか注意しないといけない点があります。

# jQuery独自セレクタ

jQueryは`querySelectorAll`どころか`getElementsByClassName`すらない時代から続いてきたこともあって、[Sizzle](https://sizzlejs.com/)という独自ライブラリをセレクタの処理に使っています。そして、独自ライブラリということもあって、本来のCSSにないセレクタを拡張しています。

独自セレクタはjQueryのサイトから[一覧](http://api.jquery.com/category/selectors/jquery-selector-extensions/)を確認できますが、以下のようなものがあります。なお、独自セレクタを使うと、

* `querySelectorAll`に任せられないためJavaScriptで処理する必要があり、遅い
* jQueryにロックインされる

などデメリットが多いので、ふつうのセレクタで書けるものはそちら優先で書いたほうがいいですし、書けないものでもできるだけ絞り込んでから`.filter`を使うなどしたほうがいい、とのことです。

## `input`の種類

`:checkbox`、`:radio`など、`<input>`の種類ごとにセレクタが用意してありますが、これは標準の属性セレクタで`input[type="radio"]`のように書けます[^1]。

## 逆向きのセレクタ

`:parent`には逆の意味の`:empty`が、`[attr!=value]`には`[attr=value]`が標準でありますので、`:not(:empty)`とすれば標準のセレクタで書けます。

## 数を数える系のセレクタ

`:even`、`:odd`、`:eq`など、jQuery要素を数えてフィルタリングするセレクタがありますが、これらは**状況によっては**標準セレクタの`:nth-child`に置き換え可能です。大きな違いとして、

* 複数の親要素に散らばっている場合、jQueryでは親要素を問わずに順番を数えるのに対して、`:nth-child`は親要素ごとに数える
* 数の基準が、jQueryは0オリジンなのに対して、`:nth-child`は1オリジン（なので、偶奇も逆転します）

## セレクタで書けないもの

標準セレクタに`:checked`がある割に`:selected`がないのですが、jQuery拡張としては存在します（`<option>`の`selected`**プロパティ**を見ていく、という手段しかありません）。あと、`:visible`や逆の`:hidden`も存在しません（内部実装は、「エレメントの`offsetWidth`、`offsetHeight`、`getClientRects()`のどれかが値を持つ」という条件で`:visible`を判定していました）。

# `[checked]`と`:checked`の違い

これはCSSのセレクタなのでjQueryに限らない話ですが、`:checked`、`:disabled`、`:required`のようなセレクタがあります。`[checked]`などでも書け…そうに思えるかもしれませんが、これは**意味が違います**。`[checked]`はHTMLに書かれた`checked` **attribute**を参照するのに対して、`:checked`はエレメントの状態（**プロパティ**）を参照します。「ページ表示時点で`checked`だった要素」を取りたいという、確固とした意志のある状況でなければ、大半の場合に`:checked`のほうが適切かと思います。

# jQueryで使えないセレクタ

`:invalid`など最近CSSに加わったセレクタは、jQueryに投げ込むとうまく認識されないことがあります。どうしてもjQueryで処理したい場合、`$(document.querySelectorAll(':invalid'))`のような形にすれば、とりあえずは通せます。

[^1]: 等価なのは`[type="radio"]`ですが、`<p type="radio">`のような変な要素を探したいのでなければ、`input`を付けておいたほうがわかりやすいのでおすすめです。
MacからWindowsさわって¥を入力したい

エキゾ大好き、加藤です。

タイトルのとおりです。

Macの[Microsoft Remote Desktop]を使用しWindowsにRDPすると困ることが多々あります。
その中でも個人的に一番煩わしいことは、、、

```
¥
```
の入力。
ファイルのパスをコマンドで指定する時、ADのアカウントを指定する時など利用頻度は圧倒的。

実はMacのキーボードで入力した`¥`は
Windows上でファイルパスを指定する時の`¥`とは違います。
なんかよくわからないものです。

どういう意味かというと、、、
下記は[Microsoft Remote Desktop]で接続したWindows 2012です。
「コマンドプロンプト」を開き、Macからそのまま`¥`を入力したものです。
<img width="456" alt="エンマーク1.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/17b1ee33-7ab6-4820-6be3-18e298fd85fc.png">

ちなみに下記が本来ファイルパスを指定する時の`¥`です。
<img width="430" alt="エンマーク2.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/d6d3f2c7-1fc1-651f-e051-1fc0f8460470.png">

何が違うんだよ！！！！って感じですが、並べると下記です。
(左側がMacからの`¥`。右側が本来入力したい`¥`)
<img width="424" alt="エンマーク3.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/2d0ffbf6-ac26-aeec-de9f-86576f076756.png">

・・・**微妙〜っ**に違うことがわかりましたか？
これのタチの悪いところはコマンドプロンプトで並べたらわかりますが、notepadではわからないところです。

下記わかりますか？
コマンドプロンプト同様、notepad上でも左4文字と右4文字は別の文字です。
(見た目まったくわからないですが、notepadの文字をコピーしてコマンドプロンプトに貼り付けると違いがわかります。)
<img width="357" alt="エンマーク4.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/25067915-037d-1fc1-8460-ab629dd1bbb8.png">

ということでMacから[Microsoft Remote Desktop]経由でWindowsを操作する際はご注意を！！

ここで便利なコマンド。というか小技を紹介。
「コマンドプロンプト」で

## 小技

```
osk
```
を入力するとソフトウェアキーボードを出せます。
<img width="243" alt="osk1.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/bc79427a-3663-5ddd-59bf-27a0e00acb08.png">

<img width="862" alt="osk2.png" src="https://qiita-image-store.s3.amazonaws.com/0/191445/a6a4e543-fa2e-b803-1eb9-a1de87dca238.png">

ここから`バックスラッシュ`をクリックするとWindowsで入力させたい`¥`になります。

小技でした。
Udemyのコース「【作りながら覚える！】 Ruby on Rails を用いたウェブ開発(Airbnbを作ろう！) 」を学ぶ。part2-2

Udemyの[こちらのコース](https://www.google.de/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&cad=rja&uact=8&ved=0ahUKEwjBu4a35bfXAhXQ16QKHfxQCvIQFggyMAE&url=https%3A%2F%2Fwww.udemy.com%2Fruby-on-rails-g%2F&usg=AOvVaw2zf_7hwBdtTsJHjjVy_0-6)を受けながら、疑問に思ったこと、調べた結果、大事なことをまとめていきます。

#part2-2 linkでページ遷移ができるようにする
    <li><%= link_to"アカウント作成", new_user_registration_path %></li>
リンクの作成の仕方。　pathは、rake routesで確認。

*_urlは絶対パス*1で、redirect_toで用いる*2。
*_pathはルート相対パス*3で、redirect_to以外ではこれで問題ない。特にlink_toなんかでは、無駄な出力が省けるので推奨される。
[参照](http://shin.hateblo.jp/entry/2013/01/13/124158)

#自己課題
- アカウント作成のリンクを配置。
- ログインのリンクを配置。

#part2-3 SignupページにViewを整える

##bootstrapのform
[リンク](https://v4-alpha.getbootstrap.com/components/forms/)

form-groupとform-controlは一体となって使う。

##html.erbファイルでのclassなどの追加方法
    <%= f.email_field :email, autofocus: true %>
    |
    <%= f.email_field :email,:class => 'form-control', autofocus: true %>
placeholderもこのように追加可能。
    <%= f.email_field :email,:class => 'form-control', :placeholder=>'your mail',autofocus: true %>

class:'form-control'でもいけるらしい。

##パスワードの文字数変更
パスワードの入力フォームはこんなんになっている。

    <div class="form-group">
          <%= f.label :password %>
          <% if @minimum_password_length %>
          <em>(<%= @minimum_password_length %> 文字以上)</em>
          <% end %><br />
          <%= f.password_field :password, :class => 'form-control', :placeholder => 'your password',autocomplete: "off" %>
    </div>

@minimum_password_lengthが変数。「devise minimumpassword」でググって見ると、config/initializer.devise.rbに変更できるとある。これで対応する変数の数字を変えればいい。（変更が反映されるのはサーバーを一旦閉じないといけない。）



#自己課題
- navbarをsign inページに追加。
- deviseページ用のcssを追加
- 配置を真ん中に。bootrsrapを使って。
- サインインページにform-group,form-control　classを適用。placehodlerも。
- パスワードの長さを８文字以上に変更。
- 下のloginの表記を「ログインはこちらから」に変更
oci runtime errorでdockerが起動しなくなった件

AWS EC2上で起動させていたコンテナがリソース不足で応答不能になったので、
EC2停止 -> スケールアップ -> EC2起動
したら、コンテナが起動しなくなってしまった。

```
$ docker-compose ps
        Name                      Command                State     Ports
------------------------------------------------------------------------
ec2user_gitlab_1       /sbin/entrypoint.sh app:start    Exit 255
ec2user_postgresql_1   /sbin/entrypoint.sh              Exit 255
ec2user_redis_1        /sbin/entrypoint.sh --logl ...   Exit 255


$ docker-compose up -d
Starting ec2user_postgresql_1 ...
Starting ec2user_redis_1 ...
Starting ec2user_postgresql_1
Starting ec2user_postgresql_1 ... error

ERROR: for ec2user_postgresql_1  Cannot start service postgresql: oci runtime error: container with id exists: 6b69a34b1f5b140bc5b8Starting ec2user_redis_1 ... error

ERROR: for ec2user_redis_1  Cannot start service redis: oci runtime error: container with id exists: fdef8901e8a94418b4cca0fb3eaa7851128cff85eda0e622e7ed9fd013707516

ERROR: for redis  Cannot start service redis: oci runtime error: container with id exists: fdef8901e8a94418b4cca0fb3eaa7851128cff85eda0e622e7ed9fd013707516

ERROR: for postgresql  Cannot start service postgresql: oci runtime error: container with id exists: 6b69a34b1f5b140bc5b889644d117d53fd1840d96879d80ffbdc6284f7ec0305
ERROR: Encountered errors while bringing up the project.

$ docker logs <container id>
   :
   :
container with id exists: <container id>

```

dockerやEC2を再起動しても解決しなかったが、以下の手順で復活できました。

```
$ sudo su -
# cd /run/runc/
# ls 
<container id1> <container id2> <container id3>
# rm -fr *

$ docker-compose up -d
Starting ec2user_postgresql_1 ...
Starting ec2user_redis_1 ...
Starting ec2user_postgresql_1
Starting ec2user_redis_1 ... done
Starting ec2user_gitlab_1 ...
Starting ec2user_gitlab_1 ... done

$ docker-compose ps
        Name                      Command               State                           Ports
---------------------------------------------------------------------------------------------------------------------
ec2user_gitlab_1       /sbin/entrypoint.sh app:start    Up      0.0.0.0:10022->22/tcp, 443/tcp, 0.0.0.0:10080->80/tcp
ec2user_postgresql_1   /sbin/entrypoint.sh              Up      5432/tcp
ec2user_redis_1        /sbin/entrypoint.sh --logl ...   Up      6379/tcp
```
めでたしめでたし。

今まで何度も同じEC2インスタンスを停止->再開していても問題はありませんでした。
今回のような問題に遭遇したのは初めてでしたが、EC2の停止にだいぶ時間がかかっており、少し怪しい気配は感じていました。

削除した `/run/runc/<container id>/` には `state.json` というファイルが存在していて、サイズは25Kほどありcontainerの状態を保持しているようでした。
コンテナを停止するとディレクトリごと消える為、サーバが異常終了し、このファイルが残ってしまった事が原因のようでした。
parallel-fastq-dump

#parallel-fastq-dump
マルチコアでfastq-dumpを実行できるラッパーです。
本家はpythonですが[inutanoさん](https://github.com/inutano/pfastq-dump)がbashで実装しています。

pfastq-dumpの実行には[sra-tools](https://github.com/ncbi/sra-tools)のfastq-dumpとsra-statのパスを通しておく必要があります。

```
git clone http://github.com/inutano/pfastq-dump
cd pfastq-dump
chmod a+x bin/pfastq-dump
```

SRA IDを指定してダウンロードからfastq変換までしたい場合は以下のコマンドを打ちます。

```
pfastq-dump -t 12 -s SRR1781891 -O pfd_test
```

fastqファイルが生成されているはずです。

例として、[SRP052999](https://www.ncbi.nlm.nih.gov/Traces/study/?WebEnv=NCID_1_36761486_130.14.22.76_5555_1514266965_2617092658_0MetA0_S_HStore&query_key=1)のデータをいくつかダウンロードしてみます。

```

for srr_id in SRR1781884 SRR1781885 SRR1781886 SRR1781887 SRR1781888 SRR1781889 SRR1781890 SRR1781891 ; \
do \
pfastq-dump -t 12 -s $srr_id ; \
done

```
RNA-Seq解析フロー



本項では公共データベースからのRNA-Seqデータのダウンロード、マッピング、正規化、各種エンリッチメント解析(GO、KEGG、wPGSA)の解析の流れをできるだけ解りやすく説明していきたいと思います。

#解析の流れ
   1.[公共レポジトリSRAからRNA-Seqデータの取得(pfastq-dump)](https://qiita.com/vanillin99/items/18b6a07c5be2ead16f8e)
   2.RNA-Seqデータのマッピング
----2-1.[STARを使ったマッピング](https://qiita.com/vanillin99/items/6c4854a62e548ec8cf71)
----2-2.kallistoを使ったマッピング
   3.[カウントデータの正規化(DESeq2)](https://qiita.com/vanillin99/items/a9e941d5290a2f21a634)
   4.エンリッチメント解析
   ----4-1.GO
   ----4-2.KEGG
   ----4-3.[wPGSA](https://qiita.com/vanillin99/items/7adf8ce3263ede233d38)
PyCharm の auto-test が地味に便利

PyCharmにauto-testという機能があるのですが、リファクタの時にこれが結構便利なんです。

# auto-testとは

ソースを変更する度に自動でユニットテストを実行する機能です。

# 使い方

1. テストクラスを手動で実行(run)する。(デバッグではダメ)
2. runタブ左側の[toggle auto-test]ボタンを押してauto-testをonにする。  
<img width="347" src="https://qiita-image-store.s3.amazonaws.com/0/35192/585a04e6-1cd4-80b5-3da3-7e80c0065f4a.png">
3. ソースを変更する。 -> 数秒後に自動でテストが再実行される。

# 設定

runタブの設定(歯車アイコン)->[Set AutoTest Delay]で、ソースを変更してからテストが実行されるまでの遅延時間を設定できます。

<img width="528" src="https://qiita-image-store.s3.amazonaws.com/0/35192/f8d854c1-3298-de6e-d5b0-4d7441ae0182.png">


# 参考

https://www.jetbrains.com/help/pycharm/test-runner-tab.html
クローリングしてきたテキスト、画像をローカルに保存

##Webから取得したデータを保存


requests とBeautifulSoup をインストールする

```console
$ pip install beautifulsoup4
```

```console
$ pip install requests
```

###txtを書き込む
ニュースのトピックなどをローカルのtxtファイルに改行を挟みながら書き込む

```py:title.py

import time
import sys 
import requests 
from bs4 import BeautifulSoup 

url = 'URL'
res = requests.get(url)
soup = BeautifulSoup(res.content,'html.parser')

for a in soup.find_all("タグ",attrs={"属性": "属性名"}):
    try:
        h1_text = a.string 
        print(h1_text)
        with open('ファイル選択', 'a+') as f:
            f.write(h1_text+"\n")
    except Exception as e:
        print(e)
    finally:
        time.sleep(2)

```

ファイル選択では絶対パスを指定する

```
C:\workspace\sample.txt
```
なら

```
c:\\workspace\\sample.txt
```

###jpgを書き込む
サイトの画像をダウンロードしてローカルに保存する

```py:jpg.py
import time
import sys 
import requests
from bs4 import BeautifulSoup 
import shutil

url = 'URL'
res = requests.get(url)
soup = BeautifulSoup(res.content,'html.parser')
i = 0

def download_img(url, file_name):
    r = requests.get(url, stream=True)
    if r.status_code == 200:
        with open(file_name, 'wb') as f:
            r.raw.decode_content = True
            shutil.copyfileobj(r.raw, f)
            
def download():
    global i
    for tag in soup.find_all("img"):
        try:
            href = tag.get("タグ")
            download_img(href, 'ファイル名%d.jpg' %i)
            print(href)
            i = i + 1
        except Exception as e:
            print(e)
        finally:
            time.sleep(2)
try:
    while(True):
        if soup.find("タグ名" ,attrs={"src": "/common/img/blank.gif"}):　#画像があれば続行する
            print(y)
            download()
            break
        else:
            url = 'URL'
            res = requests.get(url)
            soup = BeautifulSoup(res.content,'html.parser')
except Exception as e:
    print(e)

```

試したときにはそのサイトが更新時に時々画像が表示されない場合があったのでタグを見つけたら開始するようにした


##最後に
クローリングは便利だがサイトによっては利用規約などに禁止事項として載っている場合があるので注意する必要がある。
また、待ち時間を最低1秒以上はもたせて紳士的なクローリングを心掛ける
値にカンマが含まれるCSVをパースする

カンマって値中に入っていがちなので、カンマ区切りのファイルってめんどくさいですよね。

例えばこんなファイルから

```
1,A,apple,pie
2,B,"banana,blueberry",juice
3,C,cherry,pie
```

次のように3列目だけ抜き出したい場合

```
apple
banana,blueberry
cherry
```

カンマで区切ろうとすると値中のカンマが邪魔になります。

いろいろ考えてみたのですが、次の手順が比較的簡潔なのかなと思いました[^1]。

1. 行をダブルコーテーションで区切ってタプルに入れる
2. タプルの奇数番目にあるカンマを別の文字（この例では空白[^2]）に置換する
3. 2を結合した後、カンマで区切る

```python:parseComma.py
for line in inFh:
    line = line.rstrip()
    cols = line.split('"')

    tmp = [col.replace(",", " ")
           if ind%2==1 else col
           for (ind, col) in enumerate(cols)]

    line = "".join(tmp)
    cols = line.split(",")
    （以下略）
```

調べないで書きますが、もしかしたらこういうののいいパーサーがあるのかもしれないですね。

ついでにどうでもいいことですが、カンマなのかコンマなのか、ダブルコーテーションなのかダブルクォーテーションなのかも悩ましいです。

[^1]: ここでは値中のカンマは別文字に置き換えていいものとしています。あと、値中にダブルコーテーションが含まれた場合は考慮していません。

[^2]: 後でカンマに戻すならもっと特殊な文字がいいかも
EC2(Amazon Linux)とRDS(MySQL)でLAMP環境を構築するまで

備忘録程度に簡単にメモ

# EC2でLAMP環境を構築するまでにやったこと

## AWSでやったこと
- AWSのアカウントを作った
- 無料枠の範囲内でとりあえずEC2とRDSを立てる
理由はなくなんとなくAmazon LinuxとMySQLの構成で作成。
RDSを作成する時は無料枠のオプションを表示することが出来るので、そのチェックを入れておくと料金が発生する設定にしてしまうことを防ぐことができる。
- 請求アラームの作成
０ドルを超えるとメールで発報するよう設定（通常料金でも1,000円に収まる範囲だと思うが無料枠でいろいろしたいので）
- Elastic IPの取得
IPアドレスを取得し、EC2に関連付ける（無料枠内で起動しているEC2に関連付けされている間は無料らしい）
- EC2のセキュリティグループにアクセスする際のIPからのSSH接続を許可
ここで一緒に任意のIPからのHTTP/HTTPSも許可しとくといい

たぶんざっくりこんなもん
リージョンはオレゴン（リージョン次第で無料かどうか変わるのかはわからない）
## SSH接続の設定
EC2を作成したときにpemをDLしているはずなので、それを使ってSSH接続してみる
### pemの権限設定を変更する

```
$ chmod 400 [pemのパス]
```

### SSH接続してみる
```
$ ssh -i [pemのパス] ec2-user@[パブリックドメイン]
```

パブリックドメインはec2から始まるインスタンスごとに勝手に設定されているもの
こんなの（ec2-11-111-111-1.us-east-2.compute.amazonaws.com）

これでつながるはず。繋がらなかったらインバウンドで許可したIPアドレスに間違いがないか、
ユーザ名（デフォはec2-user）を別に設定していないかなどを確認

ここまでできればあとはサーバ側の設定とDNSさえどうにかすればWebサーバとして利用できる

### SSHConfigをいじって接続しやすくする（おまけ）
```
$ vi ~/.ssh/config 
```

以下のような感じで追記

```
#AWSサーバ
Host [sshコマンドで使う名前]
        HostName [パブリックドメイン]
        User ec2-user
        IdentityFile [pemのパス]
```

これで以下みたいに簡単に接続できる

```
$ ssh [sshコマンドで使う名前]
```
## サーバ側の設定（とりあえずPHPとMySQLが使える状態に持っていく）
### とりあえずソフトウェアパッケージを更新
```
$ sudo yum update -y
```
### Apahe、PHP、MySQLをインストール
```
$ sudo yum install -y httpd24 php70 mysql56-server php70-mysqlnd
```
### Apache起動とサーバ起動時に自動的に立ち上がるよう設定
```
$ sudo service httpd start
$ sudo chkconfig httpd on
chkconfig --list httpd
httpd           0:off   1:off   2:on    3:on    4:on    5:on    6:off
```

EC2のインバウンド設定でHTTPを任意のIPに対して許可していれば、ブラウザにIPアドレスを入力すると
Apacheのテストページが見れるはず
### Apacheのドキュメントルートを編集できるようにする
デフォルトではApacheは/var/www/htmlをドキュメントルートにしている。
/var/wwwディレクトリはrootが所有者なので、apacheユーザに変更する
SSH時のユーザはec2-userなので、apacheユーザグループにec2-userを追加する。

```
$ sudo usermod -a -G apache ec2-user
```

再接続する

```
$ exit
$ groups
ec2-user wheel apache
$ sudo chown -R ec2-user:apache /var/www
```

グループ編集許可を与える

```
$ sudo chmod 2775 /var/www
$ find /var/www -type d -exec sudo chmod 2775 {} \;
$ find /var/www -type f -exec sudo chmod 0664 {} \;
```

### PHPファイルの動作を確認する
さっきの設定がうまく行っていれば、ec2-userはルートディレクトリにファイルを作成する事ができるはず

```
$ echo "<?php phpinfo(); ?>" > /var/www/html/phpinfo.php
```

[IPアドレス]/phpinfo.php にアクセスしてPHPの情報が表示されるはず
公開すべき情報ではないので、忘れずに削除しとく

```
$ rm /var/www/html/phpinfo.php
```
## EC2とRDSを疎通させる
### とりあえずMySQLポートを開放
EC2のインバウンドにMYSQLの接続を任意の場所から許可するよう設定
### mysqlコマンドでRDSのMySQLへ接続してみる
RDSのインスタンスのセキュリティグループで、EC2インスタンスのセキュリティグループからのMYSQL接続を許可するよう設定

```
mysql –h [RDSインスタンスのエンドポイント] -P 3306 –u [ユーザ名] –p
Enter password: [パスワード]
```

基本的にユーザ名とパスワードはAWSのユーザ名パスワードになっているはず（何も設定していなければ）


ここまでできればApache、PHP、MySQLのセットアップはざっくりと完了。
セキュリティ的な話をすると弱い部分はたくさんあるので、実際の公開時には補強の必要があるが、
最低限は上記で完了。
後は静的HTML置くなり、Codeigniterでも入れて本格的なWebアプリ公開するなりする。
WindowsのForfilesコマンドで、特定のファイル名以外を操作する方法


# 経緯
自社で使っているサーバに保管されている一時ファイルが肥大化したため、一定日数以上、経過したファイルを削除しようと思いました。
ただ、そのフォルダの中には削除してはいけないファイルも入っており、これ以外を削除する必要がありました。

# ハマった例

### 前提
C:\temp配下にhoge.pdfとfuga.PNGファイルが存在するとします。
共に作成日は今日から15日以上前で、想定としては、fuga.PNGのみが削除されてほしいと考えています。

### 実行結果

> 何も指定しない場合

```
C:\TEMP\test>FORFILES /P "C:\TEMP\test" /S /M *.* /D -15 /C "cmd /c echo del @file"

del "fuga.PNG"
del "hoge.pdf"
```
> `if @file=="hoge.pdf"`を指定した場合、何も抽出されず…

```
C:\TEMP\test>FORFILES /P "C:\TEMP\test" /S /M *.* /D -15 /C "cmd /c if @file=="hoge.pdf" echo del @file"

C:\TEMP\test>pause
続行するには何かキーを押してください . . .
```

> `if not @file=="hoge.pdf"`と否定の条件を指定した場合、全て抽出されるのでif自体は有効と思われます

```
C:\TEMP\test>FORFILES /P "C:\TEMP\test" /S /M *.* /D -15 /C "cmd /c if not @file=="hoge.pdf" echo del @file"

del "fuga.PNG"
del "hoge.pdf"

C:\TEMP\test>pause
続行するには何かキーを押してください . . .
```

要するに`@file=="hoge.pdf"`の判定が上手くいかないがために、思った処理をすることが出来ませんでした。

# 解決方法
下記の様に判定対象の文字列を`0x22`で囲う事で問題が解消されました。
(`"`を生で書いちゃうとサブシェルに渡らないそうです… )
```
FORFILES /P "C:\TEMP\test" /S /M *.* /D -15 /C "cmd /c if @file==0x22hoge.pdf0x22 echo del @path"
```
ちなみに、サブディレクトリ配下も削除する場合は、`del @file`ではなく`del @path`とする必要もあるそうで。
今回の1件は、非常に勉強になりました。

> 引用元

[自分の質問](https://teratail.com/questions/100288)

ありがとうございました。
Project Euler Q24 【辞書式順列】

Project Eulerをワンライナーで解いてみる。
間違っていたらコメントください。


## 問題
順列とはモノの順番付きの並びのことである. たとえば, 3124は数 1, 2, 3, 4 の一つの順列である. すべての順列を数の大小でまたは辞書式に並べたものを辞書順と呼ぶ. 0と1と2の順列を辞書順に並べると
012 021 102 120 201 210

になる.

0,1,2,3,4,5,6,7,8,9からなる順列を辞書式に並べたときの100万番目はいくつか?

## アプローチ
1.辞書式に並べるとはつまり昇順に並べることである。
2.次に、例えば1桁目を0と仮定すると$9!=362880$通り存在する。
3.$1000000/362880=2 あまり274240$であるから、
1桁目が0と1の場合は全て収まりきり、1桁目が2のときに100万桁目に到達する。
よって、1桁目の値は$2$に決まる。
4.これを繰り返していく。
5.7桁目まで決まると余り4になる。
$4=2*2$であるので8桁目は残っている数字で2番目に大きい数、9桁目も2番目に大きい数になる。
(6.ロジック的に10桁目は「残っている数字で1番大きな数」とする。たまたま0だが。)

## 解答

```bash
seq 9 |
tac |
awk '{a=1;for(i=1;i<=$1;i++){a*=i};print a,11-i}' |
awk 'BEGIN{n=10^6} {s=int(n/$1);n=n%$1;print s,n,$0}' |
sed '/^0 /d' |
awk '$2!=0{print $1+1,$2,$3,$4} $2==0{v[1]=$1;v[2]=$3;v[3]=1;for(i=$4;i<=10;i++){print v[i-7],$2,$3,i}}' |
awk '{c=0;for(i=0;i<=9;i++){if(!(i in a)){c++};if(c==$1){break}};a[i]=1;printf i}'
2783915460
```

他の番目ではできないかも。
ひとまず余りが4になるような番目なら可。

疲れたからこの問題もうやりたくない。。

## 答え合わせ
こちらのサイト様と一致していればOKとした。
http://kingyojima.net/pje/024.html
プログラミング未経験者がエンジニア目指す(その4)

# N予備校の章
第1章
・ 06.JavaScriptでの計算
## はじめに
・変数とか出てきて、数学チックなことするの7年振りだった。
## 概要
・変数、数学記号、値を利用して計算させる。
## 分かったこと
・プログラムにコメントを入れられること。
## 疑問点
・浮動小数点数とは何か(テキスト読んでもさっぱりわからない)
・プログラム内で小数点がある計算させると誤差がでるらしいけど、誤差ってそもそも出て良いのかな。
・エンジニア目指すためには数学もできないとだめなのか。
## 感想
・｢計算」というだけでものすごく身構えた。(seachanはバリバリ文系なため)
## 終わりに
・プログラムで計算させるのと電卓で計算させるのどちらが早いんだろうと思った。
【Android】サービスが実行中かチェックしてから起動する

無駄にサービスのインスタンスを増やしたくなかったので、実行中かチェックしてから起動する。
minSdkVersion 23
targetSdkVersion 23
で確認しました。

```HogeService.java
import android.app.ActivityManager;
...

ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo serviceInfo : manager.getRunningServices(Integer.MAX_VALUE)) {
    if (HogeService.class.getName().equals(serviceInfo.service.getClassName())) {
    	// 実行中なら起動しない
        return;
    }
}
Intent intent = new Intent(getApplication(), HogeService.class);
startService(intent);
```
android studio 2.3 を 3.0 に自動アップデートしたら英語になった

たぶん、2.3 の設定をインポートしなかったせい。

http://mergedoc.osdn.jp/ 
上記から最新版をダウンロードしてインストール。インストール方法は上記のサイトに有るので
本当によく読めばそれだけでできる。

余談
Google で「android studio 日本語化」などで検索したときに、
上記のサイトが初めに出てくるべきだと思います。
Datagripで踏み台サーバ（Bastion）経由で接続する

ローカル環境のMac OSからAWS上に存在する踏み台サーバ経由でstaging環境へアクセスし、そこからDBへ接続する方法
``` ローカル → EC2(踏み台) → EC2(Staging) → RDBMS(Mysql) ```

## 前提
ローカル環境のMacの.ssh/configに踏み台経由での各サーバへの接続方法を記載

例：

```bash:.ssh/config
Host sample-proxy
  User user
  Port 22
  Hostname xxx.xxx.xxx
  preferredauthentications publickey
  IdentityFile ~/.ssh/id_rsa

Host *sample.jp
  User user
  port 22
  ProxyCommand ssh sample-proxy nc %h %p
  preferredauthentications publickey
  IdentityFile ~/.ssh/id_rsa
```

## 手順
2017年11月13日現在 stable版ではローカルの.ssh/configを読む設定は選択できなさそうです。
EAPだと上記設定が可能な為、設定できるようにします。

1. ``` Preferences > Appearance & Behavior > System Settings > Updates ``` で Early Access Program　を選択
  ![eap.jpeg](https://qiita-image-store.s3.amazonaws.com/0/64171/f800a75d-ad44-bc51-420f-e0e56a092064.jpeg)
2. Datagrip をアップデートする
3. SSH/SSL のAuth Typeで OpenSSH config and authentication agentを選択
  ![ssh.jpeg](https://qiita-image-store.s3.amazonaws.com/0/64171/72cf2874-5edc-85c7-5fe9-d786830e1562.jpeg)
4. これでローカルの.ssh/configを使用してDBアクセスが可能になります
await hoge() SyntaxError: Unexpected identifier


```
/file.js:3
    let fuga = await hoge.fuga();
                     ^^^^
SyntaxError: Unexpected identifier
```

大抵asyncを忘れている。

```js

browser.on('click', hoge => { // ←短いアロー関数式書けていい気になってasync忘れている
  // console.log(hoge) // ←だいたい最初はawait不要なもので動作確認している
  let fuga = await hoge.fuga(); // 本命コード書き始めて慌てる
})
```

async付けても()の省略は出来る。

```js
browser.on('click', async hoge => { // async付けましょう
  let fuga = await hoge.fuga();
})
```
[要約・翻訳]FileMaker_Devcon_2017：Server Architecture and Performance in the Cloud Era

#### はじめに
* [2017年度のFileMaker Developer Conference](https://www.filemaker.com/learning/devcon/2017/index.html)のセッション動画から、気になったものをピックアップして視聴したので、自分メモを兼ねてご紹介いたします。
* FileMaker社がYoutubeに公開しているセッション動画のYoutubeリストは[こちら](https://www.youtube.com/playlist?list=PLkvKnBkQSCeQsTI4piarGbe1WusytNR_k)


#### 他に投稿した[要約・翻訳]
* [FileMaker_Devcon_2017：Under The Hood: Server Performance](https://qiita.com/Hi_Noguchi/items/0f1736dbb14295858a1e)


# Title: Server Architecture and Performance in the Cloud Era
* Speaker: Chris Irvine
* Company: Threeprong.com LLC

* 動画URL　https://youtu.be/U2ck45XhePw


## サーバをクラウドに立てるかどうかの検討要素
- 費用／予算
- 接続の簡易さ
- 速度
- 可用性
- 拡張性
- 持続性


## ストレージの種類毎のパフォーマンス比較

### レコード転送速度
5kb／1レコード　×　1,000レコード　＝　5MB　の転送

| ネットワーク | 1Gbps | 100Mbps |
| ------ | ----- | ------- |
|        | 0.04秒 | 0.4秒    |

|          | HDD   | SSD   | PCIe  |
| -------- | ----- | ----- | ----- |
| 200Seeks | 0.60秒 | 0.02秒 | 0.02秒 |
| 5MB転送    | 0.05秒 | 0.00秒 | 0.00秒 |

### 索引つきの検索
フィールドの索引が2MBある時

|         | HDD   | SSD   | PCIe  |
| ------- | ----- | ----- | ----- |
| 50Seeks | 0.15秒 | 0.01秒 | 0.01秒 |
| 2MB転送   | 0.02秒 | 0.00秒 | 0.00秒 |

### 索引なしの検索
5kb／1レコード　×　10,000レコード　＝　50MB　の転送

|           | HDD   | SSD   | PCIe  |
| --------- | ----- | ----- | ----- |
| 2000Seeks | 6.0秒  | 0.23秒 | 0.23秒 |
| 50MB転送    | 0.50秒 | 0.05秒 | 0.01秒 |

### オブジェクトフィールド転送
50MB　の転送

| ネットワーク | 1Gbps | 100Mbps |
| ------ | ----- | ------- |
|        | 0.38秒 | 3.8秒    |

|         | HDD   | SSD   | PCIe  |
| ------- | ----- | ----- | ----- |
| 10Seeks | 0.03秒 | 0.00秒 | 0.00秒 |
| 5MB転送   | 0.05秒 | 0.00秒 | 0.00秒 |

### バックアップ
全部で1GBのデータベース

|       | HDD   | SSD  | PCIe |
| ----- | ----- | ---- | ---- |
| 1GB転送 | 10.0秒 | 2.0秒 | 0.5秒 |



## 使用技術ごとの留意点

### サーバサイドスクリプト実行

- 2コア以上にするべき

### WebDirect

- サーバサイドスクリプト実行よりパフォーマンスコストが高い
- 3コア以上にするべき
- 同時接続数が増えれば増えるほどコア数・メモリなど増やすべき


## ローカルサーバのコスト／スペック

### 開発環境

- 7万円-14万円程度

### 従業員が少規模(5-20名)の環境

- 35万円程度
- CPU：4コア以上
- WebDirect：2-10同時接続数

### 従業員が中規模(15-1,000名)の環境

- 90万円以上
- CPU：8コア以上
- WebDirect：10-100同時接続数


## 専用ホスティングサーバのコスト／スペック

### 従業員が小規模(1-50名)の環境

- 月額7千円-4万円程度
- WebDirect：1-50同時接続数


## FileMaker Cloudのコスト／スペック

### 従業員が中規模(1-250名)までの環境

- 月額6千円-24万円程度
- WebDirect：1-100同時接続数


## AWS上で稼働させるサーバのコスト／スペック

### 従業員が中規模(1-250名)までの環境

- 月額7千円-40万円程度
- WebDirect：1-100同時接続数


## 補足
AWSのお話やコンピュータアーキテクチャの話など一般論的なところは割愛します。
でも、AWSのアーキテクチャ概要は割と分かりやすいので（40分あたり）AWSへFileMaker Serverをたてようかと考えている人は、動画を見ると幸せになれそうです。
Vscode | UIにファイルのフルパスを表示する

Settings で以下を指定する。

例:

```
"window.title": "${activeEditorLong}"
```


![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/1934806c-6510-f345-f484-ab8ddf6544b2.png)

# 参考

- [Display the full workspace path in UI · Issue #3119 · Microsoft/vscode](https://github.com/Microsoft/vscode/issues/3119)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
PHPでMySQLの型が勝手にstring型にされてしまう件

# 概要
なんでかMySQLの型はtinyIntとか明らかにstringではないのに、PHPのPDOを使ってSELECTし、型をvar_dumpするとstringになっている。これには原因があり、少しハマったのでメモ。

### 犯人は「PDO」(PHP Data Objects)と呼ばれるやつ。



# 原因はPDOのエミュレートモード


具体的にはPDOがプリペアードステートメントエミュレートモードで動いている場合にint型がstring型になる様子。
PDOのデフォルトでは、プリペアードステートメントエミュレートモードというモードで動いている。
[PHPマニュアル(PDO::setAttribute)](http://php.net/manual/ja/pdo.setattribute.php)には以下のようなことが書いてある。

> PDO::ATTR_EMULATE_PREPARES プリペアドステートメントのエミュレーションを有効または無効にする。 ドライバによってはネイティブのプリペアドステートメントをサポートしていなかったり 完全には対応していなかったりするものがある。この設定を使うと、常に プリペアドステートメントをエミュレートする (TRUE の場合) か、 ネイティブのプリペアドステートメントを使おうとする (FALSE の場合) かを設定できる。現在のクエリを正しく準備できなかった場合は、常にエミュレート方式を使う。 bool で指定する。


# 型変換を回避

## 結論
### PDO::ATTR_EMULATE_PREPARES属性 => false とすることで回避可能


PHP5.3以上であればmysqlndがデフォルトになっているため、特別に何かする必要は無い。
ただし、完全対応が済んでいると思われるMySQLのようなDBでなければ、結局はstringになることは避けられない(?)。


そのため、プリペアードステートメントに完全に対応しているドライバかを確認してからこの設定を変更することが望ましい。

mysqlのドライバである、mysqlndはプリペアードステートメントに完全に対応しているドライバであるため、問題ないと思われる(既存バグが)。
Pandasで NaN (Null) の行だけ抽出

#Pandasで列が NaN の行を抽出する方法

######データの準備

```
In [3]: df=pd.DataFrame(np.random.randn(5,5))
In [4]: df.columns=list('ABCDE')
```

######iloc で Null を設定して・・・

```
In [21]: df.iloc[1,1]=np.nan

In [30]: df
Out[30]:
          A         B         C         D         E
0       NaN -0.785578 -0.688584 -0.335229 -1.981495
1  0.094032       NaN  1.482541  0.160781  0.106237
2 -1.912919  1.432783       NaN       NaN  1.212469
3 -0.549426  0.236417  0.087149       NaN  1.089239
4 -0.056149 -0.696856  1.137570  0.855886       NaN
```

~~#####isnull()  == True で NaN を持つ行だけを抽出できる~~
#####isnull()  で NaN を持つ行だけを抽出できる
(2017/11/13 修正しました。Hoxo_m さんご指摘ありがとうございます）

```
In [31]: df[df['A'].isnull()]
Out[31]:
    A         B         C         D         E
0 NaN -0.785578 -0.688584 -0.335229 -1.981495

In [32]: df[df['B'].isnull()]
Out[32]:
          A   B         C         D         E
1  0.094032 NaN  1.482541  0.160781  0.106237

In [33]: df[df['C'].isnull()]
Out[33]:
          A         B   C   D         E
2 -1.912919  1.432783 NaN NaN  1.212469

In [34]: df[df['D'].isnull()]
Out[34]:
          A         B         C   D         E
2 -1.912919  1.432783       NaN NaN  1.212469
3 -0.549426  0.236417  0.087149 NaN  1.089239

In [35]: df[df['E'].isnull()]
Out[35]:
          A         B        C         D   E
4 -0.056149 -0.696856  1.13757  0.855886 NaN

```
R.java

android studio でテンプレートを使用して出てくるプロジェクトに
R 変数(クラス)がいきなりいる。

R はメニューなどの id を管理するため、自動で生成されるものらしい。
build フォルダなどに R.java が自動で作られていた。

どこで宣言しているか、探しても見つからないから何者かと思ってしまう。

一から順に勉強している人は躓かないが、
とりあえず、android studio 触って動かして調べようなんて
めんどくさがりは引っかかるかも
Lambdaを触ってみて学んだ基本的なこと

Lambda＋Node.jsを使ったサービスを実装した際のTipsを雑多に書きます
※公式のドキュメントに書いてあることがほとんどです

# ファイルを一時的に置くためのディスク領域(/tmp)が用意されている
プログラム内でファイル出力をしたい場合は、/tmpにファイルを置いておくことができる
<pre>
一時ディスク容量 ("/tmp" スペース)	512 MB
</pre>
公式ドキュメント
AWS Lambda の制限
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/limits.html

※注意
LambdaはAWSのコンテナで動作するらしく同じLambdaファンクションであればコンテナを使いまわすことがあるようで、/tmpも使いまわされる
・前の処理で/tmpに配置したファイルが残ったまま、次のLambdaが起動して意図しない動作になる
・/tmpの容量制限512MBはコンテナごとの容量制限なので、ファイルが残ったままだと一時ディスク容量制限をオーバーしてしまう
といったことが起きるのでご注意を

# ログの出し方

標準出力させると、cloudwatchにログが出力されます
※cloudwatchにログを出力するためには、Lambdaに「Lambdaへのフルアクセス権限」を与える必要があります

Node.jsの例

Lambdaファンクションが起動すると、cloudwatchに「Lambdaが起動しました」と表示するだけの例
<pre>
exports.handler = (event, context, callback) => {
    console.log("Lambdaが起動しました");
}
</pre>

# 環境変数

Lambdaでは環境変数を利用することが出来ます

AWSコンソールのLambda関数画面の設定タブ内の「環境変数」で設定できます

設定例
![環境変数利用例.PNG](https://qiita-image-store.s3.amazonaws.com/0/146115/b2e52169-d0a4-1ba5-452a-fae1d76f06be.png)

↑の環境変数を、プログラム内で利用する例(Node.js)
<pre>
const env = process.env.NODE_ENV;
</pre>

# ストリーム(Amazon DynamoDB ストリーム、kinesisストリーム)をトリガーにする時に気を付ける事

ストリーム(Amazon DynamoDB ストリーム、kinesisストリーム)をトリガ―にする場合とストリーム以外(S3、SNSなど)をトリガーにする場合で、リトライ処理の挙動に違いがあります

-  ストリーム以外(S3、SNSなど)をトリガーにする場合
エラーが発生した場合、呼び出しが 2 回自動的に再試行される
→エラー発生後2回再試行すれば止まる

- ストリーム(Amazon DynamoDB ストリーム、kinesisストリーム)をトリガ―にする場合
AWS Lambda はデータの有効期限 (Amazon Kinesis Streams の場合 7 日間) が切れるまで、レコードのエラーが発生したバッチを試みる
→エラー原因が解消されない限り、有効期限がくるまで延々とバッチを繰り返すので無駄なお金がかかる

公式ドキュメント
エラー時の再試行
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/retries-on-errors.html

# 終了コード

Lambdaの終了コードを指定することが出来ます

- succeed

成功

- fail

失敗

- done

実行完了(引数でエラーと成功を出し分け出来る)

以下はNode.jsでの終了コード指定方法例
<pre>
const env = process.env.NODE_ENV;
exports.handler = (event, context, callback) => {
    if (env === "product") {
        console.log("本番環境です");
        context.succeed(); // 正常終了
    } else {
        console.log("本番環境ではありません");
        context.fail(); // エラー終了
    }
}
</pre>

doneは使いどころがよく分かってません

# メモリとタイムアウトについて

Lambdaファンクション設定時に、メモリとタイムアウトを設定することが出来ます
メモリを大きくするとCPU性能もそれに見合っただけ上昇します
cloudwatchのログに実際に使用したメモリ容量と処理時間が出力されるので、ファンクションを実際に動かしてみて最適な設定値を決めましょう
メモリを大きくするとコストも上がるので、最初から最大値にしておくということは避けましょう

メモリとタイムアウトが設定値を超えた場合、エラー判定となります

# 細かいこと

### トリガーを有効化して初めてLambdaを起動する場合、初期化に時間がかかります(数分？)
 すぐにログが出なくても焦らず待ちましょう
pacman -Syu で eno0 を失った時の対応まとめ

#TL;DR
`pacman -Syu` (`linux` パッケージをアップデート) する時は、 `/boot` のマウントがちゃんとされているか確認しようという話.

```
OS: Arch Linux 4.13.11
```

# 今回起きた起きた現象
## インターネットに繋がらない

- Ethernet Controller が動いていない 
    - `$ lspci -v | grep -10 Eth` でみたとき, `kernal modules: e1000e` がなくなったり, 色々 `[disabled]` になったりしていた. 
-  `$ ip addr show` だとか `$ ifconfig -a` だとかで `lo` しか表示されない.
-  NFS 関連のエラーが起動時に起きる. 

## バージョン違う！？
- `pacman -Q linux` と, `uname -a` で linux のバージョンが異なる状態になっている. 


# やったこと
```bash
$ pacman -U /var/cache/pacman/pkg/linux-<元のバージョン>
```
で, 元のバージョンに戻してから, リブート, 

すると, 正常に起動した (ように見えた) ので

```bash
$ mount /dev/<bootファイルが置いてあるパーティション> /boot
```
 
を実行し, ちゃんと `boot` がマウントできていることを確認した後に, 

再度, 

```bash
$ pacman -S linux
```

を実行した. 

# 今回起きた問題の原因
`$ pacman -Syu` で linux kernel のバージョンを上げた際に, 起動時に読み込まれる設定にしているディスクにカーネルイメージを書き込むことができていなかった. 

→ ディスクを `/boot` にマウントできていなかった. 

## インターネットに繋がらなかった原因
ネットワークアダプタードライバ [download link](https://downloadcenter.intel.com/ja/download/15817) (= Ethernet の Driver ?) であるところの `e1000e` という kernel module がアプデの影響により、`/lib/modules/4.13.11-1-ARCH/` のディレクトリにあるのに対して、実行されている ( `$ uname -a` で表示される) linux kernel は 4.13.7 だった. 
これにより、起動しているカーネルでは、ネットワークドライバが認識されていない (そんなドライバ存在しないよ！) 状態だった. 

> e1000e ないこと以外にも, lsmod で表示されるモジュールが明らかに少なかった

# 備考
当初、`systemctl` や `netctl` の profile 関連のファイルをいじって解決しようとしていたものの, それ以前の問題だった.

```bash
$ systemctl restart network
``` 

とか, 

```bash
$ netctl start <mypropile>
```

 をやった後, 

```bash
$ journalctl -xe
``` 

で出力されるログに
> Cannot find device <設定した interface 名> 

とか表示されて絶望しそうになっていた. 

```bash
$ lsmod
```

 で、 `e1000e` が表示されなかったりしたことから、`kernel module` の問題では？ と考えた.
そこで, 

```bash
$ find /lib/modules -name e1000e -print
```

を実行したことで, 先述したインターネットに繋がらなかった原因に気がついた. 

その後、研究室の先輩に 「アプデの時に `/boot` がマウントできてなかったのでは？」 というアドバイスをいただいたことにより解決に至った. 

# 最後に
他にも同じような問題を起こす方がいるかもしれないと思ったので, 備忘録も兼ねて記事にしてみました. 

Arch Linux 初心者のため, 記事には表現の間違いがあるかもしれません. 
間違いを見つけた際は, よろしければ, コメントにてご指摘いただけると嬉しいです.
Transmitの鍵認証のSFTP接続で「ファイルは未サポートの形式です。」とエラーが出るときの対処

## はじめに:CPIの場合

**対象サーバーが「CPIレンタルサーバー ACE01」の場合は、この記事の方法では接続できません。**2017年11月現在、SFTPの接続はパスワード方式のみとなっているためです。
「SSHでは接続できるのにSFTPでは接続できない」という状況になるのでかなりハマりました。

http://acesr.document.secure.ne.jp/ftp/sftp/

コントロールパネルからFTPアカウント（SFTPアカウントと共有です）を作成してください。

----

MacOS用のFTPクライアント「Transmit」は転送が早く、大量ファイルの管理がしやすいので重宝しています。

[パニック - Transmit - Mac OS X FTP + SFTP + S3 アプリケーションの完成形](https://panic.com/jp/transmit/)

「Transmit」はセキュリティ上強く推薦されている、鍵認証方式のSFTP接続にも対応していますが、いざ秘密鍵を登録しようとすると「ファイルは未サポートの形式です。」というエラーが出てしまい登録できません。

![ef7bc580a9b4ffa990aaf4b9bbf6f257.jpg](https://qiita-image-store.s3.amazonaws.com/0/21117/9a174e3c-544f-bf6c-e3be-e4930f39973a.jpeg)

これは、Transmitが秘密鍵ファイル（ここではRSA）をそのまま扱うことができないためです。一般的なOpenSSL証明書の形式である「**PEM形式**」に変換すると登録できるようになります。

※ドットではじまる非公開ファイルが、Finderで見えるよう設定している前提で解説しています。

## PEM形式のファイルを作成する

まず、受け取った秘密鍵ファイルを以下の場所へ移動してください。

```
*/Users/（MacOSのユーザー名）/.ssh/*
```

「Terminal（いわゆる、黒い画面）」を起動し、以下のコマンドを入力して、秘密鍵を置いたディレクトリへ移動してください。

```
cd /Users/（MacOSのユーザー名）/.ssh/
```

続いて、以下のコマンドを入力してください。

```
openssl rsa -in （秘密鍵のファイル名） -outform pem >（秘密鍵のファイル名）.pem
```

RSA形式ファイルをもとに、「秘密鍵のファイル名+.pem」というPEM形式のファイルを作成します。元の鍵はなくならないので安心してください。

もし、預かった秘密鍵のファイル名が「id_rsa」なら、コマンドは以下の通りとなります。

```
openssl rsa -in id_rsa -outform pem >id_rsa.pem
```

「秘密鍵のパスフレーズ（パスワード）」を聞かれるので入力してください。パスフレーズなしなら、何も入力せずエンターキーを押せばよいです。

生成されたPEM形式のファイルは、パーミッションが「644」となっています。オーナー以外が扱えないよう、以下のコマンドで「600」に変更しておきましょう。

```
chmod 600 id_rsa.pem
```
Finderでディレクトリを確認すると、PEM形式のファイルが増えているはずです。このファイルを、Transmitに登録してください。

![ec445d3dbab8fb680159bb283743db77.jpg](https://qiita-image-store.s3.amazonaws.com/0/21117/ad3d8051-5c12-2aef-1b2f-4dbd0f9f9ed7.jpeg)

## 補足

### Filezillaを利用している場合

いっぽう、同様に著名なFTPクライアントである「Filezilla」は、秘密鍵を「**PPK形式**」に変換する必要があります。こちらはコマンドは必要なく、「設定」メニューで秘密鍵を登録する際に、アプリケーション側で変換を行ってくれます。

ただし、Filezillaは非公開ディレクトリをブラウズできないので、「.ssh」ディレクトリに秘密鍵を入れていると登録できません。安全性は落ちますが、この場合は「書類」内にディレクトリを作っても問題はありません。
railsのlink_toでjavascript:voidやonclickを使う方法

#はじめに
簡単な記述ですが忘れがちなので備忘として残します

#viewに以下のようにlink_toを記述します
```
= link_to('name', 'javascript:void(0);',onclick: "console.log(’test')")
```

以上！
Angular Material のインストールガイド

# はじめに
Angular MaterialをAngular5系でインストールする手順をざっくりまとめてみた。
公式ガイドに沿っているけど、必要なさそうな部分はカットしてまとめている。
今回はAngular CLI 1.5.0 で検証。

#Angular Materialの導入

## プロジェクト作成
Angular CLIでプロジェクトを作成
作ったプロジェクトフォルダに移動

```
ng new sample-app
cd sample-app
```

## ライブラリをnpmでインストール

```
npm install --save @angular/material @angular/cdk hammerjs
```

## モジュールのインポート

```ts:app.module.ts
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonModule, MatCardModule, MatInputModule, MatToolbarModule } from '@angular/material';
    
  @NgModule({
  ...
    imports: [
      ...
      BrowserAnimationsModule,
      MatButtonModule,
      MatCardModule,
      MatInputModule,
      MatToolbarModule,
     ...

    ],
```

※Angular Materialで利用するモジュールを一つ一つ選択する点に注意。
他にも`MatCheckboxModule, MatRadioModule` などたくさんある。

## CSSテーマの設定

``` css:styles.css
@import "~@angular/material/prebuilt-themes/indigo-pink.css";
```
テーマファイルはデフォルトで以下のものが存在するのでお好みで。

- deeppurple-amber.css
- indigo-pink.css
- pink-bluegrey.css
- purple-green.css

## hammerjsのインポート

```ts:main.ts
import 'hammerjs';
```

## アイコンを利用できるようにする

```html:index.html
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
```

アイコンは必要な場合のみでOK。
でも、なぜここだけ直接Web上にあるものを参照するのだろう。。。


なにはともあれ、ここまででインストールは完了。
最新nghttpx ingress controller情報

最新の[nghttpx ingress controller](https://github.com/zlabjp/nghttpx-ingress-lb)の情報をシェアします。

nghttpx ingress controllerについては[このスライド](https://speakerdeck.com/tatsuhirot/nghttpx-ingress-controller)で簡単に紹介しています。

## --publish-service

これはnginx ingress controllerの--publish-serviceと同じ機能を提供するものです。

Ingress controllerは担当のIngressリソースの.status.loadBalancer.ingress[*]にロードバランサーのアドレスを追加します。nghttpx ingress contorllerの場合、デフォルトではingress controllerのPodのIPアドレスを追加するようになっています。

--publish-serviceフラグを使うと、指定したServiceのexternal IPsやLoadBalancerのアドレスを追加するように動作を変更します。

## default-backend-config

nghttpx ingress controllerは`ingress.zlab.co.jp/default-backend-config`アノテーションをIngressリソースに記述することで、バックエンド接続の追加設定を行うことができます。

例:

```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: greeter
  annotations:
    ingress.zlab.co.jp/backend-config: '{"greeter": {"50051": {"proto": "h2"}}}'
spec:
  rules:
  - http:
      paths:
      - path: /helloworld.Greeter/
        backend:
          serviceName: greeter
          servicePort: 50051
```

このアノテーションはjson形式で、Service名、サービスポートの組み毎に記述します。

新たに追加した`ingress.zlab.co.jp/default-backend-config`は、デフォルトのバックエンド設定を指定します。

```yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: greeter
  annotations:
    ingress.zlab.co.jp/default-backend-config: '{"affinity": "ip"}'
    ingress.zlab.co.jp/backend-config: '{"greeter": {"50051": {"proto": "h2"}}}'
spec:
  rules:
  - http:
      paths:
      - path: /helloworld.Greeter/
        backend:
          serviceName: greeter
          servicePort: 50051
```

とすると、default-backend-configの内容が合成され、greeter/50051のbackend-configは、`{"proto": "h2", "affinity": "ip"}`となります。

## affinity: cookie

`ingress.zlab.co.jp/backend-config`のaffinityで利用できる手法にcookieが追加されました。
nghttpxが`affinity-cookie-name`で指定した名前のcookieを発行し、クライアントが送り返してくるcookieの内容に応じてバックエンドサーバーを選ぶようになります。
秘密鍵・公開鍵を作成する（Win）

## 概要
windowsを使っている開発メンバーへ作成方法を共有する参考資料として作成する。

## 環境整備
まず、GitBashを使いたいので、「 [Git for Windows](https://git-for-windows.github.io/) 」をインストールする。
※インストール済みの人は不要

## インストール （Git for Windows）
![step01.jpg](https://qiita-image-store.s3.amazonaws.com/0/142279/18d42030-a468-254b-4952-9b072f71ca97.jpeg)
![step02.jpg](https://qiita-image-store.s3.amazonaws.com/0/142279/f13850ce-076a-e069-cbc4-8ce9b51185bb.jpeg)
![step03.jpg](https://qiita-image-store.s3.amazonaws.com/0/142279/8a7ea762-748c-c1ef-546d-5e49aa9baa51.jpeg)
![step04.jpg](https://qiita-image-store.s3.amazonaws.com/0/142279/93f1be1c-573d-48c6-732f-3ed1b09f87ff.jpeg)
![step05.jpg](https://qiita-image-store.s3.amazonaws.com/0/142279/be64d77c-5b44-9540-f70e-958b70860a13.jpeg)
![step06.jpg](https://qiita-image-store.s3.amazonaws.com/0/142279/b805d2f8-e894-2478-4d11-79e47c0d6127.jpeg)
![step07.jpg](https://qiita-image-store.s3.amazonaws.com/0/142279/8b55bb8b-11ea-7da7-a829-d3b695919b98.jpeg)
![step08.jpg](https://qiita-image-store.s3.amazonaws.com/0/142279/ef9f4142-c2fb-67d6-ae0c-74e085b29ae8.jpeg)
![step09.jpg](https://qiita-image-store.s3.amazonaws.com/0/142279/146f850d-59ee-78b6-d93d-fef33e02d2e6.jpeg)

## GitBashの起動
プログラムメニューから「<font color="red">Git Bash</font>」を起動します。

![menu.png](https://qiita-image-store.s3.amazonaws.com/0/142279/3e1bd4cb-bbe3-ce8d-0eb7-03817486452d.png)

下記コマンドにてssh-keygenコマンドがあるか確認する

```sh:GitBash
# コマンドの存在確認 (パス（/usr/bin/ssh-keygen）が表示されたら問題ありません)
$ which ssh-keygen
```

## 秘密鍵と公開鍵を作る
下記コマンドにて作成します（<font color="red">メールアドレスは自分のアドレスに置き換えてください</font>）

```sh:GitBash
# フォルダ作成
$ mkdir ~/.ssh && cd ~/.ssh

# 秘密鍵・公開鍵の作成
$ ssh-keygen -t rsa -b 4096 -C "hoge@example.com" -f ~/.ssh/id_rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):  <-- パスフレーズを入力（ Enterキーを押す ）
Enter same passphrase again:  <-- もう一度、パスフレーズを入力（ Enterキーを押す ）
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.

# ファイル確認
$ ls
id_rsa id_rsa.pub
```

※ id_rsa　　 （秘密鍵）・・・ クライアントPCに配置
※ id_rsa.pub （公開鍵）・・・ 接続対象サーバに登録

## 公開鍵の設置
公開鍵の方を、接続先のサーバに設置する。

githubのような管理画面で登録できる場合は、管理画面より登録する。
管理画面がない場合は、管理者へ鍵の設置依頼をする。
※ 公開鍵： <font color="red">C:¥Users¥{ユーザー名}¥.ssh¥id_rsa.pub</font>

## 参考サイト
* [WindowsでGitを始めたらまず確認！Git Bashの設定&ショートカット](https://www.granfairs.com/blog/staff/gitbash-setting-shortcut)
* [WindowsでSSHの鍵を作る](https://qiita.com/digdagdag/items/9e5c061e7d86e0af9a57)
* [WindowsにGitをインストールする](https://www.granfairs.com/blog/cto/install-git-for-windows)
* [WindowsのGitbashで、Githubをssh経由で操作できるようにセットアップした](http://yuheikagaya.hatenablog.jp/entry/2012/12/11/224216)
* [Windowsで"."から始まるフォルダ/ファイルを作る](https://qiita.com/uchi_y/items/5c8d26a3848e670b0a60)
猫でもわかりたいDDD(Domain Driven Design)　0から開発したことないあなたに　その２

前編https://qiita.com/katokonn1020/items/767b611e83fc71571c37
からの続きです。

#・ドメインに落とし込むということ

DDDの前提となっている概念があります。
それは、現実の関心をできるだけ開発上とでシンクロさせることです。

例えば
銀行業務システムがあるとします。
この中では、顧客の住所は所持しているでしょうが、顧客の髪の色などは持っていないでしょう。
なぜなら期待されているシステムで、住所は使うかもしれませんが、髪の色は不要だからです。

もう一つ、車製造システムで具体例を出します。

車があります。
車にはハンドルやタイヤが付いています。
その車に対して、タイヤは一種ですが、タイヤはその車だけに使われてるとは限りません。
なので車クラスから保持しているタイヤの種類を返す機能は自然ですが、
そのタイヤから使っている車を返す機能は、現実に即していません。

この様にシステムが持っている関心と、実際のモデルをシンクロさせることが大事です。
必要な関心、不要な関心
それらを取捨選択して、開発して行くことが大切だとエリックは言っているわけですね。

それらを可能な限り正確にやるには、専門家との話し合いが重要です。

#・話し合いという名のモデリング

よりわかりやすくDDDにおけるモデリングを理解するために例を出します。

あなたは航空監視システムを作ることになりました。
なので、実際に空港で働いている専門家を交えてモデリングをすることになりました。

あなた「航空監視システムを作る上で、何から始めればいいでしょうか」

専門家「根本的なことから始めましょうか。まず監視する**飛行機**は必ず存在します。それらは**出発地**と**到着地**を持っています」

あなた「なるほど。到着地につくならどの様なルートを進んでも大丈夫なのですか？」

専門家「いえ、パイロットは勝手にルートを決めてはいけません。必ず**航路**というのが指示されるのでそれに従います」

あなた「ふむ。航路というのは、ある地点とある地点をつなぐ三次元上の点と考えても良さそうですね」

専門家「私はそうとは考えません。結局は地図上で、緯度と経度で表されるものなので二次元上の点と考えられます」

あなた「わかりました。ではその様な地点を**運航定点**と表すことにします。とすると出発地も到着地も等しくただの運航定点であるので、特別に扱う必要はなさそうです。ちなみに二次元ということは、航路さえあっていれば高度などは自由ということですか？」

専門家「いえ、維持すべき高度も**運航計画**によって事前に決められています」

あなた「運航計画？新しいワードですね。何ですかそれは」

専門家「離陸する前に、パイロットは運行計画を受け取ります。運行計画は運行に関する情報を全て含んでいます。航路、維持すべき高度、飛行速度、飛行機の型式、さらには乗務員の情報も運行計画に含まれています。」

あなた「運航計画はかなり重要そうですね。これはモデルに取り入れましょうか」

この例はかなり重要な事柄をいくつも含んでいます。

そのうちの一つにユビキタス言語というものがあります。

#・ユビキタス言語とは

開発者と専門家の間では、同じ概念を保持しているが別の名前を持った言葉がいくつも生まれます。

例えば、漫画ビューワアプリを作成している時に
専門家は「この**漫画**のこの**ページ**におけるこの**コマ**は」などと話します。
それに対してエンジニアは、聴きながら内面で
「(ある**comic**に対して、特定の**page**で**panel**が)」なんて思ってるわけです。

つまり、現実の一つの関心について
**専門領域ワード**、**開発サイドワード**と二つの言葉が生まれてしまっているというわけですね。

この様な事態の解決策として、統一した言葉を用意しようとエリックが提唱したのが**ユビキタス言語**です。

今回の例でいうと
>ではその様な地点を運航定点と表すことにします

この運航定点こそがユビキタス言語ですね。

#・モデル駆動設計とモデルをリンクさせた実装

上記の単純な会話でも、専門家と開発者との間にたくさんの齟齬が発生しているのがわかるでしょう。
この様に、一見あなたの頭に思い浮かんだ実装が正しく思えても、実際にドメイン分析して見ると、それは現実に即していないことがわかったりします。
その齟齬をできるだけ排除して、可能な限りドメインに沿った仕様にモデリングしていきましょうというのが今回のお話でした。
やってみて分かった AWS CodeDeploy の落とし穴

# 本記事の内容

AWS CodeDeploy を触ってみて、はまってしまった落とし穴について書いたものです。

# ELB + EC2 AutoScaling + blue/green デプロイで既知のバグ：　デプロイ後、ELBからのヘルスチェックが効かなくなる

以下、ALB 使用時について説明しますが、CLB でも同様のバグがあるそうです。

blue/green デプロイをすると、新規に作成される green 環境用の AutoScaling グループに、元の blue 環境の AutoScaling グループの設定がコピーされますが、その際にターゲットグループ設定がコピーされません（空になります）。
AutoScaling のヘルスチェック設定を ELB にしていても、ターゲットグループが設定されていないため、ELB からのヘルスチェックが無効になってしまいます（EC2 インスタンスのヘルスチェックのみ有効になります）。
その結果として、ELB からのヘルスチェックが失敗しても、対象インスタンスは healthy と判定され、AutoScaling グループの自動 failover の対象となりません。

このバグは AWS 側も把握しているとのこと。早く修正して欲しいですね・・・。

workaround として以下の方法があります。
AfterAllowTraffic hook で green 環境用の autoScaling グループにターゲットグループを attach します。
autoScaling グループ名は EC2 の Tag から取得できます。


# appspec.yml の hooks に指定するスクリプトのパスには、アプリケーションモジュールの root からの相対パスを記述すること

アプリケーションモジュールをインストールするディレクトリを files セクションにて指定しますが、hooks でインストール先のパスを指定すると、ファイルが見つからないエラーになります。

CodeDeploy は hooks に指定したファイルを /opt/codedeploy-agent/deployment-root/9368645e-c79f-4304-9356-21a755b9a421/d-BK4MCFZ0P/deployment-archive/ というようなパスの配下から探します。左記のパスは CodeDeploy が EC2 にアプリケーションモジュールをインストールする際に、取得したモジュールを展開する temporary なディレクトリです。
従って、hooks ではアプリケーションモジュールの root からの相対パスを記述する必要があります。

# in-place デプロイで ApplicationStop hook に不備があると、次回以降のデプロイが失敗する

デプロイする際、 lifecycle の最初に ApplicationStop が実行されますが、ここでは最後に成功したデプロイのモジュールが使われます。つまり、直前のデプロイが成功していれば、その設定・モジュールが使われます。
従って、直前のデプロイの ApplicationStop に不備がありエラーになると、次回のデプロイがこけます。デプロイ設定でデプロイ失敗時のロールバックを有効にしていると、再度デプロイしても直前の成功デプロイ（ApplicationStop に不備があるデプロイ）の ApplicationStop が使われるため、やはりデプロイがこけます。
回避策として、デプロイ設定でロールバックを無効にすると、デプロイが失敗してもモジュールが更新されるので、再度デプロイすれば更新後の ApplicationStop が実行されます。

# codeDeploy エージェントのインストールは userData の最後で行うこと

CodeDeploy エージェントをインストール　→　userData の処理が完了
の間に、CodeDeploy によるデプロイ処理が走ってしまう可能性があるためです。

# AutoScaling グループへの初回デプロイは少し困難が伴う

初回デプロイ成功後は、AutoScaling により新たに作成されたEC2インスタンスには、CodeDeployにより直前の成功デプロイのリビジョンのアプリが自動でデプロイされます。逆にいうと、初回デプロイ成功前は、直前の成功リビジョンが存在しないため、インスタンスを起動しても、CodeDeploy はアプリをデプロイしません（できません）。しかしながら、CodeDeploy でデプロイするには、デプロイ対象のインスタンスが起動されていなければなりません。つまり、卵が先か鶏が先か、という話になります。

AutoScaling グループのヘルスチェックでは通常、 ELB ヘルスチェックを有効にしますが、アプリケーションが稼働しないとエラーになるでしょう。従って、放っておくと新規インスタンスが起動→ヘルスチェックエラーでインスタンスが停止→新規インスタンスが起動 というループが発生してしまいます。これを防ぐためには、AutoScaling グループで最初のインスタンスを作成した後に、速やかに CodeDeploy のデプロイ処理をキックしなければなりません。その際のデプロイ設定は in-place で AllAtOnce とします。

# デプロイ設定は初回は in-place、二回目以降は blue/green とするのが良いかな

初回デプロイは blue 環境がないので in-place で行います。二回目以降は blue/green で行います。

ちなみに、blue/green をすると green 環境として新たな AutoScaling グループが立ち上げられます。AutoScaling グループの設定は blue 環境のものを引きつぎ、名前は CodeDeploy_[デプロイ設定名]_[デプロイID] となります。そのため、blue/green をすると、アプリの稼働している AutoScaling グループが変更になるのですが、そうすると初回デプロイで使用した in-place のデプロイ設定は（AutoScaling グループ名が指定されているため）そのままでは使えなくなります。なので、初回デプロイで使用した in-place のデプロイ設定は削除してしまっていいと思います。

# blue/green の場合は　blue 環境の終了待ち時間を指定すること

blue/green の場合、デプロイ後に元の環境は不要になるので、デプロイ設定で「デプロイの成功後にデプロイグループの置き換え元インスタンスを終了」を選択するのが通常ですが、インスタンス終了までの時間はデフォルトでは 1時間です。これはもっと短くした方がいいと思います。なぜなら、元の環境のインスタンスが終了するまではデプロイのステータスが完了にならないのですが、完了にならないと次のデプロイを開始できない、つまりは元の環境のインスタンスが終了するまでは次のデプロイを開始できない、ためです。

# デプロイ設定は blue/green + AllAtOnce でいいのでは

他にする理由があまりないかな。

# まとめ

以上。
HomebrewでインストールしたGethをアップデートするコマンド

macOSでbrewを使ってインストールしたgethのアップデート方法。

ついつい`brew install ethereum`でインストールしたことを忘れてしまっていた。
ethereumをアップデートすればgethもアップデートされる。
脆弱性の問題もたまにあるので、忘れずにアップデートしたい。

## brewでinstallしたgethをupdateするcommand

`brew update && brew upgrade ethereum`