OmniAICreator/Qiita-1.07M huggingface dataset:
vagrantを使ってndnSIMの環境構築

# はじめに
ちょいちょい環境が何故か壊れたり
再インストールしたときに書いてある場所によって書いてあることが違いすぎて
あれどうインストールしたっけとなるので、Vagrantで環境をいい感じにしたくて
Vagrant初挑戦

何をやったかは見たくなく
実践したい人は以下をクローンして
`vagrant up`してください。
https://github.com/kmdkuk/vagrant4ndnsim
＊注意：PyVisを使うためにディスプレイを使ったり
ホストOSでシナリオやエクステンションを編集するためのフォルダ共有のあれこれはまだ

# 環境
Ubuntu16.04
Vagrant 2.1.2

# 手順
debian9に環境を作っていきます。
GuestAdditionインストールのためのvagrant-vbguestもインストール

```bash
$ vagrant init debian/stretch64
$ vagrant plugin install vagrant-vbguest
```
ここで仮想環境を立ち上げるのですが、
ndnSIMをインストールするのにメモリなど足りないので
`vagrant init`でできたVagrantfileをこんな感じに
メモリーとCPUの数を追加していきます。
initした時にいろいろなコメントが入ってありますがとりあえずスルーしました。

```ruby:Vagrantfile
Vagrant.configure("") do |config|
  config.vm.box = "debian/stretch64"
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
    vb.cpus = 2
  end
end
```

こっからはndnSIMのドキュメント通りにインストールする手順を
provisioner.shに記録していきます。
debianにはデフォルトでpkg-configが入ってない？ようだったので
installを追加しています。

```bash:provisioner.sh
sudo apt install -y build-essential libsqlite3-dev libcrypto++-dev libboost-all-dev libssl-dev git python-setuptools
sudo apt install -y python-dev python-pygraphviz python-kiwi python-pygoocanvas python-gnome2 python-rsvg ipython
sudo apt install -y pkg-config
mkdir ndnSIM
cd ndnSIM
git clone https://github.com/named-data-ndnSIM/ns-3-dev.git ns-3
git clone https://github.com/named-data-ndnSIM/pybindgen.git pybindgen
git clone --recursive https://github.com/named-data-ndnSIM/ndnSIM.git ns-3/src/ndnSIM

# Build and install NS-3 and ndnSIM
cd ns-3
./waf configure -d optimized
./waf

sudo ./waf install
cd ..

git clone https://github.com/named-data-ndnSIM/scenario-template.git scenario
cd scenario
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

./waf configure
```
以上の手順をprovision.shに書いて
プロビジョニングの設定をしていきます。

```ruby:Vagrantfile
config.vm.provision "shell", path: "provisioner.sh" #←追加
```


```bash
$ vagrant up
```

仮想環境に入り作業する

```bash
$ vagrant ssh
```

これでコマンドラインからndnSIMを使うことができます。
PyVisを使うためにディスプレイを使ったり
ホストOSでシナリオやエクステンションを編集するためのフォルダ共有のあれこれを追加編集予定
npm install でいろいろミスった

npm install　でいろいろミスった

- [x] node_modulesディレクトリ以下のパーミッションを変更する

```
sudo chown -R user:group
```

- [x] nodejsやらnodeやらがおかしい

Ubuntuで npm install しようとしたら　'/usr/bin/env: node: No such file or directory' って言われた

```
ln -s /usr/bin/nodejs /usr/bin/node
```

これで無事解決
論理回路の基礎 #2 論理演算

# レジスタとALU

レジスタとALUという言葉を聞いたことがあるでしょうか？
これは、CPUの内部にある一番コアな部分の名称です。

簡単に例えると、レジスタとは「コンピュータが今考えていること。」にあたります。

コンピュータ上では、ある程度のビットをまとめて扱っており、その量はCPUのビット数によって変わってきます。32ビットCPUであれば32個の、64ビットCPUであれば64個のビット列を同時に処理することができます。

このビットの量がまさにレジスタの記憶容量になっているのです。
レジスタは現代のマルチプロセッサでは1コア当たり16個の汎用レジスタが存在しており、基本的には、1クロックで値が入れ替わります。[^1]

そしてこれを読み込むのがALUとなっています。
ALUとは各演算に対応した回路が組み込まれており、指定された演算回路を提供するための、電子回路です。
足し算をする命令が来ていれば足し算の回路を、ビットシフトをする命令が来ていればビットシフトの回路を提供しているということです。

要するにCPU内では、

**レジスタが命令とデータを保持し、ALUがそれを処理している**

のです。

このことを考えるにあたって、重要になってくるのが2進数の演算: 論理演算です。(少し語弊がありますが、大体間違っていない。)[^2]
CPUは基本的に2進数以外扱うことができません。そのため、2進数をどうやって、10進数や文字など現実に使用しうるものにするか？ということを考える必要があったわけです。

# 2進数の演算(論理演算)

コンピュータ業界の中で、よく使われる2進数。ですが、論理だてて学んだことはないかもしれません。
基礎的な部分を少し見てみましょう。
(そんなの知ってるよ。って人は飛ばしてね！)

### 論理演算の基礎

論理演算は、論理和・論理積と呼ばれるものと否定というもので成り立っています。

まず、論理和から見ていきましょう。
論理和とは、いわゆるORにあたるもので記号は∨もしくは＋で表されます。
実際の1ビットの演算では、以下のような結果になります。

``` math
0 \lor 0 = 0\\
0 \lor 1 = 1\\
1 \lor 0 = 1\\
1 \lor 1 = 1\\
もしくは\\
0 + 0 = 0\\
0 + 1 = 1\\
1 + 0 = 1\\
1 + 1 = 1\\
```

次に、論理積です。
論理積とは、いわゆるANDにあたるもので記号は∧もしくは・であらわされます。
実際の演算では以下のような結果になります。

``` math
0 \land 0 = 0\\
0 \land 1 = 0\\
1 \land 0 = 0\\
1 \land 1 = 1\\
もしくは\\
0 \cdot 0 = 0\\
0 \cdot 1 = 0\\
1 \cdot 0 = 0\\
1 \cdot 1 = 1\\
```

これら2つは2つの項目を結ぶ2項演算子と呼ばれるものです。
それに対して、もう一つのNOTは単項演算子です。
これは、いわゆる否定(プログラムの中だと良く!マークであらわされます)にあたるもので、記号は上部に横棒もしくは￢であらわされます。

``` math
\overline 0 = 1\\
\overline 1 = 0\\
もしくは\\
\neg 0 = 1\\
\neg 1 = 0\\
```

この3つを基本として、成り立っていくのが論理演算です。

### 結合法則・交換法則・分配法則

さてはて、この論理演算の名前に和・積という名前がついていますが、これはなぜか？というと[^3]

通常の足し算・掛け算のように交換法則・結合法則・分配法則
が成り立つからなんです。例えば、交換法則であれば

``` math
A + B = B + A\\
A \cdot B = B \cdot A\\
```
とか結合法則なら

``` math
A + \left(B + C\right) = \left(A + B\right) + C\\
\left(A \cdot B\right) \cdot C = A \cdot \left(B \cdot C\right)\\
```

だったり、分配法則であれば

``` math
A\cdot \left(B + C\right) = A \cdot B + A \cdot C
```

こんな風になります。

否定に関しても、実際のマイナスと同じような扱いになります。

``` math
\overline {\overline A} = A\\
\overline {\overline {\overline A}} = \overline A
```

何となく論理演算のイメージがつかめたでしょうか？
基本的には、普通の足し算・掛け算と変わらないと思うとそんなには、難しくないかと思います。

次回は、この論理演算にしかない、特殊な法則(吸収法則・ド＝モルガンの法則)に関して書こうと思います。
では、また。

# 勉強会のお知らせ

この記事は、勉強会の資料を兼ねて書かれたものです。
2018/08/09 19:30～
溜池山王：細川ビル3階会議室で、勉強会を行います。
よろしければ、ふるってご参加くださいね！

https://connpass.com/event/93120/


[^1]: クロックはCPUが一つの処理を行える最小単位。公称2GHzのCPUで1クロック当たり約500psとなる。
[^2]: 「論理演算は2進数の演算である。」これは正しいけど、「2進数の演算は論理演算である。」これは間違い。コンピュータの細かな素子一つ一つは論理演算しかできないが、それを組み合わせることによって論理演算から2進数の演算に拡張している。そのためにはキャリーフラグ・ボローフラグ(興味があったら調べてみると面白いかも)などがあり、論理演算のみで、足し算・掛け算を論理演算のみで行うことはできない。
[^3]: この辺に興味ある人は大学課程の代数学(線形代数じゃないよ！)が面白いのでおススメ。
【Swift4】WKWebViewでヘッダー情報の取得

