OmniAICreator/Qiita-1.07M huggingface dataset:
historyコマンドの実行日時のフォーマットについて

## historyにコマンド実行日時を保存するには
まずは historyコマンドでコマンドの実行日時を保存する方法を軽く説明します。

環境変数 HISTTIMEFORMAT が設定されていて、かつその値が null でない場合は `~/.bash_history` にコマンド実行日時がタイムスタンプで保存されます。

つまり、`export HISTTIMEFORMAT="%F %T "` と実行すれば `~/.bash_history` に実行したコマンドの日時の情報（タイムスタンプ）が保存されるようになります。

`export HISTTIMEFORMAT="%F %T "` は毎回ログインしたときに実行が必要です。もちろん毎回実行するのは面倒なので `~/.bash_profile` にでも書き込んでおきましょう。全ユーザに対して実行させたいときは `/etc/profile` にでも書いておきましょう。個人的には `/etc/profile.d/history.sh` に書き込むのがすっきりしていて好きです。

ちなみに HISTTIMEFORMAT が設定されていなかったときに実行された過去のコマンドの実行日時はどうやっても知ることはできません。

## コマンド実行日時のフォーマット
さてこの historyコマンドの実行時間のフォーマットですが strftime によって任意のフォーマットに整形されて hitoryコマンドに出力されます。
`"%F %T"` なら `2016-02-05 18:05:40` に整形されます。

つまり、
**結局 HISTTIMEFORMAT で指定できるフォーマットは strftime と同じ。なので strftime のマニュアルを見るべし。**
ということです。

strftime のフォーマットは下記のリンクをチェックすると良いでしょう。
http://www.agr.unideb.hu/~agocs/informatics/11_e_unix/unixhelp/unixhelp.ed.ac.uk/CGI/man-cgie064.html?strftime+3
https://linuxjm.osdn.jp/html/LDP_man-pages/man3/strftime.3.html


## おまけ
せっかくなのでおすすめのフォーマットを紹介しましょう。

### RFC822形式（曜日, 日 月 年 時:分:秒 タイムゾーン）
```bash
HISTTIMEFORMAT="%a, %d %b %Y %H:%M:%S %z  " history

    #=> 1054  金, 05  2月 2016 18:28:27 +0900  ls -ltr
```

### シンプル
```bash
HISTTIMEFORMAT="%Y/%m/%d(%a) %T  " history 

    #=> 1054  2016/02/05(金) 18:28:27  ls -ltr
```

### 大河ドラマっぽく
```bash
HISTTIMEFORMAT="%EY %Om月%Od日 %a %OH時%OM分%OS秒 仕り候  " history

    #=> 1054  平成28年 二月五日 金 十八時二十八分二十七秒 仕り候  ls -ltr
```

### 改行を使ってみました
```bash
HISTTIMEFORMAT="%c %n------------------------------------ " history

    #=> 1054  2016年02月05日 18時28分27秒
    #=> ------------------------------------ ls -ltr
```
Githubへのプロジェクトファイルのアップロードの方法


#初回のみ

## 1 Githubページにて新しいリポジトリの作成
Githubページを見てよしなにリポジトリを作成しましょう。
*初回設定時のみ必要

