injectを使って合計を求める方法
rubyで普通にinjectを使って合計を求めようとした場合、こんな感じになります。
1 (1..10).inject(0){|sum, i| sum + i} #=> 55
しかし、以下のように書く事も出来ます。
1 (1..10).inject(&:+) #=> 55
rubyで普通にinjectを使って合計を求めようとした場合、こんな感じになります。
1 (1..10).inject(0){|sum, i| sum + i} #=> 55
しかし、以下のように書く事も出来ます。
1 (1..10).inject(&:+) #=> 55
ポジティブ/ネガティブ投票による正しいランキング方法が以下の記事で紹介されています。
How Not To Sort By Average Rating
この計算方法では、投票数が少ない場合には分散が大きく不正確な評価で、 投票数が多くなるにつれて分散が小さく正確な評価が得られているという事を考慮しています。以下数式
これはScoreの信頼区間を表しています。 この信頼区間の下界をランキングのスコアにすれば良い事になります。 ここで、は、
です。全体に占めるポジティブ投票数の割合ですね。
さて、五段階評価によるRatingに同様のテクニックを適用する場合はどうしたらいいでしょうか。
単純に、1回の投票を4度のpositive/n
従って、最終的にこんな感じになります。
Rubyコードで表すとこんな感じですね。
1 require 'statistics2' 2 3 def score(ni, alpha) 4 n = ni.inject(&:+) 5 return 0 if n == 0 6 m = ni.size 7 z = Statistics 2.pnormaldis t(1-alpha/2) 8 phat = m.times.zip(ni).inject(0){|s,(i,j)| s + i*j}/((m - 1.0)*n) 9 (phat + z*z/(2*n) - z*Math.sqrt((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n) 10 end
Enumerable
1 Dir["config/environments/ *.rb"].grep(%r{(\w+)\.rb$}){$1} 2 #=> ["developmen t", "production ", "rake", "staging", "test"]
痒いところに手が届く感じですね。
例えばJavaScript
1 [0x3000].pack("U") == " " #=> true
長い事迂回していた問題だったのでスッキリしました :-)
Special Thanks
Rails勉強会#40のセッションでも言いましたが、 エラーが発生した時等に表示されるbacktraceの表示は、 コンソールのように上から下に流れる画面上では 通常の逆順のほうが追いやすいと思います。
ということで、ちょっと試しにそのような挙動にしてみました。 以下のようなコードを実行するとテストできます。
1 class Exception 2 def set_backtrace(bt) 3 puts bt.reverse.map{|i| 4 i.sub(/^([\/\.\w]+):(\d+)/, 5 "\e[33m\\1\e[m:\e[32m\\2\e[m") 6 }.join("\n") 7 end 8 end 9 10 def foo 11 raise StandardEr ror 12 end 13 14 def bar 15 foo 16 end 17 18 bar
こんな感じに、エラーが発生した場所に近い順に、 下から上にたどっていく感じに表示されます。
上から下のbacktraceに目が慣れてしまっているので、最初は追いかけにくさを感じますが、一旦慣れてしまえば、スタックが深くて相当スクロールアップしなければエラーの発生源までたどり着けないという場合には良さそうな気がします。
stackという概念のイメージのせいで、新しいものが上の方に来るようになっているのだと思いますが、実用上は新しいものが下にくるこのスタイルの方が便利ではないでしょうか。
Rakeでnamespaceなどを使った場合に、Rubyのシンボルをネストさせたい時があるのですが、
1 task :foo => :"bar:baz"
のように書くのが、DSL的にちょっとかっこうわるいです。 そこで、以下のようなものがあればちょっと奇麗に書けます。
1 class Symbol 2 def method_missing(method, *args, &block) 3 if args.empty? && block.nil? 4 [self, method].join(':').intern 5 else 6 super 7 end 8 end 9 end 10 11 >> :foo #=> :foo 12 >> :foo.bar #=> :"foo:bar" 13 >> :foo.bar.baz #=> :"foo:bar:ba z"
いかがでしょう。
GAE/Jにはファイル数制限(1000まで)があるので、なるべく不要なファイルは減らしたいのが人情というものです。 ということで、unpackしたgemsから不要なファイルを掃除するために、以下のようなスクリプトを使用しています。
script/str
1 #!/usr/bin/env ruby 2 3 Dir['gems/gems/ *'].each do |dir| 4 %w( 5 Generaters TODO README.* README 6 spec/**/* test/**/* examples/**/* tasks/**/* 7 tutorial/**/* demo/**/* 8 CHANGES CHANGES.tx t CHANGELOG 9 LICENSE MIT-LICENS E Rakefile CONTRIBUTO RS 10 Manifest.t xt History.tx t install.rb setup.rb 11 ).each do |pattern| 12 Dir[File.join(dir, pattern)].each do |path| 13 command = "rm -rf #{path}" 14 puts command 15 system command 16 end 17 end 18 end
Gemの中に含まれているファイルには制約が無いので、 簡単なパターンで全てを掃除するのは難しいですね。
gemを指定したディレクトリにインストールする方法を紹介します。 以下のように -i オプションでディレクトリを指定します。
1 gem install -i ./gems data_objects --no-ri --no-rdoc
Gemをunpackしている場合に、もう一つ、二つGemを追加したい時などに重宝します。
Rails-2.3からRackに対応した事と関連が深いと思うのですが、
ruby-openi
1 @@logger = Logger.new(STDERR)
STDERRを使うようになっているのですが、これがRackと相性が悪いようです。
以下のように、config/ini
1 OpenID::Util::logger = Logger.new(File.join(Rails.root, %w(log openid.log)))
何回か忘れたので、記憶を定着させるためにメモしておきます。 rubyでLOAD_PATHに特定のディレクトリを追加したい場合、以下のように RUBYLIB環境変数が利用できます。
1 export RUBYLIB=/usr/lib/sit e_ruby:$RUBYLIB