OmniAICreator/Qiita-1.07M huggingface dataset:
document.querySelectorAllでmapやfilterを使う方法

`document.querySelectorAll(selectors)` を `Array.prototype.slice.call()` (`[].slice.call()`) の中に入れると、配列で使える `map` や `filter` といったメソッドが使えるようになるようです。

# サンプル
例として、[Qiitaの人気の投稿Beta](http://qiita.com/popular-items) にある記事のタイトルをコンマ区切りでアラート表示するブックマークレットを作ってみました。

![query-selector-all-map.png](https://qiita-image-store.s3.amazonaws.com/0/137045/72f037c0-cd12-59dc-dc98-a4c101ba8ed0.png)

以下のコードを[Qiitaの人気の投稿Beta](http://qiita.com/popular-items)を開いている状態でブラウザ上のアドレスバーに貼り付け(貼り付け時に先頭の `javascript:` が消える場合は `javascript:` を追記してください)してからEnterキーを押すと実行できます。
ES2015の記法(アロー関数等)は用いていないので、Internet Explorer 11でも動作します。

## `[].slice.call()` を利用
`map` メソッドで記事名の配列を生成し、`join` メソッドでコンマ区切りの文字列を生成します

```js
javascript:alert([].slice.call(document.querySelectorAll('.popularItem_articleTitle_text')).map(function(el,i){return el.innerText}).join());
```

## `[].map.call()` を利用
今回の例では `[].slice.call()` と `map` メソッドの代わりに、 `[].map.call()` でも記事名の配列を生成することができます

```js
javascript:alert([].map.call(document.querySelectorAll('.popularItem_articleTitle_text'),function(el,i){return el.innerText}).join());
```

# サンプル(jQueryが使える場合)
jQueryがあっても、すっきり書けない感じでした。
`get` メソッドでjQueryオブジェクトが持つエレメント全てを配列の形で得ることができるようです。
QiitaではjQueryが使われており、以下のサンプルは上のものと同様にして実行ができます。

## 先に `get` する
`get` メソッド以降は `[].slice.call()` を利用する場合と同様になります

```js
javascript:alert($('.popularItem_articleTitle_text').get().map(function(el,i){return el.innerText}).join());
```

## 後で `get` する
ここでの`map` メソッドはjQueryのもので、`map` メソッドの中に入れる関数で2番目の引数を用いたり、 `$(el).text()` のようにして要素が持つテキストを取得したりする必要があります

```js
javascript:alert($('.popularItem_articleTitle_text').map(function(i,el){return $(el).text()}).get().join());
```

`this` を使って以下のようにも書けます(function式をアロー関数式にすることができない例にもなっています)

```js
javascript:alert($('.popularItem_articleTitle_text').map(function(){return $(this).text()}).get().join());
```

# 参考サイト
[jQuery日本語リファレンス - get()](http://semooh.jp/jquery/api/core/get/_/)
Swift3ではKVOにkeyPath()式を使っていくのが便利

# はじめに

- KVO使う際は文字列でプロパティのkeyPathを指定しなくていいですよ
- 文字列指定だとプロパティ名が変わった時とか実行時になって間違いに気づいてヤバい
- [Swift 3からの#keyPath()式](https://github.com/apple/swift-evolution/blob/master/proposals/0062-objc-keypaths.md)を使うことで静的にチェックできるのでコンパイル時に気づけます

KVOとSwift 3でググったときにシンプルな利用例が無いので記載しておきます。

# 具体例で`#keyPath()`

具体的に例を上げて`#keyPath()`の使い方を書いておきます。`Person`クラスの`age`プロパティを`PersonOfInterest`クラスが監視する例です。

まず、監視されるクラス`Person`の定義

```swift
class Person: NSObject {
    dynamic var age: NSNumber
    
    init(age: NSNumber) {
        self.age = age
    }
}
```

これは年齢ageが変えられるように`var`にしておきます。
その年齢を監視するので`dynamic`キーワードを使用します。dynamicについては[ここ](http://qiita.com/takecian/items/882a0441b5694a4fd5e7)を読むと分かりやすいでしょう。

その上で、このageの文字列があれば監視できるので、そのために`#keyPath(Person.age)`という使い方をします。これによって文字列としてageを取得できます。

```swift
print(#keyPath(Person.age)) // age
```

`#keyPath()`式で指定する際に重要なのは

- `#keyPath(Person.age)`のクラス名.プロパティ名が正しい
- `#keyPath(インスタンス名.age)`だと駄目

当然Person.ageがTypoしていればコンパイルエラーになります。

次に`Person`を監視するクラス`PersonOfInterest`を定義。`age` を監視するメソッド`observeValue`を用意します。

```swift
final class PersonOfInterest: NSObject {
    
    override func observeValue(forKeyPath keyPath: String?,
                               of object: Any?,
                               change: [NSKeyValueChangeKey : Any]?,
                               context: UnsafeMutableRawPointer?) {
        
        guard let keyPath = keyPath, let change = change else { return }

        if keyPath == #keyPath(Person.age) {
            guard let old = change[NSKeyValueChangeKey.oldKey] as? NSNumber else { return }
            guard let current = change[NSKeyValueChangeKey.newKey] as? NSNumber else { return }
            
            print(old, current)
        }
    }
}
```

このクラス`PersonOfInterest`が `Person`を監視する例は次の通りです

```swift
let poi = PersonOfInterest()

let chris = Person(age: NSNumber(value: 10))
chris.addObserver(poi, forKeyPath: #keyPath(Person.age), options: [.old, .new], context: nil)

chris.age = NSNumber(value: 11)  // old:10, current:11
chris.age = NSNumber(value: 11)  // old:11, current:11 値は変わってないがオブジェクト変わってるから
chris.age = NSNumber(value: 20)  // old:11, current:20

chris.removeObserver(poi, forKeyPath: #keyPath(Person.age))

chris.age = NSNumber(value: 30)  // 監視を辞めた後なので反応なし
```

監視して値を出力すると、old, currentの並びで次のような値になりました。

```
10, 11
11, 11
11, 20
```

監視をやめた後に30に変更した際には反応していないのと、"11"に変えた後にまた"11"に変えても監視が呼び出されています。これは文字列のオブジェクト自体の再代入が起こっているので変化があったということでしょう。

# おわりに

`#keyPath()`式自体を利用して文字列でプロパティ名を取得するためには、今回のPersonのように、監視対象のクラスがNSObjectを継承している必要があります。そもそもaddObserverメソッドがNSObjectを継承する必要があるので忘れることはないでしょうが、SwiftのObjectで`#KeyPath()`式を試してもコンパイルエラーになるはずです。
ZabbixでNFS/SANマウントを監視する

ZabbixでNFS/SANを監視する際
#今までの提案事例

- ディレクトリをディスカバリして最大容量の違いを監視
- マウント先だけに存在するファイルでアクセスの可否を監視

とありますが
上だと自動登録されるがアラートの発砲判定が1度しかない、復旧時もアラート
下だと全てのマウント先にファイルを置く作業とそれを1つずつアイテム、トリガーの登録作業
と運用で辛みがあります。

#新提案
1. クライアント側でUserparameterにてegrep -c "ext|xfs|nfs " /etc/mtab
2. サーバ側でアイテム登録
3. サーバ側でmax(#x)<>last(0)をトリガーとして設定

1でext2-4とxfsとnfsの数を監視(nfsスペースなしだと余計なのも1つある)
3で過去x回の最大値と今の値が一致するか判定
こうすることで

- agent.dに配布する仕組みがあるなら自動化できる
- 復旧時(当然増える)と増えていた場合はアラートがならない
- maxの回数分過去を遡るので減っていた場合の発砲判定もその数だけ発生

意図的に減らす場合はメンテナンスモードなりでアラート飛ばない運用だけになります。
AWS-EC2のp2インスタンスでchainer-goghの画風変換をGPU実行してみた

# はじめに
DeepLearningの実践入門としてAWS-EC2のp2インスタンスを使用して、chainer-goghの画風変換をGPUで実行してみました。
結論としてp2.xlargeを使用してサンプル通りの画風変換を実行すると、5分程度で処理が完了します。
[参考にさせていただいたchainer-goghのGitHub](https://github.com/mattya/chainer-gogh)

# 環境
クライアントPC　: macOS Sierra 10.12.4
サーバ : EC2 p2.xlarge (時間課金なので注意してください。)

# 事前準備
GPUコンピューティングのインスタンスを立ち上げる場合、デフォルトでは作成できないためAWSの担当者に問い合わせを行い、領域を拡張してもらってください。
領域の拡張はEC2ダッシュボードを開いて、左側のメニューにある「制限」から　p2.xlarge の規制緩和の依頼ができます。

# p2インスタンスの作成
今回はディープラーニングで使用する諸々のツールがインストール済みのAMIを使用します。
※私は"バージニア北部"リージョンを使用しています。
EC2ダッシュボードから「インスタンスの作成」 → 「AWS Marketplace」の順にクリック。
検索窓に「Deep Learning AMI」を入力して検索し、「Deep Learning AMI Amazon Linux Version」のAMIを使用してください。
その後のインスタンスの作成作業は通常のEC2と同じですので、ここでは割愛させていただきます。

# 環境構築
立ち上げたp2インスタンスにsshで接続して環境構築を実施します。
### Pythonのインストール
「Deep Learning AMI Amazon Linux Version」を使用すると最初からPythonの2系と3系がインストールされているので、インストール作業は不要です。
※今回はPython3系を使用します。

### Gitのインストール
こちらも最初から入っているので不要です。

### Chainerのインストール
下記のコマンドでインストールできます。

```bash
sudo pip3 install chainer
```

### Chainer-goghのクローン
必要であれば予めGitHub上で自分のリポジトリにChainer-goghをforkしておいてください。
chainer-goghをサーバにcloneします。

```bash
git clone https://github.com/xxxxxxxxx/chainer-gogh.git
```

### モデルのダウンロード
NINモデルをダウンロードしてください。（下記リンク先のDropBoxのURLからダウンロードできます。）
https://gist.github.com/mavenlin/d802a5849de39225bcc6

ダウンロードしたファイルをクライアントマシンからサーバに送信してください。

```bash
scp -i xxxxxxx.pem xxxxxxxx/nin_imagenet.caffemodel ec2-user@host:~/chainer-gogh
```

### 出力用ディレクトリを作成

```bash
cd chainer-gogh; mkdir output
```

# 画風変換の実行
### コマンドで実行
実行には5分程度かかります。

```bash
python3 chainer-gogh.py -m nin -i sample_images/cat.png -s sample_images/style_1.png -o output -g 0
```

### 実行結果をダウンロード
ローカルのターミナルでコマンドを実行。
このコマンドではim_04950.pngをDownloadディレクトリ配下にダウンロードします。
このファイルが画風変換した最終結果になります。
100イテレーションずつ途中結果も出力されますので、outputディレクトリを確認してください。

```bash
scp -i xxxxxxx.pem ec2-user@xxxxxxxxxx:~/chainer-gogh/output/im_04950.png ~/Download/im_04950.png
```

# 後処理
EC2は時間課金になります。
確認が終わったらインスタンスを削除するか停止してください。

# まとめ
今回はchainer-goghを使用した画風変換の環境をp2インスタンスで作成し、GPU実行できるところまで確認しました。
AWSを使用することで手元にGPUマシンを用意しなくても手軽に使用できるので大変便利です！
Docker | 一番最近のコンテナID/イメージIDを得るコマンドエイリアス

# エイリアス登録

```bash:~/.zshrc
alias docker-ps-last="docker ps | head -n 2 | tail -n 1 | awk '{print \$1}'"
alias docker-image-last="docker images | head -n 2 | tail -n 1 | awk '{print \$3}'"

```

反映

```
$ source ~/.zshrc
```

# 確認

コンテナのプロセスがこんな感じの時。

```
$ docker ps
CONTAINER ID        IMAGE                           COMMAND             CREATED             STATUS              PORTS                  NAMES
d2bb2df6b8d5        yumainaura/get-started:latest   "python app.py"     11 hours ago        Up 5 minutes        0.0.0.0:4000->80/tcp   optimistic_ritchie
```

一番最近のコンテナIDを得る。

```
$ docker-ps-last
d2bb2df6b8d5
```

# 用例

## 最後に作ったイメージからコンテナを作る

```
$ docker run $(docker-last-image)
```

## プロセスをどんどん殺す

```
$ docker kill $(docker-ps-last)
```

# 環境

- Docker version 17.03.1-ce, build c6d412e
- zsh 5.3.1 (x86_64-apple-darwin15.6.0)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
React のバージョンを 15.5 系にあげたときにやったこと

React のバージョンを 15.4.2 から 15.5.4 に上げたのでそのメモ

## はじめに
* React 15.5.0 にて下記が deprecated になった
    * React.PropTypes
    * React.createClass
* 今回のプロジェクトでは React.PropTypes を使用していたのでそのマイグレーションを含めた移行手順を記載
    * 基本的にはドキュメントどおり : https://facebook.github.io/react/blog/2017/04/07/react-v15.5.0.html


## マイグレーションスクリプトの実行
* [jscodeshift](https://github.com/facebook/jscodeshift) をグローバルにインストール
    * $ yarn global add jscodeshift
* nodejs/bin のパスを通す
* マイグレーションスクリプトの取得
    * [react-codemod](https://github.com/reactjs/react-codemod) を clone してスクリプトを取得

```
$ git clone git@github.com:reactjs/react-codemod.git
```

* スクリプトの実行

```
$ jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js path/to/

Processing 459 files...
Spawning 7 workers...
Sending 50 files to free worker...
Sending 50 files to free worker...
Sending 50 files to free worker...
Sending 50 files to free worker...
Sending 50 files to free worker...
Sending 50 files to free worker...
Sending 50 files to free worker...
Sending 50 files to free worker...
Sending 50 files to free worker...
Sending 9 files to free worker...
All done.
Results:
0 errors
0 unmodified
292 skipped
167 ok
Time elapsed: 8.836seconds
```

## react, react-dom のバージョンアップと prop-types のインストール

* react, react-dom バージョンアップ

```
$ yarn upgrade react@^15.5.0 react-dom@^15.5.0
```

* prop-types パッケージの追加

```
$ yarn add prop-types
```

## 移行が推奨されている React Addons の中で使っていたもの

* [discontinuing-support-for-react-addons](https://facebook.github.io/react/blog/2017/04/07/react-v15.5.0.html#discontinuing-support-for-react-addons) に記載の通り React Addons も必要に応じて対応する必要がある
* 今回使用していたのは react-addons-css-transition-group と react-addons-test-utils
* react-addons-css-transition-group の対応
    * 代わりに react-transition-group/CSSTransitionGroup を使用する

```
$ yarn remove react-addons-css-transition-group
$ yarn add react-transition-group
// import の置換
$ grep -lr 'react-addons-css-transition-group' path/to/* | xargs sed -i -e 's/react-addons-css-transition-group/react-transition-group\/CSSTransitionGroup/g'
$ git clean -f
```

* react-addons-test-utils の対応
    * 代わりに react-dom/test-utils を使用する

````
$ yarn remove react-addons-test-utils
$ grep -lr 'react-addons-test-utils' path/to/* | xargs sed -i -e 's/react-addons-test-utils/react-dom\/test-utils/g'
$ git clean -f
````

## enzyme を使っている場合

* React を 15.5.x にあげると enzyme のバージョンアップも必要になる
* また、非推奨になった react-addons-test-utils の代わりに react-test-renderer が必要になる
    * ref. https://github.com/airbnb/enzyme/blob/edeb99c21cbcbc86e70a4d627192dc975d955544/README.md#installation

```
$ yarn upgrade enzyme
$ yarn add -D react-test-renderer
```
LPIC Lv1 学習日記_02

本日のハイライト

•trコマンドはキーボードから入力した文字を指定したフォーマットに変換して表示する。
ファイルをリダイレクトする事でキーボード以外からの出力も受け付けることが出来る。
-dオプションで合致した文字を削除する。

•ファイルの単語単位での変換や削除はsedコマンドを使う

•ファイル内の行中の特定部分だけを取り出すにはcutコマンドを使う

•ファイル内のバイト数、単語数、行数を表示するにはwcコマンドを使う

•以下のコマンドは
cat /var/log/maillog|grep'reject'|wc -l

cat /var/log/maillog
でログファイルを出力し

grep'reject'
でrejectを検索して結果を出力し

wc -l
で受け取った結果の行数を表示

ログファイルのrejectを含む行の行数がわかる
というパイプラインの問題

•ファイルの内容を8進数で表示するにはodコマンドを使う

•引数で指定されたファイル内にあるタブをスペースに変換するにはexpandコマンドを使う
スペースをタブに変換するにはunexpandコマンドを使う

•splitコマンドはファイルを決まった大きさに分割できる
何も指定しなけば1000行毎にファイルを分割する
Chart.js で棒グラフを作る

![bar_graph.png](https://qiita-image-store.s3.amazonaws.com/0/179446/50418a00-4c07-24aa-8d33-4b6282aac638.png)

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Chart.js 棒グラフ</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
<script src="bar_graph.js"></script>
</head>
<body>
<h1>Chart.js 棒グラフ</h1>
<canvas id="chart" height="200" width="400"></canvas>
<hr />
Dec/09/2021<p />
</body>
</html>
```

```js:bar_graph.js
// ----------------------------------------------------------------------
//	bar_graph.js
//
//					Aug/07/2023
// ----------------------------------------------------------------------
window.onload = ()=>
{
	const config = {
		type: 'bar',
		data: barChartData,
		responsive : true
		}

	const context = document.getElementById("chart")
	const chart = new Chart(context,config)
}

// ----------------------------------------------------------------------
const barChartData = {
	labels : ["青森","岩手","秋田","宮城","山形","福島"],
	datasets : [
		{
		label: "1年目",
		backgroundColor: "rgba(179,181,198,0.5)",
		data : [25,45,5,20,19,33]
		},
		{
		label: "2年目",
		backgroundColor: "rgba(255,99,132,0.5)",
		data : [10,54,77,32,9,78]
		}
	]
}

// ----------------------------------------------------------------------
```
netflow + elasticsearch

[前回](http://qiita.com/kwi/items/fb6aeb1c50913ddeffc2)の続き。どうにも ntopng を使って役に立つようにやりくりすることができずに、苦労していた。たぶん私の用途に合っていないだけなのだけれど、代わりの方法を探さないといけなくなってきた。

そうこうしていると、elasticsearch でいいような気分になってきて、実際 fluentd + elasticsearch + kibana で[やっている方](http://qiita.com/oikyn/items/f3e624b3cfd03b5cdb87)もいらっしゃるようだし、Cisco にも [blog 記事](https://blogs.cisco.com/security/step-by-step-setup-of-elk-for-netflow-analytics) があるので、この構成を試してみることにした。

# interfaces

Ubuntu Desktop 16.04.2 をベースにする。NetworkManager で管理されているので、モニター用のインターフェースが `ethX` だったとして、それを切り離す。promisc を設定したいので、次のようにファイルを整える。

```:/etc/NetworkManager/NetworkManager.conf
# 次の行を追加
[keyfile]
unmanaged-devices=interface-name:ethX
```

```:/etc/network/interfaces
# 次の行を追加
source-directory interfaces.d
```

```:/etc/network/interfaces.d/monitor
auto ethX
iface ethX inet manual
 pre-up ifconfig $IFACE up promisc
 post-down ifconfig $IFACE down
```

```:/etc/sysctl.d/60-monitor.conf
net.ipv6.conf.ethX.disable_ipv6=1
```

# ipt-netflow

git で https://github.com/aabc/ipt-netflow/ から取得する。`promisc` を有効にしてビルドし、インストールする。

```bash
./configure --enable-promisc
```

IPFIX を使う予定。

```:/etc/modprobe.d/netflow.conf
options ipt_NETFLOW protocol=10 promisc=1 destination=127.0.0.1:4739
```

`iptables-persistent` をインストールしてサービス登録する。

```bash
iptables -A PREROUTING -t raw -i ethX -j NETFLOW
ip6tables -A PREROUTING -t raw -i ethX -j NETFLOW
/etc/init.d/netfilter-persistent save
systemctl enable netfilter-persistent
```

デフォルトでは localhost UDP port 2055 に送るようになっている。[行儀よく](https://www.ietf.org/mail-archive/web/ipfix/current/msg02963.html) port 4739 に変えたほうが、wireshark で眺めるときなどに都合がいい。

# elasticsearch

[インストールドキュメント](https://www.elastic.co/guide/en/elasticsearch/reference/current/deb.html) に従う。`default-jre-headless` を使うと世話が無い。

手元でデバッグする都合、`0.0.0.0` で listen するように変更した。

```:/etc/elasticsearch/elasticsearch.yml
network.host: 0.0.0.0
```

`systemd` で有効化する。

```bash
systemctl enable elasticsearch
```

# logstash

[インストールドキュメント](https://www.elastic.co/guide/en/logstash/current/installing-logstash.html) に従う。

設定ファイルは YAML ではなく、[独自形式](https://www.elastic.co/guide/en/logstash/current/configuration-file-structure.html)なので混同しないように注意する。

```:/etc/logstash/conf.d/es.conf
output {
 elasticsearch {}
}
```

```:/etc/logstash/conf.d/netflow.conf
input {
  udp {
    port => 4739
    codec => netflow {
      versions => [10]
      target => ipfix
    }
    type => ipfix
  }
}
```

こちらも `systemd` で起動させる。

```bash
systemctl enable logstash
```

# kibana

外部からウェブブラウザでアクセスするので、こちらも `0.0.0.0` で listen させる。

```:/etc/kibana/kibana.yml
server.host: "0.0.0.0"
```

`systemd` で起動させる

```bash
systemctl enable kibana
```

# Dashboard

さぁて、ここからは通り一辺倒なダッシュボードでも作ってみるか（続く）
入門者にGitとGitHubを教えるときどのようにしますか？

これは「コードを書いていて困ったときに、suinがチャットで質問に答えたり相談に乗る[suinのプログラミング相談室(仮)](https://help.suin.io/)」で頂いた質問と僕の回答の要約です。

## 質問

入門者にGitとGitHubを教えるとき、どのように教えたらいいですか？対象はプログラミング経験半年ほど。主にRuby on Railsを学んだ人で、VCSの利用経験がありません。suinさんならどう教えますか？

## suinの回答

git教える、github教えるの順で別々に教えていって良いと考えてます。

バージョン管理システム未経験者はそもそも、そのメリットを感じてないので、メリットを知ってもらうとこから入るように僕は教えてます。使えるツールだなと、思ってもらえると自主学習も進むので。

たとえば、今までどうやって古いコードを復元していたか、その人の習慣を聞きます。「コードを前のバージョンに戻せるようにどうやってましたか？」「前のバージョンに戻したいことって今までありませんでしたか？そのときはどうやってましたか？」などと質問します。

僕の経験上では「フォルダをコピーして取っておく」「Ctrl-Z(戻す)を押しまくる」といった答えが返ってくるので、その作業はGitを使うと簡単だよと説明します。

メリットを納得してもらったら、あとはどういう仕組みで動いてるとか、他にどういうメリットが付随してあるとか説明していくと良いですね。

GitHubについては、「ソースコード共有するにはどうしたらいいと思いますか？」と質問してから入るといいと思います。ソースコードを共有する体験自体ないことがあるからです。git pushするだけで、簡単にコードを共有できるメリットを体験してもらってから、仕組みやコラボレーションする際においての利便性について解説すると良いと考えます。

## 回答に対して頂いた反応

過去の経験をベースにすると納得感増しますね。Gitに限らず、ツールの説明時には広く使える手法ですね。
NodeJSのtwitterモジュールで自動フォロバ

# 注意
**短時間にたくさんの人にフォローされると**
その分、フォローバックしてしまうので、
**凍結される可能性があります。**

**自己責任でご使用ください**

# 概要
NodeJSのTwitterモジュールで自動フォロバをする
サンプルがなくて、少しハマったので書いておく。

# ソース
```js
const twitter = require('twitter');

client.stream('user', function(stream) {
  stream.on('follow', function(data) {
    if (data.source.id_str=="myId") return;
    client.post('friendships/create', {user_id:data.source.id_str});
  });
});
```
followイベントは自分が誰かを**フォローした時**と誰かに**フォローされた**時に着火する
なので自分が誰かをフォローすると**自分で自分をフォローする**というよくわからない状態になってしまうので
`if (data.source.id_str=="myId") return;`
で対象が自分の場合を除外する
Ruby | git の差分を作らずに rbenv で Ruby のバージョンを固定する

# 方法1. direnv を使う

[direnv](https://github.com/direnv/direnv) でディレクトリ毎に ruby version を指定できる。

```
cd some_directory
```

```
direnv edit 
```

```.envrc
export RBENV_VERSION=2.3.1
```

## 確認

```
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]
```

```
$ rbenv versions
* 2.3.1 (set by RBENV_VERSION environment variable)
```

`RBENV_VERSION` が効いているのが分かる。
( 環境変数は rbenv global / rbenv local の設定より優先される )

# 方法2. ruby-versions + gitignore_global

`.ruby-version` を作成した上で、 個人環境で gitignore する。

```
cd some_directory
```

```
rbenv local 2.3.1
```

```~/.gitignore_global
.ruby-version
```

## 確認

`set by ~ .ruby-version` の部分で、ruby-versionの指定が効いていることが分かる。

```
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]
```

```
$ rbenv versions
* 2.3.1 (set by /some_directory/.ruby-version)
```








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
AWS SDK for PHP v3でAmazon CloudSearchを使う

検索すると v2 の記事ばかり出てきたので、v3 のを備忘録がてら書いてみました。
PHP のコードだけです。PHP は 5.6.x で書いてます。
CloudSearch の準備は他の記事を参考にしてください。
参考：[Amazon CloudSearch: 簡単な地理空間検索をやってみる - Qiita](http://qiita.com/okuda_h/items/0dcb27abeac7641ba2a4)

## 準備

まずは AWS SDK を Composer とかでインストールして、
ドメインクライアントを呼びます。

```php
use Aws\CloudSearchDomain\CloudSearchDomainClient;
```

## データのアップロード

```php:upload
$domainClient = CloudSearchDomainClient::factory([
    'endpoint' => 'http://document-xxxx.resion.cloudsearch.amazonaws.com', // Document Endpoint
    'version' => '2013-01-01',
    // credentials はコードに書かずに、環境変数等で設定するのがいいです
    // 'credentials' => [
    //     'key' => '****',
    //     'secret' => '****',
    // ],
]);

$domainClient->uploadDocuments([
    'contentType' => 'application/json',
    'documents' => json_encode([[
        'type' => 'add',
        'id' => 1,
        'fields' => [
            'age'     => 30,                     // int
            'name'    => '山田太郎',              // text
            'check'   => [ 1, 2, 3, 4 ],         // int-array
            'created' => '2017-05-01T00:00:00Z', // date
        ],
    ]]),
]);
```

新規追加も更新もこれでできます。

フィールドの型が合っていないとエラーが出ます。
date 型の場合、RFC3339 形式で UTC で指定しないといけないので、私は下記のようにしました。

```php
gmdate('Y-m-d\TH:i:s\Z', time())
```

[PHPの DateTime クラス](http://php.net/manual/ja/class.datetime.php) の `DATE_RFC3339` とかでいけるかと思ったんですが、末尾 `Z` ではなく `+00:00` になるのはエラーが出てしまいました。

チェックボックスで入力するような値は、DB ならビットで 1 カラムに入れたりしますが、検索でビット演算子が使えなそうだし、 int-array があるのでそれにしました。

## 検索

```php:search
$domainClient = CloudSearchDomainClient::factory([
    'endpoint' => 'http://search-xxxx.resion.cloudsearch.amazonaws.com', // Search Endpoint
    'version' => '2013-01-01',
]);

$result = $domainClient->search([
    'query' => "name: 'やまだ' created: [2017-04-30T15:00:00Z TO *]",
    'queryParser' => 'lucene',
]);

var_dump($result);
```

`queryParser` は Lucene にしましたが、お好みでいいと思います。

Lucene だと `'*:*'` とすると全件出せるので、他のは出し方わからなかったので、これにしました。
syntax もググるとすぐ出てきますし（[Lucene Query Syntax](http://www.lucenetutorial.com/lucene-query-syntax.html)）。
VisualC++(MFC)で複数の引数から絶対パスを返す関数

MFCで、可変長引数を用いて絶対パスを取得する関数。
C++11以上で動作。Visual Studio 2013で動作確認。

> C++Builder版
> http://qiita.com/mm_sys/items/7633cb1b52788a533176

2017/06/01 マルチバイトとUNICODE両方使えるようにLPTSTRに変更。（今までTCHARのことをよくわかってなかった・・・）

```C++:C++11
#include <vector>
#include "atlpath.h"

#include <iostream>
// (省略)

template<typename ... Args>
CString JoinPath(const Args ... strs) {
	std::vector<CString>tmp_vector_str = { strs ... };
	CString tmp_path;
	if (PathIsRelative(tmp_vector_str[0])) {
		LPTSTR fileName;
		GetFullPathName(tmp_vector_str[0], MAX_PATH, tmp_path.GetBuffer(MAX_PATH), &fileName);
	}
	else {
		tmp_path = tmp_vector_str[0];
	}
	for (int i = 1; i < tmp_vector_str.size(); i++) {
		CPath path;
		path.Combine(tmp_path, tmp_vector_str[i]);
		tmp_path = static_cast<CString>(path);
	}
	return tmp_path;
}

// 使用例
printf("%S\n", JoinPath(L"1"));
// C:\(省略)\1
printf("%S\n", JoinPath(L"1", L"2", L"3"));
// C:\(省略)\1\2\3
printf("%S\n", JoinPath(L"C:\\",L"1", L"2", L"3"));
// C:\1\2\3

```
SharePoint検索APIでアクセス数ランキングを取得するURL

管理プロパティ : '**ViewsLifeTime**' がアクセス数っぽい

#Schema
```https://{Web-Url}/_api/search/query?querytext='path:https://{Target-Url} (IsDocument:True OR contentclass:STS_ListItem)'&sortlist='ViewsLifeTime:descending'&selectproperties='Title,Path,ViewsLifeTime'&RowLimit={Result-count}&trimduplicates=false
```

※ 以下は環境に合わせる
{Web-Url} : Url of SharePoint site
{Target-Url} : Url of Scope (Tenant or SiteCollection or Web or List/Library)
{Result-count} : Count of result limit

※ (IsDocument:True OR contentclass:STS_ListItem) を入れてるとリストアイテムとドキュメントに限定される。抜いたら全部のページが対象

※ その他にも色々指定可能
[SharePoint 検索 REST API の概要](https://msdn.microsoft.com/ja-jp/library/office/jj163876.aspx)


#example(All Tenant scope)
https://art365.sharepoint.com/sites/SpecialDevDept/_api/search/query?querytext='path:https://art365.sharepoint.com (IsDocument:True OR contentclass:STS_ListItem)'&sortlist='ViewsLifeTime:descending'&selectproperties='Title,Path,ViewsLifeTime'&RowLimit=20&trimduplicates=false
そもそもHTMLとXHTMLってなんだ ～そしてHTML5と交わる道～

HTML5の勉強を始めたけどどこからやればよいのかわからない。
それなら1から順番にやっていくしかない！
自分の言葉でまとめることで勉強になるのではないかなという忘備録。
細かい単語もそういえば知らない…となったりしては調べたりしているので、すごく寄り道が多いです。

#HTML5には2種類の文法があると聞きましたが

1.MIMEタイプ「text/html」で配信するHTML構文（通常のHTML構文）
2.MIMEタイプ「text/xhtml+xml」で配信するXHTML構文（XMLの仕様に従う）

HTML5はHTMLとXHTML用に2種類の文法があることはわかりました。

そこで。
**そもそも、HTMLとXHTMLって何が違うんだ？**という壁にぶつかりました。

#HTMLのなりたち
##Hyper Text Markup Language
**Hyper Text Markup Language (HTML)**
この頭文字をとって、「HTML」なんですね。
「ハイパーテキスト」とは、リンク機能の含まれた文書のこと。

###もともとは研究の情報やデータ閲覧のために生まれた言語
**Standard Generalized Markup Language (SGML)**
「HTML」の前身は「SGML」というマニュアル文章を閲覧・長期保管しやすくするためのマークアップ言語だったそうです。
そこにハイパーテキスト・リンクの要素が加わったのが「HTML」になっていきました。

HTMLとSGMLの関係についてはこちらでも。
[そもそもどうしてHTMLに装飾書いたらダメなの？～webの歴史を添えて～](http://qiita.com/NoxGit/items/99a7401c087c8d6888f1)

#HTMLとXHTMLってなんだ
ようやく本題に戻ってきました。
HTMLはわかったけど、**なんだそのXは！**
**かっこいいから付けちゃったのか！**

##XMLという存在
**eXtensible Markup Language**
1998年2月にW3Cで勧告が出された言語、**XML**。
**HTML**は**文書を保管・閲覧するための言語**でしたが、**XML**は**データを保管するための言語**。
XMLはデータとレイアウト・デザインを完全に分離し、データ保管のためだけの言語として発展しました。
**HTML**は**使用できるタグが決められている**のに対し、**XML**は**タグを独自で設定できる**拡張性に富んでいます。

##どっちもやってやるぜXHTML
そこで双方の良いところ取りをした言語……
**The Extensible Hyper Text Markup Language**
**XHTML**が生まれました。
**構文的にはXMLに完全適合**しながら、XMLの最大の特徴**独自タグ**が使えることに加え、**既存のHTMLタグの双方が使える**のが**XHTML**。
記述するうえでHTMLと異なるのは、エレメントや属性名に小文字を使う必要があります。

しかし、XHTML WG(XHTMLを開発していた機関)は2009年末に活動終了を発表しました。
XHTML2.0が事実上開発終了になりました。
ですがXHTMLが無くなったわけではありません。

#そしてHTML5と交わる道
**HTML5はXMLとして扱うことも可能。**
これが、HTML5が2種類の文法があるところへ繋がります。

HTML5では、**セクション**という概念が追加されました。
セクションを表すための専用要素 **section、article、aside、nav**の4要素です。
セクション以外にも、構造を示す要素として**header、footer、main、**その他に**figure、template、canvas**なども追加されました。

HTML4.01以前までは、見出しや段落を**div要素にclassやid属性を付加することでグループ化**していました。
そしてHTML5では、より**文書構造の役割に応じた要素が追加されました。**

今まで**\<div id="header">**とか**\<div class="entry">**とか書いていたのが**全て要素で書けるようになった**わけです。
コードもシンプルになる上、ブラウザや検索エンジンに対してより正確に文書構造を伝えられるようになったのです。


#所感とか
個人的な感想として、文書を保管するためのHTMLにデータを保管するためのXML(XHTML)的な要素が加わってきたのかな？と感じました。
文書構造にさらにデータ情報を付与し、マシンリーダブルに適しようとしているのかなーという印象です。
見た目だけではなく、アクセシビリティの面の強化が大きく感じられました。

あとは正直なところXMLとHTMLのメリットデメリットを上手く説明出来ないのがしっかりと理解ができていない感じがしますね…言葉にするのは難しい…

HTMLは文書構造を保管するための言語。
XMLはデータ構造を保管するための言語。
という感じであっているのかなぁ……

#参考サイト
[「HTML 4.01」と「XHTML 1.0」と「HTML5」の違いまとめ](https://www.flapism.jp/html/107/)

http://www.cybertech.co.jp/xml/contents/xmlxmldb/serial/_xmlbeginner5.php
http://www.sejuku.net/blog/6093
https://techblog.yahoo.co.jp/html5/html5/
Cognos レポートでY軸の範囲を指定して、範囲外のものはプロットを表示しない

##概要
レポートでY軸の範囲を指定できるものの、指定範囲を超えた場合に、以下のイメージのようにプロットだけを表示させなくした例です。

Y軸の範囲をユーザー自身で指定できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/2f8f1a3a-969e-ba29-1d5e-4bc9a8bbe5b8.png)

こんなイメージで、Y軸の範囲を超えたアイテムは、表示自体を消す(例：A03自体を消す)のではなく、図のようにプロットを消すという表現をします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/c6eca1b4-97ae-2cf3-a724-8506c824e64a.png)

##実装
・Y軸のデータアイテムcol2の定義
?pYH?はY軸の最大、それを超えるものは?pYH?から0.01引いた値に変換される。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/810d18a6-d0c1-5c34-3f40-40fb4096af4a.png)

・プロットの表示設定
プロットは以下のようにして、指定値より大きい場合は、条件パレットで透明にしている。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/147246/c2013eb0-5cf9-a991-0e4a-7a5affb16be0.png)

簡単な説明で恐縮ですが、同じ様な要件があった場合のヒントになればと思います。
[Azure] Application Insightでカスタムメトリクスを扱う手順

カスタムメトリクスと言えば Cloudwatch、と言われるほど(?)AWSでは運用監視でよく使われてる機能ですが、AzureでもApplication Insightで同じようなことができるのは余り知られていないかと思います。

以下に使い方を紹介します。

# 情報入手

情報入手といっても、Azure Portalのブレードにチュートリアルとサンプルが隠れています。

## サンプルの入手

Application Insightで「はじめに」→「カスタム メトリックとカスタム イベントでテレメトリを強化する」を選択します

「はじめに」がまず分かりにくい場所にあり、かなり下の方に配置されています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/00bc9b2a-18de-72a9-e01e-dd45f2191f9b.png)

「カスタムメトリックとイベントでテレメトリを強化する」に各言語のサンプルが置いてあります

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/63fbcee6-b1e9-a139-2153-b8595b22d6ec.png)

今回は、「フリガナ」という謎翻訳 [^1] を押すと出てくる、rubyのサンプルを使用してみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/36140a23-4463-ca74-7318-542a73208a6f.png)

# カスタムメトリクスを登録してみる

## キーの取得

メトリクスをputするためのキー(インストルメンテーションキー)を取得します。これはApplication Insightの「概要」で確認できます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/719ce6eb-1d01-b7bc-e963-1cd5e640066f.png)

## 取得したサンプルを元に、メトリクスをputするスクリプトを作成

今回は1から100までの乱数を生成し、確認のためAzureとAWSの両方にputしてみます。

````ruby:sample.rb
#!/usr/bin/ruby
require 'application_insights'

#1から100までの乱数を生成
r = rand(100)
random_number = r + 1

#[Azure]乱数をTestMetricとしてput
tc = ApplicationInsights::TelemetryClient.new '<ここにインストルメンテーションキーを入力>'
tc.track_metric 'TestMetric', random_number
tc.flush

#[AWS]乱数をTestMetricとしてput
aws_command = '/usr/bin/aws cloudwatch put-metric-data --region ap-northeast-1 --namespace AZURE_METRIC_TEST --metric-name TestMetric --value ' + random_number.to_s + ' --unit Count'
result = `#{aws_command}`

exit 0
```

あとはこのスクリプトを定期的に実行し、結果を確認します。

# 結果確認

Azure Portalでデータが取得できたか確認します。

「メトリックエクスプローラ」を選択すると、いくつかデフォルトのグラフが表示されているので、「編集」ボタンをクリックしてグラフを構成します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/c50c2db4-c43d-d9bc-006d-d6f4fdb488d7.png)

カスタムメトリクスが正常に送信されていれば一番下の「カスタム」に追加されているので、チェックしてグラフに追加します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/f44e751d-8654-30dc-a3fa-befa7b4ceffe.png)

あとはグラフの期間や統計の種類を変更すれば結果が確認できます。

- Azureで取得されたグラフ

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/e8240571-3d05-de10-ae9e-46809432d713.png)

AWS Cloudwatchのグラフと比較すれば、同じ値が送信されていることが確認できます。

<img width="550" alt="awsCloudwatch" src="https://qiita-image-store.s3.amazonaws.com/0/172826/86c7ea84-107a-67dd-4192-a0bd4cfa6b43.png">

以上でカスタムメトリクスの使い方が確認できました。Application Insightでは他にカスタムイベントなども扱うことができます。

Azureの運用系は基本的にOMS(Operations Management Suite)に集約される方向かと思われますが、まだまだ色々なサービスに分散していて場所が分かりづらいです。こういった機能も早くOMSで一元管理できるようにしてもらいたいです。

[^1]: なぜフリガナなのか、ruby → "ルビー" → "ルビ" → "フリガナ" という経路(?)で訳されたと予想される。いくらフィードバックしても直らないのもなぜなのか。
UnityWebRequestでもローカルファイルの取得ができる

Unityにおいて、従来のバージョンで使われていたWWWクラスと同様にUnityWebRequestでもローカルファイルの取得ができます。

例えばこんな感じ (C#, Unity5.4.4f1にて検証)

```
IEnumerator GetLocalFile(string filename){
    UnityWebRequest request = UnityWebRequest.Get ("file://" + Application.persistentDataPath + filename);
    yield return request.Send();
    if (!request.isError){
        //正常系処理
    }else{
        //エラー処理
    }
}
```

当たり前すぎるからかもしれませんが日本語で明確な記述が見当たらなかったので備忘録
システムの可用性とは

#システムの可用性
システムの可用性とは、システムが継続的に稼働できるということです。
ユーザーが使いたいと思える時に使えるかどうかということなので、サービス運用において重要な観点と言えます。

#意識すべきこと
システムの可用性が高いということは
・システムが壊れにくい
・復旧が早い
・耐障害性に強い
・常に作動している
ということです。
これらを満たしていると信頼性の高いシステムになります。

#可用性を高めるために
可用性を高めるためにはシステムの二重化を行うことが効果的です。
具体的には
・予備システムを準備して、冗長性（システムに余裕のある状態）を高める
・予備システムへの切り替えや、データのリストア時間を短縮する


システムを一つの流れに乗せないで二通りの流れを作っておくことで、予期せぬ自体が起きてしまっても二つ目の流れに切り替えて運用することができます。
システムを運用する時にはぜひ意識してみてください。
Sotaでカメラの調子が悪くて、Wifiを切り替えられない時

## 前提
edison版 Sota
sshでログインする

### Wifiの設定ファイルを直接編集する
sudo vi /etc/wpa_supplicant/wpa_supplicant.conf

### 下記の設定を追記し、他の設定のpriorityを1にする。

<pre>
network={
        ssid="SSID"
        scan_ssid=1
        psk="PASSWORD"
        priority=6
}
</pre>

Sotaを再起動すると、priorityが大きい方のネットワークに接続する。
homebrew-terraformの使い方。過去バージョンのterraform使いたい人向け

# 導入

## homebrew-terraformなにそれ？
pyenv、rbenvがpythonやrubyのバージョン管理、スイッチができるようにterraformのバージョン管理、スイッチを行なうためのものです。

## 出会い
terraformがバージョンごとに変更が激しいと風のうわさで聞く前に、間違って `homebrew upgrade` をしてしまった。
元のバージョンに戻したい。でも、homebrewじゃもう再インストール無理。

# 利点・欠点
## 利点
### Terraformのバージョンを変更できる
当たり前です。そのためのツールです。

### インストール済みのTerraformのバージョン一覧が見れる
pyenv、rbenvとかにもあるやつ。あるとたまに便利です。

## 欠点

### helpがない
helpコマンドを叩くとhelpになってないhelpが出て来る。泣きそう。

### ドキュメントがない
初期導入の流れまでしか載ってません。泣けてくる

### 使えるバージョンがわからない
すでに落としてるバージョンはわかりますが、まだ落としていないバージョンはわからないので、`homebrew-terraforms`のCasksを覗くか、Terraformの公式サイトで確認してください。
homebrew-terraforms: [使えるバージョン一覧](https://github.com/Yleisradio/homebrew-terraforms/tree/master/Casks)
terraform: [過去バージョン一覧](https://releases.hashicorp.com/terraform/)

### 環境変数がおかしい
バージョン管理の一部でhomebrew-caskを使ってるのですが、自分のhomebrew-caskと違うところが指定されてた。デフォルトの状態だとterraformをインストールするところまでしか動かなかった。
ハマった。

# 説明書
## 導入

1. tapを登録する
`brew tap Yleisradio/terraforms` を実行。独自tapを登録

2. chtr (homebrew-terraform) をインストール。
`brew install chtf`を実行

3. 環境変数`CASKROOM`のパスを修正
環境変数`CASKROOM`が、`/usr/local/Caskroom`になってました。
`brew cask install`のインストール先のディレクトリがこれと異なる場合は個々で設定が必要

4. chtrにパスを通す
以下を `.bashrc` や `.zshrc` にコピペ。

```
# Source chtf
if [[ -f /usr/local/share/chtf/chtf.sh ]]; then
    source "/usr/local/share/chtf/chtf.sh"
fi
```

## 使い方

### 使いたいバージョンを指定する
`chtf (使いたいバージョン)`
使いたいバージョンがローカルにない場合は自動でインストールされる

### インストール済みのバージョン一覧を取得
`chtf`

### 手動でインストールしたterraformに戻す
`chtf system`

### chtfのバージョン確認
`chtf --version` もしくは `chtf -V`

### 使えないヘルプ
`chtf --help` もしくは `chtf -h`
ちなみにこんなのが出る
`usage: chtf [VERSION | system]`

## Appendix

### 実行できないって言われたら

```
chtf: Installing Terraform version 0.8.8
Warning: A Cask for terraform-0.8.8 is already installed.

To re-install terraform-0.8.8, run:
  brew cask reinstall terraform-0.8.8
chtf: /usr/local/Caskroom/terraform-0.8.8/0.8.8/terraform not executable
```
安心してください。インストールはできてます。
環境変数`CASKROOM`をhomebrew-caskのインストール先に揃えてください。そしたら動くはず。

### ここまで読んでもらって何ですが...

[tfenv](http://qiita.com/kamatama_41/items/ba59a070d8389aab7694)のほうが良さげです。

`brew tap` もいらないようですし。
helpも親切ですし...
軽さこそ正義！！とか全部homebrew（&cask）で管理したいんだよ！！っていうひとが、homebrew-terraformを使ったらいいんじゃないかと思います
Google Mapsをhamlに埋め込む方法

GoogleMapを表示されたい！って思って色々調べていると`gmaps4rails`っていうgemがあるらしいんだけど、うまくいかなかった
https://github.com/apneadiving/Google-Maps-for-Rails

なので最低限のやり方として埋め込む方法をメモ。

1. 検索実行後のメニューをクリック
![〒719-1154_岡山県総社市井尻野１９６８_-_Google_マップ.png](https://qiita-image-store.s3.amazonaws.com/0/32902/a00ffda5-b93c-5fcf-15f9-3cbeba99698f.png)

2. 地図を共有または埋め込むをクリック
![〒719-1154_岡山県総社市井尻野１９６８_-_Google_マップ.png](https://qiita-image-store.s3.amazonaws.com/0/32902/60cf37f6-384c-6a07-1d6f-059cb7d0be19.png)

3. 表示したい大きさを選んでURLをコピーする
![〒719-1154_岡山県総社市井尻野１９６８_-_Google_マップ.png](https://qiita-image-store.s3.amazonaws.com/0/32902/da8d12e0-0beb-9982-7b4d-20af82081022.png)

コードはこちら。
そのままコピペすると、htmlの形式なので`%`付けて`()`で囲めばOK！

```haml
%div
  %iframe(src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3280.5500946428474!2d133.7318036152679!3d34.691302780436835!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x355154eaafef50f3%3A0x1eef346c53839b77!2z44CSNzE5LTExNTQg5bKh5bGx55yM57eP56S-5biC5LqV5bC76YeO77yR77yZ77yW77yY!5e0!3m2!1sja!2sjp!4v1494925004096" width="600" height="450" frameborder="0" style="border:0" allowfullscreen)
```
Flask にアップロードされたCSVファイルを保存せずに読み込む


公式ドキュメント [Uploading Files — Flask Documentation](http://flask.pocoo.org/docs/0.12/patterns/fileuploads/) などで `save()` メソッドでアップロードされたファイルをサーバー上に保存する手順は紹介されているものの、ファイルを保存せずそのまま読み込む方法がなかなか見当たらなかったため備忘録として残します。

### その実体はバッファリングバイナリストリーム

Flask で [`request.files.get()`](http://flask.pocoo.org/docs/0.12/api/#flask.Request.files) (または `request.files.getlist()[i]`) を実行すると、Werkzeug の [`datastructures.FileStorage`](http://werkzeug.pocoo.org/docs/0.12/datastructures/#werkzeug.datastructures.FileStorage) オブジェクトを得られます。このオブジェクトの `stream` こそがアップロードされたファイルのストリーム本体です。さらに `FileStorage.stream` は [`io.BufferedIOBase`](https://docs.python.jp/3/library/io.html#io.BufferedIOBase) を継承しているようなので、このストリームを煮るなり焼くなりすればよいみたいです。


### アップロードされたCSVを読む

もしアップロードされたファイルをテキストとして読みたい場合、[`io.TextIOWrapper`](https://docs.python.jp/3/library/io.html#io.TextIOWrapper) でテキストストリームにしてやると便利です。

クライアントからアップロードされたCSVをファイルを読み込むサンプルを示します。

```python
import io

from flask import Flask, jsonify, request


@app.route('/upload/', methods=['POST'])
def csv_upload():
    filebuf = request.files.get('csvfile')
    if filebuf is None:
        return jsonify(message='ファイルを指定してください'), 400
    elif 'text/csv' != filebuf.mimetype:
        return jsonify(message='CSVファイル以外は受け付けません'), 415

    text_stream = io.TextIOWrapper(filebuf.stream, encoding='cp932')
    for row in csv.reader(text_stream):
        # do something

    return jsonify(message=f'{filebuf.filename!r} を読み込みました'), 200
```
LINE BOT チュートリアル

## 準備

### LINE@アカウント作成

https://business.line.me/ja/services/bot

### BOT昨日を有効化

「LINE@MANAGER」 => 「アカウント設定」 => 「Bot設定」 => 「APIを利用する」 => 「Webhook送信を利用する」

### 必要なkeyを取得

Line developersにアクセスして、以下を控えておく。(かタブで開いておく)

- Channel ID
- Channel Secret
- Channel Access Token

* 後々 Webhook URL の設定が必要

## 実装

### rails new
 
```
$ rails new line-bot -d postgresql
$ cd line-bot/
$ rake db:create
```

### line-bot-sdk-rubyをインストール

`Gemfile`に追記して`bundle install`

```ruby
gem 'line-bot-api', github: 'stivan622/line-bot-sdk-ruby'
gem 'dotenv-rails'
```

### コントローラー作成

```
$ rails g controller linebot
```

### ルーティングを追加

`routes.rb`
```
post '/callback' => 'linebot#callback'
```

### linebot_controllerを編集

Usageを参考にアクションを作成

```ruby
class LinebotController < ApplicationController
  require 'line/bot'
  protect_from_forgery :except => [:callback]

  def callback
    body = request.body.read

    signature = request.env['HTTP_X_LINE_SIGNATURE']
    unless client.validate_signature(body, signature)
      error 400 do 'Bad Request' end
    end

    events = client.parse_events_from(body)
    events.each { |event|
      case event
      when Line::Bot::Event::Message
        case event.type
        when Line::Bot::Event::MessageType::Text
          message = {
            type: 'text',
            text: event.message['text']
          }
          response = client.reply_message(event['replyToken'], message)
          p response
        end
      end
    }
    head :ok
  end

  private
  def client
    @client ||= Line::Bot::Client.new { |config|
      config.channel_secret = ENV["LINE_CHANNEL_SECRET"]
      config.channel_token = ENV["LINE_CHANNEL_TOKEN"]
    }
  end
end
```

## Heroku

```
$ heroku create
$ git init
$ git add -A
$ git commit -m "first commit"
$ git push heroku master
```

```
$ heroku addons:create fixie:tricycle
```

`Proxy URL`と`Outbound IPs`を控える

### 環境変数の設定

```
heroku config:add FIXIE_URL='Proxy URL'
heroku config:add LINE_CHANNEL_SECRET='LineのChannel Secret'
heroku config:add LINE_CHANNEL_TOKEN='LineのChannel Access Token'
```

## Line developersの設定

#### Whitelistの設定
タブからServer IP Whitelist =>  Outbound Ipsを設定

#### Webhook URL を設定
https://{ご自身のherokuアプリ名}.herokuapp.com/callback

## 終わり
若手エンジニアがビジネス寄りの展示会で感じたこと(その１)

2017/4/27-28
新高輪プリンスホテルで行われたIBM Watson Summit 2017に出展企業として参加してきました。
準備～ブース説明員と関わり、その中での気づきを備忘録としてまとます。うちの展示内容や他社動向等の情報は載せません。
**展示会慣れしていない方、初めて展示会に出展者として参加する方向け**

#この記事の内容
1. イベント参加した率直な感想
2. イベント準備で必要な物品

#[IBM Watson Summit 2017](https://ibmevent.jp/event/watsonsummit2017/)とは
　文字通りIBMが主催しているイベントの一つである。
　IBMやパートナー企業によるセッション（講演）やブース展示が行われました。
　詳しくは[公式サイト](https://ibmevent.jp/event/watsonsummit2017/)をご覧ください。

#短時間で興味を引く
技術うんぬんの話よりも
自社で導入したときに「何ができるのか」「どれくらいのROIが見込めるのか」
がほとんどの話題であった。
「カネ」「時間」「メリット」という率直な問いに対して、
興味を惹かせ、その後の展開（打ち合わせ、商談）につなげていく力が求められる。

#知識レベルはまちまち
来場者の知識レベルはバラバラである。
紹介しているソリューションに含まれている技術の話になったのに
来場者の前提知識を見極めておかなければ、お互い満足いく展開にはならない。
実際、対応した来場者の所属している会社のIT導入状況を聞き逃し、
紹介するソリューション導入のステップをすっ飛ばしてしまった失敗がある。

#体力はあった方がいい
展示会となると１日中立ち続けることになる。
来場者はどんどんいらっしゃる、人手は足りない、休めないという
カオスな状況を乗り切るためには**体力**である。

長くなるので、記事を分割します。
その２では、あったほうが良い持ち物を紹介します。

 [その２へ](http://qiita.com/yan_hisa_/items/fd4563be33500eff44cc)
VimでGUIのコピー&ペーストと連携する

# VimでGUIのコピー&ペーストと連携する
Vimの標準のコピー&ペーストは独自のレジスタに行われますので、GUIのコピー&ペーストと連携は出来ません、が、一旦覚えてしまうととても便利な技だったので紹介。
## 新しい結論
デフォルトのレジスタを変更することで複雑な操作なしにGUIのクリップボードと連携出来ます。
相変わらずVimの `+clipboard` サポートは必須です。
### .vimrc
```vim
set clipboard& clipboard^=unnamedplus
```
こっちの方がいいですね。
## 結論
結論: レジスタ*を使う。
まずはレジスタ*が利用可能かどうかを確認しましょう。下記のコマンドを実行します。

```bash
vim --version | grep -q '+clipboard' && echo 'OK'
```
「OK」と表示されればレジスタ*は利用可能です。何も表示されない場合は

```bash
# 一番簡単な方法はGUI版Vimをインストールする
sudo apt-get install vim-gnome
```
を実行します。これでレジスタ*はOSのレジスタと連携していますので、 "\* の直後にコピー or ペースト操作を行うことでGUIと連携したコピーペーストが行えます。
### 例
|操作|キー入力|
|---|---|
|一行コピー|"*yy|
|直前にペースト|"*P|
|直後にペースト|"*p|
## オマケ: 他の手段
### 端末のコピー&ペーストを利用する
直接マウスで文字を選択して `Ctrl+Shift+C`/INSERTモードで `Ctrl+Shift+V` をする方法です。
コピーは問題ありませんが、ペーストはキー入力として一文字づつVimに送信されていますので、オートインデント機能が行が増すにつれて勝手にインデントを増やしてしまいます。
### `:a` もしくは `:a!` を利用する
(`:i` , `:i!` でカーソルよりも前に挿入)
末尾に `!` を付けることで挿入内容のオートインデントをすることが出来ます。場合によってはこちらの方が便利かもしれません。
Shinyアプリのローカル利用（RInno）

# 1. はじめに
　Rで作成したShinyアプリを共有するには、①Shiny serverを利用する。②RがインストールされたPCで実行してもらう等の方法が考えられます。しかしながら、どちらの方法もハードルが低くありません。
　今回は、"RInno"を利用して、一般のアプリケーションと同様にローカルにインストールしてShinyアプリを実行する方法を紹介します。（対象はWindowsのみです。）※1

# 2. RInnoのインストール
Rで以下の通り記述し、GUIでRInnoをインストールします。

```{r}
install.packages("RInno")
require(RInno)
RInno::install_inno()
```

# 3. アプリの準備
今回は、サンプルを利用して、ワーキングディレクトリにShinyアプリを準備します。

```{r}
example_app(app_dir = "app") 
```
ワーキングディレクトリにappというフォルダが作成されます。自分で作成したアプリをコンパイルする場合には、app.R、もしくはui.Rとserver.Rを含むフォルダをワーキングディレクトリに置いてください。

# 4. 設定
次に、`create_app`でアプリの設定を行います。

```{r}
create_app(app_name = "test_app",
           app_dir = "フォルダパス/app",
           include_R = T, # デフォルトはFなので、Tに変更
           R_version = 2.2.1, # 古いバージョンを利用する場合は指定 
           pkgs = c("xxxx", "yyyy"))

```
　配布する相手が、Rをインストールしていなかったり、特定のバージョンのアプリを使用する場合には、`include_R = TRUE`, `R_version = x.x.x`を指定します。また、`pkgs`で利用するパッケージを指定します。デフォルトでは、`pkgs = c("jsonlite", "shiny", "magrittr")`となっています。他にもパスワードプロテクションなどのオプションがあります。※1

　実行が終わると、appフォルダ内に色々なファイルが作成されます。（アプリのアイコンも置かれます。変更することも可能です。）

# 5. コンパイル
続いてコンパイルを実施します。

```{r}
compile_iss()
```
コンパイルが終了すると、appフォルダ内に、RInno_installerというフォルダが作成されます。

# 6. アプリのインストールと起動
　RInno_installerフォルダ内のtest_app.exeをダブルクリックすると、インストールが開始され、デスクトップ上にショートカットが作成されます。起動するとブラウザが立ち上がり、アプリが実行されます。
　~~終了は閉じるだけ？だと思いますが、Rscript.exeが起動したままになっているので、タスクマネージャーでプロセスを終了すると再度起動できます。いい方法があったら教えて下さい。~~

# 7. 追記（プロセスの終了）
　自作のShinyアプリの場合、Rを終了するコードを、server.Rの方に記述しておく必要があるようです。そうしないとブラウザを閉じた後、アプリが再起動できなくなります。

```{r}
shinyServer(function(input, output, session) {
  

  output$plot1 <- renderPlot({
         
          # 処理

      })
  
  # ここから追記
  # Close the app when the session completes
  session$onSessionEnded(function() {
    stopApp()
    q("no")
  })

}
```

# 参考
1. 「RInno - How to install local shiny apps」https://ficonsulting.github.io/RInno
C++Builderで複数の引数から絶対パスを返す関数

C++Builderで、可変長引数を用いて絶対パスを取得する関数。
IncludeTrailingPathDelimiter関数でパスが\か/かは環境によって変化する。
C++11以上で動作するので、
**プロジェクト->オプション->C++コンパイラ->'従来の'Borlandコンパイラを使用**
のチェックを外してfalseにする必要がある。

> Visual C++版
> http://qiita.com/mm_sys/items/aba7297f5589c6d174f0

```c++:C++11
#include <vector>
#include <IOUtils.hpp>
// 省略
template<typename ... Args>
UnicodeString __fastcall JoinPath(const Args ... strs) {
	std::vector<UnicodeString>tmp_vector_str = {strs ...};
	UnicodeString tmp_path;
	if (TDirectory::IsRelativePath(tmp_vector_str[0])) {
		tmp_path = ExpandFileName(tmp_vector_str[0]);
	}
	else {
		tmp_path = tmp_vector_str[0];
	}
	for (int i = 1; i < tmp_vector_str.size(); i++) {
		tmp_path = IncludeTrailingPathDelimiter(tmp_path)
			+static_cast<UnicodeString>(tmp_vector_str[i]);
	}
	return tmp_path;
}
// 使用例
JoinPath(L"1");
// C:\(省略)\Win32\Debug\1

JoinPath(L"1",L"2",L"3");
// C:\(省略)\Win32\Debug\1\2\3

JoinPath(L"C:\\",L"1",L"2",L"3");
// C:\1\2\3
```
RubyでTempfileを使う際の注意

一時ファイルを生成するために

```ruby
tempfile = Tempfile.open(...) do |f|
  ...
  ...
  f.write
end

(...tempfileを使った処理...)
```

といったコードがありました。

このコード、だいたいの場合問題なく動くのですが、たまに作成したはずの一時ファイルがないと怒られることがありました。

実は `Tempfile` オブジェクトは自身への参照がなくなり、ガベージコレクションされた際に一時ファイルを削除する仕組みがあります。実はさきほどのコードでは `Tempfile` のオブジェクトへの参照が `Tempfile#open` のブロックを抜けるタイミングでなくなってしまっていたのです。

変数 `tempfile` があるじゃないか、と思うかもしれませんが実はこれ `Tempfile` のオブジェクトではないのです。

[ドキュメント](https://docs.ruby-lang.org/ja/latest/class/Tempfile.html)を見ると、

> Tempfile オブジェクトはFileクラスへのDelegatorとして定義されており、Fileクラスのオブジェクトと同じように使うことができます。

とありますが、 `File` クラスで定義されているメソッドを使うと `Tempfile` ではなく `File` のオブジェクトが返ってくるようです。( `#close` `#flush` `binmode` などなど) `Tempfile#open` にブロックを渡した場合の戻り値はブロックの戻り値であるため、 `tempfile` には `File` オブジェクトがはいってしまいます。

このため、GCが走ると作成された一時ファイルは削除される状態になっているのです。
当然Fileオブジェクトを通じてその一時ファイルにアクセスしようとしても、「そんなファイルはないよ」と怒られてしまうのです。

なので、さきほどのコードは次のように直す必要があります。

```ruby
tempfile = Tempfile.open(...) do |f|
  ...
  ...
  f.write
  f // <- Tempfileオブジェクトを返す
end

(...tempfileを使った処理...)
```

ちなみに、 `Tempfile` には `create` というメソッドがあります。こちらはブロックを渡すとブロックの中で一時ファイルを使用した処理を行い、ブロックを抜けたらすぐ一時ファイルをクリアするというものです。

```ruby
Tempfile.create(...) do |tempfile|
  (tempfileを使った処理)
end
```

こちらを使う設計になっていたほうが、いつ起きるかわからないGCに依存せず、一時ファイルの生存期間を厳密に管理できます。新規に設計を行う場合は、こちらを積極的に使うべきでしょう。

# 参考

[Ruby の Tempfile で発生した競合状態の原因を探る](http://labs.timedia.co.jp/2015/06/ruby-tempfile.html)
スマフォカメラにブラウザからアクセス


nodeのhttp-serverを利用して，スマフォブラウザ（Chrome）からカメラ映像を取得します
スマフォブラウザからカメラを利用するときはsslじゃないとだめらしいです
環境できている人なら以下のリンクで一発
http://stackoverflow.com/questions/35127383/npm-http-server-with-ssl


# 使用技術
・webRTC
今回は意識しなくていいでしょう
興味があれば途中あるリンクを読んでみてください
スマフォではAndroidのChromeのみだそうです

・ssl
スマフォのブラウザでカメラを利用するには，ssl(https)じゃないとだめらしい

・node, http-server
httpsサーバーを利用するのには色々やり方がありますが，今回はnodeで，それもhttp-serverを利用します
nodeのインストール方法などに関しては，他の記事を参考にしてください
http-serverの説明などは途中リンクにて


## 環境
・MacBookAir 10.10.5
・node v7.4.0
・npm 4.5.0
・http-server 0.10.0


# まずはPCブラウザでカメラ映像取得

そもそもブラウザでwebカメラ等を利用するときには，htmlファイルなどはサーバ上じゃないとだめ
今回，サーバはnodeでローカルマシーンにて構築します
ブラウザはChrome推奨（てかそれしか確認してないです）

## http-serverインストール
参考：Node.jsのhttp-serverっていうコマンドラインのウェブサーバーが便利
https://firegoby.jp/archives/5706

これの通りに行えばできました
使用したコマンド一覧

```
$ npm install -g http-server
```

```
$ http-server
```

その後ブラウザでlocalhost:8080にアクセス


## カメラの利用
> 2019年6月26日
サンプルコードが動かなくなっていたので編集しました

参考：[それWeb]ブラウザからデバイスのカメラを通して動画を録画する
https://qiita.com/niisan-tokyo/items/fa6ff649a9a3312148bc

```html:cam.html
<!doctype html>
<html>
 <head>
  <title>Self Camera</title>
 </head>
 <body>
   <video id="myVideo" width="400" height="300" autoplay="1" ></video>

   <script type="text/javascript">
    var video = document.getElementById("myVideo"); // 適当にvideoタグのオブジェクトを取得
      var constrains = { video: true, audio: true }; // 映像・音声を取得するかの設定
      navigator.mediaDevices
        .getUserMedia(constrains)
        .then(function(stream) {
          video.srcObject = stream; // streamはユーザーのカメラとマイクの情報で、これをvideoの入力ソースにする
          video.play();
        })
        .catch(function(err) {
          console.log("An error occured! " + err);
        });
   </script>
 </body>
</html>

```


こちらに書いてある一番上のサンプルをいただきました
それをhttp-serverのコマンドを実行したフォルダに保存
http://localhost:8080/（保存したファイル名）
この場合は，http://localhost:8080/cam.html
で見れると思います

# スマフォでカメラ映像取得

前述の通り，スマフォのブラウザでカメラを利用するには，ssl(https)じゃないとだめらしい

## ssl鍵の作成
参考：npm http-server with SSL
http://stackoverflow.com/questions/35127383/npm-http-server-with-ssl

http-serverのコマンドを実行したフォルダにssl鍵を作成します
使用したコマンド

> 追記
全部エンターだとcert.pemができなかったので
Country Nameのときに「jp」とかいれればできました

```
$ openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
```

その後，エンター何回か押す
すると，key.pemとcert.pemができるはず

## http-serverでhttpsサーバ

参考：npm http-server with SSL
http://stackoverflow.com/questions/35127383/npm-http-server-with-ssl
（ssl鍵作成のときと同じリンク）

使用したコマンド

```
$ http-server -S -C cert.pem
```

PCブラウザでまずは確認
https://localhost:8080/cam.html

![スクリーンショット 2017-05-16 16.25.48.png](https://qiita-image-store.s3.amazonaws.com/0/76572/c59150f9-2803-47b5-17f7-96d4aa6aa440.png)

下の（安全ではありません）をクリック
で，見れるはず！

## スマフォのChromeでカメラ
PCと同じwifiにスマフォもwifiを接続してください

PCでifconfigでPCのIPアドレス確認
例：192.168.10.10など

スマフォ（Android）のブラウザ（Chrome）にてhttps://192.168.10.10(例):8080/cam.html

で，見れるはず
今回，使用技術を探すのが時間かかりましたが，一つ一つの作業はスムーズにいきました

その他，ポート開放しっぱなしになってしまったときこちらを参考にしました
http://qiita.com/yokozawa/items/dbcb3b31f9308e4dcefc
JavaFXのテキスト

JavaでFXMLアプリを開発するために色々と調べ物をしながらテキストにしたものです．
うちのゼミ生たちと一緒にAPIの使い方とアプリの組み方を調べた情報をまとめました．
　
Java FX SceneBuilderに関する記述はちょっと古くなっていますが，基本的には最新の「Gluon SceneBuilder」でも通用すると思います．

[テキスト本体](http://www.k-techlabo.org/www_java/JavaFXtext.pdf)
　
NetBeans IDE + SceneBuilder でFXMLアプリを作る方法について書いています．
まだEclipseでの開発方法については触れていませんが，とりあえずJavaの新しいAPIの基本について解説しています．
　
無料で公開しますので，ご意見いただけたら嬉しいです．
　
－－－－－－－－－－－－－－－－－－－－－
##更新に関することなど

【補足】(2018/10/26)
　ORACLE曰く，JavaFXは将来的にサポートしなくなるとか…
心配ですね．
Linuxで英語キーボードのAltを変換・無変換にする

# 概要
Debian 上の Emacs でAltキーで日本語入力のオンオフをするために xcape というツールを導入して、右Alt 空打ちを「変換」、左Alt空打ちを「無変換」キーとなるようにした。

# やりたかったこと
ノートパソコンを新しくするときになんとなく英語キーボードを選んでしまった。日本語キーボードのときは「変換」キーと「無変換」キーで日本語入力をオンオフしていた。Windows だと[alt-ime-ahk] (http://www.karakaram.com/alt-ime-on-off) という素晴らしいソフトで Alt キー空打ちで日本語入力を切り替えることができた。これを Linux とかでも実現したい。

# やったこと
## Fcitx
Fcitx だと、「設定」ー「全体の設定」で「拡張オプションの表示」のチェックボックスをチェックすると入力メソッドのオンとオフにそれぞれ右Alt と左Altを設定できる（ついでに入力メソッドのオンオフも Alt-` に変更しておくのがすすめ）。Fcitx を使う場面では、これでOK。かんたん。

FireFox を使うなら Alt キーでメニューが出ないようにすると使いやすい。[ここ](https://www.crestboz.co.jp/techblog/archives/126/)とか参照。


# Emacsのために
でも、Emacs はFcitx は使わないから（だってインライン入力できないんだもん）、このままではダメ。

そこで google 先生に聞いたところ、xcape なるツールをつかうとできそうなことがわかった。
修飾キーの空打ちを別のキーにしてくれるツールらしい。


## xcape導入
Debian とか Ubuntu だとパッケージがある。

```shell-session
$ apt-get install xcape
```

さくっとインストールした。キーコードがわからないと設定できないので、

```shell-session
$ xmodmap -pke |grep Alt
```

などとして右Altや左Altのキーコードをしらべておく。そして xcape の設定。

```shell-session
$ xcape -e '#64=Muhenkan;#108=Henkan_Mode'
```
左Altがキーコード64、右Altがキーコード108、「無変換」は「Muhenkan」、「変換」は「Henkan_Mode」（なぜが Mode がつく）だった。

これを実行すると常駐してキーを監視してくれる。これで Alt キーの空打ちは「変換」「無変換」、何かのキーと一緒に押せばちゃんと修飾キーとしてき働く(M-xとか)。すばらしい。

## Emacs の設定
mozc.elを使う。何もしないと何も起きないっぽいので、[こちら](http://d.hatena.ne.jp/Nos/20120317/1331985029)からありがたくコードを頂戴して init.el にコピペ。

めでたく、右Alt と 左Alt で日本入力をオンオフできるようになりました。

# あとがき
Debian とか楽ちんですね。

あ、xcape はログイン時に自動的に動かしたいですね。そこはうまいこと設定してください。
Unity iOSのビルドをJenkinsで自動化

# 概要
UnityのiOSのビルドがとにかく時間がかかる
なのでビルド専用macを作って、それにビルドさせて、ipa作成までの最小構成をまとめる

# 詳細
## ビルド環境
- Unity 5.6
- Xcode 8.3.2
- Jenkins

## ビルド手順
### Jenkinsインストール
```shell-session
$ brew install jenkins
```
### Jenkins起動
```shell-session
$ brew services start jenkins
```
ブラウザを開き
```
localhost:8080
```
でJenkinsの起動を確認

### JenkinsにUnity3DBuilderプラグインをいれる
Jenkinsの管理 > プラグインの管理からUnity3d pluginをインストール
![スクリーンショット 2017-05-16 15.23.45.png](https://qiita-image-store.s3.amazonaws.com/0/178684/fdab424a-9836-c5a5-503d-8d9b9253a408.png)

### fastlane install
このマシンでだけfastlaneを使うこと前提

```shell-session
$ brew cask install fastlane
```

### ジョブの作成
- TOP画面で新規ジョブ作成
- 対象リポジトリ入力
- ビルド手順追加(unity)
    - unityがインストールしてある場所指定
    - unityをCLIでcall
    - ビルドスクリプトについては以下の記事参照  http://qiita.com/unsoluble_sugar/items/a268b6c38d9603d871da
- シェルスクリプト追加で以下のスクリプト追加  

```shell-session
fastlane gym
```

こんな感じ
![スクリーンショット 2017-05-16 15.37.31.png](https://qiita-image-store.s3.amazonaws.com/0/178684/c6adfb16-8c49-d239-9c6c-28a64c6cbc9e.png)

### ポイント
- UnityのiOSのPlayer SettingsでAutomatic Signing Team IDで自分のアカウントのIDを設定しておく（Apple Developerで確認できる）

### 課題
- どのタイミングでビルドを回すようにするか？