OmniAICreator/Qiita-1.07M huggingface dataset:
IBM Mass Data Migration ってなに


#2017年9月20日更新
正式にリリースされたようです！

>Cloud Mass Data Migration - IBM Bluemix
https://www.ibm.com/cloud-computing/bluemix/mass-data-migration

#リリースノート
2017月6月28日より、Bluemix Infrastructure (旧SoftLayer) で有効（ポータルメニューとしてみえるように）になったサービスのようです。

中身を読むと、
**物理的なストレージ装置を用いて、IBM Cloud Object Storage (旧Cleversafe) 120TBまでのデータを、送ったり取り出しできるサービス**、ということですね。

>Added the ability to order the Mass Data Migration Service. This offering can only be ordered by the master account user. It allows for the secure migration of up to 120TB of data per device into / out of Cleversafe Object Storage using physical storage appliances housed in waterproof, tamper-evident, shockproof cases. Official Documentation.
>
<a href="https://softlayer.github.io/release_notes/2017/20170628/" >Release notes: June 28, 2017</a>

たとえば、120TBのデータをインターネット経由で送ろうとすると理論値は、以下のようになりますので、これくらいの容量になるとこのようなサービスを使ったほうがいいですね。

- 10 Mbps で 1111日
- 100 Mbps で 111日
- 1 Gbps で 11日
- （10 Gbps で1日）



#オフィシャルドキュメント
<a href="https://console.bluemix.net/docs/infrastructure/mass-data-migration/index.html#ibm-bluemix-mass-data-migration" >IBM Bluemix Mass Data Migration</a> にあります。

