OmniAICreator/Qiita-1.07M huggingface dataset:
...の意味(PHP5.6以降の話)

Laravelのhelperを見ていたら

```php
<?php
    /**
     * Dump the passed variables and end the script.
     *
     * @param  mixed
     * @return void
     */
    function dd(...$args)
    {
        foreach ($args as $x) {
            (new Dumper)->dump($x);
        }

        die(1);
    }
```

なんか引数が見慣れない形をしている

# ...って何？
変数に余韻を残したいのか？と思う「...」ですが
ちゃんと意味はありました

## 公式ドキュメント
http://php.net/manual/ja/functions.arguments.php#functions.variable-arg-list

> PHP 5.6 以降では、引数リストに ... トークンを含めることで、 その関数が可変長の引数を受け取ることを示せます。 引数は、指定した変数に配列として渡されます。

つまり、 **無限引数の関数が作れる**

## PHP5.6より前でも可変長の引数はあった

参考: http://php-beginner.com/reference/userfunction/arg_len.html

```php
<?php
function my_func5(){
  $arg_num = func_num_args(); //引数の数取得
  $key = 0; //アクセスする引数番号
  $arg_list = func_get_args(); //引数リストを配列に格納
 
  if($arg_num >= $key+1){ //引数番号以上のリスト数があれば出力
    echo func_get_arg($key)."行：";
  };
 
  for($i=0;$i<$arg_num;$i++){ //引数の数分ループ
    echo $arg_list[$i];
  };
};
my_func5("あ","い","う","え","お");
?>
```

前からできたことのようで
PHP5.6以降で `...` と記述することでスリムに書けるようになったよーということ

# 使い所
## 関数の引数として使う
http://php.net/manual/ja/migration70.new-features.php#migration70.new-features.scalar-type-declarations

```php
<?php
// 渡された引数を全部足す関数
function sumOfInts(int ...$ints)
{
    return array_sum($ints);
}

var_dump(sumOfInts(2, '3', 4.1));
```

一見扱うには怖そうな可変長の引数も
上のような型宣言も付けることにより、安全に扱うことができる


## 関数に渡す値として使う

```php
<?php

function hoge( $key, $value1, $value2 = null, $value3 = '') {

}

$array = [1, 2, 'fuga'];

hoge($key, ...$array);

```

上の例のように、値渡しに `...` を使う時は 
変数が配列だったら個々の引数として展開されて関数に渡される

この使われ方はLaravelのcoreを調べてみるとかなり多く、
フレームワークのような引数を柔軟に処理をすることが求められる場合に
使われることが多いのかな？という印象だった


# まとめ
`...` は、関数の引数定義、引数渡しで使われる
なにか便利そうなもの
select(2)のfd_setは1024以上のfdをセットしようとすると落ちる

# はじめに
ネット上の記述によってはselectは引数のfd_setが1024個のfdしか受け付けないから、1024個までのFDしか監視できないよ、と書いてあることが多いんですが、実際には **1024以上のfdを受け付けません**。たとえ一個であれ1024以上の数字をFD_SETしようとすると落ちます。
結論は以上ですが、中身を追ってみたいと思います。

