OmniAICreator/Qiita-1.07M huggingface dataset:
コード化された UI テストをさまざまなブラウザで

# ゴール

- Web アプリをテスト
- さまざまなブラウザで
  - テストコードは共有したい
- 環境: Visual Studio 2017

---

# 前半：コード化された UI テスト

- 公式ページ

  - UI オートメーションを使用してコードをテストする
  - [https://msdn.microsoft.com/ja-jp/library/dd286726.aspx](https://msdn.microsoft.com/ja-jp/library/dd286726.aspx)

---

## 1. テストを追加

- *コード化された UI テスト プロジェクト* を追加する
- 2つ目以降の *CodedUITest* を追加するには
  - プロジェクトを右クリック > *追加* > *コード化された UI テスト*

---

### トラブルシューティング: コード化された UI テストが無い

- Visual Studio のメニューに *コード化された UI テスト* が無い
  - 次のコンポーネントのインストールが必要
  - Visual Studio Installer > Visual Studio Enterprize 2017 > 変更 > 個別のコンポーネント > デバッグとテスト > *コード化された UI テスト*

---

## 2. レコーディング

- IE を立ち上げておいて、レコーディング開始

---

## 3. ブラウザ (IE) を起動するコードを追加

```C#
BrowserWindow.Launch(
    new Uri("https://www.google.com/"));
```

---

### Tips: コードで起動したブラウザをテストにアタッチ

- *UIMap.uitest* で *Window* の *検索プロパティ* を `Name` - `Contains` - `google` などと指定する

---

### トラブルシューティング: テストが認識されない

- テスト エクスプローラーに出てこない
- `[TestMethod]` が水色にならない
  - .csproj で `PropertyGroup` の中の `IsCodedUITest` の値を `True` にする

---

# 後半：さまざまなブラウザで実行

- 公式ページ

  - コード化された UI テストでのさまざまな Web ブラウザーの使用
  - [https://msdn.microsoft.com/ja-jp/library/jj835758.aspx](https://msdn.microsoft.com/ja-jp/library/jj835758.aspx)


---

## 1. Selenium をインストール

- Selenium components for Coded UI Cross Browser Testing
- [https://marketplace.visualstudio.com/items?itemName=AtinBansal.SeleniumcomponentsforCodedUICrossBrowserTesting](https://marketplace.visualstudio.com/items?itemName=AtinBansal.SeleniumcomponentsforCodedUICrossBrowserTesting)

---

## 2. レコーディング

- レコーディングできるのは IE のみ

---

## 3. 再生する

- IE で再生するには `BrowserWindow.CurrentBrowser` に `"IE"` と設定する（既定値）
- IE 以外のブラウザのときはここを変える
  - IE 以外のブラウザは Selenium 経由で起動される

---

### コード例: Chrome を起動する

```C#
BrowserWindow.CurrentBrowser = "Chrome";
BrowserWindow.Launch(
    new Uri("https://www.google.com/"));
```

---

### Tips: 連続実行

- ブラウザを変えながら連続実行するには
  - 同一`[TestMethod]` 内では難しい
  - `[TestMethod]` は分けておいて、それら複数テストの実行ならばできる
  - それぞれの `[TestMethod]` から共通のテストコードを呼べばよい

---

### ブラウザ対応状況

<table>
<tr>
<th>ブラウザ</th>
<th>CurrentBrowser名</th>
<th>制限</th>
</tr>
<tr>
<td>Edge</td>
<td>MicrosoftEdge</td>
<td>日本語入力できない (後述)</td>
</tr>
<tr>
<td>Chrome</td>
<td>Chrome</td>
<td></td>
</tr>
<tr>
<td>FireFox</td>
<td>FireFox</td>
<td>v48 以降は動かない</td>
</tr>
<tr>
<td>Opera</td>
<td>(未対応)</td>
<td></td>
</tr>
</table>

---

### トラブルシューティング: Edge で日本語入力できない

Edge で日本語入力できない問題は、 `ExecuteScript` で回避できます。

```c#
public void RecordedMethod1()
{
    ...
    //uINameEdit.Text = this.RecordedMethod1Params.UINameEditText;
    this.UIHogeWindow.ExecuteScript($"document.getElementsByName('Name')[0].value = \"{this.RecordedMethod1Params.UINameEditText}\"");
    ...
```

---
リンクの無効化(IE10/9)

# リンクの無効化
`pointer-events:none;` を指定

# IE10・9向けの指定方法

```
.xxxxx {
  position: relative;
}
.xxxxx:after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0,0,0,0);
}
```
GitBookからSNSシェアボタンを削除する

![remove-share-button.png](https://qiita-image-store.s3.amazonaws.com/0/186574/6e886b42-9ba2-7fd6-35cc-6b3a14d0241e.png)

## 全て削除する場合

全て削除するのであれば`book.json`の`plugins`に`-sharing`を追加するだけです。

```js
// book.json
{
    plugins: ["-sharing"]
}
```

## 細かく設定する場合

`Twitter`は表示、`Facebook`は非表示という風に細かく設定する事もできます。

### `book.json`に設定を記述

※ `plugins: ["-sharing"]`は不要です。

```js
// book.json
{
    "pluginsConfig": {
        "sharing": {
            "facebook": true,
            "twitter": true,
            "google": false,
            "weibo": false,
            "instapaper": false,
            "vk": false,
            "all": [
                "facebook", "google", "twitter",
                "weibo", "instapaper"
            ]
        }
    }
}
```

## 参考

- [gitbook-plugin-sharing](https://www.npmjs.com/package/gitbook-plugin-sharing)
- [Remove social icons on gitbooks.io · Issue #1126 · GitbookIO/gitbook · GitHub](https://github.com/GitbookIO/gitbook/issues/1126)
最低限やっておくべきセキュリティ設計（OS編）


# はじめに
 サーバを立てる際に、セキュリティの観点から最低限やっておくべき設定みたいなものがあまりまとめられていないなと思い、エントリーしようと思いました。
 詳細な設定方法については記載しません。あくまでも設計時に考慮すべき項目として列挙していきます。詳細な設定方法は別途調べてください。
 今回まとめたもの以外にも、これ設定するべきだ、というものがありましたら、どしどしコメントください。追加していければなと思います。
 また、今回はOS編ですが、ネットワーク編やWebサーバ（Apache,Nginx）編などもエントリーしていこうと思います。

# 環境
 いったんCentOS6/7のみ

# 前提
 Webサーバ以外のサーバ（AP,DB,batchなど）のセキュリティ設計を行う場合を想定しています。Webサーバなど外部からのアクセスを直接受けるサーバについては、別途Webサーバ編で書きます。

# 1. パッケージアップデート
 サーバを立ててまずはじめに実施しておきたいのは、全パッケージのアップデートです。
 古いバージョンのパッケージなどがあって、脆弱性を突かれないために、はじめにアップデートしておきます。
 
 ```
 # yum -y update
 ```
 
# 2. iptables(firewalld)
 CentOS6ではiptables、CentOS7ではfirewalldになっていますが、不要なポートが開いてしまっていないように設定します。また、ssh通信の制限などを行います。
 
 [CentOS6の場合]


 ```
  # 設定ファイル編集
  vi /etc/sysconfig/iptables
  # iptablesサービスを再起動
  service iptables restart
  # 自動起動設定に追加
  chkconfig iptables on
 ``` 
 
 正しく設定されているか、Nmapで確認する。
 
 ```
  nmap -p 1-10022 hostname
 ```
 
 
 [CentOS7の場合]
 
 ```
  # 設定ファイル編集
  vi /etc/firewalld/services/*.xml
  # 設定再読み込み
  firewall-cmd --reload
  # firewalldサービスを再起動
  systemctl stop firewalld
  systemctl start firewalld
 ```
 
# 3. rootユーザのsshログイン禁止
 rootユーザとは別にユーザを別途作成し、rootユーザはsshログインできないように設定します。rootユーザでsshログインできてしまうと、不正にログインされたときに何でもできてしまうので、禁止します。
 
 ```
  # 設定ファイル編集
  vi /etc/ssh/sshd_config
  # sshdサービスの再起動
  service sshd restart
 ```

# 4. ログインユーザ認証設定（公開鍵認証によるSSHログイン）
 パスワード認証よりもよりセキュアな公開鍵認証にすることでセキュリティレベルを高めます。

# 5. SELinux
 SELinuxとはアクセス制御する機能です。設定するとセキュリティレベルは上がりますが、アクセス制御の設計が複雑になるため、利用するかしないかは各プロジェクトの要件によるのかなと思います。
 
 ```
  # 設定ファイル編集
  vi /etc/sysconfig/selinux
  # 設定反映
  サーバ再起動
  # 設定反映の確認
  getenforce
 ```

# 6. SSHポート番号変更
 
 [CentOS6の場合]

 ```
  # 設定ファイル編集
  vi /etc/ssh/sshd_config
  # sshdサービス再起動
  service sshd restart
 ```  
 
 [CentOS7の場合]
 
 ```
  # sshd設定ファイル編集
  vi /etc/ssh/sshd_config
  # firewalldの設定からssh削除
  firewall-cmd --permanent --remove-service=ssh
  # firewalldのデフォルト設定ファイルコピー
  cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/ssh-ポート番号.xml
  # firewalldの設定ファイル編集 
  vi /etc/firewalld/services/ssh-ポート番号.xml
  # firewalld設定追加
  firewall-cmd --permanent --add-service=ssh-ポート番号
  # firewalld設定反映
  firewall-cmd --reload
 ```

# 7. 不要なサービス停止
不要なサービスは停止しておき、脆弱性を突かれるリスクをなくしておきます。
 
 [CentOS6の場合]

 ```
  # サービス一覧表示
  chkconfig --list
  # 不要なサービスを停止
  service 'サービス名' stop
  chkconfig 'サービス名' off
 ```

 [CentOS7の場合]
 
 ```
  # サービス一覧表示
  stemctl list-unit-files -t service
  # 不要なサービスを停止
  systemctl stop 'サービス名'
  systemctl disable 'サービス名'
 ```

# 最後に
 サーバ立てる際の最低限やっておくべきセキュリティの設定は以上となります。
 Ansibleなど構成管理ツール管理、運用しているところとかは、このあたりをplyabookのテンプレートなどに設定しておくと便利ですね。
 

# 参考
Linuxサーバ構築標準教科書(Ver2.0.1)
http://www.lpi.or.jp/linuxtext/server.shtml
https://www.websec-room.com/2014/02/09/1822
http://fnya.cocolog-nifty.com/blog/2012/03/centos-6aa8.html
Swift3で特定の文字列の中から数字を抽出する方法

# はじめに
最近Swiftを触り始めました。

特定の文字列から数字を抽出する必要があったのですが、正規表現など使わずに簡単に実装する方法を探していたところ、下記サイトと先輩からのアドバイスで結構簡単に実装することが出来ました。

**参考**
http://programming-ios.com/swift-retrieve-int-from-string/


今回はこちらのサイトを参考にSwift3で文字列から数字の抽出方法をメモ代わりに残しておきます。


# 実装方法

```swift
let mixedString = "123abc456def"
let splitNumbers = (mixedString.components(separatedBy: NSCharacterSet.decimalDigits.inverted))
let number = splitNumbers.joined()

print(number) // "123456"
```

結構簡単に文字列から数字を抽出することが出来ました。
以上です。
numpy.ndarrayの代入について

# numpy.ndarrayの代入でハマったのでメモ

## 三行で書くと
- np.ndarrayのスライスとマスクについて．
- 単純に使う場合には元のオブジェクトに代入するときに同じように使える．
- スライスはviewを返すが，マスク(fancy index)はcopyを返すのでchainさせたり複雑なことするときは注意が必要．

## ndarrayのスライスとマスク
御存知の通りndarrayはスライスで指定した範囲に対して代入することができます．

``` python:slice.py
In [1]: import numpy as np

In [2]: table = np.zeros((2, 5))

In [3]: table[1, :3] = 1

In [4]: table
Out[4]:
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  0.,  0.]])
```

これはスライスで指定するとndarrayがcopyではなく，referenceを返すから．

また，Booleanによるマスクでも同様のことができます．

``` python:mask.py
In [1]: import numpy as np

In [2]: table = np.zeros((2, 5))

In [3]: table[1, [True, True, True, False, False]] = 1

In [4]: table
Out[4]:
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  0.,  0.]])
```
同じですね．


## ハマったポイント: ndarrayのスライスとマスクのchain
ではこれをchainさせてみましょう．

``` python:chain1.py
In [1]: import numpy as np

In [2]: table = np.zeros((2, 5))

In [3]: table[1, :3][1:] = 1

In [4]: table
Out[4]:
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  1.,  1.,  0.,  0.]])
```

スライスは，Referenceを返すので，ReferenceのReferenceはReferenceということで，無事元のtableに代入することができました．簡単ですね．
では，同じことをマスクについてもやってみましょう．

``` python:chain2.py
In [1]: import numpy as np

In [2]: table = np.zeros((2, 5))

In [3]: table[1, [True, True, True, False, False]][[False, True, True]] = 1

In [4]: table  # 代入されてない!!!!
Out[4]:
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])
```

あれ，思ったのと違う結果がでてきました．

``` python:chain3.py
In [1]: import numpy as np

In [2]: table = np.zeros((2, 5))

In [3]: table[1, [True, True, True, False, False]][1:] = 1

In [4]: table  # 代入されてない!!!!
Out[4]:
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])
```

mask+sliceのチェーンも同じです．

どういうことなんでしょうか...

## 原因と説明

公式のドキュメントに詳しい説明がのっています．
http://scipy-cookbook.readthedocs.io/items/ViewsVsCopies.html

But fancy indexing does seem to return views sometimes, doesn't it?
の節を確認すると，

```python:sample1.py
>>> a = numpy.arange(10)
>>> a[[1,2]] = 100
>>> a
array([  0, 100, 100,   3,   4,   5,   6,   7,   8,   9])
```
と

```python:sample2.py
>>> a = numpy.arange(10)
>>> c1 = a[[1,2]]
>>> c1[:] = 100
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> c1
array([100, 100])
```

について違いが説明されています．今回もこのパターンです．

結論からいうと，
mask (fancy index)は実はviewを返しているわけではありませんでした．

maskで元のobjectを上書きできたのは，viewを返しているからではなくpythonのインタープリターがinplaceの式に変換していたからだということです．

```python:fancy_index1.py
>>> a[[1,2]] = 100
```
は

```python:fancy_index1_translated.py
a.__setitem__([1,2], 100)
```
に変換されるため，元のaの値が変更されたということです．しかし，

```python:fancy_index2.py
c1 = a[[1,2]]
```
は

```python:fancy_index2_translated.py
c1 = a.__getitem__([1,2])
```
とviewではなく，copyを返すため，二行に分けた瞬間に結果が変わるということになります．

これを応用することで，chain2.py，chain3.pyの結果も説明できます．

```
table[1, [True, True, True, False, False]]
```
はコピーを返すため，その後でいくら上書きしても元のtableは変更されないわけですね．


## 最後に問題

``` python:chain4.py
In [1]: import numpy as np

In [2]: table = np.zeros((2, 5))

In [3]: table[1, :3][False, True, True] = 1

In [4]: table
Out[4]: ???
```

これはどのような結果を返すでしょうか??
GitBookで除外ファイルを設定して_bookに不要なファイルを追加させない


GitBookでは作業ディレクトリに作られたファイルは基本的に`_book`にも追加されてしまいます。

GitBookは`.gitignore`と`.bookignore`と`.ignore`に記述されたリストを除外リストとして扱うので、これらのファイルに記述することで対応可能です。

`.gitignore`だとGit管理からも外れてしまうので、Git管理しながらGitBook管理から外すには`.bookignore`が適しています。

## `.bookignore`を作成して記述する例

```bash
# ignore self
.bookignore

# ignore npm files
yarn.lock
package.json
```

## 参考

[Directory structure · GitBook Toolchain Documentation](https://toolchain.gitbook.com/structure.html)

> ### Ignoring files & folders
> GitBook will read the `.gitignore`, `.bookignore` and `.ignore` files to get a list of files and folders to skip. The format inside those files, follows the same convention as `.gitignore`:
MacOSX の less で色付け


をしようとして、確認。


```shell
$ brew info source-highlight
source-highlight: stable 3.1.8 (bottled)
Source-code syntax highlighter
https://www.gnu.org/software/src-highlite/
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/source-highlight.rb
==> Dependencies
Required: boost ✘
```

おおっと、やっぱりか。

```shell
$ brew install source-highlight
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 2 taps (caskroom/cask, homebrew/core).
==> New Formulae
<snip>
==> Installing source-highlight
==> Downloading https://homebrew.bintray.com/bottles/source-highlight-3.1.8_5.el_capitan.bottle.tar.gz
######################################################################## 100.0%
==> Pouring source-highlight-3.1.8_5.el_capitan.bottle.tar.gz
==> Caveats
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d
==> Summary
🍺  /usr/local/Cellar/source-highlight/3.1.8_5: 422 files, 6MB
```

終了。

あれ？ `src-hilite-lesspipe.sh` は何処？

```shell
$ find . -name src-hilite-lesspipe.sh -print 2>/dev/null
./usr/local/bin/src-hilite-lesspipe.sh
./usr/local/Cellar/source-highlight/3.1.8_5/bin/src-hilite-lesspipe.sh
```

へぇ、ここに配置されたのかぁ。
`~/.bashrc` に、

```bash
export LESSOPEN='| /usr/local/bin/src-hilite-lesspipe.sh %s'
export LESS='-gj10 --no-init --quit-if-one-screen --RAW-CONTROL-CHARS'
```

を指定しました。
C++ のライブラリを読むときに見るところ

[ブログ記事](http://secret-garden.hatenablog.com/entry/2015/07/23/203059)からの転載です。

そこまで頻繁に読んでるわけではないのですが、たまーに C++ のライブラリを読んだりしています。  
そんな時にわたしが特に注意している点を簡単にまとめて見ました。

## 予約済み識別子を意識してるか

C++ では以下の条件を満たす名前は将来的に予約語になる可能性があるため、回避する必要があります。  

* グローバルスコープを持ち、_ で始まる名前
* _ で始まり、その次が大文字の名前
* __ を含む名前

`_` から始まる名前は避けたほうがよいという感じです。  
例えばよくみかけるのがインクルードガードマクロで、 `__XXX_H__` というような名前を使っているのですね。  
これは『__ を含む名前』にあてはまるので違反です。  
その時点ではコンパイルエラーになるわけではないので結構違反しているコードが多いですね。  
あとは違反ではないのですが、メンバ変数で `_xxx` という風に `_` から始まる名前を使っている書き方もちょっと気になったりします。  
メンバ変数名であれば問題はないんですが、グローバルスコープだと違反になったりとややこしいので `xxx_` という風に末尾に `_` をつける事が多いですね。  

## namespace を使ってるか

基本中の基本。  
なのだけれど全く使ってないライブラリが多いのも事実。  
C++ を使ってる人なら__当然__わかるとおもいますが、 namespace を使っていないなんて何が起こるかわかったものじゃないですよね。  
以前、namespace を使ってないライブラリの中の人に『std 名前空間と衝突しない設計をしてるので問題がない。コードの短さを優先してる』と言われたことがあります。  
それは開発者側の意見で使う側からすれば何が衝突するかわかったものじゃないですよね…。  
そもそも短くしたいならユーザ側で `using namespace` すべきであって開発者側が推奨するべきでは(ry  
namespace (と using) は用法用量を守って正しく使いましょう。

## クラス名や関数名にライブラリ名の prefix を使っていないか

これもよくありがち。  
何故か namespace は使ってないのに関数名やクラス名にライブラリ名を prefix としてつける謎。  
namespace を使ってるのに関数名やクラス名にわざわざライブラリ名を prefix としてつけるのはもっと謎。  
どんだけそのライブラリ名を書きたいんだ。  
ちゃんと namespace を使っていれば prefix は必要はないはずです。  
名前の衝突が嫌であれば namespace を使いましょう。  

## マクロは使っていないか

もちろんマクロを使うべき場面は存在するんですが、C++ では定数定義などをマクロで定義するべきではないですね。  
この間見ていたライブラリで `static const` を使って定数を定義している真下にマクロを使った定数定義があって頭が痛くなりました…。  
それ以外にも `SAFE_RELEASE()` みたいなマクロ関数のも基本的に使うべきではないですねー。  
たいていはマクロを使う必要がない場面がほとんどなはずです。  

## C++11 以降のコードになってるか

むしろライブラリとしては C++03 に準じてた方が使い勝手がいいんじゃないか？と思わなくもないんですが、どのバージョンに対応しているのかはコードの質にも関わってくるので気になりますよねー。  
C++14 のコードで書かれてると『お、ちゃんと最新版の C++ に対応していてやるな』とニヤニヤする。

## const をちゃんと使ってるか

さすがに使ってないライブラリはほとんど見ませんが、`const` を使ってるか使ってないかではライブラリの使い勝手が全然違うのでかなり重要なポイントですね。  

## 所感

と、いう感じで簡単にまとめてみました。  
そこまで多くのライブラリをみているわけではないのですが、やっぱり予約済み識別子や namespace を意識してないライブラリが結構目立つ印章ですね。  
知識として予約済み識別子を知らないのはまぁしょうがないんですが、namespace は使う側にとっても影響してくるのでちゃんと使ってほしいところではありますねぇ。  
他の人がどんなところを見ているのかも気になる。

## おまけ：逆にあまり見ない点

* コーディングスタイル
* インデント
* コメントの有無

全く見ないといえば嘘になるんですが、コーディングスタイルとかはよっぽど奇抜ではない限りそこまで気にしませんね。  
インデントもタブだろうがスペースだろうがライブラリに置いてはあまり重要なポイントではないです。  
コメントもまぁあったらあったでいいんですが、ドキュメントがちゃんと書かれていればまぁ使う上では問題ないかなーと思うので気にならないですね（自分で保守する必要があるライブラリであればまた違ってきますが…。
RocketChatを導入する手順


AmazonLinuxにRocketChatをインストールして使用する手順。

## 必要なミドルウェアのインストール

GraphicsMagickとNode.jsをインストール。

```
sudo yum install GraphicsMagick
sudo yum install nodejs npm --enablerepo=epel
```

MongoDBをインストールするためにリポジトリを追加。
「/etc/yum.repos.d/」に「mongodb.repo」というファイル名で作成。

```mongodb.repo
[MongoDB]
name=MongoDB Repository
baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64
gpgcheck=0
enabled=1
```

MongoDBをインストール

```
sudo yum install mongodb-org-server
sudo yum install mongodb-org
```

## RocketChatのインストール

RocketChat用のユーザーとグループを追加。

```
sudo groupadd rocketchat
sudo adduser rocketchat -g rocketchat
```

RocketChat本体を公式からダウンロードし配置する。

```
wget -O rocket.chat.tgz https://rocket.chat/releases/latest/download
tar zxvf rocket.chat.tgz
mv bundle Rocket.Chat
sudo mv Rocket.Chat /opt/
sudo chown rocketchat:rocketchat -R /opt/Rocket.Chat
```

配置したディレクトリに移動し、npmコマンドを実行する。

```
cd /opt/Rocket.Chat/programs/server
sudo npm install -g inherits
sudo npm install
```

ここまででRocketChatのインストールが完了。
下記のように環境変数を設定して実行すればアプリケーションが起動する。

```
sudo su - rocketchat
export MONGO_URL=mongodb://127.0.0.1:27017/rocketchat
export ROOT_URL=http://{ホスト名}
export PORT=3000
cd /opt/Rocket.Chat
node main.js
```

下記のURLにアクセスするとRocketChatが開く。
http://{ホスト名}:3000


この後、Webサーバや起動設定を行なったが前回投稿したMatterMostと被るので省略。

RocketChatは前回導入したMatterMost同様にSlackクローン的なソフトウェアの１つ。
MatterMostは実際は機能が不足していたため不採用となったのでこちらを試してみることとなった。
GitBookのサイドバーの「Introduction」の文字を変更する


`./SUMARY.md`に`./README.md`のリンクを好きなテキストで設置するだけです。


```diff
# Summary

+ * [はじめに](README.md)
```


![gitbook-change-introduction-text.png](https://qiita-image-store.s3.amazonaws.com/0/186574/9309b0fd-86b4-af76-fff4-e4b07eebf429.png)

## 参考

- [Don't set main README.md file as 'introduction' on the index · Issue #476 · GitbookIO/gitbook · GitHub](https://github.com/GitbookIO/gitbook/issues/476)
- [How to change "Introduction" text in summary column? · Issue #388 · GitbookIO/gitbook · GitHub](https://github.com/GitbookIO/gitbook/issues/388)
React Fiberの「Fiber」とはなんなのか勉強してみた

色々素敵な記事が既に存在してはいますが、自分自身の理解を深めたく、React FiberのFiberとはなんなのか勉強してみたものをまとめました。
尊敬の念を込めて、大変勉強になった素晴らしい記事たちを先に紹介しときます。

* [React Fiber現状確認](http://blog.koba04.com/post/2017/04/25/a-state-of-react-Fiber/)
* [ReactはなぜFiberで書き直されたのか？Reactの課題と将来像を探る](https://html5experts.jp/shumpei-shiraishi/23265/)
* [React Fiberアーキテクチャについて](http://postd.cc/react-Fiber-architecture/)

###解説しないこと
* Fiber以外のReact ver.16以降での変更点
    * あくまでFiberとはなんなのかにフォーカスします。
    * (ただ個人的には `render()` の結果を文字列や配列で返せるようになるのは超嬉しいです。)

React Fiberを理解するための前提知識
------------------------------
React Fiberを理解するにあたって重要なキーワードは次の3つです。

* リコンシリエーション
* 作業
* スケジューリング

FiberはReactのリコンシリエーションの新しいアルゴリズムです。
このためFiberとは何ぞやを理解するためにはリコンシリエーションとは何ぞやを理解する必要があります。

###リコンシリエーションとは
端的に言うと「どの部分に変更が必要か判断すべく、ツリー同士の差分を出すアルゴリズム」です。

詳しくは[Reactのドキュメント](https://facebook.github.io/react/docs/reconciliation.html)にまとまっていますが、
簡単に解説すると、Reactはご存知の通りVirtual DOMを内部的に保持しており、Stateの更新が起きた時に、
以前のVirtual DOMとStateの更新によって変更が入ったVirtual DOMのdiffを取って最小限のリアルなDOMの更新をするように努めています。

このdiffの取り方・アルゴリズムこそがリコンシリエーションです。
特に重要なポイントとしては以下の2点が挙げられます。

* コンポーネントの種類が異なると、生成されるツリーも大幅に異なったものになることが想定される。そのような場合、Reactは差分を出すのではなく、元のツリーを完全に置き換えようとする。
* リストの差分計算は、キーを使って実行される。キーは「安定性があり、予測でき、一意である」ことが求められる。

###作業とスケジューリングとは
* 作業
    * 実行されなければならない計算。作業は通常、更新（例えばsetState）の結果として生じる。
* スケジューリング
    * 作業が実行されるべきタイミングを判断するプロセス。

スケジューリングは基本的に更新処理のタイミングを決定するためのものであり、そしてこれがFiberというものが必要になった原因なのですが、
従来のReactでは「仮想DOMのツリーを上から再帰的に比較していく」というスケジューリングの仕方がなされていました。

これの何が問題なのかと言うと
「リコンシリエーションによって更新が決定したもの全ての更新処理が終わるまで他の処理をブロックしてしまい、また中断することもできない」という点です。
UI上では必ずしも全ての更新が即座に適用される必要はありません。
更新処理が多くなると、即座に更新する必要のない部分の更新のために画面がフリーズしてしまい、ユーザ体験を阻害する恐れがあります。

これをよしとせず、すぐに更新しなければいけない部分とそうでない部分を分けて、
ユーザ体験に重要な部分に対して優先度を付けられるようにしよう、というのがReact Fiberが実現しようとしていることです。

Fiberとは
------------------------------
前の項でそこそこ概要を説明してしまった気もしますが、
初めにFiberという言葉自身の定義を述べると `作業の構成単位` という意味になります。

先の項で述べたようにReact Fiberは「更新処理に優先度が付けられるようにする」ことを目指したものです。
それを実現するために以下のようなことを実行しています。

* リコンシリエーションをツリー全体に対してではなく、Fiberの単位で実行する
    * `ReactElement`毎の更新処理をLinked Listにして、それぞれを独立したものとして扱えるようにしている
* `requestIdleCallback()`や`requestAnimationFrame()`を使って、優先度付きのスケジューリングを擬似的に行う
    *  `requestIdleCallback()`を使って指定されたFiberはブラウザの処理がひまになった時に実行される
    *  `requestAnimationFrame()` を使って指定されたFiberは優先度が高く、できるだけ早いタイミングで実行される

まとめるとFiber単位での優先度付きスケジューリングが可能になるよ、ということですね。
スケジューリングの具体的な仕方については[こちらの記事](http://blog.koba04.com/post/2017/04/25/a-state-of-react-fiber/)が詳しいため、知りたい場合はご覧になることをお勧めします。

まとめ
------------------------------
フロントエンド開発において「いかにUIをブロックせずにユーザ体験に大切なところだけを表示するか」
というのは重要な命題なので、Reactのリコンシリエーションのレベルで直接優先度付けできるようになったというのは、
アプリケーションによっては大きなメリットになりえるのかなと思いました。
[Xcode 8] Swiftのドキュメントコメントについての簡潔なまとめ

# 概要

自分自身、しばしばドキュメントコメントの書き方を忘れてしまうので、使う頻度が高いものを簡潔にまとめました。

# 前提とする環境

| Item | Version |
|:--|:--|
| Xcode | 8.x |
| Swift | 3.x |

# 基本的な書き方

```swift
/// サンプルメソッド
///
/// - Parameters:
///   - paramA: パラメータAの説明
///   - paramB: パラメータBの説明
/// - Returns: 戻り値の説明
func sampleMethod(paramA: String, paramB: String) -> String {
    return paramA + paramB
}
```

上のようにドキュメントコメントを記載しておき、呼び出し元で[alt]キーを押しながらクリックすると、以下のように表示されます。
<img width="517" alt="スクリーンショット 2017-06-11 21.12.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/122917/b1d0cdb0-cd94-76db-16e5-14d08e81f7d4.png">


# ドキュメントコメント・テンプレートの挿入方法

関数を宣言している行にカーソルがある状態で、メニューバーから以下を選択します。

- Editor > Structure > Add Documentation

![スクリーンショット 2017-06-11 17.10.50.png](https://qiita-image-store.s3.amazonaws.com/0/122917/1b212ab5-e729-65aa-e69e-5dd3ddd7dd80.png)

すると、こんな感じでテンプレートが挿入されます。
<img width="433" alt="スクリーンショット 2017-06-11 21.14.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/122917/1600c40f-c267-03ce-57f5-0f0684c7a2ad.png">

# 特殊タグ

```swift
// MARK: - 罫線付きのセクション見出し
// TODO: 「後で○○しなければならない」の意味
// FIXME: 「○○を修正する必要がある」の意味
```

上のような特殊タグを記述すると、Xcodeでは以下のように表示されます。
<img width="612" alt="スクリーンショット 2017-06-11 22.53.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/122917/d3b35125-81ab-d216-84ae-9e0cc3f25782.png">

プロジェクト内で「TODO:」や「FIXME:」が記載された箇所を一覧で確認する方法（Eclipseの「タスク」ビューのような機能）を調べてみたのですが、普通に文字列検索するしかないようです。:sweat_smile:
<img width="265" alt="スクリーンショット 2017-06-11 21.35.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/122917/d9337ea8-9f3d-eb9f-f7bf-69b69dc62c15.png">

# 補足

詳しい情報は、こちらに記載されています。

[Markup Formatting Reference](https://developer.apple.com/library/content/documentation/Xcode/Reference/xcode_markup_formatting_ref/index.html)
is_intを使ってFizzBuzz

```php:code.php
<?php
for ($i=1; $i < 101; $i++) {
  $b=true;
  if (is_int($i/3)) {
    echo "Fizz";
    $b = false;
  }
  if (is_int($i/5)) {
    echo "Buzz";
    $b = false;
  }
  if ($b) {
    echo $i;
  }
  echo "<br>";
}
```

is_intを使った方法がどこにもなかったので。

```
if ($i % 3 == 0) {
```

```
if (is_int($i/3)) {
```

文字数はそんなに変わらない。
Rails4+PDFKit+AmazonLinux でPDF出力

2017/06/10
Rails4でPDFを作成しようとした際に、結構ハマりましたので、備忘として残します。

##構成
Ruby on Rails 4
Amazon Linux
PDFKit
wkhtmltopdf 12.4

##手順
RailsでPDF作成をするにはいろいろな方法があると思いますが、今回はPDFKitとwkhtmltopdfを使います。

まず、wkhtmltopdfをインストールします。（https://wkhtmltopdf.org/）

```shell:shell
$ sudo wget https://downloads.wkhtmltopdf.org/0.12/0.12.4/wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
$ sudo tar -xvf wkhtmltox-0.12.4_linux-generic-amd64.tar.xz
$ sudo mv wkhtmltox /usr/local/lib/
$ sudo cd /usr/local/lib
$ sudo ln -s /usr/local/lib/wkhtmltox/bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf
$ /usr/local/bin/wkhtmltopdf --version
$ wkhtmltopdf 0.12.4 (with patched qt)
```

動作確認をして、エラーが出ないことを確認します。

```shell:shell
$ wkhtmltopdf http://google.com google.pdf
$ ls
google.pdf
```


日本語フォントが必要な場合は、IPAが提供しているIPAexフォントをダウンロードします。（http://ipafont.ipa.go.jp/）

```shell:shell
$ cd /usr/share/fonts/
$ wget http://dl.ipafont.ipa.go.jp/IPAexfont/IPAexfont00301.zip
$ unzip IPAexfont00301.zip
```

Gemfileを編集して、bundleします。

```ruby:Gemfile
gem 'pdfkit'
gem 'wkhtmltopdf'
```

Railsにpdfkit.rbを追加します。
私の環境では文字サイズの自動調整がlocalとAmazonLinuxでは異なったので、Linuxの方では「disable_smart_shrinking: true」にして、別途レイアウトを調整しています。（下記のmarginは適当です。）

```ruby:/config/initializers/pdfkit.rb
config.wkhtmltopdf = `which wkhtmltopdf`.to_s.strip
if Rails.env.production?
  config.default_options = {
    encoding:                "UTF-8",
    page_size:               "A4",
    margin_top:              "0.0in",
    margin_right:            "0.0in",
    margin_bottom:           "0.0in",
    margin_left:             "0.0in",
    disable_smart_shrinking: true
  }
else   
  config.default_options = {
    encoding:                "UTF-8"
  }
end
```

PDFを作る際、Controllerでは次のようなコードを書きます。
PDFKitではscssを読み込めないので、production環境では直接ファイルを見に行っています。production以外の環境ではviewからファイルを見ています。（個人的にはこの辺のハマりがクライマックスでした。）

```ruby:/app/controllers/hoges.rb
respond_to do |format|
  format.html do
    # 省略
  end
  format.pdf do
    html = render_to_string template: "hogehoge"
    pdf = PDFKit.new(html, encoding: "UTF-8", :footer_center => "[page]", :footer_font_size => 7)
		# productionではprecompileされたファイルを読みにいく
		if Rails.env.production?
			css_path = ActionController::Base.helpers.asset_path "xxxx.css"
			pdf.stylesheets << "#{Rails.root}/public#{css_path}"
		end
		#
    send_data pdf.to_pdf,
    filename:    "title",
    type:        "application/pdf",
    disposition: "inline"
  end
end
```
```html:/app/views/hoges.pdf.erb
<head>
<style>
<%= Rails.application.assets["hoge.css"].to_s %>
</style>
</head>
```

以上です。


####追記 20200405
3年ぶりぐらいに同様のコードを書いてみると、development環境でも普通にprecompileすればいいと気づきました。
なんというか、不要な苦労をしていました。
HerokuでCloud Natural Language APIを使う

# 目的
[Cloud Natural Language API ](https://github.com/GoogleCloudPlatform/google-cloud-ruby#cloud-natural-language-api-alpha)をHerokuで利用したい

# 課題
APIを利用するためには、Googleの認証が必要です。認証の際に、サービスアカウントキーの指定が必要ですが、認証キーはファイル形式でしか取得できません。Herokuは、ファイルをアップロードすることができないため、そのままでは認証できません。ファイル形式ではなく、JSONのテキストのまま読み込む必要があります。

# 解決方法

`ENV['GOOGLE_CLOUD_KEYFILE_JSON']`を使う。
`GOOGLE_CLOUD_KEYFILE_JSON`は、ファイルオープンせずにJSONのテキストをそのまま読み込みます。

設定方法

```
heroku config:set GOOGLE_CLOUD_KEYFILE_JSON="$(< ./keyfile.json)"
```

※ keyfile.jsonは、サービスアカウントキーファイルです。サービスアカウントを作成するとダウンロードされるファイルです。実際のファイル名は、`[project_name].json`

# 実行
環境変数が設定されていれば、Google::Cloud::Languageに設定を渡す必要はありません。

```
require "google/cloud/language"

language = Google::Cloud::Language.new

content = "Star Wars is a great movie. The Death Star is fearsome."
document = language.document content
annotation = document.annotate

annotation.entities.count #=> 3
annotation.sentiment.score #=> 0.10000000149011612
annotation.sentiment.magnitude #=> 1.100000023841858
annotation.sentences.count #=> 2
annotation.tokens.count #=> 13
```
引用元：　https://github.com/GoogleCloudPlatform/google-cloud-ruby/tree/master/google-cloud-language

# Tips
Heroku以外でファイルが置ける場合は、環境変数`GOOGLE_CLOUD_KEYFILE=/path/to/keyfile.json`のほうがオススメです。

# 参考
https://googlecloudplatform.github.io/google-cloud-ruby/#/docs/google-cloud-language/v0.26.2/guides/authentication
ネットワークについての個人的まとめ

ネットワークについての個人的まとめ
#この記事を書いた理由#
教えられたこと、試してみたこと、学んだことを纏めていきます。リンク集としても使っています。

#ネットワーク機器#

<b>利用図 例</b>
[社内LAN構成図サンプル＆素材](http://www.se-support.com/network/kouseizu.html)

#用語#

あくまで自分が理解している大まかな説明書きです。

|名称|説明|参考|
|:-------|:-----|:-----|
|サーバー|主にネットワークを通じて操作、および利用をするコンピューターのこと||
|スイッチングハブ|LAN中継器です。イメージ的にはタコ足のコンセントです。一台のスイッチングハブから複数のLANケーブルを複数の機器につなぎます。|[スイッチ/ハブの選び方](https://note.cman.jp/network/lan_hub.cgi)|
|NAS|ネットワーク接続されたハードディスクのこと。<br>スイッチングハブからLANケーブル繋いで使ったりします|[【初級編】ゼロからわかる NAS｜選び方から利用方法まで解説](https://navi.dropbox.jp/nas)|

#参考リンク
[基礎から学ぶネットワーク構築（3）：トラブル予防は現状の把握から](http://www.atmarkit.co.jp/ait/articles/0103/29/news003.html)
Goでのアルゴリズムクイックリファレンス第2版(ハッシュに基づいた探索)

Goに慣れるためとアルゴリズムの復習の為に週1ぐらいで更新していきます。[アルゴリズムクイックリファレンス 第2版](https://www.amazon.co.jp/gp/product/4873117852/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4873117852&linkCode=as2&tag=amesho-22&linkId=b7688201ae37a6234596fa96dfd3ccdd)を読んで各種アルゴリズムをGoで実装して行きます。

前回: [Goでのアルゴリズムクイックリファレンス第2版(二分探索)](http://qiita.com/amesho/items/f9d42fb0ba257b67aebf)

今回は[ハッシュ関数](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E9%96%A2%E6%95%B0)


> ハッシュ関数 (ハッシュかんすう、hash function) あるいは要約関数とは、あるデータが与えられた場合にそのデータを代表する数値を得る操作、または、その様な数値を得るための関数のこと。ハッシュ関数から得られた数値のことを要約値やハッシュ値または単にハッシュという。

計算量は、最良と平均は`O(1)`で最悪が`O(n)`となる。
高速でデータを取り出したい場合によく使われる


```go
package main

import "fmt"

var table [][]int

func loadTable(a *[]int) {
	table = make([][]int, len(*a))
	for _, e := range *a {
		h := hash(e, len(*a))
		if table[h] == nil {
			table[h] = make([]int, 0)
		}
		table[h] = append(table[h], e)
	}
}

func hash(key int, size int) int {
	var h int
	for i := 0; i < key+1; i++ {
		h = (h*137 + i) % size
	}
	return h
}

func search(a *[]int, t int) bool {
	h := hash(t, len(*a))
	list := table[h]
	if list == nil {
		return false
	}
	for _, v := range list {
		if v == t {
			return true
		}
	}
	return false
}

func main() {
	a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	loadTable(&a)
	fmt.Println(a)
	fmt.Printf("0:%t\n", search(&a, 0))
	fmt.Println(a)
	fmt.Printf("2:%t\n", search(&a, 2))
	fmt.Println(a)
	fmt.Printf("12:%t\n", search(&a, 12))
}
```

今回はhash関数を作成するところで以下のサイトを参考にさせていただきました。

+ http://home.a00.itscom.net/hatada/c-tips/hash01.html

次回はブルームフィルタの予定です。
Tex記法で微分の数式のダッシュを書く

「このyについてるダッシュを書きたい・・・:joy:」

```math
y = x^2 \\ 
y^{\prime} = 2x
```

「これで書けるし・・・:innocent:」

```
y = x^2 \\ 
y' = 2x
```

「これでも書けました:innocent:」

```
y = x^2 \\ 
y^{\prime} = 2x
```

##ちなみに
`\\`は改行です。

##ちなみに 2
もっと数式を気楽に書けないのか・・・
そんな方のためのツールがありました。
https://webdemo.myscript.com/views/math.html#

## ちなみに 3
原因不明ですが、
`y' = 2x`、これでダッシュを書こうとしてエラー出た上、
`\\`、これで改行しようとしたら謎の数式が複製される現象が起きたので、
まとめたつもりでした。
でも、再度やったらエラー出ませんでした。:joy:

以上ご報告でした。
Cisco IOS-XEで試す、はじめてのYDK


# YDKって何？

> The YANG Development Kit (YDK) is a Software Development Kit that provides API’s that are modeled in YANG. The main goal of YDK is to reduce the learning curve of YANG data models by expressing the model semantics in an API and abstracting protocol/encoding details. YDK is composed of a core package that defines services and providers, plus one or more module bundles that are based on YANG models.

- YANGモデルに対してAPIを提供してくれるSDK
- プロトコル（SSHやNetconf）やエンコーディング（XML）を抽象化
- YANGモデルの操作に集中でき、学習時間を大幅短縮できる
- Ciscoが作って公開 [ydk.io](http://ydk.io) [ydk.cisco.com](http://ydk.cisco.com)
- YANG? -> [YANG ExplorerでYANGモデルに慣れる](http://qiita.com/kikuta1978/items/fc205d85bbe742e7b10b)

# 背景
- YANGモデルを理解するために、[YANG ExplorerやPyang](http://qiita.com/kikuta1978/items/fc205d85bbe742e7b10b)は役立つが、コードを書く場合、NCClientやYDKを使うことになる
- NCClientの利用参考：[Pythonでget_configその1](http://qiita.com/kikuta1978/items/da7957fc3bab511231da#python%E3%81%A7get_config%E3%81%9D%E3%81%AE1)
- YDKはこれまで、IOS-XRの利用者中心に広まっていたが、2017/6/6あたりにIOS-XEバンドルAPIがリリースされ、IOS-XEでも気軽に試せるようになった

# とりあえずこれだけ
- YDK プロバイダモジュール .. 今のところNetconfServiceProviderのみ
- YDK サービスモジュール
 - CRUDService .. YDKモジュールで作ったEntityのCRUD（Create/Read/Update/Delete）操作
 - NetconfService .. Netconf Operationの操作
 - CodecService .. Entityのエンコード、ペイロードのデコード
 - ExecutorService .. RPCの実行
- YDK API
 - openconfig bundle API
 - cisco_ios_xe bundle API
 - cisco_ios_xr bundle API
 - ietf bundle API


※YANGはデータモデルなので特にNetconfに依存しないが、今のところNetconfのデータモデルとして使われている

- [IOSのコンフィグ](http://qiita.com/kikuta1978/items/da7957fc3bab511231da#%E8%A8%AD%E5%AE%9A)
- IOS-XEバージョンは16.5を利用

# インストール
楽ちんなやつ。環境によってエラーが出たら、適当に整える。

今回のメイン。

```
pip install ydk-models-cisco-ios-xe
```

ついでに入れとくやつ。

```
pip install ydk-models-cisco-ios-xe
pip install ydk-models-openconfig
pip install ydk-models-ietf
```

# サンプルコード

```python:ydk_test.py
import sys
from ydk.services import CRUDService
from ydk.providers import NetconfServiceProvider
from ydk.models.cisco_ios_xe import Cisco_IOS_XE_native as xe_native

provider = NetconfServiceProvider(address="10.71.130.57",port=830,username="cisco",password="cisco",protocol="ssh")
crud = CRUDService()

native = xe_native.Native()
native.hostname = sys.argv[1]
native.banner.motd.message = sys.argv[2]

crud.create(provider, native)

provider.close()
exit()
```

- Netconf Provider作成（装置のアクセス情報）
- YDK-IOS-XE APIを使って、Entity作成（ホスト名とバナーの設定）
- CRUDサービスオブジェクトのCreateメソッドに、ProviderとEntityを入力

※ホスト名とバナーは、CLIの引数から補完

# 実行

```bash
~ $python3 ydk_test.py CSR1KV-1 "Hello, YDK"
```

```cisco:cisco
Router#sh run | i banner
banner motd ^CHi, good morning^C
Router#
Router#
Router#
CSR1KV-1#
CSR1KV-1#sh run | i banner
banner motd ^CHello, YDK^C
CSR1KV-1#
CSR1KV-1#
```

シンプルな動作確認でした。
コマンドラインからAndroidのEmulator起動 

メモ

## 環境
- macOS Sierra

## 流れ
```zsh
#Emulatorリストの取得
emulator -list-avds
```
```zsh
#エミュレータ指定して起動
emulator @Nexus_5X_API_22
```

はいドン。

```zsh
ERROR:./android/qt/qt_setup.cpp:28:Qt library not found at ../emulator/lib64/qt/lib
Could not launch '../emulator/qemu/darwin-x86_64/qemu-system-i386': No such file or directory
```


下記でいけました。

```zsh
$ANDROID_HOME/emulator/emulator @Nexus_5X_API_22
```
君の名はlink_to_if

条件付きでlink_toするとき、普通にやると以下のようになる。

```test1.rb
if 条件文
 link_to "文字列", url, {オプション}
```

しかし、簡単な条件文なのに入れ子が生まれるとうざい。
そんな方にはlink_to_if。

```test2.rb
link_to_if 条件文, "文字列", url, {オプション}
```

unless版もある。

```test3.rb
link_to_unless !条件文, "文字列", url, {オプション}
```

test1.rb,test2.rb,test3.rbすべてが同じ動作になる。
簡単な条件文のときに使うのがオススメ。
条件文が長いと例えばこうなる。

```ruby
link_to_if hoge==1 && piyo==1 || (fuga.hoge==1 || fuga.piyo==1) , "文字列", url, {オプション}
```

読みづらい:joy:
ワンライナー狂以外の方は避けましょう。
ゆるくReactでモーダルウィンドウを実装してみる。

Reactでの開発が徐々に慣れてきたところで実装に実用的なコードも書いていきたいところです。
今回はreact-modalというライブラリを使ってゆるく実装してみたいと思います。

## 事前準備
react-modalのインストール
```npm install --save-dev react-modal
```

## 実際に書いてみる
```
import React from 'react';
import ReactDOM from 'react-dom';
import Modal from 'react-modal';

const appElement = document.getElementById('app');

const customStyles = {
  content : {
    top                   : '20%',
    left                  : '50%',
    right                 : 'auto',
    bottom                : 'auto',
    marginRight           : '-20%',
    transform             : 'translate(-50%, -50%)'
  },
  overlay : {
    backgroundColor:'black'
  }
};


class App extends React.Component {
  constructor() {
    super();

    this.state = {
      modalIsOpen: false,
    };

    this.openModal = this.openModal.bind(this);
    this.afterOpenModal = this.afterOpenModal.bind(this);
    this.closeModal = this.closeModal.bind(this);
  }

  openModal() {
    this.setState({modalIsOpen: true});
  }

  afterOpenModal() {
    // references are now sync'd and can be accessed.
    this.subtitle.style.color = '#f00';
  }

  closeModal() {
    this.setState({modalIsOpen: false});
  }
  
  render() {
    return (
      <div>
        <button onClick={this.openModal}>Open Modal</button>

        <Modal
          isOpen={this.state.modalIsOpen}
          onAfterOpen={this.afterOpenModal}
          onRequestClose={this.closeModal}
          style={customStyles}
          contentLabel="Example Modal"
        >

          <h2 ref={subtitle => this.subtitle = subtitle}>Hello</h2>
          <button onClick={this.closeModal}>close</button>
          <div>I am a modal</div>
          <form>
            <input />
            <button>tab navigation</button>
            <button>stays</button>
            <button>inside</button>
            <button>the modal</button>
          </form>
        </Modal>
      </div>
    );
  }
}

ReactDOM.render(<App />, appElement);
```
## 参考文献
[Github - react-modal](https://github.com/reactjs/react-modal)
UnityとRealSenseで表情の認識

笑うと回る箱(動画では何も伝わらない)
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">笑うと回る箱(動画では何も伝わらない) <a href="https://t.co/mNNUtyXekB">pic.twitter.com/mNNUtyXekB</a></p>&mdash; 琴葉 葵（偽） (@Hv2RMjHzDyqXVIr) <a href="https://twitter.com/Hv2RMjHzDyqXVIr/status/873931577541091328">2017年6月11日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

Version
Unity:5.6.1f1 Personal
RealSenseSDK:2016 R3
Device:SR300

動かし方
空のシーンを作ってカメラに下のコードをコピペして作ったスクリプトをアタッチするだけです。
※箱の座標は0,0,0

```csharp
using System.Collections.Generic;
using UnityEngine;
using Intel.RealSense;
using Intel.RealSense.Face;

public class FaceExpressions : MonoBehaviour
{
    SenseManager SenseM;
    FaceModule FaceM;
    FaceConfiguration FaceC;
    FaceData FaceD;

    Dictionary<FaceExpression, FaceExpressionResult> Expression;

    GameObject Obj;

    void Start()
    {
        SenseM = SenseManager.CreateInstance();

        FaceM = FaceModule.Activate(SenseM);
        FaceM.FrameProcessed += FaceM_FrameProcessed;

        FaceC = FaceM.CreateActiveConfiguration();
        FaceC.Expressions.EnableAllExpressions();
        FaceC.Expressions.Properties.Enabled = true;
        FaceC.ApplyChanges();

        FaceD = FaceM.CreateOutput();

        SenseM.Init();
        SenseM.StreamFrames(false);

        Obj = GameObject.CreatePrimitive(PrimitiveType.Cube);
        Obj.transform.localScale = new Vector3(1, 1, 1);
    }

    void FaceM_FrameProcessed(object sender, FrameProcessedEventArgs args)
    {
        FaceD.Update();
        var face = FaceD.QueryFaceByIndex(0);
        if (face != null)
        {
            if (face.Expressions != null)
            {
                Expression = face.Expressions.ExpressionResults;
            }
        }
    }

    void Update()
    {
        float z = 0;

        if (Expression != null)
        {
            z = Expression[FaceExpression.EXPRESSION_SMILE].intensity;
        }

        Obj.transform.Rotate(new Vector3(0, 0, z));
    }
}
```

参考
拾える情報

```csharp
namespace Intel.RealSense.Face
{
    public enum FaceExpression
    {
        EXPRESSION_BROW_RAISER_LEFT = 0,
        EXPRESSION_BROW_RAISER_RIGHT = 1,
        EXPRESSION_BROW_LOWERER_LEFT = 2,
        EXPRESSION_BROW_LOWERER_RIGHT = 3,
        EXPRESSION_SMILE = 4,
        EXPRESSION_KISS = 5,
        EXPRESSION_MOUTH_OPEN = 6,
        EXPRESSION_EYES_CLOSED_LEFT = 7,
        EXPRESSION_EYES_CLOSED_RIGHT = 8,
        EXPRESSION_HEAD_TURN_LEFT = 9,
        EXPRESSION_HEAD_TURN_RIGHT = 10,
        EXPRESSION_HEAD_UP = 11,
        EXPRESSION_HEAD_DOWN = 12,
        EXPRESSION_HEAD_TILT_LEFT = 13,
        EXPRESSION_HEAD_TILT_RIGHT = 14,
        EXPRESSION_EYES_TURN_LEFT = 15,
        EXPRESSION_EYES_TURN_RIGHT = 16,
        EXPRESSION_EYES_UP = 17,
        EXPRESSION_EYES_DOWN = 18,
        EXPRESSION_TONGUE_OUT = 19,
        EXPRESSION_PUFF_RIGHT = 20,
        EXPRESSION_PUFF_LEFT = 21
    }
}
```
https://software.intel.com/sites/landingpage/realsense/camera-sdk/v2016r3/documentation/html/index.html?doc_devguide_introduction.html
ワンライナーでリストとリストの突合せを行う方法

#走れメロス？
メロス(後輩)は激怒した。
かの邪智暴虐な王(常駐先のエンジニア)を除かなければならぬと決意した。

後輩はフロントエンジニアなのだが、
どうやら、バックエンド側のエンジニアが、今からコードを改修するのが面倒くさいらしく、
バックエンド側で持っているデータを、わざわざフロント側でゴニョゴニョして、
生成しなければならなくなったそうです。

##詳細を聞くと
どうやら
「listAとlistBがあって、ダブっているものがあったら、listAに何か目印を追加してほしい」
というのが、今回の要件でした。


仮にこんな感じのデータがあったと想定してみます。
※「一郎」「三郎」「四郎」をダブらせています。

```javascript
let listA = [
    {id:1, name:"一郎"},
    {id:2, name:"二郎"},
    {id:3, name:"三郎"},
    {id:4, name:"四郎"},
    {id:5, name:"五郎"}
];

let listB = [
    {id:4, name:"四郎"},
    {id:7, name:"七郎"},
    {id:9, name:"九郎"},
    {id:3, name:"三郎"},
    {id:1, name:"一郎"}
];
```

##ループ中のループ
後輩は、ループの入れ子で実装したらしく、ループが無駄にならないように、きちんとbreakしたとのこと。

おそらく、こんな感じでしょうか。

```javascript:sample1.js
for(let i=0; i<listA.length; i++){
    listA[i].flag = false;
    for(let j=0; j<listB.length; j++){
        if(listA[i].id == listB[j].id){
            listA[i].flag = true;
            break;
        }
    }
}
```

確かに、実装はできています。
でもいろいろと、改良の余地がありそうですね。

##mapで書いてみる
さらに詳しく聞いてみると、
「これだとループ中にループがあってイケてないから、mapで書き直して」
と言われたそうです。

もし私が、実装するとしたら、以下のような感じでしょうか。

```javascript:sample2.js
listA = listA.map(a => ({id:a.id, name:a.name, flag:listB.some(b=>b.id==a.id)}));
```

##リスト表示用の関数
さっそく、改良前と改良後で結果が同じかどうか、JSON形式で画面に出力してみました。
関数の定義は以下の通り。

```javascript
function Display(list){
    let result = JSON.stringify(list, undefined, 4);
    result = result.replace(/\n/g, "<br>").replace(/\s/g, "&nbsp;");
    document.write(result);
}
```

この関数は、連想配列を受け取ってJSON文字列に変換します。
そして、JSON文字列をHTMLで表示するために、改行と半角スペースを置換しています。

#それでは
実際に表示させてみます。

```javascript:sample2.js
listA = listA.map(a => ({id:a.id, name:a.name, flag:listB.some(b=>b.id==a.id)}));
Display(listA);
```

```json:sample.html
[
    {
        "id": 1,
        "name": "一郎",
        "flag": true
    },
    {
        "id": 2,
        "name": "二郎",
        "flag": false
    },
    {
        "id": 3,
        "name": "三郎",
        "flag": true
    },
    {
        "id": 4,
        "name": "四郎",
        "flag": true
    },
    {
        "id": 5,
        "name": "五郎",
        "flag": false
    }
]
```

うん！ちゃんとできてますね！

##まとめ

mapは便利ですね～。
私はC#の経験が一番長いのですが、Linqとよく似ています。
アロー演算子はゴーズトゥ演算子と同じですし、someはanyと同じですし。

今回は以下の記事を大いに参考にさせていただきました。
<a href="http://qiita.com/itagakishintaro/items/29e301f3125760b81302" target="_blank">JavaScriptでforEach, filter, map, reduceとか</a>

この調子で、実務で使用するJavaScriptでも、無駄なループが減らしながら、
見やすいコードを書いていきたいですね (^_^;
MySQL5.7でCREATE USERするときのパスワードチェックを無効にする方法

MySQL5.7で適当なパスワードでユーザーを作ろうとしようものなら容赦なく怒られた :frowning2:

```ｃonsole:
$ mysql> CREATE USER 'test'@'localhost' IDENTIFIED BY 'test';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
```

・・・こんな感じ :ghost:
このチェックを無効化にする方法を調べたのでメモ。

#パスワードのチェックを無効化する

チェックを無効にしたければvalidate_passwordプラグインを無効にするといいらしい。
ということで、my.cnfにvalidate-password=OFFを追記。これだけ。

```ｃonsole:
$ sudo vi /etc/my.cnf
```

```bash:/etc/my.cnf
[mysqld]
validate-password=OFF
```

設定反映のためmysqlの再起動。

```ｃonsole
$ sudo systemctl restart mysqld.service
```

以上であります。 :cop_tone1:
確認のため適当なパスワードでユーザーを作ってみる。

```ｃonsole
$ mysql> CREATE USER 'test'@'localhost' IDENTIFIED BY 'test';
Query OK, 0 rows affected (0.00 sec)
```

いけました :thumbsup_tone2:

#おまけ

上記の設定を無効にする前のMySQL5.7のデフォルトのチェック内容についても調べてみたのでメモ。
とりあえず以下で設定が見れる。

```ｃonsole:
$ mysql> SHOW GLOBAL VARIABLES LIKE 'validate%';
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password_check_user_name    | OFF    |
| validate_password_dictionary_file    |        |
| validate_password_length             | 8      |
| validate_password_mixed_case_count   | 1      |
| validate_password_number_count       | 1      |
| validate_password_policy             | MEDIUM |
| validate_password_special_char_count | 1      |
+--------------------------------------+--------+
7 rows in set (0.01 sec)

```


| 設定値    |説明     |デフォルト値    |
|:-----------------|:------------------|:------------------|
| validate_password_check_user_name    |パスワードにユーザー名の一部が含まれていないか    | 無効    |
| validate_password_dictionary_file    |除外する文字列を定義したファイルを設定できる       |未指定
| validate_password_length    |パスワードに必要な最小の文字数　　 |8文字        |
| validate_password_mixed_case_count|パスワードに必要な小文字および大文字の最大数。 パスワードポリシーが　MEDIUM以上で有効|１文字(有効)      |
| validate_password_number_count|パスワードに必要な数値文字 (数字) の最大数。パスワードポリシーが　MEDIUM以上で有効|１文字(有効)      |
| validate_password_policy|パスワードポリシー　　|MEDIUM       |
| validate_password_special_char_count|スワードに必要な英数字以外の文字の最大数。パスワードポリシーが　MEDIUM以上で有効|１文字(有効)      |

デフォルトはかなりガチガチ :angel_tone2:
validate_password_policy=LOWに設定すると、長さチェックだけになるみたい:writing_hand_tone2:


```bash:/etc/my.cnf
[mysqld]
validate_password_policy=LOW
```

参考：https://dev.mysql.com/doc/refman/5.7/en/validate-password-options-variables.html
paizaの問題を解くときに使えるテクニック1(Ruby編)

#Paizaの問題を解いていて、使えそうなテクニック1(入力編)
自分用アウトプットメモです。
覚えておくと便利なものであり、解法ではありません。
ちなみに趣味でしかRubyを使ったことがありません。

ようやく第2回のようなものを自分のブログに書きました。

[最近競技プログラミングしていてよく使う書き方とかメソッドとか - ボトムズ日記](https://leokun0210.hatenablog.com/entry/2019/09/19/000810)

#ファイルからの標準入力
Paizaのページ内にエディタがあるが、大半の人は自分のPCで開発すると思います。
標準入力は、使用頻度は高くないと思うので、忘れがちです。
下記のコマンドで実行すると簡単です。

```hoge.rb
p gets
```

```hoge.txt
1 2 3
```

```terminal
$ ruby hoge.rb < hoge.txt
"1 2 3"
```

#改行マークの除去
Paizaの問題には、標準入力に改行マークがある。
除去するにはchompメソッドを使用する。

[chomp, chomp! (String) - Rubyリファレンス](http://ref.xaio.jp/ruby/classes/string/chomp)

```chomp.rb
p gets
p gets.chomp
```

```hoge.txt
1 2 3
1 2 3
```

```terminal
$ ruby chomp.rb < hoge.txt
"1 2 3\n"
"1 2 3"
```

#標準入力を整数型にして、配列に格納する。
整数型にしないと、計算処理でエラーになります。

```split.rb
hoge = gets.split.map(&:to_i)
p hoge
p hoge[0] + 1

fuga = gets.split
p fuga
p fuga[0] + 1
```

```hoge.txt
1 2 3
1 2 3
```

```
$ ruby split.rb < hoge.txt 
[1, 2, 3]
2
["1", "2", "3"]
split.rb:7:in `+': no implicit conversion of Fixnum into String (TypeError)
        fromsplit.rb:7:in `<main>'
```
文字列型だとエラーになります。

#データ部分の読み込み
Paizaの問題で標準入力で、よくあるのは最初の1行と、2行目以降だとデータの構造が違うことがあります。
自分が2行目以降の読み込みには、よく下記のコードを書きます。

```read_data.rb
#1行目
p gets.split.map(&:to_i)

#2行目以降読み込み
array_of_input = []
while s = gets
  array_of_input.push(s.split.map(&:to_i))
end
p array_of_input
```

```hoge.txt
1 2 3
2 3 4 5 6
3 4 5 6 7
```

```
$ ruby read_data.rb < hoge.txt 
[1, 2, 3]
[[2, 3, 4, 5, 6], [3, 4, 5, 6, 7]]
```

`while s = gets`で、標準入力の最後まで読み込むまで、1行を変数`s`に代入しています。

#ヘッダー部分(最初の1行目)をインスタンス変数に格納して、その後の処理で使いやすくする。
ヘッダー部分は、仕様の根幹に関わる数値で、何回も参照する必要がでてくると思います。
なので、classを作って、インスタンス変数に格納して、インスタンスの中で呼び出せる様にしましょう。

```hoge.rb
class Hoge
    def initialize(x, y, z)
        @x = x
        @y = y
        @z = z
    end
    
    def display
        p "x: " + @x.to_s
        p "y: " + @y.to_s
        p "z: " + @z.to_s
    end
end

x, y, z = gets.split.map(&:to_i)
hoge = Hoge.new(x, y, z)
hoge.display
```
```hoge.txt
1 2 3
2 3 4 5 6
3 4 5 6 7
```

```
$ ruby hoge.rb < hoge.txt 
"x: 1"
"y: 2"
"z: 3"
```

#最後に
Ruby歴3ヶ月ぐらいなので、間違ってること、知らないことも多いと思うので、
もっと良い方法がありましたら、コメント欄で指摘いただけると嬉しいです。

本当は出力も一緒の記事にしようと思ったのですが、眠かったので
別の機会に書きます。
C言語について、本を読んで文字を打った

##概念
アルゴリズムとは、問題を解くための実行手順
コンピュータ：
ハードウェア→記憶装置、演算装置、制御装置、入力装置、出力装置
ソフトウェア→コンピュータを動かすのに必要なプログラミング　ex)OS(オペレーティングシステム)

###情報量の単位
　　ビット(0or1で表せるデータ)
　　バイト(8ビットの集まり)
　　ワード(数ビットをまとめたもの(16、32、64ビット))

　　1024バイト(2の10じょう)→1キロバイト
　　1024バイト→1メガバイト
　　1024メガバイト→1Gバイト


###アドレスとは
プログラムが使用するデータは、一旦メモリに書き込まれる。
その際、データの格納場所に、データの場所を示すアドレスが1バイトごとに割り振られる。
→アドレスを指定することでメモリのどの位置のデータでも自由にアクセスすることができる。

###メモリ破壊とは
アドレスの指定を誤り、メモリの内容が意味のない値になること

###プログラムが暴走した
プログラム自身メモリ上に格納されている。
プログラムが格納されている領域が破壊され、プログラムがとんでもない動きをしたり、停止できなくなること


##プログラミング言語
高級言語、低級言語がある。

###機械語(マシン語)
コンピュータが直接理解して処理できる言語

###アセンブリ言語
機械語の命令に対して一対一に対応する命令を備えた言語。
アセンブラと呼ばれるプログラミングによって簡単に機械語に変換することができる。
機械語よりプログラミングにおけるアドレス指定が容易にできる。

・低級言語：機械語に近い。　ex)アセンブリ言語
・高級言語：高級言語→コンパイル(翻訳)→機械語

##C言語の特徴
もともとは内輪で使われていた。
基本精神は「プログラマーを信頼する」。
簡単に暴走するプログラムも作れてしまう。

###C言語の長所：
1、見通しよく処理言語を記述できる。
2、言語構造がシンプル
3、複雑なデータを簡単に扱うことができる
4、ビット操作やポインタ演算など低レベルの処理ができる
5、他の高級言語より実行速度の速いプログラムが作成できる

###C言語の短所：
1、プログラムの可読性が低い。理解しづらい。
2、プログラムエラーでなくても暴走する可能性が高い。
3、文法上セイルされていない部分や多くの例外がある。

###C++
C言語にオブジェクティブ指向の考え方を取り入れて拡張したプログラミング言語
ex) カプセル化、継承、多様性

###C#
C++をベースにしたオブジェクト指向プログラミング言語

##プログラムの作成から実行まで
・Cソースのファイル(拡張子は.c)→コンパイル→オブジェクトプログラム→リンク→実行可能プログラム(a.out)
・gccコマンド：プログラムを機械語に翻訳→a.outと言うファイルに書き込まれる
試験用環境構築(2)-仮想マシンの作成と設定

[試験用環境構築(1)-ESXiホスト構築](http://qiita.com/utanesuke/items/4c5b9bbaad14756148b0)で　仮想の物理ホストESXi-01を１台構築できました。これから仮想の物理ホストで仮想マシンを作成します。

#1. 準備
1. VMware vSphereClientを起動して、ESXi-01ホストのIP/username/passwordでログイン。![image.png](https://qiita-image-store.s3.amazonaws.com/0/177240/2548c220-ab64-e879-f03d-3fbdb7de842b.png)
2. 入ったら、InventoryでたてたホストESXi-01が見えます。![image.png](https://qiita-image-store.s3.amazonaws.com/0/177240/522b06a5-b01e-3431-188b-694e9b6dc404.png)
3. ホストを選択して、構成タグ→時間の構成→プロパティで下記の設定をします。
    1. 起動ポリシー：ホストに連動して開始及び停止
    2. NTP設定で time.windows.com　のNTPサーバを追加
4. 構成タグ→ストレージで、もう一個データストアを追加、追加後は下記の通り![image.png](https://qiita-image-store.s3.amazonaws.com/0/177240/0d86ca8f-e4f6-5bb7-47f2-2e16c29a2518.png)
5. esxi01-dataデータストアの右クリックして、データストアの参照を選択、isoフォルダを作成します![image.png](https://qiita-image-store.s3.amazonaws.com/0/177240/2e91925d-d845-288e-670f-c3d3d0a338d3.png)
6. DLしたVMのGuestOS用isoファイルを先程作成したisoフォルダにアップロードします。


#2. 仮想マシンの作成
1. 下記の仮想マシンを作成
    1. 名前：WS03R2
    2. 仮想マシンファイルのターゲットストレージ：esxi01-data
    3. CPU:ソケット数１・コアの数１
    4. メモリサイズ：1GB
    5. ディスク：Thin Provision
2. 該当ホストの起動ドライブCD/DVDドライブにアップロードされたisoイメージに接続![image.png](https://qiita-image-store.s3.amazonaws.com/0/177240/6734e721-b978-45d6-4f66-de1db2c39d2b.png)
3. ホストの電源Onにして、Windows Server 2003 R2をインストールします。![image.png](https://qiita-image-store.s3.amazonaws.com/0/177240/ba4b9ae8-d93c-5bfe-f473-d9469b9a4c6b.png)
4. GuestOSをインストールしたら、電源のPower Schemesを「Always On」に設定。　
<img src="https://qiita-image-store.s3.amazonaws.com/0/177240/a105a124-cd42-4939-2326-e3e062d227b6.png" width="50%">
5. Runで「gpedit.msc」を入力してローカルグループポリシーエディターを起動する。下記の設定をす
Windows Setting→Security Settings→LocalPolicies→Security Optiongsの
・Interactive logon:Do not require CTRL+ALT+DELETE　を　Enabledに設定

#3. GuestOSの関連設定
1. VMware Toolsをインストール![image.png](https://qiita-image-store.s3.amazonaws.com/0/177240/8972c9ef-b6d4-3a2a-d90f-7e9f3c3af2de.png)
2. 仮想マシンで物理ホストのUSB設備をアクセスできるように設定
    1. 仮想マシンのハードウェアにUSBコントローラーを追加
    2. 仮想マシンの「![image.png](https://qiita-image-store.s3.amazonaws.com/0/177240/55f2858d-c525-09f6-7e8f-cc85d681e686.png)」を使って、USB設備の接続と切断をする

3. また、仮想マシンの設定を編集して、ハードディスクの追加や容量増やすなどできる。実際のハードディスク容量以上に増やせます。
    1. もう一個ハードディスク120GBを追加![image.png](https://qiita-image-store.s3.amazonaws.com/0/177240/2f130628-23e9-25b8-fee3-83203d670b79.png)
    2. 仮想マシンで120GBのDiskが追加できました<img src="https://qiita-image-store.s3.amazonaws.com/0/177240/8f0065a8-a46e-358c-f534-93d8a00721d6.png" width="80%">
    3. 同様にNicも追加できる　　　　　　　　　　　　　　　　　
    ![image.png](https://qiita-image-store.s3.amazonaws.com/0/177240/f8c58a85-23ee-01ad-f0b9-e31de7b60ae8.png)
4. 仮想マシンの自動起動を設定する![image.png](https://qiita-image-store.s3.amazonaws.com/0/177240/0ce36fc2-d438-f5e5-f8fe-6cecad42f2a3.png)　＊起動遅延時間について、一気に遅延なしですべての仮想マシンを起動すると、物理ホストに負担かかる。また、VMの起動優先順位も設定できる

#4. vCenterなしで仮想マシンの複製
1. データストアのファイルプラウザで、WS03R2でのvmdkフィアルをコーピーして、WS03R2-C01フォルダを新規して、こちへ移動
2. 新規仮想マシンを作成、ディスクの選択で「ディスクを作成しない」を選んで作成する
3. 作成したWS03R2-C01仮想マシンを設定編集して、ハードウェアの追加で、ハードディスクを追加して、「既存の仮想ディスクを使用」にして、先程コーピーしたデータストアのvmdkファイルを選択して設定します。
4. 複製できたら、２つの仮想マシンができた。
5. また、バックアップとして、vmdkファイルを物理ホストにDLできる。