OmniAICreator/Qiita-1.07M huggingface dataset:
StatsDをインストールしてみた (debパッケージ編)

# StatsD
StatsDとは、Node.js上で稼働するデータ収集デーモンである。
https://github.com/etsy/statsd

StatsDは公式にdebパッケージが存在しない。今回は、debパッケージ作成をした上でインストールする手順を記す。サーバはUbuntu 14.04を使用している。

# 依存パッケージのインストール
debパッケージ作成に必要なコンポーネントやNode.jsをインストールする。此処から先の作業はすべて`root`ユーザによる作業とする。

```shell-session
# apt-get install npm nodejs-legacy git nodejs devscripts debhelper
```

# StatsD取得

```shell-session
# mkdir ~/build
# cd ~/build
```

StatsDをGitHubから取得する。

```shell-session
# git clone https://github.com/etsy/statsd.git
```

# debパッケージ作成

```shell-session
# cd statsd
# dpkg-buildpackage
```

以下の通り、debパッケージが出来上がる。今日時点(2016/01/28)でのバージョンは、`0.7.2`らしい。

```shell-session
# cd ../
# ls -l
total 844
drwxr-xr-x 13 root root   4096 Jan 28 13:42 statsd
-rw-r--r--  1 root root  45070 Jan 28 13:43 statsd_0.7.2_all.deb
-rw-r--r--  1 root root   1368 Jan 28 13:43 statsd_0.7.2_amd64.changes
-rw-r--r--  1 root root    494 Jan 28 13:43 statsd_0.7.2.dsc
-rw-r--r--  1 root root 801078 Jan 28 13:43 statsd_0.7.2.tar.gz
```

# StatsDインストール

`dpkg`コマンドでインストールする。この際、`npm`コマンドで依存パッケージが一緒にインストールされる。もし、外部接続のためにProxyが必要な環境で実施するなら、事前に`export http_proxy="http://{myproxy}:{myport}"`みたいな感じでProxyの設定をしておく必要がある。

```shell-session
# dpkg -i statsd*.deb
Selecting previously unselected package statsd.
(Reading database ... 152932 files and directories currently installed.)
Preparing to unpack statsd_0.7.2_all.deb ...
Unpacking statsd (0.7.2) ...
Setting up statsd (0.7.2) ...
npm WARN package.json statsd@0.7.2 No README data
npm http GET https://registry.npmjs.org/winser/0.1.6
npm http GET https://registry.npmjs.org/generic-pool/2.2.0
...
```

Upstartの設定ファイルも導入されるためserviceコマンドで起動が可能である。

```shell-session
# service statsd status
statsd stop/waiting
# service statsd start
statsd start/running, process 29184
```

設定ファイルは、`/etc/statsd/localConfig.js`にある。

```shell-session
# cat /etc/statsd/localConfig.js
{
  graphitePort: 2003
, graphiteHost: "localhost"
, port: 8125
}
```

# モジュールを追加する方法

debパッケージを使ってインストールした場合、`node_modules`は`/usr/share/statsd/node_modules`に配置される。これについては、このdebパッケージの`postinst`から確認が可能である。
https://github.com/etsy/statsd/blob/master/debian/postinst#L7

よって、インストール後に追加でモジュールを追加する際には、このディレクトリに移動した上で、`npm install`コマンドを実行する。

例えば、`statsd-influxdb-backend`を追加する場合には、以下のようにコマンドを実行すればよい。

```shell-session
# cd /usr/share/statsd/node_modules
# npm install statsd-influxdb-backend
```
dovecotのエラー調査方法


postfix+dovecotの組み合わせでメールサーバーを構築することが度々あるのですが、
毎回どこかの設定でハマります（クラウドに移行したい・・・）
そんなときのエラー調査方法についてメモしておきます。

環境はRedhat系のディストリを想定しています。


## dovecotのエラー出力を詳細に

以下の設定を追記します。

```/etc/dovecot/dovecot.conf
auth_verbose = yes
auth_debug = yes
```

この設定を加えると、/var/log/maillogに出力されるdovecotのログが詳細になります。
メールアカウントの認証にMySQLをしているのですが、認証の際に発行されるSQLも出力されるので問題の特定が容易になります。
（今回の場合は、"webmaser"とタイポしてたのが原因でしたorz）


```
an 28 13:54:52 server dovecot: auth: sql(webmaser@myserver.jp,***.***.***.***): unknown user
Jan 28 13:54:54 server dovecot: auth: Debug: client out: FAIL#0112#011user=webmaser@myserver.jp
Jan 28 13:54:54 server dovecot: auth: Debug: client in: AUTH#0113#011PLAIN#011service=pop3#011lip=10.0.0.152#011rip=***.***.***.***#011lport=110#011rport=61052#011resp=<hidden>
Jan 28 13:54:58 server dovecot: auth: Debug: sql(webmaser@myserver.jp,***.***.***.***): query: SELECT password FROM mailbox WHERE username = 'webmaser@myserver.jp' AND active = '1'
Jan 28 13:54:58 server dovecot: auth: sql(webmaser@myserver.jp,***.***.***.***): unknown user
Jan 28 13:55:00 server dovecot: auth: Debug: client out: FAIL#0113#011user=webmaser@myserver.jp
Jan 28 13:55:00 server dovecot: pop3-login: Disconnected (auth failed, 3 attempts): user=<webmaser@myserver.jp>, method=PLAIN, rip=***.***.***.***, lip=10.0.0.152
```
zabbix運用におけるログ監視のちょっとしたTipsその1

zabbixはサーバリソースの監視以外でログ監視が利用出来ます。

特定の文字列に絞り込んだログ監視は得意ですが、集めたログ情報からアクション(メールを発報する等)を行う際に引っかかってしまう事があります。

例えば「/var/log/message」に対してログ監視を行う場合「error」をzabbixがアイテムで収集する設定をします。

`log[/var/log/messages,error|Error|ERROR]`

こんな感じでしょうか。勿論正規表現で書きだしても良いと思います。

その後、トリガーの条件式で
`"error"が含まれている行で"test","hoge"が入っているアイテムはトリガーの条件式としない`
を設定します。

`{log[/var/log/messages,error|Error|ERROR].iregexp(test|hoge)}#1`

こんな設定を適用するとします。

次にアクションにてこのトリガーを登録して、条件に引っかかったアイテムがあるとします。

すると
`"error"が含まれている行で"test","hoge"が入っていない」`
行が存在する場合、以下の表題でメールが受信出来ます。

`PROBLEM: ログ監視(/var/log/messages) on {ログ監視対象サーバ}`

ただ、この場合そのメールが来た後、以下の条件

`「"error"が含まれている行で"test","hoge"が入っている」行が存在する場合`

が当てはまる場合、次のメールが届いてしまいます。

`OK: ログ監視(/var/log/messages) on {ログ監視対象サーバ}`

これは「条件にあてはまればPROBLEMとして、そうでなければOK」という条件に当てはまるものによります。

これを回避したい場合以下の事を設定すれば「PROBLEM」のメールのみ発報されます。

設定内容としてはアクションの設定で

```
「アクションの実行条件」タブで

1.アクションの実行条件にて
→「トリガーの値」を「＝」と「障害」で設定

2.計算のタイプ
→「AND/OR」に変更
```
以上を行うだけです。

ログ監視の設定に悩まされてる方は参考にしてみては如何でしょうか。
NiftyCloud mBaaS + Swift ファイルストアへの読み書き


NiftyCloud mBaaSをSwiftから使う情報がほとんどないので、自分でやってみたメモ書き(その２)です。
UIImageのデータを読み書きしてみました。その他のファイルもNSDataに変換すれば大丈夫だと思います。

ファイルストアはこちら↓のiOSアプリのアプデートで使用予定です。
[OnWorkってこんなアプリです](http://meltingpot.co.jp/onwork_info/)
構築や管理の面倒なサーバサイドにNiftyCloud mBaaSを使って、プロントのアプリに集中できるのでいいですね。


##0.環境
　Xcode 8.2 + Swift 3
　[iOS SDK Version2.0.0] (https://github.com/NIFTYCloud-mbaas/ncmb_ios)

**Swift3用に書き直しました**
　
##1.準備
　1) iOS用SDKを組み込む
　2) bridge-headerを準備

```
//  NCMB-bridge-header.h

#ifndef NCMB_bridge_header_h
#define NCMB_bridge_header_h

#import "NCMB/NCMB.h"

#endif /* NCMB_bridge_header_h */
```

　3 ) AppDelegateにアプリケーションキー設定を追加

```language:Swift
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
 
        NCMB.setApplicationKey("YOUR_APPKEY",
            clientKey: "YOUR_CLIENTKEY")
        
        return true
    }
```


##2.ファイルストアからUIImageデータの読み出し

