Adds initial hot score implementation for debates
This commit is contained in:
@@ -21,6 +21,8 @@ class Debate < ActiveRecord::Base
|
||||
before_validation :sanitize_description
|
||||
before_validation :sanitize_tag_list
|
||||
|
||||
before_save :calculate_hot_score
|
||||
|
||||
scope :sorted_for_moderation, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||
scope :pending_flag_review, -> { where(ignored_flag_at: nil, hidden_at: nil) }
|
||||
scope :with_ignored_flag, -> { where("ignored_flag_at IS NOT NULL AND hidden_at IS NULL") }
|
||||
@@ -102,6 +104,24 @@ class Debate < ActiveRecord::Base
|
||||
update(ignored_flag_at: Time.now)
|
||||
end
|
||||
|
||||
def calculate_hot_score
|
||||
z = 1.96 # Normal distribution with a confidence of 0.95
|
||||
time_unit = 12.hours
|
||||
start = Time.new(2015, 6, 15)
|
||||
|
||||
n = cached_votes_total + comments_count / 3
|
||||
pos = cached_votes_up + comments_count / 3
|
||||
|
||||
phat = 1.0 * pos / n
|
||||
|
||||
weigted_score = n == 0 ? 0 :
|
||||
(phat + z*z/(2*n) - z * Math.sqrt((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n)
|
||||
|
||||
age_in_units = ((created_at || Time.now) - start) / time_unit
|
||||
|
||||
self.hot_score = (age_in_units**3 + weigted_score * 1000).round
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def sanitize_description
|
||||
@@ -111,5 +131,4 @@ class Debate < ActiveRecord::Base
|
||||
def sanitize_tag_list
|
||||
self.tag_list = TagSanitizer.new.sanitize_tag_list(self.tag_list)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -71,6 +71,10 @@ FactoryGirl.define do
|
||||
Flag.flag(FactoryGirl.create(:user), debate)
|
||||
end
|
||||
end
|
||||
|
||||
trait :with_hot_score do
|
||||
before(:save) { |d| d.calculate_hot_score }
|
||||
end
|
||||
end
|
||||
|
||||
factory :vote do
|
||||
|
||||
@@ -181,4 +181,38 @@ describe Debate do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#hot_score' do
|
||||
let(:now) { Time.now }
|
||||
|
||||
it "gets bigger for newer debates" do
|
||||
old = create(:debate, :with_hot_score, created_at: now - 1.day)
|
||||
new = create(:debate, :with_hot_score, created_at: now)
|
||||
expect(new.hot_score).to be > old.hot_score
|
||||
end
|
||||
|
||||
it "gets bigger for debates with more comments" do
|
||||
more_comments = create(:debate, :with_hot_score, created_at: now, comments_count: 10)
|
||||
less_comments = create(:debate, :with_hot_score, created_at: now, comments_count: 1)
|
||||
expect(more_comments.hot_score).to be > less_comments.hot_score
|
||||
end
|
||||
|
||||
it "gets bigger for debates with more positive votes" do
|
||||
more_likes = create(:debate, :with_hot_score, created_at: now, cached_votes_total: 10, cached_votes_up: 5)
|
||||
less_likes = create(:debate, :with_hot_score, created_at: now, cached_votes_total: 10, cached_votes_up: 1)
|
||||
expect(more_likes.hot_score).to be > less_likes.hot_score
|
||||
end
|
||||
|
||||
it "gets bigger for debates with more confidence" do
|
||||
more_confidence = create(:debate, :with_hot_score, created_at: now, cached_votes_total: 1000, cached_votes_up: 700)
|
||||
less_confidence = create(:debate, :with_hot_score, created_at: now, cached_votes_total: 10, cached_votes_up: 9)
|
||||
expect(more_confidence.hot_score).to be > less_confidence.hot_score
|
||||
end
|
||||
|
||||
it "decays older debates, even if they have more votes" do
|
||||
older_more_voted = create(:debate, :with_hot_score, created_at: now - 2.days, cached_votes_total: 1000, cached_votes_up: 900)
|
||||
new_less_voted = create(:debate, :with_hot_score, created_at: now, cached_votes_total: 10, cached_votes_up: 9)
|
||||
expect(new_less_voted.hot_score).to be > older_more_voted.hot_score
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user