OmniAICreator/Qiita-1.07M huggingface dataset:
verilogでsigned演算するときに気をつけること

書くことなんてないけれど、アドベントカレンダー用の記事を書いてたらqiitaの初投稿容量制限に引っかかったのでうんち記事を投げておく。ほぼ自分用。
# シフト演算子が絡むときは括弧をつける
いきなりsigned演算と関係がないが、私はシフト演算子の優先順位が覚えられない人である。
たし算とかけ算ならたし算の方が優先される。これはまあわかる。
わからんのはシフト演算子である。こうなっている。

優先順位
高　　　　* / %
　　　　　+ -
低　　　　<< >>

エーッ！？　って感じじゃないですか？　違いますか。そうか。
verilogとかを書くとシフト演算子を多用することになるが、もう何度引っかかったかわからないのでシフトが絡む演算は全部括弧を付けて書くようにしてしまった。

# unsignedを計算の中に入れる時
unsignedとsignedで計算する時はこう書いてやる必要がある。

```verilog
reg [8-1:0] a;
reg signed [9-1:0] b;
reg signed [10-1:0] c;

c <= $signed({1'b0, a}) + b;
```
こうしないとunsignedの計算と解釈されてしまうっぽい。定義されていないwireを使った場合勝手に1ビットのwireとして解釈する件とかもそうだが警告ぐらいしてくれればいいのに。

※追記: 
1ビットwireについては、モジュール外で

```verilog
`default_nettype none

//（モジュールの記述）

`default_nettype wire
```
のように指定しておくとエラーを出してくれるようです。

# 計算結果が溢れないように逐一wireでビット幅を指定する
一番大事。特に一行で

```verilog
reg signed [32-1:0] a;
reg signed [32-1:0] b;
reg signed [32-1:0] c;

a <= (b + c) >>> 1;
```

のような計算をする場合、たとえ最終的な計算結果は32ビットに収まるとしても、途中の`b + c`の計算結果が33ビットに溢れてしまうと計算結果が狂うことがある。というか大抵狂う。
なので、自分はこんな感じで書く。

```verilog
reg signed [32-1:0] a;
reg signed [32-1:0] b;
reg signed [32-1:0] c;
wire signed [33-1:0] d;

wire assign d = b + c;

a <= d >>> 1;
```

# 算術シフトしろ
signedにシフト演算子を適用するときはシフト(>>)ではなく算術シフト(>>>)を使おう。<<<は<<と意味が変わらないのでどっちでもいいが、自分のように頻繁に左右を間違えちゃう場合は<<<で書いておいた方が安心である。

# (即値にビット幅を指定しない)
今からすごく適当なことを書く。
signedのレジスタと即値の計算において、例えば `a - 63'd6` と書いていたところを`a - 63`と書き直したらなぜかうまくいく、というようなことがよくあった。他に正しい指定の仕方があるのかもしれないし、開発環境さんサイドの解釈がどうなるかによると思う。

# まとめ

* シフト演算子を扱っててどうも演算結果がおかしいときは演算子の優先順位を疑おう。
* 優先順位が覚えられない人は常に括弧をつけるようにしよう。
* unsignedを計算に入れる時は適宜0ビットを足す。
* 長い計算をやる時は個々の計算結果が最大何ビットになるか考えてwireを使ってビット幅を指定してあげよう。
* >>>
* (即値にはビット幅を指定しないとうまくいくかもよ)

簡潔に書くためにシンプルな例を使ったが、実際にはもっとややこしい計算で発生した事態に対してこれらの手段を講じたので、挙げた例が必ずしも正しいとは限らない。まあ開発環境の解釈と付き合う一助になれば。
IntelliJ IDEAのTerminalウィンドウでmsys2を使う

# はじめに
IntelliJのTerminalがcmd.exeのままだと何かと不便だったりするので変更してみたのですが苦労したので記録を残しておきます。

環境
win10
IntelliJ IDEA 2017.3

# インストール
http://www.msys2.org/ ここからmsys2をインストールしてください。
フォルダを解答したら任意の場所に**msys64**フォルダを置いてください。
このあと環境変数に**msys_root**のような名前でパスを通しておくと便利です。
環境変数を追加したあとに再起動するのを忘れないで下さいね。

# とりあえず設定を変更する
**file** > **Settings** > **Tools** > **Terminal** からShell Pathをmsys2.exeに変更してみます。
そのあとIntelliJ上でTerminalを開こうとすると、

![msys.PNG](https://qiita-image-store.s3.amazonaws.com/0/207330/d985a450-58df-5f45-ccaf-c579f9628949.png)

別ウィンドウでmsys2が開いてしまいました。

違う……そうだけど、そうじゃないんだ……

# 結論
結論としては、msys64フォルダまでのパスを`msys_root`として環境変数にパスを通したあとで、**file** > **Settings** > **Tools** > **Terminal** から設定画面を出し、

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/207330/9c303dda-3ae8-4f1f-aad0-d0249982537b.png)

Shell pathを

```
cmd.exe
```
から

```
"cmd.exe" /k ""%msys_root%\usr\bin\bash.exe"" --login -i
```
に変更するとTerminal画面の中でmsysが動きます。
これでlsとか使えるようになるよ！やった！