ファイルストアからファイル名を指定してUIImageを読みだして返す関数の例です。
ファイル名は拡張子なしの名称をもらい拡張子".png"を付加して読みだしていますが、使いやすいように修正してください。
読み出しに失敗するとnilを返します。


```language:Swift3
/// Read ImageData to File Store
///
/// - parameter : name of data as String
/// - returns:  image with UIImage

func getStampImage(_ name:String) -> UIImage? {
    
    var image:UIImage? = nil
    var imageData:Data?
    let fileName = name + ".png"
   
    let file:NCMBFile = NCMBFile.file(withName: fileName ,data: nil ) as! NCMBFile
        
    do {
        imageData = try file.getData()
    } catch  let error1 as NSError  {
        return image
    }
    image = UIImage(data: imageData!)
    
    return image
    
}

```


##3.ファイルストアへUIImageデータの追加

ファイルストアへファイル名を指定してUIImageを書き込む関数の例です。
ファイル名は拡張子なしの名称をもらい拡張子".png"を付加して書き込んでいますが、使いやすいように修正してください。
＊ACLは設定しなくても大丈夫です。

 __* ファイル名には"/"を使えませんが、誤って使用してしまうと、エラー種別が”E404002：該当サービスなし”となりびっくりします。
 私はファイル名を日付データにしようとして"/"を使ってしまいこのエラーとなり、原因がわからずハマりました。
 せめて”E400004：フォーマットが不正”が出てくれれば。。。__



``` language:Swift3
/// add ImageData to File Store
///
/// - parameter : image as UIImage, name of data as String
/// - returns:  nothing
func setStampImage(_ image:UIImage,name:String) {    
    // imageをNSDataに変換
    let imageData:Data = NSData(data: UIImagePNGRepresentation(image)!) as Data
    let fileName = name + ".png"
    let file:NCMBFile = NCMBFile.file(withName: fileName ,data: imageData) as! NCMBFile
    let acl = NCMBACL()
    // 全員に読み書き可とする
    acl.setPublicReadAccess(true)
    acl.setPublicWriteAccess(true)
    file.acl = acl
    
    var error1 : NSError?
    file.save(&error1)
    if error1 != nil  {
        print("Image data save error : ",error1!)
    }
}

```

##4.ファイルストアの更新

ファイルストアはファイル名を指定して書き込んだ場合に既存のファイルを上書きするようです。
上の関数でそのまま更新できました。


##5.その他
ご意見ご要望等あればコメントください。
会員管理については随時投稿予定です。
Struts2で自作の拡張タグを作る

HTMLやJSPのようなタグを独自に作る事ができる。
環境はStruts2で試しています。

## 現在時刻を表示するサンプル

### JSP
	<%@ page language="java" contentType="text/html; charset=UTF-8" pageEnco	ding="UTF-8"%>
	<%@ taglib prefix="s" uri="/struts-tags" %>
	<%@ taglib prefix="t" uri="/WEB-INF/mytaglib.tld" %>
	
	<html>
	<body>
	<t:test/>
	</body>
	</html>
### TLD
	<?xml version="1.0" ?>
	
	<taglib>
	    <tlib-version>1.1</tlib-version>
	    <jsp-version>2.1</jsp-version>
	    <short-name>HelloTag</short-name>
	    <tag>
	        <name>test</name>
	        <tag-class>mytaglib.HelloTag</tag-class>
	      <body-content>EMPTY</body-content>
	    </tag>
	</taglib>

### java

	package mytaglib;
	
	import java.io.IOException;
	import java.text.SimpleDateFormat;
	import java.util.Date;
	
	import javax.servlet.jsp.JspException;
	import javax.servlet.jsp.tagext.SimpleTagSupport;
	
	public class HelloTag extends SimpleTagSupport{
	
	    public void doTag() throws JspException, IOException {
	        String string = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
	        getJspContext().getOut().print(string);
	    }
	}
JavaでExcelファイルを作成する

JavaでExcelファイルを作成した時のメモ。
Apache-poiで使うクラスがExcelのバージョンによって異なる。

「Excel 2003」まで：HSSFWorkbook
「Excel 2007」以降：XSSFWorkbook

---
    import java.io.FileOutputStream;
    import java.io.IOException;

    //import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;

    public class Sample{
      public static void main(String[] args){
          //HSSFWorkbook workbook = new HSSFWorkbook();
          XSSFWorkbook workbook = new XSSFWorkbook();

          workbook.createSheet("test");

          FileOutputStream out = null;
          try{
              //out = new FileOutputStream("sample.xls");
              out = new FileOutputStream("sample.xlsx");
              workbook.write(out);
          }catch(IOException e){
              System.out.println(e.toString());
          }finally{
          try {
            out.close();
          }catch(IOException e){
            System.out.println(e.toString());
          }
        }
      }
    }
Cent OS 6で手軽にPython 2.7を使う方法


インストール
======

