OmniAICreator/Qiita-1.07M huggingface dataset:
macOSにHomebrewをインストール

環境：macOS Sierra 10.12.6

macOSでメジャーなパッケージマネージャ
[Homebrew](https://brew.sh/index_ja.html)を導入したい

#やりかた
**Xcodeをインストール**
App storeから[Xcode](https://geo.itunes.apple.com/jp/app/xcode/id497799835?mt=12)をインストール


**コマンドライン・デベロッパーツールをインストール**
ターミナルから`$ xcode-select --install`コマンドを発行すると
以下のようにインストールを要求される

```:ターミナル
$ xcode-select --install
xcode-select: note: install requested for command line developer tools
```

同時にポップアップが出てくるので"インストール"を選択し利用規約に同意
![スクリーンショット 2018-01-14 16.04.58.png](https://qiita-image-store.s3.amazonaws.com/0/174283/a5c520f2-8987-5452-e098-ad494695a09e.png)


**Homebrewをインストール**
コマンドは[Homebrewのサイト](https://brew.sh/index_ja.html)からコピー可能
途中でEnterの入力/インストールユーザのOSパスワードの入力を求められる

```:ターミナル
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

（中略）

Press RETURN to continue or any other key to abort
==>

(中略)

Password:

(中略)

==> Installation successful!

==> Homebrew has enabled anonymous aggregate user behaviour analytics.
Read the analytics documentation (and how to opt-out) here:
  https://docs.brew.sh/Analytics.html

==> Next steps:
- Run `brew help` to get started
- Further documentation: 
    https://docs.brew.sh

```

**Homebrewインストール完了確認**

```:ターミナル
$ brew doctor
Your system is ready to brew.
```
node-inspectでnode.jsのデバッグ環境を構築してみた

Atomエディタでnode.jsのWebアプリケーションを作ろうと勉強中なのですが、デバッグがしたい！って思い、調査したので備忘録として書きます。

Atomに[node-debugger](https://atom.io/packages/node-debugger)というパッケージを利用すれば実現できそうだが、今回はnode-inspectでデバッグ環境を構築してみました。

[公式サイト](https://nodejs.org/en/docs/inspector)を参考にnode.jsのデバッグ環境を構築してみました。

## node-inspect をインストール

node-inspectをグローバルインストール

```bash
npm install --global node-inspect
```

## chrome 拡張機能 NIM の追加

chromeでデバッグを追うことができる拡張機能[NIM (Node Inspector Manager)](https://chrome.google.com/webstore/detail/nim-node-inspector-manage/gnhhdgbaldcilmgcpfddgdbkhjohddkj) を追加します。

追加が完了したら、ブラウザの右上にアイコンが表示されます。
設定が「Auto」になっていることを確認してください。なっていなければ「Auto」に変更をしましょう。

<img width="398" alt="スクリーンショット 2018-01-14 15.16.48.png" src="https://qiita-image-store.s3.amazonaws.com/0/114561/14f75ebd-b9dd-3866-08e1-8b886f0f3467.png">

## 動作確認

起動するときに、　```--inspect```オプションをつけて起動すると、自動的にデバッグ画面が表示されます。

```
node --inspect myscript.js
```

デバッグ実行
![Jan-14-2018 15-57-13.gif](https://qiita-image-store.s3.amazonaws.com/0/114561/98eb65f1-1562-18f6-92b1-58bb2eeed3d9.gif)
PHPからMYSQLデータベースへアクセスできない

PHPから下記コードでMYSQLデータベースへアクセスを行ったがうまくいかなかった。

```mistake.php
<?php
   $dsn = 'mysql:dbname = testphp; host = localhost';
   $user = 'root';
   $password = '';
   $dbh = new PDO($dsn, $user, $password);
   $dbh->query('SET NAMES utf8');
?>
```

MYSQLへは正常に起動していてping(127.0.0.1)も正常に通っていたが
PHPからアクセスすると正常にアクセスできなくなるようだった。

色々調べたところ、原因はmysql:dbname及びhostの前後につけいていた
スペースがいらなかった。

下記が、正常にアクセスできたPHPコード。

```correct.php
<?php
   $dsn = 'mysql:dbname=testphp; host=localhost';
   //上記のdbname及びhost前後のスペースがいらない。
   $user = 'root';
   $password = '';
   $dbh = new PDO($dsn, $user, $password);
   $dbh->query('SET NAMES utf8');
?>
```
pd.scatter_matrixのエラー

# 問題のコード

```py3
import pandas as pd
grr = pd.scatter_matrix(iris_dataframe, c=y_train, figsize=(15,15), marker="o",hist_kwds={'bins':20}, s=60, alpha=.8, cmap=mglearn.cm3)
```
# 表示されたエラー

```エラー出力
/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:2: FutureWarning: pandas.scatter_matrix is deprecated. Use pandas.plotting.scatter_matrix instead
```

# 対処方法
`pd.scatter_matrix` ➡︎ `pd.plotting.scatter_matrix`

```py3

import pandas as pd
grr = pd.plotting.scatter_matrix(iris_dataframe, c=y_train, figsize=(15,15), marker="o",hist_kwds={'bins':20}, s=60, alpha=.8, cmap=mglearn.cm3)
  ```
ActiveRecord だけを使いたいとき


こんな感じのコードををよませれば ok


```rb
require 'active_record'
# Rails で言うところの config/database.yml
ActiveRecord::Base.establish_connection(
    adapter:  'mysql2',
    host: 'localhost',
    username: 'username',
    password: 'password',
    database: 'database',
    # ....
)

# 使いたいテーブルのモデル
class User < ActiveRecord::Base
  # relation とか
end

# ...
```
画像に半透明フィルターを付けたような処理

#画像に半透明フィルターを付けたようなCSS

画像に半透明処理のやり方が分からなかったので調べてやって見ました。

- HTMLファイルの記載内容

```html
<div class="filter"><img class="img" src="xxx.jpg"></div>
```

- CSSファイルの記載内容

```css
.filter {
    background-color: black; /** 半透明で加工したい色合い */
}
.img {
    opacity: 0.5; /** 画像の透明度 */
    display: block;
}
```

- 加工前

![スクリーンショット 2018-01-14 16.01.37.png](https://qiita-image-store.s3.amazonaws.com/0/208719/e8c669e0-4952-2007-dd7b-e732da1a9082.png)

- 加工後

![スクリーンショット 2018-01-14 16.00.27.png](https://qiita-image-store.s3.amazonaws.com/0/208719/acf3bcec-1828-1c89-657e-f8860749313f.png)

これで無事に半透明処理を加えたようになりました。

以上
AWS CLIに複数のAWSアカウントを登録する方法

複数のAWSを利用するプロジェクトに携わっている場合、複数のAWSアカウントをCLIで操作する可能性が出てきます。
Secret Keyは作成時しか見えませんので、毎回AWSにログインしてSecret Keyを作り直すこともナンセンスです。
本記事では、AWS CLIに複数のAWSアカウントを登録し、再度configする手間を省く方法をまとめます。

## AWS CLIのインストール

AWSの公式ドキュメントを参考にinstallを行います。
https://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html
#### 初期設定
defaultで利用するアカウントを登録します。

```
$ aws configure
AWS Access Key ID [None]: ${Your Default ID}
AWS Secret Access Key [None]: ${Your Default Secret Key}
Default region name [None]: ${Region}
Default output format [None]: json
```

## AWS CLIに複数のアカウントを登録する
AWS CLIは--profileオプションを利用することで、複数のアカウントを登録することが可能です

```
$ aws configure --profile xxxx
AWS Access Key ID [None]: ${Your ID}
AWS Secret Access Key [None]: ${Your Secret Key}
Default region name [None]: ${Region}
Default output format [None]: json
```

では、どのようにcredentialなどは登録されているのでしょうか。
AWS CLIのconfig、およびcredentialを保存しているfileを確認してみましょう。

```bash:~/.aws
$ tree ~/.aws
.aws
├── config
└── credentials
```

まずはconfigから確認してみましょう。

```bash:~/.aws/config
[default]
output = json
region = ap-northeast-1
[profile xxxx]
output = json
region = ${Region}
```
[profile　xxxx]といった項目が追加され、先ほど入力した情報と同様の情報が格納されていることが確認できます。
credentialsの方も確認してみましょう。

```bash:~/.aws/credentials
[default]
aws_access_key_id = ${Your Default ID}
aws_secret_access_key = ${Your Default Secret Key}
[xxxx]
aws_access_key_id = ${Your ID}
aws_secret_access_key = ${Your Secret Key}
```
こちらも先ほど入力した情報と同様の情報が格納されていることが確認できました。

## AWS CLIの利用方法
**--profileオプションを利用する**ことによって、~/.aws以下に保存されている情報から、--profileの引数と同様の項目からkeyなどの情報を参照して利用します。
以下の例は、s3バケットの一覧をアカウントを変えて表示させています。
アカウントが変わることで、s3のバケットが変更されるのがわかると思います。

```bash:s3バケットの一覧が変更されていることを確認
$ aws s3 ls
$ aws s3 ls --profile xxxx
```

## まとめ
今回はAWS CLIに複数のAWSアカウントを登録する方法をまとめました。
最近はAWS CLIだけではなく、Serverless frameworkやterraformを利用した構築方法もありますので、そちらの方も随時まとめていけたらと思います。
JSオブジェクトにおけるnew演算子の役割をちゃんと理解する

なんとなくでJavaScript書いてると見落としがちな`new`演算子の役割についてメモがてら書いておきます。

まずどういう時に`new`を使うかというと

```javascript
var obj1 = new Object();
var obj2 = {};

console.log(obj1); // Object {}
console.log(obj2); // Object {}
```
どちらでもオブジェクトは生成できます。

しかし、`new`を使った時とそうでない時の違いは明白。

```javascript
var myFunc = function(){
　　　　this.prop1 = 'bar';
　　　　this.prop2 = 'foo';
　　　　this.method = function(){
　　　　　　　　return this.prop1 + this.prop2;
　　　　}
}

var obj1 = new myFunc();
var obj2 = myFunc();

console.log(obj1.method()); // barfoo
console.log(obj2.method()); // エラーになる
```

もう一つ例を挙げると、

```javascript
var myFunc = function(){
　　　　this.prop1 = 'bar';
}

var obj1 = new myFunc();
var obj2 = myFunc();

console.log(obj1); // myFunc {prop1: "bar"}
console.log(obj2); // undefind
```
obj2は`undefind`になっています。

通常、JavaScriptの関数は、**return文が明示的に指定されていない場合、自動的に呼び出し元には`undefind`が返却されます。**
**`new`を用いて呼び出された場合は、return文が書かれていようがいまいが、自動的にオブジェクトのインスタンスが返却されます。**

最後にわかりやすい極端な例を挙げます。

```js
var myFunc = function(){
　　　　this.prop1 = 'bar';
　　　　return 'foo';
}

var obj1 = new myFunc();
var obj2 = myFunc();

console.log(obj1); // myFunc {prop1: "bar"}
console.log(obj2); // foo
```

`new`を用いない場合はただの関数呼び出しになっています。
仮想通貨の，時価総額に対するボラリティを計算する

# Motivation
Pythonで何かしらWebスクレイピング出来るツール無いかなぁって探していたらこんなものが見つかった
[PythonとBeautiful Soupでスクレイピング](https://qiita.com/itkr/items/513318a9b5b92bd56185)

んで実際に何スクレイピングしようかなぁって思ったところ，
[Cryptocurrency Market Capitalizations](https://coinmarketcap.com/)で，時価総額とか取引量とか表示されるのはありがたいんだけど，取引量を時価総額で割った値とか出してくれないので，勉強がてらwebから値取ってきて計算させるスクリプトを作ろうと思って作りました.

あとqiitaの記事の書き方の勉強．

# 作ったもの
[こちら(Github)](https://github.com/verb55nta/virtual-currency-market-analysis)

サイト内のタグをいろいろ抜き出すためにごちゃごちゃした実装にはなりましたが...
一応時価総額がUSDで\$10,000 ~ $5,000,000,000までのうち，取引量が時価総額の10%を超えるものを，取引量が大きい順に表示させました．
実行環境は，Python3です．

# 表示例(2018/01/14に実行したもの)

```
208             99301292.5              Ink             3.7405756828391734
33              1475400923.91           Tether          1.8505342891913141
616             4107791.18765           Capricoin               1.7432921180437937
681             2416470.0               Ethereum Dark           1.6738631143775837
924             165562.563206           Bitvolt         1.171949722465811
918             184495.709847           CybCSec         1.0481490337112274
894             313196.642869           LiteCoin Ultra          1.025186595420499
234             80374015.1158           Moeda Loyalty...                0.7798577675843676
929             141253.35874            Veros           0.742623049361127
538             8525342.196             APX             0.6710193993953788
921             180062.839795           SwapToken               0.5275791501908651
281             55410632.4461           Propy           0.5154841000557897
200             109960874.567           Viberate                0.4951524823206529
850             576903.471847           Master Swiscoin         0.4932783626503666
253             71232079.644            bitCNY          0.4495628958194734
```
一番目のカラムが時価総額ランキング，二番目のカラムが時価総額（USD），三番目のカラムが名称，四番目が(取引量)÷(時価総額) [USD]です．
cube20のルービックキューブソルバを使う

[cube20](http://cube20.org/ "cube20")のルービックキューブソルバを使う機会があったので使い方を書いておきます。

# ダウンロード

## 方法1.CWEBでインストール

### ソースコードのダウンロード

```bash:ターミナル
$ cd
$ wget -r -np http://cube20.org/src/
$ cd cube20.org/src/
```

### CWEBのインストール

```bash:ターミナル
$ sudo yum install texlive-* (※TeX環境が未インストールの場合のみ)
$ wget ftp://ftp.cs.stanford.edu/pub/cweb/cweb.tar.gz
$ mkdir cweb && tar xzf cweb.tar.gz -C cweb
$ cd cweb
$ make
$ sudo make install
```

### C++へ変換

そのまま`make`したいところだが、そうするとエラーが出るので、`twophase.w`および`hcoset.w`内の`mutex`を`mutex1`等に変えたのち

```bash:ターミナル
$ make
```

して、エラーが出なければ成功。

## 方法2.C++に変換されたものをインストール

[ここ](https://github.com/dwalton76/cube20 "ここ")からダウンロードできる。

Clone or Download -> Download ZIPからダウンロードした後、`twophase.cpp`と`hcoset.cpp`内の`mutex`を`mutex1`等に変えて

```bash:ターミナル
$ make
```

して、エラーが出なければ成功。

# 使い方

基本的には

```bash:ターミナル
$ echo "キューブの状態" | ./twophase [option]
```

で動かす。

## キューブの状態を教える

これが面倒だが、キューブの状態をプログラムに教えるため、記号でキューブの一を入れていく必要がある。

例えば、キューブの上面中央に白、前面中央にオレンジ、下面中央に黄色、後面中央に赤、右面中央に緑、左面中央に青のキューブがあるとき、

> 上面前(白オレンジ)
>同じく右(白緑)
>同じく後ろ(白赤)
>同じく左(白青)
>
>下面前(黄色オレンジ)
>同じく右(黄色緑)
>同じく後ろ(黄色赤)
>同じく左(黄色青)
>
>手前右(オレンジ緑)
>同じく 左(オレンジ青)
>
>うしろ右(赤緑)
>同じく左(赤青)
>
>右上前(白オレンジ緑)
>右上後ろ(白緑赤)
>左上後ろ(白赤青)
>左上前(白青オレンジ)
>
>右下前(黄色緑オレンジ)
>左下前(黄色オレンジ青)
>左下後ろ(黄色青赤)
>右下後ろ(黄色赤緑)

の順で、プログラムに状態を教える(例：FU RU BU LU FD RD BD LD RF LF RB LB UFR URB UBL ULF DRF DFL DLB DBR等)

## オプション

[ここ](http://cube20.org/src/twophase.html "ここ")にオプション一覧がある。

## 実際の使用例

```bash:ターミナル
$ cd cube20.org/src
$ echo "FU RU BU LU FD RD BD LD RF LF RB LB UFR URB UBL ULF DRF DFL DLB DBR" | ./twophase -s 20
```

これはSuperflip状態のキューブを20手以下の探索で打ち切るオプション付きで実行する場合である。これを実行すると

```bash:ターミナル
$ This is twophase 1.1, (C) 2010-2012 Tomas Rokicki.  All Rights Reserved.
$ Solution 1 len 20 probes 2775964
$ F1B1U2R1U3D1R2B2L2F1U2R3L3U1B2D1R2U1B2U1
$ Verified integrity of phase one pruning data: -1939391245
$ Verified integrity of phase two pruning data: 1084146253
$ Solved 1 sequences in 1.41001 seconds with 2775964 probes.
$ Completed in 1.41005
```

と表示され、正しく`F1B1U2R1U3D1R2B2L2F1U2R3L3U1B2D1R2U1B2U1`通りに動かすとそろえられる。(最初に実行したときは数分かかる)
Node.jsからSORACOM APIを使用する


Node.jsからsoracomのAPIを使用してみようと思ったら公開されているライブラリが動かなかったので作りました。

Node.jsの'request'パッケージからSORACOMのAPIを叩くと、何故かエラーが返ってきてしまい解決できなかったので、'https'のパッケージを使用して作りました。


# SORACOM APIについて

## インストール方法
```
npm install soracom_api
```

## 使い方
"authKey"と"token"はAPIにアクセスするときに自動的に取りに行きます。

### 認証
emailによる認証と、authKeyによる認証の双方に対応しています。

```
var soracom = new Soracom({email: 'mail address',password:'password'});
```
```
var soracom = new Soracom({authKeyId: 'keyId',authKey:'secret'});
```

When this API accesses SORACOM service, it takes authKey and token automatically.

### (例) IMSIの情報を取得する

```
var Soracom = require('soracom_api');
var soracom = new Soracom({email: 'mail address',password:'password'});
soracom.get('/subscriber/imsi',function(err,res){
  console.log({err:err,res:res});
});
```

### (例) SIMに名前をセットする
```
var Soracom = require('soracom_api');
var soracom = new Soracom({authKeyId: 'keyId',authKey:'secret'});
soracom.put('/subscriber/imsi/tags',[
  {
    "tagName": "name",
    "tagValue": "my_test_sim"
  }
],function(err,res){
  console.log({err:err,res:res});
});

```

## API
### soracom.get('path',function(err,res){ callback });
parameters:
 - path:  リクエストのパスを指定します
return:
 - err: エラーメッセージ、正常時はnull
 - res: 正常時にレスポンスが返ります

### soracom.post('path',params,function(err,res){ callback });
- parameters:
 - path:  リクエストのパスを指定します
 - params: リクエストのbodyを設定します。bodyが無いときは省略可能です。
- return:
 - err: エラーメッセージ、正常時はnull
 - res: 正常時にレスポンスが返ります

### soracom.put('path',params,function(err,res){ callback });
- parameters:
 - path:  request path
 - params: リクエストのbodyを設定します。bodyが無いときは省略可能です。
- return:
 - err: エラーメッセージ、正常時はnull
 - res: 正常時にレスポンスが返ります

### soracom.delete('path',params,function(err,res){ callback });
- parameters:
 - path:  request path
 - params: リクエストのbodyを設定します。bodyが無いときは省略可能です。
- return:
 - err: エラーメッセージ、正常時はnull
 - res: 正常時にレスポンスが返ります
Ubuntu16.04 インストール直後の各種設定

Ubuntuを開発用マシンとして立ち上げる際、開発に必要そうな各種設定について説明します。

# CUIで起動できるようにする

```
sudo systemctl set-default multi-user.target
```

# 開発用ツールをインストールする
筆者が必要だと思うものをざっと挙げました。

```
sudo apt-get install gcc g++ make openssl libssl-dev libbz2-dev libreadline-dev libsqlite3-dev build-essential 
```

# その他よく使うコマンドをインストールする
vim, zip, git, nkf(文字コードの変換ツール)などをインストールします。これらはデフォルトではインストールされていません。

```
sudo apt-get install zip unzip nkf git screen
```

# アップグレードする

```
sudo apt-get update
sudo apt-get upgrade
```

# pythonをインストールする
管理複数バージョンのPythonを簡単に切り替えられるようにpyenv経由でインストールします。

```
git clone git://github.com/yyuu/pyenv.git ~/.pyenv

vi ~/.bashrc

# 以下を追記して保存
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

source ~/.bashrc

pyenv install --list
pyenv install 3.5.2
pyenv global 3.5.2
```

listで表示される中からお好きなバージョンを選んでOKです。ここではバージョン3.5.2をインストールしました。

# rubyをインストールする

同様にrbenvでrubyをインストールします。

```
git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

vi ~/.bashrc

# 以下を追記して保存
export RBENV_ROOT="$HOME/.rbenv"
export PATH="$RBENV_ROOT/bin:$PATH"
eval "$(rbenv init -)"

source ~/.bashrc

rbenv install --list
rbenv install 2.2.2
rbenv global 2.2.2
```

ここでも、バージョンはお好きなものをお選びください。

これで最低限の開発環境が整いました。
以上、Ubuntuを開発用マシンとして立ち上げる際に必要な各種設定についての説明でした！　楽しいUbuntuライフを！
Raspberry Pi 3 model B 初期設定まで

初めていじったラズパイ。
忘れてしまうため、自分用のメモ

#1. 準備
1. micro SDカード
2. ディスプレイ
3. HDMIケーブル
4. USBマウス
5. USBキーボード
6. microUSB(電源用)
7. SD Card Formatter
8. NOOBS

#2. OSインストールまで
1. [SD Card Formatter](https://www.sdcard.org/downloads/formatter_4/)をダウンロード。

2. ダウンロードしたSD Card Formatterをインストール。
3. SD Card Formatterで準備したSDカードをフォーマット。
4. [NOOBS](https://www.raspberrypi.org/downloads/)をZIP形式でダウンロード。
5. NOOBSを解凍し、フォーマットしたSDカードにコピー。

#3. OSインストール
1. HDMIケーブル、USBマウス、USBキーボードを本体に接続。

2. NOOBSをコピーしたSDカードをスロットへ入れる。
3. microUSBを接続して起動させる。
4. NOOBSが起動したら、下にある言語を「日本語」、Keyboadを「jp」に設定。
5. Rasbian(recommended)にチェックを入れてインストール

#4. 初期設定
##4.1 Wi-Fi設定
1. 自分のネットワークが表示されていないため再起動。

2. パネルの「Wireless & Wired Network Settings」から自分のネットワークを選択。
3. Pre Shared Key に入力してOKを押下。

##4.2 ローカライゼーション
1. 「applications menu」-「設定」-「Raspberry Piの設定」を選択。

2. 「ローカライゼーション」タブを選択し、ロケール、タイムゾーン、キーボード、無線LANの国をそれぞれ日本に設定。

##4.3 リモート設定
<ol><li> xrdp をインストール。

~~~
sudo apt-get update
sudo apt-get install xrdp
~~~
</li>
<li>IPアドレスの確認

~~~
ifconfig
~~~
</li>
<li>PC(Windows 10 HOME)でリモートデスクトップ接続を起動</li>
<li>確認したIPアドレスを設定して接続</li>
<li>以下の設定を入力してOKを押下。
Session : Xorg
username: pi
 password: raspberry
</li>
→ 接続できるが、リモート元PCから「Raspberry Piの設定」が開けない。LXTerminalから起動してみる。

~~~
env SUDO_ASKPASS=/usr/bin/pwdrcg.sh sudo -A rc_gui
No protocol specified

(rc_gui:2267): Gtk-WARNING **: cannot open display: :10.0
~~~

ディスプレイを0.0にしたり

~~~
export DISPLAY=0.0;
~~~

Xサーバへのアクセスを許可

~~~
xhost +
~~~

をやったがうまくいかない。諦める。

<li>「Raspberry Piの設定」を起動し「インターフェース」タブを選択。</li>
<li> VNCを有効に設定。</li>
<li> リモート元PCにVNC Viewerをインストール</li>
<li>同じようにIPアドレス、ユーザ名、パスワードを入力。</li>

完了。疲れた。
Goland上でのディレクトリ構成はこうしている

# はじめに
前まではrailsで仕事をしていて、railsだと既に決まったディレクトリ構造があって、問題なく仕事はできていました。
最近、golangを触り始めていて、ディレクトリ構造のベストプラクティスってあんまり記事がないなあと思うところがあり、
「自分はこうしてますよ」という物を残そうと思います。

ツッコミ大歓迎。

# 追記 2018/12/10

最近は[Modules](https://github.com/golang/go/wiki/Modules)の方をよく使っています。
Depでやりたかったpackageの細かいバージョン管理は実現できています。
各ディレクトリに冗長的にファイルを作るよりはGOPATH以下に一括して管理できているのでいい感じです。

Modulesを導入すると必然的にこの記事に書いてあるディレクトリ作成は不要になります。

みんなModules使いましょう。

# 本題

golangって、何も考えずに開発しようと思えば、おもむろに任意のディレクトリにmain.goとかを書けば動くので、
チュートリアル的なもんであれば、特に

```
~/hoge/
  `- main.go
```

こんな感じで全然動くと思います。

でも、glideやらdepやらで管理したいとなったり、rubyでいうところのbundler or home管理下のgemの
使い分けをしたいとかなると、ちょっとこれだけじゃ困ります。

そうなると、こんな感じになります。

```
~/go
path/to/project/
  |- vendor/
  |- GoPkg.yml
  |- GoPkg.lock
  `- main.go
```

実はこれでだいたい話としてはFAです。

# goenvとの併用

自分は、golangのバージョンを切り替える目的で（まだ必要に迫られてないですが）
goenv（anyenv）を使っています。

goenvは下記の```local```コマンドでディレクトリ毎に使用するバージョンをいい感じに切り替えてくれます。

```
$ goenv local 1.9
$ cat .go-version
1.9
```

つまり```.go-version```記載のバージョンでgo実行されることになります。

# プロジェクトごとの環境切り分け

goバージョンを切り替えたりする理由はズバリ「プロジェクト毎に違う物を使う」からです。
本来なら、何も気にせず最新バージョンだけ使いたいですが、実運用だとそうは行かないです。

自分はJetBrains製のGolandを使っています。
Golandって、プロジェクト毎にGOROOT,GOPATHを切り替えることができますので、基本的にはそれを使います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12060/9d35128b-e315-56f4-b5fd-8bb91f450e02.png)

でも、これだけだと GOBIN が設定されません。
GOBINは```go get -u```や```go install```で```GOPATH/bin```にインストールしたツールにアクセスするためのパスです。

```go generate```などで使うコマンドはここに格納しておく感じです。

私はローカル上での確認はGolandのDebugやdelveや```go run```を使うので、
デバッグのためにプロジェクトのバイナリをbin以下にインストールとかはやりません。

direnvを使います。

```
$ cd path/to/project
$ direnv edit
```

```
export GOBIN=path/to/bin/ #絶対パスを指定すること
```

そうすると、ディレクトリ以下に```.envrc```ができるので、次からはそれが適用されます。

# golangって$GOPATH/src/github.com/name/projectってやんなきゃいけない
多分、やんなきゃってことではないんですが、そう推奨されてるっぽいです。

なので、こんな感じです。

```
GOPATH/
  |- bin/
  |- pkg/
  `- src/
      `- github.com/path/to/project
````

# 色々まとめるとこんな感じです。

```
# GOPATH=任意のディレクトリ
# GOROOT=goenv配下のgoディレクトリ
# GOBIN=$GOBIN/bin の絶対パス

# ディレクトリ構造
GOPATH(任意でOK) # Golandではここからプロジェクトとして開く。
  |- .envrc # GOBINを指定(direnv)
  |- bin/ # go install したツールとか
  |- pkg/ # 中間ファイルとかここ(あんまり意識しなくていい)
  `- src/ # 自分のパッケージとツール用のパッケージのソースはここで管理
　　　　　　　　　　　　`- github.com
          `- junpayment/
                `- project/
                    |- GoPkg.toml
                    |- GoPkg.lock
                    |- vendor/  # dep ensure で生成、基本気にしなくていい
                    |- lib/ # パッケージのファイルはここでコーディング
                    `- main.go
```

# 注意点
vendor以下にまだインストールしてないパッケージに依存してるのに、プロジェクトがビルドできてしてしまうことがある。
それは、 GOPATH/src直下に既にインストールしている可能性があるので超注意。

# 追記
## ディレクトリ構造を作るスクリプトを作りました
よかったら使ってください。
https://github.com/junpayment/go-dir-maker


以上
自分用Vagrant備忘録_(┐「ε:)_


コマンドを忘れるので，自分用の備忘録として共有です（まる）
（最新更新日：2018/01/14）


## そもそもVagrantって？
- [Vagrantの公式](https://www.vagrantup.com/)
- [開発環境の構築・共有を簡単にするVagrant入門](https://thinkit.co.jp/story/2015/03/19/5740)

## VagrantFileのURL
- [VagrantFileのURL](http://www.vagrantbox.es/)

## Vagrant作成

### 作成
```
#!/usr/bin/env bash
echo "vagrant box list"
vagrant box list

echo "vagrant box add NAME"
vagrant box add [vagarnt-box-name]

echo "vagrant box add NAME URL"
 vagrant box add [vagarnt-box-name] [URL or FilePath]

 echo "vagrant init NAME"
 vagrant init [vagarnt-box-name]

 echo "vagrant up"
 vagrant up

 echo "vagrant ssh"
 vagrant ssh

```
### Vagrant起動
```
#!/usr/bin/env bash
echo "cd NAME"
cd [vagarnt-box-name]

echo "vagrant up"
vagrant up

echo "vagrant ssh"
vagrant ssh

```
alexaとnode-redを用いて、運行情報を調べる

#使用した物
* ハードウェア
 * AmazonEcho    
 * GoogleHomeMini
 * ラズベリーパイ(node-red)
* ライブラリ等
 * [Node-RED Alexa Home Skill Bridge](https://alexa-node-red.bm.hardill.me.uk/)
 * [google-home-notifier](https://github.com/noelportugal/google-home-notifier)

#alexaのカスタムスキルでやろうとした
公式の[alexaスキル開発トレーニング](https://developer.amazon.com/ja/alexa-skills-kit/training/building-a-skill)と[電車の運行情報を教えてくれるAlexa Skillを作ってみた](https://qiita.com/radiocat/items/50c1b1c3b7de39a781f4)を参考に電車運行情報のスキルを作成した。
自分の場合、運行情報を調べたい路線が2路線あったので、スキルの呼び出し方が「alexa、運行情報を開いて　JR(路線名)」のようになってしまい使い勝手が悪かった。

思考錯誤した結果、以下の[Node-RED Alexa Home Skill Bridge](https://alexa-node-red.bm.hardill.me.uk/)を用いて無理やり実現することにした。

# node-red
node-red導入法は、他にも参考情報がたくさんあるので割愛します。

## Node-RED Alexa Home Skill Bridgeの無理やりな使い方
[Node-RED Alexa Home Skill Bridge](https://alexa-node-red.bm.hardill.me.uk/)は、家電に対応しているスキルの為、「〇〇をつけて(消して)」、「〇〇を✖✖%にして」の呼びかけになるが、alexaアプリの定型アクションに対応している為、呼びかけ方をラップして変更する事が出来る。

自分は「alexa、電車をつけて(消して)」の命令を「alexa、路線A(路線B)」の定型アクションにすることで実現している。

## google-home-notifier
[Node-RED Alexa Home Skill Bridge](https://alexa-node-red.bm.hardill.me.uk/)の応答メッセージを編集してAmazonEchoにしゃべらせるやり方がわからなかったので、[google-home-notifier](https://github.com/noelportugal/google-home-notifier)を用いて、GoogleHomeMiniに取得情報を喋らせた。

## node-red全体図
AmazonEchoからの音声入力の他に、injectノードを用いて、定刻に運行情報を取得するようにしている。
運行情報取得のfunctionノードの中で、各路線の運行情報を取得して、GoogleHomeMiniにしゃべらせる処理を記述している。

![運行情報.PNG](https://qiita-image-store.s3.amazonaws.com/0/226980/4cf8ddf5-2908-2bb4-3c4e-dbe2a47438f2.png)
SwiftLint の導入

今年度の 6 月頃から iOS アプリの開発をしております [@hofzzy](https://qiita.com/hofzzy) と申します。
業務で [SwiftLint](https://github.com/realm/SwiftLint) を導入したのでその知見を共有します。

## Installation

複数人開発において SwiftLint のバージョンを揃えたかったので、CocoaPods を使用してインストールしました。
Homebrew でインストールすることも可能ですが、筆者はその方法を試していないので、今回その説明は割愛させていただきます。

**Podfile に SwiftLint を追加する**

```:Podfile
platform :ios, '10.0'

target 'sample1' do
  use_frameworks!

  pod 'SwiftLint', '0.23.0'
end
```

Podfile に SwiftLint を追加したらターミナルで `pod install` を実行しましょう。以上でインストールは完了です。

## Xcode

Xcode でビルドをした際に自動で Lint が走るようにします。

Xcode でプロジェクトファイルを選択し、Build Phase の Run Script に以下のスクリプトを貼りつけましょう。

```
if which "${PODS_ROOT}/SwiftLint/swiftlint" >/dev/null; then
    ${PODS_ROOT}/SwiftLint/swiftlint
else
    echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
```

<img width="1110" alt="rub_script.png" src="https://qiita-image-store.s3.amazonaws.com/0/230887/3787ab19-1cfb-b5ee-b7e7-36412b1c1b5b.png">

これでビルド時に Lint が適用され、警告やエラーがあれば Xcode の Issue Navigator に表示されるようになります。

## Configuration

デフォルトのルールのまま運用していくには色々不都合があったため、Lint の設定をカスタマイズしています。
ます SwiftLint を導入したプロジェクトのルート直下に `.swiftlint.yml` を作成します。筆者は以下のような内容で作成しました。

```:.swiftlint.yml
included:
  - MyApp/
excluded:
  - Pods/
opt_in_rules:
  - closure_spacing
  - conditional_returns_on_newline
  - empty_count
  - operator_usage_whitespace
disabled_rules:
  - force_cast
  - force_try
line_length: 300
identifier_name:
  min_length:
    warning: 1
```

**included**

ここには Lint の対象とするディレクトリ (ファイル) のパスを記述します。

**excluded**

ここには Lint の対象から除外するディレクトリ (ファイル) のパスを記述します。筆者は CocoaPods でインストールしたライブラリを Lint の対象から除外するようにしています。

**opt_in_rules**

デフォルトでは除外されているルールを追加したい場合はここに記述します。
ルールの一覧は SwiftLint の GitHub に記載されています。(https://github.com/realm/SwiftLint/blob/master/Rules.md)

**disabled_rules**

デフォルトで適用されているルールで無効にしたいものがある場合はここに記述します。
なるべくここには何も書かない方が望ましいのかもしれませんが、筆者は場合によって force cast や force try は使用するので、この二つを警告するルールは無効化しています。

**既存ルールの警告レベルの調整**

警告レベルを調整したいルール名の後に数値を指定することで設定できます。

- line_length

line length による警告レベルを調整します。
筆者は Macbook Pro 13-inch のディスプレイで作業することが多いため、導入当初は 140 くらいで運用していたのですが、UIKit のコンポーネントに実装されている delegate メソッドなどはそれを軽々と越えてくるため、いまは 300 くらいで運用しています。

- identifier_name

変数の文字数に関する警告レベルを調整します。
デフォルトだと `min_length: warning: 2` が設定されているので、文字数が 2 文字の変数には警告が出ます。

## Auto correct

SwiftLint は autocorrect オプションをつけて実行することで、軽微なエラーを自動で修正してくれます。
Auto correct を実行したい場合は、Run Script のスクリプトを以下のように書きかえます。

```
if which "${PODS_ROOT}/SwiftLint/swiftlint" >/dev/null; then
    ${PODS_ROOT}/SwiftLint/swiftlint autocorrect
    ${PODS_ROOT}/SwiftLint/swiftlint
else
    echo "warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint"
fi
```

autocorrect オプションをつけた場合、標準の Lint は実行してくれないため `swiftlint autocorrect` と `swiftlint` の両方を実行する必要があります。

##
UbuntuにNVIDIAドライバを入れる手順

# 補足(2018/09/05追記)
この記事の投稿後，後により詳細をまとめたものを投稿した．
[GPUを積んだラップトップにUbuntu16.04をインストール](https://qiita.com/Reizouko/items/cdb208fb00df428c7742)

# はじめに

深層学習の環境構築を行うために,Ubuntu下でGPGPU環境を構築したかった.
しかし,想像以上に手こずったので備忘録として.
まだ試行錯誤の段階なので随時更新する.

### 今回試した環境
|  | |
|:--:|:--:|
|PC|MSI GE72MVR-7RG-059JP|
|OS|Ubuntu16.04LTS|
|GPU|NVIDIA GeForce GTX 1070|

 

#1.ubuntuのバージョン

ubuntuのバージョン,日本語Remixか否かによってもインストールの成否がかかってくる.
gnomeバージョンでも試したが上手くいかなかった.

#2.ubuntuをインストール

###インストールディスクのgrubでやること

これをやらなければインストール終了時に行う再起動でもれなくフリーズする.

grubを開き

```
kernel /casper/vmlinuz file=/cdrom/preseed/ubuntu.seed boot=casper quiet splash -- debian-installer/language=ja keyboard-configuration/layoutcode?=jp keyboard-configuration/modelcode?=jp106
```

この`quit splash`の部分を

`pci=nomsi quiet splash nomodeset`とする.

日本語キーボードの場合=を入力する際は^を打つ.

###grubを編集

インストールが成功し,無事起動できたらNVIDIAドライバを入れる下ごしらえとしてgrubを編集.
`sudo vi /etc/default/grub`
事前にvimをインストールしておくと良いかも.

下の2行

```
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""
```
を

```
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash pci=nomsi nomodeset"
GRUB_CMDLINE_LINUX="pci=noaer"
```
と書き換える.
編集後にreboot

#3.NVIDIAドライバを入れる

再起動に成功したらまず,`sudo service lightdm stop`
なお,これはGUI環境で行うと何故かもれなくフリーズするので,`Ctrl+Alt+F1`にてCUI環境に移動した後に行う.

その後`sudo apt search nvidia`でNVIDIAドライバを探す.

今回はnvidia-375を入れたかったので`sudo apt search nvidia |grep 37`

###インストール
`sudo apt-get install nvidia-375`
~~`sudo ubuntu-devices autoinstall`~~

`sudo service lightdm restart`

`sudo reboot`

#4.インストールの確認

`nvidia-smi`でgpuの動作を確認

#おまけ.カーネルのバージョン固定

アップグレード等でカーネルが更新されると,ドライバとの依存関係がごちゃごちゃになる様で,もれなく無限フリーズ地獄に陥り起動自体できなくなる.
カーネルのバージョンを戻して直そうにも,一度更新してしまえば時既に遅し,grubで旧バージョンのカーネルを選択してもフリーズしてしまい起動できない.

そこで,カーネルのバージョン固定を行い,更新を阻止することにした.

まず,aptitudeコマンドでカーネルのバージョンを確認する.
`$ aptitude show linux-generic`

次に,/etc/apt/preferences.d/linux-kernel.prefに下記の様に保存する.

>
Package: linux-generic
Pin: version 4.4.0.109.114
Pin-Priority: 1001
>
Package: linux-headers-generic
Pin: version 4.4.0.109.114
Pin-Priority: 1001
>
Package: linux-image-generic
Pin: version 4.4.0.109.114
Pin-Priority: 1001

#参考記事

[【罠がいっぱい！】ubuntu 16.04 LTS をMSI製ノート(GE62 6QC)にinstall](https://qiita.com/Urushibara01/items/b64f86afe5908bd30d5c)
babelのインストール


# babelのインストール

次にbabelのインストールをします。
[babel](https://babeljs.io/)とは、まだブラウザがサポートしていない標準機能を使えるようにコードを変換するnode.js製のjavascriptインタプリタです。

例えば、es2016をes2015に変換したり、Chromeのとあるバージョンに変換したりできます。

## babel-cliのインストール

```bash
$ npm install --global babel-cli
```
※「--global」はグローバルインストールをするオプション

## es2015, es2016, es2017 のいずれかにコンパイルしたい場合

```bash:es2015
$ npm install --global babel-preset-es2015
```
```bash:es2016
$ npm install --global babel-preset-es2016
```
```bash:es2017
$ npm install --global babel-preset-es2017
```
nodeのインストール

## nvmのインストール

[nvm](https://github.com/creationix/nvm)は「Node Version Manager」の頭文字を取ったもので、これを利用することで複数のバージョンのnodeをインストールすることができ、バージョンを切り替えることができます。

```bash
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
```
※2018年1月時点

nvmは無くてもnodeのインストールができますが、バージョン管理ができるということで、まずはnvmをインストールします。

## nvm による node のインストール

nvmでインストールできるnodeのバージョンの一覧を確認することができます。

```bash
$ nvm ls-remote
```

バージョンの一覧を確認して、利用したいバージョンを指定して、nodeをインストールします。

```bash
$ nvm install (version)
```

インストールしたnodeのバージョンになっていることを確認します。

```bash
$ node -v
v6.2.1
```

これで、nodeのインストールは完了です。

また、```nvm use```コマンドでバージョンを切り替えることができます。

```
nnvm use (version)
```
conoha-isoで落としたイメージが妙に古いとき

[conoha-iso](https://github.com/hironobu-s/conoha-iso)はOSを取っ替え引っ替えする自分はよくお世話になるツールだが、たまに面倒なことが起こる。

# Ctimeを見てみよう

CoreOSを入れようと思い、何となく `conoha-iso download` を行うと

```console
$ coreos-install -d /dev/vda -i ignition.json
/usr/bin/coreos-install: illegal option -- i
```

…はい？ ignition.json読めないの？

不思議に思い、少し確認してみたところ `conoha-iso list` で

```console
% conoha-iso list
[Image1]
Name:  coreos_production_iso_image.iso
Url:   https://stable.release.core-os.net/amd64-usr/current/coreos_production_iso_image.iso
Path:  /mnt/isos/repos/tenant_iso_data/e8df823792164992a808a95e7112c097/coreos_production_iso_image.iso
Ctime: Thu May 28 09:07:56 2015
Size:  169869312
```


**Thu May 28 09:07:56 2015 だあっ！？**

どうもConoHaのAPIはダウンロード要求に対して、もし同じURLが存在するなら既存のイメージを利用するようだ。
で、そのイメージは**少なくとも2年は更新されていない**ということだろうか？

## 仕方ないので

currentなどを用いず、バージョンやリビジョンを明記して落とすしか無いようだ。

```console
% conoha-iso download -i https://stable.release.core-os.net/amd64-usr/1576.5.0/coreos_production_iso_image.iso
INFO[0001] Download request was accepted.
% conoha-iso list
[Image1]
Name:  coreos_production_iso_image.iso
Url:   https://stable.release.core-os.net/amd64-usr/1576.5.0/coreos_production_iso_image.iso
Path:  /mnt/isos/repos/tenant_iso_data/e8df823792164992a808a95e7112c097/coreos_production_iso_image.iso
Ctime: Sat Jan  6 03:27:41 2018
Size:  346030080
```

頼むよおじさん…。
# jupyter notebookのインストール(windows10 + python3,6 + pip)


anacondaに入っていると言われたけれど
必要なものだけ後から入れればいいかと思い
windows10に素のpython3.6とpipで入れてみようとしたところ
下記のようなエラーが出た。

```
> pip install jupyter
...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 123: invalid start byte
```

参考:
[Win + Python3.6で「pip install」を実行したときに「UnicodeDecodeError: 'utf-8' codec can't decode byte 0x83」と表示される。](https://qiita.com/ruteshi_SI_shiteru/items/be6a58276bdbd67dc096)
[try fix encode error #4251 #4280](https://github.com/pypa/pip/pull/4280/files)

windows+python3.6+pip の既知の不具合との事。
プルリクエストは出ているそうなので、そのうち治ると言われても
今動かしたいので、上がっているプルリクエストの内容を
そのまま`pip/compat/__init__.py`に手動で追加してひとまず対応する。

```pip/compat/__init__.py
 import os
 import sys
+import locale
```

`import locale`を追加して

```pip/compat/__init__.py
 if sys.version_info >= (3,):
     def console_to_str(s):
-        try:
-            return s.decode(sys.__stdout__.encoding)
-        except UnicodeDecodeError:
-            return s.decode('utf_8')
+        return s.decode(locale.getpreferredencoding() or "utf-8", 'replace')
```

`console_to_str`関数の中身を上記のように
`return s.decode(locale.getpreferredencoding() or "utf-8", 'replace')`に変更

改めてpipでインストールし直してみる
今度は通った。
fedora26: アプリケーションをダウンロードしてDesktop Lancherから実行可能にする方法

# 参考にしたページ
https://blog.scottlowe.org/2017/11/21/installing-postman-fedora-27/

# 1. ダウンロード

curl でも wgetでもブラウザでもなんでもよいのでとりあえずローカルに持ってくる

# 2. 解凍する

例）tar.gzファイルを解凍して /opt直下に配置

```zsh
sudo tar xvzf Postman-linux-x64-5.5.0.tar.gz -C /opt
```

# 3. 実行ファイルを移動する

上記の例では```tar```コマンドのオプション```-C /opt```をつけて移動しているため省略

# 4. シンボリックリンクを作成

例）```/opt/postman/Postman```という実行ファイルのシンボリックリンクを```postman```という名前で```/usr/local/bin```直下に作成

```zsh
sudo ln -s /opt/Postman/Postman /usr/local/bin/postman
```

terminalから実行するだけならこれだけでOK。

※当たり前ですが、パスが通っている場所に置かないとダメです。パスの確認方法は以下の通りです。

```zsh
echo $PATH
```



# 5. Desktop Lancherに設定

Desktop Lancherの設定ファイルの格納場所は```~/.local/share/applications```。
ここにアプリごとの設定ファイルを作成する。

例）```~/.local/share/applications```に```postman.desktop```という設定ファイルを作成

```zsh
cat << EOF > postman.desktop
[Desktop Entry]
Name=Postman
GenericName=API Client
X-GNOME-FullName=Postman API Client
Comment=Make and view REST API calls and responses
Keywords=api;
Exec=/opt/Postman/Postman
Terminal=false
Type=Application
Icon=/opt/Postman/resources/app/assets/icon.png
Categories=Development;Utilities;
EOF
```
.desktopファイルの書き方については以下参照：
https://wiki.gnome.org/Initiatives/GnomeGoals/CorrectDesktopFiles
https://specifications.freedesktop.org/desktop-entry-spec/latest/ar01s06.html
[検証中]Reactで初回render時にcomponentDidUpdateが呼び出される時の対処法

#※注意※
この記事の対処法は現在検証中です。
また、`componentDidUpdate()`が呼び出される原因についても別の要因が考えられたため、
問題を一つずつ分解していき、わかり次第記事に追記していきたいと思います。

#問題
Reactのライフサイクルで、初回読み込み時に呼び出されるメソッドは`componentWillMount()`,`render()`,`componentDidMount()`だが、SPAを作っていて`componentDidUpdate()`も同時に呼び出されてしまうという現象にハマった。

備忘録として、原因や解決法をメモしておきます。

#原因
`render()`内で非同期的に子コンポーネントを描画する処理を書いているとそれがトリガーとなり、初回ページの読み込み時にも`componentDidUpdate()`が呼び出されてしまう。

#SPAの構造
- App (親コンポーネント)
- Message (子コンポーネント)

Appは配列で`messages`というstateを持ち、初回にFirebaseなどの外部DBに接続し、格納されているテキスト形式のメッセージを取得する。
Appの`render()`内で取得した`messages`をmapメソッドでひとつずつ個々の`Messages`コンポーネントとして`return()`する。

#具体的にはこういう処理が原因
~~class Appの`render()`内でmapメソッドを使うと、配列の要素の数だけ複数回`render()`が走ってしまう。このため、クライアント側で新たに操作を行わなくても`componentDidUpdate()`が走ってしまうようです。~~
↑ウソ。外部DB接続をせず、コード内にmessagesの内容をベタ書きしてsetStateしてみたところ、`componentDidUpdate()`は走らなかった。**したがって、mapメソッド自体に副作用はない。**
では原因は何かというとまだ不明・・・。

```JavaScript:App.js
export default class App extends Component {
  constructor(props){
    super(props)
    this.state = {
      messages : []
    }
  }
  
  //-- DBからのメッセージ読み込み (FirebaseのRealtime Database使用)
  componentWillMount(){
    messagesRef.on('value', (snapshot) => {
      const messages = []
      const val = snapshot.val()
      Object.keys(val).forEach(function (key) {
        console.log(key)
        messages.push(val[key])
      });

      this.setState({
        messages : messages // stateに取得したmessagesを格納
      });
    });
  }

  componentDidMount() {
    console.log('Mounted')
  }

  componentDidUpdate() {
    console.log('Updated') // <- 初回読み込み時にトリガーされる
  }

　　　　render() {
    return (
      <div className="App">
　　　　　　　　　　　　　　　　//---------子コンポーネントの描画---------
        <div className="Messages">
          {this.state.messages.map((m, i) => {
            return (
              <div className="message" key={i}>
                <Message message={m}/> // <- メッセージの内容をpropsで渡す
              </div> )
            })
          }
        </div>
      </div>
    )
  }
}
```
```JavaScript:Messages.js
const Message = (props) => {
  return (
    <div className="message">
      {props.message.text}
    </div>
  )
}

export default Message
```
#対処法
~~親コンポーネントの`render()`メソッド内では極力mapメソッドの使用を避ける。そのためには、`<RenderMessages />`とかの名前で新たに`<Messages />`をラップするステートレスなコンポーネントを作って、propsでmessagesを渡してあげて、その中でmapメソッドを使って展開させてやると`componentDidUpdate()`の無用な呼び出しを避けられそうです。
理想としてはこんな感じ。~~
-> mapメソッド自体は副作用をもたらさないので、親コンポーネントのrender()で使用をしても問題はない。
とはいえ、あまり親コンポーネント内で即時関数を使いたくないなぁとも思うので以下のようにラップするコンポーネントを別途用意するのはコンポーネントの設計的にもベターな気がします。ただし、propsのバケツリレーが始まってしまうので頻繁に使うのもためらわれるというジレンマ。

```Javascript:RenderMessages.js
const RenderMessages = (messages) => {
  return(
    {messages.map((m, i) => {
      return (
        <div className="message" key={i}>
          <Message message={m}/> // <- メッセージの内容をpropsで渡す
        </div> )
      })
    }
  )
}
export default RenderMessages
```

これでちゃんと動くかどうかはまだ検証していないので結果がわかったらまた追記します。

#参考
React & Firebaseで簡単なChatアプリを作ってみた
https://qiita.com/kazushikawamura/items/58ea222b3cc289882d79
Let's Encrypt のエラー対策

Let's encrypt で証明書を取得しようとした所、次のエラーが出ました。

```text
Performing the following challenges:
Client with the currently selected authenticator does not support any combination of challenges that will satisfy the CA.
```

ネット情報では、数日前から発生している問題とのこと。

Apache2 と Nginx で対処コマンドが異なります。

Centos 7 の Apache2 では、次のコマンドで解決しました。
example.com は置き換えて下さい。

```bash
sudo certbot --authenticator standalone --installer apache -d example.com --pre-hook "apachectl stop" --post-hook "apachectl start"
```

実行後

```text
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/***/fullchain.pem
```

```
Python・OpenCVでバイナリデータを扱う場合

#やりたいこと
バイナリデータから `cv2.imread` と同じ結果を得たい。

例えば、次のようなケースを想定。
1. PDFファイルをバイナリモードで開く
2. PDFデータ内から画像部分のバリナリデータを抜き取る
3. バイナリデータを画像としてOpenCVで扱う

※一般的なPDFのライブラリを使用せず、最低限の解析処理でPDFデータを扱ってみたいため

#背景
Pythonについては初心者な人間が、1ヶ月程前にOpenCVにて画像解析に手を付け始めて2,3日やったものの、それから1ヶ月手付かずの状況でふと再開しました。
これまではファイル保存していた画像を扱っていましたが、OpenCVでの処理を行なう前段階で、画像がバイナリデータの状態の時に、どのようにデータを扱うかがわからず、あれこれ調べた結果をまとめました。

#考えた事ややったこと
メモリストリームにして、ストリーム形式が扱えるメソッドに渡せばいいだろうと考えました。
しかし、OpenCVにそのようなメソッドがあるのかがわからず、適当に検索を進めます。
そして、ほぼ答えの載った内容を見つけたので、実際に試してみて足りない部分を補うような形となったのが次の結論です。

#とりあえずの結論

```py
import cv2
import numpy as np
import io
from PIL import Image

###ここはコメントをもらうまえのコード（※closeし忘れていた）
###filename = "test.png"
###img_binary = open(filename, "rb").read()

#バイナリデータを準備するのにファイル読込を行なう（テスト用なのでファイル名も直接指定）
#なお、実際には前段階でバイナリデータが渡されることを想定している
with open("test.png", 'rb') as f:
    img_binary = f.read()

#想定する処理はここから --------------------

#バイナリーストリーム <- バリナリデータ
img_binarystream = io.BytesIO(img_binary)

#PILイメージ <- バイナリーストリーム
img_pil = Image.open(img_binarystream)
print(img_pil.mode) #この段階だとRGBA

#numpy配列(RGBA) <- PILイメージ
img_numpy = np.asarray(img_pil)

#numpy配列(BGR) <- numpy配列(RGBA)
img_numpy_bgr = cv2.cvtColor(img_numpy, cv2.COLOR_RGBA2BGR)

#表示確認
cv2.imshow('window title', img_numpy_bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()
```

#今後
もっとよいやり方がわかったら追記したいと思います。
未だにPythonの構文にも慣れておらず、入出力もどうなっているのか把握できていないレベルですので・・・

以上

#参考にしたもの
- [Python - Python - バイナリデータで読み込んだ画像を保存せずにイロイロ(71426)｜teratail](https://teratail.com/questions/71426)
- [Pythonの画像読み込み: PIL, OpenCV, scikit-image - Qiita](https://qiita.com/wasnot/items/be649f289073fb96513b)
- [OpenCVとPIL（python Image library）のデータ変換 - tata色々な備忘録](http://tatabox.hatenablog.com/entry/2013/07/21/231751)
- [16.2. io — ストリームを扱うコアツール — Python 3.6.3 ドキュメント](https://docs.python.jp/3/library/io.html)
- [PDF 構文 -ファイル構造(各部)-](http://www.pdf-tools.trustss.co.jp/Syntax/fileStruct.html)
- [Pythonでのファイル操作 - Qiita](https://qiita.com/zaburo/items/0ba12417dfb39fcb1555)
- [【Python基礎】ファイル操作 - Qiita](https://qiita.com/Tocyuki/items/261bfa17c6dd5a7d03f4)
bitcoin.confにmainnetとtestnetの接続を設定する

#はじめに
Bitcoin Coreを利用する際に、mainnetへの接続かtestnetへの接続を設定するためにはbitcoin.confファイルを作成し、設定内容を記述する必要があります。
以下mainnetとtestnetそれぞれに接続するための記述例を書きました。


#mainnetとtestnetの違い
mainnetとは実際に送金を行うことができるネットワークで、testnetとは開発や実験のために使われるネットワークのことです。mainnetで取引されるビットコインには価値がありますが、testnetでのそれには価値がありません。
その他の違いとしては、ビットコインアドレスや秘密鍵の形式が少し異なっており、また標準のトランザクションのチェック等でいくつかの制限が緩和されています。

#mainnetへの接続方法
はじめにbitcoin.confというファイルを以下のディレクトリに作成します。OSごとにデータの保存先が異なることに注意してください。

- Mac OS X: ~/Library/Application Support/Bitcoin/
- Linux: ~/.bitcoin/
- Windows: C:\Users\Username\Appdate\Roaming\Bitcoin

bitcoin.conf内の内容は以下になります。

```bitcoin.conf
mainnet=1               # mainnetを利用する
txindex=1               # indexを作成して全てのトランザクションIDを参照可能にする
server=1                # JSON RPCサーバとしてコマンドを受け付ける
rest=1                  # REST インターフェースを有効にする
rpcuser= "Username"     # JSON RPCのためのユーザ名
rpcpassword= "Password" # JSON RPCのためのパスワード
rpcport=8332            # JSON RPC用ポート番号
```

#testnetへの接続方法
mainnetと同様に、bitcoin.confを指定ディレクトリ内に作成し、以下の記述をします。

```bitcoin.conf
testnet=3               # testnetを利用する
txindex=1               # indexを作成して全てのトランザクションIDを参照可能にする
server=1                # JSON RPCサーバとしてコマンドを受け付ける
rest=1                  # REST インターフェースを有効にする
rpcuser= "Username"     # JSON RPCのためのユーザ名
rpcpassword= "Password" # JSON RPCのためのパスワード
rpcport=18332           # JSON RPC用ポート番号
```

mainnetとtestnetで大きく異なる部分は、一行目と最後の行のみです。特に最後の行のポート番号の指定はmainnetとtestnetで異なるため注意してください。


#参考文献
- [ブロックチェーン・プログラミング 仮想通貨入門 (KS情報科学専門書) ](https://www.amazon.co.jp/%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%83%81%E3%82%A7%E3%83%BC%E3%83%B3%E3%83%BB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E4%BB%AE%E6%83%B3%E9%80%9A%E8%B2%A8%E5%85%A5%E9%96%80-KS%E6%83%85%E5%A0%B1%E7%A7%91%E5%AD%A6%E5%B0%82%E9%96%80%E6%9B%B8-%E5%B1%B1%E5%B4%8E-%E9%87%8D%E4%B8%80%E9%83%8E/dp/4061538314/ref=sr_1_1?ie=UTF8&qid=1515904553&sr=8-1&keywords=%E3%83%96%E3%83%AD%E3%83%83%E3%82%AF%E3%83%81%E3%82%A7%E3%83%BC%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)
[WORD VBA]正規表現を用いて、アクティブドキュメントのテキストボックスの数字をすべてコンマ付きに変えるマクロ

# 前回のマクロ
[[EXCEL VBA]正規表現を用いて、アクティブシートのテキストボックスの数字をすべてコンマ付きに変えるマクロ](https://qiita.com/Q11Q/items/cd678de3162aafdb2eef)

[Word VBA 数字をコンマ付き数字に変えるマクロ](https://qiita.com/Q11Q/items/b5748b14c44b613f8d64)というのを作りましたが、これはテキストボックスは変更できません。
しかし[[EXCEL VBA]正規表現を用いて、アクティブシートのテキストボックスの数字をすべてコンマ付きに変えるマクロ](https://qiita.com/Q11Q/items/cd678de3162aafdb2eef)を少し変えると、ワードの場合、アクティブドキュメントのすべてのテキストボックスの数字をコンマ付きに変えられることがわかりました。

## 注意点

 1. [[EXCEL VBA]正規表現を用いて、アクティブシートのテキストボックスの数字をすべてコンマ付きに変えるマクロ](https://qiita.com/Q11Q/items/cd678de3162aafdb2eef)はアクティブシートのみですが、これは全てのテキストボックスが対象です。
 2. このマクロはテキストボックスのみを変換します。
 3. 行に数字がまたがった場合うまくいかない可能性があります。
 4. [Word VBA 数字をコンマ付き数字に変えるマクロ](https://qiita.com/Q11Q/items/b5748b14c44b613f8d64)とは違い、法律や年号に対する例外を設けていません。4桁の数字をみたら変換します。

```vbnet

Sub addCommaWdTxtBox()
'For Word
'VBScript Regular Expression 5.5 Reference Setting
'ActiveSheetのすべてのテキストボックスの数字をコンマ付きに変換する
'小数点があっても区別する
Dim wDoc As Word.Document: Set wDoc = ThisDocument
Dim shp As Word.Shape
Dim REG As RegExp: Set REG = New RegExp
Dim buf As String, buf1 As String, buf2 As String
Dim tF As Word.TextFrame, i As Long, ileng As Long
Dim M As Match, Ms, sMs As SubMatches, m2 As Match
If wDoc.Shapes.Count = 0 Then Exit Sub
For Each shp In wDoc.Shapes
If shp.Type = msoTextBox Then
shp.Select 'テキストボックスを選択する
Set tF = shp.TextFrame 'WordはTextFrameになる
buf = tF.TextRange.Text '文字箱(テキストボックス)の文字をいったん全部読み込む
With REG
Debug.Print buf
.Global = True
.MultiLine = True
.Pattern = "([^0-9][0-9]+\b|[0-9]+\b|[^0-9][0-9]+\.\d{1,}\b| [0-9]+\.\d{1,}\b)"
'([^0-9][0-9]+\b 数字以外と数字の連続で任意の単語境界
'[0-9]+\b数字の連続で任意の単語境界
'[^0-9][0-9]+\.\d{1,}\b数字以外と数字の連続(小数点を含む)で任意の単語境界
'[0-9]+\.\d{1,}\b 数字と小数点、その下に1つ以上の数字の連続のあとに任意の単語境界
Set Ms = .Execute(buf): Debug.Print Ms.Count '検索して適合集合の作成
For i = 0 To Ms.Count - 1 'ポイント:マッチ順に変換するため文頭からカウントする
Set M = Ms.Item(i)
'小数点が頭にある場合はこんまがいらないのでカットする
If Left(M.Value, 1) <> "." Then
'まいなすではないとき
If Left(M.Value, 1) <> "-" Then
buf1 = M.Value
If CheckIsNumber(buf1) = True Then
'1文字目が数字ならそのまま1回だけ変換する
buf = Replace(buf, M.Value, Format(buf1, "#,##0"), 1, 1, vbTextCompare) '内部演算は15桁しかないが、それ以上でも変換できる
Else
'1文字目が数字でないなら2文字目からFormatで変換し、1文字目の数字以外のものを付ける
buf1 = Mid(M.Value, 2, M.Length)
buf = Replace(buf, M.Value, Mid(M.Value, 1, 1) & Format(buf1, "#,##0"), 1, 1, vbTextCompare)
End If
Else
'まいなすのとき
buf1 = Mid(M.Value, 2, M.Length)
buf = Replace(buf, M.Value, Left(M.Value, 1) & Format(buf1, "#,##0"), 1, 1, vbTextCompare)
End If
End If
Next i
tF.TextRange.Text = ""
tF.TextRange.Text = buf '変換後の文字列をいれる
Exit Sub
End With
End If
Next
End Sub

Function CheckIsNumber(str As String) As Boolean
'最初の文字が数字か否かを確認する関数
'文字列として数字が入る
Dim ile As Long
Dim Rex As RegExp: Set Rex = New RegExp
On Error Resume Next
'型変換をしてエラーが出るかを確認する
ile = Mid(CStr(str), 1, 1)
If Err.Number <> 0 Then
'エラーが発生したら数字ではない
CheckIsNumber = False: Exit Function
Else
'長整数型に変換できれば数字
CheckIsNumber = True: Exit Function
End If
End Function
```
railsのdeviseを使ってtwitterのOmniAuthを実装する手順

twitterログイン機能が欲しかったので、deviseを使用して実装した時の手順。
以下が構築した環境状況

# 前提条件・バージョンなど
- railsのスタート画面が表示されている状態
- Railsのバージョン 5.1.4

# gemを追加 
以下のgemを追加。

```ruby:Gemfile
gem 'devise'
gem 'omniauth-twitter'
```

```
bundle install
```

#controllerを作成
ログイン用のコントローラーを追加して、routeを設定。

```
rails g controller home index
```

```ruby:config/routes.rb
Rails.application.routes.draw do
  root "home#index"
  get "home/index"
end
```

# deviseをインストール
deviseの設定をして、ログイン機能を作成。

```
rails g devise:install
```

```ruby:config/initializers/devise.rb
  # ==> OmniAuth
  # Add a new OmniAuth provider. Check the wiki for more information on setting
  # up on your models and hooks.
  # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
  #250行目あたりに以下の内容を記述
 config.omniauth :twitter, ENV['TWITTER_CONSUMER_KEY'], ENV['TWITTER_CONSUMER_SECRET'], display: 'popup'
```

# Twitterの認証用
https://apps.twitter.com/でCreate New Appの登録をする。
「Callback URL」の設定は忘れずに
（とりあえず「http://localhost:3000」でもなんでも設定しないとエラーがでるっぽい）

以下で変数の設定。
普段は「dotenv-rails」使って設定してるけど、他の皆さんはどうやってるんだろう・・・

```
export TWITTER_CONSUMER_KEY='取得したAPI key'
export TWITTER_CONSUMER_SECRET='取得したAPI secret'
rails server
```
一旦ホーム画面が表示されたらOK。


#user modelを追加

```
rails g model user provider uid

```

```ruby:db/migrate/*_create_users.rb
class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.string :provider
      t.string :uid

      t.timestamps
    end
    add_index :users, [:provider, :uid], unique: true
  end
end
```

```
rails db:migrate
```

# callback時のログイン処理の実装
「users」フォルダを作成して、「omniauth_callbacks_controller.rb」に以下を記述。

```ruby:app/controllers/users/omniauth_callbacks_controller.rb
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
  def twitter
    @user = User.find_or_create_by(user_params)

    if @user.persisted?
      sign_in_and_redirect @user, :event => :authentication
      set_flash_message(:notice, :success, :kind => "Twitter") if is_navigational_format?
    else
      session["devise.twitter_data"] = request.env["omniauth.auth"]
      redirect_to new_user_registration_url
    end
  end

  private
  def user_params
    request.env["omniauth.auth"].slice(:provider, :uid).to_h
  end
end
```
「SSHホスト鍵が変わってるよ！」と怒られたときの対処

SSHでは初回接続時に接続先ホストの公開鍵を保存しておき、次回接続時にホスト鍵を比較して前回と同じホストに接続したかを確認するような仕組みになっています。そのため、IPアドレスの振り直しやOS再インストールなどでホスト鍵が変わってしまった場合、次のようなエラーメッセージが出てSSH接続が失敗してしまいます。

```
$ ssh example.com
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**.
Please contact your system administrator.
Add correct host key in /Users/hnw/.ssh/known_hosts to get rid of this message.
Offending RSA key in /Users/hnw/.ssh/known_hosts:133
RSA host key for example.com has changed and you have requested strict checking.
Host key verification failed.
```

この仕組みは中間者攻撃への対策として有用ですが、鍵の変更が意図通りであるような場合は大きなお世話だったりするわけです。

# コマンド一発で`known_hosts`ファイルからホスト鍵を削除する

上記エラーへの対処としては`$HOME/.ssh/known_hosts`の該当行を削除すれば同じエラーは出なくなります。これはエディタで削除してもいいのですが、下記のように`ssh-keygen`コマンドの`-R`オプションで消すこともできます。

```
$ ssh-keygen -R example.com
# Host example.com found: line 133 type RSA
/Users/hnw/.ssh/known_hosts updated.
Original contents retained as /Users/hnw/.ssh/known_hosts.old
```

エディタでファイルを開いて該当行を探して…とやっていると案外時間がかかるので、コマンドライン一発で消せるのは便利です。


次のような形式でホスト名に加えてポート番号を指定することもできます。`[]`はシェルのワイルドカード文字ですので、クォーティングは必須です。

```
$ ssh-keygen -R '[example.com]:10022'
```

## 何度もSSH鍵の変更が起こるような場合

OSインストールを繰り返しているなどの理由で、特定ホストのホスト鍵が毎回変わるような状況では、上記コマンドを打つのさえ面倒だったりします。そのような場合は次のように`$HOME/.ssh/config`の設定でホスト鍵のチェックを無効化することができます。

```
Host 192.168.1.1
  StrictHostKeyChecking no
  UserKnownHostsFile /dev/null
```

言うまでもありませんが、全ホストに対してこの設定を行うと中間者攻撃に対して脆弱になります。必要なときだけ特定ホストのみ設定すべきでしょう。
SVM はいつ複数形にするのか

# 疑問

学生時代に論文を書いていて非常に困ったのが「アルゴリズム名をいつ複数形にするのか」でした。

* Support Vector Machines (SVMs)
* Recurrent Neural Networks (RNNs)
* Convolutional deep Neural Networks (CNNs)
* ……など

TOEIC 400点台の私に使い分けがわかるはずもなく、論文を添削してくれた教授も機械学習は専門外だったので正解がわからず、仕方がないので "a SVM classifer" と名詞をくっつけて単数形にしてごまかしていました。

改めて調べてみたらなんとなくわかった気がするので、メモしておきます。

# 複数形と単数形の使い分け

基本的には、以下のような使い分けでよさそうです。

|形|使い時|例|
|:--|:--|:--|
|複数形|派生アルゴリズム全般を指すとき|論文のイントロなど|
|単数形|特定のアルゴリズムを指すとき|論文のマテメソなど|

## 複数形の持つイメージ

複数形にすると「細かい派生アルゴリズムがいっぱいあるよ」というニュアンスになるようです。

私は SVM に対して「たくさんある機械学習のアルゴリズムのひとつ」という印象を持っていたので、SVM という単語を複数形にすることにずっと違和感がありました。しかし、一言に SVM と言っても、margin の取り方の違いで hard-margin SVM や soft-margin SVM があったり、kernel の選択次第で linear classification になったり nonlinear classification になったり、更には回帰に対応させた SVR や 異常検知に対応させた one-class SVM があったりと、いろいろな派生アルゴリズムが存在します。どうやら、こういった派生アルゴリズム全般を指したいときにアルゴリズム名を複数形にするようです。

例えば、[Wikipedia の SVM の導入部](https://en.wikipedia.org/wiki/Support_vector_machine)には

> "In machine learning, **support vector machines** are supervised learning models."

と書かれています。SVM が教師あり学習のアルゴリズムであることは SVM の派生アルゴリズム全般に共通する話なので、複数形にするわけです。同様に、論文のイントロで「SVM はバイオインフォマティクスの分野でも広く用いられており～」のようなことを書く場合も、それぞれの先行研究が SVM のどの派生アルゴリズムを使っているかには興味がなく、ざっくり「SVM 役に立っているよ」という話をしたいだけなので、複数形にします。

## 単数形の持つイメージ

単数形にすると「特定のアルゴリズムを指してるよ」というニュアンスになるようです。

[Wikipedia の SVM の歴史](https://en.wikipedia.org/wiki/Support_vector_machine#History) を見てみると、

> "The original **SVM algorithm** was invented by Vladimir N. Vapnik and Alexey Ya."

と単数形で書かれています（後ろに algorithm がついてしまっていますが……）。これは、たくさんある SVM の派生アルゴリズムのうち「Vapnik さんが最初に考案したアルゴリズム」という特定のものを指しているので、単数形にするわけです。同様に、論文のマテメソで SVM の話を書く場合には、たくさんある SVM の派生アルゴリズムの中から選んだ特定のアルゴリズムについて説明するわけなので、基本的には単数形にします。

## 全般/特定の境界の決め方

基本方針としては「派生アルゴリズム全般を指したいか特定のアルゴリズムを指したいか」で単複を使い分ければよさそうですが、問題となるのが「全般/特定の境界はどこなのか？」です。「Vapnik さんが最初に考案したアルゴリズムという特定のものを指しているから単数形って言うけど、原著論文の中ではアルゴリズムを何パターンか提案しているじゃないか！複数形にしろ！」みたいなやつです。

この問題の答えは「著者のさじ加減でテキトーに決める」だと思います。論文の文脈と分野の通例と著者の気分に応じて単複がコロコロ変わっているように見えます。例えば、機械学習全般の説明をしている文脈で SVM が登場した場合には、SVM を特定のアルゴリズムと捉えて単数形にするほうが自然だと思います。[Bayesian network](https://en.wikipedia.org/wiki/Bayesian_network) は派生アルゴリズム全般の話をする文脈でも Bayesian networks とはせず単数形を用いることが多い気がします。

# 終わりに

英語詳しい人、正解を教えてください……