# Header情報の取得
### 取得するための準備

`WKWebView`の`delegate`を設定します

```swift:ViewController.swift
override func viewDidLoad() {
    super.viewDidLoad()
    wkWebView.navigationDelegate = self
}
```


`ViewController`に`delegate`を準拠させ、以下コードを記述します。

```swift:ViewController.swift
extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {

    }
}

```

### 取得

`WKWebView`がページ遷移しようとした際にこのメソッドが呼ばれるのでここでヘッダー情報を取得します。
`headers`は`[AnyHashable : Any]`型で返されるのでこれにしたがって取得を行います。

```swift:ViewController.swift
extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        guard let httpURLResponse = navigationResponse.response as? HTTPURLResponse else {
            return 
        }  //navigationResponse.responseをHTTPURLResponseにキャスト。
        let headers = httpURLResponse.allHeaderFields  //ヘッダー情報を`headers`に格納
    }
}
```
その他のヘッダー情報などは以下から取得可能です。

```swift:ViewController.swift
extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        let mimeType = navigationResponse.response.mimeType  //MIMEType
        let url = navigationResponse.response.url  //URL
        let fileName = navigationResponse.response.suggestedFilename  //ファイルの名前
        let expectedContentLength = navigationResponse.response.expectedContentLength  //ファイルのサイズ
    }
}
```
Macで最新版MongoDBをインストールして初期設定をする

##　概要
バイナリーからMacにmongoDBをインストールした際の手順をまとめておきます。

## 動作環境
MacOS High Sierra (バージョン10.13.6)

## インストールの手順

- MongoDB公式サイトからファイル一式をダウンロード
- バイナリーファイルの移動
- データ/ログフォルダの生成
- 起動

### MongoDB公式サイトからファイル一式をダウンロード
下記のMongoDBの公式ホームページから必要ファイルをダウンロードします。
https://www.mongodb.com/download-center#community

```shell-session:~
wget https://fastdl.mongodb.org/osx/mongodb-osx-ssl-x86_64-4.0.0.tgz

tar -zxvf mongodb-osx-ssl-x86_64-4.0.0.tgz  #フォルダを解凍する
```
### バイナリーファイルの移動
解凍したフォルダ内にあるbinフォルダのバイナリーを/usr/local/binに移動します。

移動例
***というファイルを/usr/local/binに移動します。

```shell-session:~
mv *** /usr/local/bin 
```

### データ/ログフォルダの生成
```shell-session:~
sudo mkdir /var/lib/mongodb
sudo touch /var/log/mongodb.log
```
データを格納するフォルダと、ログを出力するファイルを生成します。

### 起動
先程作成したデータ格納用ディレクトリとログファイルを指定してデータベース側のMongoDBを起動します。起動するとターミナルで待ち受け状態になります。

```shell-session:~
sudo mongod --dbpath /var/lib/mongodb --logpath /var/log/mongodb.log
```


別のシェルを起動し、クライアント側のmongoを起動します。

```shell-session:~
$ mongo
MongoDB shell version v4.0.0
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 4.0.0
Server has startup warnings:
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten]
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten]
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten] **          Start the server with --bind_ip <address> to specify which IP
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2018-07-17T15:16:21.962+0900 I CONTROL  [initandlisten]
---
Enable MongoDB's free cloud-based monitoring service to collect and display
metrics about your deployment (disk utilization, CPU, operation statistics,
etc).

The monitoring data will be available on a MongoDB website with a unique
URL created for you. Anyone you share the URL with will also be able to
view this page. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.

To enable free monitoring, run the following command:
db.enableFreeMonitoring()
---

>
```

無事起動し、最新版のMongoDB v4.0がインストールできました。



参考
MongoDB公式サイト：https://docs.mongodb.com/manual/tutorial/install-mongodb-on-os-x/
GoのGithub APIv4 でreflect.Value.Interfaceというが出てエラーでハマった件

GoでGithub API v4から取得したくてgithubqlを使ってみました。
https://qiita.com/siso9to/items/8ee0fc166902d5026649
https://github.com/shurcooL/githubv4

慣れないGoでAPIやJSONを扱うものは今後Goでは触りたくないと思ってしまいました。

そんな中でも強烈にハマったエラーが下記です。
`reflect.Value.Interface: cannot return value obtained from unexported field or method`

原因は非常に単純でプロパティ名も先頭の文字が大文字じゃないといけなかっただけでした。

```
type PullRequest struct {
    // ↓ok
    Title  githubv4.String
    // ↓ng
    url    githubv4.URI
}
```
ASTERIA ずんどこきよし

ASTERIAでランダムで「ずん」と「どこ」を出現させ,
「ずん」「ずん」「ずん」「ずん」「どこ」と来たら「きよし」出力させて終了する.


