OmniAICreator/Qiita-1.07M huggingface dataset:
The sample of numpy.logical_and.reduce and array indexing

```python
X = np.asarray([[1.0, 0.0, 3.0, 8.0],
                [2.0, 0.0, 1.0, 1.0],
                [1.5, 2.5, 1.0, 0.0]])
n = 4
M = np.logical_and.reduce(np.mod(X, 1) == 0, axis=-1)
print(M)
M &= (X.sum(axis=-1) == n)
print(M)
print(X[M])
M2 = [True, True, False]
print(X[M2])
print(X[np.array(M2)])
```
```
[ True  True False]
[False  True False]
[[ 2.  0.  1.  1.]]
[[ 2.  0.  1.  1.]
 [ 2.  0.  1.  1.]
 [ 1.  0.  3.  8.]]
[[ 1.  0.  3.  8.]
 [ 2.  0.  1.  1.]]
```
* The result of indexing with array and numpy.array(i.e. matrix) are different.

# Refs.
* [numpy.logical_and.reduce](https://github.com/rougier/numpy-100/blob/master/100%20Numpy%20exercises.ipynb)
主要Node.jsフレームワークのメモ


下記はよく使われているフレームワークとなり、情報量もある。

Expressはスタートアップからエンタープライズまで[広く使われており](https://stateofjs.com/2017/back-end/other/)、コミュニティも大きい。ただし、ある程度複雑なアプリケーションにはシンプルすぎるかもしれない。用途的には、HapiやKoaを採用した方がいい場合もあると考える。

## Express

- 35k GitHub stars
- 最も使用されている/コミュニティも大きい
- 情報量が多い
- Nodeの思想っぽく、シンプルなものを組み合わせてつくるという方針。そのため、ミドルウェアとして多くのライブラリが存在する。

## Koa

- 19k GitHub stars
- Express開発者によって開発された
- `async/await`が使用できる点でExpressと思想が異なる
- Expressよりは、HTTP middlewareである[Connect](https://github.com/senchalabs/connect)に近い。しかし、Expressの多くの機能はKoaに実装されつつある。
- Express同様、他のライブラリを組み合わせて実装していくスタイル

## Hapi

- 8k GitHub stars
- 中-大規模向け
- Expressと比べるとより`フレームワーク`としての機能がある
- シンプルなアプリケーションには大げさかもしれない
- 元はWalmartのエンジニアによって開発され、プロダクションでも使用されている

## Sails
## Egg
## Adonis
CheckstyleをバージョンアップしたらFileContentsHolderモジュールが無くなっていた

Checksyleをバージョンアップした所、エラーが発生したので備忘録として記載します。

リリースノートを見たところ、8.2でFileContentsHolderモジュールが削除されていました。
FileContentsHolderモジュールはSuppressionCommentFilterなどを有効にする時に使用するのですが、
エラーを解消する為にはxmlを修正する必要があるようです。

```xml:checksyle.xml(8.1まで)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
  <module name="TreeWalker">
    <module name="FileContentsHolder"/>
  </module>
  <module name="SuppressionCommentFilter"/>
</module>
```

```xml:checksyle.xml(8.2以降)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
  <module name="TreeWalker">
<!--
    <module name="FileContentsHolder"/>
-->
    <module name="SuppressionCommentFilter"/>
  </module>
</module>
```

8.2以降ではFileContentsHolderモジュールが削除されてしまった為、該当モジュールを呼ばないようコメントアウトしています。
また、Checkerモジュールにぶら下がっていたSuppressionCommentFilterモジュールをTreeWalkerの子モジュールとします。

修正したxmlを使用して再チェックした所、エラーは解消されました。

# 参考

+ [Checkstyle - Release Notes](http://checkstyle.sourceforge.net/releasenotes.html#Release_8.2)
The sample of diff, zeros_like, cumsum, linspace and interp in numpy

```python
phi = np.arange(0, 10*np.pi, 0.1)
a = 1
x = a*phi*np.cos(phi)
y = a*phi*np.sin(phi)
print(phi)
print(x)
print(y)
exit()
dr = (np.diff(x)**2 + np.diff(y)**2)**.5 # segment lengths
print(dr)
r = np.zeros_like(x)
print(r)
r[1:] = np.cumsum(dr)                # integrate path
print(r)
r_int = np.linspace(0, r.max(), 200) # regular spaced path
x_int = np.interp(r_int, r, x)       # integrate path
y_int = np.interp(r_int, r, y)
print(r_int, x_int, y_int)
```
# Refs.
* [diff](https://docs.scipy.org/doc/numpy-1.10.4/reference/generated/numpy.diff.html)
* [zeros_like](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.zeros_like.html)
* [cumsum](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.cumsum.html)
* [linspace](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.linspace.html)
* [interp](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.interp.html)
* [線形補間](https://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E8%A3%9C%E9%96%93)
Intellij IDEA で Gradle Project なのに Gradle Tool Window が表示されていない時の対処法

メニューの "Project From Existing Sources" を使ってプロジェクトを開きます。

ファイル選択ダイアログが表示されたら、 `settings.gradle` を選びます。 (私が経験したプロジェクトでは、これでいけました。)

* File -> New -> Project From Existing Sources ...

File の Open から `settings.gradle` を選択しても行けると思います。

### References

treehouse. (2016). _Gradle tool window missing_. Retrieved from https://teamtreehouse.com/community/gradle-tool-window-missing
Calculating inner product and outer product with numpy.einsum

```python
# Author: Alex Riley
# Make sure to read: http://ajcr.net/Basic-guide-to-einsum/

A = np.random.randint(0,10,10)
B = np.random.randint(0,10,10)
print(A)
print(B)
print("====einsum====")
np.einsum('i->', A)       # np.sum(A)
np.einsum('i,i->i', A, B) # A * B
X=np.einsum('i,i', A, B)    # np.inner(A, B)
print(X)
X=np.einsum('i,j->ij', A, B)    # np.outer(A, B)
print(X)
```
* e.g.

```
[8 6 8 5 7 9 6 4 6 8]
[5 8 5 6 3 4 2 3 7 5]
====einsum====
321
[[40 64 40 48 24 32 16 24 56 40]
 [30 48 30 36 18 24 12 18 42 30]
 [40 64 40 48 24 32 16 24 56 40]
 [25 40 25 30 15 20 10 15 35 25]
 [35 56 35 42 21 28 14 21 49 35]
 [45 72 45 54 27 36 18 27 63 45]
 [30 48 30 36 18 24 12 18 42 30]
 [20 32 20 24 12 16  8 12 28 20]
 [30 48 30 36 18 24 12 18 42 30]
 [40 64 40 48 24 32 16 24 56 40]]
```
# Refs.
* [内積、外積、テンソル積](http://hooktail.sub.jp/vectoranalysis/ReviewVectorProds/)
Ubuntu > security > package > DNE: Does Not Exist

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
```

MeltdownやSpectre関連の情報を見ていて下記の情報にたどりついた。
https://people.canonical.com/~ubuntu-security/cve/2017/CVE-2017-5753

> Ubuntu 16.04 LTS (Xenial Xerus):	DNE

DNEとは何か?

https://security.stackexchange.com/questions/134269/how-to-read-cve-2016-5696-correctly
> answered Aug 21 '16 at 17:16
Jonah B
>
>"DNE" means that the package does not exist within the lineage

Does Not Exist
の頭文字をとってDNEということのようだ。
The sample of numpy.ascontiguousarray and numpy.unique

```python
Z = np.random.randint(0,2,(6,3))
X = np.ascontiguousarray(Z)
print(X)
zdi = Z.dtype.itemsize
nd = np.dtype((np.void, zdi * Z.shape[1]))
print(nd)
T = X.view(nd)
_, idx = np.unique(T, return_index=True)
print(idx)
uZ = Z[idx]
print(uZ)
```
* e.g.

```
[[0 1 0]
 [0 1 1]
 [1 1 0]
 [1 1 1]
 [0 1 1]
 [1 1 0]]
|V24
[0 1 2 3]
[[0 1 0]
 [0 1 1]
 [1 1 0]
 [1 1 1]]
```
# Refs.
* [numpy.ascontiguousarray](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ascontiguousarray.html)
* [numpy.ndarray.flags](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ndarray.flags.html)
* [numpy.dtype](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.dtype.html)
node.js で公開鍵/秘密鍵によるデータの暗号化/復号

```js
import keypair from 'keypair'
import crypto from 'crypto'

const encrypt = (raw, publicKey) => {
  const encrypted = crpyto.publicEncrypt(publicKey, new Buffer(raw))
  return encrypted.toString('base64')
}

const decrypt = (encrypted, privateKey)=> {
  const decrypted = privateDecrypt(privateKey, new Buffer(encrypted, 'base64'))
  return decrypted.toString('utf8')
}

const pair = keypair()
const data = 'foo bar baz'

const encrypted = encrypt(data, pair.public)
console.log(encrypted)
const decrypted = decrypt(encrypted, pair.private)
console.log(decrypted)
```

注意: 簡単のため npm の keypair モジュールを使って公開鍵、秘密鍵を生成しているが、メモリ操作などによって脆弱な鍵を生成させられる可能性が排除できないので、 実際には openssl などの信頼できる実装を使ってください。
The sample of numpy.reshape with minus parameter, numpy.newaxis and numpy.unpackbits

```python
# Author: Warren Weckesser
I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128])
X = I.reshape(-1,1)
print(X)
Y = 2**np.arange(8)
print(Y)
Z = X & Y
print(Z)
B = (Z != 0).astype(int)
print(B[:,::-1])

# Author: Daniel T. McDonald

I = np.array([0, 1, 2, 3, 15, 16, 32, 64, 128], dtype=np.uint8)
X = I[np.newaxis,:]
print(X)
X = I[2:, np.newaxis]
print(X)
X = I[:, np.newaxis]
print(X)
print(np.unpackbits(X, axis=1))
```
```
[[  0]
 [  1]
 [  2]
 [  3]
 [ 15]
 [ 16]
 [ 32]
 [ 64]
 [128]]
[  1   2   4   8  16  32  64 128]
[[  0   0   0   0   0   0   0   0]
 [  1   0   0   0   0   0   0   0]
 [  0   2   0   0   0   0   0   0]
 [  1   2   0   0   0   0   0   0]
 [  1   2   4   8   0   0   0   0]
 [  0   0   0   0  16   0   0   0]
 [  0   0   0   0   0  32   0   0]
 [  0   0   0   0   0   0  64   0]
 [  0   0   0   0   0   0   0 128]]
[[0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 1]
 [0 0 0 0 0 0 1 0]
 [0 0 0 0 0 0 1 1]
 [0 0 0 0 1 1 1 1]
 [0 0 0 1 0 0 0 0]
 [0 0 1 0 0 0 0 0]
 [0 1 0 0 0 0 0 0]
 [1 0 0 0 0 0 0 0]]
[[  0   1   2   3  15  16  32  64 128]]
[[  2]
 [  3]
 [ 15]
 [ 16]
 [ 32]
 [ 64]
 [128]]
[[  0]
 [  1]
 [  2]
 [  3]
 [ 15]
 [ 16]
 [ 32]
 [ 64]
 [128]]
[[0 0 0 0 0 0 0 0]
 [0 0 0 0 0 0 0 1]
 [0 0 0 0 0 0 1 0]
 [0 0 0 0 0 0 1 1]
 [0 0 0 0 1 1 1 1]
 [0 0 0 1 0 0 0 0]
 [0 0 1 0 0 0 0 0]
 [0 1 0 0 0 0 0 0]
 [1 0 0 0 0 0 0 0]]
```
# Refs.
* [unpackbits](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.unpackbits.html)
* [What does -1 mean in numpy reshape?](https://stackoverflow.com/questions/18691084/what-does-1-mean-in-numpy-reshape)
render prop と HOC について

react-router の mjackson が HOC を批判していたので、自分の考えを書いておきます。

Use a Render Prop! - componentDidBlog https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce

## mjackson の主張の要約

- ES2015 Classes は mixin 的な振る舞いをサポートしていない
- HOC は 新しい mixin だ

## 主張1: HOC は自身の振る舞いを自己規定するものである

```js
const connector = ReactRedux.connect(...)
compose(
  connector,
  pure,
  lifecycle({
    componentDidMount() {
      console.log('mounted')
    }
  })
)(Counter)
```

これは

- store に connect され
- pure であり
- lifecylcle をもつ

というのは自己完結していて、外から与えられる属性ではなく、内側へ向けた定義です。ReactRedux の connect は文脈無視して props をシングルトンな store から捻り出すので、親から与えられる属性ではなく、自己定義的です。

自分は すべての Component が Stateless Functional Component として定義されるべきだと思ってるので、振る舞いを明示的に切り離す HOC は有意義であると思っています。

## 主張2: render props はライブラリが外から子の振る舞い(props)を規定するものである

とはいえ mjackson の主張に則れば Redux の connector は次のように書き直すこともできそう。

```js
<Connector
  mapStateToProps={state => state.counter}
  render={props => <Counter value={props.value}/>}
/>
```

こういうパターンも見ますね。

```js
<Connector
  mapStateToProps={state => state.counter}
>
  {props => <Counter value={props.value}/>}
</Connector>
```

これはAPIスタイル問題で、ライブラリ作者がどれを選ぶかという問題だと思うんですが、ユーザー側が選べる問題ではなく、
ライブラリ作者はとりあえず render props を採用する、というのはアリだと思います。

自己定義的なHOCはこれらのパターンからハズレて、別の役割を持っていると思います。

## 自分の思う HOC アンチパターン

とはいえ HOC が無駄に物事を複雑にするケースがあるという主張は理解できます。
例えばこういう形式のコードです。

```
compose(
  (hocA: HOC<A, B>),
  (hocB: HOC<B, C>),
  (hocC: HOC<C, D>)
): HOC<A, D>
```

これらが組み合わさって複雑になるときに、それぞれのHOCの順序に依存する、手を付けられない魔物が生まれるのは何度か経験しました。たとえば form 系ライブラリのバインディングと mapStateToProps が混ざるときです。

なので、 「state を扱う HOC は一個までとする」 みたいな縛りが必要だとは思っています。

## まとめ

- 暗黙に他のhocの順序または親のpropsに依存する HOC はいずれにせよアンチパターンである。
- HOC は自己規定であり、render prop はライブラリの削除
- ライブラリ作者は render prop で実装したほうがいい
no-login指定のユーザで起動したTomcatのThread dumpを取得してみた

#0. 今回お話しすること
+ TomcatのThread dumpを取得してみたよ
+ 'kill -3' だとcatarina.outに埋もれるから、別ファイルに書き出したよ
+ tomcatの実行ユーザがno-login指定だったからちょっと困ったけど解決したよ
+ AWS EC2 + Java + Tomcatという環境でお話しするよ

アプリケーションエンジニアが本業で、ミドルウェア〜インフラはまだまだヒヨッコです。
「当たり前だろ！」というところも優しい目で見守ってください。


#1. 前説

##1.1 'kill -3' の問題点
「Thread dumpといえば、'kill -3'でしょ！」
そういう環境で育ってきました。

もちろん'kill -3'でもThread dumpは取得できます。
できますが、問答無用でcatarina.outへと吐き出されます。

筆者はJava-Tomcatで環境構築しているのですが、
catarina.outといえば、各種ログが詰め込まれた"雑草地"です。

解析するためにThread dumpの結果部分だけを切り出すのがとてもしんどいのです。。。


##1.2 'no-login' ユーザの難点
仮想マシンを複数ユーザが共有する場合、利用する人ごとにユーザを発行するのが定石です。
また、Tomcatなどのミドルウェアを常時起動しておく場合、通常のユーザとは分けてそれ専用のユーザを発行し、そのユーザで起動することが多いかと思います。

私はこれまで「ミドルウェア実行用ユーザ」のアクセス制御をあまり考えてきませんでした。
しかし、実際にはこれらのユーザでログインする必要がないため、no-login指定をしてアクセスさせないようにしました。

するとどうでしょう。
この後お話しする'jstack'によるThread dumpは実行ユーザ自身でないと取得できないのに、'sudo su' でもログインできないではありませんか。

セキュリティを高くしたばっかりに、自分が締め出されてしまいました。。。


#2. 解決方法

##2.1 Thread dumpの結果をcatarina.out以外のファイルに

'kill -3'の代わりに、以下のように記述します。
```
jstack PID >> /PATH/FILE_NAME.log
```

※PID:  TomcatのプロセスID。psコマンドでわかる。
※/PATH/FILE_NAME.log: 結果を吐き出すパスとファイル名。
※「>>」は追記の意味なので、必要に応じて「>」に変えてください。


##2.2 no-login指定のユーザでログインするには

no-loginユーザは、ログイン時に"nologinシェル"が実行されることで、ログインできなくしています。
なのでログイン時に実行されるシェルを強制的に指定することでログインできるようになります。

```
su -s /bin/bash USERNAME
```

##2.3 自動的にスレッドダンプの結果を吐き出すためにcronに仕込んでみた（かなり強引）

jstackコマンドは、tomcatを実行しているユーザで実行しないと結果を出せません。（rootユーザでも不可）
そのため、tomcat実行ユーザでログインし、以下をcronに仕込んでみました。

もっときちんとつくることが望ましいですが、なるべく時間をかけず、ざっくり90%OKなラインで作ってみました。
より良い方法があれば是非教えてください。

```
jstack `ps aux | fgrep TOMCAT_USER | head -n 1 | cut -c 10-15` >> /PATH/FILE_NAME.log
```

※TOMCAT_USER: tomcatを実行しているユーザ名
※head -n 1: fgrepで絞り込んだ結果、複数ヒットするもののtomcatのプロセスが必ず先頭になるので先頭1行を抽出（なぜかはわからない・・・なお経験則なので確実でもない。よって強引。）
※cut -c 10-15:　先頭行のPIDがうまいこと引っかかるように文字列カット（ここもちょっと強引。）

このcronを仕込んだおかげで、これまでcatarina.outから頑張って見つけていたスレッドダンプがかなり楽にとれるようになりました。
IoT のための次世代ブロックチェーン IOTA について

IoT 分野での M2M マイクロペイメントを実現するために生まれた暗号通貨 IOTA の背景と仕組みについて、公式のホワイトペーパーや入門記事を読んで学んだことをまとめます。

## ブロックチェーン + IoT
![1_o-FtUGAGIsaSgvzsDsWqwA.png](https://qiita-image-store.s3.amazonaws.com/0/44003/49ce6928-412f-01ce-f6af-52af36360a69.png)

現在の　IoT エコシステムは、すべてのデバイスがクラウドサーバを介して互いに通信するクライアント/サーバアーキテクチャに基づいています。

ガートナー社は、2020年までには204億台の IoT デバイスが存在しているだろうと予測しています。
こうした集中型のアーキテクチャでは、IoT デバイスが爆発的に増えていくにつれて、スケーラビリティやセキュリティなどの問題を生じさせるだろうと言われています。通信を仲介するサーバにトラフィックが集中して遅延を生じたり、単一障害点になりサイバー攻撃に対して脆弱になったりしてしまいます。

ブロックチェーンは、デバイスが仲介を必要とせずにデータを交換できる技術として注目を集めています。

## ブロックチェーン技術の欠点

ブロックチェーン技術はもともと IoT 用途に作られたものではないため、多くの欠点があります。

### 取引手数料

取引手数料は、マイクロペイメント(少額決済)には適していません。取引される価値よりも高額な手数料を支払うことになります。2018年1月8日時点での [Bitcoin の平均取引手数料](https://bitinfocharts.com/comparison/bitcoin-transactionfees.html)は 31 USD (およそ
 3,514 JPY) です。
しかし、ブロックチェーン技術における取引手数料はブロック生成者(=マイナー)へのインセンティブとして働くため、取り除くことは困難です。

### スケーラビリティ

ブロックチェーンはその性質上、トランザクションが増えるほど時間がかかるというスケーラビリティ問題を抱えています。

2018年1月8日時点では 160,000 を超えるトランザクションが未承認です。トランザクションを承認させることができないばかりに、ユーザーにとって扱いづらく、ユースケースの大多数が実行できないことを意味します。もし早く承認させたければ、より多くの取引手数料を支払わなければいけません。

## IOTA とは

![iota.png](https://qiita-image-store.s3.amazonaws.com/0/44003/d65ec123-31cd-82fe-b4ea-b6ff51cb65b3.png)

IOTA (アイオータ/イオタ)は IoT 分野での M2M マイクロペイメントのために作られた仮想通貨であり、以下の特徴を持ちます。

- スケーラビリティ： IOTA は高いトランザクションスループットに到達可能です。それは並列検証が可能なためです。IOTA の並列検証では、一定間隔で承認されるトランザクションの数に制限がありません
- 取引手数料なし： IOTA には手数料がありません
- 非中央集権： IOTA にはマイナーが存在しません。トランザクションを発行するネットワーク参加者全員がコンセンサスに活動的に参加します。従って、IOTA は他のブロックチェーンよりも非中央集権的です
- 量子耐性： IOTA は Curl という名の新しい3進数のハッシュ関数を用いており、それが量子耐性となります（ヴィンテル二ッツ署名）

## Tangle の仕組み

IOTA の根幹となる分散台帳技術が Tangle です。Tangle とブロックチェーンの違いは、そのデータ構造と、合意形成に至るプロセスです。

### データ構造: 有向非循環グラフ
Tangle は有向非循環グラフ(DAG: Directed Acyclic Graph)に基づく分散台帳であり、ブロックチェーンとは異なるデータ構造を持ちます。

![import.png](https://qiita-image-store.s3.amazonaws.com/0/44003/64bacff7-6941-435c-49e1-8fe86291f89b.png)

Tangle グラフは、サイトと呼ばれるトランザクションの集合であり、トランザクションが他のトランザクションへの承認がエッジ(矢印)によって表されます。

### 合意形成: 取引発行者による承認

IOTA では重要な一つのルールがあります。それは **新規トランザクションを生成する際に過去の２つの未承認トランザクションを承認する必要がある** ということです。承認するトランザクションは MCMC(マルコフ連鎖モンテカルロ法) によってランダムに選ばれます。

![1_Co2IBbi8SxWZSJS5_UxkFw.png](https://qiita-image-store.s3.amazonaws.com/0/44003/3cbf42a0-ed61-dfdb-862e-d4713b5e21f2.png)

トランザクションが全て承認した状態のものが、完全に合意されたと見なされます。上記のグラフでは、

- グリーン: 完全に合意されたトランザクション。以後の新規トランザクションすべてが直接または間接的に承認する
- レッド: 完全な合意には至っていないトランザクション
- グレー: チップ。未承認トランザクション

を表しています。

このように、マイナーが存在せず、取引を行う人またはデバイスが過去の取引の承認を行うため、取引手数料を支払う必要がありません。
また、ブロックチェーンのように一定の間隔で限られた取引がブロック単位で合意されるのではなく、並列して取引単位で合意が行われます。そのため、取引が増えれば増えるほど安全性が高まり、効率性が向上します。


## 参考文献
- [なぜIoTの未来にブロックチェーンと分散元帳が必要なのか](http://www.huffingtonpost.co.uk/paul-mcneil/why-the-future-of-iot-nee_b_16948414.html)
- [IoTにブロックチェーンが必要な理由](https://channels.theinnovationenterprise.com/articles/sf-why-the-iot-needs-blockchain)
- [IOTA Tangle: Introductory overview of white paper for Beginners](https://medium.com/@jj1385jeff850527/iota-tangle-introductory-overview-of-white-paper-for-beginners-df9b14882b64)
- [IOTA入門](https://iotafan.jp/announcements/primer_on_iota-20170909/)
- [IOTA ~ポストスマートフォン時代のフィンテック~](https://qiita.com/tshiino48/items/6158ae77cd2ac3e56224)。
31億市場!? 　チャットの作り方 [1日コース]


（※この記事はJS初級〜中級の方向けの記事です）

![chat_market.png](https://qiita-image-store.s3.amazonaws.com/0/13827/970ec2de-c947-3c7a-5d97-d686927bf761.png)

チャットとか、ボットとか、
「何に使うんじゃい！」
...いやいや、今後使われるらしいですよ？

[**2021年にチャットボット市場は31.7億ドル**](http://c-bri.co.jp/799)までになる予想があります。

国内での関連情報**[「AI市場、年73％増の急成長続く」](http://itpro.nikkeibp.co.jp/atclact/active/17/100200154/120700020/)**では、
**「システム市場規模をユーザー支出額ベースで158億8400万円と推定」**と言っています。（※国内コグニティブAIに関する市場規模）

もう目的なんかなくても、とりあえず作り方マスターしましょう！

そんなわけで、業務で使えるレベルの本格的なチャットの作り方を、連載でまとめたいと思います。

わたくし仕事でWebチャット部品を作ってきた者ですが、
会社のみんなに「フロント側なら公開していいよー」て言ってもらえたので公開します。

## この記事の概要
サンプル程度のレベルではなく、本番のサービスで組み込めるレベルのWebチャットが開発できるようになる記事（にしたい）

※なおFirebaseは使います。

## 必要となる知識
- HTML/CSS
- Javascript
- JQuery

## 得られるモノ
- チームで開発するレベルの基本的なJavascriptの使い方（オブジェクト思考やMVCなど）
- 業務で使えるレベルのWebチャットのソースコード

作るものの最終的なイメージはこの様な感じです。
![goal_image.gif](https://qiita-image-store.s3.amazonaws.com/0/13827/f2edc80b-c77d-6581-d9a5-af93d5fda865.gif)




### 機能としてはこんな感じです
- リアルタイムなメッセージ送受信
- 機能追加が可能なメニューUI
- ステータス表示
- 書き込み中アニメーション
- 既読表示
- 日付の区切れの表示

実はまだ途中なので、全部書き切れるか不明ですが、
僕が飽きなければ全部書き切れると思います！

- **[1コマ目： 無料でカンタンにWebサイトを作る方法(2018)](https://qiita.com/st5757/items/ec7f5cc4eae0d73f332c)**（←チャットを設置するためのサイト準備）
- **[2コマ目： ゼロから作る、簡単WebチャットUIの作り方](https://qiita.com/st5757/items/ad4806c086b02a25d45d)**
- **3コマ目： [（ハンズオン用）HTMLをJavaScriptで効率よく組み立てる方法](https://qiita.com/st5757/items/1a64134cf6d4f5218e6e)**
- **4コマ目： 作ってわかる！はじめてのFirebase（データベースの基礎）**
- **5コマ目： 素のJavascriptでMVCを意識して作る**
- **6コマ目： Javascriptでクラス継承してみる**

---
↑いまこの辺までしか書いてない

- **7コマ目： Javascriptで書き込み中アニメーションを作ってみた**
- **8コマ目： textareaの高さを動的に変更する**
- **9コマ目： チャットの既読表示や日付表示（Web）**

おぉ...目次にしてみたら、かなりの量の記事になる気がする...

それでは次回[「1コマ目： 無料でカンタンにWebサイトを作る方法(2018)」](https://qiita.com/st5757/items/ec7f5cc4eae0d73f332c)からやっていきたいと思いますー
【MAYA】マテリアルのフェイスアサインがあるか無いかを判断する

マテリアルのフェイスアサインがあるか無いかを判断するプログラムを
https://qiita.com/harayoki/items/8ec88d8de7bb91357fc8
この辺りの考察を元に作ってみました。（こちらの記事から抜き出して移動しました。）
MAYA2018 + MacOS Sierraで動作確認しています。

SGへのコネクションがインスタンスオブジェクトグループとオブジェクトグループのどちらから伸びているかで確認しても良さそうですが、`objectGrpCompList`へフェイス番号が設定されているか確認するのでも良さそうなので、簡潔に書けそうなその判断でやってみます。

```python
import pymel.core as pm

def has_face_assign(shape):
    """
    シェイプにマテリアルのフェイスアサインがあるかどうか確認する

    :param shape: チェックするシェイプ
    :type shape: pymel.nodetypes.Shape
    :rtype: bool
    """
    instanceNumber = shape.instanceNumber()
    objectGrpCompList = \
        shape.instObjGroups[instanceNumber].objectGroups[0].objectGrpCompList
    num_face_block = (len(objectGrpCompList.get()))
    return num_face_block > 0
```
<img width="330" alt=" 2018-01-09 2.23.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/8302/47c28783-3c27-bb2f-1f0f-5a7698e73670.png">
こちらで動作検証します。

```python
shape = pm.PyNode('pCube1|pCubeShape1') # フェイスアサインのないシェイプ
has_fa = has_face_assign(shape)
print(has_fa)
#出力:False

shape = pm.PyNode('pCube2|pCubeShape1') # フェイスアサインのあるインスタンスシェイプ
has_fa = has_face_assign(shape)
print(has_fa)
#出力:True

shape = pm.PyNode('pCube3|pCubeShape2') # インスタンスが存在しないフェイスアサインのないシェイプ
has_fa = has_face_assign(shape)
print(has_fa)
#出力:False

shape = pm.PyNode('pCube4|pCubeShape3') #インスタンスが存在しないフェイスアサインのあるシェイプ
has_fa = has_face_assign(shape)
print(has_fa)
#出力:True

shape = pm.PyNode('pCube5|pCubeShape4') #マテリアルが外れてしまったシェイプ
has_fa = has_face_assign(shape)
print(has_fa)
#出力:False
```
問題なさそうです。
後から追加されたhtmlタグのイベント付与について

例題：\<div id="button1">を押したら\<div id="button2">が生成されるDOM(Document Object Model)がある。

１．htmlにイベントを持たせる手法・・・NG

$("button2").click(function(){
  alert("2つめクリック");
});

画面読み込み時にbutton2は存在しないためイベントが付与されない？

２．documentにイベントを持たせる手法・・・OK

$(document).on("click", "button2", function(){
    alert("2つめクリック");
});

クリックしたときにイベントを付与するため

参考サイト
https://qiita.com/negi/items/6ec0d3cedba499eac81a
GoogleHomeやChromecastのIPを確認してみた

google-home-notifierを設定している時にGoogleHomeのIPを確認する必要があったのでその時の手順をメモ


# GoogleHomeアプリから確認
**GoogleHomeアプリのデバイス登録をしている端末はすべてIPアドレスの確認が可能**
1. メニューのデバイスを選択

![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/85ec13a4-5912-62f9-a2bc-63f2b326d955.jpeg)

２．IPの確認を行いたいデバイスの**設定**を表示

![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/ad810b58-cfc9-f83c-7aad-3f18d0c2ca42.jpeg)

３．設定ページの**一番下**までスクロールする

![3.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/b53b1207-25d9-bbfc-1a62-9213e1b4a437.jpeg)

ファームウェアのバージョン、MACアドレス、現在割り振られているIPアドレスが確認できます

# iPhoneを使用してネットワーク内のデバイスのIPをまとめて表示

[Fing](https://itunes.apple.com/jp/app/fing-%E3%83%95%E3%82%A3%E3%83%B3%E3%82%B0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%84%E3%83%BC%E3%83%AB/id430921107?mt=8)というアプリを利用してネットワーク内のIPを確認することができます
**ネットワーク内のすべてのIPが確認可能**

![5.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/601a75fa-5d51-b38e-bb28-213f8534ff57.jpeg)

IPを指定して何か作業を行う場合や、ネットワークの見直し等いろいろ使うことができる便利なアプリだと思います。

# まとめ

GoogleHomeアプリを使用する前は[Fing](https://itunes.apple.com/jp/app/fing-%E3%83%95%E3%82%A3%E3%83%B3%E3%82%B0-%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%84%E3%83%BC%E3%83%AB/id430921107?mt=8)を使用してネットワーク内のIPを確認していたのですがGoogleHome、ChromecastについてはGoogleHomeアプリから確認の方が使いやすいと思います

**IPの確認方法をまとめてみましたがローカル上でIPを指定するような構築を行う場合はIPが変わらないようにDHCPで固定IP設定を行っておいたほうが良いでしょう。**
英語キーボードのPCから日本語配列設定のリモートデスクトップを使うときの対処アプリ

GPD Pocket を買いました。
いいんですが、問題は英語キーボードなことです。
何が問題かというと、リモートデスクトップで、他のPCに接続して使うときです。
接続先が、Windows の場合、ログインし直せばキー配列は正常になります。
けど、

* ログインし直したくないとき
* 接続先が Linux の場合

にも対処したいので、特定のアプリのみキー配列の変換をおこなうアプリを作ってみました。
まだ作りが荒削りですが、とりあえず動くものができたので公開。

[AppKeyChanger.zip](https://github.com/shii4c/AppKeyChanger/files/1612357/AppKeyChanger.zip)
[ソース(Github)](https://github.com/shii4c/AppKeyChanger)

## 制限事項

リモートデスクトップがフルスクリーンのときは、変換できません。
フルスクリーンでも使えるようにするには、以下の手順で設定変更してください。
（Windowsキーとか Alt+TAB とかが使えなくなりますが...）

* リモートデスクトップの接続ダイアログで「オプションの表示」をクリック
* 「ローカルリソース」タブをクリック
* 「キーボード」のところの「Windowsのキーの組み合わせを割り当てます」を「このコンピューター」にする
【MAYA】マテリアルのフェイスアサイン時のノード構成を理解する#2

この記事は、前の記事[#1](https://qiita.com/harayoki/items/81e0e3b7045d5f515087)からの続きです。

## フェイスアサイン＋インスタンス
フェイスアサインがある状態のシェイプからインスタンスを作成してみます。

<img width="369" alt=" 2018-01-09 1.25.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/8302/4b39e9e3-4be7-172d-b127-07218146186b.png">
インスタンスオブジェクトグループ(インスタンスそれぞれを示す)が１つ増えて、それぞれのオブジェクトグループ(フェイスグループを示す)から各SGへ接続が伸びています。予想通りです。

<img width="367" alt=" 2018-01-09 1.34.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/8302/808af3fc-f227-9181-6a7c-da79519efcbb.png">
子インスタンス側にSG3のマテリアルフェイスアサインを増やしてみました。インスタンスオブジェクトグループ1側にオブジェクトグループが１つ増え、SG3へコネクションが伸びています。ここも予想通りです。
（ここまで、コンポーネントのインスタンスオブジェクトグループ側の状態に変化はありません。）

で、思ったのですが、インスタンス間ではシェイプの形状はシェアしているものの、マテリアルの状態は完全別個で保持されているようなので、フェイスアサインをしたシェイプのインスタンスをガンガン増やすと、データ量がどんどん増えていく事にならないでしょうか。。

## 子インスタンス側だけにフェイスアサインする

<img width="386" alt=" 2018-01-09 1.41.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/8302/cee448ab-6628-ea91-89aa-0c486bc5188a.png">
まず、フェイスアサインする前にインスタンスを作ります。それぞれインスタンスオブジェクトグループからSGへコネクションが貼られています。

<img width="372" alt=" 2018-01-09 1.44.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/8302/57c17f5d-1cd0-96cc-acce-bd49bf8c455a.png">
子インスタンス側にマテリアルをフェイスアサインします。フェイスアサインがない方はインスタンスオブジェクトグループからSGへコネクションが貼られたままで、フェイスアサインがある方は、インスタンスオブジェクトグループ内のオブジェクトグループ側からSGへコネクションが貼られ直されました。やはり、コンポーネントのインスタンスオブジェクトグループ側の状態に変化はありません。

とりあえず、インスタンスが絡んでもわかりづらいノードグラフになる事は無いようです。

なお、

```python
objectGroup = shape.instObjGroups[0].objectGroups[0]
attrs = (objectGroup, objectGroup.objectGrpCompList,
  objectGroup.objectGroupId, objectGroup.objectGrpColor)
for a in attrs:
    print('{}({}) : {}'.format(a, a.type(), a.get()))
#以下、出力:
#pCubeShape1.instObjGroups[0].objectGroups[0](TdataCompound) : [[], 0, -1]
#pCubeShape1.instObjGroups[0].objectGroups[0].objectGrpCompList(componentList) : []
#pCubeShape1.instObjGroups[0].objectGroups[0].objectGroupId(long) : 0
#pCubeShape1.instObjGroups[0].objectGroups[0].objectGrpColor(short) : -1
```
フェイスアサインのないシェイプに対しても`objectGroups`及び`objectGrpCompList`へのアクセスはできました。対応フェイス番号がなしになっています。

#一旦まとめ
* マテリアルのフェイスアサインを行うとノードグラフが複雑になる
* が、本質的にはインスタンスオブジェクトグループ以下を見れば良い
* シェイプのインスタンスが絡んでもそこまで複雑にならない
* フェイスアサインのあるシェイプのインスタンスをガンガン作ると管理が面倒になりそう
* コンポーネントのインスタンスオブジェクトグループについてはよくわからない。デフォルトのマテリアルアサイン？

コンポーネントのインスタンスオブジェクトグループについて何か調査が進んだら#3を書きたいと思います。
英文で構わないので、解説のあるリンクなど知っている方は教えていただけると幸せ。
Jupyter Notebook上でRを使えるようにする

Jupyter Notebook上でRを使う環境設定の参考になればと思い書きました！！

# 環境
macOS High Sierra (10.13.2)

# Rのインストール
Rがmacに入っていなかったので、この[R for mac OS](https://cran.r-project.org/bin/macosx/)からパッケージをインストールします。

そしてターミナル上で

```
$ r
```

と入力してRのインタプリタを起動します。

# RとJupyter Notebookをつなぐ

以下のコマンドでバイナリーパッケージをインストールします。

```
> install.packages(c('repr', 'IRdisplay', 'evaluate', 'crayon', 'pbdZMQ', 'devtools', 'uuid', 'digest'))
> devtools::install_github('IRkernel/IRkernel')
```

そしてRとJupyter Notebookをつなぐために次の２つのコマンドを実行します。

```
> IRkernel::installspec()
> IRkernel::installspec(user = FALSE)
```

これでブラウザ上で開いてるJupyter Notebookのhome画面でnewタブを押してRが選択肢に入って入れば完了です。
fixpackでpackage.jsonの各項目を並び替える

Node.js でコードを書くときに、必ず目にする `package.json`。
その、`package.json` に関する知見である。

## `package.json` の並び順

`package.json` の並び順であるが、私は「[package.json | npm Documentation](https://docs.npmjs.com/files/package.json)」に書かれている順番で記述することが多い。(デファクト・スタンダードか公式に沿っておくのが無難である)

しかし、毎回手動で並び替えるのは手間である。
そこで、[fixpack](https://github.com/henrikjoreteg/fixpack) を利用してフォーマットすると良い。

## fixpack で並び替える

### インストール

グローバルにインストールする。

```
$ npm i -g fixpack
```

### fixpack を使う

`package.json` が存在するディレクトリで、以下を実行する。
デフォルトでは、`name` `description` `version` `author` の順で並び替えて、残りをアルファベット順で並び替える。

```
$ fixpack
```

### 並び順を設定ファイルで指定する

自分で決めた並び順にしたい場合は、設定ファイルで上書きすることができる。
`$HOME` ディレクトリに `.fixpackrc` を作成して、JSON形式で書いていく。


### 筆者の `.fixpackrc`

参考までに、自分の `.fixpackrc`　を貼っておく。


```json:.fixpackrc
{
  "sortToTop": [
    "name",
    "version",
    "description",
    "keywords",
    "homepage",
    "bugs",
    "license",
    "author",
    "files",
    "main",
    "bin",
    "man",
    "directories",
    "repository",
    "scripts",
    "config",
    "dependencies",
    "devDependencies",
    "peerDependencies",
    "bundledDependencies",
    "optionalDependencies",
    "engines",
    "os",
    "cpu",
    "private",
    "publishConfig"
  ],
  "required": [
    "name",
    "version"
  ],
  "warn": [
    "description",
    "keywords",
    "homepage",
    "bugs",
    "license",
    "author",
    "main",
    "repository"
  ],
  "sortedSubItems": [
    "files",
    "directories",
    "dependencies",
    "devDependencies",
    "peerDependencies",
    "bundledDependencies",
    "optionalDependencies"
  ]
}
```

`sortToTop` が並び順の指定である。
並び順以外にも、無いとエラーを吐く項目の指定や、無いと警告を出す項目の指定などを行っている。
他にも幾つかの設定項目があるので、[README.md](https://github.com/henrikjoreteg/fixpack#configuration) を見ると良い。

## まとめ

`package.json` の各項目の並び替えには [fixpack](https://github.com/henrikjoreteg/fixpack) を利用すると良い。
Postfixのmailbox_size_limitについて調べてみる

# 前置き
あるエントリの補足として調べていたら脱線しすぎたので別エントリとして作成。

# mailbox_size_limitとは？
Postfixでは1メッセージ（=メール）あたりの制限*message_size_limit*とMailbox(mbox)あたりの制限*mailbox_size_limit*がある（他にもあるが今回は省略）。基本的にMailboxはユーザごとに作られるため、*mailbox_size_limit*はメールアカウント毎の容量制限となる。
設定で*Maildir/*形式を利用している場合は前者のみ気にしていればいいが、*Mailbox*形式だとIMAPを利用している場合は受信トレイ、POP3の場合はサーバに残るメールの容量上限となる。
もし**受信したメールをMailboxに追記した時、この上限を超える**ようだとメールは保存されず送信者に対してMAILER-DAEMONからエラーメッセージが返信される。その後より小さなメールが届いて上限を超えないようならそのメールは保存される。

# 具体的なmailbox_size_limitの上限値
ググると初期値が50MB(5120000)とか0を指定すると無制限になるとか出てくるが、本当に無制限になるとかありえないので実際はいくらなのか調べてみる。

Postfix 2.xの早いバージョンでは[経験的に2GBであると知っていた](http://www.postfix-jp.info/ML/arc-2.4/msg00103.html)。これにより上限は2^31-1バイトで、`mailbox_size_limit = 2147483647`となる。

[Postfix 2.9からは2GB以上のMailboxサイズに対応](https://github.com/vdukhovni/postfix/blob/785264774f13d220deed7cb27785b55b5d632621/postfix/RELEASE_NOTES-2.9#L265)したようで、ソースの*postfix/src/global/mail_params.h*を確認すると確かにPostfix 2.8まではintだったものがlongへと置き換わっている（ただし*message_size_limit*は10MBで変わりないので初期値は*message_size_limit\*5*の50MBのまま）。
つまり[2^63-1](https://en.wikipedia.org/wiki/9,223,372,036,854,775,807)バイト（8EiB）までメールボックスが大きくなっても大丈夫！
また、もとはintであったことから前述の2GiB制限とも合致する。

実際にPostfix 2.10で`mailbox_size_limit = 9223372036854775807`だとメール受信可能だが、`mailbox_size_limit = 9223372036854775808`にするとmaillogにエラーが記録され受信できなくなる。
なお、この設定値はメールを受信して保存する際まで実際に評価されることが無いため、`postconf`とか`postfix check`で設定値が正常か異常か判断することができないのが厄介。

従って、`mailbox_size_limit = 0`と指定することでPostfix 2.8以前では2GiB-1バイトが、Postfix 2.9以降では8EiB-1バイトがMailboxの上限となる。

ちなみに標準ではCentOS 6ではPostfix 2.6、CentOS 7ではPostfix 2.10となっている。
Nuxt.js で Vuetify.js を使う

`Nuxt.js` 用の `Vuetify.js` プラグイン [@nuxtjs/vuetify](https://www.npmjs.com/package/@nuxtjs/vuetify) が用意されているのでそれを使う。



## インストールと設定

[@nuxtjs/vuetify](https://www.npmjs.com/package/@nuxtjs/vuetify) をインストール

```bash
$ yarn add @nuxtjs/vuetify
```

続いて `nuxt.config.js` を編集

```javascript
// file: nuxt.config.js
module.exports = {
  modules: [
    // この行を追加して有効化
    '@nuxtjs/vuetify'
  ],

  vuetify: {
    // Vuetify の設定はここに書く
    theme: {
      primary: '#3f51b5',
      secondary: '#b0bec5',
      accent: '#8c9eff',
      error: '#b71c1c'
    }
  }
}
```

## 使ってみる

とりあえず `layouts/default.vue` に[サンプル](https://github.com/vuetifyjs/vuetifyjs.com/blob/master/src/examples/layouts/baseline.vue)のコードをそのまま入れて確認。



```html

// file: layouts/default.vue
<template>
  <v-app id="inspire">
    <v-navigation-drawer
      fixed
      v-model="drawer"
      app
    >
      <v-list dense>
        <v-list-tile @click="">
          <v-list-tile-action>
            <v-icon>home</v-icon>
          </v-list-tile-action>
          <v-list-tile-content>
            <v-list-tile-title>Home</v-list-tile-title>
          </v-list-tile-content>
        </v-list-tile>
        <v-list-tile @click="">
          <v-list-tile-action>
            <v-icon>contact_mail</v-icon>
          </v-list-tile-action>
          <v-list-tile-content>
            <v-list-tile-title>Contact</v-list-tile-title>
          </v-list-tile-content>
        </v-list-tile>
      </v-list>
    </v-navigation-drawer>
    <v-toolbar color="indigo" dark fixed app>
      <v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
      <v-toolbar-title>Application</v-toolbar-title>
    </v-toolbar>
    <v-content>
      <v-container fluid fill-height>
        <v-layout
          justify-center
          align-center
        >
          <v-tooltip right>
            <v-btn icon large :href="source" target="_blank" slot="activator">
              <v-icon large>code</v-icon>
            </v-btn>
            <span>Source</span>
          </v-tooltip>
        </v-layout>
      </v-container>
    </v-content>
    <v-footer color="indigo" app>
      <span class="white--text">&copy; 2017</span>
    </v-footer>
  </v-app>
</template>

<script>
  export default {
    data: () => ({
      drawer: null
    }),

    props: {
      source: String
    }
  }
</script>
```

開発用のサーバーを起動。

```
$ yarn dev
```

`http://localhost:3000` にアクセスして確認。

![Screen Shot 2018-01-09 at 1.52.22.png](https://qiita-image-store.s3.amazonaws.com/0/186574/d0e8ef0d-cc6d-55df-8780-78cbb5fabd24.png)


いい感じ
YouTubeの再生回数(View)を増やすサービスを使ってみた

自分がYouTube動画を見ると他の人が指定のYouTube動画を見てくれるというサービスが有ることを知ったので試してみました



# サービスを利用するために

基本無料で使うことができますが手っ取り早く再生回数を増やしたい場合は有料のプランもあるようです。

 [ytmonster](https://www.ytmonster.net/register?ref=fstyle)にアクセスして新規登録を行います

![12.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/6f878197-c310-483c-6417-2d921f1d656f.jpeg)

アカウント名、メールアドレス、パスワードを設定してアカウントを作成します。

新規登録を行うとアクティベート用のメールが送られてくるので認証します。
これでサービスを利用する準備が整いました。

# 実際に使ってみた

最初は25件動画を再生する必要があるようですが実際に見る必要はなくタブで開いて放置してくだけで自動で25件再生が完了していました。（25件再生を行わないと再生回数を増やしたい動画の登録が行なえません）

## 動画を再生

１． ログイン状態で画面右上の「Client」の部分をクリックします

![2.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/4d146ac2-5bf7-b17d-4383-75f48d34e146.jpeg)


２．青いボタンになっている「Open」リンクをクリックします

![3.gif](https://qiita-image-store.s3.amazonaws.com/0/223901/284e0de7-0041-960b-2c5f-40579555f94f.gif)

３．「Start」ボタンをクリックして動画の再生を開始

![4.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/f570ae3d-ffa5-a289-9098-319e90294441.jpeg)

***上記手順を複数回繰り返すことで複数タブで同時再生が可能でした***



# 見てもらいたい動画を設定する
***25件動画を見ないと見てもらいたい動画の設定ができません***

１．右メニューの「Campaigns」ページを表示

![5.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/20adfe0f-232f-5a3e-a3ca-79423a2eab59.jpeg)

２．「Campaigns」ページの右上の「+New Campaign」をクリック

![6.jpg](https://qiita-image-store.s3.amazonaws.com/0/223901/11dd4920-33f5-5b0f-444d-be9ecf326a27.jpeg)

３． 内容を登録

```
・YouTube URL
対象の動画のURLを設定

Type
再生回数であればViewを選択

View Length
動画の再生時間を指定。短すぎてもと思い90を設定してみました

Amount
動画を閲覧するとポイントが貯まるのでそのポイントの上限まで再生数を設定しました
```


４．あとは待つだけ

20件の再生回数を試したところ1時間後に確認したら完了していました。
**同じ動画を再度指定する場合は12時間経過しないと指定できません**

# まとめ

 [ytmonster](https://www.ytmonster.net/register?ref=fstyle)　自体の仕組みは面白いなと思いました。
ただ長期で使用しているわけではないのでこちらのサービスを利用することで再生回数を上げた動画がどういうペナルティを受ける可能性があるのかが気になるところではあります。
あまり無茶な使い方をしない限りはYouTuberさん向けの良いサービスなのかなという印象でした。

**実際にサービスを利用して再生回数を増やしてみましたが、再生回数が増えて特にペナルティも受けていません。**


YouTubeに動画を投稿後再生回数が全く増えないという方は自己責任で検討して見るかちはありあそうです。
(広告表示までの時短としては有効です)

# YouTube公式ヘルプ

[YouTube での再生回数を増やす行為について](https://support.google.com/youtube/answer/3399767?hl=ja)
餓死したくないのでslackで監視する

# 毎日のご飯3食食べるのはむずかしいので監視
毎日ごはんを食べたらslackチャンネルに投稿するようにする習慣をつけようと思います。
そのために(例えば)11時, 16時, 24時 など3食食べたあとっぽい時間に自動で下のコードを叩くようにしていきます。
過去6時間以内に発言がなかった場合、ご飯を食べていないとみなし、パスワードを少しずつ公開していくコードですのよ。


# コード
適宜変えてね

```python3

import requests
import datetime
import random

if __name__ == "__main__":

    with open("slacktoken") as f:
        token = f.read()
    channel = "C******"  
    myid = "U******" 
    now = datetime.datetime.now().timestamp()
    r = requests.post(
        "https://slack.com/api/channels.history",
        data={
            "token": token,
            "channel": channel,
        },
    )
    # 自分の発言かどうかと経過秒数を記録
    messages = r.json()["messages"]
    messages = [(x["user"] == myid, now - float(x["ts"]) ) for x in messages if "user" in x and "ts" in x]
    mines = [x[1] for x in messages if x[0]]
    # 6時間以内に食べていない(自分の発言がない)場合やばい
    if len(mines) > 0 and min(mines) < 6 * 3600 :
        text = "ちゃんとご飯を食べてえらいっ"
    else:
        # やばいのでぱすわーどこうかい
        with open("passtoken") as f:
            password = f.read().split("\n")[0]
        index = random.randrange(len(password))
        text = """
        ちゃんとご飯を食べてなさそうなのでパスワード公開タイムっ
        **** の **** の{}文字のパスワードのうちの第{}文字目は
        {} だよ！
        """.format(len(password),index + 1,password[index]).replace("  ","")
    print(text)
    requests.post(
        "https://slack.com/api/chat.postMessage",
        data = {
            "token":token,
            "channel":channel,
            "link_names":1,
            "text": text,
            "username": "****",
            "icon_url":"http://****",
        }
    )
```

# さいごに

ご飯を食べるのわすれないようにするぞー
vim環境を入れてみた(※編集中)

#経緯
今までエディタへの興味は特になかったのですが、とある場所で、
「すごいエンジニアというものは必ず開発の環境への愛を持っている」という話を聞きまして
鵜呑みにした私がまず注目したのがエディタ。
普段はサクラエディタを使っていたのですが、いろいろ調べるうちにVimなるエディタが人気だと知り、
人気があるからにはよいものだろうと早速使ってみることにしました。

#手順
(環境:Windows10の場合)
①下記URLからVimをダウンロード
https://www.kaoriya.net/software/vim/

②上記URL内「その他」からvimdoc-ja「Vimドキュメント翻訳プロジェクト on github」
を参考
iOS upnpx で UPnP デバイスをブラウズ（その1 デバイス発見まで）

# upnpx

VLC でも使われているとか
https://code.google.com/archive/p/upnpx/
https://github.com/fkuehne/upnpx

CocoaPods でインストール

```
  pod "upnpx", "~> 1.4.0"
```

# UPnPデバイスの検索

UPnPDB に UPnPDBObserver を追加し、ssdp の searchSSDP を呼ぶ。

```swift
import upnpx

class RootViewController: UITableViewController {

    var devices: [BasicUPnPDevice] = [] {
        didSet {
            DispatchQueue.main.async { [weak self] in
                self?.tableView.reloadData()
            }
        }
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        searchUPnPDevices()
    }

    var upnpDB: UPnPDB?
    func searchUPnPDevices() {
        guard upnpDB == nil else { return }
        guard let db = UPnPManager.getInstance().db else { return }
        db.add(self)
        upnpDB = db
        _ = UPnPManager.getInstance().ssdp.searchSSDP
    }
    ...
}
```

UPnPDBObserver プロトコルを実装し、デバイス検出の通知を受けとる。

```swift
extension RootViewController: UPnPDBObserver {
    func uPnPDBWillUpdate(_ db: UPnPDB!) {
        print(#function)
    }
    func uPnPDBUpdated(_ db: UPnPDB!) {
        print(#function)
        if let devices = db.rootDevices as? [BasicUPnPDevice] {
            self.devices = devices
        }
    }
}
```

画面表示はよしなに。

```swift
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return devices.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "device", for: indexPath)
        let device = devices[indexPath.row]
        cell.textLabel?.text = device.friendlyName
        cell.detailTextLabel?.text = device.baseURL.host
        if device as? MediaServer1Device != nil {
            cell.accessoryType = .disclosureIndicator
        } else {
            cell.accessoryType = .none
        }
        return cell
    }
```

# 結果

<img width="526" alt="スクリーンショット 2018-01-09 0.34.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/121719/c7e8b7db-d306-2420-0ff3-f2bdf2e381fd.png">

つづく
Rust で mut self と self の互換性

以下のようなtraitがあったとき、

```rust:trait
trait BarTrait {
    fn bar(self, x: i32);
}

```

以下のように、`self`や他の引数に`mut`を付けてもimplできる（問題なくコンパイル可能）

```rust:impl
struct Foo {
    x: i32,
}

impl BarTrait for Foo {
    // selfとxに、それぞれBarTraitの定義にはなかったmutが付いている
    fn bar(mut self, mut x: i32) {
        self.x += 1;
        x += 1;
        println!("bar for foo: {} {}", self.x, x);
    }
}
```

mutの有無は関数内部の実装の問題で、外から見たIFには影響しない。
（C++でも、メソッドの宣言と定義で値引数の`const`の有無が異なったり、override時に値引数の`const`の有無が異なっても問題ない（ポインタ引数での向き先の`const`の有無に関してはもちろん駄目））

さらに、以下のように`mut`付きで定義したメソッドのドキュメントでは、自動的に`mut`が省かれる:

```rust
impl Foo {
    /// foo
    pub fn foo(mut self, mut x: i32) {
        self.x = 0;
        x = 1;
        println!("{} {}", self.x, x);
    }
}
```

```:ドキュメントを生成
cargo doc
```

|![foo.png](https://qiita-image-store.s3.amazonaws.com/0/80237/04e07b31-1323-bde4-9b13-11a53ea44c03.png "生成されたドキュメント")|
|:-:|
↑生成されたドキュメント。selfとxにmutが付いていない。

## 補足
実際、たとえ`mut`を付けずに実装しても、以下のようにすればいくらでも後から`mut`に変更可能。

```rust
    fn bar(self, x: i32) {
        let mut mself = self;
        let mut x = x;
        ...
```

引数の`mut`の有無に本質的な違いはないことが分かる。
（もちろん、`&self`と`&mut self`だとこうはいかない）
Swiftensions っていうライブラリ作りました

こんにちは **だっちゃん** デス 🙇

**Qiita** を書こうと思いなかなか書けずにいたので、2018年だし、平成30年だし、🍺🍷飲んでるノリで書きます‼️

基本的に難しいこと書けないので、ちょっとしたメモなどを書いていきたいと思います。
今後とも、宜しくお願いします。🙇



## Swiftensionsとは

`Swift` で実装している時に、 `Array` のシャッフル機能や、 `UIDevice` を使った端末名の取得など、あったら便利だなっていう機能をまとめたライブラリです。

Github: [dacchan/Swiftensions](https://github.com/dacchan/Swiftensions)


## 今ある機能
### Foundation
#### Array
- シャッフル機能


#### Bundle
- ショートバージョン取得
- ビルドバージョン取得
- 表示名（アプリ名）取得
- URLSchemeの一覧取得


#### Calendar
- カレンダー情報を各 `暦` ごとに取得


#### IndexPath
- `section` と `row` をTupleで取得
  - `UITableView` で `Static Cells` を使ったときのアクセスで便利に
  - `tupleForTable` なんてしてますが、 `Table` に限定しなくてもよかったですが・・・ 😓


#### Number
- `==` や `+` などのオペレーター機能
  - `Int` や `Float` とか毎回 `Number` 型への変換が不要になります


#### Optional
- `Scala` や `Java` の `orElse` 的な


#### Sequence
- `filter` と `count` を合わせた、条件にあう件数を取得


#### String
- 各文字コードごとの文字数取得
- 文字列のローカライズ
  - まだ未実装に近いですけど・・・ 😅

#### URL
- `URL` に含まれるクエリーパラメータを `Dictionary` に変換


### UIKit

#### UIDevice
- `iPhone` や `iPad` の端末名取得


#### UINib
- `UINib` を簡易指定名で取得
  - `reuseIdentifier` にクラス名を設定している場合だけ


#### UIView
- クラス名の取得
- `UINib` 名の取得
  - `reuseIdentifier` にクラス名を設定している場合だけ
- `reuseIdentifier` の取得
  - `reuseIdentifier` にクラス名を設定している場合だけ
- `View` の上下左右にボーダーを設定
- `View` の角丸を設定
- `View` を丸くする
- `View` を三角形にする


## 今後は
ユニテ全然書いていないのでまずは実装済の機能に対してのユニテ書いていきます。
もちろん、[Circle CI](https://circleci.com)も設定します。

あとは定期的に機能を実装していきたいですね。
最近はサボり気味なので・・・ 😰💦

[Swiftensions](https://github.com/dacchan/Swiftensions) よろしくお願いします‼️
samtoolsでvariant call

#samtools(bcftools)を使ってvariant call
ヒト以外のモデル生物とかモデル生物じゃないもののvariant callingをしたいときは、samtools mpileupを使ってvcfを作りましょう。

##準備
- samtools
- bcftools
- vcfutils.pl

アプリのダウンロードは[http://www.htslib.org/](http://www.htslib.org/)から
インストールは上記ページに書いてある通りに
(`make` -> `./configure` -> `make install`)
vcfutils.plは追記

reference(下の例では`ref.fa`)は`samtools faidx`でインデックスをつけておく
(いらないかも）

```
samtools faidx ref.fa
```

##コマンド
Samtools mpileup -> bcftools call でvariantを抽出

SNPと短いINDELが取れてくるはず

```bash:variant_call.sh
samtools mpileup -uf <ref.fa> -t AD,INFO/AD,DP,DV,DPR,INFO/DPR,DP,DP4,SP -v <hoge1.bam> <hoge2.bam> | bcftools call -c -v -o hoge_variant.vcf.txt

vcfutils.pl varFilter hoge_variant.vcf.txt > filterd_hoge_variant.vcf.txt
```
- samtools mpileupのオプション

-u ;uncompressed 出力
-f file ;リファレンスファイル指定
-t list ;追加するタグを指定
-v ;VCFを出力（このオプション無しでもbcftoolsで読めるようだけど試したことはない）

- bcftools callのオプション

-c ;original calling method (multi allelic, rare variantは-mを使うように、と説明には書いてある）
-v ;VCFを出力
-o ;出力先ファイル名指定

[samtoolsのマニュアル](http://www.htslib.org/doc/samtools.html)
"*.vcf"だけだと住所録ファイルのvcf形式として認識されてしまうので、後ろに　".txt"をつけておく


##bcftoolsでmpileupもできるらしい

```
bcftools mpileup -Ou -f <ref.fa> <sample1.bam> <sample2.bam> <sample3.bam> | bcftools call -vmO z -o <study.vcf.gz>
```
- bcftools mpileupのオプション

-Ou ;uncompressed BCF出力
-f file ;リファレンスファイル指定


#positionごとのGenotypeカウント
`filterd_hoge_variant.vcf.txt`をRで読みこむ

multi sample callingの時、判定されたgenotypeのカウントをします

0/0 -> refと同じ
0/1 -> ヘテロ
1/1 -> ホモ

##準備(必要なパッケージ)
- VariantAnnotation
[Bioconductorより](https://bioconductor.org/packages/release/bioc/html/VariantAnnotation.html)

##Rのコード
```R:genotype_count.r
library(VariantAnnotation)

in_f <- "filterd_hoge.vcf.txt"
out_f <- "count_gt_filterd_hoge.txt"

vcf <- readVcf(in_f,"hoge")　

GT <- geno(vcf)$GT　
ct <- apply(GT,1,table)
none <- sapply(ct,"[", "0/0")
hetero <- sapply(ct,"[","0/1")
homo <- sapply(ct,"[","1/1")
x <- cbind(row.names(GT),none,hetero,homo)
write.table(x,file=out_f,quote=F,sep="\t",row.names=F,col.names=T)
```
Assume-role先のRoleの権限で(AWSの機能|vagrant|terraform|serverless|apex)を使いたい

## 背景

[AWS CLIがAssumeRoleによる自動クレデンシャル取得とMFAに対応しました！ ｜ Developers\.IO](https://dev.classmethod.jp/cloud/aws/aws-cli-supports-assume-role-credentials-provider-and-mfa/)
awscliは上記で説明されているような記述を用いることにより、assume-role権限のあるroleへswitchしてコマンドを実行することができます。

しかし、この記述法は比較的最近導入されたこと、使用されることがそれほど多くないこと、内部的にSTSを使っているため自前で同様の仕組みを実装することは手間がかかることなどにより、通常 `~/.aws/credentials` を見て自動的に認証情報を取得してくれるコマンドでもこのAssumeRole記法に対応してくれていないツールがあります(代表的なものにserverless, apex, terraform, vagrant-awsがあります)。

## 解決策

そこで、[認証情報として環境変数が概ね優先される](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-getting-started.html#config-settings-and-precedence)ことを利用してラッパーコマンドを開発した人が結構います。
マイナーな欲求かつ簡単に実装できるため多数のリポジトリがありますが、以下がgithub上で自分が見つけた同様の目的のリポジトリ一覧です。

* ★99 [remind101/assume\-role: Easily assume AWS roles in your terminal\.](https://github.com/remind101/assume-role)
* ★24 [jbuck/assume\-aws\-role: Work with multiple AWS accounts more easily](https://github.com/jbuck/assume-aws-role)
* ★5 [fujiwara/aswrap: AWS assume role credential wrapper](https://github.com/fujiwara/aswrap)
* ★3 [mmmorris1975/aws\-runas: A wrapper command to prepare the environment, or execute a command, using an AWS IAM role](https://github.com/mmmorris1975/aws-runas)
* ★0 [cayasso/aws\-assume: AWS easy switch role](https://github.com/cayasso/aws-assume)

(※星の数は2018/01/09時点)

上記のリポジトリのうち、上2つは期待通り動くことを確認しました。
下3つはすみませんが動作確認をしていません。

## 結論

remind101/assume-role が期待通り動作しておりかつ星の数的にも定評があると思うので、機能的に問題なければそれを使えばいいと思います。
ちょっとずつ読むドメイン駆動設計 第四部 戦略的設計 第十五章 蒸留5 強調されたコア

# 前回までの第十五章

[コアドメイン1](https://qiita.com/YasuhiroKimesawa/items/899d1b3fd58ca91f525a)
[コアドメイン2](https://qiita.com/YasuhiroKimesawa/items/1aee3602d3aea1cb5b91)
[汎用サブドメイン](https://qiita.com/YasuhiroKimesawa/items/be23f3bd11626265f552)
[ドメインビジョン声明文](https://qiita.com/YasuhiroKimesawa/items/75e270b7d9a624823c1a)

# 強調されたコア

## 鳥の目のドメインビジョン文書と虫の目の強調されたコア

ドメインビジョン文書はいわば広い観点でコアドメインを識別するもの。
強調されたコアは具体的なコアドメインの要素の識別をするためのものです。

具体的には、モデルに印をつけてこれがコアドメインだと提示するもの。やり方は２つ。

## 蒸留ドキュメント

コアドメインの一覧をドキュメント化するもの。形式は特に指定されていません。

お勧めは**概念モデル図**を書くこと。

概念モデルは書いておしまいということも多いと思いますが、コアドメインのためのドキュメントとして、ドメインビジョン文書、インセプションデッキと一緒に保守していくといいかもしれませんね。

## コアにフラグを立てる

クラス図を詳細に書いているチームであれば、コアドメインにステレオタイプを使って印を付けておくことができます。

コアドメインが変更された場合は、この強調されたコアも変更されます。その際には、チームメンバー全員が変更について協議する必要があります。
なぜならコアドメインが変わる=ビジネスが変わるということだからです。
自己紹介

#自己紹介
初めまして、地方にてレガシーシステムと日々格闘しているcobocoboといいます。
名前からお察しの通り、俗にいうコボラーです。
30歳です。

うちの会社はその地域内ではかなり大きい方です。
しかし、担当するお客さんや業務で部署が分かれるため、一緒に仕事をするのは1～2人程度です。
そのため必然的に、開発・保守・運用を全てを担当することになっているのが現状です。

#COBOLを使ってみての所感
今回は、仕事で8年間向き合ってきて感じたCOBOLに対する所感を書いてみたいと思います。

##COBOLのいいところ
・比較的読みやすい
COBOLはプログラムを英語のような文書で記述できるようにした高級言語です。
そのため、プログラムの解読は比較的簡単です。

・覚えるのが簡単
上段と被りますが、英語のような文書で記述できるので、プログラムが書けるようになるまでも簡単です。
また、命令語もさほど多くはないためその気になれば丸暗記も可能だと思います(私はしませんが)

・10進計算が正確・簡単
COBOLの大きなメリットだと思います。
少数計算の丸め誤差に悩まされた経験はないですし、端数の切り捨て等も比較的簡単です。

・同じ業界のオジサンに好かれる
何年か前に1人で飲んでいたとき、たまたま近くにいたオジサンが同業者の方で、COBOLトークが盛り上がりました(笑) 大体40～50歳ぐらいの方だったと思います。


#COBOLの悪いところ
・冗長な記述が多い
いわゆる「おまじない」が多かったり、１つの命令語にも余計な記述が多いです。
例) Aに1を格納する　→　`MOVE 1 TO A`
　　A=1でいいでしょ(笑)

・開発環境が貧相
これは環境が汎用機だからだと思うのですが、開発や保守で利用するのはただのエディタです。
かなりキツイです。6000行に及ぶプログラムの変数の参照先を探すとかやってらんないですね。
Windows上で動作する方ではeclipse的な奴があるという噂ですが、見たことはありません。

・テストが難しい
IDEがないということは、それに伴いテストも難しくなります。
ですがCOBOLで構築されたシステムは、バグの影響度合いが(社会的に)大きいものが結構あります。
テストするのは難しいがバグを出したらマズイという2重苦です。

#まとめ
最終的にCOBOLというか開発環境に対する不満が大きくなってしまいました(笑)

実際のところ、COBOL自体はそんなに嫌いじゃありません。
そんなに難しくないので(笑)

それよりも、
・「開発環境の貧相さ」による作業時間の増大
・長期にわたって運用・保守されてきた「システムの構造的な歪み」
・プログラミング初期に記述されたがための「保守性の低いコード」の山

と8年間苦しめられてきましたので、それらに対する憎しみが非常に深いです(笑)

逆に言うと、この世のアンチパターンを体験してきたというのはある意味勉強になったのかな～とも思っています。

今回はこんなところで終了したいと思います。
ここまで読んでくださりありがとうございました<(_ _)>
センサデータを fluentd 経由で GCP 上の Elasticsearch に送信して可視化

# 1. はじめに
[以前の記事](https://qiita.com/rtakasuke/items/cd7eb029d88e1ff63588) で、RaspberryPi で収集したセンサデータを、 さくらVPS上に構築した Elasticsearch に送信して、Kibana で可視化しました。
今回は勉強を兼ねて、データを Google Cloud Platform ( GCP ) に送信するように構成を変更します。

- 関連記事
    - [センサデータを fluentd 経由で Amazon Elasticsearch Service に送信して可視化](https://qiita.com/rtakasuke/items/2bb08e79c9219056b8e3)

# 2. Server side の設定 ( GCP )
## Cloud Launcher からソリューションを検索してデプロイ
Elasticsearch と Kibana がセットになっているものを探します。
「ELK Certified by Bitnami」が良さそうだったので、今回はこれを仮想マシンにデプロイすることにします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/18646/be59317f-aebf-914a-17de-bafd2a8fff23.png)

初期設定画面。
マシンのスペックと、ディスクのサイズを下げました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/18646/4444c371-4e8f-c638-0927-ed11a5d131c0.png)

デプロイボタンをクリックすると、デプロイが始まります。

## Deployment Manager で情報を確認
デプロイが完了したら、Deployment Manager で各種情報を確認します。
Admin URL にアクセスしてユーザ名とパスワードを入力すると、Kibanaが開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/18646/3e4fc7e9-2999-c5da-5e5e-e45ec8d9f57f.png)

## VPCネットワーク > ファイアウォールルール に設定を追加
自宅のIPアドレスから Elasticsearch(9200番ポート) へのアクセスを許可します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/18646/1e7b3151-0a64-42aa-7697-0f7b4f4a1be6.png)

# 3 Sensor side の設定 ( Raspberry PI )

## 前提条件
[以前の記事](https://qiita.com/rtakasuke/items/cd7eb029d88e1ff63588) の状態が前提です。今回はこれに変更を加えます。

## プラグインのインストール
- fluentd から Elasticsearch に直接格納するためのプラグインをインストールします

```
sudo fluent-gem install fluent-plugin-elasticsearch
```

## fluentd の設定
- fluentd の設定ファイルを編集して、データの送信先を変更して、fluentd を再起動します

```:/home/pi/fluent/fluent.conf
<source>
  @type tail
  format json
  path /home/pi/myroom.log
  pos_file /home/pi/myroom.log.pos
  tag log.myroom
</source>

<match log.myroom>
  @type copy
  <store>
    @type elasticsearch
    type_name myroom
    logstash_format true
    logstash_prefix myroom
    reload_connections false
    hosts http://XXX.XXX.XXX.XXX:9200
  </store>
</match>
```

# 4. 確認
GCP 上の Elasticsearch にデータが送られていることを確認しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/18646/31a7e02a-9a61-126f-3401-beae76242081.png)