![スクリーンショット 2016-02-07 12.57.09.png](https://qiita-image-store.s3.amazonaws.com/0/36527/154565dc-8121-b292-5231-32ca0aab3b4e.png "スクリーンショット 2016-02-07 12.57.09.png")




## 2 $cd ~/Count
ターミナルにてプロジェクトファイルがあるディレクトリまで移動してください。 ~/Countの ~ の部分は人によってことなるので注意。

![スクリーンショット 2016-02-07 13.07.58.png](https://qiita-image-store.s3.amazonaws.com/0/36527/ac80e39e-7c2f-7c2f-6b32-f8fbec71c640.png "スクリーンショット 2016-02-07 13.07.58.png")


今回の例ではDocument/XcodeProjects の中にCountアプリファイルを置いてあります。


## 3 $git init
カレントディレクトリ以下を今後監視の対象とすることを宣言します。(gitファイルを生成します)
*初回設定時のみ必要

![スクリーンショット 2016-02-07 13.09.46.png](https://qiita-image-store.s3.amazonaws.com/0/36527/2bc72015-6f1c-7af9-8ac2-cca4371200cb.png "スクリーンショット 2016-02-07 13.09.46.png")


## 4 $git add .
ステージングを行います。git add ______ の______ に差分を管理したいファイル名、もしくはディレクトリ内のすべてのファイルの差分を管理したい場合は . を入力します。最初なれるまでは____の部分は.(ピリオドを使うのが無難でしょう)。ステージングとは何か気になった人は是非ググってください。

![スクリーンショット 2016-02-07 13.10.13.png](https://qiita-image-store.s3.amazonaws.com/0/36527/dfe81a14-185c-e6fb-236f-37606e86a255.png "スクリーンショット 2016-02-07 13.10.13.png")


git add したあとにきちんとステージングできているかどうか見る場合は
$git status
にてステージング状況を確認することができます。


![スクリーンショット 2016-02-07 13.10.24.png](https://qiita-image-store.s3.amazonaws.com/0/36527/343e961e-6133-6958-e906-012fedead819.png "スクリーンショット 2016-02-07 13.10.24.png")


## 5 $git commit -m "コメント"
ステージングした差分にコメントをつけてローカル内に保存します。
![スクリーンショット 2016-02-07 13.11.43.png](https://qiita-image-store.s3.amazonaws.com/0/36527/59de4ec5-38c5-0f7e-5790-dcd7633e2bed.png "スクリーンショット 2016-02-07 13.11.43.png")
commitメッセージの中身は今回の変更分はどんなことを行ったのかを後から見たときに確認しやすいように書く癖をつけておくとよいでしょう。今回はCount教科書の途中までやったよ、という想定で"techfile iPhoneコース Count教科書途中まで"というコメントにしてあります。

過去のcommitは
$git log
$git show
などで確認することができます。
log と showでは表示する内容がどのように異なるかは自分で試して確認してみてください。
![スクリーンショット 2016-02-07 13.16.39.png](https://qiita-image-store.s3.amazonaws.com/0/36527/de904366-2a86-48b2-093e-34a9b697e49f.png "スクリーンショット 2016-02-07 13.16.39.png")
![スクリーンショット 2016-02-07 13.16.32.png](https://qiita-image-store.s3.amazonaws.com/0/36527/79792267-7192-ecb8-a388-9d7306867c72.png "スクリーンショット 2016-02-07 13.16.32.png")


## 6 $git remote add origin "リポジトリURL"
初めてリモートリポジトリ(リモートリポジトリはGithubのリピジトリ(ファイル)、ローカルリポジトリはMac内のリポジトリということ)にpushする初回のみ必要。２回目以降は必要なし。
ちなみにgit@リポジトリ名をリモートリポジトリとして登録しておいた方がのちのち便利
*初回設定時のみ必要

![スクリーンショット 2016-02-07 13.18.34.png](https://qiita-image-store.s3.amazonaws.com/0/36527/d3884a09-d30b-d753-f378-2851d40caf12.png "スクリーンショット 2016-02-07 13.18.34.png")

リポジトリURLはGithubを参照
![スクリーンショット 2016-02-07 13.17.55.png](https://qiita-image-store.s3.amazonaws.com/0/36527/603d2da7-5262-8322-4f45-71c7ed780e60.png "スクリーンショット 2016-02-07 13.17.55.png")


## 7 $git push -u origin master
”ステージング”して差分を管理して、"commit"して差分にコメントをつけて保存したものはまだローカル内にしかないので、リモートリポジトリにも登録(push)する。

## 8 githubページを確認してきちんと更新されているか確認しましょう。


ここまでやってわからないことがあればメンターに直接メッセージを送って質問するか、FacebookのiPhoneグループページに投稿して質問してください。
 
# 2回目以降 Commitログを更新していくとき

```
$cd ~/Count
$git add .
$git commit -m "コミットメッセージ"
$git push -u origin master
```

以上です。
Kotlinで関数に渡された型パラメータによって処理を分岐させる方法

##Injektの不思議な代入
InjektというKotlinのDependency Inejectionフレームワークがある。
これを使って予め登録したオブジェクトを取り出す場合、下記のような記述ができる。

```kotlin
val obj:MyClass = Injekt.get()
```

一見して、Injekt.get()は返すべきオブジェクトを決定するためになんの情報も受け取っていないように見える。
実は、Injekt.get()は代入先の型にあわせて返すべきオブジェクトを決定している。

##Injekt.get()が返すオブジェクトを決定する仕組み
Injekt.get()はKotlinのreified type parameterという機能と型推論を使うことで返すオブジェクトを決定している。
reified type parameterは実際の型名のように扱える型パラメータだ。
例えば、通常の型パラメータではできないが、is演算子の右辺に置くことやclassオブジェクトを参照することができる。
Injekt.get()には型パラメータが渡されていないように見えるが、Kotlinはその強力な型推論によって代入先の型から推論してうまく型パラメータを渡してくれる。

なお、reified type parameterはinline関数でしか使えないという制約がある。

##実際に、代入先の変数型に合わせた結果を返すサンプル
```kotlin
data class MyClass(
        val id:Int,
        val name:String
)

inline fun <reified T> f1():T {
    val c = T::class
    when (c.qualifiedName) {
        "kotlin.Int" -> return 10 as T
        "kotlin.String" -> return "Hoge" as T
    }
    return "else" as T
}

fun main(args: Array<String>) {
    val c = MyClass(
            id = f1(),
            name = f1()
    )
    println(c)
}
```

この例ではMyClassのコンストラクタのパラメータ型がf1()のreified type parameterとして渡る。
f1()は与えられた型情報から返すべきオブジェクトを決定する。

##まとめ
reified type parameterを使うことで、クラスオブジェクトを引数に渡さずとも型に応じた柔軟な処理の分岐が可能になる。
この機能は頻繁に使うようなものではないかもしれないが、これを活用することで、より便利なインタフェースを提供することが
できるため、ライブラリやフレームワークの作成者などは知っておくと便利かもしれない。
aws-cliでスポットインスタンスの価格設定履歴を取得してみる


AWSが公式に出している[aws-cli](https://github.com/aws/aws-cli)を利用してスポットインスタンスの価格設定履歴をshell越しに取得してみようと思います。

そんなんグラフで見ればええやんけ・・・

ええ、ごもっともです。

## 参考にしたサイト

* [describe-spot-price-history](http://docs.aws.amazon.com/cli/latest/reference/ec2/describe-spot-price-history.html)

## 環境

* CentOS 6.7
	* aws-cli 
		* aws-cli/1.10.1 Python/2.7.10 Linux/2.6.32-573.el6.x86_64 botocore/1.3.23

## スポットインスタンスの価格設定履歴のコマンドは下記

```shell
aws ec2 describe-spot-price-history
```

このコマンドがスポットインスタンスの価格設定履歴のコマンドです。

## コマンドラインのオプション

上記コマンドのオプション(自分が使ったものだけ抜粋します)


### --instance-types

インスタンスタイプ(t1.micro,m3.large...)のインスタンスタイプを渡します。

### --availability-zone

アベイラビリティーゾーン
リージョンが東京なら現在は ``` ap-northeast-1c or ap-northeast-1a ``` のどちらか

### --product-descriptions

スポットインスタンスを取得するAmazon マシンイメージ（AMI）を指定する
AMAZON Linuxなら ``` Linux/UNIX ```

### --start-time

取得したい価格設定履歴の開始時間いつもの如くUTCで

### --end-time

取得したい価格設定履歴の終了時間いつもの如くUTCで


## 例) t1.microでap-northeast-1cのアベイラビリティゾーンでamazon linux の現在の価格設定履歴を取得する

時間は適時変更してみてください。

```shell
aws ec2 describe-spot-price-history --instance-types t1.micro --availability-zone ap-northeast-1c --product-descriptions Linux/UNIX --start-time 2016-02-05T11:34:00Z --end-time 2016-02-05T11:34:00Z 
```


## 最後に

ググったけども ``` aws cli ``` のコマンドで日本語で細やかに説明しているところがあんまないなー
jsfで<c:forEach>が<f:event type="preRenderView">の前に実行されてしまう

#環境
javaEE 6、jsf2.1

#問題
```html:test.xhtml
<!-- 前処理 -->
<f:event type="preRenderView" listener="#{xxx.init}">

<!-- 前処理でフィルタしたyyy.itemsに対して繰り返し処理を実施 -->
<c:forEach var="item" items="#{yyy.items}">
```
\<c:forEach>の結果が期待通りにならない。
前処理の結果が反映されていない状態で\<c:forEach>が実行されている。

#原因
\<c:forEach>などのタグハンドラはコンポーネントツリーのビルドやレンダリングの前に実行される。
そのためpreRenderViewの前に\<c:forEach>が評価されてしまっているのが原因。

タグハンドラとコンポーネントの処理タイミングの違いは下記サイトが分かりやすい。
http://www.ninthavenue.com.au/jsf-c-foreach-vs-ui-repeat

タグハンドラはコンポーネントではなく、コンポーネントツリーを作るのを補助するのが役目なので、
コンポーネントをビルドしたりレンダリングする前に動く必要があるらしい。

#対応方法1
**\<c:forEach>ではなく\<ui:repeat>を利用する**

```html:test.xhtml
<c:forEach var="item" items="#{yyy.items}">
↓
<ui:repeat var="item" value="#{yyy.items}">
```

#対応方法2
**前処理をpreRenderViewではなく、タグハンドラの評価タイミングで実施する**

直接xhtmlにEL式を記述する。（あまり良い方法ではないと思うが）

```html:test.xhtml
<f:event type="preRenderView" listener="#{xxx.init}">
↓
#{xxx.init()}
```
ちなみにタグハンドラから前処理を呼ぶ方法は色々試してみたが、うまく動作しなかった。
詳細は後述。

#うまくいかなかった対応1
**\<f:event>のpreRenderView以外のフェーズで前処理実施**

\<f:event>で指定できる各種フェーズで実行してみた結果。

- preValidate:動作しない
- postValidate：動作しない
- postAddToView:タグハンドラの実行後に動作
- preRenderComponent:タグハンドラの実行後に動作
- preRenderView:タグハンドラの実行後に動作

\<f:event>で指定できるフェーズ一覧。
https://javaserverfaces.java.net/docs/2.1/vdldocs/facelets/f/event.html

おそらく、コンポーネントツリーをビルドするのが「Render Response」フェーズが初めてなので、
そのタイミングで「Apply Request Values」や「Process Validations」フェーズにリスナーを仕込むことはできないのだと思う。

ちなみに一度開いた画面でsubmitした場合は、すべてのケースで期待されるフェーズで動作していた。

前回の「Render Response」フェーズで既にコンポーネントツリーを作成しているので、
「Apply Request Values」や「Process Validations」フェーズにリスナーを仕込むことができたのだと思う。

厳密にどのフェーズで実行されるのが正しいかは下記を参考に。
http://stackoverflow.com/questions/13999099/jsf-execution-order-of-fevents

#うまくいかなかった対応2
**\<f:event type="preRenderView">ではなく、\<f:viewAction>を利用する**

Java EE7、jsf2.2以降なら\<f:viewAction>が利用できる。
ただし、動作検証していないが、\<f:event>でフェーズ指定しても正しく動かなかったのと同じ理由で\<f:viewAction>もダメな気がする。

ただし、下記のコメントではできたと報告があるので要検証。
http://kikutaro777.hatenablog.com/entry/20121210/1355146339

#うまくいかなかった対応3
**タグハンドラで前処理を実施**

\<c:set>などのタグハンドラや、\<f:viewParam>で試してみたがうまく動作しなかった。

```html:test.xhtml
<f:event type="preRenderView" listener="#{xxx.init}">
↓
// 動かない
<c:set var="test" value="#{xxx.init()}" />

// 動かない
<f:viewParam id="id" name="name" value="#{xxx.init()}" />
```

参考）\<f:viewParam>を使った方法
http://stackoverflow.com/questions/8156351/jsf-method-of-fevent-prerenderview-called-after-cforeach
GitHubでユーザ名・パスワード省略（push, pull）


Amazon Linux (AWS - EC2)で確認しました。

## ユーザ名のみ省略する方法

### 1. clone済のリポジトリの設定を変更する場合

`{cloneしたリポジトリDir}/.git/config`を編集します。

`[remote "origin"]`項目の`url`に`username@`を追加する。

```:.git/config
[remote "origin"]
  url = https://username@github.com/username/repository.git
```

### 2. git cloneするURLに埋め込む（新規で`clone`する場合）

```bash
git clone https://username@github.com/username/repository.git
```

## ユーザ名・パスワード両方省略する方法

### 1. `~/.netrc`にユーザ名/パスワードを書く

```:~/.netrc
machine github.com
login username
password xxxxxxx
```

### 2. `url`に`username:password@`を追加

`{cloneしたリポジトリDir}/.git/config`を編集します。

`[remote "origin"]`項目の`url`に`username:password@`を追加する。

```:.git/config
[remote "origin"]
  url = https://username:password@github.com/username/repository.git
```

`username`か`password`に`@`が含まれている場合は、`%40` (エンコードした値)を使えば通るようです。
他の記号（`&`など）は`\`でエスケープできるようです。

※セキュリティ的に心配なのでこちらの方法は試してません。どちらの方法にしても、ファイルに生のパスワードを書かないといけないので、セキュリティ上やらないほうがいいと思います。
特に、2番めのURLにパスワードを追加する方法は、HTTPSとは言えURLにパスワードが含まれてしまうので、パスワードを生でインターネット上に送信しているようなものなんじゃないかと思います。

## 設定の優先度

両方設定した場合、`~/.netrc`の設定が優先されます。

優先度としては、`~/.netrc` > `.git/config`という感じのようです。

例えば、

- ユーザ名のみの設定（`.git/config`）

```:.git/config
[remote "origin"]
  url = https://username@github.com/username/repository.git
```
と

- ユーザ名・パスワードの設定（`~/.netrc`）

```:~/.netrc
machine github.com
login username
password xxxxxxx
```
の両方を設定した場合、ユーザ名・パスワード両方省略されました。

## 参考URL

[Githubへのpushでusername/passwordを省略する方法２つ](http://shoken.hatenablog.com/entry/20120629/p1)
[Laravel]Laravel5.1のログ出力に関して調査したまとめ

# Laravel

* Laravel5.1 について調査した結果をまとめています

# 設定
- config/app.php

```php
<?php

return [
...
	/*
	|--------------------------------------------------------------------------
	| Logging Configuration
	|--------------------------------------------------------------------------
	|
	| Here you may configure the log settings for your application. Out of
	| the box, Laravel uses the Monolog PHP logging library. This gives
	| you a variety of powerful log handlers / formatters to utilize.
	|
	| Available Settings: "single", "daily", "syslog", "errorlog"
	|
	*/
    'log' => 'daily',
    // dailyログの場合の保存期間を指定
    'log_max_files' => '10',
...
]
```

## logの設定値
保存

設定値|内容|備考|
---|---|---|
single |`storage/log/laravel.log`に出力する|単一ファイルでログローテーションは無いため別途考慮する必要がある|
daily|`storage/log/laravel-YYYY-MM-DD.log`に出力する|1ファイルに1日分のログが出力される<br>デフォルトでは5日分が保存される<br>`log_max_files`キーを追加設定すると保存期間を変更できる|
syslog|Syslogに出力する|Syslogに関しては[こちら](http://qiita.com/junpei_iwa/items/8dc9f62b4118186cf2df)|
errorlog|ログを`error_log()`で出力する|出力先はphp.iniの設定による|

## 追加設定

設定値|内容|備考|
---|---|---|
log\_max\_files|`daily `設定時のログファイル保存期間を変更できる|設定が無い場合は5日分の保存となる|

# ログの出力
- ログの出力にはLogファサードを使用する
- Logファサードにはログレベルに合わせてメソッドが用意されている

## メソッド一覧

メソッド|ログレベル|
---|---|---|
Log::debug()|debug|
Log::info()|info|
Log::notice()|notice|
Log::warning()|warning|
Log::error()|error|
Log::critical()|critical|
Log::alert()|alert|

### 各エラーレベルの出力例
```php
[05-Feb-2016 19:26:40 Asia/Tokyo] [2016-02-05 19:26:40] local.DEBUG: log test
[05-Feb-2016 19:26:40 Asia/Tokyo] [2016-02-05 19:26:40] local.INFO: log test
[05-Feb-2016 19:26:40 Asia/Tokyo] [2016-02-05 19:26:40] local.NOTICE: log test
[05-Feb-2016 19:26:40 Asia/Tokyo] [2016-02-05 19:26:40] local.WARNING: log test
[05-Feb-2016 19:26:40 Asia/Tokyo] [2016-02-05 19:26:40] local.ERROR: log test
[05-Feb-2016 19:26:40 Asia/Tokyo] [2016-02-05 19:26:40] local.CRITICAL: log test
[05-Feb-2016 19:26:40 Asia/Tokyo] [2016-02-05 19:26:40] local.ALERT: log test
```

## 第2引数に連想配列を指定
- 第2引数に連想配列を指定しログ出力することが可能

```php
\Log::debug('log test', ['apple' => 'red', 'number' => 123]);
```

### 第2引数指定しての出力例
```php
[05-Feb-2016 19:30:26 Asia/Tokyo] [2016-02-05 19:30:26] local.DEBUG: log test {"apple":"red","number":123}
```

# ログのカスタマイズ
- ログ出力には「monolog」を使用している
- 「monolog」を直接操作して処理を変更することが可能

```php
$monolog = \Log::getMonolog();
$monolog->pushProcessor(function ($record) {
    $record['extra']['logDate'] = date('Y年m月d日 H:i:s');
    return $record;
});
$monolog->pushProcessor(new \Monolog\Processor\MemoryUsageProcessor());
$monolog->info('Usage Memory');
```

## カスタマイズの出力例
```php
[05-Feb-2016 19:45:47 Asia/Tokyo] [2016-02-05 19:45:47] local.INFO: Usage Memory  {"memory_usage":"3.25 MB","logDate":"2016年02月05日 19:45:47"}
```

カスタマイズに関して詳しくは以下参照

- [Laravel公式](http://readouble.com/laravel/5/1/ja/errors.html)
- [monolog](https://github.com/Seldaek/monolog)

以上です。
SublimeTextのサイドバーのファイルアイコンを変える

SublimeTextサイドバーのファイルアイコン, 設定してあると識別しやすくなって便利ですよね. このアイコンをカスタマイズする方法を書きます.

## SetiUI-Icons-Sublimeを使う

すべてのファイル形式のアイコンを自分で設定するのはめんどくさいので, こちらのレポジトリを利用します.
https://github.com/mrmartineau/SetiUI-Icons-Sublime

### 使い方
レポジトリのマニュアルの翻訳です.

- zipをダウンロードしてくる
- Packages/User/以下に解凍して, 現在設定しているテーマのディレクトリ名に変更（テーマのディレクトリがあるならば中身をその中に入れれば大丈夫？）
- 解凍したディレクトリの中に, 現在のテーマ名.sublime-theme というファイルを作成
- SublimeTextを再起動

すると, 以下のようにアイコンが設定されます.

<img width="181" alt="Screen Shot 2016-02-05 at 19.18.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/62184/52c95d2c-b935-87e8-f3cb-cc6d3395d74d.png">

## 自己流にカスタマイズ
この状態でも十分ですが, 未定義のファイル形式のものやテーマによっては見づらいアイコンもあります.
そこで, 先ほど解凍したディレクトリに設定を追加してアイコンをカスタマイズする方法を書きます.

1. +res/file-types/に追加するファイル形式のファイルを作る（確認用）
2. 16*16, 32*32のファイルアイコンを検索してダウンロードしてくる
3. icons/以下を参考に, それぞれfile_type_ファイル形式.png, file_type_ファイル形式@2x.pngに変更してicons/以下に置く
4. icon_ファイル形式.tmPreferencesをすでにある他の形式からコピーして作成
5. tmPreferences内の\<string>の中身を変えたいファイル形式に変更
6. SublimeTextを再起動

たとえば, Haskellのアイコンを設定するとこんな感じになります.
<img width="200" alt="Screen Shot 2016-02-05 at 19.30.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/62184/ec861e14-057e-781a-fad4-620c73179357.png">

他にも, チーズバーガーのアイコンをダウンロードしてきて, file_type_c++.pngとして保存すれば, 
<img width="243" alt="Screen Shot 2016-02-05 at 19.41.43.png" src="https://qiita-image-store.s3.amazonaws.com/0/62184/5196a9c6-e2a8-9717-8802-d74e3c3c9c55.png">

こんな感じにできちゃいます.

## 参考
チーズバーガーのアイコンはこちらからダウンロードしました
http://www.flaticon.com/free-icon/big-cheeseburger_80155#term=hamburger&page=1&position=8
レガシーなPHPプロジェクトをボットでコーディング規約に沿っているか調べさせる


# 経緯
現在会社ではレガシーなPHPが使われたプロジェクトの保守が続けられています。日本ではおそらく多くのWebサイトでレガシーなPHPが使われていると思います。モダンな最新のプロジェクトとは違い、ユニットテストの自動化、CI、コードの静的解析などとは程遠いです。長い間保守されているのでコーディング規約の統一もされていません。

そこで！
新しいものを使ってレガシープロジェクトをモダンなものにしましょう！

ということでまずインデントにタブが使われているかどうかをチェクするだけのボットを作りました。僕のいる会社の言い伝えによりますとインデントはタブらしいのでスペースが入っているかどうかを判定します。

GitHubのWebhooksからpushのイベントを飛ばしてもらって、そこからコミットを取得しに行きます。

# コード
```coffee:checkIndentation.coffee
token = 'token'
apiUrl = "https://api.github.com/repos/[Organization名]"
repository = "hoge"

module.exports = (robot) ->
  robot.router.post("/github/check/commits", (req, response) ->
    data = req.body
    for commit in data.commits
      request = robot.http("#{apiUrl}/#{repository}/commits/#{commit.id}")
        .query(access_token: token)
        .get()

      request((err, res, body) ->
        if err
          robot.messageRoom("チャンネル名", "何かエラーになっちゃいました...")
          return

        commit = JSON.parse body

        if commit.message == "Not Found"
          robot.messageRoom("チャンネル名", "#{repository}が見つかりませんでした..")
          return

        fileNames = []
        for file in commit.files
          if file.status == 'modified' || file.status == 'added'
            if file.filename.match(/^.*\.php$/g) != null
              if !checkIndentation(file.patch)
                fileNames.push(file.filename)

        if fileNames.length != 0
          respond = "#{commit.committer.login}さん!\nスペースのインデントが混じってますよ!\n\n"
          respond += "#{commit.commit.message}\n\n"
          respond += "#{fileNames.join('\n')}"
          respond += "\n\n#{commit.html_url}"
          robot.messageRoom("チャンネル名", respond)
      )
    response.end('')
  )

checkIndentation = (patch) ->
  index = patch.indexOf("\n")
  while 1
    nextIndex = patch.indexOf("\n", index + 1)
    if nextIndex == -1
      break
    string = patch.slice(index + 1, nextIndex)
    if (string.slice(0, 1) == '+')
      if (string.substr(1).match(/^ +\S+/) != null)
        return false
    index = nextIndex
  return true

```

これでGitHubの設定からWebhooksを`[ボットのURL]/github/check/commits`を設定すればできるはずです。

今回はGitHub APIでファイルごとの差分をパッチ形式で取得してインデントを調べています。

# 実行した感じ

![slack.jpg](https://qiita-image-store.s3.amazonaws.com/0/72360/f0bd63dd-b10a-277f-46d0-cfdc6375b453.jpeg)

膨大なコードを全部PHP Code Snifferとかかけたらとんでもないことになりますけど、今後の変更箇所だけ指摘してくれるのでかなり有効だと思います。
FactoryGirlで実践的な関連データを作成する

TODO

# 参考

- [いまさら聞けないfactory_girl入門](http://tech.grooves.com/entry/2015/04/28/173025#Associations)
- [Rails ActiveRecordでランダムにレコードを1件取得する](http://easyramble.com/get-record-randomly-with-active-record.html)
物理的な減衰をするイージング関数とeaseOutExpo

## 減衰を表すために使う式について

減衰をする数式について勉強したのでメモします。
減衰のモデルは放射性物質が崩壊する時のモデルを使ってみます。
下記のような式で表され、$N$ は残りの量で $t$ が時間、$-λ$が減衰率です

```math
 \frac{dN}{dt} = -λN 
```

あとの計算のため右辺から$N$を消去します。

```math
 \frac{1}{N}\frac{dN}{dt} = -λ
```

これの両辺を$t$（時間）で積分します。

```math
 \int\frac{1}{N}\frac{dN}{dt}\,dt = -\intλ\,dt
```

左辺を整理。

```math
 \int\frac{1}{N}\,dN = -\intλ\,dt
```

$\int\frac{1}{x}\,dx = \log |x| + C$ なので

```math
 \log N = -λt + C
```

```math
 N = e^{-λt+C}
```

時間($t$)が0秒で、残り量の初期値が$N_0$とすると

```math
 N_0 = e^C
```

なので

```math
 N(t) = N_0e^{-λt} \tag{1}
```

という式が出来上がります。

## イージングにこの式を使うことを考える
10秒かけて0まで減衰する場合を考えます。

この式は$t$が増加すると限りなく0に近づいていきますが0にはならないので終了は0でなく0.0001まで減衰したら終了というにことします。
$(1)$の式から

```math
 N(10) = N_0e^{-10\lambda}
```

$N(10)$は初期値$N_0$の1/10000であれば良いので、下記のような式になります。

```math
 \frac{N_0}{10000} = N_0e^{-10\lambda}
```

両辺の$\log$をとります

```math
 \log N_0 - \log 10000 = \log N_0 + \log e^{-10\lambda}
```
```math
 - \log 10000 = -10\lambda
```
```math
 \log 10000 = 10\lambda
```

$\lambda = $ の式にすると

```math
 \lambda = \frac{1}{10} \log 10000
```

と減衰率を出すことができました。
コードに落とす場合、アニメーションの開始時の値と終了時の値の差が初期値$N_0$で、アニメーションの時間が$t$になります。
次は実際にコードに落としてみたいと思います。

## jQuery.animateのイージングを作ってみる
実際にイージング関数をつくってみます。jQueryのイージング関数は、与えられた引数から開始地点を0、終了地点を1とした場合、今どの辺りにいるかを計算してreturnする仕組みになっています。なので$e^{-\lambda t}$を計算して1から引いた値を返せばOKです。

```js
var ln10000 = Math.log(10000);

jQuery.extend( jQuery.easing, {
  //x: 時間の進捗具合
  //t: 経過時間
  //b: 0固定
  //c: 1固定
  //d: optionで指定したアニメーション時間
  easeCustom: function(x, t, b, c, d) {
    var e = Math.E; //e
    var l = (1/d) * ln10000 //λ
    var p = Math.pow(e, (-l*t)); //e^-λt

    return (t!=d) ? 1 - p : c;
  }
});
```

そして実際に動かしてをeaseOutExpoと比較したものがこちらです。
http://codepen.io/bukurocci/pen/mVzeWP

easeOutExpoよりも少し急な動きになっていますね。
しかし試しに減衰率を出すときに使う終了地点のパラメータを0.0001から0.001にしてみると...
http://codepen.io/bukurocci/pen/KVGvrO

全く同じ動きをしていました！

## 結論
結論としてはeaseOutExpoが物理的な動きのイージングになっているということで物理的な減衰の動きをする場合はeaseOutExpoを使うで良いと思いますが、気になったのでもうすこし調べてみます。

## 余談:easeOutExpoについて

[jQuery Easing Plugin](http://gsgd.co.uk/sandbox/jquery/easing/)のeaseOutExpoのコードを見てみると以下のようになっています。

```js
easeOutExpo: function (x, t, b, c, d) {
 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
}
```

同じ動きをしているのに計算式が全く違いますね不思議です。
$t=d$のときの式を考えてみると

### easeOutExpo
```math
2^{-10\frac{d}{d}} = 2^{-10}
```

### easeCustom
```math
e^{-\frac{d}{d} \log 1000} = e^{-\log1000} = (2^{\log_2 e})^{-\log 1000} = 2^{-\log 1000 \times \log_2 e}
```

$-\log 1000 \times \log_2 e$を計算すると-6.907x1.442で大体-10になるので
easeOutExpoの式は、この式の近似式になっているようにみられます。


## Reference
1. [対数の計算](http://www.geisya.or.jp/~mwm48961/kou2/log1.html)
2. [微分方程式で数学モデルを作ろう](http://www.amazon.co.jp/%E5%BE%AE%E5%88%86%E6%96%B9%E7%A8%8B%E5%BC%8F%E3%81%A7%E6%95%B0%E5%AD%A6%E3%83%A2%E3%83%87%E3%83%AB%E3%82%92%E4%BD%9C%E3%82%8D%E3%81%86-%E3%83%87%E3%83%B4%E3%82%A3%E3%83%83%E3%83%89%E3%83%BB%E3%83%90%E3%83%BC%E3%82%B8%E3%82%A7%E3%82%B9%E3%83%BB%E3%83%A2%E3%83%A9%E3%82%B0%E3%83%BB%E3%83%9C%E3%83%AA%E3%83%BC/dp/4535781737)
よく使うOS・ミドルウェアのサポート終了期限(EOL/ライフサイクル)をまとめた

```shell:編集履歴
- 2016/6/30 - MySQL5.7追加
- 2017/2/17 - Ruby2.1のサポート期限修正 / PostgreSQL9.6追加 / AmazonLinuxのサポート対象追加と期限追加
- 2017/6/14 - Ruby2.2のサポート期限修正
- 2019/10/19 - PHP5.6のサポート期限修正 / PHP7.0のサポート期限修正 / PHP7.1追加 / PHP7.2追加 / PHP7.3追加 / Java (Oracle版)8更新 / Ruby2.3のサポート期限修正 / Ruby2.4追加 / Ruby2.5追加 / Python2.7のサポート期限修正 / Python3.4のサポート期限修正 / Python3.5追加 / Python3.6追加 / Python3.7追加 / Python3.8追加
```

よく調べる事があるので、よく使うOS・ミドルウェアのサポート終了期限(EOL/ライフサイクル)をまとめておきました。
観点はセキュリティパッチが提供されるか。という期限を書いています。（2019年10月時点）

期限を超えているものは、脆弱性が公表されてもセキュリティパッチは提供されません。
緊急の脆弱性対策でいきなりメジャーバージョンアップとかシンドイと思うので、
サポート期限を見越して選定し、移行しましょう。

### PHP (コミュニティ版)

|Ver|期限|
|:--|:--|
|7.3|2021年12月|
|7.2|2020年11月|
|7.1|2019年12月|
|7.0|2019年1月|
|5.6|2018年12月|
|5.5|2016年6月|
|5.4|2015年9月|
|5.3|2014年8月|
|5.2|2011年1月|
|5.1|2006年8月|
|5.0|2005年9月|

### Java (Oracle版)

|Ver|期限|
|:--|:--|
|8|2019年1月(商用)|
|8|2020年12月(非商用)(予定)|
|7|2015年4月|
|6|2013年2月|

### Ruby (コミュニティ版)

|Ver|期限|
|:--|:--|
|2.5|未定|
|2.4|2020年3月|
|2.3|2019年3月|
|2.2|2018年3月|
|2.1|2017年3月|
|2.0|2016年2月|
|1.9|2015年2月|

### Python (コミュニティ版)

|Ver|期限|
|:--|:--|
|3.8|2024年10月|
|3.7|2023年6月|
|3.6|2021年12月|
|3.5|2020年9月|
|3.4|2019年3月|
|2.7|2020年1月|

### MySQL (コミュニティ版)

|Ver|期限|
|:--|:--|
|5.7|2020年10月|
|5.6|2018年2月|
|5.5|2015年12月|
|5.1|2013年12月|
|5.0|2011年12月|

### PostgreSQL (コミュニティ版)

|Ver|期限|
|:--|:--|
|9.6|2021年8月|
|9.5|2021年1月|
|9.4|2019年12月|
|9.3|2018年8月|
|9.2|2017年8月|
|9.1|2016年8月|
|9.0|2015年8月|
|8.4|2013年2月|

### Oracle (Premier Support)

|Ver|期限|
|:--|:--|
|12c R1|2018年7月|
|11g R2|2015年1月|
|11g R1|2012年8月|
|10g R2|2010年7月|

### Red Hat Enterprise Linux / CentOS

|Ver|EOL|PHP|MySQL|PostgreSQL|
|:--|:--|:--|:--|:--|
|7.x|2024年6月30日|5.4|5.5(CentOSはMariaDB)|9.2|
|6.x|2020年11月30日|5.3|5.1|8.4|
|5.x|2017年3月31日|5.1|5.0|8.1|

### Amazon Linux

|Ver|EOL|PHP|MySQL|PostgreSQL|Ruby|Python|
|:--|:--|:--|:--|:--|:--|:--|
|-|未定|5.3/5.4/5.5/5.6/7.0|5.5|8.4/9.2/9.3/9.4/9.5|1.8/1.9/2.0/2.1/2.2|2.6/2.7/3.4/3.5|
2016.09版リリースに伴い、以下ミドルウェアはサポート期限が設定されました。

|Ver|期限|
|:--|:--|
|mysql51|2017年9月|
|postgresql8|2017年9月|
|php53|2017年9月|
|php54|2017年9月|
|php55|2018年3月|
|python26|2017年9月|
|ruby18|2017年9月|
|ruby19|2017年9月|
|ruby21|2017年9月|
|ruby22|2017年9月|
| tomcat6 |2017年9月|
AndroidStudioでサイン無しのリリース版をビルドする

Android Studioでサインなしのリリース版のapkをビルドする方法を備忘録として書いておきます。
画面左下の「Build Variants」をクリックします。すると、Build Variantsウィンドウが出てくるので、Build Variantを「release」に変更します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/32065/28e2078f-8bc0-bff1-2f25-95183995d6f2.png" width="640" />

これで、Build apkすれば、release版のapkが生成されます。
PC-8001のINP関数でキー押下を取得

# PC-8001のキーボードのIOマップ

|_port_ \ _value_ | 254 | 253 | 251 | 247 | 239 | 223 | 191 | 127 |
|:----:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| 0 | 0<sub>T</sub> | 1<sub>T</sub> | 2<sub>T</sub> | 3<sub>T</sub> | 4<sub>T</sub> |5<sub>T</sub> | 6<sub>T</sub> | 7<sub>T</sub> | 
| 1 | 8<sub>T</sub> | 9<sub>T</sub> | *<sub>T</sub> | +<sub>T</sub> | =<sub>T</sub> | ,<sub>T</sub> | .<sub>T</sub> | RET |
| 2 | @ | A | B | C | D | E | F | G |
| 3 | H | I | J | K | L | M | N | O |
| 4 | P | Q | R | S | T | U | V | W |
| 5 | X | Y | Z | [ | ¥ | ] | ^ | - |
| 6 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 7 | 8 | 9 | * | + | < | > | ? | _ |
| 8 | HOME | ↑ | → | INS | GRPH | カナ | SHIFT | CTRL |
| 9 | STOP | f1 | f2 | f3 | f4 | f5 | SPACE | ESC| 
|_BIT_ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

Tの添え字は、テンキーのものを表す。

# BASICで使う時

    IF INP(_port_) = _value_ THEN ...

例えば、Xキーが押されているかを判断する場合は

    IF INP(5) = 254 THEN ...

何も押されていない時は、INP関数は255を返します。
 
# マシン語で使う時

    IN A, ( _port_ )
    BIT _BIT_, A
    JR Z, _rel_addr_

例えば、Xキーが押されているを判断する場合は

    IN A, ( 5 )
    BIT 0, A
    JR Z, _rel_addr_

ここで、ビット演算子`BIT`は、第二引数で与えられたレジスタにおいて、第一引数で指定したビットの値を反転して、Zフラグに代入します。

条件付き相対ジャンプ命令`JR Z,`は、Zフラグが立っていたら(1なら)、引数で指定されたアドレス分相対ジャンプします。
WebView#postUrlで表示したページにはブラウザバック出来ない

WebView#postUrl使っていてハマったのでメモ。

WebView#postUrlで表示したページAから、リンクを辿っていき、バックキーで戻れるようにしていた。

```java:WebFragment.java
    protected boolean onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
            return true;
        }
        return false;
    }
```

ところが、最初にアクセスしたページAに戻ろうとすると、

```
ページが見つかりませんでした
```

となってしまう。
どうやら、postパラメータを再送してくれない(or出来ない)ため、エラーになる模様。

参考
https://code.google.com/p/chromium/issues/detail?id=412751
c++ builder XE4, 10.2 Tokyo > TeeChart > 日本語OS / 英語OS > グラフ横軸の時刻表記が異なる > 日本語OS: hh:mm / 英語OS: hh:mm AM/PM

```txt:動作環境
C++ builder XE4
    TeeChart Lite v2013.08.130414
RAD Studio 10.2 Tokyo Update 2 (追記 2018/01/10)
    TeeChart v2016.17.160129 32bit VCL
```

```txt:実行環境
Windows 7 pro 32bit 日本語OS
Windows 7 pro 32bit 英語OS / Embedded 英語OS
```

TeeChartの横軸をDateTimeとして、TChartAxis.DateTimeFormat を指定していない場合のデフォルトの表記がOSによって異なるようだ。

- 日本語OS
  - hh:nn
- 英語OS
  - hh:nn AM/PM

英語OSの時にはAM/PMが付く。

以下のような設定をしておけば、OSに関係なく同じ表記にできる。

```
Chart1->BottomAxis->DateTimeFormat = L"hh:nn";
```

本来は、DateTimeFormat をきちんと設定しないといけなかった。
RenderTexture

原点からの指定範囲内からしかテクスチャ化できない気がする。
画面の一部をそのままのサイズでキャプチャは不可能なので、画面全体をキャプチャして必要な部分を拡大してあわせたりした。解決方法あるのかな？

```lang:TestScene
// 画面の原点（左下）からキャプチャする画面内のサイズ
auto renderTexture = cocos2d::RenderTexture::create(float 横幅, float 縦幅);

// テクスチャに反映する範囲を設定する（呼ばない場合はそのまま）
renderTexture->setVirtualViewport(cocos2d::Vec2 切り取り原点,
                                  Rect 反映される矩形,
                                  Rect 反映するサイズ);
// 取り込む
renderTexture->begin();
cocos2d::Director::getInstance()->getRunningScene()->visit();
renderTexture->end();

// ファイル保存する場合
renderTexture->saveToFile(const char* 保存ファイル名, bool アルファつきか, [&](bool succeed,const std::string &fileName){
    // 完了時の処理
});
```
Google Play Musicがミニプレイヤーだけで再生出来ない

プログラミングとはあまり関係ないですが、気がついたらGoogle Play Musicのミニプレイヤー単独ではGoogle Play Musicが聞けなくなっていたので、ちょっと解決策を考えてみた。

# Google Play Musicって？

[Googleが提供している定額音楽配信サービス](https://play.google.com/music/listen)。
980円/月(2016/2/5現在)で約3,500万曲が聞き放題というサービス。

# Google Play Musicのミニプレイヤーって？

![スクリーンショット 2016-02-05 18.17.14.png](https://qiita-image-store.s3.amazonaws.com/0/85034/265dde53-e7c2-18ef-fcfa-cceead99d499.png)

これ

Chromeの拡張？アプリ？としてインストールすると使える様になります。
登場当初は

1. ChromeでGoogle Play Musicにアクセス
2. 再生
3. 下部再生コントローラーの右上にある[画像(□に右上の矢印)]をクリックすると手軽に立ち上げられる
4. ChromeでGoogle Play Musicのタブを閉じてもミニプレイヤーが立ち上がっていれば再生される

という感じで、簡易プレイヤー且つChromeを閉じても再生していてくれる大変便利な拡張だったのですが・・・

# ある時からのGoogle Play Music ミニプレイヤー

ある時から、ミニプレイヤーを立ち上げた状態でChromeのGoogle Play Musicタブを閉じると、

![スクリーンショット 2016-02-05 18.08.33.png](https://qiita-image-store.s3.amazonaws.com/0/85034/2f6852c3-439b-60fa-ce1b-fec047a7de90.png)

こうなるようになってしまいました。

つまり、ChromeでGoogle Play Musicのタブを閉じてはいけない仕様に。
これでは音楽聴きながらブラウジングしていて、思わずChromeのウィンドウを全部閉じると再生が止まる！！
I'm feeling luckey を聞いていたときなんかだと、
「うぉ。閉じてしまった！！」
「今聞いていた曲名わからなーい」
という状況に...

# どうにかChromeから切り離したい

とりあえず最初に考えたのが
「そもそもWebサービスなんだから、ガンバってChromeで聞く必要ないよね」
ということで、普段使わないEdge側からの再生。
これはこれで悪くない。
３日くらい使ってみて、悪くないんだけど、、、なんか・・・なんか違う。

# Chromeの「デスクトップに追加...」って知ってる？

![2016-02-05_chromemenu.png](https://qiita-image-store.s3.amazonaws.com/0/85034/f6f4e643-1954-1333-babb-97d424ce8ed3.png)

前まで、「アプリケーションのショートカットを作成」だった気もするんだけど？？？

「デスクトップに追加」を使うと今見ているページのショートカットがデスクトップに作成されます。
そして、デスクトップに追加されたショートカットから起動するとChromeのメニュー類が無くなったウィンドウが表示されます。

![スクリーンショット 2016-02-05 18.03.10.png](https://qiita-image-store.s3.amazonaws.com/0/85034/97a4def0-6f9b-6026-29c9-a28692b402ca.png)

これで、Chromeを閉じてしまっても別ウィンドウで開いてるから再生が止まる事もないー。

そして、タスクバーに
![2016-02-05_playmusic.png](https://qiita-image-store.s3.amazonaws.com/0/85034/3ee0d180-882a-1c30-cac3-cb2f70c160ff.png)
ピン留めしちゃえば、デスクトップのショートカットを消してもGoogle Play Musicをアプリみたいに起動出来ちゃいます。

隣には同じ感じで昔からやってたChatWorkがあります。
ChatWorkをずっとこの形で使い続けてたのに、この機能を思い出すのに結構時間が掛かった…。
opensslのパスフレーズ引数について

# opensslのパスフレーズ引数でエラー「Invalid password argument」

opensslを使って、PEMからPKCS12を作る際に、下のコマンドでパスワードを付けようとしたら嵌まりましたので、メモします。最初、passwordオプションには、'test123'のように適当なパスワードを入れたところ、「Invalid password argument」が表示されました。

```
openssl pkcs12 -password [password] -in [in_file] -out [out_file] -export
```

指定したオプションは、-passwordオプションでパスワードを設定。
その他のオプションは、
 -in : 入力ファイルを指定
 -out : 出力ファイルを指定
 -export :  PKCS12を作る際に必要
となっています。

```
#エラーメッセージ
Invalid password argument "test123"
Error getting passwords
```

#PASS PHRASE ARGUMENTSについて
##pass:
調べたところ、正しくはパスワードオプションでは、パスワードの前に「pass:」が必要でした。
パスワードを直接入力する場合は、この形式での指定が必要そうです。

```
openssl pkcs12 -password [pass:password] -in [in_file] -out [out_file] -export
```

##stdin
パスワードを標準入力から指定する場合は、「stdin」を下のようにすることもできます。
この場合、「pass:」が必要ありません。
```
echo 'test123' | openssl pkcs12 -password stdin -in [in_file] -out [out_file] -export
```

##env:var
環境変数からパスワードを指定する場合に利用できるそうです。

##file:pathname
ファイルパス指定でパスワードを指定する。
指定したファイルの1行目がパスワードとして利用されます。

##fd:number
ファイルディスクリプタからも利用できるそうです。試してないです。。

##参考サイト

 - OpenSSL
https://www.openssl.org/docs/manmaster/apps/openssl.html

 - OpenSSL日本語訳版
https://www.infoscience.co.jp/technical/openssl/docs/openssl.html
サイズが不揃いな画像をgulpで全部きれいに整える 


不揃いなサイズの画像をgulpで一気に指定のサイズに整形する処理。

よくわからない部分もあるがとりあえず今のところ動いているので備忘的に。

一時は`through2`とかでいちから書くやり方も試してみたりしたけど、
普通に`gulp-gm`の延長線上で行けそう。

ここでは800x400のベース画像を用意して合成しています。

````
var gulp = require("gulp")
var gm = require("gulp-gm")
var _gm = require("gm")

// ベース画像との合成を行う。
var compositeModifier = function (gmfile,done) {
    gmfile.size(function (err, size) {
        var baseGmFile = _gm("./images/baseImg.png");
        if(size.width / size.height < 2){
            baseGmFile = baseGmFile.resize(null,size.height)
        }else{
            baseGmFile = baseGmFile.resize(size.width);
        }
        baseGmFile = baseGmFile.composite(gmfile.source);
        baseGmFile = baseGmFile.gravity("Center");

        done(err, baseGmFile)
    });
};
// リサイズを行う
var resizeModifier = function (gmfile,done) {
    done(err, gmfile.resize(800))
};

gulp.task("images",function(){
    gulp.src(["./images/banners/*"])
        .pipe(gm(compositeModifier))
        .pipe(gm(resizeModifier))
        .pipe(gulp.dest("./public/images/sponsors/"));
});

````

gulp-gmだとgmfileで来るからcompositeのパス取れへんやん…とか思って、
生のfileオブジェクト取りに行ったりもしたけど普通に`gmfile.source`で取れた。

合成後のリサイズが謎だったけど普通にpipe分けたら行ける事に気づいて萎えた。
tsvから対象のidの行を抜き出しcsvで出力するワンライナー

# tsvをcsvに変換
## コマンド
tsvから対象のidの行を抜き出しcsvで出力
```
cat ${source}.tsv | awk -F'\t' "\$1~/${id}/" | sed -e 's/\t/","/g' | sed -e 's/^/"/g' | awk -F\n -v ORS='"\n' '{print}'| sed -e 's/"NULL"/""/g' > ${store}.csv
```

## 解説
* cat ${source}.tsv
 * わざわざcatしなくてよくね？と思うが、実際はここでzcatをしてたりする。大抵こういうワンライナーでは最初はcatにしといた方が手直しが少ないという主観的なアレ。
* awk -F'\t' "\$1~/${id}/"
 * idを抜き出し。egrepとかでやろうとすると正規表現が長くなって管理しづらかった
* sed -e 's/\t/","/g' | sed -e 's/^/"/g' | awk -F\n -v ORS='"\n' '{print}'
 * 区切り文字を変換している。単純に`s/\t/,/`でやると文字列がカンマを含むパターンでデータが壊れる(ex. "1,000円")ので、要素を""で囲っている
* sed -e 's/"NULL"/""/g' 
 * NULLを空文字に変換。もっと賢いやり方があると思うが手抜き。
C++ Builder XE4 > TeeChart > DateTimeFormat > C++ builderのstandard形式 > 24時間表示 / AMPM表示[失敗]

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

TChartAxis.DateTimeFormat
のフォーマット変更が必要になり、調べていたらTeeChartのヘルプには以下の記載があった。

> Description
Chart Axis have a DateTimeFormat property. 
DateTimeFormat is <font color=red>a standard Delphi / C++Builder DateTime formatting string specifier</font>. 
Chart Axis uses it to draw the axis labels.

C++ Builder Date Time formattingをIDEのヘルプで探したが自分が見たい情報にはたどりつけれない。

別途、googleでDateTimeを調べたら以下を見つけた。
http://www.delphibasics.co.uk/RTL.asp?Name=formatdatetime


## try

24時間表記の時刻と、AM,PM表記の時刻を試した。

IN_AMPM マクロをコメントアウトするか、アンコメントすることで切り替える。

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include <DateUtils.hpp>
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------


#define IN_AMPM // AM/PM表示

__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormShow(TObject *Sender)
{
	Chart1->Series[0]->XValues->DateTime = true;
	Chart1->BottomAxis->DateTimeFormat = L"nn:ss";

	TDateTime dt;

    dt = Now();

    double yval;
    for (int idx=0; idx < 10; idx++) {
        yval = (1+ idx) % 2;
        Series1->AddXY(dt, yval, "", clRed);
		dt = IncSecond(dt, 1);
	}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TDateTime stdt = Now();
	TDateTime eddt = IncMinute(Now(), 480);

	Chart1->BottomAxis->SetMinMax(stdt, eddt);
	Chart1->BottomAxis->Increment = TTime(L"02:00");

#ifdef IN_AMPM 
	Chart1->BottomAxis->DateTimeFormat = L"hhampm:nn";
#else
	Chart1->BottomAxis->DateTimeFormat = L"hh:nn";
#endif

}
```

## Button1の実行結果

24時間表記

こちらは成功。
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/57c15ec7-6aaa-3a56-ec8a-8938d1a7fc8b.png)

AM/PM表示(のトライ)

こちらは失敗。PMの表示でなく「午後」となってしまった。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/6cbbd059-77aa-2a39-85d7-e7cb505f5ef7.png)

AM/PM表示はすぐに使わないので今回はここでやめておくが、実際に使う時があればもう少し調べないといけない。
prestoでJSTの期間指定をする雛形

# presto jstのクエリ
よく使うが忘れてしまうのでメモ

```
SELECT
  count(*) 
FROM db_name.table_name AS t
WHERE
    time BETWEEN 
      from_unixtime(to_unixtime(timestamp '2016-01-01 00:00 UTC' ) + (15 * 3600))
    AND
      from_unixtime(to_unixtime(timestamp '2016-01-02 00:00 UTC' ) + (15 * 3600))
;
```
windowsでpythonを動かした

# windowsでpythonを動かしたメモ

仕事でTableauのdata extract apiを使うことになり、こいつがPython2系で操作可能だったので使ってみた。
本当は3系が使いたかったし、Linuxも対応してたのでそっちにしたかったけども、諸事情でwin8にpython2.7という組み合わせになった。

2系でwindowsは辛いのでは…？とか思っていたものの、やってみるとコマンドプロンプトから使うのが厳しいだけ、ということが分かった。


## win機に入れたもの
* msys2
* python2.7
* pycharm


## ツールの雑感
* msys2
 * コマンドプロンプトを使いたくなかったのでコマンドはこれで全て賄おうとするも、特殊な事情（tableau）により失敗
 * 単純にshellなので使い勝手が良い
 * pacmanすごい便利だった
* python2.7
 * 途中までmsys2のpythonでやっていたが、tableauの関係でpython2.7のインストーラを落として入れた
 * インストーラに従うだけで特に詰まることはなかった
* pycharm
 * 普通ならpython関係はこれを入れるだけで完結する
 * shellもついてるのでテストも出来る
 * 今回はTableau のdata extract apiを使う関係で、テストはコマンドプロンプトから行った
Tail Blazer - Windowsでモダンなtail

# Tail Blazer
[RolandPheasant/TailBlazer: A modern file tail utility based on RX.Net](https://github.com/RolandPheasant/TailBlazer)

毎日ログファイルをtailしている作者が既存のtailライクな無料ユーティリティが気に食わなくて自分で作ってしまったようです。

開発の方針は『速い:exclamation:直感的:exclamation:高機能:exclamation:100%リアクティブ:exclamation:』

![tail_blazer.png](https://qiita-image-store.s3.amazonaws.com/0/54591/e6277b0d-db96-7e79-2d08-4fb818e9f66f.png)
キーワードでハイライトしつつ上部では抽出した行のみ表示中の図

## インストール

### Chocolatey

```ps1
choco install tailblazer
```

### バイナリ
[リリースページ](https://github.com/RolandPheasant/TailBlazer/releases)から`TailBlazer_v[x.xxxx].zip`をダウンロード

### ソースから
GitHubからclone or forkでソース持ってきてビルド。（要VS2015）

## 実装
実装はC#/WPF

モダンでリアクティブなWPFアプリを作成する際には参考になりそう
同作者が公開しているReactive関連のライブラリも要チェック
[衝撃] NoSQL KVS  お手軽DB mongo redis sqlite ローカルで神速だったのは。。。

##[衝撃] mongo redis ローカルでさくっとたてるデータベースとして、何千万、億単位、数Gのデータのデータがもっともカンタンで神速だったのは。。。

[Redis 最短入門(1)2行でインストール&起動]
(http://qiita.com/tottoko/items/6dc670ee8b3c58301c65)
[Redis 最短入門(2)5分でAPI]
(http://qiita.com/tottoko/items/fd5075397dc38539cfdc)
[Redis 最短入門(3)Pythonでも5分でAPI]
(http://qiita.com/tottoko/items/de1391329547e1782ad1)
[Mongodb 最短入門(1)EC2にインストール&起動&いきなり数万件入れてみた](http://qiita.com/tottoko/items/db306eb668167937a1ac)
[Mongodb 最短入門(2)数万件いれて探してみた]
(http://qiita.com/tottoko/items/68e61daf6eafb03d4b4b)
[Mongodb 最短入門(3)数百万件でも速くしてみた]
(http://qiita.com/tottoko/items/b6c9430b1e0ab7cb409c)
[SQLiteにpythonで数億行いれてみた]
(http://qiita.com/tottoko/items/0bf43d25c4b69b67df15)

改め、もっとカンタンに億単位を秒殺で入れる方法をみつけた。(サーバースペックにもよるけど)

##ジャカジャーン!最速なのは

#`SQLite3`　であったあるよ。。


###1000万件のCSVを持ってきた~
カンマ区切りで1行目はカラム名あるよ~

###解凍する~
> gunzip honyarara.csv.gz

###1行目を抜く
> sed -e '1,1d' honyarara.csv

###sqlite3 に　CSVをインポートする

```sql

sqlite3 /path/to/mydb.db
sqlite> create table hogagaga (id integer,name text);
sqlite> .separator ,
sqlite> .import honyarara.csv hogagaga

```

ほげっ?
早っ!あまりに速くてselect count(*) したけどほんとうだった。

```py:cgi-bin/sqlite.py

import cgi
import sqlite3

print "Content-type: text/html\n"

conn = sqlite3.connect("/path/to/mydb.db")
csr = conn.cursor()

csr.execute('select * from hogagaga' )

pagesize=100
for x in csr.fetchmany(pagesize):
    items.append(dict(zip(('id','name'), x)))
if len(items):
    print json.dumps({"items":items})

```

###はい、サーバー起動　ッターン!
> python -m CGIHTTPServer &

###JSON返してもらう　ッターン!
> curl http://0.0.0.0:8000/cgi-bin/q.py

ほぎゃ!速い
しかもすべて組み込み。ほとんどの環境ではインストールすら不要のこのコンビ(python + sqlite3)。
KIT(金沢工業大学)の学内のネットワークをRaspberry piで使う時のメモ

この記事は個人的調査によりわかったことをまとめておきます。大学自体はLinuxを公式サポートしていないので、うまく行かなくても自己責任で行ってください。もしかしたらマズい情報なのかもしれないのでやばそうだったら早めに教えていただけると助かります。

### 結論
**大学内でやってはいけない**

### why?
**糞めんどくさい**

### それでもどうしても学内に繋ぎたいんです！！！
仕方ないなぁ・・・

### 今回の調査で判明したこと
+ 有線は使ってはダメ。ただし場所によって繋がる場合がある（あとで説明）
+ やるなら無線。設定はあとで説明。しかし突然死が起きる（原因不明）
+ 見分け方としてIPアドレスが10.～の割当されてる回線はダメ。192.～（無線や、12号館の有線など）で割り当てられる回線はうまくいく。

### 設定と対策
まずプロキシの設定から。セキュリティの関係上URLは載せませんが、手動の方を書いてください。
まずはパッケージ管理ツールを設定。

```bash:etc/apt/apt.conf
Acquire::ftp::proxy "ftp://wwwhogehoge.jp:8888/";
Acquire::http::proxy "http://wwwhogehoge.jp:8888/";
Acquire::https::proxy "https://wwwhogehoge.jp:8888/";
```

次にシェルの方も設定。ここではデフォルトのbashの設定でやっています。

```bash:.bashrc
export http_proxy=http://wwwhogehoge.jp:8888/
export https_proxy=$http_proxy
export ftp_proxy=$http_proxy
export no_proxy=localhost
```

これでプロキシの設定は完了です。
さて、無線LANの設定をしましょう。
まず無線LANアダプターの申請を事前に済ませておいてください。
そんで以下の設定を書き込んでください。
例によってSSIDとか変えてますが適宜変更してください。

```bash:/etc/wpa/wpa_supplicant.conf
network={
        ssid="KIT-WIFI"
        key_mgmt=IEEE8021X
        eap="PEAP"
        identity="a学籍番号"
        password="申請したパスワード"
        phase1="peapver=0"
        phase2="MSCHAPV2"
}
```

ここまで来たら再起動しましょう。
すると繋がるようになるはずです。
しかし大学はDHCPによってIPアドレスを割り当てているので、いちいちIPアドレスを見つけてつなぐのは面倒です。
そこで、Avahiを使いラズパイをローカルネット内で名前解決してあげるようにします。
まずは導入しましょう。

```bash
$sudo apt-get install -y avahi-daemon
```

これで準備はできました。
ただ、デフォルトのホストネームだと被ってしまうので、ホストネームを変えましょう（ここではやり方は省略します。raspi-config使いましょう。）
ただしBonjour使っているのでWindowsでiTunesを導入してない方は別途導入が必要です。DLは[こちら](https://support.apple.com/kb/DL999?viewlocale=ja_JP&locale=ja_JP)。ただWindows版に提供されているのは古いのでもしかしたら最新では動かないかもしれません。(8.1proでは動作確認しました)
あとはPC側から

```bash
ssh pi@hoge.local
```

これでログインできるようになります。

### **ここまでできたらバックアップをとろう**
先程も言ったように唐突に繋がらなくなります。再起動しようが設定見なおそうがだめになります。また再インストールして上の設定して・・・と言うのはめんどくさいのでこの状態でイメージファイルを一旦作っておいて、ダメになったら復元して・・・という感じでやりましょう。WindowsならWin32 Disk Imagerがおすすめです

### 最後に
ここまで来てめんどくさそうだなぁと思った人、正解です。逆にもっと楽に繋がる方法があるよって方は教えてくれると嬉しいです。
VirtualBoxで作成したCentOSにOpenStackを構築する(インスタンス編)

[環境編](http://qiita.com/tk3fftk/items/76d696a874d829ea9fe4)
[Identity編](http://qiita.com/tk3fftk/items/546ab241ac7b89a1c3c2)
[Image編](http://qiita.com/tk3fftk/items/7899758d14cde4a9b2db)
[Compute編](http://qiita.com/tk3fftk/items/810e70533466c9307a93)
[Networking編](http://qiita.com/tk3fftk/items/07e384933eb12591b731)
[Dashboard編](http://qiita.com/tk3fftk/items/e41e7454b69232d9f534)
の続きです。

[公式ドキュメント](http://docs.openstack.org/liberty/ja/install-guide-rdo/launch-instance.html)に従ってやっていきます。

- CLIでもDashboardでもどちらでもできますが、せっかく入れたのでDashboardでやりました。
- パブリックネットワークの作成のみCLIで行います。(自分の場合はDashboardでできないっぽかったので)

# パブリックネットワークの作成
- source~で環境変数の読み込み
- ネットワークの作成
  - `# neutron net-create public --shared --provider:physical_network public --provider:network_type flat`
      - publicという名前で
      - --sharedオプションで，全てのプロジェクトがこの仮想ネットワークを使用できるようにする
      - --provider:physical_network publicでml2_conf.iniのflat_networks = publicを利用
      - --provider:network_type flatでphysical_interface_mappings = public:enp0s3を利用
             - 仮想フラットネットワークを，ホストのenp0s3インタフェースのフラットパブリック物理ネットワークに接続する
- サブネットの作成
  - `# neutron subnet-create public 192.168.12.0/24 --name public-sub --allocation-pool start=192.168.12.20,end=192.168.12.30 --dns-nameserver 8.8.8.8 --gateway 192.168.12.1`
      - public に x.x.x.x/yyの --name という名前のサブネットを作成する
      - インスタンスに割り当てるIPは--allocation-poolで最初と最後のIPを記述
      - DNSサーバの設定と，使用するゲートウェイを指定する
- これでdashboardからインスタンスの作成ができた(のでCLでもできるはず)
  - `ssh -i 鍵 cirros@hogehoge` でいけた

# インスタンスの作成
## キーペアの作成
> 多くのクラウドイメージは、一般的なパスワードによる認証ではなく、公開鍵認証 に対応しています。インスタンスの起動前に、公開鍵を Compute サービスに追加する必要があります。

- Dashboardにログインし、サイドメニューの「プロジェクト」>「コンピュート」>「アクセスとセキュリティー」を開く
- 「キーペア」タブを開く
- 「キーペアのインポート」ボタンを押す
- (今回は)コンピュートノードで以下を実行する
  - `ssh-keygen -t rsa -f test.key`
      - パスフレーズは何も入れずにEnter
      - test.keyとtest.key.pubが生成されます
  - `cat test.key.pub`を実行して、出力をコピペ
- 「キーペア名」を入力し、コピペした公開鍵を「公開鍵」に貼り付ける
- 「キーペアのインポート」ボタンを押して完了。

## セキュリティグループの追加
- サイドメニューの「プロジェクト」>「コンピュート」>「アクセスとセキュリティー」を開く
- 「セキュリティグループ」タブを開く
- 「default」の「ルールの管理」ボタンを押す
- 「ルールの追加」ボタンを押す
  - 「すべてのICMP」を受信，送信両方追加する。他の設定はそのまま
  - 「SSH」を追加して完了

## インスタンスの起動
- サイドメニューの「プロジェクト」>「コンピュート」>「インスタンス」を開く
- 「インスタンスの起動」ボタンを押す
- 「詳細」タブで以下を入力する
  - インスタンス名: test 
  - フレーバー: m1.tiny 
  - インスタンス数: 1
  - インスタンスのブートソース: イメージから起動
  - イメージ名: cirros
- 「アクセスとセキュリティー」タブで以下を行う
  - キーペア: test
  - セキュリティーグループ: defaultにチェック
- 「ネットワーク」タブでpublicが選択されていることを確認する
- 起動する

## 確認
- インスタンス一覧からtestを選択
- 「コンソール」タブを開いて接続されていることを確認
  - cirros/cubswin:)でログインできるが、デフォルトではキーボードが英字配列になっており:)の入力が困難だった
  - コンソールのアドレス解決ができていない場合
      - コンピュートノードの`/etc/nova/nova.conf`の
      - novncproxy_base_url  をブラウザから見える場所のIPにする
- コントローラノードからpingが飛ぶか確認する
  - `ping 192.168.12.xxx`
      - xxxには立ち上げたインスタンスのIPを入れる
- コントローラノードからSSHできるか確認する
  -  `ssh -i test.key cirros@192.168.12.xxx` 
  -  ログインできたらおk
[初心者向け]Symfony2を簡単にherokuにデプロイする手順

symfony2をHerokuにデプロイする手順です。

色々なブログでも紹介されていますが、個人的に一番わかりやすかったのがHerokuの公式サイト
https://devcenter.heroku.com/articles/getting-started-with-symfony
だったので日本語で手順を紹介したいと思います。

環境は以下が揃っていればいいと思います。
・Gitインストール済み
・composerまたはSymphony Installerを通じてSymfonyがインストールされている(今回はsymfony_herokuというディレクトリ内で行います。)
・herokuアカウントにサインアップし、Heroku Toolbeltがインストールできている(Herokuコマンドが使える)

上記リンクではSymfony3で行われてますが、Symfony2でもいけます。

まずGitを初期化します。
`$ git init
 $ git add .
 $ git commit -m"initial commit"`

次に同じディレクトリ内でherokuのアプリケーションを新規作成します。
`$ heroku create`だけでも作成できますが、もしアプリケーション名を指定したい場合には、
`$ heroku create -r heroku --app アプリケーション名`
で作成できます。
(同じアプリケーション名が複数あると作成できないので、その際は違うアプリケーション名にしてください)

次にheroku上でのSymfonyの環境の変更を行います。
Symfonyのプロジェクトでは複数の設定を用意することができます(`prod`:本番環境向け、`dev`:開発環境向け、`test`:テスト環境向け)。
Symfonyはデフォルトで`dev`環境に設定されていますが、このままではheroku上では正しく動きません。
そのため、この環境を`prod`にする必要があります。
変更には以下のコマンドでできます。
`$ heroku config:set SYMFONY_ENV=prod`

そしてGit経由でherokuにデプロイします。
`$ git push heroku master`

最後にきちんとデプロイされているか確認します。
`$ heroku open`

<img width="1280" alt="スクリーンショット 2016-02-05 05.14.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/86498/0d00dce4-741e-bfd9-41be-305bb1e2f6fe.png">

このような画面が出てきたらデプロイに成功しています。
PHPのprint_r()で出力されたArrayオブジェクトをRuby上で復元するプログラム

いつどこでどのように利用したのかさっぱり覚えていない・・・
けれど、なんとなくいつか使いそうな気がしなくもない・・・いや本来は利用されるべきでもないような・・・

```
module PrintR
  class Parser
    attr_reader :text
    def initialize(text)
      @text = text
    end
    def parse
      _to_object(text, 0)
    end
    def _to_object(str, indent)
      str = str.strip
      tab = "    " * indent
      if md = str.match(/^(Array|[^ ]*? Object)\n \*RECURSION\*$/m)
        obj = Recursion.new(md[1])
      elsif md = str.match(/^(?:Array|[^ ]*? Object)\n#{tab}\(\n(.*)#{tab}\)$/m)
        obj = _to_key_values(md[1].split(/(\r\n|\r|\n)/), indent+1)
        obj.each do |key, value|
          obj[key] = _to_object(value, indent+2)
        end
      else
        obj = str
      end
      obj
    end
    def _to_key_values(lines, indent)
      tab = "    " * indent
      h = {}
      key = nil
      val = ""
      lines.each do |line|
        md = line.match(/^#{tab}\[([^\]]+)\] => (.*)/)
        if md
          if key
            h[key] = val
            key = nil
            val = ""
          end
          key = md[1]
          val = md[2]
        else
          val += line
        end
      end
      if key
        h[key] = val
        key = nil
        val = ""
      end
      h
    end
  end
end
```
JavaScriptで複数行の文字列や変数を扱うならテンプレート文字列が便利

TypeScript(またはJavaScript)でHTMLの複数行のコードを書く時等、複数行の文字列を扱う場合に下記のような書き方をしていませんか？

```lang:javascript
'<div id="hoge">'
+ 'ラーメン・つけめん・中本のタンメン'
+ '</div>';
```

シングルクォーテーション(`'`)やプラス記号(`+`)を行ごとに書くのは面倒ですよね？ TypeScriptを使っているならバッククオート(`` ` ``)を使って下記のように記述できます。ちなみにOS Xでバッククオートを入力するには[`Shift`]+[`@`]です。

```lang:typescript
`<div id="hoge">
ラーメン・つけめん・中本のタンメン'
</div>`;
```

バッククオートを使うのは複数行文字列の最初と最後だけで、わざわざ行ごとに閉じたりする必要はありません。便利なので複数行の文字列を使うならこちらを使いましょう。テンプレート文字列と言います。

* * *

(余談)
IDE「[WebStorm](http://samuraism.com/products/jetbrains/webstorm)」ではテンプレート文字列を使ってHTMLコードを記述した場合も、シンタックスハイライト、コード補完等が有効なので便利です。
![Template String](https://qiita-image-store.s3.amazonaws.com/0/67884/f555716c-b05b-be18-619a-e6157d59fca5.png)
PIL (Pillow) で RGB から CIELAB へ色空間を変換する

RGB と CIELAB の間の相互変換は `PIL.Image.convert` ではなく、`PIL.ImageCms` を使って行なう。

```python
from PIL import Image, ImageCms

im = Image.open(image_path)
if im.mode != "RGB":
  im = im.convert("RGB")

srgb_profile = ImageCms.createProfile("sRGB")
lab_profile  = ImageCms.createProfile("LAB")

rgb2lab_transform = ImageCms.buildTransformFromOpenProfiles(srgb_profile, lab_profile, "RGB", "LAB")
lab_im = ImageCms.applyTransform(im, rgb2lab_transform)
```
ヒアドキュメントすごいと思ったので

PHPで文字列書くとき以下の様な感じですよね。

```php
$hoge = "私はhogeです。";
```

これでタグが出現すると、、、

```php
$hoge = "<span>私はhogeです。</span>";
```

で、このタグにクラスを設定したいとする

```php
$hoge = "<span class=\"fuga\">私はhogeです。</span>";
```

となります。
こいつをヒアドキュメントに置き換えるとこうなる。

```php
$hoge = <<<TEXT
<span class="fuga">私はhogeです。</span>
TEXT;
```

こうなる。
何が違うって「`\`」でクォートしなくていいんですよ。
変数内にタグをズラズラ書くってそんなにないと思うんですけど
もしあった場合はぜひヒアドキュメントを使って見やすくしよう、、、というお話でした。

追記：
定数は展開できない。
ではどうするか。こうするのが一つの方法？

```php
define('HOGEHOGE','ほげ！');
$hogehogehoge = HOGEHOGE;
$hoge = <<<TEXT
<span class="fuga">私はhogeです。</span>
{$hogehogehoge}
TEXT;
```

でも、せっかく定義した定数を変数に入れて使うなんてなんかナンセンス、、、
クラスを使って展開する方法もあるらしいけどどちらにしろあまりよろしくないなぁと思った。