# 全体像
![qiita_20180717_1.png](https://qiita-image-store.s3.amazonaws.com/0/180419/6307f382-d77f-b3f7-64e6-ca87e6fdb0ac.png)


## 解説①　前提条件について
「ずん」とか「どこ」をどっかで記録する必要がるのですが、他の言語を見ると配列を使っている方が大半だと思うのですが,
①ループのなかでMapperコンポーネントのParametaListを使うと初期化されるんですね.
ということで, 却下(初期化されない方法をご存知の方はそれをご教示お願いします.)
②StreamPutコンポーネントで記録する方法ですが, こちらは"代入"しかなく,追加(Linuxなら追記)機能がない.

ということで, 自分としてはやりたくないのですが,
 追加処理のある "ファイル"に記憶させます.


##解説②　再帰処理
「ずん」「ずん」「ずん」「ずん」「どこ」と並んだ終了となり, その並びになるまで処理を繰り返す.簡単に言えば,　再帰処理ですね. 
再帰処理の条件は
①無限ループである
②無限ループを抜ける終了条件がある(=これを"基底部"というそうです)

### ①無限ループについて
ASTERIAには無限ループが存在しないので(するかもしれないが私は知らない),
LoopStartコンポーネントを999回として, 事実上無限ループになるよう偽装する.


### ②基底部について
BranchStartコンポーネントは,
条件式がTRUEならば→のフローへ
条件式がFALSEならば↓フローへ行きます.
TRUEのときに, 無限ループから抜けれるように, 最後にBreakコンポーネントを設置.

ちなみにですが, ASTERIAには自己再帰(フローの中に,自分のフローを追加する)が設定できないようです.(フローだけでなく,　関数でもできません.)
無理矢理行うと以下のエラーが出力されます.
![qiita_20180717_2.png](https://qiita-image-store.s3.amazonaws.com/0/180419/a0d59206-f1a5-9a45-1291-b99e4bd74767.png)


## 解説③「ずん」or「どこ」をランダム出力
![qiita_20180717_3.png](https://qiita-image-store.s3.amazonaws.com/0/180419/367f3246-0e31-4588-7fcb-a56baba52072.png)

ランダムを出すのは基本的にRandコンポーネントでしょうか.(私は実務で使ったことがないです)
ここでは深く意識する必要はないとか思いますが, ランダムを使用するときは何分布かを意識する必要があります.
[ヘルプ](https://help.asteria.com/documentation/warp/ja/4.6/flow/designer/index_function.html) を見ても, 特に書いてないですね.
最終的に 0 or 1 を出力させたいので, 
一様分布でやるのが基本ですが, もしかしたら正規分布かも知れません.

ランダムのほかにも出すやり方として,
システムIDや実行時のミリ秒をmodして偶数か奇数かで判定するやり方する方もいるかもしれませんね.(もしかしたらRandの内部処理はこちらかも知れません.)


## 解説④　「ずん」「ずん」「ずん」「ずん」「どこ」の判定
最後の5つだけがどう出力されたかが判定条件ですので, 他は不要です.
RecordFilterコンポーネントは
Linuxでいう tail -n 5　をしているイメージです.
読み込み開始行を　${stream.RecordCount}-4 だとうまく動かなかったので, その手前でMapperで求めてるだけです.


## 解説⑤ INNER JOIN はJOINだけの意味ではない
![qiita_20180717_4.png](https://qiita-image-store.s3.amazonaws.com/0/180419/c007cfc5-e78f-a123-152b-1aeb64513433.png)

RecordTransposeコンポーネントで縦横転置して,Velocityコンポーネントで直接入力した正しい値と合致するか判定して,
判定が正しい(=すなわち出力レコードが1つか)を判定しています。

普通は
RecordFilterコンポーネントの条件式で

```
$record.field1 ="ずん" && $record.field2 ="ずん" && $record.field3 ="ずん" && $record.field4 ="ずん" && $record.field5 ="どこ"
```
 
と書いてもいいのですが, 私なら絶対にINNER JOINを使います.

## 結果を見てみましょう
![qiita_20180717_5.png](https://qiita-image-store.s3.amazonaws.com/0/180419/b51b289f-9cf3-dde4-7c85-a9a165077982.png)
うまくいってますね.


# こっからは余談.
このフローを100回まわして,　平均何回で出力されるのか知りたいくないですか？
![qiita_20180717_6.png](https://qiita-image-store.s3.amazonaws.com/0/180419/9ab835e8-e5f5-63bc-1d1a-ba0751a5df34.png)
平均値:32.25
MAX:167回
MIN:5回
だそうです. 一応参考までに.

## 戻り値
サブフローはBreakコンポーネントまで行くと, 
最後はEnd(Response)コンポーネントに行くようです.
戻り値にレコードのループ回数を入れているのですが,
親フローからモドリッチ(←言いたいだけ)をどうやってうけとるのでしょうか？(私はストリームからとりました)
ここ難しいです.

あくまで一例です.
他にも色々な方法が存在すると思いますので,　
私ならもっとベストプラクティスがある!との方は是非Qiitaにお願いします!
サブディレクトリーを含めて、カレントディレクトリー以下にあるHTMLファイルの数を数える

カレントディレクトリー以下の、拡張子htmlのファイル一覧を出す

```
find . -type f -name \*.html
```

フルパスで出すときは、

```
find `pwd` -type f -name \*.html
```

数を数えるときは

```
find `pwd` -type f -name \*.html | wc -l
```
[k8s] helmで Error: no available release name found になったとき

k8sのパッケージマネージャ helm を使おうと思ってインストール後、
helm install コマンドを実行したらエラーで怒られた

```
$ helm init
$ helm install stable/redis-ha
Error: no available release name found
```

どうやら Default の　RBACの設定だとうまく動かない模様・・・
以下のコマンド実行したら、インストールできた

```
$ kubectl create serviceaccount --namespace kube-system tiller
$ kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
$ kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
```

参考: https://github.com/kubernetes/helm/issues/3055
DockerでLAMP環境

もう何番煎じかわかりませんが、毎回調べてその都度ハマるのはもう嫌なので、自分の記録として残します。

docker-composeで以下の環境を作成します。

- Apache 2.4
- PHP 7.x
- MySQL 5.7 or 8.0

# Docker image

以下の公式イメージを使います。

PHP: [https://hub.docker.com/_/php/](https://hub.docker.com/_/php/)
MySQL: [https://hub.docker.com/_/mysql/](https://hub.docker.com/_/mysql/)

PHPはApacheが入っているもの（7.2-**apache**-stretch等）を利用します。

# ディレクトリ構造

```text
.
│  docker-compose.yml
│
├─src
│      ソースコード
│
└─docker
   │
   └─php
          Dockerfile
```

# docker-compose.yml

```yaml
version: '3'
services:
  app:
    build: ./docker/php
    volumes:
      - ./src:/var/www/html
    ports:
      - 80:80
  mysql:
    image: mysql:5.7
    environment:
      - MYSQL_ROOT_PASSWORD=root
    ports:
      - 3306:3306
    volumes:
      - dbdata:/var/lib/mysql
volumes:
  dbdata:
```

## 解説

```yaml
services:
  app:
    volumes:
      - ./src:/var/www/html
  mysql:
    volumes:
      - dbdata:/var/lib/mysql
volumes:
  dbdata:
```

Dockerのコンテナは、内部の操作はコンテナの停止と共に破棄されてしまうため、特にDBコンテナではデータの永続化をする必要があります。

アプリケーションのソースコードはservices.app.volumesでローカルのディレクトリをマウントしているため、コンテナ内の操作とローカルの操作がリアルタイムに反映しあいます。

DBのデータの永続化は、以前はデータ格納用コンテナを別途用意していましたが、トップレベルのvolumesセクションでnamed volumeを指定することで簡単にできるようになりました。
今回は**dbdata**という名前のnamed volumeを作成し、mysqlのデータディレクトリにマウントしています。
postgresqlの場合は以下のようにします。

```yaml
  volumes:
    - "dbdata:/var/lib/postgresql/data"
```

named volumeは全てのコンテナから参照できます。

# Dockerfile

```text
FROM php:7.2-apache-stretch
RUN apt-get update \
    && apt-get install -y libpq-dev \
    && docker-php-ext-install pdo_mysql pdo_pgsql
```

公式のphpイメージにはpdoがインストールされていないため、追加する必要があります（1敗）。

# 起動

```text
docker-compose up -d
```

以上
CSSカスタムプロパティ（変数）などをstylusで使う

`hsl()`とかもそうですが、
literal CSS 頼るしかなさそう。

```stylus:css
@css {
    .test {
        --hue: 50;
        background: hsl(var(--hue), 100%, 50%);  
    }
}

.test
    width 100px
    height 100px
```

<p data-height="265" data-theme-id="0" data-slug-hash="JBXBgW" data-default-tab="css,result" data-user="pokkur" data-embed-version="2" data-pen-title="CSS Custom Properties on Stylus" class="codepen">See the Pen <a href="https://codepen.io/pokkur/pen/JBXBgW/">CSS Custom Properties on Stylus</a> by pokkur (<a href="https://codepen.io/pokkur">@pokkur</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
how to bidirectional convert of between Type Sequence and Index of Type Sequence.

## require libraries
* boost
* c++11 or more than (require constexpr)

## code
### sequence_holder.hpp
```cpp
#pragma once
#include <boost/mpl/vector.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/find.hpp>

template<class ... types_t>
struct sequence_holder_t {
    using container_t = boost::mpl::vector<types_t...>;
    template<size_t index_v>
    using at_t = typename boost::mpl::at<container_t,boost::mpl::int_<index_v>>::type;
    template<class selected_t>
    static constexpr size_t at_v = boost::mpl::find<container_t,selected_t>::type::pos::value;
};
```

## usage
### main.cpp
```cpp
#include <iostream>
#include "sequence_holder.hpp"
#include <boost/core/demangle.hpp>

int main() {
    using holder_t = sequence_holder_t<int, unsigned, long, double, float>;
    std::cout << holder_t::at_v<long> << std::endl; // print to 2
    std::cout << boost::core::demangle(typeid(holder_t::at_t<2>).name()) << std::endl; // print to long
}
```

## What to use for?
for `boost::variant` `boost::fusion::vector`...
you can do it, if you want to auto detection to the type and the index of typed container by metaprogramming.

## wandbox
[https://wandbox.org/permlink/5JjiRofIcQr6wi0V](https://wandbox.org/permlink/5JjiRofIcQr6wi0V)
[AWS] IAMユーザーを擬似セッションタイムアウト（要MFA）

# 目的
IAMユーザーにはセッション切れがありません。
一度マネジメントコンソールにログインしたら、ブラウザを開いている間はずっとセッションが有効です。
<FONT color=red>※訂正：12時間で切れます。
　https://aws.amazon.com/jp/console/faqs/#session_expire</FONT>

それほど問題になるケースは無いかもしれませんが、例えば通常よりも強いAdminやPowerUserなどの権限を持つ"特権ユーザー"を利用する場合、ログインしっぱなしは防止したいところ。
ということで、擬似的にセッションタイムアウトさせてみます。

# 方法
ログインから一定時間経過後に、全ての権限を禁止（Deny）するポリシーを付与します。
尚、MFA必須です。他にログイン時間を基準にする方法がないので。

# ポリシー例

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "NumericGreaterThanIfExists": {
          "aws:MultiFactorAuthAge": "3600"
        }
      }
    }
  ]
}
```

* `"aws:MultiFactorAuthAge"` は秒数です。  
  このポリシー例の場合は 3600秒 = １時間。
* MFAなしでログインした場合は、"常に全てDeny"になります。


# 注意
* 「最後の操作から一定時間経過後」ではないことに注意。  
  何か作業途中であろうと、ログインから一定時間で問答無用で権限が剥奪されます。
パブリックBlockchainとプライベート(コンソーシアム)Blockchainを比較する

主にパブリック型Blockchainの現状や事例のまとめから、Hyperledger Fabricを中心としたプライベート/コンソーシアム型Blockchainとの立ち位置の違いを考察するスライドです。

2018年4月時点でイベント用に作成されたものであり、情報が古くなっている可能性があります。 
※資料の内容は全て個人的な見解からまとめられたものです。 

ご指摘、ご意見などありましたらよろしくお願いします！


[![thumbnail](http://image.slidesharecdn.com/blockchainbasic-180717043129/95/slide-1-1024.jpg)](https://www.slideshare.net/khit9/blockchain-106230037)
Angularでカスタムフォーム(CustomFormControls)を作る(2/2)

[前回](https://qiita.com/kiita312/items/7276a960dd8e8d18b566)からの続きです。
今回は残りのバリデーションとエラーメッセージ部分を行います。

- ~~標準のinputなどのフォームと同様の使い方ができること~~
- 入力必須のバリデーションが行われること
- 未入力の場合にエラーメッセージを表示されること

##Validationを設定する

validationを設定するには以下の2点を実装します。

- validateメソッド
- NG_VALIDATORSをDIする
 
### validateメソッドを追加する
標準のバリデーションルールを使う場合は以下のように実装します。

```
validate(ctrl: AbstractControl){
    return Validators.required(ctrl);
  }
```
自分でバリデーションルールを作る場合には、以下のように実装します。validの場合はnullを返し、invalidの場合はObjectを返します。Objectのkey名は自由です。

```
  validate(ctrl: AbstractControl){
    if(ctrl.value){
      return null;
    }else{
      return {required: true}
    }
  }
```

### NG_VALIDATORSをDIする
valueAccessorの時と同様にproviderを設定する

```
{
  provide: NG_VALIDATORS,
  multi: true,
  useExisting: RequiredTextComponent,
},
```

ここまでのDEMO
https://stackblitz.com/edit/angular-custom-form-control-k-dby8bo

## エラーメッセージを表示する
エラーメッセージを表示する場合には、コンポーネントに設定されているFormControlにアクセスできるようにする必要があります。


```
 constructor(@Self() public controlDir: NgControl){
    controlDir.valueAccessor = this;
    control.setValidators(this.validate);
    control.updateValueAndValidity();
  }
```
これはproveiderにNG_VALUE_ACCESSORとNG_VALIDATORSをDIしているのと同じことを行っています。
そのため、providersに設定した部分は外します。
ちなみに、NgControlはNgModelやFormControlNameのスーパークラスです。

``` .js
/* providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: RequiredTextComponent,
      multi: true,
    },
    {
      provide: NG_VALIDATORS,
      multi: true,
      useExisting: RequiredTextComponent,
    },
  ],
*/
```

次にView側でcontrolを使ってエラーメッセージを表示させます

```
<input type="text" #input 
  (input)="onChange($event.target.value)" 
  (blur)="onTouched()" 
  [disabled]="disabled" 
  [ngClass]="{error: controlDir && !controlDir.control.valid}">
<div class="error" 
  *ngIf="controlDir && !controlDir.control.valid">
    This field is invalid.
</div>
```

## おわりに
カスタムフォームを作る方法は以上です。
これを応用としてradioボタンを作ったれいネストしたフォームを作る方法を次回書こうかと思います。

- ~~標準のinputなどのフォームと同様の使い方ができること~~
- ~~入力必須のバリデーションが行われること~~
- ~~未入力の場合にエラーメッセージを表示されること~~


ここまでのDEMO
https://stackblitz.com/edit/angular-custom-form-control-k-c6htnz
PHPでインスタンスを生成するのにどのぐらい時間がかかるか？


データ移行用のスクリプトをPHPで作成していて、移行するデータの変換で何万回も呼び出されるメソッドがあったんですが、リファクタリングしてそのメソッドから別クラスを呼び出すようにしました。

で気になったのが、メソッドが呼ばれる度にそのクラスインスタンスを都度生成するのって遅くなるんじゃ無いかってコトでした。

クラスを new するたびに何かしら実行されるんだから、その分遅くなるのは当然として、それでどのぐらい遅くなるのかが気になりました。

インスタンス生成に結構時間かかるなら、シングルトンにするとかどこかであらかじめ生成したのを渡して呼び出すようにするとか工夫がいるかも？っておもったんですね。

というわけで実験。

# コンストラクタの無いクラス

最初の実験はコンストラクタの無いクラスの生成時間測定。

下記コードで同じクラスのインスタンスを100万回生成してからmain()を呼び出すのと、あらかじめ1回生成しておいて100万回main()を呼び出すだけのケースで比較。

```php
class NoConstructor
{
	public function main() {
		return date('YmdHis');
	}
}


$start = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
	$obj = new NoConstructor();
	$result = $obj->main();
	unset($obj);
}
$end = microtime(true);
$time = $end - $start;

var_dump($time);

$start = microtime(true);
$obj = new NoConstructor();
for ($i = 0; $i < 1000000; $i++) {
	$result = $obj->main();
	//unset($obj);
}
$end = microtime(true);
$time = $end - $start;

var_dump($time);

```

結果は、100万回生成&main()実行のケースで __3.40秒__ 。
1回だけ生成して100万main()実行のケースで __3.08秒__ 。

100万回の生成をしても 0.38秒しか余分に時間かかってません。
これだったら無理にシングルトン化するとかしなくても良さそうです。

# コンストラクタがあるクラス

次にコンストラクタがあるクラスで同様の計測をします。

```php
class UseConstructor
{
	private  $value = null;
	public function __construct() {
		$this->value = date('YmdHis');
	}

	public function main() {
		return $this->value;
	}
}

$start = microtime(true);
for ($i = 0; $i < 1000000; $i++) {
	$obj = new UseConstructor();
	$result = $obj->main();
	unset($obj);
}
$end = microtime(true);
$time = $end - $start;

var_dump($time);

$start = microtime(true);
$obj = new UseConstructor();
for ($i = 0; $i < 1000000; $i++) {
	$result = $obj->main();
	//unset($obj);
}
$end = microtime(true);
$time = $end - $start;

var_dump($time);
```

こっちの結果は
100万回生成が __4.51秒__。
1回だけが __1.30秒__。

コンストラクタでの処理が重くてメソッドの実装が軽いようなケースではハッキリ差がでますね。

というわけでコンストラクタが無ければあまりインスタンス生成の処理時間を気にしなくても良さそうでした。
Laravel でサードパーティライブラリのconfigを上書きする方法

このライブラリの
https://github.com/kristijanhusak/laravel-form-builder

これを弄りたくなったけど方法が分からなくて調べた結果
https://github.com/kristijanhusak/laravel-form-builder/blob/master/src/config/config.php


```shell

php artisan vendor:publis
``` 

を叩くと下記の候補が出る

![スクリーンショット 2018-07-17 13.33.48.png](https://qiita-image-store.s3.amazonaws.com/0/131778/8b883629-bdb3-0799-aa00-d9f9f60a9fb0.png)

好きなの選ぶと 上書き可能なファイルがconfigだとかviewとかに作られたりする

（ここに定義されてる奴が作られる模様）
https://github.com/kristijanhusak/laravel-form-builder/blob/2f14ed5736eeb1750530f2a01fa9eeca7c58ad61/src/Kris/LaravelFormBuilder/FormBuilderServiceProvider.php#L79-L82

もともとSymfonyしてた身としてはFormをフルスクラッチで作成するのが辛かったので [FormBuilder](https://github.com/kristijanhusak/laravel-form-builder) を使ってみてる。大体は同じだけど若干機能が弱い:cold_sweat:
CEKの俺的セットアップ

# はじめに

CEKに限らず、何かアプリを作り始める時はだいたい同じ作業をするのでメモにしておきます。
備忘録ってやつです。

ここで使ってるSDKは自作のやつなんですが、せっかくなので使い方書きました。
https://qiita.com/imajoriri/items/1b919b923246e69fe86e

# 環境

* Node.js 8.10以上
* Lambda使います。
* API Gateway使います。


# ディレクトリ作成

```
$ mkdir my-app
$ cd my-app
$ npm init
```

# 必要なものインストール

```
$ npm install --save love-clova clova-signature
$ curl -O https://clova-cek-requests.line.me/.well-known/signature-public-key.pem
```

# 初期設定

いくつかファイルを作成します。

```
node node_modules/love-clova/script/init-original.js
```

`exports.handler`内を以下に変更

```js:index.js
exports.handler = async function(event, content){

  var headerSignature = event.headers.signaturecek || event.headers.SignatureCEK;
  var params = {
    keyPath: './signature-public-key.pem',
    applicationId: "applicationId",
    requestBody: event.requestParameters,
    headerSignature: headerSignature,
  }
  sig.verify(params);

  clova.extensionBuilders.addRequestHandlers(
    LaunchRequestHandler,
    SessionEndedRequestHandler,
    ClovaGuideIntentHandler,
  )
    .addErrorHandlers(errorHandler)
  return clova.extensionBuilders.invoke(event.requestParameters)
  //return clova.extensionBuilders.invoke(event)
}
```

# API Gateway

マッピングテンプレート`application/json`を以下に変更

```
{
  "headers": {
#foreach( $key in $input.params().header.keySet() )
    "$key": "$input.params().header.get($key)"#if( $foreach.hasNext ),#end
#end
  },
  "requestParameters": $input.json('$')
}
```
Growiのログイン認証をldapにする

Centos7.5で構築したGrowiの認証をldapに切り替えるまでのメモ。

# 目的
Growiを構築してみたのですが、調べてみるとログイン認証は下記のようにいくつか選択できるようだったのでベーシック認証からPassport認証機構にあるldap認証に切り替えてみました。

* Passport 認証機構 (推奨)
    * LDAP 認証
    * Google OAuth2 認証
    * GitHub OAuth2 認証
    * (TBD) ~~Facebook OAuth2 認証~~
    * (TBD) ~~Twitter OAuth 認証~~
* Crowi Classic 認証機構

# 環境

| OS | centos7.5 |
|:-:|:-:|:-:|
| Growi | v3.1.9 |
※ldap環境は別サーバにて立てていることが前提です。

[Growi](https://github.com/weseek/growi.git)

# やること
以下の３つ

* ログイン認証をPassport認証機構にする
* 必要なldapの情報を記述する
* ログインテストを行い、正しくログインできるか確認する

**設定**
-------------

## __1. 認証機構の切り替え__
管理者でログインし、メニューにある管理ボタンを押します。
<img width="1207" alt="スクリーンショット 2018-07-17 11.49.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/43574/00e5a0fb-29da-2e30-6ed6-20df82ec634f.png">

出てきた画面のサイドバーにあるセキュリティ設定を選択します。
<img width="309" alt="スクリーンショット 2018-07-17 11.49.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/43574/4845998f-bee1-6dbb-7c51-6bf792fcf331.png">

Passport認証機構が選択されているかチェックし、変更があれば更新を押します。
<img width="951" alt="スクリーンショット 2018-07-17 11.49.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/43574/22fe5d13-37f0-947d-4f30-f69cd606e560.png">
Growiでは、デフォルトでPassport認証機構が選択されているようなので特に選択は必要ないと思いますが、選択されていなければ手動で選択して更新ボタンを押して下さい。

## __2. ldapの情報を記述__
[USE ldap]をONにします。
その後、以下の最低限の情報を記述します。

- Server URL
- Bind DN

<img width="726" alt="スクリーンショット 2018-07-17 12.42.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/43574/030540fe-79b8-849c-5911-bbed78153218.png">

私の環境では、「User Bind」では認証が通らなかったため、「Manager Bind」に変更して「Bind DN」のuidを抜いて記述したらテスト通りました。

また以下の２つは、オプションなので特に記述しませんでした。

- Attribute Mapping
- グループ検索フィルター

## __3. ログインテスト__
入力した設定が正しいかテストします。
ldapに登録したユーザを入力して、以下のように成功メッセージが出力されれば終了です。
<img width="595" alt="スクリーンショット 2018-07-17 11.26.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/43574/f5c09ddc-9c48-8292-b300-88ad9c125348.png">

## 参考
[最強のWiki「GROWI(旧crowi-plus)」で LDAP 認証を設定する](https://qiita.com/yuki-takei/items/a707233b47cd03338605)
[GROWI、CROWIでWindowsのADとLDAP連携する設定手順](http://forfreeworld.com/archives/51966335.html)
E2Eテスト環境を改善することでテストの安定性を高めた話

# はじめに
この記事は、以下の記事の後日談です。
[E2Eテストの導入から学んだこと](https://qiita.com/mt0m/items/7e18d8802843d9f60d28)
このときからかなり時間が経ち、弊チームのE2Eテストも改善してきたので、それについて書きます。

本記事では、具体的な設定方法は言及せず、ドキュメントのリンクを添付します。
E2Eテストを実施していない方、CIを導入したことのない方が、
E2EテストとCIの連携でどのようなことができるかを知るきっかけになればと思います。

# 環境
言語：Node.js
ライブラリ：WebdriverIO,Mocha
OS：MacOS, Amazon Linux
ブラウザ：Google Chrome, FireFox
ソース管理：GitHub Enterprise
CI：CircleCI Enterprise

# TL;DR
E2Eテストを定期実行・並列実行しました。
これにより、

* 不安定なテストを洗い出し改善したことで、テストの安定性が上がりました。
* リリース作業時間が30分近く短くなりました。


# 改善ポイント
前回の記事で対策案や、今後の展望を挙げたので、その中で改善したことについて書いてきます。

[つらいポイントと今後の対策案](https://qiita.com/mt0m/items/7e18d8802843d9f60d28#%E3%81%A4%E3%82%89%E3%81%84%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%A8%E4%BB%8A%E5%BE%8C%E3%81%AE%E5%AF%BE%E7%AD%96%E6%A1%88)

## CircleCIを並列実行することでテストの実行時間を減らした
> テストの実行時間が長い

という問題点に対し、CircleCIの機能でコンテナを並列実行しました。
これにより従来と比較し、約1/3の時間でテストを実行できるようになりました。
https://circleci.com/docs/2.0/parallelism-faster-jobs/
並列実行時は、テストデータを共有しないよう工夫が必要です。

## テストケースを地道に改善した
> テストが安定しない
> リダイレクトが多くて失敗していた

という問題に対し、定期実行後によく失敗するテストについて、チームメンバーがテストケースの改善をおこないました。
定期実行することで、どのようなテストが落ちるのか、どのくらいの確率で落ちるのか計測しやすくなります。

## テストケースごとにアカウントを分けた
> テストケースでアカウントを共有していた

という問題に対し、テストケースと環境（dev,stg）ごとにアカウントを分離しました。
これにより、テストを並列実行できるようになりました。

## フィードバックサイクルを整備した 
> フィードバックサイクルができていない

という問題に対し、CircleCI、GitHub、Slackと連携しました。
これにより、テストを定期実行しその結果をSlack通知できるようになりました。
CircleCIの定期実行方法は以下のドキュメントを参照ください。
c.f. https://circleci.com/docs/2.0/configuration-reference/#schedule
![image.png](https://qiita-image-store.s3.amazonaws.com/0/108210/ef41fe5c-eec4-11f1-6ed4-23c83ef87c3d.png)

# 「今後の展望」のその後
以下、[今後の展望](https://qiita.com/mt0m/items/7e18d8802843d9f60d28#%E4%BB%8A%E5%BE%8C%E3%81%AE%E5%B1%95%E6%9C%9B)についてのその後の様子です。

## テスト結果のSlack通知
上記のように、テスト結果をSlackに通知しています。
通知には[slack-node](https://github.com/clonn/slack-node-sdk)というライブラリを使っています。

## ChatOps化

これを書いたのは、エンジニア以外でも任意のタイミングでテスト結果を知りたいという目的でした。
しかし、テストを定期実行するようになったことで、短い間隔で誰でもテスト結果を知ることができるようになりました。
よって、今のところは実施していません。

## テストケースのグループ分け

クリティカルなテストケースにはmochaの`@smoke`タグを付け、毎時スモークテストしています。
c.f. https://github.com/mochajs/mocha/wiki/Tagging


# まとめ
以上のように、E2Eテストを定期実行・並列実行しました。
これにより、以前はリリース前にE2Eテストを実行していたのですが、定期実行の導入後はリリース時にその結果を確認するだけでよくなりました。
また、定期実行することで不安定なテストを洗い出すことができました。これによってテストの安定性が高まりました。

ポイントとしては、[以前の記事](https://qiita.com/mt0m/items/7e18d8802843d9f60d28#%E3%83%95%E3%82%A3%E3%83%BC%E3%83%89%E3%83%90%E3%83%83%E3%82%AF%E3%82%B5%E3%82%A4%E3%82%AF%E3%83%AB%E3%82%92%E6%95%B4%E5%82%99%E3%81%99%E3%82%8B%E3%81%AE%E3%81%8C%E9%81%85%E3%81%8B%E3%81%A3%E3%81%9F)でも言及していますが、開発の早い段階でフィードバックサイクルを整えることです。
今回の記事が、E2Eテストの実施に時間がかかったり、テストが安定していない方の参考になれば幸いです。
メモ: RaspberryPI 3B(+) で消費電力を抑える? (あまり実用的ではないかも)

# 序

ラズパイ2B以降は2.4A 電源が必要となって悩んでいる方は多いかと思います。
そんななか、[このような興味深い記事](https://rabbit-note.com/2017/04/29/raspberry-pi-3-model-b-power-save/)を発見したので、
自分でもちょっとだけ確認してみた。

# 上記リンクの方法を試すことができる人

- 3B以降のラズパイ限定
- 実行確認出来たディストリビューションは Raspbian のみ(流石純正OS)
    - つまり、32bit OS でいい、という人限定になりますね・・・
- WiFi 環境が整っていて、wpa_supplicant の設定も完了済み
- SSH で接続できれば問題ない、という利用方法を実践している人

上記すべてを満たす人以外、実行してはいけません。

# 上記リンクで行っていることの概要

- USB端子への給電をカットする（USBバスパワーの無効化,これは効果絶大っぽい）
- HDMI端子への出力を無効化(結構効果大の模様)
- その他の方法も提示されているが、前者2つに比べたらあまり効果はなさそうなので割愛

# メリット・デメリット

##  メリット

消費電力が大幅に抑えられる

## デメリット

<dl>
<dt>eth0 ( 有線LAN )と USB接続の周辺機器が無効化される</dt>
<dd>デバイスツリーを見ると、ラズパイのネットワークコントローラはUSBコントローラにぶら下がっているので(=USB-LAN デバイスが基板上に実装されている状態)、USB給電をカットすると、当然有線LAN自体も無効化されます。他方、3B以降に搭載されているオンボード WiFi デバイスはSDカードリーダのコントローラ（MMCデバイス）経由となっているため、USB給電をカットしても問題なく稼働します。従って、3B 以降でオンボード WiFi 環境を適切に設定,安定稼働する状況にあれば、eth は無くてもネットワークに接続できるわけです。2Bでこの操作を行ってしまうと、ネットワークはおろか、USBキーボードもマウスも、シリアルケーブルもWiFi / Bluetoothドングルもダメになるので、GPIO 経由でなにがしかのインターフェイスが接続されていなければ、「電源を引抜くまで、どこからも誰からも全く操作不能な、Linux が稼働している基板」が一時的に出来上がりますね('ω')</dd>

<dt>画面/HDMI経由のサウンドも無効化される</dt>
<dd>まあ、当然そうなりますよね。ただ、こちらは2Bでも利用可能ですから、モニタに接続していないラズパイでは積極的に使っていきたい手法ですね。</dd>
</dl>

電子工作主体の人は積極的に使って行ってもいいでしょうけれど
常時稼働鯖を運用、という方向の人だとこの手法の実効性はちょっと疑問符が付きますね・・・
ということで、HDMI の出力抑制だけ、私の環境でも実施したいと思います。
Laravel5.6 メール送信機能の作成方法

## やりたいこと

Laravelでメール送信機能を実装する方法について記載します。
コントローラーで作成したメーラーを呼び出し、メールテンプレートにデータを反映させて送信する。

例として、`ContactController`というコントローラーがあり、お問い合わせ機能のようなものがあったとして、進めます。


## 環境

* PHP 7.1
* Laravel 5.6

## 参考

[MailtrapでLaravelの簡単メール送信テスト](https://qiita.com/ubonsa/items/5514fb9c5d5783bcc758)こちらを参考にメール送信機能を実装し、テストメールを送ることをゴールとします。
@ubonsa さんわかりやすい記事をありがとうございます:bow_tone2:

以下の内容は上記記事で[Mailtrap](https://mailtrap.io/)のアカウント作成が終わり、`.env`ファイルも書き換えていることが前提となります。

## 1. ContactController

フォームがあり、送信ボタンがあると、`store`アクションが実行されると仮定します。
送られてくるパラメーターは以下とします。

送信者 | メールアドレス | 内容
----- | ---------- | ---
name | email | body

`ContactController`

```php
public function store(Request $request){
  // フォームからのリクエストデータ全てを$contactに代入
  $contact = $request->all();
}
```


## 2. メールクラスを作成

```
$ php artisan make:mail ContactMail
```

上記コマンドを実行すると、`app/Mail`に`ContactMail.php`ファイルが作成されます。

`app/Mail/ContactMail.php`

```php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class ContactMail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('view.name');
    }
}
```

## 3. ContactMail.phpを編集

フォームから受け取ったリクエストデータをテンプレート内で展開させたいので、`ContactMail.php`を編集します。
`app/Mail/ContactMail.php`

```php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class ContactMail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    // 引数で受け取ったデータ用の変数
    protected $contact;

    public function __construct($contact)
    {
      // 引数で受け取ったデータを変数にセット
      $this->contact = $contact;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this
          ->from('hoge@hoge.com') // 送信元
          ->subject('テスト送信') // メールタイトル
          ->view('contact.mail') // どのテンプレートを呼び出すか
          ->with(['contact' => $this->contact]); // withオプションでセットしたデータをテンプレートへ受け渡す
    }
}
```

## 4. テンプレートを作成

`->view('contact.mail')`と上記で定義を行なったのですが、これは`resources/views`からのパスとなっているので、`resources/views/contact/mail.blade.php`というようにファイルを作成します。

```php
こんにちわ{{$contact->name}}さん
問い合わせ内容は以下で受け取りました
{{$contact->body}}
```

## 5. ContactControllerを編集

```php
// 作成したメールクラスをuseする
use App\Mail\CotactMail;
use Illuminate\Support\Facades\Mail;

public function store(Request $request){
  // フォームからのリクエストデータ全てを$contactに代入
  $contact = $request->all();
  Mail::to($contact->email)
            ->send(new ContactMail($contact)); // 引数にリクエストデータを渡す
}
```

> 自分の環境下では`Mail`ファサードがnot foundとエラーとなったので、`use Illuminate\Support\Facades\Mail;`を加えています。


以上で、フォームからメール送信を行えばリクエスト内容を反映させたメール送信機能が出来るかと思います。
X68000 XVI > 電源基板 > R24 > 回路図には記載はあるが未実装 > 回路図が古い? > 実はシルクパターンが２つあった

```txt:動作環境
X68000 XVI
```


### 資料

- SHARP サービスマニュアル X68000 パーソナルコンピュータ CZ-634C-TN, CN-644C-TN
    - COCORO Booksにて閲覧可能

@ サービスマニュアル
p97 22. 電源基板基本配線図
p99 23. 電源基板

「電源基板基本配線図」の方は回路図のようだ。
「電源基板」の方では、基板の実装パターンが閲覧可能。

### 基板

下記は手持ちのX68000 XVIの電源基板を取出したところ。

![IMG_1209.JPG](https://qiita-image-store.s3.amazonaws.com/0/32870/18e9c2dc-ad1d-6c95-9324-72bf98dd93fc.jpeg)

左下の3つの大きな電解コンデンサ(105℃品?)の右下に「R24」の表記があるが、抵抗は実装されていないようである。

### 回路図のR24

@ サービスマニュアル
p97 22. 電源基板基本配線図
にはR24の記載がある。

T1(トランス)からD27(FMB-33S)を通り、電解コンデンサ2つの後ろにR24(470Ω、1/6W)として記載がある。

### 他の人の情報

- [X68000レストア情報室](http://retroexp.mankai.jp/restore_CZ634CTN_1.html) by 田辺敦司様
    - 6枚目の写真に電源基板が示されている。
    - ここでも左下のR24は未実装のようだ。
- [X680x0電源修理パーツセットについて](http://ixsvr.dyndns.org/pow_parts) by yuno様
    - 「X68000 電源パーツリスト」のリンクにはR24も掲載されている
        - R24(470Ω、1/6W)
- [X68kXVI HDの電源リペア](https://ameblo.jp/framgate/entry-12030385104.html) by Fram様
    - 「電源基板修理後」の画像ではR24は未実装

各位、情報感謝です。


### 修理の方針

実装していたICを交換する。

未実装のICは回路図に記載があったとしても、そのままとする。

回路図が古いのかもしれない。

### ２つのシルクパターン
(追記 2018/07/28)

基板を確認しているとR24に関して２つのシルクパターンが見つかった。

- A. D27の左型のR24: 点線の大きめの長方形
- B. C42の上のR24: 実践の小さめの長方形

Bの方のR24は回路図とも整合性がありそう。
Rundeck の実行ログを削除する

## Rundeck の実行ログを削除する
一部で OSS のジョブ管理ツール [Rundeck](https://www.rundeck.com/open-source) を使っているのですが、過去の実行結果を残しておく用途が無いのと、~~ディスクサイズがカツカツなので、~~ 週次で実行ログを削除するジョブを動かしています。

Rundeck の [API リファレンス](http://rundeck.org/docs/api/) を読めば誰でも出来るんですが、もっと効率がいい方法があれば教えてもらいたいなぁ、と考えているので、うちでのやり方を公開します。

## 詳細
### Token の取得
下記のスクリプトでトークンを取得し「.rundeck_token」というファイルに Token を残します。
トークン取得の API を実行すると xml が返ってくるので、awk と sed を使って、Token だけ抜き出してます。

```bash:
#!/bin/bash

OLD_TOKEN=~/.rundeck_token
TMP_XML=/tmp/rundeck.xml
RUNDECK_URL="http://xxx.xxx.xxx.xxx/rundeck/api"
RUNDECK_AUTH_TOKEN="X-Rundeck-Auth-Token"

if [ -e ${OLD_TOKEN} ]; then
  GET_TOKEN=`cat ${OLD_TOKEN}`
else
  GET_TOKEN=$RD_OPTION_DEF_TOKEN
fi
echo "current token: ${GET_TOKEN}"

echo "get new token"
curl -s -X POST -H "${RUNDECK_AUTH_TOKEN}:${GET_TOKEN}" -H 'Content-Type:application/json' -d "{"user":"hoge", "roles":"*","duration":"30d"}" ${RUNDECK_URL}/11/tokens -o ${TMP_XML}
NEW_TOKEN=`xmllint --xpath "token" ${TMP_XML} |awk '{print substr($0, index($0, "id="))}' |sed -e 's/id="//g' |sed -e 's/"\/>//g'`
echo "new token: ${NEW_TOKEN}"
rm -rf ${TMP_XML}

if [ -e ${OLD_TOKEN} ]; then
  echo "delete current token"
  curl -s -X DELETE -H "${RUNDECK_AUTH_TOKEN}:${NEW_TOKEN}" ${RUNDECK_URL}/11/token/${GET_TOKEN}
fi
echo ${NEW_TOKEN} > ${OLD_TOKEN}
```


### 実行結果削除 API の実行
上記で生成した Token を使って、[この API](http://rundeck.org/docs/api/#delete-all-executions-for-a-job) を呼び出しています。
"$RD_OPTION_TGT_UUID" は、↓で説明しますが、削除対象の UUID を受け取っています。

```bash:
#!/bin/bash

TOKEN_FILE=~/.rundeck_token
RUNDECK_URL="http://xxx.xxx.xxx.xxx/rundeck/api"
RUNDECK_AUTH_TOKEN="X-Rundeck-Auth-Token"

if [ -e ${TOKEN_FILE} ]; then
  GET_TOKEN=`cat ${TOKEN_FILE}`
else
  GET_TOKEN=$RD_OPTION_DEF_TOKEN
fi

echo "delete uuid ${RD_OPTION_TGT_UUID}"
curl -s -X DELETE -H "${RUNDECK_AUTH_TOKEN}:${GET_TOKEN}" ${RUNDECK_URL}/12/job/${RD_OPTION_TGT_UUID}/executions
```

### UUID の渡し方
上記の削除 API には、対象 Job の UUID が必要となります。
下図のような感じで、削除 API を別 Job にして、UUID を渡してあげるような仕組みにしています。
![Rundeck   Edit Job.png](https://qiita-image-store.s3.amazonaws.com/0/269938/31a899f5-f7fb-21a3-ad51-c477043388f8.png)

## 悩んでいる点
もっといいやり方無いですかね？
特に UUID 周り。Job の増減がある度に、変更が必要になるので面倒。。。

## 仲間募集中
[弊社](https://www.nittsu-infosys.com/)ではエンジニアを募集中です。インフラからアプリ、ユーザサポートまで幅広く業務を行ってます。
https://www.nittsu-infosys.com/recruit/2019/index.html
tmuxを使ってサーバーにタスクを投げる

# サーバーから切断しても計算を続けてほしい!
という思いからこの方法を探してきました.
本当は```qstat```とか```qsub```とかを用いて管理したいのですが,
あまり知識がありませんでしたので, もう少し簡単に使えるtmuxを選びました.

以下はサーバー内にsshで接続した状態で行ってください.

# インストール
ご自身のディストリビューションでのパッケージマネージャーにあれば簡単です.
僕はArchLinuxでしたが, pacmanにありました.

```
   sudo pacman -S tmux
```

# セッションの立ち上げ
まずはtmuxを実行します

```
   tmux
```

すると, 仮想端末が立ち上がります.

ここで実行したい計算をいつも通り実行してあげるだけで大丈夫です.

# 仮想端末に名前を付ける
作成した仮想端末に名前を付けることができます
**Ctrl-b + $**と入力すると端末名を入力できるようになりますので,
任意に名前を付けてEnterを押してください.

# 仮想端末から抜けるコマンド
先程開いたtmuxの仮想端末から抜けるには **Ctrl-b + d** と打つだけです.
そうすると普段の端末に戻ってきます.

# 仮想端末の確認
次のコマンドを実行すると, tmuxで今何の仮想端末が開いているのかが確認できます.

```
   tmux ls
```

もう一度入りたい場合は次のように打ってください

```
   tmux a -t <session-name>
```

# 最後に
これで家で寝ている間にも計算を回してくれるようになりました!
iReportで帳票修正をしてJPiereで確認する流れの中で困ったところ

#はじめに

1行目から蛇足になるのですが、JPiereのタグが無かったので念のために書いておくと、JPiereはiDempiereを日本の商習慣に対応させたモノ**らしい**です。詳しくはJPiereのHPをご覧ください。

私がやったこととしましては、iReportで既存帳票の細々とした修正をしたり、JPiereでサンプルデータを入れてみたり、帳票を出して見たり、ということです。
今回、iReportではSQLによりデータを取得しています。

iReportもiDempiereも触るのが初めてでしたので、作業をしていると所々で不明点が出てきました。

ですが、検索しても解決方法は出てきませんでした。
そこで、書いておかないと**私がすぐに忘れてしまう**ため、実際にやってみて分からなかったこと、分かりにくかったことを、**今、覚えているだけ**書いていきたいと思います。

また、作業をするにあたり参考にした投稿はこちらの二つです。

- @taku_0115 様
    - [iReportをWindows10に導入する](https://qiita.com/taku_0630/items/e1eee9d0a93ca4d1089f) 
- @Ky0ich1 様
    - [Jasperレポート作り方 ~iReport(基本編)~](https://qiita.com/Ky0ich1/items/f158219812e772c673a7#ireportdesigner%E3%81%A8%E3%81%AF) 



#iReportで困ったところ

iReportで行った修正としては、フィールドの内容変更、位置の変更です。

- iReportでは、どこにどのような内容を載せるのかという範囲が定まっており、項目はこれを超えて配置すると怒られます。なのですが、一旦配置したものをカーソルキーで移動させたり、プロパティを弄ったりすると怒られません。(なぜかは不明)
できればしないべきですが、帳票の見た目的にどうしてもそこでなければならない時に使用せざるを得ませんでした。

- しっかり表示できる範囲を指定しているのに、表示されない場合がありました。結果としてはSQLが違うだけでした。表示ができるはずなのに出来ないときは、SQLを疑ってみてもいいのかもしれないと思いました。動的データはDBから取ってきているため、SQL文がおかしいと表示がされなくなったりします。
    - この時にSQLを見ていなくて、結構悩みました……。

- 下線などの記号を入れたい場合(文字に下線を引きたい場合とかではなく、ただそこに線を表示したい時)はStaticTextで入れることができます。ただ、表示範囲を狭くしすぎると表示がおかしくなるため、適度に余裕を持たせて置かないとダメかもしれません。
    - 書いている時に気が付きましたが、Lineを使っても良かった……？ >>修正なので考えないことにします。

- TextField、StaticTextの一つの範囲の中に複数のデータを入れることが可能です。その際は、文字列連結のように、＋演算子で繋げていきます。
これは複数のフィールドを重ねた時に表示がおかしくなったりする場合に有効です。注意としては、それらのプロパティが共通になるということです。

- 修正したモノがそのまま表示されるわけではないことに注意したい。「結構間を空けたし、きっと出力した時も空いてくれるだろう！」なんていう考えで修正すると全然空いてなくて絶望したりする。きっとJasperレポートの気分次第。**小まめに確認しよう**と思いました。



#JPiereで困ったところ

JPiereはiDempiereで検索しても、JPiereで検索しても、まともに参考になるサイトが見つからなかったので特に大変でした。バグっぽいものがあったり、iDempiereと全然違う箇所があったりするので、深く考えずに触ったほうがいいかもしれないと感じました。

- 基本的に不明点としてあったのは、どこにどの項目があるのか分からないという点です。これについては、検索をかけて出てこなければ諦めて項目を追いかけるしかありませんでした。子タブをズームしていくと見つかるパターンが多かったように思います。

- 帳票には流れがあるため、何かの帳票を元にして、帳票を作成することができます。この時に、元となる帳票が完成になっていないといけない場合や、特定の値が入っていないといけない場合があったりします。元にして作成するときは、その帳票には何が必要になるのかというところを理解しなくてはいけないようです。
    - つまるところ、帳票がどのような流れで作られていくべきなのかを理解していれば困ることもなかった。

- 時にJPiereは分かりづらい項目がありました。例えば、「取引先担当者」と「取引先担当者(ユーザー)」です。これらは一見同じようですが、別物と見てもいいかもしれません。例えば、受注伝票を作成しているのであれば、取引先担当者はすぐ近くの項目ですが、確認したい項目は取引先担当者(ユーザー)にあり、それは取引先の子タブだったということがありました。

- 私が行っていたJasperファイルのアップロードは、レポートとプロセスから差し替えたい帳票を探すところから始まりました。差し替えたいファイルを見つけたら、添付ファイル(クリップのようなマークのところ)から差し替える以前のJasperレポートを削除してからアップロードします。こうしないと、ファイル名が同じでも2つファイルが出来てしまっておかしくなるみたいです。

- DBのカラムがどこに使用されているのか確認する時の手順は、Systemユーザでログインした後、テーブルとカラム＞DBテーブル名称等で検索＞子タブのカラムにズーム＞見たいカラムを選べば、子タブに使用しているフィールドというものが存在しています。




#おわりに

以上が私が作業をしてみて困ったところです。まとめる力が足りずにだらだらと書くだけになってしまって申し訳ないです。さらに、振り返ると単純に仕様を理解していないだけの気もします。とはいえ、実際分かりにくかった(参考に出来るものが無かった)ことは確かだと思います。もう少し商業(？)に詳しければ迷わないのかもしれないと思いました。

あと、iReportのパレットやらなんやらの諸々の表示がめちゃくちゃ小さいのは結局直りませんでした。
D415/D435をROSで使用する環境を５分で構築する

#　はじめに

Dockerがインストールされているものとして、
RGBDカメラであるIntel Realsense D415/D435をROSで使用する環境を５分で構築する。

Dockerをインストールしていない方は、[こちら](https://docs.docker.com/install/linux/docker-ce/ubuntu/#set-up-the-repository)を参考にDockerをインストールする。

# インストール

基本的にはhttps://github.com/IntelRealSense/librealsenseのinstall手順に従ってインストールする。
https://github.com/IntelRealSense/librealsense/blob/master/doc/installation.md
https://github.com/IntelRealSense/librealsense/blob/master/doc/installation.md#prerequisites

### prerequisites

```
sudo apt install git libssl-dev libusb-1.0-0-dev pkg-config libgtk-3-dev 
```

```/tmp```などにgit cloneしてくる。

```
cd /tmp
git clone https://github.com/IntelRealSense/librealsense
cd librealsense
```

続いてUbuntuのversion特有のインストール作業を行う。

- Ubuntu 14 or when running of Ubuntu 16.04 live-disk:

```
sudo apt-get install
./scripts/install_glfw3.sh 
```

- Ubuntu 16:

```
sudo apt install libglfw3-dev
```

- Ubuntu 18:

```
sudo apt install libglfw3-dev libgl1-mesa-dev libglu1-mesa-dev 
```

### udevにデバイス情報を記述する

```
sudo cp config/99-realsense-libusb.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules && udevadm trigger
```

### kernelが低い場合の対処

librealsenseではkernelのversionが低いと動作しないようなので、kernelを上げるかpatchを上げる必要がある。
実際のロボットなどでは様々な理由があってすぐにはkernelを上げることができないという問題がある。
そこで、ここではkernelのversionを上げずにpatchを当てる方法を説明する。
基本的には下記のコマンドを実行してmodprobeすると見えるようになる。

```
./scripts/patch-uvcvideo-ubuntu-mainline.sh
sudo modprobe uvcvideo
```

# D415/D435のDocker image

https://hub.docker.com/r/iory/docker-ros-d415/
にあるdockerイメージをpullする。

```
sudo docker pull iory/docker-ros-d415:docker.d415
```

# 実行

D415/D435をUSB3.0のポートに挿して、
以下のコマンドを実行すると、PointcloudなどのtopicがROSで見えるようになる。

```
sudo docker run --rm --net=host --privileged --volume=/dev:/dev -it iory/docker-ros-d415:docker.d415 /bin/bash -i -c 'roslaunch realsense2_camera rs_rgbd.launch enable_pointcloud:=true align_depth:=false depth_registered_processing:=true align_depth:=true'
```

![RViz-_003.png](https://qiita-image-store.s3.amazonaws.com/0/25718/7512eca4-0de3-bf79-0c88-39f3a7e08b5a.png)
ldapjsで認証失敗時のハンドリングが結構めんどくさい件


# 失敗の原因判別がつかないのでござる
* 普通にパスワード間違えた場合
* パスワードの期限が切れた場合
* アカウントがロックされた場合


これらの場合はすべて 
` Invalid Credential(49)  `

　　　　　　　　　　　　　　　　　　... 　(´ﾟдﾟ｀)ﾎﾟｶｰﾝ

有識者に聞いてみたら、一応OpenLDAPの作り的には
それで良くて、細かいメッセージは必須ではないそう

# そもそもldapsearchコマンドでも判別がつかない
上記のケースで、ターミナルでldapsearchを叩いても
` Invalid Credential(49)  `
しか出てこない
一方、ldapサーバーにリモートアクセスし、中でコマンド叩くとしっかりメッセージが細かく分かれている

ldapjsのメッセージラッピングがイけてない説を疑っていた自分を悔いつつ、
それじゃあどうしようもないわなと。。。

# 回避策
要は気合を入れてハンドリングすればいいと。
フローして：

```
*前処理*
ユーザーが認証失敗した時、
サーバーで一度管理者でbindし、そのユーザー情報をldapjsのsearch関数取得する

if searchで取れるアカウントのパスワードと実際にユーザーが入力したパスワードが一致する　{
  if pwdAccountLockedTimeという属性値を取得できたら {
       ユーザーアカウントはロックされているので、その処理を行う
     } 
  else {
    ユーザーパスワードは期限切れなので、その処理を行う
  }
} else {
 入力ミスの処理を行う
}
// 先にロック判定などしたほうがいい気もするが、今回はこの分岐にした
```

# sinippet
promiseしてない、サーセン

```js
// client は ldapjsのインスタンス
// ssha は ssha モジュールのインスタンス

  let opt = { attributes: ['pwdAccountLockedTime', 'userPassword'] };
　　client.search(`ユーザー識別子`, opt, (er, response) => {
          response.on('searchEntry', (entry) => {
                 // 一応sshaモジュールのverify関数を使う（ツッコミどころ）
                 if(pwd === entry.object.userPassword || ssha.verify(pwd, entry.object.userPassword)) {
                      if(entry.object.hasOwnProperty('pwdAccountLockedTime')) {
                        console.log('Account locked');
                      } else {
                        console.log('Password expired');
                      }
                    } else {
                       console.log('Invalid Password');
                    }
                    return;
                  });
                  response.on('searchReference', function(referral) {
                        // ...
                  });
                  response.on('error', function(err) {
                        // ...
                  });
                  response.on('end', function(result) {
                        // ...
                  });
                });
```

<font color="gray">
他のハンドリングの仕方や
ldapについて全くわかっていないため、
もしクライアント側での設定でこの問題が解決できるのであれば、
ぜひご教授いただきたいです。
</font>
[Python] Folder作り。

こんにちは
自分整理

# 必要なこと
```python:create.py
import os
```

#ディレクトリ経路

```python:create.py
dir_name = '../output/'
```

# これで

```python:create.py
if not os.path.isdir(dir_name):
    os.mkdir('../output/')
else : 
    result.to_excel('../output/result_01.xlsx')
```
Windowスクロールでふわっと出現するアレ

ブラウザスクロールでふわっと出現する視覚効果をJS単体のみで書きました。
都度書くのは面倒なのでスニペット的な備忘録です。
ちなみにjQueryを使ってます。

```JavaScript
var setTransitionFlg = false;

$(function(){
  $(".effect").each(function(index, element){
    $(element).css("opacity", "0");
    $(element).css("transform", "translate(0, 50px)");
    $(element).css("-webkit-transform", "translate(0, 50px)");
  });
});

$(window).scroll(function(){
  $(".effect").each(function(index, element){
    if (!setTransitionFlg) {
      $(element).css("transition", "all 500ms 0s ease-out");
    }
    var position = $(element).offset().top;
    var scroll = $(window).scrollTop();
    var windowHeight = $(window).height();
    if (position - windowHeight < scroll - 120) {
      $(element).css("opacity", "1.0");
      $(element).css("transform", "translate(0, 0)");
      $(element).css("-webkit-transform", "translate(0, 0)");
    }
  });
  setTransitionFlg = true;
});
```

class="effect" としたところがふわっとなります。

以上