OmniAICreator/Qiita-1.07M huggingface dataset:
ExcelでMarkdownしたが気に入らなかったのでVSCodeでMarkdown-mermaid

>[前回](http://qiita.com/WaToI/items/8f0e7bc6acca8166908c)は**mermaid**をExcel関数にした
今回は**Markdown**をExcel関数にする
![2016-11-06 (1).png](https://qiita-image-store.s3.amazonaws.com/0/145884/7bac8084-f73c-60da-37e9-3edf938c2c47.png)
結果、Excelでmarkdownは、コレジャナイ感が拭えなかったので
気分転換にVisualStudioCodeのExtensionを作った
VSCodeの既存ExtensionでMarkdown・mermaid両対応は無かったはず。
![2016-11-06.png](https://qiita-image-store.s3.amazonaws.com/0/145884/3300f318-b590-d381-7ef1-9210d671c9b6.png)

---

## まとめ
### ExcelでMarkdown → [xlMdDna](https://github.com/WaToI/xlMdDna/blob/master/xlMdDna-AddIn-packed.xll)
- エクセルでMarkdownのライブエディット
- mermaid対応


#### Issue
* ブラウザを監視できず無駄にタブを開きまくるようになった。  
※IEにうんざりして使用するブラウザコントロールをユーザーデフォルトにかえた。ちなみに、このページを見た人は半分以上Chrome。
* 今回は図だけではないのでエクセルに自動貼り付けは見送った。
どうせブラウザで開くわけなので、保存はブラウザに任せてしまえばいい・・・
ブラウザからPDFで保存。PDFなら許されるはず・・・
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/145884/4e5093b9-3a88-c614-7db0-dc0a21270834.png)

### VSCodeでMarkdown-mermaid →[MarkdownMaid](https://github.com/WaToI/vscode-markdownmaid/blob/master/extension.js)  
> 追記 VSCのバージョンアップで動かなくなった:confounded:  

* VSCodeでmarkdownテキスト編集中にコマンド MarkdownMaidを実行でサイドプレビュー
* ES6で開発
* 既存mermaid拡張:[mermaid-preview](https://github.com/vstirbu/vscode-mermaid-preview)を参考にした
* コード行数100ちょい。
* VSCodeでのコーディングはアシスト(補完)がしっかりしていて好感触

![キャプチャ2.PNG](https://qiita-image-store.s3.amazonaws.com/0/145884/593309ab-95eb-a85f-3e29-bcb0767376a5.png)
LJの力計算のSIMD化ステップ・バイ・ステップ その1

# はじめに

LJのSIMD化の試み。まずはペアのループをソフトウェアパイプライニングする。

* [その0](http://qiita.com/kaityo256/items/5be3ce71a6ff9522a0e6) 
* [その1](http://qiita.com/kaityo256/items/4d34bf144122b78fcf49) ←イマココ

* [その2](http://qiita.com/kaityo256/items/e6c41b94c5cc5189c5cc)
* [その3](http://qiita.com/kaityo256/items/7f16ab7f2281bb03e83e)
* [その3.5](http://qiita.com/kaityo256/items/b145b2d83becccd0aa53)
* [その4](http://qiita.com/kaityo256/items/636c5a407f5a6c61bb21)
* [その5](http://qiita.com/kaityo256/items/dacbe5a16abbc83eb107)
* [その6](http://qiita.com/kaityo256/items/34c371c6d040be1bdc30)

コードは
https://github.com/kaityo256/lj_simdstep
においてある。

# コード

ペア毎の力計算コードは、ループが一重ループになっている。コードはこんな感じ。

```cpp
void
force_pair(void){
  for(int k=0;k<number_of_pairs;k++){
    const int i = i_particles[k];
    const int j = j_particles[k];
    double dx = q[j][X] - q[i][X];
    double dy = q[j][Y] - q[i][Y];
    double dz = q[j][Z] - q[i][Z];
    // ★
    double r2 = (dx * dx + dy * dy + dz * dz);
    if (r2 > CL2) continue;
    double r6 = r2 * r2 * r2;
    double df = ((24.0 * r6 - 48.0) / (r6 * r6 * r2)) * dt;
    p[i][X] += df * dx;
    p[i][Y] += df * dy;
    p[i][Z] += df * dz;
    p[j][X] -= df * dx;
    p[j][Y] -= df * dy;
    p[j][Z] -= df * dz;
  }
}
```

極めてシンプル。kがループインデックスで、それがペア番号になっている。それからi粒子の番号とj粒子の番号を取ってきて、相対座標を計算し、距離を計算し、力を計算し、力積を書き戻す、という手順。ただし、[Bookkeeping法](http://qiita.com/kaityo256/items/cfacbf6f1136de63bd97)という手法を用いているので、相互作用範囲外にあるペアもペアリストに登録されている。それらは距離を調べて弾いている。

これをソフトウェアパイプライニングしよう。いろいろ試行錯誤したが、「距離の計算の直前」(★のあるところ)で切って、その前後を重ねるのが一番良さそうである。そのように修正したコードは以下の通り。

```cpp
void
force_pair_swp(void){
  int k = 0;
  int i = i_particles[k];
  int j = j_particles[k];
  double dx = q[j][X] - q[i][X];
  double dy = q[j][Y] - q[i][Y];
  double dz = q[j][Z] - q[i][Z];
  double r2 = (dx * dx + dy * dy + dz * dz);
  double r6, df;
  for(k=1;k<number_of_pairs;k++){
    r2 = (dx * dx + dy * dy + dz * dz);
    r6 = r2 * r2 * r2;
    df = ((24.0 * r6 - 48.0) / (r6 * r6 * r2)) * dt;
    if (r2 > CL2) df=0.0;
    p[i][X] += df * dx;
    p[i][Y] += df * dy;
    p[i][Z] += df * dz;
    p[j][X] -= df * dx;
    p[j][Y] -= df * dy;
    p[j][Z] -= df * dz;
    i = i_particles[k];
    j = j_particles[k];
    dx = q[j][X] - q[i][X];
    dy = q[j][Y] - q[i][Y];
    dz = q[j][Z] - q[i][Z];
  }
  r2 = (dx * dx + dy * dy + dz * dz);
  r6 = r2 * r2 * r2;
  df = ((24.0 * r6 - 48.0) / (r6 * r6 * r2)) * dt;
  if (r2 > CL2) df=0.0;
  p[i][X] += df * dx;
  p[i][Y] += df * dy;
  p[i][Z] += df * dz;
  p[j][X] -= df * dx;
  p[j][Y] -= df * dy;
  p[j][Z] -= df * dz;
}
```

ただ半分ずらしただけで、ループの前後に出てくる「はみ出し」の処理が面倒なこと以外は特に難しいことはない。

# 結果

make testは、力を計算し、最初の5粒子と最後の5粒子の運動量を表示して、他の手法と結果が一致するか確認する。これで結果が正しいことをまず確認(基本)。

そして、肝心の計算時間だが・・・

| 計算手法 | 実行時間[sec] |備考 |
|:-:|:-:|:-:|
| pair  | 8.172028  |  ペアごとにループをまわしたもの |
| pair_swp  | 8.278427  |  上記をソフトウェアパイプライニングしたもの |

遅くなってしまった。計算は独立なのだが、continue文があるのと、インデックスを共通のものを使っているので、独立に計算できることをコンパイラが判断できなかったようだ。

今回のコードはこちら。
https://github.com/kaityo256/lj_simdstep/blob/master/step1/force.cpp

[次回へ続く](http://qiita.com/kaityo256/items/e6c41b94c5cc5189c5cc)。
rubyの文字列連結（<<と+）の違い

みなさん、以下の結果について、予想できますか？
筆者はこれにハマってしまいました

```ruby
string = ''
hashes = []
%w(a b c).each do |word|
    string << word
    hashes.push(string: string)
end

p hashes
```

筆者は以下のような出力を考えていました。。。

```ruby
hashes = [
    {string: "a"},
    {string: "ab"},
    {string: "abc"}
]
```

しかし、実際には以下の出力となります。

```ruby
hashes = [
    {string: "abc"},
    {string: "abc"},
    {string: "abc"}
]
```

これを想定通りの出力にするならこうです。

```ruby
string = ''
hashes = []
%w("a b c").each do |word|
    string +=  word
    hashes.push(string: string)
end

p hashes
```

ポイントは文字列連結で、 `<<` ではなく `+` を使っている部分ですが、`<<`では同一のオブジェクトに対して中身を書き換えているのに対して、`+`では別のオブジェクトを生成するためです。（Javaの文字列連結みたいなものですね）
LJの力計算のSIMD化ステップ・バイ・ステップ その0

# はじめに

SIMD化、してますか？＞挨拶

「京」が128bit、現在のx86系の石が256bit、そして[ポスト「京」がSIMD幅可変、ハード512bit](http://news.mynavi.jp/photo/articles/2016/09/08/hc28_arm2/images/009l.jpg)という話もあって、もはやSIMD化しないといろいろつらいというか、ポスト「京」が走りだす時に、えらいひとたちがSIMD化率を気にしだしたり、アプリケーションごとにSIMD化率を提出させられたりするような未来が見えなくもないので、私もSIMD化してみようと思います。

で、「ステップ・バイ・ステップ」とあるけれど、これは教材という意味ではなくて、単に私がどういう形でSIMD化をしていったかの作業記録を保存しようという試みです。もっとすごい人はもっとスパッとSIMD化しているんだと思います。

# 背景

これまでのあらすじ。

* [LJの力計算をフルアセンブラで書いてみる](http://qiita.com/kaityo256/items/03e0240af4e9a6469bcb)
* [LJの力計算を組み込み関数で書いてみる](http://qiita.com/kaityo256/items/0d3094de324f0e63d1f4)
* [LJの力計算を組み込み関数で書いて馬鹿SIMD化](http://qiita.com/kaityo256/items/bf10fdb0f90809e3d2bf)
* [LJの力計算のSIMD化(たぶん完結編)](http://qiita.com/kaityo256/items/caf4b8458a6bc292b4cc)

で書いたように、古典分子動力学法でよく使われるカットオフ付きLennard-Jones (LJ)ポテンシャルの力計算をAVX/AVX2の命令を使ってSIMD化してみた。その結果、SIMD化していない最速コードに比べて、SIMD化によって33%程度実行時間が短縮したんだけれど、4倍幅使ってるのに、ちょっと加速率が物足りない。特に問題なのは、粒子系が低密度の場合の加速率が悪い、ということだった。

SIMD化は、ループを4倍展開して自明に独立な演算を4つ作ってSIMD化する、馬鹿SIMD化を採用しているのだが、高密度でループ長が60前後、低密度だと30前後になるため、4倍展開のゴミが見えている可能性がある。

そこで、低密度粒子径でも、もっとループ長が取れる形の計算を馬鹿SIMD化することで、もっと高速化できないか考えた。これから書くのはその作業記録。

# ソースコード

SIMD化の元になるコードは https://github.com/kaityo256/lj_simdstep/tree/master/step0 においてある。
ペアリストをO(N^2)で作成していて時間がかかるので、ファイルにキャッシュするようにした。力の計算が4種類定義されているが、それぞれ以下の通り

* force_pair ペア毎に力を計算する
* force_sorted i粒子をキーにソートし、j粒子に対してループを回す
* force_sorted_swp force_sortedを手でソフトウェアパイプライニングしたもの
* force_sorted_intrin force_sortedを手でSIMD化したもの

ペアリストを作成すると、こんな感じで粒子のペアができる。

![pair.png](https://qiita-image-store.s3.amazonaws.com/0/79744/a68e8b9d-7472-841c-ef6f-efd7188b5dd0.png)

このペア番号でループを回すのがforce_pair。

で、この方法だと、i粒子とj粒子の情報を毎回ロード/ストアしなければならない。LJの力計算はかなり軽いので、このメモリアクセスのペナルティはわりと大きい。そこで、i粒子をキーにしてソートする。

![sorted.png](https://qiita-image-store.s3.amazonaws.com/0/79744/938f2148-fdc1-a701-c7b2-02f77e9d0148.png)

すると、i粒子の情報がレジスタに載るため、メモリアクセスが減る。これをやったのがforce_sorted。

i粒子の情報がレジスタに載っている前提では、力の計算は

1. j粒子の座標を取ってくる
2. 相対ベクトルを計算する
3. 距離を計算する
4. 距離から力を計算する
5. 力から力積ベクトルを計算する
6. 力積ベクトルを運動量に書き戻す

というステップをとる。このうち、1-2と3-6をループごとにずらして、独立な計算にする。1-2の処理をA、3-6の処理をBとすると、ソフトウェアパイプライニングというのは以下のようなイメージ。

![swp.png](https://qiita-image-store.s3.amazonaws.com/0/79744/0a259096-0371-679a-875d-d8697dd16f19.png)

上が普通の処理、下がソフトウエアパイプライニングしたもの。全体の処理内容は変わっていないが、BnはAnが終わらないと実行できないが、BnとAn+1は独立に実行できるから、それを明示的に重ねてIPCを増やしましょう、という方法論。x86ではわりと効果的な最適化手法。もちろんコンパイラは勝手にはやってくれない。

# SIMD化方針

SIMD化については、とりあえずデータを

```cpp
double q[N][4];
double p[N][4];
```
と4次元ベクトルにしておいて、vmovupdで4成分を一度にロード、あとは適当にシャッフルして4つの力を一度に計算する。

で、低密度で性能が出なかったのは、ループ長が短いせいもあるだろうと考え、i粒子でソートする前のもの、つまりペアでループを回して力を計算する、force_pairをSIMD化することを考える。

ただし、そのままではメモリアクセスのペナルティが大きく、性能が出ないことが予想されるため、

* ペアごとの力の計算ルーチン force_pairを ソフトウェアパイプライニングする
* それを4倍展開する
* それをSIMD化する

というステップを踏むことにしよう。

# 性能

現状での性能は以下の通り。

| 計算手法| 実行時間[sec] |備考 |
|:-:|:-:|:-:|
| pair  | 8.166132  | ペアごとにループをまわしたもの  |
| sorted  | 7.029136  |  相互作用相手でソートして、二重ループにしたもの |
| sorted_swp   | 5.79193  |  ソートしたものを手でソフトウェアパイプライニングしたもの |
| sorted_intrin  | 3.890581  | ソートしたものを手でSIMD化したもの  |

目標は、最後の「sorted_intrin」の速度を超えること。

[次回へ続く](http://qiita.com/kaityo256/items/4d34bf144122b78fcf49)。
MacPortsのphp70でcomposerを導入

PHPの環境構築に[composer](http://getcomposer.org)がよく用いられますが、MacPortsにはありません。Composerのサイトの通りのコマンドでは、SSL関連のエラーが出ます。ここでは、MacPortsのphp70と拡張をインストールしてからcomposerをインストールします。

まずphp70の拡張をインストールします。php70がインストールされていなければ、インストールされます。
```
$ sudo port -d install php70-curl php70-openssl php70-mbstring php70-iconv
```
あとはphpの代わりにphp70とします。インストーラーのダウンロード。httpsを使っているので、php70-curlやphp70-opensslが必要になります。
```
$ php70 -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
```
インストーラーの確認。
```
$ php70 -r "if (hash_file('SHA384', 'composer-setup.php') === 'aa96f26c2b67226a324c27919f1eb05f21c248b987e6195cad9690d5c1ff713d53020a02ac8c217dbf90a7eacc9d141d') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
Installer verified
```
インストーラーの実行。ここでphp70-mbstringまたはphp70-iconvが必要。上では両方導入しました。
```
$ php70 composer-setup.php
```
composer.pharができるので、PATHの通っているところにmvします。インストーラーの削除もphpでやっていますがやりすぎでしょう。rmで良いと思います。
Windows+VagrantでCentOS7の公式boxが起動できない("rsync" could not be found on your PATH)

# TL;DR
[vagrant-vbguest](https://github.com/dotless-de/vagrant-vbguest)をインストール(`vagrant plugin install vagrant-vbguest`)して、Vagrantfileを`config.vm.synced_folder ".", "/vagrant", type: "virtualbox"`に書き換える。

# 背景
　WindowsのVagrantでCentOS7のbox(centos/7)を入れようとしたが、`vagrant up`に失敗する。

```:コマンドプロンプト
C:\Users\tenmyo\vm\test>vagrant init centos/7
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

C:\Users\tenmyo\vm\test>vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Importing base box 'centos/7'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'centos/7' is up to date...
==> default: Setting the name of the VM: test_default_1478419157855_72559
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
"rsync" could not be found on your PATH. Make sure that rsync
is properly installed on your system and available on the PATH.
```


# 調査
## 関連Qiita記事
[Windows 7 + Vagrant 1.4.2 でCentOS7のboxが起動できなかったので調べた - Qiita](http://qiita.com/ryozi_tn/items/1edf32f9c5ef174ddd53)
[Windows環境のVagrantでCentOS Atomic Hostを動かす - Qiita](http://qiita.com/tiibun/items/7f17a2c1198f5614bf4f)

### 2016/11/15 こちらの記事でばっちり解説されていました。
[vagrant において、明示的に VirtualBox の機能(vboxsf)を使いフォルダを同期するには、`config.vm.synced_folder ".", "/vagrant", type: "virtualbox"` のように Vagrantfile に設定するとよい - Qiita](http://qiita.com/toby_net/items/6eb74471871ab9fba087)


## 原因
　boxのVagrantfileで `config.vm.synced_folder ".", "/vagrant", type: "rsync"` と共有フォルダ種類を rsync 決め打ちにされていて、 Windows は rsync が入っていないためエラーとなっている。
CentOS公式BoxはVirtualBoxの共有フォルダ(Guest Additions)をあえて無効にしているみたい。[公式リリースノート](https://seven.centos.org/2017/09/updated-centos-vagrant-images-available-v1708-01/)

# 対処
　下記の方法がある。自分は手軽で便利な３にした。

1. 共有フォルダを無効にする
2. rsync をインストールする
3. 共有フォルダ種類を Vagrant デフォルトに再設定する


## 共有フォルダを無効にする
　関連Qiita記事で上がっている方法。 Vagrant ファイルを以下のように`disabled: true`する。

```ruby:Vagrantfile
Vagrant.configure(2) do |config|
  config.vm.synced_folder ".", "/vagrant", disabled: true
end
```


## rsync をインストールする
　まっとうな方法


## 共有フォルダ種類を Vagrant デフォルトに再設定する
Vagrant ファイルを以下のように`type: nil`する。

2016/11/15追記：`type:"virtualbox"`でもよいようです。

```ruby:Vagrantfile
Vagrant.configure(2) do |config|
  config.vm.synced_folder ".", "/vagrant", type:nil
end
```
JavaFXプログラムの基本構造


JavaFXのプログラムの基本的な書き方（構造）をまとめておきます。


# サンプルコード

JavaFXの基本構造は下記の通りです。

```java
public class xxx extends Application {
  public static void main(String[] args) {
    launch(args);
  }
  @Override
  public void start(Stage stage) throws Exception {
	primaryStage.show();
  }
}
```
上から順に説明していきます。

## Applicationクラス

JavaFXにおいては、
javafx.applicationパッケージにあるApplicationクラスを継承する必要があります。

その中で、いつものmainメソッドと、Applicationクラスのstartメソッドが呼ばれます。

## launchメソッド

JavaFXアプリケーションを起動するためのメソッドです。

## startメソッド

アプリケーションを開始する際の処理を記載します。
javafx.stageパッケージのStageクラスのインスタンスが引数として渡されます。

## Stageクラス

最上位のJavaFXコンテナです。
このStageの上でアプリケーションを組み立てていきます。
「枠」のようなものです。

## showメソッド

ウィンドウに表示を行うメソッドです。

# 実装例

実装例を交えつつさらに深掘りしていきます。


![Hello.JPG](https://qiita-image-store.s3.amazonaws.com/0/100978/3667a0ab-0fbe-ead8-2919-391beda64c37.jpeg)

ソースコードは下記の通りです。

```java
package javafx.test;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class Main extends Application{
	public static void main(String[] args){
		launch(args);
	}

	@Override
	public void start(Stage stage) throws Exception{
		Label label = new Label("Hello JavaFX!");
		BorderPane pane = new BorderPane();
		pane.setCenter(label);
		Scene scene = new Scene(pane,320,240);
		stage.setScene(scene);
		stage.show();
	}
}
```
## Labelクラス

ラベルを表示するためのクラスです。
引数としてラベル文字列を渡すことができます。
これはイメージしやすいと思います。

## BorderPaneクラス
部品はPaneというところに配置していきます。
Paneには複数種類があり、その中の１つがBorderPaneです。
レイアウトを決めるためのクラスです。

## Sceneクラス
Stageが枠だとしたら、Sceneは台紙のようなものです。
このScene上にPaneをのせます。

# 階層の整理

色々でてきて訳がわからなくなりそうですが、
階層構造としては下記です。
Stage>Scene>Pane>部品

これを頭にイメージしてソースコードを読むとだいぶ整理できると思います。

# まとめ
始めは構造がわかりにくかったですが、わかってしまえば簡単です。
アドバイス等あればお願いします。
ClickOnceのアプリケーションキャッシュの削除

## ClickOnceのアプリケーションキャッシュの削除
私はシステムの配布にClickOnceを使用しています。
時々、アプリケーションのダウンロードに失敗して起動すらできなくなることがあります。
そのような時はアプリケーションを削除してもらってから再度ダウンロードしてもらっています。
その時にアプリケーションを削除するツールです。

ClickOnceの起動がオンラインのみの場合に有効かと思われます。

VB.Netで記述しています。

```CleanClickOnceApplicationCache.vb
Imports system.Runtime.InteropServices

Class CleanOnlineApplicationCache

    Shared Sub Main()
        CleanOnlineAppCache()
        Console.WriteLine("Application cache cleared")
    End Sub

    <DllImport("Dfshim.dll")> _
    Private Shared Sub CleanOnlineAppCache()
    End Sub

End Class
```

配布にIE限定なのが悩みどころですね。。。
これからどうしていきましょうかね。。。
こんなズンドコキヨシは嫌だ with PHP その２

# こんなズンドコキヨシは嫌だ with PHP その２
## はじめに

- ゆるふわです

## あわせてよみたい

- [前回](http://qiita.com/shinderuman@github/items/15fe031ab9ff74ce8fb2)
- [関係ないけど一緒に書いたの](http://qiita.com/shinderuman@github/items/e6b1350980aec3497875)

## 概要

- さらにひどいズンドコキヨシをめざした
- スクリプトが配置されたディレクトリ名が `./ズン/ドコ/キ・ヨ・シ！/` の時のみズンドコ
    - `./ｽﾝ/ｽｰﾝ/ｲｪｰｽﾝｽﾝｽﾝ/` ならｽﾝｽﾝｽﾝｽｰﾝします 
- 標準出力はせず実行結果をファイル名として出力します
- `$z`, `$d`, `$k` の代入の時点で同僚に殴られるレベル
- generatorを使いたいだけの理由で `ズン`, `ドコ` を返すのをgeneratorで実装し即時呼び出してiterationさせた

## 実装

```php
<?php
$z = basename(dirname($d = dirname($k = dirname(__FILE__))));
$d = basename($d);
$k = basename($k);

$zdk = '';
$zzzd = $z . $z . $z . $d;
foreach((function () use ($z, $d) {
    loop: yield [$z, $d][mt_rand(0, 1)];
    goto loop;
})() as $zd) {
    $zdk .= $zd;
    if (mb_substr($zdk, -mb_strlen($zzzd)) === $zzzd) {
        $zdk .= $k;
        break;
    }
}
touch($zdk);
```

## ズンドコ結果

```shell-session
shinderuman4:[git][master]:キ・ヨ・シ！% pwd
/Users/shinderuman/ズン/ドコ/キ・ヨ・シ！
shinderuman4:[git][master]:キ・ヨ・シ！% ls
hoge.php
スンスンスンスントコキ・ヨ・シ！
トコスンスンスントコキ・ヨ・シ！
スンスンスンスンスンスンスンスントコキ・ヨ・シ！
トコトコスントコトコトコトコトコスンスントコスンスンスントコキ・ヨ・シ！
トコトコトコトコトコトコトコスンスントコトコトコトコスントコトコスントコトコトコトコトコトコトコトコスンスンスンスンスンスンスントコキ・ヨ・シ！
```

## ｽﾝｽﾝ結果

```shell-session
shinderuman4:[git][master]:ｲｪｰｽﾝｽﾝｽﾝ% pwd
/Users/shinderuman/ｽﾝ/ｽｰﾝ/ｲｪｰｽﾝｽﾝｽﾝ
shinderuman4:[git][master]:ｲｪｰｽﾝｽﾝｽﾝ% ls
hoge.php
ｽｰﾝｽｰﾝｽﾝｽﾝｽﾝｽﾝｽﾝｽｰﾝｲｪｰｽﾝｽﾝｽﾝ
ｽｰﾝｽｰﾝｽｰﾝｽﾝｽﾝｽﾝｽﾝｽｰﾝｲｪｰｽﾝｽﾝｽﾝ
ｽﾝｽｰﾝｽｰﾝｽｰﾝｽｰﾝｽｰﾝｽｰﾝｽｰﾝｽｰﾝｽﾝｽﾝｽｰﾝｽｰﾝｽｰﾝｽｰﾝｽﾝｽﾝｽﾝｽｰﾝｲｪｰｽﾝｽﾝｽﾝ
ｽﾝｽｰﾝｽｰﾝｽﾝｽﾝｽｰﾝｽｰﾝｽｰﾝｽｰﾝｽﾝｽｰﾝｽﾝｽｰﾝｽｰﾝｽﾝｽﾝｽｰﾝｽｰﾝｽｰﾝｽﾝｽｰﾝｽｰﾝｽﾝｽｰﾝｽﾝｽｰﾝｽﾝｽｰﾝｽｰﾝｽﾝｽｰﾝｽｰﾝｽｰﾝｽﾝｽﾝｽｰﾝｽﾝｽｰﾝｽｰﾝｽｰﾝｽﾝｽｰﾝｽﾝｽｰﾝｽｰﾝｽﾝｽｰﾝｽｰﾝｽﾝｽﾝｽｰﾝｽﾝｽｰﾝｽｰﾝｽﾝｽﾝｽｰﾝｽｰﾝｽｰﾝｽﾝｽｰﾝｽﾝｽﾝｽｰﾝｽﾝｽﾝｽｰﾝｽｰﾝｽﾝｽﾝｽｰﾝｽｰﾝｽｰﾝｽﾝｽﾝｽﾝｽﾝｽﾝｽｰﾝｲｪｰｽﾝｽﾝｽﾝ
```

## まとめ

- 仕事でこんなコード見せられたら殴る
全てのジャンクションを解決したパスを取得したい

あるパスから全てのジャンクションを解決したパス（要するに本来の場所のパス）を取得したいと思った。
汚いなりに形が出来たと喜んだのも束の間、対象としたいWindows7（PowerShell v2.0）では動かなそうなことが判明。

とりあえず現状を備忘録として残す。

# 思考の流れ
1. `Get-Item 'フォルダパス'`で`System.IO.DirectoryInfo`を取得すれば、`Attribute`からリパースポイント（ジャンクションなど）かどうかわかる（[参考](http://tech.guitarrapc.com/entry/2014/08/19/022232)）。

1. 一階層ずつジャンクションかどうか判断し、ジャンクションなら本来の場所へ移動して、また登って行けば良い。
1. ルートフォルダまで辿り着いたら探索終了とし、それまで通ってきたフォルダの履歴をパスとして接合する。

# 出来上がったもの

```ps1:Solve-JunctionPath.ps1
#引数の設定
Param(
    [Parameter (Mandatory=$true)]
    [String]$FilePath #=$Args[0]
)

[IO.FileSystemInfo]$argPath=Get-Item $FilePath

#一階層毎のフォルダ名配列 Leaf To Root
[Collections.Generic.IList[String]]$DirNameList = New-Object -TypeName Collections.Generic.List[String]


if ($argPath.Attributes -like "*Directory*")
{
    [IO.DirectoryInfo]$tmpDir = $argPath
} else {
    [IO.DirectoryInfo]$tmpDir = $argPath.Directory
}

do
{
    if ($tmpDir.Attributes -like "*ReparsePoint*")
    {
        $tmpDir = Get-Item $tmpDir.Target
    }
    
    #ジャンクション解決後のフォルダ名を取得する
    $DirNameList.Add($tmpDir.Name)
    
    $tmpDir = $tmpDir.Parent
}
until($tmpDir.FullName -eq $tmpDir.Root.FullName)

#Root To Leaf
$DirNameList.Reverse()


[String]$out = $tmpDir.FullName + ($DirNameList -join '\')

#フォルダを開く
Explorer.exe $out
#結果確認用
#$out
```

## 使用例
上記のコードを"Solve-JunctionPath.ps1"という名前で保存し、同じ場所に以下のようなbatファイルを作成する。

```bat
@PowerShell.exe -ExecutionPolicy RemoteSigned %~dp0\Solve-JunctionPath.ps1 '%~1'
```

このバッチファイルに調べたいパスを送ると、本来の場所のフォルダが開く。

# 問題の箇所

```ps1
    if ($tmpDir.Attributes -like "*ReparsePoint*")
    {
        $tmpDir=Get-Item $tmpDir.Target
    }
```
PowerShell 2.0では
（161110修正）
~~DirectoryInfoのAttributesに再解析ポイントかどうかの情報を持たないので、~~
リンク先本来の場所の情報を持たない（`.Target`プロパティが存在しない）ため、
この方法では辿ることができない。

実際、`Get-Member`をしてみると`.Target`プロパティは`CodeProperty`となっている。
つまりPowerShell側で追加されたプロパティであるため、PowerShellのバージョンが低いと存在しないということになる。

# 対応策
とりあえず思いつく解決策としては、
`cmd.exe /c dir "ディレクトリパス" /AL`
の出力結果を正規表現なりで解析する方法。

`更新日時    <JUNCTION>     ジャンクション名 [参照先]`
の形式で取得できるのでジャンクション名で判定し、参照先へ移動、すれば何とかなると思われる。

# 参考
[PowerShell で シンボリックリンクを 使えるようにしよう](http://tech.guitarrapc.com/entry/2014/08/19/022232)
[PowerShellでジャンクションを作ったら削除はRomove-Itemしてはダメ](http://m0t0k1x2.tumblr.com/post/133581820929/powershell%E3%81%A7%E3%82%B8%E3%83%A3%E3%83%B3%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E4%BD%9C%E3%81%A3%E3%81%9F%E3%82%89%E5%89%8A%E9%99%A4%E3%81%AFromove-item%E3%81%97%E3%81%A6%E3%81%AF%E3%83%80%E3%83%A1)
jupyterでhtml-javascript側の値を取得するメモ

#やりたいこと
jupyter上でhtml-javascriptを動かして、その結果の値をpython側に受け渡して使いたい
（例：javascript上でお絵かきした座標を使ってpython側で計算させたいなど）
と思い調べていると[Custom-Widget](https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Custom.html)というものがあるようで試してみました。

#使用例
以下のものはhtmlのフォームを表示させ、その中に入力したものをpython側に受け渡して表示しています。
[こちらの例](https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Custom.html#Building-a-Custom-Widget---Date-Picker)を少し改造していますが、慣れないjavascriptを使っているのでもっといい方法があるかもしれません。



![無題の図形描画.png](https://qiita-image-store.s3.amazonaws.com/0/109458/872e26d7-d063-87cf-d179-0da90a3f042d.png)

#ソース
 - html作成

```
%%html
<!DOCTYPE html><html lang="ja">
<head><mata charset="utf-8"/><title>widget test</title></head><body>
<form name="js"><input type="text" name="txt_form" value=""><br></form><script>
require.undef('hello');
define('hello', ["@jupyter-widgets/base"], function(widgets) {
    var HelloView = widgets.DOMWidgetView.extend({
        render: function() {
            this.model.on('change:value', this.value_changed, this);
        },
        value_changed: function() {
            this.model.set('html_form', document.js.txt_form.value);//ここでフォーム内のテキストを取得
            this.touch();
        },
    });
    return {
        HelloView : HelloView
    };
});
</script></body></html>
```
 - ipywidgets作成
 
```
import ipywidgets as widgets
from traitlets import Unicode
class HelloWidget(widgets.DOMWidget):
    _view_name = Unicode('HelloView').tag(sync=True)
    _view_module = Unicode('hello').tag(sync=True)
    value = Unicode('Hello World!').tag(sync=True)
    html_form = Unicode('').tag(sync=True)
my_widget = HelloWidget()
my_widget#ここで一度ウイジェットを作る必要がある
```
 - フォーム内の値を取得（取得までにはわずかな時間がかかるので、直後に値を表示させると更新されていない）

```
my_widget.value += 'w'#valueに[w]を追加することで、無理やり値を変えて、同期イベントを起こし、フォーム内の値を取得
```
- フォーム内の値を表示

```
print(my_widget.html_form)#フォーム内の値を表示
```
NotificationCenter基礎の基礎

「NotificationCenterってそもそも何？」「何がいいの？」「最低限で使うにはどうしたらいいの？」に答えるSwift3対応記事があまりなさそうだったので（Objective-Cのはあったけど）書いてみます。

図にするとこんな感じです。
![forQiita.png](https://qiita-image-store.s3.amazonaws.com/0/45467/1cf27b2f-2935-2b00-0124-be2d670a041e.png)

**親子関係がないクラス同士**の連絡にすごく重宝します。

メッセージが統一されていれば
クラスAが複数あっても、クラスBが複数あっても大丈夫。連絡が取りあえます。

サンプルとしてホームボタンを押してバックグラウンドに行く時に"willResignActive"というメッセージを発信して、ViewControllerで受け取るサンプルを作ります。

###まずSingleViewApplicationプロジェクトを作ります
<img width="732" alt="スクリーンショット 2016-11-06 16.23.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/45467/2f3c746e-67d3-596d-2348-e2b0bf7b9cca.png">


###AppDelegate.swift内で発信コードを書きます
```
    func applicationWillResignActive(_ application: UIApplication) {

        // "willResignActive"を発信！
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "willResignActive"), object: nil)
    }
```

###ViewController.swift内に監視コードと受け取りコードを記述
```
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 「"willResignActive"って呼ばれたらこのクラス(self)に書いてあるhoge()を呼んでね」
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(self.hoge),
            name: NSNotification.Name("willResignActive"),
            object: nil
        )
    }

    func hoge() {
        print("willResignActiveって呼ばれたよー！")
    }

}
```

たったこれだけで使えます。

アプリ開発を始めた頃とてもありがたい仕組みだったので、ぜひ使ってみてください。連絡を取り合うクラス同士に親子関係があるならDelegateを使った方がいいですけどね。
VagrantでCentOS7の環境を作る


作成環境

* host:mac OSX 10.10.5
* VirtualBox 5.0.20r106931
* vagrant 1.8.1

```
$ mkdir centos7
$ cd centos7
$ vagrant box add https://atlas.hashicorp.com/hfm4/boxes/centos7
```

少し時間がかかります。
404 Not Foundなどが出ると、リンク先が削除されているので、
都度確認してください。

```
vagrant box list
```


早速セットアップ開始
initの後ろの名前は使うboxにより変わります。

```
vagrant init hfm4/centos7
```

Vagrantfileが作成されていれば問題ありません。
networkの設定を変更する

```
VBoxManage list bridgedifs
```

こちらから有効なネットワークインターフェースを指定する。
例えば、こんな感じで設定します。

```
<   config.vm.network "public_network", ip: "xxx.xxx.xxx.xxx", bridge: "en0: Wi-Fi (AirPort)"
---
>   # config.vm.network "public_network"
```

vagrantの立ち上げ

```
vagrant up
```

vagrantユーザーとしてログイン

```
vagnrat ssh
```

最初の設定はvagrantユーザーでしかログインができないので、好みで設定を変更してください。

ちなみに、centos7では、ifconfigが使えないので、ネットワークインターフェースの確認は

```
ip a
```

で行ってください。
非推奨のものを使い続けるのは危険です。

ついでに通常のsshでも接続できるように以下の設定をしておくと便利です。

```
vagrant ssh-config --host xxx.xxx.xxx.xxx >>  ~/.ssh/config
```

rootでログインできないように制限をかける

```
ssh xxx.xxx.xxx.xxx
su -
vi /etc/ssh/sshd_config
```

```
> #PermitRootLogin yes
---
< PermitRootLogin no
```

サービスの再起動

```
systemctrl restart sshd.service
```

ssh でrootログインができないことを確認して完了です。
vimのnerdtreeにファイルアイコンをつける

#こんな感じになります

![スクリーンショット 2016-11-06 14.57.12.png](https://qiita-image-store.s3.amazonaws.com/0/100352/b1767637-1d6c-a231-8968-2c7627225456.png)

#参考にした記事
[rictyにnerd-fontsのパッチを当てる(試行錯誤)](http://qiita.com/nechinechi/items/27f541849db04123ea15)
[vimでatomのfile-iconsのような感じにする](http://qiita.com/tos-miyake/items/0cb4729c4d6a949bd480#_reference-79b1ff315bd6832dab2b)

#導入方法
macOSでは,gitがopensslではなくSecureTransportを使用しているためビルドしてあげる

```bash
brew reinstall git --with-brewed-curl --with-brewed-openssl
```

fontforgeのインストール

```bash
brew install fontforge --use-gcc --without-python
```

rictyのインストール

```bash
brew tap sanemat/font
brew install --powerline --vim-powerline ricty
cp -f /usr/local/Cellar/ricty/4.0.1/share/fonts/Ricty-* ~/Library/Fonts/
```

nerd-fontのインストール

```bash
git clone https://github.com/ryanoasis/nerd-fonts
cd nerd-fonts
chmod 755 font-patcher
fontforge -script ./font-patcher ~/Library/Fonts/Ricty-Regular-Powerline.ttf --fontawesome --fontlinux --octicons --pomicons --powerline --powerlineextra
cp -f ./Ricty\ Regular\ for\ Powerline\ Nerd\ Font\ Complete.ttf ~/Library/Fonts/
fc-cache -vf
```

#itermの場合
FontをRictyRegularforPowerlineNerdFontCompleteに変更する

#.vimrc
[vimでatomのfile-iconsのような感じにする](http://qiita.com/tos-miyake/items/0cb4729c4d6a949bd480#_reference-79b1ff315bd6832dab2b)を参照

#最後に
素敵なvimライフを!
rex0220 複数選択項目リセットプラグイン

# 複数選択項目リセットプラグイン（販売停止）

複数選択項目の全選択・リセットを行うプラグインです。

複数選択項目のラベル欄にチェックボックスが表示され、クリックすると全選択・リセットとなります

※サブテーブル内の複数選択項目は、対象外

[rex0220 stores で、販売中です。](https://rex0220.stores.jp/)

![mrest01.png](https://qiita-image-store.s3.amazonaws.com/0/100572/e393d91f-1849-e2ec-d8ce-6acd83ed087c.png)


# プラグインの追加

![mreset11.png](https://qiita-image-store.s3.amazonaws.com/0/100572/70efff4e-b29e-ad76-1d47-7da74cf182f9.png)


# プラグインの設定

プラグイン設定画面を開くと、複数選択項目が表示されますので、対象にする項目をチェックします。
設定後に、「保存する」ボタンをクリックします。

対象アプリのフォームを変更する場合は、フォーム変更を本番環境に反映後に、プラグインを再設定してください。

![mreset12.png](https://qiita-image-store.s3.amazonaws.com/0/100572/ecaa8d05-8f8f-2747-9cef-28ef975b4768.png)

# 注意事項

- 既に、JavaScript によるカスタマイズを行っているアプリの場合、処理が競合して、エラーになる場合があります。その場合は、該当するアプリでプラグインの使用を中止してください。
- フォームを変更した場合は、プラグインを再設定してください。
SQLおじさんの勉強会に参加しました[2016.11.05]

##はじめに
2016年11月5日に開催された
>SQLの書き方とAPIファースト開発セミナー
>http://api-first.connpass.com/event/43492/

に参加してきました。

どんなことを勉強してきたのかメモしておきます。
以下、自分の理解で書いているので間違った内容を含んでいるかもしれません。
ご容赦ください。


##勉強会の内容
1. APIファースト開発の概要と利点
　「テーブル設計を行う前でも、テーブルのスタブを使ってアプリケーション側の開発を進められる」という話を聞きました。

2. SQLの書き方
　「エクセルで書けることはSQLでも書ける」という例を見ました。

##個人的に勉強になった箇所
　以下の内容は、ある程度フィルターがかかっています。自分が知っている(つもりになっている)箇所は全くメモしていないので。

###あるアプリケーションがどのテーブルを参照しているかが簡単に分かる方法
　1. あるアプリケーションで発行されるSQL全てをPL/SQLで作成しコンパイルしておく
　2. FROM ALL_DEPENDENCIESを使った不思議な呪文を使うとPL/SQLが参照しているテーブル一覧が確認できる

　以上の簡単な手順でテーブルを変更した際にどのアプリケーションが影響を受けるか簡単に分かるようです。保守、運用の際に便利だと思いました。

###Oracleのパーサーを利用することでWhere句の条件追加が楽に書ける
　検索用のSQLで条件追加をしたりするときに、Where句に条件をどんどん追加していくと思うのですが、紹介されていた方法だと簡単に条件追加が行えていました。手続き型言語でORMを利用してWhere句に条件を追加するよりも楽に設定できて便利だと思いました。

###パラメータテーブルを用いることで手続き型言語のロジックをSQL側に移行できる
> ストアドプロシージャでビジネスロジックを書くこと
> http://qiita.com/kantomi/items/b560d3a0d400a1cc2225

　内容的には上のリンクに書いてあることと同じような説明を受けました。
　勉強会で改めて気づいたのが、自分が手続き型言語で行っていた処理を、SQLおじさんはPL/SQLで行わせているということでした。上のリンクではパラメータテーブルというビジネスロジックに関わるデータを格納したテーブルを用いてPL/SQLを実行しています。そのため、今まで手続き型言語にマップしてから処理を行っていたものが、PL/SQLだけで完結するようになっています。
　自分はこういったテーブルの作り方をしていなかったので、こういう方法もあるのだと勉強になりました。


##勉強会に参加する前にあったほうがいいと思う知識

　勉強会はOracleを主として、他の言語との違いを述べるというような形式で進みました。
　私はOracleメインで使っているのでよく理解できましが、Oracle関連の知識は事前に必要だなと感じました。

+ Oracle SQL言語リファレンスの内容

>https://docs.oracle.com/cd/E49329_01/server.121/b71278/toc.htm


　集計関数分かっていないと理解できない部分とかあったので言語リファレンスは読んでおいたほうがいいと思います。

```sql
SELECT
  SUM(点数) OVER (PARTITION BY 学生番号)
FROM
  成績表
```

　勉強会の短い時間で集計関数を理解するのは難しいと思うので。
　さすがにModel句はでてきませんでした。

+ SQL Developerの存在と実行計画の見かた

　SQL Developer上でSQL書いたり、実行計画見たりしてたので、このツールが何やっているのかくらいは知っていたほうが理解が早いと思います。このツールを触っていなくても「A5:SQL Mk-2」とか「SI Object Browser」を触っていたらなんとなくわかると思います。

##感想
　SQLおじさんはSQLについてかなり詳しかったです。業界一年目の自分が言うのもあれですが、かなり勉強されているんだと感じました。
　
　APIファースト開発自体は、かなりの部分をSQL寄りで開発を進める手法だと思いました。なんでもSQL400本あったらフェッチさせるのは4本だけで済んだという事例もあるみたいです。基本的にSQLでレコードごとの処理を行って、どうにもうまくいかないことを手続き型言語でやると思うのですが、自分なら4本どころじゃすまないだろうと思いました。ただ、SQLのコーディング力を向上させるのと、前述したパラメータテーブルを用いてロジックを各やり方を実践すればある程度はSQLのみの処理にできそうです。
　気になったのが、パラメータテーブルを作成してPL/SQLでロジックを実装する方法と、手続き型言語にパラメータを埋め込んでロジックを実装する方法のどちらが処理を簡単に実装できるかということです。まだ今回の勉強会で学んだことを実践していないので、機会があればパラメータテーブルを使う方法も実践していきたいです。

　勉強会では、「ORMはSQL主体の開発とはコンセプトが違うため、いくら進歩させても良い結果を得られない」という意見が出ました。自分の解釈ではORMのコンセプトとして「データベースへのアクセスもxmlファイルへのアクセスも、中身を気にせず同様にアクセスできるようにする」というのがあると思っていて、SQL主体で開発している側からは相容れないということだろうと思いました。

##最後に
　関係ない話が多くなっていますが、このセミナーの目的はAPIファーストで開発して開発効率UP、工数削減が目的になっています。ここには書かれていない有益な情報も数多く勉強会では発信されていました。おそらく今後も勉強会が開かれることがあると思うので興味を持った方は直接行かれてはどうかと思います。
gitにローカルブランチはいらない

少しクセのあるgitの使い方。
丸4年このやり方をして一度もローカルブランチを切る必要に迫られたことはない。
シンプルな手順なので共感するひとが増えたら嬉しい。

###前提
* github等のリモートリポジトリを使いながら開発する(スタンドアローンでgitを使う人には向かない)

###ローカルブランチを切っていたときに感じていたこと
* リモートとローカルに同名の別の内容のリビジョンのブランチができてしまうのでどこが正なのか記憶しなくてはいけない（複数サーバで開発した場合特に）
* git pullで暗黙的にブランチを書き換えるより明示的にmerge、rebaseしたい
* 作業が終わったらバックアップの意味を含めリモートにpushすべきなのでローカルブランチとして状態を持つことに意味がない

###手順
#### 新しく開発を始める
checkoutするときはリモートリポジトリを指定し、常にno branchで作業する。
```
git fetch --all
git checkout origin/master
```

####開発が一区切り着いたら
言語や環境に不慣れな場合は特に細くコミットをしながら進めるのでゴミコミットがたくさんできている。
意味のないコミットはpushする前にまとめる。
必要性を感じなければしなくていいと思う。

```
git reset --soft origin/master
git commit -m 'message'
```

####リモートリポジトリにブランチを作る
pushと同時にリモートブランチを作成する。
既存のブランチに継ぎ足す場合も同じコマンドでOK。
```
git push origin HEAD:refs/heads/new-branch-name
```

###注意点
* 作業が終わったら必ずリモートにpushすること。万一push前なのに別ブランチをチェックアウトしてしまった場合は```.git/logs/HEAD```から探す。
Pythonモジュールを作成[CarSensorAPIサポートモジュール csapi]

# やりたいこと
[CarSensor API][]をPythonで[Voicetext][]のモジュールみたいなことがしてみたい。
いつもは自分が使えればいいやコードしかかないけど、どうせならばと思い見様見真似で、作ってみた。

と、作ってみた[CarSensor-Web-API][]です。

# 環境
**★ローカル環境**
MacBook Pro (13-inch, Mid 2012)
プロセッサ: 2.5 GHz Intel Core i5
メモリ: 4 GB 1600 MHz DDR3

**★使用言語**
Python
json

# 参考した内容
APIKEYの登録やキーワード処理などは、[Voicetext][]を参考にし、
いろいろ調べつつ、作成しました。

ちなみに、Pythonモジュールは、folder内部に`__init__.py`が必須で、階層が増えても`import`を参照が可能です。以下サンプルコード。

```python:sample.py
import csapi
from csapi import parse
```
また、今回作成したフォルダーのツリーとなります。
さらに追加機能として、[パーサ][parse]などもできるようにしたいと思い、
`parse.py`というファイルを作成しています。

```folder:Tree
Tree
├── csapi
│   ├── __init__.py
│   ├── parse.py
│   └── setup.py
└── test
    └── api_test.py
```

# 工夫してみたこと & 今後の発展
今回、工夫してみたことは、Pythonコードだけではなく、[パーサ][parse]を追加してみたこと。
csapiモジュールが追加されていれば、コマンドからでもアクセス可能です。

今後の発展としては、今はまだ、中古車とカタログの検索APIのみとなってるので、その他のAPIもサポートできるモジュールとPython3対応&pipでのインストールに挑戦してみたいと思ってます。

同時に、モジュール設計について、ご教授願います。

## Link 一覧
[CarSensor API][]
[Voicetext][]
[parse][parse]
[CarSensor-Web-API][]

[CarSensor API]:https://webservice.recruit.co.jp/carsensor/reference.html
[Voicetext]:https://github.com/youtalk/python-voicetext
[parse]:http://docs.python.jp/2/library/argparse.html
[CarSensor-Web-API]:https://github.com/xapa0ace/CarSensor-Web-API
Puppet 4.8 リリースノート ピックアップ

Puppet4.8.0(2016/11/1リリース)の、リリースノートで個人的に気になる変更をピックアップしてみました。動作確認とかはしてないので、間違っている部分があればご指摘ください。

**4.8では、よりRubyぽい制御文が増えた感じです。**

# Puppet 4.8.0

Released November 1, 2016.

## New features

### New types

> The type system has been extended with two types that help working with time related values. The Timestamp type is a point in time, and the Timespan is a duration.

時刻を表すTimestampタイプと、期間を表すTimespanタイプが追加されました。

フォーマットについてはこちらを参照。

- https://docs.puppet.com/puppet/latest/reference/function.html#conversion-to-timestamp
- https://docs.puppet.com/puppet/latest/reference/function.html#conversion-to-timespan

なお、具体的な使用例は書かれていないみたいです。~~おそらく、Puppetを定期実行しているような運用で、ある時刻や期間を過ぎたら設定を反映するとかに使うかと思います。~~**いまいち用途不明なので、要検証です。**

### New functions break, next, and return

> The functions break(), next() and return() have been added to make it possible to do an “early exit” from a block of code.

break(), next(), return()が追加されました。
動作としては、Rubyとかと一緒に見えます。

### Absolute support

> It is now possible to specify that an absolute (positive) value is wanted when creating a new Integer, Float, or abstractly via Numeric by passing a second optional boolean argument to the new function where true means that an absolute value is wanted. 

絶対値がサポートされました。

## Enhancements

### PUP-5831:

> The type system and runtime now support binary data by using the Binary type. It allows binary content to be created from plain text and base 64 encoded text.

テキストなどから、バイナリーデータを作れるようになったみたいです。

https://docs.puppet.com/puppet/latest/reference/function.html#binary-value-to-string

### PUP-6789:

> This allows application components to consume capabilities from other environments. If multiple capabilities are found the capability from the current environment will be preferred.

environmentで分けている場合、他のenvironmentの機能も使えるようになったようです。具体的な部分は未確認なので、**要検証です。**

##Bug fixes

### PUP-6803:

> Some puppet types (notably file and user) are capable of generating resources. (中略)
> In Puppet 4.8.0 and later, if Puppet fails to generate resources for any managed resource, this results in a report status of failed.

リソースを変更できなかった場合の挙動が少し変わったようです。
例として、ディレクトなどをrecurse => trueにしていて、ディレクトリの中にあるsocketファイルなどが変更できなかった場合、
レポートのステータスがfailedになるようです。（以前だと、changedかunchanged）

### PUP-6414:

> Updated the puppet module tool to use “forgeapi.puppet.com” (instead of “forgeapi.puppetlabs.com”).

puppet module toolが使うURLが更新されたようです。
普通の場合は特に影響ないかと思いますが、もし、特定のURL以外の通信を許可していないようなネットワーク環境の場合、通信の許可設定を変更するとか必要かもしれません。

# 参考

Puppet 4.8 Release Notes
https://docs.puppet.com/puppet/4.8/reference/release_notes.html
pandasでデータを読み込むときに気を付けること(dtypeの指定)

### pandasでデータを読む場合、dtypeは指定したほうが安全

```
この記事ではpandas 0.18.1を利用しています。
```
dtypeに何も指定せずにいると、勝手に型を判別してしまいます。
例えば以下のようなタブ区切りのデータがあった場合

```
data_1.txt

id	x01	x02	x03	x04	x05	x06	x07	x08	x09	x10
0001	0.54	0.54	0.85	0.79	0.54	0.36	0.28	0.52	0.21	0.49
0002	0.72	0.68	0.77	0.69	0.07	na	0.29	0.42	0.32	0.51
0003	0.68	0.99	0.19	0.16	0.31	0.76	0.57	0.08	0.07	0.98
0004	0.98	na	0.49	0.47	0.09	0.52	0.42	0.35	0.83	0.64
0005	0.37	0.35	0.99	0.88	0.81	0.46	0.57	0.47	0.06	0.55
```

```
# coding: UTF-8

import pandas as pd
df = pd.read_csv('‪data_1.txt', header = 0, sep = '\t', na_values = 'na')
print df
```

```
	id	x01	x02	x03	x04	x05	x06	x07	x08	x09	x10
0	1	0.54	0.54	0.85	0.79	0.54	0.36	0.28	0.52	0.21	0.49
1	2	0.72	0.68	0.77	0.69	0.07	NaN	0.29	0.42	0.32	0.51
2	3	0.68	0.99	0.19	0.16	0.31	0.76	0.57	0.08	0.07	0.98
3	4	0.98	NaN	0.49	0.47	0.09	0.52	0.42	0.35	0.83	0.64
4	5	0.37	0.35	0.99	0.88	0.81	0.46	0.57	0.47	0.06	0.55
```

型を指定しないと、上のようになってしまい、idのゼロが落ちます。
df.dtypes でidのデータ型を確認するとintになってしまっています。

このような場合は、

```
df = pd.read_csv('data_1.txt', header = 0, sep = '\t', na_values = 'na',
                 dtype = {'id':'object', 'x01':'float', 'x02':'float','x03':'float','x04':'float','x05':'float','x06':'float',
                          'x07':'float','x08':'float','x09':'float','x10':'float'})

print df
```
```
     id   x01   x02   x03   x04   x05   x06   x07   x08   x09   x10
0  0001  0.54  0.54  0.85  0.79  0.54  0.36  0.28  0.52  0.21  0.49
1  0002  0.72  0.68  0.77  0.69  0.07   NaN  0.29  0.42  0.32  0.51
2  0003  0.68  0.99  0.19  0.16  0.31  0.76  0.57  0.08  0.07  0.98
3  0004  0.98   NaN  0.49  0.47  0.09  0.52  0.42  0.35  0.83  0.64
4  0005  0.37  0.35  0.99  0.88  0.81  0.46  0.57  0.47  0.06  0.55
```

このように、dtypeを指定するともとの形を保持できます。ＲでいうcolClasses ですね。
dtype を指定したほうが、データの読み込みが早い気もします。

また、とりあえず最初は全てobjectで読んでおいて、後から必要な個所のみ変更することもできます。

```
# 最初はすべてobjectで読む
df = pd.read_csv('data_1.txt', header = 0, sep = '\t', na_values = 'na', dtype = 'object')

var_lst = ['x01','x02','x03','x04','x05','x06','x07','x08','x09','x10']
df[var_lst] = df[var_lst].astype(float)    # データ型をfloatに変更する
```
Windows の C 言語環境でのファイル記述子、ファイルポインタ、ファイルハンドルについて整理

この記事は私が書いた記事の焼き直しです。
http://d.hatena.ne.jp/temtan/20120723/1343050321

Windows の C 言語環境でファイル入出力を扱う場合、複数の方法があり混乱しやすいので整理してみました。

Windows の C 言語環境の場合、ファイルの入出力関数に関しては複数があり、C 言語標準のファイル入出力関数群、Windows 特有のファイルハンドルを使った関数群、Unix系の関数群を模した低水準ファイル入出力があります。

<dl>
<dt>ファイルポインタ </dt>
<dd>C 言語構造体 FILE のポインタ。fopen 関数でファイルを開いたりして取得するやつ。型は FILE*</dd>
<dt>ファイルハンドル </dt>
<dd>Windows OS 特有のハンドル。CreateFile 関数で取得したりするやつ。型はHANDLE</dd>
<dt>ファイル記述子 </dt>
<dd>ファイル記述子、ファイルディスクリプタ等と呼ばれる、型が int の値。UNIX でも使われる物に相当。</dd>
</dl>

それぞれは扱う関数が別になっているので例えば Windows特有のファイルハンドルを使って C 言語標準のファイル入出力関数群を使うといったことが出来ない。

ファイルポインタは C 言語標準で C 言語が使える環境なら常に使えるようになっている筈で、後述のファイル記述子は移植性に問題があったが、こちらでは移植性が高く、便利な関数がそろってたりするので扱い易い。C 言語を勉強するときは最初にコレを勉強すると思う。自分も最初はコレだった。

ファイルハンドルは Windows OS 特有のハンドルで管理される。Windows 上で上記二つを扱う場合でも内部的に最終的にはこちらを経由して扱うことになる（と思う）。こちらでファイルアクセスする場合は、とにかく面倒臭い。Win32API の関数がやたら引数と引数に指定するパラメータが多いのでいちいちリファレンスを見ないと扱えない。その代わり細かい制御をしたい場合はこちらでないと出来ないことが多い。

ファイル記述子は UNIX でストリームを扱う際に OS により与えられる整数値。ファイルだけでなくストリーム全般を扱い低水準であるため扱いが色々面倒である部分もある。また、この概念は UNIX でない OS では無い場合もあるので移植性は基本的に無い。

| 種別 | ファイルポインタ | ファイルハンドル | ファイル記述子 |
|:--|:--|:--|:--|
|型   |FILE*   |HANDLE   |int   |
|ファイルを開く   |fopen   |CreateFile   |_open   |
|読む   |fread 等   |ReadFile  |_read（注:readではない）   |
|書く   |fwrite 等  |WriteFile    | _write（注:writeではない）  |

注意点として、ファイル記述子を使う関数は最初にアンダースコアがつくこと。アンダースコアがつかない read と write は windows socket 用の関数であり、ファイルに対しては使えない。この辺混乱しやすい。

そしてそれらの相互に変換する関数群について。

|  |  | stdio.h |  |  |  | io.h |  |  |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|ファイルポインタ   |→   |_fileno   |→|ファイル記述子   |→ | _get_osfhandle  | →   |ファイルハンドル   | 
|ファイルポインタ   |←   |_fdopen   |←|ファイル記述子   |←   |_open_osfhandle |←   | ファイルハンドル |

自分の場合、単純にファイルを開くのではなく、既に開いているパイプだったり、変な方法で開いたファイルだったり色々あってファイルハンドルで取得する場合があったりするのだが、それ用の関数の ReadFile や WriteFile が引数指定が多くて手軽に使えず、慣れているファイルポインタを使った方法を使いたかったので、そういった場合は上記の関数を使い変換して使うようにしている。
Swift3でISO8601フォーマットの文字列をDate型に変換する

GithubのAPIやQiitaのAPIなどのレスポンスに含まれている日付はISO8601フォーマットになっています。
その形式をSwiftのDate型で扱うために、下記のように`Date`の`extension`を実装していきます。

```swift:Date+ISO8601.swift
extension Date {
    private static let ISO8601Formatter: DateFormatter = {
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "en_US_POSIX")
        dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZ"
        return dateFormatter
    }()
    
    init?(fromISO8601 string: String) {
        guard let date = Date.ISO8601Formatter.date(from: string) else {
            return nil
        }
        self = date
    }
}
```

上記のextensionを利用することで、下記のように扱うことができるようになります。

```swift
let dateString = "2014-07-31T05:56:19Z"
let date = Date(fromISO8601: dateString) // Optional(2014-07-31 05:56:19 +0000)
```
TensorFlow入門時に多分一番単純で実用的なコード例（1次元入力データ群からのクラス分類）

タイトル通りです。
特徴量を入力して分類・識別（回帰）するだけの単純なコード例が意外と無いので、自分で書いときます。
下の記事でやった単純なディープラーニングの実装のTensorFlow版です。

**簡単なディープラーニングのサンプルコード (2入力1出力/2クラス分類) with Keras**
http://qiita.com/ryo_grid/items/e746238c78b8c6427200


学習用データは作るのが面倒なので、学習処理のループのところで偶数奇数で分岐して食わせるデータを変えるということをしています。
学習時の回答データは、正解のラベルに対応する要素のみ1で他は0の配列を用意します。

```python:simple_tf_regression.py
import tensorflow as tf

# number of inputs
input_len = 2
# number of classes 
classes_num = 2

sess = tf.Session()

x = tf.placeholder("float", [None, input_len])
y_ = tf.placeholder("float", [None, classes_num])

weights1 = tf.Variable(tf.truncated_normal([input_len, 50], stddev=0.0001))
biases1 = tf.Variable(tf.ones([50]))

weights2 = tf.Variable(tf.truncated_normal([50, 25], stddev=0.0001))
biases2 = tf.Variable(tf.ones([25]))

weights3 = tf.Variable(tf.truncated_normal([25, classes_num], stddev=0.0001))
biases3 = tf.Variable(tf.ones([classes_num]))

# This time we introduce a single hidden layer into our model...
hidden_layer_1 = tf.nn.relu(tf.matmul(x, weights1) + biases1)
hidden_layer_2 = tf.nn.relu(tf.matmul(hidden_layer_1, weights2) + biases2)
model = tf.nn.softmax(tf.matmul(hidden_layer_2, weights3) + biases3)

cost = -tf.reduce_sum(y_*tf.log(model))

training_step = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(cost)
                                                                    
init = tf.initialize_all_variables()
sess.run(init)

for ii in range(10000):
    # y_ -> element of correct class only must be 1
    if ii % 2 == 0: # even number [1,2] => 0
        sess.run(training_step, feed_dict={x: [[1, 2]], y_: [[1, 0]]})
    else:           # odd number  [2,1] => 1
        sess.run(training_step, feed_dict={x: [[2, 1]], y_: [[0, 1]]})

# prediction
print("result of prediction --------")
pred_rslt = sess.run(tf.argmax(model, 1), feed_dict={x: [[1, 2]]})
print("  input: [1,2] =>" + str(pred_rslt))
pred_rslt = sess.run(tf.argmax(model, 1), feed_dict={x: [[2, 1]]})
print("  input: [2,1] =>" + str(pred_rslt))
```
https://github.com/ryogrid/learnDeepLearning/blob/d21dfb567d4e31c1be03d3bca22b6c82b2fb1356/simple_tf_regression.py

実行結果
>result of prediction --------
  input: [1,2] =>[0]
  input: [2,1] =>[1]


#dropout入れた版 (11/8追記)
Keras版に合わせてdropoutを入れたものも書いてみました
https://github.com/ryogrid/learnDeepLearning/blob/master/simple_tf_regression_do.py

#その他参考になる記事など
http://qiita.com/ryo_grid/items/2fadb2b1d16f0eab1582
http://www.buildinsider.net/small/booktensorflow/0001
http://msyksphinz.hatenablog.com/entry/2015/11/19/022254
http://qiita.com/tawago/items/c977c79b76c5979874e8
http://qiita.com/tawago/items/931bea2ff6d56e32d693
Front Line of Frontend − Forkwell Meetup #2 資料まとめ

#「スタイルシートの長い夢」 GMOペパボ @shikakun
http://www.slideshare.net/shikakun/ss-68211943

#「フロントエンド最前線に流されないAtomic Designという考え方」 サイバーエージェント @79yuuki
https://speakerdeck.com/79yuuki/hurontoendozui-qian-xian-niliu-sarenai-atomic-design-toiukao-efang

#「ビジュアルCSSテスティング（仮）」 Forkwell @ringogirl
https://speakerdeck.com/ringogirl/biziyuarucsstesuteingu

#「Web ブラウザで DRM」 サイバーエージェント @ygoto3_
http://www.slideshare.net/ygoto3q/web-drm

#入社してrails世界にモダンフロントを突っ込んだ話
https://giftee.github.io/slide-shimatoku-front/#/

#「フロントエンドのパラダイムシフトの耐え方」freee @joe_re
https://speakerdeck.com/joere/hurontoendofalseparadaimusihutotopurodakutofalsecheng-chang

#スポンサーLT　NHNテコラス社

##フロントエンド開発のチームビルディング @ordbtk

##Phenomic : Modern website generator @trkw_
https://speakerdeck.com/trkw/phenomic-modern-website-generator

##UXプロジェクトファシリテーション（β）
テストデータ用にランダムな日付をn個生成する その2

# テストデータ用にランダムな日付をn個生成する その2
## 前回

- [テストデータ用にランダムな日付文字列をn個生成する](http://qiita.com/shinderuman@github/items/ea4c877faa0906d931b1)

## 読み飛ばしていい前置き

- MacBook Pro 2016 Late買った
 - キーボードが打ちづらく感じたのでとりあえずなんかコード書いてみたくなった
- DateTimeを返す関数にして呼び出し側で出力フォーマットよしなにしてもらうようにした
 - 意味もなく[Chronos](http://book.cakephp.org/3.0/ja/chronos.html)使った
 - なんとなく[Immutable](https://github.com/cakephp/chronos/blob/master/src/MutableDateTime.php)にした
 - 意味もなくgenerator使った

## 結論

- やっぱりキーボード打ちづらい
- コードはかなり微妙
 - ランダムな日付を作るのにmt_rand以外の最良手が見つからない

## 環境

- PHP 5.6.25

## 実装

### カンスー

```random_datetime.php
<?php
date_default_timezone_set('Asia/Tokyo');
require_once 'vendor/autoload.php';

use Cake\Chronos\MutableDateTime;

function createRandomMutableDateTime($count) {
    for ($i = 0;$i < $count;$i++) {
        yield MutableDateTime::createFromTimestamp(mt_rand(0, 2147483647));
    }
};
```

### 呼び出し側

```out.php
<?php
require_once 'random_datetime.php';

foreach (createRandomMutableDateTime(5) as $dateTime) {
    echo $dateTime->toDateTimeString() . PHP_EOL;
}
```

### 出力結果

```sh
% php out.php
2034-12-30 01:08:23
1997-06-06 11:41:01
2030-04-07 01:28:20
1975-11-11 00:06:48
1990-07-25 02:45:11
```


## まとめ

- 肩凝った

# 追記
## 追加仕様

- `20歳以上40歳` 以下とか指定できるようにしてみた

## 実装

```random_datetime.php
<?php
date_default_timezone_set('Asia/Tokyo');
require_once 'vendor/autoload.php';

use Cake\Chronos\Chronos;
use Cake\Chronos\MutableDateTime;

function createRandomMutableDateTimeGenerator($count, $overAge, $underAge) {
	$i = 1;
	$over = Chronos::now()->subYear($overAge);
	$under = Chronos::now()->subYear($underAge);
	while (true) {
		if ($count === $i) {
			break;
		}

		$d = MutableDateTime::createFromTimestamp(mt_rand(0, 2147483647));
		if ($d->between($under, $over)) {
	        yield $d;
	        $i++;
		}
	}
}
```

## まとめ

- Chronos使ってる感ちょっと出た
Deviseで任意のユーザとしてサインインする


セキュリティ的にどうなのよ、という部分もあるのですが、ユーザの同意を得て作業代行が発生するような仕組みでは役立つかもしれません。Deviseのsign_inメソッドを使うと任意のユーザでサインインができます。以下の例では、「admin?」がtrueを返すユーザのみが使える機能として定義しています。

``` config/routes.rb
authenticate :user do
  get 'sign-in-as' => 'users#sign_in_as'
end
```

``` app/controllers/users_controller.rb
def sign_in_as
  raise 'Only admin can access this action.' unless current_user.admin?
  id = params[:id]
  sign_in(User.find(id))
  redirect_to root_path, notice: "ID: #{id}"
end
```
rubyのmoduleメソッドの呼び出し方法

Rubyの module は慣れ親しんできたVB.NETのModuleとは
大分違うようなので整理しておこうと思います。

##moduleのメソッドは関数として使えない
Rubyのmoduleのメソッドは普通に定義しただけじゃ、関数として使えない。

```ruby:sample0.rb
module ModTest
  def sayHello
    puts "こんにちは"
  end
end
# sayHelloをmoduleの外から実行すると・・
ModTest.sayHello
#=> undefined method `sayHello' for ModTest:Module (NoMethodError)
# 呼び出せない・・
```

##moduleのメソッドを呼ぶ方法
moduleのメソッドを呼ぶには、以下の３つの方法がある。
###1. mixinを使う
別にclassを定義して、呼び出したい関数を含むmoduleをincludeする。
これがRubyで最も一般的なやり方らしい。
コードにするとこんな感じ。

```ruby:sample1.rb
class ClsTest
  include ModTest
  # ModTestをmixinします
end
# インスタンスを作ってincludeしたmoduleのメソッドを呼び出す
cls = ClsTest.new
cls.sayHello
#=> こんにちは
```

###2. module_functionを使う
module_functionで関数として使いたいメソッドが指定できる。

```ruby:sample2_1.rb
module ModTest
  def sayHello
    puts "こんにちは"
  end
  # 外部から関数として使いたいメソッドを指定します。
  module_function :sayHello
end
# sayHelloをmoduleの外から実行すると・・
ModTest.sayHello
#=> こんにちは
```

module_functionを実行すると以下の２つの処理が行われる。
　・インスタンスメソッドのprivate化
　・publicクラスメソッドの作成

なので、mixinでmodudleを取り込んだクラスから呼び出す為には、
スコープを public に戻してやる必要がある。

```ruby:sample2_2.rb
module ModTest
  def sayHello
    puts "こんにちは"
  end
  module_function :sayHello
  # module_functionを使うとインスタンスメソッドがprivate化されてしまうので、
  # mixinでも使う場合は public に戻してやる。
  public :sayHello
end

class ClsTest
  include ModTest
end

cls = ClsTest.new
cls.sayHello
#=> こんにちは
```

ただ、こういうふうに無理やりスコープを Public に戻すのが
正しいのかわからないので、とりあえずこれは使わないようにする。

###3. クラスメソッドとして宣言する
Moduleも~~Classなので、当然~~クラスメソッドを定義できます。
だから、Classのクラスメソッドと同じようにこんな感じで定義可能です。

```ruby:sample3.rb
module ModTest
  class << self
    def sayHello
      puts "こんにちは"
    end
  end
end

ModTest.sayHello
```
簡単ですね。

##まとめ
VB.NETにおける Module は関数定義を集めたもので、
ユーティリティ関数をまとめておくような使い方が一般的でした。
しかし、Rubyの module は主にクラス拡張の手段という感じですね。
~~だから、ここに書いた 2（module_functionを使う方法） や ~~
~~３（クラスメソッドとして宣言する） 方法はあまり使うべきではないのかもしれませんね。。~~

2、3に書いた方法でstatic method化することよくあるとコメントでご指摘頂きました。。
（ただし、module_function化したものを再度Publicにするのは駄目だろうという指摘も。気をつけます。）
OpenMediaVault 3 beta で PHP を実行

OpenMediaVault 3 beta（以降 OMV3）で、WebサーバであるNginxを用いてPHPを動作させます。
前提として、OMV3のインストール及び、IPアドレスの設定、アップデートの終了までは行っておいてください。
必要であれば、SSH等の設定もしておいてください。

また、**Webコンテンツを置く場所は、インストールディスクとは別にHDDが必要となります。**
ファイルシステムでHDDを追加後、共有フォルダに登録してください。

## <i class="fa fa-cube" style="font-size:1em;"></i> OMV-Extras.org Pluginのダウンロード
クライアントPCから、OMV-Extras.org PluginをOMVの[フォーラム](http://forum.openmediavault.org/index.php/Thread/5549-OMV-Extras-org-Plugin/)からダウンロードしてください。

## <i class="fa fa-cube" style="font-size:1em;"></i> OMV-Extras.org Pluginのインストール
右のプラグインメニューのアップロードボタンから先程ダウンロードしたOMV-Extras.org Pluginファイルを選択してください。

すると、パッケージリストの「セッション：Utilities」に「openmediavault-omvextrasorg 3.x.x」という項目が追加されているので、チェックボックスにチェックを入れて、上段にあるインストールボタンでインストールしてください。

インストールが完了すると、右のシステム配下に「OMV-Extras」が追加されるはずです。

## <i class="fa fa-cube" style="font-size:1em;"></i> Nginx Pluginのインストール
再度、右のプラグインメニューを選択して見るとパッケージリストにデフォルトでは存在していなかったプラグインが追加されています。
その中の「セッション：Network」にある「openmediavault-nginx 3.x.x」のチェックボックスにチェックを入れて、上段にあるインストールボタンでインストールしてください。

インストールが完了すると、右のサービス配下に「Nginx(website)」が追加されているはずです。

## <i class="fa fa-cube" style="font-size:1em;"></i> Webサイトの設定
右のNginxメニューを選択して、Nginxの有効化にチェックを入れてください。
その後、サーバタブを選択して追加ボタンを押してください。
表示されたダイアログは、以下の記述を参考に設定してください。

#### <i class="fa fa-folder-open" style="font-size:1em;"></i> [一般] - [ディレクトリ]
共有フォルダで追加したフォルダを選択してください。

#### <i class="fa fa-check-square-o" style="font-size:1em;"></i> [オプション] - [インデックス] - [index.php]
チェックを入れてください。

#### <i class="fa fa-edit" style="font-size:1em;"></i> [その他オプション]
以下をコピペして貼り付けてください。

~~~
location ~ [^/]\.php(/|$) {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
    }
~~~

## <i class="fa fa-television" style="font-size:1em;"></i> PHPの動作確認
Nginxのサーバタブの一覧に追加されたサーバ設定の「ルート」の場所にサンプルコードを配置します。
（ルートの場所は、「/media/英数字の文字列/共有フォルダ名」となっているはずです）
配置方法は、SCPや直接SSHでログインしてviで配置でも良いです。

#### <i class="fa fa-edit" style="font-size:1em;"></i> サンプルコード
~~~PHP
<html>
<body>
今日の日付は
<?php
echo date('Y年m月d日');
?>
です。
</body>
</html>
~~~

サンプルコードを登録したら、ブラウザからOMVサーバアドレスで接続してください。
うまく行けば、日付がブラウザ上に表示されます。

## <i class="fa fa-cube" style="font-size:1em;"></i> 最後に
必ず、ローカルネットワーク内での使用に限定させてください。
セキュリティとか、度外視しているので・・・。