OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonで素数

素数を捜すのに、素数で割ってみる、っていうのが意外とむずかしいのかもしれない...
Pythonだとどうやるんだろ?

Wikipediaの[エラトステネスの篩](https://ja.wikipedia.org/wiki/エラトステネスの篩)のgifを見てたら、このまんまできそうじゃね?と思い、やってみたメモ。
例?によってlambdaしばりで。

```Python

do = lambda *x : x
switch = lambda x : x[-1]


primes = (
  lambda n : find_primes( range( 2, n + 1 ), ( n + 1 ) ** 0.5, [ ] )
)

find_primes = (
  lambda xs, end_point, ys :
    
    switch(
      xs[0] <= end_point and do( ys.append( xs[0] )
              				, find_primes( remove_fst_multiples( xs ) , end_point, ys )
            				)
      
      or   					do( ys.extend( xs ) 
              				, ys 
            				)
    )
)

remove_fst_multiples = (
  lambda xs : [ x for x in xs if x % xs[0]  ]
)

print primes(100)

```
実行結果：

```Python
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
```

アルゴリズムはWikipediaのまんまです。

primesは、いい感じで値を渡すだけの関数。実体はfind_primes。

find_primesは、

+ 探索リストと、終了条件値と素数リストを引数にして、
+ 探索リストの先頭の数が終了条件値以下なら、
+ 先頭値を素数リストに加え、
+ 先頭値の倍数を除いた新しい探索リストと終了条件値と新しい素数リストで再帰的にfind_primesを呼ぶ。
+ 探索リストの先頭値が終了条件値を超えたら、
+ 残っている探索リストを素数リストに結合して、素数リストを返す。

remove_fst_multiplesは、リストをとって、そのリストの先頭値の倍数を除いたリストを返す。

#itertoolsを使ってみる
コメントいただいたので使ってみました。
といっても、どういうものかわかってないのでググってみて、とりあえず探索リストをイテレータで置き換えてみた。
ちゃんとした使い方はコメントの方とか、他にもいろいろ発表されているのでそちらを見てください。

```Python
from itertools import count, ifilter, takewhile

do = lambda *x : x
switch = lambda x : x[-1]


primes = ( lambda n : 
  find_primes( 
    takewhile(lambda x : x < n + 1, count(2))
  , ( n + 1 ) ** 0.5
  , [ ] 
  )
)

find_primes = (
  lambda xs, end_point, ys :
    (lambda a = next( xs ) :
      
      switch(
       a <= end_point and do( ys.append( a )
               			, find_primes( remove_multiples( xs, a ) , end_point, ys )
              			)
        
        or   			do( ys.append( a )
                		, ys.extend(list( xs) ) 
               			, ys 
             			)
      )
    )()
)

remove_multiples = (
  lambda xs, a : ifilter(lambda x : x % a , xs )
)

print primes(100)
```
そうだ、京都行こう。 〜Ruby Kaigi 編〜

![goodies_sp.jpg](https://qiita-image-store.s3.amazonaws.com/0/46363/a001cd15-5c69-0c91-e8c5-119604201494.jpeg)

先週ですが、Ruby Kaigi 参加してきました！
平日も含めてフル参加したので、なかなかに疲れましたね。

個人的に印象に残っているセッションの印象を振り返りたいと思います。

# １日目 dRuby in the last Century
by [Masatoshi SEKI](https://twitter.com/m_seki)

スライド : https://speakerdeck.com/m_seki/druby2016

dRuby ってなに

- 分散オブジェクトシステム
- プロセス越しにメソッドが呼べる
- プロセス間でオブジェクトが送れる

とのことなのですが、印象的なのは

**dRuby は簡単通信ライブラリではない = 既存のRPCのラッパーではない（もっと情緒的なもの）**

スライドにある `oso-matz` と `jushi-matz` による通信は `irb` で簡単に試せるので、触ったことのない方は是非試してみるとよいかと思います。
（セッション中にスライド見ながら同時に試すには少々厳しかったですが、面白かったです。`require 'drb'` を忘れずに）

全体的に分散処理の話は多かったのですが、その中でも　ｄRuby は ~~スケールしやすいのかは別として~~ 試しやすい解決策ですね。

![DSC_0143.JPG](https://qiita-image-store.s3.amazonaws.com/0/46363/aeb96f7b-ed1c-ff12-2a38-59b4407cc790.jpeg)

お弁当が毎日美味しかったです（お弁当スポンサーというのもあるんですね）

# １日目 A proposal of new concurrency model for Ruby 3
by Koichi Sasada

スライド : http://www.atdot.net/~ko1/activities/2016_rubykaigi.pdf

`Guild` という `Thread` のグループを使って、複数 Thread による処理を扱う話でした。

ご本人が Podcast でお話されているので、[みんな大好き Rebuild.fm](http://rebuild.fm/158/)を聞いていただくと良いのではないかと思います。

普段 Rails をやっている身としては、より Ruby のままで並列処理するための扱い方そのものが勉強になりました。
あぁ、 **ここもきちんとオブジェクト指向になっている** と感じれるのが設計として面白いです。

![DSC_0144.JPG](https://qiita-image-store.s3.amazonaws.com/0/46363/98fc98d7-27c8-708b-f69f-7b1532061e56.jpeg)

阿闍梨餅も美味しかったです（永和システムマネジメントさん、ありがとうございました！）

# 二日目 Fearlessly Refactoring Legacy Ruby
by Justin Searls

スライド : https://speakerdeck.com/searls/surgical-refactors


リファクタリングはビジネスサイドの人に必要性を説明するのは難しいよね、という話から

リファクタリングの９要素にそって見ていきましょう、という内容。

絵文字の使い方が非常に参考になるスライドでした。
また、Twitter 上でも気さくな方でした。

![DSC_0157.JPG](https://qiita-image-store.s3.amazonaws.com/0/46363/d66f735f-de47-bc95-f4d4-14ba255f7c5b.jpeg)

ベジタリアン用のお弁当も用意してありました。

# 二日目 SciRuby Machine Learning Current Status and Future
by Kenta Murata

スライド : https://speakerdeck.com/mrkn/sciruby-machine-learning-current-status-and-future

Python には `scikit-learn` があるから機械学習や統計処理できるけど、
Ruby の現状のライブラリではきつい！！というお話でした。

~~簡単な統計処理は R 使えるようにしようという感想をいだきました~~

![DSC_0158.JPG](https://qiita-image-store.s3.amazonaws.com/0/46363/3444b3bb-1adf-e8a9-191c-d393908f5374.jpeg)

会場の国際会館は、中庭？もとてもきれいでした！

# 三日目 Recent Advances in HTTP and Controlling them using ruby
by Kazuho Oku

スライド : http://www.slideshare.net/kazuho/recent-advances-in-http-controlling-them-using-ruby

HTTP/2 の特徴から、現状使える機能についてなども知れて良かったです。
サーバープッシュは、画像の読み込みくらいでしか現状使いづらい、というのは **やっぱり** というところでしたが、CSS などの先読み込みもすですし、動画ストリーミングでの使い方も気になるところです。

弊社のクラウドストレージサービス（具体的には https://jector.jp/ ）でも HTTP/2 対応に力を注いでいるので、より一層注目の分野です！

![DSC_0148.JPG](https://qiita-image-store.s3.amazonaws.com/0/46363/ec5b1cd7-70fd-b932-bd46-676c99487ae7.jpeg)

有名な方々が直ぐ側にいたり、夜にコミッターの方と話せたり他にも色々な楽しみがありました！
来年は、Listening 力をもう少し伸ばして参加したいと思います！
RailsのモデルでModuleを使うと、ビジネスロジックとデータ永続化の観点でファイルを分割できてとてもシンプル

# はじめに

Railsプロジェクトでは、モデルがシンプルなことはとても価値があります。
しかし、モデルは役割が大きいため複雑になりがちです。

そこで、ビジネスロジックと永続化という観点からコードを分割して、
シンプルなプロジェクトを作ってみます。

# 例
たとえば、Clientモデルを作りたいときは、以下のようになります

## データの永続化　app/models/client.rb
こちらはモデルの定義を書きます。
後述するビジネスロジックがうまく働くようにするために、データの永続化のみ記述

 - データの永続化
   - belongs_toなどのリレーション
   - バリデーション
   - Update, Create
   - スコープ

```rb
class Client < ActiveRecord::Base
  include Logic::Client
  belongs_to ...
  validate ...
  scope ...
end
```

おそらく２０行ぐらいの短いコードで済むはずです。

## ビジネスロジック　
### app/models/logic/client.rb
ビジネスロジックはこっちに

```rb
class Logic::Client < Logic::Base
  # クライアントのビジネスロジック
end
```

### app/models/logic/base.rb
```rb
class Logic::Base
  # 共通でつかうビジネスロジック
end
```

# まとめ
今回はビジネスロジックをサブディレクトリに切ることをしてみましたが、
同じ要領で***CSV出力***のためのメソッドを**reports**ディレクトリ配下に作るなど、ケースごとに汎用的に使えるのでとても便利になるとおもいます！
gitで他ブランチの特定のコミットを取り込む方法


**`git cherry-pick`**を使用することで実現することができる！


対象のコミット履歴を持っているブランチに移動する  

	$ git checkout hoge_a
	
コミット履歴を確認する(commit id をコピーしておく)

	$ git log
	
	commit hogehogehogehogehogehoge
	Author: Boku <>
	Date:   Sat Sep 17 21:43:15 2016 +0900

    色々修正
    
コミットを取り込みたいブランチに移動する

	$ git checkout hoge_b
	
先ほどコピーしたコミットIDを付与し`cherry-pick`コマンドを実行する

	$ git cherry-pick hogehogehogehogehogehoge
	
コミット履歴でコミットが反映されているのを確認できていればOK

	$ git log
	
	commit hogehogehogehogehogehoge
	Author: Boku <>
	Date:   Sat Sep 17 21:43:15 2016 +0900

	色々修正
	

ちなみに、反映させたいコミットがマージコミットだった場合optionで-mを用いて親番号を指定する必要がある

	git cherry-pick -m 親番号 hogehogehogehogehogehoge
	
以上
HashをStructに変換する

```
Person = Struct.new(:first_name, :last_name, :age)
person_hash = { first_name: "Foo", last_name: "Bar", age: 29 }
person = Person.new
person_hash.each {|k, v| person[k] = v}
```

`Struct`は普通に文字列、シンボルをキーにして`[]`でアクセスできるんですね。
Rails Conf 2013 You've got a Sinatra on your Rails by José Valim

https://www.youtube.com/watch?v=TslkdT3PfKc

```rb
resp = Fun::GamesController.action(:render_hello_world).call(request.env)
```

```
commit 3b6a40a7bd1901274807fa6f22db6083dda18a28
Author: Joseph Pecoraro <joepeck02@gmail.com>
Date:   Sat May 30 01:01:36 2009 -0400

    Fixed links to the Routing Guide.

...skipping...
    Implement FooController.action(:name)
    
      * Rails actions are now Rack endpoints, and can be retrieved
        via FooController.action(name) and called with an env
      * Updated some tests that relied on the old internal
        #process/#call implementation
```
Hamlでtextareaを使用する時の注意

Hamlでtextareaをそのまま使用すると、編集と表示で不都合があったのでメモ。

## 使用したバージョン
ruby 2.3.1
Rails 5.0.0.1

## サンプルプロジェクトの準備
###サプンプルのプロジェクトを作成
```
$ rails new sample
```

### Hamlを使用するようにGemを追加
Gemfileに以下を追加し、`bundle install`を行う

``` Gemfile
gem 'haml-rails'
gem 'erb2haml'
```

### text型のフィールドを持ったページを生成
`tests`というテーブルに`text_value`というtext型のカラムのみを定義して生成

```
$ rails g scaffold test text_value:text

$ rake db:migrate
```

これで準備は完了

## textフィールドへの入力
まずは生成したままの状態で複数行入力する
（生成したままだとtextareaが小さいので`cols: "50", rows: "10"`を設定している）
![スクリーンショット 2016-09-17 21.35.46.png](https://qiita-image-store.s3.amazonaws.com/0/128475/e0ed0ce8-307d-3481-9f0c-e17dae3712f1.png)

登録したデータを編集画面を見ると、２、3行目の先頭にスペースが入ってしまっている
![スクリーンショット 2016-09-17 20.58.53.png](https://qiita-image-store.s3.amazonaws.com/0/128475/86123437-a6bf-6082-1996-f53cd9d92dcd.png)
これは、textareaに設定する値に、Hamlの`f.text_area`を記述している行のインデントが入ってしまっているため
DBに登録された時にはスペースは入っていないが、編集画面でこれをそのままsaveするとDBにもスペースが登録されてしまう


これを回避するには、以下の設定を追加する（以下のファイルはないので自分で作成する）

``` config/initializers/haml.rb
Haml::Template.options[:ugly] = true
```

これで編集画面を見ると、無事、先頭の余分なスペースがなくなる
![スクリーンショット 2016-09-17 21.07.13.png](https://qiita-image-store.s3.amazonaws.com/0/128475/e0469f8a-25fa-ddee-133a-f985bce2a12a.png)

## textフィールドの表示
続いて、先のtextフィールドへの入力で登録したデータを表示
表示画面を開くと、text型のフィールドは以下のように１行になって表示されてしまう
![スクリーンショット 2016-09-17 20.59.06.png](https://qiita-image-store.s3.amazonaws.com/0/128475/f496fb67-1bd6-2320-54c6-46fad7d7608e.png)

改行をちゃんと反映させるには以下の通り修正する（`simple_format(h(対象の値））`）

``` app/views/tests/show.html.haml
  %b Text value:
  = simple_format(h(@test.text_value))
```

これで表示画面を見ると、ちゃんと改行された状態で表示される
![スクリーンショット 2016-09-17 21.07.41.png](https://qiita-image-store.s3.amazonaws.com/0/128475/3a90fedd-dd64-f760-efa8-806a3dfc88de.png)

おしまい
Vagrant の備忘録

# 概要
自分用に Vagrantの備忘録を記しています。

## vagrantのホーム変更
環境変数に"VAGRANT_HOME"を指定することで変更可能
> デフォルトではユーザホーム配下に作成される。
> boxのファイルが配置されるため肥大化するのが嫌であれば以下で任意フォルダに変更可能

```text:環境変数
VAGRANT_HOME=\<AnyPath>\.vagrant.d
```

## box作成
- **boxリストから作成**

```
vagrant package --base <BoxName> --output \<AnyPath>\<BoxName>.box
```

- **既存 VBoxのVMファイルから作成**

```
vagrant package --base \<AnyPath>\<VMName>.vbox --output \<AnyPath>\<BoxName>.box
```

## boxをリストへ登録
```
vagrant box add  <NewBoxName> <BoxFile>
```

## boxのリストを確認
```
vagrant box list
```

## 初期化(Vagrantfileの作成)
```
vagrant init <BoxName>
```

## VMの起動
```
vagrant up
```

## VMの停止
```
vagrant halt
```

## VMの破棄
```
vagrant destroy
```

## VMにログイン
> WindowsではSSHクライアントが入っていないと不可 

```
vagrant ssh
```
expect(1).to be 1 が成立するのが不思議だった

## 概要
RSpec の `be` マッチャーは何となく雰囲気で、いわゆる「参照一致」だと思っており、そうなら何故別変数のように見える `1` と `1` が一致するのかというのが不思議でした。


## 理由
`be` は `equal?` を使って検証するものである。

Ref) 
https://relishapp.com/rspec/rspec-expectations/v/3-5/docs/built-in-matchers/equality-matchers

> `expect(a).to be(b) # passes if a.equal?(b)`

----

`#equal?` とは [Object#equal?](https://docs.ruby-lang.org/ja/2.3.0/class/Object.html#I_EQUAL--3F) のことであり、以下の動作をする

> お互いのObject#object_idが一致する かどうかを調べます。

----

[Object#object_id](https://docs.ruby-lang.org/ja/2.3.0/class/Object.html#I_OBJECT_ID) 

> アクティブなオブジェクト間で 重複しない整数(object_id)が各オブジェクトにひとつずつ割り当てられています。

とのことだが、例外として、

> TrueClass, FalseClass, NilClass, Symbol, Fixnum クラス のインスタンスなど Immutable（変更不可）なオブジェクトの一部は同じ内容ならば必ず同じ object_id になります。

とのことだった。

だから `expect(1).to be 1` は同じ `object_id` を比較でき、成立する。


## なお、そもそも `expect(1).to be 1` は誤りなので

```rb
expect(1).to eq 1
```

と書くべきである。

同値が同object_idを持つのは、例外的な動作だから。


## 残った疑問

> Immutable（変更不可）なオブジェクト

という文は、`.frozen?` が `true` という意味と一緒なのだろうか？
公平なガチャシステムのまとめ

# はじめに

この記事は公平なガチャについての研究が数年を経て、議論が多くなったことを踏まえ研究の歴史を俯瞰できるようなまとめ記事である。


# 研究の目的

ガチャシステムの多くは運営のサーバーで確率を計算していることから、実装ミスや意図的な操作によって景品の出現率を公表とは異なる値になる可能性がある。この研究は暗号技術などを利用することで、ガチャシステムにおける景品の出現確率をユーザーが実装に基づいて確かめられるようなシステムを開発し、ガチャシステムの健全さの向上に貢献するものである。

# 研究の歴史

研究は2015年9月に最初の記事から始まり、他の人との議論を交えながら着実に進歩していった。

## 1. 最初の公平なガチャシステム

最初の公平なガチャシステムは[この記事](http://qiita.com/yyu/items/a5c281ed17bb3c49d4d5)で提案された。この記事では、ハッシュ関数を用いてガチャシステムを構成した恐らく最初の記事であった。

## 2. データストアを排除した公平なガチャシステム

[次の記事](http://qiita.com/yyu/items/90db09c57514758bd68c)では、最初の公平なガチャに必要であったサーバーサイドのデータストアを署名技術によって排除したものである。

## 3. malaさんが考えた公平なガチャシステム

malaさんによって考案されたガチャシステムは[この記事](https://gist.github.com/mala/f33c9654af5e06e8bca9)で提案された。ただ、これは対称鍵暗号を利用しているため、暗号化の時に用いた鍵と復号の時に用いる鍵が等しいことをなんらかの方法で示す必要があった。

## 4. コミットメントを用いた公平なガチャシステム

[この記事](http://qiita.com/yyu/items/fce9b33c784e0631ddf6)では、暗号技術のコミットメントを用いてガチャシステムを構成できることを示した最初の記事である。

## 5. ガチャシステムとコミットメントにおける隠蔽と束縛

[この記事](http://qiita.com/yyu/items/f172c0cd1e20da09d138)では、コミットメントが持つ隠蔽と束縛という二つの性質について解説し、両方を同時に満すコミットメントは構成できないことを述べた。さらに、そのことがガチャに与える影響を考察した。

## 6. 公平なガチャシステムと電子署名

[この記事](http://qiita.com/yyu/items/b89d6e9494712a857e10)では、ガチャシステムをコミットメントで構成した場合に、コミットメントがガチャシステムを提供する企業によって発行されたことを証明し、かつ否認を拒否する必要について述べた。

## 7. ブロックチェーンを利用した公平なガチャ

[この記事](https://qiita.com/yyu/items/4eaa43693e39c60a8661)では今までの方法とは異なり、ブロックチェーンを利用してガチャの公平性を担保するという方法について言及した。ブロックチェーンを利用することで、コミットメント方式で発生していた隠蔽と束縛による影響や鍵配布の問題を解決している。

## 8. 量子コンピュータを利用した公平なガチャ

[この記事](https://qiita.com/yyu/items/efcf471ce9b97e885957)では量子コンピュータなどを利用してガチャの公平性を担保する方法について言及した。量子計算の基礎とガチャをよりシンプルにした量子コイントスを解説した。

## 9. Ethereum上の公平なガチャ（抽選）に対する攻撃

[この記事](https://tech.recruit-mp.co.jp/etc/post-17506/)ではEthereumのインターナルトランザクションを利用して、Ethereum上の公平なガチャに対してアタックできるのではないかという考察である。

## 10. 量子コンピュータで2人の“Covert”⁉️ガチャ

[この記事](https://zenn.dev/yyu/articles/79c6c48226166aa0e875)では“Covert”なガチャの概念を説明し、それを量子コンピュータで実装した。ランダムな出力をするのが本来のガチャではあるが、この方法では参加者の「欲しいもの（希望）」を入力することができ、その希望がいい感じであればその通りにし、そして衝突している場合は抽選とする。しかし参加者たちには結果が希望どおりだったのか抽選となったのか一切分からないという不思議な抽選を量子コンピュータが持つランダム性とブラインド計算で与えた。

# まとめ

ここまでの研究で、公平なガチャシステムを実装するために必要な議論はおおむね終ったのではないかと考えている。もし、何かさらなる改良の余地を思いついた場合は、気軽にコメントなどで教えて欲しい。

# 引用・関連記事一覧

1. [僕が（一部を）考えた公平なガチャシステム](http://qiita.com/yyu/items/a5c281ed17bb3c49d4d5)
2. [僕が（ほとんどを）考えた公平なガチャシステム](http://qiita.com/yyu/items/90db09c57514758bd68c)
3. [malaさんが考えた公平なガチャシステムとその改良案](http://qiita.com/yyu/items/ff2fd858a5ae7a74d076)
4. [クライアントサイドでガチャ](https://gist.github.com/mala/f33c9654af5e06e8bca9)
5. [コミットメントを用いた公平なガチャシステム](http://qiita.com/yyu/items/fce9b33c784e0631ddf6)
6. [ガチャシステムとコミットメントにおける隠蔽と束縛](http://qiita.com/yyu/items/f172c0cd1e20da09d138)
7. [コミットメントによる公平なガチャシステムと電子署名](http://qiita.com/yyu/items/b89d6e9494712a857e10)
8. [ブロックチェーンを利用した公平なガチャ](https://qiita.com/yyu/items/4eaa43693e39c60a8661)
9. [量子コンピュータを利用した公平なガチャ](https://qiita.com/yyu/items/efcf471ce9b97e885957)
10. [Ethereum上の公平なガチャ（抽選）に対する攻撃](https://tech.recruit-mp.co.jp/etc/post-17506/)
rex0220 通し番号プラグイン

# 通し番号プラグイン(販売停止)

文字項目に、通し番号を設定するプラグインです。

- ＰＣ、スマホの新規レコード追加時・編集時、通し番号を自動設定
- 既存レコードの通し番号をプラグイン設定値で更新可能

※レコードタイトル設定プラグインとは、１アプリ内で同時使用できません。

[rex0220 stores](https://rex0220.stores.jp) で、販売中です。

## PC画面

![seq01.png](https://qiita-image-store.s3.amazonaws.com/0/100572/90a1fb9c-eceb-294e-b698-70f097d81cd9.png)


## スマホ画面

![seq02.png](https://qiita-image-store.s3.amazonaws.com/0/100572/6e1dafa9-35a9-1f45-4588-51bd842ad7f9.png)


# プラグインの追加

![seq11.png](https://qiita-image-store.s3.amazonaws.com/0/100572/adf2282b-4ac9-3f19-b8b3-45aff2ec62bf.png)

# プラグインの設定

- プラグイン有効：　プラグインの有効／無効を指定。
- 通し番号項目、先頭文字、初期番号、番号桁数を指定します。
- 通し番号項目は、クリックすると項目リストが表示されますので選択します。
- 設定値変更後、Enter キー、Tabキー、矢印キーで確定します。
- 入力が確定すると、上部の通し番号項目、フォーマット欄に反映されます。
- 既存レコードの変更が必要な場合は、「既存レコードを変更」をクリックします。
- 設定完了時、「保存する」をクリックします。


![seq12.png](https://qiita-image-store.s3.amazonaws.com/0/100572/e72f672a-e5e1-71cc-01e0-eee13a93844d.png)


# 既存レコードの変更

プラグインの設定内容で、既存の通し番号項目の設定値を変更します。
全レコードを更新しますので、事前にデータのバックアップを取ってから実行してください。
フォーム変更を行った場合は、本番環境に反映後に既存レコードの変更を行ってください。

![seq13.png](https://qiita-image-store.s3.amazonaws.com/0/100572/0d0c4e8d-d074-3c1b-7c2d-151af7d6c6d9.png)


# 注意事項

- 既に、JavaScript によるカスタマイズを行っているアプリの場合、処理が競合して、エラーになる場合があります。その場合は、該当するアプリでプラグインの使用を中止してください。
- アプリ設定を変更した場合は、プラグインを再設定してください。
RailsでBootstrapのグリッドシステムを使うときに、カラム数をRubyで計算する

## BootstrapのGridシステムについて

こちらのグリッドシステムが詳しいです
https://html5experts.jp/shumpei-shiraishi/1538/

# 本題

## Gridシステムのcol-md-4とか3とか決めるの大変

```html
<div class="container">
  <div class="row">
    <!--        ↓↓↓↓↓↓↓↓　これのことです -->
    <div class="col-md-4">レスポンシブに動く要素</div>
    <div class="col-md-4">レスポンシブに動く要素</div>
    <div class="col-md-4">レスポンシブに動く要素</div>
  </div>
</div>
```

*【レスポンシブに動く要素】*が増えたり減ったりする場合は、センスで決めるしかありません

## Rubyで計算してみる

```rb
  # 要素数に対して適切なcol数を返す
  # @param [Integer] n 要素数
  # @param [Integer] min_col col数の最小値
  # @param [Integer] max_col col数の最大値
  # @return [Integer] 適切なcol数
  # @example
  #  - if n > 0
  #  - col_count = col_count(n, 2)
  #  - col_class = "col-sm-#{col_count}"
  def col_count(n = 1, min_col = 1, max_col = 12)
    return 12 if n <= 0
    ((n/(12/min_col).to_f).ceil*max_col)/n.to_f.ceil
  end
```

## 戻り値を一覧にしてみました

### 最小幅 **１**
| 要素数 | カラム数 |
|---|---|
| 1 | 12 |
| 2 | 6 |
| 3 | 4 |
| 4 | 3 |
| 5 | 2 |
| 6 | 2 |
| 7 | 1 |
| 8 | 1 |
| 9 | 1 |

### 最小幅 **2**
| 要素数 | カラム数 |
|---|---|
| 1 | 12 |
| 2 | 6 |
| 3 | 4 |
| 4 | 3 |
| 5 | 2 |
| 6 | 2 |
| 7 | 3 |
| 8 | 3 |
| 9 | 2 |

### 最小幅 **3**
| 要素数 | カラム数 |
|---|---|
| 1 | 12 |
| 2 | 6 |
| 3 | 4 |
| 4 | 3 |
| 5 | 4 |
| 6 | 4 |
| 7 | 3 |
| 8 | 3 |
| 9 | 4 |

## まとめ
動的に増減する要素を、いい感じにレイアウトできるようになったかもしれないです！
Ajaxで取得した動的コンテンツの再配置に使ってみたいと思います！
開発サーバーでもこれだけはやっておくnginxの設定

サンプルバージョンは下記。
nginx/1.10.1

## 最大同時接続数の上限を設定
**nginxにおける同時クライアントの最大数は、worker_processes × worker_connectionsの数で決まる。**

まずは、クライアントリクエストを処理するworker_processesを設定

```
worker_processes  2;
```

CPUのコア数＝ワーカープロセス数となるので、下記コマンドで確認して値を設定。

```
grep processor /proc/cpuinfo | wc -l
2
```

次に、１つのワーカープロセスが同時に処理できる最大接続数を設定

```
events {
    worker_connections  1024;
}
```

こちらの数値は下記コマンドの値を参考にする。

```
ulimit -n
1024
```

## サーバー情報を隠蔽する
```
http {
 server_tokens off;
```

ちなみにこの設定を行っても、バージョン情報は消えるがnginxを使っていることはバレてしまう。
専用のエラーページを用意してフォローがよいかも。

## アクセスログの出力フォーマットを確認する
デフォルトでは、Apache互換の combinedが適用される。
独自に設定したい場合は、明示的に指定すること。
例） main　という出力フォーマットにしたい場合

```
server{
    access_log  /var/log/nginx/log/host.access.log main;
```

※ mainというフォーマット定義は別途行っておくこと。

## アクセスログの書き込みペースを少し調整する
随時書き込むでもいいが、例えば５秒起きに書き込む、などにするその分サーバーへの負荷を抑えられるだろう。
例）　前回出力してから５秒以上経過したら書き込む

```
server{
    access_log  /var/log/nginx/log/host.access.log main flush=5s;
```

## KeepAliveの設定を、適宜変更する
デフォルトでは、 75になっている。
例） 65にしたい場合

```
http{
    keepalive_timeout  65;
```

## sendfileをどうするか決める
sendfileは、ざっくりいうと、クライアントへのレスポンス処理をsendfileシステムコールというAPIを使って行うかどうかで、カーネル側でコンテンツの複写をもつことで、レスポンスの改善をはかる設定。
**ただし、動作が不安定になったり、静的ファイルが更新されなかったり、芳しくない評判もある。
デフォルトでは、offになっているので、悩ましければそのままで良いかと。**

```
http{
    sendfile off;
```

## 最大リクエストサイズの調整
クライアントから送信されるリクエストボディの最大許可量を設定。
デフォルトでは１MB。
例）無制限にする場合。

```
http{
    client_max_body_size 0;
```

## クライアントに返すパケットの調整
ブラウザが１度のやりとりで受け取るパケット量。これが少ないと何度もやりとりが発生する為非効率。

```
server {
    proxy_buffers 8 64m;
    proxy_buffer_size 64m;
```

もしくは、いっそBufferingしたくないとき（ファイルDL等）はこちら。

```
proxy_request_buffering off;
```


## デバッグしたい場合

```
location /debug/ {
    return 200 "access to $server_name : $server_port :  $uri";
}
```

## . から始まるファイルへのアクセスを禁止
```
location ~ /\.$ {
   deny all;
}
```
## PHP-FPMとApacheの設定の相対
pm.start_servers  :  StartServers  : 起動時に作成される子プロセス
pm.min_spare_servers  :  MinSpareServers  :  アイドル状態の子プロセスの最小数
pm.max_spare_servers  :  MaxSpareServers  :  アイドル状態の子プロセスの最大数
pm.max_requests   :   MaxClients   :  各子プロセスが再起動するまでのリクエスト数
Slash Commandを外部から実行する

# はじめに
<font color="red">**※本投稿記載の内容は、Slackのオフィシャル情報ではありません。
　Slack側の仕様変更により利用不可になる可能性が高いので、ご注意ください**</font>

最近、こちらの「[SlackのSlash commandの処理をAWS Lambdaで実装](http://qiita.com/komeda-shinji/items/bd7bb3c2680e20218023)」を参考にSlash Commandを作ってみました。
Slash Commandは基本的にSlackのユーザが能動的に入力し、各種処理を実行させるものです。

せっかくなのでこの処理部分を再利用して、定期的に自動実行させてみよう思い、SlackのAPI経由でSlash Commandを投稿してみようと試してみましたが、このAPIからは投稿できませんでした。
\# 「/command arguments」のような文字列がそのまま投稿されます。

# Webではどうやっている？
API経由ではSlash Commandが送れないので、Webインターフェースでは何をやっているか、ブラウザの開発ツールで覗いてみました。
すると、Slash Commandの実行は通常の投稿と異なり、以下のRequest URLにmultipart/form-dataのRequest BodyをPOSTしていました。
\# 通常の投稿はWebSocket経由っぽいです

**Request URL**
> https://**{TEAM_NAME}**.slack.com/api/chat.command

**Request body**
>------{boundary_string}
>Content-Disposition: form-data; name="command"
>
>**{COMMAND}**
>------{boundary_string}
>Content-Disposition: form-data; name="text"
>
>**{COMMAND_ARGS}**
>------{boundary_string}
>Content-Disposition: form-data; name="channel"
>
>**{CHANNEL_ID}**
>------{boundary_string}
>Content-Disposition: form-data; name="token"
>
>**{TOKEN}**
>------{boundary_string}--
>

**{CHANNEL_ID}**はこちらの「[Slack | APIに使う「チャンネルID」を取得する方法](http://qiita.com/Yinaura/items/bd28c7b9ef614696fb7e)」を参考に投稿先のチャンネルIDを取得してください。チャンネルの名前では動作しません。

**{TOKEN}**は有効なトークン文字列を指定してください。[こちら](https://api.slack.com/docs/oauth-test-tokens)から取得できるテスト用トークンで動作しました。またbot用トークンでは動作しませんのでご注意ください。

その他はご利用の環境に合わせて適宜変更してください。

# curlで実行する場合
下記のようになります。
>curl "https://**{TEAM_NAME}**.slack.com/api/chat.command" -H 'Content-Type: multipart/form-data; boundary=----{boundary_string}' --data-binary $'------{boundary_string}\r\nContent-Disposition: form-data; name="command"\r\n\r\n **{COMMAND}** \r\n------{boundary_string}\r\nContent-Disposition: form-data; name="text"\r\n\r\n **{COMMAND_ARGS}** \r\n------{boundary_string}\r\nContent-Disposition: form-data; name="channel"\r\n\r\n **{CHANNEL_ID}** \r\n------{boundary_string}\r\nContent-Disposition: form-data; name="token"\r\n\r\n **{TOKEN}** \r\n------{boundary_string}--\r\n'

# Slash Commandを定期自動実行する
Slash Commandを定期的に自動実行してみます。
例えば毎日7時にSlash Commandを実行するには、cronを使って上記curlコマンドを実行したらよいので、以下のようになります。

> 0 7 * * * curl -s "https://**{TEAM_NAME}**.slack.com/api/chat.command" (以下、略. 上記curl実行例と同じ)

#### おまけ
毎日7時から「**平日の**」7時としたい場合は、curlコマンドの前にtestコマンドを使って、平日かどうかの判定を入れればよいでしょう。
\# 「[国民の祝日チェック](http://s-proj.com/utils/holiday.html)」を使わせてもらいました。
> 0 7 * * * test $(curl -s "http://s-proj.com/utils/checkHoliday.php?kind=h") == "else" && curl -s "https://**{TEAM_NAME}**.slack.com/api/chat.command" (以下、略. 上記curl実行例と同じ)
Paper Plane xUI で peco を使ってフォルダ履歴をたどる


基本部分は [Paper Plane xUI で peco を使ってタブを切り替える - Qiita](http://qiita.com/hokorobi/items/4e6d5cc76be48496d2f8) とおなじ。

```js:historypeco.js9
//!*script
// ディレクトリの履歴をpecoで選択して切り替え
// PPx 1.50+3 x64 + Script Module R16

if (PPx.Extract("%h1)") == "") PPx.Quit(-1);

var Fso = new ActiveXObject('Scripting.FileSystemObject');

var file = getListFile();
PPx.Execute('%Obsq *launch peco < ' + file + ' | iconv -f UTF-8 -t CP932 | clip');

PPx.Execute('*ppc -r ' + PPx.Clipboard);
Fso.DeleteFile(file);

function getListFile() {
    // 履歴を取得
    var dirs = [];
    for (var i = 1; PPx.Extract("%h" + i) != ""; i++) {
        dirs.push(PPx.Extract("%h" + i));
    }
    // 重複削除
    var uniqdirs = dirs.filter(function (x, i, self) {
        return self.indexOf(x) === i;
    });

    // ファイル UTF-8 で出力
    var posFirst = 0;
    var posSkipBOM = 3;
    var adWriteLine = 1; // 行区切り文字（改行）も入力
    var adSaveCreateOverWrite = 2;
    var adTypeBinary = 1;
    var adTypeText = 2;

    var ado = new ActiveXObject('ADODB.Stream');
    ado.Type = adTypeText;
    ado.Charset = 'UTF-8';
    ado.Open();

    for (var i = 0; i < uniqdirs.length; ++i) {
        ado.writeText(uniqdirs[i], adWriteLine);
    }

    ado.Position = posFirst; // バイナリモードにするため先頭へ移動
    ado.Type = adTypeBinary;
    ado.Position = posSkipBOM; // BOM を飛ばす
    var list = ado.Read();
    ado.Close();

    // ファイルへ出力
    ado.Open();
    ado.Write(list);
    var file = Fso.BuildPath(PPx.Extract("%'temp'"), Fso.GetTempName());
    ado.SaveToFile(file, adSaveCreateOverWrite);
    ado.Close();
    return file;
}
```
pyenvで入れたPythonをNeoVimで使う

## NeoVimのインストール
```bash
brew install neovim
```

## pyenvに入れたPythonにNeoVimサポートをインストール
```bash
pip3 install --user --upgrade neovim
```

## .vim/init.vim に以下を追加
```bash
let g:python3_host_prog = $PYENV_ROOT . '/shims/python3'
```

(@Ressさんありがとうございます!)
[FreeBSD][Redmine] FreeBSD用Redmine起動rcスクリプト

軽く検索したけれど、見つからなかったので備忘録です。
portsは依存関係でだいぶ大変なことになってしまったので、tarボールから入れました。 :sweat_smile: 

# 前提

- FreeBSD 10R
- Redmine 3.3
- Webサーバはthin

# rcスクリプト

```bash:/usr/local/etc/rc.d/redmine
#!/bin/sh

. /etc/rc.subr

name="redmine"

redmine_dir="/usr/local/redmine"

pidfile="/var/run/redmine.pid"
procname="ruby"

command="${redmine_dir}/bin/rails"
command_args="server thin"
command_args="${command_args} --daemon"
command_args="${command_args} --binding=0.0.0.0"
command_args="${command_args} --pid=${pidfile}"
command_args="${command_args} --environment=production"

load_rc_config $name
run_rc_command "$1"
```
gitの最新版をinstallしたい

# やりたいこと

1. gitの最新版をinstallすること

# yumでinstallする場合

```bash

$ sudo yum list | grep git

# 略
git.x86_64                                 1.8.3.1-6.el7_2.1           updates  

```

1.8系しか入らないけど最新の2系を入れたい。

# wgetでソースからinstallする

準備 : perl-ExtUtils-MakeMakerを事前にインストールする
最新版 : 2016/9/17現在の最新版は2.10.0

以下で確認
https://www.kernel.org/pub/software/scm/git/

```bash
$ sudo yum install -y perl-ExtUtils-MakeMaker
$ sudo wget https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz


    CC http-push.o
http-push.c:18:19: 致命的エラー: expat.h: そのようなファイルやディレクトリはありません
 #include <expat.h>
                   ^
コンパイルを停止しました。
```

エラーにぶつかる。
調べると expat-develをインストールしていくと良いらしい

```bash

$ sudo yum install -y expat-devel
# もう一回やり直し
$ sudo wget https://www.kernel.org/pub/software/scm/git/git-2.10.0.tar.gz

# 確認
$ which git
/usr/local/bin/git
$ git --version
git version 2.10.0

```

できた。

>参考
[CentOS6にGit1.8をコンパイルインストールする方法](http://dqn.sakusakutto.jp/2012/10/centos6git18.html)
windows 10 でhostsを書き換えると警告がでる件対応

## 参考

* [Hosts ファイルは、Windows Defender のマルウェアとして検出されます。](https://support.microsoft.com/ja-jp/kb/2764944)
* [メモーる: Windows10でhostsファイルを編集もしくは上書きできない。。。。](http://memoyasu.blogspot.jp/2016/03/windows10hosts.html)
    * セキュリティソフトにてhosts書き換えが監視されていた

## Defenderから除外

![2765289.png](https://qiita-image-store.s3.amazonaws.com/0/25728/07abbde1-864c-7c8b-eb47-f48aa3e1d983.png)
Railsでリーダブルコード（モデル編）

# 目的

Railsでモデルといえば、ロジックです
こういったものが定義されていると思います

会社をモデルにすると、こんな感じです

| 記述の分類 | 例えばこんなことをします | 
|-----------------|---|
|アソシエーション    |会社には従業員をたくさんいる|
|バリデーション      |『会社名が未入力です』などのメッセージ|
|スコープ           |今月誕生日の従業員一覧をとってくるメソッド|
|インスタンスメソッド |一人の従業員に有休をとらせるメソッド|
|クラスメソッド      |従業員一覧データをCSVファイルにする|
|コールバック        |入社した、全体の従業員数をインクリメントする|

いっぱいあります

こうすると読みやすいという観点で、すごく個人的な話をしていきます
あくまで個人的なものですが、ツッコミがあれば大歓迎です！
むしろ、私などがリーダブルコードとういテーマで書くことに若干恐怖があります

# モデルをシンプルにする２つのルール

## 1. 順番を決める
先ほどリストアップした**モデルに書かなきゃいけないこと**の順番を、最初にコメントをつけてフォーマットにすることです
ex )

```rb
class Prefectural < ActiveRecord::Base
  # 関連を定義
  has_many :areas

  # scopeを定義
  scope :active, -> {  }

  # boolean
  def active?
  end

  # インスタンスメソッドを定義
  def activate
  end

  # クラスメソッドを定義
  class << self
    def to_csv
    end
  end
  # コールバックを定義
  after_save do
  end

  # バリデーションを定義
  validates :name, presence: true

  # モジュールを読み込む
  include SUGEETUKAERUMODULE
end
```

コメントをつかってモデルの中を整頓します。

この順番は私がよく見る（一番気になる）ところにしてます
順番は好みですが、プロジェクト内のすべてのモデルで統一すると、より保守性があがります

 - 似たようなメソッドが近くにあるのに気付きやすくなったり
 - このメソッドのbooleanを返す部分が共通化出来そう！
 - スコープとかメソッドが一覧になってるので、まるでドキュメント

とかけっこう出てくると思います。（私のことです）

## 2. プライベートメソッドをつかう

初期のモデルは２〜３行しかないかわいいモデルです
いつのまにかコード量が多くなり、やがてモンスターになります
影響範囲が不明なメソッドがゾンビのようにはびこるお化け屋敷モデルになることがあります

そこで、私はプライベートメソッドを使います。ポイントは２つです

1. コントローラから呼ばれるものと、呼ばれないものを区別
2. publicメソッドの動作を数行で実装していく


```rb
class Prefectural < ActiveRecord::Base

  # controllerから呼ばれるメソッドたち
  # あらゆる人が読むところなので、共通処理をprivateにしてシンプルに
  # メソッド名や説明変数などで、表現豊かに
  # ドキュメントを書いてるつもりで、yard対応のコメントをつけると
  # メタプロしない

  ########################
  private
  ########################

  # controllerから呼ばれていないメソッドたち
  # 呼ばれそうでも、呼ばれるまではここに書く（影響範囲をはっきりさせたい）

  def kyouri
    ...
  end

  def kyabetu
    ...
  end

  def same
    ...
  end

  def saba
    ...
  end

  def koorizatou
    ...
  end
end
```

こうすることで、自分があまりよく知らないモデルのメソッドを使う場合でも、どれが外部からの呼び出しに使う用のメソッドがわかりやすくなります。

# まとめ
言葉足らずでしたが、まとめに入ってしまいます。
まとめると、個人的にこんなことに気をつけてます。

>
1. モデルのフォーマットを決める
2. private宣言でモデルの機能を区別する

変数やメソッドの名前や、ロジックの分割とかはこの本がとても参考になってます。
[リーダブルコード](
https://www.amazon.co.jp/%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89-%E2%80%95%E3%82%88%E3%82%8A%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%8F%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B7%E3%83%B3%E3%83%97%E3%83%AB%E3%81%A7%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%81%AA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-Theory-practice-Boswell/dp/4873115655/ref=sr_1_1?ie=UTF8&qid=1474107840&sr=8-1&keywords=%E3%83%AA%E3%83%BC%E3%83%80%E3%83%96%E3%83%AB+%E3%82%B3%E3%83%BC%E3%83%89)
RailsにオリジナルLoggerを定義する方法

## 目次
* [目的](#anchor0)
* [使い方](#anchor1)
* [ログのサンプル](#anchor2)
* [コード](#anchor3)

## <a id="anchor0"><a href="#anchor0">目的</a></a>  

  1. ログファイルごとのフォーマット共通化が楽になります
  2. エラーのときはトレースをログに残すので、トラブル対応が簡単です
  3. 曜日があるとわかりやすいかもしれません！


## <a id="anchor1"><a href="#anchor1">使い方</a></a>  

 ```ruby
 logger = define_product_logger('happy_zone')
 logger.info 'こんにちわ'
 begin
   raise AAAA
 rescue => e
     logger.fatal e
 end
 ```

## <a id="anchor2"><a href="#anchor2">結果</a></a>

> log/happy_zone.log

```
[happy_zone] [INFO] 2015/12/15 23:11:46 (火) : こんにちわ
[happy_zone] [FATAL] 2015/12/15 23:11:46 (火) : uninitialized constant ChangeHistoriesController::AAAA
backtrace: /Users/developer/test_rails_app/app/controllers/hoges_controller.rb:14:in `index'
```

## <a id="anchor3"><a href="#anchor3">コード</a></a>  

```ruby
def define_product_logger(product_name = 'default', span = 'weekly')
  logger = Logger.new("log/#{product_name}.log", span);
  logger.formatter = proc do |severity, datetime, progname, message|
  if message.kind_of?(Exception)
    message = "#{message.message} \n\t backtrace: #{message.backtrace[0,1].join("\n")}"
  end
  youbi = %w[日 月 火 水 木 金 土]
  datetime_format = "#{datetime.strftime('%Y/%m/%d %H:%M:%S')} (#{youbi[datetime.wday]})"
  "[#{product_name}] [#{severity}] #{datetime_format} : #{message}\n "
  end
  logger
end
```

> アドバイスいただけたら嬉しいです！
Railsのバリデーションをパターン化してConcernに定義すると、設計者とコミュニケーションが捗る

# 概要
 - バリデーションを定数にします
 - いわゆるカスタムバリデータではないです

# メリット
ステークスホルダーはエンジニアとディレクターです。

 - ふたりの共通言語をつくれます
 - ふたりとも、楽ができます
 - 定義ミスが減ります
 - 仕様書も実装もシンプルになります

# 実装

```rb
module OriginValidator
  extend ActiveSupport::Concern
  # すべてのバリデーションパターンを網羅してません
  # つくりすぎても、キャッチアップが大変になるので、
  # よくつかいそうなものだけ、フォーマットに従って定義しましょう

  # 文字列
  STRING_SHORT          = { length: { minimum: 0, maximum: 50 },      allow_blank: true } # 0~50文字
  STRING_SHORT_REQUIRED = { length: { minimum: 1, maximum: 50 },      presence:    true } # 1~50文字 必須
  STRING_LONG           = { length: { minimum: 0, maximum: 100 },     allow_blank: true } # 0~100文字
  STRING_LONG_REQUIRED  = { length: { minimum: 1, maximum: 100 },     presence:    true } # 1~100文字 必須

  TEXT_SHORT          = { length: { minimum: 0, maximum: 1000 },    allow_blank: true } # 0~1000文字
  TEXT_SHORT_REQUIRED = { length: { minimum: 1, maximum: 1000 },    presence:    true } # 1~1000文字 必須
  TEXT_LONG           = { length: { minimum: 0, maximum: 10000 },   allow_blank: true } # 0~10000文字
  TEXT_LONG_REQUIRED  = { length: { minimum: 1, maximum: 10000 },   presence:    true } # 1~100000文字 必須

  # 整数
  integer_short = { numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: 99 } }
  integer_long  = { numericality: { only_integer: true, greater_than_or_equal_to: 0, less_than_or_equal_to: 999999999 } }
  INTEGER_SHORT          = integer_short.merge(allow_blank: true) # 0~99まで
  INTEGER_SHORT_REQUIRED = integer_short.merge(presence: true)    # 0~99まで 必須
  INTEGER_LONG           = integer_long.merge(allow_blank: true)  # 0~99億まで
  INTEGER_LONG_REQUIRED  = integer_long.merge(presence: true)     # 0~99億まで 必須

  # 小数
  float_short = { numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 99 } }
  float_long  = { numericality: { greater_than_or_equal_to: 0, less_than_or_equal_to: 999999999 } }
  FLOAT_SHORT          = float_short.merge(allow_blank: true) # 0~99まで
  FLOAT_SHORT_REQUIRED = float_short.merge(presence: true)    # 0~99まで 必須
  FLOAT_LONG           = float_long.merge(allow_blank: true)  # 0~99億まで
  FLOAT_LONG_REQUIRED  = float_long.merge(presence: true)     # 0~99億まで 必須
end
```

# 使い方

```rb
class User
  include OriginValidator
  validates          :name,  STRING_LONG_REQUIRED
  validates      :business,  STRING_SHORT
  validates        :income,  INTEGER_SHORT_REQUIRED
end
```

# 解説
1. `include OriginValidator` で定数を使えるようにします
2. あとは、ドキュメントを書くようにバリデーションを定義しましょう

# まとめ
simple_formとの相性が良いですね！
Railsで比較のバリデーションを１行で書くGemつくった (created_at <= deleted_at)

# Overview
AとBのカラムがあった時に、
A > B
などを検証するカスタムバリデーションを動的に追加してくれます

そんなGemの紹介です。
[active_comparison_validator](https://github.com/s1160054/active_comparison_validator)
[RubyGems](https://rubygems.org/gems/active_comparison_validator)

## **ActiveComparisonValidator**
>
 Dynamically add validation for compare the column and the other column.
 This gem provides a macro for comparing the column and the other column of the record. Type of the comparable column is Date Time Numeric, and all that jazz.

# 意訳
こんなことができます。
`入社日   <  退社日`
`予算上限 >= 購入済み金額`
`携帯番号 != 代表番号`


などなど、いろいろ使えます

# Usage

Shopモデル（店舗）が
open_at（開店） < close_at（閉店） となっていることを検証してみます

```rb
class Shop < ActiveRecord::Base
  include ActiveComparisonValidator
  comparison_validator 'open_at < close_at'
end
```

引数の文字列とオペレータの間に、スペースを空けます
`comparison_validator 'open_at < close_at'`

# 関連
[validates_timeliness](https://github.com/adzap/validates_timeliness)
Gemのメンテできる & 日時だけの比較なら、こちらでおっけー！
Railsで２つの日付の差分をそれっぽく表示する(distance_of_time_in_words)

# したいこと
ビューヘルパーに`distance_of_time_in_words`というのがありますが、
ちょっとカスタマイズしてつかいたかったので、若干つくりました

やりたかったことは、こんなことです。

# できたこと
２つの日時を引数にとり、その差分をこんなフォーマットにする


```rb
     "1日前のとき  => 1日",
     "11日前のとき => 11日",
     "21日前のとき => 21日",
     "31日前のとき => 1ヶ月",
     "41日前のとき => 1ヶ月"
```

# コード

```rb
  # 日付を比較する
  # @param [Time] from_time 日付
  # @param [Time] to_time   日付
  # @return [String] １ヶ月未満の時 => oo日, 一ヶ月以上の時 => ooヶ月
  def distance_of_months(from_time, to_time = Time.current)
    from_time = from_time.to_time if from_time.respond_to?(:to_time)
    to_time = to_time.to_time     if to_time.respond_to?(:to_time)
    from_time, to_time = to_time, from_time if from_time > to_time
    distance_in_minutes = ((to_time - from_time)/60.0).round
    I18n.with_options :scope => 'datetime.distance_in_words' do |locale|
      case distance_in_minutes
      when 0...43200 then locale.t :x_days,   :count => (distance_in_minutes.to_f / 1440.0).round
      else                locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round
      end
    end
  end
```
RailsでNVD3(グラフライブラリ)を使う方法

# 1. 導入

## 1.1 ライブラリ配置
[d3.min.js](https://cdnjs.com/libraries/d3)をダウンロード
[nv.d3.min.js, nv.d3.min.css](https://cdnjs.com/libraries/nvd3)をダウンロード

こちらにおいときます

```
vendor/assets/javascripts/d3.min.js
vendor/assets/javascripts/nv.d3.min.js
vendor/assets/stylesheets/nv.d3.min.css
```

## 1.2 パイプラインに追加
### app/assets/javascripts/application.coffee

```coffeescript
#= require d3.v3.min.js # D3 => NVDで読み込まないと動かないので注意
#= require nv.d3.min.js
```
 
### app/assets/stylesheets/application.scss
```scss
@import "nv.d3.min";
```

# 2. デモページのソースコードを動かしてみる

## 2.1 とりあえず**js2coffee**
[Stacked Area Chart - NVD3](http://nvd3.org/examples/stackedArea.html)
こちらのソースコードをコピーして[js2coffee](http://js2.coffee/)したものがこちら↓

```coffeescript
d3.json 'stackedAreaData.json', (data) ->
  nv.addGraph ->
    chart = nv.models.stackedAreaChart().margin(right: 100).x((d) ->
      d[0]
    ).y((d) ->
      d[1]
    ).useInteractiveGuideline(true).rightAlignYAxis(true).transitionDuration(500).showControls(true).clipEdge(true)
    #Format x-axis labels with custom function.
    chart.xAxis.tickFormat (d) ->
      d3.time.format('%x') new Date(d)
    chart.yAxis.tickFormat d3.format(',.2f')
    d3.select('#chart svg').datum(data).call chart
    nv.utils.windowResize chart.update
    chart
  return
```

## 2.2 動くように修正

```coffeescript
# contorollerからグラフデータをJSONで取得する
graph_reload = (params) ->
  $.ajax '/dashboard?target=' + params,
    type: 'GET'
    dataType: 'json'
    success: (res, textStatus, jqXHR) ->
      make_graph(res)

make_graph = (data) ->
  nv.addGraph ->
    # chartにマージンやら単位やらの情報をメソッドチェーンでつける。詳しくは↓
    # https://nvd3-community.github.io/nvd3/examples/documentation.html
    chart = nv.models.stackedAreaChart().margin(right: 100).x((d) ->
      d[0]
    ).y((d) ->
      chart.xAxis.tickFormat (d) -> d[1]
    ).useInteractiveGuideline(true)
    .rightAlignYAxis(true).showControls(true).clipEdge(true)

    
    # X軸のフォーマット。dは日付ではなく、0から始まるインデックスなことに注意
    chart.xAxis.tickFormat (d) ->
      d + '日'
    # もし、日付にして、しかも曜日まで表示したい時は
    # chart.xAxis.tickFormat (d) ->
    #   dx = data[0].values[d] and data[0].values[d][0] or 0
    #   date = new Date(d.data[0])
    #   "#{d3.time.format('%m/%d')(date)} (#{'日月火水木金土'[date.getDay()]})"


    # Y軸のフォーマット`d3.format(',')`は金額などをカンマ区切りにするときなど
    # もし、千円単位にしたい時は
    # chart.yAxis.tickFormat (d) ->
    #   d3.format(',f')(d/1000) + '千円'
    chart.yAxis.tickFormat(d3.format(','))


    # もしも、軸の最大値と最小値を0~1000万にしたい時は
    # chart.forceY [ 0, 1000*10*4 ]

    d3.select('svg#chart').datum(data).call chart
    nv.utils.windowResize chart.update     
    chart
  return

```

こちらに　[NVDドキュメント](https://nvd3-community.github.io/nvd3/examples/documentation.html)　があります
android studio initial setup

# JDK
android studio が起動しない場合
 環境変数 JAVA_HOMEが適切に設定されていない場合がある？
```
   JAVA_HOME=C:\Program Files\Java\jdk1.8.0_101\bin
    ↓
   JAVA_HOME=C:\Program Files\Java\jdk1.8.0_101
```


# NDKインストール
>[File]->[Other Settings]->[Default Project Structure]
> Android NDK location: 下で Download を実行

# adbの利用
環境変数のPATHでパスを通す。
場所は ANDROID_SDKはインストールした場所でその配下の platform-toolsにadb.exeがある
> PATH=%PATH%;%ANDROID_SDK%.\platform-tools
 


# 文字コード設定

> http://k-hiura.cocolog-nifty.com/blog/2015/07/androidstudio-b.html
> https://akira-watson.com/android/android-studio-encoding.html

# Terminal

Terminal でエコーバックが起こる場合は現在調査中
SoundCloud APIでoffsetが廃止された話

SoundCloudって結構有名な音楽サービスだと思うんですが意外とAPI使ってる所少なくて、Qiitaでそれ系の記事を見た事ないです。

#SoundCloud APIでoffsetが廃止された話
本題に入りますと、SoundCloudで検索やらお気に入りで曲情報を取得する時に50件目から100件取得したいなんて事があります。
この時のパラメータは今までだと`limit=100&offset=50`となります。

ただ、いつの間にかこの`offset`パラメータが廃止されていました( ﾟДﾟ)
(見たところ、完全に廃止されたわけではなくoffset=200は有効でした。ただoffset=400はダメでした。)

#開発者ブログ
[Linked partitioning to replace offset-based pagination ](https://developers.soundcloud.com/blog/offset-pagination-deprecated)
詳細はこのSoundCloud開発者ブログに載ってるんですが、ざっくり説明すると

> offsetベースのページングをリンクベースのページングに変更します

って感じです。

#じゃあどうすればいいの？
リンクベースでは`offset`の代わりに`linked_partitioning=1`というパラメータを付けると返ってくる値に`next_href`という次の結果を返すリンクが付いてきます。
多分、ツイッターとかと同じ仕様ですかね？

#その他
楽になった所もある一方、検索結果やお気に入り、タイムラインを1000件取得したい場合などにこれまでは並列リクエストで対応できた物が、`next_href`が必要になった事で直列的な処理をしなければならなくなったので時間がかかるようになり個人的には残念な変更です。
素人の言語処理100本ノック:06


[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)の挑戦記録です。環境はUbuntu 16.04 LTS ＋ Python 3.5.2 \:\: Anaconda 4.1.1 (64-bit)です。過去のノックの一覧は[こちら](http://qiita.com/segavvy/items/fb50ba8097d59475f760)からどうぞ。

## 第1章: 準備運動

###06.集合
>"paraparaparadise"と"paragraph"に含まれる文字bi-gramの集合を，それぞれ, XとYとして求め，XとYの和集合，積集合，差集合を求めよ．さらに，'se'というbi-gramがXおよびYに含まれるかどうかを調べよ．

出来上がったコード：

```python:main.py
# coding: utf-8


def n_gram(target, n):
    '''指定されたリストからn-gramを作成

    引数:
    target -- 対象リスト
    n -- n-gramのn値（1ならuni-gram、2ならbi-gram...）
    戻り値:
    gramのリスト
    '''
    result = []
    for i in range(0, len(target) - n + 1):
        result.append(target[i:i + n])

    return result


# 集合の作成
set_x = set(n_gram('paraparaparadise', 2))
print('X:' + str(set_x))
set_y = set(n_gram('paragraph', 2))
print('Y:' + str(set_y))

# 和集合
set_or = set_x | set_y
print('和集合:' + str(set_or))

# 積集合
set_and = set_x & set_y
print('積集合:' + str(set_and))

# 差集合
set_sub = set_x - set_y
print('差集合(X - Y):' + str(set_sub))
set_sub = set_y - set_x
print('差集合(Y - X):' + str(set_sub))

# 'se'が含まれるか？
print('seがXに含まれる:' + str('se' in set_x))
print('seがYに含まれる:' + str('se' in set_y))
```

実行結果：

```python:端末
X:{'se', 'ap', 'pa', 'is', 'di', 'ar', 'ra', 'ad'}
Y:{'ag', 'ap', 'pa', 'ra', 'ph', 'ar', 'gr'}
和集合:{'ag', 'se', 'ap', 'pa', 'is', 'ph', 'di', 'ar', 'ra', 'gr', 'ad'}
積集合:{'ar', 'ap', 'pa', 'ra'}
差集合(X - Y):{'se', 'is', 'di', 'ad'}
差集合(Y - X):{'ph', 'gr', 'ag'}
seがXに含まれる:True
seがYに含まれる:False
```
***
`n_gram()`は[前問](http://qiita.com/segavvy/items/6f9f028914176c069c41)の使い回しです。

先輩方の回答には、[`set.union()`](http://docs.python.jp/3/library/stdtypes.html#set.union)、 [`set.intersection()`](http://docs.python.jp/3/library/stdtypes.html#set.intersection)、 [`set.difference()`](http://docs.python.jp/3/library/stdtypes.html#set.difference)を使われているものが多いですね。そちらの方が可読性が高いということですが、英語が苦手な私は`|`や`&`や`-`の方が直感的なので、こちらにしてみました。

それにしても、こんなところで[paraparaparadise](https://ja.wikipedia.org/wiki/ParaParaParadise)が出てくるとは^^
　
7本目のノックは以上です。誤りなどありましたら、ご指摘いただけますと幸いです。
[Xcode8]コメントアウトのショートカットが効かない？

# Xcode8をインストールしてしばらくして気づいた
あれ？`command+/`でコメントアウト出来ない…

# 調べてみた
## Source Editor Extension
Editorの機能がいくつか拡張機能化された？（まだよく理解出来てない…）
（参考記事）[Xcode Editor Extension と Xcode8 で Plugin が動かなくなったことについて発表してきました](http://dealforest.hatenablog.com/entry/2016/06/24/172056)

# 解決策
## `sudo /usr/libexec/xpccachectl` & Mac reboot
* 参考記事で紹介されてた上記方法で、ショートカット利用可能になりました。
    * `command+i`とか、他ショートカットにも有効。かも。
Railsのバージョンに依存する条件分岐でテストカバレッジを100%に保つ


RailsプラグインをGemとして公開するときなど、複数バージョンのRailsをサポートしたいことがあります。
[Travis CI](https://travis-ci.org)を使用すると、依存Gemのバージョンを組み合わせて、複数環境でのテストを自動化することが出来ます。また、[Coveralls](https://coveralls.io)などを使用すると、複数環境でのテストカバレッジを可視化して管理することが出来ます。

複数バージョンのRailsをサポートするGemの開発時には、互換性のためにRailsバージョンに依存する処理の分岐を迫られることがあります。

```ruby
if Rails::VERSION::MAJOR >= 5
  # Code for Rails5
  hogehoge
else
  # Code for Rails4
  foobar
end
```

このような条件分岐が存在すると、Rails5環境下では`# Code for Rails4`は実行されず、Rails4環境下では`# Code for Rails5`が実行されないので、意図せずテストカバレッジが下がってしまいます。そのような時には、`simplecov`の`nocov_token`をカスタマイズすることで、テストカバレッジを100%に保つことが出来ます。
以下の例では、テストカバレッジの計測には[simplecov](https://github.com/colszowka/simplecov)と[Coveralls](https://coveralls.io)を使用しており、テストにはRSpecを使用しています。Minitestなど他のテストフレームワークをお使いの場合には、適宜読み替えて下さい。
[simplecovのnocov_token](http://www.rubydoc.info/gems/simplecov/SimpleCov/Configuration#nocov_token-instance_method)

# 手順
Railsのバージョンに応じて処理を分岐している箇所に、任意のアノテーションをコメントとして記述します。

```ruby
# :skip-rails4:
if Rails::VERSION::MAJOR >= 5
  # Code for Rails5
  hogehoge
# :skip-rails4:
# :skip-rails5:
else
  # Code for Rails4
  foobar
end
# :skip-rails5:
```

そして、`spec_helper.rb`などの中に、`simplecov`の`nocov_token`を定義します。

```spec/spec_helper.rb
SimpleCov.start('rails') do
  add_filter '/spec/'
  # Railsのバージョンに応じてコードカバレッジの対象外とするアノテーションを定義する
  if Rails::VERSION::MAJOR == 5
    nocov_token 'skip-rails5'
  elsif Rails::VERSION::MAJOR == 4
    nocov_token 'skip-rails4'
  end
end
```

こうして、めでたくテストカバレッジを100%に保つことが出来ます。
vagrantの起動に失敗する場合のTips3点(windows)

[株式会社オズビジョン](http://www.oz-vision.co.jp/)の@terra_yuccoです。

業務でも、[enPiTプログラム](http://enpit.aiit.ac.jp/)でも、開発環境にはvagrantを利用しています。
業務ではあまり直面しないのですが、enPiTプログラムではvagrantが起動しない壁に良く突き当たるので、参照したサイトのリンクとともに、Tryの記録を残したいと思います。

# 環境
- Windows 10 Home
- Vagrant 1.8.4
- VirtualBox 5.0.24 r108355

# 1: アップデート確認から進まない
- 事象

```bat
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'xxxxx/yyyyy' is up to date...
```

- 対処
    - vagrantファイルの以下の行のコメントを解除します。
        - ただし推奨設定ではありません
        - 本当はなんでそこで止まるのかチェックするべきではあります

```text
# config.vm.box_check_update = false
```

# 2: ポートが衝突している
- 事象

```bat
$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'xxxxx/yyyyy' is up to date...
Vagrant cannot forward the specified ports on this VM, since they
would collide with some other application that is already listening
on these ports. The forwarded port to 3000 is already in use
on the host machine.

To fix this, modify your current project's Vagrantfile to use another
port. Example, where '1234' would be replaced by a unique host port:

  config.vm.network :forwarded_port, guest: 3000, host: 1234

Sometimes, Vagrant will attempt to auto-correct this for you. In this
case, Vagrant was unable to. This is usually because the guest machine
is in a state which doesn't allow modifying port forwarding. You could
try 'vagrant reload' (equivalent of running a halt followed by an up)
so vagrant can attempt to auto-correct this upon booting. Be warned
that any unsaved work might be lost.
```

- 対処
    - もしVagrantfile内に重複エントリがあったり、別のVagrantが上がっていてぶつかるのであればポートをずらしましょう。
    - 自分は以下の設定を有効にしていたらぶつかったので、よくわからず切ってみたら起動したりしました。

```text
# config.vm.network "private_network", ip: "192.168.33.10"
# config.vm.network "public_network"
```

# 3: sshに繋がらない
- 事象

```bat
(前略)
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2222
    default: SSH username: vagrant
    default: SSH auth method: private key
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
    default: Warning: Remote connection disconnect. Retrying...
      :
      :
```

- 対処
    - とりあえず待つ。
    - Windowsだと裏でUACコントロールがポートを開ける許諾を求めていることがあります。必要なところだけはファイアウォールに穴を開けましょう。

# appendix: それでも上がらない

あ、石を投げないで...

- Windowsを再起動する
- VirtualBoxのプロセスを一度落とす

今まで何度か上記の手段を取っていますが、特にVirtualBoxのプロセスを落とすは凄く効果的です。
塞いだ覚えのないポートが塞がれているときなどは、前に挙げていたVagrantが無事に落ちきっていないというケースが多いような…？

# 参考にしたサイト、ページ
- [vagrant up起動に失敗したら](http://qiita.com/amateurgrammer/items/21e4456b8318db877f5b)
- [Vagrant on Windowsが(Booting VM...のまま)動かない！→Task ManagerからVirtualBoxとVagrantをKillしたらどうでしょう？](http://qiita.com/amateurgrammer/items/2ce3d4f4379bde78a9c9)


それではよいvagrantライフを！
おしまい。
自作のRailsプラグインGemを複数バージョン環境で自動テストする


自作のRailsプラグインをGemとして公開するときに、複数バージョンのRailsをサポートしたいことがあります。このような時には、サポートするRubyやRailsなど依存Gemのバージョンを組み合わせて、複数環境でのテストを自動化することが出来ます。その方法をまとめます。

# Travis CI
CIにはいくつか種類がありますが、[Travis CI](https://travis-ci.org)を使えば、設定のみで複数のRubyやGemのバージョンを組み合わせてテストを自動化出来ます。Travis CIの基本的な使用方法やGithubリポジトリとの連携方法などについては、多くの情報があるのでここでは割愛します。

# 複数のRubyバージョンでのテスト
`.travis.yml`の`rvm`に、対象のRubyバージョンを定義します。

```.travis.yml
rvm:
  - 2.1.10
  - 2.2.7
  - 2.3.4
  - ruby-head

matrix:
  # ruby-headはテストの失敗を許容する
  allow_failures:
    - rvm: ruby-head
```

上記の例では、Rubyの2.1系、2.2系、2.3系をテストの対象としています。`ruby-head`は開発中のRubyバージョンであるため、テストが失敗するケースがあります。そこで`allow_failures`により失敗を許容します。

# 複数の依存Gemバージョンでのテスト
例として、複数のRailsバージョンをテストの対象とします。
まず、Gemがサポートするバージョンを定義したgemspecファイルと、依存Gemバージョン毎にGemファイルを用意します。

```mygem.gemspec
  # Rubyのバージョンを指定する
  s.required_ruby_version = '>= 2.1.0'

  # Gemに本当に必要なモジュールのみをgemspecに記述する
  s.add_dependency 'railties', '>= 4.2.0', '< 5.1'
  s.add_dependency 'activerecord', '>= 4.2.0'
```

```gemfiles/Gemfile.rails-5.0
source 'https://rubygems.org'
gemspec path: '../'
gem 'rails', '~> 5.0.0'
```

```gemfiles/Gemfile.rails-4.2
source 'https://rubygems.org'
gemspec path: '../'
gem 'rails', '~> 4.2.0'
```

その上で、`.travis.yml`の`gemfile`に、対象のGemファイルを定義します。

```.travis.yml
gemfile:
  - Gemfile
  - gemfiles/Gemfile.rails-5.0
  - gemfiles/Gemfile.rails-4.2

matrix:
  exclude:
    - rvm: 2.1.10
      gemfile: gemfiles/Gemfile.rails-5.0
```

上記の例では、Railsの4.2系と5.0系をテストの対象としています。Rails5.0はRuby2.2系以上に依存するので、`exclude`によりRuby2.1系とRails5.0系の組み合わせをテスト対象から除外しています。

### ローカルでのテスト
Gemバージョンに依存する処理の開発時は、ローカルの開発環境でも複数バージョンのテストが通ることを確認する必要があります。そのような時には、環境変数にGemファイルを指定してテストを実行することが出来ます。
※以下はテストにRSpecを使用している場合の例です。適宜読み替えて下さい。

```bash
# Rails 5.0でのテスト
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-5.0 bundle exec rspec
# Rails 4.2でのテスト
BUNDLE_GEMFILE=gemfiles/Gemfile.rails-4.2 bundle exec rspec
```

# 複数の環境変数（ORMなど）でのテスト
`ActiveRecord`と`Mongoid`など、複数のORMをサポートしているGemでは、各ORMに対してテストを回したいこともあります。そのような場合は、`.travis.yml`の`env`に環境変数をセットしてテスト環境を定義します。

```.travis.yml
env:
  - MYGEM_ORM=active_record
  - MYGEM_ORM =mongoid

matrix:
  exclude:
    - env: MYGEM_ORM =mongoid
      gemfile: Gemfile

services:
  - mongodb
```

テストコードの中で、環境変数に応じて自分のGemにORMを`env`にセットします。`rvm`と`gemfile`と同じようにMatrixで条件の組み合わせを定義できます。アプリケーションの中で、環境変数`MYGEM_ORM`に応じて使用するORMを切り替える処理が必要です。`.travis.yml`の`services`に`mongodb`と記述すればCI上でMongoDBを使用出来るようになります。

# テスト結果
最終的に記述される`.travis.yml`は以下のようになります。

```.travis.yml
language: ruby

rvm:
  - 2.1.10
  - 2.2.7
  - 2.3.4
  - ruby-head

gemfile:
  - Gemfile
  - gemfiles/Gemfile.rails-5.0
  - gemfiles/Gemfile.rails-4.2

env:
  - MYGEM_ORM=active_record
  - MYGEM_ORM=mongoid

matrix:
  exclude:
    - rvm: 2.1.10
      gemfile: gemfiles/Gemfile.rails-5.0
    - rvm: 2.1.10
      gemfile: Gemfile
    - env: MYGEM_ORM=mongoid
      gemfile: Gemfile
  allow_failures:
    - rvm: ruby-head
  fast_finish: true

services:
  - mongodb

# 中略

script: bundle exec rspec
```

ソースコードがGithubリポジトリへPushされると、Travis CI上で自動的に複数環境下でのテストが実行されます。

![travisci_part.png](https://qiita-image-store.s3.amazonaws.com/0/61098/3969bded-c542-11b2-7e37-23f1ac7b418b.png)