OmniAICreator/Qiita-1.07M huggingface dataset:
Vagrant共有ディレクトリをnfsモードで起動する


# Goal

```
* MaxOSX(Host)/VirtualBox(VM)/CentOS(Guest) Vagrant環境でRails開発している
* rails serverコマンドでwebrick起動するのが異様に遅く、1分以上かかる
* 起動の高速化の方法として、Host-Guestのディレクトリ共有をnfsモードにすると速いという情報を発見
* (Host)MacOSX側をnfs server,(Guest)CentOSをnfs clientと見立てて、nfsマウントする
```

# Problem

```
* synced_folderをnfsモードにするだけだと以下のエラーが出てマウントに失敗
```

```
[default] Mounting NFS shared folders...


The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

mount -o 'vers=3,udp' 192.168.33.1:'/Users/metheglin/Documents/workspace-vagrant/rvprov-orion' /vagrant

Stdout from the command:



Stderr from the command:

mount.nfs: access denied by server while mounting 192.168.33.1:/Users/metheglin/Documents/workspace-vagrant/rvprov-orion

```

# Fix

#### nfsdの起動を確認

```bash:(Host)MacOSX
sudo nfsd status
  # runningになってることを確認
  # nfsd service is enabled
  # nfsd is running (pid 79090, 8 threads)

  # 起動させる場合
  # sudo nfsd enable
```

#### /etc/exportsをtouchする

```bash:(Host)MacOSX
sudo touch /etc/exports
```

#### synced_folder設定を追加する

```rb:Vagrantfile
config.vm.synced_folder ".", "/vagrant", type: 'nfs'
  # Vagrantfile配置ディレクトリをGuestの/vagrantでnfsマウントする
  # 一応、Vagrantfile配置ディレクトリがotherユーザのr,x権限がついていることを確認したほうがよい
  # 自分の環境では/User/metheglin/Documentsがrwx------になってた
```

#### /etc/hostsにlocalhost IPアドレスを追加する

```bash:(Host)MacOSX,/etc/hosts
192.168.33.1	localhost
  # エラーメッセージを見て、192.168.33.1でnfs serverに接続しようとしているので、このIPを追加
```

:exclamation:

```
/etc/hostsの編集は、うまくいったりいかなかったりする。
記事一番下のPSの手順をやるのが一番確実かも。
```

#### vagrant再起動

```bash
vagrant reload
```

# Result

```
rais serverでの起動がめちゃくちゃ速くなった
特にvagrant upしてから２回目以降の起動
```

# Reference

* https://github.com/mitchellh/vagrant/issues/1744
* http://qiita.com/EaleLove777/items/b7a7d1a671106cd1a78a
* https://docs.vagrantup.com/v2/synced-folders/nfs.html

# PS

その後、再起動など繰り返すとnfsマウントに失敗することが何度か発生

## 試してみること

* Host側で/etc/exportsの定義を変更してみる

```bash:/etc/exports
## vagrant upすると、VAGRANT-BEGIN, VAGRANT-ENDのコメントが自動的に書き込まれるが、そのコメントの外に記載
"/Users/metheglin/Documents/workspace-vagrant/rvprov-orion" 192.168.33.11 -alldirs -mapall=metheglin:metheglin

# =====================
# PATH HOSTNAME OPTIONS
# =====================
# PATH: 共有したいnfsサーバ(Host)のディレクトリのパス
#       ダブルクォーテーションでくくったほうが無難
# HOSTNAME: マウントを許可するホスト名またはIPアドレス（Vagrantfileで指定したGuest起動時のprivate IPアドレス）
#           ホスト名を使いたい場合は、/etc/hostsに記載しておく
# OPTIONS:
#  -alldirs: サブディレクトリをマウントポイントとすることができる
#  -mapall: nfsクライアント(Guest)からのアクセスがnfsサーバ(Host)ではここで指定したuser:groupになる
```

* Host側でcheckexports / sudo nfsd checkexports
* Host側でnfs再起動 / sudo nfsd restart

■参考
* http://www.freebsd.org/cgi/man.cgi?query=exports&sektion=5
* http://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/network-nfs.html
Debian wheezy で CapsLock を Ctrl にする


以下を追加する。

```:/etc/default/keyboard
XKBOPTIONS=",ctrl:nocaps"
```

ファイルの詳細は
```
% man keyboard
```
で確認可能。


# 参考

http://gaobin.hatenablog.com/entry/2013/05/18/232617
[objc][memo]  UINavigationBar のタイトルに画像を表示する。

 UINavigationBar のタイトルに画像を表示する。

ViewDidLoadとかの中に、

```objc

UIImage *titleImage = [UIImage imageNamed:@"HeaderLogo.png"];
UIImageView *titleImageView = [[UIImageView alloc] initWithImage:titleImage];
titleImageView.frame = CGRectMake(0, 0, titleImage.size.width * 0.5, titleImage.size.height * 0.5);//適当にサイズ調整

UIView *titleView = [[UIView alloc]initWithFrame:CGRectMake(-titleImage.size.width*0.5, 0, titleImageView.frame.size.width , titleImageView.frame.size.height)];
[titleView addSubview:titleImageView];
self.navigationItem.titleView = titleView;

```
sensuのsandbox環境をさくっと立ててみる


virtualbox でお試しできるsandbox環境を公開してくれているので
さくっと触ってみる

# 目的

* sensuのsandbox環境の起動
* 管理画面が表示される確認

# 参考URL

* introduction to Sensu - Sean Porter
	* http://vimeo.com/76414799
		* PagerDutyと連携して電話がかかってきて読み上げされるテストあり
		* わかりやすい
* introduction to Sensuの資料
	* http://slides.sensuapp.org/
		* 動画とセットで見ないとわかりにくかも
* sandbox - virtualbox
	* http://repos.sensuapp.org/ova/sandbox.ova

# 手順
## VirtualBoxインストール

割愛

## ダウンロード

http://repos.sensuapp.org/ova/sandbox.ova

をダウンロード

## VirtualBoxに認識させる

sandbox.ova
をダブルクリックしてvirtual boxに認識させる

## 起動

virtual boxから、先ほど認識させたsandbox環境を起動する

