OmniAICreator/Qiita-1.07M huggingface dataset:
FirefoxでPDFを閲覧し、拡大・縮小表示した後にデフォルトに状態を戻す話

# この記事は？
- FirefoxでPDFのファイルを閲覧することはよくある。
- 拡大・縮小表示した後にちょっとした不具合？不都合？にあたった。
- 自分用のメモもかねて記事投稿しておく。

# 事の発端
## PDFを閲覧する。
よくあることである。
![firefoxpdf-01.PNG](https://qiita-image-store.s3.amazonaws.com/0/129674/59fc9a49-5368-9c1e-43d3-5ff93a7196f8.png)

## [Ctrl] + [+] で拡大…
[Ctrl] + [+] はWEBブラウザでの拡大である。よく使われるショートカットである。
![firefoxpdf-02.PNG](https://qiita-image-store.s3.amazonaws.com/0/129674/30dd477d-67e1-f1f4-0135-0facc155f07e.png)

## [Ctrl] + [-] で縮小… あれ?
[Ctrl] + [-] はWEBブラウザでの縮小である。これまたよく使われるショートカットである。
しかしお分かりいただけるだろうか、キーボードショートカットで拡大・縮小した場合、上部のツールヘッダが縮小されないのである。
しかもこれ、どこかに設定を保持しているようで、ブラウザを閉じても直らないのです。
![firefoxpdf-03.PNG](https://qiita-image-store.s3.amazonaws.com/0/129674/1b6edbf1-812e-a42f-e647-c240545ac245.png)


# 直し方
当然といえば当然なのかもしれませんが、WEBページ閲覧時の「表示サイズを100%の状態にリセットする」キーボードショートカットである
[Ctrl] + [0] を押下することで直せます。

#おまけ：その他ショートカットキー
ショートカットキーそのものは[Firefoxキーボードショートカット](https://support.mozilla.org/ja/kb/keyboard-shortcuts-perform-firefox-tasks-quickly#w_pdf-ceccckac)
としてmozilla supportにちゃんと載っています。
[Ctrl] + [0]は「現在のページ」の箇所では「ズームをリセット」、PDF ビューアの箇所では「自動ズーム」と書かれていますね。
[Ctrl] + [Alt] + [p] のプレゼンテーションモード切り替えや、[h] での手のひらツールの切り替えあたりは覚えておくと便利そうです。
なお、ここには書かれていませんが、
　[Ctrl] + [↑]　：　最初のページへ移動
　[Ctrl] + [↓]　：　最後のページへ移動
も使えます。

* * *
以上
go-xorm/core のログレベルの定義がいつの間にか破壊的に変わっていた(>=v0.5.2)

掲題の通りです。
go-xorm/core, go-xorm/xorm をアップデートしていたら、logger のテストが突然落ちて驚いた。今更v0.4.5 を使っていたというのもあるが……
  
https://github.com/go-xorm/core/commit/42bacbe76fb75f773f7aab4e7644377ef9315e82  

ログレベルの値がどう変わったかを、当該部分を実行してみてみる。
https://play.golang.org/p/pYgmmeRwBK

```go
package main

import (
	"fmt"
)

type LogLevel int

const (
	// log level definitions of go-xorm/xorm < v0.5.2
	// !nashtsai! following level also match syslog.Priority value
	LOG_v4_UNKNOWN LogLevel = iota - 2
	LOG_v4_OFF     LogLevel = iota - 1
	LOG_v4_ERR     LogLevel = iota + 3
	LOG_v4_WARNING
	LOG_v4_INFO LogLevel = iota + 6
	LOG_v4_DEBUG
)

const (
	// log level definitions of go-xorm/xorm >= v0.5.2
	LOG_v5_DEBUG LogLevel = iota
	LOG_v5_INFO
	LOG_v5_WARNING
	LOG_v5_ERR
	LOG_v5_OFF
	LOG_v5_UNKNOWN
)

func main() {
	fmt.Println("v4_UNKNOWN ", LOG_v4_UNKNOWN)
	fmt.Println("v4_OFF ", LOG_v4_OFF)
	fmt.Println("v4_ERR ", LOG_v4_ERR)
	fmt.Println("v4_WARNING ", LOG_v4_WARNING)
	fmt.Println("v4_INFO", LOG_v4_INFO)
	fmt.Println("v4_DEBUG", LOG_v4_DEBUG)

	fmt.Println("v5_UNKNOWN ", LOG_v5_UNKNOWN)
	fmt.Println("v5_OFF ", LOG_v5_OFF)
	fmt.Println("v5_ERR ", LOG_v5_ERR)
	fmt.Println("v5_WARNING ", LOG_v5_WARNING)
	fmt.Println("v5_INFO", LOG_v5_INFO)
	fmt.Println("v5_DEBUG", LOG_v5_DEBUG)
}

```

```
v4_UNKNOWN  -2
v4_OFF  0
v4_ERR  5
v4_WARNING  6
v4_INFO 10
v4_DEBUG 11
v5_UNKNOWN  5
v5_OFF  4
v5_ERR  3
v5_WARNING  2
v5_INFO 1
v5_DEBUG 0
```

`UNKNOWN < OFF < ERR < WARNING < INFO < DEBUG`
`UNKNOWN > OFF > ERR > WARNING > INFO > DEBUG`

と、数値の大小関係が逆になってる。
大小関係を使ってた部分が落ちてたので、なるほどこういうこともあるのだなと。
Google Sign-In for iOS ケーススタディ

# はじめに
iOSにおいて、GoogleのOAuth認証は [Google Sign-In for iOS](https://developers.google.com/identity/sign-in/ios/) というSDKを用いれば簡単に実現できます。
ただ、認証情報としてMobileSafariのキャッシュを用いている関係で状態管理が複雑なうえに、公式のドキュメントに書かれている情報は手順くらいで、「こういう時にこういう値が返る」などの情報がありません。

そこで本記事では、「こういう仕様にしたいんだけど、どうすれば良いんだろう」「外部ブラウザに引っ張られないで、一貫したUXにしたい」などという場合に考えられるケースと、その解決策を書いていきます。

主にセキュリティ面で、Googleが推奨している実装にはなっていない可能性があります。
また、サンプルコードはSwiftではなくObjective-Cで書いています。
ご了承ください。

# ケース1: AppDelegate.m 以外の箇所にGIDSignInDelegateのメソッドが書きたい
諦めましょう。まずコンパイラに怒られます。
詳しくは[こちら](http://stackoverflow.com/questions/36296798/google-sign-in-via-firebase-gidsignindelegate-does-not-conform-to-viewcontrolle)をご参照ください。

で、例えばViewControllerでサインイン後の処理がしたい場合は、下記のようにGIDSignInDelegateのメソッドからNotificationを飛ばすのが良いでしょう。
(@"MyNotification" などは定数化してあげましょう)

```objc:AppDelegate.m
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error
{
    // 取得したユーザーのプロフィールや認証情報など、通知を受け取る側に渡す値を生成する
    NSDictionary * info = @{
                           @"email": user.profile.email,
                           @"error": error
                           };

    // Notificationを飛ばす
    NSNotification * n = [NSNotification notificationWithName:@"MyNotification" object:self userInfo:info];
    [[NSNotificationCenter defaultCenter] postNotification:n];
}
```

```objc:MyViewController.m
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // Notificationを登録する
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(foo:) name:@"MyNotification" object:nil];
}

- (void)viewWillDisappear:(BOOL)animated
{
    // Notificationの登録を解除する
    [[NSNotificationCenter defaultCenter removeObserver:self name:@"MyNotification" object:nil];

    [super viewWillDisappear:animated];
}

- (void)foo:(NSNotification *)n
{
    // サインインが実行された後、Notificationを受け取る処理
    // n.userInfo で通知と一緒に渡された値を取り出すことができる
    [n.userInfo objectForKey:@"email"];
}
```

# ケース2: 余計な権限を要求してくる
Google Sign-Inは、デフォルトで「メールアドレスの表示」「ユーザーのプロフィール情報の表示」の2つの権限を要求してきます。
![default_scope.png](https://qiita-image-store.s3.amazonaws.com/0/83524/d22bb26d-c8f5-7dad-806a-333080fd6630.png)
スコープの情報は[こちらの公式ドキュメント](https://developers.google.com/identity/protocols/googlescopes#google_sign-in)のprofileとemailです。

GIDSignInインスタンスのプロパティ`shouldFetchBasicProfile`をNOに設定すると、これらの権限の要求がなくなります。

YouTube Data APIを使用するためYouTubeのチャンネルの情報しか使用しないなど、これらのスコープが必要ないケースが出てくると思います。
以下にGoogleアカウントに紐づいているYouTubeの情報しか権限を要求させないための実装を示します。

```objc
GIDSignIn * signIn = [GIDSignIn sharedInstance];
signIn.scopes = @[
                  @"https://www.googleapis.com/auth/youtube.upload",
                  @"https://www.googleapis.com/auth/youtube.readonly"
                  ];
signIn.shouldFetchBasicProfile = NO;
[signIn signIn];
```

# おわりに
・・・もっといろいろあった気がしますが、今思い出せるのはこれくらいです。
何かありましたら随時更新していきます。まだまだ検証したいところもありますね。
LogstashでMySQLとElasticsearchを同期する

# 本エントリの内容

- Logstashを使ってMySQLとElasticsearch（以下ES）を同期します
- 仕事ではインフラ系のツールを触らないので変なことを書いているかもしれません

# 準備

- 各種ダウンロードについては省略します
- 確認した環境はES v2.4.0, Logstash v2.4.0, mysql v5.7.12, MacOSX v10.11.6 です
- ESとlogstashはv2のあと3と4を飛ばして現在v5となってますが、（たぶん）それほど変わりはないと思います。
- Logstashプラグイン logstash-input-jdbc が必要です
- 使用するRDBに対応するjdbc-connectorもインストールします

今回はMySQLなので下記サイトからjdbc-connectorをダウンロードします。
アクセスするとログインかサインアップを求められますが画面下部の「No thanks, just start my download.」リンクから普通にダウンロード可能です。

https://dev.mysql.com/downloads/file/?id=462850

ダウンロードしたらlogstashフォルダの直下に入れておきます。

## テーブル構造のポイント

ESに同期する対象レコードは、logstash側で管理する最終同期時刻とDate型レコードの指定カラムの比較で決定します。つまりupdated_atのようなカラムが必要になります。

また、RDBのレコード削除を検知することはできません。そのためdeleted_atなど論理削除を表すカラムの値ごとESに同期し、その値を見て削除されたデータかどうか判別する必要があります。

# logstash設定ファイル

``` logstash.conf
input {
  jdbc {
    jdbc_driver_library => "mysql-connector-java-5.1.39/mysql-connector-java-5.1.39-bin.jar"
    jdbc_driver_class => "com.mysql.jdbc.Driver"
    jdbc_connection_string => "jdbc:mysql://localhost:3306/db_name"
    jdbc_user => "mysql_user"
    jdbc_password => "mysql_password"
    statement => "select * from books where updated_at > :sql_last_run"
    type => "books"
    tracking_column => updated_at
    jdbc_default_timezone => Japan
  }
}

output {
  elasticsearch {
    hosts => ["localhost"]
    index => "%{type}"
	document_id => "%{type}_%{id}"
  }
}
```

tracking_columnに同期のタイムスタンプとして使用するDate型カラムを指定します。 
statementには同期するデータを抽出するSQLクエリを記述します。別ファイルに書く場合は
```
statement_filepath => "sql/book.sql"
```
のように書くことが可能です。重要なのはWhere句に`where updated_at > :sql_last_run`を指定することで、:sql_last_run にはlogstash側で管理する最終同期時刻がセットされます。

その他の設定についてはドキュメントを確認してください。例えばscheduleを設定すると同期のクーロン実行が可能になります。
https://www.elastic.co/guide/en/logstash/current/plugins-inputs-jdbc.html

# 同期を実行する

logstashのフォルダ構成を確認します。といっても[公式](https://www.elastic.co/downloads/logstash)からダウンロードしたlogstashフォルダにjdbc-connectorと設定ファイルを入れるだけです。

- :file_folder: logstash-2.4.0　　 // ダウンロードしたlogstashフォルダ
    - :file_folder: mysql-connector-java-5.1.39　　 // jdbc-connector
    - :page_facing_up: logstash.conf
    - その他もともと入ってたファイル(binフォルダなど)

このディレクトリで下記コマンドを実行すると同期が行われます。

```
bin/logstash -f logstash.conf
```

## 同期時刻をクリアしたい場合

logstash側で管理している最終同期時刻は**.logstash_jdbc_last_run**というファイル名でMacOSXの場合はホームディレクトリにあります（環境によって異なると思います）。

同期時刻をクリアしたい場合はこのファイルを削除するだけでOKです。
最低限しておくといいgitconfigの設定

最低限しておくといいgitconfig の設定メモ。
※Windows向け
## user.name , user.email
ユーザー名とメールアドレスは、Githubのusernameとmailaddressとそろえるといい。

    git config --global user.name "{ユーザー名}"
    git config --global user.email "{メールアドレス}"
## core.ignorecase
falseにすると、ファイルの大文字・小文字を区別して認識する。

    git config --global core.ignorecase false
## core.quotepath
falseにすると、git statusで変更ファイル一覧を表示するときに、
日本語のファイル名が文字化けしないでちゃんと表示される。

    git config --global core.quotepath false
## core.safecrlf
trueにすると、改行コードが混在している場合は変換しないというオプション。

    git config --global core.safecrlf true
## core.autocrlf
falseにすると、コミット・チェックアウト時に改行コードの変換を行わない。

    git config --global core.autocrlf false
## core.editor
コミットするときにメッセージを編集する際に使用するエディタの設定。

    git config --global core.editor 'C:\Program Files\Hidemaru\Hidemaru.exe' //cu8
エディタの設定は以下の記事が大変参考になった。
[Git for Windows で日本語を使いたい](http://qiita.com/kumazo/items/2169e1ee7be278f82b94#%E5%A4%96%E9%83%A8%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF%E3%81%AE%E8%A8%AD%E5%AE%9A)
## push.default
simpleに設定しておくと安全。
カレントブランチと同名のリモートブランチが存在する場合のみ、カレントブランチのpushが行われる。

    git config --global push.default simple
## credential.helper
Githubからソースを取得するのに、ユーザー名とパスワードを聞かれるが、
頻度が結構多いのでキャッシュしておく設定。

    git config --global credential.helper wincred
VSCodeのショートカットなどの覚書

# React.js環境構築（未完）

VSCodeのショートカットなど思い出すためにメモ投稿しておきます。

## VSCodeの導入

- VSCodeをインストール
- View Command Palette...(`⇧⌘P` or `F1`) -> `Configure Language` -> "ja" を "en" に変更保存して再起動すると英語化
- View -> Extensions(`⇧⌘X`) -> @sort:installs vim でVim拡張導入

## VSCodeの操作や設定など

- markdownを.mdで保存
- `⇧⌘V`で markdown のプレビューを新規タブで開く、`⌘K V`で縦分割プレビュー

- Extensionsはサイドバー(`⌘B`)で開かれているので`⌘B`で閉じることができる
  - [The Basics of Visual Studio Code](https://code.visualstudio.com/docs/editor/codebasics)
- `⇧⌘P` -> `Preferences: Open Keyboard Shortcuts` でキーバインド編集
  - `keybindings.json`に追加すればOK
  - [Customizing Shortcuts](https://code.visualstudio.com/docs/customization/keybindings#_customizing-shortcuts)
- タブグループは Left(`⌘1`), Center(`⌘2`), Right(`⌘3`)に分かれる
- `⇧⌘P` -> `Preferences: Open User Settings`で`"editor.renderWhitespace": "all"`を追加して空白文字表示
- ``⌃` `` もしくは `⇧⌘P` -> `View: Toogle Integrated Terminal `でターミナルが開ける
  - [Integrated Terminal](https://code.visualstudio.com/docs/editor/integrated-terminal)
- ターミナルが開かれる下部は Panel と呼ばれる場所で`⌘J`で表示/非表示をトグルできる

### Windows環境のVSCodeでVimの`Ctrl+K`を無効にする
- `Ctrl + Shift + P` -> `Preferences: Open Keyboard Shortcuts`
- `Ctrl + 1` で `Default Keybindings` に移動して[]の中身を全選択コピー
- `Ctrl + 2` で `keybindings.json` に移動して[]の中身を貼り付ける
- `keybindings.json`の`extension.vim_ctrl+k`を`-`に修正して保存
- これで VSCode の `Ctrl + K`系統が使えるようになる
- 以降の`Open Keyboard Shortcuts`は`Ctrl+K Ctrl+S`でOK

## Homebrew導入

- 導入済みだったので`brew update`実行して終了
- と思いきやEl Capitan移行によりうまくいかなかったので対応
- [Homebrewを久々にupdateしたら出来なかった時の対処法](http://qiita.com/takezoux2/items/aa2a5f0bef19cd0d8508)

## node.jsの導入

- `brew install nodenv`
- [nodenvを使ってMacにNode.jsの環境を構築する](http://qiita.com/1000ch/items/41ea7caffe8c42c5211c)
- [node.js公式サイト](https://nodejs.org/ja/download/)で最新バージョンを確認
- `~/.zshrc`(`~/.bash_profile`)に以下を記述する必要あり
 - [macにnodenvをbrewで入れ、nodeをバージョン管理する](https://joppot.info/2016/10/17/3210)

```~/.zshrc1
export NODENV_ROOT=/usr/local/var/nodenv
eval "$(nodenv init -)"
```

- `nodenv install 6.9.1`で最新版をインストール
- `nodenv rehash`
- `nodenv global 6.9.1`
- `node -v` でインストールしたバージョンが表示されたら成功
- npmもインストール済み（`npm`コマンド）

## gulpの導入

- ここから適当な新規プロジェクトのディレクトリに切り替えた
- `sudo npm install -g gulp`
- `sudo npm install -g gulp-cli`

## 参考
- [ブラウザで実行するjsの開発環境構築(主にReact.js)](http://qiita.com/_ha1f/items/af2cb29983456a8c8576)
プログラミングを適したPC環境を検討してみた

#CPU
高性能なほど処理スピードが速い
最低でも2.5GHz、3GHzあるとなおよい
•Q：クアッドコア
•S：省エネ
•T：Ｓより省エネ
•M：モバイル用（ノートや画面一体型等）
•U：モバイルの省エネ


#メモリ
作業スペース
メモリ数が多いと並列処理が可能
4GB以上が望ましい、アプリケーションの起動だけでメモリを喰うので大目に積んでおく
※AndroidStudioの起動のみで2〜3GBを利用するので、Androidアプリを作成する場合は8GB以上が望ましい。

#HDD
データ保存スペース
それほど容量は必要ではない。
SSDによる高速化を考えることが望ましい

#参考
http://eng-entrance.com/programming_pc
http://www.sejuku.net/blog/11093


#PCの性能をテストする
ベンチマークソフトのまとめ
http://bto-pc.jp/btopc-com/repair/pc-maniac-tool-10.html
Ionic 2でサポートされているジェスチャーまとめ

[Ionic 2](http://ionic.io/2)には`tap `、`press `、`pan `、`swipe `、`rotate `、`pinch `といったアプリ操作に欠かせないジェスチャーが用意されています。ありがたし:relaxed:

[Gestures | Ionic Component Documentation](http://ionicframework.com/docs/v2/components/#gestures)

ジェスチャーはボタンなどのUIに設定することが多いと思いますが、そのUIに指を乗せてスワイプしてもスクロールできないショッキングな出来事に遭遇します。ジェスチャーの挙動的には正しいかもしれないですが、スクロールして見ていく画面では操作しづらくなってしまい致命的です:confounded:。

とは言えユーザー入力はなくせないので、別のイベントで代用すると回避できるものもあります。

備忘録も兼ねてまとめておきます。

# `tap`（タップ）

```
<button (tap)="handler()"></button>
```

UIに指を置いた状態でもスクロールさせたい場合は、`click`に置換えます。

```
<button (click)="handler()"></button>
```

# `press`（長押し）

```
<button (press)="handler()"></button>
```

# `pan`（ドラッグ）

```
<button (pan)="handler()"></button>
```

# `rotate`（回転）

```
<button (rotate)="handler()"></button>
```

# `swipe`（スワイプ）

```
<button (swipe)="handler()"></button>
```

# `pinch`(ピンチ)

```
<button (pinch)="handler()"></button>
```

# なかなか代用できませんでした。。

即席で代用できたのは`tap`→`press`だけでした。Ionic 2で実装するときは、ユーザー入力とスクロールがバッティングしないように気をつけたほうがいいですね。長押しは`mousedown`から数秒たったら適応するなどはできそうですが:sweat:

他にいい方法があったらぜひご教示お願いします！
Oven を使って CakePHP3 をワンクリックでインストールする

## まえがき

CakePHP では初心者の方を歓迎しています。 CakePHP の [README.md](https://github.com/cakephp/cakephp/blob/master/README.md) に次のように書いてあるのをご存知でしたか？

> Our primary goal is to provide a structured framework that enables PHP users at all levels to rapidly develop robust web applications, without any loss to flexibility.

Google 翻訳にかけるとこんな和訳になります。

> 私たちの第一の目標は、あらゆるレベルの PHP ユーザーが、柔軟性を損なうことなく堅牢な Web アプリケーションを迅速に開発できる構造化フレームワークを提供することです。

私たちは、 PHP を覚えたての初心者でさえ手早くアプリケーションを開発できる、そんなフレームワークを目指しています。

ですが、初心者の方にとっては、そもそも最初のインストール作業が険しいハードルです。せっかく新しいことに挑戦しようと思ったのに、よくわからない別の何かが必要だとか言われて、よくわからないコマンドを打たされて、ちゃんと手順通りにしたはずなのによくわからないエラーに遭遇してしまって、検索しても英語のサイトばかりがヒットして、質問すれば「検索したんですか？」と怒られて、そうこうしているうちに挑戦しようとしていた意志もくじけてしまいがちです。

CakePHP では、この最初の難関をなるべく簡単にしようという取り組みが進められています。それが今回リリースされた [Oven](https://github.com/CakeDC/oven) です。

## インストール

まずは [CakeDC のリポジトリ](https://github.com/CakeDC/oven/releases) から Oven の zip ファイルをダウンロードして解凍してください。 CakeDC というのは CakePHP の創始者である Larry Masters 氏が設立したアメリカの企業です。

![download.png](https://qiita-image-store.s3.amazonaws.com/0/107118/716fa429-da2b-f24d-944c-811d070a717d.png)

解凍すると oven.php というファイルが含まれていますので、それをドキュメントルートに置いたら、さっそくブラウザからアクセスしてみましょう。

![oven.png](https://qiita-image-store.s3.amazonaws.com/0/107118/61d48d6a-0a5a-ac60-87e5-767eb9001022.png)
こんな画面が表示されるはずです。

`Click to install CakePHP` という説明の上にボタンが見えますね。このボタンは [雛鳥が空を見上げている絵](https://twitter.com/reinink/status/819324275647807488) ――ではなくて、オーブンのつまみ部分だそうです。

クリックするとつまみがぐるりと回ってインストールが始まります。

![knob.png](https://qiita-image-store.s3.amazonaws.com/0/107118/a1a86de2-a0ad-c1f3-ba73-e40098d306ce.png)

ずん、ずん、ずん、とケーキが積みあがっていきます。

![1.png](https://qiita-image-store.s3.amazonaws.com/0/107118/790f120e-070e-0915-dae5-8e1ceb960c32.png)

![2.png](https://qiita-image-store.s3.amazonaws.com/0/107118/b91abb76-536b-c407-3a10-e37fca500385.png)

![3.png](https://qiita-image-store.s3.amazonaws.com/0/107118/8165cda4-a383-4a85-911a-abdd94053d37.png)

なお、この処理には数分かかると思いますので気長にお待ちください。

![finish.png](https://qiita-image-store.s3.amazonaws.com/0/107118/164cc8b9-c48c-3e1f-97e8-e8bcef991dc7.png)

最後にはてっぺんにチェリーが乗ってインストールが完了しました。 `GO TO YOUR CAKEPHP APP` というボタンをクリックするとホームに飛びます。

![home.png](https://qiita-image-store.s3.amazonaws.com/0/107118/43b04f5c-2e7d-fc8c-961a-42cf57b8ec21.png)

簡単でしょう？

試しに [ロリポップ](https://lolipop.jp/) のライトプラン（250円／月）のサーバーで試したところ、3分でインストールができました。これなら FTP で全ファイルをアップロードするより、ずっと快適ですね。

## あとがき

Oven はこれが最初のリリースですので、まだいくつかの制限があります。まず、インストール先のディレクトリが app で固定になっています。環境によってはパーミションなど追加の設定が必要になるかもしれません。また intl などの PHP 拡張がそろっていないとインストールに失敗してしまいます。

![no-intl.png](https://qiita-image-store.s3.amazonaws.com/0/107118/d1ec3682-cbe2-7e09-6a6a-168dc7e65d6b.png)

このエラーになってしまった方は、 php.ini を開いて、対応する拡張のコメントアウトが外れていることを確認してください。下は Windows の例です。

```ini
extension=php_intl.dll
```

その他の OS では、場合によっては intl のインストールが必要になってしまって、ワンクリックでインストールという訳にはいかなくなってしまうのですが、これらの制限も次以降のバージョンで改善が予定されていますので、ぜひお見逃しなく！
cygwin で 日本語 markdown を textile に変換してクリップボードにコピーする

# TL; DR
- pandoc, nkf をインストールして、下記のようにパイプでつなげる
- clip コマンドは Shift-JIS じゃないと文字化けするので `nkf -s` を挟むといい感じになる
- `/dev/clipboard` を使う方法もあるが、cat にパイプする or 一度ファイルに出力する、といった一手間が必要になる

```
$ pandoc -s -S markdown-file.md -t textile | nkf -s | clip

※ nkf を使わない方法
$ pandoc -s -S markdown-file.md -t textile | cat > /dev/clipboard

※ 一度ファイルに出力してからクリップボードにコピーする方法
$ pandoc -s -S markdown-file.md -t textile -o output.textile
$ output.textile > /dev/clipboard
```

# サンプル

```
$ cat test.md
# 見出し
- hoge
- fuga

# 見出し
## 見出し2
- hoge
    - hogehoge
- hoge
    - hogehoge

## 見出し2
- hoge

$ pandoc -s -S test.md -t textile | nkf -s | clip

※ クリップボードにコピーされたデータ
h1(#見出し). 見出し

* hoge
* fuga

h1(#見出し-1). 見出し

h2(#見出し2). 見出し2

* hoge
** hogehoge
* hoge
** hogehoge

h2(#見出し2-1). 見出し2

* hoge

```

# 動作確認環境

```
$ pandoc -v
pandoc.exe 1.19.1
Compiled with pandoc-types 1.17.0.4, texmath 0.9, highlighting-kate 0.6.3
Default user data directory: C:\Users\user-name\AppData\Roaming\pandoc
Copyright (C) 2006-2016 John MacFarlane
Web:  http://pandoc.org
This is free software; see the source for copying conditions.
There is no warranty, not even for merchantability or fitness
for a particular purpose.

$ nkf -v
Network Kanji Filter Version 2.1.4 (2015-12-12)
Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa).
Copyright (C) 1996-2015, The nkf Project.

$ which clip
/cygdrive/c/WINDOWS/system32/clip
```

# 所感
- 普段 markdown でメモとってて、社内の Redmine に投稿する時に便利

EOF
UnityでHTC Viveのダッシュボードの有効化/無効化

HTC Viveで何か作ってるときにメニューボダンを押すとダッシュボードが出てきます。
ゲームしてる最中にダッシュボードが出て邪魔なので表示させない方法を調べたら

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/79067/42d3f770-8de0-2051-e1c4-f88e0e1e2e30.png)

SteamVRの設定で【VRダッシュボードを有効化】のチェックを外すと出てこなくなります。
自分ひとりならここのチェックを外すでよいのですが、アプリの説明にここのチェックを外してくださいは不親切なのでスクリプトでなんとかならないか調べました。

ということで、こんな感じ

```csharp
using UnityEngine;

/// <summary>
/// HTC ViveのDashbordをdisableにする
/// </summary>
public class DashbordDisable : MonoBehaviour
{
    bool dashbordFlag;

    void Start()
    {
        dashbordFlag = GetDashboodEnabled();
        if (dashbordFlag)
        {
            SetDashboodEanbled(false);
        }
    }

    public void OnApplicationQuit()
    {
        if(dashbordFlag != GetDashboodEnabled())
        {
            SetDashboodEanbled(true);
        }
    }

    bool GetDashboodEnabled()
    {
        Valve.VR.EVRSettingsError er = new Valve.VR.EVRSettingsError();
        return Valve.VR.OpenVR.Settings.GetBool(Valve.VR.OpenVR.k_pch_Dashboard_Section, Valve.VR.OpenVR.k_pch_Dashboard_EnableDashboard_Bool, ref er);
    }

    void SetDashboodEanbled(bool flag)
    {
        Valve.VR.EVRSettingsError er = new Valve.VR.EVRSettingsError();
        Valve.VR.OpenVR.Settings.SetBool(
            Valve.VR.OpenVR.k_pch_Dashboard_Section, 
            Valve.VR.OpenVR.k_pch_Dashboard_EnableDashboard_Bool,
            flag, ref er
            );
        Valve.VR.OpenVR.Settings.Sync(false, ref er);
    }

}
```

コンポーネントを適当に貼り付ければ動きます
JavaScripthonをWindowsで動かそうとして諦めた話。

JavaScripthonはPython3のコードをjavascript(ES6)のコードにトランスパイルしてくれるらしいツールです。
Github：https://github.com/azazel75/metapensiero.pj

SourceMapにも対応していて、Pythonコードのままデバッグ出来るとのことだったので、
面白そうだと思って試そうと思って、結局あきらめた話を書きます。
（本当は「試してみた」の記事にしたかったのですが。。。）

結論としては、Windowsでやるなということになるのでしょうか？
僕はMac持ってないにわかなので実際はわかりません。

下記参考
http://www.moongift.jp/2016/05/javascripthon-pythonで書いてes6のコードを生成/

# WindowsへのInstallで躓いた。

```bash
pip install javascripthon
```
で、「えいっ」てやると、依存している、[dukpy](https://github.com/amol-/dukpy)のインストールでこけました。
vcvarsall.batが無いと。
なにやらVisual Studio Community 2015を入れろということだったみたいです。
http://thinkami.hatenablog.com/entry/2016/06/06/225903

入れてもう一回「えいっ」てやると、やっぱり落ちました。
unistd.hが無いと。
これunix系の奴らしくpip installではWindowsにInstallできないってことで、諦めます。

# Pythonから実行して躓いた。

Githubからクローンして直接実行することにしました。
dukpyはjs動かすためのエンジンらしいので、トランスパイルだけなら実は必要ないんじゃないかというカンで直接実行してみようと思いました。

コード読む感じだと、たぶん必要なさげなので`src/metapensiero/pj/api.py`のdukpyのimportをコメントアウトして実行します。

```bash
python -m metapensiero.pj source.py
```

「えいっ」ってやると落ちました。UnicodeDecodeError。
落ちた原因はこれです。

```py3:src/metapensiero/pj/api.py
src_text = open(src_filename).readlines()
```

日本語コメントやらで死にます。
一旦書き換えてしまいます。

```py3
src_text = open(src_filename, encoding='utf-8').readlines()
```

また落ちた。次の原因はこれです。

```py3:src/metapensiero/pj/processor/util.py
def parent_of(path):
    return '/'.join(path.rstrip('/').split('/')[:-1])
```
Windowsのバックスラッシュ区切りが考慮されてませんね。
とりあえず、僕はWindowsで動かしたいので、一旦バックスラッシュに変えてしまいます。  

```py3
def parent_of(path):
    return '\\'.join(path.rstrip('\\').split('\\')[:-1])
```

# 動いたような気がするけど。。。

```bash
python -m metapensiero.pj source.py
```

で何やら.jsファイルと.js.mapファイルができました。わーい。

ですが、ちょっと踏み込んだPythonはトランスパイルできないみたいですね。
たとえば、

```py3
for i, x in enumerate(list1):
    # 処理
```
とか、変数2つのループはダメらしく、エラーになります。

もう諦めよう。まずMac買おう。妻に相談しよう。
jQueryでsubmitする方法


★ボタンをクリックしたらsubmitする

```Javascript
$('#btn').click(function() {
   $('#form1').submit();
});
```

```html
<form method="post" name="form1" id="form1">
    <input type="text" name="txt" value="" />
    <input type="submit" name="btn" id="btn" value="submit">
</form>
```

【参考】
http://raining.bear-life.com/jquery/jquery%E3%81%A7submit%EF%BC%88%E3%82%B5%E3%83%96%E3%83%9F%E3%83%83%E3%83%88%EF%BC%89%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95

※aタグにクリックイベントを付与する場合は以下のようにする

```javascript
<a href="javascript:void(0)" onclick="javascript 関数(); return false;">リンク</a>
```

【参考】
http://www.webantena.net/javascriptjquery/a-href-javascript-void0/
WebSocket(ws://)の接続がうまくいかない時に試すこと

#結論
SSL証明書使ってwss://にすればたいていうまくいく

#なんでよ
どっか（ex. proxyとか）がレスポンスのConnectionヘッダを上書きしてしまうため
Upgradeができないことが大抵の原因だったりします（実体験）

WebSocketのHandshake時、レスポンスヘッダが
> Connection: upgrade
> Upgrade: WebSocket

とならないといけないのに
> Connection: **keep-alive**
> Upgrade: WebSocket

となってしまい、Upgradeができないことが原因です。
Proxyを経由する接続の場合に多い現象です。

wssにすることでConnectionヘッダーの上書きが抑止されることが多いため
まずは接続できないという人は試してみると幸せになれるかもしれません。
（重要度：低）iPhoneと緊急速報における、ちょっとした留意事項

iPhoneにおいて、災害時の緊急速報はスピーカーより大音量で鳴り響く。たとえイヤホンをしていたとしてもだ。

例えばその時、音楽を聴いていたとする。

iPhoneのスピーカーからは大音量の緊急速報のアラームと今聴いている音楽が鳴り響く（ついさっき体験済み）。

エロい動画を見ていると大惨事になりそうなので書き留めておく。
ショートカットを活用しよう - 10 - Win + 矢印キー

# <kbd><kbd>Win</kbd> + <kbd>↑←↓→</kbd></kbd> の効果
* <kbd><kbd>Win</kbd></kbd>はWindowsのロゴマークのキーのことです。（大抵のキーボード配列で左下の<kbd><kbd>Ctrl</kbd></kbd>のとなりにありますよね。）

現在フォーカスのあるウィンドウに対して次のようにサイズ変更します。

<kbd><kbd>Win</kbd> + <kbd>↑</kbd></kbd>：最大化
<kbd><kbd>Win</kbd> + <kbd>↓</kbd></kbd>：最小化（最大化時は元のサイズに戻る）
<kbd><kbd>Win</kbd> + <kbd>←</kbd></kbd>：画面の左半分の範囲で最大化（画面の右半分の範囲で最大化している場合、元のサイズに戻る）
<kbd><kbd>Win</kbd> + <kbd>→</kbd></kbd>：画面の右半分の範囲で最大化（画面の右半分の範囲で最大化している場合、元のサイズに戻る）

また、<kbd><kbd>Win</kbd> + <kbd>←</kbd></kbd> と <kbd><kbd>Win</kbd> + <kbd>→</kbd></kbd> はループしますので、<kbd><kbd>Win</kbd> + <kbd>←</kbd></kbd>を押して行くと、左半分→右半分→元のサイズのようになります。画面が複数ある場合、その中を移動して行きます。

タスクバーを右クリックして、コンテキストメニューより並べ替えの指定を行えますが、思ったようにいかない場合、この方法で並べるとやりやすい場合などがあるかと思います。

以上

|前回|方針|次回|
|:--|:--:|--:|
|[<kbd><kbd>Ctrl</kbd> + <kbd>F10</kbd></kbd>](http://qiita.com/rrryutaro/items/fc1ba7ea4e10690e5583#_reference-31c6b0e2cfc7c8bc493a)|[記事の方針](http://qiita.com/rrryutaro/items/74d60a6e31ff149c5710)|[<kbd><kbd>Win</kbd> + <kbd>+</kbd></kbd>](http://qiita.com/rrryutaro/items/15b048396dcd5fed1705)|
GNU coreutils > date > 指定日の前日をyyyymmddで表示するワンライナー > $ date --date="20161020 1 days ago" "+%Y%m%d"

http://qiita.com/7of9/items/b9c90e27593fae16252b
の続き


```
$ date --date="20161020 1 days ago" "+%Y%m%d"
20161019
```
GNU coreutils > date > 指定の日付の前日を表示する > $ date --date="20161020 1 day ago"

```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を使用。
date (GNU coreutils) 8.4
```

参考 http://qiita.com/iruseira/items/5514a8c5bef41e7e6aca
参考 https://www.cyberciti.biz/tips/linux-unix-get-yesterdays-tomorrows-date.html

上のページを読んでいて、ダメ元で以下のコマンドを打ってみた。

```
$ date --date="20161020 1 day ago"                                                          
Wed Oct 19 00:00:00 JST 2016
```


以下でもできた。

```
$date --date="20161020 - 1 day"
$date --date="20161020 - 1 days"
```
bash > sedで使う s/20161102/20161121/g といった文字列の右側の日付をbashスクリプトの実行時引数で変更する > v0.1..v0.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を使用。
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
```

sedで使うことになる`s/20161102/20161121/g`のような文字列の右側の日付(20161121)をbash scriptの引数で指定して変更できるようにした。
(そうでないと単調作業を繰り返すことになり、失敗する）。

## v0.1

### bash script

```bash:replace_dates_170117_exec
#!/usr/bin/env bash

if [ $# -lt 2 ]; then
	echo "ERROR: too few arguments"
	echo ""
	echo "  [cmd] [current date] [previous date]"
	echo "  e.g. cmd 20161020 20161019"
	exit
fi

fmt1='s/20161102/20161121/g'
fmt2='s/20161101/20161120/g'

fmt1=$(echo $fmt1 | sed 's/20161121/'$1'/g')
echo $fmt1
fmt2=$(echo $fmt2 | sed 's/20161120/'$2'/g')
echo $fmt2
```

### 引数なし実行例

```
$ bash replace_dates_170117_exec 
ERROR: too few arguments

  [cmd] [current date] [previous date]
  e.g. cmd 20161020 20161019
```

### 引数指定実行例

```
$ bash replace_dates_170117_exec 20161020 20161119
s/20161102/20161020/g
s/20161101/20161119/g
```

fmt1, fmt2という変数になっているので、あとは以下のような使い方をする。

```
sed $fmt1 $oldfile | sed $fmt2 > $newfile
```

## v0.2

以下の方が実はシンプルだった。

```bash:replace_dates_170117_exec
#!/usr/bin/env bash

if [ $# -lt 2 ]; then
	echo "ERROR: too few arguments"
	echo ""
	echo "  [cmd] [current date] [previous date]"
	echo "  e.g. cmd 20161020 20161019"
	exit
fi

fmt1='s/20161102/'$1'/g'
fmt2='s/20161101/'$2'/g'

echo $fmt1
echo $fmt2
```

## 備考

current dateからprevious date自動計算を実装する方法があるが、面倒そうなのでしていない。
GNU findutils > 1*24時間前のwrfoutを名前に含んでいるファイルを探す > find . -mtime -1 | grep wrfout

```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を使用。
find (GNU findutils) 4.4.2
```

WRF(Weather Research and Forecasting Model)関連。

昨日処理したwrfout_***ファイルを検索したい。

参考 http://unix.stackexchange.com/questions/10041/how-to-get-only-files-created-after-a-date-with-ls

```
$ find . -mtime -1 | grep wrfout
./wrfout_d02_2016-10-20_00:00:00
./wrfout_d01_2016-10-20_00:00:00
./wrfout_d03_2016-10-20_00:00:00
```

man find

```
 -mtime n
              File’s data was last modified n*24 hours ago.  See the comments for -atime to understand how
              rounding affects the interpretation of file modification times.
```

> n * 24 hours ago

と記載しているが、`-mtime 1`でなく`-mtime -1`として指定するようだ。
多分。
辛くない、英語で会話できるようになるまでのお金のかからない楽しい英語勉強法、エンジニアこそ英語

大学生の時にノリで書いたこの記事が意外にもかなりいいねされて、でも見返してみると結構さらっと書いてあるのでちょっと追記しました。追加したところはNewといれておきました。挫折しないで楽しく効率的に英語の勉強を続けていくというのがテーマです。


##英語勉強は辛くない！楽しいから続けられる
英会話教室など一切通わず、完全に独学でTOEIC対策ほぼ皆無でTOEIC915点、海外経験なしですが日本語の話せない外国人と二人で遊んだり普通に会話できる程度の英語力**”は”**あります。実際まだまだですが。
ということで英語に関しては少しは語ってもいいかなと思ったのと、一般的なTOEICを意識した英語勉強法では会話力は身につかないばかりか辛さが身に堪えると思うので、自分なりに考えた**役に立つ英語を楽しく学ぶ方法**を記事にしたいと思います。


##やってはいけないというか、やらない方がいいと思う勉強法

**TOEIC X００点取得的なタイトルの本**：　辛いし、楽しくないし、TOEIC取る勉強しても実際に役に立たない。以下に書いたやり方でやれば対策せずとも８００は行くはず

**リーディング練習のための本**：　技術書を英語で読むなど英語で知識を得る方向に向かうべき。一石二鳥。

**英会話教室に通う**：　お金持ちならいいと思いますが、そうでないなら効果対費用がかなり悪いように思います。特に、初心者の場合自力でやるのも人に教えてもらうのもあまり変わりがない気が。上達してきて、うまく発音できない音があるとか、自分ではかなり上達したつもりだけどネイティブからすると自分の英語はどう聞こえているのか、などピンポイントな質問が出てくるまでは行かなくてもいいのかなと思います。




#オススメの勉強法


##リスニングとスピーキング
・**発音の練習**：　超大事、だけどみんなやらない。リスニング力も向上。英語を話す自信もつくので絶対やりましょう。
英語喉、虫眼鏡が表紙にある速度をゆっくりにして発音を勉強できる本がオススメです。

・**Youtubeで海外のYoutuberの面白い動画を見る**：　楽しく英語力向上。自然な英語になれることができる。かなりオススメ。辛くない。Youtuberが喋るのに合わせてシャドーウィングもやるといいと思います。

・**英会話フレーズの暗記**：これをやるやらないでは段違いです。本で学んだフレーズは会話で実際に使うのにも安心感があるものです。発音と一緒にやれば英語を話すことに抵抗が薄れて行くでしょう。言いたいことが言えるようになってくるとどんどん会話が楽しくなります。リンク先のものはオススメです。きちんとフレーズもやるといいと思います。
[ネイティブなら子どものときに身につける 英会話なるほどフレーズ100 (スティーブ・ソレイシィの英会話シリーズ)](https://www.amazon.co.jp/gp/product/4757402430/ref=oh_aui_detailpage_o02_s00?ie=UTF8&psc=1)


**海外のコンピュータサイエンスの授業の動画を見る**：技術書を英語で読むのもいいですが動画を見るのもとてもいいと思います。英語も聞き取りやすいですし、こちらのアルゴリズムの授業の動画集はオススメです。https://www.youtube.com/playlist?list=PLUl4u3cNGP61Oq3tWYp6V_F-5jb5L2iHb

・**外国人の友人を作る**：ある程度実力がついたなら、これがこの中でダントツで絶大な貢献を英語力にもたらしてくれます。正直運とか環境とか次第で難しいと思うのですがでも英語を伸ばすには本当に効果的です。


**音声変化についての理解**　New
https://agonaga.com/pronunciation-change-rules/
https://www.englishplus.jp/listening/4oto/
http://naminorism.com/pronunciation_change_rules/
ルールについて知らない方は、こちらのリンクを読んでください。頭で理解したらあとは、Listening Hackerというアプリで音声変化の練習ができるのでやってみると良いかと思います。

**シャドーウィング** New
前回書きませんでしたが、これも絶対やったほうがいいです。通勤通学中にPodcastとかで英語の音声聞きながらちょっと声に出すとか、口だけ動かすだけでもいいみたいです。詳しくは調べてみてください。
通勤通学中、本が読めない歩いている時にもやることをお勧めします。お勧めの教材はBlinkistです。有料ですが、払うだけの価値はあります。https://www.blinkist.com/

##リーディング
**技術書を英語で読む**：技術書を英語で読むというのはエンジニアならではの勉強法。英語を読む速さ、語彙力、英語を読むことへの抵抗感の減少、技術力の向上、の効果を見込めます。オライリーの本はPDFがダウンロードできるので個人的にはパソコンを手元に置きながら同じページを見ながら意味のわからないところがあったらその都度パソコンで調べると時間がかからないと思います。Macの感圧トラックパッドが活躍します。HeadFirstシリーズは英語も難しくないですし話し言葉で書かれているのでオススメです。


・**音読**：英語のリズムに慣れることはとても重要です。音読で英語のリズムを刻み込みましょう。自分の声に出してやることに意味があります。頭の中で意味を理解しながら読むこと。ネイティブの音声を真似ることがとても大事です。リーディング・リスニング両方に効果があるけど一応こっちに載せます。
下記のリンクを読めばなぜ大事かがわかるかと思います。New
https://englishacademy.live/%E9%9F%B3%E8%AA%AD/

・**単語**  New
語彙力は大事です。そして終わりがありません。コツコツやりましょう。アプリでも単語帳使うでもカードにまとめるなどなんでも。と以前このように書いたのですが、それよりも多読して出会った単語のみを覚えるようにするのが良いのかなと最近思います。単語だけの勉強はどうしても無味乾燥になりがちで、挫折しやすいです。

**・多読**　New
最近知ったのですが多読はとても有効な勉強法だと思います。しかし、出会った全ての知らない単語をノートやアプリに登録しようとするとほぼ間違いなく挫折します。なので以下のリンクにもあるように、知らない単語が出てきても飛ばしてどんどん読みすすめると良いです。知らない単語飛ばして読んでしまうのが嫌だという人は電子書籍で読むと良いです。それならすぐに意味が調べられるので挫折せずに読んで行くことができると思います。



##おわりに
質問などコメントで受け付けていますので答えられる範囲で答えます。
エンジニアにとって英語は重要であり、これからますますその傾向が強まってくると思います。この記事が少しでも皆様のお役に立てば嬉しい限りです。
Android Things - パルス幅変調(PWM)の翻訳

# What's this?

https://developer.android.com/things/sdk/pio/pwm.html
の翻訳

# PWM
[パルス幅変調](https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%AB%E3%82%B9%E5%B9%85%E5%A4%89%E8%AA%BF)(PWM)は、デジタル出力ピンを使用して外部デバイスに比例制御信号を印加する方法の一つです。例えば、サーボモーターはパルス幅変調（PWM）信号を受け取って回転角度を決定します。また、LCDディスプレイはパルス幅変調（PWM）信号の平均値に基づいて輝度を調整します。

PWMは所定の周波数及びデューティサイクルで発振するデジタル信号（矩形波信号）です。

- 周波数（Hz）は、出力パルスが繰り返される頻度を表します
- ピリオドは各サイクルにかかる時間で、周波数の逆数です
- デューティサイクル（パーセンテージ）は、その周波数ウィンドウ内のパルスの幅を表します

例: PWM信号のデューティーを50%にセットすると各サイクルの半分がアクティブになります
![pwm-signal.png](https://qiita-image-store.s3.amazonaws.com/0/129712/db809c8d-d38c-24d2-061b-3f9459c42601.png)

デューティサイクルを調整して、信号の平均「オン」時間を増減させることができます。 
次の図は、0％、25％、100％デューティのパルス列を示しています。
![pwm-duty.png](https://qiita-image-store.s3.amazonaws.com/0/129712/229a752f-369d-ec54-ada0-98a6bf257800.png)

> **注:** 多くのPWMハードはサイクル毎に少なくとも一度は値が変更される必要がある為、デューティ比が0%, 100%であったとしても各サイクルのはじめには値の変化があります。

# 接続管理

PWMポートとの接続にはポート名を知る必要があります。開発するにあたり、**PeripheralManagerService.getPwmList()**を呼び出すことで利用可能なポート名の一覧を取得することが出来ます

```java
PeripheralManagerService manager = new PeripheralManagerService();
List<String> portList = manager.getPwmList();
if (portList.isEmpty()) {
    Log.i(TAG, "No PWM port available on this device.");
} else {
    Log.i(TAG, "List of available ports: " + portList);
}
```

接続すべきポート名が分かれば、**PeripheralManagerService**クラスを使用して接続することが出来ます。ポートの利用が完了したら接続を閉じてリソースを開放してください。また、接続済みのコネクションを閉じるまで同じポートで新たな接続を開始することは出来ません。接続を閉じるには**close()**メソッドを使用します。

```java
public class HomeActivity extends Activity {
    // PWM Name
    private static final String PWM_NAME = ...;

    private Pwm mPwm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Attempt to access the PWM port
        try {
            mPwm = mPeripheralManager.openPwm(PWM_NAME);
        } catch (IOException e) {
            Log.w(TAG, "Unable to access PWM", e);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if (mPwm != null) {
            try {
                mPwm.close();
                mPwm = null;
            } catch (IOException e) {
                Log.w(TAG, "Unable to close PWM", e);
            }
        }
    }
}
```

# パルス幅変調(PWM)の設定と制御

接続後、パルス幅変調(PWM)を最初に有効にする前にタイミングパラメーターの設定をする必要があります。パルス幅変調(PWM)を有効にするには**setEnabled(true)**を実行します。もし一時的に無効にする必要がある場合は**setEnabled(false)**を実行することで無効化することが出来ます。

次のコードは、デューティ比25%(各サイクルで2.08msがOn)で120Hz（8.33ms周期のサイクル）のパルス幅変調（PWM）信号を発するように設定しています

```java
public void initializePwm(Pwm pwm) throws IOException {
    pwm.setPwmFrequencyHz(120);
    pwm.setPwmDutyCycle(25);

    // Enable the PWM signal
    pwm.setEnabled(true);
}
```
enzymeならjsdomなしでReactのテストがほぼ全てできる

## 問題意識

reactのコンポーネントのテストは、react-addon-test-utilsをそのまま使うと面倒なことが多いです。具体的には、

- コンポーネントを描画するためにdom環境が必要（jsdomやkarmaなどを使うのが一般的）
- 子コンポーネントも全て描画される

前者は、特にReact Nativeのテストをしたい時に困ります。dom環境ではないランタイムが必要でテストできないので。
後者は、単体テストの原則に反します。また、reduxのconnectなどを子コンポーネントに適用していた場合はテスト環境の構築も面倒になってきます。

そこで登場したのが[enzyme](http://airbnb.io/enzyme/)です。
shallow renderingを用いることで、jsdomなどのランタイムなしに対象のコンポーネントのみをテストすることができます。
しかし、実際にコンポーネントをmountしているわけではないため、

- 実際に表示される文言のテストがしにくかった
- 一部のライフサイクル系の振る舞いは確認できなかった
  - 参照：https://github.com/airbnb/enzyme/issues/465#issuecomment-227697726

## この記事のゴール

2017現在では、上記2つの問題を解決できて良い感じにテストできるんだよ、というのを示したいと思います。
なお、React Nativeでも同じようにテストしたいため、jsdomなどに依存しない shallow rendering を前提とします。

（ぶっちゃけ、このPR見ればほぼわかるかと思います→https://github.com/airbnb/enzyme/pull/318 ）

## 実際に表示される文言のテスト

(React Nativeの例ですが、普通のReactでも同様にテストできます。)

```js:index.ios.js
  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Welcome to React Native!
        </Text>
        <Text style={styles.instructions}>
          To get started, edit index.ios.js
        </Text>
        <Text style={styles.instructions}>
          Press Cmd+R to reload,{'\n'}
          Cmd+D or shake for dev menu
        </Text>
      </View>
    );
  }
}
```

```js:Intro-spec.js
describe('<Intro />', function () {
  it('ReactNativeSample', function () {
    const wrapper = shallow(<ReactNativeSample />);
    assert(wrapper.find('Text').at(0).prop('children') === 'Welcome to React Native!');
    assert(wrapper.find('Text').at(1).prop('children') === 'To get started, edit index.ios.js');
  })
});
```

このように、実際に表示された文字に対してassertを掛けるのではなく、`<Text>`タグなど文言の表示をするコンポーネントのpropsに渡ってくる文字列を確認することで、描画テストの代わりとみなせます。
`wrapper.contains(hoge)` みたいなテストよりもこちらの方が詳細なテストを書けるのではないでしょうか？

（※ただし、`<Text>hello {this.props.name}</Text>`のように書くと通らず、```<Text>{`hello ${this.props.name}`}</Text>```のように書く必要がありました。）

## 一部のライフサイクル系の振る舞いは確認できなかった

文言から解ると思いますが、これは上記PRのおかげでもう過去の話です。今はできます。

```js:test-spec.js
it('componentDidMount', () => {
  const spy = sinon.spy();
  class Foo extends React.Component {
    componentDidMount() {
      spy();
    }
    render() {
      return <div>foo</div>;
    }
  }
  shallow(<Foo />, { lifecycleExperimental: true });
  assert(spy.getCalls().length === 1);
});

it('componentWillUnmount', () => {
  const spy = sinon.spy();
  class Foo extends React.Component {
    componentWillUnmount() {
      spy();
    }
    render() {
      return <div>foo</div>;
    }
  }
  const wrapper = shallow(<Foo />);
  wrapper.unmount();
  assert(spy.getCalls().length === 1);
});
```

キモはこれです。`{ lifecycleExperimental: true }` 
これにより、componentDidMountのような、これまでshallowでは再現できなかったライフサイクルメソッドも扱えるようになっています。

## まとめ

いかがでしょうか。
reactを書くなら、実質enzymeは必須のように思います。

また、reduxのようなフレームワークをenzymeのshallowを駆使すると、AngularのDIの仕組みでしたかったことと同じことが出来るようになるのですが、それはまた別の話。
アルゴリズムの初歩（Insertion Sort）

ごく基本的なアルゴリズム、Insertion Sortについてです。なんでも、人に教えるというのは記憶の定着率を９０％にまで高めてくれるそうです。ちなみに、ただ本を読むのでは１０％。今アルゴリズムを学んでいるので、これからなるべく復習としてQiitaの記事にしていこうと思います。


このアルゴリズムは、一つのランダムに並んでいる数列を昇順や降順にソートします。ソートするデータのサイズが小さい時に効率的です。


Input
ソートされていない配列A[4,6,2,5,3,1]

Output
昇順にソートされた配列A’[1,2,3,4,5,6]

Method
以下をソートが完成するまで繰り返す：一つの数をKeyとしてとり、それを左の数と比べてKeyの方が小さいなら左の数をKeyにする。比べられた数の配列の場所を右にずらす。

では、手順を追って見ていきましょう。

1. ６をKeyとする。Key(6)＞４なので、何もしない。Keyを右となりの数、２にする。
2. Key(2)＜６なので左の数(6)をKeyの位置に持ってくる。[4,6,２,5,3,1]→[4,6,６,5,3,1]　左の数をさらに一つ左にずらす(4になる)。
   Key(2)＜４なので[４,6,6,5,3,1]→[4,4,6,5,3,1]。
3. 左となりにもう数がないので、4をKeyにしてKeyを次の数、５にして再開。
4. 上記の手順を繰り返す。




言葉にすると簡単ですね。では、これからPseudocode(スードーコード、簡略化された可読性の高いコード)で見ていきましょう。

```Java:pseudocode.java
    for (j=2 to A.length; j++) {
        Key = A[j]    
        i = j - 1;    //Keyの一つ左の数
        while (Key < A[i] and i > 0) {
            A[i + 1] = A[i];    //左の数を右に移動　1st loop[4,6,６,5,3,1]→ 2nd loop[4,４,6,5,3,1]
            i = i - 1;    //さらに一つ左にずらす
        }//このwhileループが終わった時、数が重複していることに注意。[4,４,6,5,3,1]
        A[i + 1] = Key; //i=0で終了。配列の最初の場所に、Key=2を代入[2,4,6,5,3,1]して重複解消。
    }
    
```

と、このようになります。個人的には、A[i + 1] = A[i];の部分で配列の中に同じ数が存在するという点にすぐ気づかず、分かりづらかったです。
ちなみに、**Insertion Sortは初めの配列がどの程度昇順に並んでいるかによって速度が変わってきます。**何回もwhileループしたりしなかったりということですね。

降順もやって見ましょう


```Java:pseudocode.java
for (j=2 to A.length; j++) {
        Key = A[j]    
        i = j - 1;    //Keyの一つ左の数
        while (Key > A[i] and i > 0) {
            A[i + 1] = A[i];    //左の数を右に移動　1st loop[4,6,６,5,3,1]→ 2nd loop[4,４,6,5,3,1]
            i = i - 1;    //さらに一つ左にずらす
        }//このwhileループが終わった時、数が重複していることに注意。
        A[i + 1] = Key;
    }
```



Javaでの実装は簡単そうなのでこの辺で。理解しながらこの記事を書いたので修正点がいくつかありました。分かりづらいことがあったらコメントしていただけると幸いです。
Jupyter / matplotlib > 2つのグラフを表示する > plt.figure() / plt.subplot()

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 14.04 LTS desktop amd64
TensorFlow v0.11
cuDNN v5.1 for Linux
CUDA v8.0
Python 2.7.6
IPython 5.1.0 -- An enhanced Interactive Python.
gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
```

2つの画像を並べて表示しようとしている。

### plt.figure使用

Python 機械学習プログラミング by Sebastian Raschkaら


```py:in100_out100.ipynb
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(123)
fig1,fig2 = plt.figure(1), plt.figure(2)
plt.figure(1)
plt.plot(np.random.rand(100))
plt.figure(2)
plt.scatter(np.random.rand(100), np.random.rand(100))
plt.show()
```

グラフが縦に並んだ。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/5df973b6-28f9-edf6-822c-6af58c1f9cee.png)

### plt.subplot()使用

plt.subplot()というのがあったことを思い出した。

```py:in100_out100.ipynb
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(123)
fig1 = plt.figure(1)
plt.subplot(221)
plt.plot(np.random.rand(100))
plt.subplot(222)
plt.scatter(np.random.rand(100), np.random.rand(100))
plt.show()
```

2x2の配置において、1,2の場所に置いてみた (1始まりのインデックス)。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b62e531e-bb92-6cad-2c40-8d5a56a6bc63.png)

### link

以下に良い記事がありました。
http://qiita.com/supersaiakujin/items/543053ca4610437112df
技術英語 > you'll know you'[re on the right track]. / back to normal rhythm

@ Introducing Python: Modern Computing in Simple Packages by Bill Lubanovic
(No. 397 / 12833)

> you'll know you'**<font color=red>re on the right track</font>**.

<hr>
関連して思い出したのは
back to normal rhythm

http://eow.alc.co.jp/search?q=back+to+normal

> jolt someone's heart **<font color=red>back to normal rhythm</font>**
> ショックを与えて（人）の心拍を正常に戻す

そろそろ年末年始休みから通常運転に戻っていくころだろうか。
カモフラージュするスパムレビュアの発見アルゴリズム

# 概要
[![Logo](https://rgmining.github.io/fraudar/_static/image.png)](https://rgmining.github.io/)

[結託したスパムレビュアを発見するアルゴリズム](http://qiita.com/jkawamoto/items/d2284316cc37cd810bfd)に引き続き，
オンラインショッピングやレストランレビューサイトにおいてスパムレビュアーを発見するために，
通常のレビュアーにカモフラージュするようなスパムレビュアを発見するアルゴリズム [FRAUDAR](https://rgmining.github.io/fraudar/) を用意した．

FRAUDAR は 2016年の [ACM SIGKDD International Conference on Knowledge Discovery and Data Mining (KDD 2016)](http://www.kdd.org/kdd2016/)でベストペーパー賞を受賞したアルゴリズムで，著者らによって[実装が公開されている](https://www.andrew.cmu.edu/user/bhooi/projects/fraudar/index.html)．

今回は，[スパムレビュア発見アルゴリズムの評価用データセット](http://qiita.com/jkawamoto/items/9a7647c47998fab4a1ad)などをより簡単に解析できるように[結託したスパムレビュアを発見するアルゴリズム](http://qiita.com/jkawamoto/items/d2284316cc37cd810bfd)と共通の[インターフェイス](https://rgmining.github.io/dataset-io/modules/dataset_io.html#graph-interface)を作成した．

# 使い方
今回作成した，FRAUDARのラッパー [`rgmining-fraudar`](https://rgmining.github.io/fraudar/) は [PyPI](https://pypi.python.org/pypi/rgmining-fraudar) に登録してあるので，`pip` コマンドにてインストールできる．

```shell-session
$ pip install --upgrade rgmining-fraudar
```

`fraudar` というパッケージが追加され，その中の `fraudar.ReviewGraph` がこのアルゴリズムを実装するグラフクラスである．
ReviewGraph クラスのコンストラクタは，オプションで何種類のカモフラージュパターンを考えるかというパラメータと，内部で使うサブアルゴリズムを受け取るが，前者のみデータセットに合わせて与えれば良いと思う（両方デフォルトでも問題ない）．

```py
import fraudar

# 例えば 10パタンのカモフラージュを考える場合．
n = 10 
graph = fraudar.ReviewGraph(n)
```

そして，グラフにレビュア，商品，そしてレビューを追加する．
[結託したスパムレビュアを発見するアルゴリズム](http://qiita.com/jkawamoto/items/d2284316cc37cd810bfd)の例と同じ方法で追加できる．

```py
reviewers = [graph.new_reviewer("reviewer-{0}".format(i)) for i in range(2)]
products = [graph.new_product("product-{0}".format(i)) for i in range(3)]
graph.add_review(reviewers[0], products[0], 0.2)
graph.add_review(reviewers[0], products[1], 0.9)
graph.add_review(reviewers[0], products[2], 0.6)
graph.add_review(reviewers[1], products[0], 0.1)
graph.add_review(reviewers[1], products[1], 0.7)
```

となる．レビュアと商品は `ReviewGraph` の `new_reviewer`, `new_product` メソッドを使って作成する．
レビューは `add_review` メソッドで追加する．

アルゴリズムの実行には，`update` メソッドを1回だけ呼ぶ．

```py
graph.update()
```

最後に，解析結果を取得する．
`new_reviewer` メソッドが返したレビュアには `anomalous_score` という属性がある．
この属性は，そのレビュアが特異（スパマー）と判断された場合 1 をそうでなければ 0 に設定される．

```py
for r in graph.reviewers:
    print(r.name, r.anomalous_score)
```

また，`new_product` メソッドが返した商品オブジェクトには `summary` という属性がある．
この値は，特異と判断されなかったレビュアーのレビューからなる平均を返す．

```py
for p in graph.products:
    print(p.name, p.summary)
```

# まとめ
[結託したスパムレビュアーを発見する Fraud Eagle アルゴリズム](http://qiita.com/jkawamoto/items/d2284316cc37cd810bfd)に引き続き，FRAUDAR アルゴリズムのラッパーを作成した．どちらも[スパムレビュア発見アルゴリズムの評価用データセット](http://qiita.com/jkawamoto/items/9a7647c47998fab4a1ad)を扱えるように[共通のAPI](https://rgmining.github.io/dataset-io/modules/dataset_io.html#graph-interface) を提供しているので，挙動を簡単に比較できると思う．
2017年版：配信通数ごとのSendGridの最安プランまとめ


> このページの情報は2017/01/17現在の情報をもとに書いています。
> 最新の価格情報は構造計画研究所さんのサイトを参考にしてください。

こちらのページを参考に配信通数ごとのSendGridの価格をグラフにしてみました。
https://sendgrid.kke.co.jp/plan/
どのプランにするのが最も割安かを検討するのにお使いください。

![vrdgboc3wj.png](https://qiita-image-store.s3.amazonaws.com/0/74551/1fef0f11-a9e8-b3d5-975a-0b040e297823.png "vrdgboc3wj.png")

青：Bronzeプラン
赤：Silverプラン
緑：Glodプラン
橙：Platinumプラン

# 最安プラン早見表

| 配信通数(万通) | 最安プラン |
|----------------|------------|
| 〜11.7         | Bronze     |
| 11.7〜23.5     | Silver     |
| 23.5〜68.3     | Gold       |
| 68.3〜         | Platinum   |

Bronzeプランでは固定IP機能やParse Webhook機能、サブユーザー機能などが使えないため、Bronze→Silverのプラン変更は上の早見表の通数よりも少ない通数で行ってもいいかなと個人的には思います。

また、月の配信通数が180万通を上回るほどになる場合は、さらに上のプランがあるそうです。
BigQuery でランダムサンプリング

ストック数的に誰も見ていないと思っていたけれど、意外と参考にしたという声を現実世界で最近ちょくちょく聞いているので [Medium の方](https://medium.com/@sfujiwara/807d64d1c2be)にちゃんと書き直しました。

# やりたいこと

タイトルの通り BigQuery でランダムサンプリングをする方法を調べたり考えたりしたのでメモを残しておきます。

# 方法その 1

乱数生成結果を入れただけの列を追加して、その列についてソートするという作業をサブクエリで記述します。

```sql
SELECT
  word
FROM (
  SELECT word, RAND() AS rand
  FROM [publicdata:samples.shakespeare]
)
ORDER BY
  rand
LIMIT
  100
```

`RAND()` 関数が真の乱数を生成するという仮定の下でランダムサンプリングが実現できており、最も素直で確実な方法だと思います。

## 欠点

ただ、この方法には 1 つ大きな欠点があります。

~~BigQuery では乱数の seed を固定できないので、**再現性がない**のです。~~
~~どう頑張っても実行するたびに結果が変わってしまいます。~~
**コメントで seed を固定が可能との指摘を頂きました。**
**ただ、 `LIMIT` を使った場合、大抵は同じ結果が返ってくるけれど、保証は無いようです。**

再現性のない実験や分析なんて、トトロやラピュタの目撃情報と大差ありません。

# 方法その 2

最近見かけて頭良いなと思った方法を改良したものです。

```sql
SELECT
  word
FROM (
  SELECT word, ROW_NUMBER() OVER() AS rand
  FROM [publicdata:samples.shakespeare]
)
WHERE
  ABS(HASH(STRING(rand))) % 1600 = 0
```

以下のような処理を行っています:

* ~~`RAND()`~~ `ROW_NUMBER()` を使って重複が無い列を追加して、その列を `HASH()` に突っ込む
  * `HASH()` は STRING か INTEGER しか受け取れないので STRING に変換している
* 負の値を除くために `HASH()` の結果を `ABS()` に突っ込む
* それを適当な整数で割った余りを指定して行を抽出する

`HASH()` が良い感じにランダムな整数値を返すという仮定の下に成り立っている方法なので、乱数としての質はイマイチだと思います。
ですが、この方法の素晴らしいところは**何度やっても同じ結果が返ってくるという再現性**です。

`LIMIT` を使って抽出する個数を制御すると BigQuery の機嫌次第で毎回結果が変わるので、何で割り切れるものを抽出するか (上記の例では 1600 になっているところ) を変えて、おおよその個数を制御しています。
今回は元のデータが 164656 行あって、大体 100 行ほどランダムサンプリングしたかったので 1600 で割り切れるものを抽出しました。

## 欠点

もう書きましたが、個数の制御がアバウトにしかできません。
`LIMIT` を使って個数を指定すると再現性が失われてしまいます。

# まとめ

紹介した 2 種類の方法で大抵の場合は何とかなりそうですが、それぞれ一長一短なので状況によって使い分ければ良いかなと思っています。

もちろん再現性と個数の正確な指定を両立できる方法があればベストですが、残念ながらそれは思いつきませんでした。
どなたか知っている人がいたらコメントで教えてください。
[VSCode]golang拡張で一部の関数の情報が出ない

VSCodeではgolangを書くための拡張機能があります。
これがよくできていて基本的に満足なのですが、以下のような場面で情報がでてきません。
(引数の情報が表示されていません。)

<img width="758" alt="スクリーンショット 2017-01-16 0.02.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/42193/e12ae068-5837-eb6a-8ff5-54a0e6bc4ac2.png">

`fmt.Println`などはしっかり出てくるのでバグなんじゃないかと思ってissuesを探りました。
そして次のissueを見つけました。
[Goto Definition, Hover, Signature Help does not work for `net` package](https://github.com/Microsoft/vscode-go/issues/442)

詳細はよくわかりませんがどうやら内部で使用しているツールの問題のようです。
解決策も書いてあるのでそれに従って設定ファイルを編集しましょう。
具体的には以下のような設定を追加します。

```
"go.docsTool": "gogetdoc"
```

🎉

<img width="607" alt="スクリーンショット 2017-01-17 1.22.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/42193/725f22bc-7f0e-1245-0684-89e6f30e2381.png">
VirtualBox と vagrantを使った開発環境

### PC上の作業ディレクトリと仮想マシンのディレクトリを同期（シンボリックリンク）させる方法 

vagrant をインストールして、諸々設定する。 
そのあと、ssh接続して /vagrant ディレクトリに移動するとVagrantfile がある。 

```
$ vagrant ssh  
$ cd /vagrant

Vagrantfile
```

この Vagrantfile はローカルPC上にもできていて

```
$ cd /Users/YOURNAME/vagrant 

Vagrant file 
```

仮想マシンのapache が見に行くディレクトリは 
```/var/www/html```

/var/www/html の /html は消しておく 
```rm -r html```

同期されるディレクトリは 
```/vagrant```

これをssh環境内でシンボリックリンクすればローカルPC上でも変更が同期されるようになる。 
```$ sudo ln -s /vagrant /var/www/html```


【参考サイト】
[Qiita: Vagrant+VirtualBoxでPHP開発環境構築](http://qiita.com/uchihashi_k/items/1438cd890966d321641a)
[Qiita: vagrantを用いたPHPの環境構築](http://qiita.com/tiwu_official/items/f135e6b6fbbe3ec6aa54)
ienagaさんの書かれた記事に感銘を受けた

#昨年急にGoogle swiffy が無くなって「あ〜ぁ」と意気消沈していたのだが、ネットをググっていて、「swf2js」に辿り着いた。

##このJavascriptのエンジンを創った ienaga氏って尊敬します。こちらプログラムとか一切ダメダメなオサーンですが、このSWFファイルの再現性には脱帽ものでした。まさかこんなに凄いツールが出来てたとは、旬な情報にウトいにも程があるなぁボク。

##すごくホッとしたのと同時に、またやる気が起きた。これでストップしてた電子書籍モドキまた創れる様になるかも。

http://qiita.com/ienaga/items/c9f04d6cd9874d4ec1a7
ATOMでJavaScriptの最強開発環境を作る

# 前提

- Windows上で使う。
- package.jsonが良しなに書かれている。
- コマンドラインから、「apm install xxx」でインストール。

# atom-runner

- ALT+Rでスクリプトを実行できる。
- jsだと、nodeがそのまま立ち上がるので、--harmonyで拡張機能が使えるようにしてあげる。
- 編集中のテストを単体実行できるように、拡張子test.jsに対して、「npm.cmd run test --」とする。

```coffeescript:config.cson
"*":
  'runner':
    'scopes':
      'js': 'node --harmony'
    'extensions':
      'test.js': 'npm.cmd run test --'
```

```json:package.json
{
  "scripts": {
    "test": "mocha"
  }
}
```

# browser-plus

- ATOM上にChromeのViewを開く。
- Ctrl+Alt+Oで開く。

# file-icons

- ツリーのファイルのアイコンをそれっぽくする。

# linter・linter-eslint

- .eslint.*は良しなに。
- .eslintignoreで必要なところだけ、eslint対象にする。

```:.eslintignore
*.js
!src/**/*.js
```

# platformio-ide-terminal

- ATOM上にbashを使えるようにする。
- 下の＋で現れる。ちょっとわかりづらい。
- デフォルトだとPowerShellなので、git-bashを設定する。
- スペースを含むとダメっぽいので、下のように、8.3のパスで指定......
- 文字がにじんで見える気がするんですが......お疲れですか？？？
- 編集中のファイルと同じディレクトリに移動したいけどできるのかな。

```coffeescript:config.cson
"*":
  "platformio-ide-terminal":
    core:
      shell: "C:\\PROGRA~1\\Git\\bin\\bash.exe"
```
phpstorm 環境設定

- [git と連動させるためには](http://tech.pjin.jp/blog/2016/07/04/phpstorm-git-settings-2/)
<br>

- [ビルドインサーバ設定](http://bashalog.c-brains.jp/13/09/13-194959.php)
<br>

- [phpstorm内で既存の仮想環境に繋げる方法](http://raichel.hatenablog.com/entry/2015/03/19/023425)
<br>

- [自動でFTPアップロードする方法](http://www.mikame.net/pr/archives/162)
<br>

- ショートカットコマンド
http://qiita.com/crifff/items/bbdf850f0d90ad16415a
http://www.happyquality.com/2012/06/14/2316.htm
http://www.karakaram.com/phpstorm-useful-tips2
<br>

- 便利設定
http://qiita.com/Arashi/items/d8c9725a3e06116e34eb#cakestorm
http://koni.hateblo.jp/entry/2016/01/12/090000