OmniAICreator/Qiita-1.07M huggingface dataset:
《CSS》CSS「scroll-behavior」だけでアンカースクロールを実装する方法。


Chrome61がリリースされ、CSSの `scroll-behavior` プロパティを利用すると、JavaScriptなしのピュアCSSでアンカースクロールが実装できるようになりました。Firefoxでは36+から使えたやつですね。





## scroll-behavior

スクロールするボックスを作って、 `scroll-behavior` に `smooth` を与えると、アンカースクロールをクリック時にスムーススクロールします。

```

.wrap {
  height: 100vh;
  overflow: scroll;
  scroll-behavior: smooth;
}


```

* [demo](https://jsfiddle.net/yutousui/xj19zwLn/)






## 対応状況

* Chrome 61+
* Firefox 36+





## 参考

* [Smooth Scrolling: The scroll-behavior Property](https://drafts.csswg.org/cssom-view/#smooth-scrolling)
* [scroll-behavior - CSS | MDN](https://developer.mozilla.org/ja/docs/Web/CSS/scroll-behavior)





おわります。
DropboxにあるフォルダごとローカルHDDにバックアップ

#DropboxのフォルダごとローカルHDDにバックアップする方法
##
環境:Windows7

###
Dropboxにあるファイルは削除してもすぐ復元できる機能がありますが、HDDにもとっておきたいアナロガー？な方はぜひご参考までに。タスクスケジューラーも使えば夜寝ている間にバックアップが終わっています。

####
１．バッチファイルを作成する。

```bat

echo d | xcopy C:\Users\ユーザー名\Dropbox\ムフフ動画 Z:\dropboxバックアップ\ムフフ動画 /e /s /d /y

```

#####
C:\はコピー元のドロップボックスのあるフォルダ（PC環境によります）、Z:\はコピー先の任意ドライブ名です。コピー先にはあらかじめコピーするフォルダを作成しておきます。

```bat
/e /s /d /y
```
#####
というオプションを使うことによって、フォルダ以下、全てのフォルダとファイルをコピーします。

/e  ファイルが存在しなくてもディレクトリごとコピー
/s  ファイルが存在する場合のみディレクトリごとコピー
/d  コピー先に同じ名前のファイルが存在する場合、更新日が新しいファイルのみコピー
/y  同じ名前のファイルがある場合、上書きの確認を行わない

```bat
echo d | 
```
#####
上記はファイルかディレクトリかと聞かれているのでd（ディレクトリ）と答えています。

###

2.テキストエディタ等で上記コマンドを書いたら、名前を付けて保存します。

```bat
任意のファイル名.bat
```
###

3.バッチファイルをWindowsのプログラムにある、タスクスケジューラで指定します。

####
タスクスケジュールライブラリを右クリックして、タスクの追加をし、
「トリガー」タブでバッチファイルを起動する曜日や時間を設定、
「操作」タブでバッチファイルのある場所を指定します。

これで指定した時間にバッチファイルが実行され、コピーされます。

最初は少ないファイルで動きを確認しながらやると安心です。
fish shellからVimPlugにコマンド一発でプラグインをインストールできるようにする

最近やたらと環境再構築することがあって、それに伴いVimのプラグインインストールさせられるので、どうせならfish shellから思いついたプラグインを一発でインストールできるようにしちまえと考えた。

こんなふうに

```sh
vim-plug "dag/vim-fish"
```

## 使用環境
- Manjaro Linux KDE Edition
- Vim 8.0
- Fish shell 2.6.0
- vim-plug

## .vimrcを編集

vim-plugにはtomlでプラグインを記述する機能は(多分)ないので、`Plug '〜'`の部分を抽出し、fish scriptからでも簡単に編集できるようにする。

```vim:~/.vimrc
" Plugins
call plug#begin('~/.vim/plugged')
source ~/.vimrc.plugins
call plug#end()
```

```vim:~/.vimrc.plugins
Plug 'Shougo/vimproc.vim', { 'do': 'make' }
Plug 'itchyny/lightline.vim'
Plug 'tomasr/molokai'
Plug 'rhysd/vim-operator-surround'
Plug 'kana/vim-operator-user'
Plug 'Shougo/deoplete.nvim'
Plug 'Shougo/denite.nvim'
Plug 'terryma/vim-multiple-cursors'
Plug 'dag/vim-fish'
```

なんか不具合あるかなと思っていたが、起動が気持ち重くなるぐらいで特に大丈夫な様子。

## config.fishにfunctionを追加
引数なしの場合、そのままプラグインリストを編集するようにしてみた。

```fish:config.fish
function vim-plug-install
    grep "Plug '$argv'" ~/.vimrc.plugins > /dev/null; or echo "Plug '$argv'" >> ~/.vimrc.plugins
end

function vim-plug-uninstall
    grep -v -F "Plug '$argv'" ~/.vimrc.plugins | tee  ~/.vimrc.plugins >> /dev/null
end

function vim-plug
    if count $argv > /dev/null
        set flag 0
        for option in $argv
            switch "$option"
                case i install
                    set flag 0
                case un uninstall
                    set flag 1
                case \*
                    set plugs $option $plugs
            end
        end

        for plug in $plugs
            if test $flag -eq 1
                vim-plug-uninstall $plug
            else
                vim-plug-install $plug
            end
        end

        if test $flag -eq 1
            vim +":PlugClean" +:qa
        else
            vim +":PlugInstall" +:qa
        end

    else
        vim ~/.vimrc.plugins
    end
end
```

これでインストールとアンインストールが一発でできるようになった。具体的には

インストール時
1. `.vimrc.plugins`に`Plug '〜'`を追加
2. Vimを起動し:PlugInstallを実行して終了

アンインストール時
1. `.vimrc.plugins`から該当の`Plug '〜'`を削除
2. Vimを起動し:PlugCleanを実行して終了(このときにユーザーの確認入力が必須だが、やろうと思えばyesで回避できるかも？)

という処理を行っている。

ちゃんと動くかはわからない。

```
vim-plug (in(stall)) "dag/vim-fish" "mhinz/vim-startify"
```
```
vim-plug un(install) "dag/vim-fish" "mhinz/vim-startify"
```
Windows Subsystem for Linux (WSL)のreaddirはバグっている？

Windows Subsystem for Linux (WSL)のファイルシステムのベンチマークをBonnie++で取ろうとしたら、以下のようなエラーで中断してしまった。/homeの下でも/mnt/cの下でも同じ結果になる。

```
$ bonnie++
Writing a byte at a time...done
Writing intelligently...done
Rewriting...done
Reading a byte at a time...done
Reading intelligently...done
start 'em...done...done...done...done...done...
Create files in sequential order...done.
Stat files in sequential order...done.
Delete files in sequential order...Bonnie: drastic I/O error (rmdir): Directory not empty
Cleaning up test directory after error.
```

テストディレクトリを見ると、確かにファイルがたくさん残っている。Bonnie++はファイルのメタデータ操作の性能を測るために、16384(16*1024)個のファイルを作成するが、その半分くらいを消しそこねている。ファイルが何個残るかは試行によって微妙に変わる。

原因を調べてみたところ、[Bonnie++がファイルを全部削除するときのロジックがbuggyであるというコメント](https://github.com/phdeniel/nfs-ganesha/issues/72#issuecomment-7576535)をNFS-Ganeshaのissueで見つけた。Bonnie++は以下のロジックでファイルをすべて削除しているが、これがまずいとのこと。

```c
opendir()
while (readdir())
    unlink();
closedir()
```

さらに調べると、[macOSのHFSでも同じ問題が生じる](https://support.apple.com/kb/TA21420)ことがわかった。この記事では、ディレクトリに変更が加えられたあとにreaddirが何を返すかは未定義なので、このロジックではすべてのファイルを削除できないとしている。WSLのreaddirも同様に、ディレクトリに変更が加えられた場合に、すべてのエントリを読み出せるとは限らない実装になっているのだろう。

[SUSv4のreaddirの仕様](http://pubs.opengroup.org/onlinepubs/9699919799/functions/readdir.html)は、opendirのあとにファイルを追加や削除した場合、そのファイルをreaddirが返すかどうかを未定義としている。readdirの返値が未定義になるわけではない。追加・削除されたエントリを除くか含めるかは別として、readdirはすべてのエントリを読み出せなければならない。このロジックでファイルを全部削除できないreaddirの実装は、バグってるのではないだろうか。
Selenium WebDriver で IE11/Edge のファイルダウンロードを自動化する

# 問題点(押すべきボタン)

IE11/Edge でファイルをダウンロードする場合、下部に応答ダイアログ（通知バー）が出てきて「保存」を押す必要があります。

このダイアログです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/f464af02-8539-20e5-3bcd-c2efa877b052.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/f01ee8e8-1c9d-bd95-aa19-abd6a31a887d.png)

今回は、Selenium WebDriver でこれをテストする方法を調査しました。実装言語はJavaになります。

# ボタンを押すコード

ブラウザ設定でダイアログを非表示にすることはできないようなので、「保存」を押す方法を調べました。

[Testing Downloading Files in IE9 via Selenium](http://blogs.bytecode.com.au/glen/2013/11/11/testing-downloading-files-in-ie9-via-selenium.html) のコードを参考に作成しましたが、IEのバージョンが違うため少し修正する必要がありました。

```java:sample.java
import java.awt.AWTException;
import java.awt.Robot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.ie.InternetExplorerDriver;

//・・・

// ダウンロード処理を行うエレメント(ボタンなど)を検索
WebElement downloadElement = driver.findElement(By.id("download"));

try {
    Robot robot = new Robot();

    // 対象エレメントにフォーカスを移動
    downloadElement.sendKeys("&quot;&quot;");

    // Enterキーを押下
    robot.keyPress(KeyEvent.VK_ENTER);
    robot.keyRelease(KeyEvent.VK_ENTER);

    // ダウンロードの通知バー(ダウンロードマネージャ)が出てくるのを待つ
    Thread.sleep(2000);

    // Alt+N を押下して、ダウンロードの通知バー(ダウンロードマネージャ)にフォーカスを移動
    robot.keyPress(KeyEvent.VK_ALT);
    robot.keyPress(KeyEvent.VK_N);
    robot.keyRelease(KeyEvent.VK_N);
    robot.keyRelease(KeyEvent.VK_ALT);

    // Enterキーを押下してダウンロード開始  
    robot.keyPress(KeyEvent.VK_ENTER);
    robot.keyRelease(KeyEvent.VK_ENTER);

    // ダウンロード終了を待つ
    Thread.sleep(2000);

    // Alt+N を押下して、ダウンロードの通知バー(ダウンロードマネージャ)にフォーカスを移動
    robot.keyPress(KeyEvent.VK_ALT);
    robot.keyPress(KeyEvent.VK_N);
    robot.keyRelease(KeyEvent.VK_N);        
    robot.keyRelease(KeyEvent.VK_ALT);

    // タブキーを3回押下して、通知バーの "X" ボタンに遷移する
    robot.keyPress(KeyEvent.VK_TAB);
    robot.keyRelease(KeyEvent.VK_TAB);

    robot.keyPress(KeyEvent.VK_TAB);
    robot.keyRelease(KeyEvent.VK_TAB);

    robot.keyPress(KeyEvent.VK_TAB);
    robot.keyRelease(KeyEvent.VK_TAB);

    // Enterキーを押下して、通知バー(ダウンロードマネージャ)を閉じる
    robot.keyPress(KeyEvent.VK_ENTER);
    robot.keyRelease(KeyEvent.VK_ENTER);
} catch (AWTException e) {
    e.printStackTrace();
}
```

# 説明と注意事項

コメントに書いたように、このコードはRobotを使用して、ダウンロードに必要なキー操作を実行しています。具体的には

- Alt+N を押す(ダウンロードダイアログにフォーカス) → Enterを押す(保存ボタンが押される) → もう一度 Alt+N を押す(ダウンロード後の確認ダイアログにフォーカス) → タブでX(閉じる)ボタンに移動 → Enterを押す(ダイアログが閉じる)

という操作を行っています。

そのため、<font color="red">テスト実行中にアクティブウインドウを変更してしまうと、そのウインドウでキー操作されてしまい、テストが失敗してしまいます</font> (例えば、正常に実行できているかを確認するためにダウンロードフォルダを開いてしまうと、そちらでキー操作されてしまう)。 ここのコードをテスト中はアクティブウインドウを切り替えないよう、注意が必要です。

また、将来的にブラウザの仕様が変わって、キー操作が変更になった場合は修正が必要です。
最後に今回確認したブラウザバージョンを記載しておきます。

IE11のバージョン情報：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/832c5b4e-d564-4f5c-4462-29c0c4ce5edd.png)

Edgeのバージョン：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/1231bca2-fab3-bde8-f38d-fec071530e6f.png)
HoloLens開発環境　CS0006　の解決方法

<h2>はじめに</h2>
改めてHoloLensの開発環境を構築したさい詰まったのでメモ
Visual Studio 2017.15.3の問題だったみたい

<h2>環境</h2>
Visual Studio 2017.15.3
unity 5.6.3f1
HoloLens

<h2>状況・エラー内容</h2>
ビルド時にエラー番号「CS0006」が表示される

<h2>解決策</h2>
unity 5.6.3p2 をインストール
↓
https://unity3d.com/jp/unity/qa/patch-releases/5.6.3p2


<h2>その他</h2>
１、 UWP　SDK  10.0.14393.795 をあててみる
⇒エラー取れず

２、下記を参考にさせていただきました。
http://blog.roy29fuku.com/virtual-reality/hololens/error-list/



以上です。
Microsoft Bing Image Search API で 写真をPOSTしてImage Insightsを取得する（Python）

MSのAPIページにあるサンプルスクリプトとリファレンス通りにしてImage Insights の Similer Images を画像アップロードで取得しようとしたら、「検索に使うクエリーqがないよ」とか言われて動かなかったので、四苦八苦の末正解にたどり着きました。

```python:upload.py
import requests

headers = {
    'Ocp-Apim-Subscription-Key': '<Your API KEY>',
}
uri = "https://api.cognitive.microsoft.com/bing/v5.0/images/search?modulesRequested=similarimages"
    
image = open('image.jpg', 'rb')
files = {'param_name': ('filename.jpg', image, 'image/jpeg')}

r = requests.post(uri, data={'dummy':"test"},files=files,
                  headers=headers)
```

ポイントは、headersに　 `'Content-Type' : 'multipart/form-data'` を　**書かない**　ことです。
files = でファイルを添付すれば、勝手にmultipart/form-dataにしてくれるのですが、headersに指定して上書きすると、boundary指定が消えてしまうのです。
どうやらAPIはこれを見ているらしく。これがないと「検索用のクエリーqがないよ」っていうエラーを返されます。insightsが欲しいのに。

ここに辿り着くまでにC#で書いてみたり、UWPアプリ作ったり、Node-redで受け取って調査したり、ラズパイのセキュリティ設定に悩まされたり、、はああ

追記
C#はこちらのスレッドのコードが動きました、
https://stackoverflow.com/questions/41463093/microsoft-cognitive-api-image-search
node-jt400を試してみた（on AWS_EC2）

#環境
AWS EC2でnode-jt400が稼働するかテストしました。
マシンイメージ：Amazon Linux AMI
タイプ：t2.micro
node.js：6.9.1 
npm：3.10.8
jdk：java：1.8.0_131

#インストール
```
mkdir myfolder
cd myfolder
npm init -y
npm install node-jt400
```
問題無く、インストールできました。

参考までに、node-jt400でインストールされるモジュールです。

```
└─┬ node-jt400@1.4.1
  └─┬ java@0.8.0
    ├── async@2.0.1
    ├─┬ find-java-home@0.1.3
    │ └── which@1.0.9
    ├─┬ glob@7.1.1
    │ ├── fs.realpath@1.0.0
    │ ├─┬ inflight@1.0.6
    │ │ └── wrappy@1.0.2
    │ ├── inherits@2.0.3
    │ ├─┬ minimatch@3.0.4
    │ │ └─┬ brace-expansion@1.1.8
    │ │   ├── balanced-match@1.0.0
    │ │   └── concat-map@0.0.1
    │ ├── once@1.4.0
    │ └── path-is-absolute@1.0.1
    ├── lodash@4.16.4
    └── nan@2.4.0

```

#EC2からIBMi(AS400)へのネットワーク接続
いろいろ方法はあるかと思いますが、今回はテストなのでSSHを使用しポート転送を行いました。転送したのは以下のポートです。
449・8470・8471・8473・8475・8476

私は以下のコマンドを実行しました。

```
ssh -C -N -f -L 449:ibmi:449 sshuser@sshhost
ssh -C -N -f -L 8470:ibmi:8470 sshuser@sshhost
：
```

#EC2のポートを開ける
nodeの待ち受けは8888ポートを使用しているので、解放します。
VPN→セキュリティグループ→インバウンドのルール

#接続先ホストの改修
[以前](http://qiita.com/yamurata/items/a61227221fdb5676b06d)のテストで使用したSQLquery.jsのhostパラメータを修正します。

```
var pool = jt400.pool({ host: '127.0.0.1', user: 'MYUSER', password: 'MYPASS' });
```

#nodeの実行
```
node SQLquery.js
```

#実行結果
![nodejt29.png](https://qiita-image-store.s3.amazonaws.com/0/146069/447b6487-e8fd-9ce2-0cd6-ad627f06c05d.png)
Bash で月初と月末を表示する方法

GNU date でのみ動作する。macOS 等にインストールされている BSD date では動作しない。

```shell-session
# 今月初め
$ echo $(date +"%Y%m%d" -d"`date +"%Y%m01"`")
20170901

# 先月初め
$ echo $(date +"%Y%m%d" -d"`date +"%Y%m01"` 1 month ago")
20170801

# 来月初め
$ echo $(date +"%Y%m%d" -d"`date +"%Y%m01"` + 1 month")
20171001

# 今月終わり
$ echo $(date +"%Y%m%d" -d"`date +"%Y%m01"` 1 days ago + 1 month")
20170930

# 先月終わり
$ echo $(date +"%Y%m%d" -d"`date +"%Y%m01"` 1 days ago")
20170831

# 来月終わり
$ echo $(date +"%Y%m%d" -d"`date +"%Y%m01"` 1 days ago + 2 month")
20171031
```

ちなみに月初めではなく月の2日目を表示するためのコマンドは以下の通りである。

```shell-session
# 今月2日目
$ echo $(date +"%Y%m%d" -d"`date +"%Y%m02"`")
20170902
```
C++ Builder > TTrackBar > 複数のTTrackBarのOnChange処理を一つのTimer1Timerで共通処理 > Tagプロパティに(NativeInt)Senderを渡して使う

```txt:動作環境
C++ Builder XE4
```

### 要望

- TTrackBar型コンポーネントが複数ある
- それぞれを変更した時、Timer1で処理したい
- 処理を共通化したい

こうしました。

- Timer1のTagプロパティにSenderを渡す
    - 参考: [Tag プロパティの真価](http://ht-deko.com/tech006.html) by ht_dekoさん
- Timer1Timer内でTagからSenderを取得
- Senderに付随するプロパティ(e.g., Name and Position)を使って処理する

### code

```Unit1.h
//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ComCtrls.hpp>
#include <Vcl.ExtCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TTrackBar *TrackBar1;
	TTrackBar *TrackBar2;
	TTrackBar *TrackBar3;
	TTimer *Timer1;
	TMemo *Memo1;
	void __fastcall TrackBarChange_general(TObject *Sender);
	void __fastcall Timer1Timer(TObject *Sender);
private:	// ユーザー宣言
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
```

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	Timer1->Enabled = false;
	Timer1->Interval = 300; // msec

	// イベントの割当て
	TrackBar1->OnChange = TrackBarChange_general;
	TrackBar2->OnChange = TrackBarChange_general;
	TrackBar3->OnChange = TrackBarChange_general;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::TrackBarChange_general(TObject *Sender)
{
	if (Timer1->Enabled) { // イベントの連発を防ぐ
		return;
	}

	Timer1->Tag = (NativeInt)Sender;

	Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
	TTrackBar *trbPtr = (TTrackBar *)Timer1->Tag;
	String msg = L"Change [" + trbPtr->Name + L"] to Position:" + IntToStr(trbPtr->Position);
	Memo1->Lines->Add(msg);

	Timer1->Enabled = false;
}
//---------------------------------------------------------------------------
```

### 実行例

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/81e035d3-43e2-49d0-6418-99c0d8f55763.png)

- (1): TrackBar1の値を変更
- (2): TrackBar2の値を変更
- (3): TrackBar3の値を変更
テキストを導入するときのフォント単位のお話

本日は、Web制作をする際のフォントの単位のお話です。

Webサイトを作る際はフォント関連だけでいうと

フォントのカラーだったり、サイズだったり、太さだったり 色々あると思います。
その中でもまあ設定に悩むであろう単位のことについて触れていきます(*‘∀‘)

↓↓ まずWebサイトの制作でよく使われるフォント単位の一覧 ↓↓

・px

・%

・em

・rem

・vw

・vh


最近、よく使われるのは、remとかですかね。筆者はあまり使ったことがないのでWebサイトとか作る人としてはヤバいので次回から意識してみようと思いました（感想

さてではおひとつずつ見ていきましょう。

###●px（ピクセル）

フォント単位の古豪。昔から使われている単位ですね。絶対指定の単位になります。画面サイズなどに対してその値から動かない。とのことです。古いIEでは拡大しても拡大されない問題が起こってしまうそうな。。。へぇ。。。( ˙-˙ )
筆者はこの単位がわかりやすいので今でも使ってしまいます。

###●% (パーセント)

相対設定ですね。筆者はこれが今でもよく使う単位ですね。
親要素のフォントサイズに対応してのパーセンテージになります。
だいたい設定してなければ16px＝100%なんじゃないかなと思います。
14pxとかにして小さくしたいなーとすると88%となります。

###●em(エム)
だいたい、% と同じです。（雑
bodyに62.5%と設定しておくと10pxと同義になるので楽だそうです。

###●rem(レム)

上記2つの単位とは違いHTML（Root）に対してのemのためremと呼ばれます。
要はhtmlにフォントサイズ100%を充てておくと1remだと基本的に16pxになる感じですね。
最初にhtmlに指定しておけば難しいことはないですね。

筆者はあんまり使ってませんがレスポンシブの流行など今後のことを考えるとWeb上ではこちらの単位を使っていこうと思います。

###●vw(Viewport width)
###●vh(viewport height)


端末やブラウザの横幅に対して可変にするのが、vw
高さに対して可変になるのが、vh

筆者は何度かこの単位を使用したことがあるのですがなかなか難しい単位です。
よく考えて設計しないとフォントが超絶でかくなります（白目
どの場面で使うのかいまだに模索中です。



フォントサイズだけの話ではないですが
可変幅デザインなどが現代では主流なので、
やはり絶対値のpxはなるべく使わず、相対値での制作が望ましいですね。
Promises

## Overviews
非同期処理の結果を渡すもので、コールバックの代わりになる。
コールバックは、処理の手順を書いた他のfunction

## Benefits
結果を成功時と失敗時に分けてかける。

```sample.js

function asyncFunc() {
  return new Promise(
    function (resolve, reject) {
      ...
      resolve(result);
      ...
      reject(error);
    })
}

asyncFunc()
.then(result => { ... })
.catch(error => { ... })

```


非同期処理を行うためのパターン
ひとつだけ結果を返す（コールバック）
Promiseはコールバックを返すのに効率的
非同期処理がPromiseを返す：最終結果を含む
コールバックがPromiseを通して行われて結果がでる
valueとevent発行、両方のコンテナ

## callbackの代わりにPromiseを使う利点
1. 逆戻りしない
rejectとresolveの値を持っているから、コントロールができる
2. 変化がシンプル
最初にasyncを使ったPromiseでデータを取得、
その後にそのデータを使った処理（loops, mapping）を使うと便利
3. エラー処理に便利
"try-catch"などかかなくてよい

## Callbacks

```sample2.js
fs.readFile('config.json',
    function (error, text) {
        if (error) {
            console.error('Error while reading config file');
        } else {
            try {
                const obj = JSON.parse(text);
                console.log(JSON.stringify(obj, null, 4));
            } catch (e) {
                console.error('Invalid JSON in file');
            }
        }
    });
```

## Promises

```sample4.js
fs.readFile('config.json')
.then( text => {
  const obj = JSON.parse(text);
  console.log(JSON.stringify(obj, null, 4));
})
.catch( error => {
  console.error('Invalid JSON in file');
})

```

## Promisesの作り方

```sample5.js

const p = new Promise(
  function (resolve, reject) {
    ...
    if ( ... ) {
      resolve(value);  // 成功条件と渡す値を定義
    } else {
      reject (reason);　// 失敗条件と渡す値を定義
    }
  });

```

## Promisesのstates
状態は３種類
Pending: 結果がまだ出ていない状態（初期状態）
Fulfilled: 結果がでて成功！
Rejected: 処理中にエラーが起きて失敗

 エラーの状態のみ明したい場合は

```.js
promise.then(
  null,
error => { /* rejection */ });

promise.catch(error => { /* rejection */ })

```
## Example
```js

// Example1
function readFile(filename) {
  return new Promise(
    function (resolve, reject) {
      readFile(filename, { encoding: 'utf8' },
        (error, data) => {
          if (error) {
            reject(error)
          } else {
            resolve(data)
          }
        })
    })
}


readFile(process.argv[2])
.then(text => {
  resolve(text)
})
.catch(error => {
  console.log(error)
})



// Example2: delaying an activity
resolve(PARAMETER)とするかresolveとするかは自由。
parameterがある場合はresolve(PARAMETER)と書く。

function delay(ms) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, ms);  // 成功した場合はms秒後にsetTimeoutを発行させる。
  }
}

delay(5000).then(() => {  // 成功時に返す値がないからparameterは無視してOK
  console.log('5 seconds has passed!')　　
})

// Example3: timing out a Promise
function timeout(ms, promise) {
  return new Promise((reslve, reject) => {
    promise.then(resolve);
    setTimeout(() => {
      reject(new Error('Timeout after' + ms + 'ms'));
    }, ms);
  })
}

timeout(5000, httpGet('http://example.com/file.txt'))
.then((value) => {
  console.log('Contents: ' + value);
})
.catch((reason) => {
  console.log('Error or timeout', reason)
})


//　Promisesを作る他の方法
Promise.resolve('abc')
.then(x => console.log(x));

const p = new Promise(() => null);
console.log(Promise.resolve(p) === p);

```

## Referece
http://exploringjs.com/es6/ch_promises.html
Raspberry Pi Zero で自律飛行ドローンを作るぞ（第4回：気圧センサで高度を維持させる）

# はじめに

前回の[Raspberry Pi Zero で自律飛行ドローンを作るぞ（第3回：フライトコントローラを使いました...）](http://qiita.com/shigeru-yokochi/items/7dd15952011f47397d4a)　では、フライトコントローラのpitch,roll,yaw姿勢制御のおかげでRaspberry Piからのスロットル操作で浮上させることができました。 

# 今回は
設定した高度を維持する制御にトライしてみました。

# 距離センサ(VL53L0X)を使用して地上高400mmをkeepする。

結果：スロットルを少し下げると一気に降下してしまいます。降下を検知してスロットルを上げるのですがそのレスポンスが悪く大きく上下にふらついてしまいます。何度か値を調整しましたが結果は良くありませんでした。

![20170819-3.PNG](https://qiita-image-store.s3.amazonaws.com/0/146154/4cc12dc3-97ac-746d-73a9-8fd84ef14738.png)


動画はこちら(YouTube)
[![IMAGE ALT TEXT HERE](http://i.ytimg.com/vi/z1Xpy53_qa4/hqdefault.jpg)](https://www.youtube.com/watch?v=z1Xpy53_qa4s)


# 気圧センサ内蔵のフライトコントローラを使用して高度を維持させる。
制御プログラム改善の前に試してみたいのがフライトコントローラに内蔵の気圧センサの力を借りることです。
今使用しているフライトコントローラ(CC3D)は気圧センサは付いていないので、気圧センサ内蔵のフライトコントローラ(NAZE32)を使うことにしました。フライトコントローラ設定用アプリはCleanflightを使用します。※フライトコントローラの設定については割愛します。

↓構成は以下の通り。NAZE32はarm(アーミング)操作が必要なので制御信号を追加しています。baro(気圧センサ)制御信号も別で追加しています。
![drone構成(naze32).PNG](https://qiita-image-store.s3.amazonaws.com/0/146154/9eb68f84-aff3-3b8e-d077-06f559d342ce.png)

結果：スロットル操作した時の降下と上昇が緩やかになった感じです。もう少し検証を続けますが気圧センサの効果はありそうです。下図は高度400mmを検知してスロットル制御をしているのですが、実際は750mm付近で高度が維持されているのがわかります。

```:設定値
#define MINIMUM_GROUND_CLEARANCE 	40 //最小地上高
#define MAXIMUM_GROUND_CLEARANCE 	400 //最大地上高
#define DEBUG_MAINLOOP_TO 			7 //デバッグ用メインループタイムアウト指定(sec)
#define FLIGHT_TIME 				5 //DEBUG_MAINLOOP_TO - FLIGHT_TIME = landing time
#define OFFSET_POWER 				600
#define LANDING_POWER 				450
```

![20170907-68.PNG](https://qiita-image-store.s3.amazonaws.com/0/146154/2f1792fb-79a8-e75a-9a61-2c0c2904e9ee.png)

動画はこちら(YouTube)
[![IMAGE ALT TEXT HERE](http://i.ytimg.com/vi/y1wnsGAwrUc/hqdefault.jpg)](https://www.youtube.com/watch?v=y1wnsGAwrUc)


# 今回検証した機体の外観

- 表側
![20170907_164340-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/146154/a49f47fa-823b-f597-febf-1e208160f75d.jpeg)


- 裏側
![20170907_164401.jpg](https://qiita-image-store.s3.amazonaws.com/0/146154/b6373d5a-f6df-f3c7-d0e6-2bfdfeacedd9.jpeg)


# 今回の感想
気圧センサはあくまでも補助なのだと感じましたので、次にやることは高度制御プログラム改善を考えています。


# コード(GitHub)
https://github.com/shigeru-yokochi/drone

# 追記

- 2020/01/04 [この機体は大きすぎるのでマイクロドローン機への乗り換えを検討中です](https://www.yokochi.jp/post/betafpv-f4-2s-aio/)
- 2020/06/22 [Raspberry Pi Zero で自律飛行ドローンを作るぞ（第5回：距離センサVL53L0Xを複数使って衝突しないようにする）](https://qiita.com/shigeru-yokochi/items/7f74ccf200a57388e241)に続きます
vimで行の中央へ移動する

# vimで行の中央へ移動する

## 初めに
vimのカーソル移動はそのままでも便利である．しかし，横方向への移動が若干めんどくさいところがある．そのため，行の中央へ移動するコマンドがあると便利だと思い調べたが，それに当たるコマンドは見つからなかった．そこで，vimscriptの関数を利用して実装した．

## 実装
.vimrcに次の行を追加した．

```vim
nn gc :call cursor(0,strlen(getline("."))/2)<CR>
```

## 解説
ここでは次の3つの関数を用いてcallで呼び出し，gcにマッピングを行っている．
- cursor()
- strlen()
- getline()
これらの関数をそれぞれ説明していく.

### cursor()
その名の通り，カーソルを指定した位置へ移動させる．
cursor(行数,先頭からの文字数)のように引数を指定する．
行数，文字数を0にした場合は現在の位置となる．

### strlen()
引数で指定した文字数を出力する．

### getline()
引数にある行の文字列を取得する．
引数では行数で指定できるが，"."と指定すると現在カーソルがある位置を指定できる．

## まとめ
行の中央をカーソルがある行の文字数の半分の位置に移動させるというプログラムである．

実装自体は簡単だが，必要な関数とその使い方を調べるのに時間がかかった．
これらの関数の利用自体は簡単にできるが，情報が少なく導入するハードルが高い．
この記事で関数が手軽に利用されればと思う．
php7.1(php-fpm)のslab_cache対策

AWSでphpを使うとslab_cacheが溜まっていく現象が起こります。
原因としてはlibcurl関連らしいです、他記事で言及されているので、対策だけ。

php-fpmについてですが、
単純に /etc/php-fpm.conf に環境変数としての設定を以下のように追加するだけです。


```
env[NSS_SDB_USE_CACHE] = "YES"
```

なのですが、remiリポジトリからインストールしたphp7.1の場合だと
YESをダブルクォーテーションで囲むのが必要で
amazonlinuxのphp7.0の場合はYESをダブルクォーテーションで囲まなくてよかったりします。
複数ファイルをコンパイルする小さなメモ(Makefile)

# 前提
[複数ファイルをコンパイルする小さなメモ - Qiita]( http://qiita.com/kure/items/de5a004831d622925df3)の記事の後

# コード

```Makefile
PROGRAM = output
OBJS = test.o functions.o
SRCS = $(OBJS:%.o=%.c)
CC = gcc
CFLASG =
LDFLAGS =

$(PROGRAM):$(OBJS)
        $(CC) $(CFLGAS) $(LDFLAGS) -o $(PROGRAM) $(OBJS) $(LDLIBS)
```

# 実行

```
# make
# ./output
hello
3
```

# 補足

| 項目       |       説明 | 
|-----------------|------------------|
| PROGRAM | 実行ファイル名 | 
| OBJS |  リンクするオブジェクトファイル名をスペース区切りで列挙 |  
| SRCS| ソースコードのファイル名（サンプルではOBJSの拡張子を.cに変更） |
| CC  | Cコンパイラのコマンド名 |   
| CFLAGS  | コンパイルのオプション |  
| LDFLAGS | リンカのオプション |
| $(PROGRAM)  | プログラムの生成方法 |
既にインスタンス化されてるObjectへjsonをMapping

引数無しのデフォルトコンストラクタが使えないBeanクラスへ
Jsonをmappingするときに使えます。
※Beanのフィールドが全部Stringの場合に限ります

ソース

```java

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ObjectMapper2 extends ObjectMapper{
	public <T> T readValue(String content, T bean)
		        throws IOException, JsonParseException, JsonMappingException
	{
		// JSON -> Map
		Map<String,String> map = null;
		ObjectMapper mapper = new ObjectMapper();
		try {
			map = mapper.readValue(content, new TypeReference<LinkedHashMap<String,String>>(){});
		} catch (Exception e) {
			e.printStackTrace();
		}
		map.forEach( (key,value)->{
			try{
				org.apache.commons.lang3.reflect.FieldUtils.writeDeclaredField(bean, key, value, true);
			}catch(Exception e){
				e.printStackTrace();
			}
		});
		return bean;
	}

}
```

呼び出し側

```java
AbcBean bean = objectMapper.readValue(loginSessionJson, new AbcBean(null,null,null));
```
Prophetで遊んでみる

どういう話かというと，時系列解析は色々ややこしくて良くわからないけど，とりあえずデータは持っているので試してみたいといったときにオススメのライブラリProphet[^1] [^2]の紹介です．

## Prophetとは

- Facebook謹製の時系列解析ツール
- 時系列解析に詳しくなくてもデータを突っ込むだけで解析してくれる．
- RとPythonで使える．

### 性能を発揮させやすい条件

- 数ヶ月(可能なら1年)の時系列データがある
- イベントのタイミングは既知

### すごいところ

- 欠損値や異常値があっても大丈夫
- 傾向の変化にも対応してくれる．
- 熟練した分析者と同程度の性能をデフォルト値で出せたこともある．
- 時系列解析が苦手な人でも使える．

### Prophetの仕組み

下記4つの重ね合わせによって予測．

- 自動検出した傾向の変化点
- 年間の大まかな流れ
- 週ごとの流れ
- ユーザー提供のイベント情報

### インストール

```bash
pip install fbprophet
```


### チュートリアル

アメフト選手のペイトン・マニング氏[^3]のWikipediaの将来のページ閲覧数の予測を題材としています．

```bash
wget https://raw.githubusercontent.com/facebookincubator/prophet/master/examples/example_wp_peyton_manning.csv
```

```python
import pandas as pd
import numpy as np
from fbprophet import Prophet
df = pd.read_csv('../examples/example_wp_peyton_manning.csv')
df['y'] = np.log(df['y'])
df.head()
```



#### 学習

データをもとに学習する．

```
m = Prophet()
m.fit(df);
```

#### 予測データの準備

将来365日分とか出したかったら下記のように書く．

```python
future = m.make_future_dataframe(periods=365)
future.tail()
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/107399/336f5130-96c2-93a2-bd4d-701bbcb13006.png)


#### 予測結果の表示


```python
forecast = m.predict(future)
forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/107399/914b13bb-c6d4-0dd0-3adf-21e48f6dba2d.png)


#### 将来の予測推移

```python
m.plot(forecast);
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/107399/4e2726b0-5d43-e1e3-3a00-827d69baf519.png)


#### 成分ごとの表示

```python
m.plot_components(forecast);
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/107399/beaad0e3-16f8-f912-1053-47b0200d77b2.png)

次の記事 「[Prophetでビットコインの価格推移を予測してみる](http://qiita.com/namakemono/items/0e5bf336fc71dd32da30)」です．



## References

[^1]: Taylor, [Prophet: forecasting at scale](https://research.fb.com/prophet-forecasting-at-scale/), 2017.
[^2]: facebookincubator, [prophet](https://github.com/facebookincubator/prophet)
[^3]: [Peyton Manning](https://en.wikipedia.org/wiki/Peyton_Manning)
Windows 10 環境構築における検討


# 方針

1. Portable 版がある場合は Portable 版を利用する。
2. サイレントインストール可能なインストーラがあれば利用する。
3. 大物はインストーラで手動インストールする。
4. 上記以外は chocolatey を利用する。
5. 自動更新可能なものはアプリ側で行う。

# 作業フロー

1. OS インストール
2. OS 初期設定
3. powershell の Invoke-WebRequest で最低限必要なものをインストール(gitなど)
4. github からインストールスクリプトをダウンロードして実行

# 初期インストールスクリプト

手入力できるように工夫する。

- gist に保存
- gist の URL を URL 短縮サービスに登録
- powershell でダウンロードして実行

## こんな感じ

```
(iwr http://tiny.cc/hogehoge).content
```

# chocolatey

## google chrome 等、自動更新機能があるパッケージへの対応

https://stackoverflow.com/questions/44144253/should-i-disable-built-in-auto-update-of-packages-installed-by-chocolatey
https://chocolatey.org/docs/how-to-install-upgrade-package-without-scripts#application-is-self-updating-like-google-chrome

```
choco pin add -n=googlechrome
```

## パッケージリストの作成

https://stackoverflow.com/questions/43167087/how-to-get-a-list-of-packages-from-one-machine-and-install-in-another-with-choco

```
Write-Output "<?xml version=`"1.0`" encoding=`"utf-8`"?>"
Write-Output "<packages>"
choco list -lo -r -y | % { "   <package id=`"$($_.SubString(0, $_.IndexOf("|")))`" />" } | Select-String "chocolatey" -NotMatch | % { $_.Line }
Write-Output "</packages>"
```
複数ファイルをコンパイルする小さなメモ

**※記事下部に頂いたコメントあり**

# コード

```c:test.c
#include <stdio.h>
#include "functions.h"

int main(int arg, char *argv[]){
        printf("hello\n");
        int n;
        n = sum(1,2);
        printf("%d", n);
}
```

```c:functions.c
int sum(int a, int b){
        int returnv;
        returnv = a + b;
        return returnv;
}
```

```c:functions.h
int sum(int, int);
```

# コンパイル

```
# gcc -c test.c
# gcc -c functions.c
★ここまででオブジェクトファイルができる
# gcc test.o functions.o -o test
# ./test
hello
3
```

# 参考
ほぼこの記事のまんま
複数ファイルのコンパイル http://7ujm.net/linux/2.html
Solrでシグモイド関数

例えばsolrで売上ランキング3000位まではboostして検索結果上位に押し上げたいみたいなときに

```
bq=フィールド名:[0 TO 3000]^3
```

こんな感じでブーストを掛けちゃうと3000位と3001位の検索結果順に差が出すぎてしまいます。

なのでシグモイド関数を使って少し緩やかにブーストが掛かるよう
Solrのファンクションクエリでシグモイド関数を書きました。

```
y=2/(1+e^(0.001*(x-3000)))+1
```

![syg.png](https://qiita-image-store.s3.amazonaws.com/0/143303/1e96180e-90ea-e643-631d-fb4ba795e09b.png)



↑これをsolrで書くとこんな感じ

```
boost=sum(div(2,sum(1,exp(product(0.01,sub(【フィールド名】,3000))))),1)
```

（注）solrのboostはスコアに対して掛け算されるため＋1をしないと0になっちゃうので足してます
AWS Pollyでシステムアラートをしゃべらせてみる

(Qiita：team内に去年書いた記事をコピペしてます）

「AWS re:Invent 2016のKeynote 1にて、テキスト読み上げサービス「Amazon Polly」がリリースされました！」との
ことなので、何かに使えないかと考え・・・
とりあえずアラートをしゃべらしたら便利なんじゃないかと思って早速使ってみました。

Pollyについてはこちら↓
http://dev.classmethod.jp/cloud/aws/reinvent2016-new-service-amazon-polly/

# 構成

社内にリソースグラフを表示する40インチモニタが設置されているので、
そこからしゃべらせればいいと思ったので、こんな感じの構成で構築。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/143303/a4336123-b369-9789-d62a-640c1313c85d.png)



# SQSから全部取って、mp3に変換して再生して、キュー消す

```php:mac上に置いたスクリプトの一部
		// 100件ずつ処理する
		// sqsから10件ずつしか取得できないのでループして100件取得するようにする
		$messageList = array();
		for ($i = 0; $i < 10; $i++) {
		    $start_time = microtime(true);

		    // キューから10件データ取得
		    $result = $this->_getSqsMessage();

		    // 無ければ処理終了
		    if (!isset($result['Messages'])) {
		        break;
		    }
		    $messageList = array_merge($messageList, $result["Messages"]);
		}

		// 処理が正常に行えたメッセージのSQS情報を保持
		$sqsKeys = array();

		// 取れた分全部しゃべらせる
		foreach ($messageList as $k => $message) {
		    $mes = $message['Body'];
			p("Speek: ".$mes);
			if($mes){
				$mes = str_replace('"', "", $mes);
				$mes = mb_strimwidth($mes, 0, 140, "・・・以下略");
				// Mac通知センターにメッセージ表示
				$rs = `osascript -e 'display notification "{$mes}" with title "Polly"'`;
				// mp3生成
				$rs = `aws polly synthesize-speech --text "{$mes}" --voice-id Mizuki --output-format mp3 speech.mp3`;
				// 再生
				$rs = `afplay speech.mp3`;
			}

	        $sqsKeys[] = array(
	            "Id" => $message["MessageId"],
	            "ReceiptHandle" => $message['ReceiptHandle'],
	        );
		}

		// 全部消す（変換失敗とかあってもスルー）
		foreach (array_chunk($sqsKeys, 10) as $keys) {
		    $this->_deleteSqsMessage($keys);
		}
```

あとはslackBotやAPIなどでSQSにメッセージをぶち込めばなんでもしゃべる。

社外からSlackで社内に音声メッセージを強制的に響かせられます！
（休みます！とかｗ）


@all
DBからBIツールをJDBC連携、SaaSをODBC連携してみたときの備忘録

DBとBIツールやSaaSでの連携でこんがらがる部分があったので自分なりに備忘録程度にまとめました。

#今回使う用語
##SaaS
Software as a Serviceの略。ソフトウェアをWeb上で使えるもの。ソフトウェアは提供側のサーバーで動き、使いたい人はWebにアクセスしWeb上で操作するもの。自分のPCの容量は食わない。

#DBとBIツールを繋ぐ
まずは、BIツールとDBの連結から。今回は、ツールがjavaで作られていることを想定しました。なのでツールの接続口はJDBCになります。
<img width="597" alt="BItool_from_DB.png" src="https://qiita-image-store.s3.amazonaws.com/0/178136/673c0224-7f74-8720-f785-23701d3032bd.png">
そこのDBをjdbcの口にあった形にして繋げる部品が必要。それは、ETL（例えばinfoteria社）であったり、データ連携に特化した製品（cdata社）であったりする。

#DBとSaaSを繋ぐ
今度はDBとSaaSの連携について。
ほとんどのSaaSはAPIが公開されてはいるもののどんな言語で作られているのかなどについてはわからない。今回は、DBとSaaSを繋げるプログラムであったりツールがRubyで書かれていたとすると、接続口はODBCになります。
<img width="662" alt="DB_to_SaaS.png" src="https://qiita-image-store.s3.amazonaws.com/0/178136/b00bbf9e-b6fb-61d9-4061-ae9d1ceff577.png">
今回も繋げる部品が必要なのですが、DB用とSaaS用の2つが必要。
主な方法は
・プログラムも接続部品も全て手組み。
・接続部品は買って、プログラムは手組み。（ETLツールであったりデータ連携に特化したアダプター）
・接続部品も入っているツールを買う。（例えばinfoteria社）
この３種類かなと思います。
そこのコストとの兼ね合いは各々の状況によって異なる。三番目にいくにつれてノンプログラミングになっていくことと、繋ぐ部品が各製品のばらつき（言語によるものとか。めんどくさい部分）を統一してくれる（今回で言えば全てodbcに）。

#まとめ
こんな感じで自分がややこしくなっていた部分をまとめてみました。
どうしてjustify-itemsとかjustify-selfプロパテイがないの？（効かないの？）

なぜなら必要ないから

margin auto 

で調整できた。


[In CSS Flexbox, why are there no “justify-items” and “justify-self” properties?](https://stackoverflow.com/questions/32551291/in-css-flexbox-why-are-there-no-justify-items-and-justify-self-properties)

が、IE11でくずれました。

結局flexで調整するのをあきらめ、position: absoluteにし
jsで各要素の高さを取り計算をして位置をセットする方法に変えた。
Rabbitを使ってみる

Rabbitはプログラマ向けのプレゼンテーションツール。
以前、まつもとゆきひろさんが使っており、面白そうだったので遊んでみました。

#インストール方法
```
$ brew install cairo
$ brew link cairo
$ brew link --overwrite pixman
$ brew install pango
$ brew install gtk+
$ brew install poppler --with-glib
$ sudo PKG_CONFIG_PATH=/usr/local/opt/libffi/lib/pkgconfig gem install rabbit
```

#ファイル操作
hoge.rdを作る。

```hoge.rd
# Rabbit

subtitle
:   hoge

author
:   fuga

institution
:   COZMIXNG

theme
:   rabbit

# Rabbit

プレゼンテーションツール

* hoge
* fuga
* hoge
* fuga
```

#Terminal操作
```
$ rabbit --allotted-time 5m hoge.rd
```
バッチファイルだけで、指定フォルダーにあるファイル全部のチェックサムリストを作ろう

* [windows標準でMD5などのハッシュ値を出力 - Qiita](http://qiita.com/akimaru86/items/792bd6654b4d44bbf775)

これを利用して、指定フォルダーの特定拡張子のファイル全部に対して、チェックサムのリストを作るバッチファイルを書いてみた（サンプルは `%windir%` だけにしているが、複数フォルダーも指定可能）

このバッチで客先環境とテスト環境で想定外の差異が発生していないかチェックできるぜ。

```checksum1.cmd
@echo off
for %%I in (
    "%windir%"
) do pushd %%I & call :sum & popd
exit /b

:sum
    echo.
    echo ******************** %CD% *************************
    echo.
    for %%I in (
        *.dll
        *.exe
    ) do for /F "skip=1 tokens=*" %%J in (
        'certutil -hashfile "%%I" ^| findstr /v [C]ertUtil'
    ) do echo %%J %%I
    exit /b
```

Windows10 の場合：

```

******************** C:\Windows *************************

e75781e15270a4913ec7d749346a27df4ea6d9d6 twain_32.dll
e8edea2110d9c5f3d9ed931cdb535e92be25536d bfsvc.exe
b508012a71504be378757825d558f48da4d11d64 explorer.exe
b852f6e3876fc32b25b9bc9484006ca30e298b2d HelpPane.exe
2925f8db589a5752984d84ad334e6ed57f3c3ab4 hh.exe
2302ba58181f3c4e1e44a47a7d214ee9397cf2ba notepad.exe
00899dd7411ae8490f5995067370ef1e8019e52d regedit.exe
71d08d00ba575bd156c3f54bc78557fe6caf1083 splwow64.exe
c81f1a6683e0c145088d4b3929eafd636210c7e2 winhlp32.exe
c2bf322de4c9a56145c6947704a77c595a7f80e9 write.exe
```

Windows7 の場合：

```

******************** C:\Windows *************************

3c ac d2 04 8d b8 8f 4f 2e 86 3b 6d e3 b1 fd 19 79 22 b3 f2 twain.dll
d8 5b 3d 28 00 ef 51 9b 53 22 b9 3c 1e a8 c0 a8 09 2c 39 ec twain_32.dll
90 f6 70 e6 9a 3a f3 02 5e 4e 69 dd 77 53 d8 85 63 8c 83 7c bfsvc.exe
16 43 e6 d0 26 5e b6 0b 07 53 cd c9 c2 83 d8 43 b9 88 e1 d5 explorer.exe
a7 cc 86 49 44 69 85 7c 5f c2 99 8e 8d 3d 60 39 04 2a be ce fveupdate.exe
22 b8 10 44 4a 4e de ba f8 74 91 84 c5 ea 54 1f ee bd 8f 02 HelpPane.exe
8a 2c 05 87 3a 05 1a 03 31 49 e0 26 77 90 d2 ac 3d de ff 34 hh.exe
fc 64 b1 ef 19 e7 f3 56 42 b2 a2 ea 5f 5d 9f 42 46 86 62 43 notepad.exe
68 22 14 96 12 28 45 3c 38 98 54 e8 1e 67 86 df 92 bb fa 67 regedit.exe
d0 e8 17 97 31 7b ca 26 76 58 7f f9 d0 1d 74 4b 23 3a d5 ec twunk_16.exe
e2 07 de 5c 58 02 79 ad 40 c8 9b f6 f2 c2 d4 7c 77 ef d6 26 twunk_32.exe
05 df 70 6a 41 18 be 1b ee a9 06 91 ff 4a 29 22 92 44 28 8e winhelp.exe
2e ce 29 e4 ae 3f db 71 3c 18 15 2f 5c 75 56 a1 aa 8a 7c 83 winhlp32.exe
11 35 aa 35 54 ff 08 fb b3 7f 8c a3 5c 58 1b af d6 46 be 53 write.exe
```

Windows7 と Windows10 で出力が違うみたいですが、どうも CertUtil.exe の出力仕様の差みたいですね。まぁ、これくらいはなんとでもなるはず…きっと
DNS権威サーバーとキャッシュサーバが同居してて、isc-dhcpdでDDNSするときの覚書

# 一言
kea-dhcp使ったDDNSの設定方法ぷりーず
エラー出ちゃうんだ
> Flags: 0xac08 Dynamic update response, RRset does not exist


# 環境
同一サーバーで権威サーバとキャッシュサーバを動かしている
- 53    -> unbound
- 10053 -> PowerDNS

この時、ISC-DHCPDを使ってDDNS UPDATEするとき、アップデート先DNSサーバの"ポート"を指定できない（標準の53番を使う）
そのため、iptablesの機能を使って変換をぶちかます


# firewalldの設定抜粋
```
# firewall-cmd --direct --add-rule ipv4 nat OUTPUT 100 -p 
udp -d 127.0.0.2/32 --dport 53 -j DNAT --to-destination 127.0.0.1:10053

問題なければ・・・
# firewall-cmd --permanent --direct --add-rule ipv4 nat OUTPUT 100 -p udp -d 127.0.0.2/32 --dport 53 -j DNAT --to-destination 127.0.0.1:1005
# firewall-cmd --reload
```


#ISC-DHCPDの設定抜粋
```text:dhcpd.conf
ddns-updates on;
ddns-update-style interim;
update-static-leases on;

subnet 10.0.100.0 netmask 255.255.255.0 {
        zone stg.home.local. {
                primary 127.0.0.2; ← ここ
                key DHCP_UPDATER;
        }
        zone 100.0.10.in-addr.arpa. {
                primary 127.0.0.2; ← ここ
                key DHCP_UPDATER;
        }
}
```


# そのほかメモ
```
ダイレクトルールの一覧確認
# firewall-cmd --direct --get-all-rules

iptablesの設定確認
# iptables-save 
```


# 参考
- [Linux女子部　firewalld徹底入門！ 23P辺り](https://www.slideshare.net/enakai/firewalld-study-v10)
- [ダイレクトルールを使ったFirewallの強化](http://www.yam-web.net/centos7/direct-rule/index.html)
- [Using iptables to change a destination port \- Stack Overflow](https://stackoverflow.com/questions/242772/using-iptables-to-change-a-destination-port)
- [iptablesの設定内容確認と設定例](https://www.virment.com/iptables-setting-example/)
macで Ansibleを使ってパスワード認証方式で ssh接続する

少し工夫がいりましたのでメモ

### 1. sshpassのインストール

```
$ brew install ansible
$ brew install http://git.io/sshpass.rb
```

### 2. ansible.cfgファイルの設定

ubuntuでは`/etc/ansible/ansible.cfg`に書くらしいが、macには無いので`~/.ansible.cfg`に書けば良いらしい

```
$ nano ~/.ansible.cfg
```

```ini:.ansible.cfg
[ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
```

書込む内容は[こちら](http://qiita.com/taka379sy/items/331a294d67e02e18d68d)を参考にしました

### [option]動作確認

```
$ cat hosts 

[child]
192.168.11.[111:112] ansible_ssh_user=pi ansible_ssh_pass=raspberry
```

```
$ ansible -i hosts child -m ping

192.168.11.112 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.11.111 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
```
Swift 4 で「プラマイ」範囲を作る

どれだけの人が必要かわかりませんが、物理学とかやってると「AA ± aa」みたいな文言見たことあるんじゃ無いかと思います。つまり「正確には AA になるはずだが、実際の環境においてはそんな超絶に精密にぴったりそんな結果になるわけがないから、上下に aa の誤差がある」と言うようなことです。例えば 1kg の水が欲しいとき、測量機器によってそんなに精密に 1kg の水が出てくることはほとんどないから、例えばプラマイ 10g の誤差でも OK だよ、と言ったときに、1kg ± 10g で 990g ~ 1010g のニュアンスを表すことがよくあります。

Swift では範囲演算子 `...` があるので、`990 ... 1010` で書けば上記のその範囲を表すことができますが、ぱっと見「欲しいのは 1kg でプラマイの 10g は誤差だよ」と言うことはなかなか読み取りにくいと思います。そこで `1000 ± 10` で `990 ... 1010` を表したいと思いました。というわけで早速演算子を定義します：

```swift:Operator.swift
infix operator ± : RangeFormationPrecedence

extension Numeric where Self: Comparable {
	
	public static func ± (lhs: Self, rhs: Self) -> ClosedRange<Self> {
		let added = lhs + rhs
		let subtracted = lhs - rhs
		let lowerBound = min(added, subtracted)
		let upperBound = max(added, subtracted)
		return lowerBound ... upperBound
	}
	
}
```

ここで Swift 4 の `Numeric` というプロトコルを使っています。このプロトコルは何のためにあるのかというと中に使っている `+` と `-` の演算子が使えるということを保証しています。そしてなぜあえて `(lhs - rhs) ... (lhs + rhs)` を使わずに `lowerBound` と `upperBound` をそれぞれ `min` と `max` で定義しているのかというと、実際の利用時に `rhs` の値がマイナスになることも十分ありうると考えていますので、確実に `lowerBound` と `upperBound` を計算しました。

これで `1000 ± 10` を書けば `990 ... 1010` の範囲を返してくれます。便利ｽﾞｲ₍₍(ง˘ω˘)ว⁾⁾ｽﾞｲ

P.S.1
「 `±` どうやって入力するの」というツッコミをいただきましたが、まあ US 配列なら `Opt` + `Shift` + `=` で `±` を入力できます。JIS は知らん。

P.S.2
ちなみに実用的な使い道として、iPhone の画面サイズが 16:9 かどうかを判定するときに、実際の計算ではぴったり `16.0 / 9.0` と結果が一致することがあまりないです（唯一一致するのは iPhone 6+ の `736.0 / 414.0` です）ので、逆に `((16.0 / 9.0) ± 0.01).contains(568.0 / 320.0)` というふうに判定することができます。ちなみに自分はさらに [`…=` という演算子](http://qiita.com/lovee/items/32ceca1effbeceb959d6)も作っています。
Twilio簡単に

# Twilioとは

KDDIウェブコミュニケーションズの提供する「Twilio」は、たった数行のコードで電話やSMSとネットをつなぐことのできるクラウドAPIサービスです。
電話を掛けたり、着信を受けたり、音声を録音出来たりするらしい。

アラートの連絡に使えるのでは？

# とりあえず準備

https://jp.twilio.com
twilioサイトでアカウント取得してログインする

# 環境つくる

この辺の言語のSDKが用意されている様子。

* C# / .NET
* Java
* Node
* PHP
* Python
* Ruby 

https://jp.twilio.com/docs/libraries/php
ここにPHPでの方法が書いてある

# 電話をかけてみる

## XMLでしゃべる内容を定義する

XMLにしゃべらせる内容を記載して、どこか外部からアクセスできるところに設置する。

```xml:hoge.xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Say voice="woman" language="ja-jp">
        Core DB が落ちました。
        事故です。
        ヤバいです。
        スプラトゥーンを中断して早く対応してください。
    </Say>
    <!-- mp3も電話で再生可能 -->
    <Play>http://demo.twilio.com/docs/classic.mp3</Play>
</Response>
```

## 電話かけるPHPを用意

sidとtokenをダッシュボードで確認しておく。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/143303/1332cc63-ab85-906d-9b9e-60e0fdbba1e2.png)



```php:sample.php
<?php
require_once __DIR__ . "/vendor/autoload.php";

use Twilio\Rest\Client;

// SIDとTokenはtwilioの管理画面で確認できます
$sid = "***";
$token = "***";
$client = new Client($sid, $token);

$call = $client->calls->create(
    "+819000000000", // ←掛けたい電話番号 +81で初めて090の最初の0は省く
    "+815000000000", // ←発信元の番号。twilioのダッシュボードから
    array("url" => "http://xxxx/hoge.xml")　// XMLのURL。パブリックじゃないとダメ
);

echo $call->sid;
```

上記PHPをコマンドラインで実行するだけでtwilioから電話がかかってきます。

## twilioダッシュボードで通話履歴も確認できる


![image.png](https://qiita-image-store.s3.amazonaws.com/0/143303/e9b64ce9-6c02-6565-0fb6-70cebd0eb9f6.png)





# 業務でつかう前に課題

* XMLをどこに置くか、IP制限かけられるのか調べる必要あり
concrete5の外部フォームでファイルアップロード

お問い合わせフォームの添付ファイル機能などに。
フォームからアップロードされたファイルはファイルマネージャに追加されます。
日本語の情報があまりないので、ググりまくってなんとか辿り着いたやりかたです。

なんか間違ってたら教えてください。

そもそもの外部フォームの作り方についてはここがとても詳しいです。
concrete5.7対応 外部フォームブロックの作り方まとめ
https://www.cherrypieweb.com/weblog/technical/20161207104805.php

## フォーム側
```application/blocks/external_form/form/hoge.php
<form enctype='multipart/form-data' action="<?php echo $this->action('send'); ?>" >
  <?php echo $form->file('attachment'); ?> // attachmentのところは任意
</form>
```
これで`<input type="file" name="attachment" id="attachment">`みたいなタグが吐き出されます

## コントローラ側
```application/blocks/external_form/form/controller/hoge.php
namespace Application\Block\ExternalForm\Form\Controller;
use Concrete\Core\Controller\AbstractController;
use Core;
use FileImporter; // ←追加

// 中略

public function action_send($bID = false)
{
  // ファイルをとりこむ
  if (!empty($_FILES['attachment']['tmp_name'])) {
    $fi = new FileImporter();
    $file = $fi->import($_FILES['attachment']['tmp_name'], $_FILES['attachment']['name']);
    $this->file_name = $_FILES['attachment']['name']; // 必要ならファイル名が取得できる
    $this->file_url = $file->getDownloadURL(); // 必要ならダウンロードリンクが取得できる
    
    // ファイルセットを作ってそれに入れておくと自分で入れたファイルと区別がついてよいです
    // (事前に"Inquire Files"ファイルセットを作っておくこと)
    $set = \Concrete\Core\File\Set\Set::getByName('Inquire Files');
    $set->addFileToSet($file);
  }
}
```

これで僕はいけました。

設定の「許可されたファイル拡張子」に入ってないファイルが来るとエラーになるので注意！
配列に複数の値のいずれかが含まれているか判定

例えば、ある配列に2と5のいずれかが含まれている、のような条件を書きたい時ありませんか？そんな時、みなさんはどう書くでしょうか。

```rb
ary = [1, 3, 5, 6, 8]
if ary.include?(2) || ary.include?(5)
  # do something
end
```

`ary.include?`を2回も書くのはちょっとイケてない気がする……ので、いくつか解決策を考えました。他にもこんなやり方あるよ！というのがあればぜひコメントで教えてください！

# Array#-
```rb
ary = [1, 3, 5, 6, 8]
#2, 5のいずれかが含まれる
list = [2, 5]
(list - ary).size < list.size

#2, 5の両方が含まれる
(list - ary).empty?
```

ただし、一致判定の方法が`Array#include?`は`==`を使うのに対して`Array#-`は`eql?`なので、配列の中身のオブジェクトの種類によっては注意が必要です。

参考：https://oshiete.goo.ne.jp/qa/7042610.html

# Enumerable#any?
```rb
ary = [1, 3, 5, 6, 8]
# 2, 5のいずれかが含まれる
[2, 5].any? {|i| ary.include?(i)}

# 2, 5の両方が含まれる
[2, 5].all? {|i| ary.include?(i)}

# 2〜5のいずれかが含まれる
ary.any? {|i| i.between?(2, 5)}
```

最後の例は、配列の中身が`4.1`や`Rational(10, 3)`でもtrueになってしまうので要注意です。

# Enumerable#grep
配列の中身が文字列の場合は`Enumerable#grep`も。正規表現が使えるので、細かい条件とかいろいろ付けられそうです。

```rb
# ARGVに -h か --help が含まれればヘルプメッセージを出力
unless ARGV.grep(/\A(-h|--help)\z/).empty?
  puts help_message
end
```

# Array#include?を再定義
いっそ引数を複数取れるようにしてしまえばスッキリですね！

```rb
module Include
  refine Array do
    # all: trueの場合
    #   listの値全てがselfに含まれているか判定
    # all: falseの場合
    #   listの値のいずれかがselfに含まれているか判定
    def include?(*list, all: true)
      method = all ? :all? : :any?
      list.__send__(method) {|i| super(i)}
    end
  end
end

using Include
ary = [1, 3, 5, 6, 8]
ary.include?(2, 5, all: false) #=> true
Ubuntu16でネットワークインタフェース追加


まずはインタフェースがOSからどんな名前で認識されているか確認します。eth0とかen0とか色々ありますが、ubuntuではens3から始まる名前でした。

```
ifconfig -a
```

`ens4` という名前が見つかったので、設定ファイルに追記します。VPS環境などの場合、すでにインターネットに接続の設定があるので、それを真似て追加したら良いと思います。

/etc/network/interfaces

``` /etc/network/interfaces
auto ens4
iface ens4 inet static
        address 192.168.0.1
        netmask 255.255.255.0
```

保存したら、ネットワークデーモン(?)を再起動します。

```
sudo service networking restart
```

一応これだけの簡単な作業のはずなんですが、さくらのVPSで色々とハマったので、以下（あまりまとまってないですが）備忘メモ。


## さくらVPS固有のお話
VPSにローカルネットワークを追加するには、まず仮想のハブを作る必要があります。VPSのコントロールパネル上で、インタフェースがハブに接続していることを先に確認しましょう。ethXはCentOS上の名前で、ubuntuでは上述の通り、ens3,4,5が対応します。

![Screen Shot 2017-09-07 at 14.37.22.png](https://qiita-image-store.s3.amazonaws.com/0/50780/2468fc58-ea63-4b4f-cd2b-9da3db79e42c.png "Screen Shot 2017-09-07 at 14.37.22.png")

デフォルトで追加されている iptablesの設定が引っかかってくるので、新しいインタフェース(ens4)の通信を許可します。

/etc/iptables/iptables.rules 

``` /etc/iptables/iptables.rules 
-A INPUT -i ens4 -j ACCEPT
```

設定を弄ってると、うまくネットワークが再起動できないことが出てきますので、その場合は、設定をflushするとうまくいったりします。

```
sudo ip addr flush dev ens4
```
サンドボックスで使えるテスト用カード番号

APIのテストを行う際にはクレジットカード番号が必要です。自分のカードでテストしてしまったら課金されてしまうので大変です。

そこで使いたいのがテスト用のカード番号になります。Squareでは以下の番号を用意しています。

[Square Connect API Documentation](https://docs.connect.squareup.com/articles/using-sandbox)より。

|ブランド|カード番号|
|-------|-------|
|Visa|4532-7597-3454-5858|
|MasterCard|5409-8899-4417-9029|
|Discover|6011-0336-2137-9697|
|Diners Club|3600-4244-8464-08|
|JCB|3566-0057-3488-0650|
|American Express|3712-6346-2726-550|
|China UnionPay|6222-5201-1913-8184|

CVV（セキュリティコード）、有効期限、郵便番号は任意で指定できます。ただし、以下の条件によってわざとエラーを起こせます。

- CVVに911を指定するとCard CVV incorrectエラーになります。
- 郵便番号に99999を指定するとCard postal code incorrectエラーになります。
- 有効期限を 01/40 （月年の順）に指定するとCard expiration date incorrectエラーになります。
- 決済金額を403にするとCard declinedエラーになります。

さらに card_nonce と customer_card_id を下記の辺りに指定することで、それぞれエラーを起こせます。

|card_nonce|customer_card_id|エラー|
|----------|----------|----------|
|fake-card-nonce-ok|fake-customer-card-id-ok|処理成功します|
|fake-card-nonce-rejected-cvv|fake-customer-card-id-rejected-cvv|Card CVV incorrect|
|fake-card-nonce-rejected-postalcode|fake-customer-card-id-rejected-postalcode|Card postal code incorrect|
|fake-card-nonce-rejected-expiration|fake-customer-card-id-rejected-expiration|Card expiration date incorrect|
|fake-card-nonce-declined|fake-customer-card-id-declined|Card declined|
|fake-card-nonce-already-used|指定なし|Card nonce already used|


これらはサンドボックス環境で使える特別な条件になりますので注意してください。テスト時に使って適切なエラー処理の実装に役立ててください。
Square APIのv1とv2、どちらを使うべきか

SquareではAPIが2つ存在します。v1とv2と呼ばれているのですが、双方に互換性はありません。開発者としてどちらのAPIを使っていくべきなのか、[Square Connect API Documentation](https://docs.connect.squareup.com/articles/connect-v2-released-2016-03?q=v1%20v2%20difference)に書かれていますので簡単に紹介します。

## v1を使って作られたアプリケーションはv2に載せ替えるべき？

いえ、それはありません。現状、v1で提供されている機能すべてをv2で提供していません。アプリケーションは必要に応じてv1とv2、両方を使うことができます。

## v1とv2の共通機能はありますか？

### パラメータフォーマットは同じです

GETまたはDELETEの場合はクエリストリングを使います。POST/PUTの場合はボディを使ってリクエストを送信します。

### ヘッダーは共通です

すべてのリクエストは下記のリクエストヘッダーを持っています。

```
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
Accept: application/json
```

### OAuth APIエンドポイント

OAuth APIのエンドポイントは変更していません。

## v1とv2で変更した場所はありますか？

### 日付フォーマット

v2はすべての日付フォーマットがRFC 3339になりました。v1はISO 8601です。

### ページネーション

v2ではcursorパラメータがレスポンスに含まれます。これが次のデータにアクセスするためのURLになります。v1ではLinkというヘッダーがレスポンスに含まれています。

### 並び順

v2では日付毎（新しい順）に並んで返ってきます。また、sort_orderを使って並び順を変更できます。v1では古いもの順に並んで返ってきます。並び替える際のキーはorderです。

### エラーフォーマット

v2ではレスポンスボディにerrorsがあり、そこにエラー情報が入ってきます。つまり複数のエラーがあった場合は配列で返ってきます。v1の場合は一つのエラーのみ返るようになっています。

----

v1とv2ではレスポンスの形式も異なりますので、必要な情報が取れるかを双方で確認して使うのが良いかと思います。個人的な印象としては v2 のが洗練されているように見えますが、v1のが結果の項目が多いように見えます。
Sublime Text3 で「View -> Word Wrap」をショートカットに割り当てる

キーバインディングに以下を追加する。

```
{ "keys": ["ctrl+w","ctrl+r"], "command": "toggle_setting", "args": {"setting": "word_wrap"}}
```

すると、<kbd>ctrl+w+r</kbd>で「Word Wrap」の切り替えができるようになる。
ちなみに<kbd>w</kbd>と<kbd>r</kbd>は「Wrap」の頭から取ってきたけど、うっかりするとウィンドウ閉じたりしちゃうのでもっとマシな割り当てにしたほうがいいかもしれない。

地味に英字キー2個同時押しショートカットのやり方なども分からずググったので、メモとして残しておく。