よく見ると[selectのmanページ](https://linuxjm.osdn.jp/html/LDP_man-pages/man2/select.2.html)にも載ってます。

> fd_set は固定サイズのバッファーである。 負や FD_SETSIZE 以上の値を持つ fd に対して FD_CLR() や FD_SET() を実行した場合、 どのような動作をするかは定義されていない。

恐怖の未定義動作宣言がされています。

# select(2)
ファイルディスクリプタやソケットディスクリプタを監視し、典型的にはサーバプログラムなどいつ着信があるかわからないプログラムが、着信を待ち受けるのによく使われるシステムコールです。

```C
int select(int nfds, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, struct timeval *timeout);
```

細かいことを置いておいて、大雑把に言ってしまうと、`fd_set`に登録されたfd(ファイルディスクリプタ)を監視してくれるシステムコールです。select(2)からread(2)を連携させることで、readをビジーwaitするより効率よくイベント駆動的にデータの読み込みができます。`boost::asio::async_read` の元祖みたいなやつですね。

# fd_setとFD_SET
`fd_set`は名前の通りfdの集合を表す構造体です。私の手元のsys/select.hを見ると（かなり省略してます）

```C
typedef long int __fd_mask;
# define __FD_SETSIZE 1024
# define __NFDBITS (8 * (int)sizeof(__fd_mask));

typedef struct
  {
    __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS];
# define __FDS_BITS(set) ((set)->fds_bits)
  } fd_set;
```

読み解いて行くと、Linuxの64bit版だとすると、longは64bitなので、

```C
typedef struct {
    long int fds_bits[16];
} fd_set;
```

ですので、結局、1024bit(64bit * 16個)の領域をもつ構造体になります。
そして、ここに含まれるfdを設定するのが`FD_SET`マクロです。

```C
#define	__FD_ELT(d)　((d) / __NFDBITS)
#define	__FD_MASK(d)　((__fd_mask) (1UL << ((d) % __NFDBITS)))
#define __FD_SET(d, set) ((void) (__FDS_BITS (set)[__FD_ELT (d)] |= __FD_MASK (d)))
#define	FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp)
```

ちょっとわかりにくいのでマクロを解いていくと、

```C
fdsetp->fds_bits[fd/64] |= (__fd_mask) (1UL << (fd % 64));
```

となり、要するにfdsetp(fd_set型変数のポインタ)のfd桁目のbitを立てる処理をしているわけです。

# お分かりでしょうか？
そうです。fdが1024を超えた瞬間、buffer overflowで落ちます。
しかも、FD_SETSIZEはdefineでハードコードされており変更するのも恐ろしくてできません。[redhatのQAページ](https://access.redhat.com/solutions/488623)でもFD_SETSIZEを書き換えちゃダメだよと書いてあります。
`ulimit`の上限は今どきのメジャーディストリビューションでも1024が多いですが、ulimitで上限外すって言うのはサーバプログラム書く方からすると当たり前のチューニングだと思います。特に、dockerとか使っているとオプションで簡単に制限を外せます。
しかし、もしあなたのプログラムで使っているライブラリが`select(2)`で実装されていたら、予期せず落ちることになります！

# まとめ
select(2)を使ったプログラムで`ulimit`の制限を外すぐらいディスクリプタを使うと、`FD_SET`で落ちます。
実際、某NWプロトコルのライブラリを使ってプログラムを書いてたらこの問題に遭遇しました。
これから低レイヤのNWプログラム書く方は`select(2)`を使わないようにしてほしいものです。
お願いだから`poll(2)`を使ってくれ！
MacBookPro初期設定

新しくPC買ったので、最速初期設定。
MacBookPro(15inch 2017) 1.9 GHz 512GB USキーボード

- キーボード
	- CapsLockをCtrに。（キーボード→修飾キー）
	- cmd + spaceで言語切替、ctr + spaceでspotlight
		- ショートカットの入力ソースの「前の入力ソースを選択」をcmd + space
		- 切り替えると、かぶってアラート出るので、それをctr + spaceに。
- xcode, chrome, kobito, slackインストール
- google日本語入力インストール
- Dock
	- 画面上の位置を左に変更
	- Dockを自動的に隠す/表示にチェック
- トラックパッド
	- タップクリックはしない
	- 軌跡の速さは早めに
- Finder
	- サイドバーで、マイファイル消して、その他適宜入れる
	- 詳細で、「すべてのファイル名拡張子を表示」にチェック
- 日付と時刻
	- 「日付を表示」にチェック
- Github desktopをインストール
- itermインストール
- プログラム系
	- dotfile系を入れる
	- homebrew入れる
	- zsh, [oh-my-zsh入れる](https://github.com/robbyrussell/oh-my-zsh)

```
// zshインストール
// デフォで入ってるが、brewで入れとく
$ brew install zsh zsh-completions 

// oh-my-zshインストール
$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)" 
// 確認
$ echo $SHELL
$ less /etc/shells
$ vim /etc/shells // 一番下に/usr/local/bin/zshを入れる
// ターミナル再起動して、下記実行
$ chsh -s $(which zsh)
// 設定入れる
$ vim ~/.zshrc 
```

あとは適宜、ruby, node, etc、エディタ入れていく。
今回はnodeを入れた。

```
$ brew install nvm
$  mkdir .nvm
$ vim .zshrc # 以下を追加
  export NVM_DIR="$HOME/.nvm"
  . "$(brew --prefix nvm)/nvm.sh"
  
$ nvm ls # ローカルに入ってるnodeを一応確認
$ nvm ls-remote # リモートのnodeバージョン確認
$ nvm install OOO # 希望のバージョンをインストール
$ node -v
```
GPT形式のパーティションはNetVaultでRawデバイスバックアップできない

DBのバックアップ手法は色々とありますが、以下の手順はよくある手法だと思います。

1. ストレージのLUをDBサーバに見せる領域(以下P-VOL)とバックアップサーバに見せる領域(以下S-VOL)に分けて作成し、P-VOLとS-VOL間で同期処理ができるようにストレージの設定を行う。
2. DBサーバのデータファイルをP-VOL上に配置する。
3. バックアップサーバでS-VOLをRawデバイスバックアップの設定をする。
4. DBの機能で静止点を作る。
5. ストレージの機能でP-VOL/S-VOLを同期し、同期が完了したらP-VOL/S-VOLを切り離す。
6. この状態でS-VOLには静止点のデータファイルが配置されているので、バックアップサーバがS-VOLをバックアップする。

今携わっているプロジェクトでも上記の手法を使っているのですが、なんとWindowsサーバにインストールされたNetVault ServerはGPT形式でフォーマットされたパーティションをRawデバイスバックアップすることができないという制約があります。

[NetVaultのマニュアル](
https://support.quest.com/technical-documents/netvault-backup/11.0/%E3%83%93%E3%83%AB%E3%83%88%E3%82%A4%E3%83%B3-%E3%83%97%E3%83%A9%E3%82%B0%E3%82%A4%E3%83%B3-%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%BA-%E3%82%AC%E3%82%A4%E3%83%89/7#TOPIC-454857)
「Windowsで、Plug-in for Raw Devicesは、GPT（GUID Partition Table）スタイルのパーティションをバックアップすることはできません。プラグインは、MBR（マスター・ブート・レコード）スタイルのパーティションのバックアップにのみ使用することができます。」

結局、PMにまでエスカレーションされた結果、DBサーバのパーティションをGPTではなくMBRにフォーマットしなおすという判断になりましたが、構築作業において大きな手戻りが発生しました。
過去にDataProtectorやNetVackupは経験があったので、NetVaultは初めてだったにもかかわらず「どのバックアップソフトも似たようなものだろ」などとエンジニアとしてあるまじきことを考えてしまったのが問題でした・・・。経験が油断となって問題を引き起こすわけですね・・・。類似製品を知っていても、製品やバージョンが違えば別物だという意識をもって仕事をすべきだと反省しました。

ただ、今後、GPT形式のフォーマットが増えていくと想定されるので、意外とインパクトのある問題だなと感じました。今回はたまたまMBRに変更可能でしたが、そうではないケースも出てくると思います。ベンダーには回避策を用意しておいてもらいたいものです。
Macにsource-code-proというフォントをインストールする方法

# Macにsource-code-proというフォントをインストールする方法

なんだかコーディングしやすいらしいですよ。


## インストール方法

コンソールを起動して、以下のコマンドを実行します。

```bash
curl -LO https://github.com/adobe-fonts/source-code-pro/archive/release.zip
unzip release.zip
cp -a source-code-pro-release/TTF/* ~/Library/Fonts
```

これでFont Bookを起動すると、ユーザーのフォントとして確認できます。

### Inconsolataも入れてみる

定番のInconsolataも入れてみましょうかね。

```bash
cd ~/Library/Fonts
curl -LO https://github.com/google/fonts/raw/master/ofl/inconsolata/Inconsolata-Regular.ttf
curl -LO https://github.com/google/fonts/raw/master/ofl/inconsolata/Inconsolata-Bold.ttf
```



---

あなたはどのフォントでコーディングしますか？
それではまた来週！

## 参考リンク
[Github:adobe-fonts/source-code-pro](https://github.com/adobe-fonts/source-code-pro)
[Github:google/fonts Inconsolata](https://github.com/google/fonts/tree/master/ofl/inconsolata)

### 追記
https://github.com/microsoft/vscode/issues/106583
こちらの通り、現在VSCodeで若干表示がバグります。。。。
PYTHON2.764bit版

今までpython.2.7.11の32bit版を使用していたのですが、メモリが２Gまで（？）しか使えないとのことでしたので、64bit版への変更を試みました。
python 2.7.13 のwindows64bit版をインストールし、試しにIDLEを起動したのですが、起動しません。作成したスクリプトを実行しても、一瞬コマンドプロンプトが立ち上がるだけで、実行されている気配がありません。どういったことが問題なのでしょうか？

IDLEが起動しない
作成したスクリプトを実行しても、一瞬コマンドプロンプトが立ち上がるだけで、実行されている気配がない
コマンドプロンプトでpythonと打つとPython2.7.13が正常に起動する
コマンドプロンプトからpythonと入力するとPython 2.7.13 (......) [MSC v.1500 64 bit (AMD64)] om win32　と表示される。
print "hello"とだけ書いてあるhello.pyに対し、コマンドプロンプトでpython hello.pyと打ったら、SyntaxError: invalid syntaxと表示される
MySQLで日別でランダムにレコードを取得する方法

## SQLだけで簡単に実現することができたので備忘録として残します。


### こういうときに使えます:point_up:

- `日別にランダムで表示してください`と仕様書に記載があったとき...等。

### やりかた:relaxed:

- `RAND()` の引数を指定するだけ！！

```sql
SELECT * FROM hoge ORDER BY RAND(20160101)
```

- 引数が同値である限り、結果（並び順）は常に同じになります。

## 参考

https://dev.mysql.com/doc/refman/5.6/ja/mathematical-functions.html#function_rand
ESP8266 Arduino Example を試す　その２

## ESP8266 Arduino Exampleを試す　その２

### ESP8266AVRISP
#### [Arduino_Wifi_AVRISP](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266AVRISP)

ESP8266 をTCP経由でAVRライタとして使うサンプル。
動作結果は以下の通り。

``` Arduino_Wifi_AVRISP
Arduino AVR-ISP over TCP

Soft WDT reset

ctx: cont 
sp: 3ffef650 end: 3ffef850 offset: 01b0

>>>stack>>>
3ffef800:  3fffdad0 3ffee6c0 3ffee7f4 40201d02  
3ffef810:  feefeffe feefeffe feefeffe feefeffe  
3ffef820:  feefeffe feefeffe feefeffe 3ffee820  
3ffef830:  3fffdad0 00000000 3ffee818 40205ac8  
3ffef840:  feefeffe feefeffe 3ffee830 40100718  
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

load 0x4010f000, len 1384, room 16 
tail 8
chksum 0x2d
csum 0x2d
v09f0c112
~ld

```

### [ESP8266HTTPClient](https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266HTTPClient)

#### Authorization
setup でWifi のアクセスポイントに接続します。
SSIDとPASSWORD は直接、ソースコードに書き込みます。

```Authorization.iso
void setup() {
    ...
    WiFiMulti.addAP("SSID", "PASSWORD"); //アクセスポイントのオープン
}
```

loop の中で、接続を確認しいずれかのURLに接続する。
当該 html を読み込みシリアルに書き出す。

 ```Authorization.iso
   if((WiFiMulti.run() == WL_CONNECTED)) {

        HTTPClient http;
  　　  ...
　      http.begin("http://user:password@192.168.1.12/test.html");
  　　  ...

        // start connection and send HTTP header
        int httpCode = http.GET();

        // httpCode will be negative on error
        if(httpCode > 0) {
            // HTTP header has been send and Server response header has been handled
            USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);

            // file found at server
            if(httpCode == HTTP_CODE_OK) {
                String payload = http.getString();
                USE_SERIAL.println(payload);
            }
        } else {
            USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n",
　　　　　　　　　　　　　　　　　http.errorToString(httpCode).c_str());
        }

        http.end();
    }
```

#### BasicHttpClient

Authorizationと同じ？

#### ReuseConnection
#### StreamHttpClient
Riot.jsライフサイクル promise superagentで受け取ったデータを即反映させる。 window.onloadを使わない


superagentの導入についての説明はしません。
CDNとかnpm install があります。

**superagentはajax処理簡単にしてくれる**

`const request = window.superagent`
↑はtagファイルのscriptに書くことでsupeagentが使えます。他のajax処理(jQuery, fetch)をする場合は必要ないです。
お任せします。

```html:file.tag
//ここの値が更新されます
<p>{ item }</p>
```
以下はfile.tagのscriptに書く

```js:
//apiを取得します
GET (url) {
  return new Promise((resolve, reject) => {
    request
      .get(url)
      .accept('application/json')
      .end((err, res) => {
        if (err) {
          console.log(err);
          reject(err);
        }
        if (res) {
          resolve(res);
        }
      });
  })
};
```

```js:
//apiを取得します
Item () {
  const url = 'おまかせurl'
  this.GET(url)
    .then(d => {
       this.item = d;
       this.update();
     })
    .catch(e => {
       console.log(e);
    });
};
```



```js:
this.on('before-mount',() => {
//ライフサイクルイベント
  this.Item();
})
```
こんな感じで自分は即反映させることができました!!
RubyのNet::HTTPでKeep-Aliveが有効にならない件

# TLDR

```rb
Net::HTTP.start("httpbin.org", 80) do |http|
  # 複数のリクエストを投げる
end
```

という形式だとKeep-Aliveが有効になる（TCPコネクションが使いまわされる）。

```rb
http = Net::HTTP.start("httpbin.org", 80)
# 複数のリクエストを投げる
```

という形式でも有効になる。

```rb
http = Net::HTTP.new("httpbin.org", 80)
http.start     # このstartを忘れると有効にならない
# 複数のリクエストを投げる
```

という形式でも有効になる。

# 確認用スクリプト

OK

```rb
require "net/http"

# 同じホストに対して2回リクエストを送る
Net::HTTP.start("httpbin.org", 80) do |http|
  2.times do
    req = Net::HTTP::Get.new "/get"
    req["Connection"] = "Keep-Alive"
    res = http.request req # Net::HTTPResponse object
    p res
    res.each do |k, v|
      puts "#{k}: #{v}"
    end
  end
end
```

NG

```rb
require "net/http"

# 1回だけNet::HTTP.newして使いまわす
http = Net::HTTP.new("httpbin.org", 80)

# 同じホストに対して2回リクエストを送る
2.times do
  req = Net::HTTP::Get.new("/get")
  req["Connection"] = "Keep-Alive"
  res = http.request(req)
  p res
  res.each do |k, v|
    puts "#{k}: #{v}"
  end
end
```

NGの方だと、サーバはちゃんと`connection: keep-alive`を返してきているにも関わらず、リクエストの度にコネクションが張られてしまう。そのことは`tcpdump -nn port 80`で見るとSYN, FINが送られていることで確認できるし、Rubyが使うエフェメラルポートも変わっている。
SQLを普段あまり書かないエンジニアのためのSQL備忘録

## はじめに
　私はWebエンジニアでありながら普段あまりSQLを書くことがありません。だからこそ、突発的にSQLを書く際には毎回ググって文法を確認しています。毎回ぐぐるのはさすがにだるいのもあり、今回は私のような境遇の人でもさらっと見返せるようなSQL備忘録を記載したいと思います。
　ちなみに、DBMSはMySQLを用いていることが前提です。また、`[hoge]`には任意のワードなり数値なりを入れることとします。

## Create
### 基本的な文法
```:insert.sql
# 新しいレコードを追加(※1)
INSERT INTO [table_name] ([column_name],[column_name],[column_name],[column_name])
VALUES ([value],[value],[value],[value])

# 新しいレコードを複数追加
INSERT INTO [table_name] ([column_name],[column_name],[column_name],[column_name])
VALUES ([value],[value],[value],[value]),
  ([value],[value],[value],[value]),
  ([value],[value],[value],[value]),
  ([value],[value],[value],[value])

# SELECT文と組み合わせてレコードを追加
INSERT INTO [table_name]
SELECT * FROM [table_name] WHERE [column_name] = [value]
```

### 補足事項
(※1)
全カラムのうち一部に値を指定してデータを追加することも可能

## Read
### 基本的な文法
```:select.sql
# あるカラムのデータを抽出
SELECT [column_name] FROM [table_name]

# 複数のカラムのデータを抽出
SELECT [column_name],[column_name],[column_name] FROM [table_name]

# すべてのカラムのデータを抽出
SELECT * FROM [table_name]

# あるカラムの値にある数値を乗算して抽出(※2)
SELECT [column_name] * [number] FROM [table_name]

# あるカラムが特定の値であるデータを抽出(※3)
SELECT * FROM [table_name] WHERE [column_name] = [value]

# 複数条件を満たすデータを抽出(※4)
SELECT * FROM [table_name] WHERE [column_name] = [value] AND [column_name] = [value]

# データを昇順にソートして抽出
SELECT * FROM [table_name] ORDER BY [column_name]

# データを降順にソートして抽出
SELECT * FROM [table_name] ORDER BY [column_name] DESC

# あるカラムの値の総和を抽出(※5)
SELECT SUM([column_name]) FROM [table_name]

# あるカラムの値の最大値と最小値を抽出
SELECT MAX([column_name]),MIN([column_name]) FROM [table_name]

# 範囲指定してデータを抽出
SELECT * FROM [table_name] WHERE [column_name] BETWEEN [number] AND [number]

# パターン検索してデータを抽出(※6)
SELECT * FROM [table_name] WHERE [column_name] LIKE '%[word]%'

# 特定のカラムでグループ化してデータを抽出
SELECT [column_name],AVG([column_name]) FROM [table_name] GROUP BY [column_name]

# グループ化してテーブルから条件選択
SELECT [column_name] FROM [table_name] GROUP BY [column_name] HAVING AVG([column_name]) <= [number]

# 重複行が削除された結果を抽出
SELECT DISTINCT [column_name] FROM [table_name]

```

### 補足事項
(※2)

|主な算術演算子|意味|
|:--:|:--:|
|+|加算|
|-|減算|
|*|乗算|
|/|除算|

(※3)

|主な比較演算子|意味|
|:--:|:--:|
|=|左辺が右辺と等しい|
|<|左辺が右辺より小さい|
|<=|左辺が右辺以下|
|>|左辺が右辺より大きい|
|>=|左辺が右辺以上|
|<>|左辺と右辺が等しくない|

(※4)

|主な論理演算子|意味|
|:--:|:--:|
|AND|かつ|
|OR|または|
|NOT|否定|

(※5)

|集合関数|意味|
|:--:|:--:|
|SUM|総和を求める|
|MAX|最大値を求める|
|MIN|最小値を求める|
|AVG|平均値を求める|
|COUNT|総数を求める|

(※6)

|LIKE記述|意味|
|:--:|:--:|
|%|任意の文字列|
|_|任意の一文字|


## Update
### 基本的な文法
```:update.sql
# 特定の条件を持つレコードを更新(※7)
UPDATE [table_name] SET [column_name] = [value],[column_name] = [value] WHERE [column_name] = [value]
```

### 補足事項
(※7)
WHERE句で用いるカラムについて特に指定がなければ主キーを指定しよう。思わぬレコードが変更されることを防ぐためです。

## Delete
### 基本的な文法
```:delete.sql
# 特定の条件を持つレコードを更新(※7)
DELETE [table_name] WHERE [column_name] = [value]
```

### 補足事項
(※8)
WHERE句は基本的に指定しよう。WHERE句を指定しないとそのテーブルの全データが消し飛びます。

## さいごに
　単数の表を操作する例に留めましたが以上になります。複数の表への問い合わせ等はまた別の機会にまとめようと思います。
PyQt4のQStringについて

## PyQt4のQString,QStringListなどについて
[「PythonのPyQtによるクロスプラットフォームGUIアプリ作成入門」](http://myenigma.hatenablog.com/entry/2016/01/24/113413#%E8%A1%A8%E5%BD%A2%E5%BC%8F%E3%81%AEGUI%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9)さまのexampleで少しハマったので記録。

python3でpyqt4を使う際に「QStringなんてありません」と言われてしまう。

```python:
AttributeError: module 'PyQt4.QtCore' has no attribute 'QString'
```

これはpython3ではQStringは自動的にstrで定義されているため。
QStringListなどにしても同様。QStringListはstrのリストとなる。

修正後のコード：

```python:TableWidget.py
from PyQt4.QtGui import * 
from PyQt4.QtCore import * 
import sys
 
def main():  
    app = QApplication(sys.argv)
    table = QTableWidget()
    tableItem = QTableWidgetItem()
    
    # initiate table
    table.setWindowTitle("QTableWidget Example")
    table.setRowCount(4)
    table.setColumnCount(2)

    horzHeaders=["Name" , "Age"]
    table.setHorizontalHeaderLabels( horzHeaders );
    
    # set data
    table.setItem(0,0, QTableWidgetItem("Tom"))
    table.setItem(0,1, QTableWidgetItem("15"))
    table.setItem(1,0, QTableWidgetItem("Ken"))
    table.setItem(1,1, QTableWidgetItem("40"))
    table.setItem(2,0, QTableWidgetItem("Susie"))
    table.setItem(2,1, QTableWidgetItem("22"))
    table.setItem(3,0, QTableWidgetItem("Kevin"))
    table.setItem(3,1, QTableWidgetItem("65"))
 
    # show table
    table.show()
    return app.exec_()
 
if __name__ == '__main__':
    main()
```

## 参考と出典
[How to create QString in PyQt4?](https://stackoverflow.com/questions/1400858/how-to-create-qstring-in-pyqt4)
[PyQt4 and Python v3](http://pyqt.sourceforge.net/Docs/PyQt4/python_v3.html)
GitHubに間違ったコミットをpushしてしまった時の対処法

#背景

iOSのアプリ開発をしていて
修正した部分をGitHubのリポジトリにpushしようとした時に
間違ったコミットをpushしてしまった。


普段は、修正点の差分を`git add -p`
で一つずつ確認しながら

y(Yes) or n(NO)で変更を採用するかしないか（ステージングにあげるかあげないか）を決めているのだが、
今回はミスって`git add .`でしてしまった。
（このコマンドだと、`ls -a`で出てくるような .~~ のファイルの差分とかも含め全て一気に採用してステージングに取り込んでしまう）

これをしてしまったため、
Carthageの不要な差分まで採用してpushしてしまい、
GitHubに上がった差分を見た時にそれに気づいた。
（ああ…これを取り消したいっ）

#対応方法

このようにGitHubにpushしたくなかったコミットの差分を
元に戻すには、

`git revert (コミットID)`
をする。

これをすると、該当のコミットの変更を取り消ししたコミット
が出来上がる。

これをpushすると、GitHub上でも前の状態に戻る！
ちなみに、間違った時のコミットとそれをrevertしたよというコミットのログは残る。
(まぁ、これは仕方がないことである)

逆に、ローカルで間違った(直前の)コミットをなかったことにしようとして
`git reset —hard HEAD^`
とかをしてしまうと逆に大変。
（HEADの後の^を二つにしてHEAD^^とすると二つ前のコミットまで戻る）


ローカルでは確かになかったことになり`git log`すると
一つ前のコミットまでは戻っているが、
これでGitHubにpushしようとしてもできない上、
GitHubの履歴に合わせてpushできるように戻そうと
慌てて `git reset —hard HEAD@{1}`
と、(stashした時にpopで戻すような感じで)戻しても、
この戻ってきた間違いコミットのコミットIDは、
GitHubにあげてしまった間違いコミットのコミットIDとは
また別物に変わってしまっているためpushができなくなっている。


なので、GitHubに間違ってpushした時は
間違ったコミットをなかったことにはせず、
素直に`git revert (コミットID)`をして、自分のミスを受け入れて
間違ったので取り消しましたとわかるコミットも履歴に残しておこう。
DockerでサクッとRubyのあれこれを実行する

いずこかなんしかRuby製の開発ツールを導入しようと思ったとき、「おやRubyが古いぞ」「おやbundlerが入っていないぞ」「おやgem installできないぞ」等々の問題が発生することがあります。
やれRVMだなんだというのも面倒ですので、Dockerが使えるならRuby環境のコンテナを作って実行してしまいましょう。
この記事を執筆するきっかけとなったケースではRedmineをherokuにデプロイする前の準備（bundel install)に使用しました。

##手順
・ソースがあるディレクトリで以下のコマンドを実行

```bash:ホストのシェル
docker run --name ruby -i -t -v `pwd`:/var/ruby -w /var/ruby ruby /bin/bash
```

・コンテナにログイン後、任意のコマンドを実行

```bash:コンテナのシェル
bundle install
...
...
...
exit #最後はログアウト
```

・作業が終わったらコンテナ削除

```bash:ホストのシェル
docker rm ruby
```

##補足

###起動コマンド

参考までに起動コマンドの解説を記載しておきます

- docker run　→コンテナの起動
    - --name ruby　→コンテナ名
    - -i -t　→コンテナのシェルとホストのシェルを接続
    - -v `pwd`:/var/ruby　→ホストのカレントディレクトリをコンテナにマウント
    - -w /var/ruby →コンテナの作業フォルダをマウントしたディレクトリに設定
    - ruby　→コンテナの作成元イメージ
    - /bin/bash　→コンテナログイン後に使用するシェル
    
Rubyのバージョンを変更する場合は、イメージを指定する際に`ruby:2.3`と書きます。

###その他注意点

作業後の`docker rm ruby`を忘れると次回の起動時にコンテナ名の重複でエラーになるので気をつけましょう。

###

##検証環境
- macOS Sierra v10.12.3
- Docker for Mac v17.03.1
- 公式Rubyコンテナ v2.4(https://hub.docker.com/_/ruby/)
RailsでページビューをカウントするimpressionistでMySQLエラーが出た時の回避法

Railsで開発途中のアプリケーションにページビュー機能を付けるgem`impressionist`使用した際に起きた問題の回避方法のメモ

## 環境

* Ruby 2.4系
* Rails 5.0系
* MySQL 5.7系

## 発生した問題

`impressionist`について調べると、Gemfileに以下のように記述されている例が紹介されている。

```Ruby
# 一般的なgemの指定方法
gem 'impressionist'

# バージョンを指定した方法
gem 'impressionist', '~> 1.5.1'
```

以上の方法で`rake db:migrate`をするとMySQL Errorで以下のようなメッセージが出る。

```
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: BLOB/TEXT column 'params' used in key specification without a key length: CREATE  INDEX `poly_params_request_index`  ON `impressions` (`impressionable_type`, `impressionable_id`, `params`)
```

## 回避方法

以下のような手順で回避出来る。

Gemfileに以下のように記述

```Ruby
gem 'impressionist', git: 'https://github.com/charlotte-ruby/impressionist.git'
```

以上記述したら、`bundle install`を行い、`rails g impressionist`、`rake db:migrate`を行う一連の流れのまま進められる。
設計についての個人的まとめ

#この記事について#
自分の備忘録として、設計全般についての自分の考えや調べたことを記載していきます。
ほぼリンク集として使用。
経験が浅いので、間違っていることもあると思いますがご容赦ください。

#概念

3つのアプローチがあります。
プロセス中心アプローチが私が経験してきた現場では多かったです。

| 事項       |       説明|       参照|
|:-----------------|:------------------|:------------------|
|プロセス中心アプローチ(構造化設計)|プログラムの処理構造に重きを置いた設計手法<br>|-|
|データ中心アプローチ|記載予定|-|
|オブジェクト指向アプローチ|記載予定|-|

<b>概念図</b>
[【初級】ゼロから学ぶDOA　第1回](http://itpro.nikkeibp.co.jp/article/COLUMN/20061019/251255/?rt=nocnt)

#プロセス中心アプローチ(構造化設計)の流れ#

必要な機能を整理し，段階的に詳細化する手法です。
参考元のリンク先がかなり分かりやすいので、それを抜粋してみました。

| 番号 | 事項       |       説明|       参照|
|:------|:-----------------|:------------------|:------------------|
|1|要件のヒアリング|記載予定|-|
|2|機能の洗出し|要件をヒアリングし、作成するべき機能の一覧を作成|-|
|3|業務フローの明確化|業務フロー図を作成|-|
|4|データフローの明確化|業務フロー図からDFD（データフローダイアグラム）を作成し、入力元、出力先を明らかにする|-|
|3|機能のグループ化|機能の一覧から類似機能を整理します|-|
|4|階層構造化|機能を実現させるための処理を分割します。<br>例<br>データ登録機能<br>　登録内容チェック<br>　データ登録処理<br>　データの採番処理<br>||
|5|機能仕様の文書化|以下をまとめた資料を作成します。<br>機能一覧<br>DFD<br>機能階層構造図<br>IO一覧<br>|-
|6|画面基本仕様の作成|以下を記載した全体資料を作成します。<br>画面一覧<br>画面遷移図<br><br>以下を記載した個別資料を作成します。<br>画面1つの1つの機能概要<br>機能詳細<br>イベント一覧<br>|-|
|7|バッチ流れ図の作成|一括してデータ処理する際の個別の処理の流れを記載します|-|
|8|システム概要図の作成|システムを構成するプログラミング言語、フレームワーク、DB製品を書いていきます|-|
|9|詳細設計|画面、バッチともに作成していきます。あると便利なのは以下のものです。<br>大まかな処理の流れ図<br>詳細なフローチャート<br>ER図<br>テーブル定義書<br>|-|

参照元
[ソフトウェア設計手法](https://www.infotech-s.co.jp/syuppan/pdf/04.pdf)
[レガシーシステムの設計手法](https://www.ogis-ri.co.jp/otc/hiroba/technical/JavaWorld_Legacy/part2/LegacyDesign.html)
[【初級】ゼロから学ぶDOA　第1回](http://itpro.nikkeibp.co.jp/article/COLUMN/20061019/251255/?rt=nocnt)
[ソフトウェア設計手法](https://www.infotech-s.co.jp/syuppan/pdf/04.pdf)

#記法#

| リンク名       |       説明|
|:------|:-----------------|
|[PAD](http://ajt.pupu.jp/WorkaPlayer/?p=37)|フローチャートを代用できる記法|
C/C++でよく見る「0x01とか0x02で関数にオプションを与えるアレ」

あいまいなタイトルで申し訳ありません。
よく見かける手法なのですが、具体的な名前を見つけられませんでした。ご存じの方いたらご教示ください。

# アレって何・・・
C/C++で以下のようなオプション的なものの定義をよく見かけませんか。

```cpp
#define DO_A 0x0001
#define DO_B 0x0002
#define DO_C 0x0004
#define DO_D 0x0008
#define DO_E 0x0010
#define DO_F 0x0020

doSomething(DO_A | DO_B | DO_F);  // この引数の与え方をアレと言っている！！！
```
ポイントは、以下です。

- 各オプションの値が2進数にした時に0001, 0010, 0100, 1000,,,と相異なる1bitのみが1になるように定義されていることと。
- 関数に与えるときに各オプションを " | "(bitwise OR)で与えること

恥ずかしながら、今までこの手法の実装方法を知らなかったのでまとめの意味で説明してみます。

# bitwise OR (念の為)
C/C++でif文でよく使うORは " || "(logical OR) ですが、ここで使うのは " | "(bitwise OR) です。
これはbit単位でORを取るものなので、
0001 | 0010 = 0011
1100 | 0011 = 1111
ということです。logical OR と bitwise OR を念のためコードで比較してみました。

```cpp:sample1.cpp
#include <cstdio>
int main (void) {
  const int X = 0x02;
  const int Y = 0x10;

  printf("logical OR: 0x%x\n", X || Y);  // %xは16進数表示
  printf("bitwise OR: 0x%x\n", X | Y);
  return 0;
}
```

```:sample1実行結果
logical OR: 0x1
bitwise OR: 0x12
```


# bitwise AND で与えられたオプションを分解
ではオプションを受け取った側はこれをどう分解し、解釈すればい良いのでしょうか。
これは bitwise OR の対となる "&" (bitwise AND) を使うと極めて簡単に書くことが出来ます。

```cpp:sample2.cpp
#include <cstdio>
const int DO_A = 0x01;
const int DO_B = 0x02;
const int DO_C = 0x04;

void doSomething(const int option) {
  if (option & DO_A) {  // これだけで DO_A が option に含まれているか判定できる
    printf("do A\n");
  }
  if (option & DO_B) {
    printf("do B\n");
  }
  if (option & DO_C) {
    printf("do C\n");
  }
}

int main (void) {
  doSomething(DO_A | DO_C);
  return 0;
}
```
```:sample2実行結果
do A
do C
```

doSomething関数が受け取る `DO_A | DO_C` の値は何でしょう？
0x01 | 0x04 なので、0001 | 0100 = 0101 → 0x05 です。これが doSomething関数の `option` に格納されます。

では if の中でやっている `if (option & DO_A)` は何をやっているのでしょうか。
0x05 & 0x01 → 0101 & 0001 = 0001 → 真、となります。

では `if (option & DO_B)` は？
0x05 & 0x02 → 0101 & 0010 = 0000 → 偽、となります。

# まとめ
というわけで、引数に与えるときは bitwise OR、与えられたものを分解解釈するときは bitwise AND で簡単にできるということでした。
ご参考になれば幸いです。

なお、定数を定義する際は以下のようにビットシフトを用いた書き方もよく見ます。

```cpp:sample3
#include <cstdio>
const int P = 1 << 0;  // << で 1を左へビットシフト
const int Q = 1 << 1;
const int R = 1 << 2;
const int S = 1 << 3;
const int T = 1 << 4;
const int U = 1 << 5;

int main (void) {
  printf("P: 0x%04x\n", P);
  printf("Q: 0x%04x\n", Q);
  printf("R: 0x%04x\n", R);
  printf("S: 0x%04x\n", S);
  printf("T: 0x%04x\n", T);
  printf("U: 0x%04x\n", U);
  return 0;
}
```

```:sample3実行結果
P: 0x0001
Q: 0x0002
R: 0x0004
S: 0x0008
T: 0x0010
U: 0x0020
```

おわり
PRMLの図をPythonとNumpyとmatplotlibで作成してみる。

PRMLに記載されている図を、主にpython,matplotlib,numpyを使って作成していきます。

コーディング作法的なことは全く知らないので、
コードが汚いだとか、計算効率が悪いだとか、何かあればコメントお願いします。

リンクが張られていないものは、記載予定の記事です。
暇を見つけて、おいおい書いていきます。

|章|内容|
|:--|:--|
|第1章 序章|[図1.4 多項式曲線フィッティング](http://qiita.com/Alreschas/items/06750a6752786a625ef8)|
|第1章 序章|[図1.15 ガウス分布の最尤推定におけるバイアス](http://qiita.com/Alreschas/items/b1dd6f65a2c2bcec8d26)|
|第1章 序章|図1.17 ベイズ曲線フィッティング|
|第1章 序章|[演習問題1.4 確率密度関数の非線形変換](http://qiita.com/Alreschas/items/847d164be04dd30d5035)|
|第2章 確率分布|図2.5 ディリクレ分布|
|第2章 確率分布|図2.7 ガウス分布|
|第2章 確率分布|図2.9 ガウス分布の条件付き分布|
|第2章 確率分布|図2.12 ガウス分布の平均$\mu$に対するベイズ推論|
|第2章 確率分布|図2.13 ガンマ分布|
|第2章 確率分布|図2.14 正規-ガンマ分布|
|第2章 確率分布|図2.16 スチューデントのt分布|
|第2章 確率分布|図2.19 フォンミーゼス分布|
|第2章 確率分布|図2.25 カーネル密度推定法|
|第2章 確率分布|図2.26 K近傍法|
[AWS Summit2017]サーバレスアプリのアンチパターンとチューニングメモ

# [AWS Summit2017]サーバレスアプリのアンチパターンとチューニングメモ

AWS Summit2017で聞いてきたサーバレスアプリのアンチパターンとチューニングのメモです。
Lambdaの仕組みの中まで知らなかったのと、気をつけるべきところが多くあったので、とても参考にさせていただいております。
プラスで自分が他に参考にしたサイトもリンクさせていただきます。

## アプリが遅くなる原因

### ① プログラムの問題
ロジックそのものの問題は、各言語のベストプラクティス、最適化手法はそのまま当てはめるべき
Node.jsで自分は書くことが多いので、下記を参考にしている

- [Node.jsベストプラクティス](https://www.webprofessional.jp/node-js-best-practices-from-the-node-gurus/)

### ② コンピューティングリソース不足
メモリ設定は最適にすること
メモリサイズと比例してCPU処理能力も割り当てられる
コストを気にしがちだが、メモリを増やせば処理時間は早くなるので、結果的にコストはそこまで変わらないときもある
※ ちょっとずつ変更して性能が変わらないところが最適値

- [Lambdaメモリによる性能のちがい](https://www.business-on-it.com/2003/techblog/aws-lambda-performance-check/)

### ③ コールドスタート
Lambdaファンクションの実行時におきていること
1. ENIの作成（10秒から30秒かかる、Durationには含まれない）
2. コンテナの作成
3. デプロイパッケージのロード
4. デプロイパッケージの展開（S3からDLやZipのファイル展開、Durationには含まれない）
5. ランタイム起動・初期化（グローバルスコープの処理もこのタイミング）
6. 関数/メソッドの実行（ハンドラーで指定した関数・メソッド、Duration値はここの実行時間）
全てを実行するのがコールドスタートという
1-5は毎回同じ内容が実行される（再利用することで効率化できる）

コールドスタートが起こる条件

- コンテナが1つもない
- 利用可能な数以上の同時リクエスト
- コードや設定変更

早くするためにはどうしたらよいか？
コンピューティングリソースを増やす（メモリを増やす）
ランタイムを変える（各言語の仕様にもよる・・）
パッケージサイズを小さくする（展開に時間がかかるので）
VPCは必要でない限りしようしない（その分10ｰ30秒ぐらい余計に必要）
⇒ VPC内のリソースが必要であればDynamoDBStreamsとLambdaで非同期に
Global領域の遅延ロードを行えばいい

### ④ アーキテクチャの問題
同期でInvokeすると同時実行数の制限に引っかかる
できるだけ、非同期でInvokeするとスケーラビリティの観点ではいい
APIGatewayからの処理として、Put系であればSQSとかに流してしまう
いかに並列処理を行うかが大事
⇒ 1つあたりのイベントを小さくして、同時に並列で動かせるアーキテクチャにする

### ⑤ 同時実行数
同時実行数＝3s/exec x 10req/sec < default1000
ストリームベースの場合は少し違う
⇒ ストリームのシャードの数だけしか同時実行数しないといけない（これはSQSやKinesisのところを変える）

## アンチパターン

### LambdaでRDBMS使いがち問題
コネクション数の問題がある（Lambdaからの1リクエストに対してコネクションがそれぞれに貼られるから）
また、VPC内にRDBMSがあるからコールドスタート問題がある

RDBMS使うときはDynamoDBStreamとLambdaで転送

### IP固定したがり問題
証明書や署名などで担保すべき（スケーラビリティがなくなる）

### サーバーレスに夢見がち問題
サーバ管理は不要だが、運用は必要
複雑なことをやろうとすると設計開発コストが上がる可能性が・・
⇒ シンプルに使おう

### 監視しなくていいと思っている問題
適切にモニタリングしてあげる（CloudWatchでみる）
特に、ErrorsとThrottles

## その他
Lambdaは最低一回実行は保証しているので、1回しか実行しないわけではない
DynamoDBを利用するときは冪等性を担保する
pdf > Deep Neural Network: Mathematical Mysteries for High Dimensional Learning by Stephane Mallat (2016)

**注意:34MBもあるファイル**
http://learning.mpi-sws.org/mlss2016/slides/CadixCours2016.pdf

Curse of Dimensionality
に対してどうするかという資料が掲載されている。

以下、気になった部分。
他の部分は自分が行いたいfunction approximationとは関係なさそう。また、内容の理解不足もある。

### 4枚目の資料 > Curse of Dimensionality

> f(x) can be approximated from examples {x_i, f(x_i)}_i by local interpolation if f is regular and there are close examples:

> Need eps^{-d} points to cover [0,1]^d at a Euclidean distance eps
Problem: ||x - x_i|| is always large

### 33枚目の資料 > Linearize Symmetries

linearize the orbits

変化の激しいorbitsを変化の緩和なorbitsに変換する。

Lipshitz:
https://en.wikipedia.org/wiki/Lipschitz_continuity

### 関連論文

Understanding Deep Convolutional Networks
Stéphane Mallat

https://arxiv.org/abs/1601.04920
Heroku Scheduler の料金がかさんだのでworker に切り替えたら大分安くなった

# 経緯
動かしているものは秒単位で変動する金融APIへ接続し発注するシステム。システムそのものの詳細はここでは省略させていただきます。

heroku scheduler の料金について調べた時にはここまで分からなかったので、具体的な事例として共有します。

## スキルのバックグラウンド
- 僕は非エンジニアであるが、サービスを作りたくて触っていたら一通りコードが書けるようになった（Rails はじめて半年とか）
- Heroku も触っていたらそれなりに使えるようになった

# まとめ

## 事前に分かっていたこと
- 24時間稼働のtaskは worker を使うこと
- schedular は短時間のバッチ処理に利用すること

## 事前に分かっていなかったこと
- schecular の料金体系

## 新たに分かったこと
- one-off dyno は起動単位で課金される
- 複数のスケジュールが立ち上がり、それぞれ長く起動すると起動ごとに課金が積み重なる

## 結論
- scheduler の長めの処理は、worker １つにまとめよう
- scheduler が使う one-off dyno の料金体系は見えにくいが、とにかく短時間で終了する設計が望ましい

# 詳細
## 動かしているアプリケーション
- 金融系の取引ツール（Railsで自作）
- API に接続しているバックエンドシステム
- 24時間常駐のWorkerを rake task で実行
- web は起動していない

## schedulerを使っていた場所
- 注文残・ポジション残をチェックして、10分おき、1時間おき、1日起きの処理を入れる
- 1分以内に終了するタスクばかりだった

ここまでは良かった。
しかし scheduler の費用がほとんど見えないくらい安かったので、この後の処理を、 scheduler から動かしてしまったのが過ちだった。

## scheduler に追加した処理
- より効率性を追い求めるために、秒単位で変動する値動きに対して、10秒ごとに統計的処理を加えて注文状況を変更する rake task を追加した
- 起動時間を長くするため、10分ごと起動のタスクの中で、10分経過するまで sleep
 を入れつつ繰り返し処理をした

worker は固定で費用がかかるが、scheduler はあまり費用がかかっていなかったので、 「__待機時間が長いだけで、ひとつひとつは重い処理ではないから__」 scheduler で動かせばいいや、と思ってしまった。
この時には 「worker で動かすこと」と、 heroku のドキュメントに書いてあることの意味が理解できていなかった。

## かかった費用
### scheduler
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141741/abf9e2d2-cf18-f65b-d1b3-ae28e3623f77.png)

14日に気づいたので、応急処置でプログラムを触らない方法で起動数を減らしました。15日から減っているのはそのためです。19日で止めています。

### worker (もともと動いている worker )
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141741/b5d5cce6-e668-7142-27ea-67c0cfa05bd6.png)


## スケジューラーを止めて worker に移行した後の worker 2
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141741/45736f87-79a3-7f0a-33b6-d02186af404f.png)

金融系なので19日の月曜日から稼働。

__費用抑制効果は一目瞭然ですね。__

# ちなみに
1ヶ月間チェックしていなかったので、この時点ですでに先月分が請求されていました。^^;

# 5月の scheduler 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/141741/1c031ef3-c671-3b9f-4c06-5fdb25b59152.png)

worker が $7 だとすると、約２０倍ですね。
dynos の数を見ての通り、並行起動は全て足し算されています。
前半は試行錯誤していたので、task が増えていた時期です。
並行起動する task が増えただけで、処理そのものは軽微なものです。
つまり、起動数を抑制するために worker1つに収めて、全てそのworker内で完結する方がコスト的に大変望ましい、ということになります。

## 費用比較時の留意点
6月に入ってscheduler の起動数は安定しました。（試行錯誤が終わりました。）
ですので、 schedulerの費用とworker移行後のコスト比較は6月で見るのが正しいです。（5月は参考程度）

スケジューラーを止めて移行した worker 2 では、それまでの処理内容は変えていません。同じ処理の起動方法が変わっただけです。（起動方法は１つのrake taskから呼び出すように変えています）

6月15日でdyno数が2になっている通り、プログラム以外の対処により起動数が減っています。厳密には 2 -> 1 に減ったことになります。
ただし、 worker に移行したことで、 14日以前の状態に戻しても 1 のままで済むと思われます（ここは推測）。そう考えると 6 -> 1 の削減です。

以上、heroku scheduler の料金について調べた時にはここまで分からなかったことと、安易に scheduler を立ち上げてしまうとこうなる事例、、ということで共有させていただきます。
windowsでTensorFlow その25

#概要
windowsでTensorFlowやってみた。
生tensorflowは、つらいので、1.2にして、Highlevel apiやってみた。
偶数分類やってみた。

#環境
windows 7 sp1 64bit
anaconda3
tensorflow1.2

#サンプルコード


```
import numpy as np
import tensorflow as tf
import tensorflow.contrib.slim as slim
from sklearn import metrics, cross_validation

def binary_encode(i):
	return np.array([i >> d & 1 for d in range(8)])

def even_odd_encode(i):
	if i % 2 == 0:
		return np.array([1])
	else:
		return np.array([0])

trX = np.array([binary_encode(i) for i in range(1, 256)])
trY = np.array([even_odd_encode(i) for i in range(1, 256)])
x_train, x_test, y_train, y_test = cross_validation.train_test_split(trX, trY, test_size = 0.2, random_state = 42)

input_ph = tf.placeholder("float", [None, 8])
output_ph = tf.placeholder("float", [None, 1])

hiddens = slim.stack(input_ph, slim.fully_connected, [10], activation_fn = tf.nn.relu)
predictions = slim.fully_connected(hiddens, 1, activation_fn = None)
loss = tf.contrib.losses.mean_squared_error(predictions, output_ph)
train_op = slim.learning.create_train_op(loss, tf.train.AdamOptimizer(0.01))

sess = tf.Session()
sess.run(tf.initialize_all_variables())
errors = []
for i in range(1001):
	mse = sess.run(train_op, feed_dict = {
		input_ph: x_train,
		output_ph: y_train
	})
	errors.append(mse)
	if i % 100 == 0:
		print ("epoch %d, validation MSE %g" % (i, mse))



```
Swift 3.0 で 別なviewcontrollerとstoryboardに遷移する方法



### 別なviewcontrollerとstoryboardに遷移するには

1.まずはXCode上に新しいStoryboardとViewControllerを作っておく
![Screen Shot 2017-06-23 at 3.21.58 PM.png](https://qiita-image-store.s3.amazonaws.com/0/158705/c1d5c442-a680-4acc-3a79-c4ce1eaf648f.png)

*Storyboard2.storyboard と ViewController2.swiftと名付けておく

2.適当にViewController.swiftにボタンを作ってアクションを加える。

3.アクション内にコードを追加！

```
    @IBAction func to2ndStoryBoard(_ sender: Any) {
        let storyboard: UIStoryboard = UIStoryboard(name: "Storyboard2", bundle: nil)
        let vc = storyboard.instantiateViewController(withIdentifier: "NextViewController") as! ViewController2
        self.show(vc, sender: self)
    }
    
```

4.結果

見た目はただのNavigationViewControllerですが、プロジェクトが大きくなる時にstoryboardを分けられると便利。

![jumptoanotherStoryboard.gif](https://qiita-image-store.s3.amazonaws.com/0/158705/121f7aab-0f17-ae6f-0969-b7f4f14e3cc4.gif)
ツクールMV用をgitで管理する（ためのgitignore）

私がツクールMVのプロジェクトをgitで管理するときに使っているgitignoreです。
コピペでどうぞ。

.gitignoreというファイルを作成し、これをプロジェクトに入れます。
このファイルはgitでバージョン管理をするときに、コミット対象を制御するためのファイルです。
Windows環境では拡張子のみのファイルを作るのに手間が必要なので、エディタで調整しましょう。
私は以下のような設定にしています。

```:.gitignore
#音声ファイル
*.m4a
*.ogg
*.png
*.psd
#desktop.iniというwindowsの設定用隠しファイル
desktop.ini

# ツクール本体が自動生成するスクリプト
# プラグインパラメータを保存したいのであれば、コメントアウト
/js/plugins.js
/data/System.json
# エディタ用の無視設定
/.vscode/
#セーブデータ
/save/
#デバッグ用の一時ファイル
/debug/
#その他リソース
/audio/
/img/
/fonts/
/icon/
/movies/

#メインのスクリプト
/js/libs/
/js/rpg_core.js
/js/rpg_managers.js
/js/rpg_objects.js
/js/rpg_scenes.js
/js/rpg_sprites.js
/js/rpg_windows.js

#自分のプラグインのみをコミット対象にする設定
#自作プラグインにプレフィックスなどを付けて、うまく制御してください。
/js/pluguins/*.js
!/js/pluguins/xx*.js

```
Swift 3.0 でのFirebaseDatabaseの読み込み(取得)・書き込み(保存)

# 自分用のメモがわり！

環境 Swift3.0 / Xcode8.3.3

Firebaseデータベースをimportした後の処理。

### 書き込み

1.まずはReference(参照をつくる)

```
let ref = Database.database().reference()
```

注意!: Swift3 とXcode8.3.3では
x FIRDatabase ではなく、○ Dababase らしい。
公式Documentが更新されていないだけ・・・。

2.子要素にランダムで作ったIDのフォルダを生成する。
        
 ```
 let folderRef = ref.child("ExploreFolders").childByAutoId();
```
childByAutoId()がrandamIDを作ってくれる！便利

3.ランダムIDの下に情報をぶち込む

```
 let newFolder = ["category": "BARS", "folderName": "JAZZBAR", "imageName":"livehouse1", "spotsNum":8 , "Spots":[]] as [String : Any]
 folderRef.updateChildValues(newFolder)

```
        
4 結果(Firebaseのconsole内)
 
![Screen Shot 2017-06-23 at 12.06.25 PM.png](https://qiita-image-store.s3.amazonaws.com/0/158705/17f5c658-a438-6039-84e4-e52a5b4a7502.png)


### 読み込み　/　取得 


1.書き込みと同じく、参照をつくる

```
let ref = Database.database().reference()
```

2.書き込み

``` 
self.ref.child("ExploreFolder").observeSingleEvent(of: .value, with: { (snapshot) in


　　　　　　　// "ExploreFolder"の子要素ごとになにかを実行
            for folder in snapshot.children {

                if let snap = folder as? DataSnapshot {
                    print(folder.category) // "category" keyの値がprintされる。
                }
            }
```
            
3.結果(Firebaseのconsole内)

```
Music
BARS
```
![Screen Shot 2017-06-23 at 12.24.03 PM.png](https://qiita-image-store.s3.amazonaws.com/0/158705/6726ec9e-719b-35e0-8760-b5f9c268a610.png)
AnsibleでHinemosインストール

# 概要
  * hinemos manager, hinemos web clientをインストールする。

# 環境
  * RHEL 7.3
  * Ansible 2.3
  * Hinemos 6.0

# スクリプト

```ini:inventory.ini
[hinemos-manager]
hinemos-manager-svr
```

```yaml:main.yml
---
# hinemos manager, web-clientをインストールする
- hosts: hinemos-manager
  become: yes

  vars:
  # hinemos 6.0
  - java_yum_name: "java-1.8.0-openjdk-devel"
  - hinemos_manager_rpm_url: "https://github.com/hinemos/hinemos/releases/download/v6.0.1/hinemos-6.0-manager-6.0.1-1.el7.x86_64.rpm"
  - hinemos_web_client_rpm_url: "https://github.com/hinemos/hinemos/releases/download/v6.0.1/hinemos-6.0-web-6.0.1-1.el7.x86_64.rpm"

  tasks:
  - name: Open JDKをインストール
    yum:
      name: "{{ java_yum_name }}"
      state: present

  - name: vim-commonをインストール
    yum:
      name: vim-common
      state: present

  - name: unzipをインストール
    yum:
      name: unzip
      state: present

  - name: SELinuxを無効化する
    selinux:
      state: disabled
      
# *** SELinuxの無効化がchangedの場合は、手動で再起動してから再実行する ***

  - name: Hinemos Managerをインストール
    yum:
      name: "{{ hinemos_manager_rpm_url }}"
      state: present

  - name: Hinemos Web Clientをインストール
    yum:
      name: "{{ hinemos_web_client_rpm_url }}"
      state: present

  - name: FirewallでHinemosが使用するポートを空ける
    firewalld:
      port: "{{ item }}"
      permanent: yes
      immediate: yes
      state: enabled
    with_items:
      - 8080/tcp
      - 8443/tcp
      - 8081/tcp
      - 8444/tcp
      - 514/tcp
      - 514/udp
      - 162/udp
      - 8082/tcp
      - 80/tcp
      - 443/tcp

  - name: Hinemos Managerを起動
    service:
      name: hinemos_manager
      state: started
      enabled: yes

  - name: Hinemos Web Clientを起動
    service:
      name: hinemos_web
      state: started
      enabled: yes
  ```

# 実行
  * 以下のコマンドを実行する

    ```
    ansible-playbook -i inventory.ini main.yml --ask-pass --ask-sudo-pass
    ```

  * sshユーザを指定する場合

    ```
    ansible-playbook -i inventory.ini main.yml -u <REMOTE-USER> --ask-pass --ask-sudo-pass
    ```

  * チェックのみで変更を加えない場合
  * 
    ```
    ansible-playbook -i inventory.ini main.yml --check --ask-pass --ask-sudo-pass
    ```

# 注意
  * SELinuxの設定が変更された場合は、手動で再起動しないとHinemmos Managerのインストールに失敗する。

# 今後の改善点
  * SELinuxの設定変更後の再起動を自動化する。
  * 日本語化, タイムゾーン指定（日本語ロケールでインストールする）

# 参考
  * [Hinemos ver\.6\.0 入門編① Hinemos ver\.6\.0を使ってみよう \| Hinemos \| クラウド時代の統合運用管理](http://www.hinemos.info/technology/nttdata/2017033001)

  * [【連載01】205\.SELinuxを無効化する【Ansible SELinuxモジュール】 \- Qiita](http://qiita.com/CsFactoryitter/items/c3670600f51bf4903dd7)
【Unity】すごくゆるいGLSL to HLSL変換

glsl(glslsandboxのコードなど)から、hlslに変換し、Unity用で、フラグメントシェーダーのみのコードに変換し、shaderファイルを出力させるツールです。

##ソースコード
https://github.com/yasuohasegawa/GLSLToHLSL

##環境
Mac Sierra 10.12
python2.7
Unity5.3.5f1


##使い方
1. ソースコード、DLもしくは、クローンする。
2. Assets/Scripts/Shader/shader.txtを開き、変換したい、GLSLのシェーダーコードをコピペし、保存する。
3. Macのターミナルで、「cd [DL/クローンしたディレクトリ]/Assets/Scripts/Shader/」
に移動する。
4. 「python GLSLToHLSLConverter.py ファイル名(任意)」 で、shaderファイルを出力。
5. ファイル名を記述した場合は、「Assets/Scripts/GLSLShader.cs」で設定している、シェーダー名を適切変更する。
6. Main.unityを開き、動作を確認。

※glslsandboxのソースコードは、結構、入れ子になった書き方もあったりで、変換が難しいところは、特に手は入れていないので、shaderファイルを出力し、UnityEditor上で確認した際に、コンソールにエラーが吐かれると思いますが、最低限は変換してあるので、エラーが出た箇所を修正していけば、大抵は、動きますが、中には、エラーは出なくなったけど、真っ黒とか、真っ白とか、というのもあります、その際は、ソースコード、見直して、調整していけば、うまく、動くようになるかとは、思います。


##検証したコード

以下は、実際に変換してみて、特にエラーなどでず、動作もだいたいGLSLで動いていたもので、一緒だったものです。

**2Dエフェクト的なもの:**
http://glslsandbox.com/e#31193.2
http://glslsandbox.com/e#40943.0
http://glslsandbox.com/e#40431.3
http://glslsandbox.com/e#40357.0
http://glslsandbox.com/e#29562.0
http://glslsandbox.com/e#22867.0
http://glslsandbox.com/e#22728.0

「ベクトル x 行列」の置換まで、対応できていないので、レイトレ的なものは、以下のような、回転行列のない、ものは、エラーなく、すぐUNITY側で、動作確認できます。

**レイトレ:**
http://glslsandbox.com/e#36565.0
http://glslsandbox.com/e#31380.0
http://glslsandbox.com/e#29454.9


##HLSLコード変換の参考
https://alastaira.wordpress.com/2015/08/07/unity-shadertoys-a-k-a-converting-glsl-shaders-to-cghlsl/
https://docs.microsoft.com/ja-jp/windows/uwp/gaming/glsl-to-hlsl-reference
http://dench.flatlib.jp/opengl/glsl_hlsl
ubuntu14.04でkubectlでGKEを使い始めるまでのコマンドメモ


```
$ sudo apt-get update
$ curl https://sdk.cloud.google.com | bash
$ exec -l $SHELL
$ gcloud init
$ gcloud components install kubectl
$ gcloud container clusters create <クラスタ名> --num-nodes=<ノード数>
$ gcloud container clusters get-credentials <クラスタ名> # これで
`$HOME/.kubectl/config`に設定が書き込まれる
```

# 参考

https://stackoverflow.com/questions/32036989/kubernetes-set-up-on-ubuntu-on-google-compute

https://github.com/kubernetes/kubernetes/issues/23726#issuecomment-307763981
Windowsでのターミナル環境構築(自分用メモ)

自分用 Windowsターミナル環境構築メモ


## パッケージマネージャ導入
https://chocolatey.org/

```Powershell
Set-ExecutionPolicy AllSigned
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
```
`$ choco install chocolateygui`


## ターミナルソフト準備

### [ConEmu](https://conemu.github.io/)
`$ choco install ConEmu`

### [RictyDiminished-for-Powerline](https://github.com/mzyy94/RictyDiminished-for-Powerline)
`$ git clone https://github.com/mzyy94/RictyDiminished-for-Powerline.git`

  * ttfをDLしてインストール
  * ターミナルのフォント設定⇒
      * `Ricty Diminished for Powerline`
      * `Monospace`：off


## シェル設定

### zsh：[Babun](http://babun.github.io/)
`$ choco install babun`

`$ vi ~/.zshrc`

```diff
- ZSH_THEME="babun"
+ ZSH_THEME="好きなテーマ"
  # ex) "agnoster", "paradox", "ys"
- plugins=(git)
+ plugins=(git themes)
```

`$ vi ~/.minttyrc`

```diff
+ Font=Ricty for Powerline
+ FontHeight=11
```

### Powershell：[oh-my-posh](https://github.com/JanJoris/oh-my-posh)
```Powershell
Install-Module posh-git -Scope CurrentUser
Install-Module oh-my-posh -Scope CurrentUser
```
```Powershell
# プロファイルにテーマ設定
if (-Not (Test-Path $profile)) {New-Item -path $profile -type file -force};
echo "Set-Theme Fish" >> $PROFILE
```


## その他参考サイト
* [Windowsで使えるターミナルとシェルのまとめ](http://qiita.com/Ted-HM/items/9a60f6fcf74bbd79a904)
* [Windows10で快適なfishシェル環境構築](http://qiita.com/ysks/items/6c9d751d9a3b3b1b8020)
* [oh-my-zshのテーマに関するTips](http://qiita.com/takc923/items/c479e38112b913b7614a)
クラス名・ファイル名・テーブル名の変換

# クラス名からファイルパスへ変換(underscore)

```
 "AdminUser".underscore           # "admin_user"
 "Backoffice::Session".underscore # "backoffice/session"
```

# ファイルパスからクラス名へ変換(camelize)

```
"product".camelize            # "Product"
"backoffice/session".camelize # "Backoffice::Session"
```

# クラス名からテーブル名へ変換(tableize)

```
"Page".tableize      # "pages"
"AdminUser".tableize # "admin_users"
```

# テーブル名からクラス名へ変換(classify)

```
"people".classify # "Person"
```
Rで作るシェルピンスキーのカーペット（四角形）

ギャスケットコードの改良を機に、シェルピンスキーのカーペットの作図方法を閃いた。

# Rで作るシェルピンスキーのカーペット（四角形）
変数xは自然数のみ有効となり、描画する。

```r:main
Sierpinski.carpet <- function(x=3) {    # x = depth
    plot(0,0,main="Sierpinski carpet",xlab=" ",ylab=" ",xaxt="n",yaxt="n")
    y <- c(-1,1, 1,1, 1,-1, -1,-1)   　 # Set the position
    polygon(c(y[1],y[3],y[5],y[7]),c(y[2],y[4],y[6],y[8]),col="gray")
    if(x > 0) {
        Sierpinski.carpet.square(x-1,y)
    }
}
```

### 上記で使用している関数（サブルーチン）

```r:sub
Sierpinski.carpet.square <- function(x,y) {
    xy <- c((y[1]*2+y[3])/3,(y[2]*2+y[8])/3,(y[1]+y[3]*2)/3,(y[4]*2+y[6])/3,(y[5]*2+y[7])/3,(y[4]+y[6]*2)/3,(y[5]+y[7]*2)/3,(y[2]+y[8]*2)/3)
    polygon(c(xy[1],xy[3],xy[5],xy[7]),c(xy[2],xy[4],xy[6],xy[8]),col="white",border=F)  # center
    if(x > 0) {
        Recall(x-1,c(y[1],y[2], xy[1],y[2], xy[1],xy[2], y[1],xy[2]))      # topleft
        Recall(x-1,c(xy[1],y[2], xy[3],y[4], xy[3],xy[4], xy[1],xy[2]))    # top
        Recall(x-1,c(xy[3],y[4], y[3],y[4], y[3],xy[4], xy[3],xy[4]))      # topright
        Recall(x-1,c(xy[3],xy[4], y[3],xy[4], y[5],xy[6], xy[5],xy[6]))    # right
        Recall(x-1,c(xy[5],xy[6], y[5],xy[6], y[5],y[6], xy[5],y[6]))      # bottomright
        Recall(x-1,c(xy[7],xy[8], xy[5],xy[6], xy[5],y[6], xy[7],y[8]))    # bottom
        Recall(x-1,c(y[7],xy[8], xy[7],xy[8], xy[7],y[8], y[7],y[8]))      # bottomleft
        Recall(x-1,c(y[1],xy[2], xy[1],xy[2], xy[7],xy[8], y[7],xy[8]))    # left
    }
}
```

## gif出力
当コードでは左上から時計回りにくり抜く処理をしていく。よって、処理を関数`readline()`を用いて止めながら取得した画像を繋げると、こうなる。
![Sierpinski-carpet_process.gif](https://qiita-image-store.s3.amazonaws.com/0/188393/f6de4dae-4c71-7a81-436b-8d8e1bd5736f.gif)

余談だが、70枚を超える画像をgifアニメーションにするのは手間だった。
どうにかRで手早くgifアニメーション画像を作れないものだろうか。
ncursesやreadlineなしでbashを作るとmakeで問題が発生するようです

クロスコンパイルでミニマムなLinuxを作ってそこからセルフコンパイルでシステムを構築しようとしていたらmakeで妙なエラーが発生しました。
ncursesやreadlineなしで作ったbashを使っていると以下のようなMakefileで(echo)が失敗してexit 123で出てきてしまうようです。

    a = false

    b = ($(a))

    all:
        if $(b); then \
          echo "yes"; \
        else \
          echo "no"; \
        fi; \
        for item in 'x y z'; do \
          (echo) || exit 123; \
        done;

幸いncursesとreadlineとbashはこの問題に引っかからずにビルドできるので、まずそれらをビルドしてインストールすれば回避できます。
シェルスクリプトで小数演算する

##最近のこと
最近大学の授業でシェルスクリプトで処理を自動化することが増えました。そこで小数演算したいなと思ったんですけどシェルスクリプト自体は整数の計算しか扱うことができないの！？となったのでいろいろ調べてできたのでそれのメモです！

##小数演算のやり方
###`bc`コマンドを使う！
`bc`コマンドは簡単に言うと数値計算を行うコマンドです。
整数、小数の計算はもちろん三角関数など複雑な計算もできます。
下の sample.sh が小数演算を行うプログラム例です。

```sample.sh
#!/bin/sh

x=10
y=`echo "scale=5; $x / 3.0" | bc`
echo "$y"
```

出力は下のようになりました。

```
$./sample.sh
3.33333
```

大成功です。
少し説明すると、`scale=5`というのは小数点以下の出力桁を決めています。sample.sh では 5桁にしています。`bc`コマンドで出た結果を`echo`で取り出してやって y に入れるみたいな感じですね。
あと 1未満の結果になると`.333`のように0が出力されないようですが、一応小数として認識できるみたいなので問題ないはずです(本当か？)。
画像取得備忘録　ギャラリー呼び出し

久しぶりにアプリ作成。
追加機能として画像取得機能をつけることにしました。

ここでの処理は画像取得前の準備段階という感じで、ギャラリーを呼び出している…でいいのかな。
Intentを準備して、そこに2つの機能を追加してアクティビティを開始。
そして、情報の受け渡しを可能にしている段階。

```java
findViewById(R.id.activity_detail_select_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                intent.addCategory(Intent.CATEGORY_OPENABLE);
                intent.setType("image/*");
                startActivityForResult(intent, RESULT_PICK_IMAGEFILE);
            }
        });
```

ここから完全に雑記

```java
ACTION_OPEN_DOCUMENT
```
ピッカーを使用して、ファイルを選択するためのintent
→ ピッカー = インタフェース


```java
CATEGORY_OPENABLE
```


URIの受け渡し
URIっていうのは名前や場所を識別するためのもの
これを受け渡す事で今回であれば画像を追加する

```java
"image/*"
```
 → 文字列の種類としてこれを選択


```java
startActivityForResult
```
→アクティビティを起動し、アクティビティから何かしらの情報を受け取ることを可能にする


まったくもって自信がないので、指摘を頂けると大変助かります。
Could not open output pipe '/dev/xconsole' [try http://www.rsyslog.com/e/2039 ]

# はじめに
rsyslogの設定をしていて以下のログを見つけました。

```text:log
Jun 10 13:02:34 hogehoge kernel: imklog 5.8.10, log source = /proc/kmsg started.
Jun 10 13:02:34 hogehoge rsyslogd: [origin software="rsyslogd" swVersion="5.8.10" x-pid="8842" x-info="http://www.rsyslog.com"] start
Jun 10 13:02:34 hogehoge rsyslogd-2039: Could not open output pipe '/dev/xconsole' [try http://www.rsyslog.com/e/2039 ]
```

*/dev/xconsole* が *Could not open...* 確かに確認して見たところそんなファイル存在しませんでした。


# 原因
これはFIFOファイルが存在しないということが原因です。

FIFOについてはこちらの 「[mkfifoコマンドって使ってますか？](http://qiita.com/richmikan@github/items/bb660a58690ac01ec295)」 にわかりやすく書かれています。


# 対応
ということで、FIFOファイルを作成してあげることで解決です。

```bash:コマンド
$ sudo mkfifo /dev/xconsole
```

# おわりに
今回、rsyslogに初めて触れてFIFOログというものがあるのを知りました。今回は作成するだけで、正直扱い方はまだまだ理解できていません。今後、少しずつでも深めていけたらなと思います。
MacPortsからHomeBrew、そしてStarRuby

表題の通り、移行してStarrubyをいれなおしました。

# MacPortsからHomeBrewへ
これはググったらいろいろ出てくるので、その辺りを参考に。


#StarRubyのインストール
下記サイト様を参考に
http://qiita.com/noanoa07/items/8cbdae701cdf78246965

```shell
ruby extconf.rb
```
ってやると

```shel
checking for Mix_OpenAudio() in -lSDL_mixer... no
```

というエラー。
確かにHomeBrewでsdl_mixerはインストールしたぞ、と思ったけど。MacのRubyは2.0で、StarRubyの1.9系まで。

ということで。

```shell
/usr/local/Cellar/ruby@1.9/1.9.3-p551_4/bin/ruby extconf.rb 
```

これだといけました。

ということで、ruby1.9系の環境ベースでビルドしないと、なんですね。

次はrsdlで動かす。HomeBrewで入れたものはやはり2.0むけなので、1.9向けのものを入れなおせば大丈夫かな、と。

```shell
/usr/local/Cellar/ruby@1.9/1.9.3-p551_4/bin/gem install rsdl
```

```shell
/usr/local/Cellar/ruby@1.9/1.9.3-p551_4/bin/gem environment
```

でrsdlを探すと、/usr/local/lib/ruby/gems/1.9.1/bin/rsdlが見つかりました。

これでいけた。

あとは毎回フルパスでrubyをしていするのが面倒だなと思いましたので、なんか上手い方法がないかな、と思いました。

rbenvはそれ経由でRubyを入れないといけないぽくて、ちょっとめんどうだな、とおもったので、結局シンボリックリンクを張ってお茶をにごしました。

```shell
$ ln -s /usr/local/lib/ruby/gems/1.9.1/bin/rsdl /usr/local/bin/rsdl19
```

これでrsdl19経由でstarrubyを使えるようになりました。

#番外編 : 教訓
あたまで考えて正解に向かおうとするとどうしても袋小路に入ってしまいます。とにかく曲がりなりにも動く状況をつくって、動くと動かない、の差を考えることで、目的を早く達成できるのでは、と思いました。
gnuplotで軸の表示書式を指数形式にする

`set format` 文を使うことで指定できる

* X軸を対数尺度にして、"1.23 ✕ 10^n" みたいに表示する

```
set format x "%.2t{/Symbol \264}10^{%T}"
```

ターミナルの種類によっては `{/Symbol }`や上付き`^` などは使えないので、そのときは多少の見た目は諦めて

```
set format x "%.2tE%T"
```

などとしよう

### 参考文献

* http://bluepost69-tech.hatenablog.com/entry/2015/12/01/200019
* http://gnuplot.sourceforge.net/docs_4.2/node184.html