OmniAICreator/Qiita-1.07M huggingface dataset:
RStudioのショートカットにpipeRを追加する

# はじめに

R界隈でもはや鉄板パッケージとなった感のあるpipeRをRStudioのショートカットに追加します。
pipeは標準でショートカットできる機能がRStudioには備わっているのですが、pipeRはショートカットが備わっていません。面倒だな～と思うのは筆者だけでしょうか。

今回は参考として、[こちらのリンク先](https://rstudio.github.io/rstudioaddins/)にある記事を同じような要領でちょいっと工夫してRStudioからpipeRをショートカットで追加できるようにしてみます。

# 準備

アドインを取得するために、[rstudio/addinexamples](https://github.com/rstudio/addinexamples)へアクセスし、ソース一式をダウンロードして任意のフォルダに展開します。

<img width="1111" alt="スクリーンショット 2018-01-08 23.56.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/162354/4d87cd19-bc7f-ee08-37be-25714b4c6385.png">


# 編集

準備が完了したら、アドインに新しい定義を追加するため、展開したフォルダ内のファイル inst/rstudio/addins.dcfを編集します。

追加するフィールドが全部で4つありますが、それぞれは以下を意味しています。

| フィールド名|説明 | 
|:-----------------|:------------------|
|Name|アドインの名前|
|Description|アドインの説明| 
| Binding|このアドインが関連付けられているR関数|
| Interactive|インタラクティブであるかどうか（Shinyアプリケーションを実行するかどうか）|

```addins.dcf

#中略

Name: Insert %>>%
Description: Inserts `%>>%` at the cursor position.
Binding: insertInPipeR
Interactive: false
```

次に、アドインと関連づけられているR関数と紐づけを行うため、R/insertInPipeR.Rファイルを作成し、以下のソースをコピペで貼り付けてください

```insertInPipeR.R
#' Insert \%>>\%.
#'
#' Call this function as an addin to insert \code{ \%>>\% } at the cursor position.
#'
#' @export
insertInPipeR <- function() {
  rstudioapi::insertText(" %>>% ")
}
```

以上で編集は完了です。

# 実行/動作確認

準備と編集が完了したら編集したファイルをRStudioに取り込みましょう。
適当なスクリプトファイルを作成し、以下を実行しましょう。

```addIn.R

devtools::install("ローカル環境パス/addinexamples-master")

```

実行後、念のためRStudioの再起動をしておくといいかもです。

最後に動作確認をします。
RStudioの[Addins]をクリックし、アドインが追加されていることを確認します。

<img width="796" alt="スクリーンショット 2018-01-09 0.07.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/162354/8e696822-7815-30a0-7095-9808a835db27.png">


[Tools]タブ→「Modify Keyboard Shortcuts...」でショートカットキーの割り当て画面を表示させ、追加したアドインに対し個別に割り当てを行います。
入力を決めたら「Apply」ボタンを押下しましょう。

<img width="900" alt="スクリーンショット 2018-01-09 0.07.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/162354/e160659d-cd49-61cb-7c8f-f5ab44899562.png">

<img width="720" alt="スクリーンショット 2018-01-09 0.08.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/162354/df9744d5-9d88-65ab-0d45-715061805c75.png">


任意のショートカットキーでカーソルを置いたところにpipeRを呼び出すことができたら成功です。

お疲れさまでした。
記事をお読みいただきありがとうございました！
おうちDNSをPowerDNSのDockerイメージで(PowerDNS Recursorインストール編)

# はじめに

[前項](https://qiita.com/whale_shark/items/afc6436c19ae8ca55067)ではPowerDNS Authoritative ServerとPowerDNS-Adminをインストールした。
今回はPowerDNS Recursorをインストールすることで本格的におうちの中で利用できるDNSサーバを構築することができる。

今回の構築イメージ。

```
クライアントPC
  ↓
PowerDNS Recursor → localドメイン → PowerDNS Authoritative Server 
  ↓
localドメイン以外
  ↓
Internet
```

# Dockerイメージ

前回のDockerファイルにさらに、PowerDNS RecursorのDockerイメージを追加した。

また、docker-composeでブリッジを作成し各コンテナのIPアドレスを固定で設定することで、PowerDNS Authoritative ServerとRecursorの経路を固定した。

linkの設定では、PowerDNS Authoritative ServerとRecursor同士の通信が正しく行えない問題があったためである。

また、内向きで利用するドメインとその検索先をforward-zonesの項目に設定する。
今回は.localドメインを追加するので下記の用に設定した。

```bash:転送先の設定例
forward-zones=local=<転送先のDNSサーバー>
```

それ以外の設定は特にいじっていないため、必要に応じてrecursor.confを編集する。

以上で、Dockerファイルの準備は完了した。

このDockerファイルも[ここ](https://github.com/whale-shark/PowerDNS4Arm)にPushしてある。

この状態でコンテナを立ち上げると、以下の様なエラーが発生しポートのバインドに失敗する。

```
0.0.0.0:53: bind: address already in use
```

事項で、調査方法と設定変更法を記載する。

# Armbianの設定

以下のコマンドで、53番ポートを使用しているアプリを調査。

```bash
sudo lsof -i -P | grep "LISTEN"
```

ポートを占有していた正体は、dnsmasqである。

詳細は割愛するが、簡易DNSサーバである。

Armbianは起動時に、NetworkManger経由でたちあげているようなので、以下のコマンドで設定変更・停止する。

```bash:NetworkManagerの設定ファイル
$ sudo vi /etc/NetworkManager/NetworkManager.conf
```

```:viで編集する項目/[main]のdnsをコメントアウト
[main]
dns=none
plugins=ifupdown,keyfile,ofono
#dns=dnsmasq

[ifupdown]
managed=true
[keyfile]
unmanaged-devices=interface-name:p2p0
```

```bash:NetworkMangerを再起動
$ sudo systemctl restart network-manager
```

# DNSの設定確認

ブラウザのアドレスバーにArmbianのIPアドレスを打ち込むとPowerDNS-Adminが表示される。

新規にDNSを登録し、正常に登録されればdigやhostコマンドなどで動作を確認する。

```bash:(例)digコマンド
$ dig @<ArmbianのIPアドレス> <作成したアドレス>
```

もし、PowerDNS-Adminでエラーが出る場合はdocker-compose upをしたターミナルを見るとPowerDNSのログが出ている。

発生しやすいエラーとして、SQLiteへの書き込みが出来ない場合である。

その場合は、ファイルの権限を見直しPowerDNSだけを再起動すれば正しく読み込むことが出来る。

# 今後の課題

リバースプロキシを設定したが、現在の設定だとPowerDNS以外のサービスの提供が難しい。

そこで、uWSGIを利用してパスを分けようとしたが、正しく起動することが出来なかった。

# 参考
[UBUNTU DNSMASQを停止する](http://www.lighthouselab.co.jp/index.php/lh-academy/linux/ubuntu-dnsmasq.html)
Google App Engineにサードパーティパッケージが必要なアプリのデプロイ

# Google App Engineにサードパーティパッケージが必要なアプリのデプロイ

Google Cloud Platformに含まれていない言語・パッケージを使用するには、[Dockerfile](https://docs.docker.com/engine/reference/builder/)を使って定義した[Custom Runtimes](https://cloud.google.com/appengine/docs/flexible/custom-runtimes/about-custom-runtimes?hl=ja)上で実行させる必要があります。

今回は、[この記事](https://qiita.com/otuhs_d/items/679a429d64ad5166bddb)で作ったDiscordのBotをApp Engineにデプロイするまでを記事にします。

> **Note:** 
> このBotでは音声ファイルを扱うためサードパーティパッケージが必要

## はじめる前に

事前に以下の作業が必要です。
詳細は[ここ](https://cloud.google.com/appengine/docs/flexible/custom-runtimes/quickstart?hl=ja)の「Before you begin」にあります。


1. GCPプロジェクトの作成
2. Google Cloud SDKのダウンロードとインストール
3. App Engineアプリケーションの作成

## app.yamlファイルを作成

Custom Runtimeを使用するには`app.yaml`に以下の記述が必要です。

```yaml
runtime: custom
env: flex
```

また、インスタンスの数を1つにするよう設定します。

```yaml
manual_scaling:
  instances: 1
```

> **Note:**
> インスタンスの数だけBotがコマンドに反応するので、複数インスタンスあるとカオス

全部あわせるとこんな感じに。

```yaml:app.yaml
runtime: custom
env: flex

manual_scaling:
  instances: 1
```

## Dockerfileを作成

`Dockerfile`は[Botの作成記事](https://qiita.com/otuhs_d/items/679a429d64ad5166bddb)で扱ったのでここでは詳細は割愛します。

```ruby:Dockerfile
FROM ruby:2.3.3

WORKDIR /app
ADD . /app

RUN apt-get update
RUN apt-get install libopus-dev -y
RUN apt-get install libsodium-dev -y
RUN apt-get update && apt-get install -y \
      wget \
      xz-utils
RUN wget http://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz \
      && tar Jxvf ./ffmpeg-release-64bit-static.tar.xz \
      && cp ./ffmpeg*64bit-static/ffmpeg /usr/local/bin/

RUN bundle install

CMD ["ruby", "team_bot.rb"]
```

> **Note:**
> `Dockerfile`と`app.yaml`は同じディレクトリに配置する必要があります

## App Engineにデプロイする

`app.yaml`と`Dockerfile`の準備ができればあとは以下を実行すればデプロイできます。

```bash
$ gcloud app deploy
```

## Future Work

GitLab CIからApp Engineに自動デプロイできるようにしようと考えてます。
MeltdownとかSpectreとか騒ぎがあったので、Amazon Aurora（MySQL互換）R4インスタンス再テスト（mysqlslap）

**2018/01/13追記：**
**「AWSが再度パッチを当てたみたい」**という情報があったので、3度目のベンチマークを行ったところ、db.r4.largeおよびdb.r4.xlargeについて、**2017/10/末頃とほぼ同じ速度に戻った**ことを確認しました。

 * **[「AWS、またパッチ当てたってよ」と聞いたので3度目のAurora（MySQL互換）R4テスト（mysqlslap）](https://qiita.com/hmatsu47/items/48e4af366c680c69f2ac)**

---
（以下、**古い情報なので現在とは状況が異なります**。）

以前、R4インスタンスが使えるようになったときに`mysqlslap`で性能テストをしたので、今回、同じ条件で再度R4インスタンスだけ`mysqlslap`してみました。

 * **[Amazon AuroraでR4インスタンスを試してみる](https://qiita.com/hmatsu47/items/f060f11b16d2892dee9a)** ※2017/10/30～31に実施

# mysqlslapの内容

前回と同じです。

```bash:mysqlslap
$ mysqlslap --auto-generate-sql --auto-generate-sql-guid-primary --engine=innodb --number-int-cols=20 --number-char-cols=20 --concurrency=150 --auto-generate-sql-write-number=2000 --auto-generate-sql-execute-number=2000 --auto-generate-sql-load-type=mixed -u 【ユーザ名】 -h 【クラスタエンドポイント】 -p
```

# 結果

結構、衝撃的です…。
なお、暗号化の有無での性能差はわずかしかありませんでしたので、今回は暗号化ありの結果のみ掲示しておきます。
また、参考として、今回はdb.r4.2xlargeインスタンスの結果も加えておきます。

| 実施時期 | db.r4.large・バイナリログなし | db.r4.large・バイナリログあり | db.r4.xlarge・バイナリログなし | db.r4.xlarge・バイナリログあり | db.r4.2xlarge・バイナリログなし | db.r4.2xlarge・バイナリログあり |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
| 前回(2017/10/末・Ver.1.15) | 48.860 | 57.737 | 33.133 | 37.857 | - | - |
| 今回(2018/01/上・Ver.1.16) | 74.779 | 91.679 | 45.433 | 54.413 | 34.180 | 39.621 |
| 性能比 | 65.3% | 63.0% | 72.9% | 69.6% | - | - |

※単位は秒。すべて暗号化ありの結果。

ちょうどインスタンスタイプ1段階分ぐらい遅くなっています。
もしかして前回インスタンスタイプの指定を1段階間違えたか？と思って請求情報を見たら、間違っていませんでした。
![aurora_cost.png](https://qiita-image-store.s3.amazonaws.com/0/123899/21d9dbcd-a6a8-f10f-6699-b7bdf4cddb46.png)

もちろん、クライアント側に問題がないか確認するためにクライアント側のEC2インスタンスもタイプを色々変えて試しましたが、結果は誤差の範囲でした（AZも一致していることを確認）。

ただ、**実際のワークロードは`mysqlslap`とは違うので、プロダクト環境でどうなるかは実際の環境で確認・検証してください**。

※明日から私もプロダクト環境と同等のステージング環境で性能テストです…つらいことになる予感。

**追記：**
参考までに記しておくと、db.r4.large・バイナリログありの今回（2018/01/上）分がピーク時CPU使用率90～100%程度、でした。
より大きなインスタンスタイプに対しても同じ負荷を掛けて計測しているため、（ディスク／ネットワークI/O側がネックにならないと仮定すれば）インスタンスタイプが大きいほど性能低下の程度が小さい、という結果が出るのは当然といえます（db.r4.xlarge以上に対しては100%の負荷を掛けていないので）。

---

 * **[Qiitaに投稿したAmazon Aurora関連記事](http://hmatsu47.hatenablog.com/aurora)**
Python 年末年始の宿題

◆問題1（復習）
　引数なし、返値なし
　関数ないで、'Hello, World'と表示

'Hello, World'

◆問題2（復習）
　引数1までの、
　1～引数1までの和を返す関数

def wa (z):
    a,b = 0,0
    while a < z:
        a = a + 1
        b = a + b
    print (b)

In :wa(3)
Out:10

◆問題3
　引数1、引数2を渡して、
　引数1～引数2までの整数のリストを返す関数

def func(a,b):
    show = list(range(a,b))
    print(show)

In :func(3,6)
Out:[3,4,5]

◆問題4
　引数1までのフィボナッチ数のリストを返す関数
　0,1,1,2,3,5,8
　隣どうしの数を足した数が次の要素になる数列

def fib(n):
    a,b = 0,1
    while a < n:
        print(a, end = ' ')
        a,b = b,a+b

In :fib(2000)
Out:0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

◆問題5
　FizzBuzz関数
　3の倍数の時'Fizz'と表示
　5の倍数の時'Buzz'と表示
　3の倍数かつ5の倍数の時'FizzBuzz'と表示
　上記以外の場合は、そのまま数字を表示
　引数1まで繰り返す

def FizzBuzz(n):
    game = ['FizzBuzz' if x % 15 == 0
            else 'Fizz' if x % 3 == 0
            else 'Buzz' if x % 5 == 0
           else x for x in range(1,n)]
    print(game)

In :FizzBuzz(20)
Out:省略
[2017/01時点] 現状最善のdotfiles管理方法

## TL;TR

dotfilesの管理は現時点では[homeshick](https://github.com/andsens/homeshick)(not [homesick](https://github.com/technicalpickles/homesick))が最もおすすめ

## dotfilesの管理がしたい背景

ノートPCとデスクトップPC、あるいはプライベートのPCと会社PCなど2つ以上のOSを使用している場合にdotfilesを一括で管理したい。

## 立ち上がる問題

* 場合によってはいくつものサーバで実行する必要があるので、なるべく手間を掛けたくない。理想はコマンド1発でプロンプトなし
* どこを接点(ハブ)としてファイルを同期させる？
    * 今時ならだいたいgithubでOK
* 秘匿情報(ユーザー名・メールアドレス・パスワード)はgithubに置きたくない。どうする？
    * [homeshickのforkがやっている](https://github.com/andsens/homeshick/wiki/Forks)redact/unredactの仕組みを使うてもあるが、別でファイルを持ってくる必要があって結局手間がかかる
    * 現状での最善策はおそらくGoogle DriveやOneDriveのようなプライベートファイルホスティングサービスを使うこと。自分の場合Dropboxを使用している https://www.dropbox.com/developers
* [こちらの記事でいうイニシャライズをどうするか](http://qiita.com/b4b4r07/items/b70178e021bef12cd4a2)
    * イニシャライズをそもそも全自動でするべきか、という問題がある
    * というのはそれほどその場で作業するつもりのないところでもとりあえずzsh用の設定を入れておきたい、ようなケースでいちいちvim, tmux, gitなどすべてをビルドするのはいくらなんでもリターンが見合わないから
    * あと後述の環境差異の問題もある
    * よってイニシャライズは基本的に手動で行うものとする。ただし頻繁に実行するようなものはシェルスクリプト化してcastleに含ませる
    * イニシャライズ(ビルド)をdotfilesセットアップですることは別の問題もある。イニシャライズは多くの場合sudo権限を必要とするが(ま、なくてもできるけど自分でコンパイルする必要があったりして成果以上にしんどい)、dotfilesの設置自体は極めてユーザーローカルな作業なので、root権限で作業するようなことと分離したい
* vimやzsh、tmuxなどのプラグインのダウンロードはどうするか
    * 前述の通りdotfilesのセットアップでコンパイルや大量のプラグインのインストールなど、重い処理はしたくない。
    * これは時間がかかる + 容量を食うの2つの意味でそれらの浪費は後回しにしたいという意味
    * なので、これらのアプリケーションのプラグインのインストールは後回し、具体的に言うとアプリケーションの初回起動時に行う
    * こうすることでdotfilesを置いたけど使うつもりない(あるいはroot権限がなくてアプリケーションを入れられないため使えない)ようなケースで時間や容量を無駄にすることがなくなる
    * zshやvimは設定ファイル自体にロジックがかけるので初回起動時にプラグインがまだなければインストールの処理を走らせる。tmuxについてもif-shellを使って同様のロジックを書く
* もうひとつ出てくる問題がアプリケーションと設定ファイルのバージョン差異の問題。zshやvimはだいぶ枯れてきているためか4,5年前から設定ファイルフォーマットの大きな変更がなく、centos6でもubuntu 16.10でも同じ設定ファイルが使えるが、1.7.10から設定ファイル分離に便利なincludeが使えるようになったgitや、マイナーバージョンアップ毎に破壊的な変更を加えるtmux(1.9, 2.0, 2.1, 2.2の設定ファイルをすべて共通で扱おうとするとほぼエラーが出る)など、バージョンによってvalidな設定ファイルは異なる。
    * これについては正直なところクリーンな回答は現状思いついていない
    * 理論的に最善なのは最新バージョン向けに設定ファイルを書いてログインする環境すべてで最新バージョンのアプリケーションを手動で入れることだがそれほど長居するつもりのないcentos6環境でzsh, tmux, gitとビルドしてインストールするのは明らかに不毛である。
    * 現在の自分の環境としてはcentos 6.5, 6.4, 7.2, mac osx, ubuntu 16.10を使っている。このうちよく使うのにOS標準のバージョンが古すぎるのはcentos 6.5, 6.4のtmuxとgitである。よって暫定的にこれら旧バージョン向けには専用のcastleを用意することにする
        * git-noninclude-castle
        * tmux-1.8-castle
    * デプロイ部分でバージョン判定をして云々ってのも考えたがdotfilesの設置をする部分にロジックを書くのはやり過ぎ感があると思い中止(そうやった結果の状態がわかりにくくなるのもデメリット)。
    * 理論的に最善であることを愚直にするのも悪くない。特にcentos 6.x系向けにtmux, gitの最新バージョンのrpmを用意できればあとはそれをインストールするだけで済む。そこまですれば古い設定ファイルを維持する必要はない

## homesickよりhomeshickをおすすめする理由

homesickはRuby(gem)に依存していますがhomeshickはシェルスクリプトだけで完結します。
新しいサーバにログインするたびRubyの環境を用意するのは手間なので後者のほうがよりお手軽です。
機能的にも現時点ではそれほど大差はありません。
zaifapiでBitcoinの動きを眺めてみた


昨年のクリスマスあたりの暴落で終わるんじゃないかと思いましたが、各種仮想通貨は盛り返してきており、まだまだ続きそうですね。

仮想通貨取引所の[Zaif](https://zaif.jp/)さんは、APIを公開されておりそれをPythonから叩ける用にしたSDKが非公式ながら提供されていましたのでこちらで遊んでみました。

[zaifapi](https://github.com/techbureau/zaifapi)

取引情報や終値の取得はもちろん、実際に売買もできるので正しく使えば取引Botもつくれそうですが、まずは価格の変化を眺めてみたいと思います。

インストール
-------------------------

Python3系のみをサポートしているようです。3系で適当にvirtualenvなりvenvして`pip`ですぐにインストールできます。

```
$ pip install zaifapi
```

ZaifPublicStreamApi
------------------------

現物の公開情報を取得するクラスは`ZaifPublicApi`と`ZaifPublicStreamApi`があるようですが、リアルタイムな情報は`ZaifPublicStreamApi`で取れるようなのでこちらを利用します。

```python
from zaifapi import ZaifPublicStreamApi

TARGET_CURRENCY_PAIR = 'btc_jpy'

zaif_stream = ZaifPublicStreamApi()
try:
    # StreamAPIはジェネレータを戻しているのでこれでずっといける
    for stream in zaif_stream.execute(currency_pair=TARGET_CURRENCY_PAIR):
        time_str = stream['timestamp']
        last_price = stream['last_price']['price']
        print(time_str, last_price)
except KeyboardInterrupt:
    print('Bye')
```

実行すると`Ctrl+C`するまで以下のように終値が表示されます。

```
2018-01-08 23:14:30.689583 1865000.0
2018-01-08 23:14:32.191223 1865000.0
2018-01-08 23:14:34.516626 1865500.0
2018-01-08 23:14:36.202791 1866295.0
2018-01-08 23:14:37.712342 1865480.0
2018-01-08 23:14:39.221654 1865000.0
2018-01-08 23:14:40.895128 1865000.0
^CBye
```

`zaif_stream.execute`はgeneratorを戻すのでそのままfor文にかければエラーが起きない限り
リアルタイムに結果が取得され続けるようです。

```python
>>> zaif_stream.execute(currency_pair=TARGET_CURRENCY_PAIR)
<generator object ZaifPublicStreamApi.execute at 0x106876360>
```

取得される内容
------------------

`ZaifPublicStreamApi`は[ストリーミング API](http://techbureau-api-document.readthedocs.io/ja/latest/public/3_streaming.html)を利用しているようでこのAPIドキュメントの戻り値通りの結果が戻っています。そのため、`last_price`だけでなく`asks`や`bids`でいた情報も入っているのでこれらも考慮し、もうちょっと手の込んだ情報も取れるようです。

もうちょっと
-----------------

実際に使うとなると、ある時点ごとでの情報ではなく、それまでの流れでの変化量が恐らく大事なので、取得した情報はある程度保持する必要があるはずです。ここらへんも考慮してとりあえず直近1000件の履歴を保持しつつ変化を眺めるコードを書きました。(といってもサンプルでは直前の価格との差分のみしかみてませんが...)

https://github.com/denzow/zaif_bot/blob/master/main.py

とりあえず実行すると、板や取引のざっくりとした平均値の遷移等がリアルタイムに表示されます。

```
$ python main.py
2018-01-08 23:34:29.265710 0 0 0 1871570.0 1871558.935 1871614.572
2018-01-08 23:34:30.967437 0.0 -786.99 0.0 1871570.0 1871558.935 1871614.572
2018-01-08 23:34:32.924461 163.39 805.21 2090.0 1873660.0 1871511.268 1871788.802
2018-01-08 23:34:34.474054 115.42 1699.9 0.0 1873660.0 1871806.516 1871878.289
2018-01-08 23:34:36.156363 537.62 -5.33 0.0 1873660.0 1871950.134 1873274.798
2018-01-08 23:34:37.662134 402.04 15.07 0.0 1873660.0 1871950.134 1873610.252
2018-01-08 23:34:39.160028 0.0 68.54 0.0 1873660.0 1871950.134 1873610.252
```

ある瞬間の取引状況を`TradeData`クラスとして格納し、それらを`TradeHistory`クラスで管理する作りにしていますので、`TradeHistory`をもう少し頑張れば面白いことができそうです。


まとめ
----------------

`zaifapi`だと簡単にリアルタイムな情報がとれて本当に楽でした。これらも時間を見つけて遊んでみようと思います。
[Cinema 4D] ボタンの動作について

Cinema 4Dで自作タグプラグインを作成する過程で，ユーザデータに追加したボタンを押したときの動作についてテストを行いました．

Matrixグループに加え，Original Matrixというグループを作成し，GetとSetのボタンとMatrix Originalというマトリックス型データを用意してあります．

![20180108-3.jpg](https://qiita-image-store.s3.amazonaws.com/0/195698/487c92e1-95a1-8273-8595-2979ca6bc98e.jpeg)

ここでは簡単な動作として，

Getボタン: タグが付いているオブジェクトのマトリックスを取得してMatrix Originalに保存する
Setボタン: Matrix Rootに設定したマトリックスをオブジェクトにセットする

ということを行ってみます．

ボタンを押した時にはボタンを押したことを知らせるメッセージが必要です．これはMSG_DESCRIPTION_COMMANDを使います．Python SDKに次のサンプルが記載されています．

[MSG_DESCRIPTION_COMMAND](https://developers.maxon.net/docs/Cinema4DPythonSDK/html/modules/c4d.plugins/BaseData/NodeData/index.html?highlight=msg_description_command#NodeData.Message "MSG_DESCRIPTION_COMMAND")

>
```
Here is how to process MSG_DESCRIPTION_COMMAND message:
def Message(self, node, type, data):
  if type==c4d.MSG_DESCRIPTION_COMMAND:
    if data[‘id’][0].id==THE_BUTTON_ID:
      print “Pushed button with command ID”, THE_BUTTON_ID
      return True
```

if data[‘id’][0].id==THE_BUTTON_ID:の後に続けて固有のボタンIDで分岐させ，それぞれのボタンを押した時の動作を記述していきます．ここではGetボタンを押したとき，get_matrix_obj関数を呼び出します．引数はマトリックスをセットするためのIDとします．

```
# Get Matrix the object
if data['id'] == idButton[Const.UI_BUTTON_GET]: # GetボタンのID
    print ( data['id'] )
    print ( "Press Button Get" )
    self.ud.get_matrix_obj(Const.UI_MATRIX_DISPLAY_ORIGINAL)
```

get_matrix_obj関数はTagDataからGetObject().GetMg()でタグが適用されているオブジェクトのマトリックスを取得し，UI_MATRIX_DISPLAY_ORIGINALにセットするだけです．

```
def get_matrix_obj(self, matrixId):
    ObjMg = self.obj.GetObject().GetMg()
    self.obj[self.idMatrix[matrixId]] = ObjMg
```

同様にSetボタンの動作も記述します．set_matrix_obj関数へはMatrix Rootを引数として渡し，オブジェクトのマトリックスにセットします．

```
# Set Matrix the objext
    if data['id'] == self.ud.idButtons[Const.UI_BUTTON_SET]:
        print(data['id'])
        print("Press Button Set")
        self.ud.set_matrix_obj(Const.UI_MATRIX_DISPLAY_ROOT)
```

```
def set_matrix_obj(self, matrixIdRoot):
    RootMat = self.obj[self.idMatrix[matrixIdRoot]]
    self.obj.GetObject().SetMg(RootMat)
```

試しにオブジェクトを適当に移動させて，Getボタンを押して現状のマトリックスをMatrix Originalにセットしておき，Setボタンを押してMatrix Rootに設定したマトリックスをオブジェクトにセットしてみました．

![20180108-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/195698/e97d90eb-b650-5570-220c-f9f523af2d43.jpeg)

さらにResetボタンを追加し，Matrix Originalに保管したマトリックスに復帰できるようにしています．

![20180108-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/195698/d0bb0311-dddb-c8ff-2327-bd927f7c68ba.jpeg)

以上の機能には特に意味があるわけではないのですが...ようやくタグプラグインからオブジェクトに対して何かを行うことができるようになりました．

では，次からはこのタグの最も行いたかった機能である，マトリックス同士を使った行列変換をテストしていきたいと思います．
EntityFramework+Azure SQL Databaseで高速な開発を実現する-LINQプログラミング編

# はじめに

データを蓄積・加工する以上、個人レベルのものであっても
システムを構築するにあたってデータモデル、そしてデータベースの設計は疎かにできません。

LINQ/EntityFrameworkでは、構築したデータベースに対して、

前回投稿：[EntityFramework+Azure SQL Databaseで高速なDB開発を実現する](https://qiita.com/KO_YAmajun/items/2e36b2023275b94e948c)

※プログラミング編では、基盤部分にあたるAzure(SQL Database)自体への言及はほぼありません。
　データベース構築の手順・今回のデモで準備されたデータベースの詳しい内容についてはリンク先を参照してください。

# 前提事項
前回のデモでは、こういうエンティティ―リレーション関係にあるテーブルを作成している。
また、テーブル構造は前回のデモを引き継いでいる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/161516/8e820308-cf95-7e52-45e5-5fc0c3dc616f.png)

同時に自動生成されたDBContextは下記の通り。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/161516/6756e850-5538-7a8b-a94a-3f186e1346d7.png)

また、前回の記事の後、EmployeeとDeptにはそれぞれ下記のようなデータを投入している。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/161516/b591fc5a-1c0b-ebbd-c734-48b0ae90984e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/161516/33809d9f-7bdf-ea45-052f-a4c04c79aea6.png)

## 1.単一テーブルに対するデータの取得

単一テーブルに対するSQLは、DBcontxtが持っているテーブルプロパティを取得することで生成できる。
[注意点]
・必ずusingを利用してリソースを閉じる（リソース・リーク防止）
・usingを抜ける前の段階で終端処理を終えておき、IEnumerableのままにしない（クエリを確定させる）

```Statistics.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using WebApplication6.Model;

    public class Statistics {

        public static List<Dept> getDept() {
            //必ずusingブロックで囲い、DBリソースは破棄する
            using (var db = new EFTestModelContainer()) {
                return db.DeptSet.ToList();
            }
        }

/**
[DB取得結果]
1,総務
2,システム
3,経理

[生成SQL]
SELECT 
    [Extent1].[DeptId] AS [DeptId], 
    [Extent1].[DeptName] AS [DeptName]
    FROM [dbo].[DeptSet] AS [Extent1]
*/

```

## 2.外部キーによるテーブルの結合(内部結合)

Where等のために結合させるケースでは、
親エンティティを取得する→親エンティティが持っている子エンティティのセットを取得してさらに処理する。

[注意点]
・結合時、Join方法を正確に指定することができない。したがって効率の悪いSQL発行となる場合がある。
・サンプルでは無視しているが、例外の発生を考慮すること。

```Statistics.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using WebApplication6.Model;

    public class Statistics {

        public static double AverageSalary(String DeptName) {
            using (var db = new EFTestModelContainer()) {
                return db.DeptSet.Where(d => d.DeptName.Equals(DeptName)).SelectMany(d => d.Employee).Average(e => e.Salary);
            }
        }

/**
[処理]
従業員が所属する部門が 総務 である従業員の 給与平均 を算出する。

[DB取得結果]
300000

[生成SQL]
exec sp_executesql N'SELECT 
    [GroupBy1].[A1] AS [C1]
    FROM ( SELECT 
        AVG( CAST( [Extent2].[Salary] AS float)) AS [A1]
        FROM  [dbo].[DeptSet] AS [Extent1]
        INNER JOIN [dbo].[EmployeeSet] AS [Extent2] ON [Extent1].[DeptId] = [Extent2].[Dept_DeptId]
        WHERE [Extent1].[DeptName] = @p__linq__0
    )  AS [GroupBy1]',N'@p__linq__0 nvarchar(4000)',@p__linq__0=N'総務'
*/

```
vue.jsにrailsのviewからユーザーが入力していない値を渡す方法

# つまりどころ

vue.jsの仕様のひとつにv-modelのついたformの初期値とvalueを無視するというのがある。railsのviewから値を渡す際にいつもview内で変数を初期値に設定してhiddenで隠し、まとめて渡すことでユーザーが入力しない情報（例えばどこのページかuser_idなど）を渡していた。そのため渡す方法を探していたのだがやっといい方法が見つかったのでメモ。

# pure jsで渡す

## inputの場合

vue.jsはpure jsもかけるのでpure jsでformを通してviewからjsファイルに渡す。

```ruby:form.erb
<input type="text" id="form_board_id" value="<%= @post.id %>" class="hidden">
```
```javascript:form.js
var form_board_id = document.getElementById("form_board_id").value;
```

これで渡せる。

document.が全体を探し出すという意味でgetElementByIdがカッコ内のidのついたformの値を受け取る。それを.valueで値に変換している。

## textareaの場合

なぜかtextareaの場合はvalueに値を入れても飛ばせなかった。

```ruby:form.erb
<textarea class="hidden" id="form_board_id"><%= @post.id %></textarea>
```
```javascript:form.js
var form_board_id = document.getElementById("form_board_id").value;
```
RaspbianのNOOBSのダウンロードが遅い件

# Raspbianとは
Raspberry PiというICカードより少し大きいくらいのPCに搭載するOSです。
詳しい話はWikipedia先生から話を聞いてみて下さい。
[Raspberry Pi -wikipedia-](https://ja.wikipedia.org/wiki/Raspberry_Pi)

RaspbianはDebianベースのOSで公式ページからダウンロードすることができます。
[https://www.raspberrypi.org/downloads/raspbian/](https://www.raspberrypi.org/downloads/raspbian/)

## 公式サイトからダウンロードしかし・・・
自宅で運用していたRaspberryPi2の調子がおかしくなったのでせっかくなのでクリーンインストールから始めようと思いたったのが始まり。
公式サイトからNOOBSからダウンロードしようと思ってダウンロードを始めたものの・・・
ダウンロードに**1６時間**とか出やがったので一旦中断
色々探してるうちにミラーサイトにたどり着いたので備忘録


## ミラーサイト
こちらのミラーサイトからダウンロードしたら二時間ちょいでいけました。
それでも二時間はかかったのですが(；・∀・)
[http://ftp.jaist.ac.jp/pub/raspberrypi/NOOBS/images/](http://ftp.jaist.ac.jp/pub/raspberrypi/NOOBS/images/)
※２０１７年１月現在の情報です。変わってたら違うミラーサイトを探してみて下さい。

ダウンロードの際は最新版のチェックを忘れずに！
Nginxについて

ConohaのVPSサーバーがNginxを使用していたけれど、聞くのが初めてだったのでメモ。
（エンジンエックスと読むらしい。エヌジンクスって読んでた。）

![NGINX_logo_rgb-01.png](https://qiita-image-store.s3.amazonaws.com/0/121228/a6c9f54b-2ccc-3f9b-7782-7fc098b96348.png)


##Nginxの由来##
ある企業がApacheを使っていたが、一度に大量のアクセスが来た際に対応しきれなくなり、同時に大量のアクセスに対応できるNginxが開発された。

##Nginxの特徴##
・ノンブロッキングI/Oを採用し、大量のデータ配信や大量同時接続に特化
・初めから多くの機能はついていない
・メモリ使用量が少ない
・静的コンテンツの配信に優れているが、動的コンテンツの配信はあまり得意ではない

国内だと、メルカリやクックパッドも使用しているようです。
Webサーバーについて全然詳しくないので少しだけ調べてみましたが、とても優れたサーバーのようです＾＾
bitZeny掘るよ

#動機
新しいPCをRYZEN Threadripper X1950で組んだのでCPU負荷試験＆性能出し。
ZNY/JPYが20として、１日14ZNY程度なので￥280/Day、電気代は稼げるから遊ばせているよりはマシ程度
CPUの値段とか考えると元は取れないので、あくまでお遊びで。

#基本的なビルド
##オリジナル手順
https://bitzeny.info/d/4-cpu/77

##OS設定から
コントロールパネルからWindows Subsystem for Linuxを有効化
ストアからUbuntuをインストール
Ubuntuを起動し、アカウント、パスワード設定

```sh
sudo apt-get update
```
*これやらないと下のapt-getで失敗する

```sh
sudo apt-get install build-essential automake mingw-w64-x86-64-dev
sudo apt install gcc-mingw-w64-x86-64

git clone https://github.com/zenywallet/cpuminer.git

cd cpuminer/deps
./build_win_deps.sh

cd ..
autoreconf -fi -I./deps/x86_64-w64-mingw32/share/aclocal
./configure --host=x86_64-w64-mingw32 \
CFLAGS="-O3 -march=native -I./deps/x86_64-w64-mingw32/include -std=c99 -DWIN32 -DCURL_STATICLIB -DPTW32_STATIC_LIB" \
--with-libcurl=deps/x86_64-w64-mingw32 LDFLAGS="-L./deps/x86_64-w64-mingw32/lib -static"
make
```
*「-Ofast -flto」より「-O3」の方が早い。

```
cp minerd.exe /mnt/d/
```
*WindowsのDドライブにコピー

###追記
https://github.com/nezumi-tech/cpuminer
こちらの方が速い

#Windows環境で実行
論理CPUは32あるが、ZENコア（やIntel CPU）はSMTなので、IO待ちが殆ど無いMiningでは物理コア数以上で回すとスレッド切り替え処理自体や切り替えによってL1キャッシュが追い出されるために遅くなる。
物理コア数(-t 16)で回すのが良い。
ホストとの通信スレッドとかOS動作もあるので、物理コア数-1の方が良かもと試したがMiningスレッドの優先度が低いので計算能力が下がるだけだった。

#今後やること
##minerd.exe解析＆改良
パフォーマンスモニターで見た限り、MiningスレッドがCPUコアに張り付いていない。
CPU間をウロチョロしているスレッドがあるので、動作スレッドがCPUコア数（論理CPU数の半分）以下なら固定化することで若干のパフォーマンス向上が見込める。
affine_to_cpu()というのが該当する関数だけど、Windowsには対応していないのね。まずはここから。

pthreads_win32公式がpthread_setaffinity_np()に対応していなかったので
https://github.com/GerHobbelt/pthread-win32
を利用するように変更。
CPUコア数の半分以下のスレッド数の時にSMT前提で偶数番号に割り当てるようにした。
効果は微々たるもの（0.8%）なので、計算側の改良にとりかかる。

##GCC7.2(8.0)化
Ryzen向けの改良とか入っているので、コンパイラーを最新にする。
＊でも、重い処理はインラインアセンブラになってるからどれだけ効果あるのか・・・
→クロスコンパイラがmingw-gccなので、gccを上げても無駄。mingw辞めてUbuntu上の動作させることを検討する。

##GPU化
bitZenyのCPUマイニングにこだわる方針とは対立する内容。
yescriptはメモリ消費量を上げたりでGPU化が難しいが、CPUと同じ程度でいいので計算出来るようになればGPUの方が安い＆１PCに複数載せれるので採掘がペイするようになるかも。
CUDAの勉強がてら挑戦してみようかと。可否判断程度はできるようになる。
*崩壊する可能性があるので公開するかは別

##数式起こし
現状計算の元になっている論文とか数式も知らないので、計算の最適化するためにも一度数式を見ておいた方がいいかなと。

#メモ
世間一般的には「yescrypt」は「yescrypt-1.0」
BitZenyは「yescrypt-0.5」
基本的な考え方とかは下記の論文。
https://password-hashing.net/submissions/specs/yescrypt-v2.pdf

Linuxの場合は
libcurl4 だけでなく libcurl4-openssl-devのインストールも必要。
無いとconfigureが通らない。
LINE botをお手軽に実装する

# 概要
LINE botで何ができて、何ができないのかの知見を得たかったので
作ってみようと思いました。
参考にしたリンクは以下になります。
http://inside.pixiv.net/entry/2016/11/14/150000
とりあえずはメッセージをオウム返しするbotです。

# 必要なもの
①LINE developersアカウント
②LINE messangingAPIからのWebhookを受け取るサーバ
③サーバ内でメッセージを返却するスクリプト

# LINE developersアカウント
以下のリンクからアクセスしてアカウントを作成します。
アカウントが作成できたらmessenger APIを選択して新規チャネルを作成します。
https://developers.line.me/ja/

# LINE messagingAPIからのWebhookを受け取るサーバ
今回はお手軽に試したかったのでGoogle Apps Script（以下GAS）を使いました。
GASでWebサービスを公開するを選択すると簡単にWebサービスライクな振る舞いができます。

# サーバ内でメッセージを返却するスクリプト
スクリプトはGithubにpushしました。
https://github.com/iTakac/line-bot/blob/master/entrepreneur.js

オウム返しするだけでは面白くなかったので
名言を教えてもらうbotにしました。
「名言教えて」とつぶやくと名言をランダムで返してくれます。

名言は以下のサイトでAPIが公開されていたのでそちらにアクセスしています。
http://meigen.doodlenote.net/

# まとめ
LINE botを触ってみることで使い方や可能性が見えてきました。
全て無料で利用可能なプラットフォームを提供してくれていて
アプリケーションエンジニアにとってはいい時代だなと感じました。
KibanaのVisualizeで利用しているIndex Patternsをまとめて変更する

Elasticsearchのインデックス名変更に伴い、KibanaのVisualizeで利用しているIndex Patternsを変更するというあんまり発生しない作業の必要があったのでメモ。

# 環境
- Elasticsearch 6.1.1
- Kibana 6.1.1

test-hoge-foodsというindexがあり、test-hoge*でIndex Patternsを登録しています。
中身は以下のような感じで種類と名前と個数が適当に登録されています。

```json
{
    "_index": "test-hoge-foods",
        "_type": "food",
        "_id": "1",
        "_score": 1,
        "_source": {
          "type": "野菜",
          "name": "にんじん",
          "count": 3
}
```
また、Visualizeを2つ作成し、以下のようなダッシュボードを作成しています。
<img width="756" alt="変更前のダッシュボード" src="https://qiita-image-store.s3.amazonaws.com/0/222603/6b71fce9-abf9-3231-78c6-c590fe951abd.jpeg">


# 手順
例としてtest-hoge-foodsをtest-piyo-foodsへ変えてみます。

### 1. test-hoge-foodsをtest-piyo-foodsへReindex
ついでにtest-hoge-foodsはcloseしておきます(削除でも可)

```
POST _reindex
{
  "source": {
    "index": "test-hoge-foods"
  },
  "dest": {
    "index": "test-piyo-foods"
  }
}
```
```
POST /test-hoge-foods/_close
```

### 2. test-piyo-foods用のIndex Patternsを登録
<img width="743" alt="新しいIndex Patternsの登録" src="https://qiita-image-store.s3.amazonaws.com/0/222603/a1ae6d55-aa78-2fb3-1bda-d35fe5f35992.jpeg">

### 3. Index Patternsを変更したいVisualizeをExport
Saved Objectsから設定を変更したいVisualizeを出力します。
(ダッシュボードはVisualizeのidを利用しており、直接Index Patternsを指定しているわけではないので変更不要です)

### 4. 出力したjsonを編集
searchSourceJSONのindexをtest-piyo-foodsのIndex Patternsのidへ変更します。
<img width="862" alt="export.jsonの変更箇所" src="https://qiita-image-store.s3.amazonaws.com/0/222603/401de25f-c996-8043-3b42-14df8ecc9a61.jpeg">

Index Patternsのidは.kibanaのインデックスから確認できます。

```
GET .kibana/_search
{
  "query":{
    "match": {
      "type": "index-pattern"
    }
  }
}
```
_idが"index-pattern:xxxxx"となっており、xxxxxの部分がIndex Patternsのidになります。

### 5. 編集したjsonをImport
編集したjsonをSaved Objectsから取り込みます。

これで移行完了です。(必要なら古い方のIndex Patternsは削除してください)
<img width="996" alt="変更後のダッシュボード" src="https://qiita-image-store.s3.amazonaws.com/0/222603/d4ee887d-4fec-ccac-a5cd-e32cf636a41b.jpeg">

# ちなみに
indexにAliasの設定をしていればKibana側の移行はしなくても済んだと思います。。。
【Ace of Spades】ダンジョン探索スクリプトを作る（第一回）【script】

#ダンジョン探索スクリプト（案）
初期状態でマップは真っ黒で、自分が移動した箇所だけマップが表示される。
ローグライクゲームとかであるようなマップシステムをAoSにも導入できないだろうかと思って開発に着手した。

開発記録1日目、今回は個々の技術的な検証を行っていきたい。

#１、プレイヤーごとにマップ情報を分ける
あるプレイヤーが探索したマップ情報が他のプレイヤーのマップに表示されないように、マップ情報をプレイヤーごとに分ける

```python:on_block_destroy(self,x,y,z,mode)

#ブロックの設置・破壊情報を作成
block_action = BlockAction()
block_action.player_id = self.player_id
block_action.value = mode
block_action.x = x
block_action.y = y
block_action.z = z


#単ブロック破壊の場合
if mode == DESTROY_BLOCK:
	#ブロックがなくなった状態を自分にのみ適用
	self.send_contained(block_action)

#スペード掘りとグレ爆破の場合
else:
	#ブロックがなくなったことを他プレイヤーにも共有
	self.protocol.send_contained(block_action)

self.protocol.map.remove_point(x, y, z)	

return False
```

##色々実験してみて分かったこと
self.send_contained(block_action)　はグラフィック上のブロックを取り除くだけで、self.protocol.map.remove_point(x, y, z)　をしないと、ブロックを破壊した本人にだけ『見えないけど当たり判定だけあって、通過できない』タイプのバグブロックが出来上がってしまう。

ちなみに、　self.protocol.send_contained(block_action)　で情報を受け取った他のプレイヤーは当たり判定も取り除かれるらしい。


また、self.send_contained(block_action)　や　self.protocol.map.remove_point(x, y, z)　をしないで　self.protocol.send_contained(block_action)　だけをすると、『見た目上そこにあるけど、当たり判定がない（体当たりするとすり抜ける・壊せない）』タイプのバグブロックが出来上がる

send_contained⇒ブロックのグラフィック操作
remove_point⇒ブロックの当たり判定操作

と思ってよさそうだ
PCBGOGOに部品実装サービス（PCB assembly）を注文して基板作成

# 初めに
KiCADで基板の図面を書いて、中国の基板製造会社に作ってもらうだけ、はネットで探せばいくらでもあるので、部品実装までやってもらう場合のノウハウを記述

# なぜPCBGOGOなのか
日本語が通じる現地スタッフがいるからです。基板だけを作るのでは、CADデータがちゃんとしていれば、ほぼちゃんと製造してくれます。しかし、部品実装になると図面に落とせない部分が発生し、打ち合わせが必要な事があります。また、細かい指示を英語や中国語で出すのが不安であり、日本語が通じる方が良いと思ったからです。
また、PCBGOGOのスタッフがTwitterをやっていて、疑問点を事前に聞けたのも良かったと思います。

# 部品実装サービスを発注する
KiCADで基板が出来ていて、発注前の段階だと思ってください。
[部品実装のお見積もり依頼フォーム](https://www.pcbgogo.jp/pcb-assembly.html)から、必要事項を入れます。

### 部品調達方法
PCBGOGOに部品を買ってもらいそれも見積もりに入れるか、自分で部品を購入し送るか、その両方かを選択します。

今回は、「代理購入」を選択し、全て購入してもらう事にしました。部品は、中国国内で手に入る物に限ります。DigiKeyやMouserで購入できる事が目安であり、日本国内でしか買えないものがあったら、「その両方」を選択し、送りましょう。

### 実装枚数
必要枚数を入力します。

### 取付の種類
基板の両面に部品が付くか、片面だけなのかを選択します。

### 表面実装（SMT）の総数
先方に実装して欲しい表面実装部品の個数を入力します。

### 挿入実装（IMT）の総数
先方に実装して欲しいスルーホール部品の個数を入力します。

### 他の依頼事項
基板のレジストの色を入力する部分がありませんので、ここに書いておけばスムーズです。（例：レジスト色は赤・板厚1.6mmでお願いします）
また、50枚と100枚だった場合など、複数の見積もりが欲しい場合は、こちらに書いておくと要望を聞いてくれます。
私は、スルーホール部品の実装無しにしたら安くなるか？と聞きました。今回の場合は、変わらないと返事をもらいました。

### BOMをアップロードする
[基板実装において必須な入稿データ一覧](https://www.pcbgogo.jp/assembly-file-requirements.html)の「BOMの例」というExcelファイルをダウンロードします。
実装して欲しい部品と型番を記述していきます。
<img width="826" alt="BOMファイル.png" src="https://qiita-image-store.s3.amazonaws.com/0/128436/b1a45e73-609d-9799-fba5-7986902d0414.png">
向きがある部品は、実装時に注意が必要ですので、説明に記述する事と、実際に実装した写真などを貼り付けると分かり易いと思います。

また、アップロードはRAR、ZIPファイルのみしか受け付けてくれませんので、ExcelファイルをZIPなどで圧縮します。

### ガーバーデータをアップロードする
普段、中国へ基板を発注する時と同じです。

# 見積もり依頼後
なにかあれば、メールかTwitter（事前にTwitterでやり取りをしていたので、お互い知っていた）で連絡が来ます。
「基板をこう直すと、製造が安くなりますよ」という連絡がきたので、直してメールで送り直しました。こういう時、日本語が通じると大変助かります。

見積もりがメールで送られてきます。1日で来ました。

内容は問題なかったので、発注をするという旨のメールを返すと、「このPayPalアカウントに支払して、支払い画面をキャプチャして送ってください」と連絡があったので、お金を支払いその趣旨の連絡を返します。

今回の実装は自動実装するから、座標データをくれと言われ、KiCADのPcbnewの[ファイル]→[各種製造用ファイル出力]→[
フットプリント位置情報ファイル]から出力したものを送ります。
<img width="454" alt="フットプリント位置情報ファイル.png" src="https://qiita-image-store.s3.amazonaws.com/0/128436/d6c8a28c-ff97-65cc-52b0-1ff6a8244ea5.png">

中を見ると、実装しないとならない部品で無いものがあり、その事を先方に伝えると、「こちらで合わせます」と言ってくれたので、助かりました。

後で、調べてみると、フットプリントの属性が「標準」になっているとファイルに反映されず、「ノーマル＋挿入部品」にしておかないとならないようです。
<img width="303" alt="プロパティ.png" src="https://qiita-image-store.s3.amazonaws.com/0/128436/8be79102-e273-42aa-a664-c556f4bde209.png">

基板を製造し部品を調達して実装するまで18日という事だったので、気長に待ちます。


# 完成品を検品
12/17に発注して1/5に不在連絡票が入っていました。予定よりちょっと早く仕上がった計算です。

段ボールには、完成基板と余った部品が入っていました。
![IMG_5260.JPG](https://qiita-image-store.s3.amazonaws.com/0/128436/d955a5fe-b4a4-a5bf-6c92-2cf833df3ba9.jpeg)

はんだのノリは申し分ないレベル
![IMG_5263.JPG](https://qiita-image-store.s3.amazonaws.com/0/128436/cf889bb5-c384-c941-d30c-ced90a6a3a3e.jpeg)
![IMG_5265.JPG](https://qiita-image-store.s3.amazonaws.com/0/128436/0d13e38a-d260-d872-3118-764df7064e27.jpeg)


今回はクオリティーチェックはお願いしていないので、こちらで目視チェックと動作確認をします。
50枚中、1枚不良がありましたが、部品起因によるものですので、部品を取り換えれば問題ありませんでした。
【Selenium】php-webdriverでchromedriverを呼んだらunknown error: Chrome failed to start: exited abnormally


## 環境
Debian 9
Selenium Standalone Server 3.8.1
ChromeDriver 2.34
Google Chrome 63.0
facebook/php-webdriver

## 起こった問題
こんなエラーが出る場合
`Curl error thrown for http POST to /session with params: ...`

まず、タイムアウトを延長して確認

```php
// $driver = RemoteWebDriver::create('http://localhost:4444/wd/hub', $capabilities);
// タイムアウトを延長してみる
$driver = RemoteWebDriver::create('http://localhost:4444/wd/hub', $capabilities, 90000, 90000);
```

エラーが以下に変わったら
`unknown error: Chrome failed to start: exited abnormally`

以下のオプションを追加すると動きました。

```php
$options->addArguments(['--no-sandbox']);
```

## 参考URL
https://blog.shimabox.net/2017/11/15/try_headless_chrome_and_firefox_with_php-webdriver/
https://github.com/SeleniumHQ/selenium/issues/4961
【Go】switch文とif文のベンチマークテスト

何かと目の敵にされてる気がするswitch文。<br>
個人的には適材適所でswitch文とif文を使い分ければ良いと思っている派です。<br>
可読性云々はさておき実行速度的にはどうなんだろうと思いベンチマークしてみた(GoのBenchmark関数を使ってみたかったというのが8割)。

## 検証法

1. math/randパッケージを使用して乱数を作成
1. 乱数値に応じてメッセージが変わる関数を作成
    - VerificationIfElse(if文)
    - VerificationSwitch(switch文)
1. Benchmark関数を使用して、`go test -bench=. -benchmem`で比較してみる

## 検証用コード

```go:verification.go
func VerificationIfElse(randomNum int) string {
	if randomNum <= 10 {
		return "10より小さい"
	} else if randomNum >= 11 && randomNum <= 20 {
		return "10より大きく20より小さい"
	} else if randomNum >= 21 && randomNum <= 30 {
		return "20より大きく30より小さい"
	} else if randomNum >= 31 && randomNum <= 40 {
		return "30より大きく40より小さい"
	} else if randomNum >= 41 && randomNum <= 50 {
		return "40より大きく50より小さい"
	}
	return ""
}

func VerificationSwitch(randomNum int) string {
	switch {
	case randomNum <= 10:
		return "10より小さい"
	case randomNum >= 11 && randomNum <= 20:
		return "10より大きく20より小さい"
	case randomNum >= 21 && randomNum <= 30:
		return "20より大きく30より小さい"
	case randomNum >= 31 && randomNum <= 40:
		return "30より大きく40より小さい"
	case randomNum >= 41 && randomNum <= 50:
		return "40より大きく50より小さい"
	}
	return ""
}
```

```go:verification_test.go
import (
	"math/rand"
	"testing"
	"time"
)

func BenchmarkVerificationIfElse(b *testing.B) {
	for i := 0; i < b.N; i++ {
		rand.Seed(time.Now().UnixNano())
		randomNum := rand.Intn(50)
		VerificationIfElse(randomNum)
	}
}

func BenchmarkVerificationSwitch(b *testing.B) {
	for i := 0; i < b.N; i++ {
		rand.Seed(time.Now().UnixNano())
		randomNum := rand.Intn(50)
		VerificationSwitch(randomNum)

	}
}
```

## 結果

```
$ go test -bench=. -benchmem
     | BenchmarkVerificationIfElse-4   	  200000	     10462 ns/op	       0 B/op	       0 allocs/op
     | BenchmarkVerificationSwitch-4   	  200000	     10315 ns/op	       0 B/op	       0 allocs/op
```

何度か叩いてみたのですが、if文の方が早かったり、switch文の方が早かったりとまちまちでした。<br>
検証法が簡易的ですが、Goでの結果はif文とswitch文の実行速度に大差はないということが分かりました。<br>
<br>
Benchmark関数便利。<br>
というかtestingパッケージがすごい。
pandasのお作法色々

**データの集計や加工で使うリスト**
ふとした時に更新していく予定

## pandasをインポート
デフォでpandasはpd, data frameはdfにしてる

```python3
import pandas as pd
```

## データフレームを最初から作る
ランダム値から入る使用はネットに色々載ってるが、空の状態から追加していきたい時が多々ある

```python
cnt = 100 # レコード数
df = pd.DataFrame(index=[i for i in range(cnt)], columns=['column_name'], data=0)

# レコード数が分からない時
df = pd.DataFrame(index=[0], columns=['column_name'], data=0)

# その後で分かった時
cnt = 100
df = df.reindex([i for i in range(cnt)])

# 一個追加の時
# atが速い https://github.com/pandas-dev/pandas/issues/6683#issuecomment-38305770
df.at[max(df.index)+1, 'column_name'] = 0
df.loc[max(df.index)+1, 'column_name'] = 0
```

## 何かしらのデータをpandasで読み込む
```python
# csv
# encoding指定する場合、大抵'utf-8', 'cp932', 'utf-8-sig'で落ち着く
df = pd.read_csv('filename.csv', encoding='utf-8', dtype={'column_a': str, 'column_b': int})

# DB(mysql)
import pymysql
con = (
    host='hostname',
    user='user',
    password='password',
    db='dbname',
    charset='utf-8'
)
df = pd.read_sql(con, 'select * from table')

# Excel
# sheetnameとconvertersはオプション
df = pd.read_excel('filename.xlsx', sheetname='Sheet1', converters={'column_a': str})
```



## カラムを追加したい時

```python
# 例: 'add_column_name'というカラムを追加し、値にhogeを入れる
df['add_column_name'] = 'hoge'

# 例: 年齢層を年齢から取得
bins = list(range(0, 101, 10)) + [999]
labels = ['10歳未満'] + ["%d0代" % i for i in range(1, 10)] + ['100歳以上 私は元気です!']
df['age_segment'] = pd.cut(df['age'], bins, False, labels)
```

## 置換

```python
df['phone_number'].replace('-', '', inplace=True)

# 辞書から取得も可能
df['pref'].replace(dict, inplace=True)
```

## 文字を正規化

```python
import jaconv


def normalize(s):
    s = str(s)
    s = jaconv.hira2kata(s)
    s = jaconv.z2h(s)
    s = s.lower()
    return s

df['norm_user_name'] = df['user_name'].apply(normalize)
```

## 特定の値を変更する
```python
# 例: 年齢が若くて名前に魚がつく人のカテゴリを変更
df['category'] = None
df.loc[(df['age_segment'] == '10代') &
       (df['user_name'].str.contains('魚')), 'category'] = 'ギョギョギョ'
```

## DataFrameを１行ずつ読み込む
```python
# tupleが速い
for row in df.itertuples():
   pass # 処理

# 遅い
for row in df.iterrows():
   pass # 処理
```

## データを他のフォーマット(形式)にする

```python
df['user_name'].tolist() # リストの場合、カラム名は必ず指定すること
df.to_dict()             # 辞書

# ファイルに吐き出す. indexはオプション
df.to_json('filename.csv', index=False)  # json
df.to_csv('filename.csv')                # csv
df.to_excel('filename.xlsx')             # エクセル
df.to_html()                             # html
```
git コマンド

__developブランチクローンからfeatureブランチ作成まで__

```shell-session:ターミナル
$ git clone -b develop {URL}        # クローンしたいリポジトリのURL
$ cd {clonerepo}                    # クローンしたリポジトリに移動
$ git checkout -b feature-XXX       # カレントブランチからfeatureブランチを作成して切り替え
$ git push origin feature-XXX       # featureブランチをリモートリポジトリへpush
$ git checkout develop              # developブランチに切り替え
$ git pull                          # developブランチを最新に更新
$ git checkout feature-XXX          # featureブランチに切り替え
$ git merge develop                 # featureブランチにdevelopブランチをマージ
$ git push origin feature-XXX       # featureブランチをリモートリポジトリへpush
```

__releaseブランチへのマージ__

```shell-session:ターミナル
$ git checkout develop                  # developブランチに切り替え
$ git pull                              # developブランチの最新化
$ git checkout release                  # releaseブランチに切り替え
$ git pull                              # releaseブランチの最新化
$ git merge --no-ff --no-commit develop # developブランチをreleaseブランチにマージ
$ git commit -m "merge develop"        # releaseブランチのコミット
$ git push origin release               # releaseブランチのpush
```

__masterブランチへのマージからタグ作成まで__

```shell-session:ターミナル
$ git checkout release                  # releaseブランチに切り替え
$ git pull                              # releaseブランチの最新化
$ git checkout master                   # masterブランチに切り替え
$ git pull                              # masterブランチの最新化
$ git merge --no-ff --no-commit release # releaseブランチをmasterブランチにマージ
$ git commit -m "v1.0.0 release"         # masterブランチのコミット
$ git push origin master                # masterブランチのpush

$ git tag -a v1.0.0 -m "tag v1.0.0"     # タグを切る
$ git push origin v1.0.0                # タグのpush
```

###__参考__
#### 現在チェックアウトしているブランチ確認
```
$ git branch -a
```

```shell-session:結果
  a
  develop
  feature
* feature-kaXXX
  remotes/origin/HEAD -> origin/master
  remotes/origin/develop
  remotes/origin/feature-goXXX
  remotes/origin/feature-kaXXX
  remotes/origin/master
```
#### ローカルの変更を全て破棄してリモートに合わせたい
```
$ git fetch origin
$ git reset --hard origin/{branch name}
```

### pullした時に「There is no tracking information for the current branch.」
下記のコマンドでgit pullのデフォルトブランチ名を指定する。

```
git branch --set-upstream-to=origin/リモートのブランチ名 ローカルのブランチ名
```
Kaoriya版Vim で migemo を使えるようにした時の覚書

## Migemoのインストール
migemo はIMEを介さずに日本語を検索できる非常に便利な機能です。
導入の際、いくつかハマった箇所があったため、メモとして記載します。

## インストール手順

Kaoriya版Vim さんの構築した vim バージョン8.0 64bit版での例となります。

### 1. C/Migemo のダウンロード
[Koronさんのサイト]”(https://www.kaoriya.net/software/cmigemo/)から C/Migemo をダウンロードする

### 2. migemo.dll を gvim.exe の置いてある場所にコピーする
アーカイブを展開し、migemo.dll を gvim.exe と同じ場所にコピーする
(私の場合 \vim80-kaoriya-win64 の直下)

### 3. migemo.vim を runtimepath の通っているディレクトリにコピーする
runtimepath は ':set runtimepath?' で確認ができます。
(私の構成では \vim80-kaoriya-win64\vim80 以下に置きました)

### 4. 辞書をコピーする
アーカイブのdict以下をコピーする
(私の構成では \vim80-kaoriya-win64 直下に置きました)

### 5. _vimrcに以下の記載して完了
辞書と場所を指定します。
'g/' でmigemoでの検索ができます。
(ここでは '/'キーで検索できるように 'g/'をリマップしています。)

```_vimrc
set incsearch
if has("migemo")
    set migemo
    set migemodict=$VIM\dict\cp932\migemo-dict
    nnoremap / g/
endif
```
未だに裸眼で車を運転できる私がやっている事

# はじめに

黎明期のパソコンを知る私は「昔の N-BASIC や MS-DOS の**配色**は良かったな」と思います。**黒色の背景上に白い文字**。文字が識別しやすく目が疲れにくい配色でした。しかし、Mac の影響を受けた Windows の時代になり、デフォルトの配色が「**白背景＋黒文字**」となってから、パソコンは酷く目を痛める装置になってしまいました。

私の場合、仕事で日常的に MS-Office を使いますが、Word、Excel、PowerPoint、Outlook の画面をずっと見ていると１時間と目が保ちません。目が痛みを感じるぐらい疲れてしまい、画面を直視できない状態になります。

そう言えば、iPod で大音量の音楽を聞いていたユーザが難聴になったとアップルを訴えた裁判がありましたが、Mac や Windows のユーザが視力低下でアップルやマイクロソフトを訴えたという話は聞いた事がありません。
目は光を入力とする感覚器官です。目に対する負荷は「黒背景＋白文字」よりはるかに「白背景＋黒文字」の方が高い筈です。音楽に例えるとすれば、前者は「静かなクラシック」、後者は「大音量のロック」といったところでしょうか。どうして誰もアップルやマイクロソフトを視力低下で訴えないのでしょう？

仕方ないので、私は **Windows、Ubuntu、iPhone の通常画面を「黒背景＋白文字」に設定**し、必要な時だけ通常の「白背景＋黒文字」に切り替えて使っています。
このお陰で、一日中 PC やスマホの画面を見続ける生活を送っていますが、未だに自動車の運転免許証に「眼鏡等」の条件が付かない程度の視力を維持できています。

そんな私の対策について紹介します。

# Windows での対策

Windows の画面設定のテーマには、視覚障害者用の「ハイコントラストモード」テーマが複数用意されており、この中に「黒背景＋白文字」テーマがありますが、私はこのテーマを使っていません。理由は２つあります。

* Windows でハイコントラストモードテーマを使用すると、Firefox が独自のハイコントラストモードになる。この結果、どの Web サイトも「黒背景＋白文字」に変更されてしまい、多くのサイトで微妙なページの色の違いが分からない
* 一部のアプリ（vSphere Clientなど）では「黒背景＋黒文字」になってしまい、文字が読めない

結局、単純な「黒背景＋白文字」テーマを諦め、通常の Windows 画面を単に**色反転**する方法を探していたところ、[NegativeScreen](http://arcanesanctum.net/negativescreen/)というフリーソフトを見つけました。その名の通り、写真のネガのように画面全体の色をリアルタイムに反転するソフトウェアです。[Win]+[Alt]+[N]のショートカットで色反転の ON/OFF が出来るため、必要な時だけ即座に通常画面に戻す事が出来ます。
但し、このソフトウェアは Windows7 以降のデスクトップコンポジションを利用しているので、リモートデスクトップ経由で使用する場合には、リモートデスクトップのオプションで以下の機能を有効にする必要があります。

* デスクトップコンポジション
* テーマ

更に、リモートのデスクトップ側の画面設定でデスクトップコンポジションを有効にしたテーマを選択する必要があります。

# Ubuntu での対策

Ubuntu は [Unity](https://ja.wikipedia.org/wiki/Unity_(%E3%83%A6%E3%83%BC%E3%82%B6%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%95%E3%82%A7%E3%83%BC%E3%82%B9)) と呼ばれる独特のデスクトップをデフォルトにしています。Unity は [Compiz](https://ja.wikipedia.org/wiki/Compiz) というウインドウマネージャをベースにしていますが、この Compiz のプラグイン（compiz-plugins）と設定アプリ（compizconfig-settings-manager）をインストールして再ログイン（＝デスクトップを再起動）し、compizconfig-settings-manager を起動して「アクセシビリティ」中の「Negative」にチェックを入れると、画面の色反転機能を使えるようになります。
デフォルトではウインドウ単位での反転になりますので、色反転したいアプリを選択して「Win」+「N」を押すと、そのウインドウの色反転を ON/OFF できます。

但し…[Unity は 18.04 でデフォルトのデスクトップではなくなります](https://qiita.com/m-shibata/items/550c42380842db9b807e)。

# iPhone での対策

iOS は標準で画面の色反転機能があります。設定の「一般」→「アクセシビリティ」→「ディスプレイ調整」→「色を反転」を設定すると画面の配色が反転します。しかし、カメラや Ingress など、アプリによっては通常の配色の方が良いものもあります。アプリ切り替え毎に上記の設定をチマチマ行うのは現実的ではありません。
そこで、ホームボタンのショートカット機能を使います。「一般」→「アクセシビリティ」→「ショートカット」→「色を反転」を設定すると、ホームボタンを３回連続押す事で色反転を ON/OFF できます。

# 最後に

そもそも長時間画面を見ないのも大事な対策です。可能であれば業務を見なおして長時間画面を見なくても良いように工夫した方が良いでしょう。

また、目の運動も効果的です。例えば、広い食堂等の天井にある照明を近い方から遠い方へ（あるいはその反対）順に見つめる（＝目の焦点を合わせる）のも良いと思います。
Juliaのインストール(on Debian9.3)

Debian9.3でのJuliaインストールについてメモ。

バージョン確認:

``` r:bash
cat /etc/debian_version 
9.3
```


aptでインストール可能なJuliaは記事執筆時点で v0.4.7 と少々古い.

``` r:bash
apt search julia|grep julia

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

julia/stable 0.4.7-6+b3 amd64
julia-common/stable 0.4.7-6 all
julia-doc/stable 0.4.7-6 all
libdatetime-calendar-julian-perl/stable 0.04-1 all

```
そこで、
公式: https://julialang.org/downloads/ からNightly builds版バイナリをDL、
Debian9.3へインストールする。

/tmp へ移動,DLして展開 -> /opt へ移動 -> シンボリックリンク作成 の3工程.

``` r:bash
cd /tmp
wget https://julialangnightlies-s3.julialang.org/bin/linux/x64/julia-latest-linux64.tar.gz
tar zxvf julia-latest-linux64.tar.gz
su
mv julia-cce56c8797 /opt/julia
ln -s /opt/julia/bin/julia /usr/local/bin/julia
exit

julia
               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: https://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.7.0-DEV.3328 (2018-01-08 08:15 UTC)
 _/ |\__'_|_|_|\__'_|  |  Commit cce56c8797 (0 days old master)
|__/                   |  x86_64-pc-linux-gnu

julia> 

```

これで出来た(ヽ'ω`)
Vue.jsでSequelizeから取得したデータをv-forしようとしてはまった話

#前提

* Vue.js 2.5.8
* Sequelize 4.22.13
* [express-vue](https://github.com/express-vue/express-vue)によりサーバーサイドからVue.jsへデータを渡す形

#やりたかったこと
Vue.jsの特徴といえば単一ファイルコンポーネントです。
コンポーネントを細かく分けることでソースコードの見通しがよくなり、整備性もよくなります。
そこで、データベースから取得したデータをカラム数などに関係なく共通のコンポーネントで表示できないか？となりました。
##普通に考えれば…
データが格納されているオブジェクトを"datas"とします。

```HTML:sample.vue
<template>
    <table>
        <tr>
            <td v-for="value in columns">
                {{value}}
            </td>
        </tr>
        <tr v-for="(row, index) in datas">
            <td v-for="col in columns">
                {{ row[col] }}
            </td>
        </tr>
    </table>
</template>

<script>
export default {
    data: function () {
        return {
        	title: 'Sample',
        }
    },
    props: ['datas'],
    computed: {
        columns: function() {
            return Object.keys(this.datas[0]);
        },
    }
}
</script>

<style lang="css">

</style>
```

このように、v-forを入れ子にすれば表示されるはずです。
実際、`[{id: 1, name: 'test'}, {id: 2, name: 'test2'}]`のような簡単な構造のオブジェクトではこれで正常に表示されました。

##しかし…
sequelizeで取得したテーブルデータを流し込むと、
`TypeError: Converting circular structure to JSON`
と例外が飛ばされてしまいます。
JSON.stringifyを行う際、オブジェクトに循環参照が含まれていると表示される例外のようです。

#解決策
Vue.jsに渡すオブジェクトを一度`JSON.stringify`してから再度`JSON.parse`します。

```javascript:sample.js
db.Sample.findAll().then(samples => {
    const data = {
        response: JSON.parse(JSON.stringify(samples))            
    };
    const vueOptions = {
        head: {
            title: 'Sample'
        }
    };
    res.renderVue('database/samples', data, vueOptions);
});
```

あまりきれいな解決法ではないかもしれませんが、とりあえずということで。

#おわりに
原因を探るためにいろいろ調べていた時、「Vue.jsって単に`console.log()`しただけじゃ`reactivegetter()`とか`reactivesetter()`になって中の値表示してくれないの何とかならないのかなぁ」と思って気分転換に調べてみたら、ネットの海に「一度JSON文字列に直す」という解決法が示されていて、「もしかしていけるのでは？」と今回の件に使ってみた結果がこれです。
数時間をドブに捨てました。
Ethereum入門を始める時に、bash <(curl -L https://install-geth.ethereum.org)が使えなかった時の対処法。

Ehereum入門のこの記事
[Gethをインストールする](https://book.ethereum-jp.net/first_use/installing_geth.html)

`$ bash <(curl -L https://install-geth.ethereum.org)
 % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0curl: (6) Could not resolve host: install-geth.ethereum.org
`

できない。。。。。
検索してみる。

##### bash <(curl -L https://install-geth.ethereum.org) できない
で検索。

結果15件、しかもほとんど中国語で日本語でこれに詰まった人がいない。。。。
仕方ないので、他の方法でGethのinstallを試みる。

##### bash <(curl -L https://install-geth.ethereum.org)　 impossible
で検索。

英語の情報なら結構あるでしょう。

結果11件、でもHomebrewでinstallできる奴をみっけた。
[go ethereum - How to run geth --fast on OSX - Ethereum Stack Exchange](https://ethereum.stackexchange.com/questions/3679/how-to-run-geth-fast-on-osx/3682)

とりあえず挑戦。
そっからリンクをここに飛んで、
[Installation Instructions for Mac](https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-Mac)

homebrewはinstallされているのでOK。

homebrewが入っているかどうかは
`$ brew -v`
`Homebrew 1.4.2`
で確認できる。


以下のコマンドをターミナルにそれぞれ打って
`$ brew tap ethereum/ethereum`
`$ brew install ethereum`

実際にgethがインストールされたかを確認するために、

`$ geth help`
のコマンドを実行。gethコマンドのオプション情報が表示されれば、正しくインストールされています。

[Installation Instructions for Mac](https://github.com/ethereum/go-ethereum/wiki/Installation-Instructions-for-Mac)のサイトには、
続きとして、以下のこと載っていたけど、実行しないでも`geth help`コマンドが実行できたので、多分必要になるまではやらなくても大丈夫。

>You can install the develop branch by running --devel:
`brew install ethereum --devel`
After installing, run geth account new to create an account on your node.
You should now be able to run geth and connect to the network.
Make sure to check the different options and commands with geth --help
For options and patches, see: https://github.com/ethereum/homebrew-ethereum

これで[Gethをインストールする](https://book.ethereum-jp.net/first_use/installing_geth.html)はでやらなければいけない事は終了なので、
次の記事の[プライベート・ネットに接続する](https://book.ethereum-jp.net/first_use/connect_to_private_net.html)に進める。
VirtualBox内のcentos7からVirtualBoxの共有フォルダをマウント

#### 1.VirtualBoxの仮想インスタンスに共有フォルダを作成する
 * `設定` > '共有フォルダ' にてhost側のフォルダの共有フォルダに設定する。その際、`永続化する`にチェックを入れるらしい

#### 2.仮想のCR−ROMにguestAdditionを挿入
* VirtualBoxを起動
* 仮想サーバーの画面を選択した状態でメニューの `Devices` > `Insert Guest Addition CD image`　をクリック

#### 3.仮想側での操作

* GuestAdditionをマウント

```
mkdir /mnt/cdrom
mount -r -t iso9660 /dev/cdrom /mnt/cdrom
```
※　念の為以下を実行しておく。
virtualboxの共有フォルダをマウントでいないときがあるため。

```
yum -y install update kernel
```

* 以下をインストールするらしい

```
yum install -y bzip2 gcc make kernel-devel kernel-headers dkms gcc-c++
```


* 再起動

```
reboot
```

* guest additionのインストール

```
cd /mnt/cdrom
./VBoxLinuxAdditions.run
```

* 共有フォルダをマウント

```
mount -t vboxsf [共有フォルダ] [マウントフォルダ] 
```


以上、個人的なメモ