OmniAICreator/Qiita-1.07M huggingface dataset:
Xamarin.Forms Quickstartをやってみた。

Xamarinを使ったクロスプラットフォーム開発のお勉強第1歩として、こちらのページにある入門用チュートリアルをやってみています。
[Xamarin.Forms Quickstart](https://developer.xamarin.com/guides/xamarin-forms/getting-started/hello-xamarin-forms/quickstart/)

Xamarin.Formsを使ったアプリの取っ掛かりとして、良い題材ですね。これを使ったクロスプラットフォーム開発がどんなものなのかが何となく分かるものになっています。

##１．このチュートリアルでできるアプリ

これはアメリカで見かける、アルファベットで表記された電話番号を通常の電話番号に変換して電話を掛けるアプリです（参考：[アメリカの電話番号のアルファベット表記](http://oshiete.goo.ne.jp/qa/97216.html)）

作ってみると、下図のような動きをするアプリが出来上がります。

<img width="851" alt="sampleApp.png" src="https://qiita-image-store.s3.amazonaws.com/0/123715/105732a4-1e0d-c1fd-4ff5-53095e74abc8.png">


##２．このプログラムの構造

実際このチュートリアル通りにプログラムを作ってみると分かるんですが、下図のような構造になっているんですね。

<img width="715" alt="プログラムの構造.png" src="https://qiita-image-store.s3.amazonaws.com/0/123715/15f2d735-313e-45f3-98e9-3458bde8f15e.png">

UIやビジネスロジックは各OS共通で書けるようですが、デバイスの操作をする部分（このチュートリアルでは電話をかける部分）は、個別にロジックを作る必要があるようです。
なので、恐らくですが、例えばGPS情報の取得のようなものは、個別に書く必要がありそうですね。

で、この共通部分と各OS個別に書く部分のデータの受け渡しを、
　(1) インターフェース
　(2) DependencyService.Get<T>();
　(3) [assembly: Dependency(typeof(<クラス名>))]
の3つを使って実現しています。

各OS毎のプログラムを組む部分を、このチュートリアルでは
　・「IDialer」インターフェースを用意
　・それを各OS毎に「PhoneDialer」クラスとして実装
という方法を採っています。通常のオブジェクト指向の実装方法ですね。

この実装したクラスのインスタンスを取得するのに、「DependencyService.Get<T>();」と「[assembly: Dependency(typeof(<クラス名>))]」を使っています。

このインスタンスの取得をしている部分が下図の部分です。ここにブレークポイントを置いてみると、今現在実行している端末のインスタンスが取得できていることが分かります。

<img width="444" alt="インスタンス取得.png" src="https://qiita-image-store.s3.amazonaws.com/0/123715/d69e7c7d-4418-5e9a-cace-d0d446127955.png">

「DependencyService.Get<T>();」というプログラムでインスタンスが取得できることが分かります。

ここで、試しに各OS毎に書いたプログラム（PhoneDialer.cs）にある「[assembly: Dependency(typeof(PhoneDialer))]」をコメントアウトして、もう一度デバッグ実行してみます。

<img width="426" alt="インスタンス取得2.png" src="https://qiita-image-store.s3.amazonaws.com/0/123715/a20002ad-5306-75e1-7946-0834ba89aeaf.png">

すると、図中に示したように、インスタンスの取得ができず、nullとなってしまいます。「[assembly: Dependency(typeof(<クラス名>))]」がないとダメなようですね。


まだ取っ掛かり程度の知識しかありませんが、Xamarin.Formsで開発する場合、
　(1) UI、ビジネスロジックはロジックを共通化できる
　(2) デバイスを直接使う部分は個別にロジックを書く必要がある
ということでしょうか？

デバイスの機能を使う部分とはいえ、例えばHTTP通信とか電波が圏外になっているかどうかなども個別にロジックが必要なのか、まだまだ調べなきゃいけないことはありますね。
Vagrant プラグインがインストール済みかどうかVagrantfile でチェックする

必要なプラグインをインストールせずに `vagrant up` など実行すると原因のわかりづらいエラーメッセージ（`Message: NameError: uninitialized constant Aws` 等）で止まる。ちょっとだけ親切にしたいと思ってVagrantfile 内でプラグインのインストール状態をチェックする様にしました。

`Vagrant#has_plugin?` を使うとプラグインがインストール済みかチェックできます。Vagrantfile にRuby コードをそのまま書けるので、こんな感じで書いてます。

```:Vagrantfile
plugins = %w(
  aws-sdk
  vagrant-aws
).reject { |name| Vagrant.has_plugin?(name) }
fail "plugins not found!\nRun `vagrant plugin install #{plugins.join(' ')}`." unless plugins.empty?
```

下記の内容を参考にやっつけ仕事しました。
[Demand a Vagrant plugin within the Vagrantfile? - Stack Overflow](http://stackoverflow.com/questions/19492738/demand-a-vagrant-plugin-within-the-vagrantfile/19507570#19507570)

# プラグインのインストールを自動化したい

[vagrant-multiplug というVagrantのプラグイン](http://qiita.com/r7kamura/items/4221035fe23c549c288f)を使うと `vagrant up` する時に自動的にインストールするように設定できるみたいです。
Debian Packageを作成する


ファイルを配置するためだけのdebian package(.deb)を例に、packageの作成方法をまとめる。


###1. ファイル構成


```
ukinau@test:~/package-test$ tree
.
├── DEBIAN
│   ├── control
│   ├── md5sums
│   ├── postinst
│   └── preinst
└── usr
    └── share
        └── doc
            └── package-test
                └── test.txt

5 directories, 5 files

```


DEBIANディレクトリ配下の４ファイルがpackage作成用のヒントファイルになる。

DEBIANディレクトリ以外のディレクトリは、実際に配備されるファイル。ディレクトリ構成(パス)は、実際のインストール先になる。
例えば、上記の構成の場合 `/usr/share/doc/package-test/test.txt` というファイルが作成されることになる。


###2. DEBIAN/controlファイルを編集

```DEBIAN/control
Package: package-test
Version: 0.0.1
Architecture: all
Maintainer: ukinau
Section: education
Priority: extra
Description: Packaging test.
```

上を見れば、雰囲気でわかるかと。
その他の設定項目などは、ここを参照。
http://www.debian.or.jp/community/devel/debian-policy-ja/policy.ja.html/ch-controlfields.html


###3. DEBIAN/md5sumsファイルを更新

これは、インストールされるファイル(DEBIANディレクトリ配下以外)のmd5ハッシュ値を羅列すればよい。

```DEBIAN/md5sums
a7e24b94ca3c80fa4808f2a5b739d41e  usr/share/doc/package-test/test.txt
```


###4. postinstとpreinstの用意

これは、ファイル配備だけであれば、特に書かなくてよい。

```DEBIAN/preinst

#!/bin/sh

set -e
#
#        written Tue Jan 20 2015


# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.



exit 0

```

```DEBIAN/postinst
#! /bin/sh
# postinst.skeleton
# Skeleton maintainer script showing all the possible cases.
# Written by Charles Briscoe-Smith, March-June 1998.  Public Domain.
# Abort if any command returns an error value
#

set -e

#        written Tue Jan 20 2015



# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.



exit 0
```

###5. dpkg-debを実行

```
ukinau@test:~/package-test$ dpkg-deb --build /home/ukinau/package-test
```

を実行すると、`/home/ukinau/package-test.deb`が作成される。

よく忘れるので一応メモ代わりに。



-----
追記:
もっと詳しく書かれているサイトを、参考に
http://walf443.hatenablog.com/entry/20090616/1245111017
gradleからtomcatやjettyを起動する。


gradleには標準でjettyと云うプラグインが入っていますが、このプラグインはjetty6で動作するらしく、servret3.x以降とかを要求する場合には使用できません。
IntelliJ IDEA CEを使ってると、商用版IDEAのようにtomcatなどを起動して試験などの機能がありませんので、gradleから起動したいところです。

grettyと云うプラグインがあり、これを利用するとjetty,tomcatともにgradleから起動できるようになるということなので、使用してみました。

gretty
https://github.com/akhikhl/gretty

```build.gradle
apply plugin: 'war'
apply plugin: 'org.akhikhl.gretty'

repositories {
    jcenter()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
}

buildscript {
    repositories { jcenter() }
    dependencies {
        classpath 'org.akhikhl.gretty:gretty:+'
    }
}

```

buildscript で 'org.akhikhl.gretty:gretty:+' を指定して、apply plugin: 'org.akhikhl.gretty' とするだけです。

 あとは gradle jettyRun 、 gradle tomcatRun などとすればアプリが組み込まれた状態でjettyやtomcatが起動します。
 
 また、以下のようにgretty.servletContainer を指定することで起動するサーブレットコンテナを指定できます。
 
```.gradle
// Jetty 7.6.14.v20131031 (Servlet-api:2.5)
gretty {
	servletContainer = 'jetty7'
}

// Jetty 8.1.8.v20121106 (Servlet-api:3.0.1)
gretty {
	servletContainer = 'jetty8'
}

// Jetty 9.2.1.v20140609 (Servlet-api:3.1.0)
gretty {
	servletContainer = 'jetty9'
}

// Tomcat 7.0.54 (Servlet-api:3.0.1)
gretty {
	servletContainer = 'tomcat7'
}

// Tomcat 8.0.8 (Servlet-api:3.1.0)
gretty {
	servletContainer = 'tomcat8'
}

```
Sikuliの使い方（ユースケース編）

Sikuliデモ

# インストーラ

>app = App("setup.exe")
app.open()
wait(Pattern_FirstScreen, 30) #最初の画面が出るまで30秒間待つ。
click(Pattern_Next) #OKボタンをクリックする
click(Pattern_Finish) #OKボタンをクリックする

解説1
インストーラは、最初の画面が出てくるまでの間に他の画面が出たり時間が掛かったりするので、wait()を使うのが良い。

解説2
クリックは、Screen().find(text).click() でも可だがOCRのほうが精度が低いのでOKボタンの形が変わるなど特別な事情がなければパターンでやったほうが良い。

# スクリーンショットを撮る

>filepath=r'c:\tests\test01'
win = app.focusedWindow()
img = win.getScreen().capture(win)
os.rename(img.filename, os.path.join(filepath, 'img.png'))

解説1
指定したfilepathに、カレントウィンドウのスクリーンショット保存する。capture()だとSikuliが指定したフォルダに保存してしまうので、ファイル作成後にファイルを移動する。

# テストの条件分岐

Regression testで条件分岐があるのか判らないが、もしものために記しておく。

```
flag = False
try: 
    wait("1460624593912.png", 1)
    flag = True
except:
    flag = False
```

解説1
wait() の代わりに find() を使うこともできる。もし待ち時間を指定したければwait()を、もしOCRを使いたいfind()を使う。

# タブ移動でテキストボックス間を移動する

>type(Key.TAB)

# Jenkinsやコマンドラインから実行する
>PATH-TO-SIKULIsikuli-ide.exe -r xxxx.sikuli
http://doc.sikuli.org/faq/010-command-line.html

解説1
exeだけでなく標準で提供されるbatファイルでもオプションは指定可能。

解説2
-rにはSikuliを保存した時のフォルダ名を指定する。

解説3
Sikuliスクリプトにパラメータを渡したい場合は、—argsパラメータを使うことも可能。

# Jenkins向けにテスト結果(XML)を出力する
unittestを使う

http://safx-dev.blogspot.jp/2013/06/sikulixml.html
----イメージ----

```
import unittest
class MyTestCase(unittest.TestCase):
  def test01(self):
    pass

if __name__ == '__main__':
  loader = unittest.TestLoader()
  module = __import__('__main__')
  test = loader.loadTestsFromModule(module)
  testRunner = xmlrunner.XMLTestRunner(verbosity=2)  # XMLTestRunnerにする
  testRunner.run(test)
```

# 番外編：Sikuli＋Selenium連携は必要か？

ウェブの記事を読むと、SikuliとSeleniumを連動させている記事を見かけることがあった。将来的にHTML5のテストも視野に入れたいので、Seleniumとの連動を考えておいたほうが良いのかと迷ったが、以下の状況から、連携はそれほど重要では無いとの結論に至った。それよりも学習コストや立ち上がりスピードを重視したい。

インストーラ：Sikuli
インストーラCLI：expectが候補。少なくてもSeleniumではない
Flex系：Sikuli, SilkTest
HTML5系：Selenium, Sikuli, SilkTest
MMC系：Sikuli, SilkTest

学習コスト
Sikuli≒Selenium＜SilkTest

Jenkinsとの連動
SilkTest：できるが大掛かりすぎ
Sikuli：unittest/XMLTestRunnerが必要
Selenium：Node.jsとの組み合わせでできる様子

# 今後

GUIテスト自動化にはSeleniumなどがあるが、Flexはまだまだ現役なので、Sikuliも並行して使い分けていく必要がありそうだ。
ちなみに、SikuliのOCRのTesseractは標準だと画像認識率がイマイチなので、学習させるか、Flexを拡大表示させるか、などの対策が必要そうだ。
【Node.js / Express 版】GitHub に公開したくない変数や値を隠して push する方法

GitHub にパブリックでソースコードを公開するときに、そのソースコードに API key やパスワードなどが含まれていた場合は、その部分だけを隠す必要があります。

調べてみると、たしかにパスワード等を隠して push する方法が書かれたサイトがたくさん出てきますが、ほとんどが Rails の記事でした (自分が調べた限りでは)

環境変数を利用するという方法もありましたが、起動する度に環境変数を入力しないといけないので大変です。

自分は今 Express (Node.js) で開発しているので、なんとかして環境変数以外の方法でできるようにならないかと調べていたら良い方法が見つけました。

# 外部ファイルに設定を移す
今回は例として、ポート番号とテストサーバのIPアドレスを GitHub では公開せずに、実際の運用のときには使えるようにすることにします。

## config.js に公開したくない情報を書く
```lang:config.js
exports.port = 3000;
exports.url  = 'http://192.168.33.10:3000';
```

## プログラムから読み込む
```lang:app.js
var config  = require('./config');
```
プログラム (app.js) と設定ファイル (config.js) は同じディレクトリに置いてください。違うディレクトリに置きたい場合は、各自 require のパスを変更してください。

## 値を使う
```lang:app.js
var config = require('./config');

~~ 省略 ~~

app.locals.home = {
  url: config.url
};

~~ 省略 ~~

app.listen(config.port);
console.log('Server running on port ' + config.port + ' ...');
```
このように、直接プログラムにポート番号やURLを書かなくても使えるようになります。

## gitignore に設定
せっかく config.js に値を切り出しても、このファイルを GitHub に公開してしまっては元も子もありません。なので、gitignore で config.js を公開しないように設定します。

Git で管理するディレクトリ (.git があるディレクトリ) に `.gitignore` というファイルを生成します。そして、.gitignore に以下を書いて保存します。

```lang:.gitignore
config.js
```

※ config.js が .git と同じディレクトリにない場合は、各自で適切なパスを設定してください。

これで完了です。安心して GitHub に公開できます。
Hashから特定のKey（複数）にマッチしないもののみを返す方法

あまりしっくり来ないがとりあえず目的は達成したのでメモ。

```main.rb
hogetable = HogeTable.find_by(hogehoge_id: id).attributes
hogetable = hogetable.reject {|k, v| k.match(/created_at|updated_at/)}
p hogetable
```

ActiveRecord使用。HogeTableからhogehoge_idでハッシュを取り出す。
しかし、created_at と updated_at の情報が不要だったので、どのように取り出すか迷った。

```main.rb
hogetable = hogetable.reject {|k, v| k.match(/created_at|updated_at/)}
```
で created_at と updated_at にマッチしないもののみを返すコードを書いた。
もっといい方法ありそう。。。

※追記！
コメントにて教えていただきました！

```main.rb
hogetable = HogeTable.find_by(hogehoge_id: id).attributes
hogetable = hogetable.except('created_at', 'updated_at')
```
(初心者)WireSharkとtsharkの導入

netcatは便利だが、パケットの詳細を見ることができなかったのでWireSharkとtshark(CLI版wireshark)を導入した。
WireSharkは便利だが、値をエディタに貼り付けるのに不便だったので、そのときはtsharkといった具合に使い分けている。

# インストール方法
これでWiareSharkとtsharkがインストールされる。

```
brew install wireshark
```

# 実行方法＆結果

試しにSNMPパケットの送信

```lang:送信側
snmpwalk -c public -v 1 localhost
```

```lang:受信側
$ sudo nc -u -l localhost 161
0&public?c?8?0
              0	+0&public?c?8?0
                               0
```

上の挙動を横からパケットキャプチャ。

```lang:tshark
$ tshark -i lo0 -l host localhost and udp
Capturing on 'Loopback'
  1   0.000000    127.0.0.1 -> 127.0.0.1    SNMP 72 get-next-request 1.3.6.1.2.1
  2   1.001250    127.0.0.1 -> 127.0.0.1    SNMP 72 get-next-request 1.3.6.1.2.1
  3   2.006483    127.0.0.1 -> 127.0.0.1    SNMP 72 get-next-request 1.3.6.1.2.1
```

以上です。
PHPのメールフォームで都道府県別に飛ばしたい。。。

PHP初心者です。。。
フリーで使われてるZEROMail（ http://zeromail.webtecnote.com/）を
利用しておりますが、PHPで都道府県で選択したときに
指定のメールアドレスに転送したいと考えてます。

メールフォームでセレクトボックス（都道府県）から選択した時に
予め設定したメールアドレスに飛ばしたいと考えてます。

飛ばしたいメールアドレス ****-mail@hogehoge.com（****は都道府県をアルファベットにしたもの）
例）東京の場合 tokyo-mail@hogehoge.com
例）大阪の場合 osaka-mail@hogehoge.com


使っているPHPの記述では下記の記述があります。
define('MAILTO','mail@hogehoge.com');

上記にifなど記述すればよいのかまったくわかりません。

質問の仕方が雑で恐縮ですがこの場合はどのように記述や
定義付けすればよろしいのでしょうか？
EC2にnodejsの環境を構築した時のメモ

sshで対象のインスタンスにログイン

yumをupdate

```lang:
$ sudo yum update
```
yumから必要なパッケージをインストール

```lang:
$ sudo yum install git gcc-c++ make openssl-devel
```

nginxを入れる

```lang:
$ sudo yum install nginx -y
```
nginxを起動する

```lang:
$  sudo chkconfig nginx on
```
```lang:
$  sudo service nginx start
```
nginx.confに設定を追加

```lang:
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://localhost:3000/;
proxy_redirect off;
}
```

nvmをいれる

```lang:
$ git clone git://github.com/creationix/nvm.git .nvm
```
~/.bash_profileに設定を追加

```lang:
if [[ -s ~/.nvm/nvm.sh ]];
 then source ~/.nvm/nvm.sh
fi
```
```lang:
$ source ~/.nvm/nvm.sh
```

インストール可能なnode.jsのバージョンの一覧を表示

```lang:
$ nvm ls-remote
```

nvmからnode.jsをインストール

```lang:
$ nvm install [任意のversion]
```

入れたnodeのversionを確認

```lang:
$ node -v
```

nvmのデフォルトバージョンを定義

```lang:
$ nvm alias default [installした任意のversion]
```
express generatorをいれる

```lang:
$ sudo npm install express-generator -g
```

expressアプリケーションを作成

```lang:
$express Testapp
```

アプリケーションフォルダに移動

```lang:
$cd Testapp
```

npmパーケージをインストール

```lang:
$sudo npm install
```

expressを起動

```lang:
$ node ./bin/www
```

NodeENVを入れる

```
~/.bash_profileに設定を追加
```

```lang:
NODE_ENV=rice
export NODE_ENV
```

これでnodejsをNginx上で動くことが確認できた
Vagrantfileに対して行った設定を反映させる

# 概要

Vagrantfileの内容を書き換えたあと、その内容を反映させるにはどうしたらよいか。

# 結論

***マシンが再起動される***

が

Vagrantfileのある位置であれば

```
vagrant reload
```

# そのほか

vmの名前を指定する場合には

```
vagrant reload [vm-name]
```

とのこと。

```
$vagrant help reload
Usage: vagrant reload [vm-name]

        --[no-]provision             Enable or disable provisioning
        --provision-with x,y,z       Enable only certain provisioners, by type or by name.
    -h, --help                       Print this help
```
node.jsの環境構築（NVMを入れよう）

# node.jsの環境構築

## nvm（node.jsのバージョン管理ツール）を入れる

NVM（Node Version Manger）
node.jsはバージョンによって対応するアプリケーションが動いたり動かなかったりする
こちらをいれることで、その環境でどのバージョンを利用するかを指定できる
※ 環境の中でアップデート、ダウングレードみたいにする手間が省ける

### インストール

- ホームにgitでクローンして有効化する

  ```bash
  git clone https://github.com/creationix/nvm.git ~/.nvm && cd ~/.nvm && git checkout `git describe --abbrev=0 --tags`
  echo "source ~/.nvm/nvm.sh” >> ~/.bashrc
  ```
  ※ ドキュメント（https://github.com/creationix/nvm）

- node.jsのインストール

  ```bash
  nvm install v0.10
  nvm use v0.10
  ```
  ※ これでv0.10.XX系の最新版をインストールして、使用するようにできる

- node.jsのデフォルト指定

  ```bash
  nvm alias default v0.10
  ```

### 確認

- nodeのインストールできるバージョン確認

  ```
  nvm ls-remote
  ```

- nvmでインストールされているバージョン確認

  ```
  nvm ls
  ```
VimのEscキーを押してからのタイムラグを取り除く

## 問題

Vimを使っていて、インサートモードからノーマルモードに戻るためにEsc（エスケープ）キーを押下した際、モードが切り替わるまでにタイムラグがあり、コマンドが本文に入力されてしまう。

## 環境

* Mac OS X 10.11.4
* NeoVim 0.1.3
* zsh 5.2
* tmux 2.1

## 解決法
### vim
キーコードシーケンスが終了するのを待つ時間を短くする。

```
set ttimeoutlen=10
```

### zsh
`KEYTIMEOUT`パラメタは1/100秒単位で指定する。デフォルトは0.4秒なので、これを短くする。下記設定を`$HOME/.zshrc`に追加。

```
KEYTIMEOUT=1
```

### tmux
下記設定を`$HOME/.tmux.conf`に追加して、エスケープシーケンスの待ち時間を消す。

```
set -s escape-time 0
```

##謝辞
John Hawthornさんの[ブログエントリ](https://www.johnhawthorn.com/2012/09/vi-escape-delays/)を参考にさせていただきました。
ビットコインプログラミング超入門編

勉強がてらに手を動かしてみたので、それのレポジトリの公開・

https://github.com/OKohei/BitcoinLeaning/blob/master/ProgramingBlockchain/Program.cs

いちようP2PKHの部分とビットコインのトランズアクションがどうなっているかわかるようになってます。

【準備編】
- Mono Developをインストール http://www.monodevelop.com/
- https://github.com/OKohei/BitcoinLeaning をcloneする。or ダウンロードする
- ProgramingBlockchain.slnというファイルをMonoDevelopから開く

【testnetにアドレスを作ってみる】
- 実行と押す (Windowsユーザーの方は、createKeys()の後に、			Console.ReadLine();という行を追加してください)

【testnetさっき作ったパブリックアドレスにtestnetからコインを送ってみる】
- https://testnet.coinfaucet.eu/en/   のアドレスに突っ込んで、送る
- しばらく待って、testnet上でconfirmationされたことを確認する

【トランズアクションを生成】
- mMyWifにさっき作ったwallet import formatを入れる
- mMyBitcoinAddress にさっき作ったアドレスを入れる
- https://tbtc.blockr.io/address/info/{自分のビットコインアドレス} にして、自分の前のトランズアクションを確認する 
- mainの中のfunctionをPayToPublicKeyHash”{直前に確認したトランズアクション}”）
- Value = Money.Coins (0.0003m)の部分を自分が送りたいアドレスに変える
-　実行ボタンを押す

【トランズアクションをAPIを利用してブロードキャスト】
- https://tbtc.blockr.io/tx/push に先ほど生成したhexを入れてみる


正しくブロードキャストできれば成功。出来ない場合は、何かおかしい部分あり。

＊注意点
https://live.blockcypher.com/btc-testnet/pushtx/
こちら側でブロードキャストすると、なんでおかしいかちゃんと教えてくれるので、ブロードキャストに失敗しまくったら、こっちでやってみる。

以上！
CentOS 6.4から、Mac OS X El Capitanに通知を送り、Growlでポップアップ表示

# やること
リモートのCentOS 6.4から、ローカルのMac OS X El Capitanに通知を送り、通知ポップアップを表示。(Growlで)

# 前提
ローカル(Mac)に[Growl](http://growl.info/)がインストールされている。

# 手順
## 手元のMacで準備 [外部からの通知を許可]
(参考資料: http://umezo.hatenablog.jp/entry/20100920/1284974406)

Growlの設定を開く。
ネットワーク＞外部からの通知を受け付ける にチェック。

<img width="558" alt="2016-04-28 18.12.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/54562/2ae1d4c9-fc0c-6180-a096-ba3f96421e75.png">

## リモート(CentOS)側で準備 [ruby-growlインストール]

[ruby-growl](https://github.com/drbrain/ruby-growl)をリモート(CentOS)にインストール。

## ローカルのIP確認

ローカル(Mac)にてifconfigし、リモートへ接続する際に利用しているネットワーク・インターフェースのIPアドレスをメモる。
IPアドレスはinet欄に記載されている。

```
$ ifconfig
.
.
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
.
.
	inet 192.168.1.2 netmask 0xffffff00 broadcast 192.168.24.255
.
.
```
今回は192.168.1.2。

## リモート(CentOS)でruby-growlを動かしてみる

リモート(CentOS)に以下スクリプトを作成。先ほどのIPアドレスを入れておく。詳しくは[ruby-growl docs](http://docs.seattlerb.org/ruby-growl/Growl.html)参照。

```rb:notify.rb
equire 'ruby-growl'

g = Growl.new "{ここにIPアドレス}", "ruby-growl"
g.add_notification "ruby-growl Notification"
g.notify "ruby-growl Notification", "It came from ruby-growl!",
         "Greetings!"
```

実行します。

```bash
$ ruby growl.rb
```

表示はこんな感じ

![image](https://qiita-image-store.s3.amazonaws.com/0/54562/279710d9-b43d-6533-04e8-448d7ac11387.png)

表示形式やアイコンが変えられるので、詳しくは [ruby-growl docs](http://docs.seattlerb.org/ruby-growl/Growl.html) へどうぞ。
[ docker ] jenkinsサーバ をdockerで始めてみる

##0. これは備忘録

用意するもの

- Docker tool > Kitematic
- Docker Hub のアカウント
- PC (いま使ってるのはWindows)

##1. やりたいこと

- JenkinsをDockerイメージとしてメンテしたい。

##2. Let's Get started

kitematicを立ち上げてDocker Hubのアカウントでサインインする
Jenkinsのイメージを見つけて`latest`でダウンロードする
KitematicのGUI上で次々と流れるログをボーっと眺める
KitematicのGUI左下にある`Docker CLI`をクリック
Docker CLI上でいろいろdockerコマンドを操作する。

```bash

docker images
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
jenkins                           latest              12354asdg        9 days ago          711.9 MB

docker ps -a
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS                  PORTS                                               NAMES
098gf098098        jenkins:latest         "/bin/tini -- /usr/lo"   3 minutes ago       Up 3 minutes            0.0.0.0:32769->8080/tcp, 0.0.0.0:32768->50000/tcp   jenkins
```

イメージを確認する。コンテナが作成されていることを確認する
再びKitematicのGUIに戻り、`WEB PREVIEW`　というペインの右上にある歯車アイコンの横の四角のアイコンをクリックするとwebブラウザにJenkinsのスタートページが表示される。
`initial password`を入力しろ、と言われるので再びDocker CLIでコンテナにアクセスする

```bash
docker exec -it ${containerID} bash
jenkins@${containerID}:/$
jenkins@${containerID}:/$ cat /var/jenkins_home/secrets/initialAdminPassword
xxxxxxxxxxxxxxxxxx     ## found initial password
# escape from container (CTRL+PQ)
```

こんな感じでパスワードゲット。
さっき開いたwebのjenkins GUIでパスワード入力。
そのまま指示に従って進む。
admin user を作成する。


##3. 自分のイメージとして保存して、Docker Hubに保管する

立ち上がったjenkinsにプラグインなど入れてみる
その状態で保存したいのでcommitして新しいイメージ作ってタグ付ける
後でdocker hubに保管するために'レポジトリ名/イメージ名:タグ'という書式にする
`docker push`でアップロードする。

```bash
docker commit ${containerID} ${dockerhub_repository_name}/${new_image_name}:1.0
docker images  ## 新しいイメージが作成されていることを確認
docker login   ## Docker Hubのアカウントで認証
docker push ${dockerhub_repository_name}/${new_image_name}:1.0
```

また後でいろいろいじるときは`docker pull`か、もしくはKitematicのGUI上で操作するかで、再びダウンロード。


##4. 所感と次の目標

あっという間にJenkinsサーバが出来た。30分もかかってない。超ラク。感動する。

次の目標:: Dockerfileをいろいろ試す
[WIP] 自分用メモ：こんなのを作ってみよう

自分向けの、勉強用の課題です。時々増やします。

- Swift
  - 値を持つ配列で、アクセスできる範囲を制限する「覗き窓配列」ラッパーを作る
  - 元の配列の途中に値を差し込むラッパーを作ってみる
  - ↑のラッパーを繋げれるようにしてみる
- UIKit
  - Safariのように、NavigationBarやTabBarを引っ込めてみる
  - カレンダーアプリの年→月→日のような画面遷移を実装してみる

- ReactiveCocoaを齧ってみた記事が古すぎるので、今時で書き換えてみる（SwiftBondかな）
Rubyの*の動作確認


呼び出す側の引数にアスタリスクを付けると与えられた配列は展開される。

```ruby:irb
def hoge1(a, b, c, d)
    p "a=#{a}";
    p "b=#{b}";
    p "c=#{c}";
    p "d=#{d}";
end

arr = [111, 222, 333];
hoge1(1, *arr)
```

呼び出される側のアスタリスクは配列にまとめてしまいます。

```ruby:irb
def hoge2(a, b, c, *d)
    p "a=#{a}";
    p "b=#{b}";
    p "c=#{c}";
    p "d=#{d}";
end

hoge2(1, 2, 3)
hoge2(1, 2, 3, 4)
hoge2(1, 2, 3, 4, 5)
hoge2(1, 2, 3, 4, 5, 6)
```
Ruby | split の引数を省略する

省略すると

```rb
split(/\s/).reject(&:empty?)
```

と書いた時と、似た動作になるようだ。

# 検証

スペースを区切り文字として扱ってくれる。

```rb
"A B C D E".split

# => ["A", "B", "C", "D", "E"]
```

改行も区切り文字として扱われる。
区切り文字が混在・連続していても、いい感じで扱ってくれる。

```rb
" A\nB\r  C  \r\nD E ".split

# => => ["A", "B", "C", "D", "E"]
```


# 参考

- [split (String) | Ruby リファレンス](http://ref.xaio.jp/ruby/classes/string/split)

# 環境

- ruby 2.3.0



<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# メンター受付


https://menta.work/user/5694

<!-- Update From Qiita API -->
Visual RecognitionとTensorFlowをもっとちゃんと比べてみた

[前の記事](http://qiita.com/VegaSato/items/9b85859686ced827f862)でVisual Recognition(VR)とTensorFlow(TF)を比較してみたのだけど、とりあえず動かしたレベルだったので、もう少しちゃんと比較してみようと思ってやってみた。

# ルール
VRの入力ファイルは10000枚まで(Positiveイメージ、Negativeイメージそれぞれ10000枚までっぽい)なので、各数字1000枚ずつ、0～9で10個あるので合計10000枚をトレーニング・セットとして使うこととした。
MNISTのトレーニング・セットは全部で55000枚あるが、数字ごとに5500枚ずつというわけではなかったりする。こんなんでいいんだろうか。まぁいいのか。

トレーニング完了後、テスト・セットを使ってトレーニング精度を判定する。MNISTは10000枚のテスト・セットがある。それを全て投入して正答率(Accuracy)を比較しようというのがこの企画である。

# Visual Recognitionの場合
VRでは、Positiveイメージ1000個、Negativeイメージ9000個でClassifierを作る。これを0～9まで10回繰り返した。
トレーニングにかかる時間はClassifier1つあたり1～2時間程度かかった。複数あると時間かかりまくり…と思ったら並行して実行できた。並行度いくつまでいけるのかは不明。一度試してみたい。
VRは判定時のClassifierを絞ることができるので、0～9までのリストを作って判定時に使用した。

VRはscore(=確信度)が0.5未満だとクラスを返してくれないので、その場合は間違いとして判定した。

その結果、**VRの正答率は0.9840(98.4%)**。意外と高かった。[前の記事](http://qiita.com/VegaSato/items/9b85859686ced827f862)で書いたとおり、VRの得意な画像サイズは320x320。一方MNISTの画像サイズは28x28。これはダメかな…と思ったけど、結構な高さを見せてくれてびっくり。

# TensorFlowの場合
チュートリアルにはBeginnersとExpertsの2つのモデルがある。せっかくなのでそれぞれやってみた。

## Begineers
デフォルトではランダムで100個選ぶのを1000回繰り返す。合計10万文字でトレーニングさせるわけだが、ランダムなので何が選ばれるかわからないわけだがこれでいいのだろうか。
今回は10種類あるので、それぞれ10文字ずつ合計100文字選ぶのを100回繰り返すことで1万文字の学習を完了させる。
その結果、**正答率は0.8469**。ちょっと低いかな、と思って、さらに10回ループして合計10万文字分学習した。結局同じ文字を10回ずつ使ったわけだが。その結果、**正答率は0.8846**。少し上昇したがこんなものか。
学習時間は1万回で1秒未満、10万回でも6秒台でありVRよりも大幅に短いわけだが、この正答率は果たして良いのか悪いのか。
<font color=red>*(※Core i5 3320MをVM環境下で2コア使用した場合。時間はマシンスペックに大いに影響されるはず。これが速いのか遅いのかはわかりません。以下同じ。)*</font>

## Experts
Expertsは、50個ランダムで選ぶのを2万回ループする。つまり合計100万文字でトレーニングさせている。これを、今回のルールに合わせて、頭から50個(5個×10文字)選ぶのを200回ループして1万文字トレーニングするようにした。
**正答率は0.9224**。まあまあだったが、せっかくなのでさらに10回ループして合計10万文字分のトレーニングをさせたら、**正答率は0.9723**まであがった。
学習時間は1万回で2分弱、10万回で15分台。VRに比べたら、まだまだ短い。

この結果をグラフにするとこんな感じになる。
Visual Recognitionはトレーニング回数とかわからないので一定の0.9840にしている。
それに対して、TensorFlowの方がトレーニング回数を横軸にしてプロットすると以下のとおり。
![Picture1.png](https://qiita-image-store.s3.amazonaws.com/0/102519/93fdd5a8-7409-7cfe-efac-fd02e6e0c0ea.png)
TensorFlowは学習回数が増えることで、きちんと正答率があがっているのがグラフからもわかる。

## 追加実験
Expertsはどこまで学習したらVRに追いつくのだろうか。
ということで、学習回数を増やしてみて、その結果をグラフにまとめてみた。

![Picture2.png](https://qiita-image-store.s3.amazonaws.com/0/102519/1acd5622-ca3c-d41c-f3f9-7ceb7f10c6e1.png)
40万回でTF Expertsの正答率がVRを追い抜いた。

![Picture3.png](https://qiita-image-store.s3.amazonaws.com/0/102519/3e84d70c-6f45-d895-1fb0-09fe3c340a77.png)
トレーニング時間はどんどん増えていき、今回のVRの平均トレーニング時間である1時間半に近づいていっている。

今回の結果だけを見れば、20万回あたりが時間と正答率のバランスがいいように思える。
もちろんこの結果は、TensorFlowのモデルを使った場合だし、データとしてはMNISTの場合に限ったことだし、このPCを使った場合の話である。TensorFlowの入力/出力が変われば結果はガラっと変わってくるだろう。

では、Watson VRとTensorFlow、どちらが優秀なのか。幸か不幸か、それは全く断言できない結果となったと思う。VRが劣勢だろうなと思っていたけども、[前の記事](http://qiita.com/VegaSato/items/9b85859686ced827f862)のとおりVRもそんなに悪くないし、こうやって数値化するとなおさら悪くない、むしろ良いとさえ思わせられる。
結局、簡単に使い始めたい、アプリからの呼び出しもあれこれしたい、というのであればWatson VRがいいだろう。逆に、自分でモデルをきめ細かく定義して最適化したいのであればTensorFlow(またはその他のDeep Learningのライブラリー)を使う必要がある、ということか。

# おわりに
比較してみると、なかなか面白い結果になって個人的には満足。そして次回はVisual Recognitionの性能を試すべく、ちょっとした実験をした結果を紹介したいと思う。
oracleの表領域が少なくなった場合の調査用SQL

#テーブルスペースの表領域使用量
```
select
   tablespace_name,
   to_char(nvl(total_bytes / 1024,0), '999,999,999' ) as "size(KB)" ,
   to_char(nvl((total_bytes - free_total_bytes) / 1024,0), '999,999,999' ) as "used(KB)" ,
   to_char(nvl(free_total_bytes/1024,0), '999,999,999' ) as "free(KB)" ,
   round(nvl((total_bytes - free_total_bytes) / total_bytes * 100,100),2) as "rate(%)"
from
   ( select
       tablespace_name,
       sum (bytes) total_bytes
     from
       dba_data_files
     group by
       tablespace_name
   ),
   ( select
       tablespace_name free_tablespace_name,
       sum (bytes) free_total_bytes
     from
       dba_free_space
     group by tablespace_name
   )
where
   tablespace_name = free_tablespace_name(+)
```

#スキーマ別 ディスク使用量
```
SELECT
     sg.tablespace_name,
     sg.owner,
     sg.segment_type,
     count (segment_name) segment_cnt,
     sum (blocks) blocks,
     round( sum (bytes)/1024/1024) mb
FROM
     dba_segments sg,
     dba_tablespaces ts
WHERE
     sg.tablespace_name = ts.tablespace_name
GROUP BY
     sg.tablespace_name,
     sg.owner,
     sg.segment_type
ORDER BY
     sg.tablespace_name,
     sg.owner,
     sg.segment_type
```
#ユーザーの表領域を浪費しているテーブルを特定する。
```
select
  tablespace_name,segment_name,segment_type,sum(bytes) / 1000 / 1000
from
  user_extents
group by
  tablespace_name,segment_name,segment_type
order by
  sum(bytes) desc
```
numpy, scipyでOpenBLASを使う

numpy，scipyが遅いと感じた場合，blasの設定を確認するとよい．試した環境はubuntu14.04．

確認方法は，python立ち上げて

```
>>> import numpy
>>> numpy.show_config()

lapack_opt_info:
    extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
    extra_compile_args = ['-msse3']
    define_macros = [('NO_ATLAS_INFO', 3)]
blas_opt_info:
    extra_link_args = ['-Wl,-framework', '-Wl,Accelerate']
    extra_compile_args = ['-msse3', '-I/System/Library/Frameworks/vecLib.framework/Headers']
    define_macros = [('NO_ATLAS_INFO', 3)]
```

にて確認する．


調べた結果，update-alternativesを使う方法等が様々出てきたが，そちらの方は挙動がおかしかったので，直接OpenBLASを設定してnumpyをコンパイルする方法を備忘録として記載

### 参考
- ubuntu 14.04でBLASを使う([link](http://verifiedby.me/adiary/058))
- Installing Numpy and OpenBLAS([link](https://hunseblog.wordpress.com/2014/09/15/installing-numpy-and-openblas/))
- (numpy, scipyちょっと遅い気がするって時はblas, lapack, atlasが入っているか見直しましょう[link](http://qiita.com/r9y9/items/b6b2a0ee00781f1bb480))


## 事前準備

OpenBLASをインストールする前準備として，　python-devとgfortranをインストールする．

```
~$ sudo apt-get install git python-dev gfortran
```

### OpenBLASインストール

gitからOpenBLASをダウンロードし，gfortranにてmake，installする．`/opt/openblas/`にインストールされていることを確認する．

```
~$ git clone https://github.com/xianyi/OpenBLAS
~$ cd OpenBLAS
~$ make FC=gfortran
~$ sudo make PREFIX=/opt/openblas install
```

その後，OpenBLASへのpathを設定しておく．`~/.bashrc`等に記載しておくとよい．

```
~$ export LD_LIBRARY_PATH=/opt/OpenBLAS/lib:$LD_LIBRARY_PATH
```

複数ユーザで使う場合は，

```
~$ sudo -s "echo '/opt/OpenBLAS/lib' > /etc/ld.so.conf.d/openblas.conf"
```

設定が終わった後，

```
~$ sudo ldconfig
```
を実行する．

### numpyインストール

gitからnumpyをダウンロードし，site.cfgにopenblas設定を記載

```
~$ git clone https://github.com/numpy/numpy
~$ cd numpy
~$ cp site.cfg.example site.cfg
~$ vi site.cfg
```

site.cfgの以下の部分をコメント解除する．

```
[openblas]
libraries = openblas
library_dirs = /opt/OpenBLAS/lib
include_dirs = /opt/OpenBLAS/include
```

その後，`~$ python setup.py config`にて設定変更がうまくいっているかを確認する．

```
openblas_info:
  FOUND:
    libraries = ['openblas', 'openblas']
    library_dirs = ['/opt/openblas/lib']
    language = c
    define_macros = [('HAVE_CBLAS', None)]

  FOUND:
    libraries = ['openblas', 'openblas']
    library_dirs = ['/opt/openblas/lib']
    language = c
    define_macros = [('HAVE_CBLAS', None)]
```

上記を確認後，`~$ python setup.py build && python setup.py install`にてビルド・インストールする．

### 動作確認

[ここにあるコード](https://gist.github.com/alimuldal/eb0f4eea8af331b2a890)で，速度を確認する．使用するスレッドの数は`OMP_NUM_THREADS`にて指定する(下の例は5000*5000の行列計算)．

```
~$ OMP_NUM_THREADS=1 python test_numpy.py
version: 1.12.0.dev0+3c394f7
maxint:  9223372036854775807

BLAS info:
 * libraries ['openblas', 'openblas']
 * library_dirs ['/opt/openblas/lib']
 * define_macros [('HAVE_CBLAS', None)]
 * language c

dot: 4.537050 sec
~$ OMP_NUM_THREADS=8 python test_numpy.py
version: 1.12.0.dev0+3c394f7
maxint:  9223372036854775807

BLAS info:
 * libraries ['openblas', 'openblas']
 * library_dirs ['/opt/openblas/lib']
 * define_macros [('HAVE_CBLAS', None)]
 * language c

dot: 1.855611 sec
```

### scipyインストール

上記でnumpyがインストールできれば，あとはpipでscipyをインストールするだけです．

```
pip install scipy
```
最近のOpenSSLではSSLv2がデフォルトで無効になっているという話

古いバージョンのOSSを最近の環境でビルドしようとすると、次のようなエラーが出ることがあります。

```
Undefined symbols for architecture x86_64:
  "_SSLv2_client_method", referenced from:
      _php_openssl_setup_crypto in xp_ssl.o
  "_SSLv2_server_method", referenced from:
      _php_openssl_setup_crypto in xp_ssl.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```

上記はMac OS Xでのエラーですが、Linux環境でも同じようなエラーで悩んでいる人がいるようです。

このエラーは、OpenSSLのSSLv2関連のAPIがその環境に存在しないのが原因です。セキュリティ上の理由から最近のOpenSSLではデフォルトでSSLv2のサポートが無効になっており、SSLv2関連のAPIを呼び出したり動的リンクしていたりすると即死するというわけです。

というわけで、私の場合は問題のOSSに対してSSLv2関連APIを呼び出さないようなパッチを書きました（というか最新版のコードからコピペしてきました）。SSLv2が無効になっているOpenSSL環境では`OPENSSL_NO_SSL2`が定義されるので、これを使って`#ifdef`で分岐することができます。

SSLv2はプロトコル上の脆弱性が見つかっているので、これを有効にしてOpenSSLをビルドしなおすのはオススメしません。念のため。
array.new with block

```rb
From: /home/vagrant/data/2.rb @ line 4 :

    1: require 'pry'
    2: 
    3: a = Array.new(2) do |a|
 => 4: 	binding.pry
    5: end

[1] pry(main)> a
=> 0
[2] pry(main)> exit

From: /home/vagrant/data/2.rb @ line 4 :

    1: require 'pry'
    2: 
    3: a = Array.new(2) do |a|
 => 4: 	binding.pry
    5: end

[1] pry(main)> a
=> 1
[2] pry(main)> exit
```

```rb

vagrant@precise64:~/data$ pry
[1] pry(main)> Array.new(8) {|a| 'o'} 
=> ["o", "o", "o", "o", "o", "o", "o", "o"]
[2] pry(main)> Array.new(8) {'o'} 
=> ["o", "o", "o", "o", "o", "o", "o", "o"]
```
ruby flatten flat_map

http://qiita.com/bananaumai/items/91aa9851c9c2267c27b1

```rb
[2] pry(main)> [1,2].flatten
=> [1, 2]
[3] pry(main)> [1,[2,3]].flatten
=> [1, 2, 3]
[4] pry(main)> [1,[2,[3,4]]].flatten
=> [1, 2, 3, 4]
```

http://martinfowler.com/articles/collection-pipeline/flat-map.html

```rb
vagrant@precise64:~/data$ ruby 2.rb 

From: /home/vagrant/data/2.rb @ line 6 :

    1: require 'pry'
    2: 
    3: a = ["two birds", "three green peas"].flat_map do |s|
    4: 	s.split
    5: end
 => 6: binding.pry
    7: puts a

[1] pry(main)> a
=> ["two", "birds", "three", "green", "peas"]
```
CentOS7でLAMP環境構築

# 各種パッケージのアップデート
OSインストール後は各種パッケージのアップデートを行う
`# yum update`

# MySQL5.6のインストール
## MySQLをインストールするためリポジトリを追加
CentOS7からデフォルトでMariaDBがインストールされるためMySQLのリポジトリ設定をDLする
`# cd ~/`
`# wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm`
`# rpm -Uvh mysql-community-release-el7-5.noarch.rpm`
## MySQLのリポジトリ設定が追加されているか確認
`# cd /etc/yum.repos.d`
`# ls -al`
## MySQLのインストール
`# yum install mysql-community-server`
## MySQLがインストールされているか確認
`# rpm -qa | grep mysql`

# MySQLの起動
## 起動
`# systemctl start mysqld`
## ステータス確認
`# systemctl status mysqld`
## 停止
`# systemctl stop mysqld`
## 自動起動をOnにする
`# systemctl enable mysqld`

## MySQLに接続
`# mysql -u root`

# MySQLの初期設定
## mysql_secure_installation の実行
`# mysql_secure_installation`

# PHP５．６のインストール
## Remi リポジトリの追加
### EPEL リポジトリの追加
`# yum install epel-release`
### Remi のリポジトリの追加
`# cd /etc/yum.repos.d`
`# wget http://rpms.famillecollet.com/enterprise/remi.repo`
## PHP5.6のインストール
`# yum --enablerepo=remi,remi-php56 install php php-common`
## PHPのバージョン確認
`# php -v`

# Apache2.4のインストール
## インストール
`# yum --enablerepo=remi,remi-php56 install httpd`
## 起動
`# systemctl start httpd`
## 自動起動をOnにする
`# systemctl enable httpd`

# Web接続する
## 設定ファイルの保存場所を確認
`# httpd -V`
## 設定ファイルの中身を確認
DocumentRootのディレクトリを確認する
`# less /etc/httpd/conf/httpd.conf`
## htmlファイルの設置
`cd /var/www/html/`
`vim index.html`

# phpMyAdminをインストールする
※おそらくphpMyAdminをYumでいれればその他のパッケージも自動でインストールされると思います。
## php-mbstringのインストール
`# yum --enablerepo=remi,remi-php56 install php-mbstring`
## php-pdoのインストール
`# yum --enablerepo=remi,remi-php56 install pdo`
## php-mysqlndのインストール
`# yum --enablerepo=remi,remi-php56 install php-mysqlnd`
## phpMyAdminインストール
`# yum --enablerepo=remi,remi-php56 install phpMyAdmin`
## 設定ファイルを修正
デフォルトでローカルからのみアクセスが許可されているのでその制限を外す

```lang:/etc/httpd/conf.d/phpMyAdmin.conf
<Directory /usr/share/phpMyAdmin/>
   AddDefaultCharset UTF-8

   <IfModule mod_authz_core.c>
     # Apache 2.4
     #Require local       #コメントアウト
     AllowOverride all    #追加
     Require all granted  #追加
   </IfModule>
   <IfModule !mod_authz_core.c>
     # Apache 2.2
     Order Deny,Allow
     Deny from All
     Allow from 127.0.0.1
     Allow from ::1
   </IfModule>
</Directory>
```
## Apache再起動
※reloadでもいい
`# systemctl restart httpd`

## 接続
`http://<ip>/phpMyAdmin/`
各formごとにvalidationのエラーメッセージ出したい

## validateしたエラーメッセージの表示について

もっと簡単なやり方教えていただきたいのでqiitaにmemoとしてアップしました。

こういうのはよく見る

```hogehoge.html.haml
= form_for @hogehoge do |f|
    - if @hogehoge.errors.any?
        %ul
          - @hogehoge.errors.full_messages.each do |msg|
            %li= msg
```
こういう風にまとめてメッセージを表示される

<img width="326" alt="スクリーンショット 2016-05-02 15.28.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/32138/ec30d521-4e16-6834-0957-f0679475c8df.png">

でも、↓みたいに表示したい
<img width="369" alt="スクリーンショット 2016-05-02 15.28.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/32138/1287ddb3-20c5-0658-c1f9-d92227656aa8.png">

こういうのはよくある話だと思ってgemとかプラグインで解決できるだろうと思ってぐぐってみてもなかなかいい情報が見つからず困る。

### 1つ目の解決策
@xxxx.errors.messagesから取り出す
@xxxx.errors.messages[:zipcode][0]にエラーメッセージ入るのでこれを表示

```
 .field
  = f.label :zipcode
  = f.text_field :zipcode
  %p{class: 'error'}=@xxxx.errors.messages[:zipcode][0]
```
#### デメリット

* これだと項目数多いと途端につらい。
* Modelに presence: {message: 'XXXXは必須入力です'} 等を書く必要がある
* なによりとてもイケてない感に襲われる

### 2つ目の解決策

formBuilderをつくってみる

参考：http://mmmpa.hatenablog.com/entry/2015/01/12/Rails_%E3%81%AE_form_for_%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC%E5%87%BA%E3%81%9F%E3%81%A8%E3%81%8D%E3%81%AB%E3%80%81%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%AF%E3%81%A1%E3%82%83%E3%82%93%E3%81%A8%E3%82%A8

まんま使ってみる

```builders/with_error_form_builder.rb
class WithErrorFormBuilder < ActionView::Helpers::FormBuilder
  def pick_errors(attribute)
    return nil if @object.nil? || (messages = @object.errors.messages[attribute]).nil?
    lis = messages.collect do |message|
      %{<li>#{message}</li>}
    end.join

    %{<ul class="errors">#{lis}</ul>}.html_safe
  end

  def text_field(attribute, options={})
    return super if options[:no_errors]

    super + pick_errors(attribute)
  end
end
```

こうなった。項目名を出したい・・・。


<img width="353" alt="スクリーンショット 2016-05-02 15.46.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/32138/0af7be56-b6bc-3fa3-fbc6-0a24774f455b.png">

@hogehoge.errors.full_messages では項目名+エラー内容となっているので
これを生成しているメソッドを探す

```~/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activemodel-4.2.6/lib/active_model/errors.rb
# Returns a full message for a given attribute.
#
#   person.errors.full_message(:name, 'is invalid') # => "Name is invalid"
def full_message(attribute, message)
  return message if attribute == :base
  attr_name = attribute.to_s.tr('.', '_').humanize
  attr_name = @base.class.human_attribute_name(attribute, default: attr_name)
  I18n.t(:"errors.format", {
    default:  "%{attribute} %{message}",
    attribute: attr_name,
    message:   message
  })
end
```

full_messageをつかってメッセージを組み立てることで出来た。

```builders/with_errror_form_builder.rb
class WithErrorFormBuilder < ActionView::Helpers::FormBuilder

  def pick_errors(attribute)
    return nil if @object.nil? || (messages = @object.errors.messages[attribute]).nil?
    lis = messages.collect do |message|
      %{<li>#{@object.errors.full_message(attribute, message)}</li>}
    end.join

    %{<ul class="errors">#{lis}</ul>}.html_safe
  end

  def text_field(attribute, options={})
    return super if options[:no_errors]

    super + pick_errors(attribute)
  end
end
```
MongoDBをモニタリングする (2016夏)

MongoDBをモニタリングしてみましょう。

## MongoDB as a Serviceを利用する

ここにたどり着いてしまったあなたは、自前でMongoDBクラスタを運用しなくてもいい可能性が高いです。 https://www.compose.io/mongodb/ などのマネージドサービスの利用を検討しましょう。

### MongoDB Cloud Manager

https://www.mongodb.com/cloud/cloud-manager

手軽に監視したいなら、MongoDB, Inc.公式のCloud Manager（旧MMS）を利用するといいでしょう。

![](https://www.mongodb.com/assets/images/cloud/visual-profiler.png)

### NewRelic MongoDB plugin

NewRelic基盤を用意しているのならば、 https://newrelic.com/mongodb を使うのがいいでしょう。

![](https://blog.newrelic.com/wp-content/uploads/Screen-Shot-2015-11-04-at-2.33.25-PM-2.jpg)

### Datadog-MongoDB Integration

Datadogを使っていれば、 https://docs.datadoghq.com/integrations/mongodb/ もいいでしょう。

### MongoDB Zabbix monitoring plugin

Zabbixによる監視システムを構築しているのであれば、このプラグインを使うのがいいでしょう。最新版のZabbix 3.0には対応していないはずです。

https://github.com/nightw/mikoomi-zabbix-mongodb-monitoring

### MongoDB Munin plugin

Muninによる監視システムを構築しているのであれば、このプラグインを使うのがいいでしょう。

https://github.com/comerford/mongo-munin

![](https://docs.mongodb.org/ecosystem/_images/munin-configuration-screen-shot-1.png)

![](https://docs.mongodb.org/ecosystem/_images/munin-configuration-screen-shot-2.png)

## MongoDB Enterprise & Ops Manager

次回はMongoDB Ops Managerについて書いてみたいですね。では。
ruby each_with_index and reduce

http://batsov.com/articles/2013/12/04/using-rubys-each-with-object/
http://rubyquicktips.com/post/20104758978/enumerableeachwithobject

```rb
From: /home/vagrant/data/2.rb @ line 5 :

    1: require 'pry'
    2: 
    3: nums = [1,1,2,3,3,5]
    4: nums.each_with_object(Array.new) do |e,a|
 => 5:  binding.pry
    6: end

[1] pry(main)> a
=> []
[2] pry(main)> e
=> 1
[3] pry(main)> 
```

```rb
From: /home/vagrant/data/2.rb @ line 5 :

    1: require 'pry'
    2: 
    3: nums = [1,1,2,3,3,5]
    4: nums.each_with_object(Hash.new(0)) do |e,a|
 => 5:  binding.pry
    6: end

[1] pry(main)> a
=> {}
[2] pry(main)> e
=> 1
[3] pry(main)> 
```

```rb

From: /home/vagrant/data/2.rb @ line 5 :

    1: require 'pry'
    2: 
    3: nums = [1,1,2,3,3,5]
    4: nums.reduce(Hash.new(0)) do |a,e|
 => 5:  binding.pry
    6: end

[1] pry(main)> a
=> {}
[2] pry(main)> e
=> 1
[3] pry(main)> 
```

reduce参数是反的 并且需要return一下

```rb


From: /home/vagrant/data/2.rb @ line 6 :

    1: require 'pry'
    2: 
    3: my_hash = {a: 'foo', b: 'bar'}
    4: 
    5: my_hash.each_with_object({}) do |(k,v), h|
 => 6: 	binding.pry
    7: end

[1] pry(main)> k
=> :a
[2] pry(main)> v
=> "foo"
[3] pry(main)> h
=> {}
[4] pry(main)> 
```
Xamarin.Formsのチュートリアル

XamarinでiOS、Androidで共通のUIコードを書こうと思ったら、Xamarin.Formsを使う必要があります。

VisualStudio2015で、「Blank App (Android)」や「Blank App (iPhone)」などのテンプレートを使うと、UIを各OS用に独自にプログラミングしなくてはなりません。

共通のUIが書けるXamarin.Formsを使うには、「Blank App (Xamarin.Forms Portable)」というテンプレートを使います。（Xamarin.Forms Sharedとの違いはまだちょっと良く分かりませんが、今後分かったらメモ書きます）

<img width="471" alt="BlankApp_Xamarin.Forms_Portable.png" src="https://qiita-image-store.s3.amazonaws.com/0/123715/7bfb5a21-618a-70e2-c96d-e9c3245814c1.png">


##１．Xamarin.Formsの最初の1歩

こちらのページに、Xamarin.Formsの入門用チュートリアルがあります。
https://developer.xamarin.com/guides/xamarin-forms/getting-started/hello-xamarin-forms/quickstart/

Xamarin.Formsの取っ掛かりとしてこちらのページに書かれている通りにプログラムを書いてみたのですが、一部そのままでは一部そのままではビルドできない箇所があります。

どこかというと、WindowsPhoneのプログラム。上記のホームページ上では下図のようになっているのですが、これはVisualStudio2015で作られるWindowsPhone 8.1ではビルドできません。

``` lang:PhoneDialer.cs
// Windows Phone 8.1ではビルドエラーとなるコード
//（Xamarin.FormsのQuickStartのコードです）

using Microsoft.Phone.Tasks;
using Phoneword.WinPhone;
using Xamarin.Forms;

[assembly: Dependency(typeof(PhoneDialer))]

namespace Phoneword.WinPhone
{
    public class PhoneDialer : IDialer
    {
        public bool Dial(string number)
        {
            PhoneCallTask phoneCallTask = new PhoneCallTask
            {
                PhoneNumber = number, DisplayName = "Phoneword"
            };

            phoneCallTask.Show();
            return true;
        }
    }
}
```

WindowsPhone 8.1からは、Microsoft.Phone.Tasks名前空間が無くなっているそうで、それが原因でこのコードはビルドエラーとなってしまうそうです。
（参照：http://stackoverflow.com/questions/24997435/microsoft-phone-tasks-namespace-is-not-available）

で、どうするかというと、こんな感じに書いてみました。

``` lang:PhoneDialer.cs
// Windows Phone 8.1でもビルドできました。

using Windows.ApplicationModel.Calls;
using Phoneword.WinPhone;
using Xamarin.Forms;

[assembly: Dependency(typeof(PhoneDialer))]

namespace Phoneword.WinPhone
{
    public class PhoneDialer : IDialer
    {
        public bool Dial(string number)
        {
            PhoneCallManager.ShowPhoneCallUI(number, "Phoneword");

            return true;
        }
    }
}
```

Windows.ApplicationModel.Calls名前空間のPhoneCallManagerクラスで、同様のことができるみたいです。
残念ながらWindows Phoneは持っていないので動作確認はしていないのですが...
ViewPager.setOnPageChangeListenerが使えない場合

ViewPagerのフリック時のイベントを取得しようと

ViewPager.setOnPageChangeListenerを使用しようとしたところ、
非推奨になっていました。

どうしたものか…と思いましたが、
ViewPager.addOnPageChangeListenerでいけました！

（「set〜」が「add〜」に、なっています）
UnityプロジェクトにおけるBundleVersion管理

Unityプロジェクトにおいて、BundleVersion値を管理していく必要があるが、
これがまた地味に面倒だったので、備忘録的に残しておく。

# 今回やりたかった事
- ヒューマンエラーを防ぐため、バージョン設定は一か所で行いたい
- 基本は[x.y.z]形式だけど、リリース後にデバッグ用にz未満のバージョンもつけたい
- アップデート通知のため、サーバにバージョン値をint型で送信したい

# BundleVersionをスクリプト側で取得する
- UnityEditor上ではUnityEditor.PlayerSettingsが使用できるので楽だが、ビルド後はNativeコードを使用する必要がある模様

## Unity側のコード
```csharp:PluginManager.cs
using UnityEngine;
using System.Runtime.InteropServices;

public class PluginManager
{
#if !UNITY_EDITOR && UNITY_IOS
  [DllImport("__Internal")]
  static private extern string _GetVersionName();
#endif

  static public string GetBundleVersion()
  {
    string bundleVersion = "0.0.0";
#if UNITY_EDITOR

    bundleVersion = UnityEditor.PlayerSettings.bundleVersion;

#elif UNITY_ANDROID
    
    AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    AndroidJavaObject context = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity").Call<AndroidJavaObject>("getApplicationContext");
    AndroidJavaObject pManager = context.Call<AndroidJavaObject>("getPackageManager");
    AndroidJavaObject pInfo = pManager.Call<AndroidJavaObject>("getPackageInfo", context.Call<string>("getPackageName"), 0);
    bundleVersion = pInfo.Get<string>("versionName");

#elif UNITY_IOS

    bundleVersion = _GetVersionName();

#endif

    return bundleVersion;
  }
}
```

### 2016/05/12追記
```
AndroidJavaObject pInfo = pManager.Call<AndroidJavaObject>("getPackageInfo", context.Call<string>("getPackageName"), pManager.GetStatic<int>("GET_ACTIVITIES"));
```
上記コードだと特定以上のAndroidOSでクラッシュする現象が起きていたので、0固定で入力するように修正。

## iOS版のみNativeコードも記述する必要がある
```objc++:PluginManager.mm
extern "C"
{
  char* _GetVersionName();
}

char* _GetVersionName()
{
  NSString *buildNo = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
  char* res = (char*)malloc(strlen([buildNo UTF8String]) + 1);
  strcpy(res, [buildNo UTF8String]);
  return res;
}
```
**@"CFBundleVersion"** だと *VersionCode* を取得してしまうので、
**@"CFBundleShortVersionString"** を使用する。

# Unityバージョンっぽく[1.0.0p1]のように定義した上でInt型に変換する
- このあたりは好みの問題なので、オマケ的な感じ。

```csharp
using System.Text.RegularExpressions;

public class Temp
{
  public int ClientVersionId
  {
    get
    {
      int bundleVersionId = 0;
      string bundleVersion = PluginManager.GetBundleVersion();
      var reg = new Regex(@"^(\d+).(\d+).(\d+)");
      var match = reg.Match(bundleVersion);
      if (match.Groups.Count == 4)
      {
        bundleVersion = string.Format("{0}{1}{2}",
          match.Groups[1].ToString(),
          match.Groups[2].ToString(),
          match.Groups[3].ToString());
        int.TryParse(bundleVersion, out bundleVersionId);
      }
      return bundleVersionId;
    }
  }
}
```

1.0.0と1.0.0p1は同バージョンとして扱いたいので、今回は無視するように設計。

ex)
- 1.0.0 => 100
- 2.0.7 => 207
- 1.0.0p1 => 100

正規表現はあまり使わないので、こんな書き方で大丈夫か？などの意見求む！
paiza.ioでswift

#概要
paiza.ioでズンドコ、やってみた。
#サンプルコード
```
import Glibc

var array = ["ズン　" , "ドコ　"]
var zun = 0
while true 
{
    let r = random() % 2
    print(array[r], terminator: "")
    if r == 0  
    {
        zun = zun + 1
    }
    else if r == 1 && zun == 4
    {
        break
    }
    else
    {
        zun = 0
    }
}
print("キ・ヨ・シ！！")

```
#実際
https://paiza.io/projects/e/WXarxwdSzfF2DX4ErwEXvQ?theme=chrome
QTimerをラップするQMLエレメントを作成する


# 動機

QMLには`Timer`エレメントが存在しているが、精度が非常に悪い（原因不明、情報求む）。
そこで応急処置として`QTimer`をラップするエレメントを作成することにした。

参考: http://doc.qt.io/qt-5/qtqml-cppintegration-definetypes.html

# コード

```cpp:cpptimer.h
#pragma once

#include <QObject>
#include <QTimer>

class CppTimer : public QObject {
    Q_OBJECT
    Q_PROPERTY(int interval MEMBER interval_ NOTIFY intervalChanged)
public:

    CppTimer();

    Q_INVOKABLE void start();
    Q_INVOKABLE void restart();
    Q_INVOKABLE void stop();

    void updateInterval();

signals:
    void triggered();
    void intervalChanged();

private:
    QTimer timer_;
    int interval_;
};
```

```cpp:cpptimer.cpp
#include "cpptimer.h"

CppTimer::CppTimer()
    : QObject()
    , timer_(this)
    , interval_(0)
{
    connect(&timer_, &QTimer::timeout, this, &CppTimer::triggered);
    connect(this, &CppTimer::intervalChanged,
            this, &CppTimer::updateInterval);
    timer_.setSingleShot(true);
}

void CppTimer::start() {
    if (!timer_.isActive()) {
        timer_.start(interval_);
    }
}

void CppTimer::restart() {
    timer_.start(interval_);
}

void CppTimer::stop() {
    timer_.stop();
}

void CppTimer::updateInterval() {
    if (timer_.isActive()) {
        timer_.start(interval_);
    }
}
```

# 登録

C++側で`qRegisterType`を使用して登録をおこなう

```cpp
qmlRegisterType<CppTimer>("com.itage.timer", 1, 0, "CppTimer");
```

# 使用

`import`して使用できる

```qml

import com.itage.timer 1.0
//(中略)
CppTimer {
  id: timer
  onTriggered: {
    console.log("onTriggered")
  }
}
```
Linux で Rubygems がインストールできなかった超初歩的なミス

環境: Vagrant (CentOS 7.1)

# Rubygems のインストール
とある目的で gem を使うことになったので以下のコマンドで rubygems をインストールしようとしました。

`$ sudo yum -y install rubygem`

すると以下のように表示され、インストールできませんでした。

```
パッケージ rubygem は利用できません。
エラー: 何もしません
```

# 原因
コマンドを間違えていた。正しくは

`$ sudo yum -y install rubygems`

`rubygem` ではなく `rubygems` でした。
疲れているとこういうミスも気づかなかったりするので注意ですね。

こんなミスをする人は多くないと思いますが、また同じミスをしないようにするための個人的なメモです。
Android StudioでDefault Activity not foundが出たときの対処

Android Studioインストール後、試しにRunしたらエラーが出たので対処したことをメモ。

# 環境
OS X 10.11.4
Android Studio 2.1

# エラー内容
Android Studioをインストール後、新規プロジェクトを作成してMainActivityを作成（未修正）。その後、上部メニューからRun -> Run 'app'を実行したら以下のエラーが出た。
<pre>
Could not identify launch activity: Default Activity not found
Error while Launching activity
</pre>

# 対処方法
起動するActivityを明示的に指定してやる。
設定を開く。
Run -> Edit Configurations... -> Android Application -> app
<img width="893" alt="RunDegugConfig_20160502_14.05.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/113458/aad10e20-013e-6017-fa36-bbd19b625746.png">
Launch Options -> Launch
「Defauit Activity」を「Specified Activity」に変更。
Activity:に「...」ボタンで先ほど作成したMainActivityを選択。

以上。
Deviseでメール認証をできるようにする

# Deviseでメール認証を実装する

## 前提条件
* Deviseの基本的な使用方法はわかっている
  * **メール認証なしの時との差分だけ書きます。**
* Gmailを使用
  * 今回は独自ドメインで利用しています。
* とりあえずローカルだけで、本番では試してません。


## ソースコードの変更箇所
以下の記述を追記

```rb:app/models/deivseを使っているモデルのファイル
devise :database_authenticatable,:registerable,
         :recoverable, :rememberable, :trackable, :validatable,
         :confirmable, :lockable, :timeoutable
```

新規でモデルを作るのか、後からメール認証を付けるかで変わりますが...
新規の場合は下記の行のコメントアウトを解除します。

```rb:マイグレーションファイル
      t.string   :confirmation_token
      t.datetime :confirmed_at
      t.datetime :confirmation_sent_at
      t.string   :unconfirmed_email # Only if using reconfirmable
```


```ruby:config/environments/development.rb
config.action_mailer.default_url_options = {  host: 'localhost', port: 3000 }
  config.action_mailer.raise_delivery_errors = true
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.smtp_settings = {
    address: 'smtp.gmail.com',
    port: '587',
    domain: '独自ドメイン',
    user_name: 'メールアドレス',
    password: 'アプリパスワード', # 詳細は後ほど
    authentication: :plain,
    enable_starttls_auto: true
  }
```
productionのときはproduction.rbもよしなに変更したらいいと思います（未確認）

## Gmailの設定変更箇所

何も設定せずにやると、`安全性の低いアプリ`と認識されて認証されません。
解除方法は、

* 安全性の低いアプリのログインを許可
* ２段階認証を登録してアプリ固有のパスワードを登録

前者が上手く行かなかったので後者にしました。

[2段階認証の設定](https://myaccount.google.com/security#signin)
[アプリパスワードの設定](https://security.google.com/settings/security/apppasswords)

`config/environments/development.rb`では使うメールアドレスのパスワードではなく、ここで指定されたアプリパスワードを使ってください。

## おわり

これでとりあえず動きました！
Gmailの設定周りを全く知らずに結構時間食いました。
プライベートネットワーク内でlinuxにhost名でアクセスする

社内サーバなどにIPアドレスじゃなくて,ホスト名でアクセスしたいときに、ホスト名を設定する方法のメモ

これを実施すると、`<hostname>.local`で社内サーバにアクセスきるようになります。

ただ、どうも固定IPと相性が悪いみたいなので、社内サーバは固定IPにしないようにしましょう。

なお、設定対象OSはubuntuを例にしています（redhat系でも似た感じでいけると思いますが…）

> 固定IPの場合、外部にアクセスできなくなってしまいます
> 固定IPの場合でも、起動後に`dhclient eth0` を実行することで外部にアクセスできるようになりますが、なぜアクセスできなくなるのか原因はわかっていません


#### 設定

avahi-daemonのインストール

```
apt-get install avahi-daemon
```

自分のホスト名の変更

```
vi /etc/hostname # 自分の好きなホスト名（ネットワーク内で一意）に変更する
```

ファイル内容の例↓

```:/etc/hostname
ninjaslayer
```

> 未確認ですが、
`/etc/hosts` の127.0.1.1の部分を上と同じ名前にする必要があるかもしれません

/etc/hostsの例↓

```:/etc/hosts
127.0.0.1 localhost
127.0.1.1 ninjaslayer
```

これで
`ssh ubuntu@ninjaslayer.local`
で社内サーバにアクセスできるようになりました