OmniAICreator/Qiita-1.07M huggingface dataset:
NSAllowsArbitraryLoadsとNSAllowsArbitraryLoadsInWebContentの設定による挙動確認

# 目的
- ATS(App Transport Security)の挙動確認。
- NSAllowsArbitraryLoadsとNSAllowsArbitraryLoadsInWebContentの設定による挙動をiOS9, iOS10で確認する。


# 環境

- Xcode Version 8.1, Objective-C 
- iPhone5 10.0.2
- iPhone7 Plus 10.1
- iPhoneSE 9.3.2
- iPhone6 8.2
    - iOS8の端末では関係無いとは思うが念のため確認。

# 準備

- http:// でも https:// でもアクセスできるURLを用意
    - 仮に http://example.com, https://example.com と記述。
- ATSに対応しているか確認(Macのターミナルで下記を実行)
    - `nscurl --ats-diagnostics https://example.com`

# 結果
- 表示・データ取得できた場合を"◯", 表示・データ取得できなかった場合を"×"
- NSAllowsArbitraryLoadsInWebContentの "-" は Info.plistに設定しないという意味
- NSAllowsArbitraryLoadsInWebContentは表示の都合で省略

## UIWebViewでの表示
### https://example.com
| NSAllowsArbitraryLoads | NSAllows...InWebContent | iOS8 | iOS9 | iOS10.0.2 | iOS10.1 |
|:-:|:-:|:-:|:-:|:-:|:-:|
| NO  | NO  | ◯ | ◯ | ◯ | ◯ |
| NO  | YES | ◯ | ◯ | ◯ | ◯ |
| NO  | -   | ◯ | ◯ | ◯ | ◯ |
| YES | -   | ◯ | ◯ | ◯ | ◯ |
| YES | NO  | ◯ | ◯ | ◯ | ◯ |
| YES | YES | ◯ | ◯ | ◯ | ◯ |
### http://example.com
| NSAllowsArbitraryLoads | NSAllows...InWebContent | iOS8 | iOS9 | iOS10.0.2 | iOS10.1 |
|:-:|:-:|:-:|:-:|:-:|:-:|
| NO  | NO  | ◯ | × | × | × |
| NO  | YES | ◯ | × | ◯ | ◯ |
| NO  | -   | ◯ | × | × | × |
| YES | -   | ◯ | ◯ | ◯ | ◯ |
| YES | NO  | ◯ | ◯ | × | × |
| YES | YES | ◯ | ◯ | ◯ | ◯ |
## WKWebViewでの表示
### https://example.com
| NSAllowsArbitraryLoads | NSAllows...InWebContent | iOS8 | iOS9 | iOS10.0.2 | iOS10.1 |
|:-:|:-:|:-:|:-:|:-:|:-:|
| NO  | NO  | ◯ | ◯ | ◯ | ◯ |
| NO  | YES | ◯ | ◯ | ◯ | ◯ |
| NO  | -   | ◯ | ◯ | ◯ | ◯ |
| YES | -   | ◯ | ◯ | ◯ | ◯ |
| YES | NO  | ◯ | ◯ | ◯ | ◯ |
| YES | YES | ◯ | ◯ | ◯ | ◯ |
### http://example.com
| NSAllowsArbitraryLoads | NSAllows...InWebContent | iOS8 | iOS9 | iOS10.0.2 | iOS10.1 |
|:-:|:-:|:-:|:-:|:-:|:-:|
| NO  | NO  | ◯ | × | × | × |
| NO  | YES | ◯ | × | ◯ | ◯ |
| NO  | -   | ◯ | × | × | × |
| YES | -   | ◯ | ◯ | ◯ | ◯ |
| YES | NO  | ◯ | ◯ | × | × |
| YES | YES | ◯ | ◯ | ◯ | ◯ |
## NSURLSession
### https://example.com
| NSAllowsArbitraryLoads | NSAllows...InWebContent | iOS8 | iOS9 | iOS10.0.2 | iOS10.1 |
|:-:|:-:|:-:|:-:|:-:|:-:|
| NO  | NO  | ◯ | ◯ | ◯ | ◯ |
| NO  | YES | ◯ | ◯ | ◯ | ◯ |
| NO  | -   | ◯ | ◯ | ◯ | ◯ |
| YES | -   | ◯ | ◯ | ◯ | ◯ |
| YES | NO  | ◯ | ◯ | ◯ | ◯ |
| YES | YES | ◯ | ◯ | ◯ | ◯ |
### http://example.com
| NSAllowsArbitraryLoads | NSAllows...InWebContent | iOS8 | iOS9 | iOS10.0.2 | iOS10.1 |
|:-:|:-:|:-:|:-:|:-:|:-:|
| NO  | NO  | ◯ | × | × | × |
| NO  | YES | ◯ | × | × | × |
| NO  | -   | ◯ | × | × | × |
| YES | -   | ◯ | ◯ | ◯ | ◯ |
| YES | NO  | ◯ | ◯ | × | × |
| YES | YES | ◯ | ◯ | × | × |


注意しなければならないのは`NSAllowsArbitraryLoadsInWebContent`をInfo.plistに追加した時点でiOS10で`NSURLSession`はhttpでの通信ができなくなるということ。
`Exception Domains`を設定することで指定したドメインのみhttpで通信可能。

以上
Crowiをセットアップする(CentOS 6.8)

# はじめに
バイト先のレガシーなpukiwikiにかわる新しいwikiを探している中、crowiがいいとの情報で動かしてみることになった。
centos6系で動かすときに色々詰まったのでメモ。

# 環境
- CentOS 6.8
- MongoDB 3.2.10
- node.js 4.4.7

# MongoDBを入れる
## 導入
MongoDBをセットアップする。  
[公式サイト](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/)を参照。  
  
```$ sudo yum upgrade```

yumでインストールできるように **/etc/yum.repos.d/mongodb-org-3.2.repo** ファイルを作る。

```
[mongodb-org-3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.2.asc
```

monogoDBを入れる
```$ sudo yum install -y mongodb-org```

SE Linuxを止める **/etc/selinux/config**

``` 
SELINUX=disabled
```

## 動作確認
mongoを動かしてみて動作を確認する

```
$ mongo
> use test
switched to db test
> db.name.insert({"name":"shuya", "age":21})
WriteResult({ "nInserted" : 1 })
> db.dropDatabase()
{ "dropped" : "test", "ok" : 1 }
> show dbs
local  0.000GB
> exit
bye
```

## crowi用のユーザの作成
ユーザの作成

```
$ mongo
> use crowidb
switched to db crowidb
>  db.createUser({user: "shuya", pwd: "shuya", roles: [{role: "userAdmin", db: "crowidb"}]})
Successfully added user: {
	"user" : "shuya",
	"roles" : [
		{
			"role" : "userAdmin",
			"db" : "crowidb"
		}
	]
}
> use admin
switched to db admin
> db.system.users.find()
{ "_id" : "crowidb.shuya", "user" : "shuya", "db" : "crowidb", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "ul5wxld3o/7ozcPt0dVEVA==", "storedKey" : "+9WQzbVivQBLUNk3eyvGJbzFxvo=", "serverKey" : "4wt1dgwpke14/zPJDOy1tKZuqkM=" } }, "roles" : [ { "role" : "userAdmin", "db" : "crowidb" } ] }
```

# nodejsを入れる
epelからの追加だとなぜかうまく動かず。。。

```
$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.30.1/install.sh | bash
$ source ~/.bash_profile
$ nvm ls-remote
$ nvm install v4.4.7
$ node -v
  v4.4.7
```



## crowiをクローン
crowiをクローンしてくる

```
$ git clone --depth 1 https://github.com/crowi/crowi.git
$ cd crowi
$ git checkout v1.5.0
$ sudo npm install --unsafe-perm
```
環境設定ファイルを書いて実行

```:crowi.sh
export PASSWORD_SEED=hoge
export MONGO_URI=mongodb://USERNAME:PASSWORD@localhost/DBNAME
node app.js
```

# アクセスする
3000番でlistenしているからブラウザにアクセス
http://localhost:3000
もし画像やCSSが描画されなかったら下記コマンドで手打ちでビルドすると治る
(ここでめちゃくちゃつまった)
```$ npm run build```

# ずっと動かす
foreverを使ってデーモン化する

```
$ npm install forever -g
$ forever start app.js
```

# 最後に
これであなたもイケてるmarkdawn wikiが使えるようになる！

