OmniAICreator/Qiita-1.07M huggingface dataset:
[PostEffect]FadeIn/FadeOutのImageEffect

# 環境

* Unity5.5
* DOTween

# コード

```csharp:test.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using DG.Tweening;

[RequireComponent(typeof(Camera)),ExecuteInEditMode]
public class FadeEffect : MonoBehaviour {

    private Material material;

    private bool isFade;
    private float _black;

    [SerializeField]
    private float fadeDuration;

    void Awake()
    {
        material = new Material (Shader.Find ("Custom/Fade"));
    }

    void Start()
    {

        StartCoroutine (gameLogic());

    }

    IEnumerator gameLogic()
    {

        yield return FadeOut ();

        Debug.Log ("Done FadeOut");

        yield return FadeIn ();

        Debug.Log ("Done FadeIn");

    }

    public IEnumerator FadeOut()
    {
        isFade = true;

        DOTween.To (black => _black = black, 1.0f, 0.0f, fadeDuration)
            .OnComplete (() => {
                isFade = false;
        });

        yield return new WaitWhile (() => isFade == true);

    }

    public IEnumerator FadeIn()
    {
        isFade = true;

        DOTween.To (black => _black = black, 0.0f, 1.0f, fadeDuration)
            .OnComplete (() => {
                isFade = false;
            });

        yield return new WaitWhile (() => isFade == true);
    }

    void OnRenderImage(RenderTexture source, RenderTexture destination)
    {
        if (isFade) {
            UpdateMaterial ();
            Graphics.Blit (source, destination, material);
        }
    }

    void UpdateMaterial()
    {
        material.SetFloat ("_Black", _black);
    }
}
```

```glsl:Fade.shader
Shader "Custom/Fade"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
        _Black ("black", float) = 0.0 
	}
	SubShader
	{
		// No culling or depth
		Cull Off ZWrite Off ZTest Always

		Pass
		{
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
			};

			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
				o.uv = v.uv;
				return o;
			}
			
			sampler2D _MainTex;
            float _Black;

			fixed4 frag (v2f i) : SV_Target
			{
				fixed4 col = tex2D(_MainTex, i.uv);
                col = col * _Black;
				return col;
			}
			ENDCG
		}
	}
}

```

# 説明

Scriptからmaterialの_BlackをDOTweenで指定時間で1.0/0.0になるように更新。
fragmentシェーダー側でPropertyの_Blackを全ピクセルに加算。

使い方としてはFadeOutの後に何か処理をしてからFadeIn命令を出す感じです。