こんな感じのデバイスなんですね。防水、不正開封防止対策、耐衝撃ケースという装備！！！
![デバイス](https://console.bluemix.net/docs/api/content/infrastructure/mass-data-migration//images/UserGuide2.jpg?lang=en)

10Gbps のポートがついているので、ローカルでの転送は最大の120TBでも丸1日程度で終わるでしょう。

#Bluemix Infrastructure (旧SoftLayer) の画面
ポータルからは、以下のようにメニューをたどると利用可能です。（マスターユーザーのみ、オーダー可能です。）
![Kobito.425to4.png](https://qiita-image-store.s3.amazonaws.com/0/101361/54338a3c-5f9b-625c-3988-0796e96dbc90.png "Kobito.425to4.png")

IBM Cloud Object Storage (旧Cleversafe)に保存されますので、クラウドストレージ保存料金も発生することに注意しましょう。
![Kobito.C6XcwI.png](https://qiita-image-store.s3.amazonaws.com/0/101361/42597026-2837-a66f-6d57-fb0979deecb7.png "Kobito.C6XcwI.png")

**デバイスによって暗号化と圧縮が有効になる**、との記載があるので、セキュリティ的にも安心ですし、実際は120TB以上のデータが入りそうです。
![Kobito.JVC7Pb.png](https://qiita-image-store.s3.amazonaws.com/0/101361/7da0f293-340a-24db-e4f8-04dcbb88dfad.png "Kobito.JVC7Pb.png")


#サポートにきいてみた
Q. Can we use it between the site in Japan and your Tokyo datacenter?

>We have received confirmation that the mentioned product will only be launched at year end and will be limited to certain data centers of the time of the launch.
>
The availability of this product will be limited to data centers like: Dallas, Wdc and San Jose.

日本の拠点と東京データセンターの間では、まだ利用できません。（執筆時点）
アメリカのデータセンターから、順次サービス展開していくようですね。
EC2でsshログインできなくなったとき（自爆）

経緯
=

EC2にログインした後、chownを間違った箇所に実行してしまいました。（自爆）
具体的には「/home/」に関係ない権限を与えてしまい、既存ユーザでsshできなくなりました。

当日はそれに気づかず、ターミナルはセッション切れに。
翌日ログインできなくなってました。。。

手順
=

1. 該当インスタンスのボリュームをデタッチします
2. デタッチしたボリュームは作業用インスタンスにアタッチします
3. アタッチしたボリュームをマウントし、sshの設定を変え、rootログイン可能にします
4. 再び元のインスタンスにアタッチし、rootログインします
5. その後必要な権限設定のやり直しを行います

以下詳細です。

1.該当インスタンスのボリュームをデタッチします
-

ボリュームをデタッチします。
※事前にインスタンスの停止が必要です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/181624/6f2b6d92-ec05-6048-1fd3-d2aacc22bcc0.png)

2. デタッチしたボリュームは作業用インスタンスにアタッチします
-

ボリュームを作業用インスタンスにアタッチします。
アタッチする際もインスタンスの停止が必要です。
※作業用インスタンスがなければ作成してください。

アタッチ時の「インスタンス」は同じアベイラビリティーゾーンのインスタンスから選択できます。
デバイスは「/dev/sdf」のままでOKです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/181624/fab1a564-f89e-c8e2-b7d2-7730ee3fe964.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/181624/8f5c849a-6cc6-09da-7104-52a4a4cf54f2.png)

3. アタッチしたボリュームをマウントし、sshの設定を変え、rootログイン可能にします
-

アタッチした作業用インスタンスを起動し、sshログインします。
ログインしたら作業用ディレクトリを作成し、ボリュームをマウントします。

####ボリュームの確認

```shell-session:
lsblk
```

####作業ディレクトリ（マウントポイント）の作成

```shell-session:
sudo mkdir /mnt/xvdf
```

####ボリュームをマウント

```shell-session:
sudo mount /dev/xvdf1 /mnt/xvdf/
```

####sshの設定変更

```shell-session:
#編集（マウント先のファイルであることに注意！元のファイルはイジらないようにね。）
vim /mnt/xvdf/etc/ssh/sshd_config

#PermitRootLogin を下記へ変更（元は no でした）
PermitRootLogin without-password
```

####公開鍵のコピー

```shell-session:
#rootのバックアップ
cp /mnt/xvdf/root/.ssh/authorized_keys /mnt/xvdf/root/.ssh/authorized_keys_bk

#centosユーザの設定をコピー（上書き）
cp /mnt/xvdf/home/centos/.ssh/authorized_keys /mnt/xvdf/root/.ssh/authorized_keys
```

これでrootでログインする準備ができました。

4. 再び元のインスタンスにアタッチし、rootログインします
-

手順2の逆です。
作業用インスタンスを停止し、ボリュームをデタッチしてください。
その後、元のインスタンスにアタッチし、インスタンスを起動してください。

####注意！
アタッチする際のデバイス欄には「/dev/sda1」を入力してください。
これを入力しないとインスタンスが起動できないので気づくと思います。

5. その後必要な権限設定のやり直しを行います
-

```shell-session:
#ログイン
ssh -i "XXX.pem" root@XX.XX.XX.XX

#その後、冒頭のchownで間違えた設定を修正しました。。。
```

※手順3の「sshの設定変更」「公開鍵のコピー」も元に戻しておきましょう。

参考
-

[AWSでSSH接続できなくなってしまったときの復旧方法]
(http://qiita.com/keisuke_kimura/items/a7c79f4ab3a954a41780)
[ec2-userの鍵を使ってrootで直にSSH接続してみる]
(https://norm-nois.com/blog/archives/2958)
Rails（ActiveRecord）で ログテーブルなどのビッグデータ系のテーブルを作るときはbigint型にすることを忘れない

Rails で、「rails g」でサクッと作っていると、
意識しないで作ってしまうのがIDカラム。

最近、integer型の桁あふれ問題（integer out of range）が発生して、ログ出力が900MB/日になるという問題が発生。

原因は、日々アクセスされた情報を記録するテーブルのIDカラムがintegerで作成されていた。
数年運営されて蓄積された情報の自動採番値がIDカラムに対して桁あふれエラーとなり、これまでinsertされ続けていた数だけエラーログとなって出力されて、膨大な量の出力を引き起こしていた。

**rails g の前後で、テーブルの用途を考えて、migrationファイル内にID属性値の型をbigintにする？などの暗黙に作られる情報も含めた検討を忘れないようにすること。**

* 設定時の参考サイト：
    * https://stackoverflow.com/questions/42673932/rails-how-to-use-bigint-as-primary-key
    * http://www.techscore.com/blog/2015/02/25/postgresql-and-rails-use-bigserial-id/
UITableViewの最後のセルのIndexPathを見つける

一番下にスクロールしたい時とか、一番下のIndexPathを見つけたい時用のextension

```swift

extension UITableView {
  var lastIndexPath: IndexPath? {
    guard let dataSource = dataSource else { return nil }
    return dataSource.lastIndexPath(in: self)
  }
}

extension UITableViewDataSource {
  func lastIndexPath(in tableView: UITableView) -> IndexPath? {
    guard let sectionCount = self.numberOfSections?(in: tableView) else { return nil }
    let lastSection = sectionCount - 1
    let rowCountOfLastSection = self.tableView(tableView, numberOfRowsInSection: lastSection)
    let lastRow = rowCountOfLastSection - 1
    return IndexPath(row: lastRow, section: lastSection)
  }
}

```

ViewModel側の要素数とか見るよりは、直接DataSourceに問い合わせた方が確実だし依存関係が最小で済むなぁと思ってextensionにしてみた。
（この辺の便利なUITableViewExtみたいなpodあるのかな…）
goofysをLinuxで使うときはpre-build binaryにしとくと良い

# goofysとは
Go製の`S3バケットを直接マウントしてファイルシステムのように使いたいケース`に利用できるミドルウェアです。
https://github.com/kahing/goofys
上の文言はこの記事からの引用。
http://dev.classmethod.jp/cloud/aws/how-to-use-s3fs-goofys/

s3fs曰く、s3fsと比較してPOSIX準拠度が低い代わりに高速らしい。

>goofys - similar to s3fs but has better performance and less POSIX compatibility
https://github.com/s3fs-fuse/s3fs-fuse

GitHub Pageには[比較のベンチとか乗ってました。](https://github.com/kahing/goofys)

# 経緯
S3をファイルシステムとしてマウントする必要があり、Gopherならgoofys使うっしょ、と思って、上のクラスメソッドさんの記事や、
http://qiita.com/digitalpeak/items/1680d291f92187a2de47
を参考にしながらgo installして、
```
/usr/local/bin/goofys {backetname} {mountpoint}
```

したら
`通信端点が接続されていません`
というfuse由来っぽいエラーが。
インストールし直してみたり、IAMの権限確認したりしたけどどこも正常で、ハマっちゃいました。

# 解決
公式には
https://github.com/kahing/goofys
`On Linux, install via pre-built binaries. You may also need to install fuse-utils first.`
バイナリ使ってね、と書いてあるのでバイナリ使おう。ハマります。

原理的には同じバイナリできるはずなんですけど、masterのbugfixの度合いとかの問題ですかね。

```
$ git show -s
commit 891e5032b452319885b53673d040c60bee8bda4f
Author: Ka-Hing Cheung <khc@hxbc.us>
Date:   Thu Jul 20 19:50:34 2017 -0700
```
使ったのはこのcommitでした。
なんかインストールうまくいかないな、という人多そうと思ったので、FYIでした。
時間があるときにでもデバッグしてみるか、という感じです。
form_forメモ

# `form_for(record, options={}, &block)`
http://api.rubyonrails.org/ の `form_for` 自分用メモ

## record
モデル名のstringかsymbol or モデルオブジェクトを受け取る

recordのルーティングが `config/routes.rb`内で`resources`メソッドを使ってRESTfulに設定してあると、`url`を明示しなくてもRailsが良きように解釈してくれる。

recordのルーティング設定で `namespace` が使われている場合(ex. 名前付きルートが`admin_user_path`)はこうする

```ruby
form_for [:admin, @user] do |f|
```

recordに関連が定義されているオブジェクトがある場合、こうする

```ruby
form_for [@document, @comment] do |f|
```

と、新規作成時にちゃんと `@document`に紐づく`@comment`が作られる。


### モデルオブジェクトを渡した時の違い
1. `input`要素の`name`属性に、渡されたモデルオブジェクトのクラス名を判断して入れてくれる。（変更したい場合は`as`オプションを使う）
2. 渡されたオブジェクトが持っている属性の値をつかって初期値を表示する。（-> 永続化されていないオブジェクトでも初期値が表示できるってことかな？）


## options
### url
フォームのsubmit先
`url_for`や`link_to`に渡せる値なら受け取れるため、名前付きルートを指定することができる。
recordに渡されたものがstringかsymbolで`url`オプションが指定されていない場合は現在のurlにフォームは送信される

### namespace
設定された値をフォームの要素の`id`属性に接頭語として使うことで、フォームごとにユニークなものにする。

```ruby
form_for @person, namespace: :hoge do |f|
  = f.text_field :name # <input type="text" id="hoge_person_name" name="person[name]"> 
```

### method
フォーム送信時のメソッド。たいてい`get`か`post`だが、`delete``patch``put`などが指定された場合は、`type="hidden"　name="_method"`の`input`要素が追加される

### remote
`true`にセットされることでsubmitの挙動を`Unobtrusive JavaScript drivers`でコントロールすることができる。　

用語： 
`Unobtrusive JavaScript` https://en.wikipedia.org/wiki/Unobtrusive_JavaScript

### html
`form`タグにつけたいhtmlの属性を設定できる
`data`属性に関しては、htmlオプションを使わずにそのまま書ける。

```ruby
form_for @person, data: {hoge: "hoge"}
```

### authenticity_token
カスタムの`authenticity_token`を使いたい時や`authenticity_token`が必要ない時に設定

### enforce_utf8
`false`にセットすると、`type="hidden" name="utf8"`という`input`要素が追加されなくなる
（IE8までのブラウザ向けにパラメータをUnicodeでエンコードするためのものらしい。
https://stackoverflow.com/questions/3222013/what-is-the-snowman-param-in-ruby-on-rails-3-forms-for/3348524#3348524）
Node-RED から 外部URL(Yahoo! API位置情報) に緯度経度をHTTPリクエストを送信して住所を取得する


１．直前のFunction Nodeで以下のようにしておく。msgオブジェクトにパラメータをセットするのがポイント。

```java
// msgオブジェクトにセットするのがポイント
msg.appid="xxx";
msg.lat="35.308266";
msg.lon="139.48856";
return msg;
```

２．HTTP request node で以下のようにする。{{}}とするとmsgのプロパティを読み取ってくれる。

```java
https://map.yahooapis.jp/geoapi/V1/reverseGeoCoder?appid={{appid}}&output=json&lat={{lat}}&lon={{lon}}&datum=wgs
```

３．Debug nodeでは出力対象を以下のようにすると住所を出力できる。

```java
payload.Feature[0].Property.Address
```

以下、コピペ用JSON

```java
[{"id":"9654a911.eee768","type":"http request","z":"cbbc355f.229888","name":"yahoo","method":"GET","ret":"obj","url":"https://map.yahooapis.jp/geoapi/V1/reverseGeoCoder?appid={{appid}}&output=json&lat={{lat}}&lon={{lon}}&datum=wgs","tls":"","x":1023.5,"y":46,"wires":[["79742e37.31db4"]]}]
```
最適な調理の順番を求める

# お題
国立情報学研究所の宇野先生の[スケジューリング問題](http://research.nii.ac.jp/~uno/schedule.htm)を解いてみましょう。

![](http://research.nii.ac.jp/~uno/images/schedule1.gif)

> たくさんある工程(スープ、焼鳥、…)を、いろいろなリソース(人、コンロ、包丁、オーブン)を使って、なるべく早く完成させます。

定式化して汎用ソルバーで解けますが、大変なので、スケジューリング専用ソルバー[OptSeq](http://logopt.com/OptSeq/OptSeq.htm)を使います。有料ですが、変数15までは無料の試用版で解けます。

インストールや使い方は、[スケジューリング最適化ソルバー OptSeq II](http://logopt.com/OptSeq/OptSeq.htm)を見てください。

# Pythonで解く

一々名前を指定しなくてもいいように、補助関数を定義します。

```py3:python
from more_itertools import pairwise
from optseq import *

def addResource(m, capacity=1, name=None, addResource_count=[0]):
    if name is None:
        addResource_count[0] += 1
        name = f'R{addResource_count[0]}'
    return m.addResource(name, capacity=capacity)
def addMode(dur, res=[], name=None, addMode_count=[0]):
    if name is None:
        addMode_count[0] += 1
        name = f'M{addMode_count[0]}'
    md = Mode(name, dur)
    for r in res:
        md.addResource(r, requirement=1)
    return md
def addActivity(m, dur, res=[], name=None, addActivity_count=[0]):
    if name is None:
        addActivity_count[0] += 1
        name = f'A{addActivity_count[0]}'
    ac = m.addActivity(name)
    md = addMode(dur, res)
    ac.addModes(md)
    return ac
```

実際にモデルを作って解いてみましょう。
4つのリソース(人、コンロ、包丁、オーブン)の組合せを1つの数字で表せるように、それぞれ 1,2,4,8 とします。「'スープ': [(5,10),…]」の5は、1(人)と4(包丁)の両方を使うことを表します。10は、作業時間(分)です。

```py3:python
# 1:人, 2:コンロ, 4:包丁, 8:オーブン
prm = {'スープ': [(5,10),(3,10),(0,20),(0,20)],
       '焼鳥': [(5,10),(9,20),(3,10)],
       '魚料理': [(3,10),(9,30)],
       '温野菜': [(5,20),(3,10)],
       '茶': [(3,10)]} # リソースフラグ,時間
m = Model() # モデル
# リソース
res = {i:addResource(m,j) for i,j in zip([1,2,4,8],[2,2,2,1])}
# 工程
act = {k:[addActivity(m, d, [r for j,r in res.items() if f&j], f'{k}{i+1}')
        for i,(f,d) in enumerate(l)] for k,l in prm.items()}
for l in act.values():
    for i,j in pairwise(l):
        m.addTemporal(i,j) # 同一料理内では順番に
m.addTemporal('sink',act['魚料理'][1],'CC') # 魚料理2は最後に
m.addTemporal('sink',act['茶'][0],'CC') # 茶1は最後に
m.Params.TimeLimit = 1 # 計算時間は1秒まで
m.Params.Makespan = True # 全工程の終了時刻を最小化
m.optimize() # ソルバー実行
```

```text:結果
 ================ Now solving the problem ================ 
Solutions:
    source     ---     0     0
      sink     ---    70    70
      スープ1   ---     0    10
      スープ2   ---    10    20
      スープ3   ---    20    40
      スープ4   ---    40    60
       焼鳥1    ---     0    10
       焼鳥2    ---    10    30
       焼鳥3    ---    30    40
      魚料理1   ---    20    30
      魚料理2   ---    40    70
      温野菜1   ---    30    50
      温野菜2   ---    50    60
        茶1    ---    60    70
```

2つの数字は、その工程の開始時刻と終了時刻を表しています。
sink が 70 なので、70分で全工程が終了することがわかります。
また、個別に見ても、下記の先生の結果とほぼ同じような答えであることがわかります。

![](http://research.nii.ac.jp/~uno/images/schedule2.gif)

以上
API Gateway でパスパラメータ及びクエリパラメータを使用してバックエンドのパスを指定する

API Gateway で元のリクエストのパスパラメータとクエリパラメータをバックエンドのパスにマッピングしようとして、少し手間取ったので記録しておきます。
例としてバックエンドを S3 とします。

API のリソースを /{path1} とします。

# リクエストメソッドの設定

![image.png](https://qiita-image-store.s3.amazonaws.com/0/108071/fd8963a3-4aa0-d8bf-a4f0-c86dd386b7ce.png)
クエリパラメータとして param1 を追加しています。

# 統合リクエストの設定

![image.png](https://qiita-image-store.s3.amazonaws.com/0/108071/a33c4ebd-04b7-c412-95a3-bf8c7dc1f658.png)

実行ロールには S3 から GetObject する権限があるものを指定してください。

# 結果

メソッドのテストで path1 に yes, param1 に no を指定すると、以下の S3 パスにアクセスされます。

https://s3-ap-northeast-1.amazonaws.com/yes/no

たったこれだけのことなんですが、公式ドキュメントから読み解くのはちょっとしんどかったです。私が慣れていないだけかもしれませんが・・・。
動的にHTMLが生成されたらイベントを発火させる

[infinitescroll](https://github.com/metafizzy/infinite-scroll)で無限スクロールを実装していましたが、新しく読み込まれたHTMLにcoffeescriptが効いていなかった時にしたことメモ。


```coffee:
  $ ->
    $(document).on "DOMNodeInserted", ->
      # なんらかの処理
```
bashで通知（slack）、ドキュメント（DocBase）、保管（aws s3）の三種の神器

bash は便利です。

- 思いついたらすぐ書ける（Linuxならね）
- 間違えても対した影響無い（テキスト吐くくらいでしょ）
- 実行も思いのまま（手動も自動も思いのまま）

# いま流行りのツールにも連携できちゃう

## slack
「slack投稿用関数」の以下の4つを書き換えて使ってください。

|書き換え箇所|説明|例|
|----|----|----|----|
|"your_slack_incoming_webhook_url"|slackのincoming webhook URL|https://slack.com/services/new/incoming-webhook から取得|
|"your_channel"|通知したいslackチャンネル|#notification|
|"your_bot_name"|通知させたいbot名|bash-robo|
|":your_icon:"|通知させたいbotアイコン|:robot:|


```bash:slack投稿用関数
function post2slack() {
  WEBHOOKURL="your_slack_incoming_webhook_url"
  CHANNEL="your_channel"
  BOTNAME="your_bot_name"
  FACEICON=":your_icon:"
  curl -s -S -X POST --data-urlencode "payload={ \
    \"channel\": \"${CHANNEL}\", \
    \"username\": \"${BOTNAME}\", \
    \"icon_emoji\": \"${FACEICON}\", \
    \"text\": \"$1\" \
  }" ${WEBHOOKURL} >/dev/null
}

```

呼び出すときに引数に通知したいメッセージを渡します。

```bash:呼び出し
post2slack "[通知] 通知したいステータス"
```

## DocBase
「docbase投稿用関数」の以下を書き換えて使ってください。
DocBaseは投稿後のURLのpost番号をAPI用URIに設定することでwebhook URLとして使えます。

|書き換え箇所|説明|例|
|----|----|----|----|
|"your_docbase_token"|DocBaseのAPIトークン|個人設定の基本設定にあるAPIトークン|
|"your_docbase_webhook_url"|DocBaseに投稿済みのURL|https://api.docbase.io/teams/your_team/posts/post_number|


```bash:docbase投稿用関数
DOCBASE_TOKEN="your_docbase_token"

function post2docbase() {
  WEBHOOKURL="your_docbase_webhook_url"
  echo $1
  curl -s -S -H 'X-DocBaseToken: '${DOCBASE_TOKEN} -X PATCH -d @$1 ${WEBHOOKURL}
}

```

呼び出すときに引数にドキュメント化したいテキストファイルを渡します。
テキストの中身はMarkdown形式で大丈夫です。

```bash:呼び出し
post2docbase "/home/your_path/your_message.txt"
```

## aws s3
awscliをインストールしておく必要があります。

`aws configure`でaws_access_key_id、aws_secret_access_keyなど適宜設定します。

詳しくは以下で。
http://qiita.com/seyself/items/43426f57c50021ea55f8


```bash:aws_s3保管用関数
function post2s3() {
  FILENAME=$1
  BUCKETNAME=$2
  aws s3 cp $FILENAME $BUCKETNAME
}
```



```bash:呼び出し
post2s3 your_path/your_log.log s3://your_s3_bucket/your_s3_folder/
```

以上
都道府県の店舗APIをたたく時のSample

## 仕様について

- 各エリアの都道府県の店舗を取得
- 都道府県ごとにAPIが存在する
- 各エリアをクリックすると都道府県と店舗が表示される

## JSON

``` javascript:sample.json
{
  "stores": [
    {
      "id": 1,
      "name": "A店",
    },
    {
      "id": 2,
      "name": "B店",
    },
    {
      "id": 3,
      "name": "C店",
    }
  ]
}
```

## HTML

※エリアは3つに絞りました

``` html:sample.html
<div class="prefecture"></div>
<ul>
  <li><a href="javascript:void(0);" class="areaLink">東北エリア</a></li>
  <li><a href="javascript:void(0);" class="areaLink">関東エリア</a></li>
  <li><a href="javascript:void(0);" class="areaLink">中部エリア</a></li>
</ul>
```

## javascript

- urlの設定はダミーになります
- 都道府県コードは[こちら](https://ja.wikipedia.org/wiki/%E5%85%A8%E5%9B%BD%E5%9C%B0%E6%96%B9%E5%85%AC%E5%85%B1%E5%9B%A3%E4%BD%93%E3%82%B3%E3%83%BC%E3%83%89)を参照

``` javascript:sample.js
var areaApiGet = {
  init: function() {
    var self = this;
    self.areaLinkHtml = '.areaLink';
    self.prefectureHtml = '.prefecture';
    self.areaListClick();
  },
  areaListClick: function() {
    var self = this;
    $(self.areaLinkHtml).on('click', function() {
      $(self.prefectureHtml).html('');
      var num = $(this).parent().index();
      self.areaCategorySelect(num);
    });
  },
  areaCategorySelect: function(num) {
    var self = this;
    var prefectureArray = [];
    var prefectureName = [];
    if (num === 0) {
      prefectureArray = [02, 03, 04, 05, 06, 07];
      prefectureName = ['青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県'];
      self.ajaxApi(prefectureArray.length, prefectureArray, prefectureName);
    } else if (num === 1) {
      prefectureArray = [08, 09, 10, 11, 12, 13, 14];
      prefectureName = ['茨城県', '栃木県', '群馬県', '埼玉県', '千葉県', '東京都', '神奈川県'];
      self.ajaxApi(prefectureArray.length, prefectureArray, prefectureName);
    } else if (num === 2) {
      prefectureArray = [15, 16, 17, 18, 19, 20, 21, 22, 23, 24];
      prefectureName = ['新潟県', '富山県', '石川県', '福井県', '山梨県', '長野県', '岐阜県', '静岡県', '愛知県', '三重県'];
      self.ajaxApi(prefectureArray.length, prefectureArray, prefectureName);
    }
  },
  ajaxApi: function(prefectureNum, prefectureArray, prefectureName) {
    var self = this;
    var i;
    var count = 0;
    for (i = 0; i < prefectureNum; i++) {
      $.ajax({
        type: 'GET',
        data: {
          'prefecture':  prefectureArray[i],
        },
        url: '/api/sample.json',
        dataType: 'json',
      })
      .done(function(data) {
        count++;
        var dataArray = data.stores;
        $(self.prefectureHtml).append('<h3>' + prefectureName[count - 1] + '</h3>');
        $.each(dataArray, function(j) {
          $(self.prefectureHtml).append('<p>id: ' + dataArray[j].id + ' name: ' + dataArray[j].name + '</p>');
        });
      })
      .fail(function() {
        console.log('error');
      });
    }
  }
}
$(function() {
  areaApiGet.init();
});
```

### APIリクエスト

``` ajax:url
https://xxxx.com/api/sample?prefecture=xx
```
kotlinでrandとプロパティ

##randの使い方が分かったので使ってみた

```kotlin:chant.kt
import java.util.*

fun main(args: Array<String>) {
    val words = arrayOf("Lets", "go","Cena")
    val rand = Random()
    val chant = Regex(".*LetsgoCena$")
    var fans = ""
	var num = 0
    loop@while (true) {
    println(fans)
    num ++
        when (chant.matches(fans)) {
            true -> {
                println("Cena Sucks ")
                println("$num chants")
                break@loop
            }
            false ->  fans += words[rand.nextInt(words.size)]
        }
    }
}
```
"Lets"と"go","Cena"の三つをランダムに出力してLetsgoCenaの順になったときに"Cena Sucks"と出力して終わるもの。
RegexやmatchesはjavaのAPIから


###おまけ
```kotlin:propa.kt 
import java.util.Scanner

public class   Human(){
    public var name : String = ""
    public var age : Int = 0
    public var live : String = ""
}
fun main(arg : Array<String>) {
    val human1 = scan()
    println("name = "+human1.name)
    println("age = " +human1.age)
    println("liveing = " +human1.live)
}
fun scan(): Human {
    val input = Scanner(System.`in`)
    val human1 = Human()
    println("name")
    human1.name = input.next()
    println("age")
    human1.age = input.nextInt()
    println("livehu")
    human1.live = input.next()
    return human1
}
```
あんまり変わってないですね。
publicは今回はいらないけど一応。
Windowsのワークステーション及び電源の操作

私のＰＣは家族が共用ＰＣではスペック不足なためできない時に使用することがあるんですが、以前弟に何の確認もなくＰＣを強制シャットダウンされてVisual Studioのプロジェクトとソースファイルが全部破損してしかも復元不能になるという悪夢がありました。それも学祭の作品提出期限間際に…

それから電源制御の権限を自分のアカウントだけにしようと思ったのですがWindows 7 Home Premiumにはグループポリシーエディタがない。そしてこれがレジストリのどこに書かれているのかが全く分からない。
エクスプローラのスタートボタン押したとこから消すのは簡単。でも自分のユーザーのまで消えてしまった。

「さあどうする？」となった時、コマンドという手を思いつきました。

```bat:Windowsのシャットダウン
C:\Windows\System32\shutdown.exe /s
```
※/fオプションをつけることで強制執行できます。
※/tオプションをつけることで時間指定シャットダウンができます。

```bat:Windowsの再起動
C:\Windows\System32\shutdown.exe /r
```
※/fオプションをつけることで強制執行できます。
※/tオプションをつけることで時間指定シャットダウンができます。

```bat:ユーザーのログオフ
C:\Windows\System32\shutdown.exe /l
```
※/fオプションをつけることで強制執行できます。

```bat:ワークステーションのロック
C:\Windows\System32\rundll32.exe user32.dll,LockWorkStation
```

```bat:スリープまたは休止状態に移行
C:\Windows\System32\rundll32.exe powrprof.dll,SetSuspendState
```
※このコマンドは、休止状態が有効なら休止状態、無効ならスリープになります。

ＰＣ修理中のため実際導入はまだしてないんですが、エクスプローラからシャットダウンメニューを消してこれのショートカットを作成してC:\Users\Public\Desktopにログオフとロックだけ置いておき、自分のデスクトップには他のショートカットを置いておけば大丈夫です。

ちなみにWindows 10 Proのほうではグループポリシーエディタがあるのでそっちでシャットダウン権限設定変更しましたけどね
Notification.Nameを生やす

Swift3あたりから徐々にNSNotificationのイベント名がNotification.Nameという構造になってきました。
そのため

```swift
NotificationCenter.default.post(Notification(name: Notification.Name("notification_name")))
```

という書き方が一般的になりました。

```swift
Notification.Name("notification_name")
```

pubsubで文字列をハードコーディングするのは怖い（送信側と購読側でtypoすると動かなくなる）ので、ミスコーディングをコンパイラに判断させるためにもNotification.Nameを自分で生やすのが良いかと思います。

```swift
extension Notification.Name {
  static var UIApplicationDidTappedStatus: Notification.Name {
    return Notification.Name(rawValue: "com.noppe.fox.notification.tapped.statusbar")
  }
}
```

このようにextensionを生やすことで

```swift
NotificationCenter.default.post(.init(name: .UIApplicationDidTappedStatus))
```

これで簡潔に、かつタイプミスの心配も無くなります。
deep_cloneを用いたassociationの保存について

[deep_cloneable](https://github.com/moiristo/deep_cloneable)という地味に便利なgemがある。
関連モデルまで含めて`clone`してくれる。データをまるっとコピーしたい時に便利。

しかし、`has_one`ならいいが、`has_many`では注意が必要。
そのままの設定だと、関連先の複数の子要素のうち、一番最後のものしかsaveしてくれない。

解決する方法はこちら。

```ruby
has_many :logs, dependent: :destroy, autosave: true
```
この`autosave`というオプションにtrueをいれてあげることで、凡ての関連先をsaveしてくれることができる。
よくよく考えれば常識な話。
Delphi で Android の振動(バイブレータ)を使用する

たとえばゲームアプリで自機にダメージを受けたときなど、振動の効果を与えたいなどありますよね。
Delphi で Android のバイブレータを使うには、Android の [Vibrator](https://developer.android.com/reference/android/os/Vibrator.html)クラスを使用します。


##設定しておくこと
Android のバイブレータを使用する際には、権限の設定が必要です。
メニューから、プロジェクト|オプションを選択して、使用する権限のバイブレーションを true に設定する必要があります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/164551/e269a327-93bb-18fa-df49-2fe268aa5041.png)

##サンプルコード
フォーム上にボタンを２つ置き

- ボタンを押すと 500ミリ秒振動させる
- ボタンを押すと 100ミリ秒後 500ミリ秒振動 200ミリ秒後 1000ミリ秒振動

という処理を記述しています。(10.2 Tokyo, Nexus 5, Android 5.1.1で確認)


```delphi
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  FMX.Controls.Presentation, FMX.StdCtrls,
  Androidapi.JNI.Os, Androidapi.Helpers, Androidapi.JNIBridge,
  Androidapi.JNI.GraphicsContentViewText, Androidapi.JNI.App;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { private 宣言 }
  public
    { public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.Button1Click(Sender: TObject);
var
  vr: JVibrator;
begin
  // Vibratorインスタンスを取得
  vr := TJVibrator.Wrap(TAndroidHelper.Activity.getSystemService(TJContext.JavaClass.VIBRATOR_SERVICE));
  vr.vibrate(500);  // 500ミリ秒振動させる
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  vr: JVibrator;
  pt: TJavaArray<Int64>;
begin
  // Vibratorインスタンスを取得
  vr := TJVibrator.Wrap(TAndroidHelper.Activity.getSystemService(TJContext.JavaClass.VIBRATOR_SERVICE));
 
  // 100ミリ秒off - 500ミリ秒振動させる - 200ミリ秒off - 1000ミリ秒振動させる
  pt := TJavaArray<Int64>.Create(4);
  pt.Items[0] := 100;    // Off
  pt.Items[1] := 500;    // On
  pt.Items[2] := 200;    // Off
  pt.Items[3] := 1000;   // On
  vr.vibrate(pt, -1);    // -1は１度だけの実行 0は繰り返す 繰り返しを止めたい場合は cancelメソッドを使用する
  pt.Free;
end;

end.
```
Cognitive Service の Custom Vision API に画像を渡し結果を受け取って何の画像かを返却する Azure Function のコード

Cognitive Service の Custom Vision API と Azure Function の勉強のため、作ってみたコードです。
コードだけ貼り付けただけでは意味ないかもしれないから、今後 Custom Vision API の使い方と Azure Function の作り方などもメモしたいと思いますが、今回はとりあえず Azure Function のコードのみ！

```js:index.js
module.exports = function (context, req) {

    // Custom Vision API 呼び出し用のパラメータ設定
    var options = {
        url: '[Custom Vision API Prediction の URL]',
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'Prediction-Key': '[Custom Vision API Prediction の Key]'
        },
        body: JSON.stringify({
            "Url": req.body   // Custom Vision API に渡す画像の URL
        })
    };

    var request = require('request');
    request(options, function (error, response, body) {

        var data = JSON.parse(body);

        // Custom Vision API の解析結果が 6 割 より大きかったら適合、小さかったら不適合にする
        if (data.Predictions[0].Probability > 0.6) {
            context.log(data.Predictions[0].Tag);
            context.res = {
                body: data.Predictions[0].Tag  // 適合した画像のタグ(ここに何の画像かを示す名称が入ってる)を返却
            };
        } else {
            context.res = {
                body: "該当なし"  // 不適合なので該当なしを返却
            };
        }
        
        context.done();
    }); 
};
```
LaradockでCentOS7上にApacheを走らせる(Docker + Laravel)

## 環境
* macOS Sierra
* Docker 17.06.0-ce-mac18
* Apache 2.4
* CentOS 7.0
* MySQL 5.5
* Laravel 5.0


## 前提条件
Lardockの基本的な導入手順を踏み、`docker-compose up -d`コマンドで**コンテナを起動する直前まで**の工程が終了していること
すでに起動してしまっている場合、Laradockで使用するphp-fpmのコンテナとイメージを一度削除してください。

コンテナを停止、ネットワークとともに削除するコマンドは下記のとおりです。

```
$ docker-compose down
```

イメージは削除されないので、

```
$ docker ls -a
```
で全てのイメージを表示し、laradockを導入してビルドしたイメージを削除します。

## 導入手順
laradockのデフォルトでは、ubuntu上にApacheを走らせるように指定されています。
laradock_apache2というイメージの元となるイメージは[webdevops/apache](https://github.com/webdevops/Dockerfile/tree/master/docker/apache)のubuntu16.04ですが、このリポジトリにはcentOS7用のイメージも用意されているので、こちらを利用します。

### pullするイメージを変更する

laradock/apache2配下のDockerfileを書き換え、DockerHubからpullしてくるイメージのを変更します。

```diff

-  FROM webdevops/apache:ubuntu16.04
+  FROM webdevops/apache:centos-7
```

### 設定ファイルを置く
デフォルトではubuntu上にApacheを置くための設定ファイルが読み込まれています。(vhost.conf)
これをcentOS上に置けるように変更します。

まず、centOS上にApacheを置く際の設定ファイルをつくります。（httpd.conf）

```
$ cd laradock/apache2

$ touch httpd.conf
```
httpd.confは、コンテナ内のファイルをコピーしてつくります。

```
$ docker cp laradock_apache2_1:/etc/httpd/conf/httpd.conf httpd.cnf
```

次に、Dockerfileを書き換え、コンテナ内にvhost.confではなくhttpd.confを同期するようにします。

```diff

- COPY vhost.conf /etc/apache2/sites-enabled/vhost.conf
+ COPY httpd.conf /etc/httpd/conf/httpd.conf
```

## イメージをbuildしてコンテナを起動する

`docker-compose up` コマンドでlaradock/apache2/配下のDockerfileからApache2のイメージをbuildし、コンテナを起動します。

オプションに-dをつけて実行すると、コンテナをバックグラウンドで起動し(デタッチドモード)、実行したままにできます。

また、今回はApache2のみイメージをビルドするように指定します。

```
$ docker-compose up -d apache2
```

centos-7のタグがついたwebdevops/apacheのイメージと、それをもとにしたlaradock_apache2というイメージがビルドされていることを確認します。

```
$ docker image ls

laradock_apache2     latest              7777d9659b9e        22 hours ago        1.26GB

webdevops/apache     centos-7            b3cba1c91baa        5 days ago          323MB
```
laradock_apache2 コンテナ内のOSがcentosになっていることを確認します。

オプションで--rmをつけると、対象のコンテナを実行後に削除してくれます。停止しているコンテナに入ることなくバージョン確認などができるので便利です。

コンテナがデタッチドモードで起動されている場合は無視されるので、--rmオプションはなくても同じ挙動になります。

```
$ docker-compose run --rm apache2 cat /etc/redhat-release

CentOS Linux release 7.3.1611 (Core)
```
Macでtelnetする時にユーザ名を指定する


普通、telnetするとき、ログイン名とパスワードを聞かれますが、
OS Xの場合、自動的にログイン名が指定されているようです。

telnet -l ログイン名 host

とすればOK。

ちなみに、上記のコマンドをホスト名でalias登録しておけば、
ホスト名叩けばtelnetパスワードいれるだけですぐログインできる。
svnリポジトリからソースを取得して、その内容をgitにpushする方法（またはsvnからgitへの移行）

svnリポジトリからソースを取得して、その内容をgitにpushする方法をまとめます。
svnからgitへの移行のために実施しました。

# ローカルgitにてsvnのソースをcheckout
```
$ git svn init -s --prefix=svn/ https://userid:password@example.com/svn/
$ git svn fetch
※prefix=svn/を付けておく
※うまくいかない場合は、svn上のルートディレクトリを指定して実行
```

# バックログのgitリポジトリに上記をpush
```
$ git remote add origin https://userid:password@example.com/git/
$ git push -u origin --all
```

# svnの更新を上記gitに適用
```
$ git svn fetch
$ git merge svn/trunk
$ git push -u origin --all
※git移行中にsvnが更新されたらこちらで
```

ベストなやり方か不明ですが、一例ということで紹介しました。
上記ですと、svnの履歴も全部引き継がれるので、便利かと思います。
プログラミング言語Go読書会#16(8.4.4-8.8)[2017/07/19]

[Go読書会 #16](https://lancers-engineer.connpass.com/event/61598/) が[ランサーズ株式会社](https://www.lancers.co.jp/)で行われたので進捗と技術的なメモ書きを書いておきます。読書会の内容は[プログラミング言語Go](https://www.amazon.co.jp/dp/4621300253/?&_encoding=UTF8&tag=amesho-22&linkCode=ur2&linkId=7e29043d833086d36f8b64c2ed3721b2&camp=247&creative=1211)を冒頭から皆で読み進めていくというものです。

## 進捗した内容

+ 8章 ゴルーチンとチャンネル
  + 8.4 チャネル
    + 8.4.3 バッファ有りチャネル
  + 8.5 並列にループする
  + 8.6 例：並行Webクローラ
  + 8.7 selectでの多重化
  + 8.8 例：平行なディレクトリ走査

## 話題に上がった話

### 8.4.3 バッファ有りチャネル

ここでは、要素のキューを指定できるバッファ有りチャンネルについて解説されていました。

```go
// 最後の引数に1以上の数値を入れる
ch := make(chan string, 3)
```

処理される順序は[FIFO(First In First Out)](https://ja.wikipedia.org/wiki/FIFO)になっていて、入れた順序で処理されます。チャンネルが一杯のケースだと`送信側が空きができるまでブロック`され、チャンネルが空きの場合は`受信操作はが別のゴルーチンが値を送信するまでブロック`されるということろが話題になりました。

あとは、`ゴルーチンのリーク(goroutine leak)`という、回収されないゴルーチンが発生する状況があり得るのでそこいに注意が必要と言うことも書かれていました。


### 8.5 並列にループする

ここでは、`気恥ずかしいほどに並列的(embarrassingly parallel)`と呼ばれる問題がでてきました。これは簡単に並列を実行できて線形にスケールする問題のことを指していました。ここでも、実装の仕方によってはゴルーチンのリークが起きるので十分な大きさをもつバッファ有りチャネルを使用することが推奨されていました。

### 8.6 例：並行Webクローラ

ここでは、制限のない並列性によって、コンピュータの資源を使い尽くしてしまう可能性があることに触れていました。解決策としてバッファ有りチャネルを使用で、`計数セマフォ(counting semaphore)`を操作して一度に起動するゴルーチンを制限する方法が書かれていました。

### 8.7 selectでの多重化

ここでは、`select文`を使用した操作の多重化がでてきました。

```go
select {
case -> cha1:
case x := <-ch2:
}
```
selectはどれかのcaseで処理の準備ができるまで待ち、準備が完了した通信を行います。こちらのI/O多重化用[select](https://linuxjm.osdn.jp/html/LDP_man-pages/man2/select.2.html)からこの名前がきてるじゃないかなという話が話題になりました。


ここまで呼んだところで、時間になりました。次回は 8.9 チャネルからです。
fluentdでログ収集

サーバのログをfluentdでS3に転送してAtenaで解析することになったのでメモ。
まずはubuntuにfluentdをインストールしてログをテスト収集できるところまで。

## 環境
Ubuntu Server 16.04 LTS

## fluentdをインストール
Ubuntu 16だとこれっぽい。

```
curl -L https://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent2.sh | sh
```
###### 参考
[Installing Fluentd using DEB Package (Debian / Ubuntu Linux)](http://docs.fluentd.org/v0.12/articles/install-by-deb)

## ログを収集確認用に仮フォルダを作成
あくまでローカルでfluentdの動作を確認するためだけに作った。

```
# mkdir /var/log/td-agent/copy-log-test/
```

## fluentdの設定
転送するファイルや間隔などを定義する。

```:設定ファイル
vi /etc/td-agent/td-agent.conf
```

#### イベントの受信方法の設定
```
<source>
  @type tail
  format syslog
  path /var/log/syslog
  pos_file /var/log/td-agent/copy.syslog.pos
  tag copy.syslog
</source>
```
###### 使ったプラグインの詳細
[tail Input Plugin](https://docs.fluentd.org/v0.12/articles/in_tail)

#### 受信したイベントの処理方法の設定
```
<match bastion.syslog>
  @type file
  path /var/log/td-agent/copy-log-test/syslog
</match>
```
###### 使ったプラグインの詳細
[file Output Plugin](https://docs.fluentd.org/v0.12/articles/out_file)

## flentdを起動
``` 
sudo /etc/init.d/td-agent start
```
さっき作った `/var/log/td-agent/copy-log-test/` フォルダにログが出来ていれば成功だが、
Permissionエラーが出たのでFluentd の実行ユーザをrootにしてしまう。

``` :/etc/init.d/td-agent
- TD_AGENT_USER=td-agent
- TD_AGENT_GROUP=td-agent

+ TD_AGENT_USER=root
+ TD_AGENT_GROUP=root
```
そして再起動

``` 
sudo /etc/init.d/td-agent restart
```
ひとまず出力は成功。

```:/var/log/td-agent/copy-log-test/
2017-07-24T18:44:45+00:00	copy.syslog	{"host":"test","ident":"dhclient","pid":"1","message":"DHCPACK of 0.0.0.0 from 0.0.0.0"}
2017-07-24T18:44:45+00:00	copy.syslog	{"host":"test","ident":"dhclient","pid":"1","message":"bound to 0.0.0.0 -- renewal in 1785 seconds."}
```
RS-232C通信 > PPPプロトコル(RFC 1662) > 0x20でXORを取る

https://stackoverflow.com/questions/1445387/how-do-you-design-a-serial-command-protocol-for-an-embedded-system
にて紹介されている下記の記事
http://eli.thegreenplace.net/2009/08/12/framing-in-serial-communications/

この中で、PPPプロトコル([RFC 1662](https://tools.ietf.org/html/rfc1662))が紹介されている。
PPPプロトコルを簡略したプロトコルをRS-232C通信で使われることがあるとのこと。

> In particular, PPP does the following:
>
- Both the start and end flag bytes are 0x7E (they shouldn't really be different, if you think about it)
- The escape byte is 0x7D
- Whenever a flag or escape byte appears in the message, it is escaped by 0x7D and the byte itself is XOR-ed with 0x20. So, for example 0x7E becomes 0x7D 0x5E. Similarly 0x7D becomes 0x7D 0x5D. The receiver unsuffs the escape byte and XORs the next byte with 0x20 again to get the original [6].

送信側において0x20でXORを取り、受信側において0x20でXORを取っている。

何故このようなことをするのだろうか。
0x7E(start and end flags bytes)や0x7D(escape byte)とかぶらないようにしているのだろうか。

例として、通信経路上で0x7D(escape byte)が別のコードに文字化けした場合、その次のコードが0x7D(データ)である場合を考える。その場合、escape byteと勘違いして「次のコード」を処理しようとする。0x20でXORしていれば、0x7D(データ)は0x5Dになっているため、「次のコード」を処理しようとはしない、という考えだろうか。

### RFC1662

https://tools.ietf.org/html/rfc1662

4.2.  Transparency

> On reception, prior to FCS computation, each octet with value less than hexadecimal 0x20 is checked.  If it is flagged in the receiving ACCM, it is simply removed (it may have been inserted by intervening data communications equipment).  Each Control Escape octet is also removed, and the following octet is exclusive-or'd with hexadecimal 0x20, unless it is the Flag Sequence (which aborts a frame).

0x20でXORを取った値が0x20未満になる条件としては、

http://ideone.com/cPkjdl

```txt:run
0x20	0x21	0x22	0x23	0x24	0x25	0x26	0x27	0x28	0x29	0x2a	0x2b	0x2c	0x2d	0x2e	0x2f	0x30	0x31	0x32	0x33	0x34	0x35	0x36	0x37	0x38	0x39	0x3a	0x3b	0x3c	0x3d	0x3e	0x3f	
```

http://www9.plala.or.jp/sgwr-t/c_sub/ascii.html
で見たところ以下のようなコード。

```
! " # $ (中略) 9 : ; < = > ? 
```

これらに対してACCMの場合削除するということらしい。
.gitignoreを後から適用する手順

#はじめに
Git上で気軽にコードを書き始めてコミットをうっかり作ってしまった後で、.gitignoreの作り忘れに気づいたときに、管理対象を修正するための手順について。

#手順
##1 .gitignoreを作る。
  SourceTreeの場合、ブラウザの右上の「設定」ボタン→右上の「高度な設定」→「リポジトリ限定無視リスト」の「編集」を押す。
　例えば、次のような条件にします。

```text:.gitignore
# Xcode (from gitignore.io)
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xcuserstate
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa

# CocoaPod
Pods/*
Podfile.lock

# others
*.swp
UserInterfaceState.xcuserstate
!.gitkeep
.DS_Store
```

一度、ここでコミットしておきます。

##2. 作業状態を解消する。
　スタッシュするなど。
##3. カレントディレクトリをプロジェクトのフォルダに移動した後、キャッシュを削除する。
　ターミナル.appから、`git rm -r --cached .`

##4. コミットする
　管理対象に.gitignoreが反映された状態のコミットが完成します。
エンジニアとしての活動

#これからのこと
エンジニアとしての取り組みをつづっていきたいなと思います。

#Qiita Githubについて
##Qiita 
情報協共有サービスです。
集合知の獲得には欠かせないツールではないかと思います。

##Github
コードのバージョン管理に欠かせないツールです。
簡単な使い方を載せておきます。
`git init`
`git add.`
`git commit`
`git remote add`
`git push master`
Qiita API を使って投稿の一覧を作成する

作成した私の投稿一覧のページ

![qiita_jul2501.png](https://qiita-image-store.s3.amazonaws.com/0/179446/813123de-bb2c-567b-6caf-fa30726e5e0e.png)

curl を使って ekzemplaro の投稿のページを取得

```bash
curl https://qiita.com/api/v2/users/ekzemplaro/items?per_page=100 > qiita_ekzemplaro.json
```

JSON のフォーマットを変換

```js:qiita_read.js
#! /usr/bin/node
// ---------------------------------------------------------------
//	qiita_read.js
//
//					Jul/25/2017
//
// ---------------------------------------------------------------
var fs = require("fs")
// ---------------------------------------------------------------
console.error ("*** 開始 ***")

const filename=process.argv[2]
const file_out=process.argv[3]

console.log (filename)

if (fs.existsSync(filename))
	{
	const json_str = fs.readFileSync (filename,'utf8')

	try
		{
		var array_out = Array()
		const array_aa = JSON.parse (json_str)

		console.log (array_aa.length)

		for (var it in array_aa)
			{
			var unit_aa = Object()
			unit_aa['title'] = array_aa[it].title
			unit_aa['url'] = array_aa[it].url
			const str_tmp = array_aa[it].updated_at.substring(0,16)
			unit_aa['updated_at'] = str_tmp.replace("T"," ")

			array_out.push(unit_aa)
			}

		const json_out = JSON.stringify(array_out)

		fs.writeFile (file_out,json_out,function (err)
		{
		if (err) {
			console.error ("Error on write: " + err)
			}
		else {
			fs.chmodSync (file_out,0666)
			console.log("File written.")
			console.error ("*** 終了 ***")
			}
		})
		}
	catch (error)
		{
		console.error ("*** error *** from JSON.parse ***")
		console.error (error)
		}
	}
else
	{
	console.error ("*** error *** " + filename + " doesn't exist. ***")
	}


console.error ("*** 終了 ***")
// ---------------------------------------------------------------

```

JSON の変換

```bash
./qiita_read.js qiita_ekzemplaro.json qiita_short.json
```

angular.js を使って、web で表示

```html
<!DOCTYPE html>
<html ng-app="myApp" lang="ja">
<head>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" />
<script src="/js/angular.min.js"></script>
<script src="qiita.js"></script>
<link rel="stylesheet" href="qiita.css">
<title>Qiita</title>
</head>
<body ng-controller="MainController">
<table>
<tr>
<th>title</th>
<th>updated_at</th>
</tr>
<tr ng-repeat="value in items">
<td><a href="{{value.url}}">
{{value.title}}</a></td>
<td>{{value.updated_at}}</td>
</tr>
</table>

<p />


<hr />
<a href="../">Return</a><p />
Jul/25/2017 AM 08:25<p />
</body>
</html>
```

参考ページ
[Qiita API v2の仕様](https://qiita.com/api/v2/docs)
JavaScriptのentries()を多重ループ内で使う場合の注意

ES2015の[Array.prototype.entries()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/entries)を多重ループ内で使うケースがあったのですが、
`entries()`を書く場所によって意図せぬ挙動になってハマったのでメモ。

例えばこんなコードがあったとします。
（この場合`entries()`は使う必要ないんですが、説明のためなのでツッコミなしで）

```js
const func = (arr) => {
  for (let i = 0; i < 2; i++) {
    for (const val of arr.entries()) {
      console.log(`${i}, [${val}]`);
    }
  }
};
const arr = [1, 2, 3];
func(arr);
```

```shell-session
0, [0,1]
0, [1,2]
0, [2,3]
1, [0,1]
1, [1,2]
1, [2,3]
```

これを、関数呼び出しの時点で`entries()`使うように書き換えると、外側ループが1回しか回らなくなっちゃいました！

```js
const func = (arr) => {
  for (let i = 0; i < 2; i++) {
    for (const val of arr) {
      console.log(`${i}, [${val}]`);
    }
  }
};
const arr = [1, 2, 3];
func(arr.entries());
```

```shell-session
0, [0,1]
0, [1,2]
0, [2,3]
```

理由ですが、正確には「外側ループが1回しか回っていない」のではなく、「2回目は内側ループが回らない」ということなのす。
`entries()`を外側ループより前に書いた場合、「作成されたイテレータが回り切って元に戻らない」のでした。

試しにデバッグ文を追加すると、こんな出力になります。

```js
const func = (arr) => {
  for (let i = 0; i < 2; i++) {
    console.log(`外側ループ ${i}`);
    for (const val of arr) {
      console.log(`${i}, [${val}]`);
    }
  }
  console.log('ループ終了');
};
const arr = [1, 2, 3];
func(arr.entries());
```

```shell-session
外側ループ 0
0, [0,1]
0, [1,2]
0, [2,3]
外側ループ 1
ループ終了
```

なので、関数の中に`entries()`書いても↓じゃダメ。

```js
const func = (arr) => {
  const itr = arr.entries();
  for (let i = 0; i < 2; i++) {
    for (const val of itr) {
      console.log(`${i}, [${val}]`);
    }
  }
};
const arr = [1, 2, 3];
func(arr);
```

↓ならOKですね。
外側ループが1周する毎にentries()が呼ばれてイテレータが再作成されるので。

```js
const func = (arr) => {
  for (let i = 0; i < 2; i++) {
    const itr = arr.entries();
    for (const val of itr) {
      console.log(`${i}, [${val}]`);
    }
  }
};
const arr = [1, 2, 3];
func(arr);
```

たぶんイテレータの扱いとしては基本的なことなんでしょうけど、
初心者は「何で変数の宣言場所違うと挙動変わるんじゃー(#ﾟДﾟ)！」ってなりそうなので、
記事に残しておきました。

ではまた〜。
Macのターミナルからtelnetしたときに日本語入力できないのを解決した


## 症状

bashrcに以下の記述をしているけど入力できない
ターミナルの詳細設定で UTF-8 指定しているのに入力できない
Google先生に色々対処方法を聞いたがよくわからない

## ポイント

テキストエンコーディングをEUC(日本語)にする等の手順があるが、
lsコマンド等の標準出力が文字化けするので適していない。
（そもそも、telnet後に文字化けしてしまうのが問題）

## 対処方法

### ターミナルの詳細設定を変更

ターミナル＞環境設定＞設定＞詳細＞非ASCII入力をエスケープ　のチェックを外す

### telnetオプションをつける

telnet の起動時に　-8 オプションをつける

「8ビット文字を使用する際にはこのオプションを指定する。」

最終的に、このオプションをつけて解決した。

## それでも解決できない場合

### ~/.inputrcに以下を記述

```
set output-meta on
set convert-meta off
set meta-flag on
```

私はこの設定を入れずに解決できた。

## 補足

普通は、デフォルトで対処されているらしいのですが、
環境によっては上記の対処をする必要がありそう。
画面構成(○○バー)


①ステータスバー
②アクションバー
③ナビゲーションバー

ググるときに必要
![device-2017-07-25-153434.png](https://qiita-image-store.s3.amazonaws.com/0/165589/86087680-47eb-4d13-6343-19b476b8948d.png)
Scotch Boxを古いバージョンでvagrant up

ScotchBoxのバージョンが3になってかなり便利で強力になりました。
でも、PHPが７だったりするので、まだ5の環境でやりたいな。。なんてときのために、2.5とかの古いバージョンで起ち上げたいとき。

```ruby:Vagrantfile
Vagrant.configure("2") do |config|

    config.vm.box = "scotch/box"
    config.vm.box_version = "2.5"
....
```

でupすればよい。

##追記
あと、2.5で使っていたのに、他のマシン立ち上げるときにboxを3にバージョン上げてしまったら、「vagrant upコマンド実行時にAuthentication failure.エラーが発生する」ようになってしまって、
[vagrant upコマンド実行時にAuthentication failure.エラーが発生する](http://qiita.com/shyse/items/9ec50b868b90f847c75f)
をやってみたのだけどうまくいかなくて困ったときも前のバージョンで起動して助かりました。

メモでした。

##参考

https://box.scotch.io/
Cognos Analyticsで負荷分散装置からのKeepAliveのガイド

##概要
負荷分散装置等から、後段の複数のCognos Analyticsノードに負荷分散を行う際に、このURLを指定して、という情報がありましたので共有します。

こちらの動画が情報元です。
**Use the Alive monitoring servlet with Cognos Analytics on Linux with the cURL command**
https://www.youtube.com/watch?v=DAdw71WcFXM

##内容
URLはズバリ以下のURLで、デフォルトではポートは9300ですね。
負荷分散装置から定期的にこのURLの応答を確認し、Headerに200 OKの応答があれば問題なし、それ以外の応答になれば、負荷分散対象から外す、という話になります。
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/59328648-1cb1-4cb6-b5f7-659acc8eb354.png)

Linuxからは、curl -I コマンドでURLを指定し、応答を確認する事も可能です。
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/6b46974a-2f24-c52e-b6eb-bfe6dcde607e.png)

ブラウザに直接URLを入力した場合、本体には何も返ってこないので、F12のデバッグツールでHeaderの内容を確認する必要があります。
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/c0d77ee5-349f-4eb8-65a9-efb9f67e7676.png)

というような内容が記載されていました。

ご参考まで。
Elasticsearch-headの導入方法 (OS: Windows 7)

# 背景
ElasticSearchのプラグインであるelasticsearch-headを以下のように導入しようとしたところ、エラー発生

コマンド：``elasticsearch-plugin.bat install mobz/elastic-search-head``

![es_plugin_error.png](https://qiita-image-store.s3.amazonaws.com/0/89402/7321f76b-2d51-d918-ff67-5ebaab434aa2.png)

``ERROR: Unknown plugin mobz/elasticsearch-head`` （不明のプラグイン：mobz/elasticsearch-head）

# 方法

参考：https://github.com/mobz/elasticsearch-head

1. コマンドプロンプトに　``git clone https://github.com/mobz/elasticsearch-head.git`` と入力し、elasticsearch-headフォルダをダウンロード  
    参考資料には``git://github.com/mobz/elasticsearch-head.git``と記載があるが、エラーが起きる場合は上記を使用。
2. elasticsearch-headのフォルダに入る ``cd elasticsearch-head``
3. インストール　``npm install``
4. 動かす　``npm run start``

# 動いた
## ``localhost:9100``より確認可能
![localhost9100.png](https://qiita-image-store.s3.amazonaws.com/0/89402/44d80039-f2fb-9e5d-588a-a98bf137a4f6.png)

# バッチファイル
いちいち入力するのが面倒なのでバッチファイルを書いた
```bat:es-head.bat
cd "Desktop/elasticsearch-head"
npm run start```

## gitによるダウンロードでエラー
- 考えられる原因：proxyを設定していない
- 解決方法：コマンドプロンプトから以下を設定
    - ```git config --global http.proxy http://***.***.***.***:port番号```
    - ```git config --global https.proxy http://***.***.***.***:port番号```
Gitlab-flowの説明

# Gitlab-flowのグラフ
![gitlab-flow.png](https://qiita-image-store.s3.amazonaws.com/0/185389/68b5a27b-e32b-d61f-6020-96de3ba1d335.png "gitlab-flow.png")


# Gitlab-flowのブランチ説明
* feature/hotfixは機能開発、不具合対応ブランチです
* masterはメインのブランチ
* pre-production(オプションブランチ)はリリース前のテスト用(git-flowで言うreleaseブランチ)
* productionはリリース済みのコード置き場

# Gitlab-flowの流れ
## 機能開発
1. 機能開発するとき、masterブランチからfeature/NAMEブランチを切って開発進む
2. 開発が終わったらfeatureブランチからmasterにMerge Requestを作成します。
3. masterをステージング環境へデプロイして、確認する
4. プリプロダクションへデプロイしたい場合、masterブランチからpre-productionブランチへのMerge Requestを作成します。マージ済みになるとデプロイする
5. pre-productionブランチからproductionブランチへのMerge Requestを作成します。マージ済みになるとデプロイする


## 不具合対応
1.  不具合があるとき、masterブランチからhotfix/NAMEブランチを切って対応を行う
* 対応が終わったら、hotfixブランチからmasterにMerge Requestを作成します。
* masterをステージング環境へデプロイして、確認する
* 確認して、問題がなければhotfixブランチを順次pre-production > production にマージ

## 注意事項
* masterに直接コミットしない
* featureが長生きする場合はmasterから適度にマージするのを忘れずに
* featureブランチはmasterにマージした後、削除する
* hotfixブランチは全てのブランチにマージしたら削除する

# メリット・デメリット
## メリット
* コミットがダウンストリームへ流れるのですべての環境で全てテスト済みであることを保証します
* CIはサポートされる
	* Gitlabはcontinuous integrationサービスを提供する。CIサービスを設定手順は下記に通りです
		1. リポジトリに```.gitlab-ci.yml```を追加する。
			* ```.gitlab-ci.yml```はjobを定義するファイルです。
		2. プロジェクトにRunnerの利用を設定する
			* Runnerは```.gitlab-ci.yml```に定義するjobを実行するバーチャルマシンです。
	*  CIを設定すると、リポジトリにpush,commitする際に、パイプラインのjobを実行される。
		* 例えば：build → 自動テスト → デプロイ
	* jobの実行状態の管理も提供するので、とても便利です。 
		* サンプルリンク [gitlab-flow_practice/pipelines](https://gitlab.com/tlt-anh/gitlab-flow_practice/pipelines)
	* 参照リンク[Getting started with GitLab CI ](https://docs.gitlab.com/ce/ci/quick_start/README.html)
* CIを使ってlatestステータスで、現在環境ごとにどんなブランチをデプロイされるの確認もやりやすい。  
	* サンプルリンク [gitlab-flow_practice/pipelines](https://gitlab.com/tlt-anh/gitlab-flow_practice/pipelines)

## デメリット
* 複雑(git-flowと同じ)
* CIが便利ですが、自動実行なのでもし誤commit、pushすると環境にデプロイしちゃう。

#お試しのリポジトリ
* URL : https://gitlab.com/tlt-anh/gitlab-flow_practice

## 構成
* ブランチ
	* master
	* pre-production
	* production
* CI
	* `.gitlab-ci.yml`ファイル

		```.gitlab-ci.yml
		before_script:
		 - echo "ジョブを実行する前の準備コマンド"

		test:
		 script:
		  - echo "テスト実施コマンド"

		staging:
		 type: deploy
		 script:
		  - echo "ステージング環境にデプロイするコマンド"
		 only:
		  - master

		pre-production:
		 type: deploy
		 script:
		  - echo "pre-production環境にデプロイするコマンド"
		 only:
		  - pre-production

		production:
		 type: deploy
		 script:
		  - echo "本番環境にデプロイするコマンド"
		 only:
		  - tags

		```
		* jobの説明
			* before_script: jobを実行する前の準備
			* test job:  
				* 内容:（仮）単体テスト実施
				* 実行する条件: 全てのブランチにpush,commitする際に実行する
			* staging job: 
				* 内容:（仮）ステージング環境にデプロイ
				* 実行する条件: masterブランチのみにpush,commitの際に実行する
			* pre-production job: 
				* 内容:（仮）pre-production環境にデプロイ
				* 実行する条件: pre-productionブランチのみにpush,commitの際に実行する
			* production:
				* 内容:（仮）production環境にデプロイ
				* 実行する条件: タグ付けの際に実行する
[Salesforce DX]Salesforce CLI操作でのエラーに対する対処法

Salesforce CLIを使ってSalesforce環境への接続やデプロイするときなどに
エラーがでたりいろいろ躓くことがあります。
Salesforce CLI自体が最近オープンベータになったばかりで
検索してもあまり情報がなく自力でなんとするしかないことが多々あります。
そんなときに参考となる情報を紹介したいと思います。


詳細は下記のリンクにまとめております。
http://dev.classmethod.jp/cloud/salesforce-cli-trouble-shooting/
ECSで dmeventd がCPU使用率が100%になってしまったときの解決策

自分の備忘録も兼ねて。

## 解消方法

とりえあず、以下のコマンドを流すと解消する。

```
sudo docker rm $(docker ps -q -f status=exited)
docker images -q | xargs --no-run-if-empty docker rmi
```

## 発生させないためには

`ecs-agent` のバージョンを `1.13.0` 以上にする。

Issue的にはこれ https://github.com/aws/amazon-ecs-agent/issues/118

## 現象

topでみたらこんなんだった。

```
top - 05:01:32 up 245 days, 37 min,  1 user,  load average: 6.16, 5.02, 5.30
Tasks: 737 total,   1 running, 163 sleeping,   0 stopped, 573 zombie
Cpu(s): 34.1%us,  1.8%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si, 64.1%st
Mem:   2051528k total,  1762020k used,   289508k free,   234300k buffers
Swap:        0k total,        0k used,        0k free,   859404k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 2322 root       2 -18  109m  49m 4292 S 93.2  2.5   3113:00 dmeventd
 2634 root      20   0  926m  67m  23m S  1.6  3.4   3873:45 docker
 2640 root      20   0  275m  15m 9292 S  0.6  0.8   1968:15 docker-containe
```

古いコンテナーやイメージがたまると、ダメっぽい。

多分これと関係があるようなきがするけど・・・
https://bugzilla.redhat.com/show_bug.cgi?id=1220529
[swift3] 特定の画面でStatusBarを隠す方法

iOS7以降から有効になった`prefersStatusBarHidden`を使う。

## Info.plist

`View controller-based status bar appearance`キーを追加して`YES`を設定。

## prefersStatusBarHidden

StatusBarを隠したいViewControllerで以下を実装。

``` swift
override var prefersStatusBarHidden: Bool {
    return true
}
```

## 問題点 1
### StatusBarStyleが死ぬ

StatusBarを白くしたいので設定していた以下の内容が無効になる。

- Info.plistの`Status bar style`の`UIStatusBarStyleLightContent`
- AppDelegateで実装していた`application.statusBarStyle = .lightContent`

### 解決策

ViewControllerに以下を実装したら解決した。

``` swift
override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}
```

## 問題点 2
### LandscapeでStatusBarが消えない

今までLnadscapeModeになると自動的にStatusBarが非表示になっていたのに表示されてしまう。
-> `View controller-based status bar appearance`を`YES`に設定したせいだと思う。

### 解決策

LandscapeとPortrateに突入する際に`prefersStatusBarHidden`がコールされるので、そこで適切な値を返してあげればよい。
例としては以下。

``` swift
class ViewController: UIViewController {
    
    var isStatusBarHidden = false
    
    override var prefersStatusBarHidden: Bool {
        return isStatusBarHidden
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        NotificationCenter.default.addObserver(self, selector: #selector(didRotateScreen), name: .UIApplicationDidChangeStatusBarOrientation, object: nil)
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    @IBAction func tapButton(_ sender: UIButton) {
        isStatusBarHidden = !isStatusBarHidden
        setNeedsStatusBarAppearanceUpdate()
    }
    
    func didRotateScreen() {
        if UIDevice.current.orientation.isLandscape {
            isStatusBarHidden = true
        } else if UIDevice.current.orientation.isPortrait {
            isStatusBarHidden = false
        }
    }
}
```

## 余談

上記のコードで記述している`@IBAction func tapButton`は、storyboardに配置した"StatusBarの表示/非表示を切り替えるボタン"に接続するIBActionです。
メソッド内で実行している`setNeedsStatusBarAppearanceUpdate()`は、実行した時点でStatusBarの表示を更新してくれます。(すなわち`prefersStatusBarHidden`が実行される)