# 参考
[Markdownで書けるWiki - Crowi](http://qiita.com/nullsnet/items/a6e69e44087339127b35)
【OSX】CakePHP3のインストール in XAMPP

OSXでCakePHP3をインストールしたので、ログに残す。


# xamppをインストール

公式ページからインストールしてください。php5.6でおｋ.

https://www.apachefriends.org/download.html#2702

# composerをインストール

macにデフォルトでインストールされているターミナルを開いて作業してください。
え？ 黒い画面怖い？ 怖くないよ。おいでおいでﾍ(￣ｰ￣ )


xamppの`htdocs`へ移動して、`composer`をインストールしましょう

```sh
$ cd /Applications/XAMPP/htdocs/
$ curl -s https://getcomposer.org/installer | /Applications/XAMPP/bin/php
```

# cakephp3をインストール

先ほどインストールした`composer`を使って、CakePHP3をインストールする。

```sh
# `cakephp` ってディレクトリが作成される.
$ /Applications/XAMPP/bin/php composer.phar create-project --prefer-dist cakephp/app cakephp
```


しかし、、、

```sh
Problem 1
    - cakephp/cakephp 3.2.8 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.2.7 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.2.6 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.2.5 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.2.4 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.2.3 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.2.2 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - cakephp/cakephp 3.2.1 requires ext-intl * -> the requested PHP extension intl is missing from your system.
```

こんなエラーがでたと思う。


これはphpの拡張ライブラリがインストールされていなから（だと思う）。


http://php.net/manual/ja/book.intl.php


すんなり入ればラッキーだと思うが、エラーがでた人はこのライブラリを使用するために、インストールが必要。


## intlをインストール

順にコマンドをタイプしていけばおｋ

```sh
# PHPのパスをXAMPPのものにする
$ PATH="/Applications/XAMPP/xamppfiles/bin:${PATH}"

# icu4cをインストール
$ brew install icu4c

# autoconfをインストール
$ brew install autoconf

# intlをインストール
$ sudo pecl update-channels
$ sudo pecl install intl 
```

コメントもらいました。
使用しているOSのバージョンによっては、```intl```のインストール手順が macOS Sierra 10.12.4 で上手くいかないようです。

以下のように icu4c インストール時に --force を付けると入るようです。

```shell-session
# PHPのパスをXAMPPのものにする
$ PATH="/Applications/XAMPP/xamppfiles/bin:${PATH}"

# icu4cをインストール
$ brew install --force icu4c

# icu4cをリンクさせる
$ brew link --force icu4c

# autoconfをインストール
$ brew install autoconf

# intlをインストール
$ sudo pecl update-channels
$ sudo pecl install intl 
```

とりあえず```intl```がインストールできればおｋ。

## php.iniを編集する


intlライブラリを認識させるために、`php.ini`ファイルを修正する。


```sh
$ sudo vi /Applications/XAMPP/etc/php.ini
```

```sh
# ;extension=php_intl.dll
# の行を
# extension=intl.so に変更．
extension=intl.so
```


編集したら、xamppのapacheを再起動してください。エラー無く起動したらおｋです。


## CakePHP3を再度インストールしてみる

さきほど途中までインストールしたCake3の残骸が残っているので一旦削除。

その後に`composer`を使ってインストールする。

```sh
$ rm -rf cakephp/

# 再度cakephpをインストール
$ /Applications/XAMPP/bin/php composer.phar create-project --prefer-dist cakephp/app cakephp
```

インストールできたかなー？
お疲れ様でした。


# 参考にしたURL

* http://blog.goo.ne.jp/toshi-mtk/e/5cb4d60fbe23dc1e7c085203cb1abf97
* http://stackoverflow.com/questions/34597100/install-php-internationalization-extension-intl-on-xampp-on-mac
* http://kou10mo.com/macosx-mavericks-use-phpize/
SSHでログインと同時にローカルのファイルを同期する

ローカルのマシンとリモートサーバーでEmacsの設定ファイル（~/.emacs.d/init.el）を同期したいことがあったので、スクリプトを書いてみました。

基本はscpとsshを続けてやっているだけですが、

- SSHのログインはキーボードインタラクティブ認証
- scpとsshで2回同じパスワードを入力するのは面倒

ということでSSHPassを利用していますが、平文でパスワードを入力するのは心許ないので少し工夫しています。

```bash
#!/bin/bash

HOST="user@hostname" #リモートのホスト名（とユーザー名）
FILE="/home/UserName/.emacs.d/init.el" #同期するファイル
DIR="~/.emacs.d/" #同期先のディレクトリ

read -sp "Password: " pass
tty -s && echo

sshpass -p $pass scp $FILE $HOST:$DIR &
sshpass -p $pass ssh $HOST
```

`scp -r`を使えばディレクトリごと同期もできるはずです。

~~ちなみに`FILE`のパスを`~/.emacs.d/init.el`にすると、なぜかNo such file or directoryが出てうまく行きませんでした。
フルパスを明示することで解決しましたが、理由がわからないとなんだか気持ちが悪いので、もしお分かりの方がいたらぜひ教えていただけるとありがたいです……~~
パスを""で囲んだためにbashが展開してくれなかったからですね

##参考
- [シェルスクリプトでパスワード入力プロンプト](http://qiita.com/quenhulu/items/f322b909beb85d67c971)
- [sshpassでssh/scpの対話型のパスワード入力を自動化する](http://qiita.com/koara-local/items/1aec16a4f866844f546d)
聴講メモ「エヌビディアが加速するディープラーニング ～ 進化するニューラルネットワークとその開発方法について～」

日本ITU協会 第56回 情報通信研究会
https://www.ituaj.jp/?kouen=56th_ict

「エヌビディアが加速するディープラーニング ～ 進化するニューラルネットワークとその開発方法について～」
講師 ： 村上真奈氏(NVIDIA ディープラーニングソリューションアーキテクト兼CUDAエンジニア)

資料とか、公開されないのかな……。似たやつがあった。http://www.slideshare.net/NVIDIAJapan/ss-61344653
ここで見つけた→ [NVIDIA Deep Learning Day 2016 Spring の個人的まとめ](http://qiita.com/it__ssei/items/822101c25568229fd3cd#%E8%AC%9B%E6%BC%94%E5%86%85%E5%AE%B9%E3%81%A8%E5%80%8B%E4%BA%BA%E7%9A%84%E3%81%BE%E3%81%A8%E3%82%81)

以下メモです:

-----
1980年の第2次AIブームでは、シナプス→ニューロン→シナプス→ニューロン……の段数が3段くらい。
2016年の第3次AIブームでは、152段。

2012年に、フィードバック(Forward/Backword Propergation)をうまくやるアイデアが登場して段数が増えた。

最近の事例:
Netflix...リコメンドエンジンでお試し会員からの正会員率を上げる、退会率を下げる
Googleデータセンタ……ラックにセンサをつけて空調を120段階で管理し、電力量を4割削減
https://devblogs.nvidia.com/parallelforall/

ニューラルネットワークの構成によっていろいろなパターンがある。”CNN”=上流では特徴抽出のための畳み込み、下流では特徴に基づいた推論をさせる……など。
顔認識の例だと、学習データ1000万点、段数8段、パラメータ(シナプス?)数10億、で学習時間が1か月くらい。

CUDA用ライブラリとして、深層学習用のcuDNN, 密行列用のcuBLAS, 疎行列用のcuSPARSE、フーリエ変換用のcuFFT、グラフ解析用のnvGraphなどがある。
これらを利用するディープラーニングフレームワークがオープンソースで増えてきて手軽になった。たとえば:
Caffe(かふぇ) ... C++/Python/Matlab用。画像認識のサンプルが多い
http://cafe.berkleyvision.org/
Torch(とーち) ... Lua/C用。Facebookによる顔認識のサンプルが多い
http://torch.ch/
Theano(しあーの)、TensorFlow(てんそるふろー)、Chainer(ちぇいなー) ... Pythonなので改造しやすい。時系列や複雑系のサンプルが多い
http://deeplearning.net/software/theano/
http://tensorflow.org/
http://github.com/pfnet/chainer
http://github.com/hido/chainer-handson (Jupyter Notebook)

CNTK(Microsoft製) ... (資料にあるものの紹介はなかった)
https://cntk.codeplex.com/


NVIDIA DIGITS にあるDebianパッケージを使えばWeb経由で簡単に画像解析と物体検出を始められますよ!
http://developer.nvidia.com/digits
https://github.com/NVIDIA/DIGITS/tree/master/examples

自主学習用コンテンツ quikLABS
https://nvidia.qwiklab.com
AWSで試せるよ!　無料コンテンツもあるよ!
有料コンテンツは15クレジット=1200円くらいだよ!

----

メモここまで
MySQL ibdataのデータサイズが肥大化した場合の対処方法。

# はじめに
MySQLでibdata1のデータサイズが肥大化していた際の対処法。

今回、とある案件でサーバの調査をしていた際に**ibdata1**のサイズがかなり大きくなっているのに気づきました。100GBを余裕で越すほどの。
これは**InnoDB**のデータ領域(テーブルスペース)です。
こうなると稼働したままデータサイズを小さくするのは難しく、リストアが必要となります。

# 事前準備
リストア作業を行う前にデータベースを利用するサービスを停止またはメンテ表示にしてトランザクションが*mysql*へ来ないようにしておきましょう。

# 作業
## 1. mysqldumpの取得
サービスを停止したら対象となるデータベースの*dump*を取得します。
だいたいこういう時はデータサイズが大きいので`&`をつけて実行しておくと便利です。

```bash:コマンド
$ mysqldump -p****** -u root -B hogehoge > hogehoge.sql &
```


## 3. MySQLの停止
*dump*が取得できたらMySQLを停止します。

```bash:コマンド
$ sudo service mysqld stop
Shutting down MySQL.. SUCCESS!
```


## 4. my.cnfの修正
同じことを繰り返さないためにも設定ファイルを修正します。
まずは原因となる箇所を見てみます。

```text:my.cnf(デフォルト)
[mysqld]
innodb_data_file_path=ibdata1:10M:autoextend
```

ここに`autoextend`が記載されていると、テーブルスペースに空き領域がなくなると自動拡張します。そのため今回は肥大化に繋がりました。
これはデフォルト設定なので**InnoDB**を利用する場合は注意が必要です。

なのでこれを回避するために`autoextend`をやめて以下のように`innodb_file_per_table`を追加しました。

```text:my.cnf（変更後）
[mysqld]
innodb_data_file_path = ibdata1:1G
innodb_file_per_table
```
これはテーブルスペースをテーブル単位で作成する設定です。
そうすることでテーブルスペースが１つにまとまってしまうのを防ぐことができます。分散されるのでパフォーマンスも良くなるみたいです。


## 5. ibdata*とib_logfile*の削除
それでは肥大化した**ibdata**を削除します。その際、**ib_logfile**もあれば削除しておきます。

```bash:コマンド
$ rm -f ibdata1 ib_logfile*
```


## 6. MySQLを起動する
MySQLを起動します。その際に削除された**ibdata**も再度作成されるので起動に多少時間がかかります。

```bash:コマンド
$ sudo service mysqld start
Starting MySQL................. SUCCESS! 
```


## 7. dumpデータの流し込み
ここまできたらあとは、はじめに*dump*したデータを流し込むだけです。

```bash:コマンド
$ mysql -p****** -uroot < hogehoge.sql &
```
フルダンプでない場合、*dump*データの流し込みには対象となるデータベースを用意しておく必要があります。ない場合は作成しておくのをお忘れなく。

完了したら最後に、事前準備で停止していた関連サービスを起動またはメンテ解除すれば完了です。


# おわりに
**InnoDB**はトランザクション機能がポイントですが、それが故に今回のような状況に陥る可能性があるので注意が必要です。
githubのコミット名(コミットする人の名前)の変更  < Commiter  Author >

#コミットする人の名前の変更について

githubでコミットした際に、コミットする人の名前を変えたい時や、
別のPCを使っていても、名前を統一したい時に、こちらの記事を参考にして頂ければ幸いです。

##変更コマンド

###グローバル設定
ホームディレクトリ/.gitconfigで定義している情報

```
git config --global user.name "sumple"
git config --global user.email sumple@tokyo.com
```

###ローカルリポジトリ設定
リポジトリごとの/.git/configで定義している情報

```
git config user.name "sumple"
git config user.email sumple@tokyo.com
```


###確認コマンド (初期はusernameとかないが、設定すると入っている)

```
git config --list
```

##実際にやってみよう
下記のようにコマンドを打って見る

```
git config --global user.name “g_user"
git config user.name “l_user"
```

確認してみる。二つ名前がある

```
MacPro:cake admin$ git config --list
credential.helper=osxkeychain
user.name=g_user
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true
remote.origin.url=https://github.com/〇〇/〇〇.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
user.name=l_user
MacPro:cake admin$
```

コミットしてブラウザで見るとこんな感じ (グローバルでないユーザーの名前が表示されている)
![git.png](https://qiita-image-store.s3.amazonaws.com/0/117024/4130d743-17d2-0a4a-f0e5-41bd361da91d.png)


ちなみに、globalで指定してあるものは、他のgitディレクトリでも、共通の名前が書かれているが、
もう一つの名前は、git config —list で出しても、出でこない。ので、gitディレクトリを新たに作成したら、usernameを指定すれば、その名前でコミットできるし、しなければ、globalで指定してある名前でコミットされるようです。

### 参考URL

http://y-ken.hatenablog.com/entry/git-commit-as-different-user

https://git-scm.com/book/ja/v1/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-%E6%9C%80%E5%88%9D%E3%81%AEGit%E3%81%AE%E6%A7%8B%E6%88%90
ECSのクラスタを安全に縮退する

あんまりEC2ノードごと増やしたり減らしたりってのは、やらないで済むに越したことはないんですが、お金に限りがある世界では、無駄に何十台もサーバー立ててられないので、適宜減らしたりしたいわけです。

増やす分には、Serviceのdesired countを上げて、Autoscaling Group(以下ASG)のdesired capacityを上げればほっとけば勝手に収束してくれるので、特に問題ありません。

問題は減らす場合で、ASGのcapacityを単純に下げると、どのノードがterminateされるかを厳密にコントロールすることができません。
そうすると、現在タスク稼動中のノードが落ちたりして無駄なコンテナの上げ下げが発生したり、いざログの転送とかが詰まってたりすると、データロストの危険が高まって心理的に余り嬉しくない。

というわけで、順番に行儀良く落とす方法を考えてみました。

まずECSからderegisterが可能なコンテナインスタンスの一覧を取得する。
実は割とめんどくさくて二種類のAPIコールが必要。

```ruby
def fetch_container_instances
  arns = []
  resp = nil
  loop do
    options = {cluster: cluster}
    options.merge(next_token: resp.next_token) if resp && resp.next_token
    resp = client.list_container_instances(options)
    arns.concat(resp.container_instance_arns)
    break unless resp.next_token
  end

  chunk_size = 50
  container_instances = []
  arns.each_slice(chunk_size) do |arn_chunk|
    is = client.describe_container_instances(cluster: cluster, container_instances: arn_chunk).container_instances
    container_instances.concat(is)
  end

  container_instances
end
```

ここから、稼働中のタスクが0のインスタンスを探す。

```ruby
container_instances = fetch_container_instances
deregisterable_instances = container_instances.select do |i|
  i.pending_tasks_count == 0 && i.running_tasks_count == 0
end
```

こいつらが、登録解除しても問題ないインスタンスなので、まずこいつらをクラスターからderegisterします。

```ruby
diff = current_desired_capacity - target_desired_capacity
deregistered_instance_ids = []
deregisterable_instances.each do |i|
  break if deregistered_instance_ids.size >= diff

  begin
    ecs_client.deregister_container_instance(cluster: service_config.cluster, container_instance: i.container_instance_arn, force: false)
    deregistered_instance_ids << i.ec2_instance_id
  rescue Aws::ECS::Errors::InvalidParameterException
  end
end
```

`force: false`にしておくのが大事です。
そうしておくと、タイミングの問題で何らかのタスクが動き始めてしまった場合はエラーにすることができます。

実際に登録が解除できたインスタンスIDのものを、まずASGからdetachしてから、terminateします。

```ruby
client.detach_instances(
  auto_scaling_group_name: name,
  instance_ids: deregistered_instance_ids,
  should_decrement_desired_capacity: true
)

sleep 1

ec2_client.terminate_instances(instance_ids: deregistered_instance_ids)
```

ASGからdetachする時に`should_decrement_desired_capacity: true`とセットしておくと、detachした数の分だけdesired capacityを減らしてくれます。
これで任意のインスタンスをASGから安全に除外しつつdesired capacityを調整できます。
その後で、terminateして完了です。

一応、これで安全に落とせるのですが、ネットワークの通信不良などで、どこかの処理がエラーになった場合、孤立したインスタンスが残ることになります。

なので、ECSのクラスタに所属しているインスタンスのIDと対応するASGに所属しているインスタンスのIDを比較して、ECSから接続が切れているのに稼動しっぱなしになっているインスタンスを落としたり、タグでインスタンスを探してASGから外れてるインスタンスを落とす等の処理が必要になるかもしれません。

ASGの設定でインスタンスの削除保護を有効にしておけば、事故る可能性はほぼ無くなるので、それと組み合わせれば、安全にECSのクラスタを縮退させられると思います。
なんか節約のために無駄な苦労を負っている気がしますが……。
pyenv をインストールしてると brew doctor で出る Warning を消す方法

pyenv をインストールしてると `brew doctor` で下記のような Warning が出る。それを消す方法をメモっとく。

```shell-session
$ brew doctor
Please note that these warnings are just used to help the Homebrew maintainers
with debugging if you file an issue. If everything you use Homebrew for is
working fine: please don't worry and just ignore them. Thanks!

Warning: "config" scripts exist outside your system or Homebrew directories.
`./configure` scripts often look for *-config scripts to determine if
software packages are installed, and what additional flags to use when
compiling and linking.

Having additional scripts in your path can confuse software installed via
Homebrew if the config script overrides a system or Homebrew provided
script of the same name. We found the following "config" scripts:
  /Users/takuya/.pyenv/shims/python-config
  /Users/takuya/.pyenv/shims/python3-config
  /Users/takuya/.pyenv/shims/python3.5-config
  /Users/takuya/.pyenv/shims/python3.5m-config
```

端的に言えば `PATH` 環境変数に `/Users/takuya/.pyenv/shims` のように pyenv のディレクトリが含まれてしまうのが原因。Homebrew を実行するときにだけ `PATH` 環境変数に pyenv のディレクトリが含まれない形にしてあげればいい。

ということで、`brew` コマンドのエイリアスを下記のように `.bash_profile` あたりで設定すれば解決する。参考にしたサイトでは置換してるけど、Homebrew 実行時に参照したい `PATH` 環境変数をベタに書く方法でいいかと。phpenv などを入れたときも修正が要らないだろうし。

```bash
alias brew="PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin brew"
```

# 参考文献

http://www.task-notes.com/entry/20141223/1419324649
http://qiita.com/takc923/items/45386905f70fde9af0e7
Salesforce の注文データで MFクラウド請求書(MoneyForward) から請求書を出力する方法

昨今、ビジネスで利用する業務システムは様々なクラウド上のサービス（Saas）として提供されています。

これらのSaasは、マーケティングや営業、請求業務などのバックオフィス業務といった各業務に特化したものが主流で、会社全体としてはSaasを組み合わせて利用しているケースが多いでしょう。これらのSaasでは目的の業務に必要なデータをSaas内のみで利用することを前提に作られているものが多く、会社全体で見ると、重複して登録していたり、手作業でファイルをアップロードしていることもあるでしょう。しかし、会社全体で見ると、扱うデータは同じものであったり引き継いだり出来るものが多いでしょう。例えば取引先の情報などがそうですし、何らかの注文が入ってその請求を出すような業務の場合、請求書の金額などは注文の情報から引き継がれるべきです。

具体例しては、リードや取引先、注文などは、セールス系に強い Salesforce を利用して管理しつつも、請求書の作成には MoneyForward のMFクラウド請求書を利用している、といったケースなどはありそうです。

そのためには、Salesforce内の取引先や注文データを、MFクラウド請求書にデータを連携しなければいけません。こういったことは、複数のSaasを組み合わせて利用している現状では避けられない課題だといえます。今回は、このような課題をCData製品を使い、使い慣れたExcelでデータを連携するサンプル、そして、Excelのマクロから請求書の一括出力といった業務の自動化のサンプルをご紹介します。

![構造図.png](https://qiita-image-store.s3.amazonaws.com/0/141193/bb0c33b9-5b45-582c-a8cb-b515dc7d7f7a.png)

この Excel によるデータ連携の詳細は[こちら](http://qiita.com/kasoorimethi/private/b3f858e17709f7d6bd82)を参照してください。
javascriptでJSONデータを扱う(登録・参照・更新・削除)

## はじめに

こんにちは。
javascriptでJSONデータをゴニョゴニョする方法を調べていたのですが、いまいちピンとくる資料がなかったので、自分が理解した範囲でまとめてみました。誰かの参考になれば幸いです。
また、こう書いた方が速い/キレイ/正しい等あれば教えて頂けると嬉しいです。よろしくお願いします。

## 前提

記事によって「オブジェクト型で格納されたJSONデータ」と
「配列型で格納されたJSONデータ」が混在している上に、
それが明記されていないせいで分かりにくいことがありました。
この記事で取り扱うのは、
「__オブジェクトの配列__として格納されたJSONデータ」
です。以下がサンプル。

````js
var data = [
  { name : "taro",
    exam : {
      math : 100,
      lang : 100
    },
    grade : "a"
  },
  { name : "jiro", exam : { math : 50, lang : 50 }, grade : "c" },
  { name : "saburo", exam : { math : 10, lang : 10 }, grade : "d" }
];
````

## データの参照

配列なので添え字([0]とか)を使用できる

````js
console.log(data[0].name); // => taro
console.log(data[0].exam.math); // =>100
````

jiroのexamのlang、など決め打ちの値が欲しい場合は
filter関数を使用する。まず
key「name」のvalueが「jiro」
という条件にマッチしたものだけを抽出した配列を作り、
その配列の先頭から必要な値を取り出す。

````js
var matchData = data.filter(function(item, index){
  if (item.name == "jiro") return true;
});

console.log(matchData[0].exam.lang); // =>50
````

## データの追加

__オブジェクト__としてデータを作成し、
既存の配列にpush関数で詰める。
(既存のデータは配列の中にオブジェクトとして格納されている。
なので、追加するデータもオブジェクトとして作成し、pushする)

````js
var addData =
  { name : "shiro", exam : { math : 10, lang : 100 }, grade : "b" }

data.push(addData);
````

## データの削除

jiroのデータを削除したい場合。
抽出のときとは逆に、filter関数を使用して
条件に当てはまらない全てのデータを抽出した配列を作成し、
既存の配列と置き換える。

````js
var newData = data.filter(function(item, index){
  if (item.name != "jiro") return true;
});

data = newData;
````

## データの更新

jiroのexamのmathを75に更新したい場合。
まずjiroのデータ(オブジェクト)を抜いた配列newDataを作り、
そこにjiroのデータを更新したchangeDataをpushする。

````js
var newData = data.filter(function(item, index){
  if (item.name != "jiro") return true;
});

var changeData = data.filter(function(item, index){
  if (item.name == "jiro") return true;
});
changeData[0].exam.math = 75;

newData.push(changeArray[0]);
// [注意]
// 最後にchangeArray[0]ではなくchangeArrayでpushすると
// 更新されたデータだけ配列型で入ってしまう。

data = newData;
````

## 補足

* 今回はpush関数を使っているので、追加や更新されたデータは常に配列の末尾に入っていく。なんとなく気持ち悪い。
* 一つのデータ(オブジェクト)を抽出するために全データを検索しているので、データ件数が増えたり各データが大きくなったりした場合処理が重くなりそう。。
Fortran からシステムコールを呼ぶ

## 概要
Fortran で TCP のソケット通信がしたい!
と思ったので，とりあえずシステムコールを呼べるかを試してみた．
忘備録程度に．

## 呼び方

    program main
        implicit none

        interface
            function socket(domain, type_, protocol) bind (c)
                integer, value :: domain, type_, protocol
                integer :: socket
            end function
        end interface

        integer :: sock

        sock = socket(2, 2, 0)
        write (*,*) sock
    end program

`bind (c)` をつけないと， `socket_`とlinkしようとして死ぬ．
`, value` をつけないと，ポインタを渡してしまうので意図した引数を渡せない．

## 結果

    $ gfortran hoge.f90
    $ strace ./a.out
    (中略)
    socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 3
    write(1, "           3\n", 13           3)          = 13
    exit_group(0)                           = ?
    +++ exited with 0 +++

呼べてる．
システムコール以外にも， C で書いた関数を Fortran から呼びたい場合も同様．
【Atom】 getaddrinfo ENOTFOUND atom.io atom.io:443　エラー対処のメモ

###Atomでパッケージをインストールする際に出たエラー
***
パッケージをインストールする際に、`getaddrinfo ENOTFOUND atom.io atom.io:443`というエラーが出ました。

![スクリーンショット 2016-10-28 18.07.59.png](https://qiita-image-store.s3.amazonaws.com/0/137880/0582a678-b5df-715e-93e6-263f867869e5.png)

ターミナルで`apm login`を実行し、言われた通りにEnterを押すことで解決できたようです(^_^;)

![スクリーンショット 2016-10-28 18.16.21.png](https://qiita-image-store.s3.amazonaws.com/0/137880/0ba70a7b-3c60-df0c-2bdd-0d5177b5c6ff.png)

参考ページ
[[Atom] getaddrinfo ENOTFOUND atom.io atom.io:443 エラーの解決方法](http://codenote.net/text-editor/3432.html)
[Java][Spring Boot][JAX-RS] Spring BootでJAX-RSを使う - NetBeansで始めるSpring Boot (2)

[Hello World!を作成しました](http://qiita.com/sengoku/items/735cb9639fd8e0686081)。

Spring Bootは、Spring MVCではなくJAX-RS実装であるところの[Jerseyも使える](http://docs.spring.io/spring-boot/docs/1.4.1.RELEASE/reference/htmlsingle/#boot-features-jersey)そうなので、慣れているこちらを使ってみることにします。

# pom.xmlを変更

依存性にある`spring-boot-starter-web`を`spring-boot-starter-jersey`へ書き換えます。

# Hello Controllerを削除

前回作成したHello Controllerは、Spring MVCのファイルだったみたいです。
よーしらんけど。

使わないので消してしまいます。

# Jerseryを使う

## リソースファイルの作成

`@Component`アノテーションが必要みたいです。

```java:HelloResource.java
package com.example.resource;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import org.springframework.stereotype.Component;

@Component
@Path("/")
public class HelloResource {

    @GET
    public String index() {
        return "Hello Spring Jersey!";
    }
}
```

## アプリケーションファイルの作成

JAX-RSリソースの場所を教えるためのクラスを作成します。

```java:JerseyConfig.java
package com.example;

import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;

@Component
@ApplicationPath("/rs")
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        packages("com.example.resource");
    }
    
}
```

`@ApplicationPath`アノテーションで、パスを設定しています。

# ビルドして実行

ビルドして実行したら、 http://localhost:8080/rs/ へアクセスしてみます。

![Screenshot from 2016-10-28 18-02-48.png](https://qiita-image-store.s3.amazonaws.com/0/59475/a1abb02b-335a-679d-2096-c20ac4d7d210.png)

こんなん表示されました。
openjdk1.7.0.111をCentOS6.xへインストールした際のエラー

##はじめに

CentOS 6.6の環境にopenjdk 1.7.0.111 をインストールし、
Tomcat7 を動作させようとすると以下のエラーが発生し動作しませんでした。

-------------------------
Exception in thread "main" java.lang.InternalError
    at sun.security.ec.SunEC.initialize(Native Method)
    at sun.security.ec.SunEC.access$000(SunEC.java:49)
    at sun.security.ec.SunEC$1.run(SunEC.java:61)
    at sun.security.ec.SunEC$1.run(SunEC.java:58)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.security.ec.SunEC.<clinit>(SunEC.java:58)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at java.lang.Class.newInstance(Class.java:383)
    at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:221)
    at sun.security.jca.ProviderConfig$2.run(ProviderConfig.java:206)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.security.jca.ProviderConfig.doLoadProvider(ProviderConfig.java:206)
    at sun.security.jca.ProviderConfig.getProvider(ProviderConfig.java:187)
    at sun.security.jca.ProviderList.loadAll(ProviderList.java:282)
    at sun.security.jca.ProviderList.removeInvalid(ProviderList.java:299)
    at sun.security.jca.Providers.getFullProviderList(Providers.java:173)
    at java.security.Security.getProviders(Security.java:456)
    at GetProviders.main(GetProviders.java:6)

-------------------------
どうも、openjdkの同バージョンでNSSのバージョンが古いと
発生する事象のようです。


##対処方法

NSSのバージョンを 3.21 以降にアップデートすることで、エラーは回避できました。

コマンド実行例）
yum update nss

-------------------------


参考情報
https://bugs.centos.org/view.php?id=11245
「Vimを使ってくれてありがとう」にさようなら


## Vim 本体に取り込まれました (2018/08/24追記)
k-takata さんが書かれているように、タイトルスタックを利用したタイトルの保存/復元機能が Vim 8.1.0253 で取り込まれました。Vim 8.1.0253 以降を使う場合は後述の設定を行わなくてもタイトルスタックに対応した端末でタイトルの復元が行われます。
これによって、他の端末でもタイトルスタックに対応してくれると嬉しいのですが。

## Vim を使ってくれてありがとう
Vim には、端末上で使う時にファイル名等の情報を端末ウィンドウのタイトルに表示する機能があります。標準では無効になっていますが、以下の設定を .vimrc に追加するとこの機能が有効になります。

```vim:.vimrc
set title
```

この機能を有効にすると Vim を終了した時にタイトルが「Vim を使ってくれてありがとう」に変わるようになります。

でも、出来れば Vim を起動する前の状態に戻したいですよね? その為にはどうすればよいのでしょうか。

## タイトル変更の仕組み
Common Desktop Environment (CDE) と呼ばれるデスクトップ環境の標準端末である dtterm にはウィンドウタイトル変更機能があります。dtterm のウィンドウタイトル変更機能では、 OSC と呼ばれる制御文字列を端末に送りつける事でタイトルを指定した文字列に変更します。現在一般的に使われている端末エミュレータの多くでは、この OSC 文字列を利用したタイトル変更機能に対応しています。

Vim も通常はこの dtterm の拡張機能を利用してウィンドウタイトルを変更するようになっています。しかしこの機能では新しいタイトルを送りつけるだけなので、古いタイトルの情報は判りません。Vim は起動時のタイトルがどうなっているかを知らないので、苦肉の策?として終了時にタイトルを「Vim を使ってくれてありがとう」に変更します。

## 現在のタイトルがどうなっているか調べられないの?
タイトルが判らないので元に戻せないのならば、タイトルを調べられればいいという事になりますよね。端末には現在のタイトルを調べる機能は無いのでしょうか?

実は有ります。dtterm の拡張機能に、ウィンドウタイトルの問い合わせ機能が有ります。この機能では端末に対してウィンドウタイトルを要求すると、端末が現在のウィンドウタイトルを返すようになっています。

しかし、この dtterm のウィンドウタイトル問い合わせ機能には

 * xterm のタイトル変更に比べて対応している端末が少ない
 * セキュリティ上の問題がある為、対応している端末でも標準では無効になっている事が多い

という問題があります。その為か Vim はこの機能に対応していません。

## タイトルを戻す別の方法
ところで、タイトルを元に戻すのに古いタイトルを知る必要があるのでしょうか。
ちょっと考えてみると、例えば以下のような機能があれば Vim 自体は古いタイトルを知らなくてもタイトルを元に戻せそうです。

 * 現在のタイトルを端末に覚えさせる命令
 * 端末が覚えていたタイトルに変更させる命令

この二つの機能があれば、Vim 起動時に端末にタイトルを記憶させ、終了時にそのタイトルに戻す命令を送れば、ウィンドウタイトルが起動前の状態に戻るようになります。
xterm にはタイトルスタックと呼ばれる上記の機能があり、Tera Term などの一部の端末エミュレータでもこのタイトルスタックをサポートしています。

## さようなら「Vim を使ってくれてありがとう」
タイトルスタックを使って終了時にウィンドウタイトルを元に戻すには .vimrc に以下の設定を追加します。

```vim:.vimrc
" Vim 8.1.0253 でタイトルスタックに対応したため、8.1.0253 のパッチが含まれていない時のみ設定を行う
if ! has("patch-8.1.0253")
  let &t_ti .= "\e[22;0t"
  let &t_te .= "\e[23;0t"
endif
```

&t_ti は Vim 起動時に送られる文字列で、&t_te は Vim 終了時に送られる文字列です。ここにそれぞれ "ウィンドウタイトルの記録命令"と"ウィンドウタイトルの復元命令"を追加します。これで set title をしていても、Vim 終了時にウィンドウタイトルが起動前の状態に戻るようになります。

問題点としては、タイトルスタックに対応していない端末がまだ結構ある事です。しかし、その場合でも上記の命令が端末に無視されて効果が無いだけで、他には悪影響はありません。
なので、タイトルスタックに対応している端末を使っている人だけではなく、対応していない端末を使っている人も設定してみてはどうでしょうか。

## 追記: タイトルスタック対応端末
2018年8月現在、自分の知っている範囲では以下の端末がタイトルスタックに対応しています。

* Windows用
  + Tera Term
  + RLogin
  + mintty
* Unix用
  + xterm
  + mlterm
  + gnome-terminal 等の libvte を利用した端末 [^1]
* Mac用
  + iTerm2 [^2]

[^1]: libvte では[2018年3月に対応](https://bugzilla.gnome.org/show_bug.cgi?id=699819)しました。バージョンでいうと vte-0.53.0 以降に含まれているようです。比較的最近に対応した為、多くのディストリビューションで利用できるようになるには少し時間がかかりそうです。

[^2]: 自分で使って確認をしていませんが、[ソース](https://github.com/gnachman/iTerm2/blob/master/sources/VT100CSIParser.m#L573 "VT100CSIParser.m")を見ると対応しているようです。
Firefoxのソースコードをいじって機能を追加してみた

# はじめに

この記事は後期実験「大規模ソフトウェアを手探る」のレポート兼ねた記事で、ここでは選択したタブだけを残し他のタブを削除する機能をつけた際の過程をまとめています。

# 実装

具体的にどのような実装にしたかというとCtrlとShiftを押したままタブバーをクリックしてタブをいくつか選択し、そのときのタブのインデックスを記憶しておきます。選択したらCtrl+Shift+Fで選択したタブを残して残りを削除します。

## タブ選択

[このページ](http://qiita.com/nagashim4/items/8b758cd5c45e17d55dd3)でも書いたようにbrowser.js内に変更を加えていきます。まず選択したタブのインデックスを記憶しておくために次のものを追加しました。

```javascript:browser.js
var tabidx = [];
document.onmousedown = function(event) {
  if(event.ctrlKey && event.shiftKey) {
    var index = gBrowser.tabContainer.selectedIndex;
    for(var i = 0; i < tabidx.length; i++) {
      if(index == tabidx[i]) {
        tabidx.splice(i, 1);
          return;
      }
    }
    tabidx.push(index);
  }
}
```

tabidxという名前をつけた配列にインデックスを追加していきます。Firefoxで定義されている関数を使ったのは4行目の

```javascript
var index = gBrowser.tabContainer.selectedIndex;
```

だけで、これは現在選択しているタブのインデックスを取得しています。 for文の部分はすでに選択されているタブをもう一度選択したときにそのタブの選択を解除するように書いています。選択したタブのインデックスがtabidxにあるか検索し、あった場合はtabidxからその要素を消しています。

## タブ削除

次に選択したタブを削除するために以下のものを追加しました。

```javascript:browser.js
document.onkeydown = function(event) {
  if(event.ctrlKey && event.shiftKey && event.keyCode == 70) {
    var numtabs = gBrowser.browsers.length;
    for(var i = numtabs-1; i >= 0; i--) {
      var s = true;
      for(var j = 0; j < tabidx.length; j++) {
        if(i == tabidx[j]) {
          s = false;
          break;
        }
      }
      if(s == true) {
        var browser = gBrowser.getBrowserAtIndex(i);
        var tab = gBrowser._getTabForBrowser(browser);
        gBrowser.removeTab(tab, false);          
      }
    }
  }
  tabidx = [];
}
```

これで何をしているか説明すると、gBrowser.browsers.lengthで現在開いているタブの数を取得できます。その後大きい方のインデックスからtabidxに含まれているかを確認し、含まれていない場合は削除しています。ページの削除はgBrowser.removeTab関数を使用しました。この関数には引数としてタブオブジェクトを渡す必要があるのでgetBrowserAtIndexメソッドとgetTabForBrowserメソッドを使用して指定したインデックスのタブオブジェクトを取得しています。getBrowserAtIndexは指定したインデックスのブラウザオブジェクトを返すものでgetTabForBrowserはブラウザオブジェクトを受け取ってそのタブオブジェクトを返すものです。削除した後はtabidexを空にします。今回は選択した複数のタブを残して削除するだけでしたが、少し変更するだけで選択した複数のタブを一度にブックマークしたりピン留めしたり出来るようにすることも可能です。

## バグ

これで目標の動作は出来るようになりましたがこの実装にはいくつか問題があります。この機能はタブを選択してからすぐに削除することを想定してインデックスを使うような実装にしているのでこのままでは、タブ選択後にタブの削除、追加、並べ替えを行うと選択したタブのインデックスと変更したタブのインデックスが一致せず意図したタブが残せません。本来はタブの変更を監視して変更があるたびにtabidxに反映させるべきなのですが、そこまでは実装できなかったため実際は上のコードに現在のタブの数がtabidxの要素数より少ない時や一つもタブが選択されていない時はalert文で警告を出し削除を行わない例外処理と削除する際にconfirm文を使い自分が消したいページと削除するページが一致しているかを確認するような動作を追加しました。またクリックで選択や選択の解除をした時、タブの色が変わるようにしてどのタブを選択しているかを分かりやすくする機能を追加しようとしたがうまくいかず実装できませんでした。
Firefoxのソースコードをいじって機能を追加してみた

# はじめに

この記事は後期実験「大規模ソフトウェエアを手探る」のレポート兼ねたものです。ここではブラウザバックをした後今開いていたタブを新しいタブで開き直す機能をつけた際の過程をまとめています。

# 目標

どのような機能かもう少し細かく説明すると、ウェブページを見ている時にリンクなどを新しいタブで開きたかったのに、そのままクリックしてしまい現在のタブで開いてしまうことがあると思います。そういうときは一度ブラウザバックしてからそのリンクを新しいタブで開くと思います。少しの手間かもしれませんが、これをショートカットキーなどで一気に出来るようにするというのが今回加えた機能です。

# 実装

[このページ](http://qiita.com/nagashim4/items/8b758cd5c45e17d55dd3)でも書いたようにbrowser.js内に変更を加えていきます。grepによる検索や[Mozillaのホームページ](https://developer.mozilla.org/ja/Firefox)などで探したところ、この機能に使えそうないくつかのメソッドやプロパティを見つけたので次のように追加しました。

```javascript:browser.js
document.onkeydown = function(e) {
  if(event.ctrlKey && event.keyCode == 8) {
    var link_browser = gBrowser.selectedBrowser;
    var link_url = link_browser.currentURI.spec;
    BrowserBack();
    gBrowser.selectedTab = gBrowser.addTab(link_url.toString());
  }
}
```

ショートカットキーはCtrl+Backspaceにしました。if文内について説明していくと、1行目で現在選択しているタブのブラウザオブジェクトを取得して2行目でそのブラウザオブジェクトのURLを取得しています。その後3行目でブラウザバックし4行目で記憶しておいたURLを新しいタブで開きそのタブに選択を移動しています。これで目標の動作をするように変更できました。ただこの機能をブラウザバックが出来ないページで行うとBrowserBack()では何も起きないのでタブを複製するだけになります。ブラウザバックが出来るかどうかによってこの機能を動かないようにすることが出来れば更に良かったと思います。
Drone で自動デプロイが急にできなくなった話(2016年10月)

こんにちは yoshi です。  
普段 Drone.io を使っていて、master で git push をすると、

```
テスト -> ビルド -> イメージのアップ -> コンテナーの削除、再構築
```

をやってくれます。全部自動です。楽チンです。

Drone io: https://drone.io/


そんな楽チンな drone さんが、急に動かなくなっちゃったのです。

  
#####こんなエラー

Web サービスをデプロイしたとき

```
# drone のlogを見ています

$ /usr/bin/docker -d
Error response from daemon: no successful auth challenge for https://asia.gcr.io/v2/ - errors: [Get https://asia.gcr.io/v2/token?account=_json_key&service=asia.gcr.io: dial tcp [2404:6800:4008:c07::52]:443: network is unreachable]
Login failed.
[info] build failed (exit code 1)
```


Api をデプロイしたとき

```
# drone のlogを見ています

Sending build context to Docker daemon 109.2 MB
Sending build context to Docker daemon 109.2 MB

Step 0 : FROM golang
Pulling repository docker.io/library/golang
Get https://registry-1.docker.io/v1/repositories/library/golang/tags/latest: dial tcp: lookup registry-1.docker.io: no such host
[info] build failed (exit code 1)
```


`no such host` と `login failed`と言われましても、よく分からない。というわけで結構調べましたが、解決手段は見つからず。  
おそらく、DNSの問題であろうとなったので、とりあえず再起動をしてみることにしました。

1, Google Compute Engine の再起動
2, Docker Container の再起動

実はこのDroneはGoogle Compute Engineのインスタンスにdockerを動かしてその中でアプリが動くような仕組みになっています。  

「1, Google Compute Engine の再起動」 は何も変わらず失敗。

「2, Docker Container の再起動」はまず、 `service docker restart`としてみると、containerが落ちるので、`docker-compose start`でサービスを起動させると、きちんと立ち上がりサービスが正常に動き始めました。

#####このエラーはなんだったのか

おそらく偶然DNSかportかネットワークかが一時的に壊れて、再起動することによって元の状態に LINK することができたのだと思います。（詳しい方教えてください。。。）  
  
パソコンが不調だったら再起動。  
Dockerが不調だったら再構築。


教訓です。


他にも色々なブログを書いています。
こちらから: http://blog.lesson-time.com/
Firefoxのソースコードをいじって機能を追加してみた

# はじめに

この記事は後期実験「大規模ソフトウェアを手探る」のレポートを兼ねた記事で、ここではFirefoxにjとkでページのスクロールをする機能をつけた際の過程をまとめています。

# 実装

過去に自分たちと同じくFirefoxを対象として実験した班の[ブログ](http://qiita.com/pupuppidoxu/items/b967a1f322578bc4fa56)の情報からbrowser.jsというファイルに変更を加えれば良さそうだということが分かったので、このファイル内に試しに

```javascript:browser.js
ducument.onkeydown = function(e) {
  if(e.keyCode == 65) {
    alert();
  }
}
```

と追加してみました。これは何かキーボードの入力があったときにそれがaだったら画面に警告用のボックスが出るように書いています。ビルドし直して実際に動かしてみるとaを押した時に期待通りポップアップ画面が出ました。なのでalert文の部分をスクロールするように変えれば目標の動きが実現できそうです。

そこで次にbrowser.js内でページスクロールが定義されている場所を探しました。ターミナルで

```javascript
grep scroll browser.js
```

などと入力して見ると

```javascript
goDoCommand("cmd_scrollPageUp")
goDoCommand("cmd_scrollPageDown")
```

というページスクロールをしてくれそうなものを発見しました。上のもの書きかえて

```javascript:browser.js
ducument.onkeydown = function(e) {
  if(e.keyCode == 75) {
    goDoCommand("cmd_scrollPageUp");
  }
  if(e.keyCode == 74) {
    goDoCommand("cmd_scrollPageDown");
  }
}
```

とするとjとkでページを上下にスクロールすることが出来るようになりました。さらにこの関数はもともと定義してあったものなので、テキストボックス内やブラウザが選択されていない時にはj、kを押しても反応せず自分たちで細かい変更を加える必要はありませんでした。
CentOS6.7にDocker Composeインストール 備忘録

環境構築中に忘れそうだったのでメモ

### docker-composeのOS対応表

docker-composeの1.8系はCentOS 7.0以降だった...orz
なので、1.5.2をインストールすることにした。

|docker-compose |docker-engine |CentOS    |
|:-------------:|:------------:|:--------:|
|1.7.0          |1.9.1-        |7.0       |
|1.6.2          |1.9.1-        |7.0       |
|1.5.2          |1.7.1-        |6.7       |

### インストール
https://docs.docker.com/compose/install

``` 
curl -L https://github.com/docker/compose/releases/download/1.5.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
```

sudoでインストールすると以下のエラー発生

```
bash: /usr/local/bin/docker-compose: 許可がありません
```


以下、[Install Compose](https://docs.docker.com/compose/install/)の注意文引用
まさしく、これだ。

>Note: If you get a “Permission denied” error, your /usr/local/bin directory probably isn’t writable and you’ll need to install Compose as the superuser. Run sudo -i, then the two commands below, then exit.

supreuserでインストールすることで無事インストール完了

### パーミッションの変更

```
chmod +x /usr/local/bin/docker-compose
```

### Command-line Completionのインストール


```
curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
```

これで、YAMLを書いていこう。
Java 複数バージョンのinstallと切り替え

HomebrewにてJavaのinstallと複数バージョンの切り替え方です。
現在Javaがinstallされていないため以下の様になります。

```
$ java -version
no java runtime present requesting install
```

## Homebrewの準備など

[Homebrew](http://brew.sh/index_ja.html)
こちらのサイトのインストール部分をコピーしてきてTerminalで実行します。
途中パスワードを聞かれますので管理者パスワードを入力。

```
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

その後以下のコマンドを実行。

```
$ brew install caskroom/cask/brew-cask
$ brew tap caskroom/versions
```
## Javaのinstall
Javaのinstallをします。

```
$ brew cask install java
```

バージョンを調べると最初と違い以下の様なメッセージが出ます。

```
$ java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b16, mixed mode)
```

## 異なるバージョンのJavaのinstall
`brew cask search java`でinstall可能なJavaが出てきますのでJava6をinstallしてみます。

```
$ brew cask install java6
```

install後にJavaのバージョンを調べると切り替わっていませんので、`.bash_profile`で切り替えてみます。

```
$ java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b16, mixed mode)
```

`.bash_profile`を開き`export JAVA_HOME=$(/usr/libexec/java_home -v 1.6)`を書き込みます。

```
$ vim ~/.bash_profile
```

```~/.bash_profile
export JAVA_HOME=$(/usr/libexec/java_home -v 1.6)
```

再度バージョンを調べると切り替わっています。

```
$ java -version
```

## installしたJavaの削除
installしたJava6を削除します。

```
$ brew cask uninstall java6
```

削除後にJavaのバーションを調べると最初にinstallしたJavaに切り替わっています。

```
$ java -version
java version "1.8.0_112"
Java(TM) SE Runtime Environment (build 1.8.0_112-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.112-b16, mixed mode)
```

もう一度削除すると最初の時と同じように`no java runtime present requesting install`になります。

```
$ brew cask uninstall java
$ java -version
no java runtime present requesting install
```
UI > ユーザに使用方法を見せる

[編集中]

新規ソフトを使っていただく場合、その使用方法をどう説明するか。

- 取説を充実する
- 実地説明
- ソフト自体で分かるようにする

<hr>

- 取説を充実する
  - (UIの変更に伴う)取説分岐問題 
  - 例: 5年後にv1.5のxxxについて聞きたいのですが
- 実地説明
  - 資料管理. 数年後どうか
- ソフト自体で分かるようにする
  - 理想的

<hr>
### 案 > 説明文書を表示するコンポーネント

- 説明文書を表示する機能
- 自作のファイル変換ソフト(個人使用）

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/619c9c60-d751-c0b7-7e8b-a29118926246.png)

<hr>
### 案 > 説明文書を表示するコンポーネント (contd)

- ソフト起動のたびに説明を表示
- 説明は薄い色で表示. 本当の結果と識別（しているつもり)
- 入力ファイルのフォーマットが分かる

<hr>
### 案 > ボタンを押した時にサンプルを該当のコンポーネントに表示

1. 表示ボタンを押す
2. 特定のテキストに例となる文字列を表示
3. その文字列の表示は指定数秒後に表示が消える

一時的な表示の処理失敗 -> 不具合の元

<hr>
### 案 > ボタンを押した時にサンプルを小さいメッセージウィンドウとして表示

- dropboxの「更新しました」表示
- 時間経過で消える

複数のコンポーネントの説明 -> 順番に表示？
表示の途中キャンセルは?
C++ Builder XE4 -> 吹き出し表示機能ない。
ヒント表示機能はある。

ヒント機能で実装してみた。

<hr>
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/6b579e58-5f51-c741-3ba0-93f0a1537973.png)

<hr>
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/06e0cc27-714f-0ea8-4daa-28fc26c991d3.png)

<hr>
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/d894d8b7-7405-7f94-6cc0-da50625f03b2.png)
[Java][Spring Boot] NetBeansで始めるSpring Boot

NetBeansを使用して、Spring Bootアプリケーションを作成していきます。

# 環境

- Java 8
- NetBeans 8.1
- NetBeansプラグイン ｰ NB SpringBoot

NetBeansのGradleサポートはいまいちなので、ビルド-ツールはMavenを使用します。

# プロジェクトの作成

MavenカテゴリにあるSpring boot basic projectを選択します。

## 生成されたファイル

このようなファイルたちが生成されました。

```
├── nbactions.xml
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── DemoApplication.java
    │   └── resources
    │       └── application.properties
    └── test
        └── java
            └── com
                └── example
                    └── DemoApplicationTests.java

```

## pom.xmlの変更

2016年10月時点では、pom.xmlの内容が古くて読み込まれていないので書き換えます。

```xml:project>parent
<version>1.4.0.RELASE</version>
```

```xml:project>properties
<java.version>1.7</java.version>
```

↓

```xml:project>parent
<version>1.4.1.RELASE</version>
```

```xml:project>properties
<java.version>1.8</java.version>
```

POMをReloadします。

![Screenshot from 2016-10-28 16-19-11.png](https://qiita-image-store.s3.amazonaws.com/0/59475/e8af35e5-c2a3-9030-088a-d81a77294d80.png)

読み込まれました。

## 依存性の変更

`spring-boot-starter`となっているところを`spring-boot-starter-web`へ変更します。

# ビルドして実行

おもむろにビルドして実行してみます。

ブラウザを起動して http://localhost:8080/ へアクセスします。

![Screenshot from 2016-10-28 16-48-58.png](https://qiita-image-store.s3.amazonaws.com/0/59475/1de7eed4-f929-71a9-5a3c-ed525e51c639.png)

# Hello Controllerの作成

[Guide](https://spring.io/guides/gs/spring-boot/)に従って、Hello Controllerを作成してみます。

```java:HelloController.java
package com.example.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @RequestMapping("/")
    public String index() {
        return "Greetings from Spring Boot!";
    }
}

```

## 実行

ビルドして実行します。
もし前のMavenが動いていたら、先に止めておきます。

![Screenshot from 2016-10-28 16-43-54.png](https://qiita-image-store.s3.amazonaws.com/0/59475/609699ee-90c6-603c-5b2d-b7332f01913a.png)

こんなん表示されました。
Angular-cliのproxy設定


Angular-cliを使っているプロジェクトで、フロントとAPIのローカル開発サーバーを分けていて、フロント側からAPIを呼ぶ場合の設定方法のメモ

1. proxy設定ファイルを書く
2. proxy設定ファイルを指定してng serveする


1. proxy設定ファイルを書く
-
```proxy.conf.json
{
  "/api": {
    "target": "http://localhost:8080",
    "secure": false
  }
}
```

2. proxy設定ファイルを指定してng serveする
-
```package.json
{
  …
  "scripts": {
    "start": "ng serve --proxy-config proxy.conf.json"
  },
  …
}
```


```
$ npm start
```


参考
-
[Proxy To Backend](https://github.com/angular/angular-cli/#proxy-to-backend)
Macのターミナルから通知センターに通知する

Macのターミナルから通知センターに通知がこんなに簡単にコマンドラインでできるとは知らなかった。これは便利:smile:

僕はSoftEtherVPNが接続されたあとに、IPアドレスを取得して表示してみました。

```bash:
echo display notification \"VPN接続完了\\n`ifconfig tap0 | grep inet`\"  with title \"SoftEther VPN\" sound name \"Glass\"| osascript
```

なお、Automatorさんからも簡単に通知できるようになっていたので自動化に合わせていろいろ使えそう。



# 関連情報

* [Mac Automation Scripting Guide: Displaying Notifications:](https://developer.apple.com/library/content/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/DisplayNotifications.html)
* sound nameで指定できるのは以下のディレクトリにあるもの 
 * /System/Library/Sounds/

今まであまり関わってこなかったけど、osascrip たのしそう
線分交差判定

線分が交差しているかを判定するアルゴリズム

```py
import numpy as np
a1 = np.array([1,1])
a2 = np.array([5,5])
# crossing
b1 = np.array([3,1])
b2 = np.array([1,3])
# non-crossing
c1 = np.array([3,1])
c2 = np.array([5,3])

def judge(p1,p2,p3,p4):
    t1 = (p1[0] - p2[0]) * (p3[1] - p1[1]) + (p1[1] - p2[1]) * (p1[0] - p3[0])
    t2 = (p1[0] - p2[0]) * (p4[1] - p1[1]) + (p1[1] - p2[1]) * (p1[0] - p4[0])
    t3 = (p3[0] - p4[0]) * (p1[1] - p3[1]) + (p3[1] - p4[1]) * (p3[0] - p1[0])
    t4 = (p3[0] - p4[0]) * (p2[1] - p3[1]) + (p3[1] - p4[1]) * (p3[0] - p2[0])
    return t1*t2<0 and t3*t4<0

print judge(a1,a2,b1,b2)
print judge(a1,a2,c1,c2)
print judge(b1,b2,c1,c2)

```

```
True
False
True
```

`return`の行の不等号(<)を等号つき(<=)にすると、クロスじゃなくてぎりぎり重なっているのもOKになる
Install Japanese Language Package to Galaxy J3.

アメリカで主要で使うことになったgalaxy J3なのでデフォルトでは日本語が使えません。
以下のWebにある通り、日本語化パッケージを入れて、設定をしてあげると使えるようになりました。
http://zbuffer.hateblo.jp/entry/galaxy-s7-simfree-japanese

###1. 日本語キーボードとして「Google日本語入力」をインストール

###2. 最初、j3がマックに認識されずにハマったのですが、ヘルプにあった通り、携帯のUSB設定をChargingからMTP(Media Transfer Protocol)に変更したら、うまくマック側に認識される。

- ヘルプ画面
![スクリーンショット 2016-10-28 0.28.52.png](https://qiita-image-store.s3.amazonaws.com/0/141816/6b1515d8-64da-80f1-ea60-430550f14e95.png)

###3. adbコマンドで日本語に設定変更できました！
- 日本語有効化
![スクリーンショット 2016-10-28 0.30.35.png](https://qiita-image-store.s3.amazonaws.com/0/141816/ced2e03c-98fa-b35b-d9fd-4a0cb76e944e.png)
PIXI.jsでフラグメントシェーダ内でアルファ値を変更できない

 
PIXI.jsで写真を部分的に透過させるという処理をしたかったのですが、つまずいたのでメモ。

下記のようにただ単純に表示されたもののアルファ値を変更しようとしたのですがうまくいきませんでした。
 
```fragment.glsl
precision mediump float;

varying vec2 vTextureCoord;
uniform sampler2D uSampler;

void main(){
   vec4 color = texture2D(uSampler, vTextureCoord);
   color.w = 0.1;

   gl_FragColor = vec4(color);
}
```


原因はレンダラーの設定でした。  
gl_FragColorの透過を反映させる場合には、レンダラーのオプションでtranparentを指定する必要があるようです。

```app.js
this.renderer = new PIXI.autoDetectRenderer(this.width, this.height);

⬇︎

this.renderer = PIXI.autoDetectRenderer(this.width, this.height, {transparent: true});

```
lexima.vim を使っている人向け便利キーマップ

# Insert モード中のカーソル移動

Insert モード中にカーソル移動をしたい場合，以下のようなキーマップを設定すると，`CTRL-l` で undo を分割せず右へ移動できます．

```vim
inoremap <C-l> <C-g>U<Right>
```

# lexima.vim による括弧の自動補完

[lexima.vim](https://github.com/cohama/lexima.vim) は，閉じ括弧を自動で入力してくれるプラグインです．
しかし lexima.vim で括弧の補完をしている場合，上記の `CTRL-l` で閉じ括弧から抜けると，undo が分割されてしまうことがあります．

例えば， `cgn` で変更中に lexima.vim で補完された括弧から抜けるため `CTRL-l` を押した場合，ドットリピートで変更を繰り返すことが出来なくなってしまいます．

![ctrl-g_U.gif](https://qiita-image-store.s3.amazonaws.com/0/31403/46b4e293-f87e-9ffb-da5e-28207f4520b2.gif)

# lexima.vim の括弧補完を `cgn` で使うためのキーマップ

`cgn` で lexima.vim の括弧補完とカーソル移動を含む変更を，ドットリピートで繰り返すためのキーマップが以下になります．

```vim
inoremap <C-l> <C-r>=lexima#insmode#leave(1, '<LT>C-G>U<LT>RIGHT>')<CR>
```

以下の gif のように，ドットリピートでも補完された括弧がちゃんと入力されます．

![ctrl-g_U_lexima.gif](https://qiita-image-store.s3.amazonaws.com/0/31403/3af5d44e-b371-764a-e2ab-a488fe694f98.gif)

lexima.vim では，閉じ括弧を補完した後に同じ閉じ括弧を入力すると，重複せずに括弧の外にカーソルが移動する機能を持っています．

```
Before        Input         After
------------------------------------
(|)           )             ()|
```

（[lexima.vim の README](https://github.com/cohama/lexima.vim#basic-rules) より引用）

紹介したキーマップはこの機能を利用して `<C-l>` を入力した際に，以下のような条件に応じた移動を実現しています．

- カーソルの右隣が lexima.vim で補完された閉じ括弧の場合
    - `lexima#insmode#leave()` でカーソルを移動
- それ以外の場合
    - `<C-g>U<Right>` で移動

## 注意点

`lexima#insmode#leave()` は help に載っていないため，将来的にこの手法が使えなくなる可能性があります．

# 環境

- MacVim 8.0.46
- lexima.vim v1.2
cobraをWindowsで使ったときにはまった、たった一つのこと

# Cobraとは

GoでCLI作成の心強い味方
https://github.com/spf13/cobra

# どこではまったか

ある日私はWindowsでCobraを使って、CLIツールを作ろうと思い立った。しかし、どうしても、 `cobra init` する時に

```
Error: Cobra only supports project within $GOPATH
```

という無慈悲なエラーが出て動かない。
コードを見、エラー箇所を見つけ、printデバッグを試してみると、パスの比較をしているところで、パス名の最初のドライブレターが、片方は大文字、片方は小文字であった。

なるほどと思った私は、おもむろにコントロールパネルを開くと、「システム」>「システムの詳細設定」で、環境変数の指定でGOPATHの最初のcをCとし、心の平安を得たのであった。

# 教訓

*NIX環境を前提としているであろうツールをWindowsで動かすときはファイルパスが鬼門
raspberry pi 1 model bで、Ｃ

#概要
raspberry pi 1 model bで、Ｃやってみた。
#開発環境
raspberry pi 1 model b
raspbian 2016_09_23 jessie lite
#サンプルコード
```
#include<stdio.h>

int main(void) 
{
    int i;
    for (i = 1; i <= 100; i++)
    {
        if (i % 3 == 0 && i % 5 == 0)
        {
            printf("FizzBuzz\n");
        }
        else if (i % 3 == 0)
        {
            printf("Fizz\n");
        }
        else if (i % 5 == 0)
        {
            printf("Buzz\n");
        }
        else
        {
            printf("%d\n", i);
        }
    }
    return 0;
}
```
#サンプルコード
```
#include <stdio.h>

zundoko(void)
{
    char * str0 = "ズン";
    char * str1 = "ドコ";
    int r = rand() % 2;
    if (r < 1)
    {
        return str0;
    }
    else
    {
        return str1;
    }
}
int main()
{
    srand((unsigned) time(NULL));
    int i = 0;
    int j = 0;
    while (j < 1)
    {
        char * s = zundoko();
        printf("%s ", s);
        if (strcmp(s, "ドコ") == 0)
        {
            if (i == 4) j = 1;
            i = 0;
        }
        else
        {
            i++;
        }
    }
    printf("キ・ヨ・シ！\n");
}
```