![Fade.gif](https://qiita-image-store.s3.amazonaws.com/0/141994/3e6daa3d-4a6c-ed5b-b654-279733e6d67a.gif)
Eclipse で .DS_Store ファイルを非表示にする

# 目障りな .DS_Store

Mac を使っていると「.DS_Store」ファイルがなかなか目障りである。

<img width="279" alt="スクリーンショット 2017-02-19 20.45.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/43205/57505861-dc02-16aa-4700-a38c86effb53.png">

「.」から始まるファイルを全て非表示にはしたくないのだが「.DS_Store」ファイルは非表示にしてもそれほど困ることはないだろう。

# 非表示の設定方法

- Package Explorer 右上の三角形のアイコンをクリックして開かれるメニューの中の「Filters...」をクリックする。

<img width="522" alt="スクリーンショット 2017-02-19 20.50.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/43205/5a72c477-7796-341d-6269-db561818182e.png">

- [Name filter patterns] のチェックをオンにする。
- フィルターに「.DS_Store」を入力。

<img width="384" alt="スクリーンショット 2017-02-19 20.39.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/43205/480b38c5-4943-7e79-bbaa-05dda5701b84.png">

うむ、消えた。

<img width="273" alt="スクリーンショット 2017-02-19 20.45.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/43205/20f62ba3-60be-690a-5595-e97ba8bb9e4b.png">
UbuntuにNetBeans+Ruby on Rails開発環境を構築する

[Windows環境にVagrant+Ubuntuデスクトップ環境をインストール](http://qiita.com/mhagita/items/8f339106c3b48eb098ca)
上記の続きで、Ubuntu環境にNetBeansをインストールし、Ruby on Railｓ開発環境を構築したので、手順を記録しておきます。

# 環境
OS: Ubuntu-16.04 64bit
Ruby: 2.3.3
Rails: 5.0.1
NetBeans IDE: 8.2

# 参考サイト
基本的には、以下のサイトの内容を適宜組み合わせて環境構築を行いましたので、紹介させて頂きます。

- [Ruby on Rails 4.2 を Ubuntu にインストールする手順をかなり丁寧に説明してみました](https://www.oiax.jp/rails/zakkan/rails_4_2_installation_on_ubunt.html)
- [UbuntuにNetBeans IDE 7.2をインストールする手順](https://www.oiax.jp/rails/zakkan/netbeans_7_2_installation_on_ubuntu.html)
- [NetBeans 8.0.1にRuby on Railsプラグインをインストールする手順](https://www.oiax.jp/rails/zakkan/how_to_install_rails_plugin_on_netbeans_8_0_1.html)

# Ruby+Ruby on Railsのインストール
[Ruby on Rails 4.2 を Ubuntu にインストールする手順をかなり丁寧に説明してみました](https://www.oiax.jp/rails/zakkan/rails_4_2_installation_on_ubunt.html)
こちらの手順通りでインストールできました。
各バージョンのみ、
Ruby: 2.3.3
Rails: 5.0.1
としました。

# NetBeans IDEのインストール
Ruby（Ruby on Rails）のフリーの開発環境はいろいろあり、以下を候補として考えました。
- Vim
- emacs
- eclipse
- NetBeans
結果として、以下の理由でNetBeansを選びました。
- 環境構築が簡単
- WindowsやMacなどでも同じ環境を再現しやすそう
また、eclipseに比べてどちらが良いかは、まだなんとも言えません。

インストール手順については、基本的に以下の通りでした。

[UbuntuにNetBeans IDE 7.2をインストールする手順](https://www.oiax.jp/rails/zakkan/netbeans_7_2_installation_on_ubuntu.html)

今回はNetBeans IDE 8.2を選びました。
また、ダウンロードするパッケージは、「HTML5/JavaScript」にしました。

# Ruby on Railsプラグインのインストール

インストール手順については、基本的に以下の通りでした。
プラグインは、NetBeans 8.0用をダウンロードしました。

[NetBeans 8.0.1にRuby on Railsプラグインをインストールする手順](https://www.oiax.jp/rails/zakkan/how_to_install_rails_plugin_on_netbeans_8_0_1.html)

# インストール後
プログラムを作成して実行しようとすると、

```
ruby: No such file or directory -- script/rails (LoadError)
```

と表示されました。

![Screenshot from 2017-02-19 20-27-38.png](https://qiita-image-store.s3.amazonaws.com/0/156795/137c40cc-224f-5ebc-47ea-42dd2fb8046d.png)

script->binへのリンクを作成することで改善しました。

```
$ cd *Railsアプリケーションのパス*
$ ln -s ./bin ./script
```

railsコマンドやbundleコマンドはターミナルから実行し、作成したディレクトリをNetBeansで読み込むと、安定して利用できると思います。
RedBootでリモートアップデート

RedBootにはtelnetでアクセスできる機能があります。この機能をRubyから叩いて、ファームウエアのアップデートをおこなってみました。

アップデートの手順は下記のようになります。

1. flashの初期化
2. tftpでkernelをメモリにロード
3. ロードされたkernelをflashに焼く
4. tftpでrootfsをメモリにロード
5. ロードされたrootfsをflashに焼く

利用したgemはnet-pingとnet-telnetです。時間がかかる処理があるので、Timeoutは長めに設定してあります。tftpサーバにはZRouterでビルドしたFon_FON2201_kernel.gz.syncとFon_FON2201_rootfs_clean.iso.ulzmaを置いてあります。

```rb|redbootup.rb
# need boot delay to 5 sec
# example usage
# ruby redbootup.rb 192.168.1.1 Fon_FON2201

require 'net/ping'
require 'net/telnet'

if ARGV.size != 2 then
  print "Usage: ruby redbootup.rb <target ip address> <build name>¥n"
  exit
end

addr = ARGV[0]
port = 9000

target = ARGV[1]

pinger = Net::Ping::External.new(addr)

while pinger.ping == false do
  sleep 1
  print "."
end

print "¥nstart telnet¥n"

telnet = Net::Telnet.new("Host" => addr, "Port" => port,
                         "Timeout" => 3600, "Prompt" => /^RedBoot>/n)

telnet.puts("¥003")

telnet.cmd("fis init -f") {|c| print c}

STDOUT.flush

telnet.cmd("Match" => /^.*continue \(y\/n\)/n, "String" => "y") {|c| print c}

STDOUT.flush

cmd = "load -r -v -b 0x80050000 " + target + "_kernel.gz.sync"

telnet.cmd(cmd) {|c| print c}

STDOUT.flush

telnet.cmd("fis create -e 0x80050100 kernel") {|c| print c}

STDOUT.flush

cmd = "load -r -v -b 0x80050000 " + target + "_rootfs_clean.iso.ulzma"

telnet.cmd(cmd) {|c| print c}

STDOUT.flush

telnet.cmd("fis create -e 0x00000000 rootfs") {|c| print c}

STDOUT.flush

telnet.cmd("fis list") {|c| print c}

telnet.close
```

^Cを送るタイミングが遅くなる事があるようで、fconfigのBoot script timeoutを5秒くらいにしておくと確実です。

あらかじめBoot scriptは以下のように設定しておきます。

```
fis load -d kernel
exec
```

上記のスクリプトを実行してから、ターゲットの電源を入れるかrebootすると処理が実行されます。

出荷時のLunixの様に圧縮していないkernelを焼けば起動が早くなりますが、flashが8Mしかないので圧縮したカーネルを利用しています。

デフォルトでは192.168.1.2にtftpサーバがいることになっていますが、ここにZRouterでビルドしたファイルを置いておきます。

net-telnet便利ですが、ちょっと分かりづらいところがあります。

FreeBSDやMac OS Xのtelnetコマンドで^Cはコードが変換されてしまうようで、telnetコマンドでRedBootを止める事は出来ないようです。

スクリプトでresetしたいのですが、resetを送るとプロンプトが帰ってこなくてスクリプトがハングするので、reset送ってません。スクリプトが終了してコマンドプロンプトに戻ったら電源をOFF/ONしてください。

これで開けてシリアルコンソールをつながなくてもアップデートできるようになって、便利になりました。

FON2100はシリアルがおかしくて、RXをつないでブートするとブートしないのでリモートアップデートが大変便利です。

なぜかわからないのですが、他のターゲットに比べFONはなぜかこの処理遅いです。

AR5312系は全てのターゲットが4M Flashでイメージが収まらないので、redbootのスクリプトで起動するたびにtftpでrootfsを焼いてその後kernelをメモリにロードして実行するようにしているのです。AR5315系はFlashがSPIの8Mなんので、この方法で更新が必要な時だけリモートで焼く事にしました。

CURRENTに入れてもらったsys/mips/atheros/ar531xで一番お勧めは、ちょっとSDRAMが小さいのですがFON2201です。もちろん法律遵守で無線は使えません。実はdev/athをいじりたくないってのが本当の理由だったりするのですが。:-)
【メモ】TCPのシーケンス番号/ACK番号

シーケンス図でメモしてみた。（RFCは読んでないので、どっか違ってるかも

# 3ウェイハンドシェイク

![３ウェイハンドシェイク.png](https://qiita-image-store.s3.amazonaws.com/0/50690/573b2b51-3fd2-d339-82d2-13135a92ba09.png)

基本的にはシーケンス番号を
送信側：シーケンス番号に
受信側：ACK番号に
入れてやり取りするイメージか

# 通信

![通信.png](https://qiita-image-store.s3.amazonaws.com/0/50690/08dceed6-c651-7dd7-7043-081953345cd6.png)

- 送信側は文字通りシーケンシャルにシーケンス番号に入れる
- 受信側は次に欲しいシーケンス番号をACKに入れて返す
[Ruby]特定の文字列の抽出

# str`[]`メソッドを使う
str`[]`は、文字列の中から部分文字列を取り出すメソッド。

## `str[regexp, num]`
第二引数が 0 の場合は、引数のない場合と同じ。
第二引数が 1 の場合は、マッチした`()`内の文字列が返る。

```irb
>> "株式会社ほげほげ（かぶしきがいしゃほげほげ）"[/（(.*?)）/, 0]
=> "（かぶしきがいしゃほげほげ）"
```
```irb
>> "株式会社ほげほげ（かぶしきがいしゃほげほげ）"[/（(.*?)）/, 1]
=> "かぶしきがいしゃほげほげ"
```

括弧内の文字列を取り出す際は、第二引数を 1 にすればいける。

# 他の使い方

## `str[idx]`
idxの位置の文字を返す。

```irb
>> s = "hello"
=> "hello"
>> s[1]
=> "e"
```

## `str[idx, len]`
idxの位置からlen文字の文字列を返す。

```irb
>> s = "hello"
=> "hello"
>> s[1, 3]
=> "ell"
```


## `str[range]`
範囲を指定すると、範囲に一致する値を返す。

```irb
>> s = "hello, world"
=> "hello, world"
>> s[7..10]
=> "worl"
```

```irb
>> s[-5..-1]
=> "world"
```

## `str[regexp]`
マッチした文字列が返る。（第二引数が0の場合と同じ挙動）

```irb
>> "株式会社ほげほげ（かぶしきがいしゃほげほげ）"[/\（(.*?)\）/]
=> "（かぶしきがいしゃほげほげ）"
```

## `str[other_str]`
一致する 文字列 を返す。
一致しない場合は nil を返す。

```irb
>> s = "hello, world"
=> "hello, world"
>> s["world"]
=> "world"
```

```irb
>> s["hoge"]
=> nil
```

## 参考リンク
http://ref.xaio.jp/ruby/classes/string/element_ref
https://docs.ruby-lang.org/ja/1.9.3/method/String/i/=5b=5d.html
http://d.hatena.ne.jp/riocampos+tech/20130630/p1
sqliteコマンド覚え書き

#接続
- `sqlite3 ＜sqliteのファイル＞`

#sqlite3のコマンド
sqlite3のコマンドプロンプトで実行できるコマンド。

- `＜SQL＞;`
SQLを実行する。末尾にセミコロンが必要。

- `.help`
ヘルプ。コマンドの一覧を表示する。

- `.table`
テーブル一覧を表示する。

- `.schame ＜テーブル名＞`
テーブルの定義する。CREATE TABLE文と、インデックスがあればCREATE INDEX文が表示される。
適宜改行が入ったりする訳ではなく、単純に1文が1行で表示されるだけなので見づらい。わかりづらい。

- `.show`
現在の設定値を表示する。

- `.quit`
終了する。
CentOS7でmilter-managerとSpamAssassin(spamass-milter)を用いてスパムメール対策


milterってのは mail filterの略で、MTAに追加できるプラグインみたいなもんらしいです。


https://milter-manager.osdn.jp/reference/ja/install-to-centos.html
を参考にさせて頂きました。

ただ、上記リンク先ではウイルス判定ソフトのclamavとグレイリストのgreylistも入れてますが
現状、そんなにspamはこないのでSpamAssassin(spamass-milter)だけを入れて様子を見てみます。
特にグレイリストを入れると、メールにかなり遅延が出てしまうので。

## milter managerのインストール
```
curl -s https://packagecloud.io/install/repositories/milter-manager/repos/script.rpm.sh | sudo bash
```
```
sudo yum install -y milter-manager
```

## spamass-milterのインストール
```
sudo yum install -y spamass-milter-postfix
```

## spamass-milterの設定
そのままデフォルトで使うんで、特に設定ファイルはいじりません
後は起動設定など

```
sudo systemctl enable spamassassin
sudo systemctl start spamassassin
sudo systemctl enable spamass-milter
sudo systemctl start spamass-milter
```


## milter-managerの設定
milter-managerを postfixグループに加えます。

```
sudo usermod -G postfix -a milter-manager
```

起動設定
```
sudo systemctl enable milter-manager
sudo systemctl start milter-manager
```

## postfix設定
```/etc/postfix/main.cf
milter_protocol = 6
milter_default_action = accept
milter_mail_macros = {auth_author} {auth_type} {auth_authen}


smtpd_milters = unix:/var/run/milter-manager/milter-manager.sock
```


postfix設定再読み込み
```
sudo systemctl reload postfix
```
早速メールを送ってみる。正常に動いていればメールヘッダにspamassassinの判定結果が追加されているはずだ。

、、、、ついてない。

ログを見てみる。

```/var/log
postfix/smtpd[11341]: warning: connect to Milter service unix:/var/run/milter-manager/milter-manager.sock: Permission denied
```

Permission deniedやな


```
srw-rw---- 1 milter-manager milter-manager 0  2月 19 18:49 /var/run/milter-manager/milter-manager.sock
```
所有権は
660だけどpostfixグループにmilter-manager追加してんだけどなあ。
chmod 666にすれば動くがサーバを再起動するともとに戻ってしまう。
とりあえず

```/etc/milter-manager/milter-manager.conf
# manager.unix_socket_mode = 0660
を
manager.unix_socket_mode = 0666
```
へ修正。

メール送信

メールヘッダに
X-Spam-Status: No, score=2.3 required=5.0 
な感じで判定が追加された。
エレガントな画面遷移アニメーションライブラリ「Hero」を使ってみた

#概要
iOS、tvOS用のエレガントな画面遷移アニメーションを実装するライブラリ「Hero」を使って簡単なサンプルを作成してみました。
今回のケースではコードでの実装は一切なく、Storyboard上の設定だけで実現しています。

#ライブラリ
https://github.com/lkzhao/Hero

#インストール
Carthage、CocoaPodsに対応しています。
今回はCocoaPodsでインストールします。

```Podfile
target 'HeroSample' do
  pod 'Hero'
end
```

#サンプル
3画面構成で、CMYKの色を以下の3パターン表示をするサンプルを作成します。
1. 簡易表示
2. タイル形式表示
3. リスト形式表示

以下のような画面遷移をするサンプルです。

![HeroExample.gif](https://qiita-image-store.s3.amazonaws.com/0/122007/3add1948-380c-0291-365c-dc4d8c6ff294.gif)

#実装
##実装のポイント
実装のポイントは3点です。
 * `UIViewController`の`isHeroEnabled`
 * `UIView`の`heroID`
 * `hero_unwindToRootViewController`メソッド
これらはHeroライブラリ内で`UIViewController`、`UIView`の`extension`に定義されています。

##Storyboard全体像
実装後のStoryboardの全体像は以下のような感じです。
3画面の各レイアウトを作成し、`Show Segue`で繋いでいます。

![Storyboard.png](https://qiita-image-store.s3.amazonaws.com/0/122007/529c9fb6-eea4-c094-9e8a-6f9d26f8ee38.png)

以下、各画面のHeroの設定について書いていきます。

##簡易表示画面
`ViewController`の`isHeroEnabled`を設定します。
この`isHeroEnabled`を設定することで、この画面に遷移してきた際にHeroの画面遷移処理が有効になります。
![SimpleView_ViewController.png](https://qiita-image-store.s3.amazonaws.com/0/122007/97bb0e56-c2e3-b6aa-bf85-81d0ae4b5c39.png)


`UIView`の`heroID`を設定します。
この`heroID`を設定することで、画面遷移元と画面遷移先の要素の紐付けができます。
ここでは、シアン色の`UIView`に`cyan`を設定します。
その他の色にもそれぞれ識別できるように各々IDを振ります。
![SimpleView_UIView.png](https://qiita-image-store.s3.amazonaws.com/0/122007/bf2970fa-0738-0661-bb63-7217ca5bdc12.png)

これで簡易表示画面の設定は終わりです。

##タイル形式表示画面
簡易表示画面と同様、`ViewController`の`isHeroEnabled`と`UIView`の`heroID`を設定します。
ここで、`heroID`は簡易表示画面の各色の`heroID`と揃えます。
シアン色の`UIView`には`cyan`の`heroID`をつけます。
(また同時に`heroModifierString`を設定し、遷移時のアニメーションを`arc`に設定しています。ここは空の文字列でも問題ありません。)
![TileView_UIView.png](https://qiita-image-store.s3.amazonaws.com/0/122007/7ae71bdf-3743-c862-1ab0-9530d4e43e86.png)

次にBackボタンの動作を設定します。
Backボタンの`Touch Up Inside`に`First Responder`の`hero_unwindToRootViewController`を繋ぎます。
![TileView_Back.png](https://qiita-image-store.s3.amazonaws.com/0/122007/f68d826d-75e6-1ede-cc33-a353dc39513d.png)

タイル形式表示画面の設定は終了です。

##リスト形式表示画面
上記で設定してきたのと同様、以下3点を設定します。
* `ViewController`の`isHeroEnabled`
* `UIView`の`heroID`
* Backボタンの`hero_unwindToRootViewController`

![ListView_ViewController.png](https://qiita-image-store.s3.amazonaws.com/0/122007/fb066a3b-09a3-275d-4027-8c670895f61d.png)

上記が完了すれば、サンプルのような画面遷移をするアプリが作成できます。

#リポジトリ
以下にソースコードをあげています。
https://github.com/ikezzi/HeroExample

#まとめ
Heroを使うと簡単にエレガントな画面遷移アニメーションが実装できます。
今回のようなケースであれば、コードでの実装も一切なくStoryboard上の設定だけで画面遷移の実装をすることができます。
画面遷移の際のアニメーションの種類も簡単に設定でき、いろいろな遷移アニメーションを作ることができます。
公式のサンプルも豊富に用意されているので気になった方は是非試してみてください！
数独のセルの予約について「Rubyで数独」

#はじめに

『[Rubyで数独：AIプログラミング入門](https://www.amazon.co.jp/dp/B01M2C4894/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)』の「セルの予約」の説明で使っている表の記法と解説をまとめる目的でこのノートは書いています。本の中で使っているパズルは数独通信からひっぱってきているので、そのままではあれなので無料で入手可能な[Open Sudoku](http://opensudoku.moire.org/)のパズルに変更しています。

#解説

[Open Sudoku](http://opensudoku.moire.org/)のHARDのステージ67をある程度まで進めた図が次の左の図になります。この状況から先に進むのに「セルの予約」というテクニックが使えます。
<img width="471" alt="セルの予約ゲーム画面.png" src="https://qiita-image-store.s3.amazonaws.com/0/227/d98268f9-93b0-d17f-7404-a2ca19248dca.png">
左にある数独の画面の7行目でセルの予約が使えます。
右にある表は7行目のマスを縦軸に、その値を横軸にとっています。A7の値は4です。これを右の表の1行目4列目に◯を打つことで表現します。
A7はその他の値にはなりえないという意味で、右の表の1行目の他の部分を✕で埋めています。
B7, D7, E7, G7の行もA7の行と同様の意味で埋まります。

次にC7はC列にすでに1, 5があるので$C7 \notin \\{1, 5\\}$。同様にI7もI列に1, 5があるので$I7 \notin \\{1, 5\\}$。これを右の表に❏で書きます(❏も意味的には✕と同じくその値にはなりえない)。

すると、数独の7行目で1になりうるのは右の表を見るとF7かH7で、5も同様です。これを△、▲で表を埋めます。
ここで▲、△の意味は次のように定義します。

```math
▲, △ \in \{◯, ✕ \}, ~~~▲ \neq △
```

簡単に言えば△と▲は△が◯ならば▲は✕をとり、△が✕ならば▲は◯を取るということです。右の表のC7の行とF7の行は1列目か5列目に◯が入るので、・の部分はXになります。・をXにするテクニックを「セルの予約」と言います。
acts-as-taggable-onをさくっと使ってみた

# はじめに
タグを管理するgem「acts-as-taggable-on」について、簡単な使用手順と登録したタグを画面に出す部分まで簡単にまとめてみた（細かい機能は割愛）。

# 使用環境
Ruby 2.3.0p0
Rails 5.0.0.1

# 手順
## 1. gemインストール
```rb:Gemfile
gem 'acts-as-taggable-on', '~> 4.0'
```
```
$ bundle
```
## 2. テーブル作成
```
$ rake acts_as_taggable_on_engine:install:migrations
```
```
$ rake db:migrate
```
これで「taggings」、「tags」テーブルが生成される。

## 3. コーディング
Draftモデル（Qiitaの「下書き」みたいなモデル）を使った例です。
### モデル
モデルに「acts_as_taggable（acts_as_taggable_on :tagsのエイリアス）」を追加する。

```rb:app/models/draft.rb
class Draft < ApplicationRecord
  acts_as_taggable
end
```

### コントローラー
コントローラーのストロングパラメータに「:tag_list」を追加する。

```rb:app/controllers/drafts_controller.rb
def draft_params
  params.require(:draft).permit(:title, :content, :user_id, :tag_list)
end
```

### ビュー
Bootstrapを使っています。

#### 編集画面
```erb
<div class="field form-group form-group-lg">
  <%= f.label :tag_list, class: "sr-only control-label" %>
  <%= text_field_tag 'draft[tag_list]', draft.tag_list.join(","), class: "form-control" %>
</div>
```
![スクリーンショット 2017-02-19 18.26.13.png](https://qiita-image-store.s3.amazonaws.com/0/60337/55626b65-9469-2c60-f823-eef303f3ab27.png)


#### 表示画面
```erb
<% @draft.tag_list.each do |tag| %>
  <span class="label label-primary"><%= tag %></span>
<% end %>
```
![スクリーンショット 2017-02-19 15.23.39.png](https://qiita-image-store.s3.amazonaws.com/0/60337/885f52b9-df35-cafb-47c7-c9cfc4788cbc.png)

# テーブルとデータ
前述のように登録するとこんな感じでデータが生成されます。
#### tagsテーブル
![スクリーンショット 2017-02-19 18.01.27.png](https://qiita-image-store.s3.amazonaws.com/0/60337/85f5af1c-15bf-4a35-80c5-3fb1ac5dcfeb.png)
#### taggingsテーブル
![スクリーンショット 2017-02-19 18.01.09.png](https://qiita-image-store.s3.amazonaws.com/0/60337/3040a1b0-4cf9-8a90-f767-7bde99f6face.png)



# 参考
[GitHub ActsAsTaggableOn](https://github.com/mbleigh/acts-as-taggable-on)

↓こちらは細かい機能を含め詳しく書かれています。参考にさせて頂きました:sunny:
[Railsでacts-as-taggable-onを使ってタグ管理を行う](http://ruby-rails.hatenadiary.com/entry/20150225/1424858414)
rubyのversionが違くて、bundle installできなかったのは、bundlerが不在だからでした。

###実行したコマンドなど
```
$ bundle install --path=vendor/bundle
```

###エラー内容
```
Your Ruby version is 2.3.3, but your Gemfile specified 2.3.1
```

###状況

ruby -v　では　2.3.1　が表示される。
→PATHの問題か？？

ーーーーーー

#####PATHの確認

``
$ which ruby
``
→```
/Users/ysk/.rbenv/shims
``` 


→``/Users/ysk/.rbenv/shims``を参照している。

ーーーーーー

``
$ echo $PATH
``
→```
/Users/ysk/.nodebrew/current/bin:/Users/ysk/.rbenv/shims:/usr/local/bin:hogehogehoge
```

　→``/User/ysk/.rbenv/shims``を参照するはず。

  →rubyのバージョンは整合性が取れている。

###解決方法
```which bundler``` してみたら、bundlerがshimsの中になかったので、
bundle installも自動的に下位のディレクトリ``/usr/local/bin``を参照していた。
(``/usr/local/bin``の中のrubyのバージョンは2.3.3だった)

なので
``cd /Users/ysk/.rbenv/shims``
``gem install bundler``
叩いてbundlerを入れて、

``bundle install --path=vendor/bundle``
で通った。

###備考・参考

* https://www.d-wood.com/blog/2016/02/02_7781.html
* https://h2ham.net/ruby-rbenv
* http://aokabin.hateblo.jp/entry/2014/09/12/225420

この辺見たけど全然解決しないよ！！ってなったけど、
もっと初歩の初歩でした。

-----------
Python - 数値データファイルからデータを読み込み重回帰線を求める。

以下のようなタブ区切りの数値データ系列ファイルからデータを読み込み重回帰線を求めるプログラム。
1行目：目的変数(y)
2行目：説明変数1(x1)
3行目：説明変数2(x2)

```text:MultipleRegressionAnalysis_Data1.txt
65.7	67.8	70.3	72.0	74.3	76.2
3.27	3.06	4.22	4.10	5.26	6.18
69.7	69.7	71.3	77.6	81.0	78.7
```



```py:MultipleRegressionAnalysis_2.py
from matplotlib import pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D 

def load_data(filename):
    with open(filename) as lines:
        return [[float(data) for data in line.strip().split('\t')]
                for line in lines]
    
def calc_average(data):
    return sum(data) / len(data)
    
def calc_sum_of_square(data_list):
    ave = calc_average(data_list)
    return sum((d - ave)**2 for data in data_list)
    
def calc_sum_of_square(data_list1, data_list2):
    ave1 = calc_average(data_list1)
    ave2 = calc_average(data_list2)
    return sum((data1 * data2 - ave1 * ave2)**2 for data1, data2 in zip(data_list1, data_list2))
    
if __name__ == "__main__":
    data = load_data('MultipleRegressionAnalysis_Data1.txt')
    s = [[calc_sum_of_square(data1, data2) for data2 in data]
            for data1 in data]

    det = s[1][1]*s[2][2] - s[1][2]**2
    # 偏回帰係数計算
    b1 = (s[0][1]*s[2][2] - s[0][2]*s[1][2])/det
    b2 = (s[0][2]*s[1][1] - s[0][1]*s[1][2])/det
    b0 = calc_average(data[0]) - b1*calc_average(data[1]) - b2*calc_average(data[2])
    # 重回帰式表示
    print("Y = " + str(b1) + " x1 + " + str(b2) + " x2 + " + str(b0))
    
    fig = plt.figure()
    ax = Axes3D(fig)
    # 求めた重回帰式から平面表示
    x1 = np.arange(0, 10, 0.25)
    x2 = np.arange(65, 80, 0.25)
    X1, X2 = np.meshgrid(x1, x2)
    Y = b1 * X1 + b2 * X2 + b0
    ax.plot_wireframe(X1, X2, Y)
    # 元データ表示
    ax.scatter3D(data[1], data[2], data[0], c='red')
    plt.show()
```

```text:結果
> python MultipleRegressionAnalysis_2.py
Y = -17.118276566578807 x1 + 1.0700625679745137 x2 + 65.58796752824318
```

![MultipleRegressionAnalysis1.PNG](https://qiita-image-store.s3.amazonaws.com/0/38382/1a57be8d-0e30-1f49-218f-8eb0eace5200.png)

![MultipleRegressionAnalysis2.PNG](https://qiita-image-store.s3.amazonaws.com/0/38382/007679ca-c11e-9f4f-ef6e-7d0b0ef711d8.png)

![MultipleRegressionAnalysis3.PNG](https://qiita-image-store.s3.amazonaws.com/0/38382/dd7ba9ab-d7ca-1f4a-424b-82ddab3b6f67.png)
《JavaScript》setIntervalを利用して、スクロールが終わった時に何か処理をする


## スクロールのタイミングを補足

`setInterval()`を利用して、スクロールが終わったときに何か処理するためのコードです。
スクロールのイベントが発生したら真偽値を代入して、それを`setInterval()`でチェックします。


### setInterval()で、スクロール終了したときになにかする

コードはjQueryを利用してます。

```javascript

let didScroll;

$(window).on('scroll', function() {
  didScroll = true;
});

setInterval(function() {
  if (didScroll) {
    didScroll = false;
    console.log('finish:)');
  }
}, 250);

```
Desktop Bridge の概要

日本マイクロソフト主催の「Microsoft Desktop Bridge セミナー」に参加してきました。
参加前は Desktop Bridge についての不明点が多々ありましたが、いくつか質問して確認できたので、わかった点を含めて概要をまとめておきます（概要のみで実際の変換手順等は記載していません）。



# Desktop Bridge と Desktop App Converter
Desktop Bridge は既存の Win32 アプリや .NET アプリ（サポートしているのは .NET 4.6.1）を、Windows ストアから配布するためのものです。

Windows ストアにあげるには、アプリをストアにあげるための形式（Appx パッケージ）にする必要がありますが、このパッケージを作成する（＝変換する）ためのツールが Desktop App Converter（以降「DAC」と表記） です。

なお、変換したアプリを実行できるのは Windows 10 Anniversary Update 以降のみです。



# Desktop Bridge の注意点
Desktop Bridge を使って既存のアプリを Windows ストアにあげるにあたり注意が必要な点があります。

* DAC が行うこと
DAC が行うのは、既存アプリを Appx パッケージに変換することだけです。
元々のアプリ自体は何も変換されず、Win32 アプリや .NET アプリのままです（UWP に変換はされるわけではありません）。
なお、DAC が必須なわけではなく、対応する処理を手作業で行うことも可能（DAC を使った方が楽ですが）ですし、処理後に作成されたマニフェストファイルを更新することでカスタマイズも可能です。
　

* 変換元のアプリ
DAC で変換を行う場合、既存アプリのインストーラ（サイレントインストールに対応しているもの）を元にするのが一般的ですが、インストーラは必須ではありません。
実行することでアプリが配置できればよいので、単純に XCOPY しているバッチファイルを指定しても変換は可能です。
　

* ストアへの申請
Desktop App Cpnverter で 変換したアプリをストアにあげるためには事前申請が必要です（UWP のように直接アップすることで申請はできません）。
事前申請は以下のページの「Windows ストアにアプリを提出する準備ができたら、こちらからお知らせください。」のリンク先から行います。
　https://developer.microsoft.com/ja-jp/windows/bridges/desktop
申請時にアプリケーションの URL を入力する必要があります（ここで入力した URL で開発者等の確認を行うとのこと）。
問題がなければ、申請時に選択した国の担当者が割り当てられ、その担当者からメールで連絡がくるので、以降は担当者とやり取りしてストアにあげるという手順になります。
　

* 管理者権限必須
アプリ起動時に管理者権限を要求してくる（一般ユーザーでは動作しない）アプリはストアにアップできません（却下されるとのこと）。
起動時にユーザーが「管理者として実行」を選んで動作させることは可能なので、一般ユーザーで起動できるようにして、権限が必要な機能については管理者権限で起動するように促すといった対応が必要です。
　

* サービス/ドライバ
元アプリのインストーラ内で別途サービスやドライバのインストールを行っている場合、変換後のパッケージを配置してもサービスやドライバはインストールされません。
別途、サービスやドライバのインストーラを用意して、ストアのアプリ説明やアプリ内でインストールを促す等の対応が必要です。





# 変換後のアプリの動作
DAC で変換を行ってもアプリは元のままですが、実行環境での配置方法が異なりますので、一部動作に影響があります。


* 配置場所
Appx パッケージを実行環境に配置する場合、"Program Files"の下やユーザーが指定した場所には置かれません。
標準ではエクスプローラーでアクセスできない場所（要するに UWP と同じ場所）に配置されますので、"Program Files"の下にあることを前提にしているアプリや、インストール先をレジストリに書いて他のアプリと連携するアプリ等はそのままでは動作しません。
　

* 書き込み場所
Appx パッケージとして配置した場合は、自アプリのフォルダ以下に書き込みアクセスは行えませんので、
そのような処理をしているアプリはそのままで動作しません。
また、AppData フォルダへのアクセスは、Appx パッケージのローカルストレージにリダイレクトされます。
単純に自アプリが読み書きするだけであれば問題ないですが、AppData フォルダを使って他アプリと連携するような処理はそのままでは動作しません。
　

* 作業フォルダ
アプリ実行時の作業フォルダは変換前と違います。
インストール時にショートカットに作業フォルダを指定している場合、変換後の作業フォルダの位置は変わってしまいますので注意が必要です。
　

* レジストリ
HKEY_LOCAL_MACHINEへの書き込みは行えません。


上記ように元アプリの処理内容によっては、何らかの対応が必要になる場合があります（上記以外でも影響がある処理があります）。
そのため、変換後はクリーンな環境に配置して動作確認を行う必要があります。



# Desktop Bridge の用途
ここまで記載してきたことを考慮すると、Desktop Bridge の用途としては以下のようなパターンでメリットがあると思います。

* 公開済のアプリをストアで配布する
すでに Web 上で公開しているアプリがあり、ストアでも配布したい場合です。
この場合、事前申請はスムーズに進むと考えられますので、変換後に動作に悪影響がないか注意しておけばよいと思います。
　
 
* UWP では使えない機能を入れたい
UWP では使えない機能がどうしても必要な場合です。
この場合、最初から注意して作れば動作的な問題は少ないと思いますので、あとは予めアプリを公開してから事前申請を行います。
なお、UWP で可能な機能しか使わないのであれば、UWP で作った方がストアにあげるのが簡単ですので、作成前にどちらにするのかよく検討する必要があります。


# ツール URL

* Desktop App Converter
http://aka.ms/converter
※ Windows ストアからダウンロードします。
　

* ベース イメージ
https://aka.ms/converterimages
※ダウンロードしたベースイメージを DAC に設定します。
　実行環境と同じバージョンのイメージを使用します。
　

* 最新の Windows SDK
https://developer.microsoft.com/windows/downloads/windows-10-sdk
※Appx への署名等で使用します。
Facebook Graph APIで投稿リストのリアクション数を取得する方法

投稿IDリストでリアクション数を取得できるエンドポイントです。

```
https://graph.facebook.com/v2.8/?ids=
  195152223850783_1439793239386669,
  195152223850783_1438730836159576
&fields=
  reactions.type(LIKE).limit(0).summary(total_count).as(reactions_like),
  reactions.type(LOVE).limit(0).summary(total_count).as(reactions_love),
  reactions.type(WOW).limit(0).summary(total_count).as(reactions_wow),
  reactions.type(HAHA).limit(0).summary(total_count).as(reactions_haha),
  reactions.type(SAD).limit(0).summary(total_count).as(reactions_sad),
  reactions.type(ANGRY).limit(0).summary(total_count).as(reactions_angry)
&access_token=アクセストークン
```

結果

```
{
   "195152223850783_1439793239386669": {
      "reactions_like": {
         "data": [],
         "summary": {
            "total_count": 11385
         }
      },
      "reactions_love": {
         "data": [],
         "summary": {
            "total_count": 528
         }
      },
      "reactions_wow": {
         "data": [],
         "summary": {
            "total_count": 81
         }
      },
      "reactions_haha": {
         "data": [],
         "summary": {
            "total_count": 5
         }
      },
      "reactions_sad": {
         "data": [],
         "summary": {
            "total_count": 1
         }
      },
      "reactions_angry": {
         "data": [],
         "summary": {
            "total_count": 0
         }
      },
      "id": "195152223850783_1439793239386669"
   },
   "195152223850783_1438730836159576": {
      "reactions_like": {
         "data": [],
         "summary": {
            "total_count": 5512
         }
      },
      "reactions_love": {
         "data": [],
         "summary": {
            "total_count": 176
         }
      },
      "reactions_wow": {
         "data": [],
         "summary": {
            "total_count": 119
         }
      },
      "reactions_haha": {
         "data": [],
         "summary": {
            "total_count": 1
         }
      },
      "reactions_sad": {
         "data": [],
         "summary": {
            "total_count": 0
         }
      },
      "reactions_angry": {
         "data": [],
         "summary": {
            "total_count": 1
         }
      },
      "id": "195152223850783_1438730836159576"
   }
}
```
Cygwinでxtermのfont設定

はじめに
=======

ノートPCの解像度が高くて(U)Xtermを表示したときに文字が小さすぎて読めない場合の対処法。
主にWindows10のCygwinで有効。X windowのリソース設定でFontを変更するといい感じになる。
(U)XtermでTrueType Font使えるの知らなかった。

Xdefaults設定
-------------

`faceName`と`faceNameDoublesize`の両方設定するのがポイント。`faceName`だけだと半角文字も全角幅で表示されてしまう。

```
xterm*faceName: DejaVu Sans Mono
xterm*faceNameDoublesize: DejaVu Sans Mono Book
xterm*faceSize: 10
```

FontはLinuxの場合以下のコマンドで調べられる。DejaVu Sansが標準でインストールされているようだ。

     $ fc-list
新米iOSエンジニアのマーケティング用語集

iOSエンジニアに転職して一月半が経過。
業務中によく聞くマーケティング用語をメモしておく。多分随時追記。

##KGIとKPI
###KGI（Key Goal Indicator）
日本語訳では、重要目標達成指標。
その会社においての最も重要とする評価指標。
会社によって千差万別。
例えば、飲食店なら顧客満足度、オークションサイトなら成約率など。

###KPI（Key Performance Indicator）
日本語訳では、重要業績評価指標。
KGIの過程にある評価指標。
オークションサイトで言えば、成約率というKGIを上げるために、訪問者数、出品数、オークション参加率などのKPIを上げる必要がある。

##Webサービス運営会社の代表的なKPI

###DAU(Daily Active User)
１日のアクティブユーザー数。

###MAU（Monthly Active User）
ひと月のアクティブユーザー数。

###コンバージョン率（Conversion Rate）
成約率とも。取引が成約した数。

##アクセス解析ツール

###GA
Google Analyticsのこと。

###[Fabric](https://get.fabric.io/)
Twitterが作ったモバイルプラットフォーム。アクセス解析、クラッシュレポートなどを提供している。つい先日[Googleに買収された](http://japan.cnet.com/news/business/35095194/)。

##その他

###ROI(Return on investment)
投資（費用）対効果。
「ROIが高い案件から優先して対応しようよ」や「それROI低くね？」などのように使う。
PRML(初版)をおさらいする 第1章 序論 2.2節以降

1.2.2 期待値と分散
--

**期待値** というのは簡単な話で、**確率重み付き平均** のこと。ある関数 $f\(x\)$ があって、変数 $x$ の生起する確率が確率密度(離散なら質量)関数 $p\(x\)$ に従う場合は、全ての $x$ についての期待値は、

```math
E_{x}\small[{} f\small({}x\small){}\small]{} = \int{} p\small({}x\small){} f\small({}x\small){} dx
```

となる。

---

**分散** は、**$x$ と $x$ の期待値の差(偏差)の２乗の期待値**。$x$ のバラツキの2乗オーダーの期待値。

２つの確率変数 $x$ と $y$ の **共分散** は、**$x$ の偏差と $y$ の偏差の積の期待値**。これは、**標準偏差で正規化した $x$ と $y$ のバラツキの相関係数** に等しい。

- [相関係数](https://ja.wikipedia.org/wiki/%E7%9B%B8%E9%96%A2%E4%BF%82%E6%95%B0)

**共分散** は、分散すなわち **バラツキの大きさをそのまま表現したものではない** ことに注意。共分散は、**２つの確率変数のバラツキの傾向(相関係数)をバラツキの大きさと掛け合わせたもの** を示している(多分、別途確認が必要)。**分散** は **同じ確率変数 $x$ と $x$ の共分散** と見做すことができる。２つは全く同一なので **相関係数は $1$** である。したがって、**分散の値** は単純に **バラツキの大きさ** を表している。

---

**2つの変数の偏差の積の期待値** が、**共分散**。2つの変数が同一の場合が、**分散**。
**2つの変数をそれぞれ標準偏差で正規化した偏差の積の期待値** が、**相互相関係数**。2つの変数が同一の場合が、**自己相関係数**。その場合、自己相関係数は $1$。

---

**分散** を多次元に拡張したものが **分散共分散行列**。

- [分散共分散行列](https://ja.wikipedia.org/wiki/%E5%88%86%E6%95%A3%E5%85%B1%E5%88%86%E6%95%A3%E8%A1%8C%E5%88%97)

なお **分散共分散行列と自己相関行列** は、**分散と相関係数** と同じ関係にある。**分散共分散行列** は、**偏差ベクトルの各次元間の積の期待値(共分散)を並べた行列** である。対角成分は同じ成分同士の積であるため、**共分散の特殊な場合である分散に等しい**。それに対して **自己相関行列** は、**標準偏差で正規化した偏差ベクトルについて同様に並べた行列** である。

---

**共分散** を多次元に拡張したものが **共分散行列**。**共分散行列** は、**２つの確率変数ベクトルの偏差(ベクトル)の全ての要素間の共分散を並べた行列** である。

1.2.3 ベイズ確率
--

**古典的確率(classical probability)**: 確率をランダムな繰り返し試行の頻度と見做す、**頻度主義的(frequentist)** な考えに基づく確率
**ベイズ確率(Bayesian probability)**: 確率を「不確実性」の度合いと見做す考えに基づく確率

例えば、1 節で取り上げた「多項式曲線フィッティング」における **適切なモデルパラメータ $w$** には **不確実性** がある。

モデルパラメータが $w$ のとき、観測データ $D$ が得られる条件付き確率は $p\(D\,|\,w\)$ である。これを **尤度関数** と呼ぶ。尤度関数は $w$ の確率分布ではないため、$w$ で積分しても $1$ とはならないことに注意。

ベイズの定理によれば、

```math
p\small({}w\,|\,D\small){} = \frac{p\small({}D\,|\,w\small){}\,p\small({}w\small){}}{p\small({}D\small){}}
```
 
である。これにより、**$D$ を観測したあとで $w$ に関する不確実性を評価することができる** ようになる。

---

## 頻度主義的アプローチ

**最尤推定(maximum liklihood)**: $p\(D\,|\,w\)$ を最大化する $w$ を推定する。

つづく
[卒論・学会] Macbookでさくっとプロジェクタにキャリブレーションする

ここにキャリブレーションツールがあるのでさくっと /Application あたりにコピーしておく．

```
/System/Library/PrivateFrameworks/AmbientDisplay.framework/Versions/A/Resources/Calibration\ Assistant.app
```

使い方はだれでも分かると思うが，下のようなウインドウがでるので傾向写真とかの色とコントラストがちゃんと見えるように指示にしたがって合わせる．以上．

<img width="1007" alt="スクリーンショット 2017-02-19 17.51.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/28835/1bb178da-0363-e940-27b6-b81952080560.png">
PHPMDのルールを変えたい

# やりたいこと

PHPMD(https://phpmd.org/) を利用する際に既存ルールを無視、あるいは閾値変更を行う

# 環境

PHP7.0
PHPMD 2.6.0

# 本題

PHPMDのチェックルールは以下の方法で定義されます。

1. 実行時のオプション引数
2. 実行時のオプション引数で設定するxmlファイル
3. PHPMDインストールの際に作成されるデフォルトのruleset


ルール変更に関しては2番のxmlファイルを作成して行うのが一番使いやすいと思います。
設定ファイルの変更であれば、バージョン管理で簡単に変更履歴を追うことができるので。

ルールの変更に際して必要なのは

* xmlファイルの作成
* 必要なルールの読み込み
* 不要なルールの除外
* 変更したいルールの除外と読み込み

です。

## xmlファイルの作成

公式サイト(https://phpmd.org/documentation/creating-a-ruleset.html) から雛型を借りてきます。

```xml
<?xml version="1.0"?>
<ruleset name="My first PHPMD rule set"
         xmlns="http://pmd.sf.net/ruleset/1.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0
                     http://pmd.sf.net/ruleset_xml_schema.xsd"
         xsi:noNamespaceSchemaLocation="
                     http://pmd.sf.net/ruleset_xml_schema.xsd">
    <description>
        My custom rule set that checks my code...
    </description>
</ruleset>
```

ファイル名は実行時に引数で指定するので、分かりやすい名前であればOKです。
phpmd.xml, ruluset.xml などが妥当だと思います。

PHPMDの実行時にこのファイルを指定することで、指定のルールセットを実行できるようになります。

## 必要なルールの読み込み

上記で作ったxmlファイルに必要なルールを読み込む設定を追加します。

ルールに関してはあらかじめルールセットという形でまとめて提供されています。
デフォルトで用意されているルールセットは

* cleancode.xml
* codesize.xml
* controversial.xml
* design.xml
* naming.xml
* unusedcode.xml

の6つです。

ルールの読み込みは```<ruleset></ruleset>```内で行います。

```xml
<ruleset ...省略>
  <rule ref="rulesets/codesize.xml" />
</ruleset>
```

上記のように```<rule>```として、参照元を指定します。
refで指定している場所はプロジェクト内にcomposerでインストールした際には
```vendor/phpmd/phpmd/src/main/resources/```
になっているので、元ファイルを参照する際にはここで見れます。

またルールの読み込みは１つ１つのルール単位で行うことも可能です。

```xml
<rule ref="rulesets/cleancode.xml/BooleanArgumentFlag" />
```

上記のようにルール単体での指定も行えます。
cleancode.xmlの中には他に

* ElseExpression (else利用を禁止する)
* StaticAccess (static呼び出しを禁止する)

というルールがありますが、使うべき場面もあるので外すようにしています。
ルールセット中で適用したいルールが少ない場合はこのように適用したいルールのみを指定する方がわかりやすいです。

## 不要なルールの除外

ルールセット中から不要なルールを除外します。
先に行ったcleancode.xmlからの読み込みを、不要なものを除外するパターンで書くと以下のようになります。

```xml
<rule ref="rulesets/cleancode.xml">
  <exclude name="ElseExpression" />
  <exclude name="StaticAccess" />
</rule>
```

```<rule>``` 内に ```<exclude>``` ディレクティブを加えます。
これでルールセット内から不要なルールを除外することができます。

## 変更したいルールの除外と読み込み

最後に本題の一部ルール変更を行う場合です。
記法に少し注意が必要です。

```xml
<rule ref="rulesets/naming.xml">
  <exclude name="ShortVariable" />
</rule>
<rule ref="rulesets/naming.xml/ShortVariable">
  <properties>
    <property name="minimum" value="2" />
  </properties>
</rule>
```

上記はnaming.xml内のShortValiable(短い変数名の禁止)の閾値を上げる例です。
まず変更したいルールを除外してルールセットの読み込みを行います。
そして、ルール単体で読み込んだ上でプロパティを書き換え、最低文字数を元々の3から2に引き下げます。
公式ドキュメントにある通りですが、除外しての読み込みを行わないと、ルールは変更ではなく追加になってしまいます。
除外を外すと変数の文字数3文字以上の制限と2文字以上の制限両方が有効なルールとなってしまうので、注意しなければいけないポイントです。

# まとめ

PHPMDのルールを変更することで、プロジェクトに合わせて柔軟に良くない匂いのプログラムを検知することができます。
重いのが辛いところですが、人が見なくてもいい問題を検知して教えてくれるので有効活用できると生産性が上がると思います。
TensorFlow の "AttributeError: 'module' object has no attribute 'xxxx'" エラーでつまづいてしまう人のための移行ガイド

TensorFlowでディープラーニングを試してみるにあたって、まずは先人たちが公開してくれているスクリプトを動かしてみよう、と思うわけですが、こういうエラーにぶつかってしまいます

- `AttributeError: 'module' object has no attribute 'scalar_summary'`
- `AttributeError: 'module' object has no attribute 'merge_all_summaries'`
- `AttributeError: 'module' object has no attribute 'SummaryWriter'`
- etc...

「そんな関数はない」と言われてるようですが、恥ずかしながらTensorFlowもPythonもちゃんと勉強しないままにまずはスクリプトを実行してみよう、という状況ですので、ひとつひとつググってStackOverflowの回答を参考にしたりしてたのですが、

- http://stackoverflow.com/questions/41066244/tensorflow-module-object-has-no-attribute-scalar-summary

どうやらこれは

- 実行環境：TensorFlow 1.0
- スクリプト：それ以前のバージョン向けに書かれたもの

という状況で起こっているらしく、それらの修正方法がまとまった**公式の移行ガイド**を見つけました。

- https://www.tensorflow.org/install/migration

関数のところを抜粋するとこんな感じです。（`旧` -> `1.0`）

- `tf.audio_summary` -> ``tf.summary.audio`
- `tf.contrib.deprecated.histogram_summary` -> `tf.summary.histogram`
- `tf.contrib.deprecated.scalar_summary` -> ``tf.summary.scalar`
- `tf.histogram_summary` -> `tf.summary.histogram`
- `tf.image_summary` -> `tf.summary.image`
- `tf.merge_all_summaries` -> `tf.summary.merge_all`
- `tf.merge_summary` -> `tf.summary.merge`
- `tf.scalar_summary` -> `tf.summary.scalar`
- `tf.train.SummaryWriter` -> `tf.summary.FileWriter`
[iOS]iOSアプリ開発用の骨組み

アプリ開発の骨組み用プロジェクトを作りました。

https://github.com/nakamurau1/SwiftAppSkelton

構成としては一番メジャー？なTabBarとNavigationControllerを組み合わせたものです。

<img width="200" alt="Screen Shot 2017-02-19 at 17.24.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/22680/804e71f6-06ea-f8e9-f597-549d4a826f60.png">

<img width="200" alt="Screen Shot 2017-02-19 at 17.25.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/22680/8760e1c7-18db-8d34-fbaf-739da7e16a73.png">

共同作業時のコンフリクトをなるべく防ぐために、TabごとにStoryboardを分割しています。

<img width="258" alt="スクリーンショット 2017-02-19 17.28.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/22680/f7a62f62-42a2-c296-4032-f82336e71cd4.png">

AppDelegateはこんな感じ。

```swift
import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    var tabController: MainTabBarController?
    var navController1, navController2: UINavigationController?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        self.tabController = MainTabBarController()
        
        var viewControllers: [UIViewController] = []
        
        // ファイル名を指定してStoryBoardを生成
        let firstStoryBoard: UIStoryboard = UIStoryboard(name: "FirstTab", bundle: nil)
        let secondStoryBoard: UIStoryboard = UIStoryboard(name: "SecondTab", bundle: nil)
        
        // 生成したStoryBoardのInitialViewControllerを取得
        let firstViewController: UIViewController = firstStoryBoard.instantiateInitialViewController()!
        let secondViewController: UIViewController = secondStoryBoard.instantiateInitialViewController()!
        
        // NavigationController
        navController1 = UINavigationController(rootViewController: firstViewController)
        navController2 = UINavigationController(rootViewController: secondViewController)
        
        viewControllers.append(navController1!)
        viewControllers.append(navController2!)
        
        self.tabController!.viewControllers = viewControllers
        
        self.window = UIWindow(frame: UIScreen.main.bounds)
        self.window?.backgroundColor = UIColor.white
        self.window?.rootViewController = self.tabController
        self.window?.makeKeyAndVisible()
        
        return true
    }
    ...
}
```
PySerialで取得したasciiコードを0埋めして表示

# 経緯
シリアル通信ソフトを作っていて、ログ表示のために16進数を0埋めしたかった。

# 実装
## 1byteのとき
- decode関数でasciiにデコード
- ord関数でcharコードを取る
- format関数を使って2桁表示に整形

```py3
# 1byteならこんな感じ -> 0x02
"0x{0:02x}".format(ord(reading.decode('ascii')))

# codecs使うとこんなふうにも書ける -> 0x02
"0x" + codecs.encode(reading, "hex_codec").decode()

# コメント欄の指摘を受けて
'0x%02x' % ord(reading.decode('ascii'))
```

## 文字列のとき
- decode関数でasciiにデコード
- 文字列をリスト分割して各要素を無名関数で整形
- mapで返るのはイテレータなので、再度リスト化
- 最後に","で繋げて返す

```py3
# 文字列ならこちら -> 0x02,0x45,0x46,0x03
",".join(list(map(lambda x: "0x{0:02x}".format(ord(x)),list(reading.decode('ascii')))))

# コメント欄にて%で書いたほうがシンプルだとの指摘を頂いたので
','.join('0x%02x' % ord(c) for c in reading.decode('ascii'))
```

# 結論
- 用途に合わせてお好みで。
- '0x02'とかが表現できる。便利。
ReadyNAS HDD増設方法（その２）

#続いて空きスロットに、10TBを設置
![2017-02-19 17_02_58-nasraid2015.png](https://qiita-image-store.s3.amazonaws.com/0/163916/d2a60d53-d88b-33d1-3a9f-8552e5ec789a.png)
これで、6台稼働になりました。
4TBx4から10TBを１台追加した時は、円グラフの変化がなかったが、２台目の場合はすぐに「フリー」の部分が、約4.5GB増加しました。
再構築完了までの時間が３日かかる予定。

![2017-02-19 16_49_32-radio.png](https://qiita-image-store.s3.amazonaws.com/0/163916/fad12cdd-3745-56f2-a945-84021e93d04b.png)
Windowsからは再構築中ですが、空き容量が増えております。

![2017-02-21 21_26_04-nasraid2015.png](https://qiita-image-store.s3.amazonaws.com/0/163916/8fd9c52b-123a-7e7e-7c09-00b9bacd0b26.png)

まる２日強かかって、再構築完了。
![2017-02-21 22_49_45-Transmission (__172.21.30.250) (Z_)のプロパティ.png](https://qiita-image-store.s3.amazonaws.com/0/163916/eab55b11-d8d6-8418-f760-28d53a02491f.png)

最終的に、4TBx4 + 10TBx2 でのX-RAID(RAID5)での利用可能領域は23.6TB でした。

あと10TBを、4台HDD購入しないといけないので、つづく。
ReadyNAS HDD増設方法

#ReadyNAS 316
4TBx4台で、RAID5を構成してましたが、そろそろ容量不足になってきたので、10TBx6 に変更するまでの方法の覚書きです。
##Firmware
現時点の最新版 6.61に更新ずみ（購入時は6.24前後だったかな）

![2017-02-18 09_31_40-nasraid2015.png](https://qiita-image-store.s3.amazonaws.com/0/163916/0e8cf066-ace3-827e-7e54-c55edcdaf933.png)
まずは、現在の状態から使用率90%を超えているので、パフォーマンスも100%発揮できないはず。
##RAID構成を
固定RAID5から、X-RAIDへ変更します。
画面右側にあるX-RAIDをクリックするだけで瞬時にX-RAIDに変更されました。
##10TB HDDを２台用意
amazonで、5万/台 前後でした
![IMG_0283.JPG](https://qiita-image-store.s3.amazonaws.com/0/163916/7fec086e-0595-471f-8789-d5a72afe35c0.jpeg)
##まずは１台接続
5秒ぐらいでアラートが表示される
![2017-02-18 10_23_51-nasraid2015.png](https://qiita-image-store.s3.amazonaws.com/0/163916/7d385aeb-4ce1-fd17-66c3-de20f2ede6e9.png)
##ボリューム状況を確認
![2017-02-18 10_24_30-nasraid2015.png](https://qiita-image-store.s3.amazonaws.com/0/163916/a4ae39a7-f69a-dec4-6d01-5eab4d652d1e.png)
`再構築まで54時間`
![2017-02-19 06_27_08-nasraid2015.png](https://qiita-image-store.s3.amazonaws.com/0/163916/41560bba-f9d8-8699-a388-663ecfe236d4.png)
![2017-02-19 16_40_09-nasraid2015.png](https://qiita-image-store.s3.amazonaws.com/0/163916/3f089885-fe80-7a36-4b7e-80aa97a59c68.png)
`結果、30時間ぐらいで完了`

追加した10TBの4TB部分しか使ってない状態です。

公式のRAID容量計算ページは[こちら](http://rdconfigurator.netgear.com/raid/index.html)

10TBHDDをもう一台追加へつづく。
cakephp3 デバッグログわかりやすく

cakephp3でログを取得する時,

```
\Cake\Log\Log::debug();
```

って感じでやるの非常にだるい。

ということで、

```
clog("cronsTable deleteZips ファイルを削除します",'cron');
clog($delete_files,'cron');
```

こんな感じでわかりやすくかいてみます。
cakephpのlogなので clog にしてみました。

・bootstrap.php で define.phpを読み込めるように
```
    Configure::load('define', 'default');
```

define.phpで

//  scopeがcronなら cron.logに書く

```

function clog($data,$scope = "debug"){

    if($scope == "debug"){
        \Cake\Log\Log::debug($data);
    } else {
        \Cake\Log\Log::info($data, ['scope'  => [$scope]]);
    }

}
```

と書く。

app.php でログを変更

    /**
     * Configures logging options
     */
    'Log' => [
        'debug' => [
            'className' => 'Cake\Log\Engine\FileLog',
            'path' => LOGS,
            'file' => 'debug',
            'levels' => ['notice', 'info', 'debug'],
            'url' => env('LOG_DEBUG_URL', null),
            'scopes' => false//これが大事
        ],
        'error' => [
            'className' => 'Cake\Log\Engine\FileLog',
            'path' => LOGS,
            'file' => 'error',
            'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'],
            'url' => env('LOG_ERROR_URL', null),
        ],
        'cron' => [
            'className' => 'Cake\Log\Engine\FileLog',
            'path' => LOGS,
            'file' => 'cron',
            'levels' => [],
            'scopes' => ['cron'],
        ],
    ],

この debug の scopes を false をするのが大事なので、忘れずに。

これで clog でログを取得することができるようになりましたね。
Djangoのデプロイ（Ubuntu 14.04 LTS + Nginx + uWSGI + Supervisor）

# 概要
タイトルの組み合わせでDjangoのデプロイするのに相当苦労したので、次回の糧に備忘録。
ハマったところも残しておく。

組み合わせは以下

- Ubuntu 14.04 LTS --- OS
- Django 1.8 --- Python Webアプリ
- Nginx 1.10.3 --- リバースプロキシ
- uWSGI 2.0.14 --- Webサーバー
- Supervisor --- uWSGIのデーモン化
- pyenv --- Python実行バージョン切り替えツール　※今回の設定で特に記述箇所はなかった。


## Django

ある程度作って下記コマンドを実行してブラウザからアプリケーションが動作することを確認。
これができてないと以下をやってもムダ。

```
$ python manage.py runserver 0.0.0.0:8000
```



## uWSGIの設定

uWSGIはaptで入れたがうまくうごかなかった。これだけで２日ハマった。

sudoをつけてuwsgiを実行すると下記のエラーが出てうまく動作しない。

```
$ sudo uwsgi ***
```

ブラウザで確認するとログにno python application found～とログが出る。

```
--- no python application found, check your startup logs for errors ---
[pid: 10523|app: -1|req: -1/1] 121.101.66.160 () {40 vars in 785 bytes} [Sun Feb 19 14:12:06 2017] GET / => generated 21 bytes in 0 msecs (HTTP/1.1 500) 2 headers in 83 bytes (0 switches on core 0)
```

ググるとこんな情報が・・・
http://www.yodiaditya.com/no-python-application-found-check-your-startup-logs-for-errors/


### uWSGIのアンインストール（本来はこの手順いらない）

```
sudo apt-get remove uwsgi*
sudo apt-get purge uwsgi*
```

### uWSGIのインストール

pip経由でuWSGIをインストール。(sudo付けたか忘れた)

```
pip install uwsgi
```

iniファイルにする前に確認（http）　ブラウザでhttp://****:8889/adminにアクセス。

```
$ uwsgi --http :8888 --file /home/<user>/<pass>/<to>/<projectname>/<projectname>/wsgi.py
```

サイトが見れた。



## Nginxの設定

以下のように設定した。とりあえず8887番ポートで。

```
# sudo vi /etc/nginx/conf.d/uwsgi.conf

upstream django {
    server unix:///tmp/<projectname>.sock;
}

server {
    listen 8887;
    access_log /var/log/nginx/<projectname>_access.log;
    error_log /var/log/nginx/<projectname>_error.log;

    location /static {
        alias /home/<user>/<pass>/<to>/<projectname>/static/;
    }

    location / {
         include uwsgi_params;
         uwsgi_pass django;
    }
}
```



uWSGIを起動した後ブラウザから動作確認

```
$ uwsgi --socket /tmp/<projectname>.sock --chmod-socket=666 --file /home/<user>/<pass>/<to>/<projectname>/<projectname>/wsgi.py
```


ブラウザで確認（http://****:8887/admin）

```
error removing unix socket, unlink(): Operation not permitted [core/socket.c line 198]
```

apt経由でuWSGIを入れた際のsocketファイルが残っていて？パーミッションエラーが出た。
rmでsocketファイルを削除する。

```
sudo rm /tmp/<projectname>.sock
```

もう一度uwsgiを起動して再度ブラウザで確認したら見れた。


## uWSGIの自動起動設定（Supervisor）


これはaptから入れる。

```
sudo apt-get install supervisor
```

設定ファイル（合ってるかどうかはわからないがとりあえず動いてはいる・・）

```
#  sudo vi /etc/supervisor/conf.d/uwsgi.conf
[program:uwsgi]
directory = /home/<user>/<pass>/<to>/<projectname>
command = /home/<user>/.pyenv/shims/uwsgi --ini /etc/uwsgi/apps-enabled/<projectname>.ini
stopasgroup = true
numprocs = 1
autostart = true
autorestart = true
user=root
redirect_stderr = true
stdout_logfile = /var/log/supervisor/uwsgi.log
```



ステータス確認

```
sudo supervisorctl status
```


## ブラウザから確認

http://*****:8889/adminとかで開けばOK！
サーバーを再起動して再度アクセスできるか確認してOK！


## 今後の課題
- サブディレクトリ（http://ドメイン/サブディレクトリ/:80）で複数のDjangoアプリケーションが運用できるようにしたい。
- Ruby用にunicornも動かしているのでhttp://ドメイン/サブディレクトリ/によってNginxからuwsgiとunicornを振り分けられるようにしたい。(両方とも80番ポートでできるのか)
- ログのローテーション
MacでのRuby on Rails環境構築コマンドまとめ


Macで以下のような環境の場合での、Rubyのアップデート及び、Ruby on Railsのインストール手順をまとめました。

* Mac OS 10.12.3（Mac OS Sierra）
* Ruby 2.0.0(Mac標準インストール)

## Rubyのバージョンアップ

Rubyのバージョンが古いとRuby on Railsのインストール時にエラーでインストール出来ません。
今回はHomebrewを使い、以下のコマンドで投稿時に最新の安定版の2.3.1へバージョンアップします。

```
$ brew install ruby-build
$ brew install rbenv
$ rbenv install 2.3.1
$ rbenv global 2.3.1
```

ただし、ここで`ruby -v`を実行すると、古いバージョンのRubyが表示されます。
そこで、`~/.bash_profile`に以下の２行を追加しましょう。

```
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"
```

上記を追加したら、ターミナルを再起動するか、`source ~/.bash_profile`を実行します。
再度、`ruby -v`を実行すると、バージョンが更新されますので、バージョンアップ完了。

```
$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]
```

## Ruby on Railsのインストール
### XcodeのCommand Line Toolsのインストール
これをやらないと、Railsをインストール時に「nokogiri」のバージョンによるエラーでインストールが出来ないようです。
Command Line ToolsはXcodeをインストール後、もしくはAppleのダウンロードサイトからダウンロード後、以下のコマンドを実行でインストールを起動しインストールします。

```
$ xcode-select --install
```

### rubygemでインストール

以下のコマンドを実行して、投稿時に最新版の5.0.1をインストールします。
パーミッションが不足している場合は、`gem install ~`の前にsudoを付けて実行してください。

```
$ gem install bundler
$ gem install rails
$ rbenv rehash
$ rails -v
Rails 5.0.1
```

## 参考
* [【macOS Sierra】Mac OSX 10.12 macOS Sierra にRuby + Rails4 開発環境の構築 【初心者必見】](http://qiita.com/keneo/items/e81bad87995fae566234)
* [MacのRubyを最新化する手順](http://qiita.com/tmknom/items/56542abd9341820bb9cc)
* [OSX への nokogiri 1.6.8.rc3 の install でハマって解決したメモ](http://qiita.com/south37/items/63c938474bf35b30c988)
* [【El Capitan】Mac OSX 10.11 El Capitan にRuby + Rails4 開発環境の構築 【初心者必見】](http://qiita.com/keneo/items/1772adc2ebbde229fb71)
* [Macで作るRails環境構築手順](https://tsuchikazu.net/mac_rail_setup/)
RailsでPDFのテキストを読み込んでみる Poppler編

[RailsでPDFのテキストを読み込んでみる pdf-reader編](http://qiita.com/kijitora-neko/items/2eae2b2b68b48e89458f)

前回うまく取り込めていなかったので、他のGemを探していたところ、`Poppler`が良さそうだったので試して見た。

## gemのインストール

Gemfileに`gem 'poppler'`を追加して`bundle install`としたらエラー。。。
色々探っていると、どうやらRabbitを入れると一緒にpopplerも入るということで、[こちら](http://rabbit-shocker.org/ja/install/homebrew.html)を参考にまずはHomebrewでinstallとLinkの設定

```
$ brew install cairo
$ brew link cairo
$ brew link --overwrite pixman
$ brew install pango
$ brew install gtk+
$ brew install poppler --with-glib
```

その後Gemfileに`gem 'rabbit'`を追加して`bundle install`
今度は成功。　やったね！

## Pdfの読み込み
* Railsのタスクに登録して見る

```lib/tasks/read_pdf.rake
namespace :read_pdf do
  desc 'PDF読み込み' # rake -T で表示する説明
  task read: :environment do
    # Report.pdfの読み込み処理
    reader = Poppler::Document.new('pdf/sample.pdf') # 読み込むPDF名
    puts reader.first.get_text                       # 読み込んだテキストの出力
  end
end
```

実行してみると

```
$ rails read_pdf:read
PDF サンプルデータ
お知らせ PDF サンプルデータお知らせ PDF サンプルデータお知らせ PDF
サンプルデータお知らせ PDF サンプルデータお知らせ PDF サンプルデー
タお知らせ PDF サンプルデータお知らせ PDF サンプルデータお知らせ
PDF サンプルデータお知らせ PDF サンプルデータお知らせ PDF サンプル
データお知らせ PDF サンプルデータ
お知らせ PDF サンプルデータお知らせ
PDF サンプルデータお知らせ PDF サ
ンプルデータお知らせ PDF サンプル
データお知らせ PDF サンプルデータお
知らせ PDF サンプルデータお知らせ
PDF サンプルデータお知らせ PDF サ
ンプルデータお知らせ PDF サンプル
データお知らせ PDF サンプルデータお
知らせ PDF サンプルデータ
お知らせ PDF サンプルデータお知らせ
PDF サンプルデータお知らせ PDF サ
ンプルデータお知らせ PDF サンプル
データお知らせ PDF サンプルデータお
知らせ PDF サンプルデータお知らせ
PDF サンプルデータお知らせ PDF サ
ンプルデータお知らせ PDF サンプル
データお知らせ PDF サンプルデータお
知らせ PDF サンプルデータ
$ 
```

pdf-reader編では文字化けしていたところがちゃんと表示されている。
installでハマらなければ、popplerの方が使いやすいね！
CakePHP3 で SessionとCookie設定でブラウザ終了後もセッションを継続する方法

以下を```/config/app.php```に追加する。

```:php
'Session'                  => [
	'defaults'                => 'database',
	'cookie'                  => 'session', // 任意の文字列
	'timeout'                 => 259200, // 180days
	'cookieTimeout'           => 259200, // 180days
	'autoRegenerate'          => false, // 自動でセッションを再生成するのをやめる
	'checkAgent'              => false, // trueにすると毎回セッションが切れることがある
	'ini'                     => [
		'session.cookie_lifetime' => 15552000, //180days
	],
	'use_cookies'     => 1, // SessionをCookieにも保存する
	'cookie_lifetime' => 15552000//180days
	],
```

##参考
これだとうまくできなかったので

[CakePHPでのSessionとCookie設定でブラウザ終了後もセッションを継続する方法
](https://jmatsuzaki.com/archives/16583)

[公式情報](https://book.cakephp.org/3.0/ja/development/sessions.html)