OmniAICreator/Qiita-1.07M huggingface dataset:
DesignSupportLibraryのFABがAPI21以上と未満でmarginが違う問題の対処法

**`com.android.support:design:22.2.0` 時点での情報です。今後のアップデートで修正されるかもしれません。**

# 現象
Lolipop以降の端末とLolipop未満の端末で、FABのmarginの大きさが変わります。

こんな感じのレイアウトを組むと、Lolipop以降は16dpのmarginで表示されますが、Lolipop未満は32dp、24dpのmarginで表示されてしまいます。

```xml
<android.support.design.widget.FloatingActionButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    android:layout_margin="16dp"
    android:src="@drawable/ic_plus_white_24dp"
    app:borderWidth="0dp" />
```

![2015-07-07_13_38_32_png_と_2015-07-07_13_40_38_png.png](https://qiita-image-store.s3.amazonaws.com/0/15267/b951e2e2-a98f-b2cd-d5f1-864dd6267a2b.png "2015-07-07_13_38_32_png_と_2015-07-07_13_40_38_png.png")


# 原因
Lolipop未満の場合、 `elevation` が使えないため、DesignSupportLibraryの中の `ShadowDrawableWrapper` というクラスでShadowを表現しています。

`FloatingActionButton`の実処理を行っている[FloatingActionButtonEclairMr1](https://github.com/android/platform_frameworks_support/blob/master/design/eclair-mr1/android/support/design/widget/FloatingActionButtonEclairMr1.java)を見るとわかりますが、Shadow部分が上下左右にそれぞれ8dp、16dp、8dp、8dp取っています。

そのため、FloatingActionButton自体にmarginをつけてしまうとShadow部分のmargin分余白が大きくなってしまうわけです。


# 対処方法
コード内でバージョンごとに分岐してmarginを動的にセットしてもできるのですが、 `values-v21`のリソースフォルダを使って対応した方がスマートに解決できます。

### values-v21/styles.xml
```xml
<style name="FabMargin">
    <item name="android:layout_margin">16dp</item>
</style>
```

### values/styles.xml
```xml
<style name="FabMargin">
    <item name="android:layout_marginLeft">8dp</item>
    <item name="android:layout_marginTop">8dp</item>
    <item name="android:layout_marginRight">8dp</item>
    <item name="android:layout_marginBottom">0dp</item>
</style>
```

### layouts
```xml
<android.support.design.widget.FloatingActionButton
    style="@style/FabMargin"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_alignParentRight="true"
    android:src="@drawable/ic_plus_white_24dp"
    app:borderWidth="0dp" />
```

おそらく今後のバージョンアップで修正されると思うので、修正後はstyleを消して `layout_margin` に書き換えればいいと思います。
【2ステップ】Gitコマンドでtab補完を有効にする

#意外と簡単にtab補完するようにできる

`git-completion.bash`という設定ファイルがあり、.bashrcにパスを通すだけでtab補完できるようになる。

#手順

## ステップ１：git-completion.bash のパスを見つける
```
sudo find / -name git-completion.bash
```
で検索。

私の場合は
/Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash
だった。
[SourceTree](https://www.sourcetreeapp.com/)を入れているので
/Applications/SourceTree.app/Contents/Resources/git_local/contrib/completion/git-completion.bash
もヒットしたが、あくまでコマンドラインで使いたいので前者を選んだ。
 
##ステップ２：.bashrc に git-completion.bash のpathを追記
vi ~/.bashrcで開いて
```
source /Library/Developer/CommandLineTools/usr/share/git-core/git-completion.bash 
```
を追加する。 

これだけでgitコマンドの最中にtabで補完できるようになる。
Rails で Value オブジェクトを利用する

# 参考

以下サイトを参考にしました。
http://blog.enogineer.com/2014/11/12/rails-model-design/


# ソースリポジトリ

ソースは以下のリポジトリを参照してください。
https://github.com/katsuhiko/sample_app_rails_4


# バージョン

| version | 
|:---|
| rails 4.2.3 |


# Value オブジェクト

Value オブジェクトは、利用しなくても問題ないんだけど、使うとスッキリするというかなんというか。
使うとメンテナンスの向上等、利点に気づけると思います。


## Value オブジェクトを作る

ざっと調べると、Value オブジェクトは app/values に格納するがベストな様です。

実際の仕事でも似たような Value オブジェクトを作りました。
アプリの仕様に特化した URL に対しての操作です。

```rb:app/values/service_url.rb
class ServiceUrl
  include Comparable

  attr_reader :service, :version

  class << self
    def from_url(url)
      self.new(url)
    end
  end

  # url : http://api.xxxx.com/v1/xxx
  def initialize(url)
    @url = url
    uri = URI(url)
    @service = uri.merge('/').to_s
    @version = uri.path.split('/')[1]
  end

  def better_than?(other)
    self > other
  end

  def <=>(other)
    other.to_s <=> to_s
  end

  def hash
    @url.hash
  end

  def eql?(other)
    to_s == other.to_s
  end

  def to_s
    @url.to_s
  end
end
```

## Value オブジェクトをテストする

RSpec を利用した Value オブジェクトのテストです。
ある程度、お決まりで書いています。不具合が出てら、再現をさせてテストを手厚くするかもしれません。

```rb:app/spec/values/service_url_spec.rb
require 'rails_helper'

describe ServiceUrl do
  context 'URLから情報を生成する場合' do
    let(:service) { 'http://api.example.com/' }
    let(:version) { 'v2' }
    let(:path) { '/xxx' }
    let(:url) { "#{service}#{version}#{path}" }

    let(:service_url) { ServiceUrl.from_url(url) }

    it 'サービス名を取得できること' do
      expect(service_url.service).to eq service
    end

    it 'バージョンを取得できること' do
      expect(service_url.version).to eq version
    end
  end

  context 'Comparable' do
    let(:obj) { ServiceUrl.from_url('http://api.com/v1/x') }
    let(:other) { ServiceUrl.from_url('http://api.com/v1/x') }
    
    it { expect(obj.better_than? other).to be false }
    it { expect(obj <=> other).to eq 0 }
    it { expect(obj.hash).to eq other.hash }
    it { expect(obj.eql? other).to be true }
  end
end
```

# 最後に

とても簡単な例で、実際のアプリケーションでどう使うのかイメージができないかもしれません。

今回の例のような小さな所にも業務／ロジックが隠れている場合があります。
そこを抜き出しておくことがメンテナンスしやすいコードになるんじゃないかと思います。
HttpURLConnectionでPOSTを使う時に、InputStreamがIOExceptionを起こす場合

出力ストリームのflush()を忘れていないか確認する。

write()などをした後にflush()せずに、入力ストリームから読み出そうとすると、(結果が空なので)IOExceptionが発生します。
(まだボディのデータを送っていないので、結果は読めない状態。)

あと、コネクションのsetDoOutput(true);も忘れずに。
(デフォルトではGETになるので。)

ついうっかりをなくそう。
CocoaPods で 画像入りで配布するときのメモ


すげー詰まってググってGitHubのissueとか読んでると「findコマンドを Build Phasesに追加すればいける」みたいなこと最近の投稿でも書いてあるけど、それももう古くて要らなくなったようです。


# やりかた

まずバージョンを最新(0.38.0.beta.2)にアップデート。

↓

**hoge.podspec**

> s.resources = 'path/to/Images.xcassets'

**pod内のSwift**

> UIImage(named: "画像ファイル名", inBundle: NSBundle(forClass: クラス名.self), compatibleWithTraitCollection: nil)


 ↓ できた例
https://github.com/entotsu/KireiShare
Crystal - Array - Instance Method - concat #crystal

## <i class="fa fa-diamond" style="font-size:1em;"></i> 概要
CrystalのArrayクラスのインスタンスメソッド`concat`について

## <i class="fa fa-check-circle" style="font-size:1em;"></i> シグネチャ
`concat(other : Array)`
`concat(other : Enumerable)`

`concat(other : Array)`については、Rubyと同じですが、
`concat(other : Enumerable)`があることによって、
Crystalでは、Enumerableも配列に結合可能になっています。

## <i class="fa fa-flask" style="font-size:1em;"></i> サンプル
### <i class="fa fa-code" style="font-size:1em;"></i> プログラム
~~~ruby
class StepTwo
  include Enumerable(Int32)

  def initialize(limit)
    @limit = limit
  end

  def each
    i = 0
    loop {
      yield i
      i += 2
      break if i > @limit
    }
  end
end

ary = [1,2,3]
pp [1,2,3].concat([4,5,6])
pp [1,2,3].concat(StepTwo.new(10))
pp [1,2,3].concat(StepTwo.new(20))
~~~

### <i class="fa fa-file-text" style="font-size:1em;"></i> 出力
~~~ruby
[1, 2, 3].concat([4, 5, 6]) = [1, 2, 3, 4, 5, 6]
[1, 2, 3].concat(StepTwo.new(10)) = [1, 2, 3, 0, 2, 4, 6, 8, 10]
[1, 2, 3].concat(StepTwo.new(20)) = [1, 2, 3, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
~~~

## <i class="fa fa-book" style="font-size:1em;"></i> 外部資料
* <i class="fa fa-external-link" style="font-size:1em;"></i> [Array - Crystal API Library](http://crystal-lang.org/api/index.html#http%3A//crystal-lang.org/api/Array.html)
NSDictionary要素追加方法 for Swift(Cocoa)


初歩的なことですがハマったのでメモします．

```swift:hoge.swift
var dictionary: NSDictionary = NSDictionary()
dictionary.setValue("hoge", forKey: hoge) // Error
```

```swift:hoge.swift
var dictionary: NSDictionary = NSMutableDictionary()
dictionary.setValue("hoge", forKey: hoge) // Success
```

### コメントを頂いたので修正
```swift:hoge.swift
let dictionary: NSDictionary = NSDictionary()
dictionary.setValue("hoge", forKey: hoge) // Error
```

```swift:hoge.swift
let dictionary: NSDictionary = NSMutableDictionary()
dictionary.setValue("hoge", forKey: hoge) // Success
```
Cのコンパイルをちょっとだけ簡単にする

# Cのコンパイル

gccがあれば簡単にできますね。

```bash:コンパイル
$ gcc hoge.c -o hoge
```

恐らく、元のfile.cから、拡張子.cを抜いたものをコンパイル後のファイル名とするかと思います。

もう形式は決まっているんですよね。
ファイル名を変えることも全然有りですが、コンパイル後のファイル名とか変えても分かりづらいだけですし、そんな事わざわざしませんよね。

<br />

じゃあわざわざ `gcc hoge.c -o hoge` なんて書くのめんどくさくね？

# コマンド一発でコンパイルしようぜ

なので、コマンド一発でコンパイルできるようにします。
コマンドがなければ作ればいいじゃない。
いじくるのは、ホームディレクトリにある `~/.bash_profile` か、もしくは `/etc/profile.d` の配下にシェルスクリプトを作ります。
これはサーバの1ユーザとして使うか、全ユーザが使えるようにするかによって変わってくるかと思います。

1ユーザとして使う場合は、下記を `~/.bash_profile` に追記します。
全ユーザが使えるようにするには、 `/etc/profile.d` 配下に適当に `compile.sh` でも作ってそこに下記を入力してください。

```bash
compile(){
    out=`echo $1 | awk -F '.' '{print $1}'`
    gcc $1 -o ${out}
}
```

一応説明しておきます。
`$1` は引数です。元になるCのファイルですね。
それを `awk` に掛けます。
区切り文字の認識を `.(ドット)` にし、一つ目のフィールドを抜き出しています。
ファイル名が `hoge.c` だとしたら、フィールドの一つ目が `hoge` で、二つ目が `c` になります。
抜き出した `hoge` を変数 `out` に入れます。
その後に `gcc` コマンドで、元の引数 `hoge.c` を、先ほど抜き出した `hoge` で出力しています。

入力したら下記を実行してください。

```bash
$ source /etc/profile
```

これで、 `compile` という名の自作コマンドが使えます。

```
$ com       ←[Tab]キーを2度押す
combinedeltarpm      command              compile              complete-ant-cmd.pl
comm                 compgen              complete             compopt
```
`compile` が候補として出てくるのが確認できます。

あとはこれでコンパイルするだけです。

```bash
$ ls
test.c
$ compile test.c
$ ls
test  test.c
```

これだけです。
因みに私はgccコマンドをよく知りません。
「gccだけでできるよ？」とか「こういうコマンドあるよ？」いうことがあれば教えて下さい・・・。
API 設計ドキュメントをGitHubのプルリクでレビューしつつ Apiary みたいに使うには

API 設計ドキュメントを GitHub のプルリクでコードレビューしつつ Apiary みたい使う方法を考えました。
既存ツールでは、[Apiary](https://apiary.io/) が良さそうだったのですが、次のような問題がありました。

  - GitHub 連携すれば diff が見られるらしいが、連携の制約が満たせなかった
  - リアルタイムプレビューが重い
  - 1ファイル管理がつらい

そこで以下の機能を手元で実現できるようにしました。

  - API Blueprint フォーマットのマークダウン形式のファイルを Group 単位で別ファイルで編集できるようにする
  - Group 単位のマークダウン形式の API 仕様を 1ファイルにまとめる
  - API Blueprint フォーマットのマークダウン形式のファイルから HTML 形式の API 仕様書を生成する
  - 編集中にリアルタイムプレビューできる

次のような利用イメージです。
apidocs/templates/layout.md に以下のようなレイアウトを作成し、

```
FORMAT: 1A
HOST: http://polls.apiblueprint.org/

<% include aaApi.md %>
```

apidocs/templates/aaApi.md に aa API の仕様を API Blueprint フォーマットのマークダウンで記載します。
以下のようなディレクトリレイアウトを想定しています。

```
~/repos/api-review-tool
% tree apidocs
.
├── published
│   └── index.html
│   └── index.md
└── templates
    ├── layout.md
    └── aaApi.md
```


編集中は、gulp のデフォルトタスクで http://localhost:8088 でリアルタイムプレビューできます。
編集がおわったら、以下のコマンドを実行します。

```
gulp publish
```

すると、apidocs/published/index.html と apidocs/published/index.md が生成されます。
生成された結果を apiary のテキストエリアに貼り付けたり、[api-mock](https://github.com/localmed/api-mock) でモックサーバーを立てたりと利用できます。


## 作り方


必要なライブラリをインストールします。

```
npm install -g aglio
npm install gulp --save-dev
npm install gulp-aglio --save-dev
npm install browser-sync --save-dev
npm install rimraf --save-dev
npm install gulp-ejs --save-dev
npm install gulp-rename --save-dev
```

gulpfile.js を作成します。

```.javascript
"use strict";

var gulp        = require('gulp');
var aglio       = require('gulp-aglio');
var browserSync = require('browser-sync');
var rimraf      = require('rimraf');
var ejs         = require('gulp-ejs');
var rename      = require('gulp-rename');

var reload = browserSync.reload;

var TEMPLATE_FILES = ['apidocs/templates/**/*.md'];
var LAYOUT_FILE = 'apidocs/templates/layout.md'
var PUBLISHED_DIR = 'apidocs/published';

gulp.task('combine', function(){
  return gulp.src(LAYOUT_FILE)
    .pipe(ejs({},{ ext: '.md' }))
    .pipe(rename('index.md'))
    .pipe(gulp.dest(PUBLISHED_DIR));
});

gulp.task('generate-api-docs', ['combine'], function() {
  return gulp.src(PUBLISHED_DIR + '/index.md')
    .pipe(aglio({template: 'default'}))
    .pipe(gulp.dest(PUBLISHED_DIR));
});

gulp.task('watch', function () {
  gulp.watch(TEMPLATE_FILES, ['generate-api-docs', reload]);
});

gulp.task('browserSync', function() {
  browserSync({
    logConnections: true,
    logFileChanges: true,
    notify: true,
    port: 8088,
    open: false,
    server: {
      baseDir: PUBLISHED_DIR
    }
  });
});

gulp.task('clean', function(cb) {
  rimraf(PUBLISHED_DIR, cb);
});

gulp.task('publish', ['clean', 'generate-api-docs']);
gulp.task('default', ['generate-api-docs', 'watch', 'browserSync']);
```

あとは上に書いたように gulp のデフォルトタスクを実行して開発、gulp publish でドキュメントを生成します。

## 追記

aglio に include 機能があるようです。成果物として1ファイルのマークダウンファイルがいらないなら、aglio の include 機能を使うのもよいと思います。

- https://github.com/danielgtaylor/aglio#including-files
無料で自分専用CMSを運用する方法（準備編）


## 用意するべきもの

* CMS
* サーバー
* DB（必要であれば）
* ドメイン
* DNSサーバー

## CMS
CMSの選択肢は以下のとおり

|サービス名|普及率(感覚)|情報量|拡張性|導入難易度|備考|
|---|---|---|---|---|---|
|WordPress|高い|多い|普通|やや難しい|PHP + MySQL環境が必要|
|OctoPress|普通|普通|普通|簡単|テーマの種類が少なめ|
|GitHub Pages|普通|普通|低い|非常に簡単|簡単なページ表示のみ|
|Hugo|低い|少ない|不明|不明|Go言語で書かれている。buildなどが早いらしい|

## サーバー
サーバーの選択肢は以下のとおり

|名称|種別|無料プラン|レスポンス|
|---|---|:-:|---|
|さくら|レンタルサーバー|×|はやい|
|Heroku|PaaS|○|アクセスがないとアプリが落ちる|
|OpenShift|PaaS|○|普通（アメリカ西海岸）|
|AppFog|PaaS|○|はやめ（シンガポール）|

## DB
サーバーに一緒に作成する

## ドメイン
[tkドメイン](http://www.dot.tk/ja/index.html)を使用する

## DNS
無料のDNSサーバーを使用する

* [Dozens](https://dozens.jp/)
Java Scriptでサーバ一覧を取得する　その２

## エラー時にローカルストレージを消す

アクセスに失敗したら以下のようにローカルストレージを消すことにします。

```js
var access = function(url, data, type, onSuccess) {
    $.ajax({
      url: url,
      data: JSON.stringify(data),
      type: type,
      headers: {
        'X-Auth-Token' : window.localStorage['token']
      },
      success: onSuccess,
      error: function() {
        console.log('$.ajax error. remove token in local storage.');
        window.localStorage.removeItem('token');
      }
    });
}
```

これにより、例えばトークンの機嫌が切れていた際には以下の様なフローとなります

1. localStorageにトークンが保存されているためservers APIにアクセス
2. errorが実行
3. トークン削除
4. 次回アクセス時にtoken APIを実行

エラー発生時に再度トークンを取得する処理でも良いですが、その場合は無限ループにならないよう気をつける必要があります。


## token API後すぐにservers APIを呼びたい

そう思って以下の様な処理にするとservers APIの呼び出しに失敗します。

```js
access(token_url, token_data, token_type, tokenOnSuccess);
access(servers_url, servers_data, servers_type, serversOnSuccess);  
```

これは`$.ajax()`が非同期に行われるためです。つまり、token APIを呼び出すと結果が返ってくるのを待たずににservers APIを呼びに行きます。この時まだトークンが得られていないためエラーとなります。

では、token APIの完了を待ってservers APIを呼ぶにはどうすればいいのでしょう。。。

`$.ajax()`の戻り値jqXHRには`.done()`という関数が定義されています。これは関数を引数に取り、ajaxの処理が終わったあとにその関数を実行するという性質があります。

なので今回もこれを使ってtoken APIが終了するのを待ってserver APIを呼ぶことにします。

ただし、せっかく`$.ajax()`の呼び出しを関数化したのに、`.done()`のあるなしで２個関数を作るのはちょっと気持ち悪いです。

そこで以下のように関数を変更しました。

↓↓↓↓↓↓↓ あなたの記事の内容
```js

───────
```js
↑↑↑↑↑↑↑ 編集リクエストの内容
var access = function(url, data, type, onSuccess) {
    return $.ajax({
      url: url,
      data: JSON.stringify(data),
      type: type,
      headers: {
        'X-Auth-Token' : window.localStorage['token']
      },
      success: onSuccess,
      error: function() {
        console.log('$.ajax error. remove token in local storage.');
        window.localStorage.removeItem('token');
      }
    });
}
```

前回との違いは`$.ajax()`の前にreturnがついたことです。これにより呼び出し側で`$.ajax()`の戻り値に`.done()`で処理が書けます。具体的には以下のようになります。

```js
$(function(){
  if (window.localStorage['token'] === undefined) {
    access(token_url, token_data, token_type, tokenOnSuccess).done(function() {
      access(servers_url, servers_data, servers_type, serversOnSuccess);  
    });
  } else {
    access(servers_url, servers_data, servers_type, serversOnSuccess);  
  }
});
```

これでtoken APIの後にservers APIを呼び出せるようになりました。


## 見た目を変える
さて、受け取ったサーバ情報をJSONのまま出力するのも味気ないので、tableにしてみます。

↓↓↓↓↓↓↓ あなたの記事の内容
```html
───────
```html:表示部
↑↑↑↑↑↑↑ 編集リクエストの内容
<h2>ConoHa API sample</h2>
<table id="server_table">
</table>
```

```js
var serversOnSuccess = function(data) {
  console.log(data);
  for (var i = 0; i < data.servers.length; i++) {
    var tr = $('<tr>');
    var td_index = $('<td>').text(i);
    var td_name = $('<td>').text(data.servers[i].name);
    tr.append(td_index).append(td_name);
    $('#server_table').append(tr);
  }
}
```

serversのJSONデータには配列が入っているのでforループで回しました。以下の様な表示になります。２個のサーバが見えていますね！

![server02.png](https://qiita-image-store.s3.amazonaws.com/0/85105/e8b3c8d7-196c-2892-9416-86f4405278c9.png)


今回のコードは[ここ](https://github.com/OttyLab/ConoHa_sample/blob/master/servers02.html)にあります。


## 改善点
servers APIはサーバ名ぐらいしか取れません。次回はサーバの詳細情報を表示します。また、東京リージョン以外のサーバ情報の取得にも挑戦します。
pidcatをwindowsでも使いたい

`adb logcat`をカラー表示してくれる[pidcat](https://github.com/JakeWharton/pidcat)ですが、
WindowsだとANSIカラーのエスケープコードがそのまま表示されてしまい使えません。

そこで、ペロっとGo言語で書いてみました。
[github.com/nocd5/crz](https://github.com/nocd5/crz/releases/tag/REV_1_0_0)
他にもエスケープコードがそのまま表示されるプログラムがたまにあるので、そういう場合にも使えるかも。

## 使い方
`python -u pidcat.py | crz`

`-u`オプションは出力のバッファを無効にするオプションです。
これがないとバッファがたまるまで表示されないため、ログが逐次表示されません。
参考:[Python で stdout/stderr のバッファを無効にするオプション](http://qiita.com/kitsuyui/items/7d1704850e503be8dd1c)

## pidcatの調整
これは好みですが、コンソールで表示できる色数が少ないWindowsでは色が付かない部分があったので少し調整しました。

```diff:pidcat.win.patch
diff --git a/pidcat.py b/pidcat.py
index da15682..60cc2b7 100755
--- a/pidcat.py
+++ b/pidcat.py
@@ -89,7 +89,7 @@ RESET = '\033[0m'
 def termcolor(fg=None, bg=None):
   codes = []
   if fg is not None: codes.append('3%d' % fg)
-  if bg is not None: codes.append('10%d' % bg)
+  if bg is not None: codes.append('4%d' % bg)
   return '\033[%sm' % ';'.join(codes) if codes else ''
 
 def colorize(message, fg=None, bg=None):
@@ -153,11 +153,11 @@ if args.color_gc:
 
 TAGTYPES = {
   'V': colorize(' V ', fg=WHITE, bg=BLACK),
-  'D': colorize(' D ', fg=BLACK, bg=BLUE),
-  'I': colorize(' I ', fg=BLACK, bg=GREEN),
-  'W': colorize(' W ', fg=BLACK, bg=YELLOW),
-  'E': colorize(' E ', fg=BLACK, bg=RED),
-  'F': colorize(' F ', fg=BLACK, bg=RED),
+  'D': colorize(' D ', fg=WHITE, bg=BLUE),
+  'I': colorize(' I ', fg=WHITE, bg=GREEN),
+  'W': colorize(' W ', fg=WHITE, bg=YELLOW),
+  'E': colorize(' E ', fg=WHITE, bg=RED),
+  'F': colorize(' F ', fg=WHITE, bg=RED),
 }
 
 PID_LINE = re.compile(r'^\w+\s+(\w+)\s+\w+\s+\w+\s+\w+\s+\w+\s+\w+\s+\w\s([\w|\.]+)$')
```
【Rubyプログラミング問題】値札分割メソッド(split_price)を作成してください


##はじめに

なんとなく思いつきで簡単なプログラミング問題を作ってみました。
チャレンジしてみたい方は以下の内容をよく読んで解答してください。

##問題

ユーザーが自由に入力できる値札データがある。
このデータ（文字列）を以下のようなルールで分割するメソッド、 `split_price` を作成せよ。

```ruby 
'110.0万円'     => ['110.0', '万円']
'2015円'        => ['2015', '円']
'1,123,456円'   => ['1,123,456', '円']
'110 - 120万円' => ['110 - 120', '万円']
'２０１５円'    => ['２０１５', '円']
'価格未定'      => ['価格未定', '']
nil             => ['', '']
```

##解答の手順

### 1. テンプレートファイルの作成

`split_price_test.rb` を作り、以下のコードをコピーしてください。

```ruby
require 'minitest/autorun'

def split_price(price_text)
  # ここに実装を書く
end

describe 'split_price' do
  let(:manyen) { '110.0万円'}
  let(:yen) { '2015円'}
  let(:comma) { '1,123,456円'}
  let(:hyphen) { '110 - 120万円'}
  let(:zenkaku) { '２０１５円'}
  let(:jponly) { '価格未定'}
  let(:blank) { nil }

  it { split_price(manyen).must_equal ['110.0', '万円'] }
  it { split_price(yen).must_equal ['2015', '円'] }
  it { split_price(comma).must_equal ['1,123,456', '円'] }
  it { split_price(hyphen).must_equal ['110 - 120', '万円'] }
  it { split_price(zenkaku).must_equal ['２０１５', '円'] }
  it { split_price(jponly).must_equal ['価格未定', ''] }
  it { split_price(blank).must_equal ['', ''] }
end
```

### 2. テストの実行（失敗）

`split_price_test.rb` を実行し、テストが失敗することを確認してください。

```bash
$ ruby split_price_test.rb
Run options: --seed 48947

# Running:

FFFFFFF

Finished in 0.001387s, 5047.4606 runs/s, 5047.4606 assertions/s.

  1) Failure:
split_price#test_0004_anonymous [price_test.rb:20]:
Expected: ["110 - 120", "万円"]
  Actual: nil


  2) Failure:
split_price#test_0003_anonymous [price_test.rb:19]:
Expected: ["1,123,456", "円"]
  Actual: nil

（省略）


  7) Failure:
split_price#test_0007_anonymous [price_test.rb:23]:
Expected: ["", ""]
  Actual: nil

7 runs, 7 assertions, 7 failures, 0 errors, 0 skips
```

### 3. split_price メソッドの実装

`split_price` メソッドの中身を実装してください。

#### 【注意】コメント欄はまだ見ないで！！

この記事のコメント欄には他の人の解答が載っています。
なので自分の実装が終わるまで見ないようにしましょう。

### 4. テストの実行（成功）

実装が完了したらテストが全部パスすることを確認しましょう。
失敗するテストがあれば実装を修正してください。

```bash
$ ruby split_price_test.rb
Run options: --seed 54905

# Running:

.......

Finished in 0.001053s, 6645.2374 runs/s, 6645.2374 assertions/s.

7 runs, 7 assertions, 0 failures, 0 errors, 0 skips
```

### 5. この記事のコメント欄に自分の解答を載せる

テストが全部パスしたら、この記事のコメントにあなたの解答を貼り付けてください。
解答としてのせるのは `split_price` メソッドだけでOKです（テストコードを載せる必要はありません）。

こだわりポイントやアピールしたい点があればそれもコメントに書いてください。

## 実行環境について

- 対象となるRubyのバージョンは2.0以上とします。（僕は2.2.2で動作確認しました）
- 外部のgemは使わず、Rubyの標準ライブラリだけで実装してください。

## その他、備考等

- テストが全部パスすればそれでOKです。それ以外の入出力パターンは考慮不要です。
  - 例：「僕のコードは全角のカンマや全角のハイフンにも対応してます！！」みたいなオリジナル実装は不要です。
- 解答に順位を付けたり、景品を贈ったりする予定は今のところありません。
- 解答に対する僕からのコメントはあまり期待しないでください（気が向いたらするかもしれません）。
- 締め切りは特に設けていません。いつでも誰でも参加可能です。

## 僕の解答例

数日後に別記事として載せようかなと思っています。

**2015.7.17追記**

解答例を書きました！解答の優秀賞も発表しています。

[【Rubyプログラミング問題】値札分割メソッド(split_price)を作成してください：解答編 - Qiita](http://qiita.com/jnchito/items/c460bff5aec851ed36f9)

## まとめ

冒頭にも書いたとおり、何となくの思いつきで始めたゆるーいプログラミングコンテスト（？）です。

上級者の方は5～10分ぐらいで、初心者の方も30分以内で解ける問題なんじゃないかな～と思います。

いろんな人からいろんな解答が出てくることを期待します。
さあ、あなたも Let's チャレンジ！！


**・・・あ、コメント欄は実装が終わるまで見たらダメですからね！！**
Windows7のワードパッドなどにある「電子メールの送信」が使えない問題

Win7Pro32bitマシンにある弥生会計からバックアップファイルや差分データを直接メーラーで送信できる機能がある。
しかし、メーラーが指定されていないみたいなエラーになる。

■確認した事
・コントロールパネルの規定のプログラムで設定しているのに。
・WEBページのMailtoリンクをクリックしたらメーラーがきちんと立ち上がる。
・AdobeReaderなどの一部アプリのメール送信だといける。
・ワードパッドの電子メールの送信はクリックさえ出来ない。
・メーラーはBecky2だけだった。

■やった事
・WindowsLiveMail2011を入れてみた・・・ダメ
・Outlookを無理やり入れてみた・・・ダメ
・MS Office2010を全パッケージ入れてみた・・・OK！！！
それから
・MS Office2010を全パッケージをアンインストール・・・またダメ
・MS Office2003の全パッケージをインストール・・・OK！

■原因
メーラーが起動しないアプリはMAPIからメール起動しないで、Outlookの何らかのプログラムを経由してメールが起動するのかなぁ・・・？。
以前はOutlookが入っていないのに、弥生会計から直接メーラーが起動したようなので、どっかで壊れたのかなぁ？

余談
弥生会計のＦＡＱはけっこう親切に書いてくれてる事に気づいた
http://cc.yayoi-kk.co.jp/faq/faq_detail.asp?SearchNodeID=20005&SearchType=1&SearchQA=0&SearchAttrs=&SearchText=%u30e1%u30fc%u30eb&SearchCase=&SearchFaqId=&SelectTab=0&NodeID=20005&Page=0&faqID=79976&baID=6&SearchOrder
[Android][Lollipop]ロックスクリーンの通知タップからChromeが起動できない

Android5.0 LollipopではiOSさながらにロックスクリーンに通知を表示することができるようになりました。
しかし、Notificationに入れるContentIntentでChromeを呼び出すようなIntentを渡したところ、ロック解除中は通知タップで普通にChromeを起動しIntentに含んだURLのサイトを表示できたものの、ロック画面の通知をタップした時は何も起こらず、困ったのでメモしておきます。

# 実現したいこと

普通に通知を送って自分のアプリ内のWebViewではなく好きなブラウザでURLのページを表示して欲しいです。
NexusだとChromeしか入ってないので、Chromeを想定してました。
追加するIntentはこんな感じです。

```java:
// httpなスキーマのACTION_VIEWの暗黙intentを渡してます。
Uri uri = Uri.parse("http://example.co.jp");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
PendingIntent pi = PendingIntent.getActivity(context, NOTIFICATION_ID, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);

// 普通にbuilderで渡したり。。
new NotificationCompat.Builder(context).setIcon(
...
).setContentIntent(pi).build();
```

# 困ったこと

ロック解除中、というかステータスバーの通知をタップすると普通にChromeが呼ばれました。

しかし、ロックスクリーンの通知をタップする時は、挙動が違います。
ユーザ視点では何もおきません。

logcatを見ると
> 
E/ChromeLauncherActivity(): Ignoring intent: Intent { act=android.intent.action.VIEW dat=http://www.google.com/ flg=0x10000000 cmp=com.android.chrome/com.google.android.apps.chrome.Main }

のように表示されていました。
明示的Intentに変更してもダメです。

調べると何やらNFC関連のissueとして上がっているようです。
[Issue 455126: 	ChromeLauncherActivity ignores intent as lock screen status (by NFC beam enabled)](https://code.google.com/p/chromium/issues/detail?id=455126)
LockScreen(画面はついてる)でNFC beamでintentをchromeに対して呼ぶと`ignoring intent`とか言われてしまいます。悲しいですね。
しかも仕様として特に対応はしてくれないようです。
まあ、ロック中なのにChrome経由で変なコードが実行されないように、ということなのでしょう。しょうがないですね。

# 回避策

上記のissueスレッドにも書かれていますが、ロックが解除されたら実行されればいいのです。
スレッドでは10秒後とかならlockが解除されたと判断できる、など書いてありますが別にもっと短くてもいいようです。

ということで自分はBroadcastReceiverを使っていたので、それを一回経由してからintentを送るようにしてみました。
もちろん、Serviceとかでも可能だと思います。


```java:
// 中身はそのまま、自分のアプリへの明示的intentにします。
Uri uri = Uri.parse("http://example.co.jp");
Intent intent = new Intent(con, MyReceiver.class);
intent.setAction(Intent.ACTION_VIEW);
intent.setData(uri);
```

受け取るBroadcastReceiverでは、UIスレッドじゃない気がするので、今回はAlarmManagerで遅延させたintentを発行してもらいます。
ServiceとかならThreadを遅延実行させればいいかもしれません。

```java:MyReceiver.java
public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Context con = context.getApplicationContext();
        if ("myaction".equals(action)) {
        ...
        } else if (Intent.ACTION_VIEW.equals(action)) {
            // 今回はとりあえず、ここでintentを作っていますが、中に入れたりしたほうがいいと思います。
            Intent i = new Intent(Intent.ACTION_VIEW, intent.getData());
            AlarmManager am = (AlarmManager) con.getSystemService(Context.ALARM_SERVICE);
            // 500msの遅延を入れてintentを飛ばしてもらいます。これは何秒でもいいと思います
            am.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 500,
                    PendingIntent.getActivity(con, 0, i, 0));
        }
    }
}

```

こうすることで、きちんとchromeを起動することができました。
面倒ですが、しょうがないですね。。
ちなみに遅延は端末の処理速度に依存するかと思いますが、5-10msとかでも全然大丈夫でした。（手元の機種では1msはさすがにダメでした）

というか、ロックスクリーンの通知はタップした直後にintentが発行されず、ロック解除時に発行されるので、結局それをロック中かロック解除後か判別してハンドリングできていないChrome or Androidのバグな気がします。。
複数の公開鍵を一括でサーバに登録

誰かがやってそうな話だけど、メモとして残しておこう

## やりたかったこと

1. リモートログイン可能なユーザの公開鍵を管理して、ansible で各サーバに配布する

## 利用したもの

- 公開鍵を登録するには [authorized_key](http://docs.ansible.com/authorized_key_module.html) を利用する
- `authorzied_key.key` には `lookup` を利用してパスを渡すの簡単（ Examples を参考に）
- 公開鍵のパスは `with_fileglob: <path>` でマッチしたものをそれぞれ渡す

## 作ったもの

```yaml:roles/authorized_key/main.yml
---
# file: roles/authorized_key/main.yml

- name: REMOVE  | public keys from all hosts
  authorized_key: 
    user: "{{ target }}"
    key: "{{ lookup('file', item) }}"
    state: absent
  sudo: yes 
  with_fileglob: "{{ publickeys }}/removed/*.pub"

- name: APPEND  | public keys into all hosts
  authorized_key: 
    user: "{{ target }}"
    key: "{{ lookup('file', item) }}"
    state: present
  sudo: yes 
  with_fileglob: "{{ publickeys }}/*.pub"
```

## 各サーバの testusr の公開鍵を集約して、それを一括で登録する例

```yaml:playbooks/update_authorized_keys.yml

- name: SETUP | public keys for testusr
  hosts: all
  user: root
  roles:
    - role: authorized_key
      target: testusr
      publickeys: ~/.ssh/public_keys/testusr
  pre_tasks:
    - name: FETCH | public keys from all hosts
      fetch:
        src: "/home/testusr/.ssh/id_rsa.pub"
        dest: "~/.ssh/public_keys/testusr/{{ ansible_hostname }}.pub"
        fail_on_missing: yes 
        flat: yes
```  

## playbook 実行後の authorized_keys

```bash
$ tree .ssh
.ssh
├── id_rsa
├── id_rsa.pub
├── known_hosts
└── public_keys
    └── testusr
        ├── hostname01.pub
        ├── hostname02.pub
        └── hostname03.pub
```

```~/.ssh/authorized_keys
ssh-rsa (略) ansible-generated on hostname01
ssh-rsa (略) ansible-generated on hostname02
ssh-rsa (略) ansible-generated on hostname03
```
Yahoo ショッピング web api, can get アダルト(category:25747) data？

Yahoo ショッピング web api, can get アダルト(category:25747) data？

ex：
http://shopping.yahooapis.jp/ShoppingWebService/V1/php/itemSearch?appid=my_app_id&category_id=25747

This code will be empty result,so how do I get the adult data by itemSearch and use categry_id 25747 ？please.
GoogleAnalyticsで怪しいリファラを除外する方法（ビュー設定を使う）

Analyticsで自社サイトを閲覧していて「PVだいぶ増えたね」と言ったら「あ、それ某国のスパムリファラっすよ」というツッコミを受けました。そこで、怪しいリファラを除外してレポートを見れるように設定します。

基本的な設定としては、Analyticsのビュー設定で、`[ボットのフィルタリング]->[既知のボットやスパイダーからのヒットをすべて除外します]`というオプションがあるので、チェックを入れれば基本的なものは除外できると思います。

![スクリーンショット_070715_011903_PM.jpg](https://qiita-image-store.s3.amazonaws.com/0/27707/703398d9-c928-099b-0ec8-d2aad43bbe07.jpeg)

- [Introducing Bot and Spider Filtering Many of you have shared with us that it’s…](https://plus.google.com/+GoogleAnalytics/posts/2tJ79CkfnZk)

除外のガイドラインとしては、以上のブログで、

>Selecting this option will exclude all hits that come from bots and spiders on the IAB know bots and spiders list. 

とありますので、IABのリストを参照して判断しているようです。

- [IAB/ABC International Spiders & Bots List](http://www.iab.net/guidelines/1418/spiders)

その他の対応方法としては、Analyticsのビュー機能を使って対象を除外したビューを作成します。

今回、怪しかったは、以下の3ドメインでした（Webサイト管理者を釣り上げようとしている感じがいかにも、、）。

- trafficmonetize.org	
- 4webmasters.org	
- webmonetizer.net

これらを除外していきます。設定方法は簡単で、ビューの設定にある「フィルタ」を使います。

![スクリーンショット_070715_025457_PM.jpg](https://qiita-image-store.s3.amazonaws.com/0/27707/4e7f02d4-7692-ae3a-b950-c6572d42fc39.jpeg)

これらの設定は既にトラッキングされたデータに対しては適用されないようなので、経過観察中です（分かり次第更新する）。
RSpec3でBASIC認証がかかったアクションをテストする

Basic認証かけたアクションのテストについて書きます。

ModuleのAuthHelper

```ruby
module AuthHelper
  def basic_login
    @env ||= {} #またはenv
    user = 'arekore'
    pw = 'passarekore'
    @env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
  end
end
```

ユーザ名とパスワードはご自分のに読み替えてください。

ただし@request.envに入れてあげないと認証は通りません。

```ruby
module AuthHelper
  def basic_login
    @request.env ||= {}
    user = 'arekore'
    pw = 'passarekore'
    @request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
  end
end
```

これなら通ります。

spec_helperに以下を追記して各specで呼び出すといいです。

```
RSpec.configure do |config|
  config.include AuthHelper, :type => :controller
end
```
クラス内の一部メソッドを特殊化した例

#はじめに
引数(argc, argv)の中身を効率よく取り出すために，Argumentクラスというのをつくっていました．その中で必要だったのは，"-i 20"のように，ある文字列("-i") のあとに続く数字("20")や文字列を任意の型でとってこられるようなメソッドでした．これは， ``int Argument::get_int(std::string)``のような関数をそれぞれの型に対して定義すればできますが，それぞれ用意しないといけないのが面倒です．できれば， ``int a = arg.get<int>("-a");``のような記述でできれば良いのですが，テンプレートの書き方が少々面倒くさいです．先日（２，３年ほど前）に調べてわかったことを，以下にまとめました．

#サンプルコード
以下のコードは，擬似的な引数解析プログラムです．簡単のためコンパイルで引数がいらないように書いています．標準ライブラリのみで作成しているため，コピペでコンパイル可能です．Argument::get()関数が例です．


```cpp:example.cpp
#include <string>
#include <iostream>
#include <vector>
#include <cstdlib>

// 文字列strをそれぞれの型に変換する．
template <typename T> T convert ( const std::string& str );
template<>
std::string convert ( const std::string& str )
{
        return str;
}

template<>
int convert ( const std::string& str )
{
        return std::atoi ( str.c_str() );
}

template<>
double convert ( const std::string& str )
{
        return std::atof ( str.c_str() );
}

// 擬似引数処理クラス
class Argument
{
private:
        std::vector<std::string> args_;
public:
        Argument ( void );
        ~Argument ( void );
        void add ( const std::string& str ) ;
        int size ( void ) const;
        template <typename T> T get ( const int i ) const;
};

Argument::Argument ( void )
{
        return;
}
Argument::~Argument ( void )
{
        return;
}

void
Argument::add ( const std::string& str )
{
        this->args_.push_back ( str );
}
int
Argument::size ( void ) const
{
        return static_cast<int> ( this->args_.size() );
}

template <typename T>
T
Argument::get ( const int i ) const
{
        if ( this->size() <= i ) return T();
        return convert<T> ( this->args_.at ( i ) );
}

// template int Argument::get<int> ( const int idx ) const; と書けばok．
// 以下はマクロを使って，手間を省いたもの
#define ARGUMENT_GET(TYPE) template TYPE Argument::get<TYPE> ( const int idx ) const
ARGUMENT_GET ( std::string );
ARGUMENT_GET ( int );
ARGUMENT_GET ( double );


int main ( int argc, char** argv )
{
        Argument arg;
        arg.add ( "abc" );
        arg.add ( "10" );
        arg.add ( "1.2" );
        std::string str = arg.get<std::string> ( 0 );
        int    a        = arg.get<int> ( 1 );
        double b        = arg.get<double> ( 2 );
        std::cerr << str << " " << a << " " << b << std::endl;
        return 0;
}

```
```bash:実行例
$ ./a.out 
abc 10 1.2
$ 
```

書いてて気づいたのですが，bashでハイライティングできるんですね．便利ですね．
メールサーバでメールを受信したら、受信したユーザでプログラムを実行

# 環境

`user1` アカウントで作業を行う。
`user1`アカウントを`audio`グループに所属させておき、音が出せることを確認。

```bash:
id | grep audio
```

## 音を出す

```bash:音量やミュートの確認
alsamixer
```

```bash:再生ソフトにmpg123を使う
sudo apt-get install -y mpg123
```

* (mplayerだと再生できませんでした。)


# procmailの設定

```bash:~/.forward
"| IFS=' ' && exec /usr/bin/procmail -f- || exit 75 "
```

## 受け取ったメールをそのまま保存

```bash:~/.procmailrc
:0
*^From:.*
| cat > a.txt
```

* メールヘッダを確認。

## 受信アドレスで処理を分岐

* 先ほどの~/.procmailrcは削除しておく。

`user1+command1@`宛にメールを送信し、受信時のレシピは以下

```bash:~/.procmailrc
:0
*^To:.*user1\+command1@
| mpg123 -q $HOME/Documents/hello.mp3
```

後は量産すれば良い。

# 備考

* `+`を付ける場合は`\`でエスケープすること。
* Maildir形式でもmbox形式でも両方で機能した。
* .procmailrc と .forward には実行権限要りません。

## エラーをログに残す

```bash:~/.procmailrc
:0
*^From:.*
| command1 2> a.log
```

## 環境変数の確認

```bash:~/.procmailrc
:0
*^From:.*
| env > a.txt
```
ActiveRecord::Relationのcountの振る舞い


## 問題点
ActiveRecord::Relationはmapやselect, eachなどのArray, Hash等で使えるメソッドをカバーしてくれています。のでcountもArray同様の振る舞いを行ってくれると思って、ブロックを渡すと…

```ruby
User.create(name: 'hoge')
User.all.count { |user| user.name == 'fuga' }
=> 1
```

```ruby
array = ['hoge']
array.count { |name| name == 'fuga' }
=> 0
```

こうなります。ActiveRecord::Relationではcountメソッドが条件判断をよしなにしてくれないのです。
※User.all.countという流れがありえんというツッコミは止めて下さい死んでしまいます

## 解決
なので先にwhereを噛まそうねという話

```ruby
User.create(name: 'hoge')
User.where(name: 'fuga').count 
=> 0
```

処理が複雑になってくると、何処までがActiveRecord::Relationなのがこんがらがることがあるので、注意したいのでした
商品コード検索(商品詳細) の利用条件

個人が開いているショッピングの商品情報を取得することができません。

ライト出店，あるいはプロフェッショナル出店のストアの商品コードしか取得できないという制限があるのでしょうか。

ちなみに発行していただいているIDで，在庫参照APIと在庫更新APIは動作しています。ただ同じストアに帯する商品コード検索が動きません。403エラーが返ります。

商品コード検索(商品詳細) を使用する際のストア側条件というのものがあるのでしょうか。

お分かりの方がおられましたら教えていただけると助かります。

どうぞよろしくお願いいたします。
NSThread などを使った時に target does not implement selector と怒られる


こんな感じのコードだと怒られる

```swift
class A 
{
  func start() {
    let thread = NSThread(target: self, selector: Selector("loop"), object: nil)
    thread.start()
  }
  
  func loop () {
    // 何か処理
  }
}
```


エラーとしてはこんな感じ

```
2015-07-07 18:47:53.693 hoge[] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSThread initWithTarget:selector:object:]: target does not implement selector (*** -[hoge.A loop])'
```


## 対応というかちゃんと書くこと

こんな感じにすればいい。swift慣れぬ…

```swift
class A : NSObject
{
  func start() {
    let thread = NSThread(target: self, selector: Selector("loop"), object: nil)
    thread.start()
  }
  
  func loop () {
    // 何か処理
  }
}

```
Qiitaの脆弱性を見つけた話

XSS脆弱性を利用して勝手にストックされる記事を投稿しところ、当然ながら運営に限定公開にされました。

![SnapCrab_NoName_2015-7-7_18-35-2_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/54810/f07e20d2-45b7-bbee-bfcb-3acc099ad18e.png)

修正のコミット
https://github.com/increments/qiita-markdown/commit/f8165300b443e549ea8dc70c321da5ffe9cbf296?diff=split

# 発見の流れ
* マークダウンのタグにclassが指定できた
* BootStrapのコンポーネントが使えた
* Tooltipコンポーネントにscriptタグを埋め込んだ

# 最後に
Qiitaにも脆弱性報酬金制度が欲しいですね。
オレオレMac開発環境構築メモ

# Mac開発環境構築

最低限これは入れないとサクサク開発できんっていうやつをメモっておく。

## 1. Chrome

WEBブラウザ
https://www.google.co.jp/chrome/browser/desktop/

## 2. Google日本語入力

日本語入力。ことえりを完全削除する。
https://www.google.co.jp/ime/

## 3. Slack

メッセージングアプリ。WEB版よりMacアプリ版を使いたい。
https://slack.com/

## 4. BetterTouchTool

タッチ操作拡張ツール。
http://www.bettertouchtool.net/

## 5. XtraFinder

Finder拡張ツール。
https://www.trankynam.com/xtrafinder/

## 6. Alfred

英訳とか和訳とかGoogle検索をサクッと。
http://www.alfredapp.com/

## 7. MiniUsage

CPU使用率をステータスバーに表示。
https://itunes.apple.com/jp/app/miniusage/id416285394?mt=12

## 8. SourceTree

GUIでGit操作。
https://www.atlassian.com/ja/software/sourcetree/overview

## 9. Chromeブックマーク

Googleアカウントを同期するか、Export/Import

## 10. Chrome拡張機能

Redux DevToolsとかDHCとか。

## 11. Node.js

nodebrewで入れる。
https://github.com/hokaccha/nodebrew

## 12. Typings

TypeScriptの型定義管理ツール。
npm install -g typings

## 13. Atom

テキストエディタ。
https://atom.io/

## 14. Atomパッケージ

```shell-session
apm install atom-language-velocity atom-typescript emmet es6-javascript file-icons git-blame language-api-blueprint language-babel language-sql-mysql linter local-history lodash-snippets open-recent pigments pretty-json
```

* atom-language-velocity
* atom-typescript
* emmet
* es6-javascript
* file-icons
* git-blame
* language-api-blueprint
* language-babel
* language-sql-mysql
* linter
* local-history
* lodash-snippets
* open-recent
* pigments
* pretty-json

## 15. Firefox

WEBブラウザ。動作確認用に一応。
https://www.mozilla.org/ja/firefox/new/

## 16. Docker Toolbox

仮想環境。
https://www.docker.com/products/docker-toolbox

## 17. その他開発に必要なもろもろ

mysqlとかredisとか入れる。
cron設定の確認のしかた(centos)

/var/spool/cron/以下からcron設定ファイルが参照できる

```zsh:おすすめ
# sudo su -  
# cat /var/spool/cron/user
```


```zsh:オプション間違えると設定ファイル消えるのでちょっと危険な方法
# crontab -u user -l
```
DockerでDB2 Express-Cの環境を作る


`DB2`を使うプロジェクトで開発時は`h2`をDB2モードにしてやっていたりするのだが、どうしても対応していないSQLがでてきたりする。
ローカルマシンに入れるのも嫌だし、専用PC用意するのも嫌なので`Docker`でやってみた。

##準備
[MacでDockerはじめました](http://qiita.com/master-of-sugar/items/885ea7a4592671b1a72a)を参考に準備する。

##DB2 Express-Cインストール済のイメージを取得する
イチからインストールするのも面倒なので[これ](https://registry.hub.docker.com/u/angoca/db2-instance/)を使わせていただく。

```
docker pull angoca/db2-instance
```

##起動する

```
docker run -i -t --privileged=true --name="db2inst1" -p 50000:50000 angoca/db2-instance
```

`ssh`で`root`ユーザーでログインした状態になる。

##インスタンスを作成する
`ssh`でログインすると`/tmp/db2_conf`にいる状態になっているはず。そのディレクトリに`createInstance`というファイルがあるので実行する。

```
./createInstance
```

`db2inst1`というインスタンスが作成され、`db2inst1`ユーザーになる。
`DB2`コマンドを確認してみる。

```
db2 list db directory
```

以下のような結果になればOK

```
SQL1031N  The database directory cannot be found on the indicated file system. 
SQLSTATE=58031
```


##日本語を使えるように設定する
このイメージはデフォルトでは日本語が使えないので設定する。この作業は`root`ユーザーで行う。

まずは現在の設定を試してみる。

```
echo $LANG
```

なにもでないはず。
以下を実行する。

```
sudo locale-gen ja_JP.UTF-8
sudo /usr/sbin/update-locale LANG=ja_JP.UTF-8
source /etc/default/locale 
```

設定がうまくいったかどうか試す。

```
echo $LANG
```

以下のような結果になればOK

```
ja_JP.UTF-8
```

##ホストマシンからアクセスしてみる
IPを確認

```
boot2docker ip
```

[ip:50000]でアクセスできる。
あとは`create database`したりすればOK。

##Tips
###SSHから抜ける
`ctrl + P + Q`で抜ける。`exit`で抜けると`docker`コンテナが終了してしまう。

###コンテナを起動
`docker start db2inst1`

###SSHで入る
`docker attach db2inst1`


##TODO
一連の流れを`Dockerfile`にしたい。
MacでDockerはじめました


##前提
 - Mac OS X
 - [VirtualBox](https://www.virtualbox.org/wiki/Downloads)

##準備
`Docker`と`boot2docker`をいれる。

```
brew install boot2docker
```

dockerも一緒にはいる。

###boot2dockerイメージを取得する
```
boot2docker init
```

`~/.boot2docker/boot2docker.iso`というファイルがダウンロードされる。

###boot2dockerを起動する
```
boot2docker start
```

```
Writing /Users/mary/.boot2docker/certs/boot2docker-vm/ca.pem
Writing /Users/mary/.boot2docker/certs/boot2docker-vm/cert.pem
Writing /Users/mary/.boot2docker/certs/boot2docker-vm/key.pem
    export DOCKER_HOST=tcp://192.168.59.103:2376
    export DOCKER_CERT_PATH=/Users/mary/.boot2docker/certs/boot2docker-vm
    export DOCKER_TLS_VERIFY=1
```

こんな感じのが出力されるので`export`を実行する。
これは`docker`クライアントが認識して`docker`サーバーの場所等を認識するための環境変数らしい。

###dockerコンテナに接続できるかどうか確認する。
```
docker version
```

```
Client version: 1.5.0
Client API version: 1.17
Go version (client): go1.4.1
Git commit (client): a8a31ef
OS/Arch (client): darwin/amd64
Server version: 1.7.0
Server API version: 1.19
Go version (server): go1.4.2
Git commit (server): 0baf609
```

こんな感じでServer部分の情報までとれたら成功。とれなかったら環境変数が設定されていないのかもしれない。

##Nginxイメージを入れてMacからアクセスしてみる

[公式ドキュメント](https://docs.docker.com/installation/mac/)を見ながらやってみる。


###dockerコンテナ起動
```
docker run -d -P --name web nginx
```
「nginxというコンテナにwebという名前をつけてポートを公開しつつバックグラウンドで実行する」という意味。

###起動したかどうか確認
```
docker ps
```

```
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                                           NAMES
9f30c1a61580        nginx               "nginx -g 'daemon of   3 minutes ago       Up 3 minutes        0.0.0.0:32768->443/tcp, 0.0.0.0:32769->80/tcp   web   
```
###ポートが公開されたかどうか確認

```
docker port web
``` 

```
443/tcp -> 0.0.0.0:32768
80/tcp -> 0.0.0.0:32769
```

###IPを確認
```
boot2docker ip
```

```
192.168.59.104
```
ここは環境によって違うので読み替えを。

###Macのブラウザからアクセスしてみる
```
http://192.168.59.104:32769/
```

![Screen Shot 2015-07-03 at 17.49.00.png](https://qiita-image-store.s3.amazonaws.com/0/10058/a88f73d9-d500-58e1-7062-2d6e67020648.png "Screen Shot 2015-07-03 at 17.49.00.png")


成功！！

###コンテナ停止
```
docker stop web
docker ps
```

```
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```



##本当にやりたかったこと
[続き](http://qiita.com/master-of-sugar/items/764c6fcaf185ad73172e)かきました。
migration間違ったときの取り消し方


## 追加してしまったカラムの取り消し方
カラム追加などした時に、カラム名間違えた！とか、うっかりindex付与しわすれた！とかやっちゃう事ありますよね。
そういうときは、前回のmigrationを取り消すロールバックを実行しましょう。

**`rake db:version`**
このコマンドで現在のマイグレーションの最新情報を見る事が出来ます。
最新のマイグレーションファイル名に付与されたタイムスタンプが、ちゃんとマイグレーションのバージョンになっています。
![スクリーンショット 2015-07-07 10.57.06.png](https://qiita-image-store.s3.amazonaws.com/0/80075/b9c81c87-d330-8e9a-b6f4-92dd5136cf49.png)

**`rake db:rollback`** 
ここで前回のrollbackを取り消してバージョンを確認してみると.....
![スクリーンショット 2015-07-07 11.04.40.png](https://qiita-image-store.s3.amazonaws.com/0/80075/56144005-66e4-1556-bfce-7138e886bc86.png)

マイグレーションのバージョン名が、取り消したマイグレーションファイルより一つ前のものに変更されています。これで基本的にロールバックは完了ですので、また正しいマイグレーションを行いましょう。

ただ不用意にrollbackすると、当然消去したカラムに入っていたデータは消滅してしますので、development環境でいじくってるだけならいいですが、大事なデータ入ってる時はちゃんとそれなりの対策必要です。


## 参考

http://www.d-wood.com/blog/2013/10/07_4799.html
CapybaraでHTTP Headerに値を追加する


RSpecでHTTP Headerにある値を編集してテストしたいとき、こうすると良いみたいです。

```rb
Capybara.current_session.driver.header('HOGE', 'fuga')
```

ただし、driverがpoltergeistの場合はメソッドが違う模様。

```rb
Capybara.current_session.driver.add_header('HOGE', 'fuga')
```

なのでこんな感じにしました。

```rb
RSpec.configure do |config|
  config.before(:each, type: :feature) do
    driver = Capybara.current_session.driver
    driver.instance_of?(Capybara::Poltergeist::Driver) ? driver.add_header('HOGE', 'fuga') : driver.header('HOGE', 'fuga')
  end
end
```

もっとスマートな方法あったら教えて下さい :bow:

## 参考

- http://stackoverflow.com/questions/17503978/how-can-i-set-http-header-for-all-capybara-features
- https://github.com/teampoltergeist/poltergeist#manipulating-request-headers
Apple Watchをブルブルさせる

<i>※ [Introducing WatchKit for watchOS 2](https://developer.apple.com/videos/wwdc/2015/?id=105) の中で一般にも公開されている内容です</i>

Taptic Engine（バイブ機能のようなもの）のAPIがようやく公開されましたね。watchOS 2から利用可能です。

```swift
WKInterfaceDevice.currentDevice().playHaptic(type: WKHapticType)
```

`type` には下記の値を設定できます。

```swift
enum WKHapticType : Int {
    
    case Notification
    case DirectionUp
    case DirectionDown
    case Success
    case Failure
    case Retry
    case Start
    case Stop
    case Click
}
```

# サンプルコード

https://github.com/koogawa/WKHapticSample

# リンク

* [Introducing WatchKit for watchOS 2](https://developer.apple.com/videos/wwdc/2015/?id=105) - WWDC 2015 Video
* [WKInterfaceDevice Class Reference](https://developer.apple.com/library/prerelease/watchos/documentation/WatchKit/Reference/WKInterfaceDevice_class/#//apple_ref/occ/instm/WKInterfaceDevice/playHaptic:)
mackerelで不正ログインの検知


mackerelとfluentdを組み合わせると、ログの統計と見える化が比較的簡単に実現できる。
Secureログにログイン記録を付けているシステムは多いと思うが、せっかくなのでそれを見える化して定常的に監視できるようにしてみよう。

以下はtd-agentを使用しているものとしての例。


##必要なfluent-pluginインストール

統計用のプラグインとmackerel用プラグインをインストールする。

```bash
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-datacounter
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-mackerel
```


##fluentd設定
以下は/etc/td-agent/config.dをincludeしているという想定。

```bash
$ cd /etc/td-agent/
$ sudo mkdir config.d
$ sudo vim config.d/mackerel-secure-check.conf
```

こんな感じで作る。
`{{ }}` の部分は変数のつもり。環境に合わせて設定してほしい。
「ログイン失敗」ではなく、「ログイン試行」を数えるためにパスワードフェイルを1回として数えている。


```mackerel-secure-check.conf
<source>
  type tail
  format syslog
  path /var/log/secure
  tag log.secure
  pos_file /tmp/secure.pos
</source>


<match log.secure>
  type datacounter
  count_interval 60s
  count_key message
  output_per_tag yes
  pattern1 password_accepted ^Accepted password
  pattern2 password_failed ^Failed password
  pattern3 publickey_accepted ^Accepted publickey
  pattern4 publickey_failed ^Failed publickey
  tag_prefix count
</match>

<match count.log.secure>
  type mackerel
  api_key {{ mackerel-apikey }}
  hostid {{ mackerel-hostid }}
  metrics_name login.count.${out_key}
  out_keys password_accepted_count,password_failed_count,publickey_accepted_count,publickey_failed_count
  use_zero_for_empty
  #service {{ service-name }}
  flush_interval 60s
</match>

```

もしhostidがわからなければ下記補足を参照。


fluentdサービスを再起動して適用。

```bash
$ sudo service td-agent restart
```

## mackerel Webサイトにてグラフの調整・監視設定

「login.count」グラフを探して見た目を直す。
好みの問題だけど、私はこうした。

* 単位を「integer」に変更
* 積み重ねグラフに変更
* 色の関係で、並び順をaccept->failed->accept->failedに変更

![メトリック表示例](https://qiita-image-store.s3.amazonaws.com/0/82212/4ec05cec-27b0-4949-e31b-72efbab0d43c.png "メトリック表示例")


これで、Monitorsから監視設定を入れることもできる。


###補足: mackerel-hostidの確認方法

```bash
$ cat /var/lib/mackerel-agent/id
```
コマンド1発でローカルサーバを建てる

```
$ cd 任意のパス
$ python -m SimpleHTTPServer 8000
```

以下の様なログが出たらOK

```
Serving HTTP on 0.0.0.0 port 8000 ...
```

ブラウザで http://localhost:8000/ にアクセスすると、"任意のパス"のファイル一覧が見える。

クライアントアプリ開発中にテストデータを流し込みたいときに便利。
とあるログファイルからUniqなID部分を抜き出して一覧する


とあるSJISのログファイルがあります。

```shell
ファイル名: aaa.c
行: 1
重要度: 2
ルール ID: (xxx.001)
メッセージ:  あああああ

ファイル名: bbb.c
行: 1
重要度: 2
ルール ID: (yyy.002)
メッセージ:  いいい

ファイル名: ccc.c
行: 1
重要度: 2
ルール ID: (zzz.003)
メッセージ:  うううううーう

...
```

と、こんな感じで延々と続く数十万行のファイルです。

ここから、ユニークなルールIDとそれに対応するメッセージを一覧にしたいんだけど、という相談を受けました。
ルールIDに対するメッセージは同じだったり、微妙に違ったりしていますので、どれか一つのメッセージがわかれば良いようです。


こんな時の私の作業はこんな感じ。
一時作業なので、繰り返しのことは考えません。ちゃちゃっとできればOK。

環境はMacです。
ログファイルはt.logとしましょう。

## 文字コードを変更する
何はともあれ、SJISは不便なのでutf-8にします。

```shell
nkf -Sw t.log > t1.log
```

## 不要な行を除く
```shell
grep -v "ファイル名" t1.log > t2.log
grep -v "重要度" t2.log > t3.log
grep -v "行:" t3.log > t4.log
```
そんな面倒なことしなくても...とお思いでしょうが、まぁできればよいのです。

## 不要なワードを取り除く

vimで開きます。

```shell
vim t4.log
```
```vim
:%s/¥nルール ID: //g
:%s/¥nメッセージ: //g
```
そして、一番下の行の空行を削除します。さらに、一番上に"ルール ID: "が残っているので手動で削除します。
これで、保存すると t4.log は

```t4.log
(xxx.001) あああああ
(yyy.002) いいい
(zzz.003) うううううーう
...
```
という感じのファイルになっています。

## 1カラム目が重複する行を削除する

sort & uniqだと、所望の結果を得られないので、
ちょっと悩んで、ググったらawkでいけそう、ということで

```shell
awk '!colname[$1]++{print $0}' u4.log > u5.log
```
これでOK。

ここまで、10分くらい。

## 参考
- [awkで重複行を高速削除する。](http://akiniwa.hatenablog.jp/entry/2014/04/04/203256)
- [ソートしないで重複行を削除する](http://qiita.com/arcizan/items/9cf19cd982fa65f87546) ＜sort & uniqをしたくない時に便利そうね。



## 所感
シェルスクリプト系って、こういうちょっとした作業に非常に便利なのですごく好きです。
CentOS7にZNCをいれてIRCクライアントから接続するまで

デスクトップの移行にともない作業をしたので記録しておく。
せっかくなのでCentOS7をつかってみることに。

# 環境
* ホストOS
    * MacOS 10.10.4
* ゲストOS(VirtualBox)
    * CentOS7
* ZNC
    * 1.6.0

```shell-session
$ znc --version
ZNC - 1.6.0 - http://znc.in
IPv6: yes, SSL: yes, DNS: threads, charset: no
```

# CentOS7インストール
早速今まで知っていたコマンドとかが軒並みつかえなくて楽しくなってくるところです。

* インストールからSSHが接続できるまではこちらの手順でできます。
    * http://www.task-notes.com/entry/20150524/1432436400
* 追加でやっておいた方がいいのはsshdの設定です。
    * ホストからのsshがおっそーくなってしまう場合はこちらの設定をしてみてください。
    * /etc/ssh/sshd_configに"UseDNS no"を追記します。

```shell-session
$ sudo cp /etc/ssh/sshd_config{,.bk.`date +%Y%m%d%k`}
$ sudo vi /etc/ssh/sshd_config
$ sudo diff /etc/ssh/sshd_config{,.bk.`date +%Y%m%d%k`}
130d129
< UseDNS no
```

# ZNCインストール
公式サイトの通りでインストールできます。znc専用のマシンにしたので、手順がやや異なっています。
http://wiki.znc.in/Installation#Fedora.2FCentOS.2FRed_Hat_Enterprise_Linux

```shell-session
sudo yum install znc -y
znc --makeconf
```

# ZNC用各種設定
WebUIから設定していきました。
サーバとチャンネルの追加は必要なだけ行います。

## 共通設定
1. ホストマシンからゲストOSの固定IPとZNCの初期設定で指定したポートにアクセスする
1. 初期設定で設定したユーザ名とパスワードでログインする
1. 右側メニューの「Global Settings」をクリックする
1. Listen Port(s)に必要な数だけポートを追加していく
    * 私の場合4つ必要だったので新たに3つ追加しました
1. 少し下にあるGlobal Modulesを選択する
    * 私はログを残したかったので「log」だけチェックしました
1. 「Save」する

## ircサーバを追加
1. 「Your Settings」をクリックする
1. Networksの[Add]をクリックする
    * サーバの設定画面が表示されるので、必要な情報を適宜入力していく
    * Network Nameは、後で使うので識別しやすく短いものが良いです
    * Modulesは「autoreply, log, simple_away」を選択しました
1. 「Save and continue」ボタンをクリックする

## チャンネルを追加
1. Channelsの[Add]をクリックする
1. チャンネル名を#も含めていれる
1. 「Add Channel and return」をボタンを選択する

## CentOS7のポートを解放してあげる
IRCクライアントからZNCを経由(proxy)して複数のサーバにアクセスするため、ポートを複数解放します。

* 解放前確認

```shell-session
$ sudo firewall-cmd --list-all --zone=public
public (default, active)
  interfaces: enp0s3 enp0s8
  sources: 
  services: dhcpv6-client ssh
  ports: 
  masquerade: no
  forward-ports: 
  icmp-blocks: 
  rich rules: 
```
* 解放

```shell-session
$ sudo firewall-cmd --add-port=16665/tcp --zone=public --permanent
         :
         :
$ sudo firewall-cmd --add-port=16669/tcp --zone=public --permanent
success
```
* 設定リロード

```shell-session

$ sudo firewall-cmd --reload
success
```
* 設定後確認

```shell-session

$ sudo firewall-cmd --list-all --zone=public
public (default, active)
  interfaces: enp0s3 enp0s8
  sources: 
  services: dhcpv6-client ssh
  ports: 16667/tcp 16665/tcp 16668/tcp 16666/tcp 16669/tcp
  masquerade: no
  forward-ports: 
  icmp-blocks: 
  rich rules: 
```

# IRCクライアントから接続する
LimeChat(MacOS版)の場合を書きます。

1. Server → Add Server → Generalタブ選択
7. Network Name: 識別しやすい名前
2. Server: ゲストOSのIPを指定する
2. Port: 開放した任意のポートを指定する
3. Server Password: 初期設定で設定したパスワード
4. Nickname: 任意の名前
5. Login name: 初期設定で設定したユーザ名
6. Real name: 任意のrealname
7. 他は空白にしておく
8. Detailsタブ選択
1. Encoding: UTF-8
1. On Loginタブ選択
2. Perform commands on login: に以下を追加
    * `msg *status JumpNetwork your-channel-name`
1. 「OK」ボタンを選択する

つながったらおしまい！
ホストOSからゲストOSへポートフォワーディングすれば別のPCからも使えるようになります。


# おわりに
ZNCの設定方法の王道はWebUIからなのだろうか。気になってます。

# 参考
* http://senoway.hatenablog.com/entry/2015/02/11/142139
* http://wiki.znc.in/ZNC
* http://www.task-notes.com/entry/20150524/1432436400