[Software Collections](https://www.softwarecollections.org/en/)を使うと比較的新しいソフトウエアを使うことが出来ます．たとえば Python 2.7 を Cent OS 6 で使いたいときには以下のようにします．

```bash
sudo yum install centos-release-scl-rh
sudo yum install python27
```

使用する
=====

Software Collectionsはインストールしただけでは利用可能にはなりません．実際に利用するには以下のコマンドを実行します．

```bash
scl enable python27 bash
```

こうすることで新しいbashが起動され，Python 2.7.8が使えるようになります．もし，常に使える状態にしておきたいときには`source /opt/rh/python27/enable`を`.bashrc`に書いておくとよいでしょう．
selectboxにoption要素の追加

ポップアップから入力した値を親画面のselectにoptionとして追加する部分で
はまったので備忘録も兼ねてメモ


#例）value=1 text=あ　のoptionを追加する
chromeでは以下のように記述すればうまくいったけど
IEで確認すると親画面にappendしてくれなかった･･･

```js:test_chrome.js
window.opener.$('[name=selectbox]').append(function(){
        //値が重複しているならば追加しない
		if(window.opener.$('[name=selectbox] option[value = 1]').size() == 0) {
			return $("<option>").val("1").text("あ");
		}
```

調べてみたらIEで要素をappendしようとするのがよくないらしく
以下のように修正したらうまく動きました。
（jQuery素人なので意味なくfunction使っていたのでそこも切り取り）

```js:test_ie.js
if(window.opener.$('[name=selectbox] option[value = 1]').size() == 0) {
		var a = '<option value ="1">あ</option>'
		window.opener.$('[name=selectbox]').append(a);
	};
```
[Linux][kernel] カーネルモジュールの情報を確認する方法まとめ

`built-in kernel module` と `loadable Kernel Module` の確認方法

# built-in kernel modules
## built-in kernel modulesの一覧を確認

```bash:組み込みカーネルモジュールの一覧を確認
$ cat /lib/modules/$(uname -r)/modules.builtin
```

## built-in kernel moduleのパラメータを確認
`/sys/module/<module_name>/parameters/*` にて確認できる。

```bash:例「bluetooth」
$ ls /sys/module/bluetooth/parameters
disable_ertm  disable_esco  enable_hs

$ cat /sys/module/bluetooth/parameters/*
N
N
N
```

## 有効なカーネルコンフィグを確認

```bash
$ grep "=y" /boot/config-$(uname -r) | less
```

TODO:
`/boot/config-$(uname -r)` のファイルが作られない場合がある。KConfigの設定で有効にする？

### 参考
+ [linux - Understanding /boot/config file - Stack Overflow](http://stackoverflow.com/questions/14587251/understanding-boot-config-file)

# loadable Kernel Module
依存関係情報は `/lib/modules/$(uname -r)/modules.dep` に記載されている。

## 1. 有効な loadable Kernel Module を確認

```bash
# 有効な全モジュールと依存関係を表示
$ lsmod

or 

# 指定したモジュールの情報を表示
$ modinfo <module_name>
```

```bash:modinfo実行例
$ modinfo bluetooth
filename:       /lib/modules/3.8.0-44-generic/kernel/net/bluetooth/bluetooth.ko
alias:          net-pf-31
license:        GPL
version:        2.16
description:    Bluetooth Core ver 2.16
author:         Marcel Holtmann <marcel@holtmann.org>
srcversion:     69F404CC8C537406DC6169A
depends:
intree:         Y
vermagic:       3.8.0-44-generic SMP mod_unload modversions
parm:           disable_esco:Disable eSCO connection creation (bool)
parm:           disable_ertm:Disable enhanced retransmission mode (bool)
parm:           enable_hs:Enable High Speed support (bool)
```

## 2. loadable Kernel Module のロード
```bash
# モジュールのロード（依存関係を考慮する）
# /lib/modules/$(uname -r)/kernel/drivers 以下から <module_name> を読み込み
$ modprobe <module_name>

or

# モジュールのロード（依存関係は考慮しない）
$ insmod <module_name>
```

## 3. loadable Kernel Module のアンロード

```bash
# モジュールのアンロード（依存するモジュールもアンロードを行う）
$ modprobe -r <module_name>

or

# モジュールのアンロード（依存関係は考慮しない）
$ rmmod <module_name>

# モジュールのアンロード（依存するモジュールもアンロードを行う）
$ rmmod -r <module_name>
```

# 関連
[Device Tree についてのまとめ - Qiita](http://qiita.com/koara-local/items/ed99a7b96a0ca252fc4e)
[カーネルモジュールのコンソールへのログ出力抑制(printkのログレベル変更) - Qiita](http://qiita.com/koara-local/items/12d10e0e6c6499640d07)

# 参考
[How to find information about built-in kernel modules on Linux - Ask Xmodulo](http://ask.xmodulo.com/find-information-builtin-kernel-modules-linux.html)
[Linux ローダブル・カーネル・モジュールの徹底調査](https://www.ibm.com/developerworks/jp/linux/library/l-lkm/)
[Linuxカーネルモジュールの管理について | OpenGroove](http://open-groove.net/lpic/linux-kernel-modules/)
[カーネルモジュール - ArchWiki](https://wiki.archlinuxjp.org/index.php/%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB)
[1.カーネルとカーネルモジュール(第1章カーネル:基本管理コースII)](https://users.miraclelinux.com/technet/document/linux/training/2_1_1.html)
[kernel - What's the difference between insmod and modprobe? - Ask Ubuntu](http://askubuntu.com/questions/20070/whats-the-difference-between-insmod-and-modprobe)
[Linuxドライバのはなし｜Wireless・のおと｜サイレックス・テクノロジー株式会社](http://www.silex.jp/blog/wireless/2015/08/linux.html)
#if 1 > 0以外は真? > #if 2 / #if 3141592

Grenningの本でも記載されている`#if 1`。

ふと思ったのが、「1以外の数値の場合は true なのか false なのか」。

```txt:動作確認
C++ Builder XE4
```

http://ftc.suki.net/tpb/saruc09.html
> `#if 定数式	' #if 1→真(0以外)「文の並び」をコンパイルする。`

```Unit1.cpp
#if 0
	ShowMessage(L"0");
#endif

#if 1
	ShowMessage(L"1");
#endif

#if 2
	ShowMessage(L"2");
#endif

#if 3141592
	ShowMessage(L"3141592");
#endif
```

0以外はすべてメッセージが表示された。

Qiitaの表示でも`#if 0`だけコメントの色になっている。
カーネルアップデート後にVirtualBoxの共有フォルダが機能しなくなった場合の対処方法


Vagrantなどで下手にカーネルをアップデートすると，共有フォルダが機能しなくなるのでその場合の対処方法．

Cent OS 6の場合
=====

以下のコマンドをゲスト内で実行してカーネルモジュールを再コンパイルします．

```bash
sudo /etc/init.d/vboxadd setup
```

その後，再起動します．

Cent OS 7の場合
=======

バージョンは適宜書き換えてください．もし，ここに`vboxadd`が無い場合は，`/etc/systemd/system/multi-user.target.wants/vboxadd.service`をみると`ExecStart=`の後ろに書いてあるはずです．

```bash
sudo /opt/VBoxGuestAdditions-5.0.12/init/vboxadd setup
```

自動的に再コンパイルを実行する
========

そもそもカーネルアップデートの度に再コンパイルするのは面倒なので，DKMSを用いて自動化します．DKMSはEPELリポジトリに入っているので，こちらを有効化してからインストールします．

```bash
sudo yum install epel-release
sudo yum install dkms
```
squidを透過プロクシーで使っていると、CDNを全くcacheしないんだけど

# squidを透過プロクシーで使っていると、CDNを全くcacheしないんだけど

# きっかけ

squidを利用して、リモートのCDNサーバーに置かれたzipファイルやdebなどをローカルに
キャッシュしようとしても毎回フェッチするので、おかしいなと感じ少し調べてみました。

# 産業で説明

CDN（コンテンツ配布）サーバーは負荷分散のためにDNSラウンドロビンなどを行なっていて
１つのURLに対して複数のIPアドレス（サーバー）を持っています
なので、squidの動作上そうなります。(リクエストしたIPアドレスと、URLから引いたIPアドレスが一致しない)

# 実際のところ何が起きてる？

src/client_side_request.cc: 556
 ClientRequestContext::hostHeaderIpVerify(const ipcache_addrs* ia, const DnsLookupDetails &dns)
  ・・・
    debugs(85, 3, HERE << "FAIL: validate IP " << clientConn->local << " possible from Host:");
    hostHeaderVerifyFailed("local IP", "any domain IP");
 }

OUCH!

同じファイルを何回ダウンロードしようが、DNSのラウンドロビンのIPアドレス全部をガチャ引きしようが、
透過プロクシーでsquidを叩く限り、このCDNサーバーのキャッシュオブジェクトは生成されません。

同一URLに対して、
運良く、端末が引いたIPアドレスとsquidが引いたIPアドレスが同じだったときだけ生成されます。

そして、運良く、もう一度端末が引いたIPアドレスでアクセスが発生し、なおかつその時点でもsquidが引いたIPアドレスと一致した場合に限りCACHE HITになります。（ベリーレアIPアイテム）


# 実験


 #if 0
     hostHeaderVerifyFailed("local IP", "any domain IP");
 #else
     http->request->flags.hostVerified = 1;
     http->doCallouts();
 #endif

//ぃぃのかょこんなことして

 HIT OKでした。

# 真面目に対策を考える
- 許された サイトURLだけ、IPアドレス不一致を許すような実装。
- http-proxyポートも開いておいて、キャッシュしたい端末には、全部proxyを設定する。

http_port 3128
http_port 3129 intercept

- iptablesでLAN側80番portリクエストをlocalhost:3129 にNATする (必要ならば)
- http-proxy は GWサーバーの3128をアナウンスする

# 補足
http-proxyモードではCDNの配布ファイルをちゃんとキャッシュしてくれます。
これは、squidに渡されるのがURLのみなので、squid内部でdnsを引きに行き、dnsキャッシュもsquid側にあるので、url->ipの一貫性があるからです。


# squid3 デバッグメッセージの出し方

 # squid3 -k debug
root権限でこれをやると、以後、/var/log/squid3/cache.log にdebugメッセージが大量に出る
 # squid3 -k reconfigure
で戻せます
Node.jsでjavaを呼びだす時のトラブル及び対策

# 導入
node.jsのマルチプロセスモジュール[Child Process](http://nodejs.jp/nodejs.org_ja/api/child_process.html)で新たなプロセスを作成する時、主に`spawn`、`exec`、`fork`というメソッドを使用する。
しかし`exec`はプロセス間の通信は基本できないとされている。そして`fork`はnode.jsのみ使用できるので、javaの子プロセスを立ち上がり、しかも通信するには`spawn`しか使えない。
# Round 1 : node.jsとclassファイルが同じフォルダにある
その場合、ことは極めて簡単に済ませられる。

* 1 まずはjava一個作る


```java:test.java
class test {
       public static void main(String argv[]){
            //まずinitialパラメータを受信する
            for ( int i = 0; i < argv.length; i++ ){
                System.out.println("argv[" + i + "] = " + argv[i] );
            }
            //繰り返して入力を待ち、処理する
            while(true){
           		System.out.println("input sth.");
           		Scanner input = new Scanner(System.in);
           		String s = input.next();
           		if (s.equals("break")){
           			break;
           		}
           		System.out.println("s = "+s);         		
           }   
       }
    }
```

+ 2 そしてjavaをコンパイルし、テストしてみる

windows使っているんだ！文句あっか！？（笑）

```
C:\test\your_java_test>javac test.java
C:\test\your_java_test>java test Hello World
argv[0] = Hello
argv[1] = World
input sth.
test\n
s = test
input sth.
hello\n
s = hello
・・・
```

+ 3 同じフォルダの中に、親プロセスにあたるjsを作る

```js:test_java.js
var child = require('child_process');
//pipeを使って、プロセス間通信を行う
//引数'test'はclass名、no

var java = child.spawn( 'java', ['test','Hello','World'],{stdio:[ 'pipe',null,null, 'pipe' ]});

//受信するたびに、内容を返す
java.stdout.on('data', function(data){
    //toString()を使わないと、バイナリのバッファー内容が返される
    console.log("[java]"+data.toString());
});

//2秒間一回、親プロセスから子プロセスへ送信
setInterval(function () {
        //送信内容は必ず"\n"で終わらせる
	java.stdin.write("Hello\n");
},2000);
```

+ 4 そのjsを回してみる

```
C:\test\your_java_test>node test_java.js
[java]argv[0] = Hello
argv[1] = World
[java]
input sth.

[java]s = Hello
input sth.

[java]s = Hello
input sth.

・・・

```

# Round2 : 別のフォルダからjavaを呼び出す
+ 1 先ほど作成したjsを一個上のフォルダにコピーしてpathを修正して、動かしてみると

```
events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: spawn ENOENT
    at errnoException (child_process.js:1000:11)
    at Process.ChildProcess._handle.onexit (child_process.js:791:34)
```

nodeかjavaかどちらが怒ったぜ。

+ 2 トラブルシューティングしてみる

```
C:\test>java ./your_java_test test
Error:java error cannot find main class
```
と、やっぱりjvmが怒ったみたいだね…

いろいろ調べてみると、`-classpath`入れるといいらしい。

```
C:\test>java -classpath ./your_java_test test
input sth.
aaa\n
s = aaa
```
では、jsの中身も改造してみよう

```js:test_java2.js
//to test how to run java in different dir

var child = require('child_process');
var path = __dirname+'/'+'test_java';
console.log(path)
var java = child.spawn( 'java', ['-classpath',path,'test','Hello','World'],{stdio:[ 'pipe',null,null, 'pipe' ]});
// $ java -classpath [yourpath] [classname]
java.stdout.on('data', function(data){
    console.log("[java]"+data.toString());
} );

setInterval(function () {
	java.stdin.write("Hello\n");//must end by "\n"
},2000);

```
動かしてみると、

```
C:\test>node test_java.js
C:\test/your_java_test
[java]argv[0] = Hello
argv[1] = World
[java]
input sth.

[java]s = Hello
input sth.

・・・

```
と、問題解決。
GPUImageの連結をわかりやすくするオペレータを定義する

#GPUImageの問題点
`addTarget`というメソッドがなんか分かりにくい。
具体的には以下のようになっている。

```swift
GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack];
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;

GPUImageFilter *customFilter = [[GPUImageFilter alloc] initWithFragmentShaderFromFile:@"CustomShader"];
GPUImageView *filteredVideoView = [[GPUImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, viewWidth, viewHeight)];

// Add the view somewhere so it's visible

[videoCamera addTarget:customFilter];
[customFilter addTarget:filteredVideoView];

[videoCamera startCameraCapture];
```
https://github.com/BradLarson/GPUImage#filtering-live-video より引用

videoCameraに対してcustomFilterをaddTargetしてそのcustomFilterに対してfilteredVideoViewをaddTargetしている。
わかればどうってことはなくて、

<img width="710" alt="スクリーンショット 2016-01-28 12.34.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/24979/71e9825e-1243-5672-0c98-2df1ca447356.png">

http://www.slideshare.net/kasajei/for-saminar123mtliphonecameran?ref=http://sssslide.com/www.slideshare.net/kasajei/for-saminar123mtliphonecameran　より引用

という感じになっている。
ただ、この図をコード上で非常に想像しにくい。
特に途中で分岐した場合や合流した場合に非常にごちゃごちゃする

そこで…

```swift

infix operator => { associativity left precedence 80 }

func => <T where T:GPUImageInput, T:GPUImageOutput>(left: GPUImageOutput,right: T) -> GPUImageOutput {
  left.addTarget(right)
  return right
}
func => <T:GPUImageInput>(left: GPUImageOutput,right: T) {
  left.addTarget(right)
}

```

を定義する。
仕組みは簡単で、`=>`オペレータでaddTargetし、GPUImageOutputが返される場合は連結出来るようにするというもの。これさえあれば、

<img width="699" alt="スクリーンショット 2016-01-28 12.45.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/24979/0ffe9cc9-a707-3040-0af9-8d5043f8fe4c.png">
http://sssslide.com/www.slideshare.net/kasajei/for-saminar123mtliphonecameran より引用

のような複雑なフィルタリングも

<img width="468" alt="スクリーンショット 2016-01-28 12.45.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/24979/c8e6194a-3c7d-93d9-0e33-ddec9ad3bc20.png">

このように図のまんまコードを組む事ができる。


#最高
【Unity】ParticleSystemのsortingOrderをスクリプト側から変更する

※この記事で使っているUnityのバージョンは Unity5.2.1p3 です。 

#ParticleSystemコンポーネントのsortingOrderを変更する
ParticleSystemのsortingOrderを変更したい場合、Rendererを取得してsortingOrderを変更するといいみたいです。
##ソースコード
```
using UnityEngine;
using System.Collections;
using System.Reflection;

public class ParticleSystemWriter : MonoBehaviour
{
  void Awake()
  {
    var ps = this.gameObject.GetComponent<ParticleSystem>();
    var r = ps.GetComponent<Renderer>();

    // sortingOrderに-1234を代入
    r.sortingOrder = -1234;
  }
}
```

##実行結果
適用前
![image](https://qiita-image-store.s3.amazonaws.com/0/44288/a87bf6a7-2ee4-22d2-529e-c4bbff49c189.png)

適用後
![image](https://qiita-image-store.s3.amazonaws.com/0/44288/f7d17639-d1b8-d4ae-dd06-19dd007b8770.png)

sortingOrderに-1234が代入されました.

<br>

#パーティクルエディタウィンドウのsortingOrderを一括変更する

##ソースコード
```
using UnityEngine;
using System.Reflection;

public class ParticleSystemWriter : MonoBehaviour
{
  void Awake()
  {
    this.Set(this.transform.GetComponent<ParticleSystem>());
    foreach (Transform t in this.transform)
    {
      var ps = t.GetComponent<ParticleSystem>();
      this.Set(ps);
    }
  }
  void Set(ParticleSystem ps)
  {
    var r = ps.GetComponent<Renderer>();

    // sortingOrderに-1234を代入
    r.sortingOrder = -1234;

  }
}
```
##実行結果
適用前
![image](https://qiita-image-store.s3.amazonaws.com/0/44288/e89045df-a105-3866-f396-739bbbaf5124.png)


適用後
![image](https://qiita-image-store.s3.amazonaws.com/0/44288/186e7d43-881a-b171-2736-532435c694aa.png)
全てのsortingOrderに-1234が代入されました.
yield return www みたいに書きたい

Unityでcoroutineを使用した際
whileを使用して待ち処理を作ることがよくあります。

```test1.cs
class ABC {
    public bool isBusy;
}

IEnumerator Hoge()
{
    ABC a = new ABC();
    while(a.isBusy) {
        yield retun null;
    }
}
```

WWWクラスを使用した際は

```test2.cs
IEnumerator Hoge()
{
    WWW www = new WWW();
    yield return www;
}
```

…なんかズルい…

自分が作ったclassでもwhile使わずに書きたい！

ググったところ Unity5.3から使える
[CustomYieldInstruction](http://blogs.unity3d.com/jp/2015/12/01/custom-coroutines/)を使用すれば実装出来ました。

CustomYieldInstructionの**keepWaiting**プロパティを
オーバーライドして条件を書けばOKでした。

```test3.cs
class ABC : CustomYieldInstruction {
    public bool isBusy;
    public override bool keepWaiting {
        get { return isBusy; }
    }
}

IEnumerator Hoge()
{
    ABC a = new ABC();
    yield return a;
}
```

便利！簡潔！
Node.jsからChatworkのタスクを追加するメモ


Node.jsからChatwork APIを使ってタスクを追加してみます。

ドキュメントはこちらです。

http://developer.chatwork.com/ja/endpoint_rooms.html#POST-rooms-room_id-tasks

過去に書いた記事も参考にしてます。

>ChatWorkの定期連絡を自動化！チャットワークAPIを使って業務を効率化してみた。
http://liginc.co.jp/web/programming/node-js/123719


## 実装

es2015です。

[botkit](https://github.com/howdyai/botkit)の起動の仕方に合わせてみました。
tokenとかはいる場合はこの起動の仕方いいですね。

```chtask.js
'use strict';

if (!process.env.chtoken) {
    console.log('Error: Specify token in environment');
    process.exit(1);
}

let request = require('request');
const ROOM_ID = '43484166';

let task = {
  body: 'test',
  limit:1385996399,
  to_ids: '12326,1138752',
}

let options = {
    url: `https://api.chatwork.com/v1/rooms/${ROOM_ID}/tasks`,
    headers: {
        'X-ChatWorkToken': process.env.chtoken 
    },
    form: task,
    json: true
};

request.post(options, (error, response, body) => {
    if (!error && response.statusCode == 200) {
      console.log(body);
    }else{
      console.log('error: '+ response.statusCode);
    }
});
```

```bash
$ chtoken=xxxxxxxxx node chtask.js
```

ポストするデータはこんな感じです。

* body: タスクの本文
* limit: タスクの期限 (unixtimeなので変換かませないと)
* to_ids: 誰にタスク追加するか (ユーザーidを他のAPIで調べましょう)


こんな感じです。
![](https://i.gyazo.com/11276c818db6dc0cedb327350cbed68d.png)

無事にタスク追加できました。

誰にタスク追加するかを指定する必要があるのでメンバーリストのAPIと組み合わせるといいかもしれません。
arduinoでcan

#概要
arduinoでcanやってみました。
#写真
![can.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/8658c1b3-8355-2b7b-3f20-2b021f619977.jpeg)
#回路図
![can1.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/62bba9bd-57bd-7d84-0fed-76ddd9b0edb2.jpeg)
#uno写真
![MVC-011S.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/4ab393d9-0e80-0265-9417-28984388f586.jpeg)
#nano写真
![MVC-012S.JPG](https://qiita-image-store.s3.amazonaws.com/0/18104/8d9ec1db-4753-c91b-8471-eb268e751b4c.jpeg)
#サンプルコード
```
#include <SPI.h>
#include "mcp_can.h"
const int SPI_CS_PIN = 10;
MCP_CAN CAN(SPI_CS_PIN);
void setup()
{
    Serial.begin(115200);
START_INIT:
    if (CAN_OK == CAN.begin(CAN_500KBPS))
    {
        Serial.println("CAN BUS Shield init ok!");
    }
    else
    {
        Serial.println("CAN BUS Shield init fail");
        Serial.println("Init CAN BUS Shield again");
        delay(100);
        goto START_INIT;
    }
}
unsigned char stmp[8] = {
	0,
	1,
	2,
	3,
	4,
	5,
	6,
	7
};
void loop()
{
    CAN.sendMsgBuf(0x00, 0, 8, stmp);
    delay(100);
}
```
#サンプルコード
```
#include <SPI.h>
#include "mcp_can.h"
const int SPI_CS_PIN = 10;
MCP_CAN CAN(SPI_CS_PIN);
void setup()
{
	Serial.begin(115200);
START_INIT:
	if (CAN_OK == CAN.begin(CAN_500KBPS))
	{
		Serial.println("CAN BUS Shield init ok!");
	}
	else
	{
		Serial.println("CAN BUS Shield init fail");
		Serial.println("Init CAN BUS Shield again");
		delay(100);
		goto START_INIT;
	}
}
void loop()
{
	unsigned char len = 0;
	unsigned char buf[8];
	if (CAN_MSGAVAIL == CAN.checkReceive())
	{
		CAN.readMsgBuf(&len, buf);
		unsigned char canId = CAN.getCanId();
		Serial.println("-----------------------------");
		Serial.println("get data from ID: ");
		Serial.println(canId);
		for (int i = 0; i < len; i++)
		{
			Serial.print(buf[i]);
			Serial.print("\t");
		}
		Serial.println();
	}
}
```
JupyterでRを使う。

IPythonからいつの間にか名前を変えていたJupyterですが、名前を変更した理由が「Python以外にも対応してきたし、IPythonって名前はおかしいんじゃね！？」ということらしい。
その恩恵にあやかって、Jupyter上でRを使って開発できるように環境を作る。

作業環境

* MacOS X Yosemite
* Jupyter 1.0.0 (Python 3.4.4 :: Anaconda 2.4.1)
* R 3.2.2

Jupyterはpyenvから入れたAnacondaに入っていたもので、RはHomeBrewを使って入れました。

以上の状態でRを立ち上げてコンソールに入り、以下のようにコマンドを実行。

**追記 2017/07/10 13:46**

コメントでインストールコマンドが古くなっていると頂いたので、新しいものに修正

```R
> install.packages(c('repr', 'IRdisplay', 'evaluate', 'crayon', 'pbdZMQ', 'devtools', 'uuid', 'digest'))
> devtools::install_github('IRkernel/IRkernel')
> IRkernel::installspec()
```
**追記ここまで**

~~> install.packages(c('repr', 'IRkernel', 'IRdisplay'), repos = c('http://irkernel.github.io/', getOption('repos')))~~
~~> IRkernel::installspec()~~

Jupyter上でRを動作させるためのカーネルを入れて設定するよ！という手順。

後は、

```
$ jupyter notebook
```

からJupyterを起動して、右上の新規ファイルメニューに「R」が追加されているのが確認できたら完了です。

### ※ ちょっと補足

もう一つの方法として「PythonにRをパッケージとして突っ込んで動作させる（要Anaconda）」という手順もあります。

```
$ conda install -c r r-essentials
```

これでも確かにできるのですが、Rへの追加パッケージインストールがうまくできないので僕はやめました。
コンソールでRを起動してもパッケージとしてインストールしたRが起動せず、コンソール上からもパッケージを追加できない状態になりました。（もしかしたら、すでにMacにRをインストールしていたのが原因か？）
オレオレOSS評価指標


自分がライブラリ(主にOSS)を選定するとき主に何を基準に選んでいるかを書いてみる。

## 機能要件

- パフォーマンス
    - 必要としているパフォーマンスを最小構成またはチューニングした状態で出せているか
    - 特定の状態の時に極端に性能劣化するケース等はないか
- 機能
    - 必要としている機能があるか
        - ない場合代替手段はあるか
        - その代替手段は一般的な方法か

## 非機能要件

- コミュニティ規模
    - コミュニティが存在するか(個人プロジェクトかどうか)
    - メイン開発者が継続出来なくなった場合でも代役になるようなコミッタがいるか(GitHubならContributionグラフを見る)
- コミュニティの多様性
    - 年齢層が若すぎないか
    - 年齢層が高すぎないか
    - 特定の利用者層に偏ってないか(公平性が保たれているか)
    - 新規参入者に対して開かれているか
- コミュニティの透明性
    - GitHubで誰でもコードを閲覧出来るか
    - GitHubだけでなくメーリングリスト、IRCなど複数の報告チャネルが利用者に対して開かれているか
- コミュニティ運営の安定性
    - issue(バグ)の数、Openになってるバグの数、Open/Close比
        - Openになってるissueに対してCloseの件数が少なすぎないか
        - ざっくり言ってCloseした件数に対してOpenになっている件数が1/10以上を超えるとCode Smellが漂ってる気がする…
    - PullRequestが適切に処理されているか
        - 大量のPRが放置されていないか
- 開発者の経歴
    - GitHubのプロフィールがあれば確認(インタビュー記事でもOK)
    - 普段使ってる言語
    - 得意な領域
    - 属しているコミュニティ
    - 他に大きなプロジェクトがあればコミュニティ運営はうまくいっているか
    - 思想が偏ってないか
- コミッタの経歴
    - 開発者の経歴と同じ
- プロジェクトの継続性
    - コミットの回数が安定して継続しているか
    - 直近でコミットの回数が落ちてきていないか
- ドキュメントの充実性
    - 公式サイトは誰が見ても分かりやすいか
    - ドキュメントがちゃんとメンテされているか
    - 最新バージョンだけでなく旧バージョンのドキュメントもメンテされているか
- ライブラリ名のググラビリティ
    - 短すぎないか(例: go等)
    - 長すぎないか(8文字以上は体感厳しい)
    - 一般名詞すぎないか(例: cake等)
    - 短すぎたり一般名詞だった場合補完するキーワードが推奨されているため問題ないかどうか(golang, cakephp等）
- ライセンスはビジネス要件と一致するか
    - ソースの明示が必須要件だった場合問題が発生しないか
- 採用事例
    - 採用時のアーキテクチャ
    - 採用規模
    - 実際に発生した問題
    - リプレースの予定はあるか
    - ワンオフではなく継続的に採用されているか
- サポート体制
    - LTSはあるか
    - 旧バージョンのサポート期間は明示されているか
- 社内での実績
    - 実績のある言語で実装されているか
    - 既存システムへの導入が容易か
    - 実績のない場合導入含めて自分で面倒見れそうか
- ロックイン
    - ライブラリ独自の機能を使う場合他のツールの組み合わせで代替可能か
    - なんらかの理由でライブラリが使えなくなった場合他のライブラリへのリプレースコストが導入メリットを上回らないか
- エコシステム
    - ライブラリを利用するためのエコシステムはあるか
- スケーラビリティ
    - スケールアウトは可能か
        - スケールアウト時にオンラインシステムを停止する必要があるか
        - スケールアウト時に極端に性能劣化しないか
        - アップグレード時にシステム全体を停止する必要はあるか

## まとめ

OSSは表面的なコストが評価しづらいため自然と非機能要件の方が多くなる
Javaのベンチマークツール、JMHにテストコードを書いて計測してみる


JMHの使い方をメモしておく。
※使ったものしかメモしていないので注意。

導入の方法は[Javaのベンチツール、JMHの導入](http://qiita.com/deaf_tadashi/items/8bb4a76f3116ef195296) を参照。

# テストしたいコードを書く
導入で自動生成されたクラス(MyBenchmark.java)にメソッド、testMethod()があるのでそこにテストコードを追記する。
テストコードの例は [Javaのマイクロベンチマークツール「JMH」](http://acro-engineer.hatenablog.com/entry/2013/11/07/120606)  を参照。


## 備考
- メソッドに @Benchmarkアノテーションが付与されていると、テスト対象と判定される。
[Javaのマイクロベンチマークツール「JMH」](http://acro-engineer.hatenablog.com/entry/2013/11/07/120606) では @GenerateMicroBenchmark と記載されているが、その後のバージョンアップでアノテーションが変わった模様。
- メソッド名は日本語では付けられない模様。起動時にエラーになる。
- 処理順はメソッド名のアルファベット昇順。

# main()メソッドを実装する
IDEから実行したい場合は必須。
コマンドプロンプトから実行する場合は、テスト対象のクラスが複数あるとき必須

```java
    public static void main(String... args) throws RunnerException {

        Options opt = new OptionsBuilder().include(実行したいクラス.class.getSimpleName()).warmupIterations(5)
                .measurementIterations(5).forks(2).build();

        new Runner(opt).run();
    }
  ```
- warmupIterations()メソッドの引数はウォーミングアップ回数
- measurementIterations()メソッドの引数は計測を繰り返す回数
- forks()の引数は計測全体の繰り返し数。

※[Javaのマイクロベンチマークツール「JMH」](http://acro-engineer.hatenablog.com/entry/2013/11/07/120606) に記載されている内容から書き方が変わっているので注意。

# コンパイルして実行する
## コマンドプロンプトで実行する時

```
mvn clean install 
java -jar target/benchmarks.jar
```
java -jar で起動時のオプションは  [Javaのマイクロベンチマークツール「JMH」](http://acro-engineer.hatenablog.com/entry/2013/11/07/120606) を参照。

### 備考
- jarファイルの名前はpom.xmlで変更できる。
プロジェクトの雛形生成機能で作成したときは benchmarks.jar になっている。

## IDEで実行する時(eclipseでしか試していない)
1. pom.xmlで clean を実行
2. pom.xmlで install を実行
3. main() メソッドが書かれているクラスを実行
FuelPHP で Orm/Model 使用して連続でInsertした時に2件目以降がupdateになる。

FuelPHP1.7でOrm/ModelについてInsert後そのオブジェクトを使用して再度Insertしようとした時にアップデートになった。
どうやらプロパティのis_newを更新しないとだめらしい。
Orm/Modelの場合はis_newはprotectedなのでそのまま更新したら追加になった。

```
$model = Model_XXXXX::forge();
$model->is_new =true;
```

なおModel_Crudを使用している場合はメソッドで更新できる。

```
$model = Model_XXXXX::forge();
$model->is_new(true);
```

しかし、このテーブルのプライマリキーをauto_incrementしていたら、その値がリセットされないという事象が発生する。。。。

SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '2' for key 'PRIMARY'

ソースは以下の通り

```
$records = array(
    array('カラム１'=>'値１')
,   array('カラム１'=>'値２')
);

$model = Model_XXXXX::forge()

foreach($records as $record) {
    $model->set($record);
    $model->is_new = true;
    $model->save();
}
```

むかつく・・・
ORMのソースみてたらcloneするとis_newも含めて新規に設定するみたいなので以下のようにして回避した。とりあえずこれでいいか。。。

こちらでOK

```
$records = array(
    array('カラム１'=>'値１')
,   array('カラム１'=>'値２')
);


foreach($records as $record) {
    $obj = Model_XXXXX::forge()
    $obj->set($record);
    $obj->save();
    unset($obj);
}
```

こっちでもできますが、無駄が多いです。

```
$records = array(
    array('カラム１'=>'値１')
,   array('カラム１'=>'値２')
);

$model = Model_XXXXX::forge()

foreach($records as $record) {
    $obj   = clone $model;
    $obj->set($record);
    $obj->save();
    unset($obj);
}
```
HTML5 の canvas 要素を base64 文字列化し画像として保存する方法まとめ

# canvas 要素の画像ファイル化

HTML5 の canvas 要素は画像として保存することができます。

デモを jsdo.it に投稿したので、合わせてご覧ください。

- [Save as Image File - Colorful Lines - jsdo.it](http://jsdo.it/clockmaker/save-as-image-file)


## JPEG 画像へ変換する方法

`canvas`変数は、`document.getElementById("ほげほげ")`で取得した`canvas`要素の参照です。`toDataURL()`メソッドの引数に変換したい種別を指定することで、その画像形式に対応した文字列(Base64方式の画像)を戻り値として受け取れます。

```js
const data = canvas.toDataURL("image/jpeg");
```

JPEG 画像は背景色を透過できませんので用途が限られるでしょう。

## PNG 画像へ変換する方法

PNG 形式であれば、背景色を透過して保存できます。可逆圧縮となるので画質の劣化もありません。

```js
const data = canvas.toDataURL("image/png");
```




## WebP 画像へ変換する方法

Google Chrome 限定ですが　WebP 形式(ウェブピーではなく、**ウェッピー**と読みます)の保存にも対応しています。WebP は新しい画像形式だけあって、JPEGやPNGと比べても容量が小さくなります。ただし、二番目の引数で画質調整をうまくしてやらないと画質がすぐに劣化するので注意が必要です。WebP 形式でも、背景色を透過して保存できます。

```js
const data = canvas.toDataURL("image/webp");
```





## 番外編 : SVG

SVG 画像にも対応していたら面白いと思ったのですが、残念ながら現状はどのブラウザも対応していないようです。

```js
const data = canvas.toDataURL("image/svg+xml");
```

ただし、[CreateJS](http://createjs.com)の機能「[EaselJS/extras/SVGExporter at master · CreateJS/EaselJS](https://github.com/CreateJS/EaselJS/tree/master/extras/SVGExporter)」を使えば、Canvas要素をSVG画像として保存することができます。CreateJSすごい！

---

今回はプレーンな JS で制御しましたが、HTML5 Canvas を制御するなら[CreateJS](http://createjs.com)がオススメです。日本語の[CreateJS入門サイト](https://ics.media/tutorial-createjs/index.html)を用意していますので、あわせて参照くださいませ。
ScalaCheckで独自のGeneratorを作る

# 概要
[ScalaCheck](https://scalacheck.org/)はPropertyベースのテスト用ライブラリです。

ランダムなパラメータを生成し、テスト対象の関数の振る舞いをテストします。

標準で文字列や数値をランダムに生成する便利なGeneratorがありますが、独自のGeneratorを作成することも可能です。

この記事では独自にGeneratorを作成してみます。

# 事前準備

ScalaCheckを使えるようにするため、`build.sbt`に以下を追加します

```build.sbt
libraryDependencies += "org.scalacheck" %% "scalacheck" % "1.12.5" % "test"
```

# 検査対象クラス
今回は以下のようなクラスでテストしてみます

```MyClass.scala
case class MyClass(number: Int, multiplier: Multiplier) {

  def calc: Int = {
    number * multiplier.number
  }
}

case class Multiplier(number: Int)

```

MyClassは`number`と`multiplier`というメンバ変数を持っていて、`calc`メソッドで`number`と`multiplier`を掛けた値を返します。

また、Multiplierは`number`をメンバ変数に持つようにしています。

# テストクラス
検査対象クラスに対してテストクラスは以下のように書いてみました。

```MyClassTest.scala
import org.scalacheck.{Arbitrary, Gen, Prop, Properties}

object MyClassTest extends Properties("MyClass") {

  // MultiplierのGenerator
  // -1000 ~ 1000のnumberを持つMultiplierを生成します
  val genMultiplier: Gen[Multiplier] = for {
    number <- Gen.chooseNum(-1000, 1000)
  } yield Multiplier(number)

  // MyClassのGenerator
  // -1000 ~ 1000のnumberとgenMultiplierで生成したMultiplierを持つMyClassを生成します
  val genMyClass: Gen[MyClass] = for {
    number <- Gen.chooseNum(-1000, 1000)
    multiplier <- genMultiplier
  } yield MyClass(number, multiplier)
  
  // Prop.forAllでMyClassの乱数を呼び出す際にArbitraryを定義
  implicit val arbMyClass = Arbitrary {genMyClass}
  
  // テストの実行
  // 100パターンのMyClassをランダムに生成してcalcの挙動を
  property("calc") = Prop.forAll{(myClass: MyClass) =>
    myClass.calc == myClass.number * myClass.multiplier.number
  }

}

```

これでテストを実行してみます

```
$ sbt test
~
[info] + MyClass.calc: OK, passed 100 tests.
[info] Passed: Total 1, Failed 0, Errors 0, Passed 1
[success] Total time: 4 s, completed 2016/01/28 11:28:23
```

うまくいったみたいですね <3
ExcelVBAを使ったプロ野球リーグ戦シミュレーション

#はじめに
元は、ExcelVBA習得の一環として、
プロ野球のマジックナンバーの算出方法ってどうやっているんだろうと
計算式を追っていったのが始まりです。

処理の流れとしては、
試合日程を生成し、日程に従って試合をシミュレーションしていき、
勝敗の記録から順位の決定とマジックの算出などを行います。

~~シミュレータとしての使用だけでなく、本来の目的である、~~
~~現実のペナントレースの試合数・勝ち数・負け数・引き分け数と残試合数を入力することで、~~
~~現時点でのマジックナンバーの算出・自力優勝の検証も行えます。~~
交流戦を考えていないため、まだ現実のペナントレースからマジックを求めることができません。

元は個人的な野球観戦のツールとして作ったものなので、
自分以外の方が使う場合、意味不明なところもあるかと思います。
コメントを頂ければ、励みになります。

#説明
メインとなる順位表の画面です。
![league_ss1.png](https://qiita-image-store.s3.amazonaws.com/0/110901/e4044fa2-0877-d9a2-dc19-83ad1652cb8e.png)

青枠のボタンを使って日程進行や、クリアを行います。
緑枠の部分は、日程作成に関するパラメータです。
デフォルトでは、とりあえず試合数を145試合にしてみたかったため、
総当たり回数29回（1チームがリーグ戦全体で特定の相手と何試合戦うか）、
1カードの試合数3回としています。29×(6-1)=145。
![league_ss5.png](https://qiita-image-store.s3.amazonaws.com/0/110901/af1945b7-19c0-f5d3-c1cb-b07591170cb1.png)

#ダウンロード
dropboxにアップロードしました。
以下のURLからダウンロード可能です。
https://www.dropbox.com/s/u231v34uj2nag99/leagueVBA_0107.xlsm?dl=0

#処理
##日程生成
入力されたチーム名からリーグ戦の日程を生成します。
チーム数が偶数である場合と、奇数である場合で、
日程生成のアルゴリズムが異なるため、その設計が大変でした。
##試合進行
前項で生成した日程表をもとに、試合を行います。
試合におけるチームの得点は、負の二項分布の乱数生成器で算出しています。[^1]
イニングごとの得点を算出していって試合を進行します。[^2]
延長戦と引き分けも考慮しています。
「日程表」シートの得点欄にカーソルを合わせることで、
すでに行われた試合の試合経過をExcelのコメント形式で表示できます。

[^1]: 負の二項分布を用いた理由は、野球の1チームの1年における合計得点をヒストグラムにして考察しているサイトがあり、その形が負の二項分布に近いかな？と感じたためです。直感で決めてしまったため、確率分布の妥当性は全く考慮していません。その妥当性の検証は、プログラム作成時の目的であるマジックの算出から外れてしまうため、とりあえずは後回しにして開発を行った次第です。
[^2]: 2015年イニング別平均得点をパラメータとして、乱数を生成しています。データは「プロ野球 ヌルデータ置き場」より引用いたしました。（http://lcom.sakura.ne.jp/NulData/）
##順位決定
前項で得られた試合結果をもとに、勝ち負けを記録していき、
順位通りにチームを並び替えます。
勝率が同率である場合の並び替え方法は、
2015年のセ・リーグの順位に関する規定に対応しています。
1.勝利数が多い球団
2.当該球団間の対戦勝率が高い球団
(3.前年度順位が上位の球団)
##マジックナンバー・自力優勝可能性計算
本プログラムの、本来の目的の部分です。
シミュレーションした順位表の各数値、または現実の順位表をもとに、
マジックナンバーと自力優勝を計算します。
1位以外の自力優勝が消滅した場合に、マジック点灯をあらわすような表示にしています。

#今後の課題
##日程生成
- チーム数偶数の場合に、ホームチームが全日程で固定となるチームがある。これは正しくない。野球では、ホームとビジターチームで、延長でサヨナラの機会がある分、ホーム側が有利である。なのでリーグ戦の結果も、この常にホームであるチームが有利となってしまう。

##試合進行
- 年間総得点の確率分布は負の二項分布に近いかもしれないが、年間イニング別得点の確率分布は全く異なる。確率分布の再検討と、乱数生成器の再設計。
- 連勝・連敗に応じて得点力アップや失点増加など考慮したら面白いかも。ただ、本来の目的である、マジックの仕組みが理解できてしまったので、そこまでするモチベーションを維持できるかが課題。

##順位決定
- 2位以降で勝率が同率である場合に、順位に関する規定の2番の条件を適用させていない。

##マジック算出
- 現実世界にある交流戦を考慮していないため、現実のペナントレースの結果からマジックを求めるといったことがまだできないorz
openstackの管理画面(horizon)でインスタンスを作成してsshしたい（けどできないまま途中。。）

# openstackインスタンス生成メモ(途中)

* CentOS7上にインストールしたOpenStack(liberty)を使用
    * ⇒ [RDOを試してみる](http://qiita.com/teratsyk/items/554044ae417d8c43084a)
* 管理画面でインスタンスを作成してsshログインしたかったが、できなかったメモ
    * sshのログインパスワードが分からないのでペンディング

# ネットワークを作成

* 「管理 > システム > ネットワーク」から「+ネットワークの作成」を実行
    * private
        * ネットワーク種別: vxlan(初期値)
        * ネットワークアドレス: 10.10.0.0/24
        * DNS: 8.8.8.8
    * public
        * ネットワークアドレス: 192.168.1.0/24
        * 「外部ネットワーク」にチェック
    * router
        * ルーターは、「プロジェクト > ネットワーク」から「+ルーターの作成」をクリックして作成する
            * 外部ネットワーク: 上記で作成した`public`を指定
                * 後付けする場合、「ゲートウェイの設定」から追加する
            * 内部ネットワーク: ルーター作成後「+インターフェースの追加」から`private`のサブネットを登録する

# キー作成

* 「プロジェクト > コンピュート > アクセスとセキュリティー」から、新規キーペアを作成
    * 作成したキー「.pemファイル」はsshログイン時に使用する

# イメージの登録

* [centos7](https://www.rdoproject.org/resources/image-resources/)のイメージを登録する
    * 一度ローカルPCのにダウンロードしてからアップしたが、URLで直接登録もできる模様
    * ユーザは「centos」と[書いてあった](http://docs.openstack.org/image-guide/obtain-images.html#centos-images)

# フレーバの作成

* 「管理 > システム > フレーバー」から新しいフレーバーを作成
    * ホストが非力なので、メモリ512MB,ディスク10GBのフレーバーを作成した

# インスタンス起動

* 「プロジェクト > コンピュート > インスタンス」からインスタンス起動
    * 上で作成したフレーバーと、privateのネットワーク、キーペアを指定してインスタンス起動

# sshで接続

* privateの`10.10.0.XX`系でも、publicの`192.168.1.XX`系でもアクセスできない。pingも通らない
* 管理画面からインスタンスのコンソールを開き、`コンソールのみを表示するにはここをクリックします`をクリックする
    * ブラウザがエラーになりコンソール表示されない（chrome, firefox）
    * ブラウザのURLバーに表示されるIPをみると`10.0.2.15`となっている（10.10.0.XXではないのか？？）
* ホストOSのコンソールから`10.0.2.15`にpingを打つと通る。。
* `ssh -i {key}.pem centos@10.0.2.15` でパスワードを聞かれるが、パスワードが分からない。。。

# 鍵があっていない？

* OpenStackで作成した鍵がインスタンスに注入できていない？
    * インスタンスのログに鍵についての出力があった。注入はできているっぽい。
        * ログ保存忘れ。。。

* パスワードを聞かれるなら設定してしまう？
    * cloud-initを使って設定する。[参考サイト](http://d.hatena.ne.jp/ytooyama/20140201/1391186305)
        * インスタンス作成時に下記のカスタムスクリプトを登録する
            * ダメだった・・。

```
#cloud-config
password: centos
chpasswd: { expire: False }
ssh_pwauth: True
```
man postsuper に記載されているmailq削除のawkをperlに変えてみた

man postsuper に記載されているmailq削除のawkをperlに変えてみた。


```console
# mailq | tail -n +2 | grep -v '^ *(' | \
      awk 'BEGIN { RS = "" } { if ($8 == "user@example.com" && $9 == "") print $1 }' \
      | tr -d '*!' | postsuper -d -
```

```console
# mailq | sed '1d' | grep -v '^ *(' | \
      perl -00ane 'print "$F[0]\n" if $F[7]=~q/@example.com$/ && $#F<8' | \
      tr -d '*!' | postsuper -d -
```

- 個人的な好みでtailはsedに変更。
- sedもgrepもtrも消したかったけど自分には無理だった。
- awkの$9は、recipient2。
OttoでRailsの開発環境を構築した時に、Webrickのレスポンスが遅い時の対応方法

# 方法1: Vagrantの設定を変更する

(TODO: dev_vagrantfileを使ったほうがよさそう。 [参考サイト](https://www.ottoproject.io/docs/apps/custom/customization.html))

synced_folderのnfsを有効にし、メモリサイズを4Gにします。

```bash
# ottoのVagrantファイルを開きます
$ vim .otto/compiled/app/dev/Vagrantfile

# 以下の部分を修正します
-----
  # nfsを有効にします
  ## Setup a synced folder from our working directory to /vagrant
  #config.vm.synced_folder '/Users/kyamada/git/hoge', "/vagrant",
  #  owner: "vagrant", group: "vagrant"
  config.vm.synced_folder '/Users/kyamada/git/hoge', "/vagrant",
    nfs: true

  # メモリを4Gにします
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "4096"
  end
-----

# Vagrantを再起動します
$ otto dev vagrant reload
```

# 方法2: Webrickの設定で`:DoNotReverseLookup`をtrueにする

```bash
$ otto dev ssh
$ gem which webrick
/opt/rubies/ruby-2.2.4/lib/ruby/2.2.0/webrick.rb
$ vim /opt/rubies/ruby-2.2.4/lib/ruby/2.2.0/webrick/config.rb 

----
#:DoNotReverseLookup => nil
:DoNotReverseLookup => true
----
```

# 参考

- [Rails Server WEBrickの起動やレスポンス速度が遅い場合の対処法](http://blog.code-life.net/blog/2014/04/14/rails-server-webrick-is-so-slow/)

- [メモ：Vagrant の NFS synced folder でいちいちパスワード聞いてこなくするやつ](http://qiita.com/yungsang/items/68f0ac35cd2774b3b957)
Amazon CloudWatch で、リクエスト数を集計する

## 背景
* Amazon CloudWatch を使って、1時間ごとの分あたりのリクエスト数の平均、最大、最小を求めたかった
* ネットで検索しても良いサンプルが見つからなかった
* シェルスクリプトで自作したので、公開する

## スクリプト例

```sh:get-cloudwatch-metric.sh
#!/bin/sh

for hour in $(seq 24 -1 0); do
  begin=$(date -u -d "$((hour + 1)) hour ago" +%FT%H:00:00)
  finish=$(date -u -d "${hour} hour ago" +%FT%H:00:00)

  echo "$begin - $finish"
  aws cloudwatch get-metric-statistics \
    --metric-name RequestCount \
    --start-time $begin \
    --end-time $finish \
    --period 60 \
    --namespace AWS/ELB \
    --statistics Sum \
    --dimensions Name=LoadBalancerName,Value=your-target-elb \
    --query "Datapoints[]" \
    --output text | awk '
      BEGIN {min = 99999}
      {
        if(max<$1){max = $1; max_time = $2;}
        if(min>$1){min = $1; min_time = $2;}
        sum += $1;
      }
      END {
        print max_time, "max: ", max;
        print min_time, "min: ", min;
        print "sum: ", sum;
      }
    '
  echo
done
```

## 解説

* 使うときは `your-target-elb` を自分の ELB の名前に変更すること
* 名前空間 AWS/ELB にある RequestCount という CloudWatch のメトリクスを利用している
* bash の `for` 文を使うときは、`seq` を使うのがオレオレベストプラクティス
* 直近から 24時間前までの 計25時間分の集計結果を出力している
* `date` コマンドを使うと、月初、年初などの境界条件をあまり気にしなくて済むので、便利
* ELB は AZ ごとに存在するので、もう1段階深く、ELB ごとのリクエスト数を集計することも可能（ここではやってないけど）
* 集計ロジックは `awk` でさくっと作成
  * `--query Datapoints[]` とすると、出力結果がスッキリして後処理がラクになる
  * `--output text` とするとテキスト形式で出力されるので、awk で後処理しやすい
  * Ruby 等で後処理するのであれば `json` 形式がオススメ
  * ごにょごにょした `aws` コマンドの結果、1列目が 回数、2列目が検索範囲の日時が返る
  * `awk` で書いたところは正直 `Perl` でも `Ruby` でもいいのだけど、シェルスクリプトの中で使うなら `awk` かな、と
ファイル名一覧が取得できない

Downloadフォルダにあるファイルパスの一覧を取得したかったが、 File#listFilesがnullで返ってきた。ファイルマネージャーで確認した所、１個以上のファイルが有ることは確認済。
ディレクトリのパスは取得できて、Fileオブジェクトもインスタンス化できるけど、File#listFilesで返ってくるはずのFile[]がnull。

# 原因
RuntimePermissionでREAD_EXTERNAL_STORAGEを許可していなかった。
まあそりゃそうかという気もする一方で、最初はnullで返ってきたのでディレクトリの取り方が違うのかとかいろいろ邪推してしまった。

# 解決策
Fileオブジェクトを触るときは、RuntimePermission発行する。以上。
http://developer.android.com/intl/ja/training/permissions/requesting.html

# 検証端末
OS:6.0
Device: Nexus5X
[JavaScript] ゲームループを作る記事を見てみる


[こちらの記事](http://t100life.blog121.fc2.com/blog-entry-209.html)を参考に、ゲームループの処理を見てみます。
（やってることは分かるんですが、自分の中にしっかり落とし込めるまで理解できてなかったのでメモとして書いておきます）

## ゲームループ

ゲームは常に画面が動き続け、かつユーザからの操作を待ちます。
また最近のゲームでは物理演算などが当たり前に利用されているので、そうした計算処理を一定の間隔でループさせて処理する必要があります。
そうした諸々の処理のループを一般的に「ゲームループ」と呼びます。

詳細については[このあたりの記事](http://rina.jpn.ph/~rance/directx8/03/01.html)が参考になりそうです。


## 解説

さて、ではさっそく記事を見ていきます。
といってもやっていることは比較的単純で、記事の言葉を引用すると以下になります。

>１秒間に可能な限り多くのフレームを描画しようとしながら、１秒毎に決められた回数のロジックを実行するよう試みます。

ということです。

紹介されているコードを少し整形して紹介。

```js
Game.fps = 50;

Game.run = (function() {
    var loops = 0;
    var skipTicks = 1000 / Game.fps;
    var maxFrameSkip = 10;
    var nextGameTick = Date.now();

    return function {
        loops = 0;

        while (Date.now() > nextGameTick && loops < maxFrameSkip) {
            Game.update();
            nextGameTick += skipTicks;
            loops++;
        }

        Game.draw();
    };
})();

// Start the game loop
Game._intervalId = setInterval(Game.run, 0);
```

[追記]
以下、コメントで間違いを指摘いただいたので修正しています。

<del>`skipTicks` は `1000ms` を `FPS` で割っています。つまり `1FPS` あたりの時間を計算しています。
`maxFrameSkip` は何フレーム分 `update` を実行したら描画を実行するかを決めています。
つまり「1秒毎に決められた回数のロジックを実行するよう試み」ているわけですね。
なのでこの場合だと `10回` ということになります。</del>

ここ、だいぶ勘違いをしていました。
コメントで指摘してもらってだいぶクリアになった気がします。

ここについてはコメントを見てもらったほうがいいと思いますが、自分なりの解釈も書いておきます。

## 解釈

まず前提として、
「 **描画処理は指定したFPS関係なく、関数が呼ばれた回数分「できるだけ」実行し、`update` 関数はFPSの指定通りの回数実行できるよう努力する** 」
という見方をします。

さて、では問題をシンプルにするために `while` 文をまるまる取って考えてみましょう。
すると `run` が呼ばれた回数だけ `draw` が実行されるのは自明ですね。

ただこれではゲームループとしてアップデートしてほしい内容がなにも更新されなくなってしまいます。
理想として `update` がコスト0で終えられるなら、前述の通り `run` 実行回数分だけ `draw` も実行されます。
しかし現実はそううまくいかないのでここにそれなりのコストがかかります。

さて、そのコストがかかった分をどうするか、が `while` 文で行っている処理と見ることができます。

`update` に要した時間が `1フレーム分の時間 == skipTicks` より小さい場合、次の `while` の評価は当然 （`(Date.now() > nextGameTick) == false`） になりループを抜けます。
この状態が維持され続ければ `update` と `draw` は1対1で実行され続けますね。

ただもし、`update` の処理が重くなってしまった場合どうなるでしょうか。
結果として `Date.now() > nextGameTick` は `true` になります。
（1フレーム分進めた時間よりも現在時刻のほうが先に行ってしまっている）

そうすると遅れた分を取り戻すためにループが開始されます。
ただ、`update` が毎回重くなってしまうと永久にループを抜けられなくなってしまうため、`maxFrameSkip` によってキャップを設け、その回数分実行したらループを抜けて一回描画を行う、という処理になります。

・・・ふぅ、この認識であってるかな( ;´Д`)
要は「遅れた分を取り戻す処理が `while` の中身」ってことだと思いますｗ