OmniAICreator/Qiita-1.07M huggingface dataset:
elastalertを利用したslackへのアラート

elastalertを利用するにあたりはまったところと、工夫したところをまとめました。:bow:

#[elastalert](https://github.com/Yelp/elastalert)とは
ElasticSearchに送ったログなどを監視してアラートを投げてくれるやつ
メールとかslackなどなど

#はまったところ
気がつけば簡単なのに気がつくまでが一苦労・・・(ノД`)とほほ･･
## elastalert-create-indexが実行できない

```
Traceback (most recent call last):
  ・・・
pkg_resources.DistributionNotFound: botocore
```

create_index.pyを直接実行すれば良い

```
python elastalert/elastalert/create_index.py
```


## elastalert-test-ruleが実行できない
elastalert/elastalert/test_rule.pyを実行すれば良いと思ったら、それも怒られた。

```
Traceback (most recent call last):
  File "elastalert/elastalert/test_rule.py", line 20, in <module>
    import elastalert.config
ImportError: No module named config
```

ファイルをコピーさせてから実行する

``` 
cp elastalert/elastalert/test_rule.py elastalert/
python elastalert/test_rule.py elastalert/rules/xxx.yaml
```

##supervisordで実行されない
原因はconfig.yamlに書いたrules_folderのパスがsupervisordが実行する場所からは見れない
####対策１
config.yamlに書いたrules_folderを絶対パスにするか

```config.yaml
rules_folder: /elastalertがインストールされているディレクトリ/rules　
```
####対策２
supervisordに登録するプロセスにdirectoryを追加する

```ini
directory=/elastalertがインストールされているディレクトリ/
```

#工夫したところ
##kibanaへのリンクを付けた
ログを全てSlackに流すわけには行かなかったため、ダッショボードとログへのkibanaのリンクが欲しかった
alert_subjectを利用する

```yaml:ruleファイル
use_kibana4_dashboard: http://kibana/app/kibana#/dashboard/applog
alert_text_type: exclude_fields
alert_subject: エラーが発生しました。（<http://indexとtypeとidをつかってログへのリンクを組み立てる/{0}/{1}/?id={2}|LogDetail> | <{3}|DashBoard>）
alert_subject_args: 
  - _index
  - _type
  - _id
  - kibana_link
```
なお`alert_text`はエスケープ処理されるためリンクは作れなかった
sqlplusでbashのCtrl-pとかを使えるようにする


rlwrapを入れるとsqlplusでbashの履歴(Ctrl-p, Ctrl-nなど)や、カーソル移動(Ctrl-a, Ctrl-eなど)、
文字列操作(Ctrl-k, Ctrl-yなど)が使えるので操作が楽になる。

以下、インストール方法。

## rlwrapインストール
1. EPEL(拡張パッケージ)インストール

```shell-session
# wget http://www.mirrorservice.org/sites/dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm 
# rpm -Uvh epel-release-6-8.noarch.rpm
```
EPELのダウンロード先は以下からバージョンにあったものを探す。
https://fedoraproject.org/wiki/EPEL/ja

2. rlwrapインストール

```shell-session
# yum install rlwrap
```

3. エイリアス設定

```shell-session
# su - oracle
$ vim .bash_profile
alias sqlplus='rlwrap sqlplus'
alias rman='rlwrap rman'
```

## 参考にしたサイト
https://oracle-base.com/articles/linux/rlwrap
RubyでBigQueryから簡単にデータを取得する 2017年1月最新版

# はじめに
みなさんGoogleのBigQuery使ってますか？とても便利なので[こちら](http://tech.vasily.jp/entry/multi_cloud_machine_learning_architecture)の記事でも紹介させて頂いたように弊社でもほぼ全てのデータをBigQueryに入れて分析しています。

RubyからBigQueryを扱うGemは以前からいくつか存在しているのですが、現状の最新(2017年1月時点)ではどう扱うのが一番良いのかをまとめておきます。

# BigQueryを扱えるGem達
## abronte/BigQuery
Googleで検索すると一番上に出てくるのでこのGemを利用している人も多いと思います。
しかし、2016年になってからあまりメンテされている様子はありませんので、利用は控えたほうが良いでしょう。

## google/google-api-client-ruby
こちらのGoogleが提供している[google-api-client-ruby](https://github.com/google/google-api-ruby-client)を最新版にしてBigQueryのインターフェースを直接利用することも出来ますが、ドキュメントもサンプルコードもほぼありませんので、ソースをひたすら読んで実装する必要があります。あまりおすすめできません。

## GoogleCloudPlatform/google-cloud-rubyを使う(推奨)
実はGoogleがBigQueryを扱うためのGem`google-cloud-bigquery`を半年ぐらい前にリリースしてくれています。(google-api-clientとは別に)
GoogleのCloud関連のAPIを呼ぶための`google-cloud`というGemの一部です。

```
gem install google-cloud-bigquery
```

こちらは公式ドキュメントやサンプルコードも全て用意されています。
そしてgoogle-api-clientも最新のバージョンに対応しています。

https://cloud.google.com/bigquery/docs/reference/libraries#client-libraries-install-ruby

こちらのGemのほうが極めてシンプルですし、Googleもこちらの利用を推奨しています。

# google-cloud-bigqueryを用いたサンプルコード
## 同期的にデータを取得する
結果のサイズが10MB以下であればこちらで取得できます。

```sync.rb
require "google/cloud/bigquery"

bigquery = Google::Cloud::Bigquery.new(
  project: "test-project", #BigQueryのプロジェクトID
  keyfile: "./auth.json" #認証用JSONキーファイル
)

sql = "select id from app.items limit 1000"
data = bigquery.query sql

puts data.count

data.each do |row|
  puts row["id"]
end
```

## 非同期でデータを取得する
クエリの実行に時間がかかる場合などはこちらを利用しましょう。

```async.rb
require "google/cloud/bigquery"

bigquery = Google::Cloud::Bigquery.new(
  project: "test-project",
  keyfile: "./auth.json"
)

job = bigquery.query_job sql

job.wait_until_done!

unless job.failed?
  puts job.query_results.size
  job.query_results.each do |row|
    puts row["id"]
  end
end
```

めんどくさい処理は必要ありません、非常にシンプルでわかりやすいインターフェースになっています。

## 大きい結果サイズを扱う場合
`query_job`の引数に`large_results:true`や`table`を設定する必要があります。(この場合は`table名`ではなく`tableオブジェクト`なので注意)

```large_result.rb
dataset = bigquery.dataset "tmp"
result_table = dataset.create_table "results"
sql = "SELECT id from app.items limit 110001"

job = bigquery.query_job(sql, table: result_table, write: 'truncate', large_results: true)

```

## StandardSQL対応は？
`google-cloud-ruby`も丁度先月@yancyaさんのコミットがマージされたことにより、Standard SQLのサポートがされたので、Standard SQLを利用することができます。

```standard_sql.rb
sql = "select FORMAT_TIMESTAMP('%Y-%m-%d %H-%M-%S', CURRENT_TIMESTAMP, 'Asia/Tokyo') as t"

data = bigquery.query sql, legacy_sql: false #use_legacy_sqlでないことに注意
puts data
```

# まとめ
RubyからシンプルにBigQueryを扱いたい場合は`google-cloud-bigquery`を利用しましょう。
ORACLEの従来型エクスポート/インポートは非推奨。Oracle Data Pump が高速。

---
# ORACLE DATABASE の従来型エクスポート/インポート
---
従来型コマンドである EXP / IMP コマンドの方が、一般に知られている。（最新の某SQLリファレンス本にも古い従来型コマンドが紹介されている）
従来型コマンドには以下の特徴がある。
・ユーザープロセスで実行される
・コマンドとして取り回しがしやすい
・『警告』時の戻り値がゼロ（UNIX系）
・ORACLE 10g 以降からは『非推奨』とされている（案外と知らない人がいる）

---
# Oracle Data Pump テクノロジー
---
ORACLE 10g 以降から推奨されているエクスポート/インポート ( EXPDP / IMPDP ) 機能。
以下のような特徴がある。
・Oracleサーバープロセスとして実行される
・対象ファイルの格納ディレクトリを『ORACLEオブジェクト』として定義する必要がある（シェルスクリプト等の中からパス指定ができない）
・対象ファイルの格納ディレクトリの書き込み権限がORACLEプロセス側から書き込み可能になっている必要がある
・ORACLE公称で従来型よりも、エクスポートで2倍以上、インポートで10数倍 - 数10倍、高速である
・戻り値：正常時ゼロ、成功だがエラー（おそらく警告）時5、異常時1

---
# 参考リンク
---
[Oracle Database ユーティリティ](http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/server.102/B19211-01/dp_overview.html)

---
# 備考
---
今回は、とりあえず備忘録としてメモ。筆者の職場でも従来型コマンドしか知らないメンバーが、ORACLE 11g で開発を完了させていた例があった。
実際に、新しい（と言っても10gからあったが）コマンドでスクリプトを作り替えてテストをしてみたところ、エクスポートでも10倍以上、処理時間が高速になった。
D3.js (v4.x)  forceSimulation with Canvas

数年ぶりに D3.js の forceLayout を使おうと思ったらメジャーバージョンアップでいろいろと変わっていたので備忘録を兼ねたメモを残します。

# シナリオ

* 時間とともにノード、リンクが増えていく無向グラフを実装
* レンダリングには Canvas を使う
* ノードのドラッグで干渉できるようにする
* Canvas のリサイズにも追従

# デモ

こちらから。 毎秒ノード／リンクが追加されていきます。
<https://bl.ocks.org/frogcat/a06132f64b7164c1b1993c49dcd9178f>

![image](https://qiita-image-store.s3.amazonaws.com/0/82494/c1de0eb7-6857-c503-4ec8-59b03edefdb0.png)

# 感想

* tick ごとに Canvas の再描画をするような実装
* SVG 固有の enter/exit みたいなことを考える必要がないのでその点は楽
* たぶん速度的には Canvas のほうが有利なんだろう
* ノードのドラッグは 公式の [Force Dragging III](http://bl.ocks.org/mbostock/ad70335eeef6d167bc36fd3c04378048) をコピペしてどうにか
* `forceSimulation.find(x,y,radius)` を使うことでマウスポインタとノードの当たり判定をやっているようだ
* リンクへの当たり判定なんかは難しいかも
* 有向グラフにする場合は Canvas でがんばって Arrow Head を書けばいいのでなんとかなるのではないか （SVG だと marker 使ったりとか逆に選択肢が多くて悩む）
* この目的だとそもそも <http://sigmajs.org/> でいいんじゃね？という疑問は常につきまとう


# 参考

* <https://github.com/d3/d3-force>
* <http://bl.ocks.org/mbostock/ad70335eeef6d167bc36fd3c04378048>
Python 1.0 をビルドする

ちょっとした考古学的興味により初期のPythonを調べてみたくなったので、Python 1.0.1 をビルドして動かしてみた。

# プログラミング考古学シリーズ

* **第1回: Python 1.0 をビルドする**
* 第2回: [Ruby 0.49 をビルドする](https://qiita.com/hakatashi/items/997afabc28c254639efe)
* 第3回: [Perl 1.0 をビルドする](https://qiita.com/hakatashi/items/5c41b3835814e13a7b6a)

# ソースコード入手

現在[Pythonの公式ページ](http://legacy.python.org/download/releases/src/)から手に入る最も古いソースコードは、Python 1.0.1 である。これはPythonの開発が始まった1989年12月からすでに5年近く経過した1994年にリリースされたものである。[README](http://legacy.python.org/download/releases/src/README)によると、

> Older sources
> =============
> 
> If you find an older Python release (e.g. 0.9.8), we're interested
> in getting a copy!  webmaster@python.org

とあるので、これ以前のバージョンはデータが失われてしまったものと思われる。1989年といえばGitもSVNもCVSもなかった時代なので致し方なし。

ダウンロードして解凍する。

```
$ curl http://legacy.python.org/download/releases/src/python1.0.1.tar.gz -O
$ tar xzf python1.0.1.tar.gz
$ cd python-1.0.1
```

# ビルド

tarballの中には`configure`や`Makefile.in`などが入っており、ビルド手順は現代と全く変わらない。

ただし、内部で使われている関数`getline`が現代の標準ライブラリと衝突するので、名前を置き換えてやる必要がある。

```
$ sed -i 's/^getline/my_getline/' Objects/fileobject.c
$ sed -i 's/ getline/ my_getline/' Objects/fileobject.c
```

あとはいつも通りにビルドすればOK。

```
$ ./configure
$ make
```

# 動かしてみる

出てきたバイナリファイル`python`で適当に遊んでみる。

```py
$ ./python
Python 1.0.1 (Jan 11 2017)
Copyright 1991-1994 Stichting Mathematisch Centrum, Amsterdam
>>> hex(12345678901234567890)
OverflowError: integer literal too large
>>> hex(12345678901234567890L)
'0xAB54A98CEB1F0AD2L'
>>> int('100')
Traceback (innermost last):
  File "<stdin>", line 1
TypeError: int() argument can't be converted to int
>>> int(1.5)
1
>>> def fibonatti(n):
...     if n == 1 or n == 2:
...         return 1
...     else:
...         return fibonatti(n - 1) + fibonatti(n - 2)
...
>>> fibonatti(5)
5
>>> o = {'foo': 1, 'bar': 'baz'}
>>> o
{'foo': 1, 'bar': 'baz'}
>>> for i in range(5):
...     print(i)
...
0
1
2
3
4
>>> range(100)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> [i * 2 for i in range(10)]
/home/esolang/python: line 3:     7 Segmentation fault      ./python
$
```

だいぶ機能は足りないが、現代のPythonとほぼ同じように使える。

# 次回

[Ruby 0.49 をビルドする - Qiita](https://qiita.com/hakatashi/items/997afabc28c254639efe)


# 参考文献

* [History of Python - Wikipedia](https://en.wikipedia.org/wiki/History_of_Python)
ちょっとした正規表現のおはなし　前編

#プロローグ
昔々、Twitterと呼ばれる所に、ゆら、もやさん、そしてゆらの取り巻きがおりました。   
いつも、ゆらが何かをすれば、取り巻きはこう言います。
*「ゆらちゃんかわいい」*
そんなある日、もやさんはこう言いました。
*「『ゆらちゃんかわいい』と言う人達を懲らしめよう
　ゆらは私の物だ。」*
それから、彼は取り巻きを懲らしめようとするのでした... (やっているとは言ってない)

#本題
最後のもやさんの一言の前半を私がJavaの正規表現でやります。
参考: http://www.javadrive.jp/regex/  
他の言語の正規表現には触れません。
    
##はじめに
まず、「ゆらちゃんかわいい」(以下A)を2つに分割して考えましょう。
「ゆらちゃん」(以下B)「かわいい」(以下C)とします。

##複雑な日本語
日本語は複雑です。
同じ「あ」でも、「ア」「ｱ」など、仮名文字だけでもいくつかあります。
同じ読みの漢字には対応しないとして、BとCをこれに対応させましょう。
[これ](http://www.javadrive.jp/regex/char/index1.html)を使えば、こうできます。
B=`[ゆゅユュﾕ][らラﾗ][ちチﾁ][やゃヤャﾔｬ][んンﾝ]`
C=`[かカヵｶ][わゎワヮﾜ][いぃイィｲ][いぃイィｲ]`
Cについては、「い」は必ず2連続するので、[これ](http://www.javadrive.jp/regex/repeat/index6.html)を使って短縮します。
C=`[かカヵｶ][わゎワヮﾜ][いぃイィｲ]{2}`
これでいいでしょう。

##言葉の倒置
正規表現は、先頭、末端の指定が無ければ、基本的には前後の関係は文字列として連結すれば合成することができます。
例えば、`B+C`であれば、「ﾕﾗﾁｬﾝｶﾜｲｲ」は100%引っ掛かります。
ですが、こう言ったらどうでしょうか。
「**かわいい**よ**ゆらちゃん**」
倒置されたら難しくなりそうです。
ここで、[これ](http://www.javadrive.jp/regex/repeat/index1.html)と[これ](http://www.javadrive.jp/regex/repeat/index3.html)を使って、新たにDを定義しましょう。
D=`.*`
`D`は、適当な0文字以上の文字列に引っ掛かります。(つまり無くても引っ掛かります)
これを使えば、先程の倒置は`C+D+B`で対応できます。
「ゆらちゃんはかわいい」でも、`B+D+C`で対応できます。

##正規表現の合成
最後に、複数の正規表現を一つにまとめましょう。
と思ったら、今度はこんな言い方をする人が現れました。
*「ゆらゆらかわいい」*
これにも対処しましょう。
「ゆら」自体は既に正規表現を作ってあるので(`[ゆゅユュﾕ][らラﾗ]`)、これをBに合成します。
ではどうするのでしょうか
Bの「ちゃん」の部分を「ゆら」でも引っ掛かるようにします。
ここで、[候補](http://www.javadrive.jp/regex/select/index1.html)を使って合成します。
B=`[ゆゅユュﾕ][らラﾗ]([ちチﾁ][やゃヤャﾔｬ][んンﾝ]|[ゆゅユュﾕ][らラﾗ])`
できました。
    
それでは本題に戻りましょう。
`B+D+C`と`C+D+B`を同時に検索できる正規表現となるよう、先程の方法で合成します。
長くなってしまいますが、こうなります。(以下E)
E=`([ゆゅユュﾕ][らラﾗ]([ちチﾁ][やゃヤャﾔｬ][んンﾝ]|[ゆゅユュﾕ][らラﾗ]).*[かカヵｶ][わゎワヮﾜ][いぃイィｲ]{2}|[かカヵｶ][わゎワヮﾜ][いぃイィｲ]{2}.*[ゆゅユュﾕ][らラﾗ]([ちチﾁ][やゃヤャﾔｬ][んンﾝ]|[ゆゅユュﾕ][らラﾗ]))`
つよそう
恐らくこれで大体の「ゆらちゃんかわいい」は見つけられるでしょう。多分。

#名前のご協力を頂いた方々
もやさん: [Twitter](https://twitter.com/M0_83)
ゆら: [Twitter](https://twitter.com/Aqcla)
ありがとうございます。
#最後に
ゆらちゃんかわいい
~~文章下手でごめんなさい~~
後編は[こちら](http://qiita.com/nao20010128nao/items/a37f8eee1a1271bddf53)へ
処理速度比較 PHP vs Node.js

# 概要
結構な数のループ処理を書くことになり、当初PHPで書いていたのですがあまりに遅く、、、
PHPでも処理を早くする書き方など色々と調べたのですが、最終的に言語を変えてNode.jsを使ったらだいぶ早くなったのでそれをまとめます。

# PHP vs Node.js
約50万×100のループ

|node.js(6.9.1)|2.605220秒|
|:--|:--|
|PHP(7.0.12)|25.499058008194秒|

コードはこんな感じです。

```js:test.js
console.log(array1.length); // 100
console.log(array2.length); // 500000
for (var i = 0, len1 = array1.length; i < len1; i++) {
    for (var k = 0, len2 = array2.length; k < len2; k++) {
         // 簡単なif文
         if (テキトーな条件) {
         }
    }
}
```

```php:test.php
$i = 0;
while ($i < 100) {
    $k = 0;
    while ($k < 500000) {
        // 簡単なif分
        if (テキトーな処理) {
        }
        ++$k;
    }
    ++$i;
}
```

結果、**PHPよりNode.jsの方が速い**

# 細かい比較
### foreach vs while (PHP)
約50万×100のループ処理

|while|25.576475143433 秒|
|:--|:--|
|foreach|35.914368867874 秒|

### ++$i vs $i++ (PHP)

約50万件のループ処理

|++$i|0.0043938159942627 秒|
|:--|:--|
|$i++|0.0054738521575928 秒|


### '==' vs '===' (PHP)

約50万×100のループ処理(if分でイコール比較が計6回ある)

|===|25.329814910889 秒|
|:--|:--|
|==|30.264646053314 秒|

### forEach vs for (Node.js)

約50万×100のループ処理

|for|0.054ms|
|:--|:--|
|forEach|6060.262ms|

# 感想
とりあえず結果的にはPHPよりNode.jsの方がループ処理するには早かったです。
普段はPHPメインで触っているので、なんでもPHPで書き始めると以外と落とし穴があるなと感じました。。
例えば今回は最終的には50万×50万のループ処理をする必要があって、上記内容だと
**PHPだと約34時間かかって、Node.jsにすると約3.6時間かかる見積もり**です。
(34時間も待ってられないし。。)

他にはGo言語とかだと速いだろうなと思って、そっちを試そうかと思ったのですが、
Node.jsの方がお手軽かなという理由でNode.jsと比較しました。

あと調べると結構こっちの書き方の方が速いというのがあるのですが、
サイトによって全然バラバラだったりします。。
もちろん実行環境や処理の内容によって微妙にずれるので、その辺はしょうがないと思いますが。
なので実際に自分で計測するのが一番確実な気がします。笑

# 参考資料
### PHP
* [PHPを高速に動かす書き方](http://utututizu.info/?p=451)
* [あなたのコード、激遅ぷんぷん丸？今すぐできる7つのチェック項目 PHP編](http://blog.generace.co.jp/2013/06/21/894)
* [[PHP]ループのメモリ使用量と処理速度を比較しました](http://qiita.com/h13/items/a75fba76f435212a2eb3)

### 言語選定
* [プログラミング言語の速度とアプリケーションの速度がいかに関係ないかがわかるグラフ](http://d.hatena.ne.jp/kwatch/20100430/1272585083)
* [集計プログラムにおける言語速度比較（PHP Perl Java Go）](http://tec-blog.beaglee.com/?p=793)
* [各言語の1秒間のループ回数](http://qiita.com/liveralmask/items/2750b083bf5ddbe68726)

### js
* [Fast Array Foreach](http://jsperf.com/fast-array-foreach)
* [JavaScriptのループはどれが一番高速なのか](http://qiita.com/keroxp/items/67804391a8d65eb32cb8)
* [letとvarの違い](http://qiita.com/y-temp4/items/289686fbdde896d22b5e)
HLSストリームのスクリーンショットを撮る

## 環境

- python 2.7
- [livestreamer](http://docs.livestreamer.io/) 1.12.2

## Installation

- livestreamerをインストール

```
pip install livestreamer
```

- ffmpegをインストール

alpine linuxの場合

```
apk add --update ffmpeg
```

## How to take a screenshot

LiveとVODのどちらでも可能

- 1枚だけ撮る

```bash
livestreamer -l debug --yes-run-as-root --player "ffmpeg -i" --player-args "{filename} -vframes 1 snapshot.png" hlsvariant://serverIp/app/stream/playlist.m3u8 best
```

- -yオプションで上書き

```bash
livestreamer -l debug --yes-run-as-root --player "ffmpeg -i" --player-args "{filename} -vframes 1 snapshot.png -y" hlsvariant://serverIp/app/stream/playlist.m3u8 best
```

- 連続して撮る（1秒間隔で出力）

```bash
livestreamer -l debug --yes-run-as-root --player "ffmpeg -i" --player-args "{filename} -vf fps=1 out%04d.png" hlsvariant://serverIp/app/stream/playlist.m3u8 best
 ```
ggplot2のscale_fill_manualではまったところ

ggplot2がデータをアルファベット順にソートしてからプロットする仕様のために、ソートしてほしくない時に辛かった話。
以下のような状況だった。

```{R}
library("ggplot2")

# B,A,Cの順番のまま棒グラフにしたいとする
# 並び順を示す数値もあるとする（3列目）
# Bは赤 Aは緑 Cは青に色付けしたいとする
dat <- read.table(text=
"B    12.3    1
B    12.1    1
B   15.2    1
B   11.3    1
B   14.6    1
B   15.3    1
B   16.1    1
B   11.5    1
B   12.6    1
A    18.7    2
A    14.6    2
A    13.9    2
A    15.4    2
A    14.2    2
A    16.5    2
A    14.3    2
A    17.1    2
C    15.4    3
C    19.6    3
C    15.2    3
C    25.5    3
C    35.5    3
C    45.2    3
C    55.4    3
C    35.4    3", header = FALSE)
colnames(dat) <- c("Variable", "Value", "Order")
```

```{R}
# ggplot2はアルファベット順にソートしてからプロットしてしまうため、間違えて色付けしてしまう
bx <- ggplot(dat, aes(x=Variable, y=Value, fill=Variable))
bx <- bx + geom_boxplot()
bx <- bx + stat_boxplot(geom = "errorbar")
bx <- bx + scale_fill_manual(values=c("red", "green", "blue"))
bx
```
![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/17038/18f98cb0-26e4-e950-dcb9-95637c937f7a.png)


```{R}
# ならばとreorderで無理やりB,A,Cの順にすると、scale_fill_manualはソート前の順番で色付けしてしまうために赤、緑、青の順にならない
bx <- ggplot(dat, aes(x=reorder(Variable, Order), y=Value, fill=Variable))
bx <- bx + geom_boxplot()
bx <- bx + stat_boxplot(geom = "errorbar")
bx <- bx + scale_fill_manual(values=c("red", "green", "blue"))
bx
```
![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/17038/5b63bd84-85f9-43f2-8c10-9beb313da7da.png)

```{R}
# ggplotはlevelsが返す順番でプロットしているらしい
levels(dat$Variable)

# levelsの順番を自分で設定するといいらしい
# 参考 : http://stackoverflow.com/questions/20041136/avoid-ggplot-sorting-the-x-axis-while-plotting-geom-bar
dat <- read.table(text=
"B    12.3    1
B    12.1    1
B   15.2    1
B   11.3    1
B   14.6    1
B   15.3    1
B   16.1    1
B   11.5    1
B   12.6    1
A    18.7    2
A    14.6    2
A    13.9    2
A    15.4    2
A    14.2    2
A    16.5    2
A    14.3    2
A    17.1    2
C    15.4    3
C    19.6    3
C    15.2    3
C    25.5    3
C    35.5    3
C    45.2    3
C    55.4    3
C    35.4    3", header = FALSE, stringsAsFactors = FALSE)
colnames(dat) <- c("Variable", "Value", "Order")
dat$Variable <- factor(dat$Variable, levels = unique(dat$Variable))

# これだとうまいく
bx <- ggplot(dat, aes(x=reorder(Variable, Order), y=Value, fill=Variable))
bx <- bx + geom_boxplot()
bx <- bx + stat_boxplot(geom = "errorbar")
bx <- bx + scale_fill_manual(values=c("red", "green", "blue"))
bx
```
![hoge.png](https://qiita-image-store.s3.amazonaws.com/0/17038/a25e911a-d3b4-1b3e-be2a-92e8f982265e.png)
gem whenever を使って Rails で定時処理を作る

## whenver とは
cron の設定を簡単な文法で書ける gem。
RSS の作成やレポートの作成など、定時実行の処理を whenever を使うと Ruby を使って設定できる。
github(<a href="https://github.com/javan/whenever" target="_blank">javan/whenever</a>)

## gem をインストール
```
gem 'whenever', require: false
```
で `bundle install`

## 定時実行処理の設定ファイル作成
```
$ wheneverize
```
を叩くと `config/schedule.rb` ができる。
この `schedule.rb` が処理の設定ファイルになるのでここに処理を記述。

## 設定ファイル

```schedule.rb
every 3.hours do # 1.minute 1.day 1.week 1.month 1.year is also supported
  runner "MyModel.some_process"
  rake "my:rake:task"
  command "/usr/bin/my_great_command"
end

every 1.day, :at => '4:30 am' do
  runner "MyModel.task_to_run_at_four_thirty_in_the_morning"
end

every :hour do # Many shortcuts available: :hour, :day, :month, :year, :reboot
  runner "SomeModel.ladeeda"
end

every :sunday, :at => '12pm' do # Use any day of the week or :weekend, :weekday
  runner "Task.do_something_great"
end

every '0 0 27-31 * *' do
  command "echo 'you can use raw cron syntax too'"
end
```

上記のコードのようにして設定していく。デフォルトでは

* command
* runner
* rake
* script
<br>
の `job_type` と呼ばれる4種類の処理を行うことができ、時間も好きに設定できる。

ちなみに上の `job_type` については<a href="http://morizyun.github.io/blog/whenever-gem-rails-ruby-capistrano/" target="_blank">酒と泪とRubyとRailsと</a>さんが綺麗な言葉にまとめてくれているので以下抜粋。

```
command: bashコマンド実行
rake: rakeタスク実行
runner: Rails内のメソッド実行
script: scriptの実行
```

これらはデフォルトでは以下のコードと同じ挙動をする

```
job_type :command, ":task :output"
job_type :rake,    "cd :path && :environment_variable=:environment bundle exec rake :task --silent :output"
job_type :runner,  "cd :path && bin/rails runner -e :environment ':task' :output"
job_type :script,  "cd :path && :environment_variable=:environment bundle exec script/:task :output"
```
ちなみに自分で `job_type` を作成する場合は

```
job_type :awesome, '/usr/local/bin/awesome :task :fun_level'

every 2.hours do
  awesome "party", :fun_level => "extreme"
end
```
1行目のようにして作成して、4行目で書いたようにして使う

## cronで見る

```
$ whenever
  [add] writing `./config/schedule.rb'
  [done] wheneverized!
```
を叩くと　schedule.rb を cron の文法にしたものが確認できる

## crontab に書く
定時処理は `crontab` をもとに実行するのでその設定が必要になるが
whenever ではコマンドを叩けば schedule.rb をもとにやってくれる。
コマンドは以下

```
$ whenever -i

または

$ whenever --update-crontab
```

今回は `--update-crontab` オプションを指定しているが、
他にもいろいろなオプションがあり

```
$ whenever -h
```
で確認できる。

この作業やっておかないと schedule.rb を処理実行されないので自動化してしまったほうがいいかも
弊社ではデプロイと同時にコマンドを叩くようにしている。

## まとめ
こんな感じで `whenever` と使うと簡単に定時処理を組むことができる。
当たり前だがタスク名が違うなどのタイポをすると動かないので注意。
(私は何度かやってくっそハマった)

## 参考
* <a href="http://morizyun.github.io/blog/whenever-gem-rails-ruby-capistrano/" target="_blank">酒と泪とRubyとRailsと</a>
* <a href="https://github.com/javan/whenever" target="_blank">github</a>
Capistrano3でリリースディレクトリ名をGitのコミットハッシュ値にする


ある日インフラのすごい人に
「イケてるデプロイシステムならリリースディレクトリ名はyyyyMMddHHmmssじゃなくてGitのコミットハッシュ値だよね〜」
とサラッと言われたので、サラッとできると思ってチャレンジしてみたら結局ゴリッとシェルを書いて解決した話です。

## Capistrano側
```ruby:config/deploy.rb
# リリースディレクトリ名の変更
set :release_hash, ENV['GIT_COMMIT']
Rake::Task["deploy:new_release_path"].clear 

namespace :deploy do
  desc 'set release path'
  task :new_release_path do
    set_release_path(fetch(:release_hash))
  end
end 
```
ちなみにCapistranoのバージョンは3.6.1ですが、おそらく3系であれば変わらないと思います。

## デプロイ用のシェル
```bash:deploy.sh
if [ $# -eq 0 ]; then
  BRA="master"
else
  BRA=$1
fi
$BRA #ブランチ名を確認
VER=`git rev-parse --short $BRA`
$VER #コミットハッシュ値を確認
bundle exec cap production deploy BRANCH=$BRA GIT_COMMIT=$VER #Bundlerを使用しない場合はcap以降のみ
```
第一引数をブランチ名として、そのコミットハッシュ値を取得し、capコマンドに渡しています。

## 使い方
`sh deploy.sh {branch名}`
上記のコマンドで任意のブランチがその最新のコミットハッシュ値をディレクトリ名とするディレクトリにデプロイされます。
引数を指定しなかった場合はmasterがデプロイされます。

## 最後に
「イケてるデプロイシステムならリリースディレクトリ名はyyyyMMddHHmmssじゃなくてGitのコミットハッシュ値だよね〜」

これが本当にサラッと言われたので、Capistrano3単体でサラッと実現できるかと思いきや、できなかったという話です。
Capistrano3でできるもんだと思って色々調べてしまい、かなり時間をかけてしまいました。

## 参考
[Capistrano3でリリースディレクトリをJSTにする方法](http://qiita.com/gusagi/items/e2f7d37b77251fef9034)
こちらのQiita記事がCapistrano3の内部処理も解説されており、とても参考になりました。
Rails で ActiveRecord を継承する models、それに関する validators / factory_girls をいい感じにネストしたい場合

# 概要
rails の公式を読んでいても、いい感じにネストする方法については特記されていないのでそれについて触れる
今回触れるのは models / validators / factory_girls の 3点

# この記事の対象者の例
科学のレポートを保存しておくために `ActiveRecord::Base` を継承したモデルを用意しておいた
がしかし、このままだと数学のレポートとか必要になったら `models/` 直下が汚くなるやべぇ！って人 or なってる人

## ディレクトリ
### 現状
```text
app/
├── models/
│   └── science_report.rb
└── validators/
    └── science_report_validator.rb
spec/
└── facotries/
    └── scicence_reports.rb
```

### 理想
```text
app/
├── models/
│   └── report/
│       └── science
└── validators/
    └── report/
        └── science_validator.rb
spec/
└── facotries/
    └── report/
        └── sciences.rb
```

## クラス
### 現状
```ruby
# app/models/science_report.rb
class ScienceReport < ActiveRecord::Base
  validates :content, science_report_validator: true # 今回は部分 validation を validator に委譲している人を対象にする
end

# app/validators/science_report_content_validator.rb
class ScienceReportValidator < ActiveModel::EachValidator
end

# spec/factories/science_reports.rb
FactoryGirl.define do
  factory :science_report do
  end
end
```

### 理想
```ruby
# app/models/report/science.rb
class Report::Science < ActiveRecord::Base
  # validation?
end

# app/validators/report/science_validator.rb これはネストするだけ
class Report::ScienceValidator < ActiveModel::EachValidator
end

# spec/factories/science_reports.rb
# ?
```

# 結論
なんてことはない

```ruby
# app/models/report/science.rb
class Report::Science < ActiveRecord::Base
  validates :'report/science_validator' => true
end

# spec/factories/science_reports.rb
FactoryGirl.define do
  factory :science_report, class: 'Report::Science' do
  end
end
```

おそらく読んだらﾌｰﾝ（ ´_ゝ`）な内容
現在使われているphp.iniの場所の探し方


PHPが複数バージョン入っているなどで、実際に読み込まれているphp.iniの場所が分からない場合に、php.iniの場所を確認する方法です。

# phpinfo

```php
phpinfo();
```
が見れる状態であれば、
そちらの「Configuration File (php.ini) Path」を確認してください。

# php -i コマンド

SSHで接続中に確認したい場合は

```shell-session
php -i | grep php.ini
```

上記コマンドで一発確認出来ます。


# まとめ

オススメは「php -i」コマンドです。

他にも、現在のTimeZone設定を知りたい場合は

```shell-session
php -i | grep timezone
```

とすれば確認出来ますし、応用が色々とききます。
[Boto3]ListUsersAPIでCognitoのユーザーを検索する



ドキュメントでは、以下のようにしてユーザーを取得できるという風に書かれています。

```python
response = client.list_users(
    UserPoolId='string',
    AttributesToGet=[
        'string',
    ],
    Limit=123,
    PaginationToken='string',
    Filter='string'
)
```
from:https://boto3.readthedocs.io/en/latest/reference/services/cognito-idp.html#CognitoIdentityProvider.Client.list_users

##ユーザーを60件取得

```python
import boto3
client = boto3.client('cognito-idp')
response = client.list_users(
    UserPoolId='YOUR_USER_POOL_ID'
)
```

ユーザープールIDだけ指定した場合、
全ユーザー
先頭60件が返ってきます。
「Limitを指定しないと全件取得する」と思っていましたが、先頭60件のみの様子です。

##メールアドレスで検索する
Filterに`email = "hoge"`と書くことで、該当するEmailアドレスを持つユーザーのみを検索することができます。

```
import boto3
client = boto3.client('cognito-idp')
response = client.list_users(
    UserPoolId='YOUR_USER_POOL_ID',
    Filter="email = \"hide\"",
)
```
この例の場合、`hide`という文字が含まれるメールアドレスを使用するユーザーを全件取得します。

`=`の代わりに`^=`とすることで、「hideから始まるメールアドレス」のような検索もできます。


## Tips:カスタム属性は`Filter`で検索できない

> 標準属性のみを検索できます。カスタム属性は検索できません。これはインデックスが付けられた属性のみが検索可能なためで、カスタム属性にインデックスを作成することはできません。
> http://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/how-to-manage-user-accounts.html#cognito-user-pools-searching-for-users-using-listusers-api

とあり、カスタム属性を使用したユーザー検索は現状対応していない様子です。

検索させたい属性については、DynamoDBやAES(Amazon Elasticsearch Service)などに格納する方が良さそうです。


##先頭10ユーザーを取得する

`Limit`クエリに数字を指定することで、取得件数を絞り込めます。

```
import boto3
client = boto3.client('cognito-idp')
response = client.list_users(
    UserPoolId='YOUR_USER_POOL_ID',
    Limit=10,
)
```

### Tips: Limitの上限は60
61件以上のデータを一気に取得しようとして、Limitを61以上の値にするとエラーになります。

```
ClientError: An error occurred (InvalidParameterException) when calling the ListUsers operation: 1 validation error detected: Value '500' at 'limit' failed to satisfy constraint: Member must have value less than or equal to 60
```

以下のような感じで再帰呼び出しするのがいいかなと思います。

```python
def getUser():
    client = boto3.client('cognito-idp')
    response = self.client.list_users(
        UserPoolId="YOUR_USERPOOL_ID"
    )
    return response

def getUsersWithPagenation(PaginationToken):
    response = self.client.list_users(
        UserPoolId="YOUR_USERPOOL_ID",
        PaginationToken=PaginationToken
    )
    return response

def workerNode(users):
    for user in users["Users"]:
    	# Do Something
    if 'PaginationToken' in users:
        newUsers = getUsersWithPagenation(users["PaginationToken"])
        workerNode(newUsers)

users = getUser()
workerNode(users)
```
ノー残業デーに蛍の光を流して帰ろうコールをする

ノー残業デー導入しても、なかなか帰らない！そんな会社もあると思います。(うちじゃないです）
そこで、蛍の光を自動で流して帰ろうコール。
常時動いているMacがあったのでスピーカーをつなげてcronで下記シェルスクリプトを起動します。

afplayコマンドでmp3をバックグランドで再生、そこへsayコマンドをかぶせるだけといえはだけですが。

```bash:play.sh
#!/bin/bash

D=`dirname $0`
cd $D
afplay -v 0.5 -t 24 hotarunohikari.mp3 &
sleep 5
say -v kyoko -r 140 みなさん、本日、`date +"%Y年%m月%d日 %a曜日"`はノー残業デーです。仕事を終わらせて早く帰りましょう。早く帰らないと、しらないですよ？
sleep 4
afplay -v 1 -t 60 hotarunohikari_rock.mp3
```

水曜日の19時ならcronはこんな感じです。

```bash:cron
0 19 * * 3 /path/to/play.sh
```
iOS実機でUnityアプリを起動するとCreateMaterialで落ちる

#症状

Unityで作ったアプリをiOS実機で起動した場合、Unityロゴが出る前に以下のようなエラーが出て、画面に何も表示されないまま30秒後ぐらいに"Thread 1"の"CreateMaterial"が"EXC_BAD_ACCESS"で落ちることがあります。

```
NullReferenceException: A null value was found where an object instance was required.
  at UnityChan.FaceUpdate.OnGUI () [0x00000] in <filename unknown>:0 
(Filename: currently not available on il2cpp Line: -1)
```

![Unity_CreateMaterial_Error.png](https://qiita-image-store.s3.amazonaws.com/0/141731/bbae5502-10b2-a6dc-030c-ecbd14c32eaf.png)

#原因

iOS版では対応していない.ddsファイル(DXT3,DXT5などの圧縮テクスチャ)がMaterialに設定してある場合に発生します。

なので、上記のエラーは副作用というか、全体の初期化が終了する前にGameObjectが走ってしまって、本来は生成済みのはずのオブジェクトが存在しない状況が発生しているようです。

#回避策

ddsファイルを使用せず、tgaやpngのような生画像をAssetとして登録して、Unity側で圧縮しましょう。

以上、めっちゃ基本的な話でした。マルチプラットフォーム開発においてUnityが面倒見てくれる部分と見てくれない部分を、一度洗いだしたほうが良さそう…。

#参考

EXC_Bad_Access Thread CreateMaterial ()
http://answers.unity3d.com/questions/1234358/exc-bad-access-thread-creatematerial.html
３日で資産が３倍に!! Azure Machine Learning(ML) でFx予測と自動売買連携。その３ データプレパレーション（データの準備）- (R)

http://qiita.com/T_Umezaki/items/05302aec04048e280dfe の続きです。

ソースはこちら
https://github.com/MIJS-FX/qiita

- - -
## 概要
- データ準備用です。GitHubに用意したデータはGBPJPYの３ヶ月分のみなので、教師用データを生成、加工したい方は読んで下さい。
動作させるだけであればこの章は不要です。

というわけで、編集リクエストがいただけたり、注目度が上がるようであれば記載します。

![image](https://qiita-image-store.s3.amazonaws.com/0/123399/2e306c7f-2f50-f4f4-0f3a-68e85bda7a36.png)

R studioで、git 上の、ForQiita.Rproj を開くと編集できます。

![image](https://qiita-image-store.s3.amazonaws.com/0/123399/5d9d65fc-f7fd-8db6-9fa5-501e6ff495bf.png)
派生クラスのインスタンスの代入に関わるデータのコピー

 今回もマークダウン記法の練習を兼ねて、投稿してみます。（私事ですがプライベートが少々忙しく、ある程度記事が書けるのは2月以降になりそうです）

 題材として、独習C++の第3章の章末確認問題の3.を解いてみます。
 クラスを継承して新しいクラスを作り、派生クラスのインスタンスを2つ作ります。基本クラスと派生クラス両方にメンバ変数が含まれていて、片方のインスタンスでは両方の変数を初期化します。ここで初期化していないインスタンスに初期化したインスタンスを代入すると、どこまでデータがコピーされるのでしょうか。基本クラスのデータまでコピーされるのでしょうか。

 まず基本クラスと派生クラスを記述します。

```cpp
class base {
    int a;
public:
    void load_a(int n){a = n;}
    int get_a(){return a;}
};


class derived : public base{
    int b;
public:
    void load_b(int n){b = n;}
    int get_b(){return b;}
};
```

 次にmain関数内で、次の命令を実行してみます。

```cpp
derived i1,i2;
i1.load_a(100);
i1.load_b(200);
cout << "i1のaは" << i1.get_a() << " i1のbは" << i1.get_b() << "\n";
i2 = i1;
cout << "i2のaは" << i2.get_a() << " i2のbは" << i2.get_b() << "\n";
```
すると、以下の結果を得ました。

---

```
i1のaは100 i1のbは200
i2のaは100 i2のbは200
```

 基本クラスのデータまでちゃんとコピーされているようです。継承がもっと深くなっても同じことがいえるでしょうか？
 次の派生クラスを追加します。

```cpp
class derived2 : public derived{
    int c;
public:
    void load_c(int n){c = n;}
    int get_c(){return c;}
};
```

 同じようにmain関数内で次を実行します。

```cpp
derived2 i1,i2;
i1.load_a(100);
i1.load_b(200);
i1.load_c(300);
cout << "i1のaは" << i1.get_a() << " i1のbは" << i1.get_b() << " i1のcは" << i1.get_c() << "\n";
i2 = i1;
cout << "i2のaは" << i2.get_a() << " i2のbは" << i2.get_b() << " i2のcは" << i2.get_c() << "\n";
```

 結果は以下のようでした。

---

```
i1のaは100 i1のbは200 i1のcは300
i2のaは100 i2のbは200 i2のcは300
```

 どうやら、継承が深くなっても、大元の基本クラスのデータまでコピーされるようです。

 簡単ですが、今回はここまでにしたいと思います。お読みいただいてありがとうございました。
秀マクロ用Splitを作ってみた。


## 最初にコード公開

```秀マクロサブルーチン
Split:
	##i=0;
	$$str=$$1;
	$$fnd=$$2;
	while(strstr($$str,$$fnd)>-1){
		$Spl[##i]=midstr($$str,0,strstr($$str,$$fnd));
		$$str=rightstr($$str,strlen($$str)-strstr($$str,$$fnd)-strlen($$fnd));
		##i = ##i + 1;
	}
	$Spl[##i]=$$str;
    return ##i+1;

```

秀マクロのサブルーチンで再現してます。

## 引数は２つ。

- 第１引数にSplit対象の文字列
- 第２引数にSplit文字列

を指定します。

サブルーチンの中で

- 第１引数は`$$1`（数値型の場合は`##1`）
- 第２引数は`$$2`（数値型の場合は`##2`）

として利用できます。

## コード説明

`$$1`や`$$2`だと分かりづらいので、

- `$$str`
- `$$fnd`

というローカル変数に代入しています。


その後の処理の流れは以下の通り。

- `$$str`内の文字列から`$$fnd`内の文字列を検索
- 【見つかった場合】
	- その前までの文字列を配列`$Spl`に格納
	- `$$str`の中からも抜き出す
	- `$$fnd`の文字列も抜き出す
	- 繰り返し処理（1に戻る）
- 【見つからなかった場合】
	- 繰り返し処理を終了
- 残りの文字列を配列`$Spl`に格納
- 分割された数を関数の戻り値として返す

という感じ。

`$Spl`はグローバル変数なので、
サブルーチンの外でも使えます。

## 利用例

```例：繰り返し全置換処理を行う
// 区切り文字
$delim = "===";

// 置換文字セットリスト
$Rep[0] = "[ 　¥¥t]+===, ";
$Rep[1] = "([a-zA-Z0-9]+)([^;])===¥¥1; ¥¥2";

// 置換文字セット数
#Rep = 2;

// メイン処理
#i = 0;
while(#i < #Rep){
	Split $Rep[#i], $delim;
	replaceallfast Spl[0],Spl[1],regular;
	#i = #i + 1;
}
endmacro;

// Split関数
Split:
	##i = 0;
	$$str = $$1;
	$$fnd = $$2;
	while(strstr($$str,$$fnd) > -1){
		$Spl[##i] = midstr($$str,0,strstr($$str,$$fnd));
		$$str = rightstr($$str,strlen($$str) - strstr($$str,$$fnd) - strlen($$fnd));
		##i = ##i + 1;
	}
	$Spl[##i] = $$str;
    return ##i + 1;

```
Windows 10 の更新プログラムを非表示にする件

# きっかけ
Windows 7からWindows 10にアップデートした後に、Windows Updateをかけると次のような項目がでた。

”Advanced Micro Devices, Inc. driver update for AMD Radeon HD 6570”

たしかにうちは[ASUS EAH6570](https://www.asus.com/jp/Graphics-Cards/EAH6570DI1GD3LP/)を積んでいるけどこのドライバー大丈夫？
と言うのもHD 6系で扱える最新のドライバーをインストール済みだったので不安を抱きながらもインストールし、再起動したらAMD Catalyst Control Centerが何故か消えていた。
色々試したが結局CCCは戻らず、相当のドライバーをアンインストールして再度AMDの公式サイトからドライバーを落としてやり直した。

その後もWindows Updateにはそのドライバーが表示され続ける上、[個別に更新プログラムをインストールする方法](http://www.atmarkit.co.jp/ait/articles/1509/07/news030.html)もあるがとっても面倒なので非表示にすることで解決したことがきっかけです。

# Windows 10で更新プログラムを非表示にする
「更新の表示/非表示」回避策パッケージをダウンロードしてくる。
https://support.microsoft.com/ja-jp/help/3073930/how-to-temporarily-prevent-a-driver-update-from-reinstalling-in-windows-10

ダウンロードしてきたwushowhide.diagcabはそのままダブルクリックで起動します。
![wu2.PNG](https://qiita-image-store.s3.amazonaws.com/0/70146/6dd49fac-1e68-6452-0e6a-26de2315ae10.png)
次へをクリック

![wu3.PNG](https://qiita-image-store.s3.amazonaws.com/0/70146/50cbf003-3b5e-4349-46c5-c98dc72911bb.png)
Hide updatesをクリック。これは更新プログラムを非表示にする選択。逆にShow hidden updatesは非表示にした更新プログラムを表示、つまり元に戻すことが出来ます。

非表示にする項目にチェックした後、次へをクリックする。
![wu4.PNG](https://qiita-image-store.s3.amazonaws.com/0/70146/20201477-0ee1-998d-d19e-7122d4b5803b.png)

完了したが
![wu5.PNG](https://qiita-image-store.s3.amazonaws.com/0/70146/f7a4b564-688d-77ef-e697-50ef3487ac80.png)
念のため、閉じてWindows 10を再起動する。
すぐには適用されないみたいな感じなので数分～数時間待ってからWindows Updateで相当項目が消えているかを確認します。
ヽ(^0^)ノ

Windows Updateの更新プログラムを非表示にするのはあまりしないと思いますが標準で出来ないってなるといざって時が面倒ですね。

# 参考

* [Windows 10: 問題を起こした更新プログラムやドライバーを Windows Update で一時的にインストールされないようにするツールの紹介](https://blogs.technet.microsoft.com/jpsecurity/2015/07/30/windows-10-windows-update-12/)
* [Windows 10 を再インストールしてから、ドライバーの更新を一時的に止める方法。](https://support.microsoft.com/ja-jp/help/3073930/how-to-temporarily-prevent-a-driver-update-from-reinstalling-in-windows-10)
circusのDockerfile作成し、Dockerhubで自動ビルドする

# 概要
* Goで書いたサーバのプロセス管理ツールとして使われるcircusd
* circusdのdockerイメージがなかったので作り方を紹介
* かなり雑なのでもっと良い方法があるはず。とりあえずって感じです。
* ベースでcentos6.8のdockerイメージを使用してます
* DockerHubにあげました　https://hub.docker.com/r/sioncojp/circusd/

# DockerHubの上げ方内容
### Dockerfileを作る
* https://github.com/sioncojp/circusd

### dockerhubのAUTOMATED BUILDとしてあげる
* 自動ビルドさせましょう

# 最後に
* 残念なことにchkconfig onにしてるんですが、コンテナ起動後に<br>docker execで `/etc/init.d/circusd restart`を打たないと機能してくれないです。
* ともあれ動くので一応投稿しました。
php ZIPファイル解凍

#php ZIPファイル解凍

zipファイルを指定ディレクトリに解凍して、中のファイル名の配列を返す。
zipファイルのオープン・解凍に失敗した場合はfalseを返却。
（解凍先に同名ファイルがある場合はunlinkをするがエラーは無視）

```php:
public function unzip($zip_path, $unzip_dir, $file_mod = 0755) {
    $zip = new ZipArchive();
    if ($zip->open($zip_path) !== TRUE) 
        return FALSE;
    
    $unzip_dir = (substr($unzip_dir, -1) == '/') ? $unzip_dir : $unzip_dir.'/';
    for ($i = 0; $i < $zip->numFiles; $i++) 
        if(file_exists($unzip_dir.$zip->getNameIndex($i))
            @unlink($unzip_dir.$zip->getNameIndex($i))
    
    if ($zip->extractTo($unzip_dir) !== TRUE) {
        $zip->close();
        return FALSE;
    }
    
    $files = [];
    for ($i = 0; $i < $zip->numFiles; $i++) {
        $files[] = $zip->getNameIndex($i);
        if(file_exists($unzip_dir.$zip->getNameIndex($i))
            chmod($unzip_dir.$zip->getNameIndex($i), $file_mod)
    }
    $zip->close();
    return $files;
}
```


##備考
php7.0以降で書く場合は、引数・戻り値ともに型指定ができるので下記になる。


```php:
public function unzip(string $zip_path, string $unzip_dir, int $file_mod = 0755) {}
```

**参考(ZipArchive クラス)**
http://php.net/manual/ja/class.ziparchive.php
C#：Struct と　Classの違い

C# 中 Struct 与 Class 的区别，以及两者的适用场合
1，class 是引用类型，structs是值类型
既然class是引用类型，class可以设为null。但是我们不能将struct设为null,因为它是值类型。
    
```csharp

struct AStruct
{
   int aField;
}
class  AClass
{
   int aField;
}
class MainClass
{
 public static void Main()
 {
  AClass b = null; // No error.
  AStruct s = null; // Error [ Cannot convert null to 'AStruct' because it is a value type ].
 }
}
```
2，当你实例一个class，它将创建在堆上。而你实例一个struct，它将创建在栈上
3，你使用的是一个对class实例的引用。而你使用的不是对一个struct的引用。（而是直接使用它们）

4，当我们将class作为参数传给一个方法，我们传递的是一个引用。struct传递的是值而非引用。

5，structs 不可以有初始化器，class可以有初始化器。

```csharp
class MyClass
{   
   int myVar =10;  //  no syntax error.    
   public void MyFun( ) 
   {       
   //  statements    
   }
}
struct MyStruct
{    
  int myVar = 10;  //  syntax error.   
  public void MyFun( )  
  {       
     //  statements    
  }
}
```

6
Classes 可以有明显的无参数构造器，但是Struct不可以

```csharp
class MyClass
{   
  int myVar = 10; 
  public MyClass( ) // no syntax error.  
 {    
// statements
 }
}
struct MyStruct
{  
  int myVar; 
  public MyStruct( ) // syntax error.
   {       
  // statements  
   }
}
```

7 类使用前必须new关键字实例化，Struct不需要

```csharp
MyClass aClassObj;     //  MyClass aClassObj=new MyClass(); is the correct format.aClassObj.
myVar=100;//NullReferenceException(because aClassObj does not contain a reference to an object of type myClass).    
MyStruct  aStructObj;
aStructObj.myVar=100; //  no exception.
```

8 class支持继承和多态，Struct不支持. 注意：但是Struct 可以鹤类一样实现接口
9 既然Struct不支持继承，其成员不能以protected 或Protected Internal 修饰
10 Class的构造器不需要初始化全部字段，Struct的构造器必须初始化所有字段

```csharp
class MyClass    //No error( No matter whether the Field ' MyClass.myString ' is initialized or not ). 
{ 
 int myInt;  
 string myString;   
 public MyClass( int aInt )
      {    myInt = aInt;    }
}
struct MyStruct    // Error ( Field ' MyStruct.myString ' must be fully assigned before it leaves the constructor ).
{ 
  int myInt;  
  string myString; 
  public MyStruct( int aInt ) 
   {    
    myInt = aInt;  
   }
}
```

11 Class可以定义析构器但是Struct不可以
12 Class比较适合大的和复杂的数据，Struct适用于作为经常使用的一些数据组合成的新类型。

适用场合：Struct有性能优势，Class有面向对象的扩展优势。
用于底层数据存储的类型设计为Struct类型，将用于定义应用程序行为的类型设计为Class。如果对类型将来的应用情况不能确定，应该使用Class。
３日で資産が３倍に!! Azure Machine Learning(ML) でFx予測と自動売買連携。-その２ Gitからのソース取得編

http://qiita.com/T_Umezaki/items/05302aec04048e280dfe の続きです。
![image](https://qiita-image-store.s3.amazonaws.com/0/123399/3f5fe2c1-5f8d-3503-b77f-bad7b476ad72.png)

https://github.com/MIJS-FX/qiita

- - -
## 概要
- その１で解説したモジュールのソースです。

## R
- R studio にて ForQiita.Rproj から各ソースにアクセスしてください。
- それぞれのモジュールにローカライズされた設定が含まれます。適宜修正してください。
- なるべく修正不要な環境を望まれる場合は、すべてのファイルをc:\test_obj 以下に展開してください。

![image](https://qiita-image-store.s3.amazonaws.com/0/123399/a842e82d-d693-d2d3-f158-8a2e72becdbe.png)

- R モジュールの役割

    - CallAzureAPI.R AzureML上のAPI呼び出し
    - CreateDataForAzureML.R Azure MLに利用する教師用・テスト用データ作成
    - CreateCurrentData.R 上記の現在値部分を補正

- インストールフォルダ以外に必要な修正は以下の通りです。
    - CallAzureAPI.R のAzure API 及びURL

## azure_ml
![image](https://qiita-image-store.s3.amazonaws.com/0/123399/c3b6c88c-9084-298d-1444-bf5a17fdf00c.png)

- Azure MLの登録方法、使い方は恐縮ですが別なページに譲ります。
- Azure MLが使える(サインアップ済み)、studioを白紙から作る（新規作成）という前提で設定方法を述べます。
- Azure ML に関してはソースの入出力はありません。手動設定です。
- その４にて詳細を記載します。
- 概要は以下の通り。
 - 教師用、試験用のデータセットを作成（datasetとしてアップロード）する
 - 必要な列を選択する
 - アルゴリズムを配置する。（例：Liner Regression）
 - 教師モデルを作成する(Train Model)
 - 実行モデルを作成する(Score Model)
 - 予測結果列を選択
 - Web API化

## batch
- WebAPIはMT4からRを起動する形で呼び出します。Rを起動するためのバッチファイルです。

## DATA
- 20160401.csv 入力データ
- GBPJPY_CURRENT.csv R で作成した中間データ。GBPJPY_ALL.csv生成に利用
- GBPJPY15.csv 15分足のデータ。サイトからダウンロードした１分足データをMT4で15分足作成。60,240 も同様
- GBPJPYALL.csv 教師用データ

## mt4
- \experts
 - mlfx_v1_0.mq4 Azure ML のAPIを呼び出し、結果により売買を行う。MQL言語
- \Files
 - mlfx_v1_0.mq4 が一時的に作成するデータとログ
３日で資産が３倍に!! Azure Machine Learning(ML) でFx予測と自動売買連携。-その１ 概要・準備編

![image](https://qiita-image-store.s3.amazonaws.com/0/123399/1e8330b7-b4b4-77cf-905a-6db881c33e8f.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/123399/cd4dd1ca-7084-6271-bdd3-03058012dad0.png)
- - -
## 概要
- Azure Machine Learning を使い、教師あり機械学習によるFx予測をします。
- 機械学習の結果をWebApi経由で入出力できる状態にします。
- Fx自動売買システムで著明なMetaTrader4(MT4)からWebApiで結果を取得し自動売買します。
- 教師用データは証券会社より配布されている１分足のデータを使います。
- データの加工はRで実装します。
- ソースコードはGitHubから取得できます。
- 本アプリケーションの仕様・概要は、 https://docs.com/user142134/9040/jazug-5-azure-mlfx にあります。まずはこちらを御覧ください。

- - -

## 目的など
- 現段階で試験的ではありますが実弾にて運用中です。ドキュメント化を順次進めています。
- 本資料では自動売買の仕組みを構築できるように順次解説します。
- アルゴリズム変更（中級）、閾値変更（初級）、組み換え（中級）などできます。ご利用ください。
- 更新が止まったら、まあ、そういうことです。Fxですから。不就労収益。いいですね。

- - -

## 記事の構成
- その１ 準備編　概要とミドルソフトセットアップ　←　いまここ
（以下　順次公開）
- その２ Gitからのソース取得と解説
- その３ データプレパレーション（データの準備）- (R)
- その４ 主処理の基本。WebApi作成まで (Azure Machine Learning)
- その５ 自動売買システムとの連携 (MetaTrader4)
- その６ 結果の評価 (Azure Machine Learning)
- その７ 結果を最適化する閾値の自動設定 (Azure Machine Learning)

- - -


## 開発環境・必要なミドルソフト
- 開発に使ったOS
 - windows
- 機械学習エンジン
 - Azure Machine Learning
     - クライアントにインストールは不要ですがAzureサブスクリプションが必要です。無償のお試し版でも動作可能です。
- 機械学習用データの準備(Rの開発環境)
 - R studio
- 自動売買実行環境及び自動売買用コード編集環境
 - MetaTrader4

 - - -

## システム概要図 ![image](https://qiita-image-store.s3.amazonaws.com/0/123399/e70ad79c-67bc-ac2f-452c-9b2e3be80db9.png)
 - - -
##環境構築
- MT4のインストール
 - MT4初心者導入マニュアル http://bit.ly/2f7aPxx
- R・R studioのインストール
 - Rの導入 https://cran.ism.ac.jp/
 - R studio導入 http://bit.ly/1HlIr0q
 - (参考資料)Rの導入とRStudio事始め(改訂版) http://bit.ly/2f7dJlF
- 教師用データの取得(GitHub上にも多少はあります)
 - MT4のヒストリカルデータの集め方 http://bit.ly/2f3vQvj
 - MT4 ヒストリカルデータ（過去データ）のインポート・設定手順 http://bit.ly/2foZTzc

 - - -

##資金３倍について
釣りタイトルです。すみません。ただ、少額のテストケースで一度３倍まで資金が伸びたことは事実です。
単純な回帰を使っているので、レンジには強かったのですが、トレンドに転換すると駄目でした。
(2017/1/16)
先日のMIJSミーティングにて、レンジを分類するAIを手前に噛ませる実装をしました。（未結合）
教師データは、グラフから目視で「ここはレンジかな。」とやったので、厳密ではありませんが、レンジ、トレード上下の３分類で57%の正答率。です。結合結果は追って配信します。

##Azule ML を使うメリット
アルゴリズムの変更が簡単にできます。ARIMA,RNNの実装も可能、試験結果の評価、パラメータ設定にも優位性があります。
こちらにつきましては次回以降の記事にて紹介させていただきます。
Azure MLの便利な部品群はこちらに記事にしました。 http://qiita.com/T_Umezaki/items/cfe5d201d926ba53bea5

 - - -
 
編集リクエスト フィードバックも歓迎します。リンクフリーです。Facebook友達申請などお気軽に。
※損をしても一切の責任は負いません。儲かったらフィードバックお願いします。
　所属する会社とは無関係です。
Grouped UITableView のセクションヘッダーおよびフッターの余白をなくす方法

# 要件

UITableView を Grouped Style にした際、このような余白がヘッダーとフッターの領域にできてしまいます。これを無くしたいです。

|イメージ|
|:--:|
|<img width=375 src="https://qiita-image-store.s3.amazonaws.com/0/3603/946adb39-60d7-bad6-5c83-fac20d8a1506.png">|

# 対応

UITableViewDelegate からセクションヘッダーおよびフッターの高さ値を返しますが、ここで `CGFloat.leastNormalMagnitude` という具合で高さ値を指定してあげれば、例の余白をなくすことができます。

ちなみに `return 0.0` や、`tableView.sectionFooterHeight = CGFloat.leastNormalMagnitude` では効果がありませんでした。

```swift:UITableViewDelegate
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
	return CGFloat.leastNormalMagnitude
}
	
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
	return CGFloat.leastNormalMagnitude
}
```

|結果|
|:--:|
|<img width=375 src="https://qiita-image-store.s3.amazonaws.com/0/3603/c9092746-63d3-3273-a9f4-5ac3d102e28c.png">|
dockerのtmpfsオプション

docker本体にオプションとして組み込まれてたの知らなかった…
コンテナ内で素直にtmpfsをmountしようとすると、権限の調整が必要でちょっと面倒。

## docker runなど

https://docs.docker.com/engine/reference/commandline/run/
http://docs.docker.jp/engine/reference/commandline/run.html#tmpfs-tmpfs (日本語訳)

tmpfsオプションがある

```
      --tmpfs value                 Mount a tmpfs directory (default [])
```

## docker-compose

https://docs.docker.com/compose/compose-file/#/tmpfs

そのまんまtmpfsという設定を書けば良い。ディレクトリ一個で良いなら文字列、複数パスにtmpfsマウントしたいなら配列で渡す。

```yaml
tmpfs: /run
tmpfs:
  - /run
  - /tmp
```
ASP.NET Coreを試す 

# ASP.NET Core / .NET Core とは

Microsoftが発表した、クロスプラットフォーム向けの.NET及びASP.NET。

従来の.NET FrameworkはWindows専用だったのに対し、
.NET Core はMac、Linuxでの開発を行う事が出来ます。

# はじめてみよう


Windowsの場合は、VisualStudio 2015/2017で作れますが、
本稿ではクロスプラットフォームを見据えてVisual Studioを使わない方式を紹介します。


## 必要なもの


#### .NET Core

ここからダウンロードできます。
https://www.microsoft.com/net/core#windowscmd

例えば、Windowsの場合、 Windows -> Command Line/Other
と選択すれば

Install .NET Core SDK

からダウンロードできます。


#### Visual Studio Code

ここからダウンロードできます。
https://code.visualstudio.com/

インストーラなのでそのままインストール可能。


#### Node.js

みんな大好きNode.js。
ここからダウンロードできます。
https://nodejs.org/en/


#### Node.js絡みの準備

```
$ npm install -g bower yo generator-aspnet gulp
```
これで一括でインストールされます。

## はじめよう

#### ASP.NET Coreプロジェクトを作成

おもむろにコマンドプロンプトを開き、
プロジェクトを作成したいフォルダに移動後、以下のコマンドを打ちます。

```shell-session
$ yo aspnet
```

プロジェクトのテンプレートが出るので、
「Web Application」
を選択することで自動でWebアプリケーションのテンプレートが作成されます。
(アプリ名や仕様CSSフレームワークは任意）


次に、NuGetで必要なフレームワークをダウンロードします。

```shell-session
$ cd [プロジェクト名]
$ dotnet restore
```

最後にVisual Studio Codeを起動。

```shell-session
$ code .
```

### MSB1003エラーが出たときは？

以下のエラーが出る場合があります。

```shell-session
MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.
```

私の場合、.NET Coreの複数バージョンがインストールされていたのが問題だったようで、
すべてアンインストールの上最新を入れなおすことで直りました。


## Visual Studio Codeの簡単な使い方

Windowsの場合ですので、MacやLinuxの場合にはご注意ください。

### ビルド
Control + Shift + B

### デバッグ実行

F5

## うまくデバッグできないときは

起動はするものの、ブレークポイントを置いてもうまく止まらない。
（そもそも、ブレークポイントが赤くならずにグレーになる）

その場合は、project.jsonを開き、以下のように変更します。

```json
  ～
  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true,
    "debugType": "portable" // <- これを追加
  },
  ～
```

私の環境ではこれでうまくいきました。
LC_ALL=C.UTF-8 は安全か

普段は mac で ja_JP.UTF-8 を使ってるけど、 Linux では予想しない挙動の変化が起きるのを嫌って C locale を使う人、いますよね。僕も常にではないけれど結構 C locale 好きです。

でも、 C locale を使うと、 vim が (`set encoding=utf-8` を書いていないと) デフォルトで latin1 になって文字化けしまくったり、 Python が (`export PYTHONIOENCODING=utf-8` しておかないと) 標準入出力がasciiになって UnicodeError になったりしてツラい気持ちになることもあります。

そんなときは、 LANG=C, LC_CTYPE=en_US.UTF-8 で LC_ALL は設定しないようにするのがただしい locale の設定方法なんですが、最近のモダンな Linux に搭載されてる C.UTF-8 はそのかわりに使えるのでしょうか？

気になるのが、 LC_COLLATE です。 Unicode に乗っ取った順序が有効になって、 http://unix.stackexchange.com/questions/169739/why-is-coreutils-sort-slower-than-python みたいな問題が起こらないでしょうか。確認しておきましょう。

```
# from http://unix.stackexchange.com/questions/169739/why-is-coreutils-sort-slower-than-python

$ cat letters.py
import string
import random

def main():
    for _ in range(1_000_000):
        c = random.choice(string.ascii_letters)
        print(c)

main()

$ python3.6 letters.py > letters.txt

$ LC_ALL=C time sort letters.txt > /dev/null
        0.35 real         0.32 user         0.02 sys

$ LC_ALL=C.UTF-8 time sort letters.txt > /dev/null
        0.36 real         0.33 user         0.02 sys

$ LC_ALL=ja_JP.UTF-8 time sort letters.txt > /dev/null
       11.03 real        10.95 user         0.04 sys

$ LC_ALL=en_US.UTF-8 time sort letters.txt > /dev/null
       11.05 real        10.97 user         0.04 sys
```

UTF-8 の部分は LC_CTYPE にだけ影響して、 LC_COLLATE には影響しないみたいですね。安心して C.UTF-8 を使えそうです。

(本当は LC_CTYPE=UTF-8 って書きたいなー。)
findとgrepの小ネタ

検索コマンドのfindとgrepの小ネタです。

主に、findはファイル名やファイルサイズ、タイムスタンプなどから
条件にあてはまるファイルを探すときに、

grepはファイルの中を見て指定のキーワードを探すときに使います。


# 今日更新されたファイルの中で、0バイトのものを除いて検索し、Homeにコピー

```
find . -name "*.log" -mtime -1 -size +1c | xargs -i cp -p {} ~/
```

「今日発生したリジェクトファイルだけ」を探し当てる時とかに便利。


# 今回実行して発生したログファイルだけ抽出し、Homeにコピーする
Shellの実行時間を算出し、それを-mminオプションでfindしている

```
find . -maxdepth -name "*.log" -mmin -$proc_min | xargs -i cp -p {} ~/
```

処理時間$proc_minは以下のように算出できる（bash）

```
proc_min=`expr \( $SECONDS / 60 \) + 1`
```

C-shellならdateの差分でも取って下さい



#grepでCRLFを探す。
解説：http://qiita.com/akmiyoshi/items/cae34407849cb8c2da1a (akmiyoshi様)

```
$ find . -type f | xargs grep -lzUP '\r\n'
```



#grepでTabを探す。
なぜか"\t"で検索できない。

grep "まで手入力したあと、
[Ctrl+v]→[Tab]　でTabが挿入できるので、手実行する。

- - -

以上。
随時更新するつもりです。

くぎゅう10P
Ansibleのrolesが見つからずsyntax errorって言われる

### 概要
playbookが増えてきてサブフォルダにplaybookをまとめたときにroleが見つからなくなる。
この時実行するplaybookにはこういう感じでroleを指定しているとする。

```yaml
roles:
  - role: xbuild
```

実行したエラーが

```bash
The offending line appears to be:

  roles:
    - role: xbuild
      ^ here
```
みたいになってエラーの原因がわかりにくかったりする。

### tl;dr
ansible.cfgにroles_pathを書く
３分でわかる基本の関数型インタフェース

#はじめに
この記事は基本の関数型インタフェースの実装例を紹介した記事です。

普通はラムダ式で実装したり、Streamの中で使ったりすると思いますが、単純にするためにあえてそのへんを使わずにおなじみのメソッドを使っています。

"メソッドが変数に入る"っていう感覚をつかめればいいなぁと思って。（厳密にはクラスですが）

java.util.functionパッケージには４３の関数型インタフェースが定義されていますが、まず抑えておくべきは基本の４つです。この４つ以外は、これらの拡張型だと思っといて問題ないです。


#Supplier
何かを持ってて、与えてくれる人。抽象メソッドはget。引数なし、戻り値あり。

```java
import java.time.LocalDateTime;
import java.util.function.Supplier;

public class Main {
    public static void main(String[] args) {
        Supplier<LocalDateTime> s = LocalDateTime::now;
        System.out.println(s.get()); // -> 2017-01-11T16:29:08.086
    }
}
```

#Consumer
もらったものを処理する人。抽象メソッドはaccept。引数あり、戻り値なし。

```java
import java.util.function.Consumer;

public class Main {
    public static void main(String[] args) {
        Consumer<String> c = System.out::println;
        c.accept("test"); // -> test
    }
}
```

#Predicate
もらったものの真偽を返す人。抽象メソッドはtest。引数あり、戻り値あり（Booleanのみ）。

```java
import java.util.function.Predicate;

public class Main {
    public static void main(String[] args) {
        Predicate<String> p = ""::equals;
        System.out.println(p.test("foo")); // -> false
    }
}
```

#Function
もらったものを加工して返す、いわゆる関数。抽象メソッドはapply。引数あり、戻り値あり。

```java
import java.util.function.Function;

public class Main {
    public static void main(String[] args) {
        Function<String, Integer> f = Integer::parseInt;
        System.out.println(f.apply("55") + 45); // -> 100
    }
}
```
VBAからSlackやRocket.Chatにメッセージ投稿する

**2020/3/24 追記：内容が古くなったので全体のリライトと、proxy利用の方法と注意点を追記しました。**

ACCESSやEXCELで作られた既存の社内システムからアラートを投げたくなる時はありませんか？
これはVBAからIncoming Webhooks経由で、slackやRocket.Chatにメッセージを投稿する方法です。

# まずはslackのWebhook URLを発行
slackのIncoming Webhookの設定方法が昔と変わりました。こちらの記事を参考にWebhook URLを取得します。
参考： slackのIncoming webhookが新しくなっていたのでまとめてみた
https://qiita.com/kshibata101/items/0e13c420080a993c5d16

# Slackへの投稿
事前準備として、VBエディタの「ツール - 参照設定」から "Microsoft WinHTTP Services, version 5.1" にチェックを入れる。

```vbnet:VBA
TargetURL = "https://hooks.slack.com/services/xxxxxxxx/xxxxxxxx/xxxxxxxxxxxxxxxxxxxxx"
Set HTTPReq = CreateObject("WinHttp.WinHttpRequest.5.1")
' proxy経由の場合、下記を指定
' HTTPReq.setProxy 2, "192.168.0.1:3128"
HTTPReq.Open "POST", TargetURL, False
HTTPReq.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
HTTPReq.send ("payload={""text"":""ほげほげ\nほげほげ""}")
```

実行するとslackのチャンネルに投稿が来ます。

# Rocket.Chatへの投稿
上記コードのTargetURLを、Rocket.Chatのwebhookに変えてやればOKです。

```vbnet:VBA
TargetURL = "http://localhost:3000/hooks/xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

# 【注意点】windows7でproxy経由する場合

Ending support for TLS 1.0 and 1.1
https://medium.com/slack-developer-blog/ending-support-for-tls-1-0-and-1-1-423ae67a80b7

slackがTLS1.0/1.1のサポートを終了したため、windows7 でエラーが出るようになります。
簡単な解決方法は、Microsoftの "MicrosoftEasyFix51044" のパッチをあてる事です。
TLS1.2をデフォルトで使用するようになります。

参考：Windows 7でセキュリティエラーが出たら、SSLが有効なコンポーネントが残っていた
https://qiita.com/kitamin/items/eac07f4a5a104530ac59

# おわりに
proxy経由で外部にアクセスできるならslack通知、逆に閉じた環境ならオンプレミスで運用できるRocket.Chatなど良いと思います。

Rocket.Chat
https://rocket.chat/