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 | ... | ... |