![aaa.PNG](https://qiita-image-store.s3.amazonaws.com/0/207330/91d341f3-adec-91e2-b8e7-13afe63da499.png)

ただしこのやり方だとカレントディレクトリがホームになってしまうので作業ディレクトリまで自分で移動しないといけません。色々試してみたのですがいい解決方法が見つかりませんでした。もっといいやり方をご存知の方がいらしたら教えいただけると幸いです。

#追記
コメントで教えていただいた[Visual Studio Code 15.1の統合シェルをMSYS2のbashにする](https://qiita.com/yumetodo/items/42132a1e8435504448aa)の記事を参考にカレントディレクトリを作業ディレクトリにすることができました！

```
  # Start MSYS in selected folder
  # c:\msys\usr\bin\bash -c "cd '%curdir'; export
  # CHERE_INVOKING=1; exec /usr/bin/bash --login -i"
  #
  # Make sure we start in home unless invoked by CHERE
  if [ ! -z "${CHERE_INVOKING}" ]; then
    unset CHERE_INVOKING
  else
    cd "${HOME}" || echo "WARNING: Failed attempt to cd into ${HOME}!"
  fi
}
```
上記の記述にあるように、**CHERE_INVOKING**という変数がシェルの起動時にHOMEディレクトリに行くかどうかを決めているようなので、環境変数に**CHERE_INVOKING**を**1**で設定するといい感じに作業ディレクトリでシェルが開いてくれました！

# 参考
https://syon.github.io/refills/rid/1498646/
https://qiita.com/rnurakami/items/59355faaac2f6698cc2c
https://qiita.com/nana4gonta/items/717a4508fa585a454690
https://qiita.com/k-takata/items/2220ba2e8dd5bcba3961
https://qiita.com/milu0_0_0/items/86322beac22501c9ddfe
https://meiji-ncc.tech/161026_developent-primer-with-python/contents/Python%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%82%88%E3%81%86/Tips/%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%8A%E3%83%AB%E3%82%BD%E3%83%95%E3%83%88.html
VSCodeでMicroPythonプログラミング


https://qiita.com/advent-calendar/2017/micropython

MicroPython Advent Calender 17日目です。

昨日は@tshimizu8さんにCircuitPythonを紹介してもらいました。
スイッチサイエンスで取り扱いが始まったので日本でも広まるといいですね！

さてMicroPythonを楽しんでいる皆さんはどうやってコードを書いていますでしょうか。
micro:bitの場合はWebIDEで書いて→転送という形になるかと思います。

STM32やESP8266/ESP32の場合はローカルでファイルを作成してampyツールで
転送という形になるかと思います。

Pycomのドキュメントを見ていたらVSCodeのプラグインなるものを見つけたので
試してみたいと思います。

https://docs.pycom.io/chapter/pymakr/

###注意
windows10とVSCodeの64bitでは動きませんでした。。。
githubでisuueがあるのでこのせいかもしれませんね。。
https://github.com/pycom/pymakr-vsc/issues/3

(2017/12/23更新)
 

32bitでは動くかもです。
以下はUbuntu16.04で行っていますのでご承知ください。

##インストール
VSCodeを入れます。
https://code.visualstudio.com/

プラグインはnodejsが必要なため、nodejsを入れます。
cmdを開いてnode -vでVersionが表示されればOKです。

https://nodejs.org/en/

事前準備ができたら、VSCodeを開きプラグインをインストールします。
VSCodeを開き拡張機能でPymakrと打ち込み出てきたものをインストールします。

![2017-12-17_12h02_01.png](https://qiita-image-store.s3.amazonaws.com/0/146663/ed9eb64e-4a2e-1a68-b05f-d2e76f29a71f.png)

インストールしてVSCodeを開きなおすと、設定ファイルが出てくるのでそいつを編集します。
ESP32をPCにつなげると/dev/ttyUSB0で認識されるので、addressにセットします。


![Screenshot from 2017-12-17 12-56-08.png](https://qiita-image-store.s3.amazonaws.com/0/146663/40f7fc22-8149-55ec-0475-c3a405cf85e9.png)


下にあるAll CommmandsからConnectを押すとコンソールが下の画面で開かれ、
REPLが出てきます。
コードを書いて下のRunを押すと転送されて実行します。

![Screenshot from 2017-12-17 13-02-29.png](https://qiita-image-store.s3.amazonaws.com/0/146663/87ab5ddf-8b9b-94ed-7677-19b93f4a5c9c.png)

設定ファイルのポートを変えるとSTM32のCNUCLEOF401でも同じことができました。
→micro:bitだと.hexにしないといけないから出来ないかな？？？

![Screenshot from 2017-12-17 13-22-19.png](https://qiita-image-store.s3.amazonaws.com/0/146663/64f14a28-8bab-783c-5fb6-8f1f45d946b5.png)

これでファイルを転送できればよかったのですが、Uploadを押すとエラーが出てきて
転送できませんでした。。orz
jsのエラーっぽいのですがちょっとわかりません...

![Screenshot from 2017-12-17 13-22-39.png](https://qiita-image-store.s3.amazonaws.com/0/146663/be9a6cb3-68ac-729f-b6f9-206c60de12f7.png)

転送はできませんでしたが、エディタ書いてそのまま実行できるのは
とても便利だと思います。
ぜひお試しください。
IntelliJ Ideaでテスト駆動開発を爆速にするショートカット集

# IntelliJ Ideaでテスト駆動開発を爆速にするショートカット集
## 前提
Mac,Java,Junit5
Windowsのショートカットキーも分かる範囲で記載しています。

## はじめに
現在、2017年10月に和訳版が発売された「テスト駆動開発(https://www.amazon.co.jp/dp/B077D2L69C/)」を読んでいます。
本書の中に出てくるソースコードを写経することでより実践的に学べるということで、IntelliJ Ideaを使って写経しています。
写経の中で私が学んだ、IntelliJ Ideaでテスト駆動開発を進めるために使えるショートカットを紹介したいと思います。
※ほとんどIntelliJ Ideaの公式チュートリアルの内容です。詳細は公式チュートリアルを参照してください。（https://www.jetbrains.com/help/idea/tutorial-test-driven-development.html)

## テスト駆動開発のサイクル
テスト駆動開発は以下を繰り返し行います。
1. テストを書く
2. 書いたテストが失敗することを確認する
3. コードを書く
4. テストを再実行し成功することを確認する
5. リファクタリングを行い重複を除去する

## IntelliJ Ideaでテスト駆動開発で使えるショートカット
### 1.テストを書く
|できること|Mac|Win|
|---|---|---|---|---|
|テストクラスを作成する|パッケージを選択してCmd+N||
|テストメソッドを作成する|クラス内でCtrl+Enter||
|コンパイルエラーを解消する|エラー箇所でCtrl+Enter||

### 2.書いたテストが失敗することを確認する
|できること|Mac|Win|
|---|---|---|---|---|
|特定のテストを実行する|テストメソッド内でCtrl+Shift+R||

### 3.コードを書く
|できること|Mac|Win|
|---|---|---|---|---|
|テストコード→プロダクトコードへ移動する|テストクラス内でCmd+Shift+T|
|テストコードで呼び出しているメソッドへ移動する|メソッドにカーソルをあわせてCtrl+Cmd+B|

### 4.テストを再実行し成功することを確認する
|できること|Mac|Win|
|---|---|---|---|---|
|最後に実行したテストの再実行|(どこでも)Ctrl+R|

5. リファクタリングを行い重複を除去する
1〜4の繰り返しになります。

## 「テスト駆動開発」の写経のはじめかた
私は以下のプロジェクトをクローンして写経しています。
https://github.com/tddbc/java_junit5
gradleの設定が済んでいるためすぐに始められます。

## おわりに
ここまで読んでいただいてありがとうございます！
Win版のショートカットはおいおい記載していこうと思います。
matplotlibでのエラー、 plt.show()が動かない

###環境
macOS High Sierra
Python 2.7.10


##エラー内容


matplotlibを使ってて下記が動かない泣

```python


plt.show()

```
こいつが動かない、グラフが表示されない。。。
エラー文は、

```
RuntimeError: Python is not installed as a framework. 
The Mac OS X backend will not be able to function correctly
if Python is not installed as a framework. 
See the Python documentation for more information 
on installing Python as a framework on Mac OS X.
 Please either reinstall Python as a framework, or try one of the other backends.
If you are using (Ana)Conda please install python.app and 
replace the use of 'python' with 'pythonw'.
 See 'Working with Matplotlib on OSX' in the Matplotlib FAQ
 for more information.
```

[Pythonでmatplotlibをimportするとエラーが出る場合の対処策（Mac）](https://qiita.com/Gen6/items/78d83d117ef67e0d53c2)

おそらく原因はこれだと思う。backend設定がMacOSXになってる。
どうやらこれをTKAggに変えれば良いみたい！
しかしここからが大変、matplotlibrcが書き換えられない。。。。





##解決法



backend設定を書き換えようとするも出来ない。。。権限ないのか？

そこで、
[初心者向け　MacでOperation not permittedの解決方法](https://qiita.com/iwaseasahi/items/9d2e29b02df5cce7285d)
を参考にして再起動するもリカバリーモードが出ない。しかし、なぜかグラフが書けた泣


一応確認でmatplotlibrc　を見てみる。
因みに場所は、terminalで以下を叩く

```

 python -c "import matplotlib;print(matplotlib.matplotlib_fname())"

```
で調べる事が出来て
僕はここにあった
/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/mpl-data/matplotlibrc

で肝心のmatplotlibrcは、

```

backend      : MacOSX

```


まんまやないかい！
なんでグラフ描けるようになったのかな？(再起動したからか？)

その後結局、今度はanimationが動かなかったのでエラーの指示通りコードの前に

```python

import matplotlib
matplotlib.use('TKAgg')

```
書いたらanimationも動くようになった。
その時のエラー文はこれ

```

matplotlib.animation.BackendError: The current backend is 'MacOSX'
and may go into an infinite loop with blit turned on.  Either
turn off blit or use an alternate backend, for example, like
'TKAgg', using the following prepended to your source code:

import matplotlib
matplotlib.use('TKAgg')

```

デフォルトの設定ではないのでいちいち書かないといけないが一応動いた。でも、この指示文出るなら最初っから出してーー泣
RailsアプリケーションをPWA化する目論見

# そもそもPWAとは
Progressive Web Apps
ウェブとアプリの両方の利点を兼ね備えたアプリです。
モバイル寄りのためコンバージョンやアクティブユーザのKPIの向上にも役立つかと。

# これがすごいぞPWA

- ウェブなのに全てのページがオフラインで動作するためフライトモードでも動作する。
- プッシュ通知が飛ぶ
- ブラウザの機能を使用できるため非ログインユーザ以外のユーザアクションを計測可能
- インストールが不要のためインストールの際の離脱が減る。


# PWAを実現するための要件

- レスポンシブデザイン
- Service Workers
- Web App Manifest
- HTTPS通信であること
- Web App Manifest
ホーム画面に追加できるため1タップでサービスへきてくれる！

#必要な要件
- モバイルフレンドリーなデザインであること(タブレットと携帯端末がメインのため)
- Service Workersが導入されていること
オフラインで動作させるために必須

# 対応ブラウザと必要なツール群
この記事参照
[やばい、iOSにネイティブアプリ要らなくなるかも。SafariもPWAに対応する可能性](https://qiita.com/Yatima/items/b9f1962da1a304dc7604)

# SEO大丈夫？
よく見かける質問で
1ページしかインデックスされていないのは）PWA のせいかな？
というポストがあるが、サイト構造の問題らしい。

# URLを動的に書き換えればSEO的にも問題はない
オフラインで遷移するため、URLが自動で書き換えられないためこの現象が発生する
Googleが作ってるだけあってSEOは大丈夫な模様。(断言はできないが)
[SEO対策はこちらの記事参照](https://webtan.impress.co.jp/e/2016/09/09/23772/page/1)


# Railsアプリケーションに導入
- HTTPSの準備

```
# config/environments/production.rb

Rails.application.configure do
  # ...

  # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
  config.force_ssl = true

  # ...
end
```
[Service Workerの導入](https://github.com/rossta/serviceworker-rails)

```
# Gemfile

gem "serviceworker-rails"
```

# 初期化

```
$ bundle install
$ rails g serviceworker:install
```

# 自動で生成されるファイルはこれ
config/initializers/serviceworker.rb - Railsアプリケーションのためのconfigファイル
app/assets/javascripts/serviceworker.js.erb - ServiceWorkerのサンプルとメインファイル？
app/assets/javascripts/serviceworker-companion.js -  ServiceWorkerをブラウザに登録するためのファイル
app/assets/javascripts/manifest.json.erb - Readme的な公開する設定情報
public/offline.html - オフラインのスタートページ

# [ServiceWorkerのライフサイクル](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle)


# サンプルプロダクトとドキュメント
- [serviceworker-rails-sandbox](https://github.com/rossta/serviceworker-rails-sandbox)
- [awesome-progressive-web-apps](https://github.com/TalAter/awesome-progressive-web-apps)
- [https://jakearchibald.com/2014/offline-cookbook/](https://jakearchibald.com/2014/offline-cookbook/)


# 所感
ドキュメントも探せばいろいろ出てくるのでそこまでトラブルはなさそうな肌感。
あまりトラップっぽいところはなさそう。
1回サンプルプロダクトを年末年始で書いて検討する価値はありそうかと！
Javaで「static でない 変数 x を static コンテキストから 参照することはできません。」のエラーが出た時の対処　プログラミング最最最初歩の教訓備忘録01

結論：メインメソッドと別で作ったメソッドの先頭に「static」を記述する。

例えばabcというメソッド名のメソッドを作って
int abc(int a,int b)
と記述しコンパイルしようとした場合に、「static でない 変数 を static コンテキストから 参照することはできません。」とエラーが出たら、
static int abc(int a,int b)
というふうに「static」を頭に記述するだけでエラーは起きません。

私の投稿記事、プログラミング最最最初歩の教訓備忘録は、
プログラミングの超絶初心者の自分が、自分のために残した学習記録のようなものです。

スキルの高い方々には全くの無益なものだと思いますが、もし同じくらいのレベルの方で同じ問題を抱えている方の一助となれば幸いかと思い投稿致しました。

初の記事投稿ということで急に変更などするかもしれません。
ざっくばらんメモ_16：kaggle, deepnetの特性解析, 既約性メモ

###kaggle recruit
Recruit Restaurant Visitor Forcasting Challengeをスタート．
[コード](https://github.com/festa78/kaggle_recruit_rest)
レストランの将来訪問者数を予測するタスク．
分析はすでにやられていて参考になる
ーhttps://www.kaggle.com/headsortails/be-my-guest-recruit-restaurant-eda
ひとまずkernelにあるスターターを参考にxgboostを実装．
ー結果：0.516
sklearnのgridsearchCVで適当にパラメータをふってチューニングしたところ
ー結果：0.512
あまりうまくないので他のkernelのパラメータも参考にしつつ手動チューニングも
取り入れたところ
ー結果：0.500
でまあまあな感じに．
他にもlightgbmも試しに適用してみたところほぼデフォルトのパラメータで
ー結果：0.493
でxgboostよりも良い感じに．今回のタスクはlightgbmが相性が良い？
現在ランク：171/707

###[Failure of Gradient-Based Deep Learning](https://arxiv.org/abs/1703.07950)
この論文を読んだ際に気になった事として，
最適化の収束速度，sample complexityなどの観点からdeep learningモデルの性能を改めて評価している点がある．
例えばEnd-to-Endモデルは複数に分解して別々に学習するよりもはるかに収束速度が遅くなるから
良くないなどとしている．
通常の論文などはとりあえず一般的の指標でSOTA出せばOKな風潮がだいぶ根付いてきたが，
改めて多面的な評価、あるいはモデルの特性の理解、の重要性を訴えている感じがする．
実用面だとただ性能が良いだけでは結局モデルの一側面でしかないので，
モデルの特性解析を理論抜きでやるはめになり，イレギュラー対応など頻繁に発生して
保守が難しい面があると感じる．

###irreducabilityとintegral domain
あるvariety Xが与えられた時、それが非ゼロでXそのものでない
二つのvariety X_1, X_2で表せる時，Xはreducibleと言い、
そうでない場合はirreducibleであるという。
Xがirreducibleな時のみにおいて、そのcoordinate ring Γ(X)は整域(integral domain)となる．
つまりXがreducibleな場合、X上に定義される非ゼロ関数が２つあって，
その積がゼロ関数になるものが存在する．
例：Xはx^2+y^2=1の解集合とする．Γ(X)=C[x,y]/(x^2+y^2-1)なので、f=x-y, g=x+yとおけば
これらはΓ(X)上でゼロ関数でないがfgはゼロ関数である．つまりΓ(X)は聖域でなくreducible．
docker-composeでupできない場合の対処

docker-composeを起動しようとして以下のコマンドを実行した。

```
docker-compose up -d
```
そうしたところ、以下のエラーが発生した。

```
Unsupported config option for services service: '[サービス名]'
```

docker-composeを更新する必要があったため以下を実行する。ただし、下記のコマンドのバージョンを新しいバージョンに書き換えて実行する。
(※私は「1.18.0-rc2」のバージョンでやりました)

```
curl -L https://github.com/docker/compose/releases/download/[バージョン名]/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
```
RecyclerViewの基本


# RecyclerViewの基本

ListView, RecyclerViewで差がないことについては、こちらの[ListViewの基本](https://qiita.com/naokomada/items/6c73c8b507f5ff1f2ede)で書きました。
ここではRecyclerViewに特有のことだけ書きます。

## LayoutManager
ListViewとちがい、RecyclerViewではViewの表示の仕方を制御するクラスとして、[RecyclerView.LayoutManager](https://developer.android.com/reference/android/support/v7/widget/RecyclerView.LayoutManager.html)を継承したクラスが必要になる。
ただ、単にリスト表示させたいだけなら（その他グリッド表示とかも）出来合いのクラスの[LinerLayoutManager](https://developer.android.com/reference/android/support/v7/widget/LinearLayoutManager.html)などがあるのでそれで足りる。

## Adapter
Adapterを作って、RecyclerViewの子Viewを作らせるのは、ListViewと変わらない。
ただRecyclerViewの場合は、[RecyclerView.Adapter](https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html)型のAdapterにする必要がある。
※ListViewでは[Adapter](https://developer.android.com/reference/android/widget/Adapter.html)を使っていたので、含まれるメソッドの構成などがかなり違う。

- getItemCount()
 - データの個数を返す
- onCreateViewHolder()
 - viewを生成したものをViewHolderに入れて返す
- onBindViewHolder()
 - ViewHolderの特定の位置にデータをセットする
 
ちなみに、上記のようなメソッドがある通り、ViewHolderの実装が必須になっている。
また、Adopterは、ListViewの時と同じく、何らかの方法で表示用のデータを保持しておく必要がある。（一番基本のパターンだと、表示用のPOJOのモデルクラスをArrayで持っておくなど）
PostgreSQLの接続方法

備忘のためメモ

## 前提
- 実行環境はCentOS6.9, PostgreSQL9.5です。他の環境ではやり方が違うかも
- PostgreSQLがインストールされていること
- PostgreSQLのパスワード設定されていること
    - 設定されていない場合は ``` sudo passwd postgres ``` で設定する  

## PostgreSQLに接続する

```bash
su - postgres
```
接続後パスワードが要求されるので入力する

接続するとこんな感じになります

```bash
-bash-4.1$ 
```

`psql`と打つことで諸々データベース操作ができるようになる

```
-bash-4.1$ psql
psql (9.5.10)
"help" でヘルプを表示します.

postgres=# 
```

## データベースに接続する


```
postgres-# \connect [DB名]
データベース "[DB名]" にユーザ"postgres"として接続しました。
```

## その他の操作
この辺りを参考にやりたいことをやりましょう
[PostgreSQLの基本的なコマンド](https://qiita.com/H-A-L/items/fe8cb0e0ee0041ff3ceb)
[PostgreSQLコマンドチートシート
](https://qiita.com/Shitimi_613/items/bcd6a7f4134e6a8f0621)



## 参考
[UbuntuでPostgreSQLを使ってみよう (2)](https://lets.postgresql.jp/documents/tutorial/ubuntu/2)
[CentOS で PostgreSQL を使ってみよう！(2)](https://lets.postgresql.jp/documents/tutorial/centos/2)
[CentOS 7にPostgreSQL最新版をインストール](http://www.hack-log.net/entry/2015/04/26/100000)
[CentOSにPostgreSQL9.5をインストールおよびテスト](https://qiita.com/SOJO/items/a1d97887d24c3e44596f)
Homebrewがおかしくなったら再インストールしよう

## はじめに
YosemiteのときにHomebrewをインストールしたのですが、El Capitanで追加されたRootlessによってパーミッション周りがおかしくなり、Homebrewが使えなくなりました。
High Sierraまでずっと放置してHomebrewを使わずにいたのですが、やはり便利なので再インストールします。

## 環境
- OS：macOS High Sierra 10.13.1
- Ruby：ruby 2.3.3p222 (2016-11-21 revision 56859) [universal.x86_64-darwin17]

## Homebrewの再インストール
アンインストールしてからインストールするだけです。

```bash
# Homebrewをアンインストールする
$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)"

# Homebrewをインストールする
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

## 参考リンク
- [Homebrewを再インストール - tomoyaonishiのブログ](http://tomoyaonishi.hatenablog.jp/entry/2016/03/13/153350)
- [FAQ — Homebrew](https://docs.brew.sh/FAQ.html)
- [Homebrew — macOS 用パッケージマネージャー](https://brew.sh/index_ja.html)
MaxOSX Sierraでriak環境構築

* Sierraでriak動かしてる情報がなかったのでメモ

## 環境

* Mac OSX Sierra
* riak 2.2.3

## 手順

### riakをインストール

```zsh
% brew install riak
```

* 起動してみる

```zsh
% riak start
!!!!
!!!! WARNING: ulimit -n is 256; 65536 is the recommended minimum.
!!!!
```

* warningが出る


* Lionまでだと/etc/launchd.confを修正すればいいらしいがファイルが見当たらない

## limit.maxfiles.plistを作成する

* /Library/LaunchDaemons/limit.maxfiles.plistを作成して以下の内容を記述する

```limit.maxfiles.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>Label</key>
    <string>limit.maxfiles</string>
    <key>ProgramArguments</key>
    <array>
      <string>launchctl</string>
      <string>limit</string>
      <string>maxfiles</string>
      <string>200000</string>
      <string>200000</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>ServiceIPC</key>
    <false/>
  </dict>
</plist>
```

* 起動してみる

```zsh
% riak start
riak failed to start within 15 seconds,
see the output of 'riak console' for more information.
If you want to wait longer, set the environment variable
WAIT_FOR_ERLANG to the number of seconds to wait.
```

* 失敗する

riak consoleなどでエラー原因などがみられるが、問題になっていそうなところを修正してもabortして終了してしまう。

公式をみると、brewで入るriakは最新になってないようなので、tarを取得して使う。

```zsh

% curl -O http://s3.amazonaws.com/downloads.basho.com/riak/2.2/2.2.3/osx/10.8/riak-2.2.3-OSX-x86_64.tar.gz
tar xzvf riak-2.2.3-osx-x86_64.tar.gz
% cd riak-2.2.3
% bin/riak start
% bin/riak ping
pong
% bin/riak stop
ok
```

* 無事動いた
Qiitaでページ内リンクがうまくいかない場合

いつもあれ？っと戸惑うので。うまく飛ばない場合。

まず、リンク元はMarkdownで記載。
`[表示文言](#アンカー名)`

リンク先は実際のHTMLをデベロッパーツールなりで見て、コピペするのが手っ取り早いと思います。大文字やスペース、括弧などがある場合特に。

例えば、次の場合。
#見出し1
##見出し 2
###見出し (3)
####header4
##### Header 5
###### HEADER, 6

Markdownではこのようにしています。

```
#見出し1
##見出し 2
###見出し (3)
####header4
##### Header 5
###### HEADER, 6
```

実際のHTMLは次のようになっていました。

```
<h1>
<span id="見出し1" class="fragment"></span><a href="#%E8%A6%8B%E5%87%BA%E3%81%971"><i class="fa fa-link"></i></a>見出し1</h1>

<h2>
<span id="見出し-2" class="fragment"></span><a href="#%E8%A6%8B%E5%87%BA%E3%81%97-2"><i class="fa fa-link"></i></a>見出し 2</h2>

<h3>
<span id="見出し-3" class="fragment"></span><a href="#%E8%A6%8B%E5%87%BA%E3%81%97-3"><i class="fa fa-link"></i></a>見出し (3)</h3>

<h4>
<span id="header4" class="fragment"></span><a href="#header4"><i class="fa fa-link"></i></a>header4</h4>

<h5>
<span id="header-5" class="fragment"></span><a href="#header-5"><i class="fa fa-link"></i></a>Header 5</h5>

<h6>
<span id="header-6" class="fragment"></span><a href="#header-6"><i class="fa fa-link"></i></a>HEADER, 6</h6>
```

このため、リンクは次のようになります。
`[見出し1 へ](#見出し1)`：[見出し1 へ](#見出し1)
`[見出し2 へ](#見出し-2)`：[見出し2 へ](#見出し-2)
`[見出し3 へ](#見出し-3)`：[見出し3 へ](#見出し-3)
`[見出し4 へ](#header4)`：[見出し4 へ](#header4)
`[見出し5 へ](#header-5)`：[見出し5 へ](#header-5)
`[見出し6 へ](#header-6)`：[見出し6 へ](#header-6)


以上
H2Oで任意のモデルを別名で保存するためのTIP

この文章は[DATUM STUDIO Advent Calendar 2017](http://qiita.com/advent-calendar/2017/datumstudio "DATUM STUDIO Advent Calendar 2017")の19日目です。

修正中
## 趣旨

最近は様々なDeepLearningパッケージが乱立してきておりますが、
今年一年はH2Oというパッケージにかかりっぱなしの一年でしたので、
年の暮れではありますが、便利なTIPを数点ほどあげたいと思います。

TIPS
1. GridSearchの利用方法
2. GridSearchの結果の取り出し方
3. GridSearchから取り出したモデルを既定のモデル名に書き換えて、保存する方法

### GridSearchの利用方法
```r
#とりあえず利用しそうなライブラリは先に読み込んでおきます
library(tidyverse)
library(h2o)

# h2oを起動します
localH2O = h2o.init(nthreads=-1)

iris

iris.hex = as.h2o(iris, destination_frame = "iris.hex")

```
個々からはモデルの話しになります。
H2Oでは、モデルのハイパーパラメーターを
グリッドサーチ形式で模索することができます。
この際に、seed値を入れてあげることで、
乱数によってどの程度結果がブレるのかを調べることが出来るのて、
二度美味しいです。

また、全部の組み合わせを試すには時間が足りない場合には、
組み合わせをランダムに選んでテストする方法もあります。

```r

#ハイパーパラメーターを事前に入れておけます。
hyper_params <- list(

  # 隠れ層： 層の数と、各層におけるニューロン数をコントロールします
  hidden=list(
    c(200, 200),
    c(200, 200, 200)
    ),

  # 学習数 　あとでここが関係する
  epochs = 100
)

# パラメーターのサーチ方法
search_criteria  <- list(
  strategy = "Cartesian", #ここを修正することで、すべての組み合わせの中からランダムにモデルを試すことも出来ます。
  seeds=c(1, 2, 3)
)

x_variables <-  c("Sepal.Length", "Sepal.Width",  "Petal.Length", "Petal.Width" )
y_variable <-  "Species"


# ディープラーニングモデルを学習させます。
grid_data = h2o.grid(
  algorithm = "deeplearning",
  x = x_variables,
  y = y_variable,
  training_frame = iris.hex,
  validation_frame = iris.hex,
  # id info
  model_id = "iris_model",
  grid_id = "grid_data",
  
  # hyper parameter
  hyper_params = hyper_params,
  
  # grid search criteria
  search_criteria = search_criteria,
  
  # クロスバリデーションを行う場合は下のオプションをつけます。
  #nfolds = 10,
  #fold_assignment = "AUTO",
  

  #変数の重要度を見るときには下のオプションを TRUEにしてください。
  variable_importances = TRUE
)

```
### GridSearchの結果の取り出し方

下記のコードのような方法で結果をデータフレームで取り出せます。

```r
grid_result <- h2o.getGrid(grid_id = "grid_data", sort_by = "r2") %>% .@summary_table
```

### GridSearchから取り出したモデルを既定のモデル名に書き換えて、保存する方法
問題は、モデルの名称は、グリッドサーチに利用した時点で、
model番号がくっついているため、
これをそのまま保存してしまうと、あとで利用しづらくなってしまいます。

モデルの名称を変えたいのですが通常の方法では書き換えができません。
そこで、checkpointの機能を利用します。

```r

parameters <- as.list(grid_result[1,])

renamed_model <-  h2o.deeplearning(
  x = x_variables,
  y = y_variable,
  training_frame = iris.hex,
  validation_frame = iris.hex,
  
  # ここは０ではなく、前回のモデルのepochsを入れてください。
  # ここでは前回の学習が微妙に多い可能性を考慮して、0.1だけ学習させる形にしています。
  # これの値が、前のモデルと一致している時、学習せずにモデルを返します。
  epochs = as.numeric(parameters$epochs)+0.1,
  
  # ここに書き換えたいモデル名を入れてください
  model_id = "model_name",
  checkpoint = grid_result$model_ids[1], # ここで前に作成したモデル名を指定します。
  
  hidden = c(lapply(strsplit(gsub("¥¥]|¥¥[","",parameters$hidden) ,","),as.numeric)[[1]]),

)


# モデルを保存しましょう
h2o.saveModel(renamed_model, path = "test", force = T)


```

以上になります。
ListViewの基本


ListViewについて基本を整理しようと思いまとめました。

公式ドキュメント
[ListView | Android Developers](https://developer.android.com/reference/android/widget/ListView.html)


ちなみに、もともとRecyclerViewについて知りたくて調べ始めたため、以下、ListViewとRecyclerViewで共通のことだけ書いています。

# ListViewについて

ListViewはViewをリスト表示するためのView。
※つまり、「（行となる子の）Viewをリスト表示する（親の）View」がListViewということになる）

さらにただリスト表示させてスクロールできるだけではなくて、スクロールアウトして表示されなくなった子Viewを再利用することでメモリの消費を抑えている。

## Adapter
ListView自体には、

 - ある行の子Viewの内容
 - 全行数
 
などの情報は保持されない。
それを保持するためにAdapterと呼ばれるクラスを別につくって、onCreate()などの時に渡すことになっている。
[公式ドキュメント アダプタを使ったレイアウトをビルドする](https://developer.android.com/guide/topics/ui/declaring-layout.html#AdapterViews)

ある行に当たる子Viewは大体自作されることが多く、その場合はAdapterも自作のクラスになるので、基本Adapterは自作するものと思っていい。
※自作というか、以下のインターフェースを実装する。
[Adapter | Android Developers](https://developer.android.com/reference/android/widget/Adapter.html)

Adapterに以下のようなメソッドを持たせておく。

 - getView()
  - 一行分のViewを作って返させる
 - add()
  - 一行分のViewのもとになる情報（データを保持したPOJOとか）を与える
  
 呼び出し側のActivityのonCreate()などでは、Adapter.add()によって情報を渡しておき、ListView.setAdapter()でAdapterを設定することで、画面に表示がされることになる。
 
## ViewHolder
普通に上記のAdapter.getView()を実装しようとした場合、行となる子Viewに含まれるTextViewなどの実際のViewをいちいちfindViewByIdで探しては、そこにPOJOなどのモデルクラスから得た情報を設定する必要がある。
findViewByIdのコストが割と高いので、そのままだとパフォーマンスが上がらない処理になる。

このため、ViewHolderと呼ばれるクラスを別途自作しておいて、そこにfindViewByIdの結果を保持させておく。

## ListViewまとめ
ということでListViewで画面表示する場合、大体以下が関連してくる

- Activity(かFragment）
 - 呼び出し元
- ListView
 - 表示するView（＋子Viewが行になっていて、その子ViewもいくつかのViewでできている）
- Adapter
 - ListViewに表示する際の処理を各クラス
- ViewHolder
 - Adapterの処理のために１行分にあたる子Viewが持っている孫Viewの情報を保持する（実装必須ではない）
rust-sdl2を用いてwasmを生成する際の音楽ファイル関連のtips

# tl;dr;
- [emscripten-portsのsdl2](https://github.com/emscripten-ports/SDL2)の問題で音楽ファイルを読み込ませられない
- Music::from_static_bytesなどを用いてWebAssembly(wasm)に予め読み込ませておけば動く
- C、C++バインディングのrustのライブラリを使う場合、emscriptenを使わざるをえないと思われる

# はじめに
　mac上の環境をぶっ壊したのでdocker上に再構築する羽目になっているr-chaser53です。正直ほとんど進捗できなかったので[rust-sdl2](https://github.com/Rust-SDL2/rust-sdl2)を使ったアプリをwasmに変換した際のtipsを書こうと思います(※1)。

# 無理やり音楽ファイルを読み込ませる
　rust-sdl2で任意のpathの音楽ファイルを読み込ませたい場合、以下のようになります。

``` rust
sdl2::mixer::Music::from_file(path).unwrap();
```
　本来ならば変数pathからメタデータを生成しSDL.rwopsというオブジェクトに格納するようなのですが、肝心のSDL.rwopsオブジェクトは[null]と最初に宣言した時のままです。値が代入されてません(※2)。そのまま実行するとnullのrwopsオブジェクトのfilenameを参照しようとして処理が進みません。以下のようなハックで動かすこともできたのですが、正直微妙なところです。そもそもファイルを読み込ませること自体に問題があるのかと思いましたが、マップを読み込ませる処理自体は問題なく動いています。おそらくそちらに問題はないでしょう。

``` html
Module['preRun'] = function () {
  FS.createPreloadedFile(
    '/',
    'filepath',
    '/filepath',
    true, false);
  SDL.rwops = [{ filename: 'filepath'}];
}
```

# 予め読み込ませてみる
 rust-sdl2は以下のようにコンパイル時に音楽データを取り込んでしまうmethodも提供しています。

```rust
sdl2::mixer::Music::from_static_bytes(include_bytes!("filepath"));
```

　こちらは問題なく読み込んでくれるようです。コンパイル後にファイルが指定できないですし、音楽ファイルの分だけファイルが大きくなってしまうのも芳しくありません。しかし複数の音楽ファイルを読み込ませた場合、上のハックではとてもメンテできそうにありません。諦めてこちらを使うのが妥当なのではないでしょうか。

# emscriptenとrustとc, c++バインディング
　進捗駄目です。レポジトリは[これ](https://github.com/rchaser53/rust_pack_man/tree/wasm)です。
![packman.gif](https://qiita-image-store.s3.amazonaws.com/0/99025/a277270b-2f90-0539-82c6-357494cbfa67.gif)
　[「Rustでパックマン風のゲームを作ってみた」](https://qiita.com/rchaser53/items/93926b00282f81d033e9)のgifと比べると分かりますが円じゃなくて矩形になってます。理由としてはsdl2-gfxという円などを描画してくれるライブラリをemscriptenがサポートしてくれていないためです。cやc++のライブラリを使用したrustのアプリからwasmを作成する際に、対象のcやc++のライブラリがあるか[emscripten ports](https://github.com/emscripten-ports)を参照しますが、今回使用したいsdl2-gfxがないのです。自力でsdl2-gfxをwasm上で動かせるように色々調べてはいますが、必要な知識が多くいつまでかかるやらという状況です。この辺については[「Rustからwasmを生成してみた話」](https://speakerdeck.com/rchaser53/rustkarawasmwosheng-cheng-sitemitahua)あたりを見てくださると嬉しいです。
　選択肢の1つとしてemscriptenを使わない「wasm32-unknown-unknown」も考えたのですが、cやc++のバインディングを考慮してくれないようでした(※3)。開発を行う上でcやc++の資産を使いたいケースは少なくないと思われます。若干emscriptenから逃げたい気持ちもあるのですが、現状wasmを作成しようとする限りemscriptenからは逃げられないのかなというのが個人の感想です。

# 備考
※1 2017/12/17 rust-sdl2 version 0.31 現在
※2 ソースを追ってみると「throw 'Mix_QuerySpec: TODO'」とか書いていて「そっか…」てなります
※3 調査不足で設定や書き方次第では「wasm32-unknown-unknown」でもc、c++バインディングのwasmを生成できてほしいと正直思っています
[macOS][iOS]EventKitを試す

<p>仕事効率化のアプリケーションには興味があって、タスク管理アプリを作ろうと考えている。その為の第一歩として、EventKitを試してみる。macOSとiOSの両方を考えているが、サンプルはiOSで。</p>

<p>iOSでは、Info.plistに以下のような定義が必要だ。</p>

<pre><code>	<key>NSCalendarsUsageDescription</key>
	<string>Access the data of the calendar.</string>
	<key>NSRemindersUsageDescription</key>
	<string>Access the data of the reminder.</string>
</code></pre>

<p>macOSでは、com.apple.security.personal-information.calendars エンタイトルメントを含めるみたいだが、まだ試していないので紹介に止める。</p>

<p>初期化処理としてイベントストアへの接続というのがあるのだが、ユーザへの認証が必要となる。</p>

<pre><code>let store = EKEventStore()
let status = EKEventStore.authorizationStatus(for: .event)
var isAuth = false
switch status {
case .notDetermined:
    isAuth = false
case .restricted:
    isAuth = false
case .denied:
    isAuth = false
case .authorized:
    isAuth = true
}
if !isAuth {
    store.requestAccess(to: .event, completion: {
        (granted, error) in
        if granted {
        }
        else {
            return
        }
    })
}
</code></pre>

<p>デフォルトのカレンダーに対して、過去一年分のイベントを取得する。</p>

<pre><code>let startDate = Date(timeIntervalSinceNow: -365.0 * 24.0 * 60.0 * 60.0)
let endDate = Date()
let defaultCalendar = store.defaultCalendarForNewEvents
let predicate = store.predicateForEvents(withStart: startDate, end: endDate, calendars: [defaultCalendar!])
let events = store.events(matching: predicate)
print(events)
</code></pre>

<p>以下の通り、取得できた。</p>

![EventKit.jpg](https://qiita-image-store.s3.amazonaws.com/0/12540/0d95c77c-7e53-3434-d380-458ae628023e.jpeg)

ソースコード
GitHubからどうぞ。<br />
<a href="https://github.com/murakami/workbook/tree/master/ios/GettingThingsDone">https://github.com/murakami/workbook/tree/master/ios/GettingThingsDone</a> - GitHub<br />

関連情報
<a href="https://cocoa-kanto.connpass.com">Cocoa勉強会 BUKURO.swift (connpass)</a><br />
<a href="https://atnd.org/groups/cocoa-study">Cocoa勉強会 BUKURO.swift (ATND)</a><br />
<a href="http://cocoa-study.peatix.com">Cocoa勉強会 BUKURO.swift (Peatix)</a><br />

【Cocoa練習帳】
<a href="http://www.bitz.co.jp/weblog/">http://www.bitz.co.jp/weblog/</a><br />
<a href="http://ameblo.jp/bitz/">http://ameblo.jp/bitz/</a>（ミラー・サイト）<br />
<a href="https://t.co/6P3h2jtbRk>note</a><br />
<a href="https://qiita.com/m_yukio>Qiita</a><br />
IBM Cloud IaaS(旧 SoftLayer)にてMcAfeeを利用するにあたっての注意点

#背景
IBM Cloud IaaSサービス(以降SoftLayerと呼びます)ではサーバオーダー時にMcAfee Anti VirusやMcAfee Host IPSといったセキュリティソフトを注文・導入することが出来ます。
ただ、導入したは良いがMcAfeeの制限によって設定変更不可となるポイントが幾つかあるため、今回備忘録としてここに記載します。


##1. OSR Audit Policy設定変更不可
Windowsサーバにおいて各種重要ディレクトリ(C:\やC:\Windows配下)の監査ポリシーを変更する際、McAfeeのルールによって実施不可となる場合があります。
> <エラー表示>
>Windows Security : Unable to save auditing changes on System(C:)
>Access is denied

この場合、McAfeeをアンインストールした上で監査ポリシーを変更し、再度インストールし直す必要があります。
※McAfee Anti VirusとHostIPS両方入れている場合は両方アンインストールしてください。

再インストールする場合はSoftLayerへチケットで依頼し対応してもらうことになります。

(注意点1)再インストールには再起動が必要です。
(注意点2)HostIPSは月額がかかります。再導入を依頼した際、SoftLayerから「コストが発生するので課金してもいいですか？」といった回答が来る場合があるため、HostIPS代支払い済みであることが分かる請求書番号を伝えるとスムーズに対応してくれます。

##2. メール送信不可
McAfee Anti Virusのアクセス保護項目には「Anti-Virus Standard Protection」として「Prevent mass mailing worms from sending mail」というルールが存在します。

これにチェックを入れると一切のメール送信が出来なくなるため、対象サーバにてアラートメールなどを送信する場合、以下のように「Block」のチェックを外す必要がある。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/167392/2ad7f76e-8ccf-40a2-9e24-dfc27f1f24cc.png)

(注意点1)あくまで対象サーバからメールを飛ばす要件がある場合にのみ上記設定の変更を実施ください。基本的にはBlockするのがデフォルトの設定です。
Windowsでgoogle-home-notifierを使う

WindowsからGoogleHomeに喋らせたいなと思ったものの見つかる記事がラズパイ向けばかりだったので苦労したメモ

## 手順的なもの

0. Node.jsを入れる
0. python2.7を入れる
0. windows-build-toolsを入れる
0. node-gypを入れる
0. Bonjour SDKを入れる
0. Bonjour Print Serviceを入れる
0. google-home-notifierを入れる
    - google-home-notifierをちょっと書き換える

### Node.jsを入れる

私はNodistで入れました

```bat
nodist + 8
nodist npm match
```

### Pythom2.7を入れる

[Download Python \| Python\.org](https://www.python.org/downloads/)
インストールしたらパスを通す

### windows-build-tools入れる

```bat
npm install -g windows-build-tools
```

### node-gyp入れる

```bat
npm install -g node-gyp
```

### Bonjour SDK入れる

[https://developer\.apple\.com/download/more/?=Bonjour SDK for Windows](https://developer.apple.com/download/more/?=Bonjour%20SDK%20for%20Windows)

### Bonjour Print Service入れる

[ダウンロード \- Bonjour Print Services \(Windows\)](https://support.apple.com/kb/DL999?locale=ja_JP)

### google-home-notifier入れる

あとは他の記事にあるように

```bat
npm install google-home-notifier
```

または

```bat
git clone https://github.com/noelportugal/google-home-notifier
cd google-home-notifier
npm install
```

で入れてexample.jsあたりのipやlanguageを環境に合わせる
※example.jsは`npm install`したものと`git clone`したものは別物っぽい

`git clone`したものであれば

```bat
node example.js
```

でサーバが立ち上がりエンドポイントが表示されるので

```ps1
# 「ﾃﾞｨﾙﾝ」という音の後に「Hello Google Home」と言う
curl https://xxxxx.ngrok.io/google-home-notifier?text=Hello+Google+Home
```

としてやれば喋ってくれる:blush:

...のだが、ip指定の場合、日本語メッセージを送っても喋ってくれない:sob:

```ps1
# 「ﾃﾞｨﾙﾝ」という音だけで「こんにちは」を言わない
curl https://xxxxx.ngrok.io/google-home-notifier?text=こんにちは
```

google-home-notifier.jsを確認してみる

```js:google-home-notifier.js
var device = function(name, lang = 'en') {
    device = name;
    language = lang;
    return this;
};

var ip = function(ip) {
    deviceAddress = ip;
    return this;
}
```

？？？
deviceの方はlangを引数に受けて設定してるけどipの方はlangを引数をして受けてないぞ？？？:fearful:
ってことでipもlangを受け取れるように変更:muscle:

```js
var ip = function(ip, lang = 'en') {
    deviceAddress = ip;
    language = lang;
    return this;
}
```

変更後、example.jsを起動し直して

```ps1
curl https://xxxxx.ngrok.io/google-home-notifier?text=こんにちは
```

やりました:sunglasses:
Moodleへのアクセス件数を曜日・時間帯毎に集計する

# 概要
Moodleの利用状況を調べるときに曜日や時間帯によってどの様なアクセス数の違いがあるか確認したいときに使うSQL。[Logging 2](https://docs.moodle.org/dev/Logging_2)以降の対応なのでたぶんMoodle 2.6以降でstandard_logを使っている場合に利用可能。
WHEREで適当に期間を区切らないと恐ろしいほど集計に時間が掛かるので、可視化ツール使えばいいのにと思う人は可視化ツール使ってください…

# 集計方法
## アクセス数の合計を単純に集計
「時間帯、曜日、アクセス数」の列で取得。

```mysql
  SELECT DATE_FORMAT(FROM_UNIXTIME(l.timecreated), '%k') AS hour,
         DATE_FORMAT(FROM_UNIXTIME(l.timecreated), '%w') AS dow,
         COUNT(*) AS accesscount
    FROM logstore_standard_log AS l
GROUP BY hour, dow
```

## アクセス元に分けて集計
社内(学内)ネットワークとそれ以外に分けて集計する場合。あとMoodleシステムからのアクセス（IPがnull）も考慮。「時間帯、曜日、イントラアクセス数、インターネットアクセス数、システムアクセス数、総アクセス数」の列で取得。
ネットワークの判別の部分は[これ](https://qiita.com/papillon/items/8da1b615c584950d00e8)を使っている。イントラのIPはダミーなので深く考えてはいけない。

```mysql
  SELECT DATE_FORMAT(FROM_UNIXTIME(l.timecreated), '%k') AS hour,
         DATE_FORMAT(FROM_UNIXTIME(l.timecreated), '%w') AS dow,
         COUNT(
           CASE WHEN 
             (INET_ATON(l.ip) ^ INET_ATON(SUBSTRING_INDEX('192.168.1.0/24', '/', 1))) >> (32 - SUBSTRING_INDEX('192.168.1.0/24', '/', -1)) = 0
           THEN 1 ELSE null END
         ) AS intranet,
         COUNT(
           CASE WHEN 
             (INET_ATON(l.ip) ^ INET_ATON(SUBSTRING_INDEX('192.168.1.0/24', '/', 1))) >> (32 - SUBSTRING_INDEX('192.168.1.0/24', '/', -1)) != 0
           THEN 1 ELSE null END
         ) AS internet,
         COUNT(
           CASE WHEN 
             ISNULL(l.ip)
           THEN 1 ELSE null END
         ) AS system,
         COUNT(*) AS allaccess
    FROM logstore_standard_log AS l
GROUP BY hour, dow
```

## アクセス元に分けて集計 その２
アクセス元のルールを後で追加しやすいように変更。「時間帯、曜日、ネットワーク種別、アクセス数」の列で取得。


```mysql
  SELECT DATE_FORMAT(FROM_UNIXTIME(l.timecreated), '%k') AS hour,
         DATE_FORMAT(FROM_UNIXTIME(l.timecreated), '%w') AS dow,
         CASE WHEN ISNULL(l.ip) THEN 'system'
         ELSE
           CASE WHEN (INET_ATON(l.ip) ^ INET_ATON(SUBSTRING_INDEX('192.168.1.0/24', '/', 1))) >> (32 - SUBSTRING_INDEX('192.168.1.0/24', '/', -1)) = 0
             THEN 'intranet1'
           WHEN (INET_ATON(l.ip) ^ INET_ATON(SUBSTRING_INDEX('192.168.2.0/24', '/', 1))) >> (32 - SUBSTRING_INDEX('192.168.2.0/24', '/', -1)) = 0
             THEN 'intranet2'
           ELSE 'internet' END
         END AS network,
         COUNT(*) AS accesscount
    FROM logstore_standard_log AS l
GROUP BY hour, dow, network
```

# メモ
userテーブルを結合させてユニークユーザ数のカウントとかコース別の集計とかもできるので、そのあたりも組み合わせると使えるデータになりそう。
わかった気になるflannelの仕組み

異なるDockerホストに配置されたコンテナ同士での通信を可能にするflannelですが、使ってばかりでその仕組みを理解していなかったので調べてみました。

# 具体的な構成
![flannel_actual_construction.png](https://qiita-image-store.s3.amazonaws.com/0/151015/1136e5bd-b568-fd76-8c6e-f43c97497c3d.png)

コンテナ10.1.11.xからコンテナ10.1.12.yへのパケット転送フローは以下の通りになります。

1. 自身のネットワークへのパケットではないので、コンテナはデフォルトゲートウェイであるLinux Bridge docker0のIP 10.1.11.1(/24)にパケットを転送する (自ホスト内のコンテナへのパケットの場合、直接転送して終了)
2. Linuxパケット転送機能を利用して、VXLANデバイス flannel0のIP 10.1.11.0(/16)にパケットを転送する
3. flannel0とflanneldはパケットの宛先とetcdの情報を参照し、パケットを転送するべきNodeのIPを判断。その後、指定されたVNIを付与したVXLANカプセル化を行う。
4. Node1のnicからNode2のnicへカプセル化されたパケットを転送する
5. flanneldとflannel0はパケットのカプセル化を解除し、docker0のIP 10.1.12.1にパケットを転送する
6. 宛先コンテナのIPである10.1.12.yにパケットを転送する

# 構成されるネットワーク
![flannel_vnet.png](https://qiita-image-store.s3.amazonaws.com/0/151015/4e9697f8-f4c0-f56e-247d-7a986f6ebe91.png)

flannelとDockerによって構成されるコンテナネットワークは上記の通りになります。flannelはLinuxパケット転送機能によってルータのように振る舞い、さらにVXLANによって物理ネットワークをバックエンドとした10.1.0.0/16の仮想ネットワークを構成します。これにより論理的にはあたかも通常のL3ネットワークが構成されたかのようになります。

# まとめ
私が理解した内容をざっくりと書いたので厳密性には欠けるかもしれませんが、なんとなくでいいので理解した気になりたい人にはこのぐらいの説明の方がむしろわかりやすいかもしれないと思い、記事にしました。Dockerでマルチホスト環境を構成する方の手助けになれば幸いです。

# 参考
* [FlannelのVXLANバックエンドの仕組み - めもめも](http://enakai00.hatenablog.com/entry/2015/04/02/173739)
* [いまさら聞けない？ VXLANの仕組みとVTEPの役割](https://www.school.ctc-g.co.jp/columns/nakai/nakai64.html)
* [https://github.com/coreos/flannel/blob/master/packet-01.png](https://github.com/coreos/flannel/blob/master/packet-01.png)
俺好みのAVかどうか判定する判定器を作ってみた



## 背景
映像系のおすすめを紹介する機能ってNetflixはまあまあ当たってるけど、DMMのAVおすすめ機能は全然当たっていない。
恐らく、通常映画よりもAVって個人の好みのベクトルが千差万別で、思うように推定できないからじゃないかなと推測。若しくは好みというより売りたいものを推薦しているのかも。
なので、深層学習を利用して自分専用にチューニングしたAVの好み判定器を作れば上手くいくんじゃないかと思って作ってみました。

## 学習データ用意
数多のサンプル動画を自分の目で見て判断してcsvに名前(商品番号)と評価の数字[良い(1)・悪い(0)]を記入します。（これが一番大変）
その後、DMMapiを使って記入した商品番号から商品情報を取得してきて商品番号に紐づけます。
とりあえず、好みに関係ありそうなデータを取得してみました。
(メーカー・レーベル・女優・監督・ジャンル) 

紐づけの方法は、評価済みの物①と評価したい物②の情報(要素)を統合して重複を除外した要素のリストを作成。そのリストを作品毎に参照して要素があると1,無いと0とする商品番号と紐づいたリストをさらに作成します。


そして、kerasを利用して上記csvから判別器を作成。
学習器のモデルはこんな感じ。試行錯誤中だけど、今はこれが一番良さそう

    #回路構築
    model = Sequential()
    model.add(Dense(10000, input_shape=(10000, )))
    model.add(Activation('relu'))

    model.add(Dense(2))
    model.add(Activation('softmax'))

    #回路コンパイル    
    model.compile(optimizer='Adam', loss='binary_crossentropy', metrics=['accuracy'])
    #訓練
    model.fit(X_train_s, y_train, nb_epoch=1000, batch_size=10, verbose=1)


学習時間は18時間かかりました。(もっと学習時間短くしても変わんないかな。でもまあ念のため)

学習が終わったら、事前に用意した②（評価したい商品番号に紐づいた要素配列）を入力すると返り値のリスト[0]と[1]に値が返ってきて、どちらが大きいかで良いか悪いかを判別してみました。



## 精度
外れてるのもあるけど、おおかた良い感じに判別できてます。
感覚としては教師用のデータ量が精度にすごく効いています。教師データ200個程度だと全然使い物にならなかったけど、400個に頑張って増やすと途端に良くなりました。
教師データを作るツールが、学習精度と作業効率化にかなり影響を与えることが分かりました。今後はそこら辺を考えて作ってみようかな。
隠れ層の階層を増やすと途端に精度が悪くなった。
（画像と違って独立したパラメータを扱うときは隠れ層を使うと良くないのかな？）

## 感想
本当は画像処理系で俺好み判定器を作りたかったです。PCのスペックが圧倒的に足りないことから、DMMapiを使用したタグ情報で判定器を作ってみましたが、それなりに良いものが作れて意外でした。
自分の好みって思ってた以上に単純だったということなのでしょうか？
重みを可視化して、何が判別に効いてるのか見えると面白そうなので、これからやってみようと思います。

## 余談
高性能なPCが買える時がきたら、画像処理を使った俺好み判別器を作りたい。
（DMMapi頼りなのでapiのサービス終了したら使えなくなっちゃうし）
さらに妄想すると画像/動画 補完器とか。[ある程度のこと](http://hi.cs.waseda.ac.jp/~iizuka/projects/completion/ja/)はできてるっぽいので後は時間の問題だと思うけど、モラル的に企業が提供するものに期待が出来ないし、自分好みは自分の頭の中にしか存在しないので、やはり判定器や補完器は自分で作るしかない。

とりあえず途中経過として書きましたが、リクエストがあれば具体的なソースを書いていこうと思います。
XHTML5からXHTML Basic1.1への変換

#XHTMLからフィーチャーフォン向けへの変換

今さらだが、フィーチャーフォン（ガラケー）用にWebサイトを変換するXSLTを投稿してみる。そのうち失われる内容なので記念碑みたいなものか。
文字中心の簡易なサイトならそれほど困らないはず。
Shift_JISの方がフィーチャーフォンには良いのだが、変換できない文字（UTF-8限定の文字）があるとエラーを起こすので下処理が必要になる。
かつては3キャリア別々にして絵文字も分けたりしていたけれど、今はこの程度のざっくり変換でも良いんじゃないかとか。

```xml

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:htm="http://www.w3.org/1999/xhtml"
xmlns="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="htm">
<xsl:output method="xml"
encoding="UTF-8"
version="1.0"
indent="no"
doctype-public="-//W3C//DTD XHTML Basic 1.1//EN"
doctype-system="http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"/>

<xsl:template match="htm:head">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="htm:link[@rel='stylesheet']|htm:title"/>
</xsl:element>
</xsl:template>

<xsl:template match="htm:link[@rel='stylesheet']">
<link rel="stylesheet" type="text/css">
<xsl:attribute name="href"><xsl:value-of select="concat(substring-before(@href,'css/'),'css/mobile.css')"/></xsl:attribute>
</link>
</xsl:template>

<xsl:template match="htm:meta|htm:link|htm:script|htm:style|htm:header|htm:figure/htm:p|node()[self::text()='&#10;']"/>

<xsl:template match="htm:time[parent::htm:article]|htm:figcaption|htm:canvas">
<p><xsl:apply-templates select="@href|node()"/></p>
</xsl:template>

<xsl:template match="htm:div|htm:section|htm:aside|htm:nav|htm:article|htm:figure|htm:blockquote|htm:span|htm:abbr|htm:cite|htm:code|htm:dfn|htm:ins|htm:q|htm:samp|htm:time">
<xsl:apply-templates select="@href|node()"/>
</xsl:template>

<xsl:template match="htm:h1[htm:span]">
<h1><xsl:value-of select="text()"/><br/><xsl:value-of select="htm:span"/></h1>
</xsl:template>

<xsl:template match="htm:a[starts-with(@href,'#')]">
<xsl:apply-templates select="node()"/>
</xsl:template>

<xsl:template match="htm:table">
<table>
<xsl:apply-templates select="htm:caption"/>
<xsl:apply-templates select="htm:thead/*"/>
<xsl:apply-templates select="htm:tbody/*"/>
<xsl:apply-templates select="htm:tfoot/*"/>
</table>
</xsl:template>

<xsl:template match="htm:dt[htm:a]">
<xsl:copy>&#9632;<xsl:apply-templates select="@href|node()"/></xsl:copy>
</xsl:template>

<xsl:template match="htm:dt">
<xsl:copy>&#9661;<xsl:apply-templates select="@href|node()"/></xsl:copy>
</xsl:template>

<xsl:template match="htm:img">
<xsl:value-of select="@alt"/>
</xsl:template>

<xsl:template match="@href|node()">
<xsl:copy><xsl:apply-templates select="@href|node()"/></xsl:copy>
</xsl:template>

</xsl:stylesheet>
```
なぜVBAの動的配列は最後の次元の配列数しか変えられないのか考えてみた

いままで、動的配列が最後の次元の配列数しか変えられないことに何の疑問も持っていませんでした。
しかし、このたび、VBA Adventcaledar 2017の12月3日のmad_nectarineさんの投稿[「Excel VBAでCognitive Service使って翻訳してみた 〜VBA未経験なWebアプリ開発者が2日間VBAと戯れた結果 ～」](https://qiita.com/mad_nectarine/items/98262b037a9e47ba29fc)を拝見して、そういえばどうしてなんだろうと思い、考えてみました。

たぶん、配列の内部構造に理由があることは間違いないと思うので、2x3次元の配列を確保して、メモリ内での配置をみてみたいと思います。
通常、メモリ内での変数の位置は、16進数で表すことが一般的だと思いますが、相対的な位置関係を見たいので、10進数でみることにします。

プログラムは以下のプログラムを書いてみました。

```vbnet
Sub Main()
    Dim a() As Long
    ReDim a(0 To 1, 0 To 2)
    
    Debug.Print 0, 0, VarPtr(a(0, 0))
    Debug.Print 0, 1, VarPtr(a(0, 1))
    Debug.Print 0, 2, VarPtr(a(0, 2))
    Debug.Print 1, 0, VarPtr(a(1, 0))
    Debug.Print 1, 1, VarPtr(a(1, 1))
    Debug.Print 1, 2, VarPtr(a(1, 2))
End Sub
```

結果は、こうなりました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215956/d0178bc9-52db-10c9-e79a-6ca2efe911f0.png)
Long型は4バイト変数なので、メモリ上での位置は4ずつずれていくんだと思ってましたが、これをみるとそうではないようです。
下二桁に注目して、メモリ上での配置を図にしてみます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215956/a60b9cd3-abec-ace2-0f72-68c6ca2933f9.png)
なるほど、a(0,0)の隣に、a(0,1)がいるかと思ったら、a(1,0)がいるんですね。
最後の次元が同じもの同士を隣同士に固めて配置しているようです。

この配置であれば、最後の添え字数を変更するだけであれば、内部処理としては、添え字数を変更しても、再配置処理は単純なコピーで済むので、高速に処理できそうです。
これが理由なのでしょう。
理解を助けるために、ためしに、配列数を変更して試してみます。

```vbnet
Sub Main()
    Dim a() As Long
    ReDim a(0 To 1, 0 To 2)
    
    Debug.Print 0, 0, VarPtr(a(0, 0))
    Debug.Print 0, 1, VarPtr(a(0, 1))
    Debug.Print 0, 2, VarPtr(a(0, 2))
    Debug.Print 1, 0, VarPtr(a(1, 0))
    Debug.Print 1, 1, VarPtr(a(1, 1))
    Debug.Print 1, 2, VarPtr(a(1, 2))
    
    Debug.Print "---------------"
    ReDim a(0 To 1, 0 To 4)
    
    Debug.Print 0, 0, VarPtr(a(0, 0))
    Debug.Print 0, 1, VarPtr(a(0, 1))
    Debug.Print 0, 2, VarPtr(a(0, 2))
    Debug.Print 0, 3, VarPtr(a(0, 3))
    Debug.Print 0, 4, VarPtr(a(0, 4))
    Debug.Print 1, 0, VarPtr(a(1, 0))
    Debug.Print 1, 1, VarPtr(a(1, 1))
    Debug.Print 1, 2, VarPtr(a(1, 2))
    Debug.Print 1, 3, VarPtr(a(1, 3))
    Debug.Print 1, 4, VarPtr(a(1, 4))
    
End Sub
```
結果はこうなりました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215956/11e1bc73-826b-bde9-9e68-1a1c24b3618e.png)

下3ケタに注目して、図にしてみます。
初期状態
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215956/2cc66723-ac79-6cbd-5ca0-9a4f2df60d38.png)

Redim Preserve後
![image.png](https://qiita-image-store.s3.amazonaws.com/0/215956/974a56f4-b6b3-791b-d7e8-3dc0fd57997a.png)

A(0,0)からa(1,2)までの部分の相対的な位置関係はRedimPreserveする前と変わりがなく、新たに後ろに、a(0,3),a(1,3),a(0,4),a(1,4)を追加しています。
配列数の変更をする際の内部処理を簡略にして、高速に処理することが、VBAの動的配列の仕様の狙いなんだろうなと思いました。
VBAはただでさえ、遅い遅いとC++派なプロプログラマーに馬鹿にされるので、高速化はうれしいところですが、VBAがプロ用の言語でないところを考えると、こういうわかりにくい仕様って、どうなんだろうとも思ったりします。
2点の緯度経度の距離を計算する

#経緯
専門学校時代にマップを扱うことがありその時に作った関数をこの機会に残しておこうと思い書きました。

#解説
[山だらけ](http://yamadarake.jp/trdi/report000001.html)にて解説されているヒュベニの公式というものを使いました。式は

```math
\sqrt{(d_yM)^2+(d_zN \cos µ_y)^2}
```

です。

わかりやすく言葉に直すと

```math
\sqrt{(緯度の差 × 子午線曲線半径)^2 + (経度の差 × 卯酉線曲率半径 × cos緯度の平均値)^2}
```

何をしてるんだろうって私も思いました。
よく見ると

```math
\sqrt{(c−a)^2+(d−b)^2}
```

という二点間の距離を求める公式になります。
そこに地球を楕円と仮定した場合の誤差を補正した式らしいです。

#コード
```java:HubenyDistance.java
public class HubenyDistance {

    //世界観測値系
    public static final double GRS80_A = 6378137.000;//長半径 a(m)
    public static final double GRS80_E2 = 0.00669438002301188;//第一遠心率  eの2乗

    public static double deg2rad(double deg){
        return deg * Math.PI / 180.0;
    }

    public static double calcDistance(double lat1, double lng1, double lat2, double lng2){
        double my = deg2rad((lat1 + lat2) / 2.0); //緯度の平均値
        double dy = deg2rad(lat1 - lat2); //緯度の差
        double dx = deg2rad(lng1 - lng2); //経度の差

        //卯酉線曲率半径を求める(東と西を結ぶ線の半径)
        double sinMy = Math.sin(my);
        double w = Math.sqrt(1.0 - GRS80_E2 * sinMy * sinMy);
        double n = GRS80_A / w;

        //子午線曲線半径を求める(北と南を結ぶ線の半径)
        double mnum = GRS80_A * (1 - GRS80_E2);
        double m = mnum / (w * w * w);

        //ヒュベニの公式
        double dym = dy * m;
        double dxncos = dx * n * Math.cos(my);
        return Math.sqrt(dym * dym + dxncos * dxncos);
    }
}
```
CentOS+Node.jsでwebサーバを作った時の話

#初めに
Linux(CentOS)上でNode.jsを試した時に発生した問題と解決策のまとめ

#80ポートでlisten出来ない
##内容
```
Erro: listen EACCES
```
というエラーが表示され、Nodeサーバが起動しない。
0~1023までのポートはウェルノウン(英:Well known "よく知られた")ポートとして既に予約済みであり、一般ユーザがそのポートをしようして受信待ちすることが出来ない。
##解決策
クローズされたテスト環境であったため、スーパーユーザ権限にて実行することにした。（本当はよくないらしい）

```
sudo node <プログラム名>.js
```

#Node.jsのバージョンとnode_modulesのバージョンが合わないことによる不具合
##内容
npmで最新のnode_modulesをインストールしたら、node v0.10.xには対応していなかったらしく、

```
throw err;
```
と表示された。

##解決策
古いnode_modulesを入手し置き換えすることによってエラーは出なくなった。

#結び
今後様々な分野でWebを利用したサービスの構築・運用を求められると思います。
Node.jsに限らず幅広く勉強していきたいです。

追伸 本記事をご覧の皆様へ
私自身まだ初心者で至らぬ点が多々あるかと思います。
至らぬ点は随時ご指摘ください。
SkyWay WebRTCで多人数テキストチャット部屋を実装してみた

SkyWay WebRTCを用いた多人数テキストチャットのサンプルコードです
必要最低限の機能しかありません

#### 処理の流れ

```javascript
// peerオブジェクトを作成

// roomへの入室処理
   // チャットの送信処理
   // チャットの受信処理

// roomからの退室処理
  
```

#### サンプルコード

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>SkyWay SFURoom テキストチャット</title>
</head>
<body>
	room: <input type="text" id="roomName"> <button id="join">入室</button>
	<br><button id="leave">退室</button>
	<hr>
	<input type="text" id="msg" placeholder="チャットを入力"> <button id="send">send</button>
	<hr>
	<div id="chatLog">
		
	</div>

	<script type="text/javascript" src="https://cdn.webrtc.ecl.ntt.com/skyway-latest.js"></script>
	<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
	<script type="text/javascript" src="script.js"></script>
</body>
</body>
</html>
```

```javascript:script.js
// peerオブジェクト
const peer = new Peer({
	key: 'API KEY', // 自分のAPIキーを入力
	debug: 3
});

// 入室
let room = null;
$('#join').click(function(){
	room = peer.joinRoom($('#roomName').val(), {mode: 'sfu'});
	chatlog('<i>' + $('#roomName').val() + '</i>に入室しました');

	// チャットを送信
	$('#send').click(function(){
		var msg = $('#msg').val();
		room.send(msg);
		chatlog('自分> ' + msg);
	});

	// チャットを受信
	room.on('data', function(data){
		chatlog('ID: ' + data.src + '> ' + data.data); // data.src = 送信者のpeerid, data.data = 送信されたメッセージ
	});
});

// 退室
$('#leave').click(function(){
	room.close();
	chatlog('<i>' + $('#roomName').val() + '</i>から退室しました');
})


// チャットログに記録するための関数
function chatlog(msg){
	$('#chatLog').append('<p>' + msg + '</p>');
}
```

####参考資料
https://www.slideshare.net/iwashi86/skyway-how-to-use-skyway-webrtc
https://webrtc.ecl.ntt.com/js-reference

####コメント
SkyWayもJavaScriptも使い始めたばかりでわからないところだらけです_:(´ཀ`」 ∠):
Swift初心者の僕がぶつかった壁①Delegateって何？？を解決する

僕は今，Swift初心者として，Apple Developing iOS https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/
のチュートリアルを進めている最中です．
この記事の主旨は，公式の説明で，今までさっぱりだったdelegateの概念を理解できたので，忘れないためにもまとめておこうというものです．

Degateとは？
辞書的な定義を紹介すると
"A delegate is an object that acts on behalf of, or in coordination with, another object. "(引用： Apple Developing iOS)
「Delegateとは，他のオブジェクトの代理，または協力してはたらくオブジェクトのことです」

なんとなく言いたいことはわかりますが，具体的なイメージが浮かびません．

ここで具体的な話をしてみます．

![スクリーンショット 2017-12-17 11.02.05.png](https://qiita-image-store.s3.amazonaws.com/0/210288/0b5a24c8-94b9-fbc7-4899-e70f777dc4dc.png)

チュートリアルでは上のように，Text Fieldに文字を打って，食べ物の名前(Meal Name)を登録するというものを作ります．

上から順に
・Default Text　がUILabel
・Enter meal name　がUITextField
・Set Default Label Text　がUIButton
となっていて，
UITextFieldに打ち込んだ文字がUILabelに表示され，UIButtonを押すと，表示がリセットされて"Default Text"を表示するという仕様になっています．

下に示すように，まだViewController．swift上で，UITextFieldに打ち込んだ文字をUILabelに表示するためのmethodが書かれていません．
![スクリーンショット 2017-12-17 11.15.15.png](https://qiita-image-store.s3.amazonaws.com/0/210288/5bdac7cb-2053-6740-9440-94dcd5722f27.png)

さあどうしようか？というところで，Delegateの説明が登場します．

もっともシンプルな方法としては，打ち込むと同時に　UILabelに表示させるという方法です．
TextFieldへのユーザーの入力を受け取るに必要となるのがText Field delegateです．

Delecating object(この場合のTextField)は他のオブジェクト(deledate)とのリファレンスを保持します．
そして，適切なタイミングで，Delegating objectがdelegateにメッセージを送ります．このメッセージには，その時にdelegateが実行するイベントに関する内容が書かれています．
（例えば，表示する情報を更新したり，今から起こるイベントがどのような影響を与えるかといったことです）

TextFieldの場合，
ユーザーが文字を入力している間，TextField Delegateと常にコミュニケーションをとって，重要なイベント(タイピングが止まった時)が起こると，これを察知します．
Delegateはこの情報を入力された情報をUILabelにすぐさま表示したり，削除したりというアクションに利用するのです．

まとめ
Delegateは他のオブジェクトとコミュニケーションをとって，仕事をする．

※1時間くらいでささっと書いたので，あとで見直して改善します