OmniAICreator/Qiita-1.07M huggingface dataset:
【Swift】【Ruby on Rails】プッシュ通知ASPを利用した通知の導入

#概要
WEBアプリ（Rails）からiOSアプリ（Swift）にプッシュ通知を送る。
特定のユーザのみに通知が遅れるようにする。


##プッシュ通知とは？
アプリ内でプッシュ通知を行うこともできるんですが、外部から通知を行うことも可能です。
アプリ内のプッシュ（ローカルプッシュ）と外部からのプッシュ（リモートプッシュ）の使い所は
僕は以下のように考えています。

・ローカルプッシュ
スケジューリングされたイベントを通知する場合
処理の完了や開始などを通知

メリット　簡単
デメリット　外部からの情報をプッシュするためには一手間必要
　⇨　データ通信機能を自作してアプリ内でプッシュ

・リモートプッシュ
外部主体の通知をする場合
一斉に情報を通知したい場合

メリット　とにかく便利
デメリット　手間


##構成
![image](https://qiita-image-store.s3.amazonaws.com/0/69919/77acef1a-b8c1-59a5-59e6-e69718f72093.png)
本来ならプッシュ通知のために複雑な構成をしなくてはいけないところを、
簡単なコーディングでプッシュ通知が実現できます。
管理コンソールからプッシュ通知をするだけならRailsサーバなしの構成でも大丈夫です。

【Swift】mobile backend を利用したpush通知　http://qiita.com/tdaiku/items/6471906e578435a8b3ed

##サーバから送信するために
１ vendor/assets/javascripts　にmobile backendにて提供されているJavascriptファイルを配置

２ app/assets/javascripts/application.jsに
　　`//= require ncmb-latest.min.js`
　を追記

3 処理を行う機能のcoffee scriptファイルに

```coffeescript:script.js.coffee

NCMB.initialize("APP_KEY", "CL_KEY");
        NCMB.Push.send {
          'immediateDeliveryFlag': true
          'target': ['ios']
          "searchCondition": 
            "deviceToken": "deviceToken"
          'badgeIncrementFlag': false
          'deliveryExpirationTime':'10 day'
          'title': 'title'
          'message': 'message'
        },
          success: ->
            alert 'Successful!'
            # 成功
            return
          error: (error) ->
            # エラー
            alert 'Failed'
            return

```

・deleveryExpirationTimeをセットしないとなぜか送られなかった
・ユーザ単体に送信する機能のためにiOSアプリからdeviceTokenを随時RailsSVに送信している
　⇨OSアップデートなどでdeviceTokenが変わる可能性があるらしいので、、、
　⇨端末のdeviceTokenは`NCMBInstallation.currentInstallation().deviceToken`で取得できる
・targetは準備されていない方が入っている場合、指定しないと配信エラーになる
　⇨androidはキーを設定、iOSは証明書を設定する必要がある


##まとめ
日本語のドキュメントがあるって素晴らしい。
ただなかなかマニュアルが見辛いです。
APIリファレンスを見ていても、パラメータのセット例が書いてなかったりしてセットの方法がわからなかったりします。
http://mb.cloud.nifty.com/doc/
iOS、Android、javascriptの切り替えがコンボボックスってのも操作性が悪いですね。

ライブラリが整備されていて、きちんとした管理画面があるので自作するコストを考えればかなり楽です。
オススメ。

有料プランの導入も視野に入れていこうかと思います。
Raspberry Pi + センサ + Jubatus 0(構想段階)

##センサを用いた機械学習
機械学習に使えそうなセンサ一覧をあげてみる

* 圧力センサ → 上に乗ったものが何かクラスタリング
* 温度センサ → ここが部屋なのか廊下なのか
* 光センサ → 研究室にいるのか廊下にいるのか
* 超音波センサ → 人が座席にいるかいないか
* 人感センサ → 人がいるかいないか

##人感センサ＋Jubatus
人感センサを用いて機械学習を簡単に行ってみようと思う．人が座席に座ってるか座っていないかを異常値検出（Anormaly）する．まずはJubatusのAnormalyのチュートリアルを改造して作ってみようかと思う.   

* RaspberryPi + 人感センサで検索してみると，デジタル出力で人がいるかどうか判断しているものが多い．

##光センサ＋Jubatus
光センサを使って，電灯を点けるか消すかを判断するプログラムを作る．今回は判断するだけであって，実際に電灯を操作する部分までは作らない．

* 光センサの値はアナログ値である
* 電灯を点けるべきか消すべきかのしきい値をJubatusで算出

これならなんか簡単に作れそう……これにしよう！



ということで次回は，光センサ+Jubatusについてやってみようかと思う．
Django: FormのDateTimeFieldにAdminのJSを適用


## forms.py

~~~py
from django import forms    
from django.conf import settings                                                        
from django.contrib.admin.widgets import AdminSplitDateTime                         
from django.contrib.admin.templatetags.admin_static import static                   
~~~

- [ModelAdmin で要求されるmedia](https://github.com/django/django/blob/master/django/contrib/admin/options.py#L555) をコピる

~~~py
    def admin_media():
        extra = '' if settings.DEBUG else '.min'
        js = [
            'core.js',
            'admin/RelatedObjectLookups.js',
            'jquery%s.js' % extra,
            'jquery.init.js',
            'actions%s.js' % extra,
            'urlify.js',
            'prepopulate%s.js' % extra,
        ]
        return forms.Media(
        	js=[static('admin/js/%s' % url) for url in js])    
~~~

~~~py
class YouForm(forms.Form):                                                     

    send_at = forms.DateTimeField(                                                  
        required=False,                                                             
        widget=AdminSplitDateTime,)                                                 

    @property                                                                       
    def admin_media(self):                                                          
        return admin_media()     
~~~

### js のオーダー

- Form.Media.js に定義するとすべてのjsをform.media['js'] で参照できるようになるが、jsの依存関係があるので、分離して別途レンダリング出来た方がよいかな

~~~py
class YouForm(forms.Form):                                                     

    class Media:
    	js = admin_media()                                                                       
~~~

## テンプレート

~~~html
{% block extrahead %}
{{ block.super }}
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
{{ form.admin_media }}		{# 先にインクルードしておく #}
{{ form.media.css }}		{# フォームで必要とされるCSS #}
{% endblock %}
~~~

~~~html
{% block content %}
...
<form method="post"> {% csrf_token %}
<table>
 {{ form.as_table }}
</table>
<input type="submit" value="Send" />

{{ form.media.js }}		{# フォームで必要とされるJS #}

</form>
</div>
{% endblock %}
~~~
CentOS 6.6にR Studio Serverをインストールする

# Rのインストール
```
$ sudo rpm -ihv http://ftp.riken.jp/Linux/fedora/epel/6/i386/epel-release-6-8.noarch.rpm
$ sudo yum -y install R
```
# R Studio Serverのインストール
```
$ wget http://download2.rstudio.org/rstudio-server-rhel-0.99.441-x86_64.rpm
$ sudo yum -y install --nogpgcheck rstudio-server-rhel-0.99.441-x86_64.rpm
```
# 日本語文字化け対応
```
$ sudo yum -y groupinstall "Japanese Support"
```
# 動作確認
http://192.168.33.10:8787/ (IPはサンプル)

もしうまくアクセスできないときは以下のコマンドを試してみる。

```
$ sudo rstudio-server verify-installation
```
heroku run をプロキシ経由で動かす

`heroku run`はHTTP経由での通信ではないので、http_proxy等を設定していてもUnable to connect to Heroku APIになってしまう。

そうなるとせっかくデプロイしたアプリのDBマイグレーションなどを実行することができず、ああ、プロキシさえなければ・・・とほぞをかむような事態になってしまうが、以下で対応可能。

`heroku run:detached`

こうすると投げたコマンドがHeroku側で実行されて、ログで実行結果が見られるようだ。

[Unable to run "heroku run" via proxy](https://github.com/heroku/heroku/issues/658)
プリプロセッサを使わないC/C++互換hello, world


問題：https://twitter.com/Nabetani/status/592538694571008001

```
#CodeIQ で出そうと思ったけどやめた問題： 「C++14 と C99 のどちらでも動作する hello, world を書いて下さい。ただし、『#include』『#define』『#if』などのプリプロセッサディレクティブは使用禁止。ideone で動作確認。」
```

通常、C/C++互換プログラムはプリプロセッサを使って書く。
プロトタイプ宣言を普通に書くと、C++モードでコンパイルした時のリンケージがC形式でなくなるのでリンクに失敗する。
かといってextern "C"するとCでコンパイルできないので困ったことになる。

私の解法はこう。[ガールフレンドめっちゃほしい！/nasm](https://github.com/cielavenir/codeiq_solutions/blob/master/q801/girl.asm)を移植した。

```asm.c
const char *str="hello, world\n";
int main(){
	__asm__(
		"movl $4,%eax;"
		"movl $1,%ebx;"
		"movl str,%ecx;"
		"movl $13,%edx;"
		"int $128;"
		"movl $1,%eax;"
		"xor %ebx,%ebx;"
		"int $128;"
	);
}
```

鍋谷氏の想定解法はこうだったらしい。しかし、Cではコンパイルできるが、C99 strictでは-Werrorのためコンパイルできず。

```nabetani_extern.c
int main() {
	extern int puts;
	((int (*)(char const*))&puts)("hello, world!");
}
```

tails氏の解法は\_\_builtin\_\_puts()を使っていて面白い。

```tails_builtin.c
int main() {
	__builtin_puts("hello work!\n");
	return 0;
}
```
【殴り書き】ゲームオブジェクトをグローバルなインスタンス１つ作って使いまわすぞー

シングルトンなクラスにすれば、Staticなグローバルなクラスになる。
シーンが移動してもDestroy(開放)されることはなく、最初に呼び出されたときに自身で作ったオブジェクトが生き続け、それを返し続ける。

ポイントは、ゲームオブジェクトがあるかどうかをシングルトンなクラス自身が管理して、なければ作って、あればそれを返す様にする為、
どのシーンで呼び出しても同じ実装でいける。ゲームオブジェクトが生きてるかどうかを気にする必要もない。

**手順**  

 * Bridge.csをシングルトンなゲームオブジェクトにする。
 * homeが実行と同時に呼ばれるシーン
 * secondはサブシーン
 * homeでゲームオブジェクトを作成し、secondで呼び出してみる。

---
```csharp:bridge.cs
public class Bridge: MonoBehaviour {

    private static Bridge instance; 
    public static Bridge Instance {
        get { 
            if (instance == null ) {
                GameObject gmObj = new GameObject ( "Bridge" );
                instance = gmObj.AddComponent< Bridge > ();
            } 
        return instance; 
        } 
    }

    public void printTest () {
        Debug.Log ("ブリッジ、生きてるよ。");
    }

    private void Awake () {
        DontDestroyOnLoad (this);
    }
}
```

```csharp:home.cs
・
・
・
void Start () {
    Bridge bi = Bridge.Instance;    // instance つくる
    bi.printTest ();     //なにか実行してみる

    if (Button ("scene change" )) {
        Application .LoadLevel ("second" );    //　シーンの移行
    }
}
・
・
・
```

```csharp:second.cs
public class second : MonoBehaviour {

             // Use this for initialization
             void Start () {
                        Bridge bi = Bridge.Instance;    // 2回目なのでさっきhomeで作られたオブジェクトが返される
                        bi.printTest ();
            }
}
```
*※Unity見習い中です！変なとこあったらどしどしコメントください！*
GitHubにPushするたびにパスワードが聞かれたら？



その原因はGitに使われているプロトコルがhttpsとなっているかも知れません。

```
$ git remote -v
origin  https://github.com/liubin/box.git (fetch)
origin  https://github.com/liubin/box.git (push)
```

`https`となっているため、`git`に書き換えます。

```
$ git remote set-url origin git@github.com:liubin/box.git

$ git remote -v
origin  git@github.com:liubin/box.git (fetch)
origin  git@github.com:liubin/box.git (push)
```

これで問題解決するはずです。
[Objective-C] バックグラウンドで継続して処理を実行する


通常、iOSアプリはバックグラウンドに回ったタイミングで処理が停止します。
これはバッテリーを長持ちさせるためにも必要な処置です。
しかしアプリによっては現在処理しているものが停止させられると困る場合があります。
（例えばなにかのダウンロード中は継続してダウンロードを終えるまで処理したほうがいいなど）

その場合に使えるのが、iOS4から実装されたマルチタスキングの機能です。
それを実現するためにはシステムに、「継続して処理を続けること」を伝えないとなりません。
そのためのメソッドが`UIApplication#beginBackgroundTaskWithExpirationHandler:`と`UIApplication#beginBackgroundTaskWithName:expirationHandler:`です。

[ドキュメントはこちら](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html)


## サンプルコード

起動したらずっと`NSLog`で値を出力するだけのサンプルです。
これを実行することでバックグラウンドに移行してもログが出力され続けるのが確認できます。
*（通常だとバックグラウンドに移行した時点でログ出力は止まる）*

ちなみにバックグラウンドに移行するタイミングで処理を開始、とかではなくて通常行っていた処理がそのまま継続します。

なお、セットで実行することとしては、フォアグラウンドに戻ってきた際に`[UIApplication.sharedApplication endBackgroundTask:self.bgid]`を実行してバックグラウンドタスクを終了する必要があります。
*（`self.bgid`は`UIBackgroundTaskIdentifier`型のID）*

```objc

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign) UIBackgroundTaskIdentifier bgid;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [NSNotificationCenter.defaultCenter addObserver:self
                                           selector:@selector(willResignActive:)
                                               name:UIApplicationWillResignActiveNotification
                                             object:nil];
    [NSNotificationCenter.defaultCenter addObserver:self
                                           selector:@selector(didBecomeActive:)
                                               name:UIApplicationDidBecomeActiveNotification
                                             object:nil];
    
    [self update];
}

- (void)update
{
    if (self.timer) {
        [self.timer invalidate];
        self.timer = nil;
    }
    self.timer = [NSTimer scheduledTimerWithTimeInterval:3
                                                  target:self
                                                selector:@selector(update)
                                                userInfo:nil
                                                 repeats:YES];
    
    NSLog(@"timer");
}

- (void)willResignActive:(NSNotification *)notification
{
    NSLog(@"resign");
    
    UIApplication *app = UIApplication.sharedApplication;
    self.bgid = [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:self.bgid];
        self.bgid = UIBackgroundTaskInvalid;
    }];
}

- (void)didBecomeActive:(NSNotification *)notification
{
    NSLog(@"become");
    
    [UIApplication.sharedApplication endBackgroundTask:self.bgid];
}

@end

```
Use keychain in OpenSSH from MacPorts


SSH bundled with OSX cannot handle ECDSA/ED25519 even on Yosemite.
So, some people recommend updating OpenSSH using Homebrew or MacPorts.
But, what about `ssh-add`? The bundled version has very nice integration with OSX Keychain, where you don't have to enter the passphrase in each login. We want to keep the feature.

I searched the Internet and found the information that I can pass `--with-keychain-support` to brew, but I couldn't find the information about MacPorts easily.
After investigating OpenSSH Portfile, I have found that gsskex varient does the work.

So, to enable ssh-add keychain feature, use this:
MacPortsのOpenSSHでキーチェーンを有効化するには次のようにします。

```bash
sudo port install openssh +gsskex
```

It is the same that you need to modify the startup file to load the correct ssh-agent.
スタートアップを書き換える必要があるのはHomebrewと同様です。

```bash
sudo sed -i '' 's/\/usr\/bin\/ssh-agent/\/opt\/local\/bin\/ssh-agent/' /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist
launchctl unload -w /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist
sudo killall ssh-agent
launchctl load -w -S Aqua /System/Library/LaunchAgents/org.openbsd.ssh-agent.plist
launchctl start org.openbsd.ssh-agent
export SSH_AUTH_SOCK=$(launchctl getenv SSH_AUTH_SOCK)
```

---

Finally, I introduce part of my .profile, which set up the ssh preference in starting up bash.

```bash
if [ "$TERMINAL_NAME" != "Apple_Terminal" ]; then
	#10.9 or below
	#export SSH_AUTH_SOCK=$(ls -1t /tmp/launch-*/Listeners|head -n 1)
	#10.10 or later
	export SSH_AUTH_SOCK=$(ls -1t /tmp/com.apple.launchd.*/Listeners|head -n 1)
fi
```

---

Well, I think GSSAPI has nothing to do with keychain, but the patch is put into one place...

---

[Edit] in the MacPorts (and Homebrew) version, the keychain-related switch is -M, not -K.
[Edit2] **You should remove all keychains before switching ssh-agent, or it will ask you to load keychain using Aqua, which causes soft-freeze on SSH.**

検索用：MacPortsのOpenSSHのssh-addでキーチェーンを利用する
ListViewのカラムスタイルを動的に切り替える

# 方法
以下のようにして成功した。

```xml
<GridViewColumn>
    <GridViewColumn.CellTemplate>
        <DataTemplate>
            <ContentControl Content={Binding}>
                <ContentControl.Style>
                    <Style TargetType="{x:Type ContentControl}">
                        <Style.Triggers>
                            <DataTrigger Binding="..." Value="...">
                                <Setter Property="ContentTemplate">
                                    <Setter.Value>
                                        <DataTemplate>
                                        ...
                                        </DataTemplate>
                                    </Setter.Value>
                                </Setter>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ContentControl.Style>
            </ContentControl>
        </DataTemplate>
    </GridViewColumn.CellTemplate>
</GridViewColumn>
```

# 注意
上記で、```<ContentControl>```タグで```Content={Binding}```が無いとバインドがうまく行かないようだ。

# 参考
1. [Change ListView CellTemplate based on state of item - Stack Overflow](http://stackoverflow.com/questions/5907528/change-listview-celltemplate-based-on-state-of-item)
2. [How to Bind To Data within a Datatemplate of a ContentControl - Stack Overflow](http://stackoverflow.com/questions/15389142/how-to-bind-to-data-within-a-datatemplate-of-a-contentcontrol)
phalcon-2.xインストールのメモ

# Phalcon2系の調査

* 既存Phalconをベースにアプリ作成
* 足りない機能だけ拡張・追加実装


~~~linux
cd /usr/local/src/


sudo git clone git://github.com/phalcon/cphalcon.git
cd cphalcon/build
sudo ./install


sudo git clone git://github.com/phalcon/phalcon-devtools.git
cd phalcon-devtools
sudo ln -s /usr/local/src/phalcon-devtools/phalcon.php /usr/bin/phalcon
sudo chmod ugo+x /usr/bin/phalcon


cd /var/www/html/
phalcon project PROJECT_NAME

~~~
Laravel5で便利クラス(Facade)使うときの儀式


Laravel5でCrypt使いたかったんです。

これ見ると、
http://laravel.com/docs/5.0/encryption

```
$encrypted = Crypt::encrypt('secret');
```

ということなんで、やってみます。

```
ERROR: Class App\Http\Controllers\Crypt does not exist
```


使えない・・・
それにCryptはController下にないし。。。。

実は、Controllerの上部でincludeしてやる宣言が必要です。

```php:
use Illuminate\Support\Facades\Crypt;
```

これで使えるようになります。

config/app.phpのaliasesに記載してあるものは、基本全てこの宣言が必要ぽい。

```php:
use Crypt;
```
これでもいけます。
MySQLとPostgreSQLのSELECT句でのサブクエリ仕様相違

MySQLだと以下の様にnum1と別名を付けたものを、同じSELECT句内で使用することが可能なのですが、PostgreSQLだと不可能でした。

```mysql
SELECT 1 as num1, (select(num1 + 1)) as num2
```

これは、MySQLの制約のゆるさ故のようですが、これをPostgreSQLやろうとした場合、以下のようにすることで可能なようです。

```postgres
WITH tbl AS (SELECT 1 as num1)
SELECT num1, num1 + 1 AS num2 from tbl
```
JQueryでAjaxを利用する(2)

参考
http://ascii.jp/elem/000/000/458/458236/

###セレクターの内容に折り返し処理をするeach()
[jQueryでAjaxを利用する(1)]では、セレクターを指定した内容に対して折り返し処理をするeach()という命令が登場しました。jQueryを使ったプログタムでは良く利用する命令です。
　
each()は、以下のような書き方で使用します。

>```
$(セレクター).each(function(){
	//折り返し処理
})
>```

折り返し処理とはどういったものなのでしょうか、table要素のサンプルを使って説明しましょう。

sample4(HTML)
>```
<table>
    <tr><th>text(...)</th><td>テキストを変更する</td></tr>
    <tr><th>html(...)</th><td>HTMLを変更する </td></tr>
    <tr><th>prepend(...)</th><td>要素内の先頭にHTMLを挿入する</td></tr>
    <tr><th>append(...)</th><td>要素内の最後にHTMLを挿入する</td></tr>
    <tr><th>before(...)</th><td>要素の前にHTMLを挿入する</td></tr>
    <tr><th>after(...)</th><td>要素の後にHTMLを挿入する</td></tr>
</table>
>```

sample4(実行結果)
>
![スクリーンショット 2015-05-28 14.54.57.png](https://qiita-image-store.s3.amazonaws.com/0/59354/5f477d2d-44b9-9a9d-517e-ce9ca12c1347.png "スクリーンショット 2015-05-28 14.54.57.png")
>
 
　```tr```要素の中にあるth要素とtd要素のテキストを「は」というテキストで結合し、```td```要素で包み直しています。

　単純にtr要素をjQueryのセレクターで指定すると```$("table tr")```ですが、このセレクターでは```table```要素内のすべての```tr```要素を一括して選択しています。sample4の実行結果のように、複数の```tr```要素を１つずつ異なる内容に書き換えるといったことはできません。
　
　これに対してeach()は、セレクターで指定した要素が複数含まれる場合に、その要素を１つずつ取り出して、```function(){...}```内の命令を１回ずつ、含まれる要素の回数だけ実行していきます。
　
sample4(スクリプト)
>```
<script type="text/javascript">
$(function(){
	$("table tr").each(function(){
		$(this).html("<td>"+$("th",this).text()+"は"+$("td",this).text()+"</td>");
	})
})
</script>
>```

　each()と一緒に利用する「this」は、「現在処理をしている要素」を表します。htisはclickイベントの処理でも登場したが、意味が少し違います。たとえば、$(this).html(...)と記述した場合は、現在処理をしている要素の中身を別のHTMLに書き換えます。
　jQueryのセレクターの後ろには,(カンマ)区切りで範囲を絞り込めます。each(function(){...})でセレクターの範囲にthisを指定することで、現在処理をしている要素の内側の要素を指定できます。
Qiitaの投稿を手っ取り早くPDF化

用途：Qiita:Teamで書いた議事録を、外部にPDFファイルで提出しなければならないような時……

# 手動

Chromeで確認した方法です。
たぶんこれが一番楽だと思います。

1. 投稿内容を範囲選択
1. 右クリックメニューから印刷
1. 送信先を「PDFに保存」

なおWebページ全体を印刷すると、レイアウトが崩れるようです。

# 自動

1. Markdownファイルを取得
    * URLの末尾に.mdを付与
        * http://qiita.com/piyo7/items/4cd941752d2d60c1e5df.md
    * Qiita APIで取得
        * [Qiita API v2ドキュメント](https://qiita.com/api/v2/docs)
1. PandocでPDFに変換
    * [Pandoc ユーザーズガイド 日本語版](http://sky-y.github.io/site-pandoc-jp/users-guide/)
Vaadin 講習会 その1

Vaadin を使いこなせるようになるため講習会を開く。
まずはプロジェクト作成、HelloVaadinあたりから。

#Mavenプロジェクト作成
Mavenプロジェクト作成の仕方は
[こちらを参照](http://qiita.com/gishi_yama/items/68c159deba7473f90772)

#Labelコンポーネントを使った例
```lang:LabelPractice
package com.example;

import javax.servlet.annotation.WebServlet;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.annotations.Widgetset;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

/**
 *
 */
@Theme("mytheme")
@Widgetset("com.example.MyAppWidgetset")
public class LabelPractice extends UI {
	@Override
	protected void init(VaadinRequest vaadinRequest) {
		//縦にコンポーネントを配置するlayuout生成・セット
		final VerticalLayout layout = new VerticalLayout();
		setContent(layout);

		//デフォルトの配置だと左上に寄せられるので、少し見やすくなるようにマージンをとる
		layout.setMargin(true);

		//これも縦の配置がギュウギュウ詰めならないようにスペースをとる
		layout.setSpacing(true);

		//文字列コンポーネントを用意 ContentMode.TEXTは省略可能
		Label label1 = new Label("Hello Vaadin.",ContentMode.TEXT);
		layout.addComponent(label1);

		//改行コード等を含めたい場合 第二引数にContentMode.PREFORMATTEDを指定
		Label label2 = new Label("Hello Vaadin.\nHello Vaadin.",ContentMode.PREFORMATTED);
		layout.addComponent(label2);

		//文字列コンポーネントhtmlで記載する。第二引数にContentMode.HTMLを指定
		Label label3 = new Label("<h3>h3テキストです。</h3>",ContentMode.HTML);
		layout.addComponent(label3);

		//文字列をテキストフィールドに入れた値で変化させる
		Label label4 = new Label("文字列が変化します");
		layout.addComponent(label4);
		TextField editor = new TextField(null,label4.getValue());
		editor.addValueChangeListener(event -> label3.setValue(editor.getValue()));
		editor.setImmediate(true);
		layout.addComponent(editor);
	}
	@WebServlet(urlPatterns = "/LabelPractice/*", name = "LabelPractice", asyncSupported = true)
	@VaadinServletConfiguration(ui = LabelPractice.class, productionMode = false)
	public static class MyUIServlet extends VaadinServlet {
	}
}
```

#実行結果

![スクリーンショット 2015-05-28 14.23.38.png](https://qiita-image-store.s3.amazonaws.com/0/44465/6d8b071d-b359-85ab-26b0-13ec2eca672f.png)
Genymotionの仮想端末に Google Play をインストール


以下のページを参考に ARM Translation と GApps をインストール

http://forum.xda-developers.com/showthread.php?t=2528952




## ARM Translation Installer のダウンロード


![スクリーンショット 2015-05-28 13.58.20 のコピー.png](https://qiita-image-store.s3.amazonaws.com/0/8219/d78e8201-af36-2b43-bb85-cc8e53b47d88.png "スクリーンショット 2015-05-28 13.58.20 のコピー.png")

## Google Apps for Android のダウンロード

仮想端末は4.4.4で作ったので "4.4"系を選択

![スクリーンショット 2015-05-28 13.59.34.png](https://qiita-image-store.s3.amazonaws.com/0/8219/96858877-b453-59ea-5490-cc753310424b.png "スクリーンショット 2015-05-28 13.59.34.png")

先頭のリンクからダウンロードしたものが正常に動作しなかったので "Download from CM11 Links" からダウンロード

http://wiki.cyanogenmod.org/w/Google_Apps#gappsCM11


![スクリーンショット 2015-05-28 14.03.34.png](https://qiita-image-store.s3.amazonaws.com/0/8219/5412fe76-123a-07ef-1c84-b662330a8c6a.png "スクリーンショット 2015-05-28 14.03.34.png")

ダウンロードしたら以下のコマンドで MD5 を確認

```
$ openssl md5 /Users/xxxx/Downloads/gapps-kk-20140606-signed.zip
MD5(/Users/xxxx/Downloads/gapps-kk-20140606-signed.zip)= d840e20fba6f0e2b85d1aebe493a88fa
```


## インストール

インストールは ARM Translation -> GApps の順番に、ダウンロードした zip ファイルを Genymotion の仮想端末のウィンドウにドラッグ＆ドロップでOK

インストールするたび「再起動」を要求してくるので、仮想端末を再起動する。

無事 Google Play Store からアプリインストールできた。

![スクリーンショット 2015-05-28 14.55.53.png](https://qiita-image-store.s3.amazonaws.com/0/8219/584e57bd-362b-f90b-4f28-d288ea5e9d90.png "スクリーンショット 2015-05-28 14.55.53.png")
Dockerコンテナのtimezone

アパッチのログがお昼ぐらいにも関わらず、午前３時とかになってる・・・

```log:/var/log/httpd/error_log
      :
[Thu May 28 03:29:56 2015] [error] ....
      :
```

変だなと思って調べてみると・・・
UTCになってる。

```bash
$ date
Thu May 28 03:54:52 UTC 2015
```

今までＯＳインストールすると日本語を選ぶので、こうなっている状況は初めて、変更方法をググるとある設定ファイルをコピーするといいらしい。
あれ？「-f」をつけているにも関わらずoverwriteの確認。
手動の場合はいいけど、Dockerでビルドするときまずくない？

```bash
# cp -f /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
cp: overwrite `/etc/localtime'? y
```

これもなんでこうなるのか・・・どうやらAliasっぽい・・・

```bash
# alias
alias cp='cp -i'
      :
```

コマンドでたたく場合は「\cp」とするか「/bin/cp」とすればいい。

デフォルトの設定を変えるかunaliasでもいいとは思うけど、それも面倒なのでDockerfileの中はこうしておけばいいということですね・・・

```text:Dockerfile
      :
RUN /bin/cp -f /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
      :
```

これでapacheのログも日本時間。
[ネタ] T4を活用してC#をスクリプトっぽく使う

以前の記事で、C#とT4が共存できることを示しましたが、

これを活用してVisualStudio上でC#コードをスクリプトっぽく手軽にコーディングや実行ができるのではないかと思いついたのでやってみました

早速コードです

```SharpScript.cs
#region T4ディレクティブ設定
/*
<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<#@ import namespace="System.Windows.Forms" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Drawing" #>
<#@ output extension="output.txt" #>
プロジェクト内のクラスを利用する場合はコメントを外す
<#//@ assembly name="$(ProjectDir)$(OutDir)$(TargetFileName)" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Drawing" #>
<#@ assembly name="System.Windows.Forms" #>
<# GenerationEnvironment.Length = 0; SharpScript_Start(); #>
<#//*/
//#><#+/*
#endregion
#region C#クラス設定
//C#上でMainメソッドを有効にする場合はコメントを外す
//#define USEMAIN
//T4関連クラスのインテリセンスを有効にしたい場合はコメントを外す(要アセンブリ設定)
//#define USET4CLASS
#endregion
#region クラス定義
using System;
using System.IO;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;
using System.Drawing;
//WindowsForms関連クラスを使用するときはコメントを外す
//using System.Windows.Forms;

class SharpScript
#if USET4CLASS
    : Microsoft.VisualStudio.TextTemplating.TextTransformation
#endif
{
#if USET4CLASS
#pragma warning disable 0169, 0649
    Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost Host;
#pragma warning restore 0169, 0649
#endif
#endregion
    //*///#><#+

    //ここにC#コードを記述します、SharpScript_Startメソッドが最初に呼ばれます
    public void SharpScript_Start()
    {
        Write("Hello World!!");
    }

    //*///#><#+/*
#region Mainメソッド
#if USEMAIN
    public static void Main(string[] args)
    {
        SharpScript s = new SharpScript();
        s.SharpScript_Start();
        s.FinalWrite();        
    }
#endif
#endregion
#region ベースメソッド
#if USET4CLASS
    public override string TransformText()
    {
        return "";
    }

    public void FinalWrite()
    {
        System.Console.Write(GenerationEnvironment);
    }
#else
    public void Write(string val)
    {
        System.Console.Write(val);
    }

    public void WriteLine(string val)
    {
        System.Console.WriteLine(val);
    }

    public void Write(string val, params object[] arg)
    {
        System.Console.Write(val, arg);
    }

    public void WriteLine(string val, params object[] arg)
    {
        System.Console.WriteLine(val, arg);
    }

    public void FinalWrite()
    {
    }
#endif
}
#endregion
//*///#>
```

これを適当なプロジェクトの新しいCSファイルにコピーしてプロパティのカスタムツール欄に「TextTemplatingFileGenerator」と入れて保存してみてください。

このまだと、出来上がったSharpScript.output.txtにHello World!と記述されているはずです。

また、ビルドをするとコマンドラインにHello World!と表示されているはずです。

Startメソッド内のコードを書き換えてみたりして遊んでみてください。


・・・でもこれじゃ全然手軽じゃないですよね、

というわけでVisualStudioテンプレートを作ってみました。これですぐに始められます。

https://github.com/uniras/T4-Template/tree/master/SharpScript
gulp-uglifyの1.2.0はダメな子


gulp-uglifyを使って次のようなタスクを作って```gulp build```を実行すると次のようなエラーが出る。

## gulpタスクの定義

```js:gulpfile.js
var gulp = require('gulp');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var react = require('gulp-react');

var path = {
  HTML         : 'src/index.html',
  ALL          : ['src/js/*.js', 'src/js/**/*.js', 'src/index.html'],
  JS           : ['src/js/*.js', 'src/js/**/*.js'],
  MINIFIED_OUT : 'build.min.js',
  DEST_SRC     : 'dist/src',
  DEST_BUILD   : 'dist/build',
  DEST         : 'dist'
}

gulp.task('build', function(){
  gulp.src(path.JS)
    .pipe(react())
    .pipe(concat(path.MINIFIED_OUT))
    .pipe(uglify(path.MINIFIED_OUT))
    .pipe(gulp.dest(path.DEST_BUILD));
});
```

## エラー内容
```
react-gulp/node_modules/gulp-uglify/node_modules/deap/lib/deap.js:56
                Object.keys(b).forEach(function(p) {
                       ^
TypeError: Object.keys called on non-object
    at Function.keys (native)
```

ググると[github](https://github.com/terinjokes/gulp-uglify/issues/98)で、

「gulp-uglifyの1.2.0はダメな子だから1.3を使わんね。」
「いやいや、1.3.0どこにあると？1.1.0に落としたらいいちゃないと？」

ってことなんで、おとなしく1.1.0に落とします。

## gulp-uglify@1.2.0のアンインストール

###消します
```
npm uninstall gulp-uglify
```

###1.1.0入れます
```
npm install --save-dev gulp-uglify@1.1.0
```

##タスク再実行
```
gulp build
[13:38:57] Using gulpfile ~/react-gulp/gulpfile.js
[13:38:57] Starting 'build'...
[13:38:57] Finished 'build' after 14 ms
```

成功！
ソフトウェアエンジニアなら１時間で解けるべき問題５に挑戦

もとの問題はこちら: [Five programming problems every Software Engineer should be able to solve in less than 1 hour](https://blog.svpino.com/2015/05/07/five-programming-problems-every-software-engineer-should-be-able-to-solve-in-less-than-1-hour)
日本語訳：[1時間以内に解けなければプログラマ失格となってしまう5つの問題](http://www.softantenna.com/wp/software/5-programming-problems/)

このうちの問題５にPythonで挑戦してみました。
*問題５：　1,2,…,9の数をこの順序で、”+”、”-“、またはななにもせず結果が100となるあらゆる組合せを出力するプログラムを記述せよ。例えば、1 + 2 + 34 – 5 + 67 – 8 + 9 = 100となる。*

# 考え方
関数 f(n, M) を、1 ~ n の数字を使って計算結果が M となる方法をすべて返す関数として定義します（戻り値はリスト）。すると、求めたい答えは f(9, 100)です。
まず、そのままで計算が成り立つ場合（例：n=3, M=123）、M を文字列にしたものが答えの１つになります。さらに、f(n, M)は、より小さな n に分解することができます。再帰的に分解を繰り返していくことで、すべての計算方法を見つけることができます。

#例：f(3, 9) の場合
まず、そのままでは式が成り立ちません（123 ≠ 9）。
f(3, 9)は次の４通りに分解できます（一般に、(n-1)*2通りの分解法があります）。
f(2, 6) "+3"
f(2, 12) "-3"
f(1, -14) "+23"
f(1, 32) "-23"

このうち、f(1, -14), f(1, 32) についてはこれ以上分解できず、またそのままで式が成立しないので不適。
f(2, 6) は、さらに f(1, 5) "+1" と f(1, 7) "-1"　に分解できますが、いずれも式が成立しません。
f(2, 12) は、そのままで式が成立するパターンですので、"12"が１つの解です。
また、f(1, 11) "+1" と f(1, 13) "-1" に分解できますが、いずれも不適。
したがって、"12-3"が唯一の解として求められます。

f(9, 100) を計算すると、出題者の提示した１１パターン（[Solution to Problem 5](https://blog.svpino.com/2015/05/08/solution-to-problem-5-and-some-other-thoughts-about-this-type-of-questions)）と同じ解がでています。

ただし、こういう再帰的な関数の使い方は多少気持ち悪くて、Pythonの場合は再帰の深度が1000を越えると実行エラーになります（[参照](http://jiy.blog.shinobi.jp/shell%20script/%E3%82%A2%E3%82%A4%E3%83%87%E3%83%B3%E3%83%86%E3%82%A3%E3%83%86%E3%82%A3)）。この例では、深さが９を超えることはないので平気です。
また、解答例では１〜９以外の数字列にも対応できる仕組みになっていましたが、僕の方法ではそれができないのが弱い。


```python
def fun5(n, M):
    digits = "123456789"[0:n]
    out = []
    if int(digits) == M:
        out += [ digits ] 
    for i in xrange(1, n):
        out += map(lambda z: z + "+" + digits[-i:n], fun5(n - i, M - int(digits[-i:n])) )
        out += map(lambda z: z + "-" + digits[-i:n], fun5(n - i, M + int(digits[-i:n])) )
    return out    

print fun5(2, 3)
print fun5(5, 168)
print fun5(9, 100)
#['1+2']
#['123+45']
#['1+23-4+56+7+8+9', '12+3-4+5+67+8+9', '1+2+34-5+67-8+9', '1+2+3-4+5+6+78+9', '123-4-5-6-7+8-9', '123+45-67+8-9', '1+23-4+5+6+78-9', '12-3-4+5-6+7+89', '12+3+4+5-6-7+89', '123-45-67+89', '123+4-5+67-89']
```
Drupal7でpagerのテキスト変更方法	



template.phpに下記コードを記載し、「yourtheme」の箇所を自分のテーマ名に変更すれば機能します。

```php
function yourtheme_preprocess_pager(&$variables, $hook) {
    if ($variables['quantity'] > 5) $variables['quantity'] = 5;
    $variables['tags'][0] = 'First';    
    $variables['tags'][1] = '<';
    $variables['tags'][3] = '>';
    $variables['tags'][4] = 'Last';
}
```
新しいメディアコントロール API を活用して様々なデバイスで統一したメディア体験を提供する

# 新しいメディアコントロール API

日本語が不自由なタイトルのように思えて仕方がありませんが、Lollipop になって以降、メディア（オーディオやビデオなど）コントロールに関して API が刷新されました。

主な新しい API は以下のとおりです。

- [MediaSession](https://developer.android.com/reference/android/media/session/MediaSession.html)
- [MediaController](https://developer.android.com/reference/android/media/session/MediaController.html)
- [MediaBrowser](https://developer.android.com/reference/android/media/browse/MediaBrowser.html)
- [Notification.MediaStyle](https://developer.android.com/reference/android/app/Notification.MediaStyle.html)

これにともなって、いくつかの API が `@Deprecated` となっています。

- [RemoteControlClient](https://developer.android.com/reference/android/media/RemoteControlClient.html)
- [RemoteController](https://developer.android.com/reference/android/media/RemoteController.html)

`@Deprecated` となった API は、新しいバージョンでは自動的に新しい API を使うような動作になるため、置き換えるコストは低いようですが、一部機能的に廃止されたもの（ロックスクリーン上での再生コントロール等）もありますので、順次移行していく必要があります。

# 新 API が提供するもの

新しい API は、Android Auto や Android Wear、Android TV との連携を目的として設計されています。新しい API を組み込むことによって、多種多様なデバイスで統一された UX を提供できるようになっています。

それぞれ、新しい API のクラスごとにどんなことができるのか見ていきます。

## MediaBrowser

MediaBrowser は Android Auto に対してアプリが持っているメディアコンテンツへのアクセスを提供します（これは MediaBrowserService と連携して行われます）。パッケージや署名が正しければ（あるいは、コンテンツを持っているアプリがそれらを見て許可するならば）、普通のアプリケーションも MediaBrowser を使用してそのコンテンツにアクセスすることが出来ます。

SDK には、Android Auto のシミュレータが付属しており、MediaBrowserService を実装しているアプリが一覧表示されます。そこから各アプリが持っているメディアコンテンツをブラウジングし、実際の再生コントロールもできるようになっています。また、GitHub には MediaBrowserService の[実装サンプル](https://github.com/googlesamples/android-MediaBrowserService/)も公開されています。

## MediaController

MediaController は専用のプレイバックコントロールアプリや Android Wear、Android TV からメディアコンテンツをコントロールするためのメソッドを提供します。MediaController.TransportControls はその直感的なメソッドを持っており、再生、停止などのコントロールを行うことが出来ます。また、再生コントロールに必要な情報（停止中か、再生中か等）も MediaController を介して取得することになります。

実際にプレイバックコントロールを MediaController を介して行うには、トークンが必要になります。これは、以下で説明する MediaSession が持っています。MediaBrowser 経由でもトークンが取得でき、Android Auto はそこから取得したトークンを元に MediaController を生成して動かしているようです。

## MediaSession

MediaController による操作をハンドリングするのが MediaSession の役目です。MediaController は、MediaSession がもつ正当なトークンをもとにして操作を行います。ですから、トークンを持たないアプリからの操作はできないようになっています。

## Notification.MediaStyle

Notification.MediaStyle は、通知上でメディアコントロールを行うための特別なスタイルです。Lollipop 以後、ロックスクリーンに通知が表示されるようになっていますので、通知の仕組みの上でメディアコントロールができるようになります。

Notification.MediaStyle は、メディアコントロールに必要なレイアウトを内包しています。つまり、自分自身で特別な UI を組み込まなくても、通知上にコントロールの UI が作り出されます。通知からのメディアコントロールは MediaController によって行われます。これまで PendingIntent 等でコントロールしていた部分はすべて、MediaController と MediaSession の仕組みに統一できるようになります。

# まとめ

MediaSession、MediaController、MediaBrowser、そして Notification.MediaStyle はすべて、統一された仕組みで動きます。独自に色々な仕組みを組み込む必要がなく、フレームワークの上で必要なコードを書くだけで様々なデバイスの上でメディアコントロールが実現できます。

# 参考情報

- [Notifications#Controlling Media Playback on the Lock Screen](http://developer.android.com/guide/topics/ui/notifiers/notifications.html#controllingMedia)
- [Android 5.0 APIs#Media](http://developer.android.com/about/versions/android-5.0.html#Media)
標準出力をLog Fileに書き出しつつLog Rotationさせたい

何らかのToolの出力をLog fileに書き出したいけど、単一のLog fileへ書き出し続けると巨大になっちゃうので、出力を(手間を掛けずに)Log Rotationさせたい、と言うときの手順をチラ裏しておきます。

### 結論
* `cronolog`というToolを使うと簡単
* Ubuntu系は`apt-get install cronolog`でinstall
* [公式Helpはここ参照](http://linux.die.net/man/1/cronolog)

### 使い方
毎秒ごとに1行づつ標準出力にLogを吐き出すScriptを10分動かして、3分毎にRotateさせつつLogをfileに保存する、というCase studyを考えてみる。Shell scriptの中身は以下の通り (600回`echoして1秒待つ`を繰り返す)

```shell-session:test.sh
for i in `seq 1 600`
do
  echo "$i times loop"
  sleep 1s
done
```

これをcronologを使いつつ、Log出力する場合

```
./test.sh | /usr/bin/cronolog --period=3minutes log-%Y-%m-%d-%H-%M.out
```

10分待つと、以下の様なfile名のlog fileが出来るはず

```
log-2015-05-28-03-00.out
log-2015-05-28-03-03.out
log-2015-05-28-03-06.out
log-2015-05-28-03-09.out
```

### その他
* [nginx access logをcronologでrotate](http://qiita.com/ogin_s57/items/1884c5adae1bdcb44947)
* [Tomcat access logをcronologでrotate](http://qiita.com/tamura__246/items/3356d2292d599584bb1d)
* [Apache2 access logをcronologでrotate](http://qiita.com/yutaro1985/items/dfec4f5a60c37fc065c7)
CoffeeScriptで、複数の無名関数を引数にして呼び出すときのレイアウト

#レイアウト、楽ちんだけど
レイアウトって楽ちんだけど、「ほんとにこの書き方って受け入れてもらえるんだろうか」、って思うと、日和って最適でない書き方をしてしまうこともあります。無名関数で書けるのにわざわざ変数にいれちゃうとかね。でも、それってかっこいくない。

と言うわけで、無名関数2つを引数にするとき、引数間のカンマと矢印は、関数呼び出しと同じインデントレベルで良いですよって話。

とりあえず、サンプルね。

```coffeescript:sample.coffee
twofuncarg = (param, func1, func2) ->
  if(param)
    func1()
  else
    func2()

#example 1

twofuncarg true, ->
  console.log 'func1'
,->
  console.log 'func2'

#example 2

twofuncarg false, ->
  console.log 'func1'
,->
  console.log 'func2'
```

今日も美味しい珈琲をどうぞ。珈琲かんちょうってにおわないんだよ。これ豆ね。あでぃおす。
png画像の圧縮には pngquant を使おう [Mac/Win]

# 結論

TinyPNG並の圧縮を手元でササッとしたい！

`pngquant --ext .png --force --speed 1 {your_dir}/*.png`

ターミナル(黒い画面)に上記コマンドを打てばOK！

# pngquantとは

https://pngquant.org/
ターミナルでpng画像を圧縮する黒い画面用のツールです ([GitHubリポジトリ](https://github.com/kornelski/pngquant))

# インストール

## Mac

**Homebrew**

`brew install pngquant`

## Windows

Windowsの方は[公式サイト](https://pngquant.org/)から[バイナリのzip](https://pngquant.org/pngquant-windows.zip)落とすと良さそうです。

or

**Git**

`git clone git://github.com/pornel/pngquant.git`

# 使い方

基本的には `pngquant {path}/image.png` で使います。

```
// 特定の画像だけ圧縮
pngquant image.png

// 特定のディレクトリ内の画像全部圧縮
pngquant images/common/*.png
```

## Tips

デフォルトのまま使うと、
圧縮前の画像を残したまま 　**圧縮した新しい画像** を作ってくれます。

### 例

`pngquant image.png`

↓

「*image-fs8.png*」が新規作成される。

これはこれで良いですが、不要なファイルは消しときたいものです。

その場合は、オプションで色々指定出来ます。

```
// 同じファイル名で圧縮後上書きする
pngquant --ext .png --force {your_dir}/*.png 

// 圧縮率を指定 (JPEGの圧縮率みたいなものらしい)
pngquant --quality=65-80 {your_dir}/*.png

// 圧縮スピード (1が最も遅く、10が最も速い。遅い方が圧縮率が高い、デフォルトは3)
pngquant --speed 1 {your_dir}/*.png

// IE6用
pngquant --iebug {your_dir}/*.png

// 圧縮率は最高で、圧縮前の画像を残さない
pngquant --ext .png --force --speed 1 {your_dir}/*.png
```

# ImageOptimは？

- デフォルトでは圧縮している間の待ち時間が長い
- GUIで操作しないといけないため手元でササッと出来ない
- CPU負荷が高くなり圧縮中に他の作業をするのも辛い
- ImageOptimの圧縮が終わるのを待たないといけない
- 圧縮するのに時間かかるわりにデフォルト設定だとそんなに圧縮されない

のようなストレスが pngquant では解消されると思います。
一度使ってみてはいかがでしょうか。

# 参考サイト

- pngquant — lossy PNG compressor : https://pngquant.org/
- pngquantでPNG圧縮 - unstable diary : http://nukesaq88.hatenablog.com/entry/2013/04/16/194251
- pngquantで一括圧縮する - Qiita : http://qiita.com/tusimarimo/items/0c0e666fecdda2ac927a
Rails RSpecの基本 ~Model編~

#モデルスペックに含めるテスト内容
[Everyday Rails - RSpecによるRailsテスト入門](https://leanpub.com/everydayrailsrspec-jp/read)より
>・有効な属性が渡された場合、モデルのcreateメソッドが正常に完了すること。
>・バリデーションを失敗させるデータがあれば、正常に完了しないこと。
>・クラスメソッドとインスタンスメソッドが期待通りに動作すること。

#exampleを作成する
```rb:/spec/models/article_spec.rb
require 'rails_helper'

describe Article do
  #titleとcontentが入っていれば有効であること
  it "is valid with title and content"
end
```

```:実行結果
Article
  is valid with title and content (PENDING: Not yet implemented)

Pending:
  Article is valid with title and content
    # Not yet implemented
    # ./spec/models/article_spec.rb:5

Finished in 0.00056 seconds
1 example, 0 failures, 1 pending
```


＊```require 'rails_helper'```はすべてのスペックに含める。


#マッチャを書いてテストをパスさせる

＊マッチャ：期待値と実際の値を比較して、一致した（もしくは一致しなかった）という結果を返すオブジェクト。

```rb:/spec/models/article_spec.rb
 #省略
describe Article do
  #titleとcontentが入っていれば有効であること
  it "is valid with title and content" do
    article = Article.new(
      title: 'hoge',
      content: 'hogehoge'
    )
    expect(article).to be_valid
  end
end
```

```:実行結果
Article
  is valid with title and content

Finished in 0.01854 seconds
1 example, 0 failures
```
マッチャに関してはこちらを参考に。
[使えるRSpec入門・その2「使用頻度の高いマッチャを使いこなす」](http://qiita.com/jnchito/items/2e79a1abe7cd8214caa5)
#exampleを入れ子に記述する

＊describeとcontextは同義。RSpecを出力したときに入れ子になって表示されてわかりやすくなる。

```/spec/models/article_spec.rb
  describe "fetch recent article" do
    #articleの作成時間が指定時間内であれば情報を返すこと
    context "created_at > time" do
      it "returns recent_articles that match"
    end
    #articleの作成時間が指定時間内でなければ情報を返さないこと
    context "create_at < time" do
      it "does not return anything"
    end
  end
```

#FactoryGirlの利用
テストデータを何度も書かなくて済むようにする

factoriesディレクトを作成。

```rb:/spec/factories/article.rb
FactoryGirl.define do
  factory :article do
    title: 'hoge'
    content: 'hogehoge'
  end
end
```

下記のように使用。

```rb:/spec/models/article_spec.rb
 #省略
describe Article do
  #titleとcontentが入っていれば有効であること
  it "is valid with title and content" do
    article = FactoryGirl.build(:article)
    expect(article).to be_valid
  end
end
```

##FactoryGirlを楽に使う
Factory.build(:article) -> build(:article)と省略出来る。
下記を追加

```rb:/spec/spec_helper.rb
#ファクトリを簡単に呼び出せるように、FactoryGirlの構文をインクルードする
config.include FactoryGirl::Syntax::Methods
```

#Fakerの利用
リアルなダミーデータを作成する

```rb:/spec/factories/article.rb
require 'faker'

FactoryGirl.define do
  factory :article do
    title: { Faker::Lorem.sentence }
    content: { Faker::Lorem.paragraph }
  end
end
```

```
title: "Et nisi et dolores et eveniet laborum et.",
content: "Consequuntur impedit minus blanditiis quos unde. Est voluptatem modi ratione culpa sunt iste. Dolores et tempore autem recusandae."
```
のようなダミーデータが入る。

その他、様々なダミーデータがあるので下記を参考に。
http://www.rubydoc.info/github/stympy/faker/master/frames





#参考

[Everyday Rails - RSpecによるRailsテスト入門](https://leanpub.com/everydayrailsrspec-jp/read)
を参考にしております。詳細な説明・使い方を知りたい方はオススメです。

[使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」](http://qiita.com/jnchito/items/42193d066bd61c740612)
RSpecに関しましてはこちらも参考になります。その1~その4まであります。
Google BigQuery テーブルスキーマ変更したいです。


アプリからイベントデータをガンガン送信するぜ！
BigQuery上にBigData載せてデータ解析するぜ！
テーブル作ったぜ！

イベントデータのプロパティに情報追加したいぜ！
BigQuery loadできないぜ！？

```
BigQuery error in load operation: Illegal Schema update. Cannot add fields (field: hogehoge)
```


そんな時は下記コマンドでちゃんとスキーマアップデートできるんです。

```
bq update db_name.table_name table.json
```


でもtable.jsonって何書くのよって話ですが、既存のカラムも書いた上で追加したいもの追加したり変更したりしないといけないのです。
なので、カラムたくさんあったりするときは大変です。
というわけで下記で今のテーブルのスキーマとってきましょう。

```
bq --format=prettyjson show db_name.table_name > table.json
```

それでtable.jsonの中身を見てみると、

```
{
  "creationTime": "000000000",
  "etag": "\"MyUncleIsAGoodTennisPlayer\"",
  "id": "MyUncle:db_name.table_name",
  "kind": "bigquery#table",
  "lastModifiedTime": "999999999999",
  "numBytes": "12",
  "numRows": "123123123",
  "schema": {
    "fields": [
      {
        "mode": "NULLABLE",
        "name": "event",
        "type": "STRING"
      },
      {
        "fields": [
          {
            "mode": "NULLABLE",
            "name": "time",
            "type": "TIMESTAMP"
          },
          {
            "mode": "NULLABLE",
            "name": "distinct_id",
            "type": "STRING"
          },
          ...
          {
            "mode": "NULLABLE",
            "name": "uncle",
            "type": "BOOLEAN"
          }
        ],
        "mode": "NULLABLE",
        "name": "properties",
        "type": "RECORD"
      }
    ]
  },
  "selfLink": "https://www.googleapis.com/bigquery/v2/projects/myuncle/datasets/db_name/tables/table_name",
  "tableReference": {
    "datasetId": "db_name",
    "projectId": "myuncleisagoodtennisplayer",
    "tableId": "table_name"
  },
  "type": "TABLE"
}
```

こんなjsonがかえってくるので、こいつを流用します。

といってもそのまま使うと怒られるので、この部分だけ残します。
コンマの後ろの半角スペースがなかったらそれもまた怒られるので、消さないようにしましょう。
エディタの設定で保存時に末尾の空白を削除する設定はないでしょうか。

```
    [
      {
        "mode": "NULLABLE",
        "name": "event",
        "type": "STRING"
      },
      {
        "fields": [
          {
            "mode": "NULLABLE",
            "name": "time",
            "type": "TIMESTAMP"
          },
          {
            "mode": "NULLABLE",
            "name": "distinct_id",
            "type": "STRING"
          },
          ...
          {
            "mode": "NULLABLE",
            "name": "uncle",
            "type": "BOOLEAN"
          }, 
          {
            "mode": "NULLABLE",
            "name": "あたらしいカラム!!!!!!!!",
            "type": "STRING"
          }
        ],
        "mode": "NULLABLE",
        "name": "properties",
        "type": "RECORD"
      }
    ]
```
    
そしてupdate。

```
bq update db_name.table_name table.json                                             
Table 'myuncleisagoodtennisplayer:db_name.table_name' successfully updated.
```
AndroidでBitmapの一時保存

#画像の一時保存の方法
画像処理するアプリを作成する場合、
カメラやギャラリーで取り込んだ元のデータを一時的にもっておきたい時があります。
そのときメンバー変数にBitmapをもっておくと、ある程度でかい画像をもっておくと
すぐにOutOfMemoryがおきてしまいます。

いままでに一時的にデータを保持する方法をいろいろ試したのでメモしておく。

## メンバー変数

### メリット
- 簡単

### デメリット
- アクティビティ終了されたらきえる
- メモリにやさしくない

### コード
private Bitmap cache;

## ファイルに書き出す

### メリット
-メモリ優しい

### デメリット
- 残ってしまった時に、ギャラリーで表示されてしまう

###コード
```java
 try {
 // sdcardフォルダを指定
 File root = Environment.getExternalStorageDirectory();

 // 日付でファイル名を作成　
 Date mDate = new Date();
 SimpleDateFormat fileName = new SimpleDateFormat("yyyyMMdd_HHmmss");

 // 保存処理開始
 FileOutputStream fos = null;
 fos = new FileOutputStream(new File(root, fileName.format(mDate) + ".jpg"));

 // jpegで保存
 mBitmap.compress(CompressFormat.JPEG, 100, fos);

 // 保存処理終了
 fos.close();
 } catch (Exception e) {
 Log.e("Error", "" + e.toString());
 }
```

## SharedPreferencesに書き出す

### メリット
- メモリにやさしい
- ホームボタンやアクティビティ終了されても、変な途中成果物がギャラリーで表示されない

### コード

書き出し

```java
Bitmap bitmap = ... //保存したいBitmap
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
String bitmapStr = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);

context.getSharedPreferences("hogehoge", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString("key", bitmapStr);
editor.apply();
```

読み込み

```java
context.getSharedPreferences("hogehoge", Context.MODE_PRIVATE);
SharedPreferences pref = createSharedPreferences(context);
String s = pref.getString("key", "");
if (!s.equals("")) {
　　BitmapFactory.Options options = new BitmapFactory.Options();
　　byte[] b = Base64.decode(s, Base64.DEFAULT);
　　Bitmap bitmap = BitmapFactory.decodeByteArray(b, 0, b.length).copy(Bitmap.Config.ARGB_8888, true);
}

```

#まとめ
現状はSharedPreferencesで保存する方法が一番安定している。
もちろんアプリ管理からデータ削除されればきえるので、あくまでもキャッシュです。
それはファイルでもっているときも同じですので。。。

##追記
@eneim さんより情報いただきました。
ありがとうございます。

まだ試してないのでなんともですが、
キャッシュに関していろいろあるみたいです。。
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
Referer付きURLSchemeの覇権争い


簡単に

- コンテキスト(=Referer)を持ったディープリンク(=URLScheme)で、アプリを超えて戻るボタンを実装できたりする
- [Googleが検索結果からアプリを開くことができるようになった](http://jp.techcrunch.com/2015/05/28/20150527google-search-will-now-also-feature-content-from-ios-apps-prompt-users-to-install-them/)
- 対応するためには、`GoogleAppIndexing`を使ってディープリンクに対応させる必要がある

- Facebookも[App Links](https://developers.facebook.com/docs/applinks/ios)というディープリンクの枠組みを提唱している

- `GoogleAppIndexing`はオープンソースではない。
- 戻るボタンを出す出さないの制御はGoogleが握っている
 - アプリ-アプリ間の遷移に対応する時にコントロールできるように?

- FacebookのApp Linksは、実装はオープンソースですが、中央にリポジトリがあり[Index API](https://developers.facebook.com/docs/applinks/index-api/v2.3)を使ってURLに対応したApp Indexを問い合わせる必要がある。
  - 誰がどのアプリを使っているのか、どのアプリに優先して遷移させるのかをFacebookか握っている状態
- 他にこの戦いに参戦できるのはFabricを持つTwitterと、Appleくらい
- WWDCが近いですね。Appleはどう出てくるでしょうか
PostgreSQLのソートで、nullの位置を制御する

PostgreSQLのORDER BYで
`ORDER BY some_time DESC NULLS LAST `
と「NULLS LAST」書くと　NULLが下に来るように制御できた。

```
some_time
----------
2015-07-01
2015-06-21
2015-05-15

・・・

null
null
```

みたいな結果になる。
デフォルトだとNULLS FIRSTになって、NULLが上に来る。

https://www.postgresql.jp/document/8.4/html/queries-order.html

普通に考えると、降順でNULLが一番下に来そうだけどな。
Rails RSpecの基本 ~導入編~

RSpecはRubyのテストフレームワークです。

#インストール
下記をGemfileに記述してbundle install。
RSpecはRailsアプリケーションにデフォルトでは入っていないので、RSpecとその他いくつかのヘルパーをインストール。

```rb:Gemfile
group :development, :test do
  gem 'rspec-rails', '~> 2.14.0'
  gem 'factory_girl_rails', '~> 4.2.1'
end

group :test do
  gem 'faker', '~> 1.1.2'
  gem 'capybara', '~> 2.1.0'
  gem 'database_cleaner', '~> 1.0.1'
  gem 'launchy', '~> 2.3.0'
  gem 'selenium-webdriver', '~>2.45.0'
end
```

**selenium-webdriverはバージョンを最新にしなければ、うまく動かない可能性があるので注意。**

#RSpecの設定
```$ bundle exec rails generate rspec:install```を実行。
下記を生成。

```
create  .rspec
create  spec
create  spec/spec_helper.rb
```

## RSpecの出力をドキュメント形式で読みやすくする。

```rb:/.rspec
--format documentation
```
を追記。

## 不要なファイルを生成しないための設定
 
```rb:/config/application.rb
config.generators do |g|
  g.test_framework :rspec,
    fixtures: true,
    view_specs: false,
    helper_specs: false,
    routing_specs: false,
    controller_specs: true,
    request_specs: false
  g.fixture_replacement :factory_girl, dir: "spec/factories"
end
```

## development環境で使われているデータベース構造をtest環境へクローンする。
```$rake db:test:clone```

＊WARNINGが出たが、とりあえず動く。

この点については下記を参照。
[Railsで既存のデータベースを使ったWeb API開発のハマりどころ]
(http://qiita.com/tetsuya/items/f21170a9667d7e465da8)
[RSpecでテストデータベースの準備](http://qiita.com/mm36/items/b47e9cca3555c5a680af)

```$bundle exec rake db:test:prepare```
や
```$bundle exec rake db:migrate RAILS_ENV=test```
も同様の役割を持つコマンドらしく、バージョンによってころころ変わる。

**なお、データベースの構造を変更したときは、cloneコマンドでtestデータベースにその変更を反映させなければならない。**

#参考

[Everyday Rails - RSpecによるRailsテスト入門](https://leanpub.com/everydayrailsrspec-jp/read)
を参考にしております。詳細な説明・使い方を知りたい方はオススメです。

[使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」](http://qiita.com/jnchito/items/42193d066bd61c740612)
RSpecに関しましてはこちらも参考になります。その1~その4まであります。
BigQuery で既存のテーブルにカラムを追加する

`bq` コマンドを使って行う。

#### はじめに `bq` コマンドで、対象のテーブルの現在のスキーマを取得する。

```
$ bq --format=prettyjson show project_id_x:dataset_id_y.table_id_z > table.json
$ cat table.json 
{
  "creationTime": "xxx", 
  "etag": "xxx", 
  "id": "project_id_x:dataset_id_y.table_id_z", 
  "kind": "bigquery#table", 
  "lastModifiedTime": "xxx", 
  "schema": {
    "fields": [
      {
        "name": "time", 
        "type": "INTEGER"
      }, 
-------------
略
-------------
      {
        "name": "hoge", 
        "type": "STRING"
      }
    ]
  }, 
  "selfLink": "xxx", 
  "tableReference": {
    "datasetId": "dataset_id_y", 
    "projectId": "project_id_x", 
    "tableId": "table_id_z"
  }, 
  "type": "TABLE"
}
```

#### 取得したスキーマを `fields` の部分だけ取り出した json に変更する。

```
$ cat table.json 
[
      {
        "name": "time", 
        "type": "INTEGER"
      }, 
-------------
略
-------------
      {
        "name": "hoge", 
        "type": "STRING"
      }
]
```

#### 変更したスキーマに 追加したいカラムを足す。

```
$ cat table.json 
[
      {
        "name": "time", 
        "type": "INTEGER"
      }, 
-------------
略
-------------
      {
        "name": "hoge", 
        "type": "STRING"
      },
      {
        "name": "new_column_dayo", 
        "type": "STRING"
      }
]
```

#### 新しいスキーマを適用する。

```
% bq update project_id_x:dataset_id_y.table_id_z table.json
Table 'project_id_x:dataset_id_y.table_id_z' successfully updated.
```