OmniAICreator/Qiita-1.07M huggingface dataset:
タッチパネルのピンチズームを無効化する

surface用にwebアプリを作っていた際、chromeブラウザだけ制御できなかった時にはまったのでメモ。

色々挑戦しました。

こいつも...

```js:js
document.addEventListener('touchstart', function(event){
    event.preventDefault();
});
```

こいつも...

```html:html
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
```

こいつも...

```
chrome://flags/#touch-events
```

ダメでした😭

ただしchrome以外のブラウザだと上から2つのどちらかで制御できると思います。


chromeだけなかなか制御できないので
「ユーザビリティ的によくないし、ピンチできるようにした方が親切ですよ！！ディレクターさん✨」　　
という言い訳が頭に過ぎりました。（ダメですね

でもとても簡単な方法がありました。

```css:css
html, css{
  touch-action:none;
}
```

たったこれだけで制御できました。

天下のStack Overflow様様ですね🙏✨

ただし、```touch-action```には罠も潜んでいるようなので気をつけたいですね。

##参考
[Disable Chrome pinch zoom for use in kiosk](https://stackoverflow.com/questions/22999829/disable-chrome-pinch-zoom-for-use-in-kiosk)
[html { touch-action: none; } に潜む罠](http://lealog.hateblo.jp/entry/2015/02/19/124748)
Paper > Deep Mutual Learning

転移学習が関係しそうな論文。

https://arxiv.org/abs/1706.00384

Deep Mutual Learning
Ying Zhang, Tao Xiang, Timothy M. Hospedales, Huchuan Lu

```
Cite as:	arXiv:1706.00384 [cs.CV]
 	(or arXiv:1706.00384v1 [cs.CV] for this version)
```

- a powerful large network からsmall networkへの転移学習?
- 一方通行でなく、相互学習をするようだ
- CIFAR-100での結果を調査
Paper > Integrated Deep and Shallow Networks for Salient Object Detection

CNN(ConvNet)関連の論文。

https://arxiv.org/abs/1706.00530

Integrated Deep and Shallow Networks for Salient Object Detection
Jing Zhang, Bo Li, Yuchao Dai, Fatih Porikli, Mingyi He

```
Cite as:	arXiv:1706.00530 [cs.CV]
 	(or arXiv:1706.00530v1 [cs.CV] for this version)
```

- Deep modelでcoarse saliency mapを出力 (1とする)
- unsupervised saliency mapと(1)をconcatenate
- Shallow modelで結果を得る

「dipoleの位置情報」と「サイズ」という異なる入力パラメータを分ける場合に使えそうか。

concatenateの詳細は未消化。
FlaskでCSVリーダーを作成する

前回はPDFをテキストへ変換したので、今回はCSVリーダーを作成します。コード自体はファイルアップロードなので、殆ど同じような感じになります。

```csvopnener.py
import os
import csv
from flask import Flask, render_template, request, redirect, url_for, send_from_directory, session
from werkzeug.utils import secure_filename
app = Flask(__name__)

UPLOAD_FOLDER = './uploads'
ALLOWED_EXTENSIONS = set(['csv'])
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['SECRET_KEY'] = os.urandom(24)

def allowed_file(filename):
    return '.' in filename and \
        filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

@app.route('/')
def index():
    return render_template('csv.html')


@app.route('/show_csv', methods=['GET', 'POST'])
def show_csv():
    if request.method == 'POST':
        send_data = request.files['send_data']
        if send_data and allowed_file(send_data.filename):
            filename = secure_filename(send_data.filename)
            send_data.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            f = open('uploads/' + filename, 'r')
            f_reader = csv.reader(f)
            result = list(f_reader)

            return render_template('csv.html', result=result)


@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

if __name__ == '__main__':
    app.debug = True
    app.run()
```

```csv.html
{% extends "base.html" %}
{% block content %}
<form method="post" action="{{ url_for('show_csv') }}" enctype="multipart/form-data">
  <input type="file" id="send_data" name="send_data">
  <input type="submit" value="送信">
</form>
<div>
  {% if result %}
  <dl>
  {% for i in result %}
    <dt>{{ i[0] }}<dt>
    <dd>{{ i[1] }}</dd>
  {% endfor %}
  </dl>
  {% endif %}
</div>
{% endblock %}
```

#実行

<img width="430" alt="スクリーンショット 2017-06-06 12.24.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/71585/b6af720f-8dd9-d10e-86a0-7d20d52fec08.png">

このようなテスト用CSVファイルを用意しました。

<img width="283" alt="スクリーンショット 2017-06-06 12.25.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/71585/26cc84be-3af1-5cfd-8192-2cabf9dac829.png">

カスタマイズすればCSVに行を追加など、結構いいんじゃないかと感じました。
DRY & DDD

# tl;dr

* 「DRYではない」みたいにドヤ顔でレビューしてくる人とかいるけどエヴァンスさんもこう言っているんだから常にDRYなコードなんてかけないでしょ

# Don't repeat yourself

* https://ja.wikipedia.org/wiki/Don%27t_repeat_yourself によると

> Don't repeat yourself (DRY) あるいはSingle Source of truth(英)[要出典]は、特にコンピューティングの領域で、重複を防ぐ考え方である。この哲学は、情報の重複は変更の困難さを増大し透明性を減少させ、不一致を生じる可能性につながるため、重複するべきでないことを強調する。

* レビューでコードやロジックが重複している場合によく「DRYではない」みたいに使われる

# 常に DRY でいられるか

* DRY にこだわることにより早すぎる最適化や誤った抽象化を行ってしまう可能性があるので常に DRY でいる必要はないと思っていた
* 伝わる人には伝わるが DRY 原則を絶対視する DRY 原理主義者が相手だと弱い

# そこで DDD

* エリック・エヴァンスのドメイン駆動設計を読んで DRY 原理主義者に立ち向かうロジックができた気がするのでまとめてみる

# DDD について簡単に

* 複雑な問題領域（ドメイン）をよりよく解決するモデルをつくり、それを出来得る限りそのままコードで表すことでシステムの複雑性をコントロールしようという設計手法
* はじめから完璧なモデルができるということはなく、ビジネス側のドメインに詳しい人（ドメインエキスパート）と協力してリファクタリングを繰り返しながらドメインについての理解を深めていくことでより良いモデルとコードをつくりあげていく

# DRY 原理主義者に DDD で立ち向かう

* ソフトウェア開発においてドメイン駆動設計を行うか行わないかにかかわらず、実装中のドメインについての理解の浅い段階というのは常に存在する
* 常に DRY であろうとすることは、理解の浅い段階でも常に正しいモデルを実装できるという誤った前提に立つものであり無理がある
* DRY であろうとすることは良いことだが、常に DRY でなければいけないという態度は単なる思考停止である
* 常にすべてを見通せる知識を持つわけではない私たちは、常に DRY ではありえないことを謙虚に認め、より DRY であることを目指しながらこつこつとソフトウェアを開発していくしかない

# さいごに

* もちろん明らかに構造化できるのにコピペしていたらドヤ顔で「DRYではない」ときめていい
* が、DRY ではありえない場合もあることを認めて自分にも同僚にも優しくなることで楽しく開発をしていけると幸せ
NotificationのObserverを使ってみる(2)

## Noticationにデータを一緒に渡す

```
/* 通知を送る*/
[[NSNotificationCenter defaultCenter] postNotificationName:@"Hello"
                                                        object:nil];
```
これにStringの変数を渡します
↓

```
/* 通知を送る*/
NSString *string = @"HelloText";
[[NSNotificationCenter defaultCenter] postNotificationName:@"Hello"
                                                        object:string];
```

次に受け取るメソッドに引数にNotificationを追加
↓

```
-(void)hello:(NSNotification*)notification
```
notificationの中身を確認するとこんな感じ


## Noticationから渡されたデータを抜き出す
```
NSConcreteNotification 0x608000043360 {name = Hello; object = HelloText}
```

ここから添付されたobject情報を抜き出す
↓

```
NSString *keyword = [NSString stringWithFormat:@"%@", [notification valueForKey:@"object"]];
```

or

```
NSString *keyword = (NSString *)notification.object;
```

といった感じになる。

以下変更したソース

```
#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIButton *button;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
        
    /* 通知を「受け取る」処理の登録----------------*/
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(hello:)
                                                 name:@"Hello"
                                               object:nil];

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

}

/* 通知を送るアクション-----------*/
- (IBAction)buttonTapped:(id)sender {

    NSString *string = @"HelloText";
    [[NSNotificationCenter defaultCenter] postNotificationName:@"Hello"
                                                        object:string];
}

/* 動かしたい処理----------------*/
-(void)hello:(NSNotification*)notification
{
    NSString *text = (NSString *)notification.object;
    NSLog(@"%@",text);
}

/* 登録した通知登録の削除----------------*/
- (void)deallo
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end
```

ソースの変更は前回の記事から続いてやっています
[前回の記事](http://qiita.com/piyomarudayo/items/15de120d1a3d86952b7a)
iOS11で新しく導入されたFramework

# この記事について
iOS10からiOS11で新しく導入されたFrameworkを列挙しました。
詳細が上がり次第アップデートいたします。

## Graphics and Games
* [ARKit](https://developer.apple.com/documentation/arkit?changes=latest_minor)
`Integrate iOS device camera and motion features to produce augmented reality experiences in your app or game.`

* [ColorSync](https://developer.apple.com/documentation/colorsync?changes=latest_minor)

* [Vision](https://developer.apple.com/documentation/vision?changes=latest_minor)
`Apply high-performance image analysis and computer vision techniques to identify faces, detect features, and classify scenes in images and video.`

* [IdentityLookup](https://developer.apple.com/documentation/identitylookup?changes=latest_minor)
`Create an app extension that can identify and filter unwanted SMS and MMS messages while preserving user privacy.`

* [PDFKit](https://developer.apple.com/documentation/pdfkit?changes=latest_minor) -> [PDFAppearanceCharacteristics](https://developer.apple.com/documentation/pdfkit/pdfappearancecharacteristics?changes=latest_minor)
`Display and manipulate PDF documents in your applications.`

## App Services
* [Core ML](https://developer.apple.com/documentation/coreml?changes=latest_minor)
`Integrate machine learning models into your app.`

* [DeviceCheck](https://developer.apple.com/documentation/devicecheck?changes=latest_minor)
`Access per-device, per-developer data that your associated server can use in its business logic.`

* [FileProvider](https://developer.apple.com/documentation/fileprovider?changes=latest_minor)
`Implement a file provider extension to let other apps access the documents and directories that are stored and managed by your containing app.`

* [FileProviderUI](https://developer.apple.com/documentation/fileproviderui?changes=latest_minor)
`Add actions to the document browser's context menu.`

## System
* [Core NFC](https://developer.apple.com/documentation/corenfc?changes=latest_minor)
`Detect NFC tags and read messages that contain NDEF data.`
iOS11 First Impressions

##気づいたポイント
###App Storeアップデート
App Storeが完全に変わりました。新しい表示対応しないと！
<img width="320" alt="IMG_0545.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/147278/88024d8c-ce17-8d0b-4b05-f5b96b62b2c1.png">

###スクショ
スクショ撮った後その場でエディットできるようになりました。役に立つかどうか分からないが楽しめる。
<img width="320" alt="IMG_0551.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/147278/dcd57b77-ea83-7a53-9eb0-bd731c0adbcb.png">

###Navigation Bar
新しいセクションヘッダーの動きがありました。下にスクロールしたらNavigation Barに入る
<img width="320" alt="IMG_0547.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/147278/0c3d5561-6efa-1213-e1ab-9ea2c69bf80e.png"> <img width="320" alt="IMG_0548.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/147278/7dfdcc30-d007-ba7e-37c7-0c96f8bf3e6d.png">

###ファイルマネジャー
まだ試していないんですが、ファイルマネジャー追加されたっぽいです！
<img width="320" alt="IMG_0546.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/147278/2444492e-0083-1231-285b-489fdb06f34d.png">

###6系のデバイスちょっと遅いです。。。
6+で試していたんですが結構framerateが落ちていた。ま、最初のBetaからかもしれないけど5S, などは大丈夫かなって感じです。

##iOS11
iOS 9と10よりアップグレードって感じだけど思ったよりGame Changerじゃなかったです。
続 2017年1番人気はBabelかTypeScriptかそれともCoffeeScriptなのか？

以前、[本当に2016年1番人気はTypeScriptなのか？ - Qiita](http://qiita.com/akameco/items/efe83016fbc40cdce28d) を書きましたが未だにこの記事が共有されているようです。

`この記事は最終更新日から1年以上が経過しています。`が見えないのかあんたたちは。タイトルにも2016年と書いてあろうが

あの記事見てなんだCoffeeScript使われてんじゃんと思われるのは、よろしくないので2017年度版を更新することにします。
ダウンロード数の比較です。

![スクリーンショット 2017-06-06 10.50.53.png](https://qiita-image-store.s3.amazonaws.com/0/15319/06ece2d1-b2a7-6a72-c978-18fdb79dd6c2.png)



[typescript vs babel-core vs coffee-script - npm trends](http://www.npmtrends.com/typescript-vs-babel-core-vs-coffee-script)

Babelが頭ひとつ抜けましたね。
TypeScriptも順調に増加しているようです。

## おまけ
いくつか比較されやすいものも列挙しときます。


![スクリーンショット 2017-06-06 11.27.03.png](https://qiita-image-store.s3.amazonaws.com/0/15319/9d9303e5-3ff0-847f-8477-5eb1de2da320.png)

[gulp vs grunt vs webpack vs browserify vs rollup - npm trends](http://www.npmtrends.com/gulp-vs-grunt-vs-webpack-vs-browserify-vs-rollup)
これがいいことなのかはわかりませんがwebpack一強です。

![スクリーンショット 2017-06-06 11.30.15.png](https://qiita-image-store.s3.amazonaws.com/0/15319/a5d7b1db-2b2f-c068-9048-b476264e2c07.png)


[react vs @angular/core vs angular vs vue vs riot - npm trends](http://www.npmtrends.com/react-vs-@angular/core-vs-angular-vs-vue-vs-riot)
予想通りすぎてつまらないのですが、みんなReactを使っているようです。
他のフレームワークについて知りたい人は各々比較してみてください。

## まとめ
去年も書いたのだけど、他と比べてTypeScriptは正月にダウンロード数が落ちませんね。
あくまでグラフから読み取る限りですが、正月に休みたければTypeScriptは採用すべきじゃないようです。
macにdockerをインストール


## 目的

新しいmacにしたので `docker` のインストールをメモしました。

## インストーラーを入手

https://www.docker.com/

![スクリーンショット 2017-06-06 10.45.50.png](https://qiita-image-store.s3.amazonaws.com/0/14914/2c914255-5efa-0758-fd57-20a1e8cca649.png "スクリーンショット 2017-06-06 10.45.50.png")

`Get Docker Community Edition` をクリック

![スクリーンショット 2017-06-06 11.04.56.png](https://qiita-image-store.s3.amazonaws.com/0/14914/46c5d79d-389d-8a34-a9cf-4749ab7aae61.png "スクリーンショット 2017-06-06 11.04.56.png")

`Get Docker CE from Docker Store` をクリック

![スクリーンショット 2017-06-06 11.06.50.png](https://qiita-image-store.s3.amazonaws.com/0/14914/11eb3d73-9db6-b034-a2c3-783f9c0d32ca.png "スクリーンショット 2017-06-06 11.06.50.png")

環境に合わせて選択する。今回はmac。

`Docker Community Edition for Mac` をクリック

![スクリーンショット 2017-06-06 11.10.15.png](https://qiita-image-store.s3.amazonaws.com/0/14914/6f380b35-c582-1a2c-2ab5-914a7198c0c5.png "スクリーンショット 2017-06-06 11.10.15.png")


`Get Docker` をクリック

`Docker.dmg` を適当なところに保存する。

保存したファイルをダブルクリック。

![スクリーンショット 2017-06-06 11.12.33.png](https://qiita-image-store.s3.amazonaws.com/0/14914/c16aebf6-5ec1-8ddc-a8de-868c5af2cabb.png "スクリーンショット 2017-06-06 11.12.33.png")

画面の通りにドラッグ・アンド・ドロップする。

スポットライトに `docker` と打ち込み実行。


画面上部に以下のようにクジラの絵が表示されれば起動成功。

## 起動確認

コンソールを起動します。

以下のコマンドを打ってクジラが表示されればOK

```bash
docker run docker/whalesay cowsay hello!
```

![スクリーンショット 2017-06-06 11.26.13.png](https://qiita-image-store.s3.amazonaws.com/0/14914/17497937-a9c4-7605-9b44-5942001d2073.png "スクリーンショット 2017-06-06 11.26.13.png")

ちなみにこのコマンドが気になる方は以下の記事にくわしくかいてありましたのでご確認ください。

[Dockerに出てくるcowsayってなに？](http://qiita.com/akiko-pusu/items/b42d3e326e56e172b30f "Dockerに出てくるcowsayってなに？")


久しぶりに `docker` をインストールしましたが簡単ですね。
SlackにGitbucketの通知を連動する


# はじめに

Gitbucketにpushとかissue発行した時とかにslackに通知を流したい。

うまくいけば↓のようにslackに通知を流すことができる

![Kobito.ai1VXj.png](https://qiita-image-store.s3.amazonaws.com/0/60056/2903292c-d159-80ec-f522-86d96fdd4978.png "Kobito.ai1VXj.png")


# 設定方法

## slackにgithubアプリのインストール

slackを開き、Apps & Integrations を開く

検索バーからgithubを検索、githubが出てくるのでクリックしてインストール

> gitbucketでなくgithubなところは気にしなくてOK

![Kobito.YJvLg6.png](https://qiita-image-store.s3.amazonaws.com/0/60056/2d2f953e-e8f0-a913-c6e5-d101e806c4ee.png "Kobito.YJvLg6.png")


「Post to Channel」といきなり聞かれるので、gitbucketの通知を
流したいslackのチャンネルを選択

![Kobito.L8Pntv.png](https://qiita-image-store.s3.amazonaws.com/0/60056/57810e0b-503b-aef7-a2d2-fac77f46e4ea.png "Kobito.L8Pntv.png")


英語でいろいろ書かれるが、緑のボタンでなく、ただのリンクの「switch to unauthed mode」を選択

![Kobito.kd6RKn.png](https://qiita-image-store.s3.amazonaws.com/0/60056/c4407692-b03f-6cdb-6ed8-cadf88ea618d.png "Kobito.kd6RKn.png")


もろもろ設定画面が出て来る

* Webhook URL
	* ここに表示されているURLをコピーしておく。後でgitbucket側の設定画面に貼り付ける。
* Branch
	* 通知対象にするBranchを指定する（無指定だと前Branch）
* Post to Channel
	* さっき指定したもの。gitbucketの通知を流し込む先のslackのチャンネルを指定する。
* Descriptive Label
	* 説明用のラベル
* Customize Name
	* 通知に表示される。githubだとわかりずらいのでgitbucketとかリポジトリ名とかにする
* Customize Icom
	* 通知に表示される。gitbucketからアイコンを拝借して設定するといい感じ

設定ができたらsaveして完了。これでslack側はOK

続いてgitbucketを開き、リポジトリのsettings画面を開く

「Service Hooks」の「Add webhook」を開く

![Kobito.mRxlFY.png](https://qiita-image-store.s3.amazonaws.com/0/60056/0d0c399e-0071-a8ab-4f4c-15ebdcf1cf02.png "Kobito.mRxlFY.png")

slack側で出てきたWebhook URLを貼り付ける。

![Kobito.unTh8C.png](https://qiita-image-store.s3.amazonaws.com/0/60056/4cc0c428-4f50-7587-838f-912f74b14101.png "Kobito.unTh8C.png")

Test Hookするとslackに通知がいくはず

この状態で保存すればOK
SoftEherVPNでTAPデバイスとのブリッジが失敗する場合

SoftetherVPNをCentOS7に導入し、br0をTAPデバイスでローカルブリッジ接続する
設定をしていたが、再起動するとbr0とTAPデバイスの間の接続が切れてしまい、
うまくいかない。原因を調べてみた。

まずtapデバイスとbr0がつながっているかを確認するには、
```/sbin/brctl show br0```
でOKなのだが、

```shell-session

bridge name     bridge id               STP enabled     interfaces
br0             8000.00ac9794c389       no              enp2s0

```
上記の状態だと、interfacesにtapデバイスが表示されていない＝tapデバイスが
br0にブリッジされていない状態。

Softetherのサービスはsystemctlで既に登録済みだが、確認すると、正常に
起動していない様子。

`systemctl status softether.service`

上記コマンドで、Activeと表示がでていなければ何らかのタイミングで失敗している。

で、見てみると、/etc/systemd/system/softether.service の中のbr0をTAPデバイスに接続しているところが正常に動いていない様子。
どうしても治らないので、起動時のスクリプトを作成して、設定しなおしてみた。

作成した起動スクリプト

```bash:vpnserver-tap-enable.sh
#!/bin/sh
TAP_DEVICE=tap_tap-br0
BR_STATUS=`/sbin/brctl show br0 | grep ${TAP_DEVICE} | wc -l`
LOOP_CNT=0

while [ $BR_STATUS = 0 ]
do
        sleep 1
        /sbin/brctl addif br0 ${TAP_DEVICE}
        if [ $? -ne 0 ]; then
                break
        fi
        LOOP_CNT=$(( LOOP_CNT + 1 ))
        if [ ${LOOP_CNT} = 10 ]; then
                break
        fi
done

exit 0
```
やっている内容としては、
起動時に指定したTAPデバイスが登録されているかを確認し、登録がなければ、brctlのaddifで登録する処理を実行。brctlコマンドが失敗するか、10回やってだめだったらあきらめる。

上記を、/etc/systemd/system/softether.serviceのExcecStartPostに設定

```bash:/etc/systemd/system/softether.service
[Unit]
Description=SoftEther VPN Server
After=network.target

[Service]
Type=forking
ExecStart=/usr/local/vpnserver/vpnserver start
ExecStop=/usr/local/vpnserver/vpnserver stop
ExecStartPost=/root/bin/vpnserver-tap-enable.sh

[Install]
WantedBy=multi-user.target
```

で、再起動したらちゃんとTAPデバイスが登録されるようになった。

```shell-session
[root@vpn]# /sbin/brctl show br0
bridge name     bridge id               STP enabled     interfaces
br0             8000.00ac9794c389       no              enp2s0
                                                        tap_tap-br0
```
serviceのstatusもいい感じ♪

```shell-session
[root@vpn]# systemctl status softether.service
● softether.service - SoftEther VPN Server
   Loaded: loaded (/etc/systemd/system/softether.service; enabled; vendor preset: disabled)
   Active: active (running) since 火 2017-06-06 11:15:16 JST; 26s ago
  Process: 1506 ExecStartPost=/root/bin/vpnserver-tap-enable.sh (code=exited, status=0/SUCCESS)
  Process: 1454 ExecStart=/usr/local/vpnserver/vpnserver start (code=exited, status=0/SUCCESS)
 Main PID: 1492 (vpnserver)
   CGroup: /system.slice/softether.service
           笏?─1492 /usr/local/vpnserver/vpnserver execsvc
           └─1498 /usr/local/vpnserver/vpnserver execsvc

 6月 06 11:15:14 vpn-gw01 systemd[1]: Starting SoftEther VPN Server...
 6月 06 11:15:14 vpn-gw01 vpnserver[1454]: The SoftEther VPN Server service has been started.
 6月 06 11:15:16 vpn-gw01 vpnserver-tap-enable.sh[1506]: device tap_tap-br0 is already a member of a b...0.
 6月 06 11:15:16 vpn-gw01 systemd[1]: Started SoftEther VPN Server.
Hint: Some lines were ellipsized, use -l to show in full.
```

ということで、起動スクリプトそのまま使うときは注意する。

あ、systemctl enable softether.service で自動起動の設定を有効にしておくことも忘れずに。
Treasure Dataのpartial delete

こんなレコードがあったとして
=

embulk-output-tdプラグインで投入

```
$ td query -d db1 "SELECT time, TD_TIME_FORMAT(time, 'yyyy-MM-dd HH:mm:ss', 'JST') AS date FROM tbl1 ORDER BY time" -w
～略～
+------------+---------------------+
| time       | date                |
+------------+---------------------+
| 1496592000 | 2017-06-05 01:00:00 |
| 1496595600 | 2017-06-05 02:00:00 |
| 1496599200 | 2017-06-05 03:00:00 |
| 1496602800 | 2017-06-05 04:00:00 |
| 1496606400 | 2017-06-05 05:00:00 |
| 1496610000 | 2017-06-05 06:00:00 |
| 1496613600 | 2017-06-05 07:00:00 |
| 1496617200 | 2017-06-05 08:00:00 |
| 1496620800 | 2017-06-05 09:00:00 |
| 1496624400 | 2017-06-05 10:00:00 |
| 1496628000 | 2017-06-05 11:00:00 |
| 1496631600 | 2017-06-05 12:00:00 |
| 1496635200 | 2017-06-05 13:00:00 |
| 1496638800 | 2017-06-05 14:00:00 |
| 1496642400 | 2017-06-05 15:00:00 |
| 1496646000 | 2017-06-05 16:00:00 |
| 1496649600 | 2017-06-05 17:00:00 |
| 1496653200 | 2017-06-05 18:00:00 |
| 1496656800 | 2017-06-05 19:00:00 |
| 1496660400 | 2017-06-05 20:00:00 |
| 1496664000 | 2017-06-05 21:00:00 |
| 1496667600 | 2017-06-05 22:00:00 |
| 1496671200 | 2017-06-05 23:00:00 |
| 1496674800 | 2017-06-06 00:00:00 |
+------------+---------------------+
24 rows in set
```

tdコマンドでpartial deleteするなら
=
```
$ td table:partial_delete db1 tbl1 --from '2017-06-05 01:00:00 JST' --to '2017-06-06 01:00:00 JST' -w
```

Digdagでpartial deleteするなら
=

```
+task1:
  td_partial_delete>: tbl1
  database: db1
  from: 2017-06-05T01:00:00+09:00
  to:   2017-06-06T01:00:00+09:00
```

[ドキュメント](https://docs.digdag.io/operators/td_partial_delete.html)

~~Webコンソール・td table:showの件数表示~~
=

~~partial delete直後に当該テーブルをWebコンソールやtd table:showコマンドで見ても削除前の件数が表示される
しかも「100件追加→partial deleteで全件削除→100件追加→partial deleteで全件削除」とした後は200件と表示される
削除後の件数はWebコンソールやtd table:showコマンドで確認しないでSELECT COUNTを発行すること~~

↑ 2018年5月頃に対応頂けたとのこと
x87命令を使ってみる

# はじめに

少し前の記事ですが、x87命令である`fsin`や`fcos`が遅いとか精度がどうとか話題になっているようです。

参考→[サイン、コサインをインテルの CPU で計算すると少しバグっているらしい](http://tomeapp.jp/archives/1282)

x87の歴史については別記事(例えば[x86の浮動小数計算とSIMD命令の変遷](http://qiita.com/lpha_z/items/eafa9c13532c9ac80d4b))に譲りますが、ようするにもともと外付けとして実装されたFPUが、そのうち内部に統合されたのがx87です。そんなわけで、もともとはコプロセッサのことを指しましたが、今は命令セットとして扱われています。内部はスタックマシンになっており、しかもFPUデータレジスタはMMXレジスタと共有なので、一緒に使うとややこしいことになります。

前置きはともかく、さっそくx87命令を使ってみようと思います。

# そもそも最近のコンパイラはx87命令吐くの？

吐きます。[先の記事のコメント欄](http://qiita.com/lpha_z/items/eafa9c13532c9ac80d4b#comment-43cd68fd29360d60bcf9)にもあるように、long doubleを使うと、デフォルトでx87命令を吐きます。

```cpp:ld.cpp
long double func(long double a, long double b){
  return a + b;
}
```

```shell-session
$ g++ -O3 -S ld.cpp
```

```nasm
func(long double, long double):
LFB0:
        fldt    24(%rsp)
        fldt    8(%rsp)
        faddp   %st, %st(1)
        ret
```

ここで出てる`fldt`とか`faddp`はx87命令です。

# なんでlong double使うとx87命令吐くの？

この辺詳しくないのですが、x86上のコンパイラの多くが`long double`の精度が80bitであり、x87に合わせてあるからだと思います。`sizeof(long double)`は16を返しますが、内部表現としては80bit精度の[拡張倍精度浮動小数点数](https://ja.wikipedia.org/wiki/%E6%8B%A1%E5%BC%B5%E5%80%8D%E7%B2%BE%E5%BA%A6%E6%B5%AE%E5%8B%95%E5%B0%8F%E6%95%B0%E7%82%B9%E6%95%B0)になっています(多分)[^1]。なので、long doubleの計算をする際には、そのままの精度で80bit精度の計算ができるx87命令が呼ばれます。

[^1]: 筆者の手元の記録では、昔のx86系の石+gcc/icc`sizeof(long double)`は12を返していたようですが、DECのAlpha21264とDECのコンパイラは8を返していたようです。

ここで`fldt`は、メモリの値をレジスタスタックに積む命令ですが、最後の"t"はsource formatが「Extended」、すなわち80bitであることを表しています。これは、メモリ上の拡張倍精度浮動小数点数をそのままレジスタに積みます、という意味です。

# x87命令を使ってみる

というわけでx87命令を使ってみましょう。先述したように、x87命令の内部精度は80bitであり、通常扱う倍精度浮動小数点数は64bitですから、変換が必要になります。これはx87のスタックに積む命令が勝手にやってくれます。

例えば、`double`を受け取ってsinの値を返す関数はこんな感じになるでしょう。

```cpp
double
 __attribute__ ((noinline))
fsin(double a){
  double r;
  asm volatile (
      "movsd %%xmm0, %0\n\t" // 1.
      "fldl %0\n\t"          // 2.
      "fsin\n\t"             // 3.
      "fstpl %1\n\t"         // 4.
      :"=m"(a)
      :"m"(r)
    );
  return r;
}
```

やってることはこんな感じです。

1. `xmm0`に入ってきた引数を、一度メモリにコピーします [^2]
2. それを`fldl`命令でx87スタックレジスタに積みます。ここで`fldl`は「64bit倍精度を積む」命令で、このとき内部で80bit表現に変換されます。
3. `fsin`で、スタックの一番上にあるデータのsin値を計算します。
4. 計算された値がスタックの一番上に積んであるので、それをメモリに書き戻します。ここで80bit表現が64bit表現にコンバートされます。

[^2]: ちょっとアホなことをやっていますが、コンパイラの最適化で変なことが起きないようにするためです。もっと賢い方法があるかもしれません。

まぁその、これみて**遅そうだな**、と思っていただければ。いや、実際に速度を測定していないのでアレですが。

ちゃんとsinを計算できてるか確認しましょう。

```cpp
#include <stdio.h>
#include <math.h>

int
main(void){
  const int N = 10000;
  const double s = 2.0*M_PI/static_cast<double>(N);
  double x = 0.0;
  for(int i=0;i<N;i++){
    printf("%f %f\n",x, fsin(x));
    x += s;
  }
}
```

```shell-session
$ g++ test.cpp
$ ./a.out > test.dat
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/79744/2bbcde83-1906-f4e2-69b8-941ae83cf029.png)

計算できているみたいですね。

# まとめ

x87命令を使ってsin関数を計算してみました。x87は内部表現が80bitで通常の倍精度実数と異なるし、外付けFPUだったころの仕様を引きずっていたりしますが、まだちゃんと使えます(ダイの上でどう実装されているかは知りません)。おそらく過去のプログラムの互換性のためだけに残されているのだと思いますが、たまにこうやって使ってあげるとx87命令も喜ぶんじゃないでしょうか。

# 参考文献

* [CS:APP2e Web Aside ASM:X87:
X87-Based Support for Floating Point (PDF)](http://csapp.cs.cmu.edu/2e/waside/waside-x87.pdf)
yarn buildはnpm run buildと同じ

## 0. yarnを使う

npmの代わりにyarnでwebpackプロジェクトをbuildしてみた。

## 1. webpack.config

```js
const path = require('path');

const config = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        use: 'babel-loader',
        test: /\.js$/,
      }
    ]
  }
};

module.exports = config;
```

## 2. .babelrc

```js
{
  "presets": ["babel-preset-env"]
}
```

## 3. build

`npm run build`のかわりに`yarn run build`もしくは`yarn build`でbuildができた。
UnityでiOSのARKitを動かす手順

UnityでiOSの[ARKit](https://developer.apple.com/arkit/)のプロジェクトをビルドし、動かすまでの手順です。

# 追記（2017/06/17）
ARKitができる事、できない事についてまとめた記事を投稿しました。
http://qiita.com/arumani/items/6efad65a17e2eafde5a1

# 追記（2017/06/07)
チュートリアルの日本語訳を投稿しました。
http://qiita.com/arumani/items/74dc65ceb9c90bd986ee

# 実行結果
**平面認識 UnityARKitScene**
<img src="https://qiita-image-store.s3.amazonaws.com/0/42051/91d0c8b6-dca7-42ee-d339-eacf9e1f38b2.png" width=80%>
平面に対して立方体を適切なサイズで置く事ができます。

**ポジショントラッキング UnityParticlePainter**
<img src="https://qiita-image-store.s3.amazonaws.com/0/42051/2dc7d467-e46c-68c3-cf07-01a0760eb466.png" width="49%"><img src="https://qiita-image-store.s3.amazonaws.com/0/42051/c7b8da17-751a-d40f-3c93-d7ee79f19c28.png" width="49%">
Tilt Brushのように空間上に色を置く事ができます。

# 環境
## Unity 5.6.1p1以降を入手
[Unity - Unity QA - Patch Releases](https://unity3d.com/jp/unity/qa/patch-releases)
現状パッチバージョンが必要なので、ここからダウンロードします。

## Xcode 9 beta版を入手
[Download - Apple Developer](https://developer.apple.com/download/)
ここからダウンロードします。有料のApple開発者アカウントが必要です。
このbeta版はインストールせずに起動できるので、既存のXcode環境を壊さずに試せます（旧バージョンの起動以外は確認していないので、どこかに影響あったらすみません）。

## iOS 11 beta版を入手
Xcode 9と同じく [Download - Apple Developer](https://developer.apple.com/download/) からダウンロードできます。
私はimageをiTunes経由でインストールしました。

## Unity ARKit Pluginを入手
[Unity-Technologies / Unity-ARKit-Plugin — Bitbucket](https://bitbucket.org/Unity-Technologies/unity-arkit-plugin)
からダウンロードします。私はUnityフォーラムに投稿されていた以下のURLからunitypackageを直接ダウンロードしました。
https://oc.unity3d.com/index.php/s/3hfM9T05P9vOpCf

# 手順
1. 新規Unityプロジェクトを作成し、上記のプラグインパッケージをimport
2. PlatformをiOSに切り替える
3. **Player Settingsの"Camera Usage Description"に何か文字列を入れる**
※これを入れないとアプリがカメラ利用許可を得られず、起動時に落ちます

4. UnityARKitScene / UnityParticlePainter をビルド対象に追加してビルド
5. Xcode 9 betaで、通常のアプリと同様にビルド、実機で実行する

# 実行結果
※本エントリ冒頭の画像と説明参照

# 参考URL
AppleのARKitホーム
[ARKit - Apple Developer](https://developer.apple.com/arkit/)

Unityフォーラム
[ARKit support for iOS via Unity-ARKit-Plugin | Unity Community](https://forum.unity3d.com/threads/arkit-support-for-ios-via-unity-arkit-plugin.474385/)

Unity ARKit Pluginレポジトリ
[Unity-Technologies / Unity-ARKit-Plugin — Bitbucket](https://bitbucket.org/Unity-Technologies/unity-arkit-plugin)
WRF / GFortran > v4.4.7とv4.9.2のバイナリ互換 > よく分からないので、混在はしないことにした

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
```

WRF(Weather Research and Forecasting Model)に関して。

[WRF / WPS > v3.9セットアップ > GFortranのバグにはまる](http://qiita.com/7of9/items/cfc8beb1d4185d12d521)
において、GFortranのv4.4.7とv4.9.2でそれぞれ作成した実行ファイルが生成するバイナリファイルの互換性が気になっている。

unformatted形式で試してみた。

### バージョンの切替 > scl使用
CentOS 6.8ではv4.4.7のGFortranがインストールできる。

一方でSoftware Collections (SCL)を用いてv4.9.2をインストールできる。
方法については以下を参照 (gcc-c++でなくgcc-gfortranとした)
http://qiita.com/phanect/items/45c67fa55d624e45367b

### code

Fortran90なのかFortran77なのか分からないcodeであるが気にしない。

```write_sample_170606.f90
	implicit none

	real(8) pi, napier, avogadro

	pi = 3.141592
	napier = 2.7182
	avogadro = 6.022

	open(10, file='test.bin', form='unformatted')
	write(10) pi
	write(10) napier
	write(10) avogadro
	close(10)

	stop
	end
```

```read_sample_170606.f90
	implicit none

	real(8) pi, napier, avogadro

	open(10, file='test.bin', form='unformatted')
	read(10) pi
	read(10) napier
	read(10) avogadro
	close(10)

	write(6,*) pi
	write(6,*) napier
	write(6,*) avogadro

	stop
	end
```

### 実行

v4.4.7の環境において

```
$ gfortran write_sample_170606.f90
$ gfortran read_sample_170606.f90 -o read_sample_v4_4_7
```

v4.9.2の環境において

```
$ gfortran read_sample_170606.f90 -o read_sample_v4_9_2
```

```
$ ./read_sample_v4_4_7 
   3.1415920257568359     
   2.7181999683380127     
   6.0219998359680176     
$ ./read_sample_v4_9_2 
   3.1415920257568359     
   2.7181999683380127     
   6.0219998359680176     
```

ここまで実施して、ふと思ったのが「バージョンが変わることでバイナリ出力形式が変更されたら大問題になるだろう」ということ。
よほどの問題がない限りは変更されないという気がしてきた。

しかしながらmodファイルはバージョンによって違う。
同じバージョンのコンパイラでビルドするのが前提のような気もする。

### link

バイナリ保存関連で見つけた記事。
http://naturesflyers.blogspot.jp/2015/01/fortran-unformatted-binary.html

### v4.4.7とv4.9.2の混在

**影響が不明のため混在をやめてv4.9.2で統一することにした。**
DB


システムを作るとき、多くのデータを扱います。それらのデータを検索・更新などの活用をしやすくしたものを「データベース」といいます。
##7.1 DBの操作
データの登録(Create)・検索(Read)・更新(Update)・削除(Delete)の4つの処理を合わせて「CRUD(クラッド)」といいます。
PHPでデータベースを利用する場合、データベースへの接続・SQL文の実行・データベースの接続切断という流れで使用する。

##7.2 SQL
データベースに履いているデータの操作をするとき、SQL文を実行する。
###INSERT文
データをDBに登録する場合、INSERT命令をを実行します。
DBのテーブルにデータを登録する(INSERT)ときは、以下のように記述する。

```php
//例)
INSERT INTO テーブル名(カラム名1, カラム名2, ... ) VALUES ("値1", "値2", ... );
```

テーブル名には、データを格納したいテーブル名を指定します。カラム名と値は、対応する順に指定してあげましょう。実際は以下のように記述します。

```php
INSERT INTO `ccm` (`member_name`) VALUES (" /*自分の名前*/ ");
```

###SELECT文
テーブルからデータを取得(SELECT)するときは、以下のように記述する。

```php
SELECT 取得したいカラム名1, 取得したいカラム名2, ... FROM テーブル名 WHERE 絞り込み条件;
```

すべてのカラムを取得したい場合、アスタリスク「*」を用います。
また、

___絞り込み条件___
(1) ___条件___
___文字列による絞り込み条件___
  ___・カラム名 = 検索文字___
  　カラムの値と検索したい文字列が完全一致するデータの表示

```php
    WHERE `member_name` = "hoge"
```

  ___・ カラム名 LIKE 検索文字(あいまい検索)___
  　カラムの値に検索したい文字列を含むデータの表示

```php
    WHERE `member_name` LIKE "%hoge%" 
```
```WHERE `member_name` LIKE %foo%```　-> 検索したい文字列に「foo」を含んでいる(部分一致)
  ```WHERE `member_name` LIKE fuga%``` -> 検索したい文字列が「fuga」から始まる文字列(前方一致)
  ```WHERE `member_name` LIKE var%``` -> 検索したい文字列が「var」で終わる文字列(後方一致)　

___数値による絞り込み条件___

|記述|意味|
|:--|:--|
|```WHERE `member_id` < 7```|member_idカラムが7より小さいレコードの表示|
|```WHERE `member_id` > 7```|member_idカラムが7より大きいレコードの表示|
|```WHERE `member_id` >= 7```|member_idカラムが7以下のレコードを表示|
|```WHERE `member_id` <= 7```|member_idカラムが7以上レコードを表示|

(2) ___データの取得数の制限___

___LIMIT___句を用いることで、検索結果を何件取得するのかという指定をすることができる。

```php
 SELECT * FROM `members` LIMIT 5
 //検索結果としては5件のみが取得できる
```

(3) ___データ件数の取得___

___COUNT___句を用いることで、検索結果を何件取得できたのかを知ることができる。

```php
SELECT COUNT(*) FROM `members`
```


(4) ___データの並び替え___
___ORDER BY___を用いることで、idの昇順・降順を指定することができます。

```php
SELECT * FROM `members` ORDER BY `member_id` ASC; //(昇順);
SELECT * FROM `members` ORDER BY `member_id` DESC; //(降順)
```

(5) ___テーブル結合___

複数のテーブルから1つのテーブルに作り変えることができ、これを用いることでテーブルの関係性を持ったデータの取得ができる。

```
SELECT カラム名1, カラム名2, ... FROM テーブル名1 LEFT JOIN テーブル名2 ON テーブル名1.フィールド名 = テーブル名2.フィールド名
WHERE 条件
```

###UPDATE文

テーブルにあるデータの更新(UPDATE)するときは、以下のように記述する。

```php
UPDATE テーブル名 SET カラム名1="値1", カラム名2="値2", ... WHERE 条件;
```

実際にmembersテーブルのデータを更新してみましょう。

```php
UPDATE `members` SET `member_name` = "hoge" WHERE `member_id` = 3;
//member_id = 3のmember_nameが櫻井に更新される
```

条件はSELECT文と同じで、更新対象のレコードの絞り込みで用います。 条件を記述しないと、全てのレコードが更新されてしまうので注意が必要です。

###DELETE文

テーブルにあるデータを削除(DELETE)するときは、以下のように記述する。

```php
DELETE FROM テーブル名 WHERE 条件;
```

実際にmembersテーブルのデータを1件削除してみましょう。

```php
DELETE FROM `members` WHERE `member_id` = 1;
//member_id = 1のレコードが削除される
```

条件はSELECT文と同じで、削除対象のレコードの絞り込みで用います。 条件を記述しないと、全てのレコードが削除されてしまうので注意が必要です。
PHP基本ルール・動作確認

PHPは、動的なWebサイトの作成を目的としたサーバーサイドで動作するプログラミング言語

##PHPの基本ルール
###ファイルの拡張子
PHPコードが書かれているファイルの拡張子は必ず「.php」とする必要があります。
「.html」とするとWEBサーバーがHTMLファイルとして判断され、正しく処理がされない。

###PHPのコーディングルール
####PHPコード
PHPコードを使用する場合、最初に`<?php`、`?>`は原則的に不必要ですが、PHPコードの後にHTML出力がある場合に限り書く必要がある。

```php
<?php
    //ここにPHPコードを記述
```

####コメントアウト
PHPコード内にコメントを残したいときは、コメントしたい文の文頭に`//`、`/* コード */`を記述してください。
コメントを書くことでプログラムの可読性が上がるのでなるべく書くようにしましょう。


```php
<?php
    //文頭に//がある場合はその行のみがコメント部分です。
    
    /*
    	コメント部分です。
    */
    //上記の文頭に/*、文末に*/がある場合はその中身全体がコメント部分です。
```

####文末
PHPコードの処理の文末に原則的にセミコロン`;`を記述しなければいけない。但し、PHPコードの他にもHTMLコードなどがあれば`?>`必要がある。PHPコード以外の他の文が無い場合には省略できます。

####インデント
PHPのインデントは、半角スペース4つです。

##動作環境
xampp 7.0.18
PHP 7.0

##動作確認
XAMPPを起動させた後、XAMPPのhtdocsフォルダに「first.php」というファイルを作成し、下記のコードを記述してPHPプログラムを実行して、ブラウザに「Hello World」という文字が出力されれば成功です。

・実行する前にXAMPPが立ち上がっていることを確認しましょう。
・実行確認をするには、ブラウザに「[http://localhost/hoge/first.php](http://localhost/ccm/first.php)」というURLを記述しよう。

```
<?php
    echo 'Hello world';
```
create-react-appでbuild先のパスを変更する

# 概要

React は環境構築が非常に面倒なイメージがありますが、つい最近 Facebook が作った `create-react-app` を使うと一瞬で環境構築が出来ます。

詳しくは下記の記事が参考になります。
[Facebook公式のcreate-react-appコマンドを使ってReact.jsアプリを爆速で作成する](http://qiita.com/chibicode/items/8533dd72f1ebaeb4b614)

`create-react-app` は `npm run build` コマンドで本番環境で使われることを想定した最適化されたファイルを build ディレクトリ生成することが出来ます。
しかし、Ruby on Rails 等のフレームワークを使ってる場合は、`/public` 以下に js を配置しなければなりません。

そこでこの記事では、 build ディレクトリ以外の任意のディレクトリに最適化された js を配置する方法を記述します。


# 前提

* macOS Sierra バージョン 10.12.4
* node v6.2.2
* npm 3.9.5
* create-react-app 1.3.0


# 解決方法

まず、予め `create-react-app` で生成したディレクトリで下記コマンドを実行し、設定ファイルをカスタマイズ出来るようにする。

```
npm run eject
```

弄るファイルは下記の3つ。

* /config/paths.js
* /config/webpack.config.prod.js
* /scripts/build.js

下記の手順で行う。

1. 最適化されたファイルが生成されるディレクトリのパスを指定
2. 生成される js の名前とパスを指定
3. ファイル生成先ディレクトリが初期化されないようにする

最終的には、 `public/js/[name].js` という形でファイルが生成されるようになる。

## 1. 最適化されたファイルが生成されるディレクトリのパスを指定

今回は build を public に変更してみる。

```/config/paths.js
// config after eject: we're in ./config/
module.exports = {
  dotenv: resolveApp('.env'),
  appBuild: resolveApp('build'), // ここを変える
  ...
```

↓

```/config/paths.js
// config after eject: we're in ./config/
module.exports = {
  dotenv: resolveApp('.env'),
  appBuild: resolveApp('public'), // ここを変える
  ...
```


## 2. 生成される js の名前とパスを指定

`static/js/[name].[chunkhash:8].js` を `js/[name].js` に変更する。

```/config/webpack.config.prod.js
    // Generated JS file names (with nested folders).
    // There will be one main bundle, and one file per asynchronous chunk.
    // We don't currently advertise code splitting but Webpack supports it.
    filename: 'static/js/[name].[chunkhash:8].js', // ここを変える
    chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js', // ここも変える
    ...
```

↓

```/config/webpack.config.prod.js
    // Generated JS file names (with nested folders).
    // There will be one main bundle, and one file per asynchronous chunk.
    // We don't currently advertise code splitting but Webpack supports it.
    filename: 'js/[name].js', // ここを変える
    chunkFilename: 'js/[name].chunk.js', // ここも変える
    ...
```


## 3. ファイル生成先ディレクトリが初期化されないようにする

公式のコメントにもいらなかったら削除しろって書いてありますね。

```/scripts/build.js
measureFileSizesBeforeBuild(paths.appBuild)
  .then(previousFileSizes => {
    // Remove all content but keep the directory so that
    // if you're in it, you don't end up in Trash
    fs.emptyDirSync(paths.appBuild); // これをコメントアウト
    ...
```

↓

```/scripts/build.js
measureFileSizesBeforeBuild(paths.appBuild)
  .then(previousFileSizes => {
    // Remove all content but keep the directory so that
    // if you're in it, you don't end up in Trash
    // fs.emptyDirSync(paths.appBuild); // これをコメントアウト
    ...
```


# まとめ

フロントエンドにはあまり詳しくないので、このようなアプローチが正しいかどうかはわかりません。
もし詳しい方で、ちゃんとした方法を知っている方がいらっしゃいましたら是非教えて頂けると幸いです。
CentOS7にvim8をインストールして簡単連番作成

SoftwareDesign6月号で紹介されていた「ビジュアルモードで選択して、g + Ctr + aで連番作成」を試してみたかったので。7.4.754以上は使えるみたいです。

手順は以下に書いてありました。
http://www.karan.org/blog/2016/11/05/vim-8-for-centos-linux-7/

```
$ wget https://copr.fedorainfracloud.org/coprs/mcepl/vim8/repo/epel-7/mcepl-vim8-epel-7.repo -P /etc/yum.repos.d/
古いvim消す
$ yum remove "vim*"
$ yum install vim-enhanced
$ vim --version
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled May 22 2017 12:47:09)
```
test.txt

```
Tokyo
Osaka
Nagoya
Sapporo
```

VでTokyoからSapporoまで選択して、:s/^/0,/

```
 0,Tokyo
 0,Osaka
 0,Nagoya
 0,Sapporo
```
gvで、再度選択した後に、g + Ctr + a

```
1,Tokyo
2,Osaka
3,Nagoya
4,Sapporo
```

gの意味がわからない。「go to」？

gvで、再度選択した後に、gを押さないで　Ctr + aのみだと以下になる。

```
 1,Tokyo
 1,Osaka
 1,Nagoya
 1,Sapporo
```

#### **追記**
---
有名な話のようですが、vimを消すと、sudoができなくなります。
visudoがvim-minimalに依存しているようです。
EC2上で実施していたので、rootでパスワードログインすることもできず。
結果的には同じインスタンスを立てて入れなくなってしまったインスタンスから
デタッチしたEBSボリュームを復旧インスタンスにアタッチしてsudoを入れ直しました。

復旧先インスタンスで実行したコマンド(sudo入れ直し)

```
/dev/xvdf1があること確認
# fdisk -l
# mkdir /hoge
# mount /dev/xvdf1 /hoge/
# yum --installroot=/hoge install sudo
```
元のインスタンスにボリュームを戻してsudo できることを確認

```
$ which sudo
/usr/bin/sudo
$ sudo su -
# 
```

やらかしてしまったので忘れないようにメモしておきます。
(メモ)Gitlab + mattermost on let's encryptの構築

初めに
===

* Gitlab + mattermostをlet's encrypt上で動かした際の参考情報です
* 完全に個人メモです

手順
===

Gitlab + let's encrypt
---

* [こちら](http://qiita.com/yuuAn/items/09a434d3f6cffa31101e)の手順でOK
* ただしlet's encryptはgit cloneで落としてきて直接letsencryptコマンドを実行した

Gitlabのbackup設定
---

* [こちら](http://urashita.com/archives/3966)の手順でOK
* cronでgitlab-rakeを叩く

```
#crontab

0 3 * * * gitlab-rake gitlab:backup:create
```

mattermost
---

* [こちら](http://qiita.com/emudome/items/cb5f3f72f4cb35ff2e80)の手順でgitlab.rbを編集してmattermost_external_urlを有効にしてreconfigureでOK
* ただし下記項目をfalseにしないとlet's encryptの証明書の取得ができなかった

```
mattermost_nginx['redirect_http_to_https'] = false
```
Railsの楽観的ロックで発行されるSQL

# はじめに
環境: Ruby on Rails 5.1.1

Railsの楽観的ロックで、どういうSQLが発行されるかを検証する。

楽観的ロックについては http://qiita.com/merrill/items/d9d41d64df292bd6432a などを参照。

もしRailsの実装で "saveする直前にselectしてlock_versionを確認し、同じならupdate" となっていたら、このselectとupdateの間に横から更新が入ると問題になる。そうなっていないかどうか念のため確認したかった。

# 先に結論

インスタンスをupdateするとき、1回のSQL文で行われる。したがって上のような問題は起きない。
where + update_all をした場合は楽観的ロックの対象外になるので注意。

# 準備

migration

```rb
class CreateDogs < ActiveRecord::Migration[5.1]
  def change
    create_table :dogs do |t|
      t.string :name, null: false
      t.integer :lock_version, default: 0

      t.timestamps
    end
  end
end
```

lock_version カラムを用意するだけでよいのがポイント。

model

```rb
class Dog < ApplicationRecord
end
```

そして、rails consoleから試す。

先にデータを準備

```
dog1 = Dog.create!(name: 'poti') # id: 1
```

# 結果

## インスタンスに対するupdate

```
irb(main):010:0> dog1.update(name: 'shige')
   (5.2ms)  BEGIN
  SQL (0.6ms)  UPDATE `dogs` SET `dogs`.`name` = 'shige', `dogs`.`updated_at` = '2017-06-06 01:16:27', `dogs`.`lock_version` = 1 WHERE `dogs`.`id` = 1 AND `dogs`.`lock_version` = 0
   (2.8ms)  COMMIT
=> true
```

where句にlock_versionを追加し、1クエリで行っている。

次に横から更新してみる

```
irb(main):011:0> dog11 = Dog.find(1)
irb(main):012:0> dog11.update(name: "yokoyari")
=> true
irb(main):014:0> dog1.update(name: "poti")
   (5.7ms)  BEGIN
  SQL (1.3ms)  UPDATE `dogs` SET `dogs`.`name` = 'poti', `dogs`.`updated_at` = '2017-06-06 01:22:40', `dogs`.`lock_version` = 2 WHERE `dogs`.`id` = 1 AND `dogs`.`lock_version` = 1
   (0.4ms)  ROLLBACK
ActiveRecord::StaleObjectError: Attempted to update a stale object: Dog.
	from (irb):14
```

lock_versionが更新されていたので ActiveRecord::StaleObjectError が出た。

最後に、横からこのdogを削除してみる。

```
irb(main):015:0> dog1 = Dog.find(1)
irb(main):016:0> dog11 = Dog.find(1)
irb(main):017:0> dog11.delete
irb(main):018:0> dog1.update(name: 'poti')
   (3.2ms)  BEGIN
  SQL (0.8ms)  UPDATE `dogs` SET `dogs`.`name` = 'poti', `dogs`.`updated_at` = '2017-06-06 01:26:45', `dogs`.`lock_version` = 3 WHERE `dogs`.`id` = 1 AND `dogs`.`lock_version` = 2
   (0.6ms)  ROLLBACK
ActiveRecord::StaleObjectError: Attempted to update a stale object: Dog.
	from (irb):18
```

同じ ActiveRecord::StaleObjectError エラーになる。仕組みを考えると当然。(このクエリの結果からはwhereにひっかからなかったことだけがわかり、消されてるかlock_versionが更新されてるかは分からない)

## where.update_all

where + update_allの場合は、lock_versionが更新されない。
したがって、横からwhere.update_allで更新されたレコードに対してupdateをかけると ActiveRecord::StaleObjectError が発生し**ない**(正常にupdateされてしまう) ということがわかった。注意が必要。

```
irb(main):024:0> dog3 = Dog.create!(name: 'inu')
irb(main):025:0> Dog.where(name: 'inu').update_all(name: 'neko')
  SQL (3.0ms)  UPDATE `dogs` SET `dogs`.`name` = 'neko' WHERE `dogs`.`name` = 'inu'
=> 1
irb(main):026:0> dog3.update(name: 'kuma')
   (4.7ms)  BEGIN
  SQL (0.9ms)  UPDATE `dogs` SET `dogs`.`name` = 'kuma', `dogs`.`updated_at` = '2017-06-06 01:34:13', `dogs`.`lock_version` = 1 WHERE `dogs`.`id` = 3 AND `dogs`.`lock_version` = 0
   (0.7ms)  COMMIT
=> true
```
[RDS]コマンドでRDSをstart stopしてみた

# コマンドでRDSをstart stopしてみた

RDSに「停止」が追加となった。
http://dev.classmethod.jp/cloud/aws/start-stop-db-instance-for-rds/

コマンドラインを確認したところコマンドが追加されていたので早速実行してみた。

## start
http://docs.aws.amazon.com/cli/latest/reference/rds/start-db-instance.html

```
aws rds rds start-db-instance --db-instance-identifier ${id}
```

## stop
スナップショットを取得してから停止
http://docs.aws.amazon.com/cli/latest/reference/rds/stop-db-instance.html

```
aws rds stop-db-instance \
  --db-instance-identifier ${id} \
  --db-snapshot-identifier ${snapshotId}
```

CopyTagsToSnapshotがtrueなのにsnapshotにタグが付かないので付与

```
snapshotARN="arn:aws:rds:ap-northeast-1:${AWSID}:snapshot:${snapshotId}"
aws rds add-tags-to-resource \
  --resource-name ${snapshotARN} \
  --tags "Key=k,Value=v"
```
Amazon Linux(2017.03)にdocker-composeでZabbix3.2をインストールするまで

## Zabbixサーバーのインストールと起動

Zabbixは公式でdocker-composeの定義を用意してくれていますので、とっても簡単に起動までできます。

Amazon Linuxを立ち上げてSSHで接続したところから、下記のコマンドで起動できます。

```bash
sudo yum update -y
sudo yum install -y docker git

# Docker起動
sudo service docker start

# docker-composeのインストール
curl -L https://github.com/docker/compose/releases/download/1.13.0/docker-compose-`uname -s`-`uname -m` > /tmp/docker-compose
chmod 755 /tmp/docker-compose
sudo mv /tmp/docker-compose /usr/local/bin/

# zabbixのdocker-compose定義を取得
git clone --depth=1 https://github.com/zabbix/zabbix-docker.git

# zabbix起動
cd zabbix-docker
sudo /usr/local/bin/docker-compose -f docker-compose_v2_alpine_mysql_latest.yaml up -d
```

Webにアクセスするとログイン画面が表示されます。
初期状態では Admin/zabbix でログインできます。

初期状態でzabbix-server自体がホストとして登録されていますが、接続に失敗している状態になっています。
IPが127.0.0.1に設定されていますが、Dockerコンテナ内なのでDockerコンテナ内から接続可能なIPである必要があります。
`sudo docker ps`などでコンテナ名を確認し、コンテナ名をドメインとして登録することで接続できます。(Dockerネットワーク内はコンテナ名でIPを引けるため)

## zabbix-agentのインストールと起動

RPMはRedHat7ではなく6用のものを使う必要があります。
7用のものを使うとsystemdが必要と言われてエラーになります。

インストールしてすぐに起動するとバインドアドレスが0.0.0.0/0になっているので油断しますが、設定ファイル(/etc/zabbix/zabbix_agentd.conf)を編集しないとローカルホスト以外からのアクセスはできないので注意が必要です。

```bash
sudo rpm -ivh http://repo.zabbix.com/zabbix/3.2/rhel/6/x86_64/zabbix-release-3.2-1.el6.noarch.rpm
sudo yum install zabbix-agent

# Server=127.0.0.1 の部分をZabbixサーバーのIPに変更する
sudo vim /etc/zabbix/zabbix_agentd.conf

sudo service zabbix-agent start
```

## セキュリティグループ

下記のポートを開けるのを忘れないこと。
サーバー: 10051
エージェント: 10050
ORACLE APEX5.1インストールメモ（12.2のPDBにインストール PL/SQL Gateway版）

**1. SYSユーザーでログインし、インストールするPDBに接続**

```
sqlplus / as sysdba
> ALTER SESSION SET CONTAINER = ORCLPDB;
```

**2. 必要に応じてAPEX用の表領域作成**

* サイズ等は要件にあわせて修正

```
> CREATE TABLESPACE "APEX" DATAFILE 
  '/u01/app/oracle/oradata/orcl/orclpdb/APEX01.DF' SIZE 104857600
  AUTOEXTEND ON NEXT 10485760 MAXSIZE 32767M
```

**3. インストール**

```
> @apexins.sql APEX APEX TEMP /i/
```

**4. インスタンス管理者アカウントを作成**

```
> @apxchpwd.sql

　Enter the administrator's username [ADMIN]
　User "ADMIN" does not yet exist and will be created.
　Enter ADMIN's email [ADMIN]
　Enter ADMIN's password []
　Created instance administrator ADMIN.
```

**5. APEX_PUBLIC_USERアカウントのロック解除**

```
> ALTER USER APEX_PUBLIC_USER ACCOUNT UNLOCK;
```

**6. APEX_PUBLIC_USERアカウントのパスワードの変更**

```
> ALTER USER APEX_PUBLIC_USER IDENTIFIED BY <新しいパスワード>;
```

**7. 必要に応じてパスワードの有効期限変更**

```
> alter profile default limit PASSWORD_LIFE_TIME UNLIMITED;
```

**8. apex_epg_config.sql構成スクリプトの実行**

```
> @apex_epg_config.sql <apex install directory>
```

**9. ANONYMOUSアカウントのロック解除**

* 共通ユーザーなので、ルートコンテナで実施する
* アカウントステータスがOPENになっていないと、APEX画面アクセス時にBASIC認証を求められる

```
sqlplus / as sysdba
> ALTER USER ANONYMOUS ACCOUNT UNLOCK;
> ALTER USER ANONYMOUS IDENTIFIED BY <適当なパスワード>;
```

**10. Oracle XML DBプロトコル・サーバーの有効化**

* PDBに接続して実施する
* ここではポートは8080にする

```
sqlplus / as sysdba
> ALTER SESSION SET CONTAINER = ORCLPDB;
> EXEC DBMS_XDB.SETHTTPPORT(8080);
```

**11. ネットワーク・サービスの有効化**

* メール送信やPDF、Webサービスを使用する際に必要
* 今回は省略

**12. 日本語のインストール**

環境変数設定

```
NLS_LANG=American_America.AL32UTF8
export NLS_LANG
```

PDBに接続後SQL実行

```
sqlplus / as sysdba
> ALTER SESSION SET CONTAINER = ORCLPDB;
> ALTER SESSION SET CURRENT_SCHEMA = APEX_050100;
> @load_ja.sql
```

**13. SHARED_SERVERSパラメータの構成**

* ルートコンテナで実行
* 同時ユーザーが少数の場合は、SHARED_SERVERSの値に5を使用することをお薦め(マニュアルより)

```
sqlplus / as sysdba
> ALTER SYSTEM SET SHARED_SERVERS = 5 SCOPE=BOTH;
```

**14. ログイン**

```
http://<hostname>:<port>/apex
```
でログイン
Arduino 1.8.2が起動しない

Arduino 1.8.2を起動させると、「起動中･･･」と表示された後、落ちてしまう。
なんで急にこんなことになったのかは不明だけど、とりあえず動いたので、その対処を忘れないようにメモっておく。

#エラー
`arduino_debug.exe`よりArduinoIDEを起動させたら、以下のようなエラーが出ていた。

```arduino_debug.exe
構成をロード中･･･
パッケージを初期化中･･･
ボードを準備中･･･
起動中･･･
java.io.FileNotFoundException: C:\Users\***\AppData\Local\Arduino15\preferences.txt (アカウントが拒否されました。)
  at java.io.FileOutputStream.open0(Native Method)
  at java.io.FileOutputStream.open0(FileOutputStream.java:270)
  at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
  at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
  at processing.app.legacy.PApplet.createWriter(PApplet.java:559)
  at processing.app.PreferencesData.save(PreferencesData.java:118)
  at processing.app.Base.handleOpen(Base.java:841)
  at processing.app.Base.handleOpen(Base.java:810)
  at processing.app.Base.handleOpen(Base.java:806)
  at processing.app.Base.handleNew(Base.java:745)
  at processing.app.Base.<init>(Base.java:456)
  at processing.app.Base.main(Base.java:140)
java.lang.RuntimeException: Couldn't create a writer for C:\Users\***\AppData\Local\Arduino15\preferences.txt
  at processing.app.legacy.PApplet.createWriter(PApplet.java:571)
  at processing.app.PreferencesData.save(PreferencesData.java:118)
  at processing.app.Base.handleOpen(Base.java:841)
  at processing.app.Base.handleOpen(Base.java:810)
  at processing.app.Base.handleOpen(Base.java:806)
  at processing.app.Base.handleNew(Base.java:745)
  at processing.app.Base.<init>(Base.java:456)
  at processing.app.Base.main(Base.java:140)
```

#対処方法
[Arduino Forum](https://forum.arduino.cc/index.php?topic=464254.0)に2つの方法が描かれていたので、試してみた。

- **ArduinoIDEを`管理者として実行`より起動させる。**
- **ポータブルモードで実行する**<br>
　`arduino.exe`や「drivers」「examples」「hardware」「java」といったフォルダが並んでいる場所に行きます。ここに、新たに「portable」というフォルダを作成し、ArduinoIDEを起動させる。<br>
（参考：[USBメモリ上で完結するArduino IDE](http://mag.switch-science.com/2012/06/10/portable-arduino)）

#結果
別々に実行したらうまくいかなかったけど、「portable」フォルダを作成し、管理者として実行したら、ArduinoIDEを起動させることができた。
丸付き数字のリストを表現するscss

# 丸付き数字リストをカジュアルに使いたい！

リスト表現で、ナンバーを多用していたら、見辛いから丸付き数字を使ってほしいと言われたのですが、リストのスタイルには丸付き数字がありません。そこで、そういうクラスを作ってみました。

`$circle_numbers`という配列に数値文字参照の文字列を突っ込んでいきます。
丸付き数字は1〜20までなので、20までしか対応しません。

## SCSSを定義

```scss
.list-circle-number {
  list-style: none;
  padding-left: 0;
  $circle_numbers: "\002460",
                   "\002461",
                   "\002462",
                   "\002463",
                   "\002464",
                   "\002465",
                   "\002466",
                   "\002467",
                   "\002468",
                   "\002469",
                   "\00246a",
                   "\00246b",
                   "\00246c",
                   "\00246d",
                   "\00246e", 
                   "\00246f",
                   "\002470",
                   "\002471",
                   "\002472",
                   "\002473";
  li {
    &:before {
      display: marker;
    }
    @each $circle_number in $circle_numbers {
      $key: index($circle_numbers, $circle_number);
      &:nth-of-type(#{$key}):before {
        content: '#{nth($circle_numbers, $key)}';
      }
    }
  }
}
```

`:nth-of-type`擬似要素を使うことで、クラスの下の要素で出現した回数だけ丸付き数字が付きます。

## 実際に使ってみる

では、使ってみましょう。`ol`タグで利用してみます。

```html
<ol class="list-circle-number">
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
  <li>abc</li>
</ol>
```

以下のような見た目になります。

![スクリーンショット 2017-06-06 10.01.23.png](https://qiita-image-store.s3.amazonaws.com/0/10078/360c25bf-8455-3771-d379-c8bbe56a92e7.png)

違和感なく利用することができますね！