OmniAICreator/Qiita-1.07M huggingface dataset:
初心者の環境構築は仮想環境上がベスト説

Cloud9を卒業して、ローカルで開発環境を構築しようとしている方って結構いると思います。
筆者もその一人ですが、なかなか思ったように動いてくれないことも多々。。
そんな方へ向けた、一つの提案です。

<h2>ホストOS上に構築するデメリット</h2>
そもそもホスト環境と仮想環境って何が違うのか？
こちらにわかりやすくまとまっているので参考にしてみてください。

[5分でわかる「仮想マシン」とは？今さら聞けない基礎・基本を解説](https://boxil.jp/mag/a1300/)

ざっくりホストOS上に環境構築するデメリットをあげると、
ホストOS上のローカル環境には目的のソフトウェア以外のソフトウェアも置かれているわけです。
すると、相互に影響すると何が原因で構築の際にエラーが起こっているのか追いかけにくくなってしまうのです。

エラーメッセージからすぐに理解して解決できるのであればよいのですが、
初心者の場合はわからなかったり、ググって出てきた解決法を意味もわからず試したりすることも多いのではないでしょうか。

<h2>理解していない解決法を試す恐ろしさ</h2>

ホストOS上で操作をしていると、PCの動作そのものに影響するものもあります。
自分で理解していない解決法を試してしまうと、結局別の部分で困ってしまうことになることもあります。
筆者は昔一度BIOSの起動設定を消してしまい大変なことに、、

そんなことになる前に、やはりきちんと理解しながら環境構築できたほうが学習の意味でもメリットは大きいです。

<h2>仮想環境上に構築するメリット</h2>

ずばり、やり直しがきくことです。
仮に設定を間違えてしまっても、最悪もう一度0から作り直すことができます。
ホストOSではこれがそう簡単にはいきません。

エラーが発生した際にも、0から作っているので必然的に原因がシンプルになります。
これならば意味を理解しながらトラブルシューティングできるはず。

<h2>vagrantとは</h2>

ここから本題です。
Vagrantとは、開発環境の構築を簡単に行うためのツールです。
仮想環境の実装を数ステップで可能にし、さらに同じ環境を別のマシンでも再現することが容易になっています。

[開発環境の構築・共有を簡単にするVagrant入門](https://thinkit.co.jp/story/2015/03/19/5740)
[ドットインストール](https://dotinstall.com/lessons/basic_vagrant)にも動画で構築の説明があります。

<h2>インストール</h2>
[Vagrant](https://www.vagrantup.com/)をダウンロード
[VirtualBox](https://www.virtualbox.org/)をダウンロード
それぞれインストール

VirtualBoxのインストールでつまづいた方、こちらを参考にしてみてください。
[Mac OS High Sierra で VirtualBox がインストールできない時は](https://webnetarium.com/howto-install-virtualbox-to-high-sierra/)

インストールが終わったら確認してみましょう。

```terminal:terminal
$ vagrant -v
$ Vagrant 1.8.1
```

<h2>vagrantの初期化と立ち上げ</h2>
vagrantの公式サイト([こちら](https://app.vagrantup.com/boxes/search でインストールするBoxファイルを検索します。))から仮想環境のOSを決めます。
今回はCentOSで作成していきます。

```terminal:terminal
$ vagrant init bento/centos-6.7
$ vagrant up
```

その後起動に成功したらSSHで接続

```terminal:terminal
$ vagrant ssh
```
CentOS7にPostgreSQL8系をインストールする

##はじめに
CentOS7にPostgreSQL8系をインストールしたとき、initdbができず結構ハマったのでメモ

- centos7
- ソースからpostgresqlをインストールする前提

##解決方法
gcc-4.4をインストールする
→CentOS7のデフォルトgccバージョンは4.8で、このバージョンでコンパイルすると、initdbに失敗する
　相性が悪い？？？


##インストール

```
yum install compat-gcc-44
cd /usr/bin
mv gcc gcc48
ln -s gcc44 gcc

#確認
gcc --version
```

これでmakeすればいけるはず
KVM PCIパススルーでCUDA 9.1ぐらいから動かなくなった時の解決策

# 状態
* KVM PCIパススルー(VFIO)でVMにGPUをパススルーして使用していたがCUDA9.1ぐらいから動かなくなった
* CUDAドライバやライブラリの組み合わせは合っている
* 仮想化を使用せず、ベアメタルであれば問題なく動く
* nvidia-smiは通常通り動く
* deviceQueryなどRead系CUDA API？は動く
* 実際に計算等を行おうとすると以下のようなエラーが出る

```
code=46(cudaErrorDevicesUnavailable)
```

# 解決策
## その1: ドライバのバージョンを下げる
調べた結果、特定のバージョン以降のドライバから上記のエラーが出て使えなくなっていた
この状況で手元で動作が確認できたドライバは下記

* CUDA 9.1
    * 387.26
* CUDA 9.0
    * 384.81
* CUDA 8.0
    * 384.66

基盤に触れない場合は上記のバージョンのドライバを使う

## その2: VMのcpu modeをhost-modelにする
ハイパーバイザーでlibvirtを使っていれば、XMLを下記のように書き換える

```xml:before
  <cpu>
    <topology sockets='40' cores='1' threads='1'/>
  </cpu>
```
```xml:after
  <cpu mode='host-model'>
    <model fallback='allow'/>
    <topology sockets='40' cores='1' threads='1'/>
  </cpu>
```

上記を書き換えてdefineしなおして再起動することでVMのCPU modelがQEMU Virtual CPUからハイパーバイザと同じものになる

```bash:before
$ cat /proc/cpuinfo | grep -e model -e flags
model		: 13
model name	: QEMU Virtual CPU version 2.5+
flags		: fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pse36 clflush mmx fxsr sse sse2 syscall nx lm rep_good nopl pni vmx cx16 x2apic popcnt hypervisor lahf_lm vnmi ept
```

```bash:after
$ cat /proc/cpuinfo | grep -e model -e flags
model		: 61
model name	: Intel Core Processor (Broadwell)
flags		: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch tpr_shadow vnmi flexpriority ept vpid fsgsbase bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat
```
これで新しいドライバでも動くようになる
代わりにVMのCompatibilityが下がる(同じCPU modelでないとlive-migrationできないなど)がGPUをパススルーしているVMにはあまり関係ないだろう

# 原因（予想）
* Security Bulletin: NVIDIA Driver Security Updates for CPU Speculative Side Channel Vulnerabilities: 
  https://nvidia.custhelp.com/app/answers/detail/a_id/4611/~/security-bulletin%3A-nvidia-driver-security-updates-for-cpu-speculative-side

VMでうまく動かなくなるあたりのドライバの更新でIntelの脆弱性対応がされている
これでドライバの仕様が変わったのではないかと考えている（PCID必須？）

# おまけ
OpenStackを使っている場合はlibvirtのxmlが書き換えられてしまうので、該当Computeのnova.confを確認する

```:nova.conf
[libvirt]
cpu_mode = host-model
```
VSCodeにおける自動フォーマットで整形が崩れる問題への対処法

# はじめに
最近、AtomからVSCodeに乗り換え中で、その時の記録です。

まず前提として、ESLintやTSLint、Prettierを使用してJavaScriptのコードをlinting、フォーマットするという状況下においての話です。

# 問題
VSCodeで自動フォーマットさせるために最初、以下のように設定を記述したところ、自動フォーマットで整形がうまくいかずに盛大に崩れました。

```json
{
    "editor.formatOnSave": true,
    "prettier.eslintIntegration": true,
    "prettier.tslintIntegration": true
}
```

上記コードだとVSCodeのフォーマッタしか効かないため、整形がうまくいかずに崩れます。
そこで、`"eslint.autoFixOnSave": true`, `"tslint.autoFixOnSave": true`を追加し、ファイルを保存して自動フォーマットしたところ、一回崩れて整形される（画面がチラつきます）という感じになります。
やはり`"editor.formatOnSave": true`が原因のようです。

```json
{
    "editor.formatOnSave": true,
    "eslint.autoFixOnSave": true,
    "tslint.autoFixOnSave": true,
    "prettier.eslintIntegration": true,
    "prettier.tslintIntegration": true
}
```

# 解決策
ですので、以下でのように、`"editor.formatOnSave": true`を削除（false）にすれば、ファイル保存時の自動フォーマットで綺麗に整形されました。
`"editor.formatOnSave": true`と`"eslint.autoFixOnSave": true`が衝突してはいけないということですね。 

```json
{
    "eslint.autoFixOnSave": true,
    "tslint.autoFixOnSave": true,
    "prettier.eslintIntegration": true,
    "prettier.tslintIntegration": true
}
```
オペアンプ回路まとめ

# 目的
オーディオアンプ回路や、センサー・マイコン間のインターフェース回路として度々登場するオペアンプの回路を備忘録として書いていきます。
(回路図はkicadで書きました)

# 反転増幅回路
![反転増幅.JPG](https://qiita-image-store.s3.amazonaws.com/0/272121/b22e901b-7dc1-33fc-7011-772fab700851.jpeg)


```math
Vo ＝ -\frac{R2}{R1} \times Vi
```

・R1とR2によって増幅率が決まる
・入力電圧の正負は反転されて出力される(入力が1[V]なら出力は-1[V])


# 非反転増幅回路
![非反転増幅.JPG](https://qiita-image-store.s3.amazonaws.com/0/272121/50407aa0-df6d-55da-5ee8-fb4903ad6701.jpeg)


```math
Vo ＝ \biggl(\frac{R2}{R1}+1\biggl) \times Vi
```
反転増幅回路の入力電圧 Vi と GND の接続場所が逆になっただけ。

・増幅率は反転増幅回路と抵抗の比率は同じように設定できるけど、1倍以上にしか設定できない
・増幅率は0.1倍みたいに入力電圧を減衰して使えない
・LM358やLMC6482など一部のオペアンプなら単電源で使用できる(必ずデータシートを確認してから使用してください)

![非反転増幅バイアス電流.JPG](https://qiita-image-store.s3.amazonaws.com/0/272121/7593d94d-f670-e857-4f6f-9763fc5f29fb.jpeg)

バイポーラタイプのオペアンプは、上記の様に入力側でコンデンサを接続して直流成分をカットした場合、R3を接続してオペアンプのバイアス電流をGNDに逃がさないと出力が飽和してしまう。
CMOSやJFETタイプのオペアンプを使用すれば電圧駆動なのでR3はいらないはず(未検証なのであくまで予測です)

# 反転加算回路
![反転加算.JPG](https://qiita-image-store.s3.amazonaws.com/0/272121/080ee5a4-3ef2-68ef-9afb-e800f6a9ea94.jpeg)
この回路の出力 Vo は下記の様になる。

```math
Vo ＝ -\Biggl(\biggl(\frac{R4}{R1}\times Vi1 \biggl)+ \biggl( \frac{R4}{R2}\times Vi2 \biggl) + \biggl( \frac{R4}{R3}\times Vi3 \biggl) \Biggl)
```

入力電圧Vi1～Vi3 の各々で増幅して加算する回路になる。
加算したい信号があったらR1～R3にならって 入力信号－抵抗－オペアンプの反転入力端子(2番ピン) のように接続すればいい。
ただし出力は反転する。


# 非反転加算回路
![非反転加算.JPG](https://qiita-image-store.s3.amazonaws.com/0/272121/f1f134da-899a-02f2-6cb0-3c12fd72f37e.jpeg)

```math
Vo ＝ Vi1 + Vi2 \\
※ただし R1=R2=R3=R4 の場合
```

この回路の抵抗値は全て統一しないとちゃんと電圧を加算してくれない。
ちなみに抵抗値を統一しない場合は下記の様になる。

```math
Vo ＝  \Biggl( \frac{R4}{R3}+1 \Biggl) \times \Biggl( \frac{R1\times Vi2 + R2\times Vi1}{R1+R2} \Biggl)
```

この様に増幅率を考えるのが面倒になるので抵抗値を統一したほうが無難だと思う。

# まとめ
初めてなりにまとめてみましたが、伝わる文章を書くのはやはり難しかったです(主に見るのは自分ですが...)。

この他にも差動増幅回路や定電流回路などがたくさんありますがまた後日書いていく予定です。
ViewControllerのinit処理ができなかった昔の僕へ



ViewControllerのinit処理みなさんどうしていますか？
僕はだいぶイケテナイ呼び出しをしていたので、ちょっとまとめてみました。


# 1.viewControllerの呼び出し
ViewControllerって当たり前だけど呼び出したいですよね。
例えばユーザー画面とか作る時、こんな書き方をしてみました。

```swift
        let viewController = UserViewController()
        viewController.userId = userId
        self.navigationController?.pushViewController(viewController, animated: true)
```

```swift
class UserViewController: UIViewController {
    var userId:Int?
      override func viewDidLoad() {
        super.viewDidLoad()
        //userを呼ぶAPIをかく
      }
  
}
```

これでも動くは動くんですよ。



# 2.動くならいいじゃん何がダメなの?
例えば他でもユーザー画面に遷移したい！！って思った時

```swift
        let viewController = UserViewController()
        //viewController.userId = userId
        self.navigationController?.pushViewController(viewController, animated: true)
```
これでもビルド通るんですよね。そうすると...


```swift
class UserViewController: UIViewController {
    var userId:Int?
      override func viewDidLoad() {
        super.viewDidLoad()
        // userを呼ぶAPIをかく
        // user呼べないよおおおおおおおお！ 
      }
  
}
```
ってなって初期表示の画面になっちゃうんですよね。
こんな感じで呼び出し方によって変わっちゃう動きはイケテナイ。

**UserViewController呼ぶときは必須にしたいよねえ！**


# 3.ViewControllerのinit書こうね
普通にinit処理書くこともできますが、便利なライブラリがあるので、それに頼ります。
https://github.com/tarunon/Instantiate

これを使って書くとこうなります

```swift
        // 初期化時に必ずuserIdが必要なように書く
        let viewController = UserViewController.instantiate(with: .init(userId:userId))
        self.navigationController?.pushViewController(viewController, animated: true)
```

```swift

import Instantiate
import InstantiateStandard

class UserViewController: UIViewController, StoryboardInstantiatable {
      
    //ここは初期化時の処理を書く
    func inject(_ dependency: UserViewController.Dependency) {
        self.userId = dependency.userId
    }


    //ここに必要な変数を書く
    struct Dependency {
        var userId:Int
    }

    var userId:Int!
  
    override func viewDidLoad() {
      super.viewDidLoad()
      //userを呼ぶAPIをかく
      //ここでは必ずuserIdが取れる！！！
    }
  
}
```

このように書くことで
**UserViewControllerを呼び出すときは必ずuserIdが必要なんだ！**
とコード上で力強く宣言できます

# 4.まとめ
ViewControllerのinit処理を正しく入れると、ViewControllerの使い回しが大変楽になります。
呼び出し側に負担を求めるViewControllerを書くのはやめましょう。（自戒をこめて...）
ちなみに他にもCellやUIViewなどもほぼ同じ方法で、init処理書けます。
ライブラリを作っていただいた人に感謝。
VS Code 1.28 の新機能 - スニペット機能の改善

https://code.visualstudio.com/updates/v1_28#_project-level-snippets

テキスト断片の登録・呼び出しを行うスニペット機能について以下の改善が行われた。

# プロジェクト単位のスニペット定義
スニペットの定義は、従来は言語ごと（＝ファイル拡張子ごと）の定義かもしくはグローバル定義の2種類だったが、今回、ワークスペースやフォルダごとのスニペットを定義できるようになった。
![prj_snippets.jpg](https://qiita-image-store.s3.amazonaws.com/0/181011/1e9a4e12-f1fc-f278-5a6b-659a002d98a5.jpeg)
VS Codeで開いたフォルダの下に`.vscode`フォルダを作成し、その下に拡張子`.code-snippets`のファイルを作成してそこにスニペットを定義すると、ローカル的なスニペット定義として使用できる。ワークスペースの場合は含まれるフォルダの下のすべての`.vscode/*.code-snippets`ファイルを読み込んでくれる。これらのスニペット定義は候補を表示した際に`ワークスペースのスニペット`として表示される。

特定のプロジェクトの中だけでしか使わないようなスニペットはこうやって定義しておけば、言語ごとやグローバルのスニペット定義を汚さないので良いね！

# prefixが配列指定可になった
`prefix`で配列指定が可能になり、1つのスニペット定義に対して複数のキーワードを指定できるようになった。
![mutli_snippets.jpg](https://qiita-image-store.s3.amazonaws.com/0/181011/67149f40-8221-fc90-86a7-9ccace860389.jpeg)
同じ操作に対するエイリアスを定義したい場合なんかは定義がスッキリ書けて良さげ。
macにJava11とspringtoolsuiteを入れる

仕事でさわる機会がありやってみました。

```bash
# インストール
brew cask install java

# バージョン確認
java --version

# OpenJDKだと半年間サポートがあるらしい。無償だとこちらがいいらしい。
openjdk 11 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

# brewでインストール。サイトからDownloadする方法もある
brew cask install springtoolsuite

Javaで他のバージョンと切り替えたりするにはJava_HOMEを設定すればいいらしい。
必要になったら設定したい。
```
指定文字が含まれていないファイルを一覧で表示する。

# 概要
指定文字が含まれていないファイルを一覧で表示したいことがたまにあるが、いつもコマンドを忘れるのでメモ。
※指定文字が含まれているファイルを一覧で表示するコマンドもついでにメモ。

# 手順
## 文字列「aaaa」を含まないhtmlファイルをディレクトリ「testdir」内から検索して一覧表示する。
```terminal
grep -Lir 'aaaaa' testdir --include='*.html’
```

※コマンドのフォーマット
grepコマンド/オプション/‘検索文字’/検索対象ディレクトリ/--include=‘*.検索対象拡張子’

## 文字列「aaaa」を含むhtmlファイルをディレクトリ「testdir」内から検索して一覧表示する。
```terminal
grep -ril 'aaaaa' testdir --include='*.html’
```
スロープ生成のコンストラクションを考えてみる

#今回やること
入力された底辺と高さからスロープを生成する
*今回もUE4で極めるゲーム開発(https://www.borndigital.co.jp/book/6359.html#book_support) で活用できるスロープコンストラクションの作成を行うので上記書籍を使用した前提で書かせていただきます。

#目標
・底辺と高さのみ与えられた状態からスロープを生成するようにする。
・上記に合わせ幅も指定できるようにする。

##1. 斜辺と角度を求める
底辺と高さから斜辺と角度を求めるのには三角関数を使用しますが、私は勉強をサボってきたので特に何も教えられません。ごめんなさい。

![斜辺を求める.png](https://qiita-image-store.s3.amazonaws.com/0/300492/350f4e86-39b5-e4fe-4b20-685063c5d1c3.png)
まずは斜辺はピタゴラスの定理を利用し求める。これで斜辺を形成するのに必要な床の枚数が分かる。ここでは、 SloopBaseLength で指定された数の床を拡大して生成する。
![傾斜を求める.png](https://qiita-image-store.s3.amazonaws.com/0/300492/fe8d3265-417c-b203-e2d2-7b98493a251d.png)
良くは分かっていないのだが、どうやら A 入力ピンには高さ、 B 入力ピンには底辺を渡すらしい。これはちょうど tanθ を求めるときの上下関係になっている。ほへー。
とりあえず1枚表示してみよう。
![大きさを変えられた.png](https://qiita-image-store.s3.amazonaws.com/0/300492/821bc981-ded0-a1c2-6025-f5d9de5fc1e8.png)
拡大も問題なくできているようだ。
オプションを見るとユーザーが指定しない値が表示されているがこれはデバッグがしやすいかなと思って見えるようにしただけなので後で隠すようにする。

##2. 2枚目以降の生成位置を決める
ブループリントの関数がどう使われるのか調べても日本語のページはなかなか見つからない。英語も読めるようにならねば。
![生成位置.png](https://qiita-image-store.s3.amazonaws.com/0/300492/fda374f6-8ae0-fb96-a397-ae7137416986.png)
AddHeight, AddWidth は移動ベクトル(？)を求めている。
sin, cos はそれぞれ受け取った値を θ に入れた sinθ, cosθ の値を返す。床1枚は縦 100 なので実際の移動距離を求めるようにしている。

![完成かな.png](https://qiita-image-store.s3.amazonaws.com/0/300492/2ba7f6bb-8661-c4af-2720-c69cbaa53688.png)
先に一列作りたかったので Wide のループの中で SloopBaseLength のループを回している。あとは特にない。確認して終わりにしよう。

#3. 並べる
![届いてない.png](https://qiita-image-store.s3.amazonaws.com/0/300492/317253f7-3af5-ad9c-bbe7-654492dfe51d.png)
なぬ。。。一定間隔でzファイトが起こっている。。。
お気付きだろうか。私は移動ベクトルを求めるところで実際の移動距離を求めるために床1枚分 100 をかけている。傾斜補正で1枚を拡大しているというのに。因みに私はこれで1時間悩んだ雑魚なのだ。

というわけで修正、ついでに整理
![修正して整理.png](https://qiita-image-store.s3.amazonaws.com/0/300492/0b87b48c-2e28-6359-a6c2-80f995fc063e.png)
拡大後の床1枚分に変更しただけ。
![でけた下.png](https://qiita-image-store.s3.amazonaws.com/0/300492/78f78e90-277a-b58b-9710-9d377cd0516f.png)
![でけた上.png](https://qiita-image-store.s3.amazonaws.com/0/300492/19ca54bc-1874-c65a-d9ab-df69fc9b0b33.png)
大丈夫そうだ。しかし念のためワイヤーフレーム上でも確認しよう。
![ピッタリ.png](https://qiita-image-store.s3.amazonaws.com/0/300492/e96ff78c-98ae-f162-2638-8c8759af1fef.png)
**完璧！！！！！**

#おわり
数学分かってたりブループリントが分かっていると非常に楽だったと思う。移動ベクトルも拡大しなければいけないのは至極当然のことですね、反省。
1つ気になるのが1枚目の床の生成場所だ。できるなら表下左角を起点にしたいのだが角度によって変わるので求め方が大変そうなので今回はやらない。頭が働かないので。お粗末！！！！
図書館のスマートコントラクト

##図書館のスマートコントラクト
このスマートコントラクトは本をアップデートして、付けることができます。そして本の使用可能をたしかめることができます。

```solidity:qiita.solc
pragma solidity ^0.4.18;
```

このコードはsolidityのバージョン用です。

```solidity:qiita.solc
struct Book {
    uint id;
    string bookTitle;
    bool isBorrowed;
    address borrower;
  }
```
Bookストラクトを作りました。
Bookの識別子はidです。
Bookのborrowerは契約の所有者です。

```solidity:qiita.solc
mapping (uint => Book) public book;
uint incrementBookId;
```

uintを本にマップしました。そしてBookのidをインクリメントします。


```solidity:qiita.solc
function addBook(string _bookTitle) public {
    incrementBookId++;
    book[incrementBookId] = Book(incrementBookId, _bookTitle, false,  address(0));
  }
```

この関数は本を付けることができています。

```solidity:qiita.solc
function borrowBook(uint _bookId) public {
    require(book[_bookId].isBorrowed == false);
    book[_bookId] = Book(incrementBookId, book[_bookId].bookTitle, true, msg.sender);
  }
```
この関数は本のステータスをfalseに変更する。本のステータスがfalseの場合は、trueに変更します。msg.senderも契約の所有者です。

```solidity:qiita.solc
function returnBook(uint _bookId) public {
    require(book[_bookId].isBorrowed == true);
    book[_bookId] = Book(incrementBookId, book[_bookId].bookTitle, false, msg.sender);
  }
```

この関数は本のステータスをtrueに変更する。本のステータスがtrueの場合は、falseに変更します。

```solidity:qiita.solc
function checkBookStatus(uint _bookId) public view returns(bool) {
    return book[_bookId].isBorrowed;
  }
```
この関数は書籍のステータスを確認しています。そして、trueとfalseに変更します。

```solidity:qiita.solc
pragma solidity ^0.4.18;
contract LibraryContract {

  struct Book {
    uint id;
    string bookTitle;
    bool isBorrowed;
    address borrower;
  }

  mapping (uint => Book) public book;

  uint incrementBookId;

  function addBook(string _bookTitle) public {
    incrementBookId++;
    book[incrementBookId] = Book(incrementBookId, _bookTitle, false,  address(0));
  }

  function borrowBook(uint _bookId) public {
    require(book[_bookId].isBorrowed == false);
    book[_bookId] = Book(incrementBookId, book[_bookId].bookTitle, true, msg.sender);
  }

  function returnBook(uint _bookId) public {
    require(book[_bookId].isBorrowed == true);
    book[_bookId] = Book(incrementBookId, book[_bookId].bookTitle, false, msg.sender);
  }

  function checkBookStatus(uint _bookId) public view returns(bool) {
    return book[_bookId].isBorrowed;
  }
}
```
mysqlへログインできない問題

基本的なことだがmysqlのログイン時の挙動でつまづいたのでメモ

#コマンドメモ
#####▼登録済みユーザーの確認
```
SELECT user, host, password FROM mysql.user;
+----------+-----------+-------------------------------------------+
| user     | host      | password                                  |
+----------+-----------+-------------------------------------------+
| root     | localhost | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
| root     | localenv  |                                           |
| root     | 127.0.0.1 |                                           |
| root     | ::1       |                                           |
|          | localhost |                                           |
|          | localenv  |                                           |
| hogehoge | %         | *0B025000DCF68B1D374153A7005639E320D41D5B |
+----------+-----------+-------------------------------------------+
```

#####▼ユーザー作成
```
CREATE USER 'user名'@'ホスト名' IDENTIFIED BY 'パスワード';
例) CREATE USER hogehoge@'%' IDENTIFIED BY 'hogehoge';
```
※ホスト名の指定なしなら「%」がデフォルトで設定される
※明示的に「%」を指定する場合はシングルクォートで囲む

#####▼権限の表示
```
SHOW GRANTS FOR 'user名'@'ホスト名 or IPアドレス';
```

#####▼パスワードの設定
```
SET PASSWORD FOR 'ユーザー名'@'ホスト名' = PASSWORD('パスワード');
例） SET PASSWORD FOR 'root'@'localhost' = PASSWORD('root');
```

#####▼ユーザーの削除
```
DROP USER 'user名'@'ホスト名 or IPアドレス';
```


#ログインできない問題の解決
ユーザーを作って、パスワードを設定したのにログインしようとするとエラー

```
mysql -uhogehoge -phogehoge
Warning: Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'hogehoge'@'localhost' (using password: YES)
```

どうやら、アクセスしたい6行目の「hogehoge@'%'」よりも先に
5行目の「''@localhost」の匿名ユーザーに該当すると判断されるようです
今回、私には匿名ユーザーは必要無かったので消しました

```
mysql> DROP USER ''@'localhost';
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT user, host, password FROM mysql.user;
+----------+-----------+-------------------------------------------+
| user     | host      | password                                  |
+----------+-----------+-------------------------------------------+
| root     | localhost | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
| root     | localenv  |                                           |
| root     | 127.0.0.1 |                                           |
| root     | ::1       |                                           |
|          | localenv  |                                           |
| hogehoge | %         | *0B025000DCF68B1D374153A7005639E320D41D5B |
+----------+-----------+-------------------------------------------+
```

はい、これでログインできました！
ユーザーを作成したのに、ログインできない！となったら他のユーザーが悪さしていないか確かめた方がよさそうです
...というか不要なユーザーはすべて消した方がいいですね
使ってみよう！MutationObserver！

#１）はじめに
DOMの監視をしたい、そんな時に使いやすいWebAPIが**MutationObserver**です。
今回はその利用方法について模索してみます。

#２）MutationObserverとは
その名の通り「Mutation（変化）」を「Observe（監視）」するAPI。
任意の要素（DOM）の変化を監視することが出来ます。

```javascript:
// 対象とするノードを取得
const target = document.getElementById('target');

// オブザーバインスタンスを作成
const observer = new MutationObserver((mutations) => {
	mutations.forEach((mutation) => {
		// 何かしたいこと
		console.log(mutation.target);
	});
});

// オブザーバの設定
const config = {
	characterData: true,
	subtree: true
};

// 対象ノードとオブザーバの設定を渡す
observer.observe(target, config);
```

```javascript:
// 何らかのタイミングで監視を解除したい時
observer.disconnect();
```

##オプションについて
**childList**、**attributes**、**characterData**いずれかに**trueが必須**となる。

###childList
対象ノードの子ノード（テキストノードも含む）に対する追加・削除を監視する場合はtrue。

###attributes
対象ノードの属性に対する変更を監視する場合はtrue。

###characterData
対象ノードのデータに対する変更を監視する場合はtrue。

###subtree
対象ノードの子孫ノードまで監視する場合はtrue。

#３）対応ブラウザについて
![image.png](https://qiita-image-store.s3.amazonaws.com/0/95865/e24bf710-dea0-3da0-de0a-854095a27fea.png)
[Can I use：Mutation Observer](https://caniuse.com/#feat=mutationobserver)
対応ブラウザを見るに、問題なく使うことが出来ますね。

#４）様々なDEMO
今ひとつ使い道が浮かばない・・

- [DEMO1：&lt;p&gt;タグの内容変化を監視](https://andus.heteml.jp/mutation_observer/1.html)
- [DEMO2：動的に読み込まれた画像のリストアップ](https://andus.heteml.jp/mutation_observer/2.html)

#５）参考リンク
- [MutationObserver - Web API インターフェイス | MDN](https://developer.mozilla.org/ja/docs/Web/API/MutationObserver)
- [JS Bin - Collaborative JavaScript Debugging]
(https://jsbin.com/ivamoh/53/edit?html,output)
Vue Component内methodsのアロー関数式内でdataを扱う

# やりたいこと
```js:とある.vueファイル(エラー)
export default {
  data: () => {
    return {
      test: 0
    }
  },
  methods: {
    testfunc: () => {
      this.test++ // エラー
    }
    /*
    testfunc2: function () {
      this.test++ // こちらはうまくいく
    }
     */
  },
  created () {
    this.testfunc() // ここではthisが使えている
  }
}
```

## うまくいかない原因
- アロー演算子`() => {}`内のthisはこのvmを参照していないため

# 対処法
```js:とある.vueファイル
var vm // --①
export default {
  data: () => {
    return {
      test: 0
    }
  },
  methods: {
    testfunc: () => {
      vm.test++ // 👏
    }
  },
  created () {
    vm = this // --②
    this.testfunc()
  }
}
```

## ポイント
①vm用の変数を確保
②vm内に`created`か`mounted`を使ってvmを代入

# もやもや
- 出来れば`var`を使わずに書きたい
- 外に仮置きしないで実装する方法は無いんだろうか…

もっときれいに書く方法が有れば、教えていただけるとありがたいです。
ログ解析

## 想定ケース

海外のホテルを検索するサイト

検索画面にアクセスし、行き先の国・宿泊日などの条件を入力することで結果一覧検討するステップを想定。
```
検索起動
↓
条件入力
↓　↑
結果一覧表示
↓
詳細画面へ
```


##
windowsローカルでネットワーク遅延を再現する（ローカルへのDB接続を遅延させたい時等）

windows環境でネットワークの遅延を再現するために、↓のアプリを使います。
http://jagt.github.io/clumsy/index.html

clumsy.exe を起動させるとそのままの設定でローカルに対しての設定になっているので、"Lag"にチェックを入れて、遅延させたいミリ秒を指定します。
で、startボタンをクリック。

遅延以外にも色々できる模様。
CI環境ではjestのオプションに--ciを付ける

https://jestjs.io/docs/en/cli.html#ci

```
$ jest --ci
```

デフォルトの挙動では、新しいスナップショットがあると保存されてしまう。
それにより、ローカルで新規スナップショットを保存せずにpushしてもCI側で新規に保存されテストが通ってしまう。
が、これを付けるとテストが落ち、`--updateSnapshot`を要求するので安全。
無名関数とか言う奴はIEユーザーって書こうとした記事の残骸

IEだと`name`プロパティ自身が未実装なので、この投稿はあとから考え直します。ごめんなさい。

---


~~JavaScriptの関数式で名前を省略した書き方を**無名関数**とか**匿名関数**とか言う人いますよね。じゃあ、下の画面を**IE以外**で見て下さい。~~

<p data-height="123" data-theme-id="0" data-slug-hash="PyOWjN" data-default-tab="html,result" data-user="raccy" data-pen-title="関数の名前" class="codepen">See the Pen <a href="https://codepen.io/raccy/pen/PyOWjN/">関数の名前</a> by raccy (<a href="https://codepen.io/raccy">@raccy</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

~~ほら、`f`って名前付いているじゃないですか。あ、IEだと`undefined`って出ますよ。つもり、無名関数とか匿名関数とか言っている人って、未だにIE使っている人達なんです。きっと、Windows10が使えなくて、ChromeもFirefoxも知らない人だから、生暖かい目で見てあげてくださいね。~~

---

## 解説編

後で書く。
React16 ErrorBoundaries

公式を読めば書いてあるので、使い方は飛ばす。

[Error Boundaries – React](https://reactjs.org/docs/error-boundaries.html)

だいたいこんなの

```jsx
class ErrorBoundary extends React.Component {
  state = { hasError: false }
  componentDidCatch(error, info) {
    this.setState({ hasError: true })
  }
  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>
    }
    return this.props.children
  }
}
```

- イベントハンドラ内のエラーはcatchしない。
`try/catch`で処理する必要がある。

- `ErrorBoundary`をどこに置くか？
ネストした場合一番近いものがcatchするという特性上、まずルートに配置し、その後機能ごとにラップするとよさそう。

- ErrorBoundary対応は必須か？
必須。React16ではcacheされてないエラーがレンダリング時に発生した場合コンポーネントのツリー全体が解除される。ので、バグがある状態でReact16対応とかやると画面が真っ白になるみたいなことが起きうる。
https://reactjs.org/docs/error-boundaries.html#new-behavior-for-uncaught-errors

- 毎回自分で`ErrorBoundary`を作る必要があるか？
自分で書いてしまってもいいが、recompose作者のbvaughn氏がシンプルな`ErrorBoundary`コンポーネントライブラリを書いているので雑に導入できる [bvaughn/react-error-boundary: Simple reusable React error boundary component](https://github.com/bvaughn/react-error-boundary)
PHP　スーパーグローバル変数GETについて

こんばんは。

PHPのスーパーグローバル変数のGETに関してのプログラムを作ってみました。

また簡単でシンプルなフォームを作ってやってみましたので、ご紹介します。

参考になれば幸いです。

![2018-10-15 (9).png](https://qiita-image-store.s3.amazonaws.com/0/200171/2e73a0d1-d54a-0e70-240b-cd9a4757a781.png)

まずは、HTMLでフォームを作りました。

POSTではなくGETで作りました。

これを送信した形が下記になります。
![2018-10-15 (10).png](https://qiita-image-store.s3.amazonaws.com/0/200171/1b497364-b26a-a4bc-5842-e31f221cb104.png)

これはどいう事かというと、アドレスバーに注目してください。

アドレスバーの後のhandle=の後にパラメータがついているのがわかるかと思います。

これが日本語から変換された形のものになります。

では、そのhandle=の後のパラメータを変えたものもご紹介します。
下記になります。

![2018-10-15 (11).png](https://qiita-image-store.s3.amazonaws.com/0/200171/2e1b753b-8315-4b16-769e-fa67bacabafe.png)

aaaaという文字がhandle=の後に入っていて
「あなたの名前はaaaaです。」という形に変わっているのが
お分かりになるかと思います。

これはどういうことかというとフォームに戻って打ち直さずとも

パラメータを削除して任意の文字にすれば

書き換えることができてしまいますよ、という事なのです。

では、サーバーサイド側ではどのような処理を施せばよいか

ということについて書いていきます。

```PHP
$data = htmlspecialchars($_GET['handle'],ENT_QUOTES,"UTF-8");
```


という形にすれば、handle=の後のパラメータがいじられても

何も起こらなくなるはずです。

・・・と思ってたった今試してみましたが変わってしまいますねぇｗ。


ということで、次回のPHPの記事を書くまでに

ちょっと調べてまた記事を書いていきます。

以上です。

いつもご覧いただきまして誠にありがとうございます。

皆様の学習の一助になれば幸いです。
UnityでThere are 2 audio listeners in the scene.のエラーが表示された

## 環境
WIndows10
Unity 2018.2.11f1 personal

## 経緯

UnityでVRゲームを作っているとき、ゲームを再生したら、以下のようなエラーが表示されました。

**There are 2 audio listeners in the scene. Please ensure there is always exactly one audio listener in the scene.**

## 原因

これは、シーン内に「AudioListener」コンポーネントが2つ以上アタッチされている場合に発生するようです。  
AudioListerコンポーネントは人間でいう「耳」の役割をしていて、シーン内に1つだけにしておかないと、正確に音が再生されないなどの弊害が出ます。

## 解決方法
ゲーム実行時にアクティブなAudio Listenerが1つだけになるように対応します。
具体的には……

* 複数のオブジェクトにAudio Listenerがアタッチされている場合、1つだけに絞る
* スクリプトなどでアクティブなAudio Listenerが1つになるように制御する

## とはいっても

シーン内に多数のオブジェクトが配置された状態でAudioListerコンポーネントがアタッチされているオブジェクトを探すのは大変!  
AudioListenerがアタッチされたオブジェクトを探す方法は、下記フォーラムに掲載されていました。

<https://answers.unity.com/questions/927548/how-do-you-find-2-audio-listeners-in-scene.html>

このフォーラムによれば

1.  ヒエラルキービューの検索窓左にある虫眼鏡アイコンをクリック 
2.  検索対象を「Type」に変更
3.  検索窓に「audiolistener」と記入して検索

これで、AudioListerコンポーネントがアタッチされたオブジェクトが検索できるそうです。

![68747470733a2f2f7368656c7469652d6761726167652e78797a2f77702d636f6e74656e742f75706c6f6164732f323031382f31302f73637265656e73686f742e312e6a7067.jpg](https://qiita-image-store.s3.amazonaws.com/0/137137/44f5e726-f24e-e630-5abf-db2624cac474.jpeg)

![68747470733a2f2f7368656c7469652d6761726167652e78797a2f77702d636f6e74656e742f75706c6f6164732f323031382f31302f73637265656e73686f742e322e6a7067.jpg](https://qiita-image-store.s3.amazonaws.com/0/137137/507d630b-4764-67bb-5ab0-b30d5be407a5.jpeg)

## 終わりに

上記のエラーが出たら、ぜひ試してみてください。  
エラーの原因や解決方法が書いてある記事は割と見つけましたが、AudioListenerがアタッチされたオブジェクトの探し方が書かれた記事は見つからなかったので書いてみました。
ソースから入れたApache2.2にphp7.1をインストール

##はじめに
ソースからインストールしたApache+Openssl1.0.1にphpもインストールしたので、備忘録
https://qiita.com/ijimakenta/items/8d530e62e3e7e5ab889e

##インストール環境
- CentOS 7


##インストール
- 必要パッケージ

```
yum install -y zlib-devel openssl-devel pcre-devel libicu-devel gettext-devel readline-devel libxml2-devel libxslt-devel libjpeg-devel libpng-devel freetype-devel libxml2-devel curl-devel gdbm-devel bzip2-devel libXpm-devel epel-release 

yum --enablerepo=epel install libmcrypt-devel -y
```

- configure

```
./configure \
  --prefix=/usr/local/php-7.1.6 \
  --with-apxs2=/usr/local/apache2/bin/apxs \
   --with-openssl=/usr/local/openssl \
  --with-mysqli=mysqlnd \
  --with-pdo-mysql=mysqlnd \
  --with-mysql-sock=/tmp/mysql.sock \
  --enable-mysqlnd \
  --enable-mbstring \
  --enable-intl \
  --with-icu-dir=/usr \
  --with-gettext=/usr \
  --with-pcre-regex \
  --with-pcre-dir \
  --with-readline=/usr \
  --with-libxml-dir=/usr/bin/xml2-config \
  --enable-soap \
  --enable-wddx \
  --with-xmlrpc \
  --with-xsl=/usr \
  --with-zlib=/usr \
  --with-zlib-dir=/usr \
  --with-gd \
  --with-jpeg-dir=/usr \
  --with-png-dir=/usr \
  --with-freetype-dir=/usr \
  --enable-gd-native-ttf \
  --enable-gd-jis-conv \
  --with-mcrypt=/usr \
  --enable-bcmath \
  --with-iconv-dir=/usr \
  --enable-zip \
  --with-curl=/usr \
  --enable-bcmath \
  --enable-sockets \
  --enable-ftp \
  --disable-opcache \
  --with-xpm-dir=/usr \
  --with-gettext \
  --with-pic \
  --with-bz2 \
  --with-layout=GNU \
  --enable-exif \
  --enable-sysvsem \
  --enable-sysvshm \
  --enable-sysvmsg \
  --with-kerberos \
  --enable-shmop \
  --enable-calendar \
  --disable-dba \
  --enable-mbregex \
  --enable-pcntl \
  --enable-cgi \
  --with-pear \
```
```
make
make install
```
@アノテーション


@PathVariable
URLから値を取得し、変数に格納してくれる。
URL : http://localhost:8080/person/post/999

	  @RequestMapping(value="/post/{id}", method=RequestMethod.POST)
	  public Person getMessages(@PathVariable(value = "id", required = false) Integer id){
		  	Person person = new Person();
		  	person.setId(id);
		  	
		  	return person;
	  }

結果 : {"id":999}

@PathVariable (複数の場合)
URL : http://localhost:8080/person/post/1/userName/99

	  @RequestMapping(value="/post/{id}/{name}/{age}",method=RequestMethod.POST)
	  public Person getMessages1(@PathVariable(value = "id", required = false) Integer id,@PathVariable(value = "name", required = false) String name,@PathVariable(value = "age", required = false) Integer age){
		  	Person mydata = new Person(id,name,age);
            //serviceは別で定義
		    return service.saveAndFlush(mydata);
		  
	  }
結果 : {"id":1,"name":"userName","age":99}

@NoArgsConstructor
デフォルトコンストラクタを生成する

	import lombok.NoArgsConstructor;

	@NoArgsConstructor
	public class Man {

	    private long id;

	    private String name;

            //※下記のコンストラクタを自動生成してくれる。
            public Man() {
            }
	}


@AllArgsConstructor
全メンバをセットするためのコンストラクタを生成する

	import lombok.AllArgsConstructor;

	@AllArgsConstructor
	public class Man {

	    private long id;

	    private String name;

        //※下記の全メンバをセットしたコンストラクタを自動生成してくれる。
        public Man(final long id, final String name) {
            this.id = id;
            this.name = name;
        }

	}
Supermicroのipmiパスワードをリセットする

パスワードがわからなくなったらリセットしよう。

# 方法
##SupermicroのIPMICFGをダウンロード

[Supermicro IPMI ユーティリティ](https://www.supermicro.com/solutions/SMS_IPMI.cfm)
から
[SMCI™ ソフトウェアのダウンロード](https://www.supermicro.com/SwDownload/SwSelect_Free.aspx)
へ飛んでIPMICFG	DOS, Windows, Linux をダウンロード。

適当な場所に展開。

## Windows上から変更

管理者のコマンドプロンプトで展開したフォルダの`Windows\64bit`を開く。

```DOS
IPCFG-Win.exe -user list
```
でユーザー番号を調べて

```DOS
IPCFG-Win.exe -user setpwd {uid} {PASSWORD}
```
で変更。

```DOS:例
IPCFG-Win.exe -user setpwd 2 ADMIN
```

ここで
```
Can not find a valid IPMI device.
```
と出る場合[^1]はDOSブートして変更する。
[^1]: Hyper-Vを使ってると駄目かもしれない。

##DOSから変更
###1.DOSブートできるUSBメモリを作る

[Rufus \- 起動可能なUSBドライブを簡単に作成できます](https://rufus.akeo.ie/) 

RufusをダウンロードしてUSBメモリを刺して実行。
![スクリーンショット (121).png](https://qiita-image-store.s3.amazonaws.com/0/199750/b3f599fd-6458-69a9-368d-cccf1d66ba0f.png)
Freedosでブートディスクを作る。

展開したIPMI ユーティリティの`DOS`フォルダの中身をUSBのルートにコピーしたら、USBを刺してリブート。

###2.変更
```DOS
>IPCFG-Win.exe -user list
>IPCFG-Win.exe -user setpwd 2 ADMIN
```
OpenJDK 11へ変更後にApacheTomcat 8が起動しなくなる件の解決方法

# 概要

これまでApacheTomcat 8をOracleJDK 8で動かしていましたが、JDKのバージョンアップの対応によりOpenJDK 11への入れ替えを行いました。すると、ApacheTomcatのログに以下のエラーメッセージが表示されて起動ができなくなりました。エラーを解消するのに苦労したため解決方法を記載しておきます。

```
[2018-10-16 02:18:51] [info]  ( prunsrv.c:1175) [ 3808] Starting service...
・・・(略)・・・
[2018-10-16 02:18:56] [error] ( javajni.c:763 ) [ 3816] CreateJavaVM Failed
[2018-10-16 02:18:56] [error] ( javajni.c:763 ) [ 3816] 指定されたファイルが見つかりません。
[2018-10-16 02:18:57] [debug] ( javajni.c:1013) [ 3816] Java Worker thread finished : with status = 2
[2018-10-16 02:18:57] [error] ( prunsrv.c:1232) [ 3808] Failed to start Java
[2018-10-16 02:18:57] [error] ( prunsrv.c:1580) [ 3808] ServiceStart returned 4
[2018-10-16 02:18:57] [debug] ( prunsrv.c:885 ) [ 3808] reportServiceStatusE: dwCurrentState = 1, dwWin32ExitCode = 1066, dwWaitHint = 0, dwServiceSpecificExitCode = 4
[2018-10-16 02:18:58] [info]  ( prunsrv.c:1645) [ 3780] Run service finished.
[2018-10-16 02:18:58] [info]  ( prunsrv.c:1814) [ 3780] Commons Daemon procrun finished
```

```
<JAVA_HOME>/lib/endorsed is not supported. Endorsed standards and standalone APIs
in modular form will be supported via the concept of upgradeable modules.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
```

# 解決方法

ApacheTomcatのJVM Optionに `java.endorsed.dirs` が含まれているとJDK 9以降ではJavaの起動に失敗します。
そのため、含まれている場合はその行の削除が必要です。

```
-Djava.endorsed.dirs=C:\Program Files\ApacheTomcat\endorsed
```

Windows環境の場合、以下のレジストリキーからApacheTomcatのJVM Optionの変更ができます。

```
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Apache Software Foundation\Procrun 2.0\Tomcat8\Parameters\Java\Options
```

その他、以下の条件に当てはまる場合にもApacheTomcatの起動に失敗するので注意が必要です。

* JVM Optionに `java.ext.dirs` が含まれている
* JVM Optionに `Xincgc` が含まれている
* `lib/ext` ディレクトリが存在する
* `lib/endorsed` ディレクトリが存在する

参考: https://docs.oracle.com/javase/jp/9/migrate/toc.htm
RawGit、CDNやめるってよ

10/8から [RawGit](https://rawgit.com/) サイトにサービス終了のお知らせが表示されています。

> ### RawGit has reached the end of its useful life
> October 8, 2018
> RawGit is now in a sunset phase and will soon shut down. It's been a fun five years, but all things must end.
>
> GitHub repositories that served content through RawGit within the last month will continue to be served until at least  October of 2019. URLs for other repositories are no longer being served.
>
> If you're currently using RawGit, please stop using it as soon as you can.

### 抄訳
> ### RawGitは寿命を迎えます
> 2018年10月8日
> RawGitは日没を迎え、まもなく終了を迎えます。楽しい5年間でしたが、しかし、すべてのものは終わりを迎えます。
>
> 先月以降保存されたGitHubリポジトリのコンテンツは少なくとも2019年10月まで提供されます。その他のリポジトリのURLはもう提供していません。
>
> もし、まだ RawGit を使っているならば、できる限りすぐに止めてください。

# どうしたら良いの？

[RawGit](https://rawgit.com/) サイトにも書かれていますが、他のCDNやサービスに移行する必要があります。  
タイプ別に移行先を示したいと思います。

## 暫定対応 (2018/10/16追記)
@basictomonokai さん、ご指摘ありがとうございます。

https://www.jsdelivr.com/rawgit にて、既にRawGitで配信しているURLから、jsDelivrのURLに変換する移行ツールが提供されています。配信済みファイルは本ツールで得られたURLに張り替えることで対応できます。
新規のファイルを配信するには、後述の方法を検討してください。

## JavaScriptやCSSのライブラリーを提供している場合

それらのファイルをNPMで公開するのが最も近道です。
現在、NPMに公開すると、自動的に[jsDelivr](https://www.jsdelivr.com/)と[UNPKG](https://unpkg.com/#/)から配信されます。
[yarn](https://yarnpkg.com/lang/en/)のサイトで確認できます。

例として、yarnの[私のリポジトリ](https://yarnpkg.com/en/package/menneu-md-notebook)へのリンクを張ります。
サイドバーのCDNsのところで確認できるかと思います。

NPMへの公開をされたことのない方は、以下の記事が参考になるかと思います。
* [初めてのnpm パッケージ公開](https://qiita.com/TsutomuNakamura/items/f943e0490d509f128ae2)

## GitHub Pages等で使用している場合
素直に、自身のGitHub Pagesのリポジトリに置きましょう。

## ブログやアプリで使用している場合

どうしても無料で利用したい場合は[Cloudflare](https://www.cloudflare.com/ja-jp/cdn/)の無料プラン等を使いましょう。
無料に拘らなければ、AWSでもAzureでもGCPでもさくらでも、いくらでも選択肢はあります。


# 最後に
RawGit これまでありがとう！
Apache2.2＋OpenSSL1.0.2 ソースからインストール

##はじめに
apache2.2系はすでにEOLしていますが、このバージョンでインストールしたい方もいるかもしれないので投稿

##環境
- apache2.2
- openssl1.0.1系
- CentOS 5, 6, 7

##★Apache2.2のconfigureについて
参考
http://httpd.apache.org/docs/2.2/programs/configure.html#synopsis

以下のインストール方法で--enable-mods-sharedは全部入りを目指しているが「ldap」を指定すると、
mod_ldap.so が古いopensslライブラリを参照していて、起動しないのでldapは外しています。

##インストール
###OpenSSL

- コンパイル

```
./config shared zlib --prefix=/usr/local/openssl-1.0.2p
make && make install
```

- バージョン情報隠蔽

```
cd /usr/local
ln -s openssl-1.0.2n openssl
```

- 共通ライブラリパス追加

```
cat <<EOT >  /etc/ld.so.conf.d/openssl.conf
/usr/local/openssl/lib
EOT

ldconfig
```

###Apache2.2
- 基本

```
./configure --prefix=/usr/local/httpd-2.2.34 \
--with-mpm=prefork \
--enable-mods-shared="all ssl cache proxy authn_alias mem_cache file_cache charset_lite dav_lock disk_cache" \
--with-ssl=/usr/local/openssl

make && make install
```
- aprもソースから入れる場合

```
cd srclib/apr
./configure --prefix=/usr/local/apr-httpd-2.2.34/
make && make install

cd srclib/apr-util
./configure --prefix=/usr/local/apr-util-httpd-2.2.34/ --with-apr=/usr/local/apr-httpd-2.2.34/
make && make install


./configure --prefix=/usr/local/httpd-2.2.34 \
--with-mpm=prefork \
--enable-mods-shared="all ssl cache proxy authn_alias mem_cache file_cache charset_lite dav_lock disk_cache" \
--with-ssl=/usr/local/openssl \
--with-apr=/usr/local/apr-httpd-2.2.34/ \
--with-apr-util=/usr/local/apr-util-httpd-2.2.34
make && make install
```

- バージョン情報隠蔽

```
ln -s httpd-2.2.34 apache2
```


##ログローテート
###CentOS6

```
/usr/local/apache2/logs/*log {
    missingok
    notifempty
    sharedscripts
    postrotate
        /sbin/service httpd-new reload > /dev/null 2>/dev/null || true
    endscript
}
```

###CentOS7
```
/usr/local/apache2/logs/*log {
    missingok
    notifempty
    sharedscripts
    compress
    postrotate
        /bin/systemctl reload httpd-2.2.service > /dev/null 2>/dev/null || true
    endscript
}
```

##起動スクリプト
###CentOS6
```
cp -p httpd-2.2.32/build/rpm/httpd.init /etc/init.d/httpd-new

vi /etc/init.d/httpd-new

prog=httpd
httpd=${HTTPD-/usr/local/apache2/bin/httpd}
pidfile=${PIDFILE-/usr/local/apache2/logs/${prog}.pid}
lockfile=${LOCKFILE-/usr/local/apache2/logs/${prog}.lock}
CONFFILE=/usr/local/apache2/conf/httpd.conf
```

###CentOS7
```
vi /etc/systemd/system/httpd-2.2.service
[Unit]
Description=Apache2.2
After=syslog.target network.target

[Service]
Type=forking
ExecStart=/usr/local/apache2/bin/httpd -k start
ExecReload=/usr/local/apache2/bin/httpd -k graceful
ExecStop=/usr/local/apache2/bin/httpd -k stop

[Install]
WantedBy=multi-user.target
```
シェルにおけるワイルドカードの挙動についての整理

#はじめに
シェルの変数と配列で”`*`”（アスタリスク）を格納する際の挙動が異なるようなので整理してみました。
環境はCentOS7.5を使用しています。

#基本

まずアスタリスクをそのままechoした場合、
`*`は特殊文字として解釈され、直下のファイル名が展開されます。
※挙動が判りやすいようにset -xオプション付きで実行。

```
[root@hostname]# echo *
+ echo test.txt test1.txt
test.txt test1.txt
```
次に`"`(ダブルコーテーション)や`\`(バックスラッシュ)で特殊文字として解釈されないようにした場合。

```
[root@hostname]# echo "*"
+ echo '*'
*
[root@hostname]# echo \*
+ echo '*'
*
```
どちらもecho `'*'`と解釈されます。

#変数に格納する場合

変数`i`に`*`を格納する場合ですが、`"`(ダブルコーテーション)で囲った場合は、先ほどと同様に`'*'`と解釈されますが、変数名に\(バックスラッシュ)を付けると変数自体を解釈しなくなります。

```
[root@hostname]# i=*
+ i='*'
[root@hostname]# echo $i
+ echo test.txt test1.txt
test.txt test1.txt

[root@hostname]# echo "$i"
+ echo '*'
*
[root@hostname]# echo \$i
+ echo '$i'
$i
```
ここまでは想定通りの動き。

#配列に格納する場合

配列に格納した場合は変数に格納した場合と異なり、配列に格納する時点で`*`が展開されてしまいます。
その為、`"`(ダブルコーテーション)で囲っても展開後のファイル名しか表示されません。

```
[root@hostname]# i=(*)　#内部的に標準出力されてから配列に格納されている？
+ i=(*)
[root@hostname]# echo ${i[@]}
+ echo test.txt test1.txt
test.txt test1.txt

[root@hostname]# echo "${i[@]}"  #ダブルコーテーションで囲っても展開後の名前が表示される
+ echo test.txt test1.txt　　
test.txt test1.txt

[root@hostname]# echo \${i[@]}
+ echo '${i[@]}'
${i[@]}
```

これは変数とは異なり、配列格納時に`*`が展開されてしまう為に発生するようです。
→内部的に標準出力で展開されたものを配列に格納している？
対策として、配列格納時に`”*”`とすると下記のようにきちんと`*`のまま格納されます。

```
[root@hostname]# i=("*")
+ i=("*")
[root@hostname]# echo $i
+ echo test.txt test1.txt
test.txt test1.txt
[root@hostname]# echo "$i"
+ echo '*'
*
```

# 応用編　アスタリスクに文字列を足した場合

`*`に文字列を足した場合は、ディレクトリ直下に該当するファイルがあるか無いかで結果が変わってくるので注意が必要です。

```
[root@hostname]# i=*
+ i='*'
[root@hostname]# echo tes$i #該当するファイルがあると展開される
+ echo test.txt test1.txt
test.txt test1.txt
[root@hostname]# echo e$i   #該当するファイルが無いとそのまま表示される
+ echo 'e*'
e*

[root@hostname]# i=(e*)     #配列を格納する場合も該当するファイルが無いとそのまま格納される
+ i=(e*)
[root@hostname]# echo ${i[@]}
+ echo 'e*'
e*
```

#まとめ
１．`*`は標準出力されるタイミングでカレントディレクトリに該当するファイルがあると勝手に展開されてしまう。
２．展開されないようにするには”(ダブルコーテーション)で囲うのが確実。
３．ただし、配列に関しては配列格納時にも`*`を展開しようとするので注意すること。



以上
Nuxt上でフロントサイドライブラリを使うメモ

# やりたかったこと
Nuxt上でTone.jsを使いたかった。
`window is not defined`っておこられた。
ESLintはStandardを使用。

公式ガイドラインにも記述がありますが、一部ハマったりしたのでメモ程度に書いています。

## Tone.js
Web Audio APIを使いやすくするためのライブラリ。

# 対処法

```js:.vueファイル内の読み込み
if (process.browser) {
  var Tone = require('tone')
}
```

```js:vueファイル内の処理
if (process.browser) {
  console.log(Tone.Frequency('A3').toMidi())
}
```


## ポイント
- `if (process.browser)`
    - サーバーサイドで実行しない
- `require('tone')`
    - `import`はインデント上で使えないため`require`を使用する

# もやもや
やっぱり`import`に統一したい。
何かいい手を知ってる方が居たらアドバイスをお願いします。
プログラマが最低限仕事をするために必要そうなこと

# 【前提】
タイトルの通りです。インフラ系は専門では無いので省いています。
賛否両論ある記事内容だと思います。色んな意見を聞けるとありがたいです！
自社の自部署の開発水準から考えた内容です。現状の業務内容としては広く浅く色んな言語や環境の開発を行っていると思っていただけると良いです。
コード規約に関連する内容やコードの書き方みたいな、プロジェクトや個人によって左右されそうなことは省いてます。
# 【必要そうなこと】
**【プログラミングの知識】**
そりゃあPGとしてご飯を食べていくならあった方があった方が良いですよね。

**・コンパイラ言語系：Java or C++ or C#**
この辺をやっておけば大体の言語はいける気がします。
メモリやらポインタやら触れるのが良いので個人的に好きなのはC++ですが、最近の流行りや言語を考えると優先度的にはC++ < Java < C#かなと思います。

**・スクリプト言語系：PHP or Python**
今時サーバサイドが絡まない内容の方が珍しい……ような気がしているので、一度はこういうスクリプト言語を触っておくべきかと。
自分自身でサーバサイドを実装しないにしろ、ネットワーク系の概念くらいはふわっと分かっておかないと色んな所で苦しくなるんじゃないかなと思います。（アプリにしろ組み込みにしろシステムにしろ）

**【バージョン管理】**
**・Git**
SubversionにしろGitにしろ、プロジェクト管理を行う上で必要になってくる概念かと思います。むしろこの辺りを使わずにどうやってバージョン管理とかしていくんだ……？ 
Gitの方が好きなのでGitにしました。まあプログラマをやっているとどっちも触る可能性が出てくるのであれですが……。

**【基礎知識】**
**・IT系の基礎知識**
資格は持っていなくても、ITパスポート～基本情報くらいの知識はあった方が良いかと思います。
日常会話とか客先との会話でさらっと出てきます。分からない単語を後日調べる、でも良いのですが、そんな優しい上司や客先ばかりではありません。。。

**・開発工程**
ITパスポート～基本情報辺りを勉強しているとさらっと出てきますが、大体の開発の流れみたいなものがあるので知っておくと良いと思います。

**【論理的思考力】**
どう表現すべきか迷って上記にしました。
これだけ見るとすごく広い言葉ですが、自分的は「論理的にプログラムを組めるかどうか」っていう力です。
よくわからなかったり学び始めの時期だったりは、参考書や試験問題をコピペや参考サイトに手を入れると実装出来たりします。
が、業務ともなればコピペや参考サイトだけでは歯が立たなくなることもありますし、ちょっと複雑になると躓いたりします。
何が問題かって、論理的に考える力が弱いとどうプログラミングしたらいいのかも分からないし、何を調べたらいいのか分からないし、何がやばそうとかどこが分からないとかいう質問もしにくいのです。
「全部分かんないんで全部教えてください！」で教えてくれる職場や環境なら問題ないですが、お仕事となると、いつまでもそれが許される訳じゃないですしね。

また、よくわかんないまま作っていると、「なんで動いているかわかんないけど動いた！」の状況になります。
俗にいう[ブラックボックス](https://kotobank.jp/word/%E3%83%96%E3%83%A9%E3%83%83%E3%82%AF%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9-8302)や[スパゲッティコード](https://www.weblio.jp/content/%E3%82%B9%E3%83%91%E3%82%B2%E3%83%83%E3%83%86%E3%82%A3%E3%82%B3%E3%83%BC%E3%83%89)が出来上がる一因だと思います。でも誰も幸せにならないので本当にやめましょう……。。。

**【色んなことにやられないメンタル】**
こういうこと言うからIT業界全体がブラックみたいに思われるかもしれないですが、まあ多分どの業界もそういう部分がありますよね。
面倒な人間関係とか縦社会とか理不尽な批判とか、まあ社会人ならそういうのに晒されるタイミングがあるかと思います。
もしかしたらIT業界は他の業界よりもそういうのに晒される機会が多いかもしれません。最初から最後まで理想通りに何の問題もなく完了するプロジェクトなんてあるんでしょうか、**いやないです（断言）。**
少なくとも、今まで自分は体験したことが無いです。周りに聞いても無いと返ってきます。でもそんなプロジェクトいつかはやってみたい。
という愚痴は置いておいて、技術者というのはそういった壁にぶつかるタイミングが多い気がしています。
立ちはだかる仕様変更や仕様未確定、どうやっても解決出来ないと思えてしまうエラー、納期前の絶望感、お客さんや上司の無茶振り、整合性なんて求めないスケジュール……などなど。

良くあることで済ませたくないですが、とてもよくあることです。だからこそ、あんまり気にしすぎないで下さい。気に病まないでください。
たまたま運悪くモンスターハウス引く可能性が高いだけなんです。絶望的に見えても意外に道は開けるものです。頼れる人がいるなら頼って、無理なものは無理と言って、さっさと切り替えて次のフロアに行きましょう！

**【好奇心】**
プログラムは一生勉強という側面が強いと感じます。言語やツールの寿命が短いので、新しい言語が現れては消え、流行ったり流行らなかったり、再来したりしなかったり。
ツールも統合開発環境も一新したりアップデートがかかるし、古いものはどんどん切り捨てられていきます。もちろん概念が一緒だったり共通点もあったりするので、全く一からの勉強になる訳ではないです。ただ、専門職で今景気の良い業界だけあってその頻度は高いです。
また、日本国内の話で行くと、今後はプログラムを義務教育でこなしてきた若者も増えます。そんな中でプログラムだけで生きていきたい人は、新しい言語やツールに興味を持って学んでいかないと、将来仕事が無くなるんだろうなあという気がしてます。
「完全に無くなる」ということは無いかもしれないですが、COBOLとかVB.6とか一世を風靡した言語の現在を見ていると、そこだけで生きていくのは難しいんじゃないかなと思います。
故に、新しいものや言語、ツールの勉強意欲につながる「興味」とか「好奇心」ってすごく大切だと思います。楽しんで学ぶのが一番効率良いし、苦しくないですしね。

# 【まとめ】
前提のところでも書きましたが、正直賛否両論あると思います。働いている環境だったり、状況だったり、年齢だったり、経験だったりで変わってくる部分だと思うので。
社内関係で少し考える機会があったので、せっかくなのでいろんな人の意見を貰えそうな場にばらまいてみました。
ご意見や指摘点等あれば頂けると幸いです。
Telnetでもリモートコマンド実行がしたい！ 

sshは遠隔でコマンドを叩けて良いなぁ、Telnetでも出来ないかなぁと思ってたんですが、**expectコマンド**で実装できたので上げてみます。
※動作環境はUbuntu16.04ですが、expectコマンドがあればUbuntuでもCentosでもMacでも動くハズ。

```
# こんな感じでコマンドを投げたい
ssh ubuntu@192.168.10.1 ls
```

# expect
シェル上で**対話的な処理を自動化**できるコマンドです。
基本的にはexpectでシェル上の文字列の出現を待ち、sendコマンドで文字列(コマンドなど)を送ります。
中身はシェルのコマンドではなく、TCLスクリプトです。

expectスクリプトとして書くか、シェルスクリプトの中に書くことも出来ます。

- expect

```
#!/usr/bin/expect
# TCLの空間
```
- Bash

```
#!/bin/bash
expect -c "
# TCLの空間
"
```

# expect導入
Telnetで遠隔コマンド実行をするスクリプトを動かすにはexpectコマンドが必要なので入れましょう。
大抵の場合最初から入っている気がしますが、

```
sudo apt install -y expect
```
Ubuntu16ならこれで入ります。(MacやCentosにもあります。)


# expectで自動Telnet ＆ 遠隔コマンド実行君
様々なログインパターン(ユーザー名・パスワードの有無、プロンプト)に対応したので、大抵の機器にはログインできると思います。(ログイン後enableが必要だったりすると上手くいかないかもですが。。。)

```
#!/usr/bin/expect -f

# telnetpass.exp
# usage = ./telnetpass.exp 172.24.0.1 loginid loginpass

set RemoteHost [lindex $argv 0]
set UserName [lindex $argv 1]
set PW [lindex $argv 2]
set Prompt "\[#$%<>\]"

set timeout 30
spawn telnet ${RemoteHost}
expect -re "\[Uu\]sername|\[Ll\]ogin" {

  ### With Username
  send -- "${UserName}\r"

    ### With Username & Password
    expect -re "\[Pp\]ass\[Ww\]ord" {

      ### Login
      send -- "${PW}\r"
      expect -re ${Prompt}

    ### With username, Without Password
    } ${Prompt} {
      ### After Login

    }

### Without Username & Password
} ${Prompt} {
  ### After Login
    
### Catch Error
} default { 
  exit 2 
} timeout {
  exit 2
} # END

### Run Commnads
set i 3
while { [lindex $argv $i ] != "" } {
  set CMD [lindex $argv $i ]

  send -- "${CMD}\r"
  expect -re ${Prompt}
  incr i
}

exit 0

```

## 実行してみる
sudo chmod +xなどで実行権限をつけましょう。
4番目の以降の引数が全てコマンドと認識され、リモートで実行されます。
パスワードない場合など、ログインに必要な引数が3つに満たない場合は、無い引数に '' を渡してください。

```
### 実行方法
./telnetpass.exp (ip) (username) (password) (command 1) (command 2) ... (command N)
```
```
ubuntu@ubuntu01:$ ./telnetpass.exp 172.24.0.100 ubuntu ubuntu123 'ls /home' 'echo hoge' 'echo fuga'

spawn telnet 172.24.0.100
Trying 172.24.0.100...
Connected to 172.24.0.100.
Escape character is '^]'.
Ubuntu 16.04.5 LTS
ubuntu02 login: ubuntu
Password: 
(snip)
ubuntu@ubuntu02:~$ ls /home
ubuntu
ubuntu@ubuntu02:~$ echo hoge
hoge
ubuntu@ubuntu02:~$ echo fuga
fuga
ubuntu@log-sv-client01:~$ ubuntu@ubuntu01:$
```

パスワードがヒストリに残る？
Telnetは暗号化されてないから使うべきではない？
(´・ω・｀)
TouchDesignerとRealsenseの連携（平面から3Dモデルを作成）

インテル RealSenseとTouchDesignerとの連携をさせてみたいと思います。

やることはRealSensenの映像から3Dデータを作るというものなのですが、ここで言う3Dモデルというのは完全な人型とか物体の3Dモデルを作るのではなく平面に奥行きを持たせた3Dモデルになります。あしからず。。

ネットワークはこんな感じになります。
<img width="845" alt="スクリーンショット 2018-10-15 20.44.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/31194/ba3ec7c8-6f06-724a-1024-036cc0939c23.png">
Realsense TOP > Level TOP > Chroma key TOP > Blur TOP > Trace SOP > Extrude SOP > Polyreduce SOP > Transform SOP


###Realsense TOP
<img src="https://qiita-image-store.s3.amazonaws.com/0/31194/5a8d0d74-c3d1-bc45-3ebd-f13258e40a97.png" width=50%>

まずはRealsense TOPです。
Realsenseの接続、設定等は済ませておけば、Realsense TOPをつなぐだけで映像が取得できると思います。
デフォルトではRGBカメラの映像になっているのですが今回はDepthカメラを使います。
Depthカメラでは映像中の奥行きをグレースケールで表示することができます。

Mirror ImageをONにすると鏡面映像になるので、ディスプレイや投射した映像に向かってインタラクティブな表現をしたい場合はONにしておくと良いかもしれません。
またMax Depthは深度を図る範囲（奥行き）になります。
デスクでイスに座って人の像を取得したいという場合はデフォルトの5で良い感じでした。

###Level TOP
<img src="https://qiita-image-store.s3.amazonaws.com/0/31194/9ff3be2f-0ee4-aa6f-ff06-7587ec159e92.png" width=50%>
次はRealsenseで取得した映像をLevel TOPで調整します。
まずは白黒反転のためInvertを1にします。
そしてその他のパラメータを、暗い部分は暗く、明るい部分は明るく、中間のグレーは階層がわかりやすいようにという感じに調整します。
コントラストも少し付けます。
ここのパラメーターは環境によってかなり異なってきますので、各自の環境に合わせて値を変える必要があります。

###Chroma key TOP
<img src="https://qiita-image-store.s3.amazonaws.com/0/31194/a68e0534-199a-bfe3-e2db-ec30cd26afd8.png" width=50%>
Level TOPで調整した映像から白と黒の部分を削除し、中間のグレーの階層の映像だけにします。
これはValタブのVal MinとVal MaxをいじってあげればOKです。


###Blur TOP
<img src="https://qiita-image-store.s3.amazonaws.com/0/31194/a87f2a7c-b3da-d665-ac31-e8b552f99a05.png" width=50%>
そしてSOPにする前にBlurをかけます。Blurをかけなくてもいいのですが、かけずにそのままSOPにすると頂点数が多くなってしまうので、ここで丸めます。

###Trace SOP
<img src="https://qiita-image-store.s3.amazonaws.com/0/31194/ca334995-97f8-bd4f-b377-22cc2be873d2.png" width=50%>
Trace SOPは平面画像の指定の閾値でトレースした絵の平面ポリゴンを作ってくれます。
今回は特にパラメーターをいじってませんが必要に応じて閾値（Threshold）を変更しても良さそうです。

###Extrude SOP
<img src="https://qiita-image-store.s3.amazonaws.com/0/31194/26fcc32e-1931-fb6c-4fa9-009a4e46df4f.png" width=50%>
Extrude SOPで平面ポリゴンを押し出します。
必要に応じてDepth Scaleを変更するなどします。

###Polyreduce SOP
<img src="https://qiita-image-store.s3.amazonaws.com/0/31194/72eda638-2c8a-da3c-9692-d5df6998d846.png" width=50%>
このSOPはポリゴンを減らしてくれるのですが、パーセンテージかポリゴン数かオブジェクトまでの距離で削減数を指定します。
あまりやり過ぎるとモデルが割れるのでここも絵によって調整が必要です。

###Transform SOP
<img src="https://qiita-image-store.s3.amazonaws.com/0/31194/fb26ccc6-ef4e-3f6b-74ac-637e667d3acb.png" width=50%>
これは単にサイズや位置調整のためだけです。

Kinectでも同じことができるのですが、これができるとパーティクルや他の3Dモデルとの衝突判定ができるのでインタラクティブな作品を作るときに便利ですね:satisfied:

最後にYouTubeのリンクを貼っておきます。
[![IMAGE ALT TEXT HERE](https://qiita-image-store.s3.amazonaws.com/0/31194/33f69461-7374-b0ec-139f-c12816a7ba32.png)](https://www.youtube.com/watch?v=a0GU_qrg-nE)