Commit 06ee1c72a98711ff7e4ce21add3f1725e6af268d
1 parent
9c36c839
Exists in
master
and in
1 other branch
Catchup algorithm in beta test
Showing
3 changed files
with
39 additions
and
12 deletions
Show diff stats
app/controllers/prompts_controller.rb
| ... | ... | @@ -64,8 +64,14 @@ class PromptsController < InheritedResources::Base |
| 64 | 64 | #@prompt.choices.each(&:compute_score!) |
| 65 | 65 | respond_to do |format| |
| 66 | 66 | if successful |
| 67 | - format.xml { render :xml => @question.picked_prompt.to_xml(:methods => [:left_choice_text, :right_choice_text, :left_choice_id, :right_choice_id]), :status => :ok } | |
| 68 | - format.json { render :json => @question.picked_prompt.to_json(:methods => [:left_choice_text, :right_choice_text, :left_choice_id, :right_choice_id]), :status => :ok } | |
| 67 | + if @question.id == 120 #test0330 | |
| 68 | + next_prompt = @question.catchup_choose_prompt | |
| 69 | + else | |
| 70 | + next_prompt = @question.picked_prompt | |
| 71 | + end | |
| 72 | + | |
| 73 | + format.xml { render :xml => next_prompt.to_xml(:methods => [:left_choice_text, :right_choice_text, :left_choice_id, :right_choice_id]), :status => :ok } | |
| 74 | + format.json { render :json => next_prompt.to_json(:methods => [:left_choice_text, :right_choice_text, :left_choice_id, :right_choice_id]), :status => :ok } | |
| 69 | 75 | else |
| 70 | 76 | format.xml { render :xml => c, :status => :unprocessable_entity } |
| 71 | 77 | format.json { render :json => c, :status => :unprocessable_entity } |
| ... | ... | @@ -173,4 +179,4 @@ class PromptsController < InheritedResources::Base |
| 173 | 179 | end_of_association_chain.with_choice_id(params[:choice_id]) |
| 174 | 180 | end |
| 175 | 181 | end |
| 176 | -end | |
| 177 | 182 | \ No newline at end of file |
| 183 | +end | ... | ... |
app/controllers/questions_controller.rb
| ... | ... | @@ -56,7 +56,12 @@ class QuestionsController < InheritedResources::Base |
| 56 | 56 | def show |
| 57 | 57 | @question = Question.find(params[:id]) |
| 58 | 58 | unless params[:barebones] |
| 59 | - @p = @question.picked_prompt | |
| 59 | + if params[:algorithm] && params[:algorithm] == "catchup" | |
| 60 | + logger.info("Question #{@question.id} requested catchup algorithm!") | |
| 61 | + @p = @question.catchup_choose_prompt | |
| 62 | + else | |
| 63 | + @p = @question.picked_prompt | |
| 64 | + end | |
| 60 | 65 | left_choice_text = Proc.new { |options| options[:builder].tag!('left_choice_text', @p.left_choice.item.data) } |
| 61 | 66 | right_choice_text = Proc.new { |options| options[:builder].tag!('right_choice_text', @p.right_choice.item.data) } |
| 62 | 67 | picked_prompt_id = Proc.new { |options| options[:builder].tag!('picked_prompt_id', @p.id) } | ... | ... |
app/models/question.rb
| ... | ... | @@ -37,17 +37,28 @@ class Question < ActiveRecord::Base |
| 37 | 37 | end until @p.active? |
| 38 | 38 | return @p |
| 39 | 39 | end |
| 40 | - | |
| 40 | + | |
| 41 | 41 | # adapted from ruby cookbook(2006): section 5-11 |
| 42 | - def catchup_choose_prompt_id | |
| 42 | + def catchup_choose_prompt | |
| 43 | 43 | weighted = catchup_prompts_weights |
| 44 | 44 | # Rand returns a number from 0 - 1, so weighted needs to be normalized |
| 45 | - target = rand | |
| 46 | - weighted.each do |item, weight| | |
| 47 | - return item if target <= weight | |
| 48 | - target -= weight | |
| 45 | + prompt = nil | |
| 46 | + | |
| 47 | + until prompt && prompt.active? | |
| 48 | + target = rand | |
| 49 | + prompt_id = nil | |
| 50 | + | |
| 51 | + weighted.each do |item, weight| | |
| 52 | + if target <= weight | |
| 53 | + prompt_id = item | |
| 54 | + break | |
| 55 | + end | |
| 56 | + target -= weight | |
| 57 | + end | |
| 58 | + prompt = Prompt.find(prompt_id, :include => ['left_choice', 'right_choice']) | |
| 49 | 59 | end |
| 50 | 60 | # check if prompt has two active choices here, maybe we can set this on the prompt level too? |
| 61 | + prompt | |
| 51 | 62 | end |
| 52 | 63 | |
| 53 | 64 | |
| ... | ... | @@ -56,8 +67,13 @@ class Question < ActiveRecord::Base |
| 56 | 67 | weights = Hash.new(0) |
| 57 | 68 | throttle_min = 0.05 |
| 58 | 69 | #assuming all prompts exist |
| 59 | - prompts.each do |p| | |
| 60 | - weights[p.id] = [(1.0/ (p.votes.size + 1).to_f).to_f, throttle_min].min | |
| 70 | + | |
| 71 | + #the_prompts = prompts.find(:all, :select => 'id, votes_count') | |
| 72 | + #We don't really need to instantiate all the objects | |
| 73 | + the_prompts = ActiveRecord::Base.connection.select_all("SELECT id, votes_count from prompts where question_id =#{self.id}") | |
| 74 | + | |
| 75 | + the_prompts.each do |p| | |
| 76 | + weights[p["id"].to_i] = [(1.0/ (p["votes_count"].to_i + 1).to_f).to_f, throttle_min].min | |
| 61 | 77 | end |
| 62 | 78 | normalize!(weights) |
| 63 | 79 | weights | ... | ... |