OmniAICreator/Qiita-1.07M huggingface dataset:
静的サイトジェネレーターの一言レビュー (Punch, Jekyll, Octopress)


チュートリアルが素晴らしく、とっつきやすいのが [Punch](http://laktek.github.io/punch/)。複雑なことやろうとすると、大変かも。できるのかもしれないけど。

GitHub Pagesでも使われていて定評あるのが [Jekyll](http://jekyllrb.com/)。ブログ以外でも使えます。例えば [markdown.jp](https://github.com/markdown-ja/markdown.jp) で使ってます。 [Jekyllいつやるの？ジキやルの？今でしょ！](http://melborne.github.io/2013/05/20/now-the-time-to-start-jekyll/) という文章が参考になるかな。

[Bootstrap](http://getbootstrap.com/) を使うなら GitHub で [twbs/bootstrap](https://github.com/twbs/bootstrap) を clone するのがおすすめ。公式サイトのリファレンスが Jekyll プロジェクトになっているので、 localhost で Bootstrap のリファレンスを利用できます。ネット回線がなくてもサイト制作できる。

ブログをするなら [Octopress](http://octopress.org/) が便利。Jekyllを拡張して、RubyのRakefileで便利なタスク管理機能をつけたり、簡単にテーマを変更できたりするようにしたもの。（GitHub Pages にデプロイするためには、事前に `rake setup_github_pages` する必要があります）

ブログをやるだけならラクだけど、いろいろ制約もあるかも、という感じ。 Jekyll (+Bootstrap) 自体を使ったほうが柔軟かな。
動画処理の定番ツール「FFmpeg」ことはじめ


# はじめに

YouTubeやFacebookでも利用されているという噂のFFmpegは、開発が非常に活発で、ここ1年だけでもバージョン1.0から2.1まで上がっています。

ちょっと前まではFFmpegでエンコードした動画をストリーミングに対応させるのは一手間かかったのですが、今では-movflags faststartオプションを付けるだけで対応できるようになりました。（…というのも新しい機能のほんの一部で、他にもたくさんあります）

ここでは、FFmpegの簡単な使い方をメモします。
内容は基本的なことですが、実運用で得たTipsもできるだけ混ぜていきたいと思います。
また、内容に誤りなどあれば、是非ご指摘頂けると有難いです。

# インストール

インストールについては公式サイトに丁寧な解説があるので、そちらをご参照ください。
https://trac.ffmpeg.org/wiki/CompilationGuide

基本的には書いてある通りに進めば問題なく動きますが、動画エンコード時に使うフィルタによっては、configure時に何らかのオプションを付ける必要があります。

例えば、映像内に文字を書き込むにはdrawtextというフィルタを使いますが、これを利用するためにはconfigure時に--enable-libfreetypeオプションを追加する必要があります。

※ビデオフィルタに関するドキュメント
http://ffmpeg.org/ffmpeg-filters.html

# 使い方

FFmpegは豊富なエンコードオプションが用意されていますが、何も指定しなくても十分に使えます。

## H.264でmp4形式に変換する

H.264でのエンコードは、以下のように行います。

```
ffmpeg -i [元動画] -movflags faststart -vcodec libx264 -acodec libfaac [新しい動画]
```

[元動画]は、FFmpegが対応しているものであれば自動判別してくれます。

ちなみに、H.264はWebでの動画配信では非常に多く利用されている動画コーデックです。ライセンスの問題があり、ブラウザによっては採用されていないのですが（その場合でもFlash経由なら使える）、つい先日CiscoがH.264のオープンソース化を発表し、それに伴ってFirefoxもH.264をサポートすることを発表しました。

※CiscoとMozilla、H.264のオープンソース化とFirefoxでのサポートを発表
http://www.itmedia.co.jp/news/articles/1310/31/news064.html

## 特定の時間帯を切り出す

特定の時間帯を切り出すのも簡単です。

```
ffmpeg -ss [開始位置(秒数)] -i [元動画] -t [切り出す秒数] [新しい動画]
```

なお、動画の切り出し方は複数パターンあり、基本的にはスピードと精度のトレードオフになっています。このあたりについては[FFmpegで素早く正確に動画をカットする自分的ベストプラクティス](http://qiita.com/kitar/items/d293e3962ade087fd850)という実験メモも書いておりますので、もしよろしければご参考ください。

## 特定の範囲を切り出す

動画の隅などに不要なものが映っていたりして、特定の範囲だけ切り取りたいこととかありますよね。

```
ffmpeg -i [元動画] -vf crop=x=[切り取りを開始するx座標]:y=[切り取りを開始するy座標]:w=[切り取る範囲の幅]:h=[切り取る範囲の高さ] [新しい動画]
```

## ビデオフィルタをかける:ぼかし処理

何か隠したいものがあることってありますよね。

```
ffmpeg -i [元動画] -vf boxblur=2:1 [新しい動画]
```

## ビデオフィルタをかける:文字を入れる

字幕を入れたいこととかありますよね。

```
ffmpeg -i [元動画] \
 -vf drawtext="[TrueTypeフォントのパス]: \
 text='あのイーハトーヴォのすきとおった風': \
 x=0: y=0: fontsize=20: box=1: boxcolor=white@0.7" [新しい動画]
```

冒頭にも書きましたが、drawtextを使うためにはffmpegコンパイル時に--enable-libfreetypeオプションが必要です。

## 動画から画像を切り出す

サムネイル画像とか作ることもありますよね。

```
ffmpeg -ss [切り出し位置(秒数)] -i [元動画] -vframes 1 -f [切り出す画像]
```

## 音声部分をを取り出す

音声部分だけ加工したい（ノーマライズなど）こともありますよね。
FFmpegはノーマライズはできないので、音声ファイルだけ取り出して別ツールで処理する必要があります。
以下の例では、16bitのwavファイルに切り出しています。

```
ffmpeg -i [元動画] -acodec pcm_s16le [取り出す音声]
```

## 映像と音声を結合する

バラバラの映像と音声を結合するには以下のようにします。

```
ffmpeg -i [元映像] -i [元音声] -map 0:0 -map 1:0 \
-movflags faststart -vcodec libx264 -acodec libfaac [新しい動画]
```

-mapの「0:0」や「1:0」は、どのファイルを何番目のストリームに配置するのかを指定しています。

なお、この時に映像や音声のコーデックを変換する必要がない場合、-vcodec copyや-acodec copyのように値にcopyを指定すると再エンコードする必要がないため余計な処理が走りません。（ncaqさんコメントありがとうございます！）

## 動画のメタデータを確認する

動画の長さや、サイズ、ビットレート、動画や音声などトラックごとの情報などを表示します。

```
ffprobe [元動画]
```

---

以上、基本的な使い方の部分をご紹介いたしました。

本家のドキュメントも充実しているので、是非あわせてご覧ください。
http://ffmpeg.org/documentation.html

## その他の記事

* [ffmpegで動画の中に動画を表示する（実況中継の隅っこにある解説者の映像のような）](http://qiita.com/kitar/items/c4da996e358e39aa7c9b)
npm で [TypeError: Request path contains unescaped characters.] がでたときの対処

何の気なしにインストールしようとすると

```
# npm install -g coffee-script
```

>
npm http GET https://registry.npmjs.org/coffee-script
npm ERR! TypeError: Request path contains unescaped characters.
npm ERR!     at Agent.request (\_http_agent.js:278:11)
npm ERR!     at TunnelingAgent.exports.request (http.js:52:22)
npm ERR!     at TunnelingAgent.createSocket (/usr/local/lib/node_modules/npm/node_modules/request/node_modules/tunnel-agent/index.js:117:25)
npm ERR!     at TunnelingAgent.createSecureSocket [as createSocket] (/usr/local/lib/node_modules/npm/node_modules/request/node_modules/tunnel-agent/index.js:184:41)
npm ERR!     at TunnelingAgent.addRequest (/usr/local/lib/node_modules/npm/node_modules/request/node_modules/tunnel-agent/index.js:80:8)
npm ERR!     at new ClientRequest (\_http_client.js:122:16)
npm ERR!     at Agent.request (\_http_agent.js:293:10)
npm ERR!     at Object.exports.request (https.js:129:22)
npm ERR!     at Request.start (/usr/local/lib/node_modules/npm/node_modules/request/request.js:584:30)
npm ERR!     at Request.end (/usr/local/lib/node_modules/npm/node_modules/request/request.js:1212:28)
npm ERR! If you need help, you may report this log at:
npm ERR!     <http://github.com/isaacs/npm/issues>
npm ERR! or email it to:
npm ERR!     <npm-@googlegroups.com>
npm ERR! System Linux 2.6.32-279.14.1.el6.x86_64
npm ERR! command "/usr/local/bin/node" "/usr/local/bin/npm" "install" "-g" "coffee-script"
npm ERR! cwd /root
npm ERR! node -v v0.11.9-pre
npm ERR! npm -v 1.3.13
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR!     /root/npm-debug.log
npm ERR! not ok code 0

怒られた。

おもむろにプロトコルをhttpに変更する。。

```
# npm config set registry http://registry.npmjs.org/
# npm install -g coffee-script
```

>
npm http GET http://registry.npmjs.org/coffee-script
npm http 200 http://registry.npmjs.org/coffee-script
npm http GET http://registry.npmjs.org/coffee-script/-/coffee-script-1.6.3.tgz
npm http 200 http://registry.npmjs.org/coffee-script/-/coffee-script-1.6.3.tgz
/usr/local/bin/coffee -> /usr/local/lib/node_modules/coffee-script/bin/coffee
/usr/local/bin/cake -> /usr/local/lib/node_modules/coffee-script/bin/cake
coffee-script@1.6.3 /usr/local/lib/node_modules/coffee-script


```
# coffee -v
CoffeeScript version 1.6.3
```

めでたし。
途中で sudo 必要な足場をはさんだ先にある鯖に入る(tramp編)

```lisp:
(add-to-list 'tramp-methods
  '("sudosaba"
    (tramp-login-program        "ssh -t saba ssh -t sudosaba sudo ssh")
    (tramp-login-args           (("%h")))
    (tramp-async-args           (("-q")))
    (tramp-remote-shell         "/bin/sh")
    (tramp-remote-shell-args    ("-c"))
    (tramp-gw-args              (("-o" "GlobalKnownHostsFile=/dev/null")
				 ("-o" "UserKnownHostsFile=/dev/null")
				 ("-o" "StrictHostKeyChecking=no")))
    (tramp-default-port         22)))
```
alist 足せばいいだけだった。別途 .ssh/config 設定とか必要な場合もあるだろうけど。
Jenkins+Apache連携(AJP) メモ

・ポート8080は閉じておきたい
・AJPポート8009は別サービスで使用中

■Jenkins側設定
vi /etc/sysconfig/jenkins
ポート8080を閉じる
#JENKINS_PORT="8080"
JENKINS_PORT="-1”

AJPポートを変更する(他のサービスとかぶらないように)
#JENKINS_AJP_PORT="8009"
JENKINS_AJP_PORT="9009"

Apache側で/jenkinsディレクトリにJenkinsを割り当てるためにJenkins側でもパス解決
#JENKINS_ARGS=""
JENKINS_ARGS="--prefix=/jenkins”

■Apache側設定
vi /etc/httpd/conf.d/jenkins.conf
以下の内容を記載する
ProxyPass /jenkins     ajp://localhost:9009/jenkins
ProxyPassReverse /jenkins ajp://localhost:9009/jenkins
ProxyRequests Off
<Proxy ajp://localhost:9009/jenkins*>
Order deny,allow
Allow from all
</Proxy>
vimで日本語が文字化けしてた


vagrant で用意した環境に 日本語ロケールが登録されてなかったっぽい。

locale コマンドで確認。

```
$ locale
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_ALL to default locale: No such file or directory
LANG=ja_JP.UTF-8
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=
```

エラーが出てる。

ロケールの一覧を取得してみる。

```
$ locale -a
locale: Cannot set LC_CTYPE to default locale: No such file or directory
locale: Cannot set LC_MESSAGES to default locale: No such file or directory
locale: Cannot set LC_COLLATE to default locale: No such file or directory
C
POSIX
en_AG
en_AG.utf8
en_AU
en_AU.iso88591
en_AU.utf8
en_BW
en_BW.iso88591
en_BW.utf8
en_CA
en_CA.iso88591
en_CA.utf8
en_DK
en_DK.iso88591
en_DK.utf8
en_GB
en_GB.iso88591
en_GB.iso885915
en_GB.utf8
en_HK
en_HK.iso88591
en_HK.utf8
en_IE
en_IE.iso88591
en_IE.iso885915@euro
en_IE.utf8
en_IE@euro
en_IN
en_IN.utf8
en_NG
en_NG.utf8
en_NZ
en_NZ.iso88591
en_NZ.utf8
en_PH
en_PH.iso88591
en_PH.utf8
en_SG
en_SG.iso88591
en_SG.utf8
en_US
en_US.iso88591
en_US.iso885915
en_US.utf8
en_ZA
en_ZA.iso88591
en_ZA.utf8
en_ZW
en_ZW.iso88591
en_ZW.utf8
```

日本語関係が全くない。

日本語ロケール(UTF-8)を追加する。

```
sudo localedef -f UTF-8 -i ja_JP ja_JP
```

もう一度、対応ロケールの一覧を確認。

```
$ locale -a
C
POSIX
 (省略)
ja_JP
ja_JP.utf8
```

今度は出てきた。

念のため現在のロケールも確認。

```
$ locale
LANG=ja_JP.UTF-8
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=
```

今度は問題なし。

# 参考
[CentOS 5.2で日本語ロケールを使えるようにするメモ | データセンターの専用サーバ データセンターダイレクト ブログ](http://blog.dc-d.jp/?p=942)
OS Xでターミナルからパスワード付きzip書庫を作る

たまにファイルやフォルダからzip書庫を作成して、書庫に対してパスワードを付加したい、ということがあるかと思います。
それをターミナルから実行しようとするたびに忘れているのでここにメモなのです。

## zip書庫作成時にパスワードを付加する

zipコマンドでパスワードを付加してzip書庫を作成するには、`-e`オプションを使います。
ちなみにディレクトリとその配下のファイルも一緒に圧縮する場合は`-r`オプションを使います。

```sh
$ zip -e file.zip file.txt
Enter password: (入力する)
Verify password: (入力する)
  adding: file.txt (deflated xx%)
```

この書庫を展開しようとすると……

```sh
$ unzip file.zip
Archive:  file.zip
[file.zip] file.txt password: (入力する)
  inflating: file.txt
```

パスワードを聞かれていますね。

## 既にあるzip書庫に対してパスワードを付加する

パスワードの付加されていないzip書庫に対して、後からパスワードを付加するにはzipcloakコマンドを使います。

```sh
$ zip file.zip file.txt
  adding: file.txt (deflated xx%)
$ zipcloak file.zip
Enter password: (入力する)
Verify password: (入力する)
encrypting: file.txt
```

この書庫も展開しようとすると……

```sh
$ unzip file.zip
Archive:  file.zip
[file.zip] file.txt password: (入力する)
  inflating: file.txt
```

となります。
UbuntuでMac OS(HFS+)のディスクを読み書きする

![975c00a0db0de591f5dbba65608b9bcd.jpeg](https://qiita-image-store.s3.amazonaws.com/0/1818/f1029a8c-1216-a8c0-72e0-ee62a4b17d55.jpeg)

Macのディスクユーティリティでフォーマットする場合はFATではなく「Mac OS拡張系」を選びますが、これはHFS+のことでありUbuntuでも読み書き可能です。

## マウント

Ubuntu側のマウントは、Ubuntu 9.10以上では問題なくマウントされるようです。

古いバージョンのUbuntuや、上手くマウントされない場合はhfsplusを使います。

### インストール
```
$ sudo apt-get install hfsplus
```

### ディスクの場所を確かめる
```
$ sudo fdisk -l
```

### マウントポイントの作成
```
$ mkdir /mnt
```

### マウント
```
$ sudo mount -t hfsplus /dev/sda2 /mnt
```

### アンマウント
-fをつけると、エラーを無視して強制的にできます。
```
$ umount -f /mnt
```

## HFS+を読み書き

Mac OS拡張フォーマットで推奨されているのはジャーナリング付きです。
しかしジャーナリングが有効だと、安全性は高まりますがUbuntuでは書き込みができなくなります。
ジャーナリングの外し方は、

```
$ diskutil disableJournal diskname
```

戻し方は、

```
$ diskutil enableJournal diskname
```

です。
よほどパフォーマンスを求めない限りジャーナリングはオンにしておきましょう。

ジャーナリングがオフでも書き込めなくなる

ジャーナリングがオフの状態でも、Mac側でディスクの権限に書き込み許可を付与しない限り書き込めません。
また、Ubuntuからディスクを外すときに正常にアンマウントされないと次回から書き込めなくなるようです。

**※ 書き込めなくなった場合の解決策が分かる人がいたら教えてください。。。**

## 参考
http://javaflavor.cocolog-nifty.com/blog/2007/06/linuxhfs_hfs_as_5283.html
https://forums.ubuntulinux.jp/viewtopic.php?pid=40131
AOJ Sort I -

[http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_A](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_A)

Bubble Sort

```py:op.py
#!/usr/bin/python
i = input()
n = map(int, raw_input().split())
cnt=0

for i in xrange(len(n)):
    for j in xrange(len(n)-1, i, -1):
        if n[j] < n[j-1]:
            n[j], n[j-1] = n[j-1], n[j]
            cnt+=1
print ' '.join(map(str,n))
print cnt
```

```a,b =b,a```
aとbの値が入れ替わるとか凄いですね。

```
        if n[j] < n[j-1]:
            n[j], n[j-1] = n[j-1], n[j]
```
の部分はいま正にfor j in〜で指定しているn[j]と次にチェックする予定のn[j-1]を比較している。  
より小さい方をn[j-1]にすることで最初の周回で最も小さい値がリストの後ろから前へ浮かび上がる。  

```perl:内側のループ一周目サンプルリスト.py
#6,8を比較。6のほうが小さいので入れ替えない。
[2, 5, 3, 1, 7, 9, 10, 4, 6, 8]

#4,6を比較。4の方が小さいので入れ替えない。
[2, 5, 3, 1, 7, 9, 10, 4, 6, 8]

#10,4を比較。4のほうが小さいので入れ替え済。
[2, 5, 3, 1, 7, 9, 4, 10, 6, 8]

#9,4を比較。4のほうが小さいので入れ替え済。
[2, 5, 3, 1, 7, 4, 9, 10, 6, 8]

#7,4を比較。4の方が小さいので入れ替え済。
[2, 5, 3, 1, 4, 7, 9, 10, 6, 8]

#1,4を比較。1のほうが小さいので入れ替えない。
#4から1に乗り換えて置いていく。
[2, 5, 3, 1, 4, 7, 9, 10, 6, 8]

#3,1を比較。入れ替え済。
[2, 5, 1, 3, 4, 7, 9, 10, 6, 8]

#5,1を比較。入れ替え済。
[2, 1, 5, 3, 4, 7, 9, 10, 6, 8]

#2,1を比較。入れ替え済み。
[1, 2, 5, 3, 4, 7, 9, 10, 6, 8]
```

途中でより小さい数があればホイホイ乗り換えて、ドンドン前へ連れて行く。  
この一周目でリスト中で最小の値が一番前へ入れ替えされることが保証される(よね・・・？)。
なので二周目はチェックが一つ手前までになる。

```python:抜粋
for i in xrange(len(n)):
#一周回る毎にチェックが一つ手前までになるようになっている。
#より小さい値を前に寄せているため。
    for j in xrange(len(n)-1, i, -1):
```

```python:終わったっぽかったら途中で打ち切るようにしてみた
for m in range(len(n)):
    for j in range(len(n)-1, m, -1):
        if n[j]<n[j-1]:
            n[j],n[j-1]=n[j-1],n[j]
            ans+=1
#        print ans
    if ans==chk: break
    chk=ans
print ' '.join(map(str,n))
print ans
```
いちおAOJのテストケースでは全部通ったけどこれいいのかよくわかんね。動作は非保証。

AOJ Sort I - Selection Sort

[http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_B](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_2_B)

はい。

```python:op.py
#!/usr/bin/python
# -*- coding: UTF-8 -*-
i = input()
n = map(int, raw_input().split())
cnt=0

#リストの一番手前からみる。
for i in xrange(len(n)):
#いま見てる番目を記憶
    min=i
#フラグ判定を0で初期化
    flag=0
#リストの二番目以降(i一周回ることに右へ寄る)から最後は一つ手前まで
    for j in xrange(i,len(n)):
        if n[j]<n[min]:
#より小さい値の順番目を記憶する。
#このifの中に入っていると入れ替え処理候補が有ったことになるのでフラグを立てる。
            min=j
            flag=1
#当初の比較のために取り出してきた値と発見した最小の値を入れ替える。
    n[i],n[min]=n[min],n[i]
    cnt+=flag
print ' '.join(map(str,n))
print cnt
```
ふーむ、False,Trueが0や1の値も持っている？ことを活用してるか、、
BaaSを比較してみた



## BaaSとは
BaaSとは__Backend as a Service__の略であり、モバイルアプリケーションを作成する上で必要な__サーバ側の機能__を提供してくれるフレームワーク及び実行環境。次のような機能を提供する。

* ユーザー登録、IDの再発行、ユーザー情報の管理
* メール通知、プッシュ通知
* GPSを活用した、位置情報サービスとの連携
* TwitterやFacebookなどソーシャルネットワークサービスとの連携
* データやコンテンツの保存／管理機能

（[@ITのBaaS説明記事](http://www.atmarkit.co.jp/ait/articles/1209/28/news146.html)より抜粋）

以下にBaaSと他のクラウドの比較を掲載する。BaaSの位置付けがよく分かると思う。  

![pic_baas1.png](https://qiita-image-store.s3.amazonaws.com/0/10225/987d9df5-5b0d-9fb2-bbcd-972f0be5c3ec.png "pic_baas1.png")

([appiariesサイトのBaaS説明ページ](http://www.appiaries.com/jp/baas/)から抜粋)

## BaaSの提供形式

現在は圧倒的にクラウド形式での提供が多い。もともと「モバイルアプリケーションをスピーディに開発＆リリースしたい」というニーズに応えるための製品なので、これは当然のこと。  

しかしオンプレ製品がないわけではない（[Helios](http://helios.io)、[AppPot](http://app-pot.jp)など）。

## 評価ポイント

実際に使ってみた結果、次のポイントが重要だと感じた。

* 提供形式（クラウドorオンプレ形式）
* SDKがサポートするプラットフォーム
* SDKの安定度
* マニュアルなどの日本語化状況
* サーバ側の管理用サイトの扱いやすさ

機能の多寡は、どのBaaS製品も基本的な機能は似通っているため、評価ポイントから外した。


### サーバ側の管理用サイトの使いやすさについて

開発中は、サーバ側の管理用サイトは、BaaS製品が提供するものをそのまま使うのが基本。よって頻繁にアクセスすることになるのに、ここの出来が悪いと非常にストレスがたまる。ニフティはこの点に難があった。非常に残念。

### 比較した製品と評価

|製品名|特長|評価|
|:--:|:--|:--|
|__Windows Azure モバイルサービス__|Windows AzureをプラットフォームとするBaaS|__△__  Windows Azureの１サービスとしての位置付けなので、MBaaSの機能のみを手軽に使いたい、という場合には向かない。膨大なドキュメントの中から狙いのコンテンツを探すのに、非常に手間がかかる。じっくり腰を据えて取り組むべき。|
|__ニフティクラウド mobile backend__|国産|__✕__  日本語化されていることやドキュメントが充実しているのはいいのだが、SDKの動作が不安定なのと、サーバ側管理画面の使いにくさが致命的。|
|__Parse__|Facebook傘下の製品|__◯__  安定したSDK、サーバ側管理画面の使いやすさ（とかっこよさ）、充分な機能など、非常に使いやすい。ただ、日本語化されていない点と、プラットフォームが不明なのがマイナス。|

[appiaries](http://www.appiaries.com/jp/)はSDKがない（REST APIのみ提供）ため、今回は比較対象から外した。しかし国産であり導入障壁が低い可能性があるため、今後に期待している。

## MBaaS利用上の注意点
[こちら](https://event.atmarkit.co.jp/events/402f6825665f828b6478395ce58d15fb/atmarkit_report)の記事を参照のこと。

## MBaaSが活用可能な局面
クラウド型のMBaaSは、一般利用者向けのアプリを素早く立ち上げる用途に最適。

企業向けシステムなど、クラウドNGな場合でもHeliosやAppPotなどのオンプレ製品を活用すれば、バックエンド開発工数の低減が見込める。

データストアがRDBでない場合が一般的なので、複雑なデータモデルやクエリが必要な場合は機能不足に陥る可能性がある。

## その他の考察

### モバイル以外での利用
BaaSの提供する機能（の一部）はモバイル以外のアプリでも利用価値がある。実際、多くのBaaS製品はREST APIやJavaScriptによるSDKを提供しており、モバイル以外での利用も念頭に置いているフシがある。

特にブラウザアプリを手軽に作るのに向いている可能性がある。

### Java製BaaSの可能性
現時点ではJava制BaaSは見当たらない。
オープンソースとして開発すると喜ぶ開発者が多いかもしれない。

開発中はローカルでJettyによるBaaSサーバを立ち上げておき、本番用には別途サーバを立てる、などJavaの開発ノウハウが活用出来るのはありがたい。
カレンダー整形問題をHaskellで、それも日本語で読めるように書いてみた


カレンダー整形問題Haskellの回答に、日本語による解説をコメントとしてではなく動作する関数として加えてみた。個人的に気に入っているのは「を」関数。
なお[gist](https://gist.github.com/jabaraster/5613069)に投稿済み。

```hs
module Main where
 
import Data.List.Split
import Data.Time.Calendar
import Data.Time.Calendar.WeekDate
import Data.Time.Clock
import Data.Time.Format
import Data.Time.LocalTime
import Data.Text (pack, unpack, center)
import System.Locale
 
主処理 = main
main = 現在日付を取得 >>= 指定日付を表示用に加工 >>= プリントアウト
 
現在日付を取得 = getZonedTime
プリントアウト = putStrLn
 
指定日付を表示用に加工 :: ZonedTime -> IO String
指定日付を表示用に加工 任意の日付 = do
  日付               <- 任意の日付 `を` 扱いやすい型に変換                           -- ZonedTime -> Day
  日付リスト         <- 日付 `を` 週毎の日付に分割して先頭週の開始曜日までは空文字を詰めたリストに変換 -- Day -> [[String]]
  日付行リスト       <- 日付リスト `を` 行毎の文字列に連結したリストに変換           -- [[String]] -> [String]
  ヘッダ             <- 日付 `を` カレンダのヘッダに変換                             -- [String] -> [String]
  ヘッダ付き行リスト <-  ヘッダ `を` (日付行リスト `と連結`)                         -- [String] -> [String] -> [String]
  ヘッダ付き行リスト `を` 改行を挟んで連結して返す                                   -- [String] -> String
 
を :: a -> (a -> b) -> IO b
を a f = return $ f a
 
と連結 xs ys = ys ++ xs
 
改行を挟んで連結して返す = unlines
 
行毎の文字列に連結したリストに変換 = toLinesFromTokens
toLinesFromTokens :: [[String]] -> [String]
toLinesFromTokens = map (\ss -> drop 1 $ concat $ map padTok ss)
         -- 上でdrop 1しているのは
         -- 3桁左寄せしてから連結しているため、
         -- 各行の先頭に空白文字が１つ入るのが気に入らないため
  where
    padTok s = case length s of
                 0 -> "   "
                 1 -> "  " ++ s
                 2 -> " "  ++ s
                 _ -> error "unexpected token -> " ++ s
 
weekdayCount = 7
lineCharCountMax = weekdayCount * 3 - 1
 
カレンダのヘッダに変換 = toHeader
toHeader :: Day -> [String]
toHeader day = let s   = formatTime defaultTimeLocale "%B %Y" day
                   fst = unpack $ center lineCharCountMax ' ' $ pack s in
               [fst, "Su Mo Tu We Th Fr Sa"]
 
週毎の日付に分割して先頭週の開始曜日までは空文字を詰めたリストに変換 = toLeftPaddedMonthDayList
toLeftPaddedMonthDayList :: Day -> [[String]]
toLeftPaddedMonthDayList day = chunksOf 7 core
  where
    core = let fstDate = toMonthFirstDate day in
           (toLeftPaddableListFromMonthFirstDate fstDate) ++ (map show $ toMonthDateList day)
 
扱いやすい型に変換 = toDayFromZonedTime
toDayFromZonedTime :: ZonedTime -> Day
toDayFromZonedTime = utctDay . zonedTimeToUTC
 
指定日付が所属する月の全ての日付のリスト = toMonthDateList
toMonthDateList :: Day -> [Int]
toMonthDateList day = let (y,m,_) = toGregorian day
                          c = gregorianMonthLength y m in
                      [1..c]
 
指定日付が所属する月の先頭の週の、開始曜日までを埋める空文字のリスト = toLeftPaddableListFromMonthFirstDate
toLeftPaddableListFromMonthFirstDate :: Day -> [String]
toLeftPaddableListFromMonthFirstDate day = take (toWeekdayIndex day) $ repeat ""
 
指定日付が所属する月の先頭日付 = toMonthFirstDate
toMonthFirstDate :: Day -> Day
toMonthFirstDate day = let (y,m,_) = toGregorian day in
                       fromGregorian y m 1
 
日曜日を0としたときの曜日のインデックス = toWeekdayIndex
toWeekdayIndex :: Day -> Int
toWeekdayIndex day = case toWeekDate day of
                      (_,_,7) -> 0
                      (_,_,d) -> d
```
jMockit Verifications 部分モッキングとか

前回に引き続きjMockitのお話で、今回はテスト対象クラス自身のメソッドを一部モック化するお話です。

### 部分的なモッキング (Partial Mocking)

http://jmockit.googlecode.com/svn/trunk/www/tutorial/BehaviorBasedTesting.html#dynamicPartial

```java:Hoge.java
public class Hoge {
    public String getFullName() {
        return getFirstName() + " " + getLastName();
    }

    public String getFirstName() {
         return this.fName;
    }

    public String getLastName() {
         return this.lName;
    }
 }
```

```java:HogeTest.java
    Hoge hoge = new Hoge();
    new Verifications(hoge) {{
        hoge.getFirstName(); result="ホゲ山";
        hoge.getLastName(); result="ほげ二郎";
    }}

    assertThat(hoge.getFullName(), is("ホゲ山 ほげ二郎"));
```

テスト対象のクラスのメソッド同士に依存関係があるときに、対象メソッド単体でテストすることが可能です。
例だとgetFirstName() ,getLastName() はごく単純ですが、これがとても複雑な場合にはモック化する価値があります。

### 部分的なモッキング (Partial Mocking)  private な場合

先の例ではgetFirstName() ,getLastName()がTestクラスからアクセス可能なスコープでしたが、privateな場合もありますよね。
テストの為だけにメソッドのスコープをデフォルトスコープにする手もありますが、本来的にprivateなのにそれを歪めるというのも嫌なものです。

jMockitの場合、privateメソッドの挙動もモック化できます。
http://jmockit.googlecode.com/svn/trunk/www/tutorial/BehaviorBasedTesting.html#deencapsulation

```java:Hoge.java
public class Hoge {
    public String getFullName() {
        return getFirstName() + " " + getLastName();
    }

    private String getFirstName() {
         return this.fName;
    }

    private String getLastName() {
         return this.lName;
    }
 }
```

```java:HogeTest.java
 import static mockit.Deencapsulation.*;

    Hoge hoge = new Hoge();
    new Verifications(hoge) {{
        invoke(hoge ,"getFirstName"); result="ホゲ山";
        invoke(hoge ,"getLastName"; result="ほげ二郎";
    }}

    assertThat(hoge.getFullName(), is("ホゲ山 ほげ二郎"));
```

この[Deencapsulation](http://jmockit.googlecode.com/svn/trunk/www/javadoc/mockit/Deencapsulation.html)というクラスのstaticメソッドが鍵です。

### privateメソッドに対するテストもかける

上記のDeencapsulationを使うとprivateメソッドに対するassertも書くことができます。

```java:HogeTest.java
 import static mockit.Deencapsulation.*;

    Hoge hoge = new Hoge();

    assertThat(invoke(hoge ,"getFirstName"), is("ホゲ山"));
    assertThat(invoke(hoge ,"getLastName"), is("ほげ二郎"));
```


ちなみにFirstName ,LastNameの設定間違えてますが疲れたのでまあいいや。
iPhotoライブラリのマージ

ちょっとハマったのでメモ

調べてすぐ出てくるのは
**iPhoto Library Manager** http://www.fatcatsoftware.com/iplm/
なんだけど、継続的に使う予定はなかったのでお値段と相談してなんとか自力でやってみた

マージ元の画像をFinderで選択してiPhotoにぶち込むのが基本戦略

# 準備
* マージ先のiPhotoの設定画面で **項目をiPhotoライブラリにコピー** にチェック

通常iPhotoは画像をコピーせず保存元へのリンクを覚えている模様で
はじめこれを知らなかったために別macのファイル共有を切ったあと大変なことになった
画像を見ようとしたら接続できませんエラーが出るのはもちろん
（サムネイルは表示されるのでぱっと見問題なさそうでよりやっかい）、
裏でiCloudアップロードが動いてて定期的にエラーが出てハゲる勢いだった

#画像の選択
* マージ元のiPhotoライブラリのコンテキストニューから **パッケージ内容を表示** を選択

内部のMastersフォルダ以下に元画像がある

#マージ先に取り込み
* Mastersをまるっとマージ先のiPhotoにドラッグ&ドロップ

同じ画像があると置き換えるかどうか聞いてくれるので親切
HARK をインストールする

# HARK とは何か
HARK とは、ロボット聴覚と呼ばれる、たくさんのマイク(マイクアレイ) を使って
* 音の方向を当てたり (音源定位)、
* 混ざった音から特定の方向の音を取り出したり (音源分離)、
* 音声を文字列に変換したり (音声認識)、
する技術を使えるソフトウェア。
URL はここ: www.hark.jp

HARK では1機能が1ノードとして表現され、LabVIEW みたいな感じでグラフィカルに
ロボット聴覚の処理 (ネットワークと呼ばれる) を実装できる。

# どうやってインストールするのか
ここでは Windows / Ubuntu (apt-get) という簡単な方法

## Windows 
ここからインストーラを落としてインストール
http://www.hark.jp/wiki.cgi?page=Softwares#p9

## Linux (Ubuntu)
* リポジトリと公開鍵登録して update

```shell-session
sudo sh -c 'echo "deb http://winnie.kuis.kyoto-u.ac.jp/HARK/harkrepos precise non-free\ndeb-src http://winnie.kuis.kyoto-u.ac.jp/HARK/harkrepos precise non-free" > /etc/apt/sources.list.d/hark.list'
```

```shell-session
wget -q -O - http://winnie.kuis.kyoto-u.ac.jp/HARK/harkrepos/public.gpg | sudo apt-key add -
```

```shell-session
sudo apt-get update
```

* apt-get

```shell-session
sudo apt-get install harkfd hark-designer julius-4.2.3-hark-plugin harktool4
```

### 説明
* harkfd: HARK の主要機能が入ったパッケージ
* hark-designer: プログラムを作成する GUI
* julius-4.2.3-hark-plugin: 音声認識ソフトウェア Julius の改造版
* harktool4: HARK で使うデータを作るソフトウェア

# どうやって実行するのか
* Windows: デスクトップにできる HARK Designer というアイコンをクリック
* Ubuntu: 端末で hark_designer を実行

HARK Designer はネットワークを作るソフトウェアで、ブラウザ上で動作する。
コンソールログが出力されない。

app.js内にTi.API.info('XXX');を埋め込んでもコンソールログが出力されない。

いくつかコンソールログが出力されない時の対処法として
・workspaceのbuildフォルダ削除
・プロジェクトのクリーン
を試しましたがいっこうに出力されません。

設定の問題でしょうか？
分かる方、お願いします！



デバッグはiOSシミュレータで動作確認を行っています。
PHP5.3.3 DatePeriodのバグ

[DatePeriod](http://php.net/manual/ja/class.dateperiod.php)は日付の間隔を表し、『1月1日から3月31日まで、1日2時間34分56秒ごと』のような自力で書くとめんどくさい繰り返しを簡単に取り扱うことができるようになります。

```php
<?php
	// 開始/終了日時
	$start  = new DateTime('2013-01-01 00:00:00', new DateTimeZone('Asia/Tokyo'));
	$finish = new DateTime('2013-01-01 00:00:03', new DateTimeZone('Asia/Tokyo'));
	
	// 任意の間隔に分割
	$dateInterval = new DateInterval('PT1S'); // 1秒
	$datePeriod = new DatePeriod($start, $dateInterval, $finish);
	
	// ループで間隔ごとに取り出せる
	foreach($datePeriod as $key=>$val){
		$val1 = clone $val;
		$val2 = clone $val;
		$val2->setTime(0, 1, 0); // $val2は0時1分0秒を指定する
		
		print( 'val1:' . $val1->format('Y-m-d H:i:s'));
		print( 'val2:' . $val2->format('Y-m-d H:i:s'));
	}
```

	val1:2013-01-01 00:00:00
	val2:2013-01-01 00:01:00
	val1:2013-01-01 00:00:01
	val2:2013-01-01 00:01:01 // bug
	val1:2013-01-01 00:00:02
	val2:2013-01-01 00:01:01 // bug

$val2には0時1分0秒を指定したはずなのですが、何故か1秒おまけされてしまっているところがあります。
DatePeriodから取得したDateTimeに対してsetTimeするとおかしな値になるぞ、というバグです。
例では秒だからまだ気付かれにくいですが、'P1D'にすると1日ずれるのでわりかし事故です。

なんか開発中に日付が一日ずれてしまう問題に突き当たり、どう見てもソースは合ってるんだが何故だろうと延々悩んでいたら実はPHPのバグだったとかいう。
いやっほうバグを見つけてやったぜいと思ってたら、当然[とうの昔に修正されている既知のバグ](https://bugs.php.net/bug.php?id=53340)でした。

[ノート](http://jp1.php.net/manual/ja/class.dateperiod.php)によると5.3.5では直っていたようです。
この後PHPをバージョンアップし、5.4.7では正しく計算されるようになっていたのを確認しました。
PHPではしれっとこういうことがあったりするのが怖いですね。

※2013/08/16に[自ブログ](http://yuubiseiharukana.blog.shinobi.jp/Entry/1222/)に掲載したもの。
TransactSql.ScriptDomを使ってTransact-SQLのコーディング規約をチェックする

##JOINをしているのにテーブル名を書いていない場所を見つける

テーブル名の宣言無しに列名が使われるとわかりづらいため、
「joinを行ったらテーブル名を書かなくてはならない」というコーディング規約が現場にある。
しかし、この規約違反を目でチェックするのが面倒なので自動化する。

つまり、

```sql:good.sql
SELECT
   book.title
FROM
   book
   INNER JOIN shelf ON boo.id_shelf = shelf.id
WHERE
   shelf.name = 'mine'
```

というのを、

```sql:bad.sql
SELECT
   title
FROM
   book
   INNER JOIN shelf ON boo.id_shelf = shelf.id
WHERE
   shelf.name = 'mine'
```

のように書いている場所を発見したい。(下のSELECT句にはbookが抜けている)

##道具の用意
静的にTransact-SQLを解析するのは自分の力ではできそうになかったので、ライブラリを使用した。
使用したのは、Microsoftが提供しているTransact-SQLのパーサー兼ジェネレータ
[TransactSql.ScriptDom](http://msdn.microsoft.com/ja-jp/library/hh215705.aspx)

使い方は[T-SQL の パーサーとジェネレーター(ScriptDom)の紹介](http://d.hatena.ne.jp/odashinsuke/20130224/1361714459)が参考になる。

これはVisitorを使用していて、動きに合わせて全ての部分に行けるのでパース結果から静的な解析が楽にできる。
が、ドキュメントが皆無なので、どんな時に何のメソッドが呼ばれるのかは実験する必要がある。

##解析する
目的は「joinを行ったのにテーブル名を書いていない場所を見つける」こと

テーブルの列名が宣言されるべき場所はSELECT, WHERE, ORDERなど色々あるが、パースした結果では共通してExplicitVisit(ColumnReferenceExpression)が呼ばれている。
そのため、

+ SELECT,INSERT,UPDATE,DELETE文内でExplicitVisit(..)が呼ばれている
+ 宣言されている列名にテーブル名がついていない
+ JOINが呼ばれている

以上を満たせば「joinがあるのにテーブル名が宣言されていない」ということがわかる。

これを利用して、T-SQL文字列から規約違反を発見することが出来る。
実際に使用しているプログラムは[Github](https://github.com/mrasu/RuleChecker)においている。
SQLChecker内が実際にT-SQLをチェックしている部分
メッセージが空のコミットに適当なメッセージを一括で入れる


`git filter-branch --msg-filter` を使う。もちろん歴史改変である。

```console
$ git filter-branch --msg-filter '
>   cat > msg
>   if [ "$(wc -w < msg)" -eq 0 ]; then
>     echo "no msg"
>   fi
>   cat msg
> ' -f
```
infoユーザー宛のメールが受信できない

postfixなどで、infoユーザーを作成すると、infoユーザーのメールボックスでメールが受信できない。
aliasesファイルを確認すると、infoはpostmasterへ転送され、postmasterはrootに転送しているのがわかる。

```
$ vim /etc/aliases
```
```
#
#  Aliases in this file will NOT be expanded in the header from
#  Mail, but WILL be visible over networks or from /bin/mail.
#
#       >>>>>>>>>>      The program "newaliases" must be run after
#       >> NOTE >>      this file is updated for any changes to
#       >>>>>>>>>>      show through to sendmail.
#

# Basic system aliases -- these MUST be present.
mailer-daemon:  postmaster
postmaster:    root

# General redirections for pseudo accounts.
bin:            root
daemon:        root
adm:            root
lp:            root
sync:          root
shutdown:      root
halt:          root
mail:          root
news:          root
uucp:          root
operator:      root
games:          root
gopher:        root
ftp:            root
nobody:        root
radiusd:        root
nut:            root
dbus:          root
vcsa:          root
canna:          root
wnn:            root
rpm:            root
nscd:          root
pcap:          root
apache:        root
webalizer:      root
dovecot:        root
fax:            root
quagga:        root
radvd:          root
pvm:            root
amanda:        root
privoxy:        root
ident:          root
named:          root
xfs:            root
gdm:            root
mailnull:      root
postgres:      root
sshd:          root
smmsp:          root
postfix:        root
netdump:        root
ldap:          root
squid:          root
ntp:            root
mysql:          root
desktop:        root
rpcuser:        root
rpc:            root
nfsnobody:      root

ingres:        root
system:        root
toor:          root
manager:        root
dumper:        root
abuse:          root

newsadm:        news
newsadmin:      news
usenet:        news
ftpadm:        ftp
ftpadmin:      ftp
ftp-adm:        ftp
ftp-admin:      ftp
www:            webmaster
webmaster:      root
noc:            root
security:      root
hostmaster:    root
info:          postmaster
marketing:      postmaster
sales:          postmaster
support:        postmaster

# trap decode to catch security attacks
decode:        root

# Person who should get root's mail
#root:          marc
```

これは、infoからの転送をコメントアウトすれば解決する。

```
# info:          postmaster
```
if 条件とクラスタ名を同じにしたいとき #rstatsj

例えば、ユーザIDとユーザの特性値 X のデータがあったとします。

```r:データ作成
id <- 1:10
x <- runif(length(id))
data <- data.frame(UserID=id, X=x)
print(data)
```

```:結果
   UserID         X
1       1 0.9502438
2       2 0.3470344
3       3 0.4456312
4       4 0.1642439
5       5 0.3765186
6       6 0.4722742
7       7 0.3034376
8       8 0.7143706
9       9 0.5404237
10     10 0.5648573
```

このユーザの特性値 X を使って、ユーザを下記の3つのクラスタに分けたいとします。

+ 0.4未満
+ 0.4 ~ 0.6
+ 0.6以上

そのとき、if 条件式とクラスタ名を同じにしたい時があります。
しかし、次のように書くと、なんだか同じことを何度も書いているような気がして冗長な感じがします。

```r:改善前
result <- transform(data, 
                    Cluster=ifelse(x < 0.4, "x < 0.4", 
                            ifelse(0.4 <= x & x < 0.6, "0.4 <= x & x < 0.6",
                                                       "0.6 <= x")))
```

そんなときは、次のように書いてはいかがでしょうか。

```r:改善後
exp1 <- expression(x < 0.4)
exp2 <- expression(0.4 <= x & x < 0.6)
exp3 <- expression(0.6 <= x)
result <- transform(data, 
                    Cluster=ifelse(eval(exp1), as.character(exp1), 
                            ifelse(eval(exp2), as.character(exp2),
                                               as.character(exp3))))
print(result)
```

expression を別にすることで、すっきりしたような気がします。
お試しあれ。

```:結果
   UserID         X            Cluster
1       1 0.9502438           0.6 <= x
2       2 0.3470344            x < 0.4
3       3 0.4456312 0.4 <= x & x < 0.6
4       4 0.1642439            x < 0.4
5       5 0.3765186            x < 0.4
6       6 0.4722742 0.4 <= x & x < 0.6
7       7 0.3034376            x < 0.4
8       8 0.7143706           0.6 <= x
9       9 0.5404237 0.4 <= x & x < 0.6
10     10 0.5648573 0.4 <= x & x < 0.6
```
FlashのCreateJS出力をTypescriptから利用

## 目的
[Flash Professional Toolkit for CreateJSのファーストステップガイド](http://www.adobe.com/jp/devnet/createjs/articles/getting-started.html) で紹介されているようなやり方、つまり、Flashでデザインやアニメーションを作成し、それを利用しながらJavascriptで機能を作っていく場合に、Javascriptの替りにTypeScriptを利用したい。

しかし、Flash Pro CCはもちろんTypeScript用の*.d.tsファイルを出力してくれないし、手で書くのは辛くて無理なのでどうにかしたい。

## 利用するもの
[CreateJS Toolkit definitions generator](https://github.com/elsassph/createjs-def)が*.d.tsファイルを出力してくれるのでこれを利用する。

以上、終了、なわけですが、一部生成されたファイルに手を入れないといけないので、それのメモ。だいぶ抜けてるかも。

## 手順
基本的には[Flash Professional Toolkit for CreateJSのファーストステップガイド](http://www.adobe.com/jp/devnet/createjs/articles/getting-started.html) の通りに進める。

異なるのは、GameDev.jsがGameDev.tsになり、それに伴ってPlatypusGame.d.tsが必要になる点。

一応、現在時点で全て最新版を利用、TypeScriptとしてエラー、警告が出なくなるまでの対応手順が以下ですが、今後、createjs, Flash Pro, Typescriptのバージョンが上がるに従って、ぜんぜん違う対処が必要になる、もしくは対処が要らなくなる可能性が高そうです。

ちなみに、createjsの*.d.tsは[Definitely Typed](https://github.com/borisyankov/DefinitelyTyped)を利用させてもらってます。

### 1. *.d.tsを生成
[CreateJS Toolkit definitions generator](https://github.com/elsassph/createjs-def)を利用して、PlatypusGame.d.tsファイルを生成。

一部書き換えが必要になる。

1. ファイル冒頭、easeljs.d.tsの参照パス指定を実際のパスに変更
1. module libで定義が始まってるが、declare module libに変更
1. 各クラスのnominalBoundsがstaticで定義されてるが、クラス名.nominalBoundsではエラーになる(そのままjsに変換されてしまう、prototype経由なら大丈夫だがそうならない)のでsaticを全て取り除く

### 2. GameDev.jsをGameDev.tsに変更

拡張子変更だけだと警告が出まくるので(当たり前ですが)、とりあえずそれを取り除く。

1. 必要なreferenceを追加
1. platypus.falling等、定義されてないプロパティへの代入はTypeScript的には警告対象なのでplatypus['falling'] = false等へ変更。
1. onClick等一部書き方が古いのでaddEventListner等に置き換え
1. handleFileLoad等のイベントハンドラが(eventObj: Object) => booleanでなければならないのに、(evt: any) => voidなのでメソッド末尾にreturn true;とかを追加
1. IntelliJ IDEAの問題(自分はPhpStormを利用)だろうと思いますが、createjs.Container.addChild等で、型としては継承関係上問題ないはずなのに警告が出るので、addChild(\<createjs.DisplayObject\>obj)等、明示的にアップキャストする

くらいで動いた。
SublimeTextをKeyRemap4Macbookのemacs-modeから除外する方法

### 背景
便利だ便利だときかされていたテキストエディタ「SublimeText」に手を出してみた．普段はemacs使いなのでsublemacsproパッケージを導入．しかし一部のemacsコマンドがうまく動かない・・・？
原因はKeyRemap4Macbookとの競合．KeyRemap4MacbookはGUIのemacsとかはデフォルトで競合しないように設定されているらしいがSublimeTextは自分で適用外に指定しないといけないらしい．以下，その方法．
### 手順
KeyRemap4macbookの環境設定 → Misc & Uninstall → Open private.xmlに以下のように記述

```private.xml
<?xml version="1.0"?>
<root>
	<appdef>
	<appname>SUBLIME</appname>
		<equal>com.sublimetext.2</equal>
 		<equal>com.sublimetext.3</equal>
	</appdef>
	<replacementdef>
	<replacementname>
		EMACS_MODE_IGNORE_APPS
	</replacementname>
	<replacementvalue>
		SUBLIME
	</replacementvalue>
	</replacementdef>
</root>
```

Cange Key → Reload XMLで完了
Warningを無視する#pragma

> 随時追加

#ios6とかでdepricated
```objc
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        BOOL available = [TWTweetComposeViewController canSendTweet];
#pragma clang diagnostic pop
```

#Category is implementing a method which will also be implemented by its primary class
カテゴリの実装でメソッドをオーバーライドするなという警告

```objc
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
- (void)addRoundedRectToPath:(CGRect)rect 
                     context:(CGContextRef)context 
                   ovalWidth:(CGFloat)ovalWidth 
                  ovalHeight:(CGFloat)ovalHeight 
{
    .....
}
#pragma clang diagnostic pop
```

#PerformSelector may cause a leak because its selector is unknown
ARC環境下でのワーニング。-performSelector:からの返り値をコントロールできなくて出る。

```objc
    SEL sel = @selector(doSomething);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
    [obj performSelector:sel];
#pragma clang diagnostic pop
```

#Unused parameter '****'
パラメータを使えーって言っていますので変数名の頭に__attribute__((unused))を追加。

```objc
    [hoge performRequestWithHandler:^(NSData *responseData, __attribute__((unused)) NSHTTPURLResponse *urlResponse, NSError *error) {
        completion(responseData, error);
    }];
```



###参考

* [Objective-C警告タイプのまとめ
](http://blog.natsuapps.com/2013/05/warning-types.html "Objective-C警告タイプのまとめ
")
* [clang document](http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas "clang document")
* [Compiler Warnings for Objective-C Developers](http://oleb.net/blog/2013/04/compiler-warnings-for-objective-c-developers/ "Compiler Warnings for Objective-C Developers")
* [アナライズを無視する](http://cocoaapi.hatenablog.com/entry/20120728/p1 "アナライズを無視する")
rbenv でインストールした ruby で no such file to load -- openssl と出た場合 (CentOS)


openssl-devel をインストールした後、uninstall の後、rbenv install する

```
sudo yum install openssl-devel
rbenv uninstall 1.8.7-p374
rbenv install 1.8.7.p374
```

参考：[ruby on rails 3 - No such file to load --openssl - Stack Overflow](http://stackoverflow.com/questions/4058364/no-such-file-to-load-openssl)
jQueryでチェックボックスのチェックを取得

`$('#elem').attr("checked")`
か

`$('#elem':checked).val()`
あるいは

`$('#elem').is(':checked');`

[参考1](http://webhako.net/jquery/checkbox-get-value/ "jQueryでチェックボックスがチェックされているかを調べる")
[参考2](http://webtech-walker.com/archive/2010/04/06155654.html "jQueryでcheckboxがcheckされてるかの値をとる - Webtech Walker")
リモートにsshでログインしてユーザーを切り替える

## リモート（foo）にsshでログイン
```bash
$ ssh foo
```
## ユーザーを（bar）切り替える（-オプションで環境変数を破棄してカレントディレクトリに移動）
```bash
$ su - bar
```
http://kazmax.zpp.jp/linux_beginner/su.html#ah_4

## 2回ログアウト
```bash
$ exit
$ exit
```
ウィンドウサイズの取得

## ウィンドウサイズのプロパティ
ウィンドウサイズは

```js
w = window.innerWidth;
h = window.innerHeight;
```

で取れるが、IEでは取れない。

IEの場合

```js
w = document.documentElement.clientWidth; // （クライアント領域の横幅）
h = document.documentElement.clientHeight; // （クライアント領域の高さ）
```

参考: [クライアント領域サイズを得る(ダイナミックHTMLとDOM)](http://www.marguerite.jp/Nihongo/WWW/DHTML/WindowSize.html)

## 2つの変数の片方を拾う

```js
var x = 5;
var y;
alert(x || y);
```

この結果は `5` になるが、 `x=0` だったら `undefined` になってしまう。
`x` がfalsyだから次に `y` を評価して `undefined` が返ってくる。
falsyな値を最終的に `0` にするなら

```js
alert(x || y || 0);
```
とすればよさげ。

## ウィンドウサイズと座標の取得
これらを踏まえて、最終的に以下の形で落ち着いた。

```js
var windowLeft = (window.screenLeft || window.screenX || 0);
var windowTop = (window.screenTop || window.screenY || 0);
var windowWidth = (window.innerWidth || document.documentElement.clientWidth || 0);
var windowHeight = (window.innerHeight || document.documentElement.clientHeight || 0);
```
実は厳格モードに入っていなかった時のハマりどころ

厳格モードで書こうとして
`"use strict"`を`"user strict"`
と間違えて書いてしまったとき。
`"use strict"`はただの文字列評価なので、間違えていても気づかないので注意。

それであとで厳格モードで書き直したときにエラーが出るところ（他にもいっぱいありそう）

## 複数の変数宣言ミス

```js
var x = "hoge";
    y = "piyo";
```

この場合yがグローバルになってしまう。
→カンマでつなげる

```js
var x = "hoge",
    y = "piyo";
```

##変数宣言と代入を一緒にしようとする

```js
var x = y = false;
```

この場合yがグローバルになってしまう。
→宣言してから代入

```js
var x, y;
x = y = false;
```
HTML5のタグ語源

[こちらより転載](http://webcre8.jp/investigate/html5-tag-etymology.html "[HTML5 入門]HTML5の略された49タグの語源全てを調べた")

| タグ名 | 基となった英単語 |
|:-----------|:-----------|
| nav | navigation links |
| h* | heading * |
| hgroup | heading group |
| p | paragraph |
| hr | horizontal rule |
| pre | preformated text |
| ol | ordered list |
| ul | unordered list |
| li | list item |
| dl | description list |
| dt | description term |
| dd | description description |
| figcaption | figure caption |
| div | division |
| a | anchor |
| em | emphasis |
| s | strike |
| q | quotation |
| dfn | definition |
| abbr | abbreviation |
| var | variable |
| samp | sample |
| kbd | keyboard |
| sub | subscript |
| sup | superscript |
| i | italic |
| b | bold |
| u | underline |
| rt | ruby text |
| rp | ruby parentheses |
| bdi | bi-directional isoration |
| bdo | bi-directional override |
| br | break |
| wbr | word break |
| ins | insert |
| del | delete |
| img | image |
| iframe | inline frame |
| param | parameter |
| colgroup | column group |
| col | column |
| tbody | table body |
| thead | table header |
| tfoot | table footer |
| tr | table row |
| td | table data cell |
| th | table header cell |
| optgroup | option group |
| keygen | key-pair generator |
Vim で 現在開いているファイルを簡単に実行して、結果を表示させる

現在開いているファイルをスペースキーを押すことによって実行します。(PHP, Ruby, Go のみ)

![vim-execute-c-urrent-file.gif](https://qiita-image-store.s3.amazonaws.com/0/11524/d78981d9-d2e5-dca9-2d7e-f704d8f27e97.gif)


```vim:.vimrc
" 現在開いているファイルを実行 (only php|ruby|go)
function! ExecuteCurrentFile()
  if &filetype == 'php' || &filetype == 'ruby'
    exe '!' . &filetype . ' %'
  endif
  if &filetype == 'go'
    exe '!go run *.go'
  endif
endfunction
nnoremap <Space> :call ExecuteCurrentFile()<CR>
```
MySQL 5.5.x 系インストールメモ


MySQL 公式ページから該当バージョンの rpm bndle (tar アーカイブ形式) をダウンロード

rpm で MySQL-server, client, shared, devel  をインストールする

```
$ sudo yum install MySQL-server-5.5.25a-1.linux2.6.x86_64.rpm
$ sudo yum install MySQL-client-5.5.25a-1.linux2.6.x86_64.rpm
$ sudo yum install MySQL-shared-5.5.25a-1.linux2.6.x86_64.rpm
$ sudo yum install MySQL-devel-5.5.25a-1.linux2.6.x86_64.rpm
```

場合によって、server のインストール時に以下のようなエラーが発生する場合がある (CentOS)

```
Transaction Check Error:
  file /usr/share/mysql/charsets/README from install of MySQL-server-5.5.34-1.linux2.6.x86_64 conflicts with file from package mysql-libs-5.1.69-1.el6_4.x86_64
  file /usr/share/mysql/charsets/Index.xml from install of MySQL-server-5.5.34-1.linux2.6.x86_64 conflicts with file from package mysql-libs-5.1.69-1.el6_4.x86_64
```

そのような場合は、shared-compat パッケージをインストールすると conflict したライブラリを互換性のあるものに置き換えてくれるので、その後、server をインストールすることができる。




デーモン起動

```
sudo /usr/bin/mysqld_safe --user=mysql &
```


server インストール時の表示されるメッセージに従い

```
/usr/bin/mysql_secure_installation
```

を実行、質問に答えるが基本でフォルト選択


上記の操作後、root のパスワードを変更するには、mysql クライアントを起動し

```
SET PASSWORD FOR root@localhost=PASSWORD('hoge');
```

参考：[MySQLのrootパスワード設定 － Gentoo Linuxで自宅サーバ](http://gentoo.reichsarchiv.jp/item/27)
画面サイズの取得

[こちらより転載](http://kaelab.ranadesign.com/blog/2010/10/javascript-5.html "JavaScriptで画面サイズを取得する | かえラボBlog")

`screen.width` 画面幅
`screen.height` 画面高
`screen.availWidth` 有効画面幅
`screen.availHeight` 有効画面高
`window.innerWidth` 表示領域幅（IE非対応）
`window.innerHeight` 表示領域高（IE非対応）
`window.outerWidth` ウィンドウ幅（IE非対応）
`window.outerHeight` ウィンドウ高（IE非対応）
`$(window).width()` 表示領域幅
`$(window).height()` 表示領域高
`document.documentElement.clientWidth` 表示領域幅
`document.documentElement.clientHeight` 表示領域高
`document.width` 表示領域幅（IE非対応）
`document.height` 表示領域高（IE非対応）
`$(document).width()` ドキュメント幅
`$(document).height()` ドキュメント高
Subversion メール送信 (Bash)

#### Google先生へのお問い合わせの結果
ちょっとSubversionサーバー作るときいつも忘れる。
メールを送信したいんだけどテンプレートがcommit-mail.pl から commit-mail.rb になっていて時代を感じた…

Googleさんに問い合わせたりした結果(5分位)

あれ?基本ruby?でみんなやってる?
はぁー なるほどね…

うん！よし、CentOSだしBashしよう！

との結論に。

とりあえず備忘録がてら初投稿(ドキドキ)

##### 要件
+ メールが飛んできさえすればいい
+ とりあえず誰が更新したか知りたい
+ 更新日も欲しいな
+ コメントは欲しい
+ 何が変更されたんでしょ
+ 詳細なdiffはredmineで見るからいらないわ

とりあえずこんな最小要件で…

****
bash で post-commit

```bash 
#!/usr/bin/env bash

#これが無いとそのまま叩かせてもエンコードをわかってくれない。
export LC_CTYPE=ja_JP.UTF-8 

#値の受け取り
REPOS="$1"
REV="$2"

#アドレス記載
TOADDR="送信したいアドレス" # ,(カンマ)で区切ると複数送信
FROMADDR="送信元アドレス"

#色々情報取ってきます。
SVNAUTHOR=`svnlook author -r $REV $REPOS`
SVNDATE=`svnlook date -r $REV $REPOS`
SVNLOG=`svnlook log -r $REV $REPOS`
SVNCHANGE=`svnlook changed -r $REV $REPOS`

#別にヒアドキュメントでもいいんだけど今回はechoで
/bin/echo " ##### NOW COMMITTED SUBVERSION ####
Commit Author  : $SVNAUTHOR
Commit Date    : $SVNDATE
Newer Revision : $REV
Log:
---->>>>>>
$SVNLOG

Changed:
[U:UPDATE A:APPEND D:DELETE]
---->>>>>>
$SVNCHANGE

" | /usr/bin/nkf -w | /bin/mail -s "SVN [ stuff : $REV ] committed" -r $FROMADDR $TOADDR

```

汚いコードだ…w
CoreDataでデフォルトデータを読みこませる　WALのとき（iOS7）

CoreDataにデフォルトのSQLiteのデータを読みこませる方法。
以前（ジャーナルモード）では下記のやり方でオッケーだったのですが、
(ジャーナルモードでのやり方) http://rakuishi.com/iossdk/2831/
iOS7以降？はデフォルトがWALになったので、少し変更が必要となりました。


結論を書いてしまうと単純なのですが、
以前は

* Hoge.sqlite

のみをコピーすればよかったのが、
WALモードでは

* Hoge.sqlite
* Hoge.sqlite-wal
* Hoge.sqlite-shm

の3つともコピーする必要があります。


というわけで、先ほどご紹介した http://rakuishi.com/iossdk/2831/ に書かれているコードを変更すると以下のようになります。
(わかりやすくするため、冗長に書いています。)

```objc
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }
        
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"Hoge.sqlite"];
    NSString *writableDBPath_wal = [documentsDirectory stringByAppendingPathComponent:@"Hoge.sqlite-wal"]; //ここ追加
    NSString *writableDBPath_shm = [documentsDirectory stringByAppendingPathComponent:@"Hoge.sqlite-shm"]; //ここ追加
    
    NSString *storePath = [[NSBundle mainBundle] pathForResource:@"Hoge" ofType:@"sqlite"];
    
    
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Hoge.sqlite"]; 
    
    NSLog(@"store URL %@", storeURL);
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:writableDBPath]) {
        NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"Hoge" ofType:@"sqlite"];
        NSString *defaultStorePath_wal = [[NSBundle mainBundle] pathForResource:@"Hoge" ofType:@"sqlite-wal"]; //ここ追加
        NSString *defaultStorePath_shm = [[NSBundle mainBundle] pathForResource:@"Hoge" ofType:@"sqlite-shm"]; //ここ追加
                
        if (defaultStorePath) {
            [fileManager copyItemAtPath:defaultStorePath toPath:writableDBPath error:NULL];
            [fileManager copyItemAtPath:defaultStorePath_wal toPath:writableDBPath_wal error:NULL]; //ここ追加
            [fileManager copyItemAtPath:defaultStorePath_shm toPath:writableDBPath_shm error:NULL]; //ここ追加
            NSLog(@"storePath= %@", storePath);
        }
    }    
    
    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    
    
    return __persistentStoreCoordinator;
}
```
プロキシ環境下でのHomebrewとMavenのインストール方法


#経緯

学生「MavericksにしたらMaven消えました…」

#Howto

## Proxy環境下なら、bashにProxy設定

```bash
$ export http_proxy=http://example.com:8080/
$ export https_proxy=$http_proxy
$ export all_proxy=$http_proxy
```
example.com:8080 などはもちろん、各自のLAN環境に合わせて。
念の為、echoコマンドで設定値を確認しておくと良い。
昔はall_proxyいらなかった気もするんだけどな。

## Homebrew が入ってなければインストール

```bash
$ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
  # Xcode Command Line Tools が求められたらインストール
  # xcode-select --install
$ brew -v
  # バージョン番号が表示されればOK
```

## Mavenのインストール

```bash
$ brew install maven
$ mvn -v
  # バージョン番号が表示されればOK
```

## MavenにProxy設定

JAVA_OPTSか、settings.xmlのどちらか一方で設定する。
BYOD環境でいちいち面倒な場合は環境変数がおすすめかも？

### 環境変数JAVA_OPTSで設定する方法
```bash
$ vim ~/.bash_profile
```

```bash
export JAVA_OPTS="-Djava.net.useSystemProxies=true"
```


### settings.xmlで設定する方法

```bash
$ vim ~/.m2/settings.xml
```

```xml:settings.xml
<settings>
  <proxies>
    <proxy>
      <active>true</active>
      <id>myHttpProxy</id>
      <protocol>http</protocol>
      <host>example.com</host>
      <port>8080</port>
    </proxy>
    <proxy>
      <active>true</active>
      <id>myHttpsProxy</id>
      <protocol>https</protocol>
      <host>example.com</host>
      <port>8080</port>
    </proxy>
  </proxies>
</settings>
```


## 参考
- [Homebrew](http://brew.sh/)
- [Maven Settings](http://maven.apache.org/ref/3.1.1/maven-settings/settings.html)
RedmineからチケットをPDFで一括ダウンロード (API & sh)


管理者をしていると、いろいろリクエストがあるので、簡単に実行できるものを用意しました…。

```
#!/bin/sh

USAGE="usage: $0 [REDMINE_URL] [PROJECT_ID] [API_KEY]"

if [ $# -lt 3 ]; then
echo >&2 $USAGE
  exit 1
fi

REDMINE_URL=$1
PROJECT_ID=$2
API_KEY=$3

echo wget --content-disposition $REDMINE_URL/projects/$PROJECT_ID/issues.csv?key=$API_KEY&status_id=*
wget -nv --content-disposition $REDMINE_URL/projects/$PROJECT_ID/issues.csv?key=$API_KEY&status_id=*

# CSVが取得できるまで待ちましょう
wait

IFS=","
while read f1 f2
do
     if [ "$f1" != "#" ]; then
     echo "IssueID: $f1"
     wget -nv --content-disposition $REDMINE_URL/issues/${f1}.pdf?key=$API_KEY --output-document=${f1}.pdf
     fi
done < issues.csv

```
### ポイント
- 基本はshell + 標準のwgetを使っていますので、特に準備は無いと思われます。
- status_id=* のパラメータをくっつけると、ステータス関係無しで全チケットをCSVに出します。
- CSV出力ルールでは、1列目がチケットIDなので、後はひたすら1列目のIDを指定してwgetでPDFを落とします…。

エラー処理とか完全ではないですが、ひとまず動きますので、執事にやってもらうでも何でもご利用いただけると嬉しいです。
メモ: Underscore vs Lo-Dash

メモ。

* Underscore.js [http://underscorejs.org/](http://underscorejs.org/)
* Lo-Dash [http://lodash.com/](http://lodash.com/)
* Lo-Dashの方が高速。
    * [Lo-Dash v2.2.1 vs Underscore v1.5.2 · jsPerf](http://jsperf.com/lo-dash-v1-1-1-vs-underscore-v1-4-4/6)
    * [native vs. array.js vs. underscore vs lo-dash · jsPerf](http://jsperf.com/native-vs-array-js-vs-underscore/8)
* Underscoreの方がファイルサイズは小さい。
    * 別表参照
    * 3.5KB程度は誤差の範囲と言って良さそう（Underscore互換版の場合）
* Lo-Dashの方が機能数が多い
    * 互換版は削ってる
    * 必要な機能だけ別途コピペで追加しても良いんじゃないかな
* Lo-DashのUnderscore互換版を使うのが良さそうか
* プロジェクトで未使用の機能をがんがん削ったらもっと軽くなりそう
    * そういう仕組みもあるみたい（手元の環境で動かなかった、今度改めてやる）

ファイル|サイズ (Bytes) (*)|差
---|--:|--:
underscore-min.js (1.5.2)|14,358|+0
lodash.underscore.min.js (2.2.1)|17,867|+3,499
lodash.min.js (2.2.1)|26,896|+12,538

(*) … ファイル本体のサイズ。転送時はgzipでより小さくなる