diff --git a/app/controllers/questions_controller.rb b/app/controllers/questions_controller.rb index 0df3131..82fa65a 100644 --- a/app/controllers/questions_controller.rb +++ b/app/controllers/questions_controller.rb @@ -84,6 +84,13 @@ class QuestionsController < InheritedResources::Base # export_format = params[:export_format] #CSV always now, could expand to xml later end + def median_votes_per_session + @question = current_user.questions.find(params[:id]) + respond_to do |format| + format.xml{ render :xml => {:median => @question.median_votes_per_session}.to_xml and return} + end + end + def object_info_by_visitor_id object_type = params[:object_type] diff --git a/app/models/question.rb b/app/models/question.rb index c3bdf8f..f22f86b 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -1,5 +1,6 @@ class Question < ActiveRecord::Base require 'set' + include Utility extend ActiveSupport::Memoizable belongs_to :creator, :class_name => "Visitor", :foreign_key => "creator_id" @@ -50,7 +51,17 @@ class Question < ActiveRecord::Base def item_count choices.size end - + + # returns array of hashes where each has has voter_id and total keys + def votes_per_session + self.votes.find(:all, :select => 'voter_id, count(*) as total', :group => :voter_id).map { |v| {:voter_id => v.voter_id, :total => v.total.to_i} } + end + + def median_votes_per_session + totals = self.votes_per_session.map { |v| v[:total] } + return median(totals) + end + def choose_prompt(options = {}) # if there is one or fewer active choices, we won't be able to find a prompt diff --git a/config/routes.rb b/config/routes.rb index e3620cb..1a378e1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,6 +6,7 @@ ActionController::Routing::Routes.draw do |map| map.resources :questions, :except => [:edit, :destroy], :member => {:object_info_totals_by_date => :get, :object_info_by_visitor_id => :get, + :median_votes_per_session => :get, :export => :post} , :collection => {:all_num_votes_by_visitor_id => :get, :all_object_info_totals_by_date => :get, diff --git a/lib/utility.rb b/lib/utility.rb new file mode 100644 index 0000000..71ec9e0 --- /dev/null +++ b/lib/utility.rb @@ -0,0 +1,12 @@ +module Utility + def mean(array) + array.inject(0) { |sum, x| sum += x } / array.size.to_f + end + + def median(array, already_sorted=false) + return nil if array.empty? + array = array.sort unless already_sorted + m_pos = array.size / 2 + return array.size % 2 == 1 ? array[m_pos] : mean(array[m_pos-1..m_pos]) + end +end diff --git a/spec/integration/questions_spec.rb b/spec/integration/questions_spec.rb index 184e83a..cbad7da 100644 --- a/spec/integration/questions_spec.rb +++ b/spec/integration/questions_spec.rb @@ -10,6 +10,15 @@ describe "Questions" do end end + describe "GET 'median_votes_per_session'" do + it "should return the median" do + Factory.create(:vote, :question => @questions.first) + get_auth median_votes_per_session_question_path(@questions.first, :format => 'xml') + response.should be_success + response.body.should have_tag("median", :text => "1") + end + end + describe "GET 'index'" do it "should return an array of questions" do get_auth questions_path(:format => 'xml') diff --git a/spec/models/question_spec.rb b/spec/models/question_spec.rb index 8eb2fe7..c4662d4 100644 --- a/spec/models/question_spec.rb +++ b/spec/models/question_spec.rb @@ -22,6 +22,15 @@ describe Question do @question.choices.active.reload.size.should == 2 end + it "should report median votes per session" do + aoiquestion = Factory.create(:aoi_question) + prompt = aoiquestion.prompts.first + Factory.create(:vote, :question => aoiquestion, :prompt => prompt) + Factory.create(:vote, :question => aoiquestion, :prompt => prompt) + aoiquestion.votes_per_session.should == [{:voter_id => aoiquestion.creator.id, :total => 2}] + aoiquestion.median_votes_per_session.should == 2 + end + it "should create a new instance given valid attributes" do # Factory.attributes_for does not return associations, this is a good enough substitute Question.create!(Factory.build(:question).attributes.symbolize_keys) -- libgit2 0.21.2