diff --git a/app/controllers/reports_controller.rb b/app/controllers/reports_controller.rb index 05d020588..9187fce9c 100644 --- a/app/controllers/reports_controller.rb +++ b/app/controllers/reports_controller.rb @@ -6,4 +6,8 @@ class ReportsController < ApplicationController def janitor_trials @report = Reports::JanitorTrials.new end + + def contributors + @report = Reports::Contributors.new + end end diff --git a/app/logical/reports/contributors.rb b/app/logical/reports/contributors.rb new file mode 100644 index 000000000..3b2a8c7dc --- /dev/null +++ b/app/logical/reports/contributors.rb @@ -0,0 +1,9 @@ +require 'statistics2' + +module Reports + class Contributors < User + def users + ::User.where("users.level >= ? and users.post_upload_count >= 250", ::User::Levels::CONTRIBUTOR).order("created_at desc").limit(50).map {|x| Reports::UserPromotions::User.new(x)} + end + end +end diff --git a/app/logical/reports/user_promotions.rb b/app/logical/reports/user_promotions.rb index ac996e08c..bbab3cb60 100644 --- a/app/logical/reports/user_promotions.rb +++ b/app/logical/reports/user_promotions.rb @@ -30,16 +30,17 @@ module Reports def self.confidence_interval_for(user, n) up_votes = Post.where("created_at >= ?", min_time).where(:is_deleted => false, :uploader_id => user.id).where("score >= ?", n).count total_votes = Post.where("created_at >= ?", min_time).where(:uploader_id => user.id).count - ci_lower_bound(up_votes, total_votes, 0.95) + ci_lower_bound(up_votes, total_votes) end - def self.deletion_confidence_interval_for(user) - deletions = Post.where(:uploader_id => user.id, :is_deleted => true).count - total = Post.where(:uploader_id => user.id).count - ci_lower_bound(deletions, total, 0.95) + def self.deletion_confidence_interval_for(user, days = nil) + date = (days || 30).days.ago + deletions = Post.where("created_at >= ?", date).where(:uploader_id => user.id, :is_deleted => true).count + total = Post.where("created_at >= ?", date).where(:uploader_id => user.id).count + ci_lower_bound(deletions, total) end - def self.ci_lower_bound(pos, n, confidence) + def self.ci_lower_bound(pos, n, confidence = 0.95) if n == 0 return 0 end diff --git a/app/models/user.rb b/app/models/user.rb index dcba0b15c..caaf03313 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -760,6 +760,12 @@ class User < ActiveRecord::Base end end + module StatisticsMethods + def deletion_confidence(days = 30) + Reports::UserPromotion.deletion_confidence_interval_for(self, days) + end + end + include BanMethods include NameMethods include PasswordMethods @@ -774,6 +780,7 @@ class User < ActiveRecord::Base include ApiMethods include CountMethods extend SearchMethods + include StatisticsMethods def initialize_default_image_size self.default_image_size = "large" diff --git a/app/views/reports/contributors.html.erb b/app/views/reports/contributors.html.erb new file mode 100644 index 000000000..191e8c644 --- /dev/null +++ b/app/views/reports/contributors.html.erb @@ -0,0 +1,52 @@ +
Binomial proportion confidence interval for how likely a user's uploads will achieve a score of at at least n with 95% confidence within the past 30 days. Most statistics are not significant unless there are at least 300 uploads.
+ +| User | +Level | +Uploads | +score:3+ | +quartile score | +median score | +deletion | +
|---|---|---|---|---|---|---|
| <%= link_to_user user.user %> | +<%= user.level_string %> | +<%= link_to user.post_upload_count, posts_path(:tags => "uploader:#{user.name} order:random", :limit => 200) %> | +<%= number_to_percentage user.confidence_interval_for(3), :precision => 0 %> | +<%= user.quartile_score %> | +<%= user.median_score %> | +<%= link_to number_to_percentage(user.deletion_confidence_interval, :precision => 0), posts_path(:tags => "uploader:#{user.name} status:deleted", :limit => 200) %> | +
Binomial proportion confidence interval for how likely a user's uploads will achieve a score of at at least n with 95% confidence within the past 30 days. Most statistics are not significant unless there are at least 300 uploads.
@@ -12,7 +12,6 @@