OmniAICreator/Qiita-1.07M huggingface dataset:
chronyがうるう秒をどう処理するのか実験してみました

# ★chronyのうるう秒の処理って？
chronyはCentOS6でもepelリポジトリからインストールする事ができます。
なので、CentOS7以外のサーバでも利用ができます。

chronyは基本的にslewモードで動くので、うるう秒が来ても、1秒ドカンと入らずに徐々に合わせてくれるような気がしてしまいますが、実際どうなるか実験してみました。

結論から言うと、ntpdと同じで1秒ドカンと挿入されました。
実験の詳細は以下です。

# ★使用ツール

NICTの時空標準研究室のサイトで公開されている、perlで書かれたSNTPを利用して、うるう秒を任意の時間に発生させるサーバを立てます。

[Perl版SNTPサーバ　うるう秒テスト用バージョン 2005.12.01](http://www2.nict.go.jp/aeri/sts/tsp/link/leap.html#2)

上記のツールの使い方については、私の会社のブログに記載したので、ここでは割愛させていただきます。

[うるう年ならぬ、うるう秒が来ます](http://www.indetail.co.jp/blog/5165/)

# ★レッツ実験！

うるう秒を発生させるツールを起動して、そこにchronydで同期させます。
すると、以下のようにLeapフラグが立つのが確認できます。


```
# chronyc tracking
Reference ID    : xx.xx.xx.xx (hogehoge.local)
Stratum         : 4
Ref time (UTC)  : Tue Jun 30 23:53:42 2015
System time     : 0.000000000 seconds slow of NTP time
Last offset     : +0.000068975 seconds
RMS offset      : 0.000068975 seconds
Frequency       : 0.014 ppm slow
Residual freq   : +33.706 ppm
Skew            : 0.143 ppm
Root delay      : 0.000231 seconds
Root dispersion : 0.001801 seconds
Update interval : 2.0 seconds
Leap status     : Insert second
```

最終行に、Insert secondの文字がありますので、leapを受信したようです。
実際のleapはうるう秒挿入の24時間前から受信が始まる事になっています。

ここでカーネルにleapが通知されているかを確認すると、

```# ntptime
ntp_gettime() returns code 1 (INS)
  time d93daae2.0c6ec000  Wed, Jul  1 2015  8:55:14.048, (.048565),
  maximum error 10000 us, estimated error 16000000 us, TAI offset 9
ntp_adjtime() returns code 1 (INS)
  modes 0x0 (),
  offset 0.000 us, frequency -25.574 ppm, interval 1 s,
  maximum error 10000 us, estimated error 16000000 us,
  status 0x10 (INS),
  time constant 7, precision 1.000 us, tolerance 500 ppm,
```

INSと出てるので、カーネルに通知されている事がわかります。
このままうるう秒まで待ってみて、直前からperlのgettimeofdayの結果を連続で表示するスクリプトを走らせます。
するとこんな結果になりました。

```
08:59:58.025634
08:59:58.125842
08:59:58.226014
08:59:58.326189
08:59:58.426417
08:59:58.526601
08:59:58.626764
08:59:58.726976
08:59:58.827187
08:59:58.927467
08:59:59.027683　←一回目の59秒
08:59:59.127878
08:59:59.228071
08:59:59.328297
08:59:59.428535
08:59:59.528753
08:59:59.628938
08:59:59.729136
08:59:59.829441
08:59:59.929633
08:59:59.029812　←二回目の59秒
08:59:59.130005
08:59:59.230200
08:59:59.330435
08:59:59.430641
08:59:59.530820
08:59:59.630993
08:59:59.731174
08:59:59.831416
08:59:59.931633
09:00:00.031870　←1秒遅れて9時になった
```

# ★実験結果まとめ

以上の結果から分かることは、基本slewモードのchronyでもうるう秒はleapをカーネルに通知してドカンと1秒挿入しちゃいます。
なので、CentOS6系で、バグ持ちカーネルにepelリポジトリからchronyをインストールしている場合は（あまり無いケースかもしれませんが）、ntpdと同様に注意が必要です。
OS X上でRedisをデーモンとして動かす

# インストール
HomebrewでRedisをインストール

	brew install redis

# 実行グループ作成
使用されているグループIDを確認する

	dscl . -list /Groups gid | sort -k 2 -n

未使用グループIDを指定してグループを作成する(今回の場合グループIDは246)

	sudo dscl . -create /Groups/_redis PrimaryGroupID 246

# 実行ユーザー作成
使用されているユーザーIDを確認する

	dscl . -list /Users UniqueID | sort -k 2 -n

未使用ユーザーIDを指定してログイン不可ユーザーを作成する(今回の場合ユーザーIDは247)

	sudo dscl . -create /Users/_redis UniqueID 247
	sudo dscl . -create /Users/_redis UserShell /usr/bin/false

先ほど作成したグループのグループIDをPrimaryGroupIDとして指定する

	sudo dscl . -create /Users/_redis PrimaryGroupID 246

ユーザーをwheelグループにも追加する

	sudo dscl . -append /Groups/wheel GroupMembership _redis

# plistファイル作成
launchdで実行する為plistファイルを作成する

	sudo vim /Library/LaunchDaemons/io.redis.redis.plist

```lang:io.redis.redis.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
	<dict>
		<key>Label</key>
		<string>io.redis.redis</string>
		<key>Program</key>
		<string>/usr/local/bin/redis-server</string>
		<key>ProgramArguments</key>
		<array>
			<string>/usr/local/bin/redis-server</string>
			<string>/usr/local/etc/redis.conf</string>
		</array>
		<key>UserName</key>
		<string>_redis</string>
		<key>GroupName</key>
		<string>_redis</string>
		<key>RunAtLoad</key>
		<true/>
		<key>KeepAlive</key>
		<dict>
			<key>SuccessfulExit</key>
			<false/>
		</dict>
	</dict>
</plist>
```

# 起動
作成したplistファイルをlaunchdに読み込ませると(問題がなければ)自動起動する

	sudo launchctl load /Library/LaunchDaemons/io.redis.redis.plist

起動しない場合、以下のディレクトリに実行ユーザー/グループでの読み書き権限があるかチェックする

- (設定でdaemonize=yesにしている場合)pidファイルの出力先(/usr/local/var/run/)
- (設定でログを出力するようにしている場合)ログ出力先ディレクトリ
- rdbファイルの出力先(/use/local/db/redis/)
文字コードと改行コードを指定して、テキストファイルに書き込み

要求仕様を満たすため、文字コードと改行コードを指定してのテキストファイルの書き込みを用意したときに気づいたこと。

java7の仕事で、標準APIのFiles#writeを使って実装してあったのですが、WindowsとLinuxで実行したときに改行コードに違いがでました。

javadocを読んでみたら、実行環境のOSによって改行コードが変わるとのこと。（厳密にはsystem propertyのline.sepalatorの値で決まるようです。）

http://docs.oracle.com/javase/jp/7/api/java/nio/file/Files.html

### 困ったときのapache commons

とりあえず巨人の肩に乗ってから考えよう、というのが最近のスタンスです。
というわけで、commons-ioのFileUtilsにそのものずばりのものがありました。

 writeLines(File file, String encoding, Collection<?> lines, String lineEnding)

https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html

車輪の再発明を避けつつ、仕様を明確に表現したいので、こういうライブラリはありがたい限りです。
PHPとイスラエル

PHPは、PHP3時代に、イスラエル工科大学の学生だったZeevとAndiによって抜本的に書きなおされました[^1]。だからといってどうということはないのですが、プログラム側からそれを認識できる場面も、2箇所ほど存在します。

# Unexpected T_PAAMAYIM_NEKUDOTAYIM
PHPでプログラムを書いていると、誤記で`Unexpected T_STRING`のようなパースエラーを起こしてしまうようなことも、少なからずあるとは思います。ですが、ある時に、プログラムのミスで吐いたエラーが、`Unexpected T_PAAMAYIM_NEKUDOTAYIM`という、まさしくエラーメッセージ自体がUnexpectedなものでした。

エラーメッセージを読むことすらできないので、ぐぐってみたのですが、ちゃんと[PHPマニュアル](http://php.net/manual/ja/language.oop5.paamayim-nekudotayim.php)に説明がありました。

>なぜダブルコロンに Paamayim Nekudotayim という名前をつけたのか、 ちょっと奇妙に感じられるかもしれません。 しかし、Zend Engine 0.5 (PHP 3のエンジン) を 書いている時に、Zend チームはこう呼ぶと決めたのです。 この奇妙な名前は、実はダブルコロンを意味するヘブライ語なのです!

かくしてこのような名前が生まれ、（ヘブライ語を解さない）多くのPHPerを[混乱に陥れる](http://stackoverflow.com/questions/592322/php-expects-t-paamayim-nekudotayim)結果となっているようです。

# 基準地点
どういう需要があるのかはあまりわからないですし、真面目に計算するなら自前の計算式を持ってくる場面でしょうが、PHP 5には、日の出日の入りを計算する、`date_sunrise()`、`date_sunset()`という標準関数があります。

で、当然ながら地点によって日の出・日の入りの時間は違うわけですが、PHP側でそのデフォルトを指定できるようになっています。そして、デフォルト値自体にもPHP標準の設定があるのですが、

* date.default_latitude = 31.7667
* date.default_longitude = 35.2333

という妙な値になっています。[Google Mapで当該地点を見てみると](https://www.google.com/maps?q=31.7667,35.2333)、ここは**東エルサレムのまっただ中**、正確な意味合いはよくわからないのですが、嘆きの壁よりは南側の地点でした。

[^1]: この2人の名前からZendという名称が生まれています。
サクッとPlantUMLで状態遷移図を書いてみた

ちょっとしたドキュメント作りたいなと探していたら、テキストで書けて比較的きれいな図が作成できる[PlantUML](http://plantuml.com/index.html)なるものを見つけたのでためしに使ってみました。

```
@startuml{状態遷移図player.png}
state PlayerTurn{
  [*] --> 入力待ち : 自摸
  入力待ち --> [*] : 打牌
  入力待ち -> カン確認入力待ち : カン [手牌=カン可能]
  入力待ち -> 和了確認表示 : [手牌=和了]
  入力待ち --> 立直打牌入力待ち : [手牌=聴牌]
  入力待ち : entry / 手牌の状態を確認
  入力待ち : do / 手牌の状態で処理を分岐
  入力待ち : do / 打牌選択
  
  立直打牌入力待ち --> [*] : 打牌選択 [打牌後の手牌=聴牌]
  立直打牌入力待ち --> 立直不可表示 : 打牌選択 [打牌後の手牌<>聴牌]
  立直打牌入力待ち --> 入力待ち : キャンセル

  立直不可表示 --> 入力待ち : OK

  和了確認表示 --> [*] : 和了宣言
  和了確認表示 --> 入力待ち : キャンセル
  
  カン確認入力待ち --> カン確定 : カン選択
  カン確認入力待ち --> 入力待ち : キャンセル

  カン確定 --> 入力待ち : 自摸
  カン確定 : do / カン公開
  カン確定 : exit / 自摸
}


@enduml
```

![状態遷移図player.png](https://qiita-image-store.s3.amazonaws.com/0/83468/e2205419-4dab-1c76-cf00-efb266bc583b.png)

麻雀の手番を表現してみました。
ちなみに状態遷移図だけでなく、各種UMLに対応しています。
ブログやwikiなどにも色々使いでありそうです。

参考：http://plantuml.sourceforge.net/index.html
Ebeanで特定項目をnullに更新

Ebeanのデフォルトの動きでは、nullがセットされている値はupdateの対象にはならないです。
通常はそれを踏まえて、主キーと更新したいプロパティの値をセットしてsaveメソッドするという使い方です。

場合によっては、DBの値をnullにセットしたいこともあります。
Ebean#updateメソッドには、第二引数にSet<String>をとるものがあります。これはSetにあるプロパティのみ更新の対象とし、nullへの上書きもできます。

あらかじめ、nullに更新したいプロパティのSetを作成し、それとBeanでnon-nullの値をもつプロパティのSetを合わせたものを渡すことで、特定項目はnullにできる更新になります。

それの結果が下記です。

``` 
     try {
            Ebean.update(bean, getUpdateProperties(bean));
            Ebean.refresh(bean)
        } catch (Exception e) {
            logger.error("update failed.", e);
        }

        logger.debug("END update");
    }

    /**
     * null更新可能なプロパティ名のセット.
     */
    private final static HashSet<String> NULLABLE_PROPERTIES =
            Sets.newHashSet(
                    "passwordExpirationDate",
                    "tokenExpirationDate"   
                    );

    /**
     * 値を持つか、null更新可能なプロパティ名のセットを取得.
     * @param bean
     * @return
     * @throws IllegalAccessException
     * @throws InvocationTargetException
     * @throws NoSuchMethodException
     */
    private Set<String> getUpdateProperties(Object bean) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        Map<String,String> beanMap = BeanUtils.describe(bean);

        Predicate<Map.Entry<String,String>> hasNotNullValueOrIsNullableKey = new Predicate<Map.Entry<String,String>>(){
            public boolean apply(Map.Entry<String, String> entry) {
                return (entry.getValue() != null) || NULLABLE_PROPERTIES.contains(entry.getKey());
            }
        };
        Map<String,String> filteredMap = Maps.filterEntries(beanMap, hasNotNullValueOrIsNullableKey);

        return filteredMap.keySet();
    }
```

non-nullなプロパティを求めるのに、commons-beanのBeanUtils#describeを使ってみました。MapのフィルタリングはGuavaを利用しています。


### 問題点

Ebean#updateのあとにEbean#refreshをしています。refreshはselect文を発行してbeanの値を再度詰め直すものです。

これをやらないと、@Entityと紐付けているテーブルとは対応していないプロパティを参照するとnullpoが発生しました･･･　更新するプロパティを制限しているせいで、オブジェクトの状態がうまくいってないのか。

## 6.x 系でのやり方

6.xでは`Ebean#update(Object bean, Set<String> properties)` がなくなっているので、別のやり方が必要。

検証中だが、次でいけそう。

* BeanPersistAdapterを継承し、preUpdateのみをoverride
* BeanPersistRequest<T>#getUpdatedValues()を使って、nullに更新したいkeyのValuePairを取得
* ValuePairは更新前後の値を持つ、setNewValue(null)で更新後の値をnullに指定

あるいは、

 `ServerConfig.setUpdateChangesOnly(false)`　として、毎回全項目を更新することで、nullへの変更をできるようにするか。（もはや項目を限定しないやり方...）

### 参考サイト

http://stackoverflow.com/questions/14795220/how-do-i-tell-play-framework-2-and-ebean-to-save-null-fields
PHPで動的計画法を用いてナップザック問題を解く

#PHPで動的計画法を用いてナップザック問題を解く

##動的計画法とは
対象となる問題を複数の部分問題に分割し、部分問題の計算結果を記録しながら解いていく手法
（メモ化再帰はまた別途）

##ナップザック問題とは
容量 C のナップサックが一つと、n 種類の品物（各々、価値 とサイズ）が与えられたとき、ナップサックの容量 C を超えない範囲でいくつかの品物をナップサックに詰め、ナップサックに入れた品物の価値の和を最大化するにはどの品物を選べばよいか？という問題

##コード
```php:Knapsack.php
/*
ナップザック
 */

class Knapsack {
    public $knapsack;      //ナップザック
    public $knapsackCount; //ナップザックの容量
    public $products;      //商品。商品はサイズと価値がある

    public function __construct($capacity) {
        $this->knapsack      = array_fill(0, $capacity + 1, 0);
        $this->knapsackCount = $capacity;
        $this->product       = array();
    }

    public function addProduct($size, $value) {
        $this->products[] = array('size' => $size, 'value' => $value);
    }

    public function solveKnapsack() {
        //ナップザックに詰め込んだ時の値を初期化
        $napValue = array_fill(0, $this->knapsackCount + 1, 0);

        //ナップザックの容量を表示する
        echo '<table  border="1" frame="box">';
        echo '<tr>';
        echo '<th>ナップサックの大きさ</th>';
        for ($i = 1; $i < $this->knapsackCount + 1; $i++) {
            echo '<td>' . $i . '</td>';
        }
        echo '</tr>';

        //扱う商品を1つずつ増やしていく
        $productCount = count($this->products);
        for ($i = 0; $i < $productCount; $i++) {
            //$napIndexの初期値は商品のサイズから。
            for ($napIndex = $this->products[$i]['size']; $napIndex < $this->knapsackCount + 1; $napIndex++) {
                $newValue = $napValue[$napIndex - $this->products[$i]['size']] + $this->products[$i]['value'];
                if ($newValue > $napValue[$napIndex]) {
                    $napValue[$napIndex] = $newValue;
                }
            }
            //表示
            echo '<tr><th>' . ($i + 1) . '番目の商品まで使用</th>';
            for ($napIndex = 1; $napIndex < $this->knapsackCount + 1; $napIndex++) {
                echo '<td>' . $napValue[$napIndex]. '</td>';
            }
            echo '</tr>';
        }
        echo '</table>';
    }
}

```

```php:knapsackTest.php
﻿<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
</head>
<body>
<?php
require_once './part/Knapsack.php';

//ナップザックの容量を設定
$knapsack = new Knapsack(32);

//ナップザックの商品を追加
$knapsack->addProduct(2,2);
$knapsack->addProduct(3,4);
$knapsack->addProduct(5,7);
$knapsack->addProduct(6,10);
$knapsack->addProduct(9,30);

//ナップザックを解く
$knapsack->solveKnapsack();
?>
</body>
</html>


```

##参考書籍
プログラミングの宝箱 アルゴリズムとデータ構造 第2版

##参考サイト
https://www.sist.ac.jp/~suganuma/kougi/other_lecture/SE/opt/dynamic/dynamic.htm
JSHintのunusedオプション

JSHintのオプションについて調べたことを、まとめます。

# unused
http://jshint.com/docs/options/#unused

このオプションは、使われていない変数があると警告を出します。
以下の値が設定できます。


## 設定できる値と、警告対象の変数

* `true` （デフォルト値）: 
varで宣言した使用されていない変数と、使われていない関数パラメータ。ただし、使用されている関数パラメータより前のパラメータは対象外。

* `vars` : 
varで宣言した使用されていない変数。関数パラメータは対象外。

* `strict` : 
全ての使われていない変数。

* `false` : 
なし

## Example

### `unused:true`
```
/* jshint unused: true */
function test(a,b,c,d,e) {
	var x=1, y=2;
	return x + c;
}
//'d' is defined but never used
//'e' is defined but never used
//'y' is defined but never used
```
関数パラメータ`a`,`b`は、使用されている関数パラメータ`c`より前にあので、警告されません。

### `unused:vars`
```
/* jshint unused: vars */
function test(a,b,c,d,e) {
	var x=1, y=2;
	return x + c;
}
//'y' is defined but never used
```
関数パラメータは警告されません。

### `unused:strict`
```
/* jshint unused: true */
function test(a,b,c,d,e) {
	var x=1, y=2;
	return x + c;
}
//'d' is defined but never used
//'e' is defined but never used
//'b' is defined but never used
//'a' is defined but never used
//'y' is defined but never used
```


## 考察
デフォルト値は`true`ですが、私は`vars`を設定することをおすすめします。

コールバック関数に渡される引数は全て定義した方がいいと思うからです。

たとえば、Array.prototype.forEachから呼ばれるコールバック関数は
function (
連結されたgzipを1行ずつ見る


最近は物騒でして、危ないサイトにアクセスしていないか？って依頼が来ることがあります。そういうことでプロキシのログを見るんですけど、効率よく検索できないと難しいところです。

で、そのプロキシログなんですが、gzip圧縮された状態で100MB以上(展開したら5倍ぐらいになる)のファイルが毎日たまっていっています。こんなの全部展開していたらログサーバはすぐにいっぱいになってしまいます。

ということで、Rubyでgzipを展開しながら見ていけばいいと言うことでこんなメソッドを作りました。

```rb
require 'zlib'
def gzip_each_line(filename, &block)
  Zlib::GzipReader.open(filename) do |gz|
    gz.each_line &block
  end
end
```

これで万事オッケーのはずってやってみたら、なぜか1行だけしか読み取ってくれなかったのです。もしかしてファイル壊れている？と思ってgunzipしたら、ちゃんと展開されました。で、gzipについて調べているととんでもない事実を発見しました。

http://linuxjm.osdn.jp/html/GNU_gzip/man1/gzip.1.html#lbAF

> 複数の圧縮ファイルを連結することができる。 この場合、 gunzip はすべての圧縮ファイルを一度に伸長する。たとえば、
>
>     gzip -c file1  > foo.gz 
>     gzip -c file2 >> foo.gz
>
> の後に
>
>     gunzip -c foo
>
> とするのは、以下と同じである。
>
>     cat file1 file2
>

え、gzipって単純連結できるの？というより、このログファイルはgzipの単純連結になってるーーー

さすが青いやつ[^1]です。ただのgzipの筈が無かった。ということで何度もGzipReaderに喰わしてあげればいいやと書き直してみました。

[^1]: ザクとは違う青いやつではありません。シェアは高いですが、まぁ、いろいろありますね、あの製品は。

```rb
require 'zlib'
def gzip_each_line(filename, &block)
  File.open(filename, "rb") do |io|
    until io.eof?
      Zlib::GzipReader.wrap(io) do |gz|
        gz.each_line &block
        gz.finish
      end
    end
  end
end
```

これでうまくいくはずと思ってやったら、二つ目のgzipでgzipじゃないよってエラーになって終わっちゃいます。どうやら、GzipReaderではioをバッファ単位で取得しているらしく、GzipReaderを閉じても使われなかったバッファが戻ってこないようなのです。つまり、読み込まれなかった分をちゃんと数えてその分戻してやらないといけない・・・となって、こうなりました。

```rb
require 'zlib'
def gzip_each_line(filename, &block)
  File.open(filename, "rb") do |io|
    unused_size = 0
    until io.eof?
      Zlib::GzipReader.wrap(io) do |gz|
        gz.each_line &block
        unused_size = gz.unused ? gz.unused.size : 0
        gz.finish
      end
      io.seek(-unused_size, IO::SEEK_CUR)
    end
  end
end
```

`GzipReader#unused`は使われなかったバッファが入っています。そのサイズ分、毎回戻してやれば、次のgzipもうまく見に行けるって方法です。これでやっといろいろ検索ができるようになりました。

というかGzipReaderがはじめから連結されたgzipファイルも対応しておいてくれていれば良かったんだけどなー。なお、単に検索するなら`zcat | grep`とかでいいんじゃね？という指摘は受け付けておりません！
Perlで座標計算

CPANで見つけられなかったので書いた。

#まずは
```
use Math::Trig;
```

# 2点の距離を求める
```
$dist = sqrt(($x2 - $x1) * ($x2 - $x1) + ($y2 - $y1) * ($y2-$y1) + ($z2 - $z1) * ($z2 - $z1));
```

# 中間点の直交座標を求める
```
$cx = ($x2 + $x1) / 2;
$cy = ($y2 + $y1) / 2;
$cz = ($z2 + $z1) / 2;
```

# 直交座標を球面座標に変換
```
$r = sqrt($x ** 2 + $y ** 2 + $z ** 2);
$t = atan2($y, $x);
$p = acos($z / sqrt($x ** 2 + $y ** 2 + $z ** 2));
```

# 球面座標を直交座標に変換
```
$x = $r * sin($p) * cos($t);
$y = $r * sin($p) * sin($t);
$z = $r * cos($p);
```
emptyが使えない(；´Д｀)

CodeigniterですがPHPの初歩なのかもしれません
いつのまにやら、emptyが使えなくなりましたが、ヒントを下さい

var_dump(empty(''));
echo empty('');


どの実行結果もこれ
PHP Parse error:  syntax error, unexpected T_CONSTANT_ENCAPSED_STRING in controllers/**.php on line ***
Errors parsing controllers/**.php

echo 'hello';
ではエラーは出ません。なんか、◯◯の設定見てごらん…的なものかと思ってますが…

よろしくお願いします。
WiX ToolsetでWelcomeDlgとExitDlgを出さないようにする

業務でインストーラーを作っていると、色々な事情で難しい要求が出てきたりする訳ですが、今回の事例もそんな物のひとつでした。
WiX Toolsetでインストーラーを作っていましたが、「最初に"WelcomeDlg"を出さないで"CustomizeDlg"を最初に出す。ExitDlgも出さない。」という仕様で実装することになりました（Dialog SetはWixUI_FeatureTreeの使用が前提です）。
WixUI Dialog Libraryでは、中間のダイアログを省いたり、カスタムなダイアログを挿入したり、といったことはできますが、"WelcomeDlg"を省く、なんてことはできません（誰かやり方知ってたら教えて！）。
そこで、インストーラー作成者のお友達、Orcaの登場です。見るべきところは、ここ。
![WiX_dlgTest1.png](https://qiita-image-store.s3.amazonaws.com/0/83170/c810dd27-3580-1abc-43fc-706dfdc55666.png)
InstallUISequenceでActionがxxxDlgとなっているところです。赤線で囲ったところは、最初に表示されるダイアログです。そう、WiX ToolsetのUIの起点はここにあるのです。WelcomeDlgとExit
Dialogダイアログで、あるパブリックプロパティ（ここではSHRINKUI）がセットされていたら、Conditionがfalseになるよう設定を変更します。

|Action|Condition|Sequence|
|:--|:--|:--|
|ExitDialog|NOT SHRINKUI|-1|
|WelcomeDlg|NOT SHRINKUI AND (NOT Installed OR PATCH)|1298|

そして、下記のようにインストーラーを実行すると、WelcomeDlgとExitDialogが表示されないことが確認できます。

> msiexec SHRINKUI=1 /i dlgTest.msi

ただ、これだとProgressDlgまでの全てのダイアログが表示されません。SHRINKUIがセットされているときは、CustomizeDlg以降を表示させるようにします。  
InstallUISequenceに下記の行を追加します。

|Action|Condition|Sequence|
|:--|:--|:--|
|CustomizeDlg|SHRINKUI|1295|

再度、コマンドラインオプションにSHRINKUIプロパティを指定してインストーラーを起動すると、仕様の通りCustomizeDlg以降が表示されるようになります。  
ここまでの編集で、InstallUISequenceは下記のようになりました。
![WiX_dlgTest2.png](https://qiita-image-store.s3.amazonaws.com/0/83170/29264fc0-0844-aaa6-edf0-71d1f1fbf76e.png)
【RSpec】APIのRSpecの書き方 for　初心者



# ○テストケース
基本は200 successをチェックします。
jsonの値をチェックしたり、モデルの増減を調べたりしますが、それは他のサイトで何を書くべきか調べてください。

```rb
it "200 success" do
  get url, params 
  expect(response).to have_http_status 200
end
```

普通のrspecと同じですね。 
getで、paramsと一緒にurlを叩くとうまくいきます。
という流れです。

# ○全体の流れ

```rb
Rspec.describe InternalApi::Books, type: :request do
  describe 'GET /books/show' do	
	let(:url) { "/internal/books/show" }
	let(:book) { create(:book, title: 'ノルウェイの森', author: '村上春樹') }
	let(:params) do
		{
			id: book.id,
			access_token: "aaaaaaaaaaaaa" 
		}
	end
	
	# "do {} end == {{}}" 中の{}はハッシュです。紛らわしいですが。
	# ここまででurlとparamsを作成しました。
	
	it "200 success" do
	  get url, params
	  expect(response).to have_http_status 200
	end
	
	# urlとparamsをgetメソッドに渡すと成功します。
```





# ○コツ
この形さえ抑えてしまえば、テストデータを作成することと、マッチャを変更するだけで汎用可能です。
rubocopのチェック結果をpecoで選択して、vimで該当行にジャンプした状態で開く

下記関数を.bashrcなりに追加して、`virc <ソースDIR>` すれば（出力フォーマットをカスタマイズしていなければ）コードのpathと行番号が出力されている部分を選択すると、その行をvimで開くことが出来る

```bash
# rubocopの結果をvimで開く
function virc {
    DIR="$1"

    F=$(rubocop ${DIR} | peco | awk -F ":" '{print "-c "$2" "$1}')
    if [ $? -eq 0 -a "${F}" != "" ]
    then
      eval "vi ${F}"
    fi
}
```

```bash:lhmのソースでの実行例
QUERY>                                                                                                                                                                                    IgnoreCase [239 (1/5)]
Inspecting 17 files
.CW.CC.CCC.CCC...
Offenses:
lib/lhm/atomic_switcher.rb:38:27: C: Space inside string interpolation detected.  # この行を選択
        "rename table `#{ @origin.name }` to `#{ @migration.archive_name }`, " \
                          ^^^^^^^^^^^^
lib/lhm/atomic_switcher.rb:38:50: C: Space inside string interpolation detected.
        "rename table `#{ @origin.name }` to `#{ @migration.archive_name }`, " \
                                                 ^^^^^^^^^^^^^^^^^^^^^^^
lib/lhm/atomic_switcher.rb:39:14: C: Space inside string interpolation detected.
        "`#{ @destination.name }` to `#{ @origin.name }`"
             ^^^^^^^^^^^^^^^^^
lib/lhm/atomic_switcher.rb:39:42: C: Space inside string interpolation detected.
        "`#{ @destination.name }` to `#{ @origin.name }`"
                                         ^^^^^^^^^^^^
lib/lhm/atomic_switcher.rb:46:20: C: Space inside string interpolation detected.
        error "`#{ @origin.name }` and `#{ @destination.name }` must exist"
                   ^^^^^^^^^^^^
lib/lhm/atomic_switcher.rb:46:44: C: Space inside string interpolation detected.
        error "`#{ @origin.name }` and `#{ @destination.name }` must exist"
                                           ^^^^^^^^^^^^^^^^^
lib/lhm/atomic_switcher.rb:53:7: C: Redundant begin block detected.
      begin
      ^^^^^
:
:
```

```ruby:atomic_switcher.rb
 22     def initialize(migration, connection = nil)
 23       @migration = migration
 24       @connection = connection
 25       @origin = migration.origin
 26       @destination = migration.destination
 27       @retries = 0
 28       @max_retries = MAX_RETRIES
 29       @retry_sleep_time = RETRY_SLEEP_TIME
 30     end
 31
 32     def statements
 33       atomic_switch
 34     end
 35
 36     def atomic_switch
 37       [
 38         "rename table `#{ @origin.name }` to `#{   #@migration.archive_name }`, " \  # この行が選択された状態で開く
 39         "`#{ @destination.name }` to `#{ @origin.name }`"
 40       ]
 41     end
 42
 43     def validate
 44       unless @connection.table_exists?(@origin.name) &&
 45              @connection.table_exists?(@destination.name)
 46         error "`#{ @origin.name }` and `#{ @destination.name }` must exist"
 47       end
 48     end
```
CMDファイルで JScript


```js:RunInBAT.CMD
@if(0)==(0) REM /* Shift-JIS(シフトJIS)で書かないとエラーになる・・・当然か
ECHO OFF
PUSHD %~dp0
CScript.exe //NoLogo //E:JScript "%~f0" %*
POPD
GOTO :EOF
REM */
@end

WScript.Echo('コマンドラインで実行中');
wshShell = new ActiveXObject('WScript.Shell');
wshShell.Popup('完了！',5);

```

```js:RunWithCscript.js
@if(0)==(0) REM /* Shift-JIS(シフトJIS)で書かないとエラーになる・・・当然か
ECHO OFF
PUSHD %~dp0
CScript.exe //NoLogo //E:JScript "%~f0" %*
POPD
GOTO :EOF
REM */
@end
/*
* JavaScriptのいろいろなコーディングルールをまとめてみた
** http://efcl.info/2011/0527/res2764/
* 他人にやさしいソースコードの書き方 コーディング規約 JavaScript編
** http://www.hp-stylelink.com/news/2013/10/20131008.php
*/

//	コマンドラインで実行！
RunInCscript();

WScript.Echo('コマンドラインで実行中');
wshShell = new ActiveXObject('WScript.Shell');
wshShell.Popup('完了！',5);

/**
 * WSCRIPT で実行中だったら、CSCRIPT で再実行する。
 */
function RunInCscript() {
	var path = WScript.FullName.toUpperCase();
	if (path.search('CSCRIPT\.EXE$') >= 0) {
		return;
	}
	var cmd = 'CSCRIPT.EXE //NoLogo //E:JScript ' + WScript.ScriptFullName;
	var args = WScript.Arguments
	var n = args.length;
	var i;
	for (i=0;i<n;i++) {
		var arg = args(i);
		if (arg.search('\ ') >= 0) {
			arg = '"' + arg + '"';
		}
		cmd += ' ' + arg;
	}
	wshShell = new ActiveXObject('WScript.Shell');
	var r = wshShell.Run(cmd,5,true);
//	wshShell.Popup('done!',5);
	WScript.Quit(r);
}

function echo(msg) {
	WScript.Echo(msg);
}
```

----
# 参考サイト
http://180.cocolog-nifty.com/blog/2011/12/jscript-aca0.html
http://blogs.msdn.com/b/joshpoley/archive/2008/01/15/running-jscript-in-a-cmd-file.aspx
jquery/js＜レスポンシブでウィンドウサイズを変えた時だけ何かするjs＞

・・・1年ぶりにjqueryの勉強を再開したペペロン(p_p;)

```lang:js
<script type="text/javascript">

$(function() {
    var w = $(window).width();
    var x = 768;
    if (w <= x) {
	$(".hoge").addClass("pele");
    }
    var timer = false;
    $(window).resize(function() {
        if (timer !== false) {
            clearTimeout(timer);
        }
        timer = setTimeout(function() {
            var w = $(window).width();
            var x = 768;
            if (w <= x) {
                $(".hoge").addClass("pele");
            }else{
                $(".hoge").removeClass("pele");
            }
        }, 200);
    });
});


</script>
```

```lang:html&css
<style type="text/css">

.hoge {
	background: #eee;
}
.pele {
	background: yellow;
}

</style>

<p class="hoge">ほげっと</p>

```
結果を見る
http://jsfiddle.net/jackotonashi/coak0ard/

参考サイト：
http://kadoppe.com/archives/2012/02/jquery-window-resize-event.html
http://bl6.jp/web/javascript/change-process-get-window-size/
PEPPER InputしたらRandomでOutputするPythonBoxをつくる

# 概要

PythonBoxにてRandomで分岐を作りたいとき

![スクリーンショット 2015-06-26 18.35.37.png](https://qiita-image-store.s3.amazonaws.com/0/84155/069cb025-7fa4-4dc7-c0ad-e59067890bbd.png)


```py
class MyClass(GeneratedClass):
    def __init__(self):
        GeneratedClass.__init__(self)

    def onLoad(self):
        pass

    def onUnload(self):
        pass

    def onInput_onStart(self):
        import random
        num = random.randint(0, 1)
        if num == 0:
            self.onA()
        else:
            self.onB()
```

こういう実装をすると
分岐を2つから3つにしたいときにコードをいじって、
ボックスを編集からアウトプットを増やしてという手順を踏まなければいけないので、
アプトプットを増やしら、勝手に分岐を作ってくれるようにします。


## 実装

```py
import numpy

class MyClass(GeneratedClass):
    def __init__(self):
        GeneratedClass.__init__(self)

    def onLoad(self):
        self.outputs = []
        for attr in dir(self):
            if callable(getattr(self, str(attr))) and "output" in str(attr):
                self.outputs.append(attr)

    def onUnload(self):
        self.outputs = []

    def onInput_onStart(self):
        r = numpy.random.randint(0, len(self.outputs))
        method = getattr(self, self.outputs[r])
        method()
```

## 解説

ボックスを編集から入力、出力を増やすとボックスのメソッドが宣言されます。
onLoad時にdir(self)を使ってボックスのプロパティを取得して、
callableで実行可能か（メソッドであるか）チェックして、
outputと付いているメソッドをself.outputsにappendしてます。

onInput_onStartでself.outputsにappendしておいたメソッドを実行してます。
人工知能歴史パート


# 人工知能とは？

* 世間的 「その製品が何か考えているように見える」例: ルンバ
* 筆者「人工的につくられた人間のような知能」

# 人工知能のレベル

* Lv1: 簡単な制御プログラム。掃除機・洗濯機・エアコン・制御工学
* Lv2: 古典的な人工知能。入力→出力の関連付け。パズルを解くプログラム・診断プログラム
* Lv3: 機械学習を取り入れた人工知能。ビッグデータなどからルールや知恵を自ら学ぶ。(最近のいわゆる「人工知能」)
* Lv4: ディープラーニングを取り入れた人工知能。機械学習をする際に特徴量を自ら学ぶ。

# 弱いAIと強いAI

どちらも問題を解くことができる。

* 哲学者ジョン・サールが言った。
* 弱いAI: 意識がない。「中国語の部屋」
* 強いAI: 意識がある。

# 歴史

* 1956年の伝説のワークショップで「人工知能」を命名
    * 人工知能研究の四皇が集結
        * ジョン・マッカーシー
        * マービン・ミンスキー
        * アレン・ニューウェル
        * ハーバード・サイモン
    * 定理を自動的に証明するプログラムのデモ(世界最古の人工知能)

## 1950〜1960年台

* 第一次AIブーム(推論探索の時代)
* 推論/探索で特定の問題が解けるAI✨
* 探索木で、迷路・ハノイの塔 
* ロボットの行動計画(前提条件・行動・結果)
* 「これは行けるッ！」

    
## 1970年台

* 人工知能研究の冬
* 組み合わせで計算結果が膨大に💦＼CPU足りない／
* 複雑な現実の問題は解けない💦
* ルールが決まりきってる「トイ・プロブレム」しか解けない
* 四皇のマービン・ミンスキー「ニューラルネットワークいじってたら、限界あるの見つけたわ…。一定条件下だけど」
    * → 世間の反応「ニューラルネットワーク、オワコンかよ…」
* 米政府のALPACレポート「機械翻訳は当分無理だねぇ」


## 1980年台

* 第二次AIブーム(知識の時代)
* 「知識」を入れることでAIが賢くなった✨
* エキスパートシステムなど産業で活躍する実用的なものも✨
* 病気に関するDB → お医者さんAI
    * MYCIN(マイシン) 感染症を診断して、69%の精度で処方(専門医は80%)
* ELIZA(イライザ) … いわゆる人工無能

## 1995年ごろ

* AIの冬が再到来
* 知識の管理が大変💦
* 知識の記述が大変💦
    * サイクプロジェクト(1984年〜) 人間の知識を全て記述するプロジェクト。30年経った今でも続いている…😨
* (1997年ディープブルーがチェスで人類に勝利…こいつは探索木)
* 一方、そのころインターネットが爆発的に普及
    * 1998年 Google

## 2000年代

* Webの広がりとともに「機械学習」がひっそりと広がりはじめる
* Webのテキスト処理のため統計的自然言語処理が発展

## 現代

* 第三次AIブーム(機械学習とディープラーニングの2つの大波)
* ビックデータ💚機械学習
* ディープラーニング(ばばーん！)
    * 2012年の画像認識のコンペティション「ILSVRC」
    * 写っているのがヨットなのか花なのか猫なのか認識して、正答率を競う。
    * 東大・オックスフォード・ゼロックスなど名だたるチームが参加。
    * コンマ何%の精度を競い、エラー率26%台の攻防戦になる予定だった…。
    * 名だたるチームと大差を付けて、初参加のカナダのトロント大学が開発したSuperVisionが圧倒的勝利！(エラー率脅威の15%！)
    * トロント大学のジェフリー・ヒントン教授が発明したディープラーニングが勝利をもたらしたのだった。
* 衝撃の出来事
    * ワトソン(2011年クイズ番組「ジョパディ！」で歴代チャンピオンに勝利)
    * 将棋電王戦(2012年第一回将棋電王戦でボンクラーズが将棋で人類を破る)
* 恐怖心へのあおり
    * レイ・カーツワイル「シンギュラリティがおとずれて機械が人間を超えるよ！やばいぜー」
    * スティーブン・ホーキング「AIを作ったら勝手に進化してって人類滅亡＼(^o^)／」
Viewport系のバグ

Macのシステム環境設定 > 一般 > スクロールバーの表示 が **常に表示** になってると _vw_ がスクロールバーの幅を含んだ画面幅を元にしてしまうバグ。
_%_ だと問題ない。

[サンプル](http://jsfiddle.net/hrtsgt/921q0s88/)
[バグレポート](https://bugs.webkit.org/show_bug.cgi?id=133271)
Mac OS X のマウスのカーソルが遅すぎる問題対策



マウスのカーソルが、遅すぎる問題の解決方法

結論: カーソルセンス以外はダメのよう。


## 問題点

* カーソルのスピード
* カーソルの加速度


## 解決方法

### SmoothMouseを使う (無料)

* [SmoothMouse for OS X](http://smoothmouse.com/)

 * → スピード最大にしても遅すぎる

### ControllerMate

* $24.95 試してない
 * [ControllerMate :: Doc :: Custom Acceleration Curves](http://www.orderedbytes.com/controllermate/doc/#custom_acceleration_curve)

### SteerMouse

* [ステアーマウス](http://plentycom.jp/steermouse/index.html)

### カーソルセンス (1080円)

* [カーソルセンス](http://plentycom.jp/cursorsense/index.html)
* お試しした。いい感じ。


### ターミナルで設定を調整

以下をターミナルで打つ

>defaults write "Apple Global Domain" com.apple.mouse.scaling 5.1


* デフォルトが1.7らしいので、5.1だと3倍。
20位にしてみた。


## その他の方法

* MouseZoom [Ben Net - MouseZoom OS X Official Site](http://benh57.com/mousezoom.html)


## 環境

* Mac OS X Yosemite (10.10.3)

  
## 参考 
* [【Mac】Macのマウスカーソルの速度を速くする３つの方法 | Crazy One - glad design blog -](http://gladdesign.net/2012/06/13/mac-mouse-cursor-speedup-3way/)

* [Macのマウスの操作性を改善 | aNote](http://ogre.mx/1390)
PEPPERで音声ファイルを再生する

# PEPPERで音声ファイルを再生する

PEPPERアプリケーションでタブレットのイベントで音声ファイルを再生する方法。
この記事での実現方法は3通りの方法を紹介します。

## jsでALMemoryのイベントをあげてpythonで再生

うちの会社で開発しているアプリでは

1. ユーザがボタンを押す
2. SEがなる
3. PEPPERが喋る

というパターンが多いので、
基本はこの方法を使っています。

**javascript**

```js

var qis = new QiSession();
qis.socket().on('connect', function() {
    // ALMemoryを取得
    qis.service('ALMemory').done( function(m) {
    memory = m;
    });
});

// ボタンを押したらイベントを発生
$("#play").on("click", function(e) {
    memory.raiseEvent("PlaySound", "");
});

```

**Choregraphe**

![ss.png](https://qiita-image-store.s3.amazonaws.com/0/84155/1591fd83-f5a0-d1bb-59ab-123a168fb0c8.png)

PlaySoundボックスは標準で入っているものです。
この実装方法だと効果音や音声が終わってから次の処理に行くことができるので、
音が鳴った後にPEPPERが喋る場合はこの方法を使います。


## jsでALAudioPlayerを取得して再生

タブレット単体で遊ぶアプリなどはこの実装をします。
再生する音声の種類が多い時や、複雑なロジックをjs側に書かなければいけないときや、
Choregraphe側のボックスを減らしたいときなどはこの方法で実装することが多いです。

```js
var qis = new QiSession();
qis.socket().on('connect', function() {
    // ALAudioPlayerを取得
    qis.service('ALAudioPlayer').done( function(ap) {
        audio = ap;
    });
});

// ボタンを押したら再生
$("#play").on("click", function(e) {
    audio.playFile(app_dir + "hello.wav");
});
```


## jsでAudioを作成してタブレットのスピーカーから再生

どうしてもjs側でaddEventListenerとかを使いたい場合はこの方法を使います。
メタデータとるときとか。

```js
var audio = new Audio("sound/hello.wav");
$("#play").on("click", function(e) {
    audio();
});
```

ただ、スピーカーの性能的にも
タブレットのスピーカーよりもPEPPERの耳のスピーカーの方がいいので、
この方法を採用することはほぼないです。


## まとめ

結局のところ、音を鳴らすときはPEPPERが何かしら反応することが多いので、
jsでALMemoryのイベントをあげてpythonで再生する方法が一番扱いやすいです。
タブレットしか使わないようなアプリはPEPPERでやる必要はないので。



今回紹介したコードのサンプルはこちら
https://github.com/hws-hitorobo/pepper_play_sound
非デザイナでもUIしたい!  Android StudioにAndroid-Bootstrapをサクッと導入するための情報集


はじめに
----
Androidアプリの作成に慣れてくると、やっぱり次はレイアウトのデザインにもこだわりたいですよね。
Androidの標準ウィジェットも豊富ではありますが、いまひとつといった時は**Android-Bootstrap**というものがあります。
CSSフレームワークとしてはおなじみのBootstrapのAndroid版と考えてもらえれば分かりやすいのではないでしょうか。

>[Android-Bootstrap](https://github.com/Bearded-Hen/Android-Bootstrap)
![68747470733a2f2f7261772e6769746875622e636f6d2f426561726465642d48656e2f416e64726f69642d426f6f7473747261702f6d61737465722f696d616765732f6465766963655f696d6167652e706e67 (1).png](https://qiita-image-store.s3.amazonaws.com/0/48330/f0534867-c9a5-b785-9cd9-419ceff4af0d.png)


今回はAndroid StudioでAndroid-Bootstrapを利用する際に参考になる情報をまとめました。
ググると情報はいろいろあるのですが、よりお手軽にはじめられるようにしています。

なお今回利用したAndroid Studioのバージョンは1.2.2です。

Android-Bootstrapの導入
----
Android Studioに導入する際にググって一番多い情報では、githubから直接ソースを落として、ライブラリプロジェクトとして参照する設定をして、Gradleの設定をいじって・・・などなどそこそこ作業が必要です。
かつ、意外とすんなりいきません。。
私の場合はGradleでのビルドがなかなか通らずいろいろとごにょごにょしてました。

実はProject Structureから設定できることを知り、再度実施したところすんなり設定できました。
その際に、こちらの記事が大変参考になりました。(ありがとうございます！)
>[AndroidのボタンデザインにはBootStrapを使おう！(使い方)](http://android.tecc0.com/?p=127)

Android-Bootstrapの使い方
-----
使い方については[Trashfeed](http://qiita.com/Trashfeed)さんがまとめてくださっているので、こちらをご参照ください。

>[デザインが出来ないエンジニアのAndroid-Bootstrap利用方法](http://qiita.com/Trashfeed/items/70627d792bf44de76590)



それでは素敵な開発生活を！
hover擬似クラス

:hover　カーソルなどが乗った際のスタイルを指定します。
　　　　a:hoverでは“カーソルは乗っているがクリックはされていない状態”です。
:active　要素がアクティブになった際のスタイルを指定します。
　　　　a:activeでは“クリックされてから離されるまでの状態”です。

HPのサンプル作成
↓一部

```lang:HTML
<div class="navi">
			<ul>
				<li><a href="#">トップページ<br><span>Top</span></a></li>
				<li><a href="#">ごあいさつ<br><span>Greeting</span></a></li>
				<li><a href="#">サービス概要<br><span>Service</span></a></li>
				<li><a href="#">弊社の取り組み<br><span>Approach</span></a></li>
				<li><a href="#">会社情報<br><span>Company</span></a></li>
				<li><a href="#">お問い合わせ<br><span>Contact</span></a></li>
			</ul>
		</div>
```

```lang:CSS
.navi{
	width:100%;
	height:50px;
	background:#f1f1f1;
}
.navi:after{
	content:"";display:block;clear:both;
}
.navi ul{
	width:930px;
	margin:0px auto 0px auto;
	padding:0px;
}
.navi ul li{
	float:left;
	width:16.5%;
	height:50px;
	font-size:12px;
	text-align:center;
	background:#eeeeee;
	list-style-type: none
}
.navi ul li a{
	width:100%;
	height:45px;
	padding-top:5px;
	display:block;
	text-decoration:none;
}
.navi ul li a:hover{
	color:#fff;
	background-color:#ccc;
}
```
ソースファイル以外でも#ifで切り分ける


製品用のビルドと、社内テスター向けのベータビルドなど、目的のビルドによっては少しプログラムを変更したいということがたまにあります。1つのコードから有料版と無料版といった2種類のプロダクトをリリースしている場合なんかもそうです。

Objective-Cのソースファイルの場合は `#if` 〜 `#endif` などのプリプロセッサディレクティブを使うことで処理を切り分けられます。

```objectivec
#if BETA_BUILD
NSString *serverURL = @"http://.....";
#else
NSString *serverURL = @"https://.....";
#endif
```

こんな感じの切り分けをソースファイルじゃないものでもやっちゃいましょうというのが今回の話。例えば、アプリバンドルに持たせているデータファイルとかですね。（※ただしテキストに限る）


やりたいこと
-----------------

例えば、こんな感じのJSONで書かれたデータ、guides.jsonがあるとしましょう。

```json:guides.json
{
  "guides": [
    {
      "id": "mes001",
      "message": "もう一度やり直すにはここをタップ！",
      "when": "back"
    },
    {
      "id": "mes002",
      "message": "ともだちに教えてあげよう！",
      "when": "finish"
    },
    {
      "id": "mes003",
      "message": "行き詰まったらちょっと休憩してみる？",
      "when": "back"
    }
  ]
}
```

ベータビルドでは、このうち、真ん中のmes002のデータを除外することになりました。
そこで、こう書いておきます。

```json:guides.json
{
  "guides": [
    {
      "id": "mes001",
      "message": "もう一度やり直すにはここをタップ！",
      "when": "back"
    },
#if !BETA_BUILD
    {
      "id": "mes002",
      "message": "ともだちに教えてあげよう！",
      "when": "finish"
    },
#endif
    {
      "id": "mes003",
      "message": "行き詰まったらちょっと休憩してみる？",
      "when": "back"
    }
  ]
}
```

すると、ベータビルド時にはこうなってほしい。

```json:guides-beta.json
{
  "guides": [
    {
      "id": "mes001",
      "message": "もう一度やり直すにはここをタップ！",
      "when": "back"
    },
    {
      "id": "mes003",
      "message": "行き詰まったらちょっと休憩してみる？",
     "when": "back"
    }
  ]
}
```

では、やってみましょう
------------

心配ありません。Mac OS Xには最初から（？）、unifdefというコマンドラインツールがインストールされています。こいつは、プリプロセッサマクロ定義を与えると、その定義に応じて選択的に `#if` 〜 `#endif` を削除するツールです。

`#if` だけでなく、 `#ifdef`, `#ifndef`, `#elif`, `#else` なんかも大丈夫ですし、 `#if HOGE > 10` とか `#if AAA && BBB` といった演算子を使った式にも対応しているスグレモノです。

今回の例であれば、ターミナルから

```bash
unifdef -DBETA_BUILD guides.json
```

と実行すれば、標準出力に結果が出力されます。 `-o` オプションでファイルに出力させることもできます。

詳細は `man unifdef` で表示されるマニュアルを参照。

もうちょっとだけ詳しく
--------------------

unifdefにプリプロセッサマクロが定義されていることを伝えるオプションが `-D定義名=値` です。複数定義したければ、このオプションを複数指定します。値の指定を省略すると1を指定したことになります。

```bash
unifdef -DBETA_BUILD -DAPI_LEVEL=3 file
```

逆に、プリプロセッサマクロが定義されていないことを伝えるオプションが `-U定義名` です。こちらも複数指定できます。

```bash
unifdef -UBETA_BUILD -UEVALUATION file
```

ところで、unifdefは指定したプリプロセッサマクロだけを処理します。 `-D` でも `-U` でも指定しなかったものについては、 `#if` 〜 `#endif` が残ったままになります。

例えば、こんなファイルin.txtに対して

```text:in.txt
#if HOGE
あああ
#else
いいい
#endif
#if FUGA
ううう
#endif
```

```bash
unifdef -UHOGE -o out.txt in.txt
```

と、 `HOGE` が定義されていないことだけ伝えてやると、結果のout.txtは、こうなります。

```text:out.txt
いいい
#if FUGA
ううう
#endif
```

その他の注意点として、unifdefはデフォルトでC言語のコメントや（行末のバックスラッシュによる）行の連結を解釈します。例えば `/*` 〜 `*/` のコメント内に書かれた `#ifdef` は無視されてそのまま残ります。 `/*` や `//` に特別な意味を持たせたくないときは、 `-t` オプションを付ければOKです。
「Jenkins says my reverse proxy setup is broken」でもう一つ確認すべき場所


結論: システム設定にあるJenkins URLが正しいかを確認しよう。


 * https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+says+my+reverse+proxy+setup+is+broken
 * http://smokycat.info/devops/859

# どうでも良い詳細

```
ProxyPass         /jenkins  http://localhost:8042/jenkins nocanon
ProxyPassReverse  /jenkins  http://localhost:8042/jenkins
ProxyRequests     Off
AllowEncodedSlashes NoDecode

# Local reverse proxy authorization override
# Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)
<Proxy http://localhost:8042/jenkins>
  Order deny,allow
  Allow from all
</Proxy>
```

大体こういう感じの設定で問題ないはずなんだけど、それでもうまくいかないという不思議状況が発生した。

本家のドキュメント (https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+says+my+reverse+proxy+setup+is+broken) に従ってcurlコマンドを実行してみる。

```shell-session
$ curl -iL -e http://example.com/jenkins/manage http://example.com/jenkins/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/test
```

これでも最終的に404が出る。ところが http://example.com:8080/jenkins/admin... となるべきところが何故か http://example.com:8080/admin... となる。へ？？

リバースプロキシさせているApacheではなくJettyに直接curlを投げ込んでみた。

```shell-session
$ curl -iL http://example.com:8080/jenkins/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/test
```

ここで何故か、Jettyが

http://example.com:8080/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/test

にRedirect (304 Found) し、(/jenkins プレフィクスがないので) ここで404となる。

デバッグのため、試しに/etc/default/jenkinsと/etc/apache2/sites-enabled/...の双方のポート番号を変えてみたところ、それでも8080番ポートの誤ったURLに飛ぶ。再起動しても同じ。(ﾟДﾟ)ﾊｧ?

ここまで来ると流石に別の場所に「8080」という文字列を含む別の永続ストレージに設定が残っていると考えざるをえない。

で、Jenkinsのシステム設定を見たら、多分自分で設定したんだがJenkins URLにhttp://example.com:8080 とあった。これをhttp://example.com/jenkins に変えたら症状は落ち着いた。「my reverse proxy setup is broken」とも言われなくなった。
Atom apmの使い方

# apmを使う上でのメモ
apmとはAtomのパッケージを管理するツール
コマンドラインから使う

## 準備

```
$ apm login
```
ログインしないと使えないのでログインします。
GitHubのアカウントがあれば大丈夫です。
上のコマンドを実行すると認証が要求されるので、ブラウザで表示されたページにあるトークンをコピペすればOK。

## パッケージのインストール

```
$ apm install <package_name>
```

## パッケージのアンインストール

```
$ apm uninstall <package_name>
```

## スターについて
apmでは気に入ったパッケージにスターをつけることが推奨されています。
どんなメリットがあるかというと、`apm stars --install`を実行するとスターをつけたパッケージが自動的にインストールされる。
これにより、他のPCでも自分の環境が一瞬で構築することができる。

### スターをつける

```
$ apm star <package_name>
```

### スターを解除する

```
$ apm unstar <package_name>
```

### スターの一覧を表示

```
$ apm stars
```

###
gcfg で Value に # を含める

[https://godoc.org/code.google.com/p/gcfg](https://godoc.org/code.google.com/p/gcfg) を使うときのおはなし。

こういう書き方だと `URH` がコメント扱いになります。

```ini
name = zcx2#URH
```

素直にクォートしましょう。

```ini
name = "zcx2#URH"
```
localオプションを指定してgemをインストールする


たとえば、サーバなどで外部へのHTTP/HTTPS通信が制限されている環境で
インターネットにつながらない≒[rubygems.org](https://rubygems.org/)につながらない環境下で ```gem install``` したい場合のTips。常識かもしれませんが、知らなかったのでメモ。

# インターネットにつながらない環境下でgemをインストールする

:warning: rubyのインストールは終わっている前提でのお話です

## gemを手動でダウンロードする

インターネットに繋がる環境（例えば手元の端末）でgem(xxx.gem)をダウンロードします。

![gem_download.jpg](https://qiita-image-store.s3.amazonaws.com/0/31059/eada4cf7-cdca-2153-2652-ffe9830f1201.jpeg "gem_download.jpg")

## gemファイルをサーバへ手動でコピー

WindowsならRDP, FTPなど、LinuxならSFTP, RSyncなどを利用してgemをインストールしたい端末へダウンロードしたgemファイルをコピーします。

:point_up: このとき、PATHの通った場所にgemファイルを配置します

## localオプションをつけてgem install

```gem install``` コマンドにlocalオプションをつけてインストール。

```sh
$ gem install --local xxx
```

これでサーバにコピーしたxxx.gemからインストールが実施されます :+1: 

---

カンタンですが、以上です。
YumでJenkinsセットアップ

忘備録

【OS】
今回はCentOS6.6_x86_64版を使用。詳細は以下を参照。
http://centos.server-manual.com/
事前準備
セットアップに必要なパッケージを事前に設定しておく必要がある。以下を全て設定する。
システム変更が発生するので管理者権限が必須。rootにsuしておく事。

【YUMパッケージ管理】
yum -y install yum-plugin-fastestmirror
yum -y update
yum -y groupinstall "Base" "Development tools" "Japanese Support"
[RPMforgeリポジトリ追加]
rpm --import http://apt.sw.be/RPM-GPG-KEY.dag.txt
rpm -ivh http://apt.sw.be/redhat/el6/en/x86_64/rpmforge/RPMS/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
[EPELリポジトリ追加]
rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-6
rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
[ELRepoリポジトリ追加]
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-6-6.el6.elrepo.noarch.rpm
[Remiリポジトリ追加]
rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm

【SELinux無効化】
getenforce
Enforcing ←SELinux有効
setenforce 0
getenforce
Permissive ←SELinux無効
vi /etc/sysconfig/selinux
SELINUX=enforcing 
SELINUX=disabled ←変更(起動時に無効にする)

【iptablesで8090を許可】
vi /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8090 -j ACCEPT ←追加
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
Iptables再起動
service iptables restart

【JAVA】
CentOS構築時にデフォルトでインストールされたバージョンをアンインストール。
yum erase java*
最新版をネットより入手(rpm版)しインストール
rpm –ivh jdk-8u45-linux-x64.rpm
バージョン確認
java –version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
■JAVA_HOME設定
vi /etc/profile
<pre>
export JAVA_HOME=/usr/java/default
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
</pre>
【Jenkins】
セットアップには2種類あり、warファイルをTomcatへ展開する方法と、yumより直接インストールする方法があります。今回はVerupが簡単な事から、後者の方法でセットアップし、Portを変更して実行します。
[リポジトリ追加]
wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat/jenkins.repo
rpm --import http://pkg.jenkins-ci.org/redhat/jenkins-ci.org.key

[インストール]
yum -y install jenkins

vi /etc/sysconfig/jenkins
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true"
↓
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Dhudson.util.ProcessTree.disable=true"

JENKINS_PORT="8090"
JENKINS_AJP_PORT="8010"

JENKINS_ARGS="--prefix=/jenkins"

Jenkins起動・自動起動設定
service jenkins start
chkconfig jenkins on

PCよりブラウザで接続確認。
http://localhost:8090/jenkns
ID:admin PW:adminでログオンを実施し、各種設定を実施する。
Microsoft AzureのTimezoneはGMT

## これは何？
AzureはGMTを基準にしてますよ　というメモ。
Web Appsのアクセスログ、エラーログ関連の話はまた書きます。

## Web Apps
### Web サーバ(IIS)のアクセスログ
![Screen Shot 2015-06-26 at 3.48.41 PM.png](https://qiita-image-store.s3.amazonaws.com/0/14859/81c0c1b2-fb22-8822-5267-bb1c500aea08.png)

を有効にすると取れるようになるやーつ


のこの辺の時間はGMT

![Screen Shot 2015-06-26 at 4.05.46 PM.png](https://qiita-image-store.s3.amazonaws.com/0/14859/cc8e5ce4-bb50-f7c2-0fd9-f5c77337725e.png)

Azure Web Apps上のIISのログフォーマット
https://msdn.microsoft.com/ja-jp/library/cc338018.aspx
processingで球面に針を刺す

球面上の座標を計算して、その点からもう一回り大きい球面の座標に線を引くと、
球面に針が刺さっているように見えました。
![20150209.jpg](https://qiita-image-store.s3.amazonaws.com/0/75611/b5da0ba0-fd37-7ee4-4619-67bc63056b1d.jpeg)

~~~java

int num = 6000;

float[] x01 = new float[num];
float[] y01 = new float[num];
float[] z01 = new float[num];
float[] x02 = new float[num];
float[] y02 = new float[num];
float[] z02 = new float[num];
float[] deg01 = new float[num];
float[] deg02 = new float[num];
float rot_x;
float rot_y;
float rot_z;
float amp01;
float amp02;
float range;

void setup () {

	//デフォルトの球面の半径
	amp01 = 200.0;

	rot_x = 0.0;
	rot_y = 0.0;
	rot_z = 0.0;

	range = 4.0;

	size (1920, 1080, P3D);
	colorMode (RGB, 256);
	background (0);
	frameRate (60);

	for (int i = 0; i < num; i++) {

		//球面の座標を得る為に2つの角度を用意
		deg01[i] = random (360);
		deg02[i] = random (360);

	}

	for (int i = 0; i < num; i++) {

		//2つの角度から球面上の座標を計算
		x01[i] = amp01 * cos (radians (deg01[i])) * sin (radians (deg02[i]));
		y01[i] = amp01 * sin (radians (deg01[i]));
		z01[i] = amp01 * cos (radians (deg01[i])) * cos (radians (deg02[i]));

	}

}

void draw () {

	background (0);

	//カメラの設定
	camera (mouseX - (width / 2), mouseY - (height / 2), 0.0,
			width / 2, height / 2, 0.0,
			0.0, 1.0, 0.0);

	translate (width / 2, height / 2);
	rotateX (radians (rot_x));
	rotateY (radians (rot_y));
	rotateZ (radians (rot_z));

	for (int i = 0; i < num; i++) {

		//マウスの位置を取得
		float offsetx = mouseX - (width / 2);
		float offsety = mouseY - (height / 2);

		//マウスの位置と球面上座標との差を計算
		float diffx = abs (offsetx - x01[i]);
		float diffy = abs (offsety - y01[i]);

		//上の差に基づいて針の長さを計算（特に公式はなくいい感じになるように）
		amp02 = (4000 / (diffx + diffy + 1)) + amp01 + 1;

		//針が伸びた先の座標を研鑽
		x02[i] = amp02 * cos (radians (deg01[i])) * sin (radians (deg02[i]));
		y02[i] = amp02 * sin (radians (deg01[i]));
		z02[i] = amp02 * cos (radians (deg01[i])) * cos (radians (deg02[i]));

		stroke (int (abs (x01[i])), int (abs (y01[i])), int (abs (z01[i])));
		strokeWeight (1);
		noFill ();
		//球面上の座標から針の先の座標まで線を描く
		line (x01[i], y01[i], z01[i], x02[i], y02[i], z02[i]);

	}

	rot_x += map (mouseY, 0, height, -range, range);
	rot_y += map (mouseX, 0, width, -range, range);
	rot_z += ((map (mouseY, 0, height, -range, range) + map (mouseX, 0, width, -range, range)) / 2);

	//saveFrame ();

}
~~~
capistranoでsshログインの時にパスワード入力を求められるようになった


---

■事象

・以前作ったcapistrano環境
　
　set :user, 'ユーザ名'
　set :password, 'パスワード'

　を指定することで cap 〜 shell で対象ホストにパスワード入力なしでssh接続することが出来た。

・最近作ったcapistrano環境

　set :user, 'ユーザ名'
　set :password, 'パスワード'

　を指定しているのに cap 〜 shell で対象ホストにパスワード入力を求められる、かつパスワード入力できない。。

---

■環境の差異を調べた

・以前作ったcapistrano環境

	# gem list -l
	*** LOCAL GEMS ***

	bigdecimal (1.1.0)
	capistrano (2.15.4)
	capistrano-colorized-stream (0.2.3)
	capistrano-ext (1.2.1)
	capistrano_colors (0.5.5)
	capistrano_rsync_with_remote_cache (2.4.0)
	colorize (0.5.8)
	highline (1.6.19)
	io-console (0.3)
	json (1.5.4)
	minitest (2.5.1)
	net-scp (1.1.1)
	net-sftp (2.1.2)
	net-ssh (2.6.7)
	net-ssh-gateway (1.2.0)
	rake (0.9.2.2)
	rdoc (3.9.4)
	rubygems-update (2.0.3)

・最近作ったcapistrano環境

	# gem list -l

	*** LOCAL GEMS ***

	bigdecimal (1.1.0)
	capistrano (2.15.4)
	capistrano-colorized-stream (0.2.3)
	capistrano-ext (1.2.1)
	capistrano_colors (0.5.5)
	capistrano_rsync_with_remote_cache (2.4.0)
	colorize (0.7.7)
	highline (1.7.2)
	io-console (0.3)
	json (1.5.5)
	minitest (2.5.1)
	net-scp (1.2.1)
	net-sftp (2.1.2)
	net-ssh (2.9.2)
	net-ssh-gateway (1.2.0)
	rake (0.9.2.2)
	rdoc (3.9.5)
	rubygems-update (2.4.7)

#### net-scp, net-ssh あたりのバージョン差異が怪しそうな気がする。

---

# GitHubにこの問題が書かれていた。

https://github.com/net-ssh/net-ssh/issues/164

※同じような事象の記事も見つけた。
　http://qiita.com/takashibagura/items/33034c7529b553d2d0f9

---

ということで、他のgemとの関係でnet-sshのバージョンを固定できないのでssh_optionsで回避してみた。


	# net-ssh-2.9.x 系でパスワード効かれてしまう問題対応
	set :ssh_options, {
	   config: false
	}
	
これで回避できた。
React + react-router と browserify + babalify で ES6のクラスとか使った簡単なサンプル


## 目的

react-router が取りあえず動く簡単なサンプルを書いてみる。

バージョン指定せずに `npm install react-router` すると古い v0.13.3 が入ってしまい、github の README などに書いてあるサンプルコードが動作しないので気をつける（現時点で v1.0.0-beta2 だと動く）

## ファイル構成

こんな感じ。

.
├── dest
│   └── app.js
├── index.html
├── package.json
└── src
    ├── app.js
    └── router.js

## インストール

```package.json
{
  "devDependencies": {
    "babelify": "^6.1.2",
    "browserify": "^10.2.4",
    "react": "^0.13.3",
    "react-router": "^1.0.0-beta2",
    "watchify": "^3.2.3"
  },
  "scripts": {
    "watch": "watchify -t babelify src/app.js -o dest/app.js -v"
  }
}

```

```
$ npm install
```

## watch

src ディレクトリの js ファイルを src/app.js で import でまとめる感じにしておいて監視、変更あったらビルド。

```
$ npm run watch
```

## ファイル作成

```src/app.js
import React from 'react/addons';
import router from './router';

React.render(router, document.getElementById('example'));
```

```src/router.js
import React from 'react/addons';
import BrowserHistory from 'react-router/lib/BrowserHistory';
import { Router, Route, Link } from 'react-router';


class Home extends React.Component {
    render() {
        return (
            <div>
                <h1>Home</h1>
                <ul>
                    <li><Link to="/foo/">Foo</Link></li>
                    <li><Link to="/bar/">Bar</Link></li>
                </ul>
            </div>
        );
    }
}

class Foo extends React.Component {
    render() {
        return (
            <div>
                <h2>Foo!</h2>
                <ul>
                    <li><Link to="/">Home</Link></li>
                    <li><Link to="/bar/">Bar</Link></li>
                </ul>
            </div>
        );
    }
}

class Bar extends React.Component {
    render() {
        return (
            <div>
                <h2>Bar!</h2>
                <ul>
                    <li><Link to="/">Home</Link></li>
                    <li><Link to="/foo/">Foo</Link></li>
                </ul>
            </div>
        );
    }
}

var router = (
    <Router history={new BrowserHistory}>
        <Route path="/" component={Home} />
        <Route path="/foo/" component={Foo} />
        <Route path="/bar/" component={Bar} />
    </Router>
);

module.exports = router;
```

```index.html
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>react-router</title>
    </head>
    <body>
        <div id="example"></div>

        <script src="dest/app.js"></script>
    </body>
</html>
```

## 動作確認

### サーバー起動

```
$ python -m SimpleHTTPServer 8080
```

- http://localhost:8080/
- http://localhost:8080/foo/
- http://localhost:8080/bar/

![スクリーンショット 2015-06-26 16.26.36.png](https://qiita-image-store.s3.amazonaws.com/0/41656/fc33dc33-8991-bd1d-45de-7e9db31e6bae.png "スクリーンショット 2015-06-26 16.26.36.png")

## メモ

- react-router の `BrowserHistory` を使うと `http://localhost:8080/#/foo/` みたいな `#` が入らない。ちなみに `HashHistory` などを使うと `#` が入る。
- react-router v0.13.3 から v1.0.0-beta2 にアプデしてだいぶ変更されたらしい


## 参考

- https://github.com/rackt/react-router
- [入門 React](http://www.oreilly.co.jp/books/9784873117195/)
【CakePHP】jsonを出力する

ajaxのリクエストに対してjsonを返す方法。
CakePHP2.1以降より使える。

```php:jsonを返す方法
$res = [
  'name'=>'suzuki',
  'age'=>34,
  'score'=>[86,57,73]
];

$this->viewClass = 'json';
$this->set(compact('res'));
$this->set('_serialize','res');
```

```json:返されるjson
{"name":"suzuki","age":34,"score":[86,57,73]}
```