![sensu-0001..png](https://qiita-image-store.s3.amazonaws.com/0/17518/f57a5ba8-c921-da05-f3c6-a479086f9631.png "sensu-0001..png")


2222 portからvagrantユーザでログインできる

`ssh vagrant@localhost -p 2222`

User：vagrant
Pass：vagrant

## sensu 管理画面ログイン

http://localhost:8080/

id/passは/etc/sensu/config.json の"dashboard"を確認

最初から１件warningが表示されるようになっているので
簡単なテストがしやすい！

![sensu-0002.png](https://qiita-image-store.s3.amazonaws.com/0/17518/60673c22-bcc0-a0a4-0389-b5ff53fea0b1.png "sensu-0002.png")


## graphite画面ログイン

http://localhost:8081/


![sensu-0003.png](https://qiita-image-store.s3.amazonaws.com/0/17518/889501ca-ba1e-8d22-20af-1f8b4d245111.png "sensu-0003.png")
[objc] JASidePanelsのハンバーガーボタンをUIImageにカスタマイズする

JASidePanelController.m を継承したクラスで 下記２つのメソッドをオーバーライド

```objc

- (UIBarButtonItem *)leftButtonForCenterPanel
+ (UIImage *)defaultImage

```

↓こんな感じで任意の画像にカスタマイズします

```objc

/**
* [override] 
*/
- (UIBarButtonItem *)leftButtonForCenterPanel
{
    UIImage *humbergerImage = [[self class] defaultImage];

    //ボタンアクションがきくようにUIButton作成
    //参考 : @see http://akisute.com/2010/04/uibarbuttonitem.html
    UIButton *customHumbergerButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, humbergerImage.size.width*0.5, humbergerImage.size.height*0.5)];
    [customHumbergerButton setBackgroundImage:humbergerImage forState:UIControlStateNormal];
    [customHumbergerButton addTarget:self action:@selector(toggleLeftPanel:) forControlEvents:UIControlEventTouchUpInside];

    //バーボタンアイテム作成
    UIBarButtonItem* humbergerItem = [[UIBarButtonItem alloc] initWithCustomView:customHumbergerButton];
    return humbergerItem;
}

/**
* [override] 
*/
+ (UIImage *)defaultImage
{
    static UIImage *defaultImage = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^
    {
        //任意の画像
        defaultImage = [UIImage imageNamed:@"HeaderBtnHunberger.png"];
    });
    return defaultImage;
}


```
PhpStorm の PHPUnit が実行できない時の対処法


PHPUnit Runner: Class IDE_PHPUnit_Framework_TestListener contains 1 abstract method... というエラーが出るケースの対処法。

（参考）
http://stackoverflow.com/questions/21415898/unable-to-run-unit-tests-in-phpstorms-ide

現状のPhpStorm(7.1.3)はPHPUnit 3.7より上のやつに対応していないみたい。（2014-04-20現在）

PHPUnitのバージョンを 3.7にすればOK.

## 1. phpunit 3.7の配置

PHPUnitのサイトから古いバージョンをダウンロードして /usr/local/bin/phpunit-3.7.phar に配置

## 2. PhpStormの設定

Preferences > PHP > PHPUnit の

(*) Path to phpunit.phar のところで、

```
/usr/local/bin/phpunit-3.7.phar
```

のようにダウンロードしたファイルのパスを指定した。

## その他

composer.json で 下記のように指定しても良いらしい。未確認。

```
    "require-dev": {
        "phpunit/phpunit": "3.7.*"
    }
```


## 今回発生した環境

PhpStorm 7.1.3 Build #PS-133.982
PHPUnit 4.0.14
knife solo cook コマンドの誤爆を防ぐ

`knife solo cook`コマンドはchefリポジトリ内で実行しないと、失敗するだけでなく、

余計なnodeファイルなどが作成されてしまう。
ただ、エラーで終了してくれればいいんだけど。。。

しばらく、失敗している原因（実行するディレクトリが違う事）に気づかいない場合も多々ある。
Recipeやnodeファイルを無駄に見なおしたり。。。

ということで、 対症療法ですがaliasでなんとかしてみました。

### 方法
以下の関数とaliasを`.zshrc`や`.bashrc`に設定するだけです。

```sh
function knife_solo_check() {
  if [ "$1" = 'solo' ] && [ "$2" = 'cook' ] && [ ! -d .chef ]; then
    \echo -e '\033[0;31mERROR:\033[0;39m Not chef repository directory.'
  else
    \knife $@
  fi
}
alias knife=knife_solo_check
```

内容は単純で、`knife`コマンドの引数が`solo cook`であるとき且つ、
実行した場所に`.chef`ディレクトリが存在しない場合にだけエラーを表示します。

もしかしたら、こういうことにならない方法がすでにあるかもしれないし、
もっといい方法があるかもしれない。。
あったら教えて下さい。
どんなに優秀なプログラマでも死者を生き返らせることは出来ない


# 現状における問題点

> この記事は筆者の偏見と独断にもとづき記述されたフィクションです。
> 実在の人物・企画・デスマーチとは一切関係がありません。

プログラマと非プログラマの企画職との間で、実装可能かどうかで意見が対立することがなくもない。
非プログラマからすると、「簡単に操作できそうなものは実装も簡単なんだろう」と思っているふしが見え隠れするときもあるような…。プログラマならよくわかっているとおり、「操作を簡単にするためにプログラマがかなり苦労して実装している」場合がほとんどである。
それはともかく、あきらかに対象のハードウェア（スマホ等）では荷が勝ちすぎて実現はほぼ不可能と思われる機能の実装を頼まれることがあったり…しますよね（？）

# 対応策

では、実際にこのような事象に遭遇したとき、企画職を説得するにはどうしたらよいのだろうか？

その答えが、この記事のタイトルにもなっている

「どんなに優秀なプログラマでも死者を生き返らせることは出来ない」

である。

現時点では、この言葉だけで説得するのは無理だろう。

だが、これが世界中に流行って非プログラマでも当たり前に知っている世の中がきたらどうだろう。
そんな世界になったら、実現不可能な企画を持ち込まれたときに
「あ、それは”どんなに優秀なプログラマでも死者を生き返らせることは出来ない”のと同じで、実現はほぼ不可能です」
とか言うだけで、非プログラマの企画職に一言で通じるのだ。素晴らしい！

# 実現までの長い道のり

とはいえ、現時点ではこんな言葉はぐぐっても出てこないレベル（実際にぐぐった結果）なので、これから流行らせる必要があるわけだが…。

誰もが一言でピンとくる世界のために、今はまず、徐々にこの言葉を使っていくしかないだろう。
以下に、如何にしてこの台詞を使って会話をするかの例をあげておく。


## 例

企画「こういうことって、このアプリで実現できますか？」
プログラマ「あー、それは技術的に無理ですね」
企画「そこをなんとか、なりません（笑顔」
プログラマ「プログラムにも出来ることと出来ないことがありますから…無理です」
企画「いやー、○○さん（プログラマの名前）なら出来るんじゃないですか」
プログラマ「んー、そうですね。たとえば、プログラムを組んで死者を生き返らせることって出来ると思います？」
企画「それは無理っしょw」
プログラマ「では、プログラムを組んでタケコプターを飛ばすことって出来ると思います？」
企画「無理…かな？」
プログラマ「可能ですよ。タケコプターのハードウェアさえ誰かが開発してくれればですけどね。タケコプターぐらいのハードウェアには当然、それを動かすプログラムが必要になるでしょうから可能…といえます」
企画「いや、無茶なw　ハードが無いと組めないのに…組めるというのは言い過ぎな気がしますねぇ」
プログラマ「ハードが無いと組めないですか…いいでしょう。そこは企画さんの言うとおりですね（にっこり』
企画「でしょー（笑顔」
プログラマ「それで、ですね。さきほど企画さんがおっしゃったアプリの機能ですが、現在のハードウェアでは実現するのは無理なんですよ。タケコプターがないからタケコプターのソフトが組めないのと同じことです」
企画「」


> こんな感じでいけるんじゃないかという夢をみた…。
やっとenumが導入されたよ..遅いよね..


(注) タイトルはあくまでネタであり、Pythonディスってるわけではありません。むしろ大好き。

Python3.4から導入されたenumは、インスタンス変数やメソッドを持たせることができる。もうJavaのenumを羨む必要がなくなった。

```python3:メソッドを持つenum
from enum import Enum


class JavaLikeEnum(Enum):

    foo = ('foo_name', 50)
    bar = ('bar_name', 100)

    def __init__(self, item_name, price):
        self.item_name = item_name
        self.price = price

    def with_tax(self):
        return self.price * 1.08

print(JavaLikeEnum.foo.with_tax())
print(JavaLikeEnum.bar.with_tax())
```

バックポート用のパッケージがpipで提供されているので、Python3.3以前でも大丈夫。
これからガンガン使っていこう。

```bash:
% pip search enum34
enum34                    - Python 3.4 Enum backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4
```
Pixiv小説検索APIの結果を元に小説本文を取得する

#概要
Pixiv小説検索APIの結果をCSV形式で取得し、
そのCSVファイルを元に小説本文をテキスト形式で取得する。

#処理

##01.Pixiv小説検索APIの結果をCSV形式で取得
[ -> Pixiv検索結果をCSVダウンロードするHTMLファイルを用意した](http://qiita.com/nezuq/items/55800d55c03606e0b13c)
　※CSVファイルの名前はINPUT.csvに変える。

##02.取得CSVファイルの同階層に、下記Rubyコードを配置

```ruby:pxcsv2novel.rb
# encoding: utf-8

require 'csv'
require 'uri'
require 'net/http'
require 'fileutils'

#入力ファイル名
INPUT_CSV = ARGV[0] || 'INPUT.csv'

path = Time.now.strftime("%y%m%d%H%M%S")
FileUtils.mkdir_p(path)

CSV.foreach(INPUT_CSV, encoding: "UTF-8") do |row|
  sleep(rand(3) + 6)
  if (0 < row[0].length) then
    uri = URI.parse("http://spapi.pixiv.net/iphone/novel_text.php?id=" + row[0])
    text = Net::HTTP.get(uri)
    open(path + '/' + (row[0] + ".txt"), "wb") {|f|
      f.write(text)
    }
  end
end

puts "end!"
```

#出力イメージ
yyMMddhhmmss（出力フォルダ）
　|ー0000001.txt（出力テキストファイル）
　|ー0000002.txt
　|ー0000003.txt
　|ー etc...

#関連ページ
[ -> Rで自然言語処理。Pixiv小説で単語別の出現数を調べる](http://qiita.com/nezuq/items/7f48b7a1c25bde626150)
[ -> ニコニコ大百科データからMeCab辞書を生成する](http://qiita.com/nezuq/items/875ac806d9b1afb3798d)
[ -> Rで文書分類器。未来設定のラブライブ!百合小説を抽出する](http://qiita.com/nezuq/items/99a599587b1e48705c65)
【AngularJS】hover/active時にクラスを追加するdirective


# 背景

普通にスタイルを指定するだけなら`:hover`，`:active`擬似クラスを利用すれば問題ない．しかし，スマートフォン対応をしようとすれば`:hover`が効かないものがあるらしい（[参考](http://argument.hatenablog.jp/entry/2013/09/05/235949)）．

ということで，AngularJSのお勉強がてらhover/active時に任意のクラスを追加するdirectiveを作ってみた．

# Directive

実際に使ってみるとこんな感じ．
html内で追加するクラスを任意で決定できるから便利っぽい？

```html:test.html
<ul>
  <li cls-hover cls-active>hover時: hover，active時: active追加</li>
  <li cls-hover="li-hover">hover時: li-hover追加</li>
  <li cls-active="li-active">active時: li-active追加</li>
</ul>
```

Directiveのコードは以下．

```coffeescript:class_setter.coffee
app = angular.module 'MyApplication'

CLS_HOVER_DEFAULT = "hover"
CLS_ACTIVE_DEFAULT = "active"

app.directive 'clsHover', ->
  restrict: 'A'
  link: (scope, element, attrs, ctrl) ->

    clsHover = attrs.clsHover || CLS_HOVER_DEFAULT

    element.on 'mouseenter', ->
      element.addClass clsHover

    element.on 'mouseleave', ->
      element.removeClass clsHover


app.directive 'clsActive', ->
  restrict: 'A'
  link: (scope, element, attrs, ctrl) ->

    clsActive = attrs.clsActive || CLS_ACTIVE_DEFAULT

    element.on 'touchstart mousedown', ->
      element.addClass clsActive

    element.on 'touchmove touchcancel touchend mousemove mouseup', ->
      element.removeClass clsActive
```


# 参考

- [【AngularJS】hover/active時にクラスを追加するdirective](https://gist.github.com/izumin5210/11104751)（gist）
- [スマートフォンサイトでのhover - argumentLog](http://argument.hatenablog.jp/entry/2013/09/05/235949)

# 謝辞

参考サイトを教えてくれた後輩氏（[@DeNAri01](https://twitter.com/DeNAri01)），ありがとう．
Android で ImageView に画像を表示するときに使えるライブラリ4つ

**TODO 後で追記する**

# ImageView に画像を表示したいけど・・・なときのメモ

## ぜんてい

- ネットから取得した画像を表示するかも
- ローカルの画像を表示するかも
- キャッシュ使いたいかも
- 非同期で処理したいかも

## ４つの候補

- Picasso http://goo.gl/tpTc1
- Android Universal Image Loader (UIL) http://goo.gl/obp2C
- UrlImageViewHelper http://goo.gl/AoPK90
- Volley - http://goo.gl/iB4YWG

## とくちょうとか

TODO 後で書く

めも

- UrlImageViewHelper は速いらしい。
- Volley も速いらしい。キャッシュの実装は自分でやる。ネットの画像のみ対応。機能は限定的。
- UIL は機能が豊富で一通り全部できる。
- Picasso は機能が豊富で一通り全部できる。Square が提供しているから信頼できそう？使っている人が多いらしい。

## けつろん

みんなが使っているらしい Picasso がいいんじゃない？（自己責任でお願いします）

## さんこう

- Testing ALL the Android Image and http Libraries I've been… - http://goo.gl/Hx3WDj
- Local image caching solution for Android: Square Picasso vs Universal Image Loader - Stack Overflow - http://goo.gl/RqKZAA
CoreDataに簡単に初期データを追加する


[NTYPopulator](https://github.com/naoty/NTYPopulator)というライブラリで簡単に初期データを追加できる。CocoaPodsからインストールできる。

```rb:Podfile
pod "NTYPopulator"
```

```sh
$ pod install
```

使い方は`AppDelegate.m`に一行加えるだけ。

```objective-c:AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
	[[NTYPopulator new] run];
	return YES;
}
```

リソースバンドル内にある`seeds/*.csv`を探しだして、ファイル名と同名のEntityにデータを追加する。例えば、`seeds/user.csv`のデータは`User`というEntityに追加される。

デフォルトではモデルファイルとして`Model.momd`が参照され、SQLiteファイルとして`$(CFBundleName).sqlite`が参照される。これを変更することも可能。

```objective-c:AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyModel" withExtension:@"momd"];
    NSURL *documentDirectoryURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    NSURL *sqliteURL = [documentDirectoryURL URLByAppendingPathComponent:@"MySQLite.sqlite"];
    
    NTYPopulator *populator = [[NTYPopulator alloc] initWithModelURL:modelURL sqliteURL:sqliteURL];
    [populator run];
    
    return YES;
}
```

---

以上、ステマでした。

---
### 追記

NTYPopulatorで想定していたユースケースは開発時に初期データをさくっと入れたいというものなので、リリース時には作成済みのSQLiteファイルを使った方がいいと思う。
Android で誰もが書いたことのあるコードがライブラリ化された Amalgam が便利

# 我らが @KeithYokoma について

※敬称略

Qiita の Android 界隈では誰もが知る @KeithYokoma をたたけばほこりが出るんじゃなくて、面白いものが出てくるだろうと探索してきました。公開されているプロジェクト名が読みにくいことで定評のある @KeithYokoma 。「Laevatein」もそうだが、この「Amalgam」も読めないよ。

## commons みたいな Amalgam

Android - Amalgam でコードを整理する - Qiita - http://goo.gl/IQlftp

↑は @KeithYokoma 自身が書いているQiitaの解説。これ以外にも、IOUtil 、StringUtil 系の良くありがちなものや、面倒が多い Bitmap 系もあるし、とりあえず新規Androidプロジェクト作ったら、入れたらいいんじゃないかな。

## github

https://github.com/nohana/Amalgam
Mezzanine:ガラケ対応


[Mezzanine](http://mezzanine.jupo.org/)をガラケ対応してみる。

settings.DEVICE_USER_AGENTSにエージェントを登録.

mezzanine.core.middleware.TemplateForDeviceMiddlewareで、

```py

    tuple('デバイス', tuple('エージェント1', 'エージェント2',..))
```

 をループで判別して、現在のデバイスを判定し、判定した'デバイス/'を指定された
 テンプレート名の頭に挿入してリストを返す(mezzanine.utils.device.templates_for_device())。

例えば、サイトルートがアクセスされると、テンプレートリストは以下になるので、:

```py

    [u'pages/index.html', u'pages/index/richtextpage.html', u'pages/richtextpage.html', u'pages/page.html']
```

ミドルウェアは、

```py

    [u'デバイス/pages/index.html', u'pages/index.html', u'デバイス/pages/index/richtextpage.html', 
    u'pages/index/richtextpage.html', u'デバイス/pages/richtextpage.html', u'pages/richtextpage.html', 
    u'デバイス/pages/page.html', u'pages/page.html']
```

を返します。

デバイスの判定は、'エージェントn' の文字列が request.META["HTTP_USER_AGENT"].lower() の文字列にふく
まれ手いるかどうかだけで判定するので、 スマホの判定をガレケの判定の前にいれないと、DoCoMoのAndroidが
ガラケ扱いされてしまうこともある。

phone アプリを Mezzaineに追加し、:

    python manage.py startapp phone

settins.py:

    INSTALLED_APPS += (
        'phone',
    )


mezzanine.mobile.templatesとmezzanine.mobile.staticをコピってHTMLを作成。
extends のパスを "phone/" にするなどして修正:

    sample
    ├── phone
    │   ├── __init__.py
    │   ├── __init__.pyc
    │   ├── models.py
    │   ├── models.pyc
    │   ├── static
    │   │   ├── css
    │   │   │   ├── global-mobile.css
    │   │   │   └── mobile.rtl.css
    │   │   └── img
    │   │       ├── icon-home.png
    │   │       └── mobile-bg.gif
    │   └── templates
    │       └── phone
    │           ├── 404.html
    │           ├── 500.html
    │           ├── base.html
    │           ├── blog
    │           │   ├── blog_post_detail.html
    │           │   └── blog_post_list.html
    │           ├── includes
    │           │   ├── footer_scripts.html
    │           │   ├── pagination.html
    │           │   └── search.html
    │           ├── index.html
    │           ├── pages
    │           │   ├── form.html
    │           │   ├── index.html
    │           │   ├── menus
    │           │   │   └── phone.html
    │           │   ├── page.html
    │           │   └── richtextpage.html
    │           └── search_results.html

    
local_settings.pyにDEVICE_USER_AGENTSを作成:

```py

    DEVICE_USER_AGENTS = ( 
        ("mobile", ("Android", "BlackBerry",
                    "iPhone", "iPad", "iPod", "Windows Phone")),
        ("phone", ('DoCoMo', 'SoftBank', 'KDDI', 'Vodafone',
                   'Nokia', 'MOT-', 'J-PHONE', 'BlackBerry', 'Symbian',)),
    )
```


サイトテーマ使うならば、

    sample/static/テーマ名/phone/...
    sample/templates/テーマ名/phone/...

のパスに作れば良さそう。
Meteor で CoffeeScript ファイルをクラス単位に分割する


## CoffeeScript をクラス単位で分割
Meteor はフルスタックの PaaS であり、クライアントもサーバーも JavaScript が使えるお手軽なプログラミング環境です。小規模なアプリでもあれこれ機能を追加していくうちにコード量が増えていくのでコンパクトに書くためにも CoffeeScript を使いたいものです。Coffee 使うならクラス単位でファイル分割して見通しを良くしたいです。

Meteor では、クライアントとサーバーのコードより外側のスコープにクラスのインスタンスを生成するとファイルを超えて参照できるようです。ファイル結合して JavaScript にコンパイルするからでしょうけど。
このことを利用して、分割したファイルにクラス定義とインスタンス化のコードを書きクラスの初期メソッドをメインファイルから呼べば OK でした。クラス定義の必要ないオブジェクトなどは、1箇所にまとめることもできます。
なお、「クラス単位」と書いていますが、ライフサイクルの短いクラスや何らかのクラスに集約されるようなクラスは、ファクトリや集約ルートのクラスファイルの中で定義し、それらのファクトリや集約クラス内で生成するようにするとメインのクラスからは隠蔽できますし、他のクラスファイルからは単なるオブジェクト扱いにできます。

![Coffee Files](http://f.st-hatena.com/images/fotolife/k/kondoumh/20140420/20140420100836.png "Coffee Files")


ファイル分割することで、メインのファイルからクラスのメソッドを呼び出す必要があります。Context 系のクラスであれば

```coffeescript:HogeContext.coffee
class HogeContext
  setUp: ->
    @status = new HogeStatus ({
          : # createContext
    })
      :

@hogeContext = new HogeContext
```

のように、初期構築にふさわしいメソッド定義ができて、メインから呼ばれるのは自然ですが、普通のクラスはちょっとわざわざ呼んでもらうメソッドを定義するのが微妙です。空の初期化メソッドでも作って呼んでおけばいいでしょう。

```coffeescript:Fuga.coffee
class Fuga
  initialize: ->
      : #nop

@fuga = new Fuga
```

メインのファイルからは、各クラスの初期化メソッドを適切な順序で呼び出します。

```coffeescript:Main.coffee

if Meteor.isClient

  Meteor.startup ->
    HogeContext.setUp()
    Fuga.initialize()

if Meteor.isServer
  Meteor.startup ->
     :

```


## ファイル分割のデメリット
ファイル分割のデメリットとして

* Enum 的な情報を1箇所に持てない。
* Factory クラスのように static にしたいものもインスタンス化する必要がある。

前者は、例えば

```coffeescript:
TicketStatus =
  NEW      : 0
  ASSIGNED : 1
  CLOSED   : 2
```

のように定義して Ticket オブジェクトの属性に設定したりして使いますが、色々なファイルから参照したい場合は、グローバルなインスタンスとして扱うしかありません。

後者は例えば

```coffeescript:HogeFactory.coffee
class HogeFactory
   @createHoge: ->
       :
     hoge
``` 

```hoge = HogeFactory.createHoge()``` のように使えなくなるということですが、Factory のインスタンスを生成してメソッドの定義から ```@``` を外すだけなのでそれほど残念ではありません。
まあ、これらは見通しが悪いことに比べれば些細な問題と言えるでしょう。
ffmpegのビルド

* [Download FFmpeg](https://ffmpeg.org/download.html#build-linux)から`Static Builds`をダウンロードすると良いです。
* 変換オプションは[ffmpegの使い方：tech.ckme.co.jp](http://tech.ckme.co.jp/ffmpeg.shtml)が詳しいです。

## 以下古い情報

ubuntu 14.04にはffmpegがdelicateになっててパッケージが無い。
avconvを使うもコアダンプ吐いてどうしようもないのでビルドすることにした。

* [UbuntuCompilationGuide – FFmpeg](https://trac.ffmpeg.org/wiki/UbuntuCompilationGuide)

# 必要なパッケージインストール

```bash:必要なパッケージインストール
$ sudo apt-get -y install \
autoconf \
automake \
build-essential \
libass-dev \
libfreetype6-dev \
libgpac-dev \
libsdl1.2-dev \
libtheora-dev \
libtool \
libva-dev \
libvdpau-dev \
libvorbis-dev \
libx11-dev \
libxext-dev \
libxfixes-dev \
pkg-config \
texi2html \
zlib1g-dev \
yasm \
libmp3lame-dev \
nasm \
libfdk-aac-dev \
unzip
```

# ビルド
```bash:build.sh
## yasm
mkdir ~/src && cd ~/src
wget http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz
tar xzf yasm-1.2.0.tar.gz
cd yasm-1.2.0
./configure --prefix="$HOME/local/"
make && make install

## x264
cd ~/src
wget http://download.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xjf last_x264.tar.bz2
cd x264-snapshot*
./configure --prefix="$HOME/local" --enable-static
make && make install

## lame
cd ~/src
wget http://downloads.sourceforge.net/project/lame/lame/3.99/lame-3.99.5.tar.gz
tar xzf lame-3.99.5.tar.gz
cd lame-3.99.5
./configure --prefix="$HOME/local" --enable-nasm --disable-shared
make && make install

## opus
cd ~/src
wget http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz
tar xzf opus-1.1.tar.gz
cd opus-1.1
./configure --prefix="$HOME/local" --disable-shared
make && make install

## webm
cd ~/src
wget http://webm.googlecode.com/files/libvpx-v1.3.0.tar.bz2
tar xjf libvpx-v1.3.0.tar.bz2
cd libvpx-v1.3.0
./configure --prefix="$HOME/local" --disable-examples
make && make install

## ffmpeg
cd ~/src
wget http://ffmpeg.org/releases/ffmpeg-snapshot.tar.bz2
tar xjf ffmpeg-snapshot.tar.bz2
cd ffmpeg
export PKG_CONFIG_PATH="$HOME/local/lib/pkgconfig"
./configure \
--prefix="$HOME/local" \
--extra-cflags="-I$HOME/local/include" \
--extra-ldflags="-L$HOME/local/lib" \
--extra-libs="-ldl" \
--enable-gpl \
--enable-libass \
--enable-libfdk-aac \
--enable-libfreetype \
--enable-libmp3lame \
--enable-libopus \
--enable-libtheora \
--enable-libvorbis \
--enable-libvpx \
--enable-libx264 \
--enable-nonfree \
--enable-x11grab
make && make install

## clean
rm -rf ~/src
```

## 実行

```bash:
~/local/bin/ffmpeg
```
ClangFormat-XcodeでObjective-Cのコードを整形してみた


コード整形ツール[ClangFormat-Xcode](https://github.com/travisjeffery/ClangFormat-Xcode)を使って、Objective-Cのコードを整形します。

ClangFormat-Xcodeのインストールには、Xcode5向けのパッケージマネージャである[Alcatraz](https://github.com/supermarin/Alcatraz)を利用します。

### Alcatraz インストール
ターミナルで以下を入力するとAlcatrazがインストールされます。

```shell-session
 curl -fsSL https://raw.github.com/supermarin/Alcatraz/master/Scripts/install.sh | sh
```

Xcodeを再起動すると、メニューバーの"Window"項目の中に、"Package Manager"が追加されています。
![スクリーンショット 2014-04-20 8.54.23.png](https://qiita-image-store.s3.amazonaws.com/0/42150/b5e10602-f78e-20c2-a403-9e2e83dde0ad.png "スクリーンショット 2014-04-20 8.54.23.png")

クリックするとPackage Managerが立ち上がります。![スクリーンショット 2014-04-20 8.58.23.png](https://qiita-image-store.s3.amazonaws.com/0/42150/0c08dd7c-6bc1-17eb-840e-3691d8e0657f.png "スクリーンショット 2014-04-20 8.58.23.png")

### ClangFormat インストール
"ClangFormat"で検索すると、ClangFormatが表示されるので、左のレゴブロックのアイコンをクリック。
![スクリーンショット 2014-04-20 8.59.27.png](https://qiita-image-store.s3.amazonaws.com/0/42150/5c8df236-db97-a47f-ca32-33eaf0d9bb0b.png "スクリーンショット 2014-04-20 8.59.27.png")

メニューバーの"Edit"項目に"Clang Format"が追加されるので、選択して"Format 〜"をクリックすると整形できます。
![スクリーンショット 2014-04-20 9.01.53.png](https://qiita-image-store.s3.amazonaws.com/0/42150/83a1e917-eb3a-2210-944a-6038d65c326a.png "スクリーンショット 2014-04-20 9.01.53.png")

### フォーマットのカスタマイズ
カスタマイズをしたい場合は、プロジェクトのルートディレクトリに```.clang-format```を作成し、[Clang-Format Style Options](http://clang.llvm.org/docs/ClangFormatStyleOptions.html)の記法に従って入力します。
例えば以下のようになります。

```yaml:.clang-format
BasedOnStyle: Google
IndentWidth: 4
UseTab:	Never
BreakBeforeBraces: Linux
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
```

カスタマイズしたフォーマットは、"Edit"→"Clang Fomat"→"File"を選択すると適用され、"Format 〜"をクリックすると整形されます。

"Enable Format on Save"をクリックすると、セーブするたびに整形されます。
Node.jsでメールを送信するパッケージ

nodemailer npm公式サイト
http://www.nodemailer.com/

nodemailer npmパッケージサイト
https://npmjs.org/package/nodemailer

nodemailer GitHubサイト
https://github.com/andris9/nodemailer

## SMTPに使用できるメールサービス

- DynectEmail
- Gmail
- hot.ee
- Hotmail
- iCloud
- mail.ee
- Mail.Ru
- Mailgun
- Mailjet
- Mandrill
- Postmark
- QQ
- QQex (Tencent Business Email)
- SendGrid
- SendCloud
- SES
- Yahoo
- yandex
- Zoho

## インストール

```
npm install nodemailer
```

## サンプルコード

```js:
var mailer = require('nodemailer');
 
//SMTPの設定
var setting = {
    //SMTPサーバーを使う場合
    host: 'SMTPホスト',
    auth: {
        user: 'ユーザ名',
        pass: 'パスワード',
        port: 'SMTPポート番号'
    }
    
    /*
    //Webサービスを使う場合
    service: 'サービス名', //'Gmail'、'Hotmail'、'Yahoo Mail'など
    auth: {
        user: 'アカンと名',
        pass: 'パスワード',
        port: 'ポート番号' //'25'など
    }
    */
};
 
//メールの内容
var mailOptions = {
    from: '送信者のメールアドレス',
    to: '送信先メールアドレス',
    subject: 'メールの件名',
    html: 'メールの内容' //HTMLタグが使えます
};
 
//SMTPの接続
var smtp = mailer.createTransport('SMTP', setting);
 
//メールの送信
smtp.sendMail(mailOptions, function(err, res){
    //送信に失敗したとき
    if(err){
        console.log(err);
    //送信に成功したとき
    }else{
        console.log('Message sent: ' + res.message);
    }
    //SMTPの切断
    smtp.close();
});
```
CreateJS IE10/11 タッチ端末でドラッグ＆ドロップ（スワイプ）

#概要
Flash CC からのCanvas書き出しでのドラッグ＆ドロップ（兼タッチ端末でのスワイプ）の実現にあたって、ネット上にあるサンプルコードで、Androidブラウザ、Chrome、Safariなどでのマウス操作/タッチ操作はうまく動作する。IE10/11もマウス操作はうまく動作する。
が、IE10/11のタッチ端末での動作だけ、なかなかうまく動かせずハマったのでメモ。

注：FlashやCreateJSの細かいバージョンで、いろいろ変わるようなので201.04.20現在の最新情報としてご覧ください。

##環境
Flash CC Ver.13.1 を適用済。
このバージョンから、書き出し方法が変わっています。
参考 http://plus.adobe-adc.jp/post-5022/

##参考
・IE10/11のタッチ操作でうまく動くもの
　http://kudox.jp/java-script/createjs-easeljs-event
　この中のドラッグ＆ドロップのサンプル
・IE10/11のタッチ操作でうまく動かなかったもの
　http://pops-web.com/main/pops/archives/221
　ここにあるサンプル

#コード(Flash内タイムライン上のJavaScript)
`aa`というインスタンス名をつけたMovieClipをステージに配置します。
細かい説明は省きますが、水平方向にドラッグ移動できるようにしました。

```js
if (createjs.Touch.isSupported()) {
	createjs.Touch.enable(stage, true);
}

function mouseDownHandler(mouseDownEvent){
	console.log("down");
	var target = mouseDownEvent.target;
	var basex = target.x - mouseDownEvent.stageX;
	function pressMoveHandler(pressMoveEvent){
		console.log("move");
		target.x = basex + pressMoveEvent.stageX;
		stage.update();
	}
	function pressUpHandler(pressUpEvent){
		target.removeEventListener("pressmove", pressMoveHandler);
		target.removeEventListener("pressup", pressUpHandler);
		console.log("up");
	}
	target.addEventListener("pressmove", pressMoveHandler);
	target.addEventListener("pressup", pressUpHandler);
}

this.aa.addEventListener("mousedown",mouseDownHandler);
```

これを書きだしたもの
http://dev.elephancube.jp/qiita/drag140420.html
・・・IE10/11のタッチ端末だけ、動きません。


##解決法
Flashから書き出されたhtmlに手を加えます。

###書き換えポイント1
Flash CC 13.1 で書き出されるCreateJSが、EaseJS 0.7.0 と TweenJS 0.5.0 ですが、最新は、EaseJS 0.7.1 と TweenJS 0.5.1。このマイナーバージョンの違いで変わるので、CreateJS本家サイトから最新版をダウンロードしてきて、リンクを変更する。

CreateJS本家サイト http://www.createjs.com/

書き換え前

```html
<script src="libs/easeljs-0.7.0.min.js"></script>
<script src="libs/tweenjs-0.5.0.min.js"></script>
<script src="libs/movieclip-0.7.0.min.js"></script>
```

書き換え後

```html
<script src="libs2/easeljs-0.7.1.min.js"></script>
<script src="libs2/tweenjs-0.5.1.min.js"></script>
<script src="libs2/movieclip-0.7.1.min.js"></script>
```


###書き換えポイント2
Flash CC 13.1 で書き出されたままのhtmlだと、Tickerイベントが動作していない！？（定義はされているが、挙動しているのか不明。）ようなので、明示的に定義する。

書き換え前（function init()内）

```html
createjs.Ticker.addEventListener("tick", stage);
```

書き換え後（function init()内）

```html
function tickHandler(evt) {
	stage.update();
}
createjs.Ticker.addEventListener("tick", tickHandler);
```

書き換えた後
http://dev.elephancube.jp/qiita/drag140420kai.html
うごいたー！！

##ソース
flaファイルと書き換え前後のhtmlファイルを入れています。欲しい方はどうぞ。
http://dev.elephancube.jp/qiita/drag140420_src.zip
Android Error: error opening trace file: No such file or directory(2)



上記エラーが出た。

## How to fix: 直し方

```xml:AndroidManifest.xml
    <uses-permission android:name="android.permission.INTERNET"/>
```

Add following line.
しかなかったところに、以下を追加したら解決


```xml:AndroidManifest.xml
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
```


## Error: エラー内容

LogCat で以下のようなエラーが出た

```
error opening trace file: No such file or directory(2)
```


## Ref

[error opening trace file: No such file or directory(2)](http://stackoverflow.com/questions/16132807/android-error-opening-trace-file-no-such-file-or-directory2 "error opening trace file: No such file or directory(2)")
リファクタリング Nullオブジェクトの導入

###どういう時に使うといいのか？
プログラムを書いていると頻繁に登場するのがNullチェックです。例えば以下のようなコード。

~~~ruby:example
if customer.nil?
  return
end
puts customer.name
~~~

Nullである事をチェックせずに```customer.name```を実行すると```NoMethodError```になります。
Nullオブジェクトの導入はそんなNullチェックを繰り返しているコードに対して有効なリファクタリング方法です。

###リファクタリング前
以下にリファクタリング前のサンプルを示します。

~~~ruby:before_クラス定義
class Site
  attr_reader :customer
end

class Customer
  attr_reader :name, :plan, :history
end

class PaymentHistory
  def weeks_delinquent_in_last_year
	#処理
  end
end

~~~
nullチェックをplan,customer_name, weeks_delinquentそれぞれで必要になってきます。

~~~ruby:before_処理
customer = site.customer

paln = customer ? customer.plan : BillingPaln.basic

customer_name = customer ? customer.name : 'occupant'

weeks_delinquent = customer.nil? ? 0 : customer.history.weeks_delinquent_in_last_year
~~~

###リファクタリング後

Nullな状態を表すクラスを定義しその中でNullの時の振る舞いを記述します。

~~~ruby:after_クラス定義
class Site
  def customer
    @customer || Customer.new_missing
  end
end

class Customer
  def self.new_missing
      NullCustomer.new
  end
  attr_reader :name, :plan, :history
end
#Nullな状態を表すCustomerを定義しその中でNullの時の振る舞いを記述する
class NullCustomer
  def missing? true; end
  def name 'occupant'; end
  def plan BillingPlan.basic; end
  def history; PaymentHistory.new_null end
end

class PaymentHistory
  def weeks_delinquent_in_last_year
    #処理
  end
end
#Nullな状態を表すPaymentHistoryを定義しその中でNullの時の振る舞いを記述する
class NullPaymentHistory
  def weeks_delinquent_in_last_year; 0; end
end
~~~

そうする事で下記のようにif文が不要になり、コードを簡潔にする事ができます。

~~~ruby:after_処理
customer = site.customer

plan = customer.plan

customer_name = customer.name

weeks_delinquent = customer.history.weeks_delinquent_in_last_year
~~~

下記の本を参考にしました。
[リファクタリング:Rubyエディション](http://www.amazon.co.jp/%E3%83%AA%E3%83%95%E3%82%A1%E3%82%AF%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0-Ruby%E3%82%A8%E3%83%87%E3%82%A3%E3%82%B7%E3%83%A7%E3%83%B3-Jay-Fields/dp/4048678841)
Ubuntu + Tomcat7 + JFreeChart がうまく表示されない

Tomcat7 + JFreeChart を使ってグラフを出力するプロジェクトでの話。

実行環境は CentOS6 上で稼働しており、``` WEB-INF/lib ``` の下にJFreeChart関連のjarを配置しておけば、ちゃんとグラフが表示されます。

しかし、開発環境として Ubuntu12 + Tomcat7 で実行したところ、JFreeChartの実体を取得するところで、``` ClassNotFoundException ``` が発生。前述のとおりJarファイルは ``` WEB-INF/lib ``` に配置しているので、クラスがないはずがない。

ネットを漁っていると、Tomcatの起動時に ``` -Djava.awt.headless=true ``` を指定してやると回避できるかもという記事を発見。試してみるとちゃんと動いた。
CentOSではこんなことなかったのに・・・・

Ubuntuは開発環境なので、もちろんデスクトップでGUIで作業しているので、java.awt.headless なんて必要ないはずなのだが・・・・・

Ubuntuはなんだか怪しい。
見た目はかっこいいけど、なんだかメインで使い込む気になれない。
Python3.4 インストールメモ


いくつかの前提が満たされたため、メインの環境をPython3.4に切りかえることとした。以下、メモ書き程度。

# インストール

今までは、homebrewでインストール -> virtualenv作成としていたのだが、今回は自前でビルドすることとした。
python31, python32という感じのマイナーバージョンを指定してインストールするformulaがなくなっており、既存のメイン環境であるPython3.3をアップデートで消してしまうのではないか、という恐れがあったため。(実際にどうかは未確認)

```bash:
% brew search python3
python3
```

ソースはgithubからcloneする. https://github.com/python/cpython

```bash:
% git clone https://github.com/python/cpython
% cd cpython
```

configureでインストールディレクトリを指定する。デフォルト(/usr/local)のままでも良いが、その場合は`make install`ではなく`make altinstall`として、既存のシンボリックリンクを上書きしないようにする。
(ref.) https://github.com/python/cpython/blob/master/README

```bash:Python3.4.0のインストール
% ./configure --prefix=~/python/python34/3.4.0
% make
% make install
% ls ~/python/python34/3.4.0/bin/
2to3  2to3-3.4  easy_install-3.4  idle3  idle3.4  pip3  pip3.4  pydoc3  pydoc3.4  python3  python3-config  python3.4  python3.4-config  python3.4m  python3.4m-config  pyvenv  pyvenv-3.4
```

# 仮想環境の構築

自身の環境ではシステムデフォルトのPython(2.7.5)は変更せずに、各バージョン用の仮想環境を構築している。
仮想環境を作成するにはvirtualenvを使用するのが一般的だが、Python3.4から標準ライブラリのpyvenvを使用するという選択肢ができた。
https://docs.python.org/3.4/using/scripts.html#scripts-pyvenv

軽くしか試していないので断言できないが、virtualenvを置きかえるだけ、ならば問題なさそう。
ただし、virtualenvにはvirtualenvwrapperという素晴しいユーティリティがあるため、ここが何らかの方法で解決されない限りはpyvenvの移行はしないつもり。(自分で実装しろやゴルァ、って指摘はあるけど…)
とはいえ、仮想環境構築が標準ライブラリで出来るようになった意義はデカいと思う。今後に期待。

```bash:virtualenv(wrapper)での仮想環境構築
% mkvirtualenv -p ~/python/python34/3.4.0/bin/python3.4 py3.4.0
…
(py3.4.0)% python
Python 3.4.0+ (default, Apr 19 2014, 14:38:58)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.76)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

このメイン環境は可能な限りクリーンにしておくが、iPythonだけはいれておく。無いとだらっと何かを確かめたい時に不便なので。
virtualevnwrapperは仮想環境作成時のフックをサポートしているため、それを利用する。
仮想環境作成後の動作は、postmkvirtualenvファイルにより定義できるため、ここにipythonをインストールする処理を書く。

```bash:postmkvirtualenv
#!/bin/zsh
# This hook is run after a new virtualenv is activated.

pip install ipython
```

(ref.) http://virtualenvwrapper.readthedocs.org/en/latest/scripts.html

あと[httpie](https://github.com/jkbr/httpie)も何かと便利なので入れておいた。

```bash:
(py3.4.0)% pip install httpie
```

# デフォルトでPython3.4の仮想環境を使用する

現状だと、端末を立ち上げる度に以下のコマンドを入力して作成した仮想環境の使用を明示しなければならない。

```bash:
# workonはvirtualenvwrapperが提供する
% workon py3.4.0
(py3.4.0)%
```

これは不便なので、ログイン時にworkonするようにしておく。以下はzsh使用前提。

```bash:~/.zlogin
% cat ~/.zlogin
# 仮想環境の名前には規則性を持たせる。(py + (version))
# デフォルトバージョンは別途ファイルで管理
if [ -f ~/.venv/.defaultver ];then
    DEFAULT_VER=`cat ~/.venv/.defaultver`
    workon py${DEFAULT_VER}
fi

% cat ~/.venv/.defaultver
3.4.0
```

(ref.) http://qiita.com/yuku_t/items/40bcc63bb8ad94f083f1 
* 現状、.zshrcでvirtualenvwrapperの読み込みを行っているため、.zloginにworkon処理を書いているが、読み込みもあわせて.zprofileに書いた方がいいかも。

# プロジェクト毎に仮想環境を切る

普段は上記の仮想環境を使用するが、前述の通りメイン環境はクリーンにしておきたいので、ここから更にプロジェクト毎に仮想環境を作成する。
デフォルトでPython3.4.0を使用するよう設定しているため、指定するインタープリタがどこに入っているかを意識することは基本的にない(=\`which python`で指定できる)

```bash:
(py3.4.0)% mkvirtualenv -p `which python` new_project
```
PHP の三項演算子・・・

# まず比較

```shell-session:perl
$ perl -e "print (1 ? 't' : 0 ? 'f' : 'n');"
t
```

```shell-session:ruby
$ ruby -e "puts (true ? 't' : false ? 'f' : 'n')"
t
```

```shell-session:python
$ python -c "print ('t' if True else 'f' if False else 'n');"
t
```

```shell-session:php
$ php -r "echo (true ? 't' : false ? 'f' : 'n');"
f
```

言語ごとに思想があってしかるべきだと思うので、他と違うからだめだというわけでもないですが、じゃあ PHP に思想があるのかって話で・・・。

# PHP の思想？

## マニュアルでは

実際には、PHP はマニュアルで「なるべくネストさせるな」と言っています。

>Note:
It is recommended that you avoid "stacking" ternary expressions. PHP's behaviour when using more than one ternary operator within a single statement is non-obvious:

>Example #4 Non-obvious Ternary Behaviour

```php
<?php
// on first glance, the following appears to output 'true'
echo (true?'true':false?'t':'f');

// however, the actual output of the above is 't'
// this is because ternary expressions are evaluated from left to right

// the following is a more obvious version of the same code as above
echo ((true ? 'true' : false) ? 't' : 'f');

// here, you can see that the first expression is evaluated to 'true', which
// in turn evaluates to (bool)true, thus returning the true branch of the
// second ternary expression.
?>
```

## しかし

例を見ればわかりますが

```php
echo (true?'true':false?'t':'f');
```

これが、

```php
echo ((true ? 'true' : false) ? 't' : 'f');
```

こう解釈されるからわかりづらいんですよ、と PHP は言っているようなのです。そして、最初の式が (bool)true と判断されるから、と。
ということは、最初の式が false を返すと結果が変わるんですね。PHP はいろんな物を false として判定する言語なので、例えば以下の例では

```php
echo (true ? false : '1' ? 't' : 'f');
echo (true ? '0' : '1' ? 't' : 'f');
echo (true ? '' : '1' ? 't' : 'f');
echo (true ? array() : '1' ? 't' : 'f');
```

すべて、出力は `f` になります。わかりづらいよ・・・。

# 最後にそもそもですが

さんざん言っておいてなんですが、できればネストは避けるか、どうしてもネストさせたいなら、実用的には明示的に括弧をつける局面だと思います。

```shell-session:php
$ php -r "echo (true ? '0' : (false ? 'f' : 'n'));"
0
```

括弧さえつけておけば、評価順を気にする必要無いですからね。
これはもちろん PHP に限らずどの言語でも言えることです。
rubocop gemを使うためにたった1つの重要なこと

rubocopは`.rubocop.yml`を編集すれば、独自のルールを設定できる。
ただし、この設定ファイルはデフォルトの項目を **オーバーライド**する！

例えば、`AllCops/Exclude`に設定を追加したい場合、下記のように書かないとうまく動かない。

```.rubocop.yml
AllCops:
  Exclude:
    - 'vendor/**' # default.ymlに設定されている項目
    - 'tools/**'  # 追加したい項目
```

これは、先に書いたようにデフォルトの`AllCops/Exclude`がオーバーライドされてしまうため。

余談だが`AllCops/Exclude`から'vendor/**'が失われると、インストールされているgemに含まれる.rubocop.ymlが読み込まれることになり、特にrubocop 0.20.0以降、設定項目のrenameが行われたようで、下記のようなメッセージが表示され、原因の特定が難しくなるだろう。(というかハマった・・・のでこれ書いてる
`AllCops/Excludes was renamed to AllCops/Exclude`

ちなみに、デフォルトの設定が書かれているファイルはrubocop gemのディレクトリ下`config/default.yml`。
gemがvendor/bundle下にインストールされているなら`vendor/bundle/gems/rubocop-x.y.z/config/default.yml`にあるので、変更する際は参照してみると良いと思う。
Railsのマイグレーションのindex_exists?の罠

マイグレーションのインデックスネタをもう一つ。

手動でインデックスを追加しちゃった環境や、テストでDBを共用していて、何度もmigrationをかけるときのために、テーブルの変更には必ず存在チェックをしてから変更するように書いている。

初めて、index_exists?を使ったのだが、なぜか存在がうまく検出出来なかった。

```Ruby
unless index_exists?(:target_table, :name => 'additional_idx01') do
  add_index :target_table, [:col1, :col2], name => 'additional_idx01'
end
```

と書いて、名前で指定していたら確実だろうと勝手に想像していたが、なぜか正しく検出できなかった。

試しに以下のように書き直すと、成功した。

```Ruby
unless index_exists?(:target_table, [:col1, :col2], :name => 'additional_idx01') do
  add_index :target_table, [:col1, :col2], name => 'additional_idx01'
end
```

なんで、名前を正しく指定しているのに検出出来ないのだろう。なんでカラムを全て記述しないといけないんだろう。カラムと名前が合っていないときは、どうなるんだろう。

なんて役に立たないんだ！ と腹を立てた今日でした。
Railsのマイグレーションで複合キーのインデックス

Railsのマイグレーションで複合キーのインデックスを貼る作業をした。
対象のRDBMSはMySQLでしかも、複合キーとなるカラムにTEXTがあったので、lengthを指定しなければいけなかった。

SQLで書くとこんな感じ。

```SQL
ALTER TABLE target_table ADD INDEX additional_idx01(    
    long_text(255)   ,
    saved_on      
)
```

最初は http://railsdoc.com/migration#%E3%82%A4%E3%83%B3%E3%83%87%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AE%E8%BF%BD%E5%8A%A0(add_index) で調べていた。

これによると、複合キーの場合のインデックスの追加は

```Ruby
add_index :target_table, [:long_text, :saved_on], :name => 'additional_idx01'
```

で、いけるらしい。
しかし、これでは長さが指定出来ないので、migrateでSQLエラーが発生する。

ドキュメントでインデックスの長さを指定する例を見てみると

```Ruby
add_index :users, :name, :name => 'by_name', :length => 10
```

と、書いてある。長さはオプションで指定するらしいのだが、このままだとカラム全体に長さ制限が掛かってしまう。
試しに、以下のように書いてみたがもちろんSQLエラー。

```Ruby
add_index :target_table, [:long_text, :saved_on], :name => 'additional_idx01', :length => 255
```

散々悩んで、WEBをあさりまくったら、英語圏のブログに解決策を書いているおっさんがいた。感謝感謝。

結局解決した記述。

```Ruby
add_index :target_table, [:long_text, :saved_on], :name => 'additional_idx01', :length => {:long_text => 255}
```

こんなん想像つくかーーーー！！！！

最初、第2引数に配列が書けるだけでもショックだったのに、オプションの指定で値ではなくハッシュが渡せるなんて。Ruby界隈の人はこれは当たり前なんだろうか。
ChefDk (Chef Development Kit)でお手軽Chef構築

Chef Dkなるものが公開されていたので、入れてみた。
試したのはXubuntu 12.04 LTS
ChefDkのバージョンは0.0.1
Ubuntuでもきっと同じ方法で動くと思う。

[http://www.getchef.com/downloads/chef-dk/](http://www.getchef.com/downloads/chef-dk/)

からダウンロードしてdebパッケージをインストールする。

```bash:shell
sudo dpkg -i chefdk_0.0.1-1_amd64.deb
```

~/.bashrcに追加

```bash:.bashrc
export PATH=/opt/chefdk/embedded/bin:$PATH
```

とこれだけで、rubyとchefとberkshelfが使えるようになる。
ただこのままだとsudoが必要で扱いづらいので、グループを変更した。

```bash:shell
sudo chmod -R g+rwx /opt/chefdk/
sudo chgrp -R adm /opt/chefdk/
```

knife-soloは入ってないので必要なら入れる

```bash:shell
gem install knife-solo
```

vagrantと同じく依存関係がパッケージングされてるようなので
手軽にChefを構築出来そう。
何よりberkshelfが同梱されているのが良い。

デメリットというか注意点としては既存のruby環境を上書きしてしまうので、
ruby関係はgem含めすべてアンインストールしてから行う。
docker の container に、host 上にあるファイルをコピーする

docker run 時に -v で mount させるファイル/ディレクトリを指定できるので、それを使う。

```shell-session
Host# docker run -v /home/hoge/shared:/shared -d -i -t ubuntu /bin/bash
Host# docker attach <CONTAINER-ID>
Container$ cp /shared/hoge.conf .
```

最初、rsync でもしないとあかんのかなと思って必死に設定してたけど、どうってことはなかった。
Android で非同期でファイル一覧みたいなもののサムネイル表示する例 ThreadPoolExecutor を使う場合

# ThreadPoolExecutor を使ってサムネイル表示する例

## ぜんてい

1. 非同期でやりたい
2. サムネイル用の画像ファイル自体が無い場合も想定
3. ImageView に画像を表示
4. ネットワーク通信はしない

## ポイント

1. ThreadPoolExecutor を使うよ
2. LinkedBlockingQueue がベストなのかわからん
3. 非同期だから WeakReference 使うよ

## ソース

**ThreadPoolExecutor を用意するメソッド**

```java
    /**
     * thumbnailManagerExecutor のスコープは private です
     * 
     * @return executor
     */
    private ThreadPoolExecutor getThumbnailExecutor() {
        if (thumbnailManagerExecutor == null || thumbnailManagerExecutor.isShutdown()) {
            thumbnailManagerExecutor = new ThreadPoolExecutor(4, 10, 3600, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
        }
        return thumbnailManagerExecutor;
    }
```

ThreadPoolExecutor のコンストラクターの引数について

- corePoolSize アイドルであってもプール内に維持されるスレッドの数 => 4
- maximumPoolSize プール内で可能なスレッドの最大数 => 10
- keepAliveTime- スレッドの数がコアよりも多い場合、これは超過したアイドル状態のスレッドが新しいタスクを待機してから終了するまでの最大時間 => 3600
- unit keepAliveTime 引数の時間単位
- workQueue タスクが超過するまで保持するために使用するキュー。このキューは、execute メソッドで送信された Runnable タスクだけを保持する


**ImageView にサムネイルをセットする**

```java
    /**
     * ImageView にサムネイルをセットする
     * 
     * @param icon
     *            ImageViewです
     * @param FileItem
     *            ファイル情報が入ったコンテナ
     */
    public void setThumbnailIntoView(final ImageView icon, final FileItem item) {
        // ★WeakReference を使いましょう
        final WeakReference<ImageView> iconHolder = new WeakReference<ImageView>(icon);
        final Resources res = icon.getResources();
        getThumbnailExecutor().execute(new Runnable() {
            public void run() {
                // デフォルトのサムネイルか何かを表示させる処理
                setThumbnail(iconHolder.get(), getDefaultIconResource(item));
                // ファイルのサムネイル（ドキュメントの縮小版画像とか）のキャッシュがあれば取得する処理
                Bitmap cachedIcon = getCachedIcon(item);
                // キャッシュがあったら、デフォルトのサムネイルから置き換える処理
                if (cachedIcon != null) {
                    setThumbnail(iconHolder.get(), new BitmapDrawable(res, cachedIcon));
                }
            }
        });

    }
```


## さんこうしりょう

- box/box-android-sdk-v2 - http://goo.gl/K6a7sP
- Java の BlockingQueue 実装の性能を比較してみた ~ blog.k11i.biz - http://goo.gl/z7Fjgy
- 画像ダウンロードでAsncTaskを立ち上げまくるのはやめましょう - satohu20xx's diary - http://goo.gl/ejtK7N
- Executorsを利用してみる - happytanの足跡 - http://goo.gl/GVrgRK

QiitaでもThreadPoolExecutor関連記事を書いている人がいました

- Java - ExecutorService の復習 - Qiita - http://goo.gl/VBu7fz
JAX-RSのサブリソースでEntityManagerを使用する。

# 概要

JAX-RSのサブリソースでEntityManagerを使用する際に試行錯誤したのでその経緯をメモに残します。

* ボツ：ルートリソースからEntityManagerを引き回す。
 * findは問題ないが、mergeなどDBの書き換えでTransactionRequiredExceptionが発生しました。
* 成功：サブリソースをStateless Session Beanにして、ルートリソースに@Injectする。

# 環境
* GlassFish 3.1.2.2
* Java EE 6

# ボツ：ルートリソースからEntityManagerを引き回す。

ルートリソース

```java
@Stateless
@Path("/")
public class A {
    
    @PersistenceContext(unitName="jaxrsejbsamplePU")
    private EntityManager em;

    public A() {
    }
    
    @Path("/{id}/ra1")
    public B resource1(@PathParam("id") int id) {
        return new B(em, id);
    }    
}
```

サブリソース

```java
public class B {
    EntityManager emA;
    int id;
    public B() {
    }
    
    public B(EntityManager em, int id) {
        this.emA = em;
        this.id = id;
    }
    
    @GET
    @Path("rb1")
    @Produces(MediaType.APPLICATION_XML)
    public TableA resource1() {
        TableA tabA = emA.find(TableA.class, id);
        tabA.setCola(tabA.getCola()+"1");
        emA.merge(tabA);
        return tabA;
    } 
}
```

サブリソースではTableAのcolaフィールドの文字列に"1"という文字を追加してマージしています。mergeメソッド実行時に、以下のエラーが発生してしまいました。

`javax.persistence.TransactionRequiredException`

ルートリソースではサブリソースをnewしているのですが、ここでトランザクションから外れてしまうことが原因と思われます。

そこで以下の方法を試してみました。

# 成功：サブリソースをStateless Session Beanにして、ルートリソースに@Injectする。

ルートリソース

```java
@Stateless
@Path("/")
public class A {
   
    @Inject
    private B b;
    
    public A() {
    }
        
    @Path("/{id}/ra2")
    public B resource2() {
        return b;
    }
}
```

サブリソース

```java
@Stateless
public class B {
   
    @PersistenceContext(unitName="jaxrsejbsamplePU")
    EntityManager em;
    
    public B() {
    }
            
    @GET
    @Path("rb2")
    @Produces(MediaType.APPLICATION_XML)
    public TableA resource1(@PathParam("id") int id) {
        TableA tabA = em.find(TableA.class, id);
        tabA.setCola(tabA.getCola()+"1");
        return tabA;
    } 
    
}
```

今度はバッチリです。エラーは発生しませんでした。mergeしなくてもトランザクションの中なのでtabAがmanaged状態のため、colaフィールドの値が更新されます。

@Injectにすると元々ルートリソースで取得してサブリソースに渡していたパスパラメータidが渡せなくなるのですが、サブリソース側で@PathParamで取得できました。さすがJAX-RS！空気読めるヤツです。

ただし、GlassFishには以下のバグがあるようなので要注意です。

* JAX-RSにEJBをinjectする際の注意点 その２
　http://www.coppermine.jp/docs/programming/2012/12/jax-rs-ejb2.html

# 参考

今回の対応にあたり、CDI、EJBがよくわかっていなかったので調査しました。以下の記事は大変分かりやすく参考になりました。

* CDIが業務システム開発にもたらすメリットとは？ EJBとの使い分けは？──最新Java EE開発“虎の穴” 第3回 上妻宜人氏　 http://builder.japan.zdnet.com/sp_oracle/weblogic/35045391/
Android Youtube API で動画を自動再生するには loadVideo を使う

# Android Youtube API で動画を自動再生するには loadVideo を使う

```java
	@Override
	public void onInitializationSuccess(YouTubePlayer.Provider provider,
			YouTubePlayer player, boolean wasRestored) {
		if (!wasRestored) {
			player.loadVideo(video_id); // ここ。サンプルコードにある cueVideo だと自動再生されない
			// player.cueVideo(video_id);
		}
	}
```
Pixivタグ検索結果からMeCab辞書を生成する

#概要
[Pixiv](http://www.pixiv.net)のタグ検索結果から、[MeCab](http://mecab.googlecode.com/svn/trunk/mecab/doc/index.html)の辞書を生成・適用する。
特定用途に特化したテキストマイニングをするなら、ありかもしれない。
[ピクシブ百科事典](http://dic.pixiv.net/)にまだ載っていないタグも取れる。
　※実行環境はLinuxMint13(Ubuntu12.04 LTS)です。

#方法
##01.Pixiv検索結果のデータを取得する。
[-> Pixiv検索結果をCSVダウンロードするHTMLファイルを用意した](http://qiita.com/nezuq/items/55800d55c03606e0b13c)

##02.取得データと同じ階層に下記Rubyコードを配置する。
  ※取得データのファイル名は「INPUT.csv」にすること。

```rb:pxcsv2mecab.rb
# coding: UTF-8

require 'csv'

#しきい値（出現回数が指定範囲外のタグは出力しない）
MIN_COUNT = ARGV[0] || 3
#入力ファイル名
INPUT_CSV = ARGV[1] || 'INPUT.csv'
#出力ファイル名
OUTPUT_CSV = ARGV[2] || 'pixiv.csv'
#表示しないタグのパターン
UNDISP_KEYPATTERN = Regexp.new (ARGV[3] || "漫画|落書き")

h = {}
h.default = 0
CSV.foreach(INPUT_CSV, encoding: "UTF-8") do |row|
    row[13].split(' ').each do |item|
        h[item.downcase] += 1
    end
end

CSV.open(OUTPUT_CSV, "wb") do |csv|
    h.sort_by{|key, cnt|
        -cnt
    }.each do |set|
        break if (set[1] < MIN_COUNT)
        next if (set[0] =~ UNDISP_KEYPATTERN)
        word = set[0]
        cost = [-32768, (6000 - 200 *(word.length**1.3))].max.to_i
        csv << [word,0,0,cost,'名詞','一般','*','*','*','*',word,'*','*','pixiv']
    end
end

puts 'end!'
```
※コスト計算方法は[こちらのサイト](http://yu8star.blog9.fc2.com/blog-entry-16.html)を参考にさせてもらった。

##03.Rubyコードを実行する。
```
ruby pxcsv2mecab.rb
```
※pixiv.csvが同階層に出力される。

##04.MeCabの辞書を生成・適用する。
出力したCSVを使い、[MeCab: 単語の追加方法](http://mecab.googlecode.com/svn/trunk/mecab/doc/dic.html)の「ユーザ辞書への追加」を実行した。
ただし、辞書生成コマンドは下記のようにした。
```
/usr/local/libexec/mecab/mecab-dict-index -d/usr/local/lib/mecab/dic/ipadic -u pixiv.dic -f utf-8 -t utf-8 pixiv.csv
```

#結果
にこまきは、ラブライブ!の矢澤にこと西木野真姫のカップリングです。
にこまき	名詞,一般,*,*,*,*,にこまき,*,*,pixiv
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
、	記号,読点,*,*,*,*,、,、,、
ラブライブ!	名詞,一般,*,*,*,*,ラブライブ!,*,*,pixiv
の	助詞,連体化,*,*,*,*,の,ノ,ノ
矢澤にこ	名詞,一般,*,*,*,*,矢澤にこ,*,*,pixiv
と	フィラー,*,*,*,*,*,と,ト,ト
西木野真姫	名詞,一般,*,*,*,*,西木野真姫,*,*,pixiv
の	助詞,連体化,*,*,*,*,の,ノ,ノ
カップリング	名詞,一般,*,*,*,*,カップリング,カップリング,カップリング
です	助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
。	記号,句点,*,*,*,*,。,。,。
EOS


#感想
ラブライブ百合SS内では、
にこちゃん・まきちゃん・えりち・のんたん等のニックネームが多用される。
SSのテキストマイニングするなら、こんなんじゃ甘いよ（棒読み）
Twitterのハッシュタグを集めなきゃ……（使命感）
【facebook php sdk】ログアウトする

#ログアウトする方法
```php:logout.php
$config = array(
    'appId'   => APPID,
    'secret'  => SECRET,
);
$facebook = new Facebook($config);
$logoutUrl = $facebook->getLogoutUrl();
//これがないとセッションを保持してしまうため、別のアカウントでログインできない
//次ログイン画面を出してもID, パスワードの画面が出ない
$facebook->destroySession(); 
header("Location: ".$logoutUrl);
```
OnSharedPreferenceChangeListener が動かない！何で？というときは無名関数になってないかを疑う

# OnSharedPreferenceChangeListener が最初は呼ばれるんだけどしばらくすると呼ばれなくなるよ

## 現象

SharedPreference の更新時に自動的に何かの処理をするとき **SharedPreferences#registerOnSharedPreferenceChangeListener** 使ってリスナー登録する。でも、しばらくすると「リスナーが呼ばれてないんだけど」という現象が起こる。例えばこんなコード。

```java
// prefs は SharedPreference
prefs.registerOnSharedPreferenceChangeListener(
  new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // TODO なんか実装
  }
});
```

## 理由

**これだと、GC 対象になってリスナーが知らないうちに消えてるから注意！**

## 解決方法

1. 無名関数はやめよう
2. 普通にリスナーをインスタンス化したものを　registerOnSharedPreferenceChangeListener　しよう

```java
// インスタンス化したものを用意、 listener が参照を保持してれば GC されない
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
  public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
    // TODO なんか実装
  }
};
// ここで登録する
prefs.registerOnSharedPreferenceChangeListener(listener);